mirror of
https://github.com/PyCQA/flake8.git
synced 2026-03-30 10:46:54 +00:00
It seems likely that the multiprocessing module on Windows is not capable of serializing an object with the structure that we have and preserving the attributes we dynamically set on plugins (like the FlakesChecker). To avoid issues like this with all plugins (although we have only found this on Windows with the FlakesChecker), let's try serializing the Checkers PluginTypeManager to a dictionary so that the only object that a Queue is really trying to serialize/deserialize is the FlakesChecker itself. Related to #179
150 lines
5.5 KiB
Python
150 lines
5.5 KiB
Python
"""Integration tests for the checker submodule."""
|
|
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)
|