Esempio n. 1
0
def handle_assert_regex(node, capture, arguments):
    """
    self.assertRegex(text, pattern, msg)
    --> assert re.search(pattern, text), msg

    self.assertNotRegex(text, pattern, msg)
    --> assert not re.search(pattern, text), msg

    """
    function_name = capture["function_name"].value
    invert = function_name in INVERT_FUNCTIONS
    function_name = SYNONYMS.get(function_name, function_name)
    num_arguments = ARGUMENTS[function_name]

    if len(arguments) not in (num_arguments, num_arguments + 1):
        # Not sure what this is. Leave it alone.
        return None

    if len(arguments) == num_arguments:
        message = None
    else:
        message = arguments.pop()
        if message.type == syms.argument:
            # keyword argument (e.g. `msg=abc`)
            message = message.children[2].clone()

    arguments[0].prefix = " "
    arguments[1].prefix = ""

    # Adds a 'import re' if there wasn't one already
    touch_import(None, "re", node)

    op_tokens = []
    if invert:
        op_tokens.append(keyword("not"))

    assert_test_nodes = [
        Node(
            syms.power,
            op_tokens + Attr(keyword("re"), keyword("search", prefix="")) +
            [ArgList([arguments[1], Comma(), arguments[0]])],
        )
    ]
    return Assert(assert_test_nodes,
                  message.clone() if message else None,
                  prefix=node.prefix)
Esempio n. 2
0
def handle_assertraises(node, capture, arguments):
    """
    with self.assertRaises(x):

        --> with pytest.raises(x):

    self.assertRaises(ValueError, func, arg1)

        --> pytest.raises(ValueError, func, arg1)
    """
    capture["self_attr"].replace(
        keyword("pytest", prefix=capture["self_attr"].prefix))
    capture["raises_attr"].replace(
        Node(syms.trailer, [Dot(), keyword("raises", prefix="")]))
    # Let's remove the msg= keyword argument if found
    for child in node.children:
        if child.type != syms.trailer:
            continue
        for tchild in child.children:
            if tchild.type != syms.arglist:
                continue
            previous_argument = None
            for argument in tchild.children:
                if isinstance(argument, Leaf):
                    previous_argument = argument
                    continue
                if isinstance(argument, Node):
                    if argument.type != syms.argument:
                        previous_argument = argument
                        continue
                    for leaf in argument.leaves():
                        if leaf.value == "msg":
                            argument.remove()
                            if previous_argument.value == ",":
                                # previous_argument is a comma, remove it.
                                previous_argument.remove()

    # Adds a 'import pytest' if there wasn't one already
    touch_import(None, "pytest", node)
Esempio n. 3
0
def assertmethod_to_assert(node, capture, arguments):
    """
    self.assertEqual(foo, bar, msg)
    --> assert foo == bar, msg

    self.assertTrue(foo, msg)
    --> assert foo, msg

    self.assertIsNotNone(foo, msg)
    --> assert foo is not None, msg

    .. etc
    """
    function_name = capture["function_name"].value
    invert = function_name in INVERT_FUNCTIONS
    function_name = SYNONYMS.get(function_name, function_name)
    num_arguments = ARGUMENTS[function_name]

    if len(arguments) not in (num_arguments, num_arguments + 1):
        # Not sure what this is. Leave it alone.
        return None

    if len(arguments) == num_arguments:
        message = None
    else:
        message = arguments.pop()
        if message.type == syms.argument:
            # keyword argument (e.g. `msg=abc`)
            message = message.children[2].clone()

    if function_name == "assertIsInstance":
        arguments[0].prefix = ""
        assert_test_nodes = [
            Call(keyword("isinstance"),
                 [arguments[0], Comma(), arguments[1]])
        ]
        if invert:
            assert_test_nodes.insert(0, keyword("not"))
    elif function_name == "assertAlmostEqual":
        arguments[1].prefix = ""
        # TODO: insert the `import pytest` at the top of the file
        if invert:
            op_token = Leaf(TOKEN.NOTEQUAL, "!=", prefix=" ")
        else:
            op_token = Leaf(TOKEN.EQEQUAL, "==", prefix=" ")
        assert_test_nodes = [
            Node(
                syms.comparison,
                [
                    arguments[0],
                    op_token,
                    Node(
                        syms.power,
                        Attr(keyword("pytest"), keyword("approx", prefix="")) +
                        [
                            ArgList([
                                arguments[1],
                                Comma(),
                                KeywordArg(keyword("abs"),
                                           Leaf(TOKEN.NUMBER, "1e-7")),
                            ])
                        ],
                    ),
                ],
            )
        ]
        # Adds a 'import pytest' if there wasn't one already
        touch_import(None, "pytest", node)

    else:
        op_tokens = OPERATORS[function_name]
        if not isinstance(op_tokens, list):
            op_tokens = [op_tokens]
        op_tokens = [o.clone() for o in op_tokens]

        if invert:
            if not op_tokens:
                op_tokens.append(keyword("not"))
            elif op_tokens[0].type == TOKEN.NAME and op_tokens[0].value == "is":
                op_tokens[0] = Node(
                    syms.comp_op,
                    [keyword("is"), keyword("not")], prefix=" ")
            elif op_tokens[0].type == TOKEN.NAME and op_tokens[0].value == "in":
                op_tokens[0] = Node(
                    syms.comp_op,
                    [keyword("not"), keyword("in")], prefix=" ")
            elif op_tokens[0].type == TOKEN.EQEQUAL:
                op_tokens[0] = Leaf(TOKEN.NOTEQUAL, "!=", prefix=" ")

        if num_arguments == 2:
            # a != b, etc.
            assert_test_nodes = [arguments[0]] + op_tokens + [arguments[1]]
        elif function_name == "assertTrue":
            assert_test_nodes = op_tokens + [arguments[0]]
            # not a
        elif function_name == "assertIsNone":
            # a is not None
            assert_test_nodes = [arguments[0]] + op_tokens
    return Assert(assert_test_nodes,
                  message.clone() if message else None,
                  prefix=node.prefix)
