Skip to content

Commit

Permalink
Support array indexing by range II (#634)
Browse files Browse the repository at this point in the history
  • Loading branch information
hdwalters authored Dec 18, 2024
1 parent 2d89f1e commit 3d5c47f
Show file tree
Hide file tree
Showing 7 changed files with 118 additions and 46 deletions.
51 changes: 27 additions & 24 deletions src/tests/mod.rs
Original file line number Diff line number Diff line change
@@ -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;
Expand All @@ -14,39 +14,43 @@ mod stdlib;
mod validity;
mod erroring;

const SUCCEEDED: &str = "Succeeded";

pub enum TestOutcomeTarget {
Success,
Failure,
}

pub fn eval_amber_code(code: &str) -> Result<String, Message> {
fn eval_amber(code: &str) -> Result<String, Message> {
let options = CompilerOptions::default();
let mut compiler = AmberCompiler::new(code.to_string(), None, options);
compiler.test_eval()
}

/// 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)
}
}
}
}
Expand All @@ -73,7 +77,7 @@ pub fn eval_bash<T: Into<String>>(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>) -> String {
code.into()
.lines()
Expand All @@ -86,19 +90,18 @@ fn extract_output(code: impl Into<String>) -> 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);
Expand Down
30 changes: 30 additions & 0 deletions src/tests/validity/array_get_negative_index_by_copy.ab
Original file line number Diff line number Diff line change
@@ -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"
}
}
30 changes: 30 additions & 0 deletions src/tests/validity/array_get_negative_index_by_ref.ab
Original file line number Diff line number Diff line change
@@ -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"
}
}
29 changes: 29 additions & 0 deletions src/tests/validity/array_get_negative_index_local.ab
Original file line number Diff line number Diff line change
@@ -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"
}
}
Original file line number Diff line number Diff line change
@@ -1,17 +1,12 @@
// 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"
// Value at 3: "three"
// Value at 4: ""

fun test_index(array) {
for index in -5..=4 {
for index in 0..=4 {
echo "Value at {index}: \"{array[index]}\""
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,17 +1,12 @@
// 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"
// Value at 3: "three"
// Value at 4: ""

fun test_index(ref byref) {
for index in -5..=4 {
for index in 0..=4 {
echo "Value at {index}: \"{byref[index]}\""
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -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"
Expand All @@ -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]}\""
Expand Down

0 comments on commit 3d5c47f

Please sign in to comment.