use super::harness::*; #[test] fn rand_in_range() { let f = forth_seeded(12345); f.evaluate("0 10 rand", &default_ctx()).unwrap(); let val = stack_float(&f); assert!(val >= 0.0 && val < 10.0, "rand {} not in [0, 10)", val); } #[test] fn rand_deterministic() { let f1 = forth_seeded(99); let f2 = forth_seeded(99); f1.evaluate("0 100 rand", &default_ctx()).unwrap(); f2.evaluate("0 100 rand", &default_ctx()).unwrap(); assert_eq!(f1.stack(), f2.stack()); } #[test] fn seed_resets() { let f1 = forth_seeded(1); f1.evaluate("42 seed 0 100 rand", &default_ctx()).unwrap(); let f2 = forth_seeded(999); f2.evaluate("42 seed 0 100 rand", &default_ctx()).unwrap(); assert_eq!(f1.stack(), f2.stack()); } #[test] fn coin_binary() { let f = forth_seeded(42); f.evaluate("coin", &default_ctx()).unwrap(); let val = stack_int(&f); assert!(val == 0 || val == 1); } #[test] fn chance_zero() { // 0.0 probability should never execute the quotation let f = run("99 { 42 } 0.0 chance"); assert_eq!(stack_int(&f), 99); // quotation not executed, 99 still on stack } #[test] fn chance_one() { // 1.0 probability should always execute the quotation let f = run("{ 42 } 1.0 chance"); assert_eq!(stack_int(&f), 42); } #[test] fn choose_from_list() { let f = forth_seeded(42); f.evaluate("10 20 30 3 choose", &default_ctx()).unwrap(); let val = stack_int(&f); assert!(val == 10 || val == 20 || val == 30); } #[test] fn choose_underflow() { expect_error("1 2 5 choose", "stack underflow"); } #[test] fn cycle_deterministic() { for runs in 0..6 { let ctx = ctx_with(|c| c.runs = runs); let f = run_ctx("10 20 30 3 cycle", &ctx); let expected = [10, 20, 30][runs % 3]; assert_eq!(stack_int(&f), expected, "cycle at runs={}", runs); } } #[test] fn cycle_zero_count() { expect_error("1 2 3 0 cycle", "cycle count must be > 0"); } #[test] fn mtof_a4() { expect_float("69 mtof", 440.0); } #[test] fn mtof_octave() { expect_float("81 mtof", 880.0); } #[test] fn mtof_c4() { expect_floats_close("60 mtof", 261.6255653, 0.001); } #[test] fn ftom_440() { expect_float("440 ftom", 69.0); } #[test] fn ftom_880() { expect_float("880 ftom", 81.0); } #[test] fn mtof_ftom_roundtrip() { expect_float("60 mtof ftom", 60.0); }