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

Closes #1327 #1851

Merged
merged 16 commits into from Feb 7, 2021
9 changes: 8 additions & 1 deletion .github/workflows/test.yml
@@ -1,6 +1,13 @@
name: test

on: [push, pull_request, workflow_dispatch]
'on':
push:
pull_request:
branches:
# Branches from forks have the form 'user:branch-name'. Reference:
# https://github.community/t/how-to-trigger-an-action-on-push-or-pull-request-but-not-both/16662/9
- '**:**'
workflow_dispatch:

jobs:
build:
Expand Down
14 changes: 12 additions & 2 deletions tests/test_visitors/conftest.py
Expand Up @@ -46,11 +46,21 @@ def factory(
baseline: Optional[int] = None,
*,
multiple: bool = False,
ignored_types=None,
):
if ignored_types:
real_errors = [
error
for error in visitor.violations
if not isinstance(error, ignored_types)
]
else:
real_errors = visitor.violations

if not multiple:
assert len(visitor.violations) == 1
assert len(real_errors) == 1

violation = visitor.violations[0]
violation = real_errors[0]
error_format = ': {0}'

assert error_format in violation.error_template
Expand Down
49 changes: 46 additions & 3 deletions tests/test_visitors/test_ast/test_naming/conftest.py
Expand Up @@ -14,7 +14,7 @@

# Class names:

class_name = 'class {0}: ...'
class_name = 'class {0}(SomeParent): ...'


# Function names:
Expand Down Expand Up @@ -75,7 +75,7 @@ def test(self, *, {0}=True): ...
lambda_argument = 'lambda {0}: ...'
lambda_posonly_argument = 'lambda {0}, /: ...'

# Class attributes:
# Defined attributes:

static_attribute = """
class Test:
Expand Down Expand Up @@ -104,6 +104,10 @@ def __init__(self):
self.{0}: int = 123
"""

# Foreign attributes:

foreign_attribute = 'other.{0} = 1'

# Variables:

variable_def = '{0} = 1'
Expand Down Expand Up @@ -180,12 +184,13 @@ def container():
method_kwonly_argument,
lambda_argument,

# Class attributes:
# Attributes:
static_attribute,
static_typed_attribute,
static_typed_annotation,
instance_attribute,
instance_typed_attribute,
foreign_attribute,

# Variables:
variable_def,
Expand All @@ -207,6 +212,20 @@ def container():
assignment_expression,
}

_ATTRIBUTES = frozenset((
method_name,

static_attribute,
static_typed_attribute,
static_typed_annotation,
instance_attribute,
instance_typed_attribute,
))

_FOREIGN_NAME_PATTERNS = frozenset((
foreign_attribute,
))

