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(); } // TODO /*#[test] fn if_single_line() { common::test_program("if 3 = 3 then print \"hi\"\n", "hi\n") }*/ #[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", ); }