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_lint_configuration_rule(self): # Test that all rules are ignored because of matching regex lint_config = LintConfig() lint_config.set_rule_option("I1", "regex", "^Just a title(.*)") linter = GitLinter(lint_config) violations = linter.lint( self.gitcommit(self.get_sample("commit_message/sample2"))) self.assertListEqual(violations, []) # Test ignoring only certain rules lint_config = LintConfig() lint_config.set_rule_option("I1", "regex", "^Just a title(.*)") lint_config.set_rule_option("I1", "ignore", "B6") linter = GitLinter(lint_config) violations = linter.lint( self.gitcommit(self.get_sample("commit_message/sample2"))) # Normally we'd expect a B6 violation, but that one is skipped because of the specific ignore set above expected = [ RuleViolation("T5", "Title contains the word 'WIP' (case-insensitive)", u"Just a title contåining WIP", 1) ] self.assertListEqual(violations, expected)
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_gitcontext_ignore_all(self): config = LintConfig() original_rules = config.rules # nothing gitlint context = self.gitcontext("test\ngitlint\nfoo") config.apply_config_from_commit(context.commits[-1]) self.assertListEqual(config.rules, original_rules) # ignore all rules context = self.gitcontext("test\ngitlint-ignore: all\nfoo") config.apply_config_from_commit(context.commits[-1]) self.assertEqual(config.rules, []) # ignore all rules, no space config = LintConfig() context = self.gitcontext("test\ngitlint-ignore:all\nfoo") config.apply_config_from_commit(context.commits[-1]) self.assertEqual(config.rules, []) # ignore all rules, more spacing config = LintConfig() context = self.gitcontext("test\ngitlint-ignore: \t all\nfoo") config.apply_config_from_commit(context.commits[-1]) self.assertEqual(config.rules, [])
def test_lint_configuration_rule(self): # Test that all rules are ignored because of matching regex lint_config = LintConfig() lint_config.set_rule_option("I1", "regex", "^Just a title(.*)") linter = GitLinter(lint_config) violations = linter.lint( self.gitcommit(self.get_sample("commit_message/sample2"))) self.assertListEqual(violations, []) # Test ignoring only certain rules lint_config = LintConfig() lint_config.set_rule_option("I1", "regex", "^Just a title(.*)") lint_config.set_rule_option("I1", "ignore", "B6") linter = GitLinter(lint_config) violations = linter.lint( self.gitcommit(self.get_sample("commit_message/sample2"))) # Normally we'd expect a B6 violation, but that one is skipped because of the specific ignore set above expected = [ RuleViolation("T5", "Title contains the word 'WIP' (case-insensitive)", u"Just a title contåining WIP", 1) ] self.assertListEqual(violations, expected) # Test ignoring body lines lint_config = LintConfig() linter = GitLinter(lint_config) lint_config.set_rule_option("I3", "regex", u"(.*)tråiling(.*)") violations = linter.lint( self.gitcommit(self.get_sample("commit_message/sample1"))) expected_errors = [ RuleViolation( "T3", "Title has trailing punctuation (.)", u"Commit title contåining 'WIP', as well as trailing punctuation.", 1), RuleViolation( "T5", "Title contains the word 'WIP' (case-insensitive)", u"Commit title contåining 'WIP', as well as trailing punctuation.", 1), RuleViolation("B4", "Second line is not empty", "This line should be empty", 2), RuleViolation( "B1", "Line exceeds max length (135>80)", "This is the first line of the commit message body and it is meant to test " + "a line that exceeds the maximum line length of 80 characters.", 3), RuleViolation("B2", "Line has trailing whitespace", "This line has a trailing tab.\t", 4), RuleViolation("B3", "Line contains hard tab characters (\\t)", "This line has a trailing tab.\t", 4) ] self.assertListEqual(violations, expected_errors)
def test_e(self): display = Display(LintConfig()) display.config.verbosity = 2 with patch('gitlint.display.stdout', new=StringIO()) as stdout: # Non exact outputting, should output both v and vv output with patch('gitlint.display.stderr', new=StringIO()) as stderr: display.e(u"tëst") display.ee(u"tëst2") # vvvv should be ignored regardless display.eee(u"tëst3.1") display.eee(u"tëst3.2", exact=True) self.assertEqual(u"tëst\ntëst2\n", stderr.getvalue()) # exact outputting, should only output v with patch('gitlint.display.stderr', new=StringIO()) as stderr: display.e(u"tëst", exact=True) display.ee(u"tëst2", exact=True) # vvvv should be ignored regardless display.eee(u"tëst3.1") display.eee(u"tëst3.2", exact=True) self.assertEqual(u"tëst2\n", stderr.getvalue()) # standard output should be empty throughtout all of this self.assertEqual('', stdout.getvalue())
def test_lint_regex_rules(self): """ Additional test for title-match-regex, body-match-regex """ commit = self.gitcommit( self.get_sample("commit_message/no-violations")) lintconfig = LintConfig() linter = GitLinter(lintconfig) violations = linter.lint(commit) # No violations by default self.assertListEqual(violations, []) # Matching regexes shouldn't be a problem rule_regexes = [("title-match-regex", u"Tïtle$"), ("body-match-regex", u"Sïgned-Off-By: (.*)$")] for rule_regex in rule_regexes: lintconfig.set_rule_option(rule_regex[0], "regex", rule_regex[1]) violations = linter.lint(commit) self.assertListEqual(violations, []) # Non-matching regexes should return violations rule_regexes = [("title-match-regex", ), ("body-match-regex", )] lintconfig.set_rule_option("title-match-regex", "regex", u"^Tïtle") lintconfig.set_rule_option("body-match-regex", "regex", u"Sügned-Off-By: (.*)$") expected_violations = [ RuleViolation("T7", u"Title does not match regex (^Tïtle)", u"Normal Commit Tïtle", 1), RuleViolation("B8", u"Body does not match regex (Sügned-Off-By: (.*)$)", None, 6) ] violations = linter.lint(commit) self.assertListEqual(violations, expected_violations)
def test_set_config_from_string_list(self): config = LintConfig() # assert some defaults self.assertEqual( config.get_rule_option('title-max-length', 'line-length'), 72) self.assertEqual( config.get_rule_option('body-max-line-length', 'line-length'), 80) self.assertListEqual( config.get_rule_option('title-must-not-contain-word', 'words'), ["WIP"]) self.assertEqual(config.verbosity, 3) # change and assert changes config_builder = LintConfigBuilder() config_builder.set_config_from_string_list([ 'general.verbosity=1', 'title-max-length.line-length=60', 'body-max-line-length.line-length=120', u"title-must-not-contain-word.words=håha" ]) config = config_builder.build() self.assertEqual( config.get_rule_option('title-max-length', 'line-length'), 60) self.assertEqual( config.get_rule_option('body-max-line-length', 'line-length'), 120) self.assertListEqual( config.get_rule_option('title-must-not-contain-word', 'words'), [u"håha"]) self.assertEqual(config.verbosity, 1)
def test_set_general_option(self): config = LintConfig() # Check that default general options are correct self.assertTrue(config.ignore_merge_commits) self.assertFalse(config.debug) self.assertEqual(config.verbosity, 3) active_rule_classes = tuple(type(rule) for rule in config.rules) self.assertTupleEqual(active_rule_classes, config.default_rule_classes) # ignore - set by string config.set_general_option("ignore", "title-trailing-whitespace, B2") self.assertEqual(config.ignore, ["title-trailing-whitespace", "B2"]) # ignore - set by list config.set_general_option("ignore", ["T1", "B3"]) self.assertEqual(config.ignore, ["T1", "B3"]) # verbosity config.set_general_option("verbosity", 1) self.assertEqual(config.verbosity, 1) # ignore_merge_commit config.set_general_option("ignore-merge-commits", "false") self.assertFalse(config.ignore_merge_commits) # debug config.set_general_option("debug", "true") self.assertTrue(config.debug) # target config.set_general_option("target", self.SAMPLES_DIR) self.assertEqual(config.target, self.SAMPLES_DIR)
def test_commit_msg_hook_path(self): lint_config = LintConfig() lint_config.target = self.SAMPLES_DIR expected_path = os.path.join(self.SAMPLES_DIR, COMMIT_MSG_HOOK_DST_PATH) path = GitHookInstaller.commit_msg_hook_path(lint_config) self.assertEqual(path, expected_path)
def test_lint_sample3(self): linter = GitLinter(LintConfig()) gitcontext = self.gitcontext(self.get_sample("commit_message/sample3")) violations = linter.lint(gitcontext.commits[-1]) title = u" Commit title containing 'WIP', \tleading and tråiling whitespace and longer than 72 characters." expected = [ RuleViolation("T1", "Title exceeds max length (95>72)", title, 1), RuleViolation("T3", "Title has trailing punctuation (.)", title, 1), RuleViolation("T4", "Title contains hard tab characters (\\t)", title, 1), RuleViolation("T5", "Title contains the word 'WIP' (case-insensitive)", title, 1), RuleViolation("T6", "Title has leading whitespace", title, 1), RuleViolation("B4", "Second line is not empty", "This line should be empty", 2), RuleViolation( "B1", "Line exceeds max length (101>80)", u"This is the first line is meånt to test a line that exceeds the maximum line " + "length of 80 characters.", 3), RuleViolation("B2", "Line has trailing whitespace", "This line has a trailing space. ", 4), RuleViolation("B2", "Line has trailing whitespace", u"This line has a tråiling tab.\t", 5), RuleViolation("B3", "Line contains hard tab characters (\\t)", u"This line has a tråiling tab.\t", 5) ] self.assertListEqual(violations, expected)
def test_print_violations(self): violations = [ RuleViolation("RULE_ID_1", u"Error Messåge 1", "Violating Content 1", None), RuleViolation("RULE_ID_2", "Error Message 2", u"Violåting Content 2", 2) ] linter = GitLinter(LintConfig()) # test output with increasing verbosity with patch('gitlint.display.stderr', new=StringIO()) as stderr: linter.config.verbosity = 0 linter.print_violations(violations) self.assertEqual("", stderr.getvalue()) with patch('gitlint.display.stderr', new=StringIO()) as stderr: linter.config.verbosity = 1 linter.print_violations(violations) expected = u"-: RULE_ID_1\n2: RULE_ID_2\n" self.assertEqual(expected, stderr.getvalue()) with patch('gitlint.display.stderr', new=StringIO()) as stderr: linter.config.verbosity = 2 linter.print_violations(violations) expected = u"-: RULE_ID_1 Error Messåge 1\n2: RULE_ID_2 Error Message 2\n" self.assertEqual(expected, stderr.getvalue()) with patch('gitlint.display.stderr', new=StringIO()) as stderr: linter.config.verbosity = 3 linter.print_violations(violations) expected = u"-: RULE_ID_1 Error Messåge 1: \"Violating Content 1\"\n" + \ u"2: RULE_ID_2 Error Message 2: \"Violåting Content 2\"\n" self.assertEqual(expected, stderr.getvalue())
def test_lint_sample5(self): gitcontext = self.gitcontext(self.get_sample("commit_message/sample5")) lintconfig = LintConfig() lintconfig.apply_config_from_commit(gitcontext.commits[-1]) linter = GitLinter(lintconfig) violations = linter.lint(gitcontext.commits[-1], gitcontext) title = " Commit title containing 'WIP', \tleading and trailing whitespace and longer than 72 characters." # expect only certain violations because sample5 has a 'gitlint: T3,' expected = [ RuleViolation("T1", "Title exceeds max length (95>72)", title, 1), RuleViolation("T4", "Title contains hard tab characters (\\t)", title, 1), RuleViolation("T5", "Title contains the word 'WIP' (case-insensitive)", title, 1), RuleViolation("B4", "Second line is not empty", "This line should be empty", 2), RuleViolation("B2", "Line has trailing whitespace", "This line has a trailing space. ", 4), RuleViolation("B2", "Line has trailing whitespace", "This line has a trailing tab.\t", 5), RuleViolation("B3", "Line contains hard tab characters (\\t)", "This line has a trailing tab.\t", 5) ] self.assertListEqual(violations, expected)
def test_set_general_option_negative(self): config = LintConfig() with self.assertRaisesRegexp(LintConfigError, "'foo' is not a valid gitlint option"): config.set_general_option("foo", "bar") # invalid verbosity incorrect_values = [-1, "foo"] for value in incorrect_values: expected_msg = r"Option 'verbosity' must be a positive integer \(current value: '{0}'\)".format(value) with self.assertRaisesRegexp(LintConfigError, expected_msg): config.verbosity = value incorrect_values = [4] for value in incorrect_values: with self.assertRaisesRegexp(LintConfigError, "Option 'verbosity' must be set between 0 and 3"): config.verbosity = value # invalid ignore_merge_commits incorrect_values = [-1, 4, "foo"] for value in incorrect_values: with self.assertRaisesRegexp(LintConfigError, r"Option 'ignore-merge-commits' must be either 'true' or 'false'"): config.ignore_merge_commits = value # invalid debug with self.assertRaisesRegexp(LintConfigError, r"Option 'debug' must be either 'true' or 'false'"): config.debug = "foobar"
def test_set_general_option(self): config = LintConfig() # Check that default general options are correct self.assertTrue(config.ignore_merge_commits) self.assertFalse(config.debug) self.assertEqual(config.verbosity, 3) active_rule_classes = [type(rule) for rule in config.rules] self.assertListEqual(active_rule_classes, config.default_rule_classes) # Check that we can change the general options # ignore config.set_general_option("ignore", "title-trailing-whitespace, B2") expected_ignored_rules = set([rules.BodyTrailingWhitespace, rules.TitleTrailingWhitespace]) active_rule_classes = set(type(rule) for rule in config.rules) # redetermine active rule classes expected_active_rule_classes = set(config.default_rule_classes) - expected_ignored_rules self.assertSetEqual(active_rule_classes, expected_active_rule_classes) # verbosity config.set_general_option("verbosity", 1) self.assertEqual(config.verbosity, 1) # ignore_merge_commit config.set_general_option("ignore-merge-commits", "false") self.assertFalse(config.ignore_merge_commits) # debug config.set_general_option("debug", "true") self.assertTrue(config.debug)
def test_gitcontext_ignore_specific(self): # ignore specific rules config = LintConfig() context = self.gitcontext("test\ngitlint-ignore: T1, body-hard-tab") config.apply_config_from_commit(context.commits[-1]) expected_rules = [rule for rule in config.rules if rule.id not in ["T1", "body-hard-tab"]] self.assertEqual(config.rules, expected_rules)
def test_uninstall_commit_msg_hook_negative(self, isdir, path_exists, remove): lint_config = LintConfig() lint_config.target = u"/foo/bår" # mock that the current directory is not a git repo isdir.return_value = False expected_msg = u"{0} is not a git repository".format(u"/foo/bår") with self.assertRaisesRegex(GitHookInstallerError, expected_msg): GitHookInstaller.uninstall_commit_msg_hook(lint_config) isdir.assert_called_with(os.path.join(u"/foo/bår", '.git/hooks')) path_exists.assert_not_called() remove.assert_not_called() # mock that there is no commit hook present isdir.return_value = True path_exists.return_value = False expected_dst = os.path.join(u"/foo/bår", COMMIT_MSG_HOOK_DST_PATH) expected_msg = u"There is no commit-msg hook present in {0}.".format(expected_dst) with self.assertRaisesRegex(GitHookInstallerError, expected_msg): GitHookInstaller.uninstall_commit_msg_hook(lint_config) isdir.assert_called_with(os.path.join(u"/foo/bår", '.git/hooks')) path_exists.assert_called_once_with(expected_dst) remove.assert_not_called() # mock that there is a different (=not gitlint) commit hook isdir.return_value = True path_exists.return_value = True read_data = "#!/bin/sh\nfoo" expected_dst = os.path.join(u"/foo/bår", COMMIT_MSG_HOOK_DST_PATH) expected_msg = u"The commit-msg hook in {0} was not installed by gitlint ".format(expected_dst) + \ r"\(or it was modified\).\nUninstallation of 3th party or modified gitlint hooks " + \ "is not supported." with patch('gitlint.hooks.open', mock_open(read_data=read_data), create=True): with self.assertRaisesRegex(GitHookInstallerError, expected_msg): GitHookInstaller.uninstall_commit_msg_hook(lint_config) remove.assert_not_called()
def test_lint_sample1(self): linter = GitLinter(LintConfig()) gitcontext = self.gitcontext(self.get_sample("commit_message/sample1")) violations = linter.lint(gitcontext.commits[-1]) expected_errors = [ RuleViolation( "T3", "Title has trailing punctuation (.)", u"Commit title contåining 'WIP', as well as trailing punctuation.", 1), RuleViolation( "T5", "Title contains the word 'WIP' (case-insensitive)", u"Commit title contåining 'WIP', as well as trailing punctuation.", 1), RuleViolation("B4", "Second line is not empty", "This line should be empty", 2), RuleViolation( "B1", "Line exceeds max length (135>80)", "This is the first line of the commit message body and it is meant to test " + "a line that exceeds the maximum line length of 80 characters.", 3), RuleViolation("B2", "Line has trailing whitespace", u"This line has a tråiling space. ", 4), RuleViolation("B2", "Line has trailing whitespace", "This line has a trailing tab.\t", 5), RuleViolation("B3", "Line contains hard tab characters (\\t)", "This line has a trailing tab.\t", 5) ] self.assertListEqual(violations, expected_errors)
def test_set_rule_option_negative(self): config = LintConfig() # non-existing rule expected_error_msg = "No such rule 'foobar'" with self.assertRaisesRegexp(LintConfigError, expected_error_msg): config.set_rule_option('foobar', 'line-length', 60) # non-existing option expected_error_msg = "Rule 'title-max-length' has no option 'foobar'" with self.assertRaisesRegexp(LintConfigError, expected_error_msg): config.set_rule_option('title-max-length', 'foobar', 60) # invalid option value expected_error_msg = "'foo' is not a valid value for option 'title-max-length.line-length'. " + \ "Option 'line-length' must be a positive integer \(current value: 'foo'\)." with self.assertRaisesRegexp(LintConfigError, expected_error_msg): config.set_rule_option('title-max-length', 'line-length', "foo") # invalid verbosity with self.assertRaisesRegexp(LintConfigError, "verbosity must be set between 0 and 3"): config.verbosity = -1 with self.assertRaisesRegexp(LintConfigError, "verbosity must be set between 0 and 3"): config.verbosity = 4
def test_set_from_commit_ignore_all(self): config = LintConfig() original_rules = config.rules original_rule_ids = [rule.id for rule in original_rules] config_builder = LintConfigBuilder() # nothing gitlint config_builder.set_config_from_commit( self.gitcommit(u"tëst\ngitlint\nfoo")) config = config_builder.build() self.assertListEqual(config.rules, original_rules) self.assertListEqual(config.ignore, []) # ignore all rules config_builder.set_config_from_commit( self.gitcommit(u"tëst\ngitlint-ignore: all\nfoo")) config = config_builder.build() self.assertEqual(config.ignore, original_rule_ids) # ignore all rules, no space config_builder.set_config_from_commit( self.gitcommit(u"tëst\ngitlint-ignore:all\nfoo")) config = config_builder.build() self.assertEqual(config.ignore, original_rule_ids) # ignore all rules, more spacing config_builder.set_config_from_commit( self.gitcommit(u"tëst\ngitlint-ignore: \t all\nfoo")) config = config_builder.build() self.assertEqual(config.ignore, original_rule_ids)
def test_apply_config_options_negative(self): config = LintConfig() # assert error on incorrect rule with self.assertRaisesRegexp(LintConfigError, "No such rule 'foo'"): config.apply_config_options(['foo.bar=1']) # no equal sign expected_msg = "'foo.bar' is an invalid configuration option. Use '<rule>.<option>=<value>'" with self.assertRaisesRegexp(LintConfigError, expected_msg): config.apply_config_options(['foo.bar']) # missing value expected_msg = "'foo.bar=' is an invalid configuration option. Use '<rule>.<option>=<value>'" with self.assertRaisesRegexp(LintConfigError, expected_msg): config.apply_config_options(['foo.bar=']) # space instead of equal sign expected_msg = "'foo.bar 1' is an invalid configuration option. Use '<rule>.<option>=<value>'" with self.assertRaisesRegexp(LintConfigError, expected_msg): config.apply_config_options(['foo.bar 1']) # no period between rule and option names expected_msg = "'foobar=1' is an invalid configuration option. Use '<rule>.<option>=<value>'" with self.assertRaisesRegexp(LintConfigError, expected_msg): config.apply_config_options(['foobar=1'])
def test_install_commit_msg_hook_negative(self, git_hooks_dir, isdir, path_exists, copy): lint_config = LintConfig() lint_config.target = os.path.join(u"/hür", u"dur") git_hooks_dir.return_value = os.path.join(u"/föo", u"bar", ".git", "hooks") # mock that current dir is not a git repo isdir.return_value = False expected_msg = u"{0} is not a git repository".format( lint_config.target) with self.assertRaisesRegex(GitHookInstallerError, expected_msg): GitHookInstaller.install_commit_msg_hook(lint_config) isdir.assert_called_with(git_hooks_dir.return_value) path_exists.assert_not_called() copy.assert_not_called() # mock that there is already a commit hook present isdir.return_value = True path_exists.return_value = True expected_dst = os.path.join(git_hooks_dir.return_value, COMMIT_MSG_HOOK_DST_PATH) expected_msg = u"There is already a commit-msg hook file present in {0}.\n".format(expected_dst) + \ "gitlint currently does not support appending to an existing commit-msg file." with self.assertRaisesRegex(GitHookInstallerError, expected_msg): GitHookInstaller.install_commit_msg_hook(lint_config)
def test_named_rules(self): """ Test that when named rules are present, both them and the original (non-named) rules executed """ lint_config = LintConfig() for rule_name in [u"my-ïd", u"another-rule-ïd"]: rule_id = TitleMustNotContainWord.id + ":" + rule_name lint_config.rules.add_rule(TitleMustNotContainWord, rule_id) lint_config.set_rule_option(rule_id, "words", [u"Föo"]) linter = GitLinter(lint_config) violations = [ RuleViolation("T5", u"Title contains the word 'WIP' (case-insensitive)", u"WIP: Föo bar", 1), RuleViolation(u"T5:another-rule-ïd", u"Title contains the word 'Föo' (case-insensitive)", u"WIP: Föo bar", 1), RuleViolation(u"T5:my-ïd", u"Title contains the word 'Föo' (case-insensitive)", u"WIP: Föo bar", 1) ] self.assertListEqual( violations, linter.lint( self.gitcommit(u"WIP: Föo bar\n\nFoo bår hur dur bla bla")))
def test_ignore_independent_from_rules(self): # Test that the lintconfig rules are not modified when setting config.ignore # This was different in the past, this test is mostly here to catch regressions config = LintConfig() original_rules = config.rules config.ignore = ["T1", "T2"] self.assertEqual(config.ignore, ["T1", "T2"]) self.assertSequenceEqual(config.rules, original_rules)
def test_config_equality(self): self.assertEqual(LintConfig(), LintConfig()) self.assertNotEqual(LintConfig(), LintConfigGenerator()) # Ensure LintConfig are not equal if they differ on their attributes attrs = [("verbosity", 1), ("rules", []), ("ignore_stdin", True), ("debug", True), ("ignore", ["T1"]), ("staged", True), ("_config_path", self.get_sample_path()), ("ignore_merge_commits", False), ("ignore_fixup_commits", False), ("ignore_squash_commits", False), ("ignore_revert_commits", False), ("extra_path", self.get_sample_path("user_rules")), ("target", self.get_sample_path()), ("contrib", ["CC1"])] for attr, val in attrs: config = LintConfig() setattr(config, attr, val) self.assertNotEqual(LintConfig(), config) # Other attributes don't matter config1 = LintConfig() config2 = LintConfig() config1.foo = u"bår" self.assertEqual(config1, config2) config2.foo = u"dūr" self.assertEqual(config1, config2)
def test_set_rule_option(self): config = LintConfig() # assert default title line-length self.assertEqual(config.get_rule_option('title-max-length', 'line-length'), 72) # change line length and assert it is set config.set_rule_option('title-max-length', 'line-length', 60) self.assertEqual(config.get_rule_option('title-max-length', 'line-length'), 60)
def test_lint_sample2(self): linter = GitLinter(LintConfig()) gitcontext = self.gitcontext(self.get_sample("commit_message/sample2")) violations = linter.lint(gitcontext.commits[-1]) expected = [RuleViolation("T5", "Title contains the word 'WIP' (case-insensitive)", u"Just a title contåining WIP", 1), RuleViolation("B6", "Body message is missing", None, 3)] self.assertListEqual(violations, expected)
def test_lint_sample4(self): gitcontext = self.gitcontext(self.get_sample("commit_message/sample4")) lintconfig = LintConfig() lintconfig.apply_config_from_commit(gitcontext.commits[-1]) linter = GitLinter(lintconfig) violations = linter.lint(gitcontext.commits[-1], gitcontext) # expect no violations because sample4 has a 'gitlint: disable line' expected = [] self.assertListEqual(violations, expected)
def test_install_commit_msg_hook(isdir, path_exists, copy, stat, chmod): lint_config = LintConfig(target="/foo/bar") expected_dst = os.path.join("/foo/bar", COMMIT_MSG_HOOK_DST_PATH) GitHookInstaller.install_commit_msg_hook(lint_config) isdir.assert_called_once_with('/foo/bar/.git/hooks') path_exists.assert_called_once_with(expected_dst) copy.assert_called_once_with(COMMIT_MSG_HOOK_SRC_PATH, expected_dst) stat.assert_called_once_with(expected_dst) chmod.assert_called_once_with(expected_dst, ANY)
def test_set_general_option_negative(self): config = LintConfig() # Note that we should't test whether we can set unicode because python just doesn't allow unicode attributes with self.assertRaisesRegex(LintConfigError, "'foo' is not a valid gitlint option"): config.set_general_option("foo", u"bår") # try setting _config_path, this is a real attribute of LintConfig, but the code should prevent it from # being set with self.assertRaisesRegex( LintConfigError, "'_config_path' is not a valid gitlint option"): config.set_general_option("_config_path", u"bår") # invalid verbosity` incorrect_values = [-1, u"föo"] for value in incorrect_values: expected_msg = u"Option 'verbosity' must be a positive integer \(current value: '{0}'\)".format( value) with self.assertRaisesRegex(LintConfigError, expected_msg): config.verbosity = value incorrect_values = [4] for value in incorrect_values: with self.assertRaisesRegex( LintConfigError, "Option 'verbosity' must be set between 0 and 3"): config.verbosity = value # invalid ignore_merge_commits incorrect_values = [-1, 4, u"föo"] for value in incorrect_values: with self.assertRaisesRegex( LintConfigError, "Option 'ignore-merge-commits' must be either 'true' or 'false'" ): config.ignore_merge_commits = value # invalid ignore -> not here because ignore is a ListOption which converts everything to a string before # splitting which means it it will accept just about everything # invalid debug with self.assertRaisesRegex( LintConfigError, "Option 'debug' must be either 'true' or 'false'"): config.debug = u"föobar" # extra-path has its own negative test # invalid target with self.assertRaisesRegex( LintConfigError, u"Option target must be an existing directory \(current value: 'föo/bar'\)" ): config.target = u"föo/bar"