mirror of
https://github.com/PyCQA/flake8.git
synced 2026-04-09 14:24:17 +00:00
Merge pull request #1319 from PyCQA/format_tests
extend black formatting to tests as well
This commit is contained in:
commit
645cd71f57
45 changed files with 1644 additions and 1307 deletions
|
|
@ -1,14 +1,12 @@
|
||||||
exclude: ^tests/fixtures/example-code/
|
exclude: ^tests/fixtures/
|
||||||
repos:
|
repos:
|
||||||
- repo: https://github.com/pre-commit/pre-commit-hooks
|
- repo: https://github.com/pre-commit/pre-commit-hooks
|
||||||
rev: v3.4.0
|
rev: v3.4.0
|
||||||
hooks:
|
hooks:
|
||||||
- id: check-yaml
|
- id: check-yaml
|
||||||
- id: debug-statements
|
- id: debug-statements
|
||||||
exclude: ^tests/fixtures/example-code/invalid-syntax.py$
|
|
||||||
- id: end-of-file-fixer
|
- id: end-of-file-fixer
|
||||||
- id: trailing-whitespace
|
- id: trailing-whitespace
|
||||||
exclude: ^tests/fixtures/diffs/
|
|
||||||
- repo: https://github.com/asottile/reorder_python_imports
|
- repo: https://github.com/asottile/reorder_python_imports
|
||||||
rev: v2.4.0
|
rev: v2.4.0
|
||||||
hooks:
|
hooks:
|
||||||
|
|
@ -18,8 +16,7 @@ repos:
|
||||||
rev: 20.8b1
|
rev: 20.8b1
|
||||||
hooks:
|
hooks:
|
||||||
- id: black
|
- id: black
|
||||||
args: [--line-length=78]
|
args: [--line-length=79]
|
||||||
files: ^src/
|
|
||||||
- repo: https://github.com/asottile/pyupgrade
|
- repo: https://github.com/asottile/pyupgrade
|
||||||
rev: v2.12.0
|
rev: v2.12.0
|
||||||
hooks:
|
hooks:
|
||||||
|
|
@ -29,4 +26,4 @@ repos:
|
||||||
rev: v0.812
|
rev: v0.812
|
||||||
hooks:
|
hooks:
|
||||||
- id: mypy
|
- id: mypy
|
||||||
exclude: ^(docs/|example-plugin/|tests/fixtures)
|
exclude: ^(docs/|example-plugin/)
|
||||||
|
|
|
||||||
|
|
@ -16,45 +16,45 @@ import sys
|
||||||
# If extensions (or modules to document with autodoc) are in another directory,
|
# If extensions (or modules to document with autodoc) are in another directory,
|
||||||
# add these directories to sys.path here. If the directory is relative to the
|
# add these directories to sys.path here. If the directory is relative to the
|
||||||
# documentation root, use os.path.abspath to make it absolute, like shown here.
|
# documentation root, use os.path.abspath to make it absolute, like shown here.
|
||||||
#sys.path.insert(0, os.path.abspath('.'))
|
# sys.path.insert(0, os.path.abspath('.'))
|
||||||
|
|
||||||
# -- General configuration ------------------------------------------------
|
# -- General configuration ------------------------------------------------
|
||||||
|
|
||||||
# If your documentation needs a minimal Sphinx version, state it here.
|
# If your documentation needs a minimal Sphinx version, state it here.
|
||||||
needs_sphinx = '1.3'
|
needs_sphinx = "1.3"
|
||||||
|
|
||||||
# Add any Sphinx extension module names here, as strings. They can be
|
# Add any Sphinx extension module names here, as strings. They can be
|
||||||
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
|
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
|
||||||
# ones.
|
# ones.
|
||||||
extensions = [
|
extensions = [
|
||||||
'sphinx.ext.autodoc',
|
"sphinx.ext.autodoc",
|
||||||
'sphinx.ext.doctest',
|
"sphinx.ext.doctest",
|
||||||
'sphinx.ext.extlinks',
|
"sphinx.ext.extlinks",
|
||||||
'sphinx.ext.intersphinx',
|
"sphinx.ext.intersphinx",
|
||||||
'sphinx.ext.todo',
|
"sphinx.ext.todo",
|
||||||
'sphinx.ext.coverage',
|
"sphinx.ext.coverage",
|
||||||
'sphinx.ext.viewcode',
|
"sphinx.ext.viewcode",
|
||||||
'sphinx-prompt',
|
"sphinx-prompt",
|
||||||
]
|
]
|
||||||
|
|
||||||
# Add any paths that contain templates here, relative to this directory.
|
# Add any paths that contain templates here, relative to this directory.
|
||||||
templates_path = ['_templates']
|
templates_path = ["_templates"]
|
||||||
|
|
||||||
# The suffix(es) of source filenames.
|
# The suffix(es) of source filenames.
|
||||||
# You can specify multiple suffix as a list of string:
|
# You can specify multiple suffix as a list of string:
|
||||||
# source_suffix = ['.rst', '.md']
|
# source_suffix = ['.rst', '.md']
|
||||||
source_suffix = '.rst'
|
source_suffix = ".rst"
|
||||||
|
|
||||||
# The encoding of source files.
|
# The encoding of source files.
|
||||||
#source_encoding = 'utf-8-sig'
|
# source_encoding = 'utf-8-sig'
|
||||||
|
|
||||||
# The master toctree document.
|
# The master toctree document.
|
||||||
master_doc = 'index'
|
master_doc = "index"
|
||||||
|
|
||||||
# General information about the project.
|
# General information about the project.
|
||||||
project = 'flake8'
|
project = "flake8"
|
||||||
copyright = '2016, Ian Stapleton Cordasco'
|
copyright = "2016, Ian Stapleton Cordasco"
|
||||||
author = 'Ian Stapleton Cordasco'
|
author = "Ian Stapleton Cordasco"
|
||||||
|
|
||||||
import flake8
|
import flake8
|
||||||
|
|
||||||
|
|
@ -80,9 +80,9 @@ language = None
|
||||||
|
|
||||||
# There are two options for replacing |today|: either, you set today to some
|
# There are two options for replacing |today|: either, you set today to some
|
||||||
# non-false value, then it is used:
|
# non-false value, then it is used:
|
||||||
#today = ''
|
# today = ''
|
||||||
# Else, today_fmt is used as the format for a strftime call.
|
# Else, today_fmt is used as the format for a strftime call.
|
||||||
#today_fmt = '%B %d, %Y'
|
# today_fmt = '%B %d, %Y'
|
||||||
|
|
||||||
# List of patterns, relative to source directory, that match files and
|
# List of patterns, relative to source directory, that match files and
|
||||||
# directories to ignore when looking for source files.
|
# directories to ignore when looking for source files.
|
||||||
|
|
@ -90,27 +90,27 @@ exclude_patterns = []
|
||||||
|
|
||||||
# The reST default role (used for this markup: `text`) to use for all
|
# The reST default role (used for this markup: `text`) to use for all
|
||||||
# documents.
|
# documents.
|
||||||
#default_role = None
|
# default_role = None
|
||||||
|
|
||||||
# If true, '()' will be appended to :func: etc. cross-reference text.
|
# If true, '()' will be appended to :func: etc. cross-reference text.
|
||||||
#add_function_parentheses = True
|
# add_function_parentheses = True
|
||||||
|
|
||||||
# If true, the current module name will be prepended to all description
|
# If true, the current module name will be prepended to all description
|
||||||
# unit titles (such as .. function::).
|
# unit titles (such as .. function::).
|
||||||
#add_module_names = True
|
# add_module_names = True
|
||||||
|
|
||||||
# If true, sectionauthor and moduleauthor directives will be shown in the
|
# If true, sectionauthor and moduleauthor directives will be shown in the
|
||||||
# output. They are ignored by default.
|
# output. They are ignored by default.
|
||||||
#show_authors = False
|
# show_authors = False
|
||||||
|
|
||||||
# The name of the Pygments (syntax highlighting) style to use.
|
# The name of the Pygments (syntax highlighting) style to use.
|
||||||
pygments_style = 'sphinx'
|
pygments_style = "sphinx"
|
||||||
|
|
||||||
# A list of ignored prefixes for module index sorting.
|
# A list of ignored prefixes for module index sorting.
|
||||||
#modindex_common_prefix = []
|
# modindex_common_prefix = []
|
||||||
|
|
||||||
# If true, keep warnings as "system message" paragraphs in the built documents.
|
# If true, keep warnings as "system message" paragraphs in the built documents.
|
||||||
#keep_warnings = False
|
# keep_warnings = False
|
||||||
|
|
||||||
# If true, `todo` and `todoList` produce output, else they produce nothing.
|
# If true, `todo` and `todoList` produce output, else they produce nothing.
|
||||||
todo_include_todos = True
|
todo_include_todos = True
|
||||||
|
|
@ -120,31 +120,31 @@ todo_include_todos = True
|
||||||
|
|
||||||
# The theme to use for HTML and HTML Help pages. See the documentation for
|
# The theme to use for HTML and HTML Help pages. See the documentation for
|
||||||
# a list of builtin themes.
|
# a list of builtin themes.
|
||||||
html_theme = 'sphinx_rtd_theme'
|
html_theme = "sphinx_rtd_theme"
|
||||||
|
|
||||||
# Theme options are theme-specific and customize the look and feel of a theme
|
# Theme options are theme-specific and customize the look and feel of a theme
|
||||||
# further. For a list of options available for each theme, see the
|
# further. For a list of options available for each theme, see the
|
||||||
# documentation.
|
# documentation.
|
||||||
#html_theme_options = {}
|
# html_theme_options = {}
|
||||||
|
|
||||||
# Add any paths that contain custom themes here, relative to this directory.
|
# Add any paths that contain custom themes here, relative to this directory.
|
||||||
#html_theme_path = []
|
# html_theme_path = []
|
||||||
|
|
||||||
# The name for this set of Sphinx documents. If None, it defaults to
|
# The name for this set of Sphinx documents. If None, it defaults to
|
||||||
# "<project> v<release> documentation".
|
# "<project> v<release> documentation".
|
||||||
#html_title = None
|
# html_title = None
|
||||||
|
|
||||||
# A shorter title for the navigation bar. Default is the same as html_title.
|
# A shorter title for the navigation bar. Default is the same as html_title.
|
||||||
#html_short_title = None
|
# html_short_title = None
|
||||||
|
|
||||||
# The name of an image file (relative to this directory) to place at the top
|
# The name of an image file (relative to this directory) to place at the top
|
||||||
# of the sidebar.
|
# of the sidebar.
|
||||||
#html_logo = None
|
# html_logo = None
|
||||||
|
|
||||||
# The name of an image file (within the static path) to use as favicon of the
|
# The name of an image file (within the static path) to use as favicon of the
|
||||||
# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
|
# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
|
||||||
# pixels large.
|
# pixels large.
|
||||||
#html_favicon = None
|
# html_favicon = None
|
||||||
|
|
||||||
# Add any paths that contain custom static files (such as style sheets) here,
|
# Add any paths that contain custom static files (such as style sheets) here,
|
||||||
# relative to this directory. They are copied after the builtin static files,
|
# relative to this directory. They are copied after the builtin static files,
|
||||||
|
|
@ -154,109 +154,111 @@ html_theme = 'sphinx_rtd_theme'
|
||||||
# Add any extra paths that contain custom files (such as robots.txt or
|
# Add any extra paths that contain custom files (such as robots.txt or
|
||||||
# .htaccess) here, relative to this directory. These files are copied
|
# .htaccess) here, relative to this directory. These files are copied
|
||||||
# directly to the root of the documentation.
|
# directly to the root of the documentation.
|
||||||
#html_extra_path = []
|
# html_extra_path = []
|
||||||
|
|
||||||
# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
|
# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
|
||||||
# using the given strftime format.
|
# using the given strftime format.
|
||||||
#html_last_updated_fmt = '%b %d, %Y'
|
# html_last_updated_fmt = '%b %d, %Y'
|
||||||
|
|
||||||
# If true, SmartyPants will be used to convert quotes and dashes to
|
# If true, SmartyPants will be used to convert quotes and dashes to
|
||||||
# typographically correct entities.
|
# typographically correct entities.
|
||||||
#html_use_smartypants = True
|
# html_use_smartypants = True
|
||||||
|
|
||||||
# Custom sidebar templates, maps document names to template names.
|
# Custom sidebar templates, maps document names to template names.
|
||||||
#html_sidebars = {}
|
# html_sidebars = {}
|
||||||
|
|
||||||
# Additional templates that should be rendered to pages, maps page names to
|
# Additional templates that should be rendered to pages, maps page names to
|
||||||
# template names.
|
# template names.
|
||||||
#html_additional_pages = {}
|
# html_additional_pages = {}
|
||||||
|
|
||||||
# If false, no module index is generated.
|
# If false, no module index is generated.
|
||||||
#html_domain_indices = True
|
# html_domain_indices = True
|
||||||
|
|
||||||
# If false, no index is generated.
|
# If false, no index is generated.
|
||||||
#html_use_index = True
|
# html_use_index = True
|
||||||
|
|
||||||
# If true, the index is split into individual pages for each letter.
|
# If true, the index is split into individual pages for each letter.
|
||||||
#html_split_index = False
|
# html_split_index = False
|
||||||
|
|
||||||
# If true, links to the reST sources are added to the pages.
|
# If true, links to the reST sources are added to the pages.
|
||||||
#html_show_sourcelink = True
|
# html_show_sourcelink = True
|
||||||
|
|
||||||
# If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
|
# If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
|
||||||
#html_show_sphinx = True
|
# html_show_sphinx = True
|
||||||
|
|
||||||
# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.
|
# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.
|
||||||
#html_show_copyright = True
|
# html_show_copyright = True
|
||||||
|
|
||||||
# If true, an OpenSearch description file will be output, and all pages will
|
# If true, an OpenSearch description file will be output, and all pages will
|
||||||
# contain a <link> tag referring to it. The value of this option must be the
|
# contain a <link> tag referring to it. The value of this option must be the
|
||||||
# base URL from which the finished HTML is served.
|
# base URL from which the finished HTML is served.
|
||||||
#html_use_opensearch = ''
|
# html_use_opensearch = ''
|
||||||
|
|
||||||
# This is the file name suffix for HTML files (e.g. ".xhtml").
|
# This is the file name suffix for HTML files (e.g. ".xhtml").
|
||||||
#html_file_suffix = None
|
# html_file_suffix = None
|
||||||
|
|
||||||
# Language to be used for generating the HTML full-text search index.
|
# Language to be used for generating the HTML full-text search index.
|
||||||
# Sphinx supports the following languages:
|
# Sphinx supports the following languages:
|
||||||
# 'da', 'de', 'en', 'es', 'fi', 'fr', 'hu', 'it', 'ja'
|
# 'da', 'de', 'en', 'es', 'fi', 'fr', 'hu', 'it', 'ja'
|
||||||
# 'nl', 'no', 'pt', 'ro', 'ru', 'sv', 'tr'
|
# 'nl', 'no', 'pt', 'ro', 'ru', 'sv', 'tr'
|
||||||
#html_search_language = 'en'
|
# html_search_language = 'en'
|
||||||
|
|
||||||
# A dictionary with options for the search language support, empty by default.
|
# A dictionary with options for the search language support, empty by default.
|
||||||
# Now only 'ja' uses this config value
|
# Now only 'ja' uses this config value
|
||||||
#html_search_options = {'type': 'default'}
|
# html_search_options = {'type': 'default'}
|
||||||
|
|
||||||
# The name of a javascript file (relative to the configuration directory) that
|
# The name of a javascript file (relative to the configuration directory) that
|
||||||
# implements a search results scorer. If empty, the default will be used.
|
# implements a search results scorer. If empty, the default will be used.
|
||||||
#html_search_scorer = 'scorer.js'
|
# html_search_scorer = 'scorer.js'
|
||||||
|
|
||||||
# Output file base name for HTML help builder.
|
# Output file base name for HTML help builder.
|
||||||
htmlhelp_basename = 'flake8doc'
|
htmlhelp_basename = "flake8doc"
|
||||||
|
|
||||||
# -- Options for LaTeX output ---------------------------------------------
|
# -- Options for LaTeX output ---------------------------------------------
|
||||||
|
|
||||||
latex_elements = {
|
latex_elements = {
|
||||||
# The paper size ('letterpaper' or 'a4paper').
|
# The paper size ('letterpaper' or 'a4paper').
|
||||||
#'papersize': 'letterpaper',
|
#'papersize': 'letterpaper',
|
||||||
|
# The font size ('10pt', '11pt' or '12pt').
|
||||||
# The font size ('10pt', '11pt' or '12pt').
|
#'pointsize': '10pt',
|
||||||
#'pointsize': '10pt',
|
# Additional stuff for the LaTeX preamble.
|
||||||
|
#'preamble': '',
|
||||||
# Additional stuff for the LaTeX preamble.
|
# Latex figure (float) alignment
|
||||||
#'preamble': '',
|
#'figure_align': 'htbp',
|
||||||
|
|
||||||
# Latex figure (float) alignment
|
|
||||||
#'figure_align': 'htbp',
|
|
||||||
}
|
}
|
||||||
|
|
||||||
# Grouping the document tree into LaTeX files. List of tuples
|
# Grouping the document tree into LaTeX files. List of tuples
|
||||||
# (source start file, target name, title,
|
# (source start file, target name, title,
|
||||||
# author, documentclass [howto, manual, or own class]).
|
# author, documentclass [howto, manual, or own class]).
|
||||||
latex_documents = [
|
latex_documents = [
|
||||||
(master_doc, 'flake8.tex', 'flake8 Documentation',
|
(
|
||||||
'Ian Stapleton Cordasco', 'manual'),
|
master_doc,
|
||||||
|
"flake8.tex",
|
||||||
|
"flake8 Documentation",
|
||||||
|
"Ian Stapleton Cordasco",
|
||||||
|
"manual",
|
||||||
|
),
|
||||||
]
|
]
|
||||||
|
|
||||||
# The name of an image file (relative to this directory) to place at the top of
|
# The name of an image file (relative to this directory) to place at the top of
|
||||||
# the title page.
|
# the title page.
|
||||||
#latex_logo = None
|
# latex_logo = None
|
||||||
|
|
||||||
# For "manual" documents, if this is true, then toplevel headings are parts,
|
# For "manual" documents, if this is true, then toplevel headings are parts,
|
||||||
# not chapters.
|
# not chapters.
|
||||||
#latex_use_parts = False
|
# latex_use_parts = False
|
||||||
|
|
||||||
# If true, show page references after internal links.
|
# If true, show page references after internal links.
|
||||||
#latex_show_pagerefs = False
|
# latex_show_pagerefs = False
|
||||||
|
|
||||||
# If true, show URL addresses after external links.
|
# If true, show URL addresses after external links.
|
||||||
#latex_show_urls = False
|
# latex_show_urls = False
|
||||||
|
|
||||||
# Documents to append as an appendix to all manuals.
|
# Documents to append as an appendix to all manuals.
|
||||||
#latex_appendices = []
|
# latex_appendices = []
|
||||||
|
|
||||||
# If false, no module index is generated.
|
# If false, no module index is generated.
|
||||||
#latex_domain_indices = True
|
# latex_domain_indices = True
|
||||||
|
|
||||||
|
|
||||||
# -- Options for manual page output ---------------------------------------
|
# -- Options for manual page output ---------------------------------------
|
||||||
|
|
@ -264,12 +266,11 @@ latex_documents = [
|
||||||
# One entry per manual page. List of tuples
|
# One entry per manual page. List of tuples
|
||||||
# (source start file, name, description, authors, manual section).
|
# (source start file, name, description, authors, manual section).
|
||||||
man_pages = [
|
man_pages = [
|
||||||
('manpage', 'flake8', 'Flake8 Command Line Documentation',
|
("manpage", "flake8", "Flake8 Command Line Documentation", [author], 1)
|
||||||
[author], 1)
|
|
||||||
]
|
]
|
||||||
|
|
||||||
# If true, show URL addresses after external links.
|
# If true, show URL addresses after external links.
|
||||||
#man_show_urls = False
|
# man_show_urls = False
|
||||||
|
|
||||||
|
|
||||||
# -- Options for Texinfo output -------------------------------------------
|
# -- Options for Texinfo output -------------------------------------------
|
||||||
|
|
@ -278,26 +279,32 @@ man_pages = [
|
||||||
# (source start file, target name, title, author,
|
# (source start file, target name, title, author,
|
||||||
# dir menu entry, description, category)
|
# dir menu entry, description, category)
|
||||||
texinfo_documents = [
|
texinfo_documents = [
|
||||||
('index', 'Flake8', 'Flake8 Documentation', 'Tarek Ziade',
|
(
|
||||||
'Flake8', 'Code checking using pycodestyle, pyflakes and mccabe',
|
"index",
|
||||||
'Miscellaneous'),
|
"Flake8",
|
||||||
|
"Flake8 Documentation",
|
||||||
|
"Tarek Ziade",
|
||||||
|
"Flake8",
|
||||||
|
"Code checking using pycodestyle, pyflakes and mccabe",
|
||||||
|
"Miscellaneous",
|
||||||
|
),
|
||||||
]
|
]
|
||||||
|
|
||||||
# Documents to append as an appendix to all manuals.
|
# Documents to append as an appendix to all manuals.
|
||||||
#texinfo_appendices = []
|
# texinfo_appendices = []
|
||||||
|
|
||||||
# If false, no module index is generated.
|
# If false, no module index is generated.
|
||||||
#texinfo_domain_indices = True
|
# texinfo_domain_indices = True
|
||||||
|
|
||||||
# How to display URL addresses: 'footnote', 'no', or 'inline'.
|
# How to display URL addresses: 'footnote', 'no', or 'inline'.
|
||||||
#texinfo_show_urls = 'footnote'
|
# texinfo_show_urls = 'footnote'
|
||||||
|
|
||||||
# If true, do not generate a @detailmenu in the "Top" node's menu.
|
# If true, do not generate a @detailmenu in the "Top" node's menu.
|
||||||
#texinfo_no_detailmenu = False
|
# texinfo_no_detailmenu = False
|
||||||
|
|
||||||
|
|
||||||
# Example configuration for intersphinx: refer to the Python standard library.
|
# Example configuration for intersphinx: refer to the Python standard library.
|
||||||
intersphinx_mapping = {'python': ('https://docs.python.org/3/', None)}
|
intersphinx_mapping = {"python": ("https://docs.python.org/3/", None)}
|
||||||
|
|
||||||
extlinks = {
|
extlinks = {
|
||||||
"issue": ("https://github.com/pycqa/flake8/issues/%s", "#"),
|
"issue": ("https://github.com/pycqa/flake8/issues/%s", "#"),
|
||||||
|
|
|
||||||
|
|
@ -1,29 +1,29 @@
|
||||||
import setuptools
|
import setuptools
|
||||||
|
|
||||||
setuptools.setup(
|
setuptools.setup(
|
||||||
name='flake8-example-plugin',
|
name="flake8-example-plugin",
|
||||||
license='MIT',
|
license="MIT",
|
||||||
version='1.0.0',
|
version="1.0.0",
|
||||||
description='Example plugin to Flake8',
|
description="Example plugin to Flake8",
|
||||||
author='Ian Cordasco',
|
author="Ian Cordasco",
|
||||||
author_email='graffatcolmingov@gmail.com',
|
author_email="graffatcolmingov@gmail.com",
|
||||||
url='https://github.com/pycqa/flake8',
|
url="https://github.com/pycqa/flake8",
|
||||||
package_dir={'': 'src/'},
|
package_dir={"": "src/"},
|
||||||
packages=['flake8_example_plugin'],
|
packages=["flake8_example_plugin"],
|
||||||
entry_points={
|
entry_points={
|
||||||
'flake8.extension': [
|
"flake8.extension": [
|
||||||
'X1 = flake8_example_plugin:ExampleOne',
|
"X1 = flake8_example_plugin:ExampleOne",
|
||||||
'X2 = flake8_example_plugin:ExampleTwo',
|
"X2 = flake8_example_plugin:ExampleTwo",
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
classifiers=[
|
classifiers=[
|
||||||
'Framework :: Flake8',
|
"Framework :: Flake8",
|
||||||
'License :: OSI Approved :: MIT License',
|
"License :: OSI Approved :: MIT License",
|
||||||
'Programming Language :: Python',
|
"Programming Language :: Python",
|
||||||
'Programming Language :: Python :: 3',
|
"Programming Language :: Python :: 3",
|
||||||
'Programming Language :: Python :: 3.8',
|
"Programming Language :: Python :: 3.8",
|
||||||
'Programming Language :: Python :: 3.9',
|
"Programming Language :: Python :: 3.9",
|
||||||
'Topic :: Software Development :: Libraries :: Python Modules',
|
"Topic :: Software Development :: Libraries :: Python Modules",
|
||||||
'Topic :: Software Development :: Quality Assurance',
|
"Topic :: Software Development :: Quality Assurance",
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,6 @@ from .off_by_default import ExampleTwo
|
||||||
from .on_by_default import ExampleOne
|
from .on_by_default import ExampleOne
|
||||||
|
|
||||||
__all__ = (
|
__all__ = (
|
||||||
'ExampleOne',
|
"ExampleOne",
|
||||||
'ExampleTwo',
|
"ExampleTwo",
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -3,8 +3,9 @@
|
||||||
|
|
||||||
class ExampleTwo:
|
class ExampleTwo:
|
||||||
"""Second Example Plugin."""
|
"""Second Example Plugin."""
|
||||||
name = 'off-by-default-example-plugin'
|
|
||||||
version = '1.0.0'
|
name = "off-by-default-example-plugin"
|
||||||
|
version = "1.0.0"
|
||||||
|
|
||||||
off_by_default = True
|
off_by_default = True
|
||||||
|
|
||||||
|
|
@ -13,5 +14,9 @@ class ExampleTwo:
|
||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
"""Do nothing."""
|
"""Do nothing."""
|
||||||
yield (1, 0, 'X200 The off-by-default plugin was enabled',
|
yield (
|
||||||
'OffByDefaultPlugin')
|
1,
|
||||||
|
0,
|
||||||
|
"X200 The off-by-default plugin was enabled",
|
||||||
|
"OffByDefaultPlugin",
|
||||||
|
)
|
||||||
|
|
|
||||||
|
|
@ -3,8 +3,9 @@
|
||||||
|
|
||||||
class ExampleOne:
|
class ExampleOne:
|
||||||
"""First Example Plugin."""
|
"""First Example Plugin."""
|
||||||
name = 'on-by-default-example-plugin'
|
|
||||||
version = '1.0.0'
|
name = "on-by-default-example-plugin"
|
||||||
|
version = "1.0.0"
|
||||||
|
|
||||||
def __init__(self, tree):
|
def __init__(self, tree):
|
||||||
self.tree = tree
|
self.tree = tree
|
||||||
|
|
|
||||||
2
setup.py
2
setup.py
|
|
@ -4,6 +4,6 @@ import sys
|
||||||
|
|
||||||
import setuptools
|
import setuptools
|
||||||
|
|
||||||
sys.path.insert(0, os.path.join(os.path.dirname(__file__), 'src'))
|
sys.path.insert(0, os.path.join(os.path.dirname(__file__), "src"))
|
||||||
|
|
||||||
setuptools.setup()
|
setuptools.setup()
|
||||||
|
|
|
||||||
|
|
@ -17,9 +17,7 @@ LOG = logging.getLogger(__name__)
|
||||||
LOG.addHandler(logging.NullHandler())
|
LOG.addHandler(logging.NullHandler())
|
||||||
|
|
||||||
__version__ = "3.9.1"
|
__version__ = "3.9.1"
|
||||||
__version_info__ = tuple(
|
__version_info__ = tuple(int(i) for i in __version__.split(".") if i.isdigit())
|
||||||
int(i) for i in __version__.split(".") if i.isdigit()
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
# There is nothing lower than logging.DEBUG (10) in the logging library,
|
# There is nothing lower than logging.DEBUG (10) in the logging library,
|
||||||
|
|
|
||||||
|
|
@ -241,9 +241,7 @@ class Manager:
|
||||||
"""
|
"""
|
||||||
results_reported = results_found = 0
|
results_reported = results_found = 0
|
||||||
for checker in self._all_checkers:
|
for checker in self._all_checkers:
|
||||||
results = sorted(
|
results = sorted(checker.results, key=lambda tup: (tup[1], tup[2]))
|
||||||
checker.results, key=lambda tup: (tup[1], tup[2])
|
|
||||||
)
|
|
||||||
filename = checker.display_name
|
filename = checker.display_name
|
||||||
with self.style_guide.processing_file(filename):
|
with self.style_guide.processing_file(filename):
|
||||||
results_reported += self._handle_results(filename, results)
|
results_reported += self._handle_results(filename, results)
|
||||||
|
|
|
||||||
|
|
@ -39,9 +39,7 @@ class InvalidSyntax(Flake8Exception):
|
||||||
def __init__(self, exception: Exception) -> None:
|
def __init__(self, exception: Exception) -> None:
|
||||||
"""Initialize our InvalidSyntax exception."""
|
"""Initialize our InvalidSyntax exception."""
|
||||||
self.original_exception = exception
|
self.original_exception = exception
|
||||||
self.error_message = (
|
self.error_message = f"{type(exception).__name__}: {exception.args[0]}"
|
||||||
f"{type(exception).__name__}: {exception.args[0]}"
|
|
||||||
)
|
|
||||||
self.error_code = "E902"
|
self.error_code = "E902"
|
||||||
self.line_number = 1
|
self.line_number = 1
|
||||||
self.column_number = 0
|
self.column_number = 0
|
||||||
|
|
|
||||||
|
|
@ -369,6 +369,4 @@ def get_local_plugins(config_finder):
|
||||||
return local_plugins
|
return local_plugins
|
||||||
|
|
||||||
|
|
||||||
LocalPlugins = collections.namedtuple(
|
LocalPlugins = collections.namedtuple("LocalPlugins", "extension report paths")
|
||||||
"LocalPlugins", "extension report paths"
|
|
||||||
)
|
|
||||||
|
|
|
||||||
|
|
@ -472,8 +472,7 @@ class Checkers(PluginTypeManager):
|
||||||
plugin.to_dictionary() for plugin in self.logical_line_plugins
|
plugin.to_dictionary() for plugin in self.logical_line_plugins
|
||||||
],
|
],
|
||||||
"physical_line_plugins": [
|
"physical_line_plugins": [
|
||||||
plugin.to_dictionary()
|
plugin.to_dictionary() for plugin in self.physical_line_plugins
|
||||||
for plugin in self.physical_line_plugins
|
|
||||||
],
|
],
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -289,9 +289,7 @@ class FileProcessor:
|
||||||
except (tokenize.TokenError, SyntaxError) as exc:
|
except (tokenize.TokenError, SyntaxError) as exc:
|
||||||
raise exceptions.InvalidSyntax(exception=exc)
|
raise exceptions.InvalidSyntax(exception=exc)
|
||||||
|
|
||||||
def _noqa_line_range(
|
def _noqa_line_range(self, min_line: int, max_line: int) -> Dict[int, str]:
|
||||||
self, min_line: int, max_line: int
|
|
||||||
) -> Dict[int, str]:
|
|
||||||
line_range = range(min_line, max_line + 1)
|
line_range = range(min_line, max_line + 1)
|
||||||
joined = "".join(self.lines[min_line - 1 : max_line])
|
joined = "".join(self.lines[min_line - 1 : max_line])
|
||||||
return dict.fromkeys(line_range, joined)
|
return dict.fromkeys(line_range, joined)
|
||||||
|
|
|
||||||
|
|
@ -368,9 +368,7 @@ class StyleGuideManager:
|
||||||
:rtype:
|
:rtype:
|
||||||
:class:`~flake8.style_guide.StyleGuide`
|
:class:`~flake8.style_guide.StyleGuide`
|
||||||
"""
|
"""
|
||||||
per_file = utils.parse_files_to_codes_mapping(
|
per_file = utils.parse_files_to_codes_mapping(options.per_file_ignores)
|
||||||
options.per_file_ignores
|
|
||||||
)
|
|
||||||
for filename, violations in per_file:
|
for filename, violations in per_file:
|
||||||
yield self.default_style_guide.copy(
|
yield self.default_style_guide.copy(
|
||||||
filename=filename, extend_ignore_with=violations
|
filename=filename, extend_ignore_with=violations
|
||||||
|
|
@ -579,11 +577,7 @@ class StyleGuide:
|
||||||
)
|
)
|
||||||
is_not_inline_ignored = error.is_inline_ignored(disable_noqa) is False
|
is_not_inline_ignored = error.is_inline_ignored(disable_noqa) is False
|
||||||
is_included_in_diff = error.is_in(self._parsed_diff)
|
is_included_in_diff = error.is_in(self._parsed_diff)
|
||||||
if (
|
if error_is_selected and is_not_inline_ignored and is_included_in_diff:
|
||||||
error_is_selected
|
|
||||||
and is_not_inline_ignored
|
|
||||||
and is_included_in_diff
|
|
||||||
):
|
|
||||||
self.formatter.handle(error)
|
self.formatter.handle(error)
|
||||||
self.stats.record(error)
|
self.stats.record(error)
|
||||||
return 1
|
return 1
|
||||||
|
|
|
||||||
|
|
@ -271,13 +271,10 @@ def parse_unified_diff(diff: Optional[str] = None) -> Dict[str, Set[int]]:
|
||||||
# comparing.
|
# comparing.
|
||||||
if hunk_match:
|
if hunk_match:
|
||||||
(row, number_of_rows) = [
|
(row, number_of_rows) = [
|
||||||
1 if not group else int(group)
|
1 if not group else int(group) for group in hunk_match.groups()
|
||||||
for group in hunk_match.groups()
|
|
||||||
]
|
]
|
||||||
assert current_path is not None
|
assert current_path is not None
|
||||||
parsed_paths[current_path].update(
|
parsed_paths[current_path].update(range(row, row + number_of_rows))
|
||||||
range(row, row + number_of_rows)
|
|
||||||
)
|
|
||||||
|
|
||||||
# We have now parsed our diff into a dictionary that looks like:
|
# We have now parsed our diff into a dictionary that looks like:
|
||||||
# {'file.py': set(range(10, 16), range(18, 20)), ...}
|
# {'file.py': set(range(10, 16), range(18, 20)), ...}
|
||||||
|
|
|
||||||
|
|
@ -3,4 +3,4 @@ import sys
|
||||||
|
|
||||||
import flake8
|
import flake8
|
||||||
|
|
||||||
flake8.configure_logging(2, 'test-logs-%s.%s.log' % sys.version_info[0:2])
|
flake8.configure_logging(2, "test-logs-%s.%s.log" % sys.version_info[0:2])
|
||||||
|
|
|
||||||
|
|
@ -4,8 +4,8 @@
|
||||||
class ExtensionTestPlugin2:
|
class ExtensionTestPlugin2:
|
||||||
"""Extension test plugin in its own directory."""
|
"""Extension test plugin in its own directory."""
|
||||||
|
|
||||||
name = 'ExtensionTestPlugin2'
|
name = "ExtensionTestPlugin2"
|
||||||
version = '1.0.0'
|
version = "1.0.0"
|
||||||
|
|
||||||
def __init__(self, tree):
|
def __init__(self, tree):
|
||||||
"""Construct an instance of test plugin."""
|
"""Construct an instance of test plugin."""
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@ from flake8.options import aggregator
|
||||||
from flake8.options import config
|
from flake8.options import config
|
||||||
from flake8.options import manager
|
from flake8.options import manager
|
||||||
|
|
||||||
CLI_SPECIFIED_CONFIG = 'tests/fixtures/config_files/cli-specified.ini'
|
CLI_SPECIFIED_CONFIG = "tests/fixtures/config_files/cli-specified.ini"
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
|
|
@ -18,8 +18,8 @@ def optmanager():
|
||||||
prelim_parser = argparse.ArgumentParser(add_help=False)
|
prelim_parser = argparse.ArgumentParser(add_help=False)
|
||||||
options.register_preliminary_options(prelim_parser)
|
options.register_preliminary_options(prelim_parser)
|
||||||
option_manager = manager.OptionManager(
|
option_manager = manager.OptionManager(
|
||||||
prog='flake8',
|
prog="flake8",
|
||||||
version='3.0.0',
|
version="3.0.0",
|
||||||
parents=[prelim_parser],
|
parents=[prelim_parser],
|
||||||
)
|
)
|
||||||
options.register_default_options(option_manager)
|
options.register_default_options(option_manager)
|
||||||
|
|
@ -28,31 +28,50 @@ def optmanager():
|
||||||
|
|
||||||
def test_aggregate_options_with_config(optmanager):
|
def test_aggregate_options_with_config(optmanager):
|
||||||
"""Verify we aggregate options and config values appropriately."""
|
"""Verify we aggregate options and config values appropriately."""
|
||||||
arguments = ['flake8', '--select',
|
arguments = [
|
||||||
'E11,E34,E402,W,F', '--exclude', 'tests/*']
|
"flake8",
|
||||||
|
"--select",
|
||||||
|
"E11,E34,E402,W,F",
|
||||||
|
"--exclude",
|
||||||
|
"tests/*",
|
||||||
|
]
|
||||||
config_finder = config.ConfigFileFinder(
|
config_finder = config.ConfigFileFinder(
|
||||||
'flake8',
|
"flake8", config_file=CLI_SPECIFIED_CONFIG
|
||||||
config_file=CLI_SPECIFIED_CONFIG)
|
)
|
||||||
options, args = aggregator.aggregate_options(
|
options, args = aggregator.aggregate_options(
|
||||||
optmanager, config_finder, arguments)
|
optmanager, config_finder, arguments
|
||||||
|
)
|
||||||
|
|
||||||
assert options.select == ['E11', 'E34', 'E402', 'W', 'F']
|
assert options.select == ["E11", "E34", "E402", "W", "F"]
|
||||||
assert options.ignore == ['E123', 'W234', 'E111']
|
assert options.ignore == ["E123", "W234", "E111"]
|
||||||
assert options.exclude == [os.path.abspath('tests/*')]
|
assert options.exclude == [os.path.abspath("tests/*")]
|
||||||
|
|
||||||
|
|
||||||
def test_aggregate_options_when_isolated(optmanager):
|
def test_aggregate_options_when_isolated(optmanager):
|
||||||
"""Verify we aggregate options and config values appropriately."""
|
"""Verify we aggregate options and config values appropriately."""
|
||||||
arguments = ['flake8', '--select', 'E11,E34,E402,W,F',
|
arguments = [
|
||||||
'--exclude', 'tests/*']
|
"flake8",
|
||||||
config_finder = config.ConfigFileFinder(
|
"--select",
|
||||||
'flake8', ignore_config_files=True)
|
"E11,E34,E402,W,F",
|
||||||
optmanager.extend_default_ignore(['E8'])
|
"--exclude",
|
||||||
options, args = aggregator.aggregate_options(
|
"tests/*",
|
||||||
optmanager, config_finder, arguments)
|
|
||||||
|
|
||||||
assert options.select == ['E11', 'E34', 'E402', 'W', 'F']
|
|
||||||
assert sorted(options.ignore) == [
|
|
||||||
'E121', 'E123', 'E126', 'E226', 'E24', 'E704', 'E8', 'W503', 'W504',
|
|
||||||
]
|
]
|
||||||
assert options.exclude == [os.path.abspath('tests/*')]
|
config_finder = config.ConfigFileFinder("flake8", ignore_config_files=True)
|
||||||
|
optmanager.extend_default_ignore(["E8"])
|
||||||
|
options, args = aggregator.aggregate_options(
|
||||||
|
optmanager, config_finder, arguments
|
||||||
|
)
|
||||||
|
|
||||||
|
assert options.select == ["E11", "E34", "E402", "W", "F"]
|
||||||
|
assert sorted(options.ignore) == [
|
||||||
|
"E121",
|
||||||
|
"E123",
|
||||||
|
"E126",
|
||||||
|
"E226",
|
||||||
|
"E24",
|
||||||
|
"E704",
|
||||||
|
"E8",
|
||||||
|
"W503",
|
||||||
|
"W504",
|
||||||
|
]
|
||||||
|
assert options.exclude == [os.path.abspath("tests/*")]
|
||||||
|
|
|
||||||
|
|
@ -5,8 +5,8 @@ from flake8.api import legacy
|
||||||
def test_legacy_api(tmpdir):
|
def test_legacy_api(tmpdir):
|
||||||
"""A basic end-to-end test for the legacy api reporting errors."""
|
"""A basic end-to-end test for the legacy api reporting errors."""
|
||||||
with tmpdir.as_cwd():
|
with tmpdir.as_cwd():
|
||||||
t_py = tmpdir.join('t.py')
|
t_py = tmpdir.join("t.py")
|
||||||
t_py.write('import os # unused import\n')
|
t_py.write("import os # unused import\n")
|
||||||
|
|
||||||
style_guide = legacy.get_style_guide()
|
style_guide = legacy.get_style_guide()
|
||||||
report = style_guide.check_files([t_py.strpath])
|
report = style_guide.check_files([t_py.strpath])
|
||||||
|
|
|
||||||
|
|
@ -10,13 +10,13 @@ from flake8.processor import FileProcessor
|
||||||
|
|
||||||
PHYSICAL_LINE = "# Physical line content"
|
PHYSICAL_LINE = "# Physical line content"
|
||||||
|
|
||||||
EXPECTED_REPORT = (1, 1, 'T000 Expected Message')
|
EXPECTED_REPORT = (1, 1, "T000 Expected Message")
|
||||||
EXPECTED_REPORT_PHYSICAL_LINE = (1, 'T000 Expected Message')
|
EXPECTED_REPORT_PHYSICAL_LINE = (1, "T000 Expected Message")
|
||||||
EXPECTED_RESULT_PHYSICAL_LINE = (
|
EXPECTED_RESULT_PHYSICAL_LINE = (
|
||||||
'T000',
|
"T000",
|
||||||
0,
|
0,
|
||||||
1,
|
1,
|
||||||
'Expected Message',
|
"Expected Message",
|
||||||
None,
|
None,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -24,8 +24,8 @@ EXPECTED_RESULT_PHYSICAL_LINE = (
|
||||||
class PluginClass:
|
class PluginClass:
|
||||||
"""Simple file plugin class yielding the expected report."""
|
"""Simple file plugin class yielding the expected report."""
|
||||||
|
|
||||||
name = 'test'
|
name = "test"
|
||||||
version = '1.0.0'
|
version = "1.0.0"
|
||||||
|
|
||||||
def __init__(self, tree):
|
def __init__(self, tree):
|
||||||
"""Construct a dummy object to provide mandatory parameter."""
|
"""Construct a dummy object to provide mandatory parameter."""
|
||||||
|
|
@ -33,26 +33,26 @@ class PluginClass:
|
||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
"""Run class yielding one element containing the expected report."""
|
"""Run class yielding one element containing the expected report."""
|
||||||
yield EXPECTED_REPORT + (type(self), )
|
yield EXPECTED_REPORT + (type(self),)
|
||||||
|
|
||||||
|
|
||||||
def plugin_func(func):
|
def plugin_func(func):
|
||||||
"""Decorate file plugins which are implemented as functions."""
|
"""Decorate file plugins which are implemented as functions."""
|
||||||
func.name = 'test'
|
func.name = "test"
|
||||||
func.version = '1.0.0'
|
func.version = "1.0.0"
|
||||||
return func
|
return func
|
||||||
|
|
||||||
|
|
||||||
@plugin_func
|
@plugin_func
|
||||||
def plugin_func_gen(tree):
|
def plugin_func_gen(tree):
|
||||||
"""Yield the expected report."""
|
"""Yield the expected report."""
|
||||||
yield EXPECTED_REPORT + (type(plugin_func_gen), )
|
yield EXPECTED_REPORT + (type(plugin_func_gen),)
|
||||||
|
|
||||||
|
|
||||||
@plugin_func
|
@plugin_func
|
||||||
def plugin_func_list(tree):
|
def plugin_func_list(tree):
|
||||||
"""Return a list of expected reports."""
|
"""Return a list of expected reports."""
|
||||||
return [EXPECTED_REPORT + (type(plugin_func_list), )]
|
return [EXPECTED_REPORT + (type(plugin_func_list),)]
|
||||||
|
|
||||||
|
|
||||||
@plugin_func
|
@plugin_func
|
||||||
|
|
@ -98,35 +98,37 @@ def mock_file_checker_with_plugin(plugin_target):
|
||||||
Useful as a starting point for mocking reports/results.
|
Useful as a starting point for mocking reports/results.
|
||||||
"""
|
"""
|
||||||
# Mock an entry point returning the plugin target
|
# Mock an entry point returning the plugin target
|
||||||
entry_point = mock.Mock(spec=['load'])
|
entry_point = mock.Mock(spec=["load"])
|
||||||
entry_point.name = plugin_target.name
|
entry_point.name = plugin_target.name
|
||||||
entry_point.load.return_value = plugin_target
|
entry_point.load.return_value = plugin_target
|
||||||
entry_point.value = 'mocked:value'
|
entry_point.value = "mocked:value"
|
||||||
|
|
||||||
# Load the checker plugins using the entry point mock
|
# Load the checker plugins using the entry point mock
|
||||||
with mock.patch.object(
|
with mock.patch.object(
|
||||||
importlib_metadata,
|
importlib_metadata,
|
||||||
'entry_points',
|
"entry_points",
|
||||||
return_value={'flake8.extension': [entry_point]},
|
return_value={"flake8.extension": [entry_point]},
|
||||||
):
|
):
|
||||||
checks = manager.Checkers()
|
checks = manager.Checkers()
|
||||||
|
|
||||||
# Prevent it from reading lines from stdin or somewhere else
|
# Prevent it from reading lines from stdin or somewhere else
|
||||||
with mock.patch('flake8.processor.FileProcessor.read_lines',
|
with mock.patch(
|
||||||
return_value=['Line 1']):
|
"flake8.processor.FileProcessor.read_lines", return_value=["Line 1"]
|
||||||
|
):
|
||||||
file_checker = checker.FileChecker(
|
file_checker = checker.FileChecker(
|
||||||
'-',
|
"-", checks.to_dictionary(), mock.MagicMock()
|
||||||
checks.to_dictionary(),
|
|
||||||
mock.MagicMock()
|
|
||||||
)
|
)
|
||||||
return file_checker
|
return file_checker
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize('plugin_target', [
|
@pytest.mark.parametrize(
|
||||||
PluginClass,
|
"plugin_target",
|
||||||
plugin_func_gen,
|
[
|
||||||
plugin_func_list,
|
PluginClass,
|
||||||
])
|
plugin_func_gen,
|
||||||
|
plugin_func_list,
|
||||||
|
],
|
||||||
|
)
|
||||||
def test_handle_file_plugins(plugin_target):
|
def test_handle_file_plugins(plugin_target):
|
||||||
"""Test the FileChecker class handling different file plugin types."""
|
"""Test the FileChecker class handling different file plugin types."""
|
||||||
file_checker = mock_file_checker_with_plugin(plugin_target)
|
file_checker = mock_file_checker_with_plugin(plugin_target)
|
||||||
|
|
@ -138,20 +140,25 @@ def test_handle_file_plugins(plugin_target):
|
||||||
report = mock.Mock()
|
report = mock.Mock()
|
||||||
file_checker.report = report
|
file_checker.report = report
|
||||||
file_checker.run_ast_checks()
|
file_checker.run_ast_checks()
|
||||||
report.assert_called_once_with(error_code=None,
|
report.assert_called_once_with(
|
||||||
line_number=EXPECTED_REPORT[0],
|
error_code=None,
|
||||||
column=EXPECTED_REPORT[1],
|
line_number=EXPECTED_REPORT[0],
|
||||||
text=EXPECTED_REPORT[2])
|
column=EXPECTED_REPORT[1],
|
||||||
|
text=EXPECTED_REPORT[2],
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize('plugin_target,len_results', [
|
@pytest.mark.parametrize(
|
||||||
(plugin_func_physical_ret, 1),
|
"plugin_target,len_results",
|
||||||
(plugin_func_physical_none, 0),
|
[
|
||||||
(plugin_func_physical_list_single, 1),
|
(plugin_func_physical_ret, 1),
|
||||||
(plugin_func_physical_list_multiple, 2),
|
(plugin_func_physical_none, 0),
|
||||||
(plugin_func_physical_gen_single, 1),
|
(plugin_func_physical_list_single, 1),
|
||||||
(plugin_func_physical_gen_multiple, 3),
|
(plugin_func_physical_list_multiple, 2),
|
||||||
])
|
(plugin_func_physical_gen_single, 1),
|
||||||
|
(plugin_func_physical_gen_multiple, 3),
|
||||||
|
],
|
||||||
|
)
|
||||||
def test_line_check_results(plugin_target, len_results):
|
def test_line_check_results(plugin_target, len_results):
|
||||||
"""Test the FileChecker class handling results from line checks."""
|
"""Test the FileChecker class handling results from line checks."""
|
||||||
file_checker = mock_file_checker_with_plugin(plugin_target)
|
file_checker = mock_file_checker_with_plugin(plugin_target)
|
||||||
|
|
@ -167,54 +174,100 @@ def test_logical_line_offset_out_of_bounds():
|
||||||
|
|
||||||
@plugin_func
|
@plugin_func
|
||||||
def _logical_line_out_of_bounds(logical_line):
|
def _logical_line_out_of_bounds(logical_line):
|
||||||
yield 10000, 'L100 test'
|
yield 10000, "L100 test"
|
||||||
|
|
||||||
file_checker = mock_file_checker_with_plugin(_logical_line_out_of_bounds)
|
file_checker = mock_file_checker_with_plugin(_logical_line_out_of_bounds)
|
||||||
|
|
||||||
logical_ret = (
|
logical_ret = (
|
||||||
'',
|
"",
|
||||||
'print("xxxxxxxxxxx")',
|
'print("xxxxxxxxxxx")',
|
||||||
[(0, (1, 0)), (5, (1, 5)), (6, (1, 6)), (19, (1, 19)), (20, (1, 20))],
|
[(0, (1, 0)), (5, (1, 5)), (6, (1, 6)), (19, (1, 19)), (20, (1, 20))],
|
||||||
)
|
)
|
||||||
with mock.patch.object(
|
with mock.patch.object(
|
||||||
FileProcessor, 'build_logical_line', return_value=logical_ret,
|
FileProcessor,
|
||||||
|
"build_logical_line",
|
||||||
|
return_value=logical_ret,
|
||||||
):
|
):
|
||||||
file_checker.run_logical_checks()
|
file_checker.run_logical_checks()
|
||||||
assert file_checker.results == [('L100', 0, 0, 'test', None)]
|
assert file_checker.results == [("L100", 0, 0, "test", None)]
|
||||||
|
|
||||||
|
|
||||||
PLACEHOLDER_CODE = 'some_line = "of" * code'
|
PLACEHOLDER_CODE = 'some_line = "of" * code'
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize('results, expected_order', [
|
@pytest.mark.parametrize(
|
||||||
# No entries should be added
|
"results, expected_order",
|
||||||
([], []),
|
[
|
||||||
# Results are correctly ordered
|
# No entries should be added
|
||||||
([('A101', 1, 1, 'placeholder error', PLACEHOLDER_CODE),
|
([], []),
|
||||||
('A101', 2, 1, 'placeholder error', PLACEHOLDER_CODE)], [0, 1]),
|
# Results are correctly ordered
|
||||||
# Reversed order of lines
|
(
|
||||||
([('A101', 2, 1, 'placeholder error', PLACEHOLDER_CODE),
|
[
|
||||||
('A101', 1, 1, 'placeholder error', PLACEHOLDER_CODE)], [1, 0]),
|
("A101", 1, 1, "placeholder error", PLACEHOLDER_CODE),
|
||||||
# Columns are not ordered correctly (when reports are ordered correctly)
|
("A101", 2, 1, "placeholder error", PLACEHOLDER_CODE),
|
||||||
([('A101', 1, 2, 'placeholder error', PLACEHOLDER_CODE),
|
],
|
||||||
('A101', 1, 1, 'placeholder error', PLACEHOLDER_CODE),
|
[0, 1],
|
||||||
('A101', 2, 1, 'placeholder error', PLACEHOLDER_CODE)], [1, 0, 2]),
|
),
|
||||||
([('A101', 2, 1, 'placeholder error', PLACEHOLDER_CODE),
|
# Reversed order of lines
|
||||||
('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, 1, "placeholder error", PLACEHOLDER_CODE),
|
||||||
('A101', 2, 2, 'placeholder error', PLACEHOLDER_CODE),
|
("A101", 1, 1, "placeholder error", PLACEHOLDER_CODE),
|
||||||
('A101', 2, 1, 'placeholder error', PLACEHOLDER_CODE)], [0, 2, 1]),
|
],
|
||||||
([('A101', 1, 3, 'placeholder error', PLACEHOLDER_CODE),
|
[1, 0],
|
||||||
('A101', 2, 2, 'placeholder error', PLACEHOLDER_CODE),
|
),
|
||||||
('A101', 3, 1, 'placeholder error', PLACEHOLDER_CODE)], [0, 1, 2]),
|
# Columns are not ordered correctly
|
||||||
([('A101', 1, 1, 'placeholder error', PLACEHOLDER_CODE),
|
# (when reports are ordered correctly)
|
||||||
('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, 2, "placeholder error", PLACEHOLDER_CODE),
|
||||||
([('A101', 1, 1, 'placeholder error', PLACEHOLDER_CODE),
|
("A101", 1, 1, "placeholder error", PLACEHOLDER_CODE),
|
||||||
('A101', 2, 1, 'charlie error', PLACEHOLDER_CODE)], [0, 1]),
|
("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):
|
def test_report_order(results, expected_order):
|
||||||
"""
|
"""
|
||||||
Test in which order the results will be reported.
|
Test in which order the results will be reported.
|
||||||
|
|
@ -222,6 +275,7 @@ def test_report_order(results, expected_order):
|
||||||
It gets a list of reports from the file checkers and verifies that the
|
It gets a list of reports from the file checkers and verifies that the
|
||||||
result will be ordered independent from the original report.
|
result will be ordered independent from the original report.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def count_side_effect(name, sorted_results):
|
def count_side_effect(name, sorted_results):
|
||||||
"""Side effect for the result handler to tell all are reported."""
|
"""Side effect for the result handler to tell all are reported."""
|
||||||
return len(sorted_results)
|
return len(sorted_results)
|
||||||
|
|
@ -230,11 +284,11 @@ def test_report_order(results, expected_order):
|
||||||
# tuples to create the expected result lists from the indexes
|
# tuples to create the expected result lists from the indexes
|
||||||
expected_results = [results[index] for index in expected_order]
|
expected_results = [results[index] for index in expected_order]
|
||||||
|
|
||||||
file_checker = mock.Mock(spec=['results', 'display_name'])
|
file_checker = mock.Mock(spec=["results", "display_name"])
|
||||||
file_checker.results = results
|
file_checker.results = results
|
||||||
file_checker.display_name = 'placeholder'
|
file_checker.display_name = "placeholder"
|
||||||
|
|
||||||
style_guide = mock.MagicMock(spec=['options', 'processing_file'])
|
style_guide = mock.MagicMock(spec=["options", "processing_file"])
|
||||||
|
|
||||||
# Create a placeholder manager without arguments or plugins
|
# Create a placeholder manager without arguments or plugins
|
||||||
# Just add one custom file checker which just provides the results
|
# Just add one custom file checker which just provides the results
|
||||||
|
|
@ -244,9 +298,9 @@ def test_report_order(results, expected_order):
|
||||||
# _handle_results is the first place which gets the sorted result
|
# _handle_results is the first place which gets the sorted result
|
||||||
# Should something non-private be mocked instead?
|
# Should something non-private be mocked instead?
|
||||||
handler = mock.Mock(side_effect=count_side_effect)
|
handler = mock.Mock(side_effect=count_side_effect)
|
||||||
with mock.patch.object(manager, '_handle_results', handler):
|
with mock.patch.object(manager, "_handle_results", handler):
|
||||||
assert manager.report() == (len(results), len(results))
|
assert manager.report() == (len(results), len(results))
|
||||||
handler.assert_called_once_with('placeholder', expected_results)
|
handler.assert_called_once_with("placeholder", expected_results)
|
||||||
|
|
||||||
|
|
||||||
def test_acquire_when_multiprocessing_pool_can_initialize():
|
def test_acquire_when_multiprocessing_pool_can_initialize():
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@ def _call_main(argv, retv=0):
|
||||||
|
|
||||||
def test_diff_option(tmpdir, capsys):
|
def test_diff_option(tmpdir, capsys):
|
||||||
"""Ensure that `flake8 --diff` works."""
|
"""Ensure that `flake8 --diff` works."""
|
||||||
t_py_contents = '''\
|
t_py_contents = """\
|
||||||
import os
|
import os
|
||||||
import sys # unused but not part of diff
|
import sys # unused but not part of diff
|
||||||
|
|
||||||
|
|
@ -26,9 +26,9 @@ print('(to avoid trailing whitespace in test)')
|
||||||
print(os.path.join('foo', 'bar'))
|
print(os.path.join('foo', 'bar'))
|
||||||
|
|
||||||
y # part of the diff and an error
|
y # part of the diff and an error
|
||||||
'''
|
"""
|
||||||
|
|
||||||
diff = '''\
|
diff = """\
|
||||||
diff --git a/t.py b/t.py
|
diff --git a/t.py b/t.py
|
||||||
index d64ac39..7d943de 100644
|
index d64ac39..7d943de 100644
|
||||||
--- a/t.py
|
--- a/t.py
|
||||||
|
|
@ -39,39 +39,39 @@ index d64ac39..7d943de 100644
|
||||||
print(os.path.join('foo', 'bar'))
|
print(os.path.join('foo', 'bar'))
|
||||||
+
|
+
|
||||||
+y # part of the diff and an error
|
+y # part of the diff and an error
|
||||||
'''
|
"""
|
||||||
|
|
||||||
with mock.patch.object(utils, 'stdin_get_value', return_value=diff):
|
with mock.patch.object(utils, "stdin_get_value", return_value=diff):
|
||||||
with tmpdir.as_cwd():
|
with tmpdir.as_cwd():
|
||||||
tmpdir.join('t.py').write(t_py_contents)
|
tmpdir.join("t.py").write(t_py_contents)
|
||||||
_call_main(['--diff'], retv=1)
|
_call_main(["--diff"], retv=1)
|
||||||
|
|
||||||
out, err = capsys.readouterr()
|
out, err = capsys.readouterr()
|
||||||
assert out == "t.py:8:1: F821 undefined name 'y'\n"
|
assert out == "t.py:8:1: F821 undefined name 'y'\n"
|
||||||
assert err == ''
|
assert err == ""
|
||||||
|
|
||||||
|
|
||||||
def test_form_feed_line_split(tmpdir, capsys):
|
def test_form_feed_line_split(tmpdir, capsys):
|
||||||
"""Test that form feed is treated the same for stdin."""
|
"""Test that form feed is treated the same for stdin."""
|
||||||
src = 'x=1\n\f\ny=1\n'
|
src = "x=1\n\f\ny=1\n"
|
||||||
expected_out = '''\
|
expected_out = """\
|
||||||
t.py:1:2: E225 missing whitespace around operator
|
t.py:1:2: E225 missing whitespace around operator
|
||||||
t.py:3:2: E225 missing whitespace around operator
|
t.py:3:2: E225 missing whitespace around operator
|
||||||
'''
|
"""
|
||||||
|
|
||||||
with tmpdir.as_cwd():
|
with tmpdir.as_cwd():
|
||||||
tmpdir.join('t.py').write(src)
|
tmpdir.join("t.py").write(src)
|
||||||
|
|
||||||
with mock.patch.object(utils, 'stdin_get_value', return_value=src):
|
with mock.patch.object(utils, "stdin_get_value", return_value=src):
|
||||||
_call_main(['-', '--stdin-display-name=t.py'], retv=1)
|
_call_main(["-", "--stdin-display-name=t.py"], retv=1)
|
||||||
out, err = capsys.readouterr()
|
out, err = capsys.readouterr()
|
||||||
assert out == expected_out
|
assert out == expected_out
|
||||||
assert err == ''
|
assert err == ""
|
||||||
|
|
||||||
_call_main(['t.py'], retv=1)
|
_call_main(["t.py"], retv=1)
|
||||||
out, err = capsys.readouterr()
|
out, err = capsys.readouterr()
|
||||||
assert out == expected_out
|
assert out == expected_out
|
||||||
assert err == ''
|
assert err == ""
|
||||||
|
|
||||||
|
|
||||||
def test_e101_indent_char_does_not_reset(tmpdir, capsys):
|
def test_e101_indent_char_does_not_reset(tmpdir, capsys):
|
||||||
|
|
@ -89,82 +89,79 @@ if True:
|
||||||
"""
|
"""
|
||||||
|
|
||||||
with tmpdir.as_cwd():
|
with tmpdir.as_cwd():
|
||||||
tmpdir.join('t.py').write(t_py_contents)
|
tmpdir.join("t.py").write(t_py_contents)
|
||||||
_call_main(['t.py'])
|
_call_main(["t.py"])
|
||||||
|
|
||||||
|
|
||||||
def test_statistics_option(tmpdir, capsys):
|
def test_statistics_option(tmpdir, capsys):
|
||||||
"""Ensure that `flake8 --statistics` works."""
|
"""Ensure that `flake8 --statistics` works."""
|
||||||
with tmpdir.as_cwd():
|
with tmpdir.as_cwd():
|
||||||
tmpdir.join('t.py').write('import os\nimport sys\n')
|
tmpdir.join("t.py").write("import os\nimport sys\n")
|
||||||
_call_main(['--statistics', 't.py'], retv=1)
|
_call_main(["--statistics", "t.py"], retv=1)
|
||||||
|
|
||||||
out, err = capsys.readouterr()
|
expected = """\
|
||||||
assert out == '''\
|
|
||||||
t.py:1:1: F401 'os' imported but unused
|
t.py:1:1: F401 'os' imported but unused
|
||||||
t.py:2:1: F401 'sys' imported but unused
|
t.py:2:1: F401 'sys' imported but unused
|
||||||
2 F401 'os' imported but unused
|
2 F401 'os' imported but unused
|
||||||
'''
|
"""
|
||||||
assert err == ''
|
out, err = capsys.readouterr()
|
||||||
|
assert out == expected
|
||||||
|
assert err == ""
|
||||||
|
|
||||||
|
|
||||||
def test_show_source_option(tmpdir, capsys):
|
def test_show_source_option(tmpdir, capsys):
|
||||||
"""Ensure that --show-source and --no-show-source work."""
|
"""Ensure that --show-source and --no-show-source work."""
|
||||||
with tmpdir.as_cwd():
|
with tmpdir.as_cwd():
|
||||||
tmpdir.join('tox.ini').write('[flake8]\nshow_source = true\n')
|
tmpdir.join("tox.ini").write("[flake8]\nshow_source = true\n")
|
||||||
tmpdir.join('t.py').write('import os\n')
|
tmpdir.join("t.py").write("import os\n")
|
||||||
_call_main(['t.py'], retv=1)
|
_call_main(["t.py"], retv=1)
|
||||||
|
|
||||||
out, err = capsys.readouterr()
|
expected = """\
|
||||||
assert out == '''\
|
|
||||||
t.py:1:1: F401 'os' imported but unused
|
t.py:1:1: F401 'os' imported but unused
|
||||||
import os
|
import os
|
||||||
^
|
^
|
||||||
'''
|
"""
|
||||||
assert err == ''
|
out, err = capsys.readouterr()
|
||||||
|
assert out == expected
|
||||||
|
assert err == ""
|
||||||
|
|
||||||
with tmpdir.as_cwd():
|
with tmpdir.as_cwd():
|
||||||
_call_main(['t.py', '--no-show-source'], retv=1)
|
_call_main(["t.py", "--no-show-source"], retv=1)
|
||||||
|
|
||||||
out, err = capsys.readouterr()
|
expected = """\
|
||||||
assert out == '''\
|
|
||||||
t.py:1:1: F401 'os' imported but unused
|
t.py:1:1: F401 'os' imported but unused
|
||||||
'''
|
"""
|
||||||
assert err == ''
|
out, err = capsys.readouterr()
|
||||||
|
assert out == expected
|
||||||
|
assert err == ""
|
||||||
|
|
||||||
|
|
||||||
def test_extend_exclude(tmpdir, capsys):
|
def test_extend_exclude(tmpdir, capsys):
|
||||||
"""Ensure that `flake8 --extend-exclude` works."""
|
"""Ensure that `flake8 --extend-exclude` works."""
|
||||||
for d in ['project', 'vendor', 'legacy', '.git', '.tox', '.hg']:
|
for d in ["project", "vendor", "legacy", ".git", ".tox", ".hg"]:
|
||||||
tmpdir.mkdir(d).join('t.py').write('import os\nimport sys\n')
|
tmpdir.mkdir(d).join("t.py").write("import os\nimport sys\n")
|
||||||
|
|
||||||
with tmpdir.as_cwd():
|
with tmpdir.as_cwd():
|
||||||
_call_main(['--extend-exclude=vendor,legacy/'], retv=1)
|
_call_main(["--extend-exclude=vendor,legacy/"], retv=1)
|
||||||
|
|
||||||
out, err = capsys.readouterr()
|
out, err = capsys.readouterr()
|
||||||
expected_out = '''\
|
expected_out = """\
|
||||||
./project/t.py:1:1: F401 'os' imported but unused
|
./project/t.py:1:1: F401 'os' imported but unused
|
||||||
./project/t.py:2:1: F401 'sys' imported but unused
|
./project/t.py:2:1: F401 'sys' imported but unused
|
||||||
'''
|
"""
|
||||||
assert out == expected_out.replace('/', os.sep)
|
assert out == expected_out.replace("/", os.sep)
|
||||||
assert err == ''
|
assert err == ""
|
||||||
|
|
||||||
|
|
||||||
def test_malformed_per_file_ignores_error(tmpdir, capsys):
|
def test_malformed_per_file_ignores_error(tmpdir, capsys):
|
||||||
"""Test the error message for malformed `per-file-ignores`."""
|
"""Test the error message for malformed `per-file-ignores`."""
|
||||||
setup_cfg = '''\
|
setup_cfg = """\
|
||||||
[flake8]
|
[flake8]
|
||||||
per-file-ignores =
|
per-file-ignores =
|
||||||
incorrect/*
|
incorrect/*
|
||||||
values/*
|
values/*
|
||||||
'''
|
"""
|
||||||
|
expected = """\
|
||||||
with tmpdir.as_cwd():
|
|
||||||
tmpdir.join('setup.cfg').write(setup_cfg)
|
|
||||||
_call_main(['.'], retv=1)
|
|
||||||
|
|
||||||
out, err = capsys.readouterr()
|
|
||||||
assert out == '''\
|
|
||||||
There was a critical error during execution of Flake8:
|
There was a critical error during execution of Flake8:
|
||||||
Expected `per-file-ignores` to be a mapping from file exclude patterns to ignore codes.
|
Expected `per-file-ignores` to be a mapping from file exclude patterns to ignore codes.
|
||||||
|
|
||||||
|
|
@ -172,50 +169,59 @@ Configured `per-file-ignores` setting:
|
||||||
|
|
||||||
incorrect/*
|
incorrect/*
|
||||||
values/*
|
values/*
|
||||||
''' # noqa: E501
|
""" # noqa: E501
|
||||||
|
|
||||||
|
with tmpdir.as_cwd():
|
||||||
|
tmpdir.join("setup.cfg").write(setup_cfg)
|
||||||
|
_call_main(["."], retv=1)
|
||||||
|
|
||||||
|
out, err = capsys.readouterr()
|
||||||
|
assert out == expected
|
||||||
|
|
||||||
|
|
||||||
def test_tokenization_error_but_not_syntax_error(tmpdir, capsys):
|
def test_tokenization_error_but_not_syntax_error(tmpdir, capsys):
|
||||||
"""Test that flake8 does not crash on tokenization errors."""
|
"""Test that flake8 does not crash on tokenization errors."""
|
||||||
with tmpdir.as_cwd():
|
with tmpdir.as_cwd():
|
||||||
# this is a crash in the tokenizer, but not in the ast
|
# this is a crash in the tokenizer, but not in the ast
|
||||||
tmpdir.join('t.py').write("b'foo' \\\n")
|
tmpdir.join("t.py").write("b'foo' \\\n")
|
||||||
_call_main(['t.py'], retv=1)
|
_call_main(["t.py"], retv=1)
|
||||||
|
|
||||||
out, err = capsys.readouterr()
|
out, err = capsys.readouterr()
|
||||||
assert out == 't.py:1:1: E902 TokenError: EOF in multi-line statement\n'
|
assert out == "t.py:1:1: E902 TokenError: EOF in multi-line statement\n"
|
||||||
assert err == ''
|
assert err == ""
|
||||||
|
|
||||||
|
|
||||||
def test_tokenization_error_is_a_syntax_error(tmpdir, capsys):
|
def test_tokenization_error_is_a_syntax_error(tmpdir, capsys):
|
||||||
"""Test when tokenize raises a SyntaxError."""
|
"""Test when tokenize raises a SyntaxError."""
|
||||||
with tmpdir.as_cwd():
|
with tmpdir.as_cwd():
|
||||||
tmpdir.join('t.py').write('if True:\n pass\n pass\n')
|
tmpdir.join("t.py").write("if True:\n pass\n pass\n")
|
||||||
_call_main(['t.py'], retv=1)
|
_call_main(["t.py"], retv=1)
|
||||||
|
|
||||||
out, err = capsys.readouterr()
|
out, err = capsys.readouterr()
|
||||||
assert out == 't.py:1:1: E902 IndentationError: unindent does not match any outer indentation level\n' # noqa: E501
|
expected = "t.py:1:1: E902 IndentationError: unindent does not match any outer indentation level\n" # noqa: E501
|
||||||
assert err == ''
|
assert out == expected
|
||||||
|
assert err == ""
|
||||||
|
|
||||||
|
|
||||||
def test_bug_report_successful(capsys):
|
def test_bug_report_successful(capsys):
|
||||||
"""Test that --bug-report does not crash."""
|
"""Test that --bug-report does not crash."""
|
||||||
_call_main(['--bug-report'])
|
_call_main(["--bug-report"])
|
||||||
out, err = capsys.readouterr()
|
out, err = capsys.readouterr()
|
||||||
assert json.loads(out)
|
assert json.loads(out)
|
||||||
assert err == ''
|
assert err == ""
|
||||||
|
|
||||||
|
|
||||||
def test_specific_noqa_does_not_clobber_pycodestyle_noqa(tmpdir, capsys):
|
def test_specific_noqa_does_not_clobber_pycodestyle_noqa(tmpdir, capsys):
|
||||||
"""See https://github.com/pycqa/flake8/issues/1104."""
|
"""See https://github.com/pycqa/flake8/issues/1104."""
|
||||||
with tmpdir.as_cwd():
|
with tmpdir.as_cwd():
|
||||||
tmpdir.join('t.py').write("test = ('ABC' == None) # noqa: E501\n")
|
tmpdir.join("t.py").write("test = ('ABC' == None) # noqa: E501\n")
|
||||||
_call_main(['t.py'], retv=1)
|
_call_main(["t.py"], retv=1)
|
||||||
|
|
||||||
out, err = capsys.readouterr()
|
expected = """\
|
||||||
assert out == '''\
|
|
||||||
t.py:1:15: E711 comparison to None should be 'if cond is None:'
|
t.py:1:15: E711 comparison to None should be 'if cond is None:'
|
||||||
'''
|
"""
|
||||||
|
out, err = capsys.readouterr()
|
||||||
|
assert out == expected
|
||||||
|
|
||||||
|
|
||||||
def test_specific_noqa_on_line_with_continuation(tmpdir, capsys):
|
def test_specific_noqa_on_line_with_continuation(tmpdir, capsys):
|
||||||
|
|
@ -230,60 +236,64 @@ x = """
|
||||||
'''
|
'''
|
||||||
|
|
||||||
with tmpdir.as_cwd():
|
with tmpdir.as_cwd():
|
||||||
tmpdir.join('t.py').write(t_py_src)
|
tmpdir.join("t.py").write(t_py_src)
|
||||||
_call_main(['t.py'], retv=0)
|
_call_main(["t.py"], retv=0)
|
||||||
|
|
||||||
out, err = capsys.readouterr()
|
out, err = capsys.readouterr()
|
||||||
assert out == err == ''
|
assert out == err == ""
|
||||||
|
|
||||||
|
|
||||||
def test_physical_line_file_not_ending_in_newline(tmpdir, capsys):
|
def test_physical_line_file_not_ending_in_newline(tmpdir, capsys):
|
||||||
"""See https://github.com/PyCQA/pycodestyle/issues/960."""
|
"""See https://github.com/PyCQA/pycodestyle/issues/960."""
|
||||||
t_py_src = 'def f():\n\tpass'
|
t_py_src = "def f():\n\tpass"
|
||||||
|
|
||||||
with tmpdir.as_cwd():
|
with tmpdir.as_cwd():
|
||||||
tmpdir.join('t.py').write(t_py_src)
|
tmpdir.join("t.py").write(t_py_src)
|
||||||
_call_main(['t.py'], retv=1)
|
_call_main(["t.py"], retv=1)
|
||||||
|
|
||||||
out, err = capsys.readouterr()
|
expected = """\
|
||||||
assert out == '''\
|
|
||||||
t.py:2:1: W191 indentation contains tabs
|
t.py:2:1: W191 indentation contains tabs
|
||||||
t.py:2:6: W292 no newline at end of file
|
t.py:2:6: W292 no newline at end of file
|
||||||
'''
|
"""
|
||||||
|
out, err = capsys.readouterr()
|
||||||
|
assert out == expected
|
||||||
|
|
||||||
|
|
||||||
def test_physical_line_file_not_ending_in_newline_trailing_ws(tmpdir, capsys):
|
def test_physical_line_file_not_ending_in_newline_trailing_ws(tmpdir, capsys):
|
||||||
"""See https://github.com/PyCQA/pycodestyle/issues/960."""
|
"""See https://github.com/PyCQA/pycodestyle/issues/960."""
|
||||||
t_py_src = 'x = 1 '
|
t_py_src = "x = 1 "
|
||||||
|
|
||||||
with tmpdir.as_cwd():
|
with tmpdir.as_cwd():
|
||||||
tmpdir.join('t.py').write(t_py_src)
|
tmpdir.join("t.py").write(t_py_src)
|
||||||
_call_main(['t.py'], retv=1)
|
_call_main(["t.py"], retv=1)
|
||||||
|
|
||||||
out, err = capsys.readouterr()
|
expected = """\
|
||||||
assert out == '''\
|
|
||||||
t.py:1:6: W291 trailing whitespace
|
t.py:1:6: W291 trailing whitespace
|
||||||
t.py:1:9: W292 no newline at end of file
|
t.py:1:9: W292 no newline at end of file
|
||||||
'''
|
"""
|
||||||
|
out, err = capsys.readouterr()
|
||||||
|
assert out == expected
|
||||||
|
|
||||||
|
|
||||||
def test_obtaining_args_from_sys_argv_when_not_explicity_provided(capsys):
|
def test_obtaining_args_from_sys_argv_when_not_explicity_provided(capsys):
|
||||||
"""Test that arguments are obtained from 'sys.argv'."""
|
"""Test that arguments are obtained from 'sys.argv'."""
|
||||||
with mock.patch('sys.argv', ['flake8', '--help']):
|
with mock.patch("sys.argv", ["flake8", "--help"]):
|
||||||
_call_main(None)
|
_call_main(None)
|
||||||
|
|
||||||
out, err = capsys.readouterr()
|
out, err = capsys.readouterr()
|
||||||
assert out.startswith('usage: flake8 [options] file file ...\n')
|
assert out.startswith("usage: flake8 [options] file file ...\n")
|
||||||
assert err == ''
|
assert err == ""
|
||||||
|
|
||||||
|
|
||||||
def test_cli_config_option_respected(tmp_path):
|
def test_cli_config_option_respected(tmp_path):
|
||||||
"""Test --config is used."""
|
"""Test --config is used."""
|
||||||
config = tmp_path / "flake8.ini"
|
config = tmp_path / "flake8.ini"
|
||||||
config.write_text("""\
|
config.write_text(
|
||||||
|
"""\
|
||||||
[flake8]
|
[flake8]
|
||||||
ignore = F401
|
ignore = F401
|
||||||
""")
|
"""
|
||||||
|
)
|
||||||
|
|
||||||
py_file = tmp_path / "t.py"
|
py_file = tmp_path / "t.py"
|
||||||
py_file.write_text("import os\n")
|
py_file.write_text("import os\n")
|
||||||
|
|
@ -294,10 +304,12 @@ ignore = F401
|
||||||
def test_cli_isolated_overrides_config_option(tmp_path):
|
def test_cli_isolated_overrides_config_option(tmp_path):
|
||||||
"""Test --isolated overrides --config."""
|
"""Test --isolated overrides --config."""
|
||||||
config = tmp_path / "flake8.ini"
|
config = tmp_path / "flake8.ini"
|
||||||
config.write_text("""\
|
config.write_text(
|
||||||
|
"""\
|
||||||
[flake8]
|
[flake8]
|
||||||
ignore = F401
|
ignore = F401
|
||||||
""")
|
"""
|
||||||
|
)
|
||||||
|
|
||||||
py_file = tmp_path / "t.py"
|
py_file = tmp_path / "t.py"
|
||||||
py_file.write_text("import os\n")
|
py_file.write_text("import os\n")
|
||||||
|
|
@ -316,13 +328,13 @@ def test_file_not_found(tmpdir, capsys):
|
||||||
|
|
||||||
def test_output_file(tmpdir, capsys):
|
def test_output_file(tmpdir, capsys):
|
||||||
"""Ensure that --output-file is honored."""
|
"""Ensure that --output-file is honored."""
|
||||||
tmpdir.join('t.py').write('import os\n')
|
tmpdir.join("t.py").write("import os\n")
|
||||||
|
|
||||||
with tmpdir.as_cwd():
|
with tmpdir.as_cwd():
|
||||||
_call_main(['t.py', '--output-file=f'], retv=1)
|
_call_main(["t.py", "--output-file=f"], retv=1)
|
||||||
|
|
||||||
out, err = capsys.readouterr()
|
out, err = capsys.readouterr()
|
||||||
assert out == err == ""
|
assert out == err == ""
|
||||||
|
|
||||||
expected = "t.py:1:1: F401 'os' imported but unused\n"
|
expected = "t.py:1:1: F401 'os' imported but unused\n"
|
||||||
assert tmpdir.join('f').read() == expected
|
assert tmpdir.join("f").read() == expected
|
||||||
|
|
|
||||||
|
|
@ -1,15 +1,15 @@
|
||||||
"""Integration tests for plugin loading."""
|
"""Integration tests for plugin loading."""
|
||||||
from flake8.main import application
|
from flake8.main import application
|
||||||
|
|
||||||
LOCAL_PLUGIN_CONFIG = 'tests/fixtures/config_files/local-plugin.ini'
|
LOCAL_PLUGIN_CONFIG = "tests/fixtures/config_files/local-plugin.ini"
|
||||||
LOCAL_PLUGIN_PATH_CONFIG = 'tests/fixtures/config_files/local-plugin-path.ini'
|
LOCAL_PLUGIN_PATH_CONFIG = "tests/fixtures/config_files/local-plugin-path.ini"
|
||||||
|
|
||||||
|
|
||||||
class ExtensionTestPlugin:
|
class ExtensionTestPlugin:
|
||||||
"""Extension test plugin."""
|
"""Extension test plugin."""
|
||||||
|
|
||||||
name = 'ExtensionTestPlugin'
|
name = "ExtensionTestPlugin"
|
||||||
version = '1.0.0'
|
version = "1.0.0"
|
||||||
|
|
||||||
def __init__(self, tree):
|
def __init__(self, tree):
|
||||||
"""Construct an instance of test plugin."""
|
"""Construct an instance of test plugin."""
|
||||||
|
|
@ -20,14 +20,14 @@ class ExtensionTestPlugin:
|
||||||
@classmethod
|
@classmethod
|
||||||
def add_options(cls, parser):
|
def add_options(cls, parser):
|
||||||
"""Register options."""
|
"""Register options."""
|
||||||
parser.add_option('--anopt')
|
parser.add_option("--anopt")
|
||||||
|
|
||||||
|
|
||||||
class ReportTestPlugin:
|
class ReportTestPlugin:
|
||||||
"""Report test plugin."""
|
"""Report test plugin."""
|
||||||
|
|
||||||
name = 'ReportTestPlugin'
|
name = "ReportTestPlugin"
|
||||||
version = '1.0.0'
|
version = "1.0.0"
|
||||||
|
|
||||||
def __init__(self, tree):
|
def __init__(self, tree):
|
||||||
"""Construct an instance of test plugin."""
|
"""Construct an instance of test plugin."""
|
||||||
|
|
@ -39,28 +39,29 @@ class ReportTestPlugin:
|
||||||
def test_enable_local_plugin_from_config():
|
def test_enable_local_plugin_from_config():
|
||||||
"""App can load a local plugin from config file."""
|
"""App can load a local plugin from config file."""
|
||||||
app = application.Application()
|
app = application.Application()
|
||||||
app.initialize(['flake8', '--config', LOCAL_PLUGIN_CONFIG])
|
app.initialize(["flake8", "--config", LOCAL_PLUGIN_CONFIG])
|
||||||
|
|
||||||
assert app.check_plugins is not None
|
assert app.check_plugins is not None
|
||||||
assert app.check_plugins['XE'].plugin is ExtensionTestPlugin
|
assert app.check_plugins["XE"].plugin is ExtensionTestPlugin
|
||||||
assert app.formatting_plugins is not None
|
assert app.formatting_plugins is not None
|
||||||
assert app.formatting_plugins['XR'].plugin is ReportTestPlugin
|
assert app.formatting_plugins["XR"].plugin is ReportTestPlugin
|
||||||
|
|
||||||
|
|
||||||
def test_local_plugin_can_add_option():
|
def test_local_plugin_can_add_option():
|
||||||
"""A local plugin can add a CLI option."""
|
"""A local plugin can add a CLI option."""
|
||||||
app = application.Application()
|
app = application.Application()
|
||||||
app.initialize(
|
app.initialize(
|
||||||
['flake8', '--config', LOCAL_PLUGIN_CONFIG, '--anopt', 'foo'])
|
["flake8", "--config", LOCAL_PLUGIN_CONFIG, "--anopt", "foo"]
|
||||||
|
)
|
||||||
|
|
||||||
assert app.options is not None
|
assert app.options is not None
|
||||||
assert app.options.anopt == 'foo'
|
assert app.options.anopt == "foo"
|
||||||
|
|
||||||
|
|
||||||
def test_enable_local_plugin_at_non_installed_path():
|
def test_enable_local_plugin_at_non_installed_path():
|
||||||
"""Can add a paths option in local-plugins config section for finding."""
|
"""Can add a paths option in local-plugins config section for finding."""
|
||||||
app = application.Application()
|
app = application.Application()
|
||||||
app.initialize(['flake8', '--config', LOCAL_PLUGIN_PATH_CONFIG])
|
app.initialize(["flake8", "--config", LOCAL_PLUGIN_PATH_CONFIG])
|
||||||
|
|
||||||
assert app.check_plugins is not None
|
assert app.check_plugins is not None
|
||||||
assert app.check_plugins['XE'].plugin.name == 'ExtensionTestPlugin2'
|
assert app.check_plugins["XE"].plugin.name == "ExtensionTestPlugin2"
|
||||||
|
|
|
||||||
|
|
@ -6,13 +6,13 @@ import pytest
|
||||||
|
|
||||||
def options_from(**kwargs):
|
def options_from(**kwargs):
|
||||||
"""Generate a Values instances with our kwargs."""
|
"""Generate a Values instances with our kwargs."""
|
||||||
kwargs.setdefault('hang_closing', True)
|
kwargs.setdefault("hang_closing", True)
|
||||||
kwargs.setdefault('max_line_length', 79)
|
kwargs.setdefault("max_line_length", 79)
|
||||||
kwargs.setdefault('max_doc_length', None)
|
kwargs.setdefault("max_doc_length", None)
|
||||||
kwargs.setdefault('indent_size', 4)
|
kwargs.setdefault("indent_size", 4)
|
||||||
kwargs.setdefault('verbose', False)
|
kwargs.setdefault("verbose", False)
|
||||||
kwargs.setdefault('stdin_display_name', 'stdin')
|
kwargs.setdefault("stdin_display_name", "stdin")
|
||||||
kwargs.setdefault('disable_noqa', False)
|
kwargs.setdefault("disable_noqa", False)
|
||||||
return argparse.Namespace(**kwargs)
|
return argparse.Namespace(**kwargs)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -10,10 +10,10 @@ from flake8.main import application as app
|
||||||
|
|
||||||
def options(**kwargs):
|
def options(**kwargs):
|
||||||
"""Generate argparse.Namespace for our Application."""
|
"""Generate argparse.Namespace for our Application."""
|
||||||
kwargs.setdefault('verbose', 0)
|
kwargs.setdefault("verbose", 0)
|
||||||
kwargs.setdefault('output_file', None)
|
kwargs.setdefault("output_file", None)
|
||||||
kwargs.setdefault('count', False)
|
kwargs.setdefault("count", False)
|
||||||
kwargs.setdefault('exit_zero', False)
|
kwargs.setdefault("exit_zero", False)
|
||||||
return argparse.Namespace(**kwargs)
|
return argparse.Namespace(**kwargs)
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -24,19 +24,20 @@ def application():
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize(
|
||||||
'result_count, catastrophic, exit_zero, value', [
|
"result_count, catastrophic, exit_zero, value",
|
||||||
|
[
|
||||||
(0, False, False, False),
|
(0, False, False, False),
|
||||||
(0, True, False, True),
|
(0, True, False, True),
|
||||||
(2, False, False, True),
|
(2, False, False, True),
|
||||||
(2, True, False, True),
|
(2, True, False, True),
|
||||||
|
|
||||||
(0, True, True, True),
|
(0, True, True, True),
|
||||||
(2, False, True, False),
|
(2, False, True, False),
|
||||||
(2, True, True, True),
|
(2, True, True, True),
|
||||||
]
|
],
|
||||||
)
|
)
|
||||||
def test_exit_does_raise(result_count, catastrophic, exit_zero, value,
|
def test_exit_does_raise(
|
||||||
application):
|
result_count, catastrophic, exit_zero, value, application
|
||||||
|
):
|
||||||
"""Verify Application.exit doesn't raise SystemExit."""
|
"""Verify Application.exit doesn't raise SystemExit."""
|
||||||
application.result_count = result_count
|
application.result_count = result_count
|
||||||
application.catastrophic_failure = catastrophic
|
application.catastrophic_failure = catastrophic
|
||||||
|
|
@ -53,10 +54,10 @@ def test_warns_on_unknown_formatter_plugin_name(application):
|
||||||
default = mock.Mock()
|
default = mock.Mock()
|
||||||
execute = default.execute
|
execute = default.execute
|
||||||
application.formatting_plugins = {
|
application.formatting_plugins = {
|
||||||
'default': default,
|
"default": default,
|
||||||
}
|
}
|
||||||
with mock.patch.object(app.LOG, 'warning') as warning:
|
with mock.patch.object(app.LOG, "warning") as warning:
|
||||||
assert execute is application.formatter_for('fake-plugin-name')
|
assert execute is application.formatter_for("fake-plugin-name")
|
||||||
|
|
||||||
assert warning.called is True
|
assert warning.called is True
|
||||||
assert warning.call_count == 1
|
assert warning.call_count == 1
|
||||||
|
|
@ -67,12 +68,12 @@ def test_returns_specified_plugin(application):
|
||||||
desired = mock.Mock()
|
desired = mock.Mock()
|
||||||
execute = desired.execute
|
execute = desired.execute
|
||||||
application.formatting_plugins = {
|
application.formatting_plugins = {
|
||||||
'default': mock.Mock(),
|
"default": mock.Mock(),
|
||||||
'desired': desired,
|
"desired": desired,
|
||||||
}
|
}
|
||||||
|
|
||||||
with mock.patch.object(app.LOG, 'warning') as warning:
|
with mock.patch.object(app.LOG, "warning") as warning:
|
||||||
assert execute is application.formatter_for('desired')
|
assert execute is application.formatter_for("desired")
|
||||||
|
|
||||||
assert warning.called is False
|
assert warning.called is False
|
||||||
|
|
||||||
|
|
@ -80,10 +81,11 @@ def test_returns_specified_plugin(application):
|
||||||
def test_prelim_opts_args(application):
|
def test_prelim_opts_args(application):
|
||||||
"""Verify we get sensible prelim opts and args."""
|
"""Verify we get sensible prelim opts and args."""
|
||||||
opts, args = application.parse_preliminary_options(
|
opts, args = application.parse_preliminary_options(
|
||||||
['--foo', '--verbose', 'src', 'setup.py', '--statistics', '--version'])
|
["--foo", "--verbose", "src", "setup.py", "--statistics", "--version"]
|
||||||
|
)
|
||||||
|
|
||||||
assert opts.verbose
|
assert opts.verbose
|
||||||
assert args == ['--foo', 'src', 'setup.py', '--statistics', '--version']
|
assert args == ["--foo", "src", "setup.py", "--statistics", "--version"]
|
||||||
|
|
||||||
|
|
||||||
def test_prelim_opts_ignore_help(application):
|
def test_prelim_opts_ignore_help(application):
|
||||||
|
|
@ -91,16 +93,16 @@ def test_prelim_opts_ignore_help(application):
|
||||||
# GIVEN
|
# GIVEN
|
||||||
|
|
||||||
# WHEN
|
# WHEN
|
||||||
_, args = application.parse_preliminary_options(['--help', '-h'])
|
_, args = application.parse_preliminary_options(["--help", "-h"])
|
||||||
|
|
||||||
# THEN
|
# THEN
|
||||||
assert args == ['--help', '-h']
|
assert args == ["--help", "-h"]
|
||||||
|
|
||||||
|
|
||||||
def test_prelim_opts_handles_empty(application):
|
def test_prelim_opts_handles_empty(application):
|
||||||
"""Verify empty argv lists are handled correctly."""
|
"""Verify empty argv lists are handled correctly."""
|
||||||
irrelevant_args = ['myexe', '/path/to/foo']
|
irrelevant_args = ["myexe", "/path/to/foo"]
|
||||||
with mock.patch.object(sys, 'argv', irrelevant_args):
|
with mock.patch.object(sys, "argv", irrelevant_args):
|
||||||
opts, args = application.parse_preliminary_options([])
|
opts, args = application.parse_preliminary_options([])
|
||||||
|
|
||||||
assert args == []
|
assert args == []
|
||||||
|
|
|
||||||
|
|
@ -10,23 +10,23 @@ from flake8.formatting import base
|
||||||
|
|
||||||
def options(**kwargs):
|
def options(**kwargs):
|
||||||
"""Create an argparse.Namespace instance."""
|
"""Create an argparse.Namespace instance."""
|
||||||
kwargs.setdefault('output_file', None)
|
kwargs.setdefault("output_file", None)
|
||||||
kwargs.setdefault('tee', False)
|
kwargs.setdefault("tee", False)
|
||||||
return argparse.Namespace(**kwargs)
|
return argparse.Namespace(**kwargs)
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize('filename', [None, 'out.txt'])
|
@pytest.mark.parametrize("filename", [None, "out.txt"])
|
||||||
def test_start(filename):
|
def test_start(filename):
|
||||||
"""Verify we open a new file in the start method."""
|
"""Verify we open a new file in the start method."""
|
||||||
mock_open = mock.mock_open()
|
mock_open = mock.mock_open()
|
||||||
formatter = base.BaseFormatter(options(output_file=filename))
|
formatter = base.BaseFormatter(options(output_file=filename))
|
||||||
with mock.patch('flake8.formatting.base.open', mock_open):
|
with mock.patch("flake8.formatting.base.open", mock_open):
|
||||||
formatter.start()
|
formatter.start()
|
||||||
|
|
||||||
if filename is None:
|
if filename is None:
|
||||||
assert mock_open.called is False
|
assert mock_open.called is False
|
||||||
else:
|
else:
|
||||||
mock_open.assert_called_once_with(filename, 'a')
|
mock_open.assert_called_once_with(filename, "a")
|
||||||
|
|
||||||
|
|
||||||
def test_stop():
|
def test_stop():
|
||||||
|
|
@ -45,68 +45,79 @@ def test_format_needs_to_be_implemented():
|
||||||
formatter = base.BaseFormatter(options())
|
formatter = base.BaseFormatter(options())
|
||||||
with pytest.raises(NotImplementedError):
|
with pytest.raises(NotImplementedError):
|
||||||
formatter.format(
|
formatter.format(
|
||||||
style_guide.Violation('A000', 'file.py', 1, 1, 'error text', None)
|
style_guide.Violation("A000", "file.py", 1, 1, "error text", None)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def test_show_source_returns_nothing_when_not_showing_source():
|
def test_show_source_returns_nothing_when_not_showing_source():
|
||||||
"""Ensure we return nothing when users want nothing."""
|
"""Ensure we return nothing when users want nothing."""
|
||||||
formatter = base.BaseFormatter(options(show_source=False))
|
formatter = base.BaseFormatter(options(show_source=False))
|
||||||
assert formatter.show_source(
|
assert (
|
||||||
style_guide.Violation('A000', 'file.py', 1, 1, 'error text', 'line')
|
formatter.show_source(
|
||||||
) == ''
|
style_guide.Violation(
|
||||||
|
"A000", "file.py", 1, 1, "error text", "line"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
== ""
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def test_show_source_returns_nothing_when_there_is_source():
|
def test_show_source_returns_nothing_when_there_is_source():
|
||||||
"""Ensure we return nothing when there is no line."""
|
"""Ensure we return nothing when there is no line."""
|
||||||
formatter = base.BaseFormatter(options(show_source=True))
|
formatter = base.BaseFormatter(options(show_source=True))
|
||||||
assert formatter.show_source(
|
assert (
|
||||||
style_guide.Violation('A000', 'file.py', 1, 1, 'error text', None)
|
formatter.show_source(
|
||||||
) == ''
|
style_guide.Violation("A000", "file.py", 1, 1, "error text", None)
|
||||||
|
)
|
||||||
|
== ""
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize(('line1', 'line2', 'column'), [
|
@pytest.mark.parametrize(
|
||||||
(
|
("line1", "line2", "column"),
|
||||||
'x=1\n',
|
[
|
||||||
' ^',
|
(
|
||||||
2,
|
"x=1\n",
|
||||||
),
|
" ^",
|
||||||
(
|
2,
|
||||||
' x=(1\n +2)\n',
|
),
|
||||||
' ^',
|
(
|
||||||
5,
|
" x=(1\n +2)\n",
|
||||||
),
|
" ^",
|
||||||
(
|
5,
|
||||||
'\tx\t=\ty\n',
|
),
|
||||||
'\t \t \t^',
|
(
|
||||||
6,
|
"\tx\t=\ty\n",
|
||||||
),
|
"\t \t \t^",
|
||||||
])
|
6,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
)
|
||||||
def test_show_source_updates_physical_line_appropriately(line1, line2, column):
|
def test_show_source_updates_physical_line_appropriately(line1, line2, column):
|
||||||
"""Ensure the error column is appropriately indicated."""
|
"""Ensure the error column is appropriately indicated."""
|
||||||
formatter = base.BaseFormatter(options(show_source=True))
|
formatter = base.BaseFormatter(options(show_source=True))
|
||||||
error = style_guide.Violation('A000', 'file.py', 1, column, 'error', line1)
|
error = style_guide.Violation("A000", "file.py", 1, column, "error", line1)
|
||||||
output = formatter.show_source(error)
|
output = formatter.show_source(error)
|
||||||
assert output == line1 + line2
|
assert output == line1 + line2
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize('tee', [False, True])
|
@pytest.mark.parametrize("tee", [False, True])
|
||||||
def test_write_uses_an_output_file(tee):
|
def test_write_uses_an_output_file(tee):
|
||||||
"""Verify that we use the output file when it's present."""
|
"""Verify that we use the output file when it's present."""
|
||||||
line = 'Something to write'
|
line = "Something to write"
|
||||||
source = 'source'
|
source = "source"
|
||||||
filemock = mock.Mock()
|
filemock = mock.Mock()
|
||||||
|
|
||||||
formatter = base.BaseFormatter(options(tee=tee))
|
formatter = base.BaseFormatter(options(tee=tee))
|
||||||
formatter.output_fd = filemock
|
formatter.output_fd = filemock
|
||||||
|
|
||||||
with mock.patch('flake8.formatting.base.print') as print_func:
|
with mock.patch("flake8.formatting.base.print") as print_func:
|
||||||
formatter.write(line, source)
|
formatter.write(line, source)
|
||||||
if tee:
|
if tee:
|
||||||
assert print_func.called
|
assert print_func.called
|
||||||
assert print_func.mock_calls == [
|
assert print_func.mock_calls == [
|
||||||
mock.call(line, end='\n'),
|
mock.call(line, end="\n"),
|
||||||
mock.call(source, end='\n'),
|
mock.call(source, end="\n"),
|
||||||
]
|
]
|
||||||
else:
|
else:
|
||||||
assert not print_func.called
|
assert not print_func.called
|
||||||
|
|
@ -119,11 +130,11 @@ def test_write_uses_an_output_file(tee):
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
@mock.patch('flake8.formatting.base.print')
|
@mock.patch("flake8.formatting.base.print")
|
||||||
def test_write_uses_print(print_function):
|
def test_write_uses_print(print_function):
|
||||||
"""Verify that we use the print function without an output file."""
|
"""Verify that we use the print function without an output file."""
|
||||||
line = 'Something to write'
|
line = "Something to write"
|
||||||
source = 'source'
|
source = "source"
|
||||||
|
|
||||||
formatter = base.BaseFormatter(options())
|
formatter = base.BaseFormatter(options())
|
||||||
formatter.write(line, source)
|
formatter.write(line, source)
|
||||||
|
|
@ -131,8 +142,8 @@ def test_write_uses_print(print_function):
|
||||||
assert print_function.called is True
|
assert print_function.called is True
|
||||||
assert print_function.call_count == 2
|
assert print_function.call_count == 2
|
||||||
assert print_function.mock_calls == [
|
assert print_function.mock_calls == [
|
||||||
mock.call(line, end='\n'),
|
mock.call(line, end="\n"),
|
||||||
mock.call(source, end='\n'),
|
mock.call(source, end="\n"),
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -163,14 +174,14 @@ def test_handle_formats_the_error():
|
||||||
formatter = FormatFormatter(options(show_source=False))
|
formatter = FormatFormatter(options(show_source=False))
|
||||||
filemock = formatter.output_fd = mock.Mock()
|
filemock = formatter.output_fd = mock.Mock()
|
||||||
error = style_guide.Violation(
|
error = style_guide.Violation(
|
||||||
code='A001',
|
code="A001",
|
||||||
filename='example.py',
|
filename="example.py",
|
||||||
line_number=1,
|
line_number=1,
|
||||||
column_number=1,
|
column_number=1,
|
||||||
text='Fake error',
|
text="Fake error",
|
||||||
physical_line='a = 1',
|
physical_line="a = 1",
|
||||||
)
|
)
|
||||||
|
|
||||||
formatter.handle(error)
|
formatter.handle(error)
|
||||||
|
|
||||||
filemock.write.assert_called_once_with(repr(error) + '\n')
|
filemock.write.assert_called_once_with(repr(error) + "\n")
|
||||||
|
|
|
||||||
|
|
@ -10,10 +10,12 @@ from flake8.main.options import JobsArgument
|
||||||
|
|
||||||
def style_guide_mock():
|
def style_guide_mock():
|
||||||
"""Create a mock StyleGuide object."""
|
"""Create a mock StyleGuide object."""
|
||||||
return mock.MagicMock(**{
|
return mock.MagicMock(
|
||||||
'options.diff': False,
|
**{
|
||||||
'options.jobs': JobsArgument("4"),
|
"options.diff": False,
|
||||||
})
|
"options.jobs": JobsArgument("4"),
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def _parallel_checker_manager():
|
def _parallel_checker_manager():
|
||||||
|
|
@ -27,21 +29,21 @@ def _parallel_checker_manager():
|
||||||
|
|
||||||
def test_oserrors_cause_serial_fall_back():
|
def test_oserrors_cause_serial_fall_back():
|
||||||
"""Verify that OSErrors will cause the Manager to fallback to serial."""
|
"""Verify that OSErrors will cause the Manager to fallback to serial."""
|
||||||
err = OSError(errno.ENOSPC, 'Ominous message about spaceeeeee')
|
err = OSError(errno.ENOSPC, "Ominous message about spaceeeeee")
|
||||||
with mock.patch('_multiprocessing.SemLock', side_effect=err):
|
with mock.patch("_multiprocessing.SemLock", side_effect=err):
|
||||||
manager = _parallel_checker_manager()
|
manager = _parallel_checker_manager()
|
||||||
with mock.patch.object(manager, 'run_serial') as serial:
|
with mock.patch.object(manager, "run_serial") as serial:
|
||||||
manager.run()
|
manager.run()
|
||||||
assert serial.call_count == 1
|
assert serial.call_count == 1
|
||||||
|
|
||||||
|
|
||||||
@mock.patch('flake8.checker._multiprocessing_is_fork', return_value=True)
|
@mock.patch("flake8.checker._multiprocessing_is_fork", return_value=True)
|
||||||
def test_oserrors_are_reraised(is_windows):
|
def test_oserrors_are_reraised(is_windows):
|
||||||
"""Verify that unexpected OSErrors will cause the Manager to reraise."""
|
"""Verify that unexpected OSErrors will cause the Manager to reraise."""
|
||||||
err = OSError(errno.EAGAIN, 'Ominous message')
|
err = OSError(errno.EAGAIN, "Ominous message")
|
||||||
with mock.patch('_multiprocessing.SemLock', side_effect=err):
|
with mock.patch("_multiprocessing.SemLock", side_effect=err):
|
||||||
manager = _parallel_checker_manager()
|
manager = _parallel_checker_manager()
|
||||||
with mock.patch.object(manager, 'run_serial') as serial:
|
with mock.patch.object(manager, "run_serial") as serial:
|
||||||
with pytest.raises(OSError):
|
with pytest.raises(OSError):
|
||||||
manager.run()
|
manager.run()
|
||||||
assert serial.call_count == 0
|
assert serial.call_count == 0
|
||||||
|
|
@ -50,7 +52,7 @@ def test_oserrors_are_reraised(is_windows):
|
||||||
def test_multiprocessing_is_disabled():
|
def test_multiprocessing_is_disabled():
|
||||||
"""Verify not being able to import multiprocessing forces jobs to 0."""
|
"""Verify not being able to import multiprocessing forces jobs to 0."""
|
||||||
style_guide = style_guide_mock()
|
style_guide = style_guide_mock()
|
||||||
with mock.patch('flake8.checker.multiprocessing', None):
|
with mock.patch("flake8.checker.multiprocessing", None):
|
||||||
manager = checker.Manager(style_guide, [], [])
|
manager = checker.Manager(style_guide, [], [])
|
||||||
assert manager.jobs == 0
|
assert manager.jobs == 0
|
||||||
|
|
||||||
|
|
@ -58,20 +60,20 @@ def test_multiprocessing_is_disabled():
|
||||||
def test_make_checkers():
|
def test_make_checkers():
|
||||||
"""Verify that we create a list of FileChecker instances."""
|
"""Verify that we create a list of FileChecker instances."""
|
||||||
style_guide = style_guide_mock()
|
style_guide = style_guide_mock()
|
||||||
files = ['file1', 'file2']
|
files = ["file1", "file2"]
|
||||||
checkplugins = mock.Mock()
|
checkplugins = mock.Mock()
|
||||||
checkplugins.to_dictionary.return_value = {
|
checkplugins.to_dictionary.return_value = {
|
||||||
'ast_plugins': [],
|
"ast_plugins": [],
|
||||||
'logical_line_plugins': [],
|
"logical_line_plugins": [],
|
||||||
'physical_line_plugins': [],
|
"physical_line_plugins": [],
|
||||||
}
|
}
|
||||||
with mock.patch('flake8.checker.multiprocessing', None):
|
with mock.patch("flake8.checker.multiprocessing", None):
|
||||||
manager = checker.Manager(style_guide, files, checkplugins)
|
manager = checker.Manager(style_guide, files, checkplugins)
|
||||||
|
|
||||||
with mock.patch('flake8.utils.filenames_from') as filenames_from:
|
with mock.patch("flake8.utils.filenames_from") as filenames_from:
|
||||||
filenames_from.side_effect = [['file1'], ['file2']]
|
filenames_from.side_effect = [["file1"], ["file2"]]
|
||||||
with mock.patch('flake8.utils.fnmatch', return_value=True):
|
with mock.patch("flake8.utils.fnmatch", return_value=True):
|
||||||
with mock.patch('flake8.processor.FileProcessor'):
|
with mock.patch("flake8.processor.FileProcessor"):
|
||||||
manager.make_checkers()
|
manager.make_checkers()
|
||||||
|
|
||||||
assert manager._all_checkers
|
assert manager._all_checkers
|
||||||
|
|
|
||||||
|
|
@ -7,73 +7,93 @@ import pytest
|
||||||
|
|
||||||
from flake8.options import config
|
from flake8.options import config
|
||||||
|
|
||||||
CLI_SPECIFIED_FILEPATH = 'tests/fixtures/config_files/cli-specified.ini'
|
CLI_SPECIFIED_FILEPATH = "tests/fixtures/config_files/cli-specified.ini"
|
||||||
BROKEN_CONFIG_PATH = 'tests/fixtures/config_files/broken.ini'
|
BROKEN_CONFIG_PATH = "tests/fixtures/config_files/broken.ini"
|
||||||
|
|
||||||
|
|
||||||
def test_cli_config():
|
def test_cli_config():
|
||||||
"""Verify opening and reading the file specified via the cli."""
|
"""Verify opening and reading the file specified via the cli."""
|
||||||
cli_filepath = CLI_SPECIFIED_FILEPATH
|
cli_filepath = CLI_SPECIFIED_FILEPATH
|
||||||
finder = config.ConfigFileFinder('flake8')
|
finder = config.ConfigFileFinder("flake8")
|
||||||
|
|
||||||
parsed_config = finder.cli_config(cli_filepath)
|
parsed_config = finder.cli_config(cli_filepath)
|
||||||
assert parsed_config.has_section('flake8')
|
assert parsed_config.has_section("flake8")
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize('cwd,expected', [
|
@pytest.mark.parametrize(
|
||||||
# Root directory of project
|
"cwd,expected",
|
||||||
(os.path.abspath('.'),
|
[
|
||||||
[os.path.abspath('setup.cfg'),
|
# Root directory of project
|
||||||
os.path.abspath('tox.ini')]),
|
(
|
||||||
# Subdirectory of project directory
|
os.path.abspath("."),
|
||||||
(os.path.abspath('src'),
|
[os.path.abspath("setup.cfg"), os.path.abspath("tox.ini")],
|
||||||
[os.path.abspath('setup.cfg'),
|
),
|
||||||
os.path.abspath('tox.ini')]),
|
# Subdirectory of project directory
|
||||||
# Outside of project directory
|
(
|
||||||
(os.path.abspath('/'),
|
os.path.abspath("src"),
|
||||||
[]),
|
[os.path.abspath("setup.cfg"), os.path.abspath("tox.ini")],
|
||||||
])
|
),
|
||||||
|
# Outside of project directory
|
||||||
|
(os.path.abspath("/"), []),
|
||||||
|
],
|
||||||
|
)
|
||||||
def test_generate_possible_local_files(cwd, expected):
|
def test_generate_possible_local_files(cwd, expected):
|
||||||
"""Verify generation of all possible config paths."""
|
"""Verify generation of all possible config paths."""
|
||||||
finder = config.ConfigFileFinder('flake8')
|
finder = config.ConfigFileFinder("flake8")
|
||||||
|
|
||||||
with mock.patch.object(os, 'getcwd', return_value=cwd):
|
with mock.patch.object(os, "getcwd", return_value=cwd):
|
||||||
config_files = list(finder.generate_possible_local_files())
|
config_files = list(finder.generate_possible_local_files())
|
||||||
|
|
||||||
assert config_files == expected
|
assert config_files == expected
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize('extra_config_files,expected', [
|
@pytest.mark.parametrize(
|
||||||
# Extra config files specified
|
"extra_config_files,expected",
|
||||||
([CLI_SPECIFIED_FILEPATH],
|
[
|
||||||
[os.path.abspath('setup.cfg'),
|
# Extra config files specified
|
||||||
os.path.abspath('tox.ini'),
|
(
|
||||||
os.path.abspath(CLI_SPECIFIED_FILEPATH)]),
|
[CLI_SPECIFIED_FILEPATH],
|
||||||
# Missing extra config files specified
|
[
|
||||||
([CLI_SPECIFIED_FILEPATH,
|
os.path.abspath("setup.cfg"),
|
||||||
'tests/fixtures/config_files/missing.ini'],
|
os.path.abspath("tox.ini"),
|
||||||
[os.path.abspath('setup.cfg'),
|
os.path.abspath(CLI_SPECIFIED_FILEPATH),
|
||||||
os.path.abspath('tox.ini'),
|
],
|
||||||
os.path.abspath(CLI_SPECIFIED_FILEPATH)]),
|
),
|
||||||
])
|
# Missing extra config files specified
|
||||||
|
(
|
||||||
|
[
|
||||||
|
CLI_SPECIFIED_FILEPATH,
|
||||||
|
"tests/fixtures/config_files/missing.ini",
|
||||||
|
],
|
||||||
|
[
|
||||||
|
os.path.abspath("setup.cfg"),
|
||||||
|
os.path.abspath("tox.ini"),
|
||||||
|
os.path.abspath(CLI_SPECIFIED_FILEPATH),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
],
|
||||||
|
)
|
||||||
def test_local_config_files(extra_config_files, expected):
|
def test_local_config_files(extra_config_files, expected):
|
||||||
"""Verify discovery of local config files."""
|
"""Verify discovery of local config files."""
|
||||||
finder = config.ConfigFileFinder('flake8', extra_config_files)
|
finder = config.ConfigFileFinder("flake8", extra_config_files)
|
||||||
|
|
||||||
assert list(finder.local_config_files()) == expected
|
assert list(finder.local_config_files()) == expected
|
||||||
|
|
||||||
|
|
||||||
def test_local_configs():
|
def test_local_configs():
|
||||||
"""Verify we return a ConfigParser."""
|
"""Verify we return a ConfigParser."""
|
||||||
finder = config.ConfigFileFinder('flake8')
|
finder = config.ConfigFileFinder("flake8")
|
||||||
|
|
||||||
assert isinstance(finder.local_configs(), configparser.RawConfigParser)
|
assert isinstance(finder.local_configs(), configparser.RawConfigParser)
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize('files', [
|
@pytest.mark.parametrize(
|
||||||
[BROKEN_CONFIG_PATH],
|
"files",
|
||||||
[CLI_SPECIFIED_FILEPATH, BROKEN_CONFIG_PATH],
|
[
|
||||||
])
|
[BROKEN_CONFIG_PATH],
|
||||||
|
[CLI_SPECIFIED_FILEPATH, BROKEN_CONFIG_PATH],
|
||||||
|
],
|
||||||
|
)
|
||||||
def test_read_config_catches_broken_config_files(files):
|
def test_read_config_catches_broken_config_files(files):
|
||||||
"""Verify that we do not allow the exception to bubble up."""
|
"""Verify that we do not allow the exception to bubble up."""
|
||||||
_, parsed = config.ConfigFileFinder._read_config(*files)
|
_, parsed = config.ConfigFileFinder._read_config(*files)
|
||||||
|
|
@ -82,40 +102,42 @@ def test_read_config_catches_broken_config_files(files):
|
||||||
|
|
||||||
def test_read_config_catches_decoding_errors(tmpdir):
|
def test_read_config_catches_decoding_errors(tmpdir):
|
||||||
"""Verify that we do not allow the exception to bubble up."""
|
"""Verify that we do not allow the exception to bubble up."""
|
||||||
setup_cfg = tmpdir.join('setup.cfg')
|
setup_cfg = tmpdir.join("setup.cfg")
|
||||||
# pick bytes that are unlikely to decode
|
# pick bytes that are unlikely to decode
|
||||||
setup_cfg.write_binary(b'[x]\ny = \x81\x8d\x90\x9d')
|
setup_cfg.write_binary(b"[x]\ny = \x81\x8d\x90\x9d")
|
||||||
_, parsed = config.ConfigFileFinder._read_config(setup_cfg.strpath)
|
_, parsed = config.ConfigFileFinder._read_config(setup_cfg.strpath)
|
||||||
assert parsed == []
|
assert parsed == []
|
||||||
|
|
||||||
|
|
||||||
def test_config_file_default_value():
|
def test_config_file_default_value():
|
||||||
"""Verify the default 'config_file' attribute value."""
|
"""Verify the default 'config_file' attribute value."""
|
||||||
finder = config.ConfigFileFinder('flake8')
|
finder = config.ConfigFileFinder("flake8")
|
||||||
assert finder.config_file is None
|
assert finder.config_file is None
|
||||||
|
|
||||||
|
|
||||||
def test_setting_config_file_value():
|
def test_setting_config_file_value():
|
||||||
"""Verify the 'config_file' attribute matches constructed value."""
|
"""Verify the 'config_file' attribute matches constructed value."""
|
||||||
config_file_value = 'flake8.ini'
|
config_file_value = "flake8.ini"
|
||||||
finder = config.ConfigFileFinder('flake8', config_file=config_file_value)
|
finder = config.ConfigFileFinder("flake8", config_file=config_file_value)
|
||||||
assert finder.config_file == config_file_value
|
assert finder.config_file == config_file_value
|
||||||
|
|
||||||
|
|
||||||
def test_ignore_config_files_default_value():
|
def test_ignore_config_files_default_value():
|
||||||
"""Verify the default 'ignore_config_files' attribute value."""
|
"""Verify the default 'ignore_config_files' attribute value."""
|
||||||
finder = config.ConfigFileFinder('flake8')
|
finder = config.ConfigFileFinder("flake8")
|
||||||
assert finder.ignore_config_files is False
|
assert finder.ignore_config_files is False
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize('ignore_config_files_arg', [
|
@pytest.mark.parametrize(
|
||||||
False,
|
"ignore_config_files_arg",
|
||||||
True,
|
[
|
||||||
])
|
False,
|
||||||
|
True,
|
||||||
|
],
|
||||||
|
)
|
||||||
def test_setting_ignore_config_files_value(ignore_config_files_arg):
|
def test_setting_ignore_config_files_value(ignore_config_files_arg):
|
||||||
"""Verify the 'ignore_config_files' attribute matches constructed value."""
|
"""Verify the 'ignore_config_files' attribute matches constructed value."""
|
||||||
finder = config.ConfigFileFinder(
|
finder = config.ConfigFileFinder(
|
||||||
'flake8',
|
"flake8", ignore_config_files=ignore_config_files_arg
|
||||||
ignore_config_files=ignore_config_files_arg
|
|
||||||
)
|
)
|
||||||
assert finder.ignore_config_files is ignore_config_files_arg
|
assert finder.ignore_config_files is ignore_config_files_arg
|
||||||
|
|
|
||||||
|
|
@ -12,51 +12,82 @@ def test_dependencies():
|
||||||
assert [] == debug.dependencies()
|
assert [] == debug.dependencies()
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize('plugins, expected', [
|
@pytest.mark.parametrize(
|
||||||
([], []),
|
"plugins, expected",
|
||||||
([manager.PluginVersion('pycodestyle', '2.0.0', False)],
|
[
|
||||||
[{'plugin': 'pycodestyle', 'version': '2.0.0', 'is_local': False}]),
|
([], []),
|
||||||
([manager.PluginVersion('pycodestyle', '2.0.0', False),
|
(
|
||||||
manager.PluginVersion('mccabe', '0.5.9', False)],
|
[manager.PluginVersion("pycodestyle", "2.0.0", False)],
|
||||||
[{'plugin': 'mccabe', 'version': '0.5.9', 'is_local': False},
|
[
|
||||||
{'plugin': 'pycodestyle', 'version': '2.0.0', 'is_local': False}]),
|
{
|
||||||
([manager.PluginVersion('pycodestyle', '2.0.0', False),
|
"plugin": "pycodestyle",
|
||||||
manager.PluginVersion('my-local', '0.0.1', True),
|
"version": "2.0.0",
|
||||||
manager.PluginVersion('mccabe', '0.5.9', False)],
|
"is_local": False,
|
||||||
[{'plugin': 'mccabe', 'version': '0.5.9', 'is_local': False},
|
}
|
||||||
{'plugin': 'my-local', 'version': '0.0.1', 'is_local': True},
|
],
|
||||||
{'plugin': 'pycodestyle', 'version': '2.0.0', 'is_local': False}]),
|
),
|
||||||
])
|
(
|
||||||
|
[
|
||||||
|
manager.PluginVersion("pycodestyle", "2.0.0", False),
|
||||||
|
manager.PluginVersion("mccabe", "0.5.9", False),
|
||||||
|
],
|
||||||
|
[
|
||||||
|
{"plugin": "mccabe", "version": "0.5.9", "is_local": False},
|
||||||
|
{
|
||||||
|
"plugin": "pycodestyle",
|
||||||
|
"version": "2.0.0",
|
||||||
|
"is_local": False,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
),
|
||||||
|
(
|
||||||
|
[
|
||||||
|
manager.PluginVersion("pycodestyle", "2.0.0", False),
|
||||||
|
manager.PluginVersion("my-local", "0.0.1", True),
|
||||||
|
manager.PluginVersion("mccabe", "0.5.9", False),
|
||||||
|
],
|
||||||
|
[
|
||||||
|
{"plugin": "mccabe", "version": "0.5.9", "is_local": False},
|
||||||
|
{"plugin": "my-local", "version": "0.0.1", "is_local": True},
|
||||||
|
{
|
||||||
|
"plugin": "pycodestyle",
|
||||||
|
"version": "2.0.0",
|
||||||
|
"is_local": False,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
),
|
||||||
|
],
|
||||||
|
)
|
||||||
def test_plugins_from(plugins, expected):
|
def test_plugins_from(plugins, expected):
|
||||||
"""Test that we format plugins appropriately."""
|
"""Test that we format plugins appropriately."""
|
||||||
option_manager = mock.Mock(registered_plugins=set(plugins))
|
option_manager = mock.Mock(registered_plugins=set(plugins))
|
||||||
assert expected == debug.plugins_from(option_manager)
|
assert expected == debug.plugins_from(option_manager)
|
||||||
|
|
||||||
|
|
||||||
@mock.patch('platform.python_implementation', return_value='CPython')
|
@mock.patch("platform.python_implementation", return_value="CPython")
|
||||||
@mock.patch('platform.python_version', return_value='3.5.3')
|
@mock.patch("platform.python_version", return_value="3.5.3")
|
||||||
@mock.patch('platform.system', return_value='Linux')
|
@mock.patch("platform.system", return_value="Linux")
|
||||||
def test_information(system, pyversion, pyimpl):
|
def test_information(system, pyversion, pyimpl):
|
||||||
"""Verify that we return all the information we care about."""
|
"""Verify that we return all the information we care about."""
|
||||||
expected = {
|
expected = {
|
||||||
'version': '3.1.0',
|
"version": "3.1.0",
|
||||||
'plugins': [{'plugin': 'mccabe', 'version': '0.5.9',
|
"plugins": [
|
||||||
'is_local': False},
|
{"plugin": "mccabe", "version": "0.5.9", "is_local": False},
|
||||||
{'plugin': 'pycodestyle', 'version': '2.0.0',
|
{"plugin": "pycodestyle", "version": "2.0.0", "is_local": False},
|
||||||
'is_local': False}],
|
],
|
||||||
'dependencies': [],
|
"dependencies": [],
|
||||||
'platform': {
|
"platform": {
|
||||||
'python_implementation': 'CPython',
|
"python_implementation": "CPython",
|
||||||
'python_version': '3.5.3',
|
"python_version": "3.5.3",
|
||||||
'system': 'Linux',
|
"system": "Linux",
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
option_manager = mock.Mock(
|
option_manager = mock.Mock(
|
||||||
registered_plugins={
|
registered_plugins={
|
||||||
manager.PluginVersion('pycodestyle', '2.0.0', False),
|
manager.PluginVersion("pycodestyle", "2.0.0", False),
|
||||||
manager.PluginVersion('mccabe', '0.5.9', False),
|
manager.PluginVersion("mccabe", "0.5.9", False),
|
||||||
},
|
},
|
||||||
version='3.1.0',
|
version="3.1.0",
|
||||||
)
|
)
|
||||||
assert expected == debug.information(option_manager)
|
assert expected == debug.information(option_manager)
|
||||||
pyimpl.assert_called_once_with()
|
pyimpl.assert_called_once_with()
|
||||||
|
|
@ -64,14 +95,16 @@ def test_information(system, pyversion, pyimpl):
|
||||||
system.assert_called_once_with()
|
system.assert_called_once_with()
|
||||||
|
|
||||||
|
|
||||||
@mock.patch('flake8.main.debug.print')
|
@mock.patch("flake8.main.debug.print")
|
||||||
@mock.patch('flake8.main.debug.information', return_value={})
|
@mock.patch("flake8.main.debug.information", return_value={})
|
||||||
@mock.patch('json.dumps', return_value='{}')
|
@mock.patch("json.dumps", return_value="{}")
|
||||||
def test_print_information_no_plugins(dumps, information, print_mock):
|
def test_print_information_no_plugins(dumps, information, print_mock):
|
||||||
"""Verify we print and exit only when we have plugins."""
|
"""Verify we print and exit only when we have plugins."""
|
||||||
option_manager = mock.Mock(registered_plugins=set())
|
option_manager = mock.Mock(registered_plugins=set())
|
||||||
action = debug.DebugAction(
|
action = debug.DebugAction(
|
||||||
"--bug-report", dest="bug_report", option_manager=option_manager,
|
"--bug-report",
|
||||||
|
dest="bug_report",
|
||||||
|
option_manager=option_manager,
|
||||||
)
|
)
|
||||||
assert action(None, None, None, None) is None
|
assert action(None, None, None, None) is None
|
||||||
assert dumps.called is False
|
assert dumps.called is False
|
||||||
|
|
@ -79,21 +112,23 @@ def test_print_information_no_plugins(dumps, information, print_mock):
|
||||||
assert print_mock.called is False
|
assert print_mock.called is False
|
||||||
|
|
||||||
|
|
||||||
@mock.patch('flake8.main.debug.print')
|
@mock.patch("flake8.main.debug.print")
|
||||||
@mock.patch('flake8.main.debug.information', return_value={})
|
@mock.patch("flake8.main.debug.information", return_value={})
|
||||||
@mock.patch('json.dumps', return_value='{}')
|
@mock.patch("json.dumps", return_value="{}")
|
||||||
def test_print_information(dumps, information, print_mock):
|
def test_print_information(dumps, information, print_mock):
|
||||||
"""Verify we print and exit only when we have plugins."""
|
"""Verify we print and exit only when we have plugins."""
|
||||||
plugins = [
|
plugins = [
|
||||||
manager.PluginVersion('pycodestyle', '2.0.0', False),
|
manager.PluginVersion("pycodestyle", "2.0.0", False),
|
||||||
manager.PluginVersion('mccabe', '0.5.9', False),
|
manager.PluginVersion("mccabe", "0.5.9", False),
|
||||||
]
|
]
|
||||||
option_manager = mock.Mock(registered_plugins=set(plugins))
|
option_manager = mock.Mock(registered_plugins=set(plugins))
|
||||||
action = debug.DebugAction(
|
action = debug.DebugAction(
|
||||||
"--bug-report", dest="bug_report", option_manager=option_manager,
|
"--bug-report",
|
||||||
|
dest="bug_report",
|
||||||
|
option_manager=option_manager,
|
||||||
)
|
)
|
||||||
with pytest.raises(SystemExit):
|
with pytest.raises(SystemExit):
|
||||||
action(None, None, None, None)
|
action(None, None, None, None)
|
||||||
print_mock.assert_called_once_with('{}')
|
print_mock.assert_called_once_with("{}")
|
||||||
dumps.assert_called_once_with({}, indent=2, sort_keys=True)
|
dumps.assert_called_once_with({}, indent=2, sort_keys=True)
|
||||||
information.assert_called_once_with(option_manager)
|
information.assert_called_once_with(option_manager)
|
||||||
|
|
|
||||||
|
|
@ -7,21 +7,21 @@ from flake8 import exceptions
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize(
|
||||||
'err',
|
"err",
|
||||||
(
|
(
|
||||||
exceptions.FailedToLoadPlugin(
|
exceptions.FailedToLoadPlugin(
|
||||||
plugin_name='plugin_name',
|
plugin_name="plugin_name",
|
||||||
exception=ValueError('boom!'),
|
exception=ValueError("boom!"),
|
||||||
),
|
),
|
||||||
exceptions.InvalidSyntax(exception=ValueError('Unexpected token: $')),
|
exceptions.InvalidSyntax(exception=ValueError("Unexpected token: $")),
|
||||||
exceptions.PluginRequestedUnknownParameters(
|
exceptions.PluginRequestedUnknownParameters(
|
||||||
plugin={'plugin_name': 'plugin_name'},
|
plugin={"plugin_name": "plugin_name"},
|
||||||
exception=ValueError('boom!'),
|
exception=ValueError("boom!"),
|
||||||
),
|
),
|
||||||
exceptions.PluginExecutionFailed(
|
exceptions.PluginExecutionFailed(
|
||||||
plugin={'plugin_name': 'plugin_name'},
|
plugin={"plugin_name": "plugin_name"},
|
||||||
exception=ValueError('boom!'),
|
exception=ValueError("boom!"),
|
||||||
)
|
),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
def test_pickleable(err):
|
def test_pickleable(err):
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ import flake8
|
||||||
from flake8 import checker
|
from flake8 import checker
|
||||||
|
|
||||||
|
|
||||||
@mock.patch('flake8.processor.FileProcessor')
|
@mock.patch("flake8.processor.FileProcessor")
|
||||||
def test_run_ast_checks_handles_SyntaxErrors(FileProcessor): # noqa: N802,N803
|
def test_run_ast_checks_handles_SyntaxErrors(FileProcessor): # noqa: N802,N803
|
||||||
"""Stress our SyntaxError handling.
|
"""Stress our SyntaxError handling.
|
||||||
|
|
||||||
|
|
@ -15,26 +15,31 @@ def test_run_ast_checks_handles_SyntaxErrors(FileProcessor): # noqa: N802,N803
|
||||||
"""
|
"""
|
||||||
processor = mock.Mock(lines=[])
|
processor = mock.Mock(lines=[])
|
||||||
FileProcessor.return_value = processor
|
FileProcessor.return_value = processor
|
||||||
processor.build_ast.side_effect = SyntaxError('Failed to build ast',
|
processor.build_ast.side_effect = SyntaxError(
|
||||||
('', 1, 5, 'foo(\n'))
|
"Failed to build ast", ("", 1, 5, "foo(\n")
|
||||||
|
)
|
||||||
file_checker = checker.FileChecker(__file__, checks={}, options=object())
|
file_checker = checker.FileChecker(__file__, checks={}, options=object())
|
||||||
|
|
||||||
with mock.patch.object(file_checker, 'report') as report:
|
with mock.patch.object(file_checker, "report") as report:
|
||||||
file_checker.run_ast_checks()
|
file_checker.run_ast_checks()
|
||||||
|
|
||||||
report.assert_called_once_with(
|
report.assert_called_once_with(
|
||||||
'E999', 1, 3,
|
"E999",
|
||||||
'SyntaxError: Failed to build ast',
|
1,
|
||||||
|
3,
|
||||||
|
"SyntaxError: Failed to build ast",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@mock.patch('flake8.checker.FileChecker._make_processor', return_value=None)
|
@mock.patch("flake8.checker.FileChecker._make_processor", return_value=None)
|
||||||
def test_repr(*args):
|
def test_repr(*args):
|
||||||
"""Verify we generate a correct repr."""
|
"""Verify we generate a correct repr."""
|
||||||
file_checker = checker.FileChecker(
|
file_checker = checker.FileChecker(
|
||||||
'example.py', checks={}, options=object(),
|
"example.py",
|
||||||
|
checks={},
|
||||||
|
options=object(),
|
||||||
)
|
)
|
||||||
assert repr(file_checker) == 'FileChecker for example.py'
|
assert repr(file_checker) == "FileChecker for example.py"
|
||||||
|
|
||||||
|
|
||||||
def test_nonexistent_file():
|
def test_nonexistent_file():
|
||||||
|
|
@ -50,7 +55,7 @@ def test_nonexistent_file():
|
||||||
|
|
||||||
def test_raises_exception_on_failed_plugin(tmp_path, default_options):
|
def test_raises_exception_on_failed_plugin(tmp_path, default_options):
|
||||||
"""Checks that a failing plugin results in PluginExecutionFailed."""
|
"""Checks that a failing plugin results in PluginExecutionFailed."""
|
||||||
foobar = tmp_path / 'foobar.py'
|
foobar = tmp_path / "foobar.py"
|
||||||
foobar.write_text("I exist!") # Create temp file
|
foobar.write_text("I exist!") # Create temp file
|
||||||
plugin = {
|
plugin = {
|
||||||
"name": "failure",
|
"name": "failure",
|
||||||
|
|
@ -60,6 +65,7 @@ def test_raises_exception_on_failed_plugin(tmp_path, default_options):
|
||||||
}
|
}
|
||||||
"""Verify a failing plugin results in an plugin error"""
|
"""Verify a failing plugin results in an plugin error"""
|
||||||
fchecker = checker.FileChecker(
|
fchecker = checker.FileChecker(
|
||||||
str(foobar), checks=[], options=default_options)
|
str(foobar), checks=[], options=default_options
|
||||||
|
)
|
||||||
with pytest.raises(flake8.exceptions.PluginExecutionFailed):
|
with pytest.raises(flake8.exceptions.PluginExecutionFailed):
|
||||||
fchecker.run_check(plugin)
|
fchecker.run_check(plugin)
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@ def test_read_lines_splits_lines(default_options):
|
||||||
|
|
||||||
|
|
||||||
def _lines_from_file(tmpdir, contents, options):
|
def _lines_from_file(tmpdir, contents, options):
|
||||||
f = tmpdir.join('f.py')
|
f = tmpdir.join("f.py")
|
||||||
# be careful to write the bytes exactly to avoid newline munging
|
# be careful to write the bytes exactly to avoid newline munging
|
||||||
f.write_binary(contents)
|
f.write_binary(contents)
|
||||||
return processor.FileProcessor(f.strpath, options).lines
|
return processor.FileProcessor(f.strpath, options).lines
|
||||||
|
|
@ -26,111 +26,125 @@ def _lines_from_file(tmpdir, contents, options):
|
||||||
def test_read_lines_universal_newlines(tmpdir, default_options):
|
def test_read_lines_universal_newlines(tmpdir, default_options):
|
||||||
r"""Verify that line endings are translated to \n."""
|
r"""Verify that line endings are translated to \n."""
|
||||||
lines = _lines_from_file(
|
lines = _lines_from_file(
|
||||||
tmpdir, b'# coding: utf-8\r\nx = 1\r\n', default_options)
|
tmpdir, b"# coding: utf-8\r\nx = 1\r\n", default_options
|
||||||
assert lines == ['# coding: utf-8\n', 'x = 1\n']
|
)
|
||||||
|
assert lines == ["# coding: utf-8\n", "x = 1\n"]
|
||||||
|
|
||||||
|
|
||||||
def test_read_lines_incorrect_utf_16(tmpdir, default_options):
|
def test_read_lines_incorrect_utf_16(tmpdir, default_options):
|
||||||
"""Verify that an incorrectly encoded file is read as latin-1."""
|
"""Verify that an incorrectly encoded file is read as latin-1."""
|
||||||
lines = _lines_from_file(
|
lines = _lines_from_file(
|
||||||
tmpdir, b'# coding: utf16\nx = 1\n', default_options)
|
tmpdir, b"# coding: utf16\nx = 1\n", default_options
|
||||||
assert lines == ['# coding: utf16\n', 'x = 1\n']
|
)
|
||||||
|
assert lines == ["# coding: utf16\n", "x = 1\n"]
|
||||||
|
|
||||||
|
|
||||||
def test_read_lines_unknown_encoding(tmpdir, default_options):
|
def test_read_lines_unknown_encoding(tmpdir, default_options):
|
||||||
"""Verify that an unknown encoding is still read as latin-1."""
|
"""Verify that an unknown encoding is still read as latin-1."""
|
||||||
lines = _lines_from_file(
|
lines = _lines_from_file(
|
||||||
tmpdir, b'# coding: fake-encoding\nx = 1\n', default_options)
|
tmpdir, b"# coding: fake-encoding\nx = 1\n", default_options
|
||||||
assert lines == ['# coding: fake-encoding\n', 'x = 1\n']
|
)
|
||||||
|
assert lines == ["# coding: fake-encoding\n", "x = 1\n"]
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize('first_line', [
|
@pytest.mark.parametrize(
|
||||||
'\xEF\xBB\xBF"""Module docstring."""\n',
|
"first_line",
|
||||||
'\uFEFF"""Module docstring."""\n',
|
[
|
||||||
])
|
'\xEF\xBB\xBF"""Module docstring."""\n',
|
||||||
|
'\uFEFF"""Module docstring."""\n',
|
||||||
|
],
|
||||||
|
)
|
||||||
def test_strip_utf_bom(first_line, default_options):
|
def test_strip_utf_bom(first_line, default_options):
|
||||||
r"""Verify that we strip '\xEF\xBB\xBF' from the first line."""
|
r"""Verify that we strip '\xEF\xBB\xBF' from the first line."""
|
||||||
lines = [first_line]
|
lines = [first_line]
|
||||||
file_processor = processor.FileProcessor('-', default_options, lines[:])
|
file_processor = processor.FileProcessor("-", default_options, lines[:])
|
||||||
assert file_processor.lines != lines
|
assert file_processor.lines != lines
|
||||||
assert file_processor.lines[0] == '"""Module docstring."""\n'
|
assert file_processor.lines[0] == '"""Module docstring."""\n'
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize('lines, expected', [
|
@pytest.mark.parametrize(
|
||||||
(['\xEF\xBB\xBF"""Module docstring."""\n'], False),
|
"lines, expected",
|
||||||
(['\uFEFF"""Module docstring."""\n'], False),
|
[
|
||||||
(['#!/usr/bin/python', '# flake8 is great', 'a = 1'], False),
|
(['\xEF\xBB\xBF"""Module docstring."""\n'], False),
|
||||||
(['#!/usr/bin/python', '# flake8: noqa', 'a = 1'], True),
|
(['\uFEFF"""Module docstring."""\n'], False),
|
||||||
(['#!/usr/bin/python', '# flake8:noqa', 'a = 1'], True),
|
(["#!/usr/bin/python", "# flake8 is great", "a = 1"], False),
|
||||||
(['# flake8: noqa', '#!/usr/bin/python', 'a = 1'], True),
|
(["#!/usr/bin/python", "# flake8: noqa", "a = 1"], True),
|
||||||
(['# flake8:noqa', '#!/usr/bin/python', 'a = 1'], True),
|
(["#!/usr/bin/python", "# flake8:noqa", "a = 1"], True),
|
||||||
(['#!/usr/bin/python', 'a = 1', '# flake8: noqa'], True),
|
(["# flake8: noqa", "#!/usr/bin/python", "a = 1"], True),
|
||||||
(['#!/usr/bin/python', 'a = 1', '# flake8:noqa'], True),
|
(["# flake8:noqa", "#!/usr/bin/python", "a = 1"], True),
|
||||||
(['#!/usr/bin/python', 'a = 1 # flake8: noqa'], False),
|
(["#!/usr/bin/python", "a = 1", "# flake8: noqa"], True),
|
||||||
(['#!/usr/bin/python', 'a = 1 # flake8:noqa'], False),
|
(["#!/usr/bin/python", "a = 1", "# flake8:noqa"], True),
|
||||||
])
|
(["#!/usr/bin/python", "a = 1 # flake8: noqa"], False),
|
||||||
|
(["#!/usr/bin/python", "a = 1 # flake8:noqa"], False),
|
||||||
|
],
|
||||||
|
)
|
||||||
def test_should_ignore_file(lines, expected, default_options):
|
def test_should_ignore_file(lines, expected, default_options):
|
||||||
"""Verify that we ignore a file if told to."""
|
"""Verify that we ignore a file if told to."""
|
||||||
file_processor = processor.FileProcessor('-', default_options, lines)
|
file_processor = processor.FileProcessor("-", default_options, lines)
|
||||||
assert file_processor.should_ignore_file() is expected
|
assert file_processor.should_ignore_file() is expected
|
||||||
|
|
||||||
|
|
||||||
def test_should_ignore_file_to_handle_disable_noqa(default_options):
|
def test_should_ignore_file_to_handle_disable_noqa(default_options):
|
||||||
"""Verify that we ignore a file if told to."""
|
"""Verify that we ignore a file if told to."""
|
||||||
lines = ['# flake8: noqa']
|
lines = ["# flake8: noqa"]
|
||||||
file_processor = processor.FileProcessor('-', default_options, lines)
|
file_processor = processor.FileProcessor("-", default_options, lines)
|
||||||
assert file_processor.should_ignore_file() is True
|
assert file_processor.should_ignore_file() is True
|
||||||
default_options.disable_noqa = True
|
default_options.disable_noqa = True
|
||||||
file_processor = processor.FileProcessor('-', default_options, lines)
|
file_processor = processor.FileProcessor("-", default_options, lines)
|
||||||
assert file_processor.should_ignore_file() is False
|
assert file_processor.should_ignore_file() is False
|
||||||
|
|
||||||
|
|
||||||
@mock.patch('flake8.utils.stdin_get_value')
|
@mock.patch("flake8.utils.stdin_get_value")
|
||||||
def test_read_lines_from_stdin(stdin_get_value, default_options):
|
def test_read_lines_from_stdin(stdin_get_value, default_options):
|
||||||
"""Verify that we use our own utility function to retrieve stdin."""
|
"""Verify that we use our own utility function to retrieve stdin."""
|
||||||
stdin_get_value.return_value = ''
|
stdin_get_value.return_value = ""
|
||||||
processor.FileProcessor('-', default_options)
|
processor.FileProcessor("-", default_options)
|
||||||
stdin_get_value.assert_called_once_with()
|
stdin_get_value.assert_called_once_with()
|
||||||
|
|
||||||
|
|
||||||
@mock.patch('flake8.utils.stdin_get_value')
|
@mock.patch("flake8.utils.stdin_get_value")
|
||||||
def test_stdin_filename_attribute(stdin_get_value, default_options):
|
def test_stdin_filename_attribute(stdin_get_value, default_options):
|
||||||
"""Verify that we update the filename attribute."""
|
"""Verify that we update the filename attribute."""
|
||||||
stdin_get_value.return_value = ''
|
stdin_get_value.return_value = ""
|
||||||
file_processor = processor.FileProcessor('-', default_options)
|
file_processor = processor.FileProcessor("-", default_options)
|
||||||
assert file_processor.filename == 'stdin'
|
assert file_processor.filename == "stdin"
|
||||||
|
|
||||||
|
|
||||||
@mock.patch('flake8.utils.stdin_get_value')
|
@mock.patch("flake8.utils.stdin_get_value")
|
||||||
def test_read_lines_uses_display_name(stdin_get_value, default_options):
|
def test_read_lines_uses_display_name(stdin_get_value, default_options):
|
||||||
"""Verify that when processing stdin we use a display name if present."""
|
"""Verify that when processing stdin we use a display name if present."""
|
||||||
default_options.stdin_display_name = 'display_name.py'
|
default_options.stdin_display_name = "display_name.py"
|
||||||
stdin_get_value.return_value = ''
|
stdin_get_value.return_value = ""
|
||||||
file_processor = processor.FileProcessor('-', default_options)
|
file_processor = processor.FileProcessor("-", default_options)
|
||||||
assert file_processor.filename == 'display_name.py'
|
assert file_processor.filename == "display_name.py"
|
||||||
|
|
||||||
|
|
||||||
@mock.patch('flake8.utils.stdin_get_value')
|
@mock.patch("flake8.utils.stdin_get_value")
|
||||||
def test_read_lines_ignores_empty_display_name(
|
def test_read_lines_ignores_empty_display_name(
|
||||||
stdin_get_value, default_options,
|
stdin_get_value,
|
||||||
|
default_options,
|
||||||
):
|
):
|
||||||
"""Verify that when processing stdin we use a display name if present."""
|
"""Verify that when processing stdin we use a display name if present."""
|
||||||
stdin_get_value.return_value = ''
|
stdin_get_value.return_value = ""
|
||||||
default_options.stdin_display_name = ''
|
default_options.stdin_display_name = ""
|
||||||
file_processor = processor.FileProcessor('-', default_options)
|
file_processor = processor.FileProcessor("-", default_options)
|
||||||
assert file_processor.filename == 'stdin'
|
assert file_processor.filename == "stdin"
|
||||||
|
|
||||||
|
|
||||||
def test_noqa_line_for(default_options):
|
def test_noqa_line_for(default_options):
|
||||||
"""Verify we grab the correct line from the cached lines."""
|
"""Verify we grab the correct line from the cached lines."""
|
||||||
file_processor = processor.FileProcessor('-', default_options, lines=[
|
file_processor = processor.FileProcessor(
|
||||||
'Line 1\n',
|
"-",
|
||||||
'Line 2\n',
|
default_options,
|
||||||
'Line 3\n',
|
lines=[
|
||||||
])
|
"Line 1\n",
|
||||||
|
"Line 2\n",
|
||||||
|
"Line 3\n",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
for i in range(1, 4):
|
for i in range(1, 4):
|
||||||
assert file_processor.noqa_line_for(i) == f'Line {i}\n'
|
assert file_processor.noqa_line_for(i) == f"Line {i}\n"
|
||||||
|
|
||||||
|
|
||||||
def test_noqa_line_for_continuation(default_options):
|
def test_noqa_line_for_continuation(default_options):
|
||||||
|
|
@ -145,15 +159,15 @@ world
|
||||||
""" # 7
|
""" # 7
|
||||||
'''
|
'''
|
||||||
lines = src.splitlines(True)
|
lines = src.splitlines(True)
|
||||||
file_processor = processor.FileProcessor('-', default_options, lines=lines)
|
file_processor = processor.FileProcessor("-", default_options, lines=lines)
|
||||||
|
|
||||||
assert file_processor.noqa_line_for(0) is None
|
assert file_processor.noqa_line_for(0) is None
|
||||||
|
|
||||||
l_1_2 = 'from foo \\\n import bar # 2\n'
|
l_1_2 = "from foo \\\n import bar # 2\n"
|
||||||
assert file_processor.noqa_line_for(1) == l_1_2
|
assert file_processor.noqa_line_for(1) == l_1_2
|
||||||
assert file_processor.noqa_line_for(2) == l_1_2
|
assert file_processor.noqa_line_for(2) == l_1_2
|
||||||
|
|
||||||
assert file_processor.noqa_line_for(3) == '\n'
|
assert file_processor.noqa_line_for(3) == "\n"
|
||||||
|
|
||||||
l_4_7 = 'x = """\nhello\nworld\n""" # 7\n'
|
l_4_7 = 'x = """\nhello\nworld\n""" # 7\n'
|
||||||
for i in (4, 5, 6, 7):
|
for i in (4, 5, 6, 7):
|
||||||
|
|
@ -164,76 +178,104 @@ world
|
||||||
|
|
||||||
def test_noqa_line_for_no_eol_at_end_of_file(default_options):
|
def test_noqa_line_for_no_eol_at_end_of_file(default_options):
|
||||||
"""Verify that we properly handle noqa line at the end of the file."""
|
"""Verify that we properly handle noqa line at the end of the file."""
|
||||||
src = 'from foo \\\nimport bar' # no end of file newline
|
src = "from foo \\\nimport bar" # no end of file newline
|
||||||
lines = src.splitlines(True)
|
lines = src.splitlines(True)
|
||||||
file_processor = processor.FileProcessor('-', default_options, lines=lines)
|
file_processor = processor.FileProcessor("-", default_options, lines=lines)
|
||||||
|
|
||||||
l_1_2 = 'from foo \\\nimport bar'
|
l_1_2 = "from foo \\\nimport bar"
|
||||||
assert file_processor.noqa_line_for(1) == l_1_2
|
assert file_processor.noqa_line_for(1) == l_1_2
|
||||||
assert file_processor.noqa_line_for(2) == l_1_2
|
assert file_processor.noqa_line_for(2) == l_1_2
|
||||||
|
|
||||||
|
|
||||||
def test_next_line(default_options):
|
def test_next_line(default_options):
|
||||||
"""Verify we update the file_processor state for each new line."""
|
"""Verify we update the file_processor state for each new line."""
|
||||||
file_processor = processor.FileProcessor('-', default_options, lines=[
|
file_processor = processor.FileProcessor(
|
||||||
'Line 1',
|
"-",
|
||||||
'Line 2',
|
default_options,
|
||||||
'Line 3',
|
lines=[
|
||||||
])
|
"Line 1",
|
||||||
|
"Line 2",
|
||||||
|
"Line 3",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
for i in range(1, 4):
|
for i in range(1, 4):
|
||||||
assert file_processor.next_line() == f'Line {i}'
|
assert file_processor.next_line() == f"Line {i}"
|
||||||
assert file_processor.line_number == i
|
assert file_processor.line_number == i
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize('params, args, expected_kwargs', [
|
@pytest.mark.parametrize(
|
||||||
({'blank_before': True, 'blank_lines': True},
|
"params, args, expected_kwargs",
|
||||||
None,
|
[
|
||||||
{'blank_before': 0, 'blank_lines': 0}),
|
(
|
||||||
({'noqa': True, 'fake': True},
|
{"blank_before": True, "blank_lines": True},
|
||||||
{'fake': 'foo'},
|
None,
|
||||||
{'noqa': False, 'fake': 'foo'}),
|
{"blank_before": 0, "blank_lines": 0},
|
||||||
({'blank_before': True, 'blank_lines': True, 'noqa': True},
|
),
|
||||||
{'blank_before': 10, 'blank_lines': 5, 'noqa': True},
|
(
|
||||||
{'blank_before': 10, 'blank_lines': 5, 'noqa': True}),
|
{"noqa": True, "fake": True},
|
||||||
({}, {'fake': 'foo'}, {'fake': 'foo'}),
|
{"fake": "foo"},
|
||||||
({'non-existent': False}, {'fake': 'foo'}, {'fake': 'foo'}),
|
{"noqa": False, "fake": "foo"},
|
||||||
])
|
),
|
||||||
|
(
|
||||||
|
{"blank_before": True, "blank_lines": True, "noqa": True},
|
||||||
|
{"blank_before": 10, "blank_lines": 5, "noqa": True},
|
||||||
|
{"blank_before": 10, "blank_lines": 5, "noqa": True},
|
||||||
|
),
|
||||||
|
({}, {"fake": "foo"}, {"fake": "foo"}),
|
||||||
|
({"non-existent": False}, {"fake": "foo"}, {"fake": "foo"}),
|
||||||
|
],
|
||||||
|
)
|
||||||
def test_keyword_arguments_for(params, args, expected_kwargs, default_options):
|
def test_keyword_arguments_for(params, args, expected_kwargs, default_options):
|
||||||
"""Verify the keyword args are generated properly."""
|
"""Verify the keyword args are generated properly."""
|
||||||
file_processor = processor.FileProcessor('-', default_options, lines=[
|
file_processor = processor.FileProcessor(
|
||||||
'Line 1',
|
"-",
|
||||||
])
|
default_options,
|
||||||
|
lines=[
|
||||||
|
"Line 1",
|
||||||
|
],
|
||||||
|
)
|
||||||
kwargs_for = file_processor.keyword_arguments_for
|
kwargs_for = file_processor.keyword_arguments_for
|
||||||
|
|
||||||
assert kwargs_for(params, args) == expected_kwargs
|
assert kwargs_for(params, args) == expected_kwargs
|
||||||
|
|
||||||
|
|
||||||
def test_keyword_arguments_for_does_not_handle_attribute_errors(
|
def test_keyword_arguments_for_does_not_handle_attribute_errors(
|
||||||
default_options,
|
default_options,
|
||||||
):
|
):
|
||||||
"""Verify we re-raise AttributeErrors."""
|
"""Verify we re-raise AttributeErrors."""
|
||||||
file_processor = processor.FileProcessor('-', default_options, lines=[
|
file_processor = processor.FileProcessor(
|
||||||
'Line 1',
|
"-",
|
||||||
])
|
default_options,
|
||||||
|
lines=[
|
||||||
|
"Line 1",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
with pytest.raises(AttributeError):
|
with pytest.raises(AttributeError):
|
||||||
file_processor.keyword_arguments_for({'fake': True})
|
file_processor.keyword_arguments_for({"fake": True})
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize('unsplit_line, expected_lines', [
|
@pytest.mark.parametrize(
|
||||||
('line', []),
|
"unsplit_line, expected_lines",
|
||||||
('line 1\n', ['line 1']),
|
[
|
||||||
('line 1\nline 2\n', ['line 1', 'line 2']),
|
("line", []),
|
||||||
('line 1\n\nline 2\n', ['line 1', '', 'line 2']),
|
("line 1\n", ["line 1"]),
|
||||||
])
|
("line 1\nline 2\n", ["line 1", "line 2"]),
|
||||||
|
("line 1\n\nline 2\n", ["line 1", "", "line 2"]),
|
||||||
|
],
|
||||||
|
)
|
||||||
def test_split_line(unsplit_line, expected_lines, default_options):
|
def test_split_line(unsplit_line, expected_lines, default_options):
|
||||||
"""Verify the token line splitting."""
|
"""Verify the token line splitting."""
|
||||||
file_processor = processor.FileProcessor('-', default_options, lines=[
|
file_processor = processor.FileProcessor(
|
||||||
'Line 1',
|
"-",
|
||||||
])
|
default_options,
|
||||||
|
lines=[
|
||||||
|
"Line 1",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
token = (1, unsplit_line, (0, 0), (0, 0), '')
|
token = (1, unsplit_line, (0, 0), (0, 0), "")
|
||||||
actual_lines = list(file_processor.split_line(token))
|
actual_lines = list(file_processor.split_line(token))
|
||||||
assert expected_lines == actual_lines
|
assert expected_lines == actual_lines
|
||||||
|
|
||||||
|
|
@ -242,9 +284,9 @@ def test_split_line(unsplit_line, expected_lines, default_options):
|
||||||
|
|
||||||
def test_build_ast(default_options):
|
def test_build_ast(default_options):
|
||||||
"""Verify the logic for how we build an AST for plugins."""
|
"""Verify the logic for how we build an AST for plugins."""
|
||||||
file_processor = processor.FileProcessor('-', default_options, lines=[
|
file_processor = processor.FileProcessor(
|
||||||
'a = 1\n'
|
"-", default_options, lines=["a = 1\n"]
|
||||||
])
|
)
|
||||||
|
|
||||||
module = file_processor.build_ast()
|
module = file_processor.build_ast()
|
||||||
assert isinstance(module, ast.Module)
|
assert isinstance(module, ast.Module)
|
||||||
|
|
@ -252,25 +294,25 @@ def test_build_ast(default_options):
|
||||||
|
|
||||||
def test_next_logical_line_updates_the_previous_logical_line(default_options):
|
def test_next_logical_line_updates_the_previous_logical_line(default_options):
|
||||||
"""Verify that we update our tracking of the previous logical line."""
|
"""Verify that we update our tracking of the previous logical line."""
|
||||||
file_processor = processor.FileProcessor('-', default_options, lines=[
|
file_processor = processor.FileProcessor(
|
||||||
'a = 1\n'
|
"-", default_options, lines=["a = 1\n"]
|
||||||
])
|
)
|
||||||
|
|
||||||
file_processor.indent_level = 1
|
file_processor.indent_level = 1
|
||||||
file_processor.logical_line = 'a = 1'
|
file_processor.logical_line = "a = 1"
|
||||||
assert file_processor.previous_logical == ''
|
assert file_processor.previous_logical == ""
|
||||||
assert file_processor.previous_indent_level == 0
|
assert file_processor.previous_indent_level == 0
|
||||||
|
|
||||||
file_processor.next_logical_line()
|
file_processor.next_logical_line()
|
||||||
assert file_processor.previous_logical == 'a = 1'
|
assert file_processor.previous_logical == "a = 1"
|
||||||
assert file_processor.previous_indent_level == 1
|
assert file_processor.previous_indent_level == 1
|
||||||
|
|
||||||
|
|
||||||
def test_visited_new_blank_line(default_options):
|
def test_visited_new_blank_line(default_options):
|
||||||
"""Verify we update the number of blank lines seen."""
|
"""Verify we update the number of blank lines seen."""
|
||||||
file_processor = processor.FileProcessor('-', default_options, lines=[
|
file_processor = processor.FileProcessor(
|
||||||
'a = 1\n'
|
"-", default_options, lines=["a = 1\n"]
|
||||||
])
|
)
|
||||||
|
|
||||||
assert file_processor.blank_lines == 0
|
assert file_processor.blank_lines == 0
|
||||||
file_processor.visited_new_blank_line()
|
file_processor.visited_new_blank_line()
|
||||||
|
|
@ -279,9 +321,9 @@ def test_visited_new_blank_line(default_options):
|
||||||
|
|
||||||
def test_inside_multiline(default_options):
|
def test_inside_multiline(default_options):
|
||||||
"""Verify we update the line number and reset multiline."""
|
"""Verify we update the line number and reset multiline."""
|
||||||
file_processor = processor.FileProcessor('-', default_options, lines=[
|
file_processor = processor.FileProcessor(
|
||||||
'a = 1\n'
|
"-", default_options, lines=["a = 1\n"]
|
||||||
])
|
)
|
||||||
|
|
||||||
assert file_processor.multiline is False
|
assert file_processor.multiline is False
|
||||||
assert file_processor.line_number == 0
|
assert file_processor.line_number == 0
|
||||||
|
|
@ -292,63 +334,87 @@ def test_inside_multiline(default_options):
|
||||||
assert file_processor.multiline is False
|
assert file_processor.multiline is False
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize('string, expected', [
|
@pytest.mark.parametrize(
|
||||||
('""', '""'),
|
"string, expected",
|
||||||
("''", "''"),
|
[
|
||||||
('"a"', '"x"'),
|
('""', '""'),
|
||||||
("'a'", "'x'"),
|
("''", "''"),
|
||||||
('"x"', '"x"'),
|
('"a"', '"x"'),
|
||||||
("'x'", "'x'"),
|
("'a'", "'x'"),
|
||||||
('"abcdef"', '"xxxxxx"'),
|
('"x"', '"x"'),
|
||||||
("'abcdef'", "'xxxxxx'"),
|
("'x'", "'x'"),
|
||||||
('""""""', '""""""'),
|
('"abcdef"', '"xxxxxx"'),
|
||||||
("''''''", "''''''"),
|
("'abcdef'", "'xxxxxx'"),
|
||||||
('"""a"""', '"""x"""'),
|
('""""""', '""""""'),
|
||||||
("'''a'''", "'''x'''"),
|
("''''''", "''''''"),
|
||||||
('"""x"""', '"""x"""'),
|
('"""a"""', '"""x"""'),
|
||||||
("'''x'''", "'''x'''"),
|
("'''a'''", "'''x'''"),
|
||||||
('"""abcdef"""', '"""xxxxxx"""'),
|
('"""x"""', '"""x"""'),
|
||||||
("'''abcdef'''", "'''xxxxxx'''"),
|
("'''x'''", "'''x'''"),
|
||||||
('"""xxxxxx"""', '"""xxxxxx"""'),
|
('"""abcdef"""', '"""xxxxxx"""'),
|
||||||
("'''xxxxxx'''", "'''xxxxxx'''"),
|
("'''abcdef'''", "'''xxxxxx'''"),
|
||||||
])
|
('"""xxxxxx"""', '"""xxxxxx"""'),
|
||||||
|
("'''xxxxxx'''", "'''xxxxxx'''"),
|
||||||
|
],
|
||||||
|
)
|
||||||
def test_mutate_string(string, expected, default_options):
|
def test_mutate_string(string, expected, default_options):
|
||||||
"""Verify we appropriately mutate the string to sanitize it."""
|
"""Verify we appropriately mutate the string to sanitize it."""
|
||||||
actual = processor.mutate_string(string)
|
actual = processor.mutate_string(string)
|
||||||
assert expected == actual
|
assert expected == actual
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize('string, expected', [
|
@pytest.mark.parametrize(
|
||||||
(' ', 4),
|
"string, expected",
|
||||||
(' ', 6),
|
[
|
||||||
('\t', 8),
|
(" ", 4),
|
||||||
('\t\t', 16),
|
(" ", 6),
|
||||||
(' \t', 8),
|
("\t", 8),
|
||||||
(' \t', 16),
|
("\t\t", 16),
|
||||||
])
|
(" \t", 8),
|
||||||
|
(" \t", 16),
|
||||||
|
],
|
||||||
|
)
|
||||||
def test_expand_indent(string, expected):
|
def test_expand_indent(string, expected):
|
||||||
"""Verify we correctly measure the amount of indentation."""
|
"""Verify we correctly measure the amount of indentation."""
|
||||||
actual = processor.expand_indent(string)
|
actual = processor.expand_indent(string)
|
||||||
assert expected == actual
|
assert expected == actual
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize('token, log_string', [
|
@pytest.mark.parametrize(
|
||||||
[(tokenize.COMMENT, '# this is a comment',
|
"token, log_string",
|
||||||
(1, 0), # (start_row, start_column)
|
[
|
||||||
(1, 19), # (end_ro, end_column)
|
[
|
||||||
'# this is a comment',),
|
(
|
||||||
"l.1\t[:19]\tCOMMENT\t'# this is a comment'"],
|
tokenize.COMMENT,
|
||||||
[(tokenize.COMMENT, '# this is a comment',
|
"# this is a comment",
|
||||||
(1, 5), # (start_row, start_column)
|
(1, 0), # (start_row, start_column)
|
||||||
(1, 19), # (end_ro, end_column)
|
(1, 19), # (end_ro, end_column)
|
||||||
'# this is a comment',),
|
"# this is a comment",
|
||||||
"l.1\t[5:19]\tCOMMENT\t'# this is a comment'"],
|
),
|
||||||
[(tokenize.COMMENT, '# this is a comment',
|
"l.1\t[:19]\tCOMMENT\t'# this is a comment'",
|
||||||
(1, 0), # (start_row, start_column)
|
],
|
||||||
(2, 19), # (end_ro, end_column)
|
[
|
||||||
'# this is a comment',),
|
(
|
||||||
"l.1\tl.2\tCOMMENT\t'# this is a comment'"],
|
tokenize.COMMENT,
|
||||||
])
|
"# this is a comment",
|
||||||
|
(1, 5), # (start_row, start_column)
|
||||||
|
(1, 19), # (end_ro, end_column)
|
||||||
|
"# this is a comment",
|
||||||
|
),
|
||||||
|
"l.1\t[5:19]\tCOMMENT\t'# this is a comment'",
|
||||||
|
],
|
||||||
|
[
|
||||||
|
(
|
||||||
|
tokenize.COMMENT,
|
||||||
|
"# this is a comment",
|
||||||
|
(1, 0), # (start_row, start_column)
|
||||||
|
(2, 19), # (end_ro, end_column)
|
||||||
|
"# this is a comment",
|
||||||
|
),
|
||||||
|
"l.1\tl.2\tCOMMENT\t'# this is a comment'",
|
||||||
|
],
|
||||||
|
],
|
||||||
|
)
|
||||||
def test_log_token(token, log_string):
|
def test_log_token(token, log_string):
|
||||||
"""Verify we use the log object passed in."""
|
"""Verify we use the log object passed in."""
|
||||||
log = mock.Mock()
|
log = mock.Mock()
|
||||||
|
|
@ -359,15 +425,18 @@ def test_log_token(token, log_string):
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize('current_count, token_text, expected', [
|
@pytest.mark.parametrize(
|
||||||
(0, '(', 1),
|
"current_count, token_text, expected",
|
||||||
(0, '[', 1),
|
[
|
||||||
(0, '{', 1),
|
(0, "(", 1),
|
||||||
(1, ')', 0),
|
(0, "[", 1),
|
||||||
(1, ']', 0),
|
(0, "{", 1),
|
||||||
(1, '}', 0),
|
(1, ")", 0),
|
||||||
(10, '+', 10),
|
(1, "]", 0),
|
||||||
])
|
(1, "}", 0),
|
||||||
|
(10, "+", 10),
|
||||||
|
],
|
||||||
|
)
|
||||||
def test_count_parentheses(current_count, token_text, expected):
|
def test_count_parentheses(current_count, token_text, expected):
|
||||||
"""Verify our arithmetic is correct."""
|
"""Verify our arithmetic is correct."""
|
||||||
assert processor.count_parentheses(current_count, token_text) == expected
|
assert processor.count_parentheses(current_count, token_text) == expected
|
||||||
|
|
|
||||||
|
|
@ -7,8 +7,8 @@ from flake8.formatting import default
|
||||||
|
|
||||||
def options(**kwargs):
|
def options(**kwargs):
|
||||||
"""Create an argparse.Namespace instance."""
|
"""Create an argparse.Namespace instance."""
|
||||||
kwargs.setdefault('output_file', None)
|
kwargs.setdefault("output_file", None)
|
||||||
kwargs.setdefault('tee', False)
|
kwargs.setdefault("tee", False)
|
||||||
return argparse.Namespace(**kwargs)
|
return argparse.Namespace(**kwargs)
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -18,22 +18,23 @@ def test_caches_filenames_already_printed():
|
||||||
assert formatter.filenames_already_printed == set()
|
assert formatter.filenames_already_printed == set()
|
||||||
|
|
||||||
formatter.format(
|
formatter.format(
|
||||||
style_guide.Violation('code', 'file.py', 1, 1, 'text', 'l'))
|
style_guide.Violation("code", "file.py", 1, 1, "text", "l")
|
||||||
assert formatter.filenames_already_printed == {'file.py'}
|
)
|
||||||
|
assert formatter.filenames_already_printed == {"file.py"}
|
||||||
|
|
||||||
|
|
||||||
def test_only_returns_a_string_once_from_format():
|
def test_only_returns_a_string_once_from_format():
|
||||||
"""Verify format ignores the second error with the same filename."""
|
"""Verify format ignores the second error with the same filename."""
|
||||||
formatter = default.FilenameOnly(options())
|
formatter = default.FilenameOnly(options())
|
||||||
error = style_guide.Violation('code', 'file.py', 1, 1, 'text', '1')
|
error = style_guide.Violation("code", "file.py", 1, 1, "text", "1")
|
||||||
|
|
||||||
assert formatter.format(error) == 'file.py'
|
assert formatter.format(error) == "file.py"
|
||||||
assert formatter.format(error) is None
|
assert formatter.format(error) is None
|
||||||
|
|
||||||
|
|
||||||
def test_show_source_returns_nothing():
|
def test_show_source_returns_nothing():
|
||||||
"""Verify show_source returns nothing."""
|
"""Verify show_source returns nothing."""
|
||||||
formatter = default.FilenameOnly(options())
|
formatter = default.FilenameOnly(options())
|
||||||
error = style_guide.Violation('code', 'file.py', 1, 1, 'text', '1')
|
error = style_guide.Violation("code", "file.py", 1, 1, "text", "1")
|
||||||
|
|
||||||
assert formatter.show_source(error) is None
|
assert formatter.show_source(error) is None
|
||||||
|
|
|
||||||
|
|
@ -23,8 +23,8 @@ def test_get_local_plugins_uses_cli_config():
|
||||||
config_finder = mock.MagicMock()
|
config_finder = mock.MagicMock()
|
||||||
config_finder.cli_config.return_value = config_obj
|
config_finder.cli_config.return_value = config_obj
|
||||||
config_finder.ignore_config_files = False
|
config_finder.ignore_config_files = False
|
||||||
config_obj.get.return_value = ''
|
config_obj.get.return_value = ""
|
||||||
config_file_value = 'foo.ini'
|
config_file_value = "foo.ini"
|
||||||
config_finder.config_file = config_file_value
|
config_finder.config_file = config_file_value
|
||||||
|
|
||||||
config.get_local_plugins(config_finder)
|
config.get_local_plugins(config_finder)
|
||||||
|
|
@ -34,12 +34,12 @@ def test_get_local_plugins_uses_cli_config():
|
||||||
|
|
||||||
def test_get_local_plugins():
|
def test_get_local_plugins():
|
||||||
"""Verify get_local_plugins returns expected plugins."""
|
"""Verify get_local_plugins returns expected plugins."""
|
||||||
config_fixture_path = 'tests/fixtures/config_files/local-plugin.ini'
|
config_fixture_path = "tests/fixtures/config_files/local-plugin.ini"
|
||||||
config_finder = config.ConfigFileFinder('flake8')
|
config_finder = config.ConfigFileFinder("flake8")
|
||||||
|
|
||||||
with mock.patch.object(config_finder, 'local_config_files') as localcfs:
|
with mock.patch.object(config_finder, "local_config_files") as localcfs:
|
||||||
localcfs.return_value = [config_fixture_path]
|
localcfs.return_value = [config_fixture_path]
|
||||||
local_plugins = config.get_local_plugins(config_finder)
|
local_plugins = config.get_local_plugins(config_finder)
|
||||||
|
|
||||||
assert local_plugins.extension == ['XE = test_plugins:ExtensionTestPlugin']
|
assert local_plugins.extension == ["XE = test_plugins:ExtensionTestPlugin"]
|
||||||
assert local_plugins.report == ['XR = test_plugins:ReportTestPlugin']
|
assert local_plugins.report == ["XR = test_plugins:ReportTestPlugin"]
|
||||||
|
|
|
||||||
|
|
@ -21,12 +21,14 @@ def test_get_style_guide():
|
||||||
)
|
)
|
||||||
mockedapp = mock.Mock()
|
mockedapp = mock.Mock()
|
||||||
mockedapp.parse_preliminary_options.return_value = (prelim_opts, [])
|
mockedapp.parse_preliminary_options.return_value = (prelim_opts, [])
|
||||||
mockedapp.program = 'flake8'
|
mockedapp.program = "flake8"
|
||||||
with mock.patch('flake8.api.legacy.config.ConfigFileFinder') as mock_config_finder: # noqa: E501
|
with mock.patch(
|
||||||
|
"flake8.api.legacy.config.ConfigFileFinder"
|
||||||
|
) as mock_config_finder: # noqa: E501
|
||||||
config_finder = ConfigFileFinder(mockedapp.program)
|
config_finder = ConfigFileFinder(mockedapp.program)
|
||||||
mock_config_finder.return_value = config_finder
|
mock_config_finder.return_value = config_finder
|
||||||
|
|
||||||
with mock.patch('flake8.main.application.Application') as application:
|
with mock.patch("flake8.main.application.Application") as application:
|
||||||
application.return_value = mockedapp
|
application.return_value = mockedapp
|
||||||
style_guide = api.get_style_guide()
|
style_guide = api.get_style_guide()
|
||||||
|
|
||||||
|
|
@ -35,7 +37,8 @@ def test_get_style_guide():
|
||||||
mockedapp.find_plugins.assert_called_once_with(config_finder)
|
mockedapp.find_plugins.assert_called_once_with(config_finder)
|
||||||
mockedapp.register_plugin_options.assert_called_once_with()
|
mockedapp.register_plugin_options.assert_called_once_with()
|
||||||
mockedapp.parse_configuration_and_cli.assert_called_once_with(
|
mockedapp.parse_configuration_and_cli.assert_called_once_with(
|
||||||
config_finder, [])
|
config_finder, []
|
||||||
|
)
|
||||||
mockedapp.make_formatter.assert_called_once_with()
|
mockedapp.make_formatter.assert_called_once_with()
|
||||||
mockedapp.make_guide.assert_called_once_with()
|
mockedapp.make_guide.assert_called_once_with()
|
||||||
mockedapp.make_file_checker_manager.assert_called_once_with()
|
mockedapp.make_file_checker_manager.assert_called_once_with()
|
||||||
|
|
@ -45,22 +48,22 @@ def test_get_style_guide():
|
||||||
def test_styleguide_options():
|
def test_styleguide_options():
|
||||||
"""Show that we proxy the StyleGuide.options attribute."""
|
"""Show that we proxy the StyleGuide.options attribute."""
|
||||||
app = mock.Mock()
|
app = mock.Mock()
|
||||||
app.options = 'options'
|
app.options = "options"
|
||||||
style_guide = api.StyleGuide(app)
|
style_guide = api.StyleGuide(app)
|
||||||
assert style_guide.options == 'options'
|
assert style_guide.options == "options"
|
||||||
|
|
||||||
|
|
||||||
def test_styleguide_paths():
|
def test_styleguide_paths():
|
||||||
"""Show that we proxy the StyleGuide.paths attribute."""
|
"""Show that we proxy the StyleGuide.paths attribute."""
|
||||||
app = mock.Mock()
|
app = mock.Mock()
|
||||||
app.paths = 'paths'
|
app.paths = "paths"
|
||||||
style_guide = api.StyleGuide(app)
|
style_guide = api.StyleGuide(app)
|
||||||
assert style_guide.paths == 'paths'
|
assert style_guide.paths == "paths"
|
||||||
|
|
||||||
|
|
||||||
def test_styleguide_check_files():
|
def test_styleguide_check_files():
|
||||||
"""Verify we call the right application methods."""
|
"""Verify we call the right application methods."""
|
||||||
paths = ['foo', 'bar']
|
paths = ["foo", "bar"]
|
||||||
app = mock.Mock()
|
app = mock.Mock()
|
||||||
style_guide = api.StyleGuide(app)
|
style_guide = api.StyleGuide(app)
|
||||||
report = style_guide.check_files(paths)
|
report = style_guide.check_files(paths)
|
||||||
|
|
@ -80,8 +83,8 @@ def test_styleguide_excluded():
|
||||||
file_checker_manager = app.file_checker_manager = mock.Mock()
|
file_checker_manager = app.file_checker_manager = mock.Mock()
|
||||||
style_guide = api.StyleGuide(app)
|
style_guide = api.StyleGuide(app)
|
||||||
|
|
||||||
style_guide.excluded('file.py')
|
style_guide.excluded("file.py")
|
||||||
file_checker_manager.is_path_excluded.assert_called_once_with('file.py')
|
file_checker_manager.is_path_excluded.assert_called_once_with("file.py")
|
||||||
|
|
||||||
|
|
||||||
def test_styleguide_excluded_with_parent():
|
def test_styleguide_excluded_with_parent():
|
||||||
|
|
@ -95,10 +98,10 @@ def test_styleguide_excluded_with_parent():
|
||||||
file_checker_manager.is_path_excluded.return_value = False
|
file_checker_manager.is_path_excluded.return_value = False
|
||||||
style_guide = api.StyleGuide(app)
|
style_guide = api.StyleGuide(app)
|
||||||
|
|
||||||
style_guide.excluded('file.py', 'parent')
|
style_guide.excluded("file.py", "parent")
|
||||||
assert file_checker_manager.is_path_excluded.call_args_list == [
|
assert file_checker_manager.is_path_excluded.call_args_list == [
|
||||||
mock.call('file.py'),
|
mock.call("file.py"),
|
||||||
mock.call(os.path.join('parent', 'file.py')),
|
mock.call(os.path.join("parent", "file.py")),
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -123,7 +126,7 @@ def test_styleguide_init_report_with_non_subclass():
|
||||||
|
|
||||||
def test_styleguide_init_report():
|
def test_styleguide_init_report():
|
||||||
"""Verify we do the right incantation for the Application."""
|
"""Verify we do the right incantation for the Application."""
|
||||||
app = mock.Mock(guide='fake')
|
app = mock.Mock(guide="fake")
|
||||||
style_guide = api.StyleGuide(app)
|
style_guide = api.StyleGuide(app)
|
||||||
|
|
||||||
class FakeFormatter(formatter.BaseFormatter):
|
class FakeFormatter(formatter.BaseFormatter):
|
||||||
|
|
@ -140,16 +143,16 @@ def test_styleguide_input_file():
|
||||||
"""Verify we call StyleGuide.check_files with the filename."""
|
"""Verify we call StyleGuide.check_files with the filename."""
|
||||||
app = mock.Mock()
|
app = mock.Mock()
|
||||||
style_guide = api.StyleGuide(app)
|
style_guide = api.StyleGuide(app)
|
||||||
with mock.patch.object(style_guide, 'check_files') as check_files:
|
with mock.patch.object(style_guide, "check_files") as check_files:
|
||||||
style_guide.input_file('file.py')
|
style_guide.input_file("file.py")
|
||||||
check_files.assert_called_once_with(['file.py'])
|
check_files.assert_called_once_with(["file.py"])
|
||||||
|
|
||||||
|
|
||||||
def test_report_total_errors():
|
def test_report_total_errors():
|
||||||
"""Verify total errors is just a proxy attribute."""
|
"""Verify total errors is just a proxy attribute."""
|
||||||
app = mock.Mock(result_count='Fake count')
|
app = mock.Mock(result_count="Fake count")
|
||||||
report = api.Report(app)
|
report = api.Report(app)
|
||||||
assert report.total_errors == 'Fake count'
|
assert report.total_errors == "Fake count"
|
||||||
|
|
||||||
|
|
||||||
def test_report_get_statistics():
|
def test_report_get_statistics():
|
||||||
|
|
@ -160,5 +163,5 @@ def test_report_get_statistics():
|
||||||
app = mock.Mock(guide=style_guide)
|
app = mock.Mock(guide=style_guide)
|
||||||
|
|
||||||
report = api.Report(app)
|
report = api.Report(app)
|
||||||
assert report.get_statistics('E') == []
|
assert report.get_statistics("E") == []
|
||||||
stats.statistics_for.assert_called_once_with('E')
|
stats.statistics_for.assert_called_once_with("E")
|
||||||
|
|
|
||||||
|
|
@ -11,47 +11,54 @@ from flake8.options import manager
|
||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
def optmanager():
|
def optmanager():
|
||||||
"""Generate an OptionManager with simple values."""
|
"""Generate an OptionManager with simple values."""
|
||||||
return manager.OptionManager(prog='flake8', version='3.0.0a1')
|
return manager.OptionManager(prog="flake8", version="3.0.0a1")
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
def config_finder():
|
def config_finder():
|
||||||
"""Generate a simple ConfigFileFinder."""
|
"""Generate a simple ConfigFileFinder."""
|
||||||
return config.ConfigFileFinder('flake8')
|
return config.ConfigFileFinder("flake8")
|
||||||
|
|
||||||
|
|
||||||
def test_parse_cli_config(optmanager, config_finder):
|
def test_parse_cli_config(optmanager, config_finder):
|
||||||
"""Parse the specified config file as a cli config file."""
|
"""Parse the specified config file as a cli config file."""
|
||||||
optmanager.add_option('--exclude', parse_from_config=True,
|
optmanager.add_option(
|
||||||
comma_separated_list=True,
|
"--exclude",
|
||||||
normalize_paths=True)
|
parse_from_config=True,
|
||||||
optmanager.add_option('--ignore', parse_from_config=True,
|
comma_separated_list=True,
|
||||||
comma_separated_list=True)
|
normalize_paths=True,
|
||||||
optmanager.add_option('--quiet', parse_from_config=True,
|
)
|
||||||
action='count')
|
optmanager.add_option(
|
||||||
|
"--ignore", parse_from_config=True, comma_separated_list=True
|
||||||
|
)
|
||||||
|
optmanager.add_option("--quiet", parse_from_config=True, action="count")
|
||||||
parser = config.MergedConfigParser(optmanager, config_finder)
|
parser = config.MergedConfigParser(optmanager, config_finder)
|
||||||
|
|
||||||
config_file = 'tests/fixtures/config_files/cli-specified.ini'
|
config_file = "tests/fixtures/config_files/cli-specified.ini"
|
||||||
parsed_config = parser.parse_cli_config(config_file)
|
parsed_config = parser.parse_cli_config(config_file)
|
||||||
|
|
||||||
config_dir = os.path.dirname(config_file)
|
config_dir = os.path.dirname(config_file)
|
||||||
assert parsed_config == {
|
assert parsed_config == {
|
||||||
'ignore': ['E123', 'W234', 'E111'],
|
"ignore": ["E123", "W234", "E111"],
|
||||||
'exclude': [
|
"exclude": [
|
||||||
os.path.abspath(os.path.join(config_dir, 'foo/')),
|
os.path.abspath(os.path.join(config_dir, "foo/")),
|
||||||
os.path.abspath(os.path.join(config_dir, 'bar/')),
|
os.path.abspath(os.path.join(config_dir, "bar/")),
|
||||||
os.path.abspath(os.path.join(config_dir, 'bogus/')),
|
os.path.abspath(os.path.join(config_dir, "bogus/")),
|
||||||
],
|
],
|
||||||
'quiet': 1,
|
"quiet": 1,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize('filename,is_configured_by', [
|
@pytest.mark.parametrize(
|
||||||
('tests/fixtures/config_files/cli-specified.ini', True),
|
"filename,is_configured_by",
|
||||||
('tests/fixtures/config_files/no-flake8-section.ini', False),
|
[
|
||||||
])
|
("tests/fixtures/config_files/cli-specified.ini", True),
|
||||||
|
("tests/fixtures/config_files/no-flake8-section.ini", False),
|
||||||
|
],
|
||||||
|
)
|
||||||
def test_is_configured_by(
|
def test_is_configured_by(
|
||||||
filename, is_configured_by, optmanager, config_finder):
|
filename, is_configured_by, optmanager, config_finder
|
||||||
|
):
|
||||||
"""Verify the behaviour of the is_configured_by method."""
|
"""Verify the behaviour of the is_configured_by method."""
|
||||||
parsed_config, _ = config.ConfigFileFinder._read_config(filename)
|
parsed_config, _ = config.ConfigFileFinder._read_config(filename)
|
||||||
parser = config.MergedConfigParser(optmanager, config_finder)
|
parser = config.MergedConfigParser(optmanager, config_finder)
|
||||||
|
|
@ -61,83 +68,94 @@ def test_is_configured_by(
|
||||||
|
|
||||||
def test_parse_user_config(optmanager, config_finder):
|
def test_parse_user_config(optmanager, config_finder):
|
||||||
"""Verify parsing of user config files."""
|
"""Verify parsing of user config files."""
|
||||||
optmanager.add_option('--exclude', parse_from_config=True,
|
optmanager.add_option(
|
||||||
comma_separated_list=True,
|
"--exclude",
|
||||||
normalize_paths=True)
|
parse_from_config=True,
|
||||||
optmanager.add_option('--ignore', parse_from_config=True,
|
comma_separated_list=True,
|
||||||
comma_separated_list=True)
|
normalize_paths=True,
|
||||||
optmanager.add_option('--quiet', parse_from_config=True,
|
)
|
||||||
action='count')
|
optmanager.add_option(
|
||||||
|
"--ignore", parse_from_config=True, comma_separated_list=True
|
||||||
|
)
|
||||||
|
optmanager.add_option("--quiet", parse_from_config=True, action="count")
|
||||||
parser = config.MergedConfigParser(optmanager, config_finder)
|
parser = config.MergedConfigParser(optmanager, config_finder)
|
||||||
|
|
||||||
config_finder.user_config_file = ('tests/fixtures/config_files/'
|
config_finder.user_config_file = (
|
||||||
'cli-specified.ini')
|
"tests/fixtures/config_files/" "cli-specified.ini"
|
||||||
|
)
|
||||||
parsed_config = parser.parse_user_config()
|
parsed_config = parser.parse_user_config()
|
||||||
|
|
||||||
assert parsed_config == {
|
assert parsed_config == {
|
||||||
'ignore': ['E123', 'W234', 'E111'],
|
"ignore": ["E123", "W234", "E111"],
|
||||||
'exclude': [
|
"exclude": [
|
||||||
os.path.abspath('foo/'),
|
os.path.abspath("foo/"),
|
||||||
os.path.abspath('bar/'),
|
os.path.abspath("bar/"),
|
||||||
os.path.abspath('bogus/'),
|
os.path.abspath("bogus/"),
|
||||||
],
|
],
|
||||||
'quiet': 1,
|
"quiet": 1,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
def test_parse_local_config(optmanager, config_finder):
|
def test_parse_local_config(optmanager, config_finder):
|
||||||
"""Verify parsing of local config files."""
|
"""Verify parsing of local config files."""
|
||||||
optmanager.add_option('--exclude', parse_from_config=True,
|
optmanager.add_option(
|
||||||
comma_separated_list=True,
|
"--exclude",
|
||||||
normalize_paths=True)
|
parse_from_config=True,
|
||||||
optmanager.add_option('--ignore', parse_from_config=True,
|
comma_separated_list=True,
|
||||||
comma_separated_list=True)
|
normalize_paths=True,
|
||||||
optmanager.add_option('--quiet', parse_from_config=True,
|
)
|
||||||
action='count')
|
optmanager.add_option(
|
||||||
|
"--ignore", parse_from_config=True, comma_separated_list=True
|
||||||
|
)
|
||||||
|
optmanager.add_option("--quiet", parse_from_config=True, action="count")
|
||||||
parser = config.MergedConfigParser(optmanager, config_finder)
|
parser = config.MergedConfigParser(optmanager, config_finder)
|
||||||
|
|
||||||
with mock.patch.object(config_finder, 'local_config_files') as localcfs:
|
with mock.patch.object(config_finder, "local_config_files") as localcfs:
|
||||||
localcfs.return_value = [
|
localcfs.return_value = [
|
||||||
'tests/fixtures/config_files/cli-specified.ini'
|
"tests/fixtures/config_files/cli-specified.ini"
|
||||||
]
|
]
|
||||||
parsed_config = parser.parse_local_config()
|
parsed_config = parser.parse_local_config()
|
||||||
|
|
||||||
assert parsed_config == {
|
assert parsed_config == {
|
||||||
'ignore': ['E123', 'W234', 'E111'],
|
"ignore": ["E123", "W234", "E111"],
|
||||||
'exclude': [
|
"exclude": [
|
||||||
os.path.abspath('foo/'),
|
os.path.abspath("foo/"),
|
||||||
os.path.abspath('bar/'),
|
os.path.abspath("bar/"),
|
||||||
os.path.abspath('bogus/'),
|
os.path.abspath("bogus/"),
|
||||||
],
|
],
|
||||||
'quiet': 1,
|
"quiet": 1,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
def test_merge_user_and_local_config(optmanager, config_finder):
|
def test_merge_user_and_local_config(optmanager, config_finder):
|
||||||
"""Verify merging of parsed user and local config files."""
|
"""Verify merging of parsed user and local config files."""
|
||||||
optmanager.add_option('--exclude', parse_from_config=True,
|
optmanager.add_option(
|
||||||
comma_separated_list=True,
|
"--exclude",
|
||||||
normalize_paths=True)
|
parse_from_config=True,
|
||||||
optmanager.add_option('--ignore', parse_from_config=True,
|
comma_separated_list=True,
|
||||||
comma_separated_list=True)
|
normalize_paths=True,
|
||||||
optmanager.add_option('--select', parse_from_config=True,
|
)
|
||||||
comma_separated_list=True)
|
optmanager.add_option(
|
||||||
|
"--ignore", parse_from_config=True, comma_separated_list=True
|
||||||
|
)
|
||||||
|
optmanager.add_option(
|
||||||
|
"--select", parse_from_config=True, comma_separated_list=True
|
||||||
|
)
|
||||||
parser = config.MergedConfigParser(optmanager, config_finder)
|
parser = config.MergedConfigParser(optmanager, config_finder)
|
||||||
|
|
||||||
with mock.patch.object(config_finder, 'local_config_files') as localcfs:
|
with mock.patch.object(config_finder, "local_config_files") as localcfs:
|
||||||
localcfs.return_value = [
|
localcfs.return_value = [
|
||||||
'tests/fixtures/config_files/local-config.ini'
|
"tests/fixtures/config_files/local-config.ini"
|
||||||
]
|
]
|
||||||
config_finder.user_config_file = ('tests/fixtures/config_files/'
|
config_finder.user_config_file = (
|
||||||
'user-config.ini')
|
"tests/fixtures/config_files/" "user-config.ini"
|
||||||
|
)
|
||||||
parsed_config = parser.merge_user_and_local_config()
|
parsed_config = parser.merge_user_and_local_config()
|
||||||
|
|
||||||
assert parsed_config == {
|
assert parsed_config == {
|
||||||
'exclude': [
|
"exclude": [os.path.abspath("docs/")],
|
||||||
os.path.abspath('docs/')
|
"ignore": ["D203"],
|
||||||
],
|
"select": ["E", "W", "F"],
|
||||||
'ignore': ['D203'],
|
|
||||||
'select': ['E', 'W', 'F'],
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -154,7 +172,7 @@ def test_parse_isolates_config(optmanager):
|
||||||
|
|
||||||
def test_parse_uses_cli_config(optmanager):
|
def test_parse_uses_cli_config(optmanager):
|
||||||
"""Verify behaviour of the parse method with a specified config."""
|
"""Verify behaviour of the parse method with a specified config."""
|
||||||
config_file_value = 'foo.ini'
|
config_file_value = "foo.ini"
|
||||||
config_finder = mock.MagicMock()
|
config_finder = mock.MagicMock()
|
||||||
config_finder.config_file = config_file_value
|
config_finder.config_file = config_file_value
|
||||||
config_finder.ignore_config_files = False
|
config_finder.ignore_config_files = False
|
||||||
|
|
@ -164,62 +182,74 @@ def test_parse_uses_cli_config(optmanager):
|
||||||
config_finder.cli_config.assert_called_once_with(config_file_value)
|
config_finder.cli_config.assert_called_once_with(config_file_value)
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize('config_fixture_path', [
|
@pytest.mark.parametrize(
|
||||||
'tests/fixtures/config_files/cli-specified.ini',
|
"config_fixture_path",
|
||||||
'tests/fixtures/config_files/cli-specified-with-inline-comments.ini',
|
[
|
||||||
'tests/fixtures/config_files/cli-specified-without-inline-comments.ini',
|
"tests/fixtures/config_files/cli-specified.ini",
|
||||||
])
|
"tests/fixtures/config_files/cli-specified-with-inline-comments.ini",
|
||||||
|
"tests/fixtures/config_files/cli-specified-without-inline-comments.ini", # noqa: E501
|
||||||
|
],
|
||||||
|
)
|
||||||
def test_parsed_configs_are_equivalent(
|
def test_parsed_configs_are_equivalent(
|
||||||
optmanager, config_finder, config_fixture_path):
|
optmanager, config_finder, config_fixture_path
|
||||||
|
):
|
||||||
"""Verify the each file matches the expected parsed output.
|
"""Verify the each file matches the expected parsed output.
|
||||||
|
|
||||||
This is used to ensure our documented behaviour does not regress.
|
This is used to ensure our documented behaviour does not regress.
|
||||||
"""
|
"""
|
||||||
optmanager.add_option('--exclude', parse_from_config=True,
|
optmanager.add_option(
|
||||||
comma_separated_list=True,
|
"--exclude",
|
||||||
normalize_paths=True)
|
parse_from_config=True,
|
||||||
optmanager.add_option('--ignore', parse_from_config=True,
|
comma_separated_list=True,
|
||||||
comma_separated_list=True)
|
normalize_paths=True,
|
||||||
|
)
|
||||||
|
optmanager.add_option(
|
||||||
|
"--ignore", parse_from_config=True, comma_separated_list=True
|
||||||
|
)
|
||||||
parser = config.MergedConfigParser(optmanager, config_finder)
|
parser = config.MergedConfigParser(optmanager, config_finder)
|
||||||
|
|
||||||
with mock.patch.object(config_finder, 'local_config_files') as localcfs:
|
with mock.patch.object(config_finder, "local_config_files") as localcfs:
|
||||||
localcfs.return_value = [config_fixture_path]
|
localcfs.return_value = [config_fixture_path]
|
||||||
with mock.patch.object(config_finder,
|
with mock.patch.object(config_finder, "user_config_file") as usercf:
|
||||||
'user_config_file') as usercf:
|
usercf.return_value = ""
|
||||||
usercf.return_value = ''
|
|
||||||
parsed_config = parser.merge_user_and_local_config()
|
parsed_config = parser.merge_user_and_local_config()
|
||||||
|
|
||||||
assert parsed_config['ignore'] == ['E123', 'W234', 'E111']
|
assert parsed_config["ignore"] == ["E123", "W234", "E111"]
|
||||||
assert parsed_config['exclude'] == [
|
assert parsed_config["exclude"] == [
|
||||||
os.path.abspath('foo/'),
|
os.path.abspath("foo/"),
|
||||||
os.path.abspath('bar/'),
|
os.path.abspath("bar/"),
|
||||||
os.path.abspath('bogus/'),
|
os.path.abspath("bogus/"),
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize('config_file', [
|
@pytest.mark.parametrize(
|
||||||
'tests/fixtures/config_files/config-with-hyphenated-options.ini'
|
"config_file",
|
||||||
])
|
["tests/fixtures/config_files/config-with-hyphenated-options.ini"],
|
||||||
|
)
|
||||||
def test_parsed_hyphenated_and_underscored_names(
|
def test_parsed_hyphenated_and_underscored_names(
|
||||||
optmanager, config_finder, config_file):
|
optmanager, config_finder, config_file
|
||||||
|
):
|
||||||
"""Verify we find hyphenated option names as well as underscored.
|
"""Verify we find hyphenated option names as well as underscored.
|
||||||
|
|
||||||
This tests for options like --max-line-length and --enable-extensions
|
This tests for options like --max-line-length and --enable-extensions
|
||||||
which are able to be specified either as max-line-length or
|
which are able to be specified either as max-line-length or
|
||||||
max_line_length in our config files.
|
max_line_length in our config files.
|
||||||
"""
|
"""
|
||||||
optmanager.add_option('--max-line-length', parse_from_config=True,
|
optmanager.add_option(
|
||||||
type=int)
|
"--max-line-length", parse_from_config=True, type=int
|
||||||
optmanager.add_option('--enable-extensions', parse_from_config=True,
|
)
|
||||||
comma_separated_list=True)
|
optmanager.add_option(
|
||||||
|
"--enable-extensions",
|
||||||
|
parse_from_config=True,
|
||||||
|
comma_separated_list=True,
|
||||||
|
)
|
||||||
parser = config.MergedConfigParser(optmanager, config_finder)
|
parser = config.MergedConfigParser(optmanager, config_finder)
|
||||||
|
|
||||||
with mock.patch.object(config_finder, 'local_config_files') as localcfs:
|
with mock.patch.object(config_finder, "local_config_files") as localcfs:
|
||||||
localcfs.return_value = [config_file]
|
localcfs.return_value = [config_file]
|
||||||
with mock.patch.object(config_finder,
|
with mock.patch.object(config_finder, "user_config_file") as usercf:
|
||||||
'user_config_file') as usercf:
|
usercf.return_value = ""
|
||||||
usercf.return_value = ''
|
|
||||||
parsed_config = parser.merge_user_and_local_config()
|
parsed_config = parser.merge_user_and_local_config()
|
||||||
|
|
||||||
assert parsed_config['max_line_length'] == 110
|
assert parsed_config["max_line_length"] == 110
|
||||||
assert parsed_config['enable_extensions'] == ['H101', 'H235']
|
assert parsed_config["enable_extensions"] == ["H101", "H235"]
|
||||||
|
|
|
||||||
|
|
@ -7,15 +7,15 @@ from flake8.formatting import default
|
||||||
|
|
||||||
def options(**kwargs):
|
def options(**kwargs):
|
||||||
"""Create an argparse.Namespace instance."""
|
"""Create an argparse.Namespace instance."""
|
||||||
kwargs.setdefault('output_file', None)
|
kwargs.setdefault("output_file", None)
|
||||||
kwargs.setdefault('tee', False)
|
kwargs.setdefault("tee", False)
|
||||||
return argparse.Namespace(**kwargs)
|
return argparse.Namespace(**kwargs)
|
||||||
|
|
||||||
|
|
||||||
def test_format_returns_nothing():
|
def test_format_returns_nothing():
|
||||||
"""Verify Nothing.format returns None."""
|
"""Verify Nothing.format returns None."""
|
||||||
formatter = default.Nothing(options())
|
formatter = default.Nothing(options())
|
||||||
error = style_guide.Violation('code', 'file.py', 1, 1, 'text', '1')
|
error = style_guide.Violation("code", "file.py", 1, 1, "text", "1")
|
||||||
|
|
||||||
assert formatter.format(error) is None
|
assert formatter.format(error) is None
|
||||||
|
|
||||||
|
|
@ -23,6 +23,6 @@ def test_format_returns_nothing():
|
||||||
def test_show_source_returns_nothing():
|
def test_show_source_returns_nothing():
|
||||||
"""Verify Nothing.show_source returns None."""
|
"""Verify Nothing.show_source returns None."""
|
||||||
formatter = default.Nothing(options())
|
formatter = default.Nothing(options())
|
||||||
error = style_guide.Violation('code', 'file.py', 1, 1, 'text', '1')
|
error = style_guide.Violation("code", "file.py", 1, 1, "text", "1")
|
||||||
|
|
||||||
assert formatter.show_source(error) is None
|
assert formatter.show_source(error) is None
|
||||||
|
|
|
||||||
|
|
@ -10,9 +10,9 @@ from flake8.options import manager
|
||||||
def test_to_argparse():
|
def test_to_argparse():
|
||||||
"""Test conversion to an argparse arguments."""
|
"""Test conversion to an argparse arguments."""
|
||||||
opt = manager.Option(
|
opt = manager.Option(
|
||||||
short_option_name='-t',
|
short_option_name="-t",
|
||||||
long_option_name='--test',
|
long_option_name="--test",
|
||||||
action='count',
|
action="count",
|
||||||
parse_from_config=True,
|
parse_from_config=True,
|
||||||
normalize_paths=True,
|
normalize_paths=True,
|
||||||
)
|
)
|
||||||
|
|
@ -20,42 +20,44 @@ def test_to_argparse():
|
||||||
assert opt.parse_from_config is True
|
assert opt.parse_from_config is True
|
||||||
|
|
||||||
args, kwargs = opt.to_argparse()
|
args, kwargs = opt.to_argparse()
|
||||||
assert args == ['-t', '--test']
|
assert args == ["-t", "--test"]
|
||||||
assert kwargs == {'action': 'count', 'type': mock.ANY}
|
assert kwargs == {"action": "count", "type": mock.ANY}
|
||||||
assert isinstance(kwargs['type'], functools.partial)
|
assert isinstance(kwargs["type"], functools.partial)
|
||||||
|
|
||||||
|
|
||||||
def test_to_optparse():
|
def test_to_optparse():
|
||||||
"""Test that .to_optparse() produces a useful error message."""
|
"""Test that .to_optparse() produces a useful error message."""
|
||||||
with pytest.raises(AttributeError) as excinfo:
|
with pytest.raises(AttributeError) as excinfo:
|
||||||
manager.Option('--foo').to_optparse
|
manager.Option("--foo").to_optparse
|
||||||
msg, = excinfo.value.args
|
(msg,) = excinfo.value.args
|
||||||
assert msg == 'to_optparse: flake8 now uses argparse'
|
assert msg == "to_optparse: flake8 now uses argparse"
|
||||||
|
|
||||||
|
|
||||||
def test_to_argparse_creates_an_option_as_we_expect():
|
def test_to_argparse_creates_an_option_as_we_expect():
|
||||||
"""Show that we pass all keyword args to argparse."""
|
"""Show that we pass all keyword args to argparse."""
|
||||||
opt = manager.Option('-t', '--test', action='count')
|
opt = manager.Option("-t", "--test", action="count")
|
||||||
args, kwargs = opt.to_argparse()
|
args, kwargs = opt.to_argparse()
|
||||||
assert args == ['-t', '--test']
|
assert args == ["-t", "--test"]
|
||||||
assert kwargs == {'action': 'count'}
|
assert kwargs == {"action": "count"}
|
||||||
|
|
||||||
|
|
||||||
def test_config_name_generation():
|
def test_config_name_generation():
|
||||||
"""Show that we generate the config name deterministically."""
|
"""Show that we generate the config name deterministically."""
|
||||||
opt = manager.Option(long_option_name='--some-very-long-option-name',
|
opt = manager.Option(
|
||||||
parse_from_config=True)
|
long_option_name="--some-very-long-option-name",
|
||||||
|
parse_from_config=True,
|
||||||
|
)
|
||||||
|
|
||||||
assert opt.config_name == 'some_very_long_option_name'
|
assert opt.config_name == "some_very_long_option_name"
|
||||||
|
|
||||||
|
|
||||||
def test_config_name_needs_long_option_name():
|
def test_config_name_needs_long_option_name():
|
||||||
"""Show that we error out if the Option should be parsed from config."""
|
"""Show that we error out if the Option should be parsed from config."""
|
||||||
with pytest.raises(ValueError):
|
with pytest.raises(ValueError):
|
||||||
manager.Option('-s', parse_from_config=True)
|
manager.Option("-s", parse_from_config=True)
|
||||||
|
|
||||||
|
|
||||||
def test_dest_is_not_overridden():
|
def test_dest_is_not_overridden():
|
||||||
"""Show that we do not override custom destinations."""
|
"""Show that we do not override custom destinations."""
|
||||||
opt = manager.Option('-s', '--short', dest='something_not_short')
|
opt = manager.Option("-s", "--short", dest="something_not_short")
|
||||||
assert opt.dest == 'something_not_short'
|
assert opt.dest == "something_not_short"
|
||||||
|
|
|
||||||
|
|
@ -9,13 +9,13 @@ from flake8 import utils
|
||||||
from flake8.main.options import JobsArgument
|
from flake8.main.options import JobsArgument
|
||||||
from flake8.options import manager
|
from flake8.options import manager
|
||||||
|
|
||||||
TEST_VERSION = '3.0.0b1'
|
TEST_VERSION = "3.0.0b1"
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
def optmanager():
|
def optmanager():
|
||||||
"""Generate a simple OptionManager with default test arguments."""
|
"""Generate a simple OptionManager with default test arguments."""
|
||||||
return manager.OptionManager(prog='flake8', version=TEST_VERSION)
|
return manager.OptionManager(prog="flake8", version=TEST_VERSION)
|
||||||
|
|
||||||
|
|
||||||
def test_option_manager_creates_option_parser(optmanager):
|
def test_option_manager_creates_option_parser(optmanager):
|
||||||
|
|
@ -27,30 +27,29 @@ def test_option_manager_including_parent_options():
|
||||||
"""Verify parent options are included in the parsed options."""
|
"""Verify parent options are included in the parsed options."""
|
||||||
# GIVEN
|
# GIVEN
|
||||||
parent_parser = argparse.ArgumentParser(add_help=False)
|
parent_parser = argparse.ArgumentParser(add_help=False)
|
||||||
parent_parser.add_argument('--parent')
|
parent_parser.add_argument("--parent")
|
||||||
|
|
||||||
# WHEN
|
# WHEN
|
||||||
optmanager = manager.OptionManager(
|
optmanager = manager.OptionManager(
|
||||||
prog='flake8',
|
prog="flake8", version=TEST_VERSION, parents=[parent_parser]
|
||||||
version=TEST_VERSION,
|
)
|
||||||
parents=[parent_parser])
|
option, _ = optmanager.parse_args(["--parent", "foo"])
|
||||||
option, _ = optmanager.parse_args(['--parent', 'foo'])
|
|
||||||
|
|
||||||
# THEN
|
# THEN
|
||||||
assert option.parent == 'foo'
|
assert option.parent == "foo"
|
||||||
|
|
||||||
|
|
||||||
def test_parse_args_forwarding_default_values(optmanager):
|
def test_parse_args_forwarding_default_values(optmanager):
|
||||||
"""Verify default provided values are present in the final result."""
|
"""Verify default provided values are present in the final result."""
|
||||||
namespace = argparse.Namespace(foo='bar')
|
namespace = argparse.Namespace(foo="bar")
|
||||||
options, args = optmanager.parse_args([], namespace)
|
options, args = optmanager.parse_args([], namespace)
|
||||||
assert options.foo == 'bar'
|
assert options.foo == "bar"
|
||||||
|
|
||||||
|
|
||||||
def test_parse_args_forwarding_type_coercion(optmanager):
|
def test_parse_args_forwarding_type_coercion(optmanager):
|
||||||
"""Verify default provided values are type converted from add_option."""
|
"""Verify default provided values are type converted from add_option."""
|
||||||
optmanager.add_option('--foo', type=int)
|
optmanager.add_option("--foo", type=int)
|
||||||
namespace = argparse.Namespace(foo='5')
|
namespace = argparse.Namespace(foo="5")
|
||||||
options, args = optmanager.parse_args([], namespace)
|
options, args = optmanager.parse_args([], namespace)
|
||||||
assert options.foo == 5
|
assert options.foo == 5
|
||||||
|
|
||||||
|
|
@ -60,8 +59,8 @@ def test_add_option_short_option_only(optmanager):
|
||||||
assert optmanager.options == []
|
assert optmanager.options == []
|
||||||
assert optmanager.config_options_dict == {}
|
assert optmanager.config_options_dict == {}
|
||||||
|
|
||||||
optmanager.add_option('-s', help='Test short opt')
|
optmanager.add_option("-s", help="Test short opt")
|
||||||
assert optmanager.options[0].short_option_name == '-s'
|
assert optmanager.options[0].short_option_name == "-s"
|
||||||
|
|
||||||
|
|
||||||
def test_add_option_long_option_only(optmanager):
|
def test_add_option_long_option_only(optmanager):
|
||||||
|
|
@ -69,9 +68,9 @@ def test_add_option_long_option_only(optmanager):
|
||||||
assert optmanager.options == []
|
assert optmanager.options == []
|
||||||
assert optmanager.config_options_dict == {}
|
assert optmanager.config_options_dict == {}
|
||||||
|
|
||||||
optmanager.add_option('--long', help='Test long opt')
|
optmanager.add_option("--long", help="Test long opt")
|
||||||
assert optmanager.options[0].short_option_name is manager._ARG.NO
|
assert optmanager.options[0].short_option_name is manager._ARG.NO
|
||||||
assert optmanager.options[0].long_option_name == '--long'
|
assert optmanager.options[0].long_option_name == "--long"
|
||||||
|
|
||||||
|
|
||||||
def test_add_short_and_long_option_names(optmanager):
|
def test_add_short_and_long_option_names(optmanager):
|
||||||
|
|
@ -79,9 +78,9 @@ def test_add_short_and_long_option_names(optmanager):
|
||||||
assert optmanager.options == []
|
assert optmanager.options == []
|
||||||
assert optmanager.config_options_dict == {}
|
assert optmanager.config_options_dict == {}
|
||||||
|
|
||||||
optmanager.add_option('-b', '--both', help='Test both opts')
|
optmanager.add_option("-b", "--both", help="Test both opts")
|
||||||
assert optmanager.options[0].short_option_name == '-b'
|
assert optmanager.options[0].short_option_name == "-b"
|
||||||
assert optmanager.options[0].long_option_name == '--both'
|
assert optmanager.options[0].long_option_name == "--both"
|
||||||
|
|
||||||
|
|
||||||
def test_add_option_with_custom_args(optmanager):
|
def test_add_option_with_custom_args(optmanager):
|
||||||
|
|
@ -89,11 +88,11 @@ def test_add_option_with_custom_args(optmanager):
|
||||||
assert optmanager.options == []
|
assert optmanager.options == []
|
||||||
assert optmanager.config_options_dict == {}
|
assert optmanager.config_options_dict == {}
|
||||||
|
|
||||||
optmanager.add_option('--parse', parse_from_config=True)
|
optmanager.add_option("--parse", parse_from_config=True)
|
||||||
optmanager.add_option('--commas', comma_separated_list=True)
|
optmanager.add_option("--commas", comma_separated_list=True)
|
||||||
optmanager.add_option('--files', normalize_paths=True)
|
optmanager.add_option("--files", normalize_paths=True)
|
||||||
|
|
||||||
attrs = ['parse_from_config', 'comma_separated_list', 'normalize_paths']
|
attrs = ["parse_from_config", "comma_separated_list", "normalize_paths"]
|
||||||
for option, attr in zip(optmanager.options, attrs):
|
for option, attr in zip(optmanager.options, attrs):
|
||||||
assert getattr(option, attr) is True
|
assert getattr(option, attr) is True
|
||||||
|
|
||||||
|
|
@ -103,10 +102,10 @@ def test_parse_args_normalize_path(optmanager):
|
||||||
assert optmanager.options == []
|
assert optmanager.options == []
|
||||||
assert optmanager.config_options_dict == {}
|
assert optmanager.config_options_dict == {}
|
||||||
|
|
||||||
optmanager.add_option('--config', normalize_paths=True)
|
optmanager.add_option("--config", normalize_paths=True)
|
||||||
|
|
||||||
options, args = optmanager.parse_args(['--config', '../config.ini'])
|
options, args = optmanager.parse_args(["--config", "../config.ini"])
|
||||||
assert options.config == os.path.abspath('../config.ini')
|
assert options.config == os.path.abspath("../config.ini")
|
||||||
|
|
||||||
|
|
||||||
def test_parse_args_handles_comma_separated_defaults(optmanager):
|
def test_parse_args_handles_comma_separated_defaults(optmanager):
|
||||||
|
|
@ -114,11 +113,12 @@ def test_parse_args_handles_comma_separated_defaults(optmanager):
|
||||||
assert optmanager.options == []
|
assert optmanager.options == []
|
||||||
assert optmanager.config_options_dict == {}
|
assert optmanager.config_options_dict == {}
|
||||||
|
|
||||||
optmanager.add_option('--exclude', default='E123,W234',
|
optmanager.add_option(
|
||||||
comma_separated_list=True)
|
"--exclude", default="E123,W234", comma_separated_list=True
|
||||||
|
)
|
||||||
|
|
||||||
options, args = optmanager.parse_args([])
|
options, args = optmanager.parse_args([])
|
||||||
assert options.exclude == ['E123', 'W234']
|
assert options.exclude == ["E123", "W234"]
|
||||||
|
|
||||||
|
|
||||||
def test_parse_args_handles_comma_separated_lists(optmanager):
|
def test_parse_args_handles_comma_separated_lists(optmanager):
|
||||||
|
|
@ -126,11 +126,12 @@ def test_parse_args_handles_comma_separated_lists(optmanager):
|
||||||
assert optmanager.options == []
|
assert optmanager.options == []
|
||||||
assert optmanager.config_options_dict == {}
|
assert optmanager.config_options_dict == {}
|
||||||
|
|
||||||
optmanager.add_option('--exclude', default='E123,W234',
|
optmanager.add_option(
|
||||||
comma_separated_list=True)
|
"--exclude", default="E123,W234", comma_separated_list=True
|
||||||
|
)
|
||||||
|
|
||||||
options, args = optmanager.parse_args(['--exclude', 'E201,W111,F280'])
|
options, args = optmanager.parse_args(["--exclude", "E201,W111,F280"])
|
||||||
assert options.exclude == ['E201', 'W111', 'F280']
|
assert options.exclude == ["E201", "W111", "F280"]
|
||||||
|
|
||||||
|
|
||||||
def test_parse_args_normalize_paths(optmanager):
|
def test_parse_args_normalize_paths(optmanager):
|
||||||
|
|
@ -138,57 +139,61 @@ def test_parse_args_normalize_paths(optmanager):
|
||||||
assert optmanager.options == []
|
assert optmanager.options == []
|
||||||
assert optmanager.config_options_dict == {}
|
assert optmanager.config_options_dict == {}
|
||||||
|
|
||||||
optmanager.add_option('--extra-config', normalize_paths=True,
|
optmanager.add_option(
|
||||||
comma_separated_list=True)
|
"--extra-config", normalize_paths=True, comma_separated_list=True
|
||||||
|
)
|
||||||
|
|
||||||
options, args = optmanager.parse_args([
|
options, args = optmanager.parse_args(
|
||||||
'--extra-config', '../config.ini,tox.ini,flake8/some-other.cfg'
|
["--extra-config", "../config.ini,tox.ini,flake8/some-other.cfg"]
|
||||||
])
|
)
|
||||||
assert options.extra_config == [
|
assert options.extra_config == [
|
||||||
os.path.abspath('../config.ini'),
|
os.path.abspath("../config.ini"),
|
||||||
'tox.ini',
|
"tox.ini",
|
||||||
os.path.abspath('flake8/some-other.cfg'),
|
os.path.abspath("flake8/some-other.cfg"),
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
def test_generate_versions(optmanager):
|
def test_generate_versions(optmanager):
|
||||||
"""Verify a comma-separated string is generated of registered plugins."""
|
"""Verify a comma-separated string is generated of registered plugins."""
|
||||||
optmanager.registered_plugins = [
|
optmanager.registered_plugins = [
|
||||||
manager.PluginVersion('Testing 100', '0.0.0', False),
|
manager.PluginVersion("Testing 100", "0.0.0", False),
|
||||||
manager.PluginVersion('Testing 101', '0.0.0', False),
|
manager.PluginVersion("Testing 101", "0.0.0", False),
|
||||||
manager.PluginVersion('Testing 300', '0.0.0', True),
|
manager.PluginVersion("Testing 300", "0.0.0", True),
|
||||||
]
|
]
|
||||||
assert (optmanager.generate_versions()
|
assert (
|
||||||
== 'Testing 100: 0.0.0, Testing 101: 0.0.0, Testing 300: 0.0.0')
|
optmanager.generate_versions()
|
||||||
|
== "Testing 100: 0.0.0, Testing 101: 0.0.0, Testing 300: 0.0.0"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def test_plugins_are_sorted_in_generate_versions(optmanager):
|
def test_plugins_are_sorted_in_generate_versions(optmanager):
|
||||||
"""Verify we sort before joining strings in generate_versions."""
|
"""Verify we sort before joining strings in generate_versions."""
|
||||||
optmanager.registered_plugins = [
|
optmanager.registered_plugins = [
|
||||||
manager.PluginVersion('pyflakes', '1.5.0', False),
|
manager.PluginVersion("pyflakes", "1.5.0", False),
|
||||||
manager.PluginVersion('mccabe', '0.7.0', False),
|
manager.PluginVersion("mccabe", "0.7.0", False),
|
||||||
manager.PluginVersion('pycodestyle', '2.2.0', False),
|
manager.PluginVersion("pycodestyle", "2.2.0", False),
|
||||||
manager.PluginVersion('flake8-docstrings', '0.6.1', False),
|
manager.PluginVersion("flake8-docstrings", "0.6.1", False),
|
||||||
manager.PluginVersion('flake8-bugbear', '2016.12.1', False),
|
manager.PluginVersion("flake8-bugbear", "2016.12.1", False),
|
||||||
]
|
]
|
||||||
assert (optmanager.generate_versions()
|
assert (
|
||||||
== 'flake8-bugbear: 2016.12.1, '
|
optmanager.generate_versions() == "flake8-bugbear: 2016.12.1, "
|
||||||
'flake8-docstrings: 0.6.1, '
|
"flake8-docstrings: 0.6.1, "
|
||||||
'mccabe: 0.7.0, '
|
"mccabe: 0.7.0, "
|
||||||
'pycodestyle: 2.2.0, '
|
"pycodestyle: 2.2.0, "
|
||||||
'pyflakes: 1.5.0')
|
"pyflakes: 1.5.0"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def test_generate_versions_with_format_string(optmanager):
|
def test_generate_versions_with_format_string(optmanager):
|
||||||
"""Verify a comma-separated string is generated of registered plugins."""
|
"""Verify a comma-separated string is generated of registered plugins."""
|
||||||
optmanager.registered_plugins.update([
|
optmanager.registered_plugins.update(
|
||||||
manager.PluginVersion('Testing', '0.0.0', False),
|
[
|
||||||
manager.PluginVersion('Testing', '0.0.0', False),
|
manager.PluginVersion("Testing", "0.0.0", False),
|
||||||
manager.PluginVersion('Testing', '0.0.0', False),
|
manager.PluginVersion("Testing", "0.0.0", False),
|
||||||
])
|
manager.PluginVersion("Testing", "0.0.0", False),
|
||||||
assert (
|
]
|
||||||
optmanager.generate_versions() == 'Testing: 0.0.0'
|
|
||||||
)
|
)
|
||||||
|
assert optmanager.generate_versions() == "Testing: 0.0.0"
|
||||||
|
|
||||||
|
|
||||||
def test_update_version_string(optmanager):
|
def test_update_version_string(optmanager):
|
||||||
|
|
@ -197,17 +202,20 @@ def test_update_version_string(optmanager):
|
||||||
assert optmanager.version_action.version == TEST_VERSION
|
assert optmanager.version_action.version == TEST_VERSION
|
||||||
|
|
||||||
optmanager.registered_plugins = [
|
optmanager.registered_plugins = [
|
||||||
manager.PluginVersion('Testing 100', '0.0.0', False),
|
manager.PluginVersion("Testing 100", "0.0.0", False),
|
||||||
manager.PluginVersion('Testing 101', '0.0.0', False),
|
manager.PluginVersion("Testing 101", "0.0.0", False),
|
||||||
manager.PluginVersion('Testing 300', '0.0.0', False),
|
manager.PluginVersion("Testing 300", "0.0.0", False),
|
||||||
]
|
]
|
||||||
|
|
||||||
optmanager.update_version_string()
|
optmanager.update_version_string()
|
||||||
|
|
||||||
assert optmanager.version == TEST_VERSION
|
assert optmanager.version == TEST_VERSION
|
||||||
assert (optmanager.version_action.version == TEST_VERSION
|
assert (
|
||||||
+ ' (Testing 100: 0.0.0, Testing 101: 0.0.0, Testing 300: 0.0.0) '
|
optmanager.version_action.version
|
||||||
+ utils.get_python_version())
|
== TEST_VERSION
|
||||||
|
+ " (Testing 100: 0.0.0, Testing 101: 0.0.0, Testing 300: 0.0.0) "
|
||||||
|
+ utils.get_python_version()
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def test_generate_epilog(optmanager):
|
def test_generate_epilog(optmanager):
|
||||||
|
|
@ -215,14 +223,14 @@ def test_generate_epilog(optmanager):
|
||||||
assert optmanager.parser.epilog is None
|
assert optmanager.parser.epilog is None
|
||||||
|
|
||||||
optmanager.registered_plugins = [
|
optmanager.registered_plugins = [
|
||||||
manager.PluginVersion('Testing 100', '0.0.0', False),
|
manager.PluginVersion("Testing 100", "0.0.0", False),
|
||||||
manager.PluginVersion('Testing 101', '0.0.0', False),
|
manager.PluginVersion("Testing 101", "0.0.0", False),
|
||||||
manager.PluginVersion('Testing 300', '0.0.0', False),
|
manager.PluginVersion("Testing 300", "0.0.0", False),
|
||||||
]
|
]
|
||||||
|
|
||||||
expected_value = (
|
expected_value = (
|
||||||
'Installed plugins: Testing 100: 0.0.0, Testing 101: 0.0.0, Testing'
|
"Installed plugins: Testing 100: 0.0.0, Testing 101: 0.0.0, Testing"
|
||||||
' 300: 0.0.0'
|
" 300: 0.0.0"
|
||||||
)
|
)
|
||||||
|
|
||||||
optmanager.generate_epilog()
|
optmanager.generate_epilog()
|
||||||
|
|
@ -233,14 +241,14 @@ def test_extend_default_ignore(optmanager):
|
||||||
"""Verify that we update the extended default ignore list."""
|
"""Verify that we update the extended default ignore list."""
|
||||||
assert optmanager.extended_default_ignore == set()
|
assert optmanager.extended_default_ignore == set()
|
||||||
|
|
||||||
optmanager.extend_default_ignore(['T100', 'T101', 'T102'])
|
optmanager.extend_default_ignore(["T100", "T101", "T102"])
|
||||||
assert optmanager.extended_default_ignore == {'T100', 'T101', 'T102'}
|
assert optmanager.extended_default_ignore == {"T100", "T101", "T102"}
|
||||||
|
|
||||||
|
|
||||||
def test_parse_known_args(optmanager):
|
def test_parse_known_args(optmanager):
|
||||||
"""Verify we ignore unknown options."""
|
"""Verify we ignore unknown options."""
|
||||||
with mock.patch('sys.exit') as sysexit:
|
with mock.patch("sys.exit") as sysexit:
|
||||||
optmanager.parse_known_args(['--max-complexity', '5'])
|
optmanager.parse_known_args(["--max-complexity", "5"])
|
||||||
|
|
||||||
assert sysexit.called is False
|
assert sysexit.called is False
|
||||||
|
|
||||||
|
|
@ -249,101 +257,101 @@ def test_optparse_normalize_callback_option_legacy(optmanager):
|
||||||
"""Test the optparse shim for `callback=`."""
|
"""Test the optparse shim for `callback=`."""
|
||||||
callback_foo = mock.Mock()
|
callback_foo = mock.Mock()
|
||||||
optmanager.add_option(
|
optmanager.add_option(
|
||||||
'--foo',
|
"--foo",
|
||||||
action='callback',
|
action="callback",
|
||||||
callback=callback_foo,
|
callback=callback_foo,
|
||||||
callback_args=(1, 2),
|
callback_args=(1, 2),
|
||||||
callback_kwargs={'a': 'b'},
|
callback_kwargs={"a": "b"},
|
||||||
)
|
)
|
||||||
callback_bar = mock.Mock()
|
callback_bar = mock.Mock()
|
||||||
optmanager.add_option(
|
optmanager.add_option(
|
||||||
'--bar',
|
"--bar",
|
||||||
action='callback',
|
action="callback",
|
||||||
type='string',
|
type="string",
|
||||||
callback=callback_bar,
|
callback=callback_bar,
|
||||||
)
|
)
|
||||||
callback_baz = mock.Mock()
|
callback_baz = mock.Mock()
|
||||||
optmanager.add_option(
|
optmanager.add_option(
|
||||||
'--baz',
|
"--baz",
|
||||||
action='callback',
|
action="callback",
|
||||||
type='string',
|
type="string",
|
||||||
nargs=2,
|
nargs=2,
|
||||||
callback=callback_baz,
|
callback=callback_baz,
|
||||||
)
|
)
|
||||||
|
|
||||||
optmanager.parse_args(['--foo', '--bar', 'bararg', '--baz', '1', '2'])
|
optmanager.parse_args(["--foo", "--bar", "bararg", "--baz", "1", "2"])
|
||||||
|
|
||||||
callback_foo.assert_called_once_with(
|
callback_foo.assert_called_once_with(
|
||||||
mock.ANY, # the option / action instance
|
mock.ANY, # the option / action instance
|
||||||
'--foo',
|
"--foo",
|
||||||
None,
|
None,
|
||||||
mock.ANY, # the OptionParser / ArgumentParser
|
mock.ANY, # the OptionParser / ArgumentParser
|
||||||
1,
|
1,
|
||||||
2,
|
2,
|
||||||
a='b',
|
a="b",
|
||||||
)
|
)
|
||||||
callback_bar.assert_called_once_with(
|
callback_bar.assert_called_once_with(
|
||||||
mock.ANY, # the option / action instance
|
mock.ANY, # the option / action instance
|
||||||
'--bar',
|
"--bar",
|
||||||
'bararg',
|
"bararg",
|
||||||
mock.ANY, # the OptionParser / ArgumentParser
|
mock.ANY, # the OptionParser / ArgumentParser
|
||||||
)
|
)
|
||||||
callback_baz.assert_called_once_with(
|
callback_baz.assert_called_once_with(
|
||||||
mock.ANY, # the option / action instance
|
mock.ANY, # the option / action instance
|
||||||
'--baz',
|
"--baz",
|
||||||
('1', '2'),
|
("1", "2"),
|
||||||
mock.ANY, # the OptionParser / ArgumentParser
|
mock.ANY, # the OptionParser / ArgumentParser
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize(
|
||||||
('type_s', 'input_val', 'expected'),
|
("type_s", "input_val", "expected"),
|
||||||
(
|
(
|
||||||
('int', '5', 5),
|
("int", "5", 5),
|
||||||
('long', '6', 6),
|
("long", "6", 6),
|
||||||
('string', 'foo', 'foo'),
|
("string", "foo", "foo"),
|
||||||
('float', '1.5', 1.5),
|
("float", "1.5", 1.5),
|
||||||
('complex', '1+5j', 1 + 5j),
|
("complex", "1+5j", 1 + 5j),
|
||||||
# optparse allows this but does not document it
|
# optparse allows this but does not document it
|
||||||
('str', 'foo', 'foo'),
|
("str", "foo", "foo"),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
def test_optparse_normalize_types(optmanager, type_s, input_val, expected):
|
def test_optparse_normalize_types(optmanager, type_s, input_val, expected):
|
||||||
"""Test the optparse shim for type="typename"."""
|
"""Test the optparse shim for type="typename"."""
|
||||||
optmanager.add_option('--foo', type=type_s)
|
optmanager.add_option("--foo", type=type_s)
|
||||||
opts, args = optmanager.parse_args(['--foo', input_val])
|
opts, args = optmanager.parse_args(["--foo", input_val])
|
||||||
assert opts.foo == expected
|
assert opts.foo == expected
|
||||||
|
|
||||||
|
|
||||||
def test_optparse_normalize_choice_type(optmanager):
|
def test_optparse_normalize_choice_type(optmanager):
|
||||||
"""Test the optparse shim for type="choice"."""
|
"""Test the optparse shim for type="choice"."""
|
||||||
optmanager.add_option('--foo', type='choice', choices=('1', '2', '3'))
|
optmanager.add_option("--foo", type="choice", choices=("1", "2", "3"))
|
||||||
opts, args = optmanager.parse_args(['--foo', '1'])
|
opts, args = optmanager.parse_args(["--foo", "1"])
|
||||||
assert opts.foo == '1'
|
assert opts.foo == "1"
|
||||||
# fails to parse
|
# fails to parse
|
||||||
with pytest.raises(SystemExit):
|
with pytest.raises(SystemExit):
|
||||||
optmanager.parse_args(['--foo', '4'])
|
optmanager.parse_args(["--foo", "4"])
|
||||||
|
|
||||||
|
|
||||||
def test_optparse_normalize_help(optmanager, capsys):
|
def test_optparse_normalize_help(optmanager, capsys):
|
||||||
"""Test the optparse shim for %default in help text."""
|
"""Test the optparse shim for %default in help text."""
|
||||||
optmanager.add_option('--foo', default='bar', help='default: %default')
|
optmanager.add_option("--foo", default="bar", help="default: %default")
|
||||||
with pytest.raises(SystemExit):
|
with pytest.raises(SystemExit):
|
||||||
optmanager.parse_args(['--help'])
|
optmanager.parse_args(["--help"])
|
||||||
out, err = capsys.readouterr()
|
out, err = capsys.readouterr()
|
||||||
output = out + err
|
output = out + err
|
||||||
assert 'default: bar' in output
|
assert "default: bar" in output
|
||||||
|
|
||||||
|
|
||||||
def test_optmanager_group(optmanager, capsys):
|
def test_optmanager_group(optmanager, capsys):
|
||||||
"""Test that group(...) causes options to be assigned to a group."""
|
"""Test that group(...) causes options to be assigned to a group."""
|
||||||
with optmanager.group('groupname'):
|
with optmanager.group("groupname"):
|
||||||
optmanager.add_option('--foo')
|
optmanager.add_option("--foo")
|
||||||
with pytest.raises(SystemExit):
|
with pytest.raises(SystemExit):
|
||||||
optmanager.parse_args(['--help'])
|
optmanager.parse_args(["--help"])
|
||||||
out, err = capsys.readouterr()
|
out, err = capsys.readouterr()
|
||||||
output = out + err
|
output = out + err
|
||||||
assert '\ngroupname:\n' in output
|
assert "\ngroupname:\n" in output
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize(
|
||||||
|
|
|
||||||
|
|
@ -11,8 +11,8 @@ from flake8.plugins import manager
|
||||||
|
|
||||||
def test_load_plugin_fallsback_on_old_setuptools():
|
def test_load_plugin_fallsback_on_old_setuptools():
|
||||||
"""Verify we fallback gracefully to on old versions of setuptools."""
|
"""Verify we fallback gracefully to on old versions of setuptools."""
|
||||||
entry_point = mock.Mock(spec=['load'])
|
entry_point = mock.Mock(spec=["load"])
|
||||||
plugin = manager.Plugin('T000', entry_point)
|
plugin = manager.Plugin("T000", entry_point)
|
||||||
|
|
||||||
plugin.load_plugin()
|
plugin.load_plugin()
|
||||||
entry_point.load.assert_called_once_with()
|
entry_point.load.assert_called_once_with()
|
||||||
|
|
@ -20,8 +20,8 @@ def test_load_plugin_fallsback_on_old_setuptools():
|
||||||
|
|
||||||
def test_load_plugin_is_idempotent():
|
def test_load_plugin_is_idempotent():
|
||||||
"""Verify we use the preferred methods on new versions of setuptools."""
|
"""Verify we use the preferred methods on new versions of setuptools."""
|
||||||
entry_point = mock.Mock(spec=['load'])
|
entry_point = mock.Mock(spec=["load"])
|
||||||
plugin = manager.Plugin('T000', entry_point)
|
plugin = manager.Plugin("T000", entry_point)
|
||||||
|
|
||||||
plugin.load_plugin()
|
plugin.load_plugin()
|
||||||
plugin.load_plugin()
|
plugin.load_plugin()
|
||||||
|
|
@ -31,9 +31,9 @@ def test_load_plugin_is_idempotent():
|
||||||
|
|
||||||
def test_load_plugin_catches_and_reraises_exceptions():
|
def test_load_plugin_catches_and_reraises_exceptions():
|
||||||
"""Verify we raise our own FailedToLoadPlugin."""
|
"""Verify we raise our own FailedToLoadPlugin."""
|
||||||
entry_point = mock.Mock(spec=['load'])
|
entry_point = mock.Mock(spec=["load"])
|
||||||
entry_point.load.side_effect = ValueError('Test failure')
|
entry_point.load.side_effect = ValueError("Test failure")
|
||||||
plugin = manager.Plugin('T000', entry_point)
|
plugin = manager.Plugin("T000", entry_point)
|
||||||
|
|
||||||
with pytest.raises(exceptions.FailedToLoadPlugin):
|
with pytest.raises(exceptions.FailedToLoadPlugin):
|
||||||
plugin.load_plugin()
|
plugin.load_plugin()
|
||||||
|
|
@ -41,9 +41,9 @@ def test_load_plugin_catches_and_reraises_exceptions():
|
||||||
|
|
||||||
def test_load_noncallable_plugin():
|
def test_load_noncallable_plugin():
|
||||||
"""Verify that we do not load a non-callable plugin."""
|
"""Verify that we do not load a non-callable plugin."""
|
||||||
entry_point = mock.Mock(spec=['load'])
|
entry_point = mock.Mock(spec=["load"])
|
||||||
entry_point.load.return_value = mock.NonCallableMock()
|
entry_point.load.return_value = mock.NonCallableMock()
|
||||||
plugin = manager.Plugin('T000', entry_point)
|
plugin = manager.Plugin("T000", entry_point)
|
||||||
|
|
||||||
with pytest.raises(exceptions.FailedToLoadPlugin):
|
with pytest.raises(exceptions.FailedToLoadPlugin):
|
||||||
plugin.load_plugin()
|
plugin.load_plugin()
|
||||||
|
|
@ -52,8 +52,8 @@ def test_load_noncallable_plugin():
|
||||||
|
|
||||||
def test_plugin_property_loads_plugin_on_first_use():
|
def test_plugin_property_loads_plugin_on_first_use():
|
||||||
"""Verify that we load our plugin when we first try to use it."""
|
"""Verify that we load our plugin when we first try to use it."""
|
||||||
entry_point = mock.Mock(spec=['load'])
|
entry_point = mock.Mock(spec=["load"])
|
||||||
plugin = manager.Plugin('T000', entry_point)
|
plugin = manager.Plugin("T000", entry_point)
|
||||||
|
|
||||||
assert plugin.plugin is not None
|
assert plugin.plugin is not None
|
||||||
entry_point.load.assert_called_once_with()
|
entry_point.load.assert_called_once_with()
|
||||||
|
|
@ -61,14 +61,14 @@ def test_plugin_property_loads_plugin_on_first_use():
|
||||||
|
|
||||||
def test_execute_calls_plugin_with_passed_arguments():
|
def test_execute_calls_plugin_with_passed_arguments():
|
||||||
"""Verify that we pass arguments directly to the plugin."""
|
"""Verify that we pass arguments directly to the plugin."""
|
||||||
entry_point = mock.Mock(spec=['load'])
|
entry_point = mock.Mock(spec=["load"])
|
||||||
plugin_obj = mock.Mock()
|
plugin_obj = mock.Mock()
|
||||||
plugin = manager.Plugin('T000', entry_point)
|
plugin = manager.Plugin("T000", entry_point)
|
||||||
plugin._plugin = plugin_obj
|
plugin._plugin = plugin_obj
|
||||||
|
|
||||||
plugin.execute('arg1', 'arg2', kwarg1='value1', kwarg2='value2')
|
plugin.execute("arg1", "arg2", kwarg1="value1", kwarg2="value2")
|
||||||
plugin_obj.assert_called_once_with(
|
plugin_obj.assert_called_once_with(
|
||||||
'arg1', 'arg2', kwarg1='value1', kwarg2='value2'
|
"arg1", "arg2", kwarg1="value1", kwarg2="value2"
|
||||||
)
|
)
|
||||||
|
|
||||||
# Extra assertions
|
# Extra assertions
|
||||||
|
|
@ -77,23 +77,24 @@ def test_execute_calls_plugin_with_passed_arguments():
|
||||||
|
|
||||||
def test_version_proxies_to_the_plugin():
|
def test_version_proxies_to_the_plugin():
|
||||||
"""Verify that we pass arguments directly to the plugin."""
|
"""Verify that we pass arguments directly to the plugin."""
|
||||||
entry_point = mock.Mock(spec=['load'])
|
entry_point = mock.Mock(spec=["load"])
|
||||||
plugin_obj = mock.Mock(spec_set=['version'])
|
plugin_obj = mock.Mock(spec_set=["version"])
|
||||||
plugin_obj.version = 'a.b.c'
|
plugin_obj.version = "a.b.c"
|
||||||
plugin = manager.Plugin('T000', entry_point)
|
plugin = manager.Plugin("T000", entry_point)
|
||||||
plugin._plugin = plugin_obj
|
plugin._plugin = plugin_obj
|
||||||
|
|
||||||
assert plugin.version == 'a.b.c'
|
assert plugin.version == "a.b.c"
|
||||||
|
|
||||||
|
|
||||||
def test_register_options():
|
def test_register_options():
|
||||||
"""Verify we call add_options on the plugin only if it exists."""
|
"""Verify we call add_options on the plugin only if it exists."""
|
||||||
# Set up our mocks and Plugin object
|
# Set up our mocks and Plugin object
|
||||||
entry_point = mock.Mock(spec=['load'])
|
entry_point = mock.Mock(spec=["load"])
|
||||||
plugin_obj = mock.Mock(spec_set=['name', 'version', 'add_options',
|
plugin_obj = mock.Mock(
|
||||||
'parse_options'])
|
spec_set=["name", "version", "add_options", "parse_options"]
|
||||||
|
)
|
||||||
option_manager = mock.MagicMock(spec=options_manager.OptionManager)
|
option_manager = mock.MagicMock(spec=options_manager.OptionManager)
|
||||||
plugin = manager.Plugin('T000', entry_point)
|
plugin = manager.Plugin("T000", entry_point)
|
||||||
plugin._plugin = plugin_obj
|
plugin._plugin = plugin_obj
|
||||||
|
|
||||||
# Call the method we're testing.
|
# Call the method we're testing.
|
||||||
|
|
@ -106,10 +107,10 @@ def test_register_options():
|
||||||
def test_register_options_checks_plugin_for_method():
|
def test_register_options_checks_plugin_for_method():
|
||||||
"""Verify we call add_options on the plugin only if it exists."""
|
"""Verify we call add_options on the plugin only if it exists."""
|
||||||
# Set up our mocks and Plugin object
|
# Set up our mocks and Plugin object
|
||||||
entry_point = mock.Mock(spec=['load'])
|
entry_point = mock.Mock(spec=["load"])
|
||||||
plugin_obj = mock.Mock(spec_set=['name', 'version', 'parse_options'])
|
plugin_obj = mock.Mock(spec_set=["name", "version", "parse_options"])
|
||||||
option_manager = mock.Mock(spec=['register_plugin'])
|
option_manager = mock.Mock(spec=["register_plugin"])
|
||||||
plugin = manager.Plugin('T000', entry_point)
|
plugin = manager.Plugin("T000", entry_point)
|
||||||
plugin._plugin = plugin_obj
|
plugin._plugin = plugin_obj
|
||||||
|
|
||||||
# Call the method we're testing.
|
# Call the method we're testing.
|
||||||
|
|
@ -122,12 +123,13 @@ def test_register_options_checks_plugin_for_method():
|
||||||
def test_provide_options():
|
def test_provide_options():
|
||||||
"""Verify we call add_options on the plugin only if it exists."""
|
"""Verify we call add_options on the plugin only if it exists."""
|
||||||
# Set up our mocks and Plugin object
|
# Set up our mocks and Plugin object
|
||||||
entry_point = mock.Mock(spec=['load'])
|
entry_point = mock.Mock(spec=["load"])
|
||||||
plugin_obj = mock.Mock(spec_set=['name', 'version', 'add_options',
|
plugin_obj = mock.Mock(
|
||||||
'parse_options'])
|
spec_set=["name", "version", "add_options", "parse_options"]
|
||||||
|
)
|
||||||
option_values = argparse.Namespace(enable_extensions=[])
|
option_values = argparse.Namespace(enable_extensions=[])
|
||||||
option_manager = mock.Mock()
|
option_manager = mock.Mock()
|
||||||
plugin = manager.Plugin('T000', entry_point)
|
plugin = manager.Plugin("T000", entry_point)
|
||||||
plugin._plugin = plugin_obj
|
plugin._plugin = plugin_obj
|
||||||
|
|
||||||
# Call the method we're testing.
|
# Call the method we're testing.
|
||||||
|
|
@ -139,10 +141,13 @@ def test_provide_options():
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize('ignore_list, code, expected_list', [
|
@pytest.mark.parametrize(
|
||||||
(['E', 'W', 'F', 'C9'], 'W', ['E', 'F', 'C9']),
|
"ignore_list, code, expected_list",
|
||||||
(['E', 'W', 'F'], 'C9', ['E', 'W', 'F']),
|
[
|
||||||
])
|
(["E", "W", "F", "C9"], "W", ["E", "F", "C9"]),
|
||||||
|
(["E", "W", "F"], "C9", ["E", "W", "F"]),
|
||||||
|
],
|
||||||
|
)
|
||||||
def test_enable(ignore_list, code, expected_list):
|
def test_enable(ignore_list, code, expected_list):
|
||||||
"""Verify that enabling a plugin removes it from the ignore list."""
|
"""Verify that enabling a plugin removes it from the ignore list."""
|
||||||
options = mock.Mock(ignore=ignore_list)
|
options = mock.Mock(ignore=ignore_list)
|
||||||
|
|
@ -157,8 +162,8 @@ def test_enable(ignore_list, code, expected_list):
|
||||||
def test_enable_without_providing_parsed_options():
|
def test_enable_without_providing_parsed_options():
|
||||||
"""Verify that enabling a plugin removes it from the ignore list."""
|
"""Verify that enabling a plugin removes it from the ignore list."""
|
||||||
optmanager = mock.Mock()
|
optmanager = mock.Mock()
|
||||||
plugin = manager.Plugin('U4', mock.Mock())
|
plugin = manager.Plugin("U4", mock.Mock())
|
||||||
|
|
||||||
plugin.enable(optmanager)
|
plugin.enable(optmanager)
|
||||||
|
|
||||||
optmanager.remove_from_default_ignore.assert_called_once_with(['U4'])
|
optmanager.remove_from_default_ignore.assert_called_once_with(["U4"])
|
||||||
|
|
|
||||||
|
|
@ -5,54 +5,53 @@ from flake8._compat import importlib_metadata
|
||||||
from flake8.plugins import manager
|
from flake8.plugins import manager
|
||||||
|
|
||||||
|
|
||||||
@mock.patch.object(importlib_metadata, 'entry_points')
|
@mock.patch.object(importlib_metadata, "entry_points")
|
||||||
def test_calls_entrypoints_on_instantiation(entry_points_mck):
|
def test_calls_entrypoints_on_instantiation(entry_points_mck):
|
||||||
"""Verify that we call entry_points() when we create a manager."""
|
"""Verify that we call entry_points() when we create a manager."""
|
||||||
entry_points_mck.return_value = {}
|
entry_points_mck.return_value = {}
|
||||||
manager.PluginManager(namespace='testing.entrypoints')
|
manager.PluginManager(namespace="testing.entrypoints")
|
||||||
entry_points_mck.assert_called_once_with()
|
entry_points_mck.assert_called_once_with()
|
||||||
|
|
||||||
|
|
||||||
@mock.patch.object(importlib_metadata, 'entry_points')
|
@mock.patch.object(importlib_metadata, "entry_points")
|
||||||
def test_calls_entrypoints_creates_plugins_automaticaly(entry_points_mck):
|
def test_calls_entrypoints_creates_plugins_automaticaly(entry_points_mck):
|
||||||
"""Verify that we create Plugins on instantiation."""
|
"""Verify that we create Plugins on instantiation."""
|
||||||
entry_points_mck.return_value = {
|
entry_points_mck.return_value = {
|
||||||
'testing.entrypoints': [
|
"testing.entrypoints": [
|
||||||
importlib_metadata.EntryPoint('T100', '', 'testing.entrypoints'),
|
importlib_metadata.EntryPoint("T100", "", "testing.entrypoints"),
|
||||||
importlib_metadata.EntryPoint('T200', '', 'testing.entrypoints'),
|
importlib_metadata.EntryPoint("T200", "", "testing.entrypoints"),
|
||||||
],
|
],
|
||||||
}
|
}
|
||||||
plugin_mgr = manager.PluginManager(namespace='testing.entrypoints')
|
plugin_mgr = manager.PluginManager(namespace="testing.entrypoints")
|
||||||
|
|
||||||
entry_points_mck.assert_called_once_with()
|
entry_points_mck.assert_called_once_with()
|
||||||
assert 'T100' in plugin_mgr.plugins
|
assert "T100" in plugin_mgr.plugins
|
||||||
assert 'T200' in plugin_mgr.plugins
|
assert "T200" in plugin_mgr.plugins
|
||||||
assert isinstance(plugin_mgr.plugins['T100'], manager.Plugin)
|
assert isinstance(plugin_mgr.plugins["T100"], manager.Plugin)
|
||||||
assert isinstance(plugin_mgr.plugins['T200'], manager.Plugin)
|
assert isinstance(plugin_mgr.plugins["T200"], manager.Plugin)
|
||||||
|
|
||||||
|
|
||||||
@mock.patch.object(importlib_metadata, 'entry_points')
|
@mock.patch.object(importlib_metadata, "entry_points")
|
||||||
def test_handles_mapping_functions_across_plugins(entry_points_mck):
|
def test_handles_mapping_functions_across_plugins(entry_points_mck):
|
||||||
"""Verify we can use the PluginManager call functions on all plugins."""
|
"""Verify we can use the PluginManager call functions on all plugins."""
|
||||||
entry_points_mck.return_value = {
|
entry_points_mck.return_value = {
|
||||||
'testing.entrypoints': [
|
"testing.entrypoints": [
|
||||||
importlib_metadata.EntryPoint('T100', '', 'testing.entrypoints'),
|
importlib_metadata.EntryPoint("T100", "", "testing.entrypoints"),
|
||||||
importlib_metadata.EntryPoint('T200', '', 'testing.entrypoints'),
|
importlib_metadata.EntryPoint("T200", "", "testing.entrypoints"),
|
||||||
],
|
],
|
||||||
}
|
}
|
||||||
plugin_mgr = manager.PluginManager(namespace='testing.entrypoints')
|
plugin_mgr = manager.PluginManager(namespace="testing.entrypoints")
|
||||||
plugins = [plugin_mgr.plugins[name] for name in plugin_mgr.names]
|
plugins = [plugin_mgr.plugins[name] for name in plugin_mgr.names]
|
||||||
|
|
||||||
assert list(plugin_mgr.map(lambda x: x)) == plugins
|
assert list(plugin_mgr.map(lambda x: x)) == plugins
|
||||||
|
|
||||||
|
|
||||||
@mock.patch.object(importlib_metadata, 'entry_points')
|
@mock.patch.object(importlib_metadata, "entry_points")
|
||||||
def test_local_plugins(entry_points_mck):
|
def test_local_plugins(entry_points_mck):
|
||||||
"""Verify PluginManager can load given local plugins."""
|
"""Verify PluginManager can load given local plugins."""
|
||||||
entry_points_mck.return_value = {}
|
entry_points_mck.return_value = {}
|
||||||
plugin_mgr = manager.PluginManager(
|
plugin_mgr = manager.PluginManager(
|
||||||
namespace='testing.entrypoints',
|
namespace="testing.entrypoints", local_plugins=["X = path.to:Plugin"]
|
||||||
local_plugins=['X = path.to:Plugin']
|
|
||||||
)
|
)
|
||||||
|
|
||||||
assert plugin_mgr.plugins['X'].entry_point.value == 'path.to:Plugin'
|
assert plugin_mgr.plugins["X"].entry_point.value == "path.to:Plugin"
|
||||||
|
|
|
||||||
|
|
@ -14,8 +14,8 @@ def create_plugin_mock(raise_exception=False):
|
||||||
plugin = mock.create_autospec(manager.Plugin, instance=True)
|
plugin = mock.create_autospec(manager.Plugin, instance=True)
|
||||||
if raise_exception:
|
if raise_exception:
|
||||||
plugin.load_plugin.side_effect = exceptions.FailedToLoadPlugin(
|
plugin.load_plugin.side_effect = exceptions.FailedToLoadPlugin(
|
||||||
plugin_name='T101',
|
plugin_name="T101",
|
||||||
exception=ValueError('Test failure'),
|
exception=ValueError("Test failure"),
|
||||||
)
|
)
|
||||||
return plugin
|
return plugin
|
||||||
|
|
||||||
|
|
@ -28,7 +28,7 @@ def create_mapping_manager_mock(plugins):
|
||||||
yield func(plugin)
|
yield func(plugin)
|
||||||
|
|
||||||
# Mock out the PluginManager instance
|
# Mock out the PluginManager instance
|
||||||
manager_mock = mock.Mock(spec=['map'])
|
manager_mock = mock.Mock(spec=["map"])
|
||||||
# Replace the map method
|
# Replace the map method
|
||||||
manager_mock.map = fake_map
|
manager_mock.map = fake_map
|
||||||
return manager_mock
|
return manager_mock
|
||||||
|
|
@ -47,7 +47,7 @@ class FakeTestType(manager.PluginTypeManager):
|
||||||
namespace = TEST_NAMESPACE
|
namespace = TEST_NAMESPACE
|
||||||
|
|
||||||
|
|
||||||
@mock.patch('flake8.plugins.manager.PluginManager')
|
@mock.patch("flake8.plugins.manager.PluginManager")
|
||||||
def test_instantiates_a_manager(PluginManager): # noqa: N803
|
def test_instantiates_a_manager(PluginManager): # noqa: N803
|
||||||
"""Verify we create a PluginManager on instantiation."""
|
"""Verify we create a PluginManager on instantiation."""
|
||||||
FakeTestType()
|
FakeTestType()
|
||||||
|
|
@ -55,26 +55,22 @@ def test_instantiates_a_manager(PluginManager): # noqa: N803
|
||||||
PluginManager.assert_called_once_with(TEST_NAMESPACE, local_plugins=None)
|
PluginManager.assert_called_once_with(TEST_NAMESPACE, local_plugins=None)
|
||||||
|
|
||||||
|
|
||||||
@mock.patch('flake8.plugins.manager.PluginManager')
|
@mock.patch("flake8.plugins.manager.PluginManager")
|
||||||
def test_proxies_names_to_manager(PluginManager): # noqa: N803
|
def test_proxies_names_to_manager(PluginManager): # noqa: N803
|
||||||
"""Verify we proxy the names attribute."""
|
"""Verify we proxy the names attribute."""
|
||||||
PluginManager.return_value = mock.Mock(names=[
|
PluginManager.return_value = mock.Mock(names=["T100", "T200", "T300"])
|
||||||
'T100', 'T200', 'T300'
|
|
||||||
])
|
|
||||||
type_mgr = FakeTestType()
|
type_mgr = FakeTestType()
|
||||||
|
|
||||||
assert type_mgr.names == ['T100', 'T200', 'T300']
|
assert type_mgr.names == ["T100", "T200", "T300"]
|
||||||
|
|
||||||
|
|
||||||
@mock.patch('flake8.plugins.manager.PluginManager')
|
@mock.patch("flake8.plugins.manager.PluginManager")
|
||||||
def test_proxies_plugins_to_manager(PluginManager): # noqa: N803
|
def test_proxies_plugins_to_manager(PluginManager): # noqa: N803
|
||||||
"""Verify we proxy the plugins attribute."""
|
"""Verify we proxy the plugins attribute."""
|
||||||
PluginManager.return_value = mock.Mock(plugins=[
|
PluginManager.return_value = mock.Mock(plugins=["T100", "T200", "T300"])
|
||||||
'T100', 'T200', 'T300'
|
|
||||||
])
|
|
||||||
type_mgr = FakeTestType()
|
type_mgr = FakeTestType()
|
||||||
|
|
||||||
assert type_mgr.plugins == ['T100', 'T200', 'T300']
|
assert type_mgr.plugins == ["T100", "T200", "T300"]
|
||||||
|
|
||||||
|
|
||||||
def test_generate_call_function():
|
def test_generate_call_function():
|
||||||
|
|
@ -82,21 +78,28 @@ def test_generate_call_function():
|
||||||
optmanager = object()
|
optmanager = object()
|
||||||
plugin = mock.Mock(method_name=lambda x: x)
|
plugin = mock.Mock(method_name=lambda x: x)
|
||||||
func = manager.PluginTypeManager._generate_call_function(
|
func = manager.PluginTypeManager._generate_call_function(
|
||||||
'method_name', optmanager,
|
"method_name",
|
||||||
|
optmanager,
|
||||||
)
|
)
|
||||||
|
|
||||||
assert callable(func)
|
assert callable(func)
|
||||||
assert func(plugin) is optmanager
|
assert func(plugin) is optmanager
|
||||||
|
|
||||||
|
|
||||||
@mock.patch('flake8.plugins.manager.PluginManager')
|
@mock.patch("flake8.plugins.manager.PluginManager")
|
||||||
def test_load_plugins(PluginManager): # noqa: N803
|
def test_load_plugins(PluginManager): # noqa: N803
|
||||||
"""Verify load plugins loads *every* plugin."""
|
"""Verify load plugins loads *every* plugin."""
|
||||||
# Create a bunch of fake plugins
|
# Create a bunch of fake plugins
|
||||||
plugins = [create_plugin_mock(), create_plugin_mock(),
|
plugins = [
|
||||||
create_plugin_mock(), create_plugin_mock(),
|
create_plugin_mock(),
|
||||||
create_plugin_mock(), create_plugin_mock(),
|
create_plugin_mock(),
|
||||||
create_plugin_mock(), create_plugin_mock()]
|
create_plugin_mock(),
|
||||||
|
create_plugin_mock(),
|
||||||
|
create_plugin_mock(),
|
||||||
|
create_plugin_mock(),
|
||||||
|
create_plugin_mock(),
|
||||||
|
create_plugin_mock(),
|
||||||
|
]
|
||||||
# Return our PluginManager mock
|
# Return our PluginManager mock
|
||||||
PluginManager.return_value = create_mapping_manager_mock(plugins)
|
PluginManager.return_value = create_mapping_manager_mock(plugins)
|
||||||
|
|
||||||
|
|
@ -109,13 +112,19 @@ def test_load_plugins(PluginManager): # noqa: N803
|
||||||
assert type_mgr.plugins_loaded is True
|
assert type_mgr.plugins_loaded is True
|
||||||
|
|
||||||
|
|
||||||
@mock.patch('flake8.plugins.manager.PluginManager')
|
@mock.patch("flake8.plugins.manager.PluginManager")
|
||||||
def test_load_plugins_fails(PluginManager): # noqa: N803
|
def test_load_plugins_fails(PluginManager): # noqa: N803
|
||||||
"""Verify load plugins bubbles up exceptions."""
|
"""Verify load plugins bubbles up exceptions."""
|
||||||
plugins = [create_plugin_mock(), create_plugin_mock(True),
|
plugins = [
|
||||||
create_plugin_mock(), create_plugin_mock(),
|
create_plugin_mock(),
|
||||||
create_plugin_mock(), create_plugin_mock(),
|
create_plugin_mock(True),
|
||||||
create_plugin_mock(), create_plugin_mock()]
|
create_plugin_mock(),
|
||||||
|
create_plugin_mock(),
|
||||||
|
create_plugin_mock(),
|
||||||
|
create_plugin_mock(),
|
||||||
|
create_plugin_mock(),
|
||||||
|
create_plugin_mock(),
|
||||||
|
]
|
||||||
# Return our PluginManager mock
|
# Return our PluginManager mock
|
||||||
PluginManager.return_value = create_mapping_manager_mock(plugins)
|
PluginManager.return_value = create_mapping_manager_mock(plugins)
|
||||||
|
|
||||||
|
|
@ -133,13 +142,19 @@ def test_load_plugins_fails(PluginManager): # noqa: N803
|
||||||
assert plugin.load_plugin.called is False
|
assert plugin.load_plugin.called is False
|
||||||
|
|
||||||
|
|
||||||
@mock.patch('flake8.plugins.manager.PluginManager')
|
@mock.patch("flake8.plugins.manager.PluginManager")
|
||||||
def test_register_options(PluginManager): # noqa: N803
|
def test_register_options(PluginManager): # noqa: N803
|
||||||
"""Test that we map over every plugin to register options."""
|
"""Test that we map over every plugin to register options."""
|
||||||
plugins = [create_plugin_mock(), create_plugin_mock(),
|
plugins = [
|
||||||
create_plugin_mock(), create_plugin_mock(),
|
create_plugin_mock(),
|
||||||
create_plugin_mock(), create_plugin_mock(),
|
create_plugin_mock(),
|
||||||
create_plugin_mock(), create_plugin_mock()]
|
create_plugin_mock(),
|
||||||
|
create_plugin_mock(),
|
||||||
|
create_plugin_mock(),
|
||||||
|
create_plugin_mock(),
|
||||||
|
create_plugin_mock(),
|
||||||
|
create_plugin_mock(),
|
||||||
|
]
|
||||||
# Return our PluginManager mock
|
# Return our PluginManager mock
|
||||||
PluginManager.return_value = create_mapping_manager_mock(plugins)
|
PluginManager.return_value = create_mapping_manager_mock(plugins)
|
||||||
optmanager = object()
|
optmanager = object()
|
||||||
|
|
@ -151,13 +166,19 @@ def test_register_options(PluginManager): # noqa: N803
|
||||||
plugin.register_options.assert_called_with(optmanager)
|
plugin.register_options.assert_called_with(optmanager)
|
||||||
|
|
||||||
|
|
||||||
@mock.patch('flake8.plugins.manager.PluginManager')
|
@mock.patch("flake8.plugins.manager.PluginManager")
|
||||||
def test_provide_options(PluginManager): # noqa: N803
|
def test_provide_options(PluginManager): # noqa: N803
|
||||||
"""Test that we map over every plugin to provide parsed options."""
|
"""Test that we map over every plugin to provide parsed options."""
|
||||||
plugins = [create_plugin_mock(), create_plugin_mock(),
|
plugins = [
|
||||||
create_plugin_mock(), create_plugin_mock(),
|
create_plugin_mock(),
|
||||||
create_plugin_mock(), create_plugin_mock(),
|
create_plugin_mock(),
|
||||||
create_plugin_mock(), create_plugin_mock()]
|
create_plugin_mock(),
|
||||||
|
create_plugin_mock(),
|
||||||
|
create_plugin_mock(),
|
||||||
|
create_plugin_mock(),
|
||||||
|
create_plugin_mock(),
|
||||||
|
create_plugin_mock(),
|
||||||
|
]
|
||||||
# Return our PluginManager mock
|
# Return our PluginManager mock
|
||||||
PluginManager.return_value = create_mapping_manager_mock(plugins)
|
PluginManager.return_value = create_mapping_manager_mock(plugins)
|
||||||
optmanager = object()
|
optmanager = object()
|
||||||
|
|
@ -167,32 +188,30 @@ def test_provide_options(PluginManager): # noqa: N803
|
||||||
type_mgr.provide_options(optmanager, options, [])
|
type_mgr.provide_options(optmanager, options, [])
|
||||||
|
|
||||||
for plugin in plugins:
|
for plugin in plugins:
|
||||||
plugin.provide_options.assert_called_with(optmanager,
|
plugin.provide_options.assert_called_with(optmanager, options, [])
|
||||||
options,
|
|
||||||
[])
|
|
||||||
|
|
||||||
|
|
||||||
@mock.patch('flake8.plugins.manager.PluginManager')
|
@mock.patch("flake8.plugins.manager.PluginManager")
|
||||||
def test_proxy_contains_to_managers_plugins_dict(PluginManager): # noqa: N803
|
def test_proxy_contains_to_managers_plugins_dict(PluginManager): # noqa: N803
|
||||||
"""Verify that we proxy __contains__ to the manager's dictionary."""
|
"""Verify that we proxy __contains__ to the manager's dictionary."""
|
||||||
plugins = {'T10%i' % i: create_plugin_mock() for i in range(8)}
|
plugins = {"T10%i" % i: create_plugin_mock() for i in range(8)}
|
||||||
# Return our PluginManager mock
|
# Return our PluginManager mock
|
||||||
PluginManager.return_value = create_manager_with_plugins(plugins)
|
PluginManager.return_value = create_manager_with_plugins(plugins)
|
||||||
|
|
||||||
type_mgr = FakeTestType()
|
type_mgr = FakeTestType()
|
||||||
for i in range(8):
|
for i in range(8):
|
||||||
key = 'T10%i' % i
|
key = "T10%i" % i
|
||||||
assert key in type_mgr
|
assert key in type_mgr
|
||||||
|
|
||||||
|
|
||||||
@mock.patch('flake8.plugins.manager.PluginManager')
|
@mock.patch("flake8.plugins.manager.PluginManager")
|
||||||
def test_proxies_getitem_to_managers_plugins_dict(PluginManager): # noqa: N803
|
def test_proxies_getitem_to_managers_plugins_dict(PluginManager): # noqa: N803
|
||||||
"""Verify that we can use the PluginTypeManager like a dictionary."""
|
"""Verify that we can use the PluginTypeManager like a dictionary."""
|
||||||
plugins = {'T10%i' % i: create_plugin_mock() for i in range(8)}
|
plugins = {"T10%i" % i: create_plugin_mock() for i in range(8)}
|
||||||
# Return our PluginManager mock
|
# Return our PluginManager mock
|
||||||
PluginManager.return_value = create_manager_with_plugins(plugins)
|
PluginManager.return_value = create_manager_with_plugins(plugins)
|
||||||
|
|
||||||
type_mgr = FakeTestType()
|
type_mgr = FakeTestType()
|
||||||
for i in range(8):
|
for i in range(8):
|
||||||
key = 'T10%i' % i
|
key = "T10%i" % i
|
||||||
assert type_mgr[key] is plugins[key]
|
assert type_mgr[key] is plugins[key]
|
||||||
|
|
|
||||||
|
|
@ -18,14 +18,14 @@ def test_all_pyflakes_messages_have_flake8_codes_assigned():
|
||||||
|
|
||||||
def test_undefined_local_code():
|
def test_undefined_local_code():
|
||||||
"""In pyflakes 2.1.0 this code's string formatting was changed."""
|
"""In pyflakes 2.1.0 this code's string formatting was changed."""
|
||||||
src = '''\
|
src = """\
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
def f():
|
def f():
|
||||||
sys = sys
|
sys = sys
|
||||||
'''
|
"""
|
||||||
tree = ast.parse(src)
|
tree = ast.parse(src)
|
||||||
checker = pyflakes_shim.FlakesChecker(tree, (), 't.py')
|
checker = pyflakes_shim.FlakesChecker(tree, (), "t.py")
|
||||||
message_texts = [s for _, _, s, _ in checker.run()]
|
message_texts = [s for _, _, s, _ in checker.run()]
|
||||||
assert message_texts == [
|
assert message_texts == [
|
||||||
"F823 local variable 'sys' defined in enclosing scope on line 1 referenced before assignment", # noqa: E501
|
"F823 local variable 'sys' defined in enclosing scope on line 1 referenced before assignment", # noqa: E501
|
||||||
|
|
|
||||||
|
|
@ -4,19 +4,19 @@ import pytest
|
||||||
from flake8 import statistics as stats
|
from flake8 import statistics as stats
|
||||||
from flake8 import style_guide
|
from flake8 import style_guide
|
||||||
|
|
||||||
DEFAULT_ERROR_CODE = 'E100'
|
DEFAULT_ERROR_CODE = "E100"
|
||||||
DEFAULT_FILENAME = 'file.py'
|
DEFAULT_FILENAME = "file.py"
|
||||||
DEFAULT_TEXT = 'Default text'
|
DEFAULT_TEXT = "Default text"
|
||||||
|
|
||||||
|
|
||||||
def make_error(**kwargs):
|
def make_error(**kwargs):
|
||||||
"""Create errors with a bunch of default values."""
|
"""Create errors with a bunch of default values."""
|
||||||
return style_guide.Violation(
|
return style_guide.Violation(
|
||||||
code=kwargs.pop('code', DEFAULT_ERROR_CODE),
|
code=kwargs.pop("code", DEFAULT_ERROR_CODE),
|
||||||
filename=kwargs.pop('filename', DEFAULT_FILENAME),
|
filename=kwargs.pop("filename", DEFAULT_FILENAME),
|
||||||
line_number=kwargs.pop('line_number', 1),
|
line_number=kwargs.pop("line_number", 1),
|
||||||
column_number=kwargs.pop('column_number', 1),
|
column_number=kwargs.pop("column_number", 1),
|
||||||
text=kwargs.pop('text', DEFAULT_TEXT),
|
text=kwargs.pop("text", DEFAULT_TEXT),
|
||||||
physical_line=None,
|
physical_line=None,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -29,26 +29,29 @@ def test_key_creation():
|
||||||
assert key.code == DEFAULT_ERROR_CODE
|
assert key.code == DEFAULT_ERROR_CODE
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize('code, filename, args, expected_result', [
|
@pytest.mark.parametrize(
|
||||||
# Error prefix matches
|
"code, filename, args, expected_result",
|
||||||
('E123', 'file000.py', ('E', None), True),
|
[
|
||||||
('E123', 'file000.py', ('E1', None), True),
|
# Error prefix matches
|
||||||
('E123', 'file000.py', ('E12', None), True),
|
("E123", "file000.py", ("E", None), True),
|
||||||
('E123', 'file000.py', ('E123', None), True),
|
("E123", "file000.py", ("E1", None), True),
|
||||||
# Error prefix and filename match
|
("E123", "file000.py", ("E12", None), True),
|
||||||
('E123', 'file000.py', ('E', 'file000.py'), True),
|
("E123", "file000.py", ("E123", None), True),
|
||||||
('E123', 'file000.py', ('E1', 'file000.py'), True),
|
# Error prefix and filename match
|
||||||
('E123', 'file000.py', ('E12', 'file000.py'), True),
|
("E123", "file000.py", ("E", "file000.py"), True),
|
||||||
('E123', 'file000.py', ('E123', 'file000.py'), True),
|
("E123", "file000.py", ("E1", "file000.py"), True),
|
||||||
# Error prefix does not match
|
("E123", "file000.py", ("E12", "file000.py"), True),
|
||||||
('E123', 'file000.py', ('W', None), False),
|
("E123", "file000.py", ("E123", "file000.py"), True),
|
||||||
# Error prefix matches but filename does not
|
# Error prefix does not match
|
||||||
('E123', 'file000.py', ('E', 'file001.py'), False),
|
("E123", "file000.py", ("W", None), False),
|
||||||
# Error prefix does not match but filename does
|
# Error prefix matches but filename does not
|
||||||
('E123', 'file000.py', ('W', 'file000.py'), False),
|
("E123", "file000.py", ("E", "file001.py"), False),
|
||||||
# Neither error prefix match nor filename
|
# Error prefix does not match but filename does
|
||||||
('E123', 'file000.py', ('W', 'file001.py'), False),
|
("E123", "file000.py", ("W", "file000.py"), False),
|
||||||
])
|
# Neither error prefix match nor filename
|
||||||
|
("E123", "file000.py", ("W", "file001.py"), False),
|
||||||
|
],
|
||||||
|
)
|
||||||
def test_key_matching(code, filename, args, expected_result):
|
def test_key_matching(code, filename, args, expected_result):
|
||||||
"""Verify Key#matches behaves as we expect with fthe above input."""
|
"""Verify Key#matches behaves as we expect with fthe above input."""
|
||||||
key = stats.Key.create_from(make_error(code=code, filename=filename))
|
key = stats.Key.create_from(make_error(code=code, filename=filename))
|
||||||
|
|
@ -75,7 +78,7 @@ def test_statistic_increment():
|
||||||
def test_recording_statistics():
|
def test_recording_statistics():
|
||||||
"""Verify that we appropriately create a new Statistic and store it."""
|
"""Verify that we appropriately create a new Statistic and store it."""
|
||||||
aggregator = stats.Statistics()
|
aggregator = stats.Statistics()
|
||||||
assert list(aggregator.statistics_for('E')) == []
|
assert list(aggregator.statistics_for("E")) == []
|
||||||
aggregator.record(make_error())
|
aggregator.record(make_error())
|
||||||
storage = aggregator._store
|
storage = aggregator._store
|
||||||
for key, value in storage.items():
|
for key, value in storage.items():
|
||||||
|
|
@ -88,9 +91,9 @@ def test_recording_statistics():
|
||||||
def test_statistics_for_single_record():
|
def test_statistics_for_single_record():
|
||||||
"""Show we can retrieve the only statistic recorded."""
|
"""Show we can retrieve the only statistic recorded."""
|
||||||
aggregator = stats.Statistics()
|
aggregator = stats.Statistics()
|
||||||
assert list(aggregator.statistics_for('E')) == []
|
assert list(aggregator.statistics_for("E")) == []
|
||||||
aggregator.record(make_error())
|
aggregator.record(make_error())
|
||||||
statistics = list(aggregator.statistics_for('E'))
|
statistics = list(aggregator.statistics_for("E"))
|
||||||
assert len(statistics) == 1
|
assert len(statistics) == 1
|
||||||
assert isinstance(statistics[0], stats.Statistic)
|
assert isinstance(statistics[0], stats.Statistic)
|
||||||
|
|
||||||
|
|
@ -98,11 +101,11 @@ def test_statistics_for_single_record():
|
||||||
def test_statistics_for_filters_by_filename():
|
def test_statistics_for_filters_by_filename():
|
||||||
"""Show we can retrieve the only statistic recorded."""
|
"""Show we can retrieve the only statistic recorded."""
|
||||||
aggregator = stats.Statistics()
|
aggregator = stats.Statistics()
|
||||||
assert list(aggregator.statistics_for('E')) == []
|
assert list(aggregator.statistics_for("E")) == []
|
||||||
aggregator.record(make_error())
|
aggregator.record(make_error())
|
||||||
aggregator.record(make_error(filename='example.py'))
|
aggregator.record(make_error(filename="example.py"))
|
||||||
|
|
||||||
statistics = list(aggregator.statistics_for('E', DEFAULT_FILENAME))
|
statistics = list(aggregator.statistics_for("E", DEFAULT_FILENAME))
|
||||||
assert len(statistics) == 1
|
assert len(statistics) == 1
|
||||||
assert isinstance(statistics[0], stats.Statistic)
|
assert isinstance(statistics[0], stats.Statistic)
|
||||||
|
|
||||||
|
|
@ -111,11 +114,11 @@ def test_statistic_for_retrieves_more_than_one_value():
|
||||||
"""Show this works for more than a couple statistic values."""
|
"""Show this works for more than a couple statistic values."""
|
||||||
aggregator = stats.Statistics()
|
aggregator = stats.Statistics()
|
||||||
for i in range(50):
|
for i in range(50):
|
||||||
aggregator.record(make_error(code=f'E1{i:02d}'))
|
aggregator.record(make_error(code=f"E1{i:02d}"))
|
||||||
aggregator.record(make_error(code=f'W2{i:02d}'))
|
aggregator.record(make_error(code=f"W2{i:02d}"))
|
||||||
|
|
||||||
statistics = list(aggregator.statistics_for('E'))
|
statistics = list(aggregator.statistics_for("E"))
|
||||||
assert len(statistics) == 50
|
assert len(statistics) == 50
|
||||||
|
|
||||||
statistics = list(aggregator.statistics_for('W22'))
|
statistics = list(aggregator.statistics_for("W22"))
|
||||||
assert len(statistics) == 10
|
assert len(statistics) == 10
|
||||||
|
|
|
||||||
|
|
@ -14,86 +14,92 @@ from flake8.plugins import manager as plugin_manager
|
||||||
RELATIVE_PATHS = ["flake8", "pep8", "pyflakes", "mccabe"]
|
RELATIVE_PATHS = ["flake8", "pep8", "pyflakes", "mccabe"]
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize("value,expected", [
|
@pytest.mark.parametrize(
|
||||||
("E123,\n\tW234,\n E206", ["E123", "W234", "E206"]),
|
"value,expected",
|
||||||
("E123,W234,E206", ["E123", "W234", "E206"]),
|
[
|
||||||
("E123 W234 E206", ["E123", "W234", "E206"]),
|
("E123,\n\tW234,\n E206", ["E123", "W234", "E206"]),
|
||||||
("E123\nW234 E206", ["E123", "W234", "E206"]),
|
("E123,W234,E206", ["E123", "W234", "E206"]),
|
||||||
("E123\nW234\nE206", ["E123", "W234", "E206"]),
|
("E123 W234 E206", ["E123", "W234", "E206"]),
|
||||||
("E123,W234,E206,", ["E123", "W234", "E206"]),
|
("E123\nW234 E206", ["E123", "W234", "E206"]),
|
||||||
("E123,W234,E206, ,\n", ["E123", "W234", "E206"]),
|
("E123\nW234\nE206", ["E123", "W234", "E206"]),
|
||||||
("E123,W234,,E206,,", ["E123", "W234", "E206"]),
|
("E123,W234,E206,", ["E123", "W234", "E206"]),
|
||||||
("E123, W234,, E206,,", ["E123", "W234", "E206"]),
|
("E123,W234,E206, ,\n", ["E123", "W234", "E206"]),
|
||||||
("E123,,W234,,E206,,", ["E123", "W234", "E206"]),
|
("E123,W234,,E206,,", ["E123", "W234", "E206"]),
|
||||||
("", []),
|
("E123, W234,, E206,,", ["E123", "W234", "E206"]),
|
||||||
])
|
("E123,,W234,,E206,,", ["E123", "W234", "E206"]),
|
||||||
|
("", []),
|
||||||
|
],
|
||||||
|
)
|
||||||
def test_parse_comma_separated_list(value, expected):
|
def test_parse_comma_separated_list(value, expected):
|
||||||
"""Verify that similar inputs produce identical outputs."""
|
"""Verify that similar inputs produce identical outputs."""
|
||||||
assert utils.parse_comma_separated_list(value) == expected
|
assert utils.parse_comma_separated_list(value) == expected
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize(
|
||||||
('value', 'expected'),
|
("value", "expected"),
|
||||||
(
|
(
|
||||||
# empty option configures nothing
|
# empty option configures nothing
|
||||||
('', []), (' ', []), ('\n\n\n', []),
|
("", []),
|
||||||
|
(" ", []),
|
||||||
|
("\n\n\n", []),
|
||||||
# basic case
|
# basic case
|
||||||
(
|
(
|
||||||
'f.py:E123',
|
"f.py:E123",
|
||||||
[('f.py', ['E123'])],
|
[("f.py", ["E123"])],
|
||||||
),
|
),
|
||||||
# multiple filenames, multiple codes
|
# multiple filenames, multiple codes
|
||||||
(
|
(
|
||||||
'f.py,g.py:E,F',
|
"f.py,g.py:E,F",
|
||||||
[('f.py', ['E', 'F']), ('g.py', ['E', 'F'])],
|
[("f.py", ["E", "F"]), ("g.py", ["E", "F"])],
|
||||||
),
|
),
|
||||||
# demonstrate that whitespace is not important around tokens
|
# demonstrate that whitespace is not important around tokens
|
||||||
(
|
(
|
||||||
' f.py , g.py : E , F ',
|
" f.py , g.py : E , F ",
|
||||||
[('f.py', ['E', 'F']), ('g.py', ['E', 'F'])],
|
[("f.py", ["E", "F"]), ("g.py", ["E", "F"])],
|
||||||
),
|
),
|
||||||
# whitespace can separate groups of configuration
|
# whitespace can separate groups of configuration
|
||||||
(
|
(
|
||||||
'f.py:E g.py:F',
|
"f.py:E g.py:F",
|
||||||
[('f.py', ['E']), ('g.py', ['F'])],
|
[("f.py", ["E"]), ("g.py", ["F"])],
|
||||||
),
|
),
|
||||||
# newlines can separate groups of configuration
|
# newlines can separate groups of configuration
|
||||||
(
|
(
|
||||||
'f.py: E\ng.py: F\n',
|
"f.py: E\ng.py: F\n",
|
||||||
[('f.py', ['E']), ('g.py', ['F'])],
|
[("f.py", ["E"]), ("g.py", ["F"])],
|
||||||
),
|
),
|
||||||
# whitespace can be used in place of commas
|
# whitespace can be used in place of commas
|
||||||
(
|
(
|
||||||
'f.py g.py: E F',
|
"f.py g.py: E F",
|
||||||
[('f.py', ['E', 'F']), ('g.py', ['E', 'F'])],
|
[("f.py", ["E", "F"]), ("g.py", ["E", "F"])],
|
||||||
),
|
),
|
||||||
# go ahead, indent your codes
|
# go ahead, indent your codes
|
||||||
(
|
(
|
||||||
'f.py:\n E,F\ng.py:\n G,H',
|
"f.py:\n E,F\ng.py:\n G,H",
|
||||||
[('f.py', ['E', 'F']), ('g.py', ['G', 'H'])],
|
[("f.py", ["E", "F"]), ("g.py", ["G", "H"])],
|
||||||
),
|
),
|
||||||
# capitalized filenames are ok too
|
# capitalized filenames are ok too
|
||||||
(
|
(
|
||||||
'F.py,G.py: F,G',
|
"F.py,G.py: F,G",
|
||||||
[('F.py', ['F', 'G']), ('G.py', ['F', 'G'])],
|
[("F.py", ["F", "G"]), ("G.py", ["F", "G"])],
|
||||||
),
|
),
|
||||||
# it's easier to allow zero filenames or zero codes than forbid it
|
# it's easier to allow zero filenames or zero codes than forbid it
|
||||||
(':E', []), ('f.py:', []),
|
(":E", []),
|
||||||
(':E f.py:F', [('f.py', ['F'])]),
|
("f.py:", []),
|
||||||
('f.py: g.py:F', [('g.py', ['F'])]),
|
(":E f.py:F", [("f.py", ["F"])]),
|
||||||
('f.py:E:', []),
|
("f.py: g.py:F", [("g.py", ["F"])]),
|
||||||
('f.py:E.py:', []),
|
("f.py:E:", []),
|
||||||
('f.py:Eg.py:F', [('Eg.py', ['F'])]),
|
("f.py:E.py:", []),
|
||||||
|
("f.py:Eg.py:F", [("Eg.py", ["F"])]),
|
||||||
# sequences are also valid (?)
|
# sequences are also valid (?)
|
||||||
(
|
(
|
||||||
['f.py:E,F', 'g.py:G,H'],
|
["f.py:E,F", "g.py:G,H"],
|
||||||
[('f.py', ['E', 'F']), ('g.py', ['G', 'H'])],
|
[("f.py", ["E", "F"]), ("g.py", ["G", "H"])],
|
||||||
),
|
),
|
||||||
# six-digits codes are allowed
|
# six-digits codes are allowed
|
||||||
(
|
(
|
||||||
'f.py: ABC123',
|
"f.py: ABC123",
|
||||||
[('f.py', ['ABC123'])],
|
[("f.py", ["ABC123"])],
|
||||||
)
|
),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
def test_parse_files_to_codes_mapping(value, expected):
|
def test_parse_files_to_codes_mapping(value, expected):
|
||||||
|
|
@ -102,16 +108,19 @@ def test_parse_files_to_codes_mapping(value, expected):
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize(
|
||||||
'value',
|
"value",
|
||||||
(
|
(
|
||||||
# code while looking for filenames
|
# code while looking for filenames
|
||||||
'E123', 'f.py,E123', 'f.py E123',
|
"E123",
|
||||||
|
"f.py,E123",
|
||||||
|
"f.py E123",
|
||||||
# eof while looking for filenames
|
# eof while looking for filenames
|
||||||
'f.py', 'f.py:E,g.py'
|
"f.py",
|
||||||
|
"f.py:E,g.py"
|
||||||
# colon while looking for codes
|
# colon while looking for codes
|
||||||
'f.py::',
|
"f.py::",
|
||||||
# no separator between
|
# no separator between
|
||||||
'f.py:E1F1',
|
"f.py:E1F1",
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
def test_invalid_file_list(value):
|
def test_invalid_file_list(value):
|
||||||
|
|
@ -120,22 +129,32 @@ def test_invalid_file_list(value):
|
||||||
utils.parse_files_to_codes_mapping(value)
|
utils.parse_files_to_codes_mapping(value)
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize("value,expected", [
|
@pytest.mark.parametrize(
|
||||||
("flake8", "flake8"),
|
"value,expected",
|
||||||
("../flake8", os.path.abspath("../flake8")),
|
[
|
||||||
("flake8/", os.path.abspath("flake8")),
|
("flake8", "flake8"),
|
||||||
])
|
("../flake8", os.path.abspath("../flake8")),
|
||||||
|
("flake8/", os.path.abspath("flake8")),
|
||||||
|
],
|
||||||
|
)
|
||||||
def test_normalize_path(value, expected):
|
def test_normalize_path(value, expected):
|
||||||
"""Verify that we normalize paths provided to the tool."""
|
"""Verify that we normalize paths provided to the tool."""
|
||||||
assert utils.normalize_path(value) == expected
|
assert utils.normalize_path(value) == expected
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize("value,expected", [
|
@pytest.mark.parametrize(
|
||||||
(["flake8", "pep8", "pyflakes", "mccabe"],
|
"value,expected",
|
||||||
["flake8", "pep8", "pyflakes", "mccabe"]),
|
[
|
||||||
(["../flake8", "../pep8", "../pyflakes", "../mccabe"],
|
(
|
||||||
[os.path.abspath(f"../{p}") for p in RELATIVE_PATHS]),
|
["flake8", "pep8", "pyflakes", "mccabe"],
|
||||||
])
|
["flake8", "pep8", "pyflakes", "mccabe"],
|
||||||
|
),
|
||||||
|
(
|
||||||
|
["../flake8", "../pep8", "../pyflakes", "../mccabe"],
|
||||||
|
[os.path.abspath(f"../{p}") for p in RELATIVE_PATHS],
|
||||||
|
),
|
||||||
|
],
|
||||||
|
)
|
||||||
def test_normalize_paths(value, expected):
|
def test_normalize_paths(value, expected):
|
||||||
"""Verify we normalizes a sequence of paths provided to the tool."""
|
"""Verify we normalizes a sequence of paths provided to the tool."""
|
||||||
assert utils.normalize_paths(value) == expected
|
assert utils.normalize_paths(value) == expected
|
||||||
|
|
@ -143,19 +162,22 @@ def test_normalize_paths(value, expected):
|
||||||
|
|
||||||
def test_is_windows_checks_for_nt():
|
def test_is_windows_checks_for_nt():
|
||||||
"""Verify that we correctly detect Windows."""
|
"""Verify that we correctly detect Windows."""
|
||||||
with mock.patch.object(os, 'name', 'nt'):
|
with mock.patch.object(os, "name", "nt"):
|
||||||
assert utils.is_windows() is True
|
assert utils.is_windows() is True
|
||||||
|
|
||||||
with mock.patch.object(os, 'name', 'posix'):
|
with mock.patch.object(os, "name", "posix"):
|
||||||
assert utils.is_windows() is False
|
assert utils.is_windows() is False
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize('filename,patterns,expected', [
|
@pytest.mark.parametrize(
|
||||||
('foo.py', [], True),
|
"filename,patterns,expected",
|
||||||
('foo.py', ['*.pyc'], False),
|
[
|
||||||
('foo.pyc', ['*.pyc'], True),
|
("foo.py", [], True),
|
||||||
('foo.pyc', ['*.swp', '*.pyc', '*.py'], True),
|
("foo.py", ["*.pyc"], False),
|
||||||
])
|
("foo.pyc", ["*.pyc"], True),
|
||||||
|
("foo.pyc", ["*.swp", "*.pyc", "*.py"], True),
|
||||||
|
],
|
||||||
|
)
|
||||||
def test_fnmatch(filename, patterns, expected):
|
def test_fnmatch(filename, patterns, expected):
|
||||||
"""Verify that our fnmatch wrapper works as expected."""
|
"""Verify that our fnmatch wrapper works as expected."""
|
||||||
assert utils.fnmatch(filename, patterns) is expected
|
assert utils.fnmatch(filename, patterns) is expected
|
||||||
|
|
@ -165,104 +187,110 @@ def test_fnmatch(filename, patterns, expected):
|
||||||
def files_dir(tmpdir):
|
def files_dir(tmpdir):
|
||||||
"""Create test dir for testing filenames_from."""
|
"""Create test dir for testing filenames_from."""
|
||||||
with tmpdir.as_cwd():
|
with tmpdir.as_cwd():
|
||||||
tmpdir.join('a/b/c.py').ensure()
|
tmpdir.join("a/b/c.py").ensure()
|
||||||
tmpdir.join('a/b/d.py').ensure()
|
tmpdir.join("a/b/d.py").ensure()
|
||||||
tmpdir.join('a/b/e/f.py').ensure()
|
tmpdir.join("a/b/e/f.py").ensure()
|
||||||
yield tmpdir
|
yield tmpdir
|
||||||
|
|
||||||
|
|
||||||
def _normpath(s):
|
def _normpath(s):
|
||||||
return s.replace('/', os.sep)
|
return s.replace("/", os.sep)
|
||||||
|
|
||||||
|
|
||||||
def _normpaths(pths):
|
def _normpaths(pths):
|
||||||
return {_normpath(pth) for pth in pths}
|
return {_normpath(pth) for pth in pths}
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.usefixtures('files_dir')
|
@pytest.mark.usefixtures("files_dir")
|
||||||
def test_filenames_from_a_directory():
|
def test_filenames_from_a_directory():
|
||||||
"""Verify that filenames_from walks a directory."""
|
"""Verify that filenames_from walks a directory."""
|
||||||
filenames = set(utils.filenames_from(_normpath('a/b/')))
|
filenames = set(utils.filenames_from(_normpath("a/b/")))
|
||||||
# should include all files
|
# should include all files
|
||||||
expected = _normpaths(('a/b/c.py', 'a/b/d.py', 'a/b/e/f.py'))
|
expected = _normpaths(("a/b/c.py", "a/b/d.py", "a/b/e/f.py"))
|
||||||
assert filenames == expected
|
assert filenames == expected
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.usefixtures('files_dir')
|
@pytest.mark.usefixtures("files_dir")
|
||||||
def test_filenames_from_a_directory_with_a_predicate():
|
def test_filenames_from_a_directory_with_a_predicate():
|
||||||
"""Verify that predicates filter filenames_from."""
|
"""Verify that predicates filter filenames_from."""
|
||||||
filenames = set(utils.filenames_from(
|
filenames = set(
|
||||||
arg=_normpath('a/b/'),
|
utils.filenames_from(
|
||||||
predicate=lambda path: path.endswith(_normpath('b/c.py')),
|
arg=_normpath("a/b/"),
|
||||||
))
|
predicate=lambda path: path.endswith(_normpath("b/c.py")),
|
||||||
|
)
|
||||||
|
)
|
||||||
# should not include c.py
|
# should not include c.py
|
||||||
expected = _normpaths(('a/b/d.py', 'a/b/e/f.py'))
|
expected = _normpaths(("a/b/d.py", "a/b/e/f.py"))
|
||||||
assert filenames == expected
|
assert filenames == expected
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.usefixtures('files_dir')
|
@pytest.mark.usefixtures("files_dir")
|
||||||
def test_filenames_from_a_directory_with_a_predicate_from_the_current_dir():
|
def test_filenames_from_a_directory_with_a_predicate_from_the_current_dir():
|
||||||
"""Verify that predicates filter filenames_from."""
|
"""Verify that predicates filter filenames_from."""
|
||||||
filenames = set(utils.filenames_from(
|
filenames = set(
|
||||||
arg=_normpath('./a/b'),
|
utils.filenames_from(
|
||||||
predicate=lambda path: path == 'c.py',
|
arg=_normpath("./a/b"),
|
||||||
))
|
predicate=lambda path: path == "c.py",
|
||||||
|
)
|
||||||
|
)
|
||||||
# none should have matched the predicate so all returned
|
# none should have matched the predicate so all returned
|
||||||
expected = _normpaths(('./a/b/c.py', './a/b/d.py', './a/b/e/f.py'))
|
expected = _normpaths(("./a/b/c.py", "./a/b/d.py", "./a/b/e/f.py"))
|
||||||
assert filenames == expected
|
assert filenames == expected
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.usefixtures('files_dir')
|
@pytest.mark.usefixtures("files_dir")
|
||||||
def test_filenames_from_a_single_file():
|
def test_filenames_from_a_single_file():
|
||||||
"""Verify that we simply yield that filename."""
|
"""Verify that we simply yield that filename."""
|
||||||
filenames = set(utils.filenames_from(_normpath('a/b/c.py')))
|
filenames = set(utils.filenames_from(_normpath("a/b/c.py")))
|
||||||
assert filenames == {_normpath('a/b/c.py')}
|
assert filenames == {_normpath("a/b/c.py")}
|
||||||
|
|
||||||
|
|
||||||
def test_filenames_from_a_single_file_does_not_exist():
|
def test_filenames_from_a_single_file_does_not_exist():
|
||||||
"""Verify that a passed filename which does not exist is returned back."""
|
"""Verify that a passed filename which does not exist is returned back."""
|
||||||
filenames = set(utils.filenames_from(_normpath('d/n/e.py')))
|
filenames = set(utils.filenames_from(_normpath("d/n/e.py")))
|
||||||
assert filenames == {_normpath('d/n/e.py')}
|
assert filenames == {_normpath("d/n/e.py")}
|
||||||
|
|
||||||
|
|
||||||
def test_filenames_from_exclude_doesnt_exclude_directory_names(tmpdir):
|
def test_filenames_from_exclude_doesnt_exclude_directory_names(tmpdir):
|
||||||
"""Verify that we don't greedily exclude subdirs."""
|
"""Verify that we don't greedily exclude subdirs."""
|
||||||
tmpdir.join('1').ensure_dir().join('dont_return_me.py').ensure()
|
tmpdir.join("1").ensure_dir().join("dont_return_me.py").ensure()
|
||||||
tmpdir.join('2').join('1').ensure_dir().join('return_me.py').ensure()
|
tmpdir.join("2").join("1").ensure_dir().join("return_me.py").ensure()
|
||||||
exclude = [tmpdir.join('1').strpath]
|
exclude = [tmpdir.join("1").strpath]
|
||||||
|
|
||||||
# This acts similar to src.flake8.checker.is_path_excluded
|
# This acts similar to src.flake8.checker.is_path_excluded
|
||||||
def predicate(pth):
|
def predicate(pth):
|
||||||
return utils.fnmatch(os.path.abspath(pth), exclude)
|
return utils.fnmatch(os.path.abspath(pth), exclude)
|
||||||
|
|
||||||
with tmpdir.as_cwd():
|
with tmpdir.as_cwd():
|
||||||
filenames = list(utils.filenames_from('.', predicate))
|
filenames = list(utils.filenames_from(".", predicate))
|
||||||
assert filenames == [os.path.join('.', '2', '1', 'return_me.py')]
|
assert filenames == [os.path.join(".", "2", "1", "return_me.py")]
|
||||||
|
|
||||||
|
|
||||||
def test_parameters_for_class_plugin():
|
def test_parameters_for_class_plugin():
|
||||||
"""Verify that we can retrieve the parameters for a class plugin."""
|
"""Verify that we can retrieve the parameters for a class plugin."""
|
||||||
|
|
||||||
class FakeCheck:
|
class FakeCheck:
|
||||||
def __init__(self, tree):
|
def __init__(self, tree):
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
plugin = plugin_manager.Plugin('plugin-name', object())
|
plugin = plugin_manager.Plugin("plugin-name", object())
|
||||||
plugin._plugin = FakeCheck
|
plugin._plugin = FakeCheck
|
||||||
assert utils.parameters_for(plugin) == {'tree': True}
|
assert utils.parameters_for(plugin) == {"tree": True}
|
||||||
|
|
||||||
|
|
||||||
def test_parameters_for_function_plugin():
|
def test_parameters_for_function_plugin():
|
||||||
"""Verify that we retrieve the parameters for a function plugin."""
|
"""Verify that we retrieve the parameters for a function plugin."""
|
||||||
|
|
||||||
def fake_plugin(physical_line, self, tree, optional=None):
|
def fake_plugin(physical_line, self, tree, optional=None):
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
plugin = plugin_manager.Plugin('plugin-name', object())
|
plugin = plugin_manager.Plugin("plugin-name", object())
|
||||||
plugin._plugin = fake_plugin
|
plugin._plugin = fake_plugin
|
||||||
assert utils.parameters_for(plugin) == {
|
assert utils.parameters_for(plugin) == {
|
||||||
'physical_line': True,
|
"physical_line": True,
|
||||||
'self': True,
|
"self": True,
|
||||||
'tree': True,
|
"tree": True,
|
||||||
'optional': False,
|
"optional": False,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -273,29 +301,32 @@ def read_diff_file(filename):
|
||||||
return content
|
return content
|
||||||
|
|
||||||
|
|
||||||
SINGLE_FILE_DIFF = read_diff_file('tests/fixtures/diffs/single_file_diff')
|
SINGLE_FILE_DIFF = read_diff_file("tests/fixtures/diffs/single_file_diff")
|
||||||
SINGLE_FILE_INFO = {
|
SINGLE_FILE_INFO = {
|
||||||
'flake8/utils.py': set(range(75, 83)).union(set(range(84, 94))),
|
"flake8/utils.py": set(range(75, 83)).union(set(range(84, 94))),
|
||||||
}
|
}
|
||||||
TWO_FILE_DIFF = read_diff_file('tests/fixtures/diffs/two_file_diff')
|
TWO_FILE_DIFF = read_diff_file("tests/fixtures/diffs/two_file_diff")
|
||||||
TWO_FILE_INFO = {
|
TWO_FILE_INFO = {
|
||||||
'flake8/utils.py': set(range(75, 83)).union(set(range(84, 94))),
|
"flake8/utils.py": set(range(75, 83)).union(set(range(84, 94))),
|
||||||
'tests/unit/test_utils.py': set(range(115, 128)),
|
"tests/unit/test_utils.py": set(range(115, 128)),
|
||||||
}
|
}
|
||||||
MULTI_FILE_DIFF = read_diff_file('tests/fixtures/diffs/multi_file_diff')
|
MULTI_FILE_DIFF = read_diff_file("tests/fixtures/diffs/multi_file_diff")
|
||||||
MULTI_FILE_INFO = {
|
MULTI_FILE_INFO = {
|
||||||
'flake8/utils.py': set(range(75, 83)).union(set(range(84, 94))),
|
"flake8/utils.py": set(range(75, 83)).union(set(range(84, 94))),
|
||||||
'tests/unit/test_utils.py': set(range(115, 129)),
|
"tests/unit/test_utils.py": set(range(115, 129)),
|
||||||
'tests/fixtures/diffs/single_file_diff': set(range(1, 28)),
|
"tests/fixtures/diffs/single_file_diff": set(range(1, 28)),
|
||||||
'tests/fixtures/diffs/two_file_diff': set(range(1, 46)),
|
"tests/fixtures/diffs/two_file_diff": set(range(1, 46)),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize("diff, parsed_diff", [
|
@pytest.mark.parametrize(
|
||||||
(SINGLE_FILE_DIFF, SINGLE_FILE_INFO),
|
"diff, parsed_diff",
|
||||||
(TWO_FILE_DIFF, TWO_FILE_INFO),
|
[
|
||||||
(MULTI_FILE_DIFF, MULTI_FILE_INFO),
|
(SINGLE_FILE_DIFF, SINGLE_FILE_INFO),
|
||||||
])
|
(TWO_FILE_DIFF, TWO_FILE_INFO),
|
||||||
|
(MULTI_FILE_DIFF, MULTI_FILE_INFO),
|
||||||
|
],
|
||||||
|
)
|
||||||
def test_parse_unified_diff(diff, parsed_diff):
|
def test_parse_unified_diff(diff, parsed_diff):
|
||||||
"""Verify that what we parse from a diff matches expectations."""
|
"""Verify that what we parse from a diff matches expectations."""
|
||||||
assert utils.parse_unified_diff(diff) == parsed_diff
|
assert utils.parse_unified_diff(diff) == parsed_diff
|
||||||
|
|
@ -304,19 +335,19 @@ def test_parse_unified_diff(diff, parsed_diff):
|
||||||
def test_matches_filename_for_excluding_dotfiles():
|
def test_matches_filename_for_excluding_dotfiles():
|
||||||
"""Verify that `.` and `..` are not matched by `.*`."""
|
"""Verify that `.` and `..` are not matched by `.*`."""
|
||||||
logger = logging.Logger(__name__)
|
logger = logging.Logger(__name__)
|
||||||
assert not utils.matches_filename('.', ('.*',), '', logger)
|
assert not utils.matches_filename(".", (".*",), "", logger)
|
||||||
assert not utils.matches_filename('..', ('.*',), '', logger)
|
assert not utils.matches_filename("..", (".*",), "", logger)
|
||||||
|
|
||||||
|
|
||||||
def test_stdin_get_value_crlf():
|
def test_stdin_get_value_crlf():
|
||||||
"""Ensure that stdin is normalized from crlf to lf."""
|
"""Ensure that stdin is normalized from crlf to lf."""
|
||||||
stdin = io.TextIOWrapper(io.BytesIO(b'1\r\n2\r\n'), 'UTF-8')
|
stdin = io.TextIOWrapper(io.BytesIO(b"1\r\n2\r\n"), "UTF-8")
|
||||||
with mock.patch.object(sys, 'stdin', stdin):
|
with mock.patch.object(sys, "stdin", stdin):
|
||||||
assert utils.stdin_get_value.__wrapped__() == '1\n2\n'
|
assert utils.stdin_get_value.__wrapped__() == "1\n2\n"
|
||||||
|
|
||||||
|
|
||||||
def test_stdin_unknown_coding_token():
|
def test_stdin_unknown_coding_token():
|
||||||
"""Ensure we produce source even for unknown encodings."""
|
"""Ensure we produce source even for unknown encodings."""
|
||||||
stdin = io.TextIOWrapper(io.BytesIO(b'# coding: unknown\n'), 'UTF-8')
|
stdin = io.TextIOWrapper(io.BytesIO(b"# coding: unknown\n"), "UTF-8")
|
||||||
with mock.patch.object(sys, 'stdin', stdin):
|
with mock.patch.object(sys, "stdin", stdin):
|
||||||
assert utils.stdin_get_value.__wrapped__() == '# coding: unknown\n'
|
assert utils.stdin_get_value.__wrapped__() == "# coding: unknown\n"
|
||||||
|
|
|
||||||
|
|
@ -6,61 +6,74 @@ import pytest
|
||||||
from flake8 import style_guide
|
from flake8 import style_guide
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize('error_code,physical_line,expected_result', [
|
@pytest.mark.parametrize(
|
||||||
('E111', 'a = 1', False),
|
"error_code,physical_line,expected_result",
|
||||||
('E121', 'a = 1 # noqa: E111', False),
|
[
|
||||||
('E121', 'a = 1 # noqa: E111,W123,F821', False),
|
("E111", "a = 1", False),
|
||||||
('E111', 'a = 1 # noqa: E111,W123,F821', True),
|
("E121", "a = 1 # noqa: E111", False),
|
||||||
('W123', 'a = 1 # noqa: E111,W123,F821', True),
|
("E121", "a = 1 # noqa: E111,W123,F821", False),
|
||||||
('W123', 'a = 1 # noqa: E111, W123,F821', True),
|
("E111", "a = 1 # noqa: E111,W123,F821", True),
|
||||||
('E111', 'a = 1 # noqa: E11,W123,F821', True),
|
("W123", "a = 1 # noqa: E111,W123,F821", True),
|
||||||
('E121', 'a = 1 # noqa:E111,W123,F821', False),
|
("W123", "a = 1 # noqa: E111, W123,F821", True),
|
||||||
('E111', 'a = 1 # noqa:E111,W123,F821', True),
|
("E111", "a = 1 # noqa: E11,W123,F821", True),
|
||||||
('W123', 'a = 1 # noqa:E111,W123,F821', True),
|
("E121", "a = 1 # noqa:E111,W123,F821", False),
|
||||||
('W123', 'a = 1 # noqa:E111, W123,F821', True),
|
("E111", "a = 1 # noqa:E111,W123,F821", True),
|
||||||
('E111', 'a = 1 # noqa:E11,W123,F821', True),
|
("W123", "a = 1 # noqa:E111,W123,F821", True),
|
||||||
('E111', 'a = 1 # noqa, analysis:ignore', True),
|
("W123", "a = 1 # noqa:E111, W123,F821", True),
|
||||||
('E111', 'a = 1 # noqa analysis:ignore', True),
|
("E111", "a = 1 # noqa:E11,W123,F821", True),
|
||||||
('E111', 'a = 1 # noqa - We do not care', True),
|
("E111", "a = 1 # noqa, analysis:ignore", True),
|
||||||
('E111', 'a = 1 # noqa: We do not care', True),
|
("E111", "a = 1 # noqa analysis:ignore", True),
|
||||||
('E111', 'a = 1 # noqa:We do not care', True),
|
("E111", "a = 1 # noqa - We do not care", True),
|
||||||
('ABC123', 'a = 1 # noqa: ABC123', True),
|
("E111", "a = 1 # noqa: We do not care", True),
|
||||||
('E111', 'a = 1 # noqa: ABC123', False),
|
("E111", "a = 1 # noqa:We do not care", True),
|
||||||
('ABC123', 'a = 1 # noqa: ABC124', False),
|
("ABC123", "a = 1 # noqa: ABC123", True),
|
||||||
])
|
("E111", "a = 1 # noqa: ABC123", False),
|
||||||
|
("ABC123", "a = 1 # noqa: ABC124", False),
|
||||||
|
],
|
||||||
|
)
|
||||||
def test_is_inline_ignored(error_code, physical_line, expected_result):
|
def test_is_inline_ignored(error_code, physical_line, expected_result):
|
||||||
"""Verify that we detect inline usage of ``# noqa``."""
|
"""Verify that we detect inline usage of ``# noqa``."""
|
||||||
error = style_guide.Violation(
|
error = style_guide.Violation(
|
||||||
error_code, 'filename.py', 1, 1, 'error text', None)
|
error_code, "filename.py", 1, 1, "error text", None
|
||||||
|
)
|
||||||
# We want `None` to be passed as the physical line so we actually use our
|
# We want `None` to be passed as the physical line so we actually use our
|
||||||
# monkey-patched linecache.getline value.
|
# monkey-patched linecache.getline value.
|
||||||
|
|
||||||
with mock.patch('linecache.getline', return_value=physical_line):
|
with mock.patch("linecache.getline", return_value=physical_line):
|
||||||
assert error.is_inline_ignored(False) is expected_result
|
assert error.is_inline_ignored(False) is expected_result
|
||||||
|
|
||||||
|
|
||||||
def test_disable_is_inline_ignored():
|
def test_disable_is_inline_ignored():
|
||||||
"""Verify that is_inline_ignored exits immediately if disabling NoQA."""
|
"""Verify that is_inline_ignored exits immediately if disabling NoQA."""
|
||||||
error = style_guide.Violation(
|
error = style_guide.Violation(
|
||||||
'E121', 'filename.py', 1, 1, 'error text', 'line')
|
"E121", "filename.py", 1, 1, "error text", "line"
|
||||||
|
)
|
||||||
|
|
||||||
with mock.patch('linecache.getline') as getline:
|
with mock.patch("linecache.getline") as getline:
|
||||||
assert error.is_inline_ignored(True) is False
|
assert error.is_inline_ignored(True) is False
|
||||||
|
|
||||||
assert getline.called is False
|
assert getline.called is False
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize('violation_file,violation_line,diff,expected', [
|
@pytest.mark.parametrize(
|
||||||
('file.py', 10, {}, True),
|
"violation_file,violation_line,diff,expected",
|
||||||
('file.py', 1, {'file.py': range(1, 2)}, True),
|
[
|
||||||
('file.py', 10, {'file.py': range(1, 2)}, False),
|
("file.py", 10, {}, True),
|
||||||
('file.py', 1, {'other.py': range(1, 2)}, False),
|
("file.py", 1, {"file.py": range(1, 2)}, True),
|
||||||
('file.py', 10, {'other.py': range(1, 2)}, False),
|
("file.py", 10, {"file.py": range(1, 2)}, False),
|
||||||
])
|
("file.py", 1, {"other.py": range(1, 2)}, False),
|
||||||
|
("file.py", 10, {"other.py": range(1, 2)}, False),
|
||||||
|
],
|
||||||
|
)
|
||||||
def test_violation_is_in_diff(violation_file, violation_line, diff, expected):
|
def test_violation_is_in_diff(violation_file, violation_line, diff, expected):
|
||||||
"""Verify that we find violations within a diff."""
|
"""Verify that we find violations within a diff."""
|
||||||
violation = style_guide.Violation(
|
violation = style_guide.Violation(
|
||||||
'E001', violation_file, violation_line, 1, 'warning', 'line',
|
"E001",
|
||||||
|
violation_file,
|
||||||
|
violation_line,
|
||||||
|
1,
|
||||||
|
"warning",
|
||||||
|
"line",
|
||||||
)
|
)
|
||||||
|
|
||||||
assert violation.is_in(diff) is expected
|
assert violation.is_in(diff) is expected
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue