fetch: add support for the traditional FETCH_HEAD behavior
[git-cola.git] / test / main_model_test.py
blob624094cac59b5d61a192be9f84a373bb6c093785
1 import os
3 import pytest
5 from cola import core
6 from cola import git
7 from cola.models import main
8 from cola.models.main import FETCH, FETCH_HEAD, PULL, PUSH
10 from . import helper
11 from .helper import app_context
12 from .helper import Mock
15 # prevent unused imports lint errors.
16 assert app_context is not None
18 REMOTE = 'server'
19 LOCAL_BRANCH = 'local'
20 REMOTE_BRANCH = 'remote'
23 @pytest.fixture
24 def mock_context():
25 """Return a Mock context for testing"""
26 context = Mock()
27 context.git = git.create()
28 return context
31 def test_project(app_context):
32 """Test the 'project' attribute."""
33 project = os.path.basename(core.getcwd())
34 app_context.model.set_worktree(core.getcwd())
35 assert app_context.model.project == project
38 def test_local_branches(app_context):
39 """Test the 'local_branches' attribute."""
40 helper.commit_files()
41 app_context.model.update_status()
42 assert app_context.model.local_branches == ['main']
45 def test_remote_branches(app_context):
46 """Test the 'remote_branches' attribute."""
47 app_context.model.update_status()
48 assert app_context.model.remote_branches == []
49 helper.commit_files()
50 helper.run_git('remote', 'add', 'origin', '.')
51 helper.run_git('fetch', 'origin')
52 app_context.model.update_status()
53 assert app_context.model.remote_branches == ['origin/main']
56 def test_modified(app_context):
57 """Test the 'modified' attribute."""
58 helper.write_file('A', 'change')
59 app_context.model.update_status()
60 assert app_context.model.modified == ['A']
63 def test_unstaged(app_context):
64 """Test the 'unstaged' attribute."""
65 helper.write_file('A', 'change')
66 helper.write_file('C', 'C')
67 app_context.model.update_status()
68 assert app_context.model.unstaged == ['A', 'C']
71 def test_untracked(app_context):
72 """Test the 'untracked' attribute."""
73 helper.write_file('C', 'C')
74 app_context.model.update_status()
75 assert app_context.model.untracked == ['C']
78 def test_stageable(app_context):
79 """Test the 'stageable' attribute."""
80 assert not app_context.model.is_stageable()
83 def test_remotes(app_context):
84 """Test the 'remote' attribute."""
85 helper.run_git('remote', 'add', 'origin', '.')
86 app_context.model.update_status()
87 assert app_context.model.remotes == ['origin']
90 def test_currentbranch(app_context):
91 """Test the 'currentbranch' attribute."""
92 helper.run_git('checkout', '-b', 'test')
93 app_context.model.update_status()
94 assert app_context.model.currentbranch == 'test'
97 def test_tags(app_context):
98 """Test the 'tags' attribute."""
99 helper.commit_files()
100 helper.run_git('tag', 'test')
101 app_context.model.update_status()
102 assert app_context.model.tags == ['test']
105 def test_remote_args_fetch(mock_context):
106 """FETCH swaps arguments vs. PUSH and PULL"""
107 (args, kwargs) = main.remote_args(
108 mock_context,
109 REMOTE,
110 FETCH,
111 local_branch=LOCAL_BRANCH,
112 remote_branch=REMOTE_BRANCH,
114 assert args == [REMOTE, 'remote:local']
115 assert kwargs['verbose']
116 assert 'tags' not in kwargs
117 assert 'rebase' not in kwargs
120 def test_remote_args_fetch_head(mock_context):
121 """Fetch handles the implicit FETCH_HEAD ref"""
122 # When FETCH_HEAD is used then we should not specify a tracking branch target.
123 (args, kwargs) = main.remote_args(
124 mock_context,
125 REMOTE,
126 FETCH,
127 local_branch=FETCH_HEAD,
128 remote_branch=REMOTE_BRANCH,
130 assert args == [REMOTE, 'remote']
133 def test_remote_args_fetch_tags(mock_context):
134 # Fetch tags
135 (args, kwargs) = main.remote_args(
136 mock_context,
137 REMOTE,
138 FETCH,
139 tags=True,
140 local_branch=LOCAL_BRANCH,
141 remote_branch=REMOTE_BRANCH,
143 assert args == [REMOTE, 'remote:local']
144 assert kwargs['verbose']
145 assert kwargs['tags']
146 assert 'rebase' not in kwargs
149 def test_remote_args_fetch_into_tracking_branch(mock_context):
150 (args, kwargs) = main.remote_args(
151 mock_context,
152 REMOTE,
153 FETCH,
154 remote_branch=REMOTE_BRANCH,
156 assert args == [REMOTE, 'remote:refs/remotes/server/remote']
159 def test_remote_args_pull(mock_context):
160 # Pull
161 (args, kwargs) = main.remote_args(
162 mock_context,
163 REMOTE,
164 PULL,
165 local_branch='',
166 remote_branch=REMOTE_BRANCH,
168 assert args == [REMOTE, 'remote']
169 assert kwargs['verbose']
170 assert 'rebase' not in kwargs
171 assert 'tags' not in kwargs
174 def test_remote_args_pull_rebase(mock_context):
175 # Rebasing pull
176 (args, kwargs) = main.remote_args(
177 mock_context,
178 REMOTE,
179 PULL,
180 rebase=True,
181 local_branch='',
182 remote_branch=REMOTE_BRANCH,
184 assert args == [REMOTE, 'remote']
185 assert kwargs['verbose']
186 assert kwargs['rebase']
187 assert 'tags' not in kwargs
190 def test_remote_args_push(mock_context):
191 """PUSH swaps local and remote branches"""
192 (args, kwargs) = main.remote_args(
193 mock_context,
194 REMOTE,
195 PUSH,
196 local_branch=LOCAL_BRANCH,
197 remote_branch=REMOTE_BRANCH,
199 assert args == [REMOTE, 'local:remote']
200 assert kwargs['verbose']
201 assert 'tags' not in kwargs
202 assert 'rebase' not in kwargs
205 def test_remote_args_push_tags(mock_context):
206 """Pushing tags uses --tags"""
207 (args, kwargs) = main.remote_args(
208 mock_context,
209 REMOTE,
210 PUSH,
211 tags=True,
212 local_branch=LOCAL_BRANCH,
213 remote_branch=REMOTE_BRANCH,
215 assert args == [REMOTE, 'local:remote']
216 assert kwargs['verbose']
217 assert kwargs['tags']
218 assert 'rebase' not in kwargs
221 def test_remote_args_push_same_remote_and_local(mock_context):
222 (args, kwargs) = main.remote_args(
223 mock_context,
224 REMOTE,
225 PUSH,
226 tags=True,
227 local_branch=LOCAL_BRANCH,
228 remote_branch=LOCAL_BRANCH,
230 assert args == [REMOTE, 'local']
231 assert kwargs['verbose']
232 assert kwargs['tags']
233 assert 'rebase' not in kwargs
236 def test_remote_args_push_set_upstream(mock_context):
237 (args, kwargs) = main.remote_args(
238 mock_context,
239 REMOTE,
240 PUSH,
241 tags=True,
242 local_branch=LOCAL_BRANCH,
243 remote_branch=LOCAL_BRANCH,
244 set_upstream=True,
246 assert args == [REMOTE, 'local']
247 assert kwargs['verbose']
248 assert kwargs['tags']
249 assert kwargs['set_upstream']
250 assert 'rebase' not in kwargs
253 def test_remote_args_rebase_only(mock_context):
254 (_, kwargs) = main.remote_args(
255 mock_context, REMOTE, PULL, rebase=True, ff_only=True
257 assert kwargs['rebase']
258 assert 'ff_only' not in kwargs
261 def test_run_remote_action(mock_context):
262 """Test running a remote action"""
263 (args, kwargs) = main.run_remote_action(
264 mock_context,
265 lambda *args, **kwargs: (args, kwargs),
266 REMOTE,
267 FETCH,
268 local_branch=LOCAL_BRANCH,
269 remote_branch=REMOTE_BRANCH,
271 assert args == (REMOTE, 'remote:local')
272 assert kwargs['verbose']
273 assert 'tags' not in kwargs
274 assert 'rebase' not in kwargs