use xbasic::xbasic::XBasic;
mod common;
#[test]
fn if_test_true() {
common::test_program(
"if 3 = 3 then\nprint \"1\"\nend if\nprint \"done\"\n",
"1\ndone\n",
);
}
#[test]
fn if_test_false() {
common::test_program(
"if 3 = 4 then\nprint \"1\"\nend if\nprint \"done\"\n",
"done\n",
);
}
#[test]
fn if_no_terminator() {
let tio = common::TestIO::new("");
let mut xb = XBasic::new(tio);
assert!(xb.run("if 3 = 4 then\n").is_err());
assert!(xb.error_handler.had_errors);
assert_eq!(
xb.error_handler.errors,
["[line 2] Error at end: Expected END IF after IF statement."]
);
xb.get_io().check();
}
#[test]
fn if_else_true() {
common::test_program(
"if 3 = 3 then\nprint \"1\"\nelse\nprint \"2\"\nend if\nprint \"done\"\n",
"1\ndone\n",
);
}
#[test]
fn if_else_false() {
common::test_program(
"if 3 = 4 then\nprint \"1\"\nelse\nprint \"2\"\nend if\nprint \"done\"\n",
"2\ndone\n",
);
}
#[test]
fn if_elseif() {
common::test_program(
"if 3 = 4 then
print \"1\"
elseif 5 = 3 then
print \"2\"
end if
print \"done\"
",
"done\n",
);
common::test_program(
"if 3 = 3 then
print \"1\"
elseif 5 = 5 then
print \"2\"
end if
print \"done\"
",
"1\ndone\n",
);
common::test_program(
"if 3 = 4 then
print \"1\"
elseif 5 = 5 then
print \"2\"
end if
print \"done\"
",
"2\ndone\n",
);
}
#[test]
fn if_elseif_else() {
common::test_program(
"if 3 = 4 then
print \"1\"
elseif 5 = 3 then
print \"2\"
else
print 3
end if
print \"done\"
",
"3\ndone\n",
);
common::test_program(
"if 3 = 3 then
print \"1\"
elseif 5 = 5 then
print \"2\"
else
print 3
end if
print \"done\"
",
"1\ndone\n",
);
common::test_program(
"if 3 = 4 then
print \"1\"
elseif 5 = 5 then
print \"2\"
else
print 3
end if
print \"done\"
",
"2\ndone\n",
);
}
#[test]
fn if_elseif_missing_then() {
let tio = common::TestIO::new("");
let mut xb = XBasic::new(tio);
assert!(xb
.run(
"if 5 = 3 then
print \"hi\"
elseif 3 = 5
print \"bye\"\
end if
"
)
.is_err());
assert!(xb.error_handler.had_errors);
assert_eq!(
xb.error_handler.errors,
["[line 3] Error at newline: Expected THEN after ELSEIF statement condition."]
);
xb.get_io().check();
}
#[test]
fn if_missing_endif() {
let tio = common::TestIO::new("");
let mut xb = XBasic::new(tio);
assert!(xb
.run(
"if 5 = 3 then
print \"hi\"
"
)
.is_err());
assert!(xb.error_handler.had_errors);
assert_eq!(
xb.error_handler.errors,
["[line 3] Error at end: Expected END IF after IF statement."]
);
xb.get_io().check();
}
#[test]
fn nested_if_missing_endif() {
let tio = common::TestIO::new("");
let mut xb = XBasic::new(tio);
assert!(xb
.run(
"
if 6 = 5 then
if 5 = 3 then
print \"hi\"
end if
a = 5
"
)
.is_err());
assert!(xb.error_handler.had_errors);
assert_eq!(
xb.error_handler.errors,
["[line 7] Error at end: Expected END IF after IF statement."]
);
xb.get_io().check();
}
#[test]
fn nested_if_in_for_missing_endif() {
let tio = common::TestIO::new("");
let mut xb = XBasic::new(tio);
assert!(xb
.run(
"
for x = 0 to 5
for y = 0 to 5
if 6 = 5 then
if 5 = 3 then
print \"hi\"
end if
a = 5
next y
next x
"
)
.is_err());
assert!(xb.error_handler.had_errors);
assert_eq!(
xb.error_handler.errors,
["[line 9] Error at 'y': Expected expression."]
);
xb.get_io().check();
}
#[test]
fn if_assignment_edgecase_1() {
common::test_program(
"
if 4 = 0 then
b = 0
end if
a = 4
",
"",
);
}
#[test]
fn if_assignment_edgecase_2() {
common::test_program(
"
a = 0
if 4 = 0 then
a = 1
end if
a = 4
",
"",
);
}
#[test]
fn if_assignment_edgecase_3() {
common::test_program(
"
if 4 = 0 then
a = 0
end if
a = 4
",
"",
);
}
#[test]
fn while_loop() {
common::test_program(
"while a < 10
print a
a = a + 1
wend
",
"0\n1\n2\n3\n4\n5\n6\n7\n8\n9\n",
);
}
#[test]
fn for_loop() {
common::test_program(
"for x = 0 to 10
print x
next x
",
"0\n1\n2\n3\n4\n5\n6\n7\n8\n9\n10\n",
)
}
#[test]
fn for_loop_backwards() {
common::test_program(
"for x = 10 to 0
print x
next x
",
"",
)
}
#[test]
fn for_loop_same_number() {
common::test_program(
"for x = 10 to 10
print x
next x
",
"10\n",
)
}
#[test]
fn for_loop_invalid_next() {
let tio = common::TestIO::new("");
let mut xb = XBasic::new(tio);
assert!(xb
.run(
"for x = 0 to 10
print x
next y
"
)
.is_err());
assert!(xb.error_handler.had_errors);
assert_eq!(
xb.error_handler.errors,
["[line 3] Error at 'y': Incorrect variable after NEXT."]
);
xb.get_io().check();
}
#[test]
fn for_loop_edge_case() {
common::test_program(
"x = 15
for x = 0 to x
print x
next x
print \"x is\" x
",
"0\n1\n2\n3\n4\n5\n6\n7\n8\n9\n10\n11\n12\n13\n14\n15\nx is 16\n",
)
}
#[test]
fn nested_for_loop() {
common::test_program(
"
a = 0
for x = 1 to 192
for y = 1 to 108
a += 1
next y
next x
print a
",
"20736\n",
);
}