(content: str, file: str)
| 77 | |
| 78 | |
| 79 | def main(content: str, file: str) -> int: |
| 80 | lines = content.splitlines() |
| 81 | tree = ast.parse(content) |
| 82 | names = list(_find_names(tree)) |
| 83 | ret = 0 |
| 84 | for node in tree.body: |
| 85 | if is_misnamed_test_func(node, names, lines[node.lineno - 1]): |
| 86 | print( |
| 87 | f"{file}:{node.lineno}:{node.col_offset} " |
| 88 | "found test function which does not start with 'test'" |
| 89 | ) |
| 90 | ret = 1 |
| 91 | elif is_misnamed_test_class(node, names, lines[node.lineno - 1]): |
| 92 | print( |
| 93 | f"{file}:{node.lineno}:{node.col_offset} " |
| 94 | "found test class which does not start with 'Test'" |
| 95 | ) |
| 96 | ret = 1 |
| 97 | if ( |
| 98 | isinstance(node, ast.ClassDef) |
| 99 | and names.count(node.name) == 0 |
| 100 | and not any( |
| 101 | _is_register_dtype(decorator) for decorator in node.decorator_list |
| 102 | ) |
| 103 | and PRAGMA not in lines[node.lineno - 1] |
| 104 | ): |
| 105 | for _node in node.body: |
| 106 | if is_misnamed_test_func(_node, names, lines[_node.lineno - 1]): |
| 107 | # It could be that this function is used somewhere by the |
| 108 | # parent class. For example, there might be a base class |
| 109 | # with |
| 110 | # |
| 111 | # class Foo: |
| 112 | # def foo(self): |
| 113 | # assert 1+1==2 |
| 114 | # def test_foo(self): |
| 115 | # self.foo() |
| 116 | # |
| 117 | # and then some subclass overwrites `foo`. So, we check that |
| 118 | # `self.foo` doesn't appear in any of the test classes. |
| 119 | # Note some false negatives might get through, but that's OK. |
| 120 | # This is good enough that has helped identify several examples |
| 121 | # of tests not being run. |
| 122 | assert isinstance(_node, ast.FunctionDef) # help mypy |
| 123 | should_continue = False |
| 124 | for _file in (Path("pandas") / "tests").rglob("*.py"): |
| 125 | with open(os.path.join(_file), encoding="utf-8") as fd: |
| 126 | _content = fd.read() |
| 127 | if f"self.{_node.name}" in _content: |
| 128 | should_continue = True |
| 129 | break |
| 130 | if should_continue: |
| 131 | continue |
| 132 | |
| 133 | print( |
| 134 | f"{file}:{_node.lineno}:{_node.col_offset} " |
| 135 | "found test function which does not start with 'test'" |
| 136 | ) |
no test coverage detected