test_commit.py (3734B)
1 # This Source Code Form is subject to the terms of the Mozilla Public 2 # License, v. 2.0. If a copy of the MPL was not distributed with this 3 # file, You can obtain one at http://mozilla.org/MPL/2.0/. 4 5 import re 6 from datetime import datetime 7 from pathlib import Path 8 9 import mozunit 10 11 from mozversioncontrol import get_repository_object 12 13 STEPS = { 14 "hg": [ 15 "", 16 """ 17 echo "bar" >> bar 18 echo "baz" > foo 19 """, 20 ], 21 "git": [ 22 "", 23 """ 24 echo "bar" >> bar 25 echo "baz" > foo 26 """, 27 ], 28 "jj": [ 29 """ 30 jj describe -m "Ignore file for testing" 31 echo foo > .gitignore 32 jj new 33 """, 34 """ 35 echo "bar" >> bar 36 echo "baz" > foo 37 """, 38 ], 39 } 40 41 42 def test_commit(repo): 43 vcs = get_repository_object(repo.dir) 44 assert vcs.working_directory_clean() 45 46 # Setup step for jj to allow untracked changes. 47 repo.execute_next_step() 48 49 # Modify both foo and bar 50 repo.execute_next_step() 51 if repo.vcs != "jj": 52 # jj never has a dirty working directory. 53 assert not vcs.working_directory_clean() 54 55 date_string = "2017-07-14 02:40:00 +0000" 56 57 # Commit just bar 58 vcs.commit( 59 message="Modify bar\n\nbut not baz", 60 author="Testing McTesterson <test@example.org>", 61 date=date_string, 62 paths=["bar"], 63 ) 64 65 original_date = datetime.strptime(date_string, "%Y-%m-%d %H:%M:%S %z") 66 date_from_vcs = vcs.get_last_modified_time_for_file(Path("bar")) 67 68 assert original_date == date_from_vcs 69 70 # We only committed bar, so foo is still keeping the working dir dirty. jj 71 # always treats the working directory as clean, because the top commit holds 72 # any changes in it. 73 if repo.vcs == "jj": 74 assert vcs.working_directory_clean() 75 else: 76 assert not vcs.working_directory_clean() 77 78 if repo.vcs == "git": 79 log_cmd = ["log", "-1", "--format=%an,%ae,%aD,%B"] 80 patch_cmd = ["log", "-1", "-p"] 81 elif repo.vcs == "hg": 82 log_cmd = [ 83 "log", 84 "-l", 85 "1", 86 "-T", 87 "{person(author)},{email(author)},{date|rfc822date},{desc}", 88 ] 89 patch_cmd = ["log", "-l", "1", "-p"] 90 elif repo.vcs == "jj": 91 log_cmd = [ 92 "log", 93 "-n1", 94 "--no-graph", 95 "-r@-", 96 "-T", 97 'separate(",", author.name(), author.email(), commit_timestamp(self).format("%a, %d %b %Y %H:%M:%S %z"), description)', 98 ] 99 patch_cmd = ["show", "@-", "--git"] 100 101 # Verify commit metadata (we rstrip to normalize trivial differences) 102 log = vcs._run(*log_cmd).rstrip() 103 assert log == ( 104 "Testing McTesterson,test@example.org,Fri, 14 " 105 "Jul 2017 02:40:00 +0000,Modify bar\n\nbut not baz" 106 ) 107 108 # Verify only the intended file was added to the commit 109 patch = vcs._run(*patch_cmd) 110 111 def find_diff_marker(patch: str, filename: str): 112 patterns = [ 113 rf"^diff --git a/{re.escape(filename)} b/{re.escape(filename)}$", 114 rf"^Modified regular file {re.escape(filename)}:$", 115 ] 116 117 matches = [ 118 line 119 for line in patch.splitlines() 120 if any(re.fullmatch(p, line) for p in patterns) 121 ] 122 123 assert matches, f"No diff marker found for '{filename}'" 124 assert len(matches) == 1, ( 125 f"More than one diff marker for '{filename}': {matches}" 126 ) 127 128 return matches[0] 129 130 marker = find_diff_marker(patch, "bar") 131 132 assert marker in [ 133 "diff --git a/bar b/bar", 134 "Modified regular file bar:", 135 ] 136 137 138 if __name__ == "__main__": 139 mozunit.main()