summaryrefslogtreecommitdiff
path: root/rust/src
diff options
context:
space:
mode:
Diffstat (limited to 'rust/src')
-rw-r--r--rust/src/ast.rs4
-rw-r--r--rust/src/lambda.rs12
-rw-r--r--rust/src/web.rs35
3 files changed, 48 insertions, 3 deletions
diff --git a/rust/src/ast.rs b/rust/src/ast.rs
index 3f8b772..e70f323 100644
--- a/rust/src/ast.rs
+++ b/rust/src/ast.rs
@@ -38,6 +38,10 @@ pub fn identifier() -> RegexGeneratorStrategy<String> {
string_regex(IDENTIFIER).unwrap()
}
+pub fn ascii_identifier() -> RegexGeneratorStrategy<String> {
+ string_regex("[a-zA-Z][a-zA-Z0-9]*").unwrap()
+}
+
impl Arbitrary for Value {
type Parameters = ();
type Strategy = BoxedStrategy<Self>;
diff --git a/rust/src/lambda.rs b/rust/src/lambda.rs
index 9b7045f..e22d210 100644
--- a/rust/src/lambda.rs
+++ b/rust/src/lambda.rs
@@ -1,5 +1,6 @@
use proptest::{
arbitrary::{any, any_with, arbitrary_with},
+ prelude::*,
strategy::{Strategy, ValueTree},
test_runner::TestRunner,
};
@@ -109,11 +110,20 @@ pub fn generate_expr(size: u32, runner: &mut TestRunner) -> Value {
let n = any::<u16>().new_tree(runner).unwrap().current();
Value::Num(n.into())
}
- 2 => Value::Sym(identifier().new_tree(runner).unwrap().current()),
+ 2 => Value::Sym(ascii_identifier().new_tree(runner).unwrap().current()),
+ 3 => Value::Sym(identifier().new_tree(runner).unwrap().current()),
+ 4 => simple_app().new_tree(runner).unwrap().current(),
_ => todo!(),
}
}
+fn simple_app() -> impl Strategy<Value = Value> {
+ let any_num = any::<i32>().prop_map(Value::Num);
+ let any_sym = identifier().prop_map(Value::Sym);
+ let leaf = prop_oneof![any_num, any_sym];
+ (leaf.clone(), leaf.clone()).prop_map(|(l, r)| Value::App(Box::new(l), Box::new(r)))
+}
+
#[cfg(test)]
mod lambda_test {
use crate::parser::parse;
diff --git a/rust/src/web.rs b/rust/src/web.rs
index 62dea22..af27eda 100644
--- a/rust/src/web.rs
+++ b/rust/src/web.rs
@@ -387,20 +387,51 @@ mod app_tests {
}
#[test]
- async fn client_generates_variables_at_level_2() {
+ async fn client_generates_ascii_variables_at_level_2() {
let mut client = client();
client.grade = 2;
let (input, _) = client.generate_expr();
let parsed = parse(&input);
- match parsed[..] {
+ match &parsed[..] {
+ [Value::Sym(name)] => {
+ println!("{}", name);
+ assert!(name.chars().all(|c| c.is_ascii_alphanumeric()));
+ }
+ _ => panic!("Expected symbol, got {:?}", parsed),
+ }
+ }
+
+ #[test]
+ async fn client_generates_unicode_variables_at_level_3() {
+ let mut client = client();
+ client.grade = 3;
+
+ let (input, _) = client.generate_expr();
+
+ let parsed = parse(&input);
+ match &parsed[..] {
[Value::Sym(_)] => (),
_ => panic!("Expected symbol, got {:?}", parsed),
}
}
#[test]
+ async fn client_generates_binary_application_at_level_4() {
+ let mut client = client();
+ client.grade = 4;
+
+ let (input, _) = client.generate_expr();
+
+ let parsed = parse(&input);
+ match &parsed[..] {
+ [Value::App(_, _)] => (),
+ _ => panic!("Expected symbol, got {:?}", parsed),
+ }
+ }
+
+ #[test]
async fn client_increases_grade_on_successful_test() {
let mut client = client();
let expected = "1".to_string();