Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add test for functional tests directories structure #5753

Merged
merged 2 commits into from
Feb 10, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
68 changes: 60 additions & 8 deletions pylint/testutils/functional/find_functional_tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,29 +3,81 @@

import os
from pathlib import Path
from typing import List, Union
from typing import List, Set, Union

from pylint.testutils.functional.test_file import FunctionalTestFile

# 'Wet finger' number of files that are reasonable to display by an IDE
# 'Wet finger' as in 'in my settings there are precisely this many'.
REASONABLY_DISPLAYABLE_VERTICALLY = 48
"""'Wet finger' number of files that are reasonable to display by an IDE."""
SHOULD_BE_IN_THE_SAME_DIRECTORY = 5
"""'Wet finger' as in 'in my settings there are precisely this many'."""

IGNORED_PARENT_DIRS = {
"deprecated_relative_import",
"ext",
"regression",
"regression_02",
}
"""Direct parent directories that should be ignored."""

IGNORED_PARENT_PARENT_DIRS = {
"docparams",
"deprecated_relative_import",
"ext",
}
"""Parents of direct parent directories that should be ignored."""


def get_functional_test_files_from_directory(
input_dir: Union[Path, str]
) -> List[FunctionalTestFile]:
"""Get all functional tests in the input_dir."""
suite = []

_check_functional_tests_structure(Path(input_dir))

for dirpath, _, filenames in os.walk(input_dir):
if dirpath.endswith("__pycache__"):
continue

assert (
len(filenames) <= REASONABLY_DISPLAYABLE_VERTICALLY
), f"{dirpath} contains too many functional tests files."

for filename in filenames:
if filename != "__init__.py" and filename.endswith(".py"):
suite.append(FunctionalTestFile(dirpath, filename))
return suite


def _check_functional_tests_structure(directory: Path) -> None:
"""Check if test directories follow correct file/folder structure."""
# Ignore underscored directories
if Path(directory).stem.startswith("_"):
return

files: Set[Path] = set()
dirs: Set[Path] = set()

# Collect all subdirectories and files in directory
for file_or_dir in directory.iterdir():
if file_or_dir.is_file():
if file_or_dir.suffix == ".py" and not file_or_dir.stem.startswith("_"):
files.add(file_or_dir)
elif file_or_dir.is_dir():
dirs.add(file_or_dir)
_check_functional_tests_structure(file_or_dir)

assert len(files) <= REASONABLY_DISPLAYABLE_VERTICALLY, (
f"{directory} contains too many functional tests files "
+ f"({len(files)} > {REASONABLY_DISPLAYABLE_VERTICALLY})."
)

for file in files:
possible_dir = file.parent / file.stem.split("_")[0]
assert not possible_dir.exists(), f"{file} should go in {possible_dir}."

# Exclude some directories as they follow a different structure
if (
not len(file.parent.stem) == 1 # First letter subdirectories
and file.parent.stem not in IGNORED_PARENT_DIRS
and file.parent.parent.stem not in IGNORED_PARENT_PARENT_DIRS
):
assert file.stem.startswith(
file.parent.stem
), f"{file} should not go in {file.parent}"
2 changes: 1 addition & 1 deletion tests/functional/i/import_error.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
pass


from functional.s.syntax_error import toto # [no-name-in-module,syntax-error]
from functional.s.syntax.syntax_error import toto # [no-name-in-module,syntax-error]


# Don't emit `import-error` or `no-name-in-module`
Expand Down
4 changes: 2 additions & 2 deletions tests/functional/i/import_error.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import-error:3:0:3:22::Unable to import 'totally_missing':UNDEFINED
import-error:21:4:21:26::Unable to import 'maybe_missing_2':UNDEFINED
no-name-in-module:33:0:33:42::No name 'syntax_error' in module 'functional.s':UNDEFINED
syntax-error:33:0:None:None::Cannot import 'functional.s.syntax_error' due to syntax error 'invalid syntax (<unknown>, line 1)':UNDEFINED
no-name-in-module:33:0:33:49::No name 'syntax_error' in module 'functional.s.syntax':UNDEFINED
syntax-error:33:0:None:None::Cannot import 'functional.s.syntax.syntax_error' due to syntax error 'invalid syntax (<unknown>, line 1)':UNDEFINED
multiple-imports:78:0:78:15::Multiple imports on one line (foo, bar):UNDEFINED
1 change: 1 addition & 0 deletions tests/functional/s/symlink/_binding/__init__.py
1 change: 1 addition & 0 deletions tests/functional/s/symlink/_binding/symlink_module.py
1 change: 0 additions & 1 deletion tests/functional/s/symlink/binding/__init__.py

This file was deleted.

1 change: 0 additions & 1 deletion tests/functional/s/symlink/binding/symlinked_module.py

This file was deleted.

2 changes: 1 addition & 1 deletion tests/functional/u/unbalanced_tuple_unpacking.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
"""Check possible unbalanced tuple unpacking """
from __future__ import absolute_import
from typing import NamedTuple
from functional.u.unpacking import unpack
from functional.u.unpacking.unpacking import unpack

# pylint: disable=missing-class-docstring, missing-function-docstring, using-constant-test, useless-object-inheritance,import-outside-toplevel