Esempio n. 4
0
def assertalmostequal_to_assert(node, capture, arguments):
    function_name = capture["function_name"].value
    invert = function_name in INVERT_FUNCTIONS
    function_name = SYNONYMS.get(function_name, function_name)

    nargs = len(arguments)
    if nargs < 2 or nargs > 5:
        return None

    def get_kwarg_value(index, name):
        idx = 0
        for arg in arguments:
            if arg.type == syms.argument:
                if arg.children[0].value == name:
                    return arg.children[2].clone()
            else:
                if idx == index:
                    return arg.clone()
                idx += 1
        return None

    first = get_kwarg_value(0, "first")
    second = get_kwarg_value(1, "second")

    if first is None or second is None:
        # Not sure what this is, leave it alone
        return

    places = get_kwarg_value(2, "places")
    msg = get_kwarg_value(3, "msg")
    delta = get_kwarg_value(4, "delta")

    if delta is not None:
        try:
            abs_delta = float(delta.value)
        except ValueError:
            # this should be a number, give up.
            return
    else:
        if places is None:
            places = 7
        else:
            try:
                places = int(places.value)
            except (ValueError, AttributeError):
                # this should be an int, give up.
                return
        abs_delta = "1e-%d" % places

    arguments[1].prefix = ""
    if invert:
        op_token = Leaf(TOKEN.NOTEQUAL, "!=", prefix=" ")
    else:
        op_token = Leaf(TOKEN.EQEQUAL, "==", prefix=" ")
    assert_test_nodes = [
        Node(
            syms.comparison,
            [
                arguments[0],
                op_token,
                Node(
                    syms.power,
                    Attr(keyword("pytest"), keyword("approx", prefix="")) + [
                        ArgList([
                            arguments[1],
                            Comma(),
                            KeywordArg(keyword("abs"),
                                       Leaf(TOKEN.NUMBER, abs_delta)),
                        ])
                    ],
                ),
            ],
        )
    ]
    # Adds a 'import pytest' if there wasn't one already
    touch_import(None, "pytest", node)

    return Assert(assert_test_nodes,
                  msg.clone() if msg else None,
                  prefix=node.prefix)
Esempio n. 5
0
def handle_assertraises_regex(node, capture, arguments):
    """
    with self.assertRaisesRegex(x, "regex match"):

        --> with pytest.raises(x, match="regex match"):

    self.assertRaises(ValueError, "regex match", func, arg1)

        --> pytest.raises(ValueError, func, arg1, match="regex match")
    """
    capture["self_attr"].replace(
        keyword("pytest", prefix=capture["self_attr"].prefix))
    capture["raises_attr"].replace(
        Node(syms.trailer, [Dot(), keyword("raises", prefix="")]))
    # Let's remove the msg= keyword argument if found and replace the second argument
    # with a match keyword argument
    regex_match = None
    for child in node.children:
        if child.type != syms.trailer:
            continue
        for tchild in child.children:
            if tchild.type != syms.arglist:
                continue
            previous_argument = None
            argnum = 0
            for argument in list(tchild.children):
                if isinstance(argument, Leaf):
                    if argument.value != ",":
                        argnum += 1
                    else:
                        previous_argument = argument
                        continue

                    if argnum != 2:
                        previous_argument = argument
                        continue

                    if argnum == 2:
                        regex_match = Node(
                            syms.argument,
                            [
                                Leaf(TOKEN.NAME, "match"),
                                Leaf(TOKEN.EQUAL, "="),
                                Leaf(TOKEN.STRING, argument.value),
                            ],
                            prefix=" ",
                        )
                        argument.remove()
                        if previous_argument and previous_argument.value == ",":
                            previous_argument.remove()
                        previous_argument = None
                        continue
                if isinstance(argument, Node):
                    if argument.type != syms.argument:
                        previous_argument = argument
                        continue
                    for leaf in argument.leaves():
                        if leaf.value == "msg":
                            argument.remove()
                            if previous_argument and previous_argument.value == ",":
                                # previous_argument is a comma, remove it.
                                previous_argument.remove()

    if regex_match:
        regex_match_added = False
        for child in node.children:
            if regex_match_added:
                break
            if child.type != syms.trailer:
                continue
            for tchild in child.children:
                if tchild.type != syms.arglist:
                    continue
                tchild.children.append(Leaf(TOKEN.COMMA, ","))
                tchild.children.append(regex_match)
                regex_match_added = True
                break

    # Adds a 'import pytest' if there wasn't one already
    touch_import(None, "pytest", node)