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 mut tio = common::TestIO::new("");
{
let mut xb = XBasic::new(&mut 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."]
);
}
tio.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 mut tio = common::TestIO::new("");
{
let mut xb = XBasic::new(&mut 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."]
);
}
tio.check();
}
#[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 mut tio = common::TestIO::new("");
{
let mut xb = XBasic::new(&mut 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."]
);
}
tio.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",
)
}