Skip to content

Commit

Permalink
Fix --varformat to alloww nay formats
Browse files Browse the repository at this point in the history
This fixes th' --varformat flag fer both lint and translate to alloww fer
nay variable formats by passin' in an empty strin'.

Fixes #83
  • Loading branch information
willkg committed Nov 6, 2016
1 parent 3bb5412 commit 0431887
Show file tree
Hide file tree
Showing 3 changed files with 115 additions and 33 deletions.
21 changes: 12 additions & 9 deletions dennis/linter.py
Expand Up @@ -102,9 +102,7 @@ class MalformedNoTypeLintRule(LintRule):
def lint(self, vartok, linted_entry):
msgs = []

# This only applies if one of the variable tokenizers
# is python-format.
# FIXME: Generalize this.
# This only applies if one of the variable tokenizers is python-format.
if not vartok.contains('python-format'):
return msgs

Expand Down Expand Up @@ -143,9 +141,7 @@ class MalformedMissingRightBraceLintRule(LintRule):
def lint(self, vartok, linted_entry):
msgs = []

# This only applies if one of the variable tokenizers
# is python-brace-format.
# FIXME: Generalize this.
# This only applies if one of the variable tokenizers is python-brace-format.
if not vartok.contains('python-brace-format'):
return []

Expand Down Expand Up @@ -179,9 +175,7 @@ class MalformedMissingLeftBraceLintRule(LintRule):
def lint(self, vartok, linted_entry):
msgs = []

# This only applies if one of the variable tokenizers
# is python-brace-format.
# FIXME: Generalize this.
# This only applies if one of the variable tokenizers is python-brace-format.
if not vartok.contains('python-brace-format'):
return []

Expand Down Expand Up @@ -253,6 +247,11 @@ class MissingVarsLintRule(LintRule):

def lint(self, vartok, linted_entry):
msgs = []

# If there are no variable formats, skip this rule.
if not vartok.formats:
return []

for trstr in linted_entry.strs:
if not trstr.msgstr_string:
continue
Expand Down Expand Up @@ -443,6 +442,10 @@ class InvalidVarsLintRule(LintRule):
desc = 'Checks for variables not in msgid, but in msgstr'

def lint(self, vartok, linted_entry):
# If there are no variable formats, skip this rule.
if not vartok.formats:
return []

msgs = []
for trstr in linted_entry.strs:
if not trstr.msgstr_string:
Expand Down
47 changes: 31 additions & 16 deletions dennis/tools.py
Expand Up @@ -108,22 +108,30 @@ def __init__(self, formats=None):
if formats is None:
formats = all_formats.keys()

# Convert names to classes
self.formats = []

for fmt in formats:
try:
self.formats.append(all_formats[fmt])
except KeyError:
raise UnknownFormat(
'{0} is not a known variable format'.format(fmt))

# Generate variable regexp
self.vars_re = re.compile(
r'(' +
'|'.join([vt.regexp for vt in self.formats]) +
r')'
)
formats = [fmt for fmt in formats if fmt]

# If they don't want variable tokenizing at all
if not formats:
self.formats = []
self.vars_re = None

else:
# Convert names to classes
self.formats = []

for fmt in formats:
try:
self.formats.append(all_formats[fmt])
except KeyError:
raise UnknownFormat(
'{0} is not a known variable format'.format(fmt))

# Generate variable regexp
self.vars_re = re.compile(
r'(' +
'|'.join([vt.regexp for vt in self.formats]) +
r')'
)