_FORBIDDEN_UNUSED_TUPLE = frozenset((
unpacking_variables,
variable_def,
Expand Down Expand Up @@ -249,6 +268,30 @@ def naming_template(request):
return request.param


@pytest.fixture(params=_ATTRIBUTES)
def attribute_template(request):
"""Parametrized fixture that contains patterns for attributes."""
return request.param


@pytest.fixture(params=_ALL_FIXTURES - _ATTRIBUTES)
def non_attribute_template(request):
"""Fixture that contains all naming templates except attributes."""
return request.param


@pytest.fixture(params=_FOREIGN_NAME_PATTERNS)
def foreign_naming_template(request):
"""Fixture that contains all foreign name templates."""
return request.param


@pytest.fixture(params=_ALL_FIXTURES - _FOREIGN_NAME_PATTERNS)
def own_naming_template(request):
"""Fixture that contains all own name templates."""
return request.param


@pytest.fixture(params=_FORBIDDEN_UNUSED_TUPLE)
def forbidden_tuple_unused_template(request):
"""Returns template that can be used to define wrong unused tuples."""
Expand Down
Expand Up @@ -3,7 +3,9 @@
from wemake_python_styleguide.violations.naming import (
UpperCaseAttributeViolation,
)
from wemake_python_styleguide.visitors.ast.naming import WrongNameVisitor
from wemake_python_styleguide.visitors.ast.naming.validation import (
WrongNameVisitor,
)

static_attribute = """
class Test(object):
Expand Down
@@ -1,7 +1,9 @@
import pytest

from wemake_python_styleguide.constants import SPECIAL_ARGUMENT_NAMES_WHITELIST
from wemake_python_styleguide.visitors.ast.naming import WrongNameVisitor
from wemake_python_styleguide.visitors.ast.naming.validation import (
WrongNameVisitor,
)

lambda_first_argument = 'lambda {0}: ...'
function_first_argument = 'def function({0}): ...'
Expand Down
Expand Up @@ -3,7 +3,7 @@
from wemake_python_styleguide.violations.best_practices import (
WrongModuleMetadataViolation,
)
from wemake_python_styleguide.visitors.ast.naming import (
from wemake_python_styleguide.visitors.ast.naming.variables import (
MODULE_METADATA_VARIABLES_BLACKLIST,
WrongModuleMetadataVisitor,
)
Expand Down
@@ -1,28 +1,69 @@
import pytest

from wemake_python_styleguide.constants import BUILTINS_WHITELIST
from wemake_python_styleguide.violations.naming import BuiltinShadowingViolation
from wemake_python_styleguide.visitors.ast.naming import WrongNameVisitor
from wemake_python_styleguide.visitors.ast.naming.validation import (
WrongNameVisitor,
)


@pytest.mark.parametrize('wrong_name', [
real_builtins = frozenset((
'list',
'str',
'sum',
])
))


@pytest.mark.parametrize('wrong_name', real_builtins)
def test_builtin_shadowing(
assert_errors,
assert_error_text,
parse_ast_tree,
naming_template,
non_attribute_template,
default_options,
mode,
wrong_name,
):
"""Test names that shadow builtins."""
tree = parse_ast_tree(mode(naming_template.format(wrong_name)))
tree = parse_ast_tree(mode(non_attribute_template.format(wrong_name)))

visitor = WrongNameVisitor(default_options, tree=tree)
visitor.run()

assert_errors(visitor, [BuiltinShadowingViolation])
assert_error_text(visitor, wrong_name)


@pytest.mark.parametrize('wrong_name', BUILTINS_WHITELIST)
def test_builtin_shadowing_whitelist(
assert_errors,
parse_ast_tree,
non_attribute_template,
default_options,
mode,
wrong_name,
):
"""Test names that shadow allowed builtins."""
tree = parse_ast_tree(mode(non_attribute_template.format(wrong_name)))

visitor = WrongNameVisitor(default_options, tree=tree)
visitor.run()

assert_errors(visitor, [])


@pytest.mark.parametrize('wrong_name', real_builtins | BUILTINS_WHITELIST)
def test_builtin_attribute(
assert_errors,
parse_ast_tree,
attribute_template,
default_options,
mode,
wrong_name,
):
"""Test attribute names that do not shadow builtins."""
tree = parse_ast_tree(mode(attribute_template.format(wrong_name)))

visitor = WrongNameVisitor(default_options, tree=tree)
visitor.run()

assert_errors(visitor, [])
Expand Up @@ -3,29 +3,55 @@
from wemake_python_styleguide.violations.naming import (
ConsecutiveUnderscoresInNameViolation,
)
from wemake_python_styleguide.visitors.ast.naming import WrongNameVisitor

from wemake_python_styleguide.visitors.ast.naming.validation import (
WrongNameVisitor,
)

@pytest.mark.parametrize('underscored_name', [
patterns = (
'with__underscore',
'mutliple__under__score',
'triple___underscore',
'__magic__name__',
])
)


@pytest.mark.parametrize('underscored_name', patterns)
def test_underscored_variable_name(
assert_errors,
assert_error_text,
parse_ast_tree,
naming_template,
own_naming_template,
default_options,
mode,
underscored_name,
):
"""Ensures that underscored names are not allowed."""
tree = parse_ast_tree(mode(naming_template.format(underscored_name)))
tree = parse_ast_tree(
mode(own_naming_template.format(underscored_name)),
)

visitor = WrongNameVisitor(default_options, tree=tree)
visitor.run()

assert_errors(visitor, [ConsecutiveUnderscoresInNameViolation])
assert_error_text(visitor, underscored_name)


@pytest.mark.parametrize('underscored_name', patterns)
def test_underscored_attribute_name(
assert_errors,
parse_ast_tree,
foreign_naming_template,
default_options,
mode,
underscored_name,
):
"""Ensures that attribute underscored names are allowed."""
tree = parse_ast_tree(
mode(foreign_naming_template.format(underscored_name)),
)

visitor = WrongNameVisitor(default_options, tree=tree)
visitor.run()

assert_errors(visitor, [])
@@ -1,6 +1,8 @@
import pytest

from wemake_python_styleguide.visitors.ast.naming import WrongNameVisitor
from wemake_python_styleguide.visitors.ast.naming.validation import (
WrongNameVisitor,
)


@pytest.mark.parametrize('correct_name', [
Expand Down
@@ -1,18 +1,23 @@
from wemake_python_styleguide.violations.naming import TooLongNameViolation
from wemake_python_styleguide.visitors.ast.naming import WrongNameVisitor
from wemake_python_styleguide.visitors.ast.naming.validation import (
WrongNameVisitor,
)

long_name = 'incredibly_long_name_that_should_not_pass_the_long_name_test'


def test_long_variable_name(
assert_errors,
assert_error_text,
parse_ast_tree,
naming_template,
own_naming_template,
default_options,
mode,
):
"""Ensures that long names are not allowed."""
long_name = 'incredibly_long_name_that_should_not_pass_the_long_name_test'
tree = parse_ast_tree(mode(naming_template.format(long_name)))
tree = parse_ast_tree(
mode(own_naming_template.format(long_name)),
)

visitor = WrongNameVisitor(default_options, tree=tree)
visitor.run()
Expand All @@ -21,16 +26,36 @@ def test_long_variable_name(
assert_error_text(visitor, long_name, default_options.max_name_length)


def test_long_foreign_name(
assert_errors,
parse_ast_tree,
foreign_naming_template,
default_options,
mode,
):
"""Ensures that long names are not allowed."""
tree = parse_ast_tree(
mode(foreign_naming_template.format(long_name)),
)

visitor = WrongNameVisitor(default_options, tree=tree)
visitor.run()

assert_errors(visitor, [])


def test_long_variable_name_config(
assert_errors,
parse_ast_tree,
naming_template,
own_naming_template,
options,
mode,
):
"""Ensures that it is possible to configure `max_name_length`."""
long_name = 'incredibly_long_name_that_should_not_pass_the_long_name_test'
tree = parse_ast_tree(mode(naming_template.format(long_name)))
tree = parse_ast_tree(
mode(own_naming_template.format(long_name)),
)

option_values = options(max_name_length=len(long_name) + 1)
visitor = WrongNameVisitor(option_values, tree=tree)
Expand Down
@@ -1,5 +1,7 @@
from wemake_python_styleguide.violations.naming import PrivateNameViolation
from wemake_python_styleguide.visitors.ast.naming import WrongNameVisitor
from wemake_python_styleguide.visitors.ast.naming.validation import (
WrongNameVisitor,
)


def test_private_variable_name(
Expand Down