##// END OF EJS Templates
contrib: add an utility module to parse test scripts...
contrib: add an utility module to parse test scripts This patch centralizes the logic to pick up code fragments embedded in *.t script, in order to: - apply checking with patterns in check-code.py on such embedded code fragments Now, check-code.py completely ignores embedded code fragments. I'll post another patch series to check them. - replace similar code path in contrib/import-checker.py Current import-checker.py has problems below. Fixing each of them is a little difficult, because parsing logic and pattern strings are tightly coupled. - overlook (or mis-detect) the end of inline script in doctest style 8a8dd6e4a97a fixed a part of this issue, but not enough. - it overlooks inline script in doctest style at the end of file (and ignores invalid un-closed heredoc at the end of file, too) - it overlooks code fragment in styles below - "python <<EOF" (heredoc should be "cat > file <<EOF" style) - "cat > foobar.py << ANYLIMIT" (limit mark should be "EOF") - "cat << EOF > foobar.py" (filename should be placed before limit mark) - "cat >> foobar.py << EOF" (appending is ignored) - it is not extensible for other than python code fragments (e.g. shell script, hgrc file, and so on) This new module can detect python code fragments in styles below: - inline script in doctest style (starting by " >>> " line) - python invocation with heredoc script ("python <<EOF") - python script in heredoc style (redirected into ".py" file) As an example of extensibility of new module, this patch also contains implementation to pick up code fragment below. This will be useful to add additional restriction for them, for example. - shell script in heredoc style (redirected into ".sh" file) - hgrc configuration in heredoc style (redirected into hgrc or $HGRCPATH)

File last commit:

