From 22503c96a19fcf7fe9ad1ea98e9ebaa175e47382 Mon Sep 17 00:00:00 2001 From: Hannes Kaeufler Date: Mon, 9 Dec 2019 16:03:53 +0100 Subject: [PATCH 1/8] Improve error message When forgetting to install the protobuf compiler, an error message is shown which had a missing space between two words. --- setup.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/setup.py b/setup.py index 03057e679..cced30ab7 100644 --- a/setup.py +++ b/setup.py @@ -39,8 +39,8 @@ def find_protoc(): if protoc is None: sys.stderr.write( 'protoc not found. Is protobuf-compiler installed? \n' - 'Alternatively, you can point the PROTOC environment variable' - 'at a local version.') + 'Alternatively, you can point the PROTOC environment variable ' + 'to a local version.') sys.exit(1) return protoc From e9c1e12142cd3da4fcd03bdd28bc41c94d1e4216 Mon Sep 17 00:00:00 2001 From: Hannes Kaeufler Date: Mon, 9 Dec 2019 16:05:16 +0100 Subject: [PATCH 2/8] Remove trailing whitespace --- tests/test_comment_type.py | 6 +++--- tests/test_doxygen_output.py | 2 +- tests/test_invalid_enum.py | 4 ++-- tests/test_invalid_html.py | 29 +++++++++++++---------------- tests/test_invalid_message.py | 6 +++--- tests/test_newline.py | 2 +- 6 files changed, 23 insertions(+), 26 deletions(-) diff --git a/tests/test_comment_type.py b/tests/test_comment_type.py index 96ad618c6..e1104acdd 100644 --- a/tests/test_comment_type.py +++ b/tests/test_comment_type.py @@ -6,7 +6,7 @@ class TestCommentType(unittest.TestCase): - ''' Test class for mandatory new line. ''' + ''' Test class for mandatory new line. ''' def test_brief_necessity(self): ''' Test the necessity of "brief" comment. ''' @@ -57,7 +57,7 @@ def test_brief_necessity(self): noComment += 1; if comment.find("\\brief") != -1: hasBrief = True - + elif len(saveStatement) == 0: if re.search(r"\bmessage\b", statement) is not None or re.search(r"\bextend\b",statement) is not None: self.assertTrue(hasBrief, file + " in line " + str(i - 1) + ": \\brief section in comment is missing for: '" + statement + "'") @@ -140,7 +140,7 @@ def test_comment_existence(self): saveStatement = "" for line in fin: - i += 1 + i += 1 # Divide statement and comment. Concatenate multi line statements. diff --git a/tests/test_doxygen_output.py b/tests/test_doxygen_output.py index b6a1a9cba..4a2e8ef5e 100644 --- a/tests/test_doxygen_output.py +++ b/tests/test_doxygen_output.py @@ -15,7 +15,7 @@ def test_hash(self): i = 0 for line in fin: - i += 1 + i += 1 matchHash = re.search(r"([\s>]|^)#\w(\S)*", line) if matchHash is not None: diff --git a/tests/test_invalid_enum.py b/tests/test_invalid_enum.py index 3bab9b6e4..1ff63cae2 100644 --- a/tests/test_invalid_enum.py +++ b/tests/test_invalid_enum.py @@ -56,13 +56,13 @@ def test_correct_enum_name(self): if matchName is not None: checkName = statement[matchName.start():matchName.end()] - # Test to check correct ENUM name. + # Test to check correct ENUM name. self.assertEqual(checkName.find(enumName), 0, file + " in line " + str(i) + ": enum type wrong. '" + checkName + "' should start with '" + enumName + "'") # Test to check ENUM type is in captial letters/upper case. self.assertEqual(checkName, checkName.upper(), file + " in line " + str(i) + ": enum type wrong. '" + checkName + "' should use upper case") - + # Search for "enum". matchEnum = re.search(r"\benum\b", statement) diff --git a/tests/test_invalid_html.py b/tests/test_invalid_html.py index 3037db788..c94c40daa 100644 --- a/tests/test_invalid_html.py +++ b/tests/test_invalid_html.py @@ -27,16 +27,16 @@ def test_invalid_slash(self): else: statement = line comment = "" - + # Add part of the statement from last line. statement = saveStatement + " " + statement saveStatement = "" - + # New line is not necessary. Remove for a better output. statement = statement.replace("\n", "") comment = comment.replace("\n", "") - # Is statement complete + # Is statement complete matchSep = re.search(r"[{};]", statement) if matchSep is None: saveStatement = statement @@ -90,16 +90,16 @@ def test_invalid_hash(self): else: statement = line comment = "" - + # Add part of the statement from last line. statement = saveStatement + " " + statement saveStatement = "" - + # New line is not necessary. Remove for a better output. statement = statement.replace("\n", "") comment = comment.replace("\n", "") - # Is statement complete + # Is statement complete matchSep = re.search(r"[{};]", statement) if matchSep is None: saveStatement = statement @@ -131,7 +131,7 @@ def test_invalid_hash(self): htmlblock = False self.assertEqual(htmlComment.find("#"), -1, file + " in line " + str(i) + ": doxygen comment #.. reference found: '" + htmlComment + "'") - + def test_invalid_at(self): ''' Test case to check invalid @ in comments ''' @@ -152,16 +152,16 @@ def test_invalid_at(self): else: statement = line comment = "" - + # Add part of the statement from last line. statement = saveStatement + " " + statement saveStatement = "" - + # New line is not necessary. Remove for a better output. statement = statement.replace("\n", "") comment = comment.replace("\n", "") - # Is statement complete + # Is statement complete matchSep = re.search(r"[{};]", statement) if matchSep is None: saveStatement = statement @@ -193,7 +193,6 @@ def test_invalid_at(self): htmlblock = False self.assertEqual(comment.find("@"), -1, file + " in line " + str(i) + ": @ tag found (please replace with \\): '" + htmlFreeComment + "'") - def test_no_endhtmlonly(self): ''' Test case to check no \endhtmlonly in comments ''' @@ -214,16 +213,16 @@ def test_no_endhtmlonly(self): else: statement = line comment = "" - + # Add part of the statement from last line. statement = saveStatement + " " + statement saveStatement = "" - + # New line is not necessary. Remove for a better output. statement = statement.replace("\n", "") comment = comment.replace("\n", "") - # Is statement complete + # Is statement complete matchSep = re.search(r"[{};]", statement) if matchSep is None: saveStatement = statement @@ -258,5 +257,3 @@ def test_no_endhtmlonly(self): elif htmlblock: self.assertFalse(htmlblock, file + " in line " + str(i - 1) + ": doxygen comment html section without endhtmlonly") htmlblock = False - - \ No newline at end of file diff --git a/tests/test_invalid_message.py b/tests/test_invalid_message.py index 51d796830..ce3340bc3 100644 --- a/tests/test_invalid_message.py +++ b/tests/test_invalid_message.py @@ -10,7 +10,7 @@ class TestInvalidMessage(unittest.TestCase): def test_message_name(self): ''' Test to check if message name have any special character. It should not have any special character. ''' - + for file in glob("*.proto"): with open(file, "rt") as fin: i = 0 @@ -255,7 +255,7 @@ def test_field_type(self): if matchName is not None: checkType = " " + type[matchName.start():matchName.end() - 1] + " " # Test to check nested message type - matchNameConv = re.search(r"[ ][a-zA-Z][a-zA-Z0-9]*([\.][A-Z][a-zA-Z0-9]*)*[ ]", checkType) + matchNameConv = re.search(r"[ ][a-zA-Z][a-zA-Z0-9]*([\.][A-Z][a-zA-Z0-9]*)*[ ]", checkType) checkType = checkType.strip() self.assertIsNotNone(matchNameConv, file + " in line " + str(i) + ": field message type wrong. Check: '" + checkType + "'") @@ -355,7 +355,7 @@ def test_field_multiplicity(self): matchName = re.search(r"\b\w[\S]*\b\s*=", statement) if matchName is not None: checkName = statement[matchName.start():matchName.end() - 1] - + # Check field message type (remove field name) type = statement.replace(checkName, "") matchName = re.search(r"\b\w[\S\.]*\s*=", type) diff --git a/tests/test_newline.py b/tests/test_newline.py index 04d348db0..7bf464295 100644 --- a/tests/test_newline.py +++ b/tests/test_newline.py @@ -6,7 +6,7 @@ class TestNewLine(unittest.TestCase): - ''' Test class for mandatory new line. ''' + ''' Test class for mandatory new line. ''' def test_newline(self): ''' Test to check last line of file must end with a new line. ''' From 60b9a7216760e6f9fd4879b683cf72d0e7e58203 Mon Sep 17 00:00:00 2001 From: Hannes Kaeufler Date: Mon, 9 Dec 2019 16:18:39 +0100 Subject: [PATCH 3/8] Read file in one go There is no reason to traverse the file line by line if all we care about is the last character. This also uses unittests subTest to show the file which fails the test. --- tests/test_newline.py | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/tests/test_newline.py b/tests/test_newline.py index 7bf464295..55826e9e8 100644 --- a/tests/test_newline.py +++ b/tests/test_newline.py @@ -11,11 +11,6 @@ class TestNewLine(unittest.TestCase): def test_newline(self): ''' Test to check last line of file must end with a new line. ''' for file in glob("*.proto"): - with open(file, "rt") as fin: - hasNewLine = True - - for line in fin: - hasNewLine = line.endswith("\n") - - self.assertTrue(hasNewLine, file + " has no new line at the end of the file.") - \ No newline at end of file + with open(file, "rt") as fin, self.subTest(file=file): + lastCharacter = fin.read()[-1] + self.assertEqual(lastCharacter, "\n", file + " has no new line at the end of the file.") From 6950230abda174911a98c16544f25612e3f91ccf Mon Sep 17 00:00:00 2001 From: Hannes Kaeufler Date: Mon, 9 Dec 2019 16:39:45 +0100 Subject: [PATCH 4/8] Fix header comment --- tests/test_comment_type.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_comment_type.py b/tests/test_comment_type.py index e1104acdd..0128d5093 100644 --- a/tests/test_comment_type.py +++ b/tests/test_comment_type.py @@ -6,7 +6,7 @@ class TestCommentType(unittest.TestCase): - ''' Test class for mandatory new line. ''' + ''' Test class for mandatory comments. ''' def test_brief_necessity(self): ''' Test the necessity of "brief" comment. ''' From 8a51a49de317c906b428568aded47b23de7dbe1c Mon Sep 17 00:00:00 2001 From: Hannes Kaeufler Date: Mon, 9 Dec 2019 16:45:11 +0100 Subject: [PATCH 5/8] Use subTest to show all failing files When one file is failing, due to the fact that all tests contain for loops, the other failures are swallowed because python stops running the test on the first assertion. With subTest one can introduce a subcontext which allows showing all of the failed files as well a diagnostic as to which file failed. --- tests/test_comment_type.py | 16 ++++++++-------- tests/test_doxygen_output.py | 15 ++++++++------- tests/test_invalid_comment.py | 12 +++++++----- tests/test_invalid_enum.py | 4 ++-- tests/test_invalid_html.py | 8 ++++---- tests/test_invalid_message.py | 8 ++++---- tests/test_invalid_punctuation.py | 2 +- tests/test_invalid_tabs.py | 6 +++--- tests/test_non_ascii.py | 2 +- 9 files changed, 38 insertions(+), 35 deletions(-) diff --git a/tests/test_comment_type.py b/tests/test_comment_type.py index 0128d5093..4b3b7c58e 100644 --- a/tests/test_comment_type.py +++ b/tests/test_comment_type.py @@ -1,9 +1,10 @@ import sys import unicodedata import re -from glob import * +import glob import unittest +PROTO_FILES = glob.glob("*.proto") class TestCommentType(unittest.TestCase): ''' Test class for mandatory comments. ''' @@ -11,8 +12,8 @@ class TestCommentType(unittest.TestCase): def test_brief_necessity(self): ''' Test the necessity of "brief" comment. ''' - for file in glob("*.proto"): - with open(file, "rt") as fin: + for file in PROTO_FILES: + with open(file, "rt") as fin, self.subTest(file=file): i = 0 noMessage = 0 noComment = 0 @@ -73,8 +74,8 @@ def test_brief_necessity(self): def test_min_two_lines(self): ''' Test to check if short comment is of minimum two lines. ''' - for file in glob("*.proto"): - with open(file, "rt") as fin: + for file in PROTO_FILES: + with open(file, "rt") as fin, self.subTest(file=file): i = 0 isEnum = False noMessage = 0 @@ -129,9 +130,8 @@ def test_min_two_lines(self): def test_comment_existence(self): ''' Test to check if every message, extend , statement or enum has a comment. ''' - for file in glob("*.proto"): - - with open(file, "rt") as fin: + for file in PROTO_FILES: + with open(file, "rt") as fin, self.subTest(file=file): i = 0 isEnum = False noMessage = 0 diff --git a/tests/test_doxygen_output.py b/tests/test_doxygen_output.py index 4a2e8ef5e..fbe616262 100644 --- a/tests/test_doxygen_output.py +++ b/tests/test_doxygen_output.py @@ -1,17 +1,18 @@ import sys import unicodedata import re -from glob import * +import glob import unittest +DOC_FILES = glob.glob("doc/html/*.htm*") class TestDoxygenOutput(unittest.TestCase): """ Test class for the doxygen output. """ def test_hash(self): ''' Test case is checking if there are illegal hash chars in the documentation. -> doxygen link not found. ''' - for file in glob("doc/html/*.htm*"): - with open(file, "rt") as fin: + for file in DOC_FILES: + with open(file, "rt") as fin, self.subTest(file=file): i = 0 for line in fin: @@ -25,8 +26,8 @@ def test_hash(self): def test_slash_triplet(self): ''' Test case is checking if there are slash triplets in the documentation. -> doxygen didn't interpret something properly. ''' - for file in glob("doc/html/*.htm*"): - with open(file, "rt") as fin: + for file in DOC_FILES: + with open(file, "rt") as fin, self.subTest(file=file): i = 0 for line in fin: @@ -39,8 +40,8 @@ def test_slash_triplet(self): def test_backslash_triplet(self): ''' Test case is checking if there are backslash triplets in the documentation. -> doxygen didn't interpret something properly. ''' - for file in glob("doc/html/*.htm*"): - with open(file, "rt") as fin: + for file in DOC_FILES: + with open(file, "rt") as fin, self.subTest(file=file): i = 0 for line in fin: diff --git a/tests/test_invalid_comment.py b/tests/test_invalid_comment.py index 32eda856c..2c509e178 100644 --- a/tests/test_invalid_comment.py +++ b/tests/test_invalid_comment.py @@ -1,16 +1,18 @@ import sys import unicodedata import re -from glob import * +import glob import unittest +PROTO_FILES = glob.glob("*.proto") + class TestInvalidCommentType(unittest.TestCase): """Test class for invalid comment types""" def test_triple_slash(self): ''' Test to check if more than two forward slash('/') are present in comment section of proto file. ''' - for file in glob("*.proto"): - with open(file, "rt") as fin: + for file in PROTO_FILES: + with open(file, "rt") as fin, self.subTest(file=file): i = 0 for line in fin: @@ -19,8 +21,8 @@ def test_triple_slash(self): def test_comments_invalid_syntax(self): ''' Test to check if comments are given using invalid syntax '/*' or '*/' ''' - for file in glob("*.proto"): - with open(file, "rt") as fin: + for file in PROTO_FILES: + with open(file, "rt") as fin, self.subTest(file=file): i = 0 for line in fin: diff --git a/tests/test_invalid_enum.py b/tests/test_invalid_enum.py index 1ff63cae2..ce7a553d7 100644 --- a/tests/test_invalid_enum.py +++ b/tests/test_invalid_enum.py @@ -10,7 +10,7 @@ class TestInvalidEnum(unittest.TestCase): def test_correct_enum_name(self): ''' Test if enum name is correct. ''' for file in glob("*.proto"): - with open(file, "rt") as fin: + with open(file, "rt") as fin, self.subTest(file=file): i = 0 isEnum = False enumName = "" @@ -85,7 +85,7 @@ def test_correct_enum_name(self): def test_invalid_enum(self): ''' Test invalid enum definition. ''' for file in glob("*.proto"): - with open(file, "rt") as fin: + with open(file, "rt") as fin, self.subTest(file=file): i = 0 isEnum = False enumName = "" diff --git a/tests/test_invalid_html.py b/tests/test_invalid_html.py index c94c40daa..c00db148c 100644 --- a/tests/test_invalid_html.py +++ b/tests/test_invalid_html.py @@ -11,7 +11,7 @@ class TestInvalidHtml(unittest.TestCase): def test_invalid_slash(self): ''' Test case to check invalid slash in htmlonly sections ''' for file in glob("*.proto"): - with open(file, "rt") as fin: + with open(file, "rt") as fin, self.subTest(file=file): i = 0 htmlblock = False saveStatement = "" @@ -74,7 +74,7 @@ def test_invalid_slash(self): def test_invalid_hash(self): ''' Test case to check invalid # in htmlonly sections ''' for file in glob("*.proto"): - with open(file, "rt") as fin: + with open(file, "rt") as fin, self.subTest(file=file): i = 0 htmlblock = False saveStatement = "" @@ -136,7 +136,7 @@ def test_invalid_hash(self): def test_invalid_at(self): ''' Test case to check invalid @ in comments ''' for file in glob("*.proto"): - with open(file, "rt") as fin: + with open(file, "rt") as fin, self.subTest(file=file): i = 0 htmlblock = False saveStatement = "" @@ -197,7 +197,7 @@ def test_invalid_at(self): def test_no_endhtmlonly(self): ''' Test case to check no \endhtmlonly in comments ''' for file in glob("*.proto"): - with open(file, "rt") as fin: + with open(file, "rt") as fin, self.subTest(file=file): i = 0 htmlblock = False saveStatement = "" diff --git a/tests/test_invalid_message.py b/tests/test_invalid_message.py index ce3340bc3..e70d57d1f 100644 --- a/tests/test_invalid_message.py +++ b/tests/test_invalid_message.py @@ -12,7 +12,7 @@ def test_message_name(self): ''' Test to check if message name have any special character. It should not have any special character. ''' for file in glob("*.proto"): - with open(file, "rt") as fin: + with open(file, "rt") as fin, self.subTest(file=file): i = 0 isEnum = False enumName = "" @@ -89,7 +89,7 @@ def test_field_name(self): ''' Test to check if field names are in lower case. ''' for file in glob("*.proto"): - with open(file, "rt") as fin: + with open(file, "rt") as fin, self.subTest(file=file): i = 0 isEnum = False enumName = "" @@ -187,7 +187,7 @@ def test_field_type(self): ''' Test to check nested message type. ''' for file in glob("*.proto"): - with open(file, "rt") as fin: + with open(file, "rt") as fin, self.subTest(file=file): i = 0 isEnum = False enumName = "" @@ -288,7 +288,7 @@ def test_field_multiplicity(self): for file in glob("*.proto"): - with open(file, "rt") as fin: + with open(file, "rt") as fin, self.subTest(file=file): i = 0 isEnum = False enumName = "" diff --git a/tests/test_invalid_punctuation.py b/tests/test_invalid_punctuation.py index f7637f478..d96449166 100644 --- a/tests/test_invalid_punctuation.py +++ b/tests/test_invalid_punctuation.py @@ -10,7 +10,7 @@ class TestInvalidPunctuation(unittest.TestCase): def test_invalid_punctuation(self): ''' Test to check invalid punctuation character '__' ''' for file in glob("*.proto"): - with open(file, "rt") as fin: + with open(file, "rt") as fin, self.subTest(file=file): i = 0 for line in fin: diff --git a/tests/test_invalid_tabs.py b/tests/test_invalid_tabs.py index 207acc0c1..54d302217 100644 --- a/tests/test_invalid_tabs.py +++ b/tests/test_invalid_tabs.py @@ -11,9 +11,9 @@ class TestInvalidTabs(unittest.TestCase): def test_invalid_tabs(self): ''' Test to check if invalid tabs exist. ''' for file in glob("*.proto"): - i = 0 - - with open(file, "rt") as fin: + i = 0 + + with open(file, "rt") as fin, self.subTest(file=file): for line in fin: i += 1 self.assertEqual(line.find("\t"), -1, file + " in line " + str(i) + ": not permitted tab found") diff --git a/tests/test_non_ascii.py b/tests/test_non_ascii.py index b6612dd27..02bc41b8c 100644 --- a/tests/test_non_ascii.py +++ b/tests/test_non_ascii.py @@ -11,7 +11,7 @@ class TestNonAscii(unittest.TestCase): def test_non_ascii(self): ''' Test if there are any non ASCII characters present like an "Umlaut". ''' for file in glob("*.proto"): - with open(file, "rt") as fin: + with open(file, "rt") as fin, self.subTest(file=file): i = 0 for line in fin: From 0a6c162721b5226aa03998412e7e55ad907d3d76 Mon Sep 17 00:00:00 2001 From: Hannes Kaeufler Date: Mon, 9 Dec 2019 17:04:07 +0100 Subject: [PATCH 6/8] Use enumeration index for line count Python provides mechanisms for that, no reason to manually track a count. --- tests/test_comment_type.py | 14 +++----------- tests/test_doxygen_output.py | 15 +++------------ tests/test_invalid_comment.py | 10 ++-------- tests/test_invalid_enum.py | 10 ++-------- tests/test_invalid_html.py | 20 ++++---------------- tests/test_invalid_punctuation.py | 5 +---- tests/test_invalid_tabs.py | 3 +-- tests/test_non_ascii.py | 6 +----- 8 files changed, 17 insertions(+), 66 deletions(-) diff --git a/tests/test_comment_type.py b/tests/test_comment_type.py index 4b3b7c58e..734d49d2b 100644 --- a/tests/test_comment_type.py +++ b/tests/test_comment_type.py @@ -14,14 +14,12 @@ def test_brief_necessity(self): for file in PROTO_FILES: with open(file, "rt") as fin, self.subTest(file=file): - i = 0 noMessage = 0 noComment = 0 hasBrief = False saveStatement = "" - for line in fin: - i += 1 + for i, line in enumerate(fin, start=1): # Divide statement and comment. Concatenate multi line statements. @@ -76,16 +74,13 @@ def test_min_two_lines(self): for file in PROTO_FILES: with open(file, "rt") as fin, self.subTest(file=file): - i = 0 isEnum = False noMessage = 0 noComment = 0 hasBrief = False saveStatement = "" - for line in fin: - i += 1 - + for i, line in enumerate(fin, start=1): # Divide statement and comment. Concatenate multi line statements. # Search for comment ("//"). @@ -132,16 +127,13 @@ def test_comment_existence(self): for file in PROTO_FILES: with open(file, "rt") as fin, self.subTest(file=file): - i = 0 isEnum = False noMessage = 0 noComment = 0 hasBrief = False saveStatement = "" - for line in fin: - i += 1 - + for i, line in enumerate(fin, start=1): # Divide statement and comment. Concatenate multi line statements. # Search for comment ("//"). diff --git a/tests/test_doxygen_output.py b/tests/test_doxygen_output.py index fbe616262..456ba50a1 100644 --- a/tests/test_doxygen_output.py +++ b/tests/test_doxygen_output.py @@ -13,10 +13,7 @@ def test_hash(self): ''' Test case is checking if there are illegal hash chars in the documentation. -> doxygen link not found. ''' for file in DOC_FILES: with open(file, "rt") as fin, self.subTest(file=file): - i = 0 - - for line in fin: - i += 1 + for i, line in enumerate(fin, start=1): matchHash = re.search(r"([\s>]|^)#\w(\S)*", line) if matchHash is not None: @@ -28,10 +25,7 @@ def test_slash_triplet(self): for file in DOC_FILES: with open(file, "rt") as fin, self.subTest(file=file): - i = 0 - - for line in fin: - i += 1 + for i, line in enumerate(fin, start=1): matchHash = re.search(r"([\s>]|^)///\s*",line) if matchHash is not None: @@ -42,10 +36,7 @@ def test_backslash_triplet(self): ''' Test case is checking if there are backslash triplets in the documentation. -> doxygen didn't interpret something properly. ''' for file in DOC_FILES: with open(file, "rt") as fin, self.subTest(file=file): - i = 0 - - for line in fin: - i += 1 + for i, line in enumerate(fin, start=1): matchHash = re.search(r"([\s>]|^)\\\\\\\s*",line) if matchHash is not None: diff --git a/tests/test_invalid_comment.py b/tests/test_invalid_comment.py index 2c509e178..4995c8700 100644 --- a/tests/test_invalid_comment.py +++ b/tests/test_invalid_comment.py @@ -13,19 +13,13 @@ def test_triple_slash(self): ''' Test to check if more than two forward slash('/') are present in comment section of proto file. ''' for file in PROTO_FILES: with open(file, "rt") as fin, self.subTest(file=file): - i = 0 - - for line in fin: - i += 1 + for i, line in enumerate(fin, start=1): self.assertEqual(line.find("///"), -1, file + " in line " + str(i) + ": not permitted use of '///' ") def test_comments_invalid_syntax(self): ''' Test to check if comments are given using invalid syntax '/*' or '*/' ''' for file in PROTO_FILES: with open(file, "rt") as fin, self.subTest(file=file): - i = 0 - - for line in fin: - i += 1 + for i, line in enumerate(fin, start=1): self.assertEqual(line.find("/*"), -1, file + " in line " + str(i) + ": not permitted use of '/*' ") self.assertEqual(line.find("*/"), -1, file + " in line " + str(i) + ": not permitted use of '*/' ") \ No newline at end of file diff --git a/tests/test_invalid_enum.py b/tests/test_invalid_enum.py index ce7a553d7..5314ecb44 100644 --- a/tests/test_invalid_enum.py +++ b/tests/test_invalid_enum.py @@ -11,14 +11,11 @@ def test_correct_enum_name(self): ''' Test if enum name is correct. ''' for file in glob("*.proto"): with open(file, "rt") as fin, self.subTest(file=file): - i = 0 isEnum = False enumName = "" saveStatement = "" - for line in fin: - i += 1 - + for i, line in enumerate(fin, start=1): # Divide statement and comment. Concatenate multi line statements. # Search for comment ("//"). @@ -86,14 +83,11 @@ def test_invalid_enum(self): ''' Test invalid enum definition. ''' for file in glob("*.proto"): with open(file, "rt") as fin, self.subTest(file=file): - i = 0 isEnum = False enumName = "" saveStatement = "" - for line in fin: - i += 1 - + for i, line in enumerate(fin, start=1): # Divide statement and comment. Concatenate multi line statements. # Search for comment ("//"). diff --git a/tests/test_invalid_html.py b/tests/test_invalid_html.py index c00db148c..fdd45c88b 100644 --- a/tests/test_invalid_html.py +++ b/tests/test_invalid_html.py @@ -12,13 +12,10 @@ def test_invalid_slash(self): ''' Test case to check invalid slash in htmlonly sections ''' for file in glob("*.proto"): with open(file, "rt") as fin, self.subTest(file=file): - i = 0 htmlblock = False saveStatement = "" - for line in fin: - i += 1 - + for i, line in enumerate(fin, start=1): # Search for comment ("//"). matchComment = re.search("//", line) if matchComment is not None: @@ -75,13 +72,10 @@ def test_invalid_hash(self): ''' Test case to check invalid # in htmlonly sections ''' for file in glob("*.proto"): with open(file, "rt") as fin, self.subTest(file=file): - i = 0 htmlblock = False saveStatement = "" - for line in fin: - i += 1 - + for i, line in enumerate(fin, start=1): # Search for comment ("//"). matchComment = re.search("//", line) if matchComment is not None: @@ -137,13 +131,10 @@ def test_invalid_at(self): ''' Test case to check invalid @ in comments ''' for file in glob("*.proto"): with open(file, "rt") as fin, self.subTest(file=file): - i = 0 htmlblock = False saveStatement = "" - for line in fin: - i += 1 - + for i, line in enumerate(fin, start=1): # Search for comment ("//"). matchComment = re.search("//", line) if matchComment is not None: @@ -198,13 +189,10 @@ def test_no_endhtmlonly(self): ''' Test case to check no \endhtmlonly in comments ''' for file in glob("*.proto"): with open(file, "rt") as fin, self.subTest(file=file): - i = 0 htmlblock = False saveStatement = "" - for line in fin: - i += 1 - + for i, line in enumerate(fin, start=1): # Search for comment ("//"). matchComment = re.search("//", line) if matchComment is not None: diff --git a/tests/test_invalid_punctuation.py b/tests/test_invalid_punctuation.py index d96449166..0b5c785fa 100644 --- a/tests/test_invalid_punctuation.py +++ b/tests/test_invalid_punctuation.py @@ -11,8 +11,5 @@ def test_invalid_punctuation(self): ''' Test to check invalid punctuation character '__' ''' for file in glob("*.proto"): with open(file, "rt") as fin, self.subTest(file=file): - i = 0 - - for line in fin: - i += 1 + for i, line in enumerate(fin, start=1): self.assertEqual(line.find("__"), -1, file + " in line " + str(i) + ": not permitted use of '__' ") diff --git a/tests/test_invalid_tabs.py b/tests/test_invalid_tabs.py index 54d302217..f9213da11 100644 --- a/tests/test_invalid_tabs.py +++ b/tests/test_invalid_tabs.py @@ -14,6 +14,5 @@ def test_invalid_tabs(self): i = 0 with open(file, "rt") as fin, self.subTest(file=file): - for line in fin: - i += 1 + for i, line in enumerate(fin, start=1): self.assertEqual(line.find("\t"), -1, file + " in line " + str(i) + ": not permitted tab found") diff --git a/tests/test_non_ascii.py b/tests/test_non_ascii.py index 02bc41b8c..b51e1d7c7 100644 --- a/tests/test_non_ascii.py +++ b/tests/test_non_ascii.py @@ -12,11 +12,7 @@ def test_non_ascii(self): ''' Test if there are any non ASCII characters present like an "Umlaut". ''' for file in glob("*.proto"): with open(file, "rt") as fin, self.subTest(file=file): - i = 0 - - for line in fin: - i += 1 - + for i, line in enumerate(fin, start=1): if (sys.version_info >= (3, 0)): self.assertEqual(line, unicodedata.normalize('NFKD', line).encode('ASCII', 'ignore').decode(), file + " in line " + str(i) + ": a none ASCII char is present") else: From 96698ca19805e8de986633c44fe04d091a5c4838 Mon Sep 17 00:00:00 2001 From: Hannes Kaeufler Date: Mon, 9 Dec 2019 17:05:22 +0100 Subject: [PATCH 7/8] Remove unused imports, only glob once The globs where repeated a whole bunch of times which is both information duplication as well as unneccessary work. --- tests/test_doxygen_output.py | 2 -- tests/test_invalid_comment.py | 3 --- tests/test_invalid_enum.py | 10 +++++----- tests/test_invalid_html.py | 13 ++++++------- tests/test_invalid_message.py | 14 ++++++-------- tests/test_invalid_punctuation.py | 9 ++++----- tests/test_invalid_tabs.py | 10 +++------- tests/test_newline.py | 8 +++----- tests/test_non_ascii.py | 6 +++--- 9 files changed, 30 insertions(+), 45 deletions(-) diff --git a/tests/test_doxygen_output.py b/tests/test_doxygen_output.py index 456ba50a1..e4cdc5ff2 100644 --- a/tests/test_doxygen_output.py +++ b/tests/test_doxygen_output.py @@ -1,5 +1,3 @@ -import sys -import unicodedata import re import glob import unittest diff --git a/tests/test_invalid_comment.py b/tests/test_invalid_comment.py index 4995c8700..59c0f7163 100644 --- a/tests/test_invalid_comment.py +++ b/tests/test_invalid_comment.py @@ -1,6 +1,3 @@ -import sys -import unicodedata -import re import glob import unittest diff --git a/tests/test_invalid_enum.py b/tests/test_invalid_enum.py index 5314ecb44..b1b1853c4 100644 --- a/tests/test_invalid_enum.py +++ b/tests/test_invalid_enum.py @@ -1,15 +1,15 @@ -import sys -import unicodedata import re -from glob import * +import glob import unittest +PROTO_FILES = glob.glob("*.proto") + class TestInvalidEnum(unittest.TestCase): ''' Test class to check invalid enum ''' def test_correct_enum_name(self): ''' Test if enum name is correct. ''' - for file in glob("*.proto"): + for file in PROTO_FILES: with open(file, "rt") as fin, self.subTest(file=file): isEnum = False enumName = "" @@ -81,7 +81,7 @@ def test_correct_enum_name(self): def test_invalid_enum(self): ''' Test invalid enum definition. ''' - for file in glob("*.proto"): + for file in PROTO_FILES: with open(file, "rt") as fin, self.subTest(file=file): isEnum = False enumName = "" diff --git a/tests/test_invalid_html.py b/tests/test_invalid_html.py index fdd45c88b..776b0b5a3 100644 --- a/tests/test_invalid_html.py +++ b/tests/test_invalid_html.py @@ -1,16 +1,15 @@ -import sys -import unicodedata import re -from glob import * +import glob import unittest +PROTO_FILES = glob.glob("*.proto") class TestInvalidHtml(unittest.TestCase): """ Test class for invalid html comment. """ def test_invalid_slash(self): ''' Test case to check invalid slash in htmlonly sections ''' - for file in glob("*.proto"): + for file in PROTO_FILES: with open(file, "rt") as fin, self.subTest(file=file): htmlblock = False saveStatement = "" @@ -70,7 +69,7 @@ def test_invalid_slash(self): def test_invalid_hash(self): ''' Test case to check invalid # in htmlonly sections ''' - for file in glob("*.proto"): + for file in PROTO_FILES: with open(file, "rt") as fin, self.subTest(file=file): htmlblock = False saveStatement = "" @@ -129,7 +128,7 @@ def test_invalid_hash(self): def test_invalid_at(self): ''' Test case to check invalid @ in comments ''' - for file in glob("*.proto"): + for file in PROTO_FILES: with open(file, "rt") as fin, self.subTest(file=file): htmlblock = False saveStatement = "" @@ -187,7 +186,7 @@ def test_invalid_at(self): def test_no_endhtmlonly(self): ''' Test case to check no \endhtmlonly in comments ''' - for file in glob("*.proto"): + for file in PROTO_FILES: with open(file, "rt") as fin, self.subTest(file=file): htmlblock = False saveStatement = "" diff --git a/tests/test_invalid_message.py b/tests/test_invalid_message.py index e70d57d1f..8d2f8eaf5 100644 --- a/tests/test_invalid_message.py +++ b/tests/test_invalid_message.py @@ -1,9 +1,8 @@ -import sys -import unicodedata import re -from glob import * +import glob import unittest +PROTO_FILES = glob.glob("*.proto") class TestInvalidMessage(unittest.TestCase): """ Test class for invalid html comment. """ @@ -11,7 +10,7 @@ class TestInvalidMessage(unittest.TestCase): def test_message_name(self): ''' Test to check if message name have any special character. It should not have any special character. ''' - for file in glob("*.proto"): + for file in PROTO_FILES: with open(file, "rt") as fin, self.subTest(file=file): i = 0 isEnum = False @@ -88,7 +87,7 @@ def test_message_name(self): def test_field_name(self): ''' Test to check if field names are in lower case. ''' - for file in glob("*.proto"): + for file in PROTO_FILES: with open(file, "rt") as fin, self.subTest(file=file): i = 0 isEnum = False @@ -186,7 +185,7 @@ def test_field_name(self): def test_field_type(self): ''' Test to check nested message type. ''' - for file in glob("*.proto"): + for file in PROTO_FILES: with open(file, "rt") as fin, self.subTest(file=file): i = 0 isEnum = False @@ -286,8 +285,7 @@ def test_field_type(self): def test_field_multiplicity(self): ''' Test to check if every field has the multiplicity "repeated" or "optional". ''' - for file in glob("*.proto"): - + for file in PROTO_FILES: with open(file, "rt") as fin, self.subTest(file=file): i = 0 isEnum = False diff --git a/tests/test_invalid_punctuation.py b/tests/test_invalid_punctuation.py index 0b5c785fa..224411322 100644 --- a/tests/test_invalid_punctuation.py +++ b/tests/test_invalid_punctuation.py @@ -1,15 +1,14 @@ -import sys -import unicodedata -import re -from glob import * +import glob import unittest +PROTO_FILES = glob.glob("*.proto") + class TestInvalidPunctuation(unittest.TestCase): ''' Test class to check invalid punctuation character '__' ''' def test_invalid_punctuation(self): ''' Test to check invalid punctuation character '__' ''' - for file in glob("*.proto"): + for file in PROTO_FILES: with open(file, "rt") as fin, self.subTest(file=file): for i, line in enumerate(fin, start=1): self.assertEqual(line.find("__"), -1, file + " in line " + str(i) + ": not permitted use of '__' ") diff --git a/tests/test_invalid_tabs.py b/tests/test_invalid_tabs.py index f9213da11..4b55f58f8 100644 --- a/tests/test_invalid_tabs.py +++ b/tests/test_invalid_tabs.py @@ -1,18 +1,14 @@ -from glob import * -import sys -import unicodedata -import re +import glob import unittest +PROTO_FILES = glob.glob("*.proto") class TestInvalidTabs(unittest.TestCase): """Test class for invalid tabulators""" def test_invalid_tabs(self): ''' Test to check if invalid tabs exist. ''' - for file in glob("*.proto"): - i = 0 - + for file in PROTO_FILES: with open(file, "rt") as fin, self.subTest(file=file): for i, line in enumerate(fin, start=1): self.assertEqual(line.find("\t"), -1, file + " in line " + str(i) + ": not permitted tab found") diff --git a/tests/test_newline.py b/tests/test_newline.py index 55826e9e8..1260659f7 100644 --- a/tests/test_newline.py +++ b/tests/test_newline.py @@ -1,16 +1,14 @@ -import sys -import unicodedata -import re -from glob import * +import glob import unittest +PROTO_FILES = glob.glob("*.proto") class TestNewLine(unittest.TestCase): ''' Test class for mandatory new line. ''' def test_newline(self): ''' Test to check last line of file must end with a new line. ''' - for file in glob("*.proto"): + for file in PROTO_FILES: with open(file, "rt") as fin, self.subTest(file=file): lastCharacter = fin.read()[-1] self.assertEqual(lastCharacter, "\n", file + " has no new line at the end of the file.") diff --git a/tests/test_non_ascii.py b/tests/test_non_ascii.py index b51e1d7c7..ccfc76acb 100644 --- a/tests/test_non_ascii.py +++ b/tests/test_non_ascii.py @@ -1,16 +1,16 @@ import sys import unicodedata -import re -from glob import * +import glob import unittest +PROTO_FILES = glob.glob("*.proto") class TestNonAscii(unittest.TestCase): """Class is checking if there is an "Umlaut" or any non ASCII characters are present.""" def test_non_ascii(self): ''' Test if there are any non ASCII characters present like an "Umlaut". ''' - for file in glob("*.proto"): + for file in PROTO_FILES: with open(file, "rt") as fin, self.subTest(file=file): for i, line in enumerate(fin, start=1): if (sys.version_info >= (3, 0)): From 5c1a1bf4b0f450c066bec5bf17bae2584827c4b7 Mon Sep 17 00:00:00 2001 From: Hannes Kaeufler Date: Mon, 9 Dec 2019 17:09:51 +0100 Subject: [PATCH 8/8] Remove needless conditionals in front of assert There is no reason to guard the assertions in the conditional. --- tests/test_doxygen_output.py | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/tests/test_doxygen_output.py b/tests/test_doxygen_output.py index e4cdc5ff2..317086bb3 100644 --- a/tests/test_doxygen_output.py +++ b/tests/test_doxygen_output.py @@ -14,8 +14,7 @@ def test_hash(self): for i, line in enumerate(fin, start=1): matchHash = re.search(r"([\s>]|^)#\w(\S)*", line) - if matchHash is not None: - self.assertIsNone(matchHash, file + " in line " + str(i) + ": not permitted hash found. Search for: '"+ line[matchHash.start():matchHash.end()]) + self.assertIsNone(matchHash, file + " in line " + str(i) + ": not permitted hash found. Search for: '"+ line[matchHash.start():matchHash.end()]) def test_slash_triplet(self): @@ -26,8 +25,7 @@ def test_slash_triplet(self): for i, line in enumerate(fin, start=1): matchHash = re.search(r"([\s>]|^)///\s*",line) - if matchHash is not None: - self.assertIsNone(matchHash, file + " in line " + str(i) + ": not permitted slash triplet found. Search for: '"+line[matchHash.start():matchHash.end()]) + self.assertIsNone(matchHash, file + " in line " + str(i) + ": not permitted slash triplet found. Search for: '"+line[matchHash.start():matchHash.end()]) def test_backslash_triplet(self): @@ -37,5 +35,4 @@ def test_backslash_triplet(self): for i, line in enumerate(fin, start=1): matchHash = re.search(r"([\s>]|^)\\\\\\\s*",line) - if matchHash is not None: - self.assertIsNone(matchHash, file + " in line " + str(i) + ": not permitted backslash triplet found. Search for: '"+line[matchHash.start():matchHash.end()]) + self.assertIsNone(matchHash, file + " in line " + str(i) + ": not permitted backslash triplet found. Search for: '"+line[matchHash.start():matchHash.end()])