class NumberTest(CSTNodeTest): @data_provider( ( # Simple number (cst.Integer("5"), "5", parse_expression), # Negted number ( cst.UnaryOperation(operator=cst.Minus(), expression=cst.Integer("5")), "-5", parse_expression, CodeRange((1, 0), (1, 2)), ), # In parenthesis ( cst.UnaryOperation( lpar=(cst.LeftParen(),), operator=cst.Minus(), expression=cst.Integer("5"), rpar=(cst.RightParen(),), ), "(-5)", parse_expression, CodeRange((1, 1), (1, 3)), ), ( cst.UnaryOperation( lpar=(cst.LeftParen(),), operator=cst.Minus(), expression=cst.Integer( "5", lpar=(cst.LeftParen(),), rpar=(cst.RightParen(),) ), rpar=(cst.RightParen(),), ), "(-(5))", parse_expression, CodeRange((1, 1), (1, 5)), ), ( cst.UnaryOperation( operator=cst.Minus(), expression=cst.UnaryOperation( operator=cst.Minus(), expression=cst.Integer("5") ), ), "--5", parse_expression, CodeRange((1, 0), (1, 3)), ), # multiple nested parenthesis ( cst.Integer( "5", lpar=(cst.LeftParen(), cst.LeftParen()), rpar=(cst.RightParen(), cst.RightParen()), ), "((5))", parse_expression, CodeRange((1, 2), (1, 3)), ), ( cst.UnaryOperation( lpar=(cst.LeftParen(),), operator=cst.Plus(), expression=cst.Integer( "5", lpar=(cst.LeftParen(), cst.LeftParen()), rpar=(cst.RightParen(), cst.RightParen()), ), rpar=(cst.RightParen(),), ), "(+((5)))", parse_expression, CodeRange((1, 1), (1, 7)), ), ) ) def test_valid( self, node: cst.CSTNode, code: str, parser: Optional[Callable[[str], cst.CSTNode]], position: Optional[CodeRange] = None, ) -> None: self.validate_node(node, code, parser, expected_position=position) @data_provider( ( ( lambda: cst.Integer("5", lpar=(cst.LeftParen(),)), "left paren without right paren", ), ( lambda: cst.Integer("5", rpar=(cst.RightParen(),)), "right paren without left paren", ), ( lambda: cst.Float("5.5", lpar=(cst.LeftParen(),)), "left paren without right paren", ), ( lambda: cst.Float("5.5", rpar=(cst.RightParen(),)), "right paren without left paren", ), ( lambda: cst.Imaginary("5i", lpar=(cst.LeftParen(),)), "left paren without right paren", ), ( lambda: cst.Imaginary("5i", rpar=(cst.RightParen(),)), "right paren without left paren", ), ) ) def test_invalid( self, get_node: Callable[[], cst.CSTNode], expected_re: str ) -> None: self.assert_invalid(get_node, expected_re)
class UnaryOperationTest(CSTNodeTest): @data_provider( ( # Simple unary operations (cst.UnaryOperation(cst.Plus(), cst.Name("foo")), "+foo"), (cst.UnaryOperation(cst.Minus(), cst.Name("foo")), "-foo"), (cst.UnaryOperation(cst.BitInvert(), cst.Name("foo")), "~foo"), (cst.UnaryOperation(cst.Not(), cst.Name("foo")), "not foo"), # Parenthesized unary operation ( cst.UnaryOperation( lpar=(cst.LeftParen(),), operator=cst.Not(), expression=cst.Name("foo"), rpar=(cst.RightParen(),), ), "(not foo)", CodeRange((1, 1), (1, 8)), ), ( cst.UnaryOperation( operator=cst.Not(whitespace_after=cst.SimpleWhitespace("")), expression=cst.Name( "foo", lpar=(cst.LeftParen(),), rpar=(cst.RightParen(),) ), ), "not(foo)", CodeRange((1, 0), (1, 8)), ), # Make sure that spacing works ( cst.UnaryOperation( lpar=(cst.LeftParen(whitespace_after=cst.SimpleWhitespace(" ")),), operator=cst.Not(whitespace_after=cst.SimpleWhitespace(" ")), expression=cst.Name("foo"), rpar=(cst.RightParen(whitespace_before=cst.SimpleWhitespace(" ")),), ), "( not foo )", CodeRange((1, 2), (1, 10)), ), ) ) def test_valid( self, node: cst.CSTNode, code: str, position: Optional[CodeRange] = None ) -> None: self.validate_node(node, code, parse_expression, expected_position=position) @data_provider( ( ( lambda: cst.UnaryOperation( cst.Plus(), cst.Name("foo"), lpar=(cst.LeftParen(),) ), "left paren without right paren", ), ( lambda: cst.UnaryOperation( cst.Plus(), cst.Name("foo"), rpar=(cst.RightParen(),) ), "right paren without left paren", ), ( lambda: cst.UnaryOperation( operator=cst.Not(whitespace_after=cst.SimpleWhitespace("")), expression=cst.Name("foo"), ), "at least one space after not operator", ), ) ) def test_invalid( self, get_node: Callable[[], cst.CSTNode], expected_re: str ) -> None: self.assert_invalid(get_node, expected_re)