def testEmpty(self): """Tests for empty expression """ parser = ParserYacc() # empty expression is allowed, returns None tree = parser.parse("") self.assertIsNone(tree)
def testParseParens(self): """Tests for identifiers """ parser = ParserYacc() tree = parser.parse('(a)') self.assertIsInstance(tree, exprTree.Parens) self.assertIsInstance(tree.expr, exprTree.Identifier) self.assertEqual(tree.expr.name, 'a')
def testParseIdentifiers(self): """Tests for identifiers """ parser = ParserYacc() tree = parser.parse('a') self.assertIsInstance(tree, exprTree.Identifier) self.assertEqual(tree.name, 'a') tree = parser.parse('a.b') self.assertIsInstance(tree, exprTree.Identifier) self.assertEqual(tree.name, 'a.b')
def testCompareOps(self): """Tests for comparison operators """ parser = ParserYacc() for op in ('=', '!=', '<', '<=', '>', '>='): tree = parser.parse('a {} 10'.format(op)) self.assertIsInstance(tree, exprTree.BinaryOp) self.assertEqual(tree.op, op) self.assertIsInstance(tree.lhs, exprTree.Identifier) self.assertIsInstance(tree.rhs, exprTree.NumericLiteral) self.assertEqual(tree.lhs.name, 'a') self.assertEqual(tree.rhs.value, '10')
def testUnaryOps(self): """Tests for unary plus and minus """ parser = ParserYacc() tree = parser.parse('+a') self.assertIsInstance(tree, exprTree.UnaryOp) self.assertEqual(tree.op, '+') self.assertIsInstance(tree.operand, exprTree.Identifier) self.assertEqual(tree.operand.name, 'a') tree = parser.parse('- x.y') self.assertIsInstance(tree, exprTree.UnaryOp) self.assertEqual(tree.op, '-') self.assertIsInstance(tree.operand, exprTree.Identifier) self.assertEqual(tree.operand.name, 'x.y')
def testParseLiteral(self): """Tests for literals (strings/numbers) """ parser = ParserYacc() tree = parser.parse('1') self.assertIsInstance(tree, exprTree.NumericLiteral) self.assertEqual(tree.value, '1') tree = parser.parse('.5e-2') self.assertIsInstance(tree, exprTree.NumericLiteral) self.assertEqual(tree.value, '.5e-2') tree = parser.parse("'string'") self.assertIsInstance(tree, exprTree.StringLiteral) self.assertEqual(tree.value, 'string') tree = parser.parse("10..20") self.assertIsInstance(tree, exprTree.RangeLiteral) self.assertEqual(tree.start, 10) self.assertEqual(tree.stop, 20) self.assertEqual(tree.stride, None) tree = parser.parse("-10 .. 10:5") self.assertIsInstance(tree, exprTree.RangeLiteral) self.assertEqual(tree.start, -10) self.assertEqual(tree.stop, 10) self.assertEqual(tree.stride, 5)
def testIsIn(self): """Tests for IN """ parser = ParserYacc() tree = parser.parse("a in (1,2,'X')") self.assertIsInstance(tree, exprTree.IsIn) self.assertFalse(tree.not_in) self.assertIsInstance(tree.lhs, exprTree.Identifier) self.assertEqual(tree.lhs.name, 'a') self.assertIsInstance(tree.values, list) self.assertEqual(len(tree.values), 3) self.assertIsInstance(tree.values[0], exprTree.NumericLiteral) self.assertEqual(tree.values[0].value, '1') self.assertIsInstance(tree.values[1], exprTree.NumericLiteral) self.assertEqual(tree.values[1].value, '2') self.assertIsInstance(tree.values[2], exprTree.StringLiteral) self.assertEqual(tree.values[2].value, 'X') tree = parser.parse("10 not in (1000, 2000..3000:100)") self.assertIsInstance(tree, exprTree.IsIn) self.assertTrue(tree.not_in) self.assertIsInstance(tree.lhs, exprTree.NumericLiteral) self.assertEqual(tree.lhs.value, '10') self.assertIsInstance(tree.values, list) self.assertEqual(len(tree.values), 2) self.assertIsInstance(tree.values[0], exprTree.NumericLiteral) self.assertEqual(tree.values[0].value, '1000') self.assertIsInstance(tree.values[1], exprTree.RangeLiteral) self.assertEqual(tree.values[1].start, 2000) self.assertEqual(tree.values[1].stop, 3000) self.assertEqual(tree.values[1].stride, 100) tree = parser.parse("10 in (-1000, -2000)") self.assertIsInstance(tree, exprTree.IsIn) self.assertFalse(tree.not_in) self.assertIsInstance(tree.lhs, exprTree.NumericLiteral) self.assertEqual(tree.lhs.value, '10') self.assertIsInstance(tree.values, list) self.assertEqual(len(tree.values), 2) self.assertIsInstance(tree.values[0], exprTree.NumericLiteral) self.assertEqual(tree.values[0].value, '-1000') self.assertIsInstance(tree.values[1], exprTree.NumericLiteral) self.assertEqual(tree.values[1].value, '-2000')
def testBoolOps(self): """Tests for boolean operators """ parser = ParserYacc() for op in ('OR', 'AND'): tree = parser.parse('a {} b'.format(op)) self.assertIsInstance(tree, exprTree.BinaryOp) self.assertEqual(tree.op, op) self.assertIsInstance(tree.lhs, exprTree.Identifier) self.assertIsInstance(tree.rhs, exprTree.Identifier) self.assertEqual(tree.lhs.name, 'a') self.assertEqual(tree.rhs.name, 'b') tree = parser.parse('NOT b') self.assertIsInstance(tree, exprTree.UnaryOp) self.assertEqual(tree.op, 'NOT') self.assertIsInstance(tree.operand, exprTree.Identifier) self.assertEqual(tree.operand.name, 'b')
def testExpression(self): """Test for more or less complete expression""" parser = ParserYacc() expression = ("((instrument='HSC' AND detector != 9) OR instrument='CFHT') " "AND tract=8766 AND patch.cell_x > 5 AND " "patch.cell_y < 4 AND abstract_filter='i'") tree = parser.parse(expression) self.assertIsInstance(tree, exprTree.BinaryOp) self.assertEqual(tree.op, 'AND') self.assertIsInstance(tree.lhs, exprTree.BinaryOp) # AND is left-associative, so rhs operand will be the # last sub-expressions self.assertIsInstance(tree.rhs, exprTree.BinaryOp) self.assertEqual(tree.rhs.op, '=') self.assertIsInstance(tree.rhs.lhs, exprTree.Identifier) self.assertEqual(tree.rhs.lhs.name, 'abstract_filter') self.assertIsInstance(tree.rhs.rhs, exprTree.StringLiteral) self.assertEqual(tree.rhs.rhs.value, 'i')
def testStr(self): """Test for formatting""" parser = ParserYacc() tree = parser.parse("(a+b)") self.assertEqual(str(tree), '(a + b)') tree = parser.parse("1 in (1,'x',3)") self.assertEqual(str(tree), "1 IN (1, 'x', 3)") tree = parser.parse("a not in (1,'x',3)") self.assertEqual(str(tree), "a NOT IN (1, 'x', 3)") tree = parser.parse("(A or B) And NoT (x+3 > y)") self.assertEqual(str(tree), "(A OR B) AND NOT (x + 3 > y)") tree = parser.parse("A in (100, 200..300:50)") self.assertEqual(str(tree), "A IN (100, 200..300:50)")
def testBinaryOps(self): """Tests for binary operators """ parser = ParserYacc() tree = parser.parse('a + b') self.assertIsInstance(tree, exprTree.BinaryOp) self.assertEqual(tree.op, '+') self.assertIsInstance(tree.lhs, exprTree.Identifier) self.assertIsInstance(tree.rhs, exprTree.Identifier) self.assertEqual(tree.lhs.name, 'a') self.assertEqual(tree.rhs.name, 'b') tree = parser.parse('a - 2') self.assertIsInstance(tree, exprTree.BinaryOp) self.assertEqual(tree.op, '-') self.assertIsInstance(tree.lhs, exprTree.Identifier) self.assertIsInstance(tree.rhs, exprTree.NumericLiteral) self.assertEqual(tree.lhs.name, 'a') self.assertEqual(tree.rhs.value, '2') tree = parser.parse('2 * 2') self.assertIsInstance(tree, exprTree.BinaryOp) self.assertEqual(tree.op, '*') self.assertIsInstance(tree.lhs, exprTree.NumericLiteral) self.assertIsInstance(tree.rhs, exprTree.NumericLiteral) self.assertEqual(tree.lhs.value, '2') self.assertEqual(tree.rhs.value, '2') tree = parser.parse('1.e5/2') self.assertIsInstance(tree, exprTree.BinaryOp) self.assertEqual(tree.op, '/') self.assertIsInstance(tree.lhs, exprTree.NumericLiteral) self.assertIsInstance(tree.rhs, exprTree.NumericLiteral) self.assertEqual(tree.lhs.value, '1.e5') self.assertEqual(tree.rhs.value, '2') tree = parser.parse('333%76') self.assertIsInstance(tree, exprTree.BinaryOp) self.assertEqual(tree.op, '%') self.assertIsInstance(tree.lhs, exprTree.NumericLiteral) self.assertIsInstance(tree.rhs, exprTree.NumericLiteral) self.assertEqual(tree.lhs.value, '333') self.assertEqual(tree.rhs.value, '76')
def testException(self): """Test for exceptional cases""" def _assertExc(exc, expr, token, pos, lineno, posInLine): """Check exception attribute values""" self.assertEqual(exc.expression, expr) self.assertEqual(exc.token, token) self.assertEqual(exc.pos, pos) self.assertEqual(exc.lineno, lineno) self.assertEqual(exc.posInLine, posInLine) parser = ParserYacc() expression = "(1, 2, 3)" with self.assertRaises(ParseError) as catcher: parser.parse(expression) _assertExc(catcher.exception, expression, ",", 2, 1, 2) expression = "\n(1\n,\n 2, 3)" with self.assertRaises(ParseError) as catcher: parser.parse(expression) _assertExc(catcher.exception, expression, ",", 4, 3, 0)
def testVisit(self): """Test for visitor methods""" # test should cover all visit* methods parser = ParserYacc() visitor = _Visitor() tree = parser.parse("(a+b)") result = tree.visit(visitor) self.assertEqual(result, "P(B(ID(a) + ID(b)))") tree = parser.parse("(A or B) and not (x + 3 > y)") result = tree.visit(visitor) self.assertEqual(result, "B(P(B(ID(A) OR ID(B))) AND U(NOT P(B(B(ID(x) + N(3)) > ID(y)))))") tree = parser.parse("x in (1,2) AND y NOT IN (1.1, .25, 1e2) OR z in ('a', 'b')") result = tree.visit(visitor) self.assertEqual(result, "B(B(IN(ID(x) (N(1), N(2))) AND !IN(ID(y) (N(1.1), N(.25), N(1e2))))" " OR IN(ID(z) (S(a), S(b))))") tree = parser.parse("x in (1,2,5..15) AND y NOT IN (-100..100:10)") result = tree.visit(visitor) self.assertEqual(result, "B(IN(ID(x) (N(1), N(2), R(5..15))) AND !IN(ID(y) (R(-100..100:10))))")
def testInstantiate(self): """Tests for making ParserLex instances """ parser = ParserYacc() # noqa: F841