mirror of
https://github.com/PyCQA/flake8.git
synced 2026-04-07 21:44:18 +00:00
Mock 2.0 is using pbr which is hostile to environments without network access. It's not required on Python 3.5+ so I made it possible to use `unittest.mock` on this version. Updated tox.ini to reflect this. Tested with 2.7.11, 3.3.6, 3.4.5, and 3.5.2 on macOS 10.12.1 with tox and pyenv.
153 lines
5.6 KiB
Python
153 lines
5.6 KiB
Python
"""Integration tests for the checker submodule."""
|
|
try:
|
|
import mock
|
|
except ImportError:
|
|
from unittest import mock
|
|
import pytest
|
|
|
|
from flake8 import checker
|
|
from flake8.plugins import manager
|
|
|
|
|
|
EXPECTED_REPORT = (1, 1, 'T000 Expected Message')
|
|
|
|
|
|
class PluginClass(object):
|
|
"""Simple file plugin class yielding the expected report."""
|
|
|
|
name = 'test'
|
|
version = '1.0.0'
|
|
|
|
def __init__(self, tree):
|
|
"""Dummy constructor to provide mandatory parameter."""
|
|
pass
|
|
|
|
def run(self):
|
|
"""Run class yielding one element containing the expected report."""
|
|
yield EXPECTED_REPORT + (type(self), )
|
|
|
|
|
|
def plugin_func(func):
|
|
"""Decorator for file plugins which are implemented as functions."""
|
|
func.name = 'test'
|
|
func.version = '1.0.0'
|
|
return func
|
|
|
|
|
|
@plugin_func
|
|
def plugin_func_gen(tree):
|
|
"""Simple file plugin function yielding the expected report."""
|
|
yield EXPECTED_REPORT + (type(plugin_func_gen), )
|
|
|
|
|
|
@plugin_func
|
|
def plugin_func_list(tree):
|
|
"""Simple file plugin function returning a list of reports."""
|
|
return [EXPECTED_REPORT + (type(plugin_func_list), )]
|
|
|
|
|
|
@pytest.mark.parametrize('plugin_target', [
|
|
PluginClass,
|
|
plugin_func_gen,
|
|
plugin_func_list,
|
|
])
|
|
def test_handle_file_plugins(plugin_target):
|
|
"""Test the FileChecker class handling different file plugin types."""
|
|
# Mock an entry point returning the plugin target
|
|
entry_point = mock.Mock(spec=['require', 'resolve', 'load'])
|
|
entry_point.name = plugin_target.name
|
|
entry_point.resolve.return_value = plugin_target
|
|
|
|
# Load the checker plugins using the entry point mock
|
|
with mock.patch('pkg_resources.iter_entry_points',
|
|
return_value=[entry_point]):
|
|
checks = manager.Checkers()
|
|
|
|
# Prevent it from reading lines from stdin or somewhere else
|
|
with mock.patch('flake8.processor.FileProcessor.read_lines',
|
|
return_value=['Line 1']):
|
|
file_checker = checker.FileChecker(
|
|
'-',
|
|
checks.to_dictionary(),
|
|
mock.MagicMock()
|
|
)
|
|
|
|
# Do not actually build an AST
|
|
file_checker.processor.build_ast = lambda: True
|
|
|
|
# Forward reports to this mock
|
|
report = mock.Mock()
|
|
file_checker.report = report
|
|
file_checker.run_ast_checks()
|
|
report.assert_called_once_with(error_code=None,
|
|
line_number=EXPECTED_REPORT[0],
|
|
column=EXPECTED_REPORT[1],
|
|
text=EXPECTED_REPORT[2])
|
|
|
|
|
|
PLACEHOLDER_CODE = 'some_line = "of" * code'
|
|
|
|
|
|
@pytest.mark.parametrize('results, expected_order', [
|
|
# No entries should be added
|
|
([], []),
|
|
# Results are correctly ordered
|
|
([('A101', 1, 1, 'placeholder error', PLACEHOLDER_CODE),
|
|
('A101', 2, 1, 'placeholder error', PLACEHOLDER_CODE)], [0, 1]),
|
|
# Reversed order of lines
|
|
([('A101', 2, 1, 'placeholder error', PLACEHOLDER_CODE),
|
|
('A101', 1, 1, 'placeholder error', PLACEHOLDER_CODE)], [1, 0]),
|
|
# Columns are not ordered correctly (when reports are ordered correctly)
|
|
([('A101', 1, 2, 'placeholder error', PLACEHOLDER_CODE),
|
|
('A101', 1, 1, 'placeholder error', PLACEHOLDER_CODE),
|
|
('A101', 2, 1, 'placeholder error', PLACEHOLDER_CODE)], [1, 0, 2]),
|
|
([('A101', 2, 1, 'placeholder error', PLACEHOLDER_CODE),
|
|
('A101', 1, 1, 'placeholder error', PLACEHOLDER_CODE),
|
|
('A101', 1, 2, 'placeholder error', PLACEHOLDER_CODE)], [1, 2, 0]),
|
|
([('A101', 1, 2, 'placeholder error', PLACEHOLDER_CODE),
|
|
('A101', 2, 2, 'placeholder error', PLACEHOLDER_CODE),
|
|
('A101', 2, 1, 'placeholder error', PLACEHOLDER_CODE)], [0, 2, 1]),
|
|
([('A101', 1, 3, 'placeholder error', PLACEHOLDER_CODE),
|
|
('A101', 2, 2, 'placeholder error', PLACEHOLDER_CODE),
|
|
('A101', 3, 1, 'placeholder error', PLACEHOLDER_CODE)], [0, 1, 2]),
|
|
([('A101', 1, 1, 'placeholder error', PLACEHOLDER_CODE),
|
|
('A101', 1, 3, 'placeholder error', PLACEHOLDER_CODE),
|
|
('A101', 2, 2, 'placeholder error', PLACEHOLDER_CODE)], [0, 1, 2]),
|
|
# Previously sort column and message (so reversed) (see bug 196)
|
|
([('A101', 1, 1, 'placeholder error', PLACEHOLDER_CODE),
|
|
('A101', 2, 1, 'charlie error', PLACEHOLDER_CODE)], [0, 1]),
|
|
])
|
|
def test_report_order(results, expected_order):
|
|
"""
|
|
Test in which order the results will be reported.
|
|
|
|
It gets a list of reports from the file checkers and verifies that the
|
|
result will be ordered independent from the original report.
|
|
"""
|
|
def count_side_effect(name, sorted_results):
|
|
"""Side effect for the result handler to tell all are reported."""
|
|
return len(sorted_results)
|
|
|
|
# To simplify the parameters (and prevent copy & pasting) reuse report
|
|
# tuples to create the expected result lists from the indexes
|
|
expected_results = [results[index] for index in expected_order]
|
|
|
|
file_checker = mock.Mock(spec=['results', 'display_name'])
|
|
file_checker.results = results
|
|
file_checker.display_name = 'placeholder'
|
|
|
|
style_guide = mock.Mock(spec=['options'])
|
|
|
|
# Create a placeholder manager without arguments or plugins
|
|
# Just add one custom file checker which just provides the results
|
|
manager = checker.Manager(style_guide, [], [])
|
|
manager.checkers = [file_checker]
|
|
|
|
# _handle_results is the first place which gets the sorted result
|
|
# Should something non-private be mocked instead?
|
|
handler = mock.Mock()
|
|
handler.side_effect = count_side_effect
|
|
manager._handle_results = handler
|
|
|
|
assert manager.report() == (len(results), len(results))
|
|
handler.assert_called_once_with('placeholder', expected_results)
|