Skip to content

Commit

Permalink
Merge pull request #23 from jamescooke/restructure
Browse files Browse the repository at this point in the history
Restructure
  • Loading branch information
jamescooke committed Jun 15, 2018
2 parents 237a6e8 + 6723a2c commit e421479
Show file tree
Hide file tree
Showing 10 changed files with 187 additions and 241 deletions.
9 changes: 5 additions & 4 deletions flake8_aaa/checker.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import asttokens

from .__about__ import __short_name__, __version__
from .exceptions import ValidationError
from .function import Function
from .helpers import find_test_functions, is_test_file

Expand Down Expand Up @@ -39,7 +40,7 @@ def run(self):
if is_test_file(self.filename):
self.load()
for function_def in find_test_functions(self.tree):
function = Function(function_def)
function.parse()
for error in function.check():
yield error + (type(self), )
try:
Function(function_def).check_all()
except ValidationError as error:
yield error.to_flake8(type(self))
35 changes: 29 additions & 6 deletions flake8_aaa/exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,38 @@ class Flake8AAAException(Exception):
pass


class FunctionNotParsed(Flake8AAAException):
class NotActionBlock(Flake8AAAException):
"""
``Function.check()`` was called without ``Function.parse()`` being called
first.
Used when parsing if lines of a function should be considered Action
blocks.
"""


class NotActionBlock(Flake8AAAException):
class ValidationError(Flake8AAAException):
"""
Used when parsing if lines of a function should be considered Action
blocks.
Attributes:
line_number (int)
offset (int)
text (str)
"""

def __init__(self, line_number, offset, text):
self.line_number = line_number
self.offset = offset
self.text = text

def to_flake8(self, checker_cls):
"""
Args:
checker_cls (type): Class performing the check to be passed back to
flake8.
Returns:
tuple: Error to pass back to Flake8.
"""
return (
self.line_number,
self.offset,
self.text,
checker_cls,
)
83 changes: 30 additions & 53 deletions flake8_aaa/function.py
Original file line number Diff line number Diff line change
@@ -1,18 +1,13 @@
from .act_block import ActBlock
from .exceptions import FunctionNotParsed, NotActionBlock
from .exceptions import NotActionBlock, ValidationError
from .helpers import function_is_noop


class Function:
"""
Attributes:
act_blocks (list (ActBlock)): List of nodes that are considered Act
blocks for this test. Defaults to ``None`` when function has not
been parsed.
act_block (ActBlock): Act block for the test.
node (ast.FunctionDef): AST for the test under lint.
is_noop (bool): Function is considered empty. Consists just of comments
or ``pass``.
parsed (bool): Function's nodes have been parsed.
"""

def __init__(self, node):
Expand All @@ -21,65 +16,47 @@ def __init__(self, node):
node (ast.FunctionDef)
"""
self.node = node
self.act_blocks = []
self.is_noop = False
self.parsed = False
self.act_block = None

def parse(self):
def check_all(self):
"""
Processes the child nodes of ``node`` to find Act blocks which are kept
in the ``act_blocks`` attribute. Sets ``parsed`` to ``True``.
Run everything required for checking this function.
Returns:
int: Number of Act blocks found.
"""
self.act_blocks = []
None: On success.
Raises:
ValidationError: When an error is found.
"""
if function_is_noop(self.node):
self.parsed = True
self.is_noop = True
return 0

for child_node in self.node.body:
try:
self.act_blocks.append(ActBlock.build(child_node))
except NotActionBlock:
continue
return

# Allow `pytest.raises` in assert blocks
if len(self.act_blocks) > 1:
self.act_blocks = [self.act_blocks[0]] + list(
filter(lambda ab: ab.block_type != ActBlock.PYTEST_RAISES, self.act_blocks[1:])
)
self.act_block = self.load_act_block()

self.parsed = True
return len(self.act_blocks)

def check(self):
def load_act_block(self):
"""
Check test function for errors.
Returns:
list (tuple): Errors in flake8 (line_number, offset, text)
ActBlock
Raises:
FunctionNotParsed: When ``parse`` has not been called on this
instance yet.
ValidationError
"""
if not self.parsed:
raise FunctionNotParsed()

if self.is_noop:
return []
act_blocks = []
for child_node in self.node.body:
try:
act_blocks.append(ActBlock.build(child_node))
except NotActionBlock:
continue

if len(self.act_blocks) < 1:
return [
(self.node.lineno, self.node.col_offset, 'AAA01 no Act block found in test'),
]
# Allow `pytest.raises` in assert blocks - ignore all act blocks that
# are `pytest.raises` blocks that are not the first.
if len(act_blocks) > 1:
act_blocks = [act_blocks[0]
] + list(filter(lambda ab: ab.block_type != ActBlock.PYTEST_RAISES, act_blocks[1:]))

if len(self.act_blocks) > 1:
return [
(self.node.lineno, self.node.col_offset, 'AAA02 multiple Act blocks found in test'),
]
if len(act_blocks) < 1:
raise ValidationError(self.node.lineno, self.node.col_offset, 'AAA01 no Act block found in test')
if len(act_blocks) > 1:
raise ValidationError(self.node.lineno, self.node.col_offset, 'AAA02 multiple Act blocks found in test')

return []
return act_blocks[0]
Empty file added tests/exceptions/__init__.py
Empty file.
12 changes: 12 additions & 0 deletions tests/exceptions/test_validation_error.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
from flake8_aaa.checker import Checker
from flake8_aaa.exceptions import ValidationError


def test():
result = ValidationError(
line_number=99,
offset=777,
text='__MESSAGE__',
)

assert result.to_flake8(Checker) == (99, 777, '__MESSAGE__', Checker)
104 changes: 0 additions & 104 deletions tests/function/test_check.py

This file was deleted.

13 changes: 13 additions & 0 deletions tests/function/test_check_all.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import pytest


@pytest.mark.parametrize(
'code_str', [
'def test():\n pass',
'def test_docstring():\n """This test will work great"""',
]
)
def test_noop(function):
result = function.check_all()

assert result is None
4 changes: 1 addition & 3 deletions tests/function/test_init.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,4 @@ def test(first_node_with_tokens):
result = Function(first_node_with_tokens)

assert result.node == first_node_with_tokens
assert result.act_blocks == []
assert result.parsed is False
assert result.is_noop is False
assert result.act_block is None

0 comments on commit e421479

Please sign in to comment.