use lex_ast::canonicalize_program;
use lex_bytecode::{compile_program, vm::Vm, Value};
use lex_runtime::{DefaultHandler, Policy};
use lex_syntax::parse_source;
fn run(src: &str, func: &str, args: Vec<Value>) -> Value {
let prog = parse_source(src).expect("parse");
let stages = canonicalize_program(&prog);
if let Err(errs) = lex_types::check_program(&stages) {
panic!("type errors: {errs:#?}");
}
let bc = compile_program(&stages);
let handler = DefaultHandler::new(Policy::permissive());
let mut vm = Vm::with_handler(&bc, Box::new(handler));
vm.call(func, args).expect("vm")
}
#[test]
fn parallel_list_runs_three_actions_in_input_order() {
let src = r#"
import "std.flow" as flow
fn run3() -> List[Int] {
flow.parallel_list([
fn () -> Int { 7 },
fn () -> Int { 11 },
fn () -> Int { 13 }
])
}
"#;
let r = run(src, "run3", vec![]);
assert_eq!(
r,
Value::List(vec![Value::Int(7), Value::Int(11), Value::Int(13)].into())
);
}
#[test]
fn parallel_list_empty_returns_empty_list() {
let src = r#"
import "std.flow" as flow
fn run0() -> List[Int] {
flow.parallel_list([])
}
"#;
let r = run(src, "run0", vec![]);
assert_eq!(r, Value::List(vec![].into()));
}
#[test]
fn parallel_list_single_action_returns_singleton() {
let src = r#"
import "std.flow" as flow
fn run1() -> List[Int] {
flow.parallel_list([fn () -> Int { 42 }])
}
"#;
let r = run(src, "run1", vec![]);
assert_eq!(r, Value::List(vec![Value::Int(42)].into()));
}
#[test]
fn parallel_list_preserves_captured_locals() {
let src = r#"
import "std.flow" as flow
fn run_caps() -> List[Int] {
let a := 1
let b := 2
let c := 3
flow.parallel_list([
fn () -> Int { a + 10 },
fn () -> Int { b + 20 },
fn () -> Int { c + 30 }
])
}
"#;
let r = run(src, "run_caps", vec![]);
assert_eq!(
r,
Value::List(vec![Value::Int(11), Value::Int(22), Value::Int(33)].into())
);
}
#[test]
fn parallel_list_works_with_string_return_type() {
let src = r#"
import "std.flow" as flow
fn run_strs() -> List[Str] {
flow.parallel_list([
fn () -> Str { "alpha" },
fn () -> Str { "beta" },
fn () -> Str { "gamma" }
])
}
"#;
let r = run(src, "run_strs", vec![]);
assert_eq!(
r,
Value::List(vec![
Value::Str("alpha".into()),
Value::Str("beta".into()),
Value::Str("gamma".into()),
].into())
);
}