Expand Down
4 changes: 2 additions & 2 deletions tests/functional/u/unbalanced_tuple_unpacking.txt
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
unbalanced-tuple-unpacking:11:4:11:27:do_stuff:"Possible unbalanced tuple unpacking with sequence (1, 2, 3): left side has 2 label(s), right side has 3 value(s)":UNDEFINED
unbalanced-tuple-unpacking:17:4:17:29:do_stuff1:"Possible unbalanced tuple unpacking with sequence [1, 2, 3]: left side has 2 label(s), right side has 3 value(s)":UNDEFINED
unbalanced-tuple-unpacking:23:4:23:29:do_stuff2:"Possible unbalanced tuple unpacking with sequence (1, 2, 3): left side has 2 label(s), right side has 3 value(s)":UNDEFINED
unbalanced-tuple-unpacking:82:4:82:28:do_stuff9:"Possible unbalanced tuple unpacking with sequence defined at line 7 of functional.u.unpacking: left side has 2 label(s), right side has 3 value(s)":UNDEFINED
unbalanced-tuple-unpacking:96:8:96:33:UnbalancedUnpacking.test:"Possible unbalanced tuple unpacking with sequence defined at line 7 of functional.u.unpacking: left side has 2 label(s), right side has 3 value(s)":UNDEFINED
unbalanced-tuple-unpacking:82:4:82:28:do_stuff9:"Possible unbalanced tuple unpacking with sequence defined at line 7 of functional.u.unpacking.unpacking: left side has 2 label(s), right side has 3 value(s)":UNDEFINED
unbalanced-tuple-unpacking:96:8:96:33:UnbalancedUnpacking.test:"Possible unbalanced tuple unpacking with sequence defined at line 7 of functional.u.unpacking.unpacking: left side has 2 label(s), right side has 3 value(s)":UNDEFINED
unbalanced-tuple-unpacking:140:8:140:43:MyClass.sum_unpack_3_into_4:"Possible unbalanced tuple unpacking with sequence defined at line 128: left side has 4 label(s), right side has 3 value(s)":UNDEFINED
unbalanced-tuple-unpacking:145:8:145:28:MyClass.sum_unpack_3_into_2:"Possible unbalanced tuple unpacking with sequence defined at line 128: left side has 2 label(s), right side has 3 value(s)":UNDEFINED
unbalanced-tuple-unpacking:157:0:157:24::"Possible unbalanced tuple unpacking with sequence defined at line 151: left side has 2 label(s), right side has 0 value(s)":UNDEFINED
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
# pylint: disable=too-few-public-methods, invalid-name, attribute-defined-outside-init, unused-variable
# pylint: disable=using-constant-test, no-init, missing-docstring, wrong-import-order,wrong-import-position,no-else-return, useless-object-inheritance
from os import rename as nonseq_func
from functional.u.unpacking import nonseq
from functional.u.unpacking.unpacking import nonseq
from typing import NamedTuple

__revision__ = 0
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ unpacking-non-sequence:78:0:78:15::Attempting to unpack a non-sequence defined a
unpacking-non-sequence:79:0:79:17::Attempting to unpack a non-sequence:UNDEFINED
unpacking-non-sequence:80:0:80:11::Attempting to unpack a non-sequence None:UNDEFINED
unpacking-non-sequence:81:0:81:8::Attempting to unpack a non-sequence 1:UNDEFINED
unpacking-non-sequence:82:0:82:13::Attempting to unpack a non-sequence defined at line 9 of functional.u.unpacking:UNDEFINED
unpacking-non-sequence:83:0:83:15::Attempting to unpack a non-sequence defined at line 11 of functional.u.unpacking:UNDEFINED
unpacking-non-sequence:82:0:82:13::Attempting to unpack a non-sequence defined at line 9 of functional.u.unpacking.unpacking:UNDEFINED
unpacking-non-sequence:83:0:83:15::Attempting to unpack a non-sequence defined at line 11 of functional.u.unpacking.unpacking:UNDEFINED
unpacking-non-sequence:84:0:84:18::Attempting to unpack a non-sequence:UNDEFINED
unpacking-non-sequence:99:8:99:33:ClassUnpacking.test:Attempting to unpack a non-sequence defined at line 75:UNDEFINED
unpacking-non-sequence:100:8:100:35:ClassUnpacking.test:Attempting to unpack a non-sequence:UNDEFINED
Expand Down
12 changes: 12 additions & 0 deletions tests/test_functional_directories.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
"""Test that the directory structure of the functional tests is correct."""
from pathlib import Path

from pylint.testutils.functional.find_functional_tests import (
get_functional_test_files_from_directory,
)


def test_directories() -> None:
"""Test that the directory structure of the functional tests is correct."""
functional_dir = Path(__file__).parent / "functional"
get_functional_test_files_from_directory(functional_dir)
Empty file.
Empty file.
Empty file.
Empty file.
11 changes: 10 additions & 1 deletion tests/testutils/test_functional_testutils.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,10 @@
import pytest

from pylint import testutils
from pylint.testutils.functional import FunctionalTestFile
from pylint.testutils.functional import (
FunctionalTestFile,
get_functional_test_files_from_directory,
)

HERE = Path(__file__).parent
DATA_DIRECTORY = HERE / "data"
Expand All @@ -19,3 +22,9 @@ def test_parsing_of_pylintrc_init_hook() -> None:
with pytest.raises(RuntimeError):
test_file = FunctionalTestFile(str(DATA_DIRECTORY), "init_hook.py")
testutils.LintModuleTest(test_file)


def test_get_functional_test_files_from_directory() -> None:
"""Test that we correctly check the functional test directory structures."""
with pytest.raises(AssertionError, match="using_dir.py should not go in"):
get_functional_test_files_from_directory(DATA_DIRECTORY)