use super::harness::*;

#[test]
fn single_clause_match() {
    expect_int("1 case 1 of 42 endof endcase", 42);
}

#[test]
fn single_clause_no_match() {
    let f = run("1 case 2 of 42 endof endcase");
    assert!(f.stack().is_empty());
}

#[test]
fn multi_clause_first() {
    expect_int("0 case 0 of 10 endof 1 of 20 endof 2 of 30 endof endcase", 10);
}

#[test]
fn multi_clause_middle() {
    expect_int("1 case 0 of 10 endof 1 of 20 endof 2 of 30 endof endcase", 20);
}

#[test]
fn multi_clause_last() {
    expect_int("2 case 0 of 10 endof 1 of 20 endof 2 of 30 endof endcase", 30);
}

#[test]
fn no_match_stack_clean() {
    let f = run("99 case 0 of 10 endof 1 of 20 endof endcase");
    assert!(f.stack().is_empty());
}

#[test]
fn expression_test_value() {
    expect_int("3 case 1 2 + of 42 endof endcase", 42);
}

#[test]
fn expression_case_value() {
    expect_int("1 2 + case 3 of 42 endof endcase", 42);
}

#[test]
fn body_with_computation() {
    expect_int("1 case 1 of 10 20 + endof endcase", 30);
}

#[test]
fn default_clause() {
    // Default drops case value and pushes replacement twice (endcase drops one)
    expect_int("99 case 0 of 10 endof 1 of 20 endof drop 42 42 endcase", 42);
}

#[test]
fn default_clause_uses_case_value() {
    // dup preserves case value through endcase's drop
    expect_int("99 case 0 of 10 endof dup endcase", 99);
}

#[test]
fn default_clause_not_reached_on_match() {
    expect_int("0 case 0 of 10 endof 999 endcase", 10);
}

#[test]
fn nested_case_in_case() {
    // outer matches 1, inner matches 2
    expect_int("1 case 1 of 2 case 2 of 42 endof endcase endof endcase", 42);
}

#[test]
fn if_inside_case_body() {
    expect_int("1 case 1 of 1 if 42 else 99 then endof endcase", 42);
}

#[test]
fn case_inside_if_body() {
    expect_int("1 if 2 case 2 of 42 endof endcase then", 42);
}

#[test]
fn preserves_stack_below() {
    let f = run("100 1 case 1 of 42 endof endcase");
    let stack = f.stack();
    assert_eq!(stack.len(), 2);
}

#[test]
fn missing_endcase() {
    expect_error("1 case 0 of 10 endof", "missing 'endcase'");
}

#[test]
fn stray_of() {
    expect_error("1 of", "unexpected 'of'");
}

#[test]
fn stray_endof() {
    expect_error("1 endof", "unexpected 'endof'");
}

#[test]
fn stray_endcase() {
    expect_error("1 endcase", "unexpected 'endcase'");
}
