def test_gitcommit_equality(self): # Test simple equality case now = datetime.datetime.utcnow() context1 = GitContext() commit_message1 = GitCommitMessage(u"tëst\n\nfoo", u"tëst\n\nfoo", u"tēst", ["", u"föo"]) commit1 = GitCommit(context1, commit_message1, now, u"Jöhn Smith", u"jö[email protected]", None, True, [u"föo/bar"]) context1.commits = [commit1] context2 = GitContext() commit_message2 = GitCommitMessage(u"tëst\n\nfoo", u"tëst\n\nfoo", u"tēst", ["", u"föo"]) commit2 = GitCommit(context1, commit_message1, now, u"Jöhn Smith", u"jö[email protected]", None, True, [u"föo/bar"]) context2.commits = [commit2] self.assertEqual(context1, context2) self.assertEqual(commit_message1, commit_message2) self.assertEqual(commit1, commit2) # Check that objects are inequal when changing a single attribute for attr in [ 'message', 'author_name', 'author_email', 'parents', 'is_merge_commit', 'changed_files' ]: prev_val = getattr(commit1, attr) setattr(commit1, attr, u"föo") self.assertNotEqual(commit1, commit2) setattr(commit1, attr, prev_val) self.assertEqual(commit1, commit2)
def test_gitcontext(self, sh): sh.git.side_effect = [ u"#", # git config --get core.commentchar u"\nfoöbar\n" ] expected_calls = [ call("config", "--get", "core.commentchar", _ok_code=[0, 1], **self.expected_sh_special_args), call("rev-parse", "--abbrev-ref", "HEAD", **self.expected_sh_special_args) ] context = GitContext(u"fåke/path") self.assertEqual(sh.git.mock_calls, []) # gitcontext.comment_branch self.assertEqual(context.commentchar, u"#") self.assertEqual(sh.git.mock_calls, expected_calls[0:1]) # gitcontext.current_branch self.assertEqual(context.current_branch, u"foöbar") self.assertEqual(sh.git.mock_calls, expected_calls)
def test_lint_sample3(self): linter = GitLinter(LintConfig()) gitcontext = GitContext() gitcontext.set_commit_msg(self.get_sample("commit_message/sample3")) violations = linter.lint(gitcontext) title = " Commit title containing 'WIP', \tleading and trailing 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)", "This is the first line 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 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 cli(config, c, ignore, verbose, silent): """ Git lint tool, checks your git commit messages for styling issues """ try: # Config precedence: # First, load default config or config from configfile lint_config = get_lint_config(config) # Then process any commandline configuration flags try: lint_config.apply_config_options(c) except LintConfigError as e: click.echo("Config Error: {}".format(e.message)) exit(CONFIG_ERROR_CODE) # Finally, overwrite with any convenience commandline flags lint_config.apply_on_csv_string(ignore, lint_config.disable_rule) if silent: lint_config.verbosity = 0 elif verbose > 0: lint_config.verbosity = verbose except LintConfigError as e: click.echo("Config Error: {0}".format(e.message)) exit(CONFIG_ERROR_CODE) # return 10000 on config error if sys.stdin.isatty(): gitcontext = GitContext.from_environment() else: gitcontext = GitContext() gitcontext.set_commit_msg(sys.stdin.read()) linter = GitLinter(lint_config) violations = linter.lint(gitcontext) linter.print_violations(violations) exit(len(violations))
def test_lint_sample1(self): linter = GitLinter(LintConfig()) gitcontext = GitContext() gitcontext.set_commit_msg(self.get_sample("commit_message/sample1")) violations = linter.lint(gitcontext) expected_errors = [ RuleViolation( "T3", "Title has trailing punctuation (.)", "Commit title containing 'WIP', as well as trailing punctuation.", 1), RuleViolation( "T5", "Title contains the word 'WIP' (case-insensitive)", "Commit title containing '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 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_gitcommitmessage_equality(self): commit_message1 = GitCommitMessage(GitContext(), u"tëst\n\nfoo", u"tëst\n\nfoo", u"tēst", ["", u"föo"]) attrs = ['original', 'full', 'title', 'body'] self.object_equality_test(commit_message1, attrs, {"context": commit_message1.context})
def test_gitcontext_equality(self, sh): sh.git.side_effect = [ u"û\n", # context1: git config --get core.commentchar u"û\n", # context2: git config --get core.commentchar u"my-brånch\n", # context1: git rev-parse --abbrev-ref HEAD u"my-brånch\n", # context2: git rev-parse --abbrev-ref HEAD ] context1 = GitContext(u"fåke/path") context1.commits = [ u"fōo", u"bår" ] # we don't need real commits to check for equality context2 = GitContext(u"fåke/path") context2.commits = [u"fōo", u"bår"] self.assertEqual(context1, context2) # INEQUALITY # Different commits context2.commits = [u"hür", u"dür"] self.assertNotEqual(context1, context2) # Different repository_path context2.commits = context1.commits context2.repository_path = u"ōther/path" self.assertNotEqual(context1, context2) # Different comment_char context3 = GitContext(u"fåke/path") context3.commits = [u"fōo", u"bår"] sh.git.side_effect = ([ u"ç\n", # context3: git config --get core.commentchar u"my-brånch\n" # context3: git rev-parse --abbrev-ref HEAD ]) self.assertNotEqual(context1, context3) # Different current_branch context4 = GitContext(u"fåke/path") context4.commits = [u"fōo", u"bår"] sh.git.side_effect = ([ u"û\n", # context4: git config --get core.commentchar u"different-brånch\n" # context4: git rev-parse --abbrev-ref HEAD ]) self.assertNotEqual(context1, context4)
def test_commit_msg_custom_commentchar(self, patched): patched.return_value = "ä" context = GitContext() message = GitCommitMessage.from_full_message(context, "Tïtle\n\nBödy 1\näCömment\nBody 2") self.assertEqual(message.title, "Tïtle") self.assertEqual(message.body, ["", "Bödy 1", "Body 2"]) self.assertEqual(message.full, "Tïtle\n\nBödy 1\nBody 2") self.assertEqual(message.original, "Tïtle\n\nBödy 1\näCömment\nBody 2")
def gitcontext(commit_msg_str, changed_files=None): """ Utility method to easily create gitcontext objects based on a given commit msg string and set of changed files""" gitcontext = GitContext() gitcontext.set_commit_msg(commit_msg_str) if changed_files: gitcontext.changed_files = changed_files else: gitcontext.changed_files = [] return gitcontext
def test_gitcommit_equality(self, git): # git will be called to setup the context (commentchar and current_branch), just return the same value # This only matters to test gitcontext equality, not gitcommit equality git.return_value = "foöbar" # Test simple equality case now = datetime.datetime.utcnow() context1 = GitContext() commit_message1 = GitCommitMessage(context1, "tëst\n\nfoo", "tëst\n\nfoo", "tēst", ["", "föo"]) commit1 = GitCommit(context1, commit_message1, "shä", now, "Jöhn Smith", "jö[email protected]", None, ["föo/bar"], ["brånch1", "brånch2"]) context1.commits = [commit1] context2 = GitContext() commit_message2 = GitCommitMessage(context2, "tëst\n\nfoo", "tëst\n\nfoo", "tēst", ["", "föo"]) commit2 = GitCommit(context2, commit_message1, "shä", now, "Jöhn Smith", "jö[email protected]", None, ["föo/bar"], ["brånch1", "brånch2"]) context2.commits = [commit2] self.assertEqual(context1, context2) self.assertEqual(commit_message1, commit_message2) self.assertEqual(commit1, commit2) # Check that objects are unequal when changing a single attribute kwargs = {'message': commit1.message, 'sha': commit1.sha, 'date': commit1.date, 'author_name': commit1.author_name, 'author_email': commit1.author_email, 'parents': commit1.parents, 'changed_files': commit1.changed_files, 'branches': commit1.branches} self.object_equality_test(commit1, kwargs.keys(), {"context": commit1.context}) # Check that the is_* attributes that are affected by the commit message affect equality special_messages = {'is_merge_commit': "Merge: foöbar", 'is_fixup_commit': "fixup! foöbar", 'is_squash_commit': "squash! foöbar", 'is_revert_commit': "Revert: foöbar"} for key in special_messages: kwargs_copy = copy.deepcopy(kwargs) clone1 = GitCommit(context=commit1.context, **kwargs_copy) clone1.message = GitCommitMessage.from_full_message(context1, special_messages[key]) self.assertTrue(getattr(clone1, key)) clone2 = GitCommit(context=commit1.context, **kwargs_copy) clone2.message = GitCommitMessage.from_full_message(context1, "foöbar") self.assertNotEqual(clone1, clone2)
def test_set_commit_msg_just_title(self): gitcontext = GitContext() gitcontext.set_commit_msg(self.get_sample("commit_message/sample2")) self.assertEqual(gitcontext.commit_msg.title, "Just a title containing WIP") self.assertEqual(gitcontext.commit_msg.body, []) self.assertEqual(gitcontext.commit_msg.full, "Just a title containing WIP") self.assertEqual(gitcontext.commit_msg.original, "Just a title containing WIP")
def test_lint_sample2(self): linter = GitLinter(LintConfig()) gitcontext = GitContext() gitcontext.set_commit_msg(self.get_sample("commit_message/sample2")) violations = linter.lint(gitcontext) expected = [ RuleViolation("T5", "Title contains the word 'WIP' (case-insensitive)", "Just a title containing WIP", 1), RuleViolation("B6", "Body message is missing", None, 3) ] self.assertListEqual(violations, expected)
def test_set_commit_msg_full(self): gitcontext = GitContext() gitcontext.set_commit_msg(self.get_sample("commit_message/sample1")) expected_title = "Commit title containing 'WIP', as well as trailing punctuation." expected_body = [ "This line should be empty", "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.", "This line has a trailing space. ", "This line has a trailing tab.\t", "" ] expected_full = expected_title + "\n" + "\n".join(expected_body) expected_original = expected_full + "# This is a commented line\n" self.assertEqual(gitcontext.commit_msg.title, expected_title) self.assertEqual(gitcontext.commit_msg.body, expected_body) self.assertEqual(gitcontext.commit_msg.full, expected_full) self.assertEqual(gitcontext.commit_msg.original, expected_original)