예제 #1
0
    def test_body_min_length(self):
        rule = rules.BodyMinLength()

        # assert no error - body is long enough
        gitcontext = self.gitcontext("Title\n\nThis is the second body line\n")
        violations = rule.validate(gitcontext)
        self.assertIsNone(violations)

        # assert no error - no body
        gitcontext = self.gitcontext("Title\n")
        violations = rule.validate(gitcontext)
        self.assertIsNone(violations)

        # assert no error - short but more than one body line
        gitcontext = self.gitcontext("Title\n\nsecond\nthird\n")
        violations = rule.validate(gitcontext)
        self.assertIsNone(violations)

        # body is too short
        expected_violation = rules.RuleViolation("B5", "Body message is too short (8<20)", "tooshort", 3)

        gitcontext = self.gitcontext("Title\n\ntooshort\n")
        violations = rule.validate(gitcontext)
        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)", "a" * 21, 3)

        rule = rules.BodyMinLength({'min-length': 120})
        gitcontext = self.gitcontext("Title\n\n%s\n" % ("a" * 21))
        violations = rule.validate(gitcontext)
        self.assertListEqual(violations, [expected_violation])
예제 #2
0
    def test_trailing_whitespace(self):
        rule = rules.BodyTrailingWhitespace()

        # assert no error
        violations = rule.validate("a", None)
        self.assertIsNone(violations)

        # trailing space
        expected_violation = rules.RuleViolation("B2", "Line has trailing whitespace", "a ")
        violations = rule.validate("a ", None)
        self.assertListEqual(violations, [expected_violation])

        # trailing tab
        expected_violation = rules.RuleViolation("B2", "Line has trailing whitespace", "a\t")
        violations = rule.validate("a\t", None)
        self.assertListEqual(violations, [expected_violation])
예제 #3
0
    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 habe 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)
예제 #4
0
    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", u"Commit violåtion 1", u"Contënt 1", 1)])
예제 #5
0
    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("[<class 'my_commit_rules.MyUserCommitRule'>]",
                         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)
        ])
예제 #6
0
    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%s\n" % ("å" * 21))
        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%s\n" % ("å" * 8))
        violations = rule.validate(commit)
        self.assertIsNone(violations)
예제 #7
0
    def test_hard_tabs(self):
        rule = rules.BodyHardTab()

        # assert no error
        violations = rule.validate("This is a test", None)
        self.assertIsNone(violations)

        # contains hard tab
        expected_violation = rules.RuleViolation("B3", "Line contains hard tab characters (\\t)", "This is a\ttest")
        violations = rule.validate("This is a\ttest", None)
        self.assertListEqual(violations, [expected_violation])
예제 #8
0
    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])
예제 #9
0
    def test_max_line_length(self):
        rule = rules.BodyMaxLineLength()

        # assert no error
        violation = rule.validate("a" * 80, None)
        self.assertIsNone(violation)

        # assert error on line length > 80
        expected_violation = rules.RuleViolation("B1", "Line exceeds max length (81>80)", "a" * 81)
        violations = rule.validate("a" * 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("a" * 73, None)
        self.assertIsNone(violations)

        # assert raise on 121
        expected_violation = rules.RuleViolation("B1", "Line exceeds max length (121>120)", "a" * 121)
        violations = rule.validate("a" * 121, None)
        self.assertListEqual(violations, [expected_violation])
예제 #10
0
    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])
예제 #11
0
    def test_body_first_line_empty(self):
        rule = rules.BodyFirstLineEmpty()

        # assert no error
        gitcontext = self.gitcontext("Title\n\nThis is the second body line")
        violations = rule.validate(gitcontext)
        self.assertIsNone(violations)

        # contains hard tab
        expected_violation = rules.RuleViolation("B4", "Second line is not empty", "not empty", 2)

        gitcontext = self.gitcontext("Title\nnot empty\nThis is the second body line")
        violations = rule.validate(gitcontext)
        self.assertListEqual(violations, [expected_violation])
예제 #12
0
    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)
예제 #13
0
    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])
예제 #14
0
    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])