def test_module_position(self, *, code: str, expected: CodeRange) -> None: module = parse_module(code) provider = SyntacticPositionProvider() module.code_for_node(module, provider) self.assertEqual(provider._computed[module], expected) # TODO: remove this self.assertEqual(module._metadata[SyntacticPositionProvider], expected)
def test_function_position(self) -> None: module = parse_module("def foo():\n pass") provider = SyntacticPositionProvider() module.code_for_node(module, provider) fn = cast(cst.FunctionDef, module.body[0]) stmt = cast(cst.SimpleStatementLine, fn.body.body[0]) pass_stmt = cast(cst.Pass, stmt.body[0]) self.cmp_position(provider._computed[stmt], (2, 4), (2, 8)) self.cmp_position(provider._computed[pass_stmt], (2, 4), (2, 8))
def test_multiline_string_position(self) -> None: module = parse_module('"abc"\\\n"def"') provider = SyntacticPositionProvider() module.code_for_node(module, provider) stmt = cast(cst.SimpleStatementLine, module.body[0]) expr = cast(cst.Expr, stmt.body[0]) string = expr.value self.cmp_position(provider._computed[stmt], (1, 0), (2, 5)) self.cmp_position(provider._computed[expr], (1, 0), (2, 5)) self.cmp_position(provider._computed[string], (1, 0), (2, 5))
def __assert_codegen( self, node: cst.CSTNode, expected: str, expected_position: Optional[CodeRange] = None, ) -> None: """ Verifies that the given node's `_codegen` method is correct. """ module = cst.Module([]) provider = None if expected_position is None else SyntacticPositionProvider() self.assertEqual(module.code_for_node(node, provider=provider), expected) if provider is not None: self.assertEqual(provider._computed[node], expected_position)
def test_syntactic_position(self) -> None: # create a dummy node node = cst.Pass() # simulate codegen behavior for the dummy node # generates the code " pass " state = SyntacticCodegenState(" " * 4, "\n", SyntacticPositionProvider()) start = CodePosition(state.line, state.column) state.add_token(" ") with state.record_syntactic_position(node): state.add_token("pass") state.add_token(" ") end = CodePosition(state.line, state.column) state.record_position(node, CodeRange(start, end)) # check syntactic position ignores whitespace self.assertEqual(state.provider._computed[node], CodeRange((1, 1), (1, 5)))
def test_nested_indent_position(self) -> None: module = parse_module( "if True:\n if False:\n x = 1\nelse:\n return") provider = SyntacticPositionProvider() module.code_for_node(module, provider) outer_if = cast(cst.If, module.body[0]) inner_if = cast(cst.If, outer_if.body.body[0]) assign = cast(cst.SimpleStatementLine, inner_if.body.body[0]).body[0] outer_else = cast(cst.Else, outer_if.orelse) return_stmt = cast(cst.SimpleStatementLine, outer_else.body.body[0]).body[0] self.cmp_position(provider._computed[outer_if], (1, 0), (5, 10)) self.cmp_position(provider._computed[inner_if], (2, 4), (3, 13)) self.cmp_position(provider._computed[assign], (3, 8), (3, 13)) self.cmp_position(provider._computed[outer_else], (4, 0), (5, 10)) self.cmp_position(provider._computed[return_stmt], (5, 4), (5, 10))