def test_indentation(): ind = Indentation(PythonFile.from_statement(""" def foo(): pass """)) nits = list(ind.nits()) assert len(nits) == 1 assert nits[0].code == 'T100' assert nits[0].severity == Nit.ERROR ind = Indentation(PythonFile.from_statement(""" def foo(): pass """)) nits = list(ind.nits()) assert len(nits) == 0 ind = Indentation(PythonFile.from_statement(""" def foo(): baz = ( "this " "is " "ok") """)) nits = list(ind.nits()) assert len(nits) == 0
def test_missing_contextmanager(): mcm = MissingContextManager(PythonFile.from_statement(""" with open("derp.txt"): pass with open("herp.txt") as fp: fp.read() """)) nits = list(mcm.nits()) assert len(nits) == 0 mcm = MissingContextManager(PythonFile.from_statement(""" foo = open("derp.txt") """)) nits = list(mcm.nits()) assert len(nits) == 1 assert nits[0].code == 'T802' assert nits[0].severity == Nit.WARNING # TODO(wickman) In these cases suggest using contextlib.closing mcm = MissingContextManager(PythonFile.from_statement(""" from urllib2 import urlopen the_googs = urlopen("http://www.google.com").read() """)) nits = list(mcm.nits()) assert len(nits) == 0
def test_new_style_classes(): nsc = NewStyleClasses(PythonFile.from_statement(""" class OldStyle: pass class NewStyle(object): pass """)) nits = list(nsc.nits()) assert len(nits) == 1 assert nits[0]._line_number == 1 assert nits[0].code == 'T606' assert nits[0].severity == Nit.ERROR nsc = NewStyleClasses(PythonFile.from_statement(""" class NewStyle(OtherThing, ThatThing, WhatAmIDoing): pass """)) nits = list(nsc.nits()) assert len(nits) == 0 nsc = NewStyleClasses(PythonFile.from_statement(""" class OldStyle(): # unspecified mro pass """)) nits = list(nsc.nits()) assert len(nits) == 1 assert nits[0].code == 'T606'
def test_newlines(): for toplevel_def in ('def bar():', 'class Bar(object):'): for num_newlines in (0, 1, 3, 4): newlines = Newlines(PythonFile.from_statement(TOPLEVEL % ('\n' * num_newlines, toplevel_def))) nits = list(newlines.nits()) assert len(nits) == 1 assert nits[0].code == 'T302' assert nits[0].severity == Nit.ERROR newlines = Newlines(PythonFile.from_statement(TOPLEVEL % ('\n\n', toplevel_def))) assert len(list(newlines.nits())) == 0
def test_lower_snake_method_names(): p8 = PEP8VariableNames(PythonFile.from_statement(""" def totally_fine(): print("Not in a class body") class DhisRight(object): def clearlyNotThinking(self): print("In a class body") """)) nits = list(p8.nits()) assert len(nits) == 1 assert nits[0].code == 'T002' assert nits[0]._line_number == 5 assert nits[0].severity == Nit.ERROR p8 = PEP8VariableNames(PythonFile.from_statement(""" class DhisRight: def clearlyNotThinking(self): print("In a class body") """)) nits = list(p8.nits()) assert len(nits) == 1 assert nits[0].code == 'T002' assert nits[0]._line_number == 2 assert nits[0].severity == Nit.ERROR # Allow derivations from other modules to be ok. p8 = PEP8VariableNames(PythonFile.from_statement(""" class TestCase(unittest.TestCase): def setUp(self): pass """)) nits = list(p8.nits()) assert len(list(p8.nits())) == 0 p8 = PEP8VariableNames(PythonFile.from_statement(""" def clearlyNotThinking(): print("Not in a class body") class DhisRight(object): def totally_fine(self): print("In a class body") """)) nits = list(p8.nits()) assert len(nits) == 1 assert nits[0].code == 'T002' assert nits[0]._line_number == 1 assert nits[0].severity == Nit.ERROR
def test_exception_map(): tw = TrailingWhitespace(PythonFile.from_statement(""" test_string_001 = "" test_string_002 = " " test_string_003 = \"\"\" foo \"\"\" test_string_006 = (" " " ") class Foo(object): pass # comment 010 test_string_011 = '' # comment 012 # comment 013 """)) assert len(list(tw.nits())) == 0 assert not tw.has_exception(9, 0, 0) assert not tw.has_exception(3, 0, 1) assert not tw.has_exception(3, 17, 17) assert tw.has_exception(3, 18, 18) assert tw.has_exception(3, 18, 10000) # """ continuated strings have no ends. assert not tw.has_exception(6, 8, 8) assert tw.has_exception(6, 19, 19) assert tw.has_exception(6, 19, 23) assert not tw.has_exception(6, 23, 25) # (" " continuations have string termination
def test_import_wildcard(): io = ImportOrder(PythonFile.from_statement(""" from twitter.common.dirutil import * """)) nits = list(io.nits()) assert len(nits) == 1 assert nits[0].code == 'T400' assert nits[0].severity == Nit.ERROR
def test_import_lexical_order(): io = ImportOrder(PythonFile.from_statement(""" from twitter.common.dirutil import safe_rmtree, safe_mkdtemp """)) nits = list(io.nits()) assert len(nits) == 1 assert nits[0].code == 'T401' assert nits[0].severity == Nit.ERROR
def test_continuation_with_exception(): tw = TrailingWhitespace(PythonFile.from_statement(""" test_string_001 = (" " " ") """)) nits = list(tw.nits()) assert len(nits) == 1 assert nits[0].code == 'T200' assert nits[0].severity == Nit.ERROR
def test_noqa_line_filter(): nits = apply_filter(PythonFile.from_statement(""" print('This is not fine') print('This is fine') # noqa """), Rage, None) nits = list(nits) assert len(nits) == 1, ('Actually got nits: %s' % (' '.join('%s:%s' % (nit._line_number, nit) for nit in nits))) assert nits[0].code == 'T999'
def test_noqa_file_filter(): nits = apply_filter(PythonFile.from_statement(""" # checkstyle: noqa print('This is not fine') print('This is fine') """), Rage, None) nits = list(nits) assert len(nits) == 0
def test_class_names(): p8 = PEP8VariableNames(PythonFile.from_statement(""" class dhis_not_right(object): pass """)) nits = list(p8.nits()) assert len(nits) == 1 assert nits[0].code == 'T000' assert nits[0]._line_number == 1 assert nits[0].severity == Nit.ERROR
def test_classdefs(): newlines = Newlines(PythonFile.from_statement(GOOD_CLASS_DEF_1)) assert len(list(newlines.nits())) == 0 newlines = Newlines(PythonFile.from_statement(GOOD_CLASS_DEF_2)) assert len(list(newlines.nits())) == 0 newlines = Newlines(PythonFile.from_statement(BAD_CLASS_DEF_1)) nits = list(newlines.nits()) assert len(nits) == 1 assert nits[0].code == 'T301' assert nits[0]._line_number == 4 assert nits[0].severity == Nit.ERROR newlines = Newlines(PythonFile.from_statement(BAD_CLASS_DEF_2)) nits = list(newlines.nits()) assert len(nits) == 1 assert nits[0].code == 'T301' assert nits[0]._line_number == 7 assert nits[0].severity == Nit.ERROR
def test_class_globals(): p8 = PEP8VariableNames(PythonFile.from_statement(""" class DhisRight(object): RIGHT = 123 notRight = 321 """)) nits = list(p8.nits()) assert len(nits) == 1 assert nits[0].code == 'T001' assert nits[0]._line_number == 3 assert nits[0].severity == Nit.ERROR
def test_noqa_line_filter(): nits = apply_filter( PythonFile.from_statement(""" print('This is not fine') print('This is fine') # noqa """), Rage, None) nits = list(nits) assert len(nits) == 1, ('Actually got nits: %s' % (' '.join('%s:%s' % (nit._line_number, nit) for nit in nits))) assert nits[0].code == 'T999'
def test_class_globals(): p8 = PEP8VariableNames( PythonFile.from_statement(""" class DhisRight(object): RIGHT = 123 notRight = 321 """)) nits = list(p8.nits()) assert len(nits) == 1 assert nits[0].code == 'T001' assert nits[0]._line_number == 3 assert nits[0].severity == Nit.ERROR
def test_python_file(): pf = PythonFile(PYTHON_STATEMENT, 'keeper.py') assert pf.filename == 'keeper.py' assert pf.logical_lines == { 1: (1, 2, 0), 2: (2, 6, 0), 7: (7, 8, 0), 10: (10, 11, 0), 11: (11, 12, 2), 12: (12, 13, 4), 14: (14, 15, 2), 15: (15, 16, 4) } with pytest.raises(IndexError): pf[0] with pytest.raises(IndexError): pf[len(PYTHON_STATEMENT.splitlines()) + 1] assert pf[1] == ["import ast"] assert pf[2] == ["from os.path import (", " join,", " split,", ")"] assert pf[3] == [" join,"] assert '\n'.join(pf) == PYTHON_STATEMENT assert list(pf.enumerate()) == list( enumerate(PYTHON_STATEMENT.splitlines(), 1))
def test_print_statements(): ps = PrintStatements(PythonFile.from_statement(""" from __future__ import print_function print("I do what I want") class Foo(object): def print(self): "I can do this because it's not a reserved word." """)) assert len(list(ps.nits())) == 0 ps = PrintStatements(PythonFile.from_statement(""" print("I do what I want") """)) assert len(list(ps.nits())) == 0 ps = PrintStatements(PythonFile.from_statement(""" print["I do what I want"] """)) nits = list(ps.nits()) assert len(nits) == 1 assert nits[0].code == 'T607' assert nits[0].severity == Nit.ERROR
def test_builtin_overrides(): p8 = PEP8VariableNames(PythonFile.from_statement(""" def range(): print("Not in a class body") class DhisRight(object): def any(self): print("In a class body") """)) nits = list(p8.nits()) assert len(nits) == 1 assert nits[0].code == 'T801' assert nits[0]._line_number == 1 assert nits[0].severity == Nit.ERROR
def test_builtin_overrides(): p8 = PEP8VariableNames( PythonFile.from_statement(""" def range(): print("Not in a class body") class DhisRight(object): def any(self): print("In a class body") """)) nits = list(p8.nits()) assert len(nits) == 1 assert nits[0].code == 'T801' assert nits[0]._line_number == 1 assert nits[0].severity == Nit.ERROR
def test_trailing_slash(): tw = TrailingWhitespace(PythonFile.from_statement(""" foo = \\ 123 bar = \"\"\" bin/bash foo \\ bar \\ baz \"\"\" """)) nits = list(tw.nits()) assert len(nits) == 1 assert nits[0].code == 'T201' assert nits[0].severity == Nit.ERROR assert nits[0]._line_number == 1
def test_trailing_slash(): tw = TrailingWhitespace( PythonFile.from_statement(""" foo = \\ 123 bar = \"\"\" bin/bash foo \\ bar \\ baz \"\"\" """)) nits = list(tw.nits()) assert len(nits) == 1 assert nits[0].code == 'T201' assert nits[0].severity == Nit.ERROR assert nits[0]._line_number == 1
def test_style_error(): pf = PythonFile(PYTHON_STATEMENT, 'keeper.py') class ActualCheckstylePlugin(CheckstylePlugin): def nits(self): return [] cp = ActualCheckstylePlugin(pf) se = cp.error('A123', 'You have a terrible taste in libraries.') assert se.line_number is None assert se.code == 'A123' str(se) se = cp.error('A123', 'You have a terrible taste in libraries.', 7) assert se.line_number == '007' str(se) se = cp.error('A123', 'You have a terrible taste in libraries.', 2) assert se.line_number == '002-005' assert se.severity == Nit.ERROR str(se) sw = cp.warning('A321', 'You have a terrible taste in libraries.', 2) assert sw.severity == Nit.WARNING assert sw.code == 'A321' str(sw) import_from = None for node in ast.walk(pf.tree): if isinstance(node, ast.ImportFrom): import_from = node assert import_from is not None ase = cp.error('B380', "I don't like your from import!", import_from) assert ase.severity == Nit.ERROR se = cp.error('B380', "I don't like your from import!", 2) assert str(se) == str(ase)
def exemplar_pass(statement): nits = list(FutureCompatibility(PythonFile.from_statement(statement)).nits()) assert len(nits) == 0
from twitter.checkstyle.common import Nit, PythonFile from twitter.checkstyle.plugins.class_factoring import ClassFactoring BAD_CLASS = PythonFile.from_statement(""" class Distiller(object): CONSTANT = "foo" def foo(self, value): return os.path.join(Distiller.CONSTANT, value) """) def test_class_factoring(): plugin = ClassFactoring(BAD_CLASS) nits = list(plugin.nits()) assert len(nits) == 1 assert nits[0].code == 'T800' assert nits[0].severity == Nit.WARNING
def exemplar_pass(statement): nits = list( FutureCompatibility(PythonFile.from_statement(statement)).nits()) assert len(nits) == 0
def nits_from(clause): return list(ExceptStatements(PythonFile.from_statement(EXCEPT_TEMPLATE % clause)).nits())
def exemplar_fail(code, severity, statement): nits = list(FutureCompatibility(PythonFile.from_statement(statement)).nits()) assert len(nits) == 1 assert nits[0].code == code assert nits[0].severity == severity return nits[0]