diff --git a/src/tests/mod.rs b/src/tests/mod.rs index 8c9a5392..aa2f41af 100644 --- a/src/tests/mod.rs +++ b/src/tests/mod.rs @@ -1,6 +1,6 @@ extern crate test_generator; -use heraclitus_compiler::prelude::Message; use crate::compiler::{AmberCompiler, CompilerOptions}; +use heraclitus_compiler::prelude::Message; use itertools::Itertools; use pretty_assertions::assert_eq; use std::fs; @@ -14,12 +14,14 @@ mod stdlib; mod validity; mod erroring; +const SUCCEEDED: &str = "Succeeded"; + pub enum TestOutcomeTarget { Success, Failure, } -pub fn eval_amber_code(code: &str) -> Result { +fn eval_amber(code: &str) -> Result { let options = CompilerOptions::default(); let mut compiler = AmberCompiler::new(code.to_string(), None, options); compiler.test_eval() @@ -27,26 +29,28 @@ pub fn eval_amber_code(code: &str) -> Result { /// Tests script output in case of success or failure pub fn test_amber(code: &str, result: &str, target: TestOutcomeTarget) { - let evaluated = eval_amber_code(code); + let evaluated = eval_amber(code); match target { TestOutcomeTarget::Success => match evaluated { Ok(stdout) => { - assert_eq!( - stdout.trim_end_matches('\n'), - result.trim_end_matches('\n'), - ) - }, + let stdout = stdout.trim_end_matches('\n'); + if stdout != SUCCEEDED { + let result = result.trim_end_matches('\n'); + assert_eq!(stdout, result) + } + } Err(err) => { panic!("ERROR: {}", err.message.unwrap()) - }, + } } TestOutcomeTarget::Failure => match evaluated { Ok(stdout) => { panic!("Expected error, got: {}", stdout) - }, + } Err(err) => { - assert_eq!(err.message.expect("Error message expected"), result) - }, + let message = err.message.expect("Error message expected"); + assert_eq!(message, result) + } } } } @@ -73,7 +77,7 @@ pub fn eval_bash>(code: T) -> (String, String) { ) } -/// Extracts the output from the comment of amber code +/// Extracts the output from the comment of Amber code fn extract_output(code: impl Into) -> String { code.into() .lines() @@ -86,19 +90,18 @@ fn extract_output(code: impl Into) -> String { /// Inner test logic for testing script output in case of success or failure pub fn script_test(input: &str, target: TestOutcomeTarget) { - let code = - fs::read_to_string(input).unwrap_or_else(|_| panic!("Failed to open {input} test file")); - - // extract Output from script comment + let code = fs::read_to_string(input) + .unwrap_or_else(|_| panic!("Failed to open {input} test file")); + // Extract output from script comment let mut output = extract_output(&code); - - // if output is not in comment, try to read from .output.txt file + // If output is not in comment, try to read from .output.txt file if output.is_empty() { - let output_path = PathBuf::from(input.replace(".ab", ".output.txt")); - output = match output_path.exists() { - true => fs::read_to_string(output_path) - .unwrap_or_else(|_| panic!("Failed to open {input}.output.txt file")), - _ => "Succeeded".to_string(), + let path = PathBuf::from(input.replace(".ab", ".output.txt")); + output = if path.exists() { + fs::read_to_string(&path) + .unwrap_or_else(|_| panic!("Failed to open {} test file", path.display())) + } else { + SUCCEEDED.to_string() }; } test_amber(&code, &output, target); diff --git a/src/tests/validity/array_get_negative_index_by_copy.ab b/src/tests/validity/array_get_negative_index_by_copy.ab new file mode 100644 index 00000000..afa06d00 --- /dev/null +++ b/src/tests/validity/array_get_negative_index_by_copy.ab @@ -0,0 +1,30 @@ +// Output +// Value at -5: "" +// Value at -4: "zero" +// Value at -3: "one" +// Value at -2: "two" +// Value at -1: "three" + +// Replace this with builtin if/when we get around to writing one. +#[allow_absurd_cast] +fun bash_version(): Num { + let major = trust $ echo "\$\{BASH_VERSINFO[0]}" $ as Num + let minor = trust $ echo "\$\{BASH_VERSINFO[1]}" $ as Num + return (major * 100) + minor +} + +fun test_index(array) { + for index in -5..=-1 { + echo "Value at {index}: \"{array[index]}\"" + } +} + +main { + if bash_version() >= 402 { + let array = ["zero", "one", "two", "three"] + test_index(array) + } else { + // Negative indexing is not supported before Bash 4.2. + echo "Succeeded" + } +} diff --git a/src/tests/validity/array_get_negative_index_by_ref.ab b/src/tests/validity/array_get_negative_index_by_ref.ab new file mode 100644 index 00000000..443486a1 --- /dev/null +++ b/src/tests/validity/array_get_negative_index_by_ref.ab @@ -0,0 +1,30 @@ +// Output +// Value at -5: "" +// Value at -4: "zero" +// Value at -3: "one" +// Value at -2: "two" +// Value at -1: "three" + +// Replace this with builtin if/when we get around to writing one. +#[allow_absurd_cast] +fun bash_version(): Num { + let major = trust $ echo "\$\{BASH_VERSINFO[0]}" $ as Num + let minor = trust $ echo "\$\{BASH_VERSINFO[1]}" $ as Num + return (major * 100) + minor +} + +fun test_index(ref byref) { + for index in -5..=-1 { + echo "Value at {index}: \"{byref[index]}\"" + } +} + +main { + if bash_version() >= 402 { + let array = ["zero", "one", "two", "three"] + test_index(array) + } else { + // Negative indexing is not supported before Bash 4.2. + echo "Succeeded" + } +} diff --git a/src/tests/validity/array_get_negative_index_local.ab b/src/tests/validity/array_get_negative_index_local.ab new file mode 100644 index 00000000..3ed56631 --- /dev/null +++ b/src/tests/validity/array_get_negative_index_local.ab @@ -0,0 +1,29 @@ +// Output +// Value at -5: "" +// Value at -4: "zero" +// Value at -3: "one" +// Value at -2: "two" +// Value at -1: "three" + +// Replace this with builtin if/when we get around to writing one. +#[allow_absurd_cast] +fun bash_version(): Num { + let major = trust $ echo "\$\{BASH_VERSINFO[0]}" $ as Num + let minor = trust $ echo "\$\{BASH_VERSINFO[1]}" $ as Num + return (major * 100) + minor +} + +main { + if bash_version() >= 402 { + // Do not use loop; we want to test compile time arithmetic. + let array = ["zero", "one", "two", "three"] + echo "Value at -5: \"{array[-5]}\"" + echo "Value at -4: \"{array[-4]}\"" + echo "Value at -3: \"{array[-3]}\"" + echo "Value at -2: \"{array[-2]}\"" + echo "Value at -1: \"{array[-1]}\"" + } else { + // Negative indexing is not supported before Bash 4.2. + echo "Succeeded" + } +} diff --git a/src/tests/validity/array_get_index_by_copy.ab b/src/tests/validity/array_get_positive_index_by_copy.ab similarity index 67% rename from src/tests/validity/array_get_index_by_copy.ab rename to src/tests/validity/array_get_positive_index_by_copy.ab index e1394566..0a246b42 100644 --- a/src/tests/validity/array_get_index_by_copy.ab +++ b/src/tests/validity/array_get_positive_index_by_copy.ab @@ -1,9 +1,4 @@ // Output -// Value at -5: "" -// Value at -4: "zero" -// Value at -3: "one" -// Value at -2: "two" -// Value at -1: "three" // Value at 0: "zero" // Value at 1: "one" // Value at 2: "two" @@ -11,7 +6,7 @@ // Value at 4: "" fun test_index(array) { - for index in -5..=4 { + for index in 0..=4 { echo "Value at {index}: \"{array[index]}\"" } } diff --git a/src/tests/validity/array_get_index_by_ref.ab b/src/tests/validity/array_get_positive_index_by_ref.ab similarity index 67% rename from src/tests/validity/array_get_index_by_ref.ab rename to src/tests/validity/array_get_positive_index_by_ref.ab index 6c2e7b4d..889af2ed 100644 --- a/src/tests/validity/array_get_index_by_ref.ab +++ b/src/tests/validity/array_get_positive_index_by_ref.ab @@ -1,9 +1,4 @@ // Output -// Value at -5: "" -// Value at -4: "zero" -// Value at -3: "one" -// Value at -2: "two" -// Value at -1: "three" // Value at 0: "zero" // Value at 1: "one" // Value at 2: "two" @@ -11,7 +6,7 @@ // Value at 4: "" fun test_index(ref byref) { - for index in -5..=4 { + for index in 0..=4 { echo "Value at {index}: \"{byref[index]}\"" } } diff --git a/src/tests/validity/array_get_index_local.ab b/src/tests/validity/array_get_positive_index_local.ab similarity index 57% rename from src/tests/validity/array_get_index_local.ab rename to src/tests/validity/array_get_positive_index_local.ab index 9ad9dd92..ed094170 100644 --- a/src/tests/validity/array_get_index_local.ab +++ b/src/tests/validity/array_get_positive_index_local.ab @@ -1,9 +1,4 @@ // Output -// Value at -5: "" -// Value at -4: "zero" -// Value at -3: "one" -// Value at -2: "two" -// Value at -1: "three" // Value at 0: "zero" // Value at 1: "one" // Value at 2: "two" @@ -13,11 +8,6 @@ main { // Do not use loop; we want to test compile time arithmetic. let array = ["zero", "one", "two", "three"] - echo "Value at -5: \"{array[-5]}\"" - echo "Value at -4: \"{array[-4]}\"" - echo "Value at -3: \"{array[-3]}\"" - echo "Value at -2: \"{array[-2]}\"" - echo "Value at -1: \"{array[-1]}\"" echo "Value at 0: \"{array[0]}\"" echo "Value at 1: \"{array[1]}\"" echo "Value at 2: \"{array[2]}\""