From 72b8c35be4293bd21de123854491c658c53af100 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sat, 4 Dec 2021 04:31:41 +0100 Subject: Adding upstream version 0.17.0. Signed-off-by: Daniel Baumann --- gitlint/tests/rules/__init__.py | 0 gitlint/tests/rules/test_body_rules.py | 236 ---------------------- gitlint/tests/rules/test_configuration_rules.py | 140 ------------- gitlint/tests/rules/test_meta_rules.py | 59 ------ gitlint/tests/rules/test_rules.py | 23 --- gitlint/tests/rules/test_title_rules.py | 186 ----------------- gitlint/tests/rules/test_user_rules.py | 256 ------------------------ 7 files changed, 900 deletions(-) delete mode 100644 gitlint/tests/rules/__init__.py delete mode 100644 gitlint/tests/rules/test_body_rules.py delete mode 100644 gitlint/tests/rules/test_configuration_rules.py delete mode 100644 gitlint/tests/rules/test_meta_rules.py delete mode 100644 gitlint/tests/rules/test_rules.py delete mode 100644 gitlint/tests/rules/test_title_rules.py delete mode 100644 gitlint/tests/rules/test_user_rules.py (limited to 'gitlint/tests/rules') diff --git a/gitlint/tests/rules/__init__.py b/gitlint/tests/rules/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/gitlint/tests/rules/test_body_rules.py b/gitlint/tests/rules/test_body_rules.py deleted file mode 100644 index 812c74a..0000000 --- a/gitlint/tests/rules/test_body_rules.py +++ /dev/null @@ -1,236 +0,0 @@ -# -*- coding: utf-8 -*- -from gitlint.tests.base import BaseTestCase -from gitlint import rules - - -class BodyRuleTests(BaseTestCase): - def test_max_line_length(self): - rule = rules.BodyMaxLineLength() - - # assert no error - violation = rule.validate("å" * 80, None) - self.assertIsNone(violation) - - # assert error on line length > 80 - expected_violation = rules.RuleViolation("B1", "Line exceeds max length (81>80)", "å" * 81) - violations = rule.validate("å" * 81, None) - self.assertListEqual(violations, [expected_violation]) - - # set line length to 120, and check no violation on length 73 - rule = rules.BodyMaxLineLength({'line-length': 120}) - violations = rule.validate("å" * 73, None) - self.assertIsNone(violations) - - # assert raise on 121 - expected_violation = rules.RuleViolation("B1", "Line exceeds max length (121>120)", "å" * 121) - violations = rule.validate("å" * 121, None) - self.assertListEqual(violations, [expected_violation]) - - def test_trailing_whitespace(self): - rule = rules.BodyTrailingWhitespace() - - # assert no error - violations = rule.validate("å", None) - self.assertIsNone(violations) - - # trailing space - expected_violation = rules.RuleViolation("B2", "Line has trailing whitespace", "å ") - violations = rule.validate("å ", None) - self.assertListEqual(violations, [expected_violation]) - - # trailing tab - expected_violation = rules.RuleViolation("B2", "Line has trailing whitespace", "å\t") - violations = rule.validate("å\t", None) - self.assertListEqual(violations, [expected_violation]) - - def test_hard_tabs(self): - rule = rules.BodyHardTab() - - # assert no error - violations = rule.validate("This is ã test", None) - self.assertIsNone(violations) - - # contains hard tab - expected_violation = rules.RuleViolation("B3", "Line contains hard tab characters (\\t)", "This is å\ttest") - violations = rule.validate("This is å\ttest", None) - self.assertListEqual(violations, [expected_violation]) - - def test_body_first_line_empty(self): - rule = rules.BodyFirstLineEmpty() - - # assert no error - commit = self.gitcommit("Tïtle\n\nThis is the secōnd body line") - violations = rule.validate(commit) - self.assertIsNone(violations) - - # second line not empty - expected_violation = rules.RuleViolation("B4", "Second line is not empty", "nöt empty", 2) - - commit = self.gitcommit("Tïtle\nnöt empty\nThis is the secönd body line") - violations = rule.validate(commit) - self.assertListEqual(violations, [expected_violation]) - - def test_body_min_length(self): - rule = rules.BodyMinLength() - - # assert no error - body is long enough - commit = self.gitcommit("Title\n\nThis is the second body line\n") - - violations = rule.validate(commit) - self.assertIsNone(violations) - - # assert no error - no body - commit = self.gitcommit("Tïtle\n") - violations = rule.validate(commit) - self.assertIsNone(violations) - - # body is too short - expected_violation = rules.RuleViolation("B5", "Body message is too short (8<20)", "töoshort", 3) - - commit = self.gitcommit("Tïtle\n\ntöoshort\n") - violations = rule.validate(commit) - self.assertListEqual(violations, [expected_violation]) - - # assert error - short across multiple lines - expected_violation = rules.RuleViolation("B5", "Body message is too short (11<20)", "secöndthïrd", 3) - commit = self.gitcommit("Tïtle\n\nsecönd\nthïrd\n") - violations = rule.validate(commit) - self.assertListEqual(violations, [expected_violation]) - - # set line length to 120, and check violation on length 21 - expected_violation = rules.RuleViolation("B5", "Body message is too short (21<120)", "å" * 21, 3) - - rule = rules.BodyMinLength({'min-length': 120}) - commit = self.gitcommit("Title\n\n{0}\n".format("å" * 21)) # pylint: disable=consider-using-f-string - violations = rule.validate(commit) - self.assertListEqual(violations, [expected_violation]) - - # Make sure we don't get the error if the body-length is exactly the min-length - rule = rules.BodyMinLength({'min-length': 8}) - commit = self.gitcommit("Tïtle\n\n{0}\n".format("å" * 8)) # pylint: disable=consider-using-f-string - violations = rule.validate(commit) - self.assertIsNone(violations) - - def test_body_missing(self): - rule = rules.BodyMissing() - - # assert no error - body is present - commit = self.gitcommit("Tïtle\n\nThis ïs the first body line\n") - violations = rule.validate(commit) - self.assertIsNone(violations) - - # body is too short - expected_violation = rules.RuleViolation("B6", "Body message is missing", None, 3) - - commit = self.gitcommit("Tïtle\n") - violations = rule.validate(commit) - self.assertListEqual(violations, [expected_violation]) - - def test_body_missing_multiple_empty_new_lines(self): - rule = rules.BodyMissing() - - # body is too short - expected_violation = rules.RuleViolation("B6", "Body message is missing", None, 3) - - commit = self.gitcommit("Tïtle\n\n\n\n") - violations = rule.validate(commit) - self.assertListEqual(violations, [expected_violation]) - - def test_body_missing_merge_commit(self): - rule = rules.BodyMissing() - - # assert no error - merge commit - commit = self.gitcommit("Merge: Tïtle\n") - violations = rule.validate(commit) - self.assertIsNone(violations) - - # assert error for merge commits if ignore-merge-commits is disabled - rule = rules.BodyMissing({'ignore-merge-commits': False}) - violations = rule.validate(commit) - expected_violation = rules.RuleViolation("B6", "Body message is missing", None, 3) - self.assertListEqual(violations, [expected_violation]) - - def test_body_changed_file_mention(self): - rule = rules.BodyChangedFileMention() - - # assert no error when no files have changed and no files need to be mentioned - commit = self.gitcommit("This is a test\n\nHere is a mention of föo/test.py") - violations = rule.validate(commit) - self.assertIsNone(violations) - - # assert no error when no files have changed but certain files need to be mentioned on change - rule = rules.BodyChangedFileMention({'files': "bar.txt,föo/test.py"}) - commit = self.gitcommit("This is a test\n\nHere is a mention of föo/test.py") - violations = rule.validate(commit) - self.assertIsNone(violations) - - # assert no error if a file has changed and is mentioned - commit = self.gitcommit("This is a test\n\nHere is a mention of föo/test.py", ["föo/test.py"]) - violations = rule.validate(commit) - self.assertIsNone(violations) - - # assert no error if multiple files have changed and are mentioned - commit_msg = "This is a test\n\nHere is a mention of föo/test.py\nAnd here is a mention of bar.txt" - commit = self.gitcommit(commit_msg, ["föo/test.py", "bar.txt"]) - violations = rule.validate(commit) - self.assertIsNone(violations) - - # assert error if file has changed and is not mentioned - commit_msg = "This is a test\n\nHere is å mention of\nAnd here is a mention of bar.txt" - commit = self.gitcommit(commit_msg, ["föo/test.py", "bar.txt"]) - violations = rule.validate(commit) - expected_violation = rules.RuleViolation("B7", "Body does not mention changed file 'föo/test.py'", None, 4) - self.assertEqual([expected_violation], violations) - - # assert multiple errors if multiple files have changed and are not mentioned - commit_msg = "This is å test\n\nHere is a mention of\nAnd here is a mention of" - commit = self.gitcommit(commit_msg, ["föo/test.py", "bar.txt"]) - violations = rule.validate(commit) - expected_violation_2 = rules.RuleViolation("B7", "Body does not mention changed file 'bar.txt'", None, 4) - self.assertEqual([expected_violation_2, expected_violation], violations) - - def test_body_match_regex(self): - # We intentionally add 2 newlines at the end of our commit message as that's how git will pass the - # message. This way we also test that the rule strips off the last line. - commit = self.gitcommit("US1234: åbc\nIgnored\nBödy\nFöo\nMy-Commit-Tag: föo\n\n") - - # assert no violation on default regex (=everything allowed) - rule = rules.BodyRegexMatches() - violations = rule.validate(commit) - self.assertIsNone(violations) - - # assert no violation on matching regex - # (also note that first body line - in between title and rest of body - is ignored) - rule = rules.BodyRegexMatches({'regex': "^Bödy(.*)"}) - violations = rule.validate(commit) - self.assertIsNone(violations) - - # assert we can do end matching (and last empty line is ignored) - # (also note that first body line - in between title and rest of body - is ignored) - rule = rules.BodyRegexMatches({'regex': "My-Commit-Tag: föo$"}) - violations = rule.validate(commit) - self.assertIsNone(violations) - - # common use-case: matching that a given line is present - rule = rules.BodyRegexMatches({'regex': "(.*)Föo(.*)"}) - violations = rule.validate(commit) - self.assertIsNone(violations) - - # assert violation on non-matching body - rule = rules.BodyRegexMatches({'regex': "^Tëst(.*)Foo"}) - violations = rule.validate(commit) - expected_violation = rules.RuleViolation("B8", "Body does not match regex (^Tëst(.*)Foo)", None, 6) - self.assertListEqual(violations, [expected_violation]) - - # assert no violation on None regex - rule = rules.BodyRegexMatches({'regex': None}) - violations = rule.validate(commit) - self.assertIsNone(violations) - - # Assert no issues when there's no body or a weird body variation - bodies = ["åbc", "åbc\n", "åbc\nföo\n", "åbc\n\n", "åbc\nföo\nblå", "åbc\nföo\nblå\n"] - for body in bodies: - commit = self.gitcommit(body) - rule = rules.BodyRegexMatches({'regex': ".*"}) - violations = rule.validate(commit) - self.assertIsNone(violations) diff --git a/gitlint/tests/rules/test_configuration_rules.py b/gitlint/tests/rules/test_configuration_rules.py deleted file mode 100644 index 9302da5..0000000 --- a/gitlint/tests/rules/test_configuration_rules.py +++ /dev/null @@ -1,140 +0,0 @@ -# -*- coding: utf-8 -*- -from gitlint.tests.base import BaseTestCase -from gitlint import rules -from gitlint.config import LintConfig - - -class ConfigurationRuleTests(BaseTestCase): - def test_ignore_by_title(self): - commit = self.gitcommit("Releäse\n\nThis is the secōnd body line") - - # No regex specified -> Config shouldn't be changed - rule = rules.IgnoreByTitle() - config = LintConfig() - rule.apply(config, commit) - self.assertEqual(config, LintConfig()) - self.assert_logged([]) # nothing logged -> nothing ignored - - # Matching regex -> expect config to ignore all rules - rule = rules.IgnoreByTitle({"regex": "^Releäse(.*)"}) - expected_config = LintConfig() - expected_config.ignore = "all" - rule.apply(config, commit) - self.assertEqual(config, expected_config) - - expected_log_message = "DEBUG: gitlint.rules Ignoring commit because of rule 'I1': " + \ - "Commit title 'Releäse' matches the regex '^Releäse(.*)', ignoring rules: all" - self.assert_log_contains(expected_log_message) - - # Matching regex with specific ignore - rule = rules.IgnoreByTitle({"regex": "^Releäse(.*)", - "ignore": "T1,B2"}) - expected_config = LintConfig() - expected_config.ignore = "T1,B2" - rule.apply(config, commit) - self.assertEqual(config, expected_config) - - expected_log_message = "DEBUG: gitlint.rules Ignoring commit because of rule 'I1': " + \ - "Commit title 'Releäse' matches the regex '^Releäse(.*)', ignoring rules: T1,B2" - - def test_ignore_by_body(self): - commit = self.gitcommit("Tïtle\n\nThis is\n a relëase body\n line") - - # No regex specified -> Config shouldn't be changed - rule = rules.IgnoreByBody() - config = LintConfig() - rule.apply(config, commit) - self.assertEqual(config, LintConfig()) - self.assert_logged([]) # nothing logged -> nothing ignored - - # Matching regex -> expect config to ignore all rules - rule = rules.IgnoreByBody({"regex": "(.*)relëase(.*)"}) - expected_config = LintConfig() - expected_config.ignore = "all" - rule.apply(config, commit) - self.assertEqual(config, expected_config) - - expected_log_message = "DEBUG: gitlint.rules Ignoring commit because of rule 'I2': " + \ - "Commit message line ' a relëase body' matches the regex '(.*)relëase(.*)'," + \ - " ignoring rules: all" - self.assert_log_contains(expected_log_message) - - # Matching regex with specific ignore - rule = rules.IgnoreByBody({"regex": "(.*)relëase(.*)", - "ignore": "T1,B2"}) - expected_config = LintConfig() - expected_config.ignore = "T1,B2" - rule.apply(config, commit) - self.assertEqual(config, expected_config) - - expected_log_message = "DEBUG: gitlint.rules Ignoring commit because of rule 'I2': " + \ - "Commit message line ' a relëase body' matches the regex '(.*)relëase(.*)', ignoring rules: T1,B2" - self.assert_log_contains(expected_log_message) - - def test_ignore_by_author_name(self): - commit = self.gitcommit("Tïtle\n\nThis is\n a relëase body\n line", author_name="Tëst nåme") - - # No regex specified -> Config shouldn't be changed - rule = rules.IgnoreByAuthorName() - config = LintConfig() - rule.apply(config, commit) - self.assertEqual(config, LintConfig()) - self.assert_logged([]) # nothing logged -> nothing ignored - - # Matching regex -> expect config to ignore all rules - rule = rules.IgnoreByAuthorName({"regex": "(.*)ëst(.*)"}) - expected_config = LintConfig() - expected_config.ignore = "all" - rule.apply(config, commit) - self.assertEqual(config, expected_config) - - expected_log_message = ("DEBUG: gitlint.rules Ignoring commit because of rule 'I4': " - "Commit Author Name 'Tëst nåme' matches the regex '(.*)ëst(.*)'," - " ignoring rules: all") - self.assert_log_contains(expected_log_message) - - # Matching regex with specific ignore - rule = rules.IgnoreByAuthorName({"regex": "(.*)nåme", "ignore": "T1,B2"}) - expected_config = LintConfig() - expected_config.ignore = "T1,B2" - rule.apply(config, commit) - self.assertEqual(config, expected_config) - - expected_log_message = ("DEBUG: gitlint.rules Ignoring commit because of rule 'I4': " - "Commit Author Name 'Tëst nåme' matches the regex '(.*)nåme', ignoring rules: T1,B2") - self.assert_log_contains(expected_log_message) - - def test_ignore_body_lines(self): - commit1 = self.gitcommit("Tïtle\n\nThis is\n a relëase body\n line") - commit2 = self.gitcommit("Tïtle\n\nThis is\n a relëase body\n line") - - # no regex specified, nothing should have happened: - # commit and config should remain identical, log should be empty - rule = rules.IgnoreBodyLines() - config = LintConfig() - rule.apply(config, commit1) - self.assertEqual(commit1, commit2) - self.assertEqual(config, LintConfig()) - self.assert_logged([]) - - # Matching regex - rule = rules.IgnoreBodyLines({"regex": "(.*)relëase(.*)"}) - config = LintConfig() - rule.apply(config, commit1) - # Our modified commit should be identical to a commit that doesn't contain the specific line - expected_commit = self.gitcommit("Tïtle\n\nThis is\n line") - # The original message isn't touched by this rule, this way we always have a way to reference back to it, - # so assert it's not modified by setting it to the same as commit1 - expected_commit.message.original = commit1.message.original - self.assertEqual(commit1, expected_commit) - self.assertEqual(config, LintConfig()) # config shouldn't have been modified - self.assert_log_contains("DEBUG: gitlint.rules Ignoring line ' a relëase body' because it " + - "matches '(.*)relëase(.*)'") - - # Non-Matching regex: no changes expected - commit1 = self.gitcommit("Tïtle\n\nThis is\n a relëase body\n line") - rule = rules.IgnoreBodyLines({"regex": "(.*)föobar(.*)"}) - config = LintConfig() - rule.apply(config, commit1) - self.assertEqual(commit1, commit2) - self.assertEqual(config, LintConfig()) # config shouldn't have been modified diff --git a/gitlint/tests/rules/test_meta_rules.py b/gitlint/tests/rules/test_meta_rules.py deleted file mode 100644 index 568ca3f..0000000 --- a/gitlint/tests/rules/test_meta_rules.py +++ /dev/null @@ -1,59 +0,0 @@ -# -*- coding: utf-8 -*- -from gitlint.tests.base import BaseTestCase -from gitlint.rules import AuthorValidEmail, RuleViolation - - -class MetaRuleTests(BaseTestCase): - def test_author_valid_email_rule(self): - rule = AuthorValidEmail() - - # valid email addresses - valid_email_addresses = ["föo@bar.com", "Jöhn.Doe@bar.com", "jöhn+doe@bar.com", "jöhn/doe@bar.com", - "jöhn.doe@subdomain.bar.com"] - for email in valid_email_addresses: - commit = self.gitcommit("", author_email=email) - violations = rule.validate(commit) - self.assertIsNone(violations) - - # No email address (=allowed for now, as gitlint also lints messages passed via stdin that don't have an - # email address) - commit = self.gitcommit("") - violations = rule.validate(commit) - self.assertIsNone(violations) - - # Invalid email addresses: no TLD, no domain, no @, space anywhere (=valid but not allowed by gitlint) - invalid_email_addresses = ["föo@bar", "JöhnDoe", "Jöhn Doe", "Jöhn Doe@foo.com", " JöhnDoe@foo.com", - "JöhnDoe@ foo.com", "JöhnDoe@foo. com", "JöhnDoe@foo. com", "@bår.com", - "föo@.com"] - for email in invalid_email_addresses: - commit = self.gitcommit("", author_email=email) - violations = rule.validate(commit) - self.assertListEqual(violations, - [RuleViolation("M1", "Author email for commit is invalid", email)]) - - def test_author_valid_email_rule_custom_regex(self): - # regex=None -> the rule isn't applied - rule = AuthorValidEmail() - rule.options['regex'].set(None) - emailadresses = ["föo", None, "hür dür"] - for email in emailadresses: - commit = self.gitcommit("", author_email=email) - violations = rule.validate(commit) - self.assertIsNone(violations) - - # Custom domain - rule = AuthorValidEmail({'regex': "[^@]+@bår.com"}) - valid_email_addresses = [ - "föo@bår.com", "Jöhn.Doe@bår.com", "jöhn+doe@bår.com", "jöhn/doe@bår.com"] - for email in valid_email_addresses: - commit = self.gitcommit("", author_email=email) - violations = rule.validate(commit) - self.assertIsNone(violations) - - # Invalid email addresses - invalid_email_addresses = ["föo@hur.com"] - for email in invalid_email_addresses: - commit = self.gitcommit("", author_email=email) - violations = rule.validate(commit) - self.assertListEqual(violations, - [RuleViolation("M1", "Author email for commit is invalid", email)]) diff --git a/gitlint/tests/rules/test_rules.py b/gitlint/tests/rules/test_rules.py deleted file mode 100644 index 6fcf9bc..0000000 --- a/gitlint/tests/rules/test_rules.py +++ /dev/null @@ -1,23 +0,0 @@ -# -*- coding: utf-8 -*- -from gitlint.tests.base import BaseTestCase -from gitlint.rules import Rule, RuleViolation - - -class RuleTests(BaseTestCase): - - def test_rule_equality(self): - self.assertEqual(Rule(), Rule()) - # Ensure rules are not equal if they differ on their attributes - for attr in ["id", "name", "target", "options"]: - rule = Rule() - setattr(rule, attr, "åbc") - self.assertNotEqual(Rule(), rule) - - def test_rule_log(self): - rule = Rule() - rule.log.debug("Tēst message") - self.assert_log_contains("DEBUG: gitlint.rules Tēst message") - - def test_rule_violation_equality(self): - violation1 = RuleViolation("ïd1", "My messåge", "My cöntent", 1) - self.object_equality_test(violation1, ["rule_id", "message", "content", "line_nr"]) diff --git a/gitlint/tests/rules/test_title_rules.py b/gitlint/tests/rules/test_title_rules.py deleted file mode 100644 index 10b4aab..0000000 --- a/gitlint/tests/rules/test_title_rules.py +++ /dev/null @@ -1,186 +0,0 @@ -# -*- coding: utf-8 -*- -from gitlint.tests.base import BaseTestCase -from gitlint.rules import TitleMaxLength, TitleTrailingWhitespace, TitleHardTab, TitleMustNotContainWord, \ - TitleTrailingPunctuation, TitleLeadingWhitespace, TitleRegexMatches, RuleViolation, TitleMinLength - - -class TitleRuleTests(BaseTestCase): - def test_max_line_length(self): - rule = TitleMaxLength() - - # assert no error - violation = rule.validate("å" * 72, None) - self.assertIsNone(violation) - - # assert error on line length > 72 - expected_violation = RuleViolation("T1", "Title exceeds max length (73>72)", "å" * 73) - violations = rule.validate("å" * 73, None) - self.assertListEqual(violations, [expected_violation]) - - # set line length to 120, and check no violation on length 73 - rule = TitleMaxLength({'line-length': 120}) - violations = rule.validate("å" * 73, None) - self.assertIsNone(violations) - - # assert raise on 121 - expected_violation = RuleViolation("T1", "Title exceeds max length (121>120)", "å" * 121) - violations = rule.validate("å" * 121, None) - self.assertListEqual(violations, [expected_violation]) - - def test_trailing_whitespace(self): - rule = TitleTrailingWhitespace() - - # assert no error - violations = rule.validate("å", None) - self.assertIsNone(violations) - - # trailing space - expected_violation = RuleViolation("T2", "Title has trailing whitespace", "å ") - violations = rule.validate("å ", None) - self.assertListEqual(violations, [expected_violation]) - - # trailing tab - expected_violation = RuleViolation("T2", "Title has trailing whitespace", "å\t") - violations = rule.validate("å\t", None) - self.assertListEqual(violations, [expected_violation]) - - def test_hard_tabs(self): - rule = TitleHardTab() - - # assert no error - violations = rule.validate("This is å test", None) - self.assertIsNone(violations) - - # contains hard tab - expected_violation = RuleViolation("T4", "Title contains hard tab characters (\\t)", "This is å\ttest") - violations = rule.validate("This is å\ttest", None) - self.assertListEqual(violations, [expected_violation]) - - def test_trailing_punctuation(self): - rule = TitleTrailingPunctuation() - - # assert no error - violations = rule.validate("This is å test", None) - self.assertIsNone(violations) - - # assert errors for different punctuations - punctuation = "?:!.,;" - for char in punctuation: - line = "This is å test" + char # note that make sure to include some unicode! - gitcontext = self.gitcontext(line) - expected_violation = RuleViolation("T3", f"Title has trailing punctuation ({char})", line) - violations = rule.validate(line, gitcontext) - self.assertListEqual(violations, [expected_violation]) - - def test_title_must_not_contain_word(self): - rule = TitleMustNotContainWord() - - # no violations - violations = rule.validate("This is å test", None) - self.assertIsNone(violations) - - # no violation if WIP occurs inside a word - violations = rule.validate("This is å wiping test", None) - self.assertIsNone(violations) - - # match literally - violations = rule.validate("WIP This is å test", None) - expected_violation = RuleViolation("T5", "Title contains the word 'WIP' (case-insensitive)", - "WIP This is å test") - self.assertListEqual(violations, [expected_violation]) - - # match case insensitive - violations = rule.validate("wip This is å test", None) - expected_violation = RuleViolation("T5", "Title contains the word 'WIP' (case-insensitive)", - "wip This is å test") - self.assertListEqual(violations, [expected_violation]) - - # match if there is a colon after the word - violations = rule.validate("WIP:This is å test", None) - expected_violation = RuleViolation("T5", "Title contains the word 'WIP' (case-insensitive)", - "WIP:This is å test") - self.assertListEqual(violations, [expected_violation]) - - # match multiple words - rule = TitleMustNotContainWord({'words': "wip,test,å"}) - violations = rule.validate("WIP:This is å test", None) - expected_violation = RuleViolation("T5", "Title contains the word 'wip' (case-insensitive)", - "WIP:This is å test") - expected_violation2 = RuleViolation("T5", "Title contains the word 'test' (case-insensitive)", - "WIP:This is å test") - expected_violation3 = RuleViolation("T5", "Title contains the word 'å' (case-insensitive)", - "WIP:This is å test") - self.assertListEqual(violations, [expected_violation, expected_violation2, expected_violation3]) - - def test_leading_whitespace(self): - rule = TitleLeadingWhitespace() - - # assert no error - violations = rule.validate("a", None) - self.assertIsNone(violations) - - # leading space - expected_violation = RuleViolation("T6", "Title has leading whitespace", " a") - violations = rule.validate(" a", None) - self.assertListEqual(violations, [expected_violation]) - - # leading tab - expected_violation = RuleViolation("T6", "Title has leading whitespace", "\ta") - violations = rule.validate("\ta", None) - self.assertListEqual(violations, [expected_violation]) - - # unicode test - expected_violation = RuleViolation("T6", "Title has leading whitespace", " ☺") - violations = rule.validate(" ☺", None) - self.assertListEqual(violations, [expected_violation]) - - def test_regex_matches(self): - commit = self.gitcommit("US1234: åbc\n") - - # assert no violation on default regex (=everything allowed) - rule = TitleRegexMatches() - violations = rule.validate(commit.message.title, commit) - self.assertIsNone(violations) - - # assert no violation on matching regex - rule = TitleRegexMatches({'regex': "^US[0-9]*: å"}) - violations = rule.validate(commit.message.title, commit) - self.assertIsNone(violations) - - # assert violation when no matching regex - rule = TitleRegexMatches({'regex': "^UÅ[0-9]*"}) - violations = rule.validate(commit.message.title, commit) - expected_violation = RuleViolation("T7", "Title does not match regex (^UÅ[0-9]*)", "US1234: åbc") - self.assertListEqual(violations, [expected_violation]) - - def test_min_line_length(self): - rule = TitleMinLength() - - # assert no error - violation = rule.validate("å" * 72, None) - self.assertIsNone(violation) - - # assert error on line length < 5 - expected_violation = RuleViolation("T8", "Title is too short (4<5)", "å" * 4, 1) - violations = rule.validate("å" * 4, None) - self.assertListEqual(violations, [expected_violation]) - - # set line length to 3, and check no violation on length 4 - rule = TitleMinLength({'min-length': 3}) - violations = rule.validate("å" * 4, None) - self.assertIsNone(violations) - - # assert no violations on length 3 (this asserts we've implemented a *strict* less than) - rule = TitleMinLength({'min-length': 3}) - violations = rule.validate("å" * 3, None) - self.assertIsNone(violations) - - # assert raise on 2 - expected_violation = RuleViolation("T8", "Title is too short (2<3)", "å" * 2, 1) - violations = rule.validate("å" * 2, None) - self.assertListEqual(violations, [expected_violation]) - - # assert raise on empty title - expected_violation = RuleViolation("T8", "Title is too short (0<3)", "", 1) - violations = rule.validate("", None) - self.assertListEqual(violations, [expected_violation]) diff --git a/gitlint/tests/rules/test_user_rules.py b/gitlint/tests/rules/test_user_rules.py deleted file mode 100644 index 5bf9b77..0000000 --- a/gitlint/tests/rules/test_user_rules.py +++ /dev/null @@ -1,256 +0,0 @@ -# -*- coding: utf-8 -*- - -import os -import sys - -from gitlint.tests.base import BaseTestCase -from gitlint.rule_finder import find_rule_classes, assert_valid_rule_class -from gitlint.rules import UserRuleError - -from gitlint import options, rules - - -class UserRuleTests(BaseTestCase): - def test_find_rule_classes(self): - # Let's find some user classes! - user_rule_path = self.get_sample_path("user_rules") - classes = find_rule_classes(user_rule_path) - - # Compare string representations because we can't import MyUserCommitRule here since samples/user_rules is not - # a proper python package - # Note that the following check effectively asserts that: - # - There is only 1 rule recognized and it is MyUserCommitRule - # - Other non-python files in the directory are ignored - # - Other members of the my_commit_rules module are ignored - # (such as func_should_be_ignored, global_variable_should_be_ignored) - # - Rules are loaded non-recursively (user_rules/import_exception directory is ignored) - self.assertEqual("[]", str(classes)) - - # Assert that we added the new user_rules directory to the system path and modules - self.assertIn(user_rule_path, sys.path) - self.assertIn("my_commit_rules", sys.modules) - - # Do some basic asserts on our user rule - self.assertEqual(classes[0].id, "UC1") - self.assertEqual(classes[0].name, "my-üser-commit-rule") - expected_option = options.IntOption('violation-count', 1, "Number of violåtions to return") - self.assertListEqual(classes[0].options_spec, [expected_option]) - self.assertTrue(hasattr(classes[0], "validate")) - - # Test that we can instantiate the class and can execute run the validate method and that it returns the - # expected result - rule_class = classes[0]() - violations = rule_class.validate("false-commit-object (ignored)") - self.assertListEqual(violations, [rules.RuleViolation("UC1", "Commit violåtion 1", "Contënt 1", 1)]) - - # Have it return more violations - rule_class.options['violation-count'].value = 2 - violations = rule_class.validate("false-commit-object (ignored)") - self.assertListEqual(violations, [rules.RuleViolation("UC1", "Commit violåtion 1", "Contënt 1", 1), - rules.RuleViolation("UC1", "Commit violåtion 2", "Contënt 2", 2)]) - - def test_extra_path_specified_by_file(self): - # Test that find_rule_classes can handle an extra path given as a file name instead of a directory - user_rule_path = self.get_sample_path("user_rules") - user_rule_module = os.path.join(user_rule_path, "my_commit_rules.py") - classes = find_rule_classes(user_rule_module) - - rule_class = classes[0]() - violations = rule_class.validate("false-commit-object (ignored)") - self.assertListEqual(violations, [rules.RuleViolation("UC1", "Commit violåtion 1", "Contënt 1", 1)]) - - def test_rules_from_init_file(self): - # Test that we can import rules that are defined in __init__.py files - # This also tests that we can import rules from python packages. This use to cause issues with pypy - # So this is also a regression test for that. - user_rule_path = self.get_sample_path(os.path.join("user_rules", "parent_package")) - classes = find_rule_classes(user_rule_path) - - # convert classes to strings and sort them so we can compare them - class_strings = sorted([str(clazz) for clazz in classes]) - expected = ["", ""] - self.assertListEqual(class_strings, expected) - - def test_empty_user_classes(self): - # Test that we don't find rules if we scan a different directory - user_rule_path = self.get_sample_path("config") - classes = find_rule_classes(user_rule_path) - self.assertListEqual(classes, []) - - # Importantly, ensure that the directory is not added to the syspath as this happens only when we actually - # find modules - self.assertNotIn(user_rule_path, sys.path) - - def test_failed_module_import(self): - # test importing a bogus module - user_rule_path = self.get_sample_path("user_rules/import_exception") - # We don't check the entire error message because that is different based on the python version and underlying - # operating system - expected_msg = "Error while importing extra-path module 'invalid_python'" - with self.assertRaisesRegex(UserRuleError, expected_msg): - find_rule_classes(user_rule_path) - - def test_find_rule_classes_nonexisting_path(self): - with self.assertRaisesMessage(UserRuleError, "Invalid extra-path: föo/bar"): - find_rule_classes("föo/bar") - - def test_assert_valid_rule_class(self): - class MyLineRuleClass(rules.LineRule): - id = 'UC1' - name = 'my-lïne-rule' - target = rules.CommitMessageTitle - - def validate(self): - pass - - class MyCommitRuleClass(rules.CommitRule): - id = 'UC2' - name = 'my-cömmit-rule' - - def validate(self): - pass - - class MyConfigurationRuleClass(rules.ConfigurationRule): - id = 'UC3' - name = 'my-cönfiguration-rule' - - def apply(self): - pass - - # Just assert that no error is raised - self.assertIsNone(assert_valid_rule_class(MyLineRuleClass)) - self.assertIsNone(assert_valid_rule_class(MyCommitRuleClass)) - self.assertIsNone(assert_valid_rule_class(MyConfigurationRuleClass)) - - def test_assert_valid_rule_class_negative(self): - # general test to make sure that incorrect rules will raise an exception - user_rule_path = self.get_sample_path("user_rules/incorrect_linerule") - with self.assertRaisesMessage(UserRuleError, - "User-defined rule class 'MyUserLineRule' must have a 'validate' method"): - find_rule_classes(user_rule_path) - - def test_assert_valid_rule_class_negative_parent(self): - # rule class must extend from LineRule or CommitRule - class MyRuleClass: - pass - - expected_msg = "User-defined rule class 'MyRuleClass' must extend from gitlint.rules.LineRule, " + \ - "gitlint.rules.CommitRule or gitlint.rules.ConfigurationRule" - with self.assertRaisesMessage(UserRuleError, expected_msg): - assert_valid_rule_class(MyRuleClass) - - def test_assert_valid_rule_class_negative_id(self): - - for parent_class in [rules.LineRule, rules.CommitRule]: - - class MyRuleClass(parent_class): - pass - - # Rule class must have an id - expected_msg = "User-defined rule class 'MyRuleClass' must have an 'id' attribute" - with self.assertRaisesMessage(UserRuleError, expected_msg): - assert_valid_rule_class(MyRuleClass) - - # Rule ids must be non-empty - MyRuleClass.id = "" - with self.assertRaisesMessage(UserRuleError, expected_msg): - assert_valid_rule_class(MyRuleClass) - - # Rule ids must not start with one of the reserved id letters - for letter in ["T", "R", "B", "M", "I"]: - MyRuleClass.id = letter + "1" - expected_msg = f"The id '{letter}' of 'MyRuleClass' is invalid. " + \ - "Gitlint reserves ids starting with R,T,B,M,I" - with self.assertRaisesMessage(UserRuleError, expected_msg): - assert_valid_rule_class(MyRuleClass) - - def test_assert_valid_rule_class_negative_name(self): - for parent_class in [rules.LineRule, rules.CommitRule]: - - class MyRuleClass(parent_class): - id = "UC1" - - # Rule class must have an name - expected_msg = "User-defined rule class 'MyRuleClass' must have a 'name' attribute" - with self.assertRaisesMessage(UserRuleError, expected_msg): - assert_valid_rule_class(MyRuleClass) - - # Rule names must be non-empty - MyRuleClass.name = "" - with self.assertRaisesMessage(UserRuleError, expected_msg): - assert_valid_rule_class(MyRuleClass) - - def test_assert_valid_rule_class_negative_option_spec(self): - - for parent_class in [rules.LineRule, rules.CommitRule]: - - class MyRuleClass(parent_class): - id = "UC1" - name = "my-rüle-class" - - # if set, option_spec must be a list of gitlint options - MyRuleClass.options_spec = "föo" - expected_msg = "The options_spec attribute of user-defined rule class 'MyRuleClass' must be a list " + \ - "of gitlint.options.RuleOption" - with self.assertRaisesMessage(UserRuleError, expected_msg): - assert_valid_rule_class(MyRuleClass) - - # option_spec is a list, but not of gitlint options - MyRuleClass.options_spec = ["föo", 123] # pylint: disable=bad-option-value,redefined-variable-type - with self.assertRaisesMessage(UserRuleError, expected_msg): - assert_valid_rule_class(MyRuleClass) - - def test_assert_valid_rule_class_negative_validate(self): - - baseclasses = [rules.LineRule, rules.CommitRule] - for clazz in baseclasses: - class MyRuleClass(clazz): - id = "UC1" - name = "my-rüle-class" - - with self.assertRaisesMessage(UserRuleError, - "User-defined rule class 'MyRuleClass' must have a 'validate' method"): - assert_valid_rule_class(MyRuleClass) - - # validate attribute - not a method - MyRuleClass.validate = "föo" - with self.assertRaisesMessage(UserRuleError, - "User-defined rule class 'MyRuleClass' must have a 'validate' method"): - assert_valid_rule_class(MyRuleClass) - - def test_assert_valid_rule_class_negative_apply(self): - class MyRuleClass(rules.ConfigurationRule): - id = "UCR1" - name = "my-rüle-class" - - expected_msg = "User-defined Configuration rule class 'MyRuleClass' must have an 'apply' method" - with self.assertRaisesMessage(UserRuleError, expected_msg): - assert_valid_rule_class(MyRuleClass) - - # validate attribute - not a method - MyRuleClass.validate = "föo" - with self.assertRaisesMessage(UserRuleError, expected_msg): - assert_valid_rule_class(MyRuleClass) - - def test_assert_valid_rule_class_negative_target(self): - class MyRuleClass(rules.LineRule): - id = "UC1" - name = "my-rüle-class" - - def validate(self): - pass - - # no target - expected_msg = "The target attribute of the user-defined LineRule class 'MyRuleClass' must be either " + \ - "gitlint.rules.CommitMessageTitle or gitlint.rules.CommitMessageBody" - with self.assertRaisesMessage(UserRuleError, expected_msg): - assert_valid_rule_class(MyRuleClass) - - # invalid target - MyRuleClass.target = "föo" - with self.assertRaisesMessage(UserRuleError, expected_msg): - assert_valid_rule_class(MyRuleClass) - - # valid target, no exception should be raised - MyRuleClass.target = rules.CommitMessageTitle # pylint: disable=bad-option-value,redefined-variable-type - self.assertIsNone(assert_valid_rule_class(MyRuleClass)) -- cgit v1.2.3