def contains(self, fmt):
"""Does this tokenizer contain specified variable format?"""
Expand All @@ -139,10 +147,15 @@ def tokenize(self, text):
:returns: list of tokens---every even one is a Python variable
"""
if not self.vars_re:
return [text]
return [token for token in self.vars_re.split(text) if token]

def extract_tokens(self, text, unique=True):
"""Returns the set of variable in the text"""
if not self.vars_re:
return set()

try:
tokens = self.vars_re.findall(text)
if unique:
Expand All @@ -153,6 +166,8 @@ def extract_tokens(self, text, unique=True):

def is_token(self, text):
"""Is this text a variable?"""
if not self.vars_re:
return False
return self.vars_re.match(text) is not None

def extract_variable_name(self, text):
Expand Down
80 changes: 72 additions & 8 deletions tests/test_linter.py
Expand Up @@ -161,6 +161,16 @@ def test_ignore_non_formatting_tokens(self):
msgs = self.lintrule.lint(self.vartok, linted_entry)
assert msgs == []

def test_varformat_empty(self):
vartok = VariableTokenizer([])
linted_entry = build_linted_entry(
'#: foo/foo.py:5\n'
'msgid "%s foo"\n'
'msgstr "%a FOO"\n'
)
msgs = self.lintrule.lint(vartok, linted_entry)
assert msgs == []


class TestMalformedNoTypeLintRule(LintRuleTestCase):
lintrule = MalformedNoTypeLintRule()
Expand All @@ -180,7 +190,7 @@ def test_fine(self):
'msgstr "Oof: {foo}"\n')

msgs = self.lintrule.lint(self.vartok, linted_entry)
assert len(msgs) == 0
assert msgs == []

def test_python_var_with_space(self):
linted_entry = build_linted_entry(
Expand Down Expand Up @@ -228,7 +238,19 @@ def test_python_var_not_malformed(self):
'msgstr "%(stars)s de %(user)s el %(date)s (%(locale)s)"\n')

msgs = self.lintrule.lint(self.vartok, linted_entry)
assert len(msgs) == 0
assert msgs == []

def test_varformat_empty(self):
vartok = VariableTokenizer([])

linted_entry = build_linted_entry(
'#: kitsune/questions/templates/questions/answers.html:56\n'
'msgid "%(count)s view"\n'
'msgid_plural "%(count)s views"\n'
'msgstr[0] "%(count) zoo"\n')

msgs = self.lintrule.lint(vartok, linted_entry)
assert msgs == []


class TestMalformedMissingRightBraceLintRule(LintRuleTestCase):
Expand Down Expand Up @@ -292,6 +314,16 @@ def test_python_var_missing_right_curly_brace_two_vars(self):
'missing right curly-brace: {0]" excede el tamano de {'
)

def test_varformat_empty(self):
vartok = VariableTokenizer([])

linted_entry = build_linted_entry(
'msgid "Value for key \\"{0}\\" exceeds the length of {1}"\n'
'msgstr "Valor para la clave \\"{0}\\" excede el tamano de {1]"\n')

msgs = self.lintrule.lint(vartok, linted_entry)
assert msgs == []


class TestMalformedMissingLeftBraceLintRuleTest(LintRuleTestCase):
lintrule = MalformedMissingLeftBraceLintRule()
Expand Down Expand Up @@ -339,6 +371,17 @@ def test_python_var_missing_left_curly_brace(self):
'missing left curly-brace: }}'
)

def test_varformat_empty(self):
vartok = VariableTokenizer([])

linted_entry = build_linted_entry(
'#: kitsune/questions/templates/questions/question_details.html:14\n'
'msgid "{q} | {product} Support Forum"\n'
'msgstr "{q} | {product}} foo bar"\n')

msgs = self.lintrule.lint(vartok, linted_entry)
assert msgs == []


class TestMissingVarsLintRule(LintRuleTestCase):
lintrule = MissingVarsLintRule()
Expand Down Expand Up @@ -471,6 +514,17 @@ def test_python_format_are_errors_unnamed(self):
'missing variables: %s'
)

def test_varformat_empty(self):
vartok = VariableTokenizer([])

linted_entry = build_linted_entry(
'#: kitsune/kbforums/feeds.py:23\n'
'msgid "Recently updated threads about %s"\n'
'msgstr "RECENTLY UPDATED THREADS"\n'
)
msgs = self.lintrule.lint(vartok, linted_entry)
assert msgs == []


class TestInvalidVarsLintRule(LintRuleTestCase):
lintrule = InvalidVarsLintRule()
Expand All @@ -482,15 +536,15 @@ def test_fine(self):
'msgstr "Oof"\n')

msgs = self.lintrule.lint(self.vartok, linted_entry)
assert len(msgs) == 0
assert msgs == []

linted_entry = build_linted_entry(
'#: foo/foo.py:5\n'
'msgid "Foo: {foo}"\n'
'msgstr "Oof: {foo}"\n')

msgs = self.lintrule.lint(self.vartok, linted_entry)
assert len(msgs) == 0
assert msgs == []

def test_invalid(self):
linted_entry = build_linted_entry(
Expand Down Expand Up @@ -539,7 +593,7 @@ def test_plurals(self):
'msgstr[0] "{n} mooo"\n')

msgs = self.lintrule.lint(self.vartok, linted_entry)
assert len(msgs) == 0
assert msgs == []

def test_double_percent(self):
# Double-percent shouldn't be picked up as a variable.
Expand All @@ -550,7 +604,7 @@ def test_double_percent(self):
'msgstr "more than 50%% of the traffic"\n')

msgs = self.lintrule.lint(self.vartok, linted_entry)
assert len(msgs) == 0
assert msgs == []

def test_urlencoded_urls(self):
# urlencoding uses % and that shouldn't get picked up
Expand All @@ -562,7 +616,7 @@ def test_urlencoded_urls(self):
'msgstr "http://example.com/foo%20%E5%B4%A9%E6%BA%83 is best"\n')

msgs = self.lintrule.lint(self.vartok, linted_entry)
assert len(msgs) == 0
assert msgs == []

def test_msgid_no_vars(self):
linted_entry = build_linted_entry(
Expand All @@ -571,7 +625,17 @@ def test_msgid_no_vars(self):
'msgstr "http://it.wikipedia.org/wiki/Canvas_%28elemento_HTML%29"\n')

msgs = self.lintrule.lint(self.vartok, linted_entry)
assert len(msgs) == 0
assert msgs == []

def test_varformat_empty(self):
vartok = VariableTokenizer([])
linted_entry = build_linted_entry(
'#: foo/foo.py:5\n'
'msgid "Foo {bar}"\n'
'msgstr "Oof: {foo}"\n')

msgs = self.lintrule.lint(vartok, linted_entry)
assert msgs == []


class TestBlankLintRule(LintRuleTestCase):
Expand Down

0 comments on commit 0431887

Please sign in to comment.