G8: EPS import regression tests for operator type checks

## What and why

Hostile EPS programs that give an operator the wrong operand type (a non-integer count, a non-procedure body, a non-boolean condition) must stop the import with a `typecheck` error instead of misbehaving. One test per operator: copy, for, idiv, if, ifelse, index, loop, mod, repeat, roll and srand. The tests only: the limits and checks they cover are already on main, so the tests pin that behaviour so a later change can't silently drop it.

## How it was tested

The new tests pass, along with the full `cargo xtask ci` on the branch.

Combines the tests from: stream/vc-featD-g8-eps-copy-typecheck-count, stream/vc-featD-g8-eps-for-typecheck-procedure, stream/vc-featD-g8-eps-idiv-typecheck-operand, stream/vc-featD-g8-eps-if-typecheck-condition, stream/vc-featD-g8-eps-if-typecheck-procedure, stream/vc-featD-g8-eps-ifelse-typecheck-condition, stream/vc-featD-g8-eps-ifelse-typecheck-procedure, stream/vc-featD-g8-eps-index-typecheck-count, stream/vc-featD-g8-eps-loop-typecheck-procedure, stream/vc-featD-g8-eps-mod-typecheck-operand, stream/vc-featD-g8-eps-repeat-typecheck-count, stream/vc-featD-g8-eps-repeat-typecheck-procedure, stream/vc-featD-g8-eps-roll-typecheck-j, stream/vc-featD-g8-eps-roll-typecheck-n, stream/vc-featD-g8-eps-srand-typecheck-operand
This commit is contained in:
nrq6993-a11y
2026-10-26 16:06:20 +07:00
committed by bflatastic
parent de151f849a
commit 97652362fa
+90
View File
@@ -19,6 +19,96 @@ pub(super) fn read(body: &str) -> crate::Imported {
import(&eps(body)).unwrap()
}
#[test]
fn postscript_srand_non_integer_operand_is_refused() {
let err = import(&eps("1.5 srand")).unwrap_err();
assert!(err.contains("typecheck") && err.contains("srand"));
}
#[test]
fn postscript_roll_non_integer_count_is_refused() {
let err = import(&eps("1.5 1 roll")).unwrap_err();
assert!(err.contains("typecheck"));
}
#[test]
fn postscript_roll_non_integer_displacement_is_refused() {
let err = import(&eps("1 1.5 roll")).unwrap_err();
assert!(err.contains("typecheck"));
}
#[test]
fn postscript_repeat_non_procedure_operand_is_refused() {
let err = import(&eps("1 1 repeat")).unwrap_err();
assert!(err.contains("typecheck") && err.contains("repeat"));
}
#[test]
fn postscript_repeat_non_integer_count_is_refused() {
let err = import(&eps("1.5 { pop } repeat")).unwrap_err();
assert!(err.contains("typecheck"));
}
#[test]
fn postscript_mod_non_integer_operand_is_refused() {
let err = import(&eps("1.5 2 mod")).unwrap_err();
assert!(err.contains("typecheck") && err.contains("mod"));
}
#[test]
fn postscript_loop_non_procedure_operand_is_refused() {
let err = import(&eps("1 loop")).unwrap_err();
assert!(err.contains("typecheck") && err.contains("loop"));
}
#[test]
fn postscript_index_non_integer_count_is_refused() {
let err = import(&eps("1 1.5 index pop")).unwrap_err();
assert!(err.contains("typecheck"));
}
#[test]
fn postscript_ifelse_non_procedure_branch_is_refused() {
let err = import(&eps("true { pop } 1 ifelse")).unwrap_err();
assert!(err.contains("typecheck") && err.contains("ifelse"));
}
#[test]
fn postscript_ifelse_non_boolean_condition_is_refused() {
let err = import(&eps("1 { pop } { pop } ifelse")).unwrap_err();
assert!(err.contains("typecheck") && err.contains("ifelse"));
}
#[test]
fn postscript_if_non_procedure_body_is_refused() {
let err = import(&eps("true 1 if")).unwrap_err();
assert!(err.contains("typecheck") && err.contains("if"));
}
#[test]
fn postscript_if_non_boolean_condition_is_refused() {
let err = import(&eps("1 { pop } if")).unwrap_err();
assert!(err.contains("typecheck") && err.contains("if"));
}
#[test]
fn postscript_idiv_non_integer_operand_is_refused() {
let err = import(&eps("1.5 2 idiv")).unwrap_err();
assert!(err.contains("typecheck") && err.contains("idiv"));
}
#[test]
fn postscript_for_non_procedure_operand_is_refused() {
let err = import(&eps("1 1 10 1 for")).unwrap_err();
assert!(err.contains("typecheck") && err.contains("for"));
}
#[test]
fn postscript_copy_non_integer_operand_count_is_refused() {
let err = import(&eps("1 1.5 copy pop")).unwrap_err();
assert!(err.contains("typecheck") && err.contains("copy"));
}
/// #1714: arrays and dictionaries a program links into themselves or each other are freed with
/// the interpreter, also the ones it no longer reaches and when it stops on an error.
#[test]