From f60441ef9d44914aed91422caac647896cf691c3 Mon Sep 17 00:00:00 2001 From: 0x4261756D <38735823+0x4261756D@users.noreply.github.com> Date: Sun, 18 Dec 2022 04:05:50 +0100 Subject: [PATCH] Improved the test system --- src/main.rs | 92 ++++++++++++++++++----- tests/invalid_function_name_intrinsic.qbl | 2 +- tests/invalid_function_name_operation.qbl | 2 +- tests/missing_function_name.qbl | 2 +- tests/recursion.qbl | 5 +- tests/req_impl.qbl | 4 + tests/rule110.qbl | 2 +- tests/test.qbl | 5 +- tests/typecheck_function_multiple_io.qbl | 5 +- tests/unknown_function_basic.qbl | 2 +- tests/unknown_function_hard.qbl | 2 +- tests/unknown_function_in_function.qbl | 2 +- tests/while.qbl | 5 +- 13 files changed, 96 insertions(+), 34 deletions(-) diff --git a/src/main.rs b/src/main.rs index b6c0a41..20a31a4 100644 --- a/src/main.rs +++ b/src/main.rs @@ -102,24 +102,72 @@ fn main() { "-t" | "--test" => { + let mut count = 0; for f in fs::read_dir(&args[2]).unwrap() { let f = f.unwrap(); let file_content = fs::read_to_string(f.path()).unwrap(); println!("========NOW TESTING '{:?}'========", f.path()); - match compile(file_content, &intrinsics, interpret, debug) + match compile(&file_content, &intrinsics, interpret, debug) { - Ok(()) => println!("\n\n\n---Successfully parsed '{:?}'---", f.path()), - Err(msg) => println!("ERROR: {}", msg), + Ok(maybe_msg) => + { + println!("---Successfully parsed '{:?}'---", f.path()); + if let Some(msg) = &maybe_msg + { + print!("---Output---\n'{}'\n", msg); + } + let expected = &format!("//valid,{}:END:", maybe_msg.unwrap_or(String::new()).replace("\n", "\n//")); + if file_content.starts_with(expected) + { + println!("===PASSED==="); + count += 1; + } + else if let Some(index) = file_content.find("//:END:") + { + let expected_output = file_content[8..index].replace("\n//", "\n"); + println!("\n===FAILED===\nExpected the output to be\n'{}'\n({})", expected_output, expected); + } + else + { + panic!("Could not find an ending marker (:END:) for the expected output in {:?}", f.file_name()); + } + } + Err(msg) => + { + println!("ERROR: {}", msg); + if file_content.starts_with(&format!("//invalid,{}:END:", msg.replace("\n", "\n//"))) + { + println!("===PASSED==="); + count += 1; + } + else if let Some(index) = file_content.find(":END:") + { + let expected_output = file_content[10..index].replace("\n//", "\n"); + println!("\n\n===FAILED===\nExpected the output to be {}", expected_output); + } + else + { + panic!("Could not find an ending marker (//:END:) for the expected output in {:?}", f.file_name()); + } + } } } + println!("\n\n=========RESULT=========\n{}/{}", count, fs::read_dir(&args[2]).unwrap().count()); } "-c" | "--compile" => { let file_content = fs::read_to_string(&args[2]).expect("Could not read the source file"); - match compile(file_content, &intrinsics, interpret, debug) + match compile(&file_content, &intrinsics, interpret, debug) { - Ok(()) => println!("\n\n\n---Successfully parsed '{}'---", args[2]), + Ok(maybe_msg) => + { + println!("---Successfully parsed '{}'---", args[2]); + if let Some(msg) = maybe_msg + { + print!("---Output---\n\n{}", msg); + } + } Err(msg) => println!("ERROR: {}", msg), } } @@ -127,7 +175,7 @@ fn main() } } -fn compile(file_content: String, intrinsics: &HashMap<&str, (Vec, Vec)>, interpret: bool, debug: bool) -> Result<(), String> +fn compile(file_content: &String, intrinsics: &HashMap<&str, (Vec, Vec)>, interpret: bool, debug: bool) -> Result, String> { let mut tokens: Vec = tokenize(&file_content)?; println!("---Done tokenizing, got {} tokens---", tokens.len()); @@ -139,21 +187,26 @@ fn compile(file_content: String, intrinsics: &HashMap<&str, (Vec, Vec< println!("---Done validating function calls---"); typecheck(&operations, &functions, &intrinsics, debug)?; println!("---Done typechecking---"); - if interpret + let output = if interpret { - println!("---Starting to interpret the program---\n\n"); - interpret_program(&operations, &mut Vec::new(), &functions, &intrinsics, debug); + println!("---Starting to interpret the program---"); + Some(interpret_program(&operations, &mut Vec::new(), &functions, &intrinsics, debug)) } - return Ok(()); + else + { + None + }; + return Ok(output); } -fn interpret_program(operations: &Vec, queue: &mut Vec, functions: &Vec, intrinsics: &HashMap<&str, (Vec, Vec)>, debug: bool) +fn interpret_program(operations: &Vec, queue: &mut Vec, functions: &Vec, intrinsics: &HashMap<&str, (Vec, Vec)>, debug: bool) -> String { + let mut output = String::new(); for operation in operations { if debug { - println!("before: {:?}: {:?}", operation, queue); + println!("before: {:?}: {:?}, '{}'", operation, queue, output); } match operation { @@ -191,7 +244,7 @@ fn interpret_program(operations: &Vec, queue: &mut Vec, funct let val = queue.remove(0); function_context.push(val); } - interpret_program(&function.content, function_context, functions, intrinsics, debug); + output += interpret_program(&function.content, function_context, functions, intrinsics, debug).as_str(); for val in function_context { queue.push(val.to_string()); @@ -202,11 +255,11 @@ fn interpret_program(operations: &Vec, queue: &mut Vec, funct let val = queue.remove(0); if val == "true" { - interpret_program(if_block, queue, functions, intrinsics, debug); + output += interpret_program(if_block, queue, functions, intrinsics, debug).as_str(); } else if let Some(else_block) = maybe_else_block { - interpret_program(else_block, queue, functions, intrinsics, debug); + output += interpret_program(else_block, queue, functions, intrinsics, debug).as_str(); } } Operation::Intrinsic(intrinsic_name, line, col) => @@ -215,7 +268,7 @@ fn interpret_program(operations: &Vec, queue: &mut Vec, funct { "print" => { - print!("{}", queue.remove(0)); + output += format!("{}", queue.remove(0)).as_str(); } "-" => { @@ -260,7 +313,7 @@ fn interpret_program(operations: &Vec, queue: &mut Vec, funct } "println" => { - println!("{}", queue.remove(0)); + output += format!("{}\n", queue.remove(0)).as_str(); } _ => { @@ -277,7 +330,7 @@ fn interpret_program(operations: &Vec, queue: &mut Vec, funct { break; } - interpret_program(while_block, queue, functions, intrinsics, debug); + output += interpret_program(while_block, queue, functions, intrinsics, debug).as_str(); } } Operation::Depth(_, _) => @@ -292,9 +345,10 @@ fn interpret_program(operations: &Vec, queue: &mut Vec, funct } if debug { - println!("after: {:?}: {:?}", operation, queue); + println!("after: {:?}: {:?}, '{}'", operation, queue, output); } } + return output; } fn typecheck(operations: &Vec, functions: &Vec, intrinsics: &HashMap<&str, (Vec, Vec)>, debug: bool) -> Result<(), String> diff --git a/tests/invalid_function_name_intrinsic.qbl b/tests/invalid_function_name_intrinsic.qbl index a40633e..bb66172 100644 --- a/tests/invalid_function_name_intrinsic.qbl +++ b/tests/invalid_function_name_intrinsic.qbl @@ -1,4 +1,4 @@ -//invalid,Function name print at 3:22 is already an intrinsic +//invalid,Function name print at 3:22 is already an intrinsic:END: function int => print { diff --git a/tests/invalid_function_name_operation.qbl b/tests/invalid_function_name_operation.qbl index 3fa6d83..dbe3236 100644 --- a/tests/invalid_function_name_operation.qbl +++ b/tests/invalid_function_name_operation.qbl @@ -1,4 +1,4 @@ -//invalid,Expected function name but got deq at 3:20 +//invalid,Expected function name but got deq at 3:20:END: function int => deq { diff --git a/tests/missing_function_name.qbl b/tests/missing_function_name.qbl index ef8b34e..be8070a 100644 --- a/tests/missing_function_name.qbl +++ b/tests/missing_function_name.qbl @@ -1,4 +1,4 @@ -//invalid,Expected function name but got { at 4:2 +//invalid,Expected function name but got { at 4:2:END: function int => { diff --git a/tests/recursion.qbl b/tests/recursion.qbl index 46f7b9e..f942510 100644 --- a/tests/recursion.qbl +++ b/tests/recursion.qbl @@ -1,3 +1,6 @@ +//valid,10946 +//:END: + function int int int int => int fibonacci { dup 0 == req req req req @@ -11,4 +14,4 @@ function int int int int => int fibonacci } } -20 0 1 0 fibonacci print \ No newline at end of file +20 0 1 0 fibonacci println \ No newline at end of file diff --git a/tests/req_impl.qbl b/tests/req_impl.qbl index 8f7cb8c..f8d5d12 100644 --- a/tests/req_impl.qbl +++ b/tests/req_impl.qbl @@ -1,3 +1,7 @@ +//valid,231 +//231 +//:END: + function int => int req_impl { } 1 2 3 req_impl print print println diff --git a/tests/rule110.qbl b/tests/rule110.qbl index 7f5dad1..0557be5 100644 --- a/tests/rule110.qbl +++ b/tests/rule110.qbl @@ -1,4 +1,4 @@ - +//valid,:END: function bool bool bool => bool rule110 { if diff --git a/tests/test.qbl b/tests/test.qbl index f252b28..152d4b0 100644 --- a/tests/test.qbl +++ b/tests/test.qbl @@ -1,6 +1,5 @@ -//valid -//output: Hello, World! -//4242test2Falsetesttesttest +//valid,Hello, World! +//4242test2Falsetesttesttest:END: "Hello, World!\n" print 43 foo foo deq diff --git a/tests/typecheck_function_multiple_io.qbl b/tests/typecheck_function_multiple_io.qbl index 9ae2695..054ae6b 100644 --- a/tests/typecheck_function_multiple_io.qbl +++ b/tests/typecheck_function_multiple_io.qbl @@ -1,8 +1,9 @@ -//valid,output:42footesttest2stuff +//valid,42footesttest2stuff +//:END: function int str any => str str str foo { print req deq "test" "test2" "stuff" print } -42 "foo" "bar" foo print print print \ No newline at end of file +42 "foo" "bar" foo print print println \ No newline at end of file diff --git a/tests/unknown_function_basic.qbl b/tests/unknown_function_basic.qbl index fdace0f..4f39e5e 100644 --- a/tests/unknown_function_basic.qbl +++ b/tests/unknown_function_basic.qbl @@ -1,2 +1,2 @@ -//invalid,Call to unknown function foo at 2:4 +//invalid,Call to unknown function 'foo' at 2:4:END: foo \ No newline at end of file diff --git a/tests/unknown_function_hard.qbl b/tests/unknown_function_hard.qbl index a7169a3..6b20c82 100644 --- a/tests/unknown_function_hard.qbl +++ b/tests/unknown_function_hard.qbl @@ -1,4 +1,4 @@ -//invalid,Call to unknown function bar at 9:7 +//invalid,Call to unknown function 'bar' at 9:7:END: function int => foo { diff --git a/tests/unknown_function_in_function.qbl b/tests/unknown_function_in_function.qbl index 9ba2efa..4883756 100644 --- a/tests/unknown_function_in_function.qbl +++ b/tests/unknown_function_in_function.qbl @@ -1,4 +1,4 @@ -//invalid,Call to unknown function bar at 5:5 +//invalid,Call to unknown function 'bar' at 5:5:END: function => foo { diff --git a/tests/while.qbl b/tests/while.qbl index e9584b5..69c8da0 100644 --- a/tests/while.qbl +++ b/tests/while.qbl @@ -1,4 +1,5 @@ -//valid,output:10987654321falsefalse +//valid,10987654321falsefalse +//:END: true while { @@ -18,4 +19,4 @@ true true true while { false } -print print \ No newline at end of file +print println \ No newline at end of file