99
1010from libvcs .sync .git import GitSync
1111from vcspull .cli import cli
12- from vcspull .cli .sync import EXIT_ON_ERROR_MSG
12+ from vcspull .cli .sync import EXIT_ON_ERROR_MSG , NO_REPOS_FOR_TERM_MSG
1313
14+ if t .TYPE_CHECKING :
15+ from typing_extensions import TypeAlias
16+
17+ ExpectedOutput : TypeAlias = t .Optional [t .Union [str , t .List [str ]]]
18+
19+
20+ class SyncCLINonExistentRepo (t .NamedTuple ):
21+ test_id : str
22+ sync_args : list [str ]
23+ expected_exit_code : int
24+ expected_in_output : "ExpectedOutput" = None
25+ expected_not_in_output : "ExpectedOutput" = None
26+
27+
28+ SYNC_CLI_EXISTENT_REPO_FIXTURES = [
29+ SyncCLINonExistentRepo (
30+ test_id = "exists" ,
31+ sync_args = ["my_git_project" ],
32+ expected_exit_code = 0 ,
33+ expected_in_output = "Already on 'master'" ,
34+ expected_not_in_output = NO_REPOS_FOR_TERM_MSG .format (name = "my_git_repo" ),
35+ ),
36+ SyncCLINonExistentRepo (
37+ test_id = "non-existent-only" ,
38+ sync_args = ["this_isnt_in_the_config" ],
39+ expected_exit_code = 0 ,
40+ expected_in_output = NO_REPOS_FOR_TERM_MSG .format (name = "this_isnt_in_the_config" ),
41+ ),
42+ SyncCLINonExistentRepo (
43+ test_id = "non-existent-mixed" ,
44+ sync_args = ["this_isnt_in_the_config" , "my_git_project" , "another" ],
45+ expected_exit_code = 0 ,
46+ expected_in_output = [
47+ NO_REPOS_FOR_TERM_MSG .format (name = "this_isnt_in_the_config" ),
48+ NO_REPOS_FOR_TERM_MSG .format (name = "another" ),
49+ ],
50+ expected_not_in_output = NO_REPOS_FOR_TERM_MSG .format (name = "my_git_repo" ),
51+ ),
52+ ]
53+
54+
55+ @pytest .mark .parametrize (
56+ list (SyncCLINonExistentRepo ._fields ),
57+ SYNC_CLI_EXISTENT_REPO_FIXTURES ,
58+ ids = [test .test_id for test in SYNC_CLI_EXISTENT_REPO_FIXTURES ],
59+ )
60+ def test_sync_cli_repo_term_non_existent (
61+ user_path : pathlib .Path ,
62+ config_path : pathlib .Path ,
63+ tmp_path : pathlib .Path ,
64+ git_repo : GitSync ,
65+ test_id : str ,
66+ sync_args : list [str ],
67+ expected_exit_code : int ,
68+ expected_in_output : "ExpectedOutput" ,
69+ expected_not_in_output : "ExpectedOutput" ,
70+ ) -> None :
71+ config = {
72+ "~/github_projects/" : {
73+ "my_git_project" : {
74+ "url" : f"git+file://{ git_repo .dir } " ,
75+ "remotes" : {"test_remote" : f"git+file://{ git_repo .dir } " },
76+ },
77+ }
78+ }
79+ yaml_config = config_path / ".vcspull.yaml"
80+ yaml_config_data = yaml .dump (config , default_flow_style = False )
81+ yaml_config .write_text (yaml_config_data , encoding = "utf-8" )
1482
15- def test_sync_cli_non_existent (tmp_path : pathlib .Path ) -> None :
1683 runner = CliRunner ()
1784 with runner .isolated_filesystem (temp_dir = tmp_path ):
18- result = runner .invoke (cli , ["sync" , "hi" ])
19- assert result .exit_code == 0
20- assert "" in result .output
85+ result = runner .invoke (cli , ["sync" , * sync_args ])
86+ assert result .exit_code == expected_exit_code
87+ output = "" .join (list (result .output ))
88+
89+ if expected_in_output is not None :
90+ if isinstance (expected_in_output , str ):
91+ expected_in_output = [expected_in_output ]
92+ for needle in expected_in_output :
93+ assert needle in output
94+
95+ if expected_not_in_output is not None :
96+ if isinstance (expected_not_in_output , str ):
97+ expected_not_in_output = [expected_not_in_output ]
98+ for needle in expected_not_in_output :
99+ assert needle not in output
21100
22101
23102def test_sync (
@@ -51,12 +130,6 @@ def test_sync(
51130 assert "my_git_repo" in output
52131
53132
54- if t .TYPE_CHECKING :
55- from typing_extensions import TypeAlias
56-
57- ExpectedOutput : TypeAlias = t .Optional [t .Union [str , t .List [str ]]]
58-
59-
60133class SyncBrokenFixture (t .NamedTuple ):
61134 test_id : str
62135 sync_args : list [str ]
@@ -86,25 +159,25 @@ class SyncBrokenFixture(t.NamedTuple):
86159 ),
87160 SyncBrokenFixture (
88161 test_id = "normal-first-broken" ,
89- sync_args = ["non_existent_repo " , "my_git_repo" ],
162+ sync_args = ["my_git_repo_not_found " , "my_git_repo" ],
90163 expected_exit_code = 0 ,
91164 expected_not_in_output = EXIT_ON_ERROR_MSG ,
92165 ),
93166 SyncBrokenFixture (
94167 test_id = "normal-last-broken" ,
95- sync_args = ["my_git_repo" , "non_existent_repo " ],
168+ sync_args = ["my_git_repo" , "my_git_repo_not_found " ],
96169 expected_exit_code = 0 ,
97170 expected_not_in_output = EXIT_ON_ERROR_MSG ,
98171 ),
99172 SyncBrokenFixture (
100173 test_id = "exit-on-error--exit-on-error-first-broken" ,
101- sync_args = ["non_existent_repo " , "my_git_repo" , "--exit-on-error" ],
174+ sync_args = ["my_git_repo_not_found " , "my_git_repo" , "--exit-on-error" ],
102175 expected_exit_code = 1 ,
103176 expected_in_output = EXIT_ON_ERROR_MSG ,
104177 ),
105178 SyncBrokenFixture (
106179 test_id = "exit-on-error--x-first-broken" ,
107- sync_args = ["non_existent_repo " , "my_git_repo" , "-x" ],
180+ sync_args = ["my_git_repo_not_found " , "my_git_repo" , "-x" ],
108181 expected_exit_code = 1 ,
109182 expected_in_output = EXIT_ON_ERROR_MSG ,
110183 expected_not_in_output = "master" ,
@@ -114,13 +187,13 @@ class SyncBrokenFixture(t.NamedTuple):
114187 #
115188 SyncBrokenFixture (
116189 test_id = "exit-on-error--exit-on-error-last-broken" ,
117- sync_args = ["my_git_repo" , "non_existent_repo " , "-x" ],
190+ sync_args = ["my_git_repo" , "my_git_repo_not_found " , "-x" ],
118191 expected_exit_code = 1 ,
119192 expected_in_output = [EXIT_ON_ERROR_MSG , "Already on 'master'" ],
120193 ),
121194 SyncBrokenFixture (
122195 test_id = "exit-on-error--x-last-item" ,
123- sync_args = ["my_git_repo" , "non_existent_repo " , "--exit-on-error" ],
196+ sync_args = ["my_git_repo" , "my_git_repo_not_found " , "--exit-on-error" ],
124197 expected_exit_code = 1 ,
125198 expected_in_output = [EXIT_ON_ERROR_MSG , "Already on 'master'" ],
126199 ),
@@ -157,7 +230,7 @@ def test_sync_broken(
157230 "url" : f"git+file://{ git_repo .dir } " ,
158231 "remotes" : {"test_remote" : f"git+file://{ git_repo .dir } " },
159232 },
160- "non_existent_repo " : {
233+ "my_git_repo_not_found " : {
161234 "url" : "git+file:///dev/null" ,
162235 },
163236 }
0 commit comments