# Tests common to several calculators module CalcTestsCommon def parser @parser ||= @grammar.new_parser end def test_01_grammar assert_kind_of(Rockit::DParser::Grammar, @grammar) end def test_02_creation_of_parser assert_kind_of(Rockit::DParser::Parser, parser) end def test_03_constant ast = parser.parse "1234567890" assert_equal("Constant", ast.name) assert_kind_of(parser.astclass_of_name(:Constant), ast) assert_equal(1, ast.num_children) assert_equal("1234567890", ast[0]) assert_equal("1234567890", ast.num) end Ops = [["+", :Plus], ["-", :Minus], ["*", :Mul], ["/", :Div]] def test_04_operators Ops.each do |op, n| num1, num2 = rand(10).to_s, rand(10).to_s str = num1 + op + num2 ast = parser.parse str assert_equal(n.to_s, ast.name) assert_kind_of(parser.astclass_of_name(n), ast) assert_equal(2, ast.num_children) assert_kind_of(parser.astclass_of_name(:Constant), ast[0]) assert_equal(num1, ast[0].num) assert_kind_of(parser.astclass_of_name(:Constant), ast.left) assert_equal(num1, ast.left.num) assert_kind_of(parser.astclass_of_name(:Constant), ast[1]) assert_equal(num2, ast[1].num) assert_kind_of(parser.astclass_of_name(:Constant), ast.right) assert_equal(num2, ast.right.num) end end def test_05_paren ast = parser.parse "2 * (4 + 67)" assert_kind_of(parser.astclass_of_name(:Mul), ast) assert_equal(2, ast.num_children) assert_kind_of(parser.astclass_of_name(:Constant), ast.left) assert_equal("2", ast.left.num) assert_kind_of(parser.astclass_of_name(:Plus), ast.right) assert_kind_of(parser.astclass_of_name(:Constant), ast.right.left) assert_equal("4", ast.right.left.num) assert_kind_of(parser.astclass_of_name(:Constant), ast.right.right) assert_equal("67", ast.right.right.num) assert_equal('Mul[Constant["2"], Plus[Constant["4"], Constant["67"]]]', ast.inspect) end def assert_calc(expected, str) assert_equal(expected, @calculator.eval(parser.parse(str))) end def test_06_left_associative_operators Ops.each do |op, name| ast = parser.parse "1 #{op} 2 #{op} 3" assert_kind_of(parser.astclass_of_name(name), ast) assert_kind_of(parser.astclass_of_name(name), ast.left) assert_equal("1", ast.left.left.num) assert_equal("2", ast.left.right.num) assert_kind_of(parser.astclass_of_name(:Constant), ast.right) assert_equal("3", ast.right.num) end end def test_07_mul_higher_precedence_than_plus ast = parser.parse "1 + 2 * 3" assert_kind_of(parser.astclass_of_name(:Plus), ast) assert_kind_of(parser.astclass_of_name(:Constant), ast.left) assert_equal("1", ast.left.num) assert_kind_of(parser.astclass_of_name(:Mul), ast.right) assert_equal("2", ast.right.left.num) assert_equal("3", ast.right.right.num) end def test_08_eval assert_calc(2, "2") assert_calc(2 * (4+67), "2 * (4 + 67)") assert_calc(987 * (456+671), "987*(456+671)") assert_calc((9-5) * (100/10), "(9-5) * (100/10)") end end