r35316:e223c043 default
r40129:726cfc47 default
Show More
test-contrib-check-code.t
375 lines | 8.6 KiB | text/troff | Tads3Lexer
/ tests / test-contrib-check-code.t
Pierre-Yves David
test: rename 'check-code' own test to 'test-contrib-check-code.t'...
r27367 $ cat > correct.py <<EOF
> def toto(arg1, arg2):
> del arg2
> return (5 + 6, 9)
> EOF
$ cat > wrong.py <<EOF
> def toto( arg1, arg2):
> del(arg2)
> return ( 5+6, 9)
> EOF
$ cat > quote.py <<EOF
> # let's use quote in comments
> (''' ( 4x5 )
> but """\\''' and finally''',
> """let's fool checkpatch""", '1+2',
> '"""', 42+1, """and
> ( 4-1 ) """, "( 1+1 )\" and ")
> a, '\\\\\\\\', "\\\\\\" x-2", "c-1"
> EOF
$ cat > classstyle.py <<EOF
> class newstyle_class(object):
> pass
>
> class oldstyle_class:
> pass
>
> class empty():
> pass
>
> no_class = 1:
> pass
> EOF
$ check_code="$TESTDIR"/../contrib/check-code.py
$ "$check_code" ./wrong.py ./correct.py ./quote.py ./classstyle.py
./wrong.py:1:
> def toto( arg1, arg2):
gratuitous whitespace in () or []
./wrong.py:2:
> del(arg2)
Python keyword is not a function
./wrong.py:3:
> return ( 5+6, 9)
gratuitous whitespace in () or []
missing whitespace in expression
./quote.py:5:
> '"""', 42+1, """and
missing whitespace in expression
./classstyle.py:4:
> class oldstyle_class:
old-style class, use class foo(object)
./classstyle.py:7:
> class empty():
class foo() creates old style object, use class foo(object)
[1]
$ cat > python3-compat.py << EOF
> foo <> bar
> reduce(lambda a, b: a + b, [1, 2, 3, 4])
> dict(key=value)
> EOF
$ "$check_code" python3-compat.py
python3-compat.py:1:
> foo <> bar
<> operator is not available in Python 3+, use !=
python3-compat.py:2:
> reduce(lambda a, b: a + b, [1, 2, 3, 4])
reduce is not available in Python 3+
python3-compat.py:3:
> dict(key=value)
dict() is different in Py2 and 3 and is slower than {}
[1]
Augie Fackler
check-code: prevent use of strcpy
r28594 $ cat > foo.c <<EOF
> void narf() {
> strcpy(foo, bar);
> // strcpy_s is okay, but this comment is not
> strcpy_s(foo, bar);
> }
> EOF
$ "$check_code" ./foo.c
./foo.c:2:
> strcpy(foo, bar);
don't use strcpy, use strlcpy or memcpy
./foo.c:3:
> // strcpy_s is okay, but this comment is not
don't use //-style comments
[1]
Pierre-Yves David
test: rename 'check-code' own test to 'test-contrib-check-code.t'...
r27367 $ cat > is-op.py <<EOF
> # is-operator comparing number or string literal
> x = None
> y = x is 'foo'
> y = x is "foo"
> y = x is 5346
> y = x is -6
> y = x is not 'foo'
> y = x is not "foo"
> y = x is not 5346
> y = x is not -6
> EOF
$ "$check_code" ./is-op.py
./is-op.py:3:
> y = x is 'foo'
object comparison with literal
./is-op.py:4:
> y = x is "foo"
object comparison with literal
./is-op.py:5:
> y = x is 5346
object comparison with literal
./is-op.py:6:
> y = x is -6
object comparison with literal
./is-op.py:7:
> y = x is not 'foo'
object comparison with literal
./is-op.py:8:
> y = x is not "foo"
object comparison with literal
./is-op.py:9:
> y = x is not 5346
object comparison with literal
./is-op.py:10:
> y = x is not -6
object comparison with literal
[1]
$ cat > for-nolineno.py <<EOF
> except:
> EOF
$ "$check_code" for-nolineno.py --nolineno
for-nolineno.py:0:
> except:
naked except clause
[1]
$ cat > warning.t <<EOF
> $ function warnonly {
> > }
> $ diff -N aaa
> $ function onwarn {}
> EOF
$ "$check_code" warning.t
$ "$check_code" --warn warning.t
warning.t:1:
> $ function warnonly {
warning: don't use 'function', use old style
warning.t:3:
> $ diff -N aaa
warning: don't use 'diff -N'
warning.t:4:
> $ function onwarn {}
warning: don't use 'function', use old style
[1]
Augie Fackler
style: ban [ foo == bar] bashism in tests
r32293 $ cat > error.t <<EOF
> $ [ foo == bar ]
> EOF
$ "$check_code" error.t
error.t:1:
> $ [ foo == bar ]
[ foo == bar ] is a bashism, use [ foo = bar ] instead
[1]
$ rm error.t
Pierre-Yves David
test: rename 'check-code' own test to 'test-contrib-check-code.t'...
r27367 $ cat > raise-format.py <<EOF
> raise SomeException, message
> # this next line is okay
> raise SomeException(arg1, arg2)
> EOF
$ "$check_code" not-existing.py raise-format.py
Skipping*not-existing.py* (glob)
raise-format.py:1:
> raise SomeException, message
don't use old-style two-argument raise, use Exception(message)
[1]
Yuya Nishihara
check-code: allow tabs in heredoc
r35316 $ cat <<EOF > tab.t
> indent
> > heredoc
> EOF
$ "$check_code" tab.t
tab.t:1:
> indent
don't use tabs to indent
[1]
$ rm tab.t
Pierre-Yves David
test: rename 'check-code' own test to 'test-contrib-check-code.t'...
r27367 $ cat > rst.py <<EOF
> """problematic rst text
>
> .. note::
> wrong
> """
>
> '''
>
> .. note::
>
> valid
>
> new text
>
> .. note::
>
> also valid
> '''
>
> """mixed
>
> .. note::
>
> good
>
> .. note::
> plus bad
> """
> EOF
$ $check_code -w rst.py
rst.py:3:
> .. note::
warning: add two newlines after '.. note::'
rst.py:26:
> .. note::
warning: add two newlines after '.. note::'
[1]
$ cat > ./map-inside-gettext.py <<EOF
Augie Fackler
tests: clean up many print statements to be print functions instead...
r33687 > print(_("map inside gettext %s" % v))
Pierre-Yves David
test: rename 'check-code' own test to 'test-contrib-check-code.t'...
r27367 >
Augie Fackler
tests: clean up many print statements to be print functions instead...
r33687 > print(_("concatenating " " by " " space %s" % v))
> print(_("concatenating " + " by " + " '+' %s" % v))
Pierre-Yves David
test: rename 'check-code' own test to 'test-contrib-check-code.t'...
r27367 >
Augie Fackler
tests: clean up many print statements to be print functions instead...
r33687 > print(_("mapping operation in different line %s"
> % v))
Pierre-Yves David
test: rename 'check-code' own test to 'test-contrib-check-code.t'...
r27367 >
Augie Fackler
tests: clean up many print statements to be print functions instead...
r33687 > print(_(
> "leading spaces inside of '(' %s" % v))
Pierre-Yves David
test: rename 'check-code' own test to 'test-contrib-check-code.t'...
r27367 > EOF
$ "$check_code" ./map-inside-gettext.py
./map-inside-gettext.py:1:
Augie Fackler
tests: clean up many print statements to be print functions instead...
r33687 > print(_("map inside gettext %s" % v))
Pierre-Yves David
test: rename 'check-code' own test to 'test-contrib-check-code.t'...
r27367 don't use % inside _()
./map-inside-gettext.py:3:
Augie Fackler
tests: clean up many print statements to be print functions instead...
r33687 > print(_("concatenating " " by " " space %s" % v))
Pierre-Yves David
test: rename 'check-code' own test to 'test-contrib-check-code.t'...
r27367 don't use % inside _()
./map-inside-gettext.py:4:
Augie Fackler
tests: clean up many print statements to be print functions instead...
r33687 > print(_("concatenating " + " by " + " '+' %s" % v))
Pierre-Yves David
test: rename 'check-code' own test to 'test-contrib-check-code.t'...
r27367 don't use % inside _()
./map-inside-gettext.py:6:
Augie Fackler
tests: clean up many print statements to be print functions instead...
r33687 > print(_("mapping operation in different line %s"
Pierre-Yves David
test: rename 'check-code' own test to 'test-contrib-check-code.t'...
r27367 don't use % inside _()
./map-inside-gettext.py:9:
Augie Fackler
tests: clean up many print statements to be print functions instead...
r33687 > print(_(
Pierre-Yves David
test: rename 'check-code' own test to 'test-contrib-check-code.t'...
r27367 don't use % inside _()
[1]
web templates
$ mkdir -p mercurial/templates
$ cat > mercurial/templates/example.tmpl <<EOF
> {desc}
> {desc|escape}
> {desc|firstline}
> {desc|websub}
> EOF
$ "$check_code" --warnings mercurial/templates/example.tmpl
mercurial/templates/example.tmpl:2:
> {desc|escape}
warning: follow desc keyword with either firstline or websub
[1]
FUJIWARA Katsunori
check-code: replace quoted characters correctly...
r29276
'string join across lines with no space' detection
$ cat > stringjoin.py <<EOF
> foo = (' foo'
> 'bar foo.'
> 'bar foo:'
> 'bar foo@'
FUJIWARA Katsunori
check-code: make repquote distinguish more characters for exact detection...
r29279 > 'bar foo%'
> 'bar foo*'
> 'bar foo+'
> 'bar foo-'
FUJIWARA Katsunori
check-code: replace quoted characters correctly...
r29276 > 'bar')
> EOF
FUJIWARA Katsunori
check-code: detect "missing _() in ui message" more exactly...
r29397
'missing _() in ui message' detection
$ cat > uigettext.py <<EOF
> ui.status("% 10s %05d % -3.2f %*s %%"
> # this use '\\\\' instead of '\\', because the latter in
> # heredoc on shell becomes just '\'
> '\\\\ \n \t \0'
> """12345
> """
> '''.:*+-=
> ''' "%-6d \n 123456 .:*+-= foobar")
> EOF
Augie Fackler
contrib: add a check to check-code to ban superfluous pass statements...
r34383 superfluous pass
$ cat > superfluous_pass.py <<EOF
> # correct examples
> if foo:
> pass
> else:
> # comment-only line means still need pass
> pass
> def nothing():
> pass
> class empty(object):
> pass
> if whatever:
> passvalue(value)
> # bad examples
> if foo:
> "foo"
> pass
> else: # trailing comment doesn't fool checker
> wat()
> pass
> def nothing():
> "docstring means no pass"
> pass
> class empty(object):
> """multiline
> docstring also
> means no pass"""
> pass
> EOF
FUJIWARA Katsunori
check-code: build translation table for repquote in global for efficiency...
r29398 (Checking multiple invalid files at once examines whether caching
translation table for repquote() works as expected or not. All files
should break rules depending on result of repquote(), in this case)
Augie Fackler
contrib: add a check to check-code to ban superfluous pass statements...
r34383 $ "$check_code" stringjoin.py uigettext.py superfluous_pass.py
FUJIWARA Katsunori
check-code: replace quoted characters correctly...
r29276 stringjoin.py:1:
> foo = (' foo'
string join across lines with no space
stringjoin.py:2:
> 'bar foo.'
string join across lines with no space
stringjoin.py:3:
> 'bar foo:'
string join across lines with no space
stringjoin.py:4:
> 'bar foo@'
string join across lines with no space
FUJIWARA Katsunori
check-code: make repquote distinguish more characters for exact detection...
r29279 stringjoin.py:5:
> 'bar foo%'
string join across lines with no space
stringjoin.py:6:
> 'bar foo*'
string join across lines with no space
stringjoin.py:7:
> 'bar foo+'
string join across lines with no space
stringjoin.py:8:
> 'bar foo-'
string join across lines with no space
FUJIWARA Katsunori
check-code: detect "missing _() in ui message" more exactly...
r29397 uigettext.py:1:
> ui.status("% 10s %05d % -3.2f %*s %%"
missing _() in ui message (use () to hide false-positives)
Augie Fackler
contrib: add a check to check-code to ban superfluous pass statements...
r34383 superfluous_pass.py:14:
> if foo:
omit superfluous pass
superfluous_pass.py:17:
> else: # trailing comment doesn't fool checker
omit superfluous pass
superfluous_pass.py:20:
> def nothing():
omit superfluous pass
superfluous_pass.py:23:
> class empty(object):
omit superfluous pass
FUJIWARA Katsunori
check-code: detect "missing _() in ui message" more exactly...
r29397 [1]