3
Tests for L{pyflakes.scripts.pyflakes}.
7
from StringIO import StringIO
9
from twisted.python.filepath import FilePath
10
from twisted.trial.unittest import TestCase
12
from pyflakes.scripts.pyflakes import checkPath
14
def withStderrTo(stderr, f):
16
Call C{f} with C{sys.stderr} redirected to C{stderr}.
18
(outer, sys.stderr) = (sys.stderr, stderr)
26
class CheckTests(TestCase):
28
Tests for L{check} and L{checkPath} which check a file for flakes.
30
def test_missingTrailingNewline(self):
32
Source which doesn't end with a newline shouldn't cause any
33
exception to be raised nor an error indicator to be returned by
37
FilePath(fName).setContent("def foo():\n\tpass\n\t")
38
self.assertFalse(checkPath(fName))
41
def test_checkPathNonExisting(self):
43
L{checkPath} handles non-existing files.
46
count = withStderrTo(err, lambda: checkPath('extremo'))
47
self.assertEquals(err.getvalue(), 'extremo: No such file or directory\n')
48
self.assertEquals(count, 1)
51
def test_multilineSyntaxError(self):
53
Source which includes a syntax error which results in the raised
54
L{SyntaxError.text} containing multiple lines of source are reported
55
with only the last line of that source.
68
# Sanity check - SyntaxError.text should be multiple lines, if it
69
# isn't, something this test was unprepared for has happened.
72
exc = self.assertRaises(SyntaxError, evaluate, source)
73
self.assertTrue(exc.text.count('\n') > 1)
75
sourcePath = FilePath(self.mktemp())
76
sourcePath.setContent(source)
78
count = withStderrTo(err, lambda: checkPath(sourcePath.path))
79
self.assertEqual(count, 1)
87
""" % (sourcePath.path,))
90
def test_eofSyntaxError(self):
92
The error reported for source files which end prematurely causing a
93
syntax error reflects the cause for the syntax error.
96
sourcePath = FilePath(self.mktemp())
97
sourcePath.setContent(source)
99
count = withStderrTo(err, lambda: checkPath(sourcePath.path))
100
self.assertEqual(count, 1)
104
%s:1: unexpected EOF while parsing
107
""" % (sourcePath.path,))
110
def test_nonDefaultFollowsDefaultSyntaxError(self):
112
Source which has a non-default argument following a default argument
113
should include the line number of the syntax error. However these
114
exceptions do not include an offset.
117
def foo(bar=baz, bax):
120
sourcePath = FilePath(self.mktemp())
121
sourcePath.setContent(source)
123
count = withStderrTo(err, lambda: checkPath(sourcePath.path))
124
self.assertEqual(count, 1)
128
%s:1: non-default argument follows default argument
129
def foo(bar=baz, bax):
130
""" % (sourcePath.path,))
133
def test_nonKeywordAfterKeywordSyntaxError(self):
135
Source which has a non-keyword argument after a keyword argument should
136
include the line number of the syntax error. However these exceptions
137
do not include an offset.
142
sourcePath = FilePath(self.mktemp())
143
sourcePath.setContent(source)
145
count = withStderrTo(err, lambda: checkPath(sourcePath.path))
146
self.assertEqual(count, 1)
150
%s:1: non-keyword arg after keyword arg
152
""" % (sourcePath.path,))
155
def test_permissionDenied(self):
157
If the a source file is not readable, this is reported on standard
160
sourcePath = FilePath(self.mktemp())
161
sourcePath.setContent('')
164
count = withStderrTo(err, lambda: checkPath(sourcePath.path))
165
self.assertEquals(count, 1)
167
err.getvalue(), "%s: Permission denied\n" % (sourcePath.path,))
170
def test_misencodedFile(self):
172
If a source file contains bytes which cannot be decoded, this is
179
sourcePath = FilePath(self.mktemp())
180
sourcePath.setContent(source)
182
count = withStderrTo(err, lambda: checkPath(sourcePath.path))
183
self.assertEquals(count, 1)
185
err.getvalue(), "%s: problem decoding source\n" % (sourcePath.path,))