Overhaul the spec tests to work in rspec2.
[puppet_vcsrepo.git] / spec / unit / puppet / provider / vcsrepo / git_spec.rb
1 require 'spec_helper'
2
3 describe Puppet::Type.type(:vcsrepo).provider(:git_provider) do
4
5   let(:resource) { Puppet::Type.type(:vcsrepo).new({
6     :name     => 'test',
7     :ensure   => :present,
8     :provider => :git,
9     :revision => '2634',
10     :source   => 'git@repo',
11     :path     => '/tmp/test',
12   })}
13
14   let(:provider) { resource.provider }
15
16   before :each do
17     Puppet::Util.stubs(:which).with('git').returns('/usr/bin/git')
18   end
19
20   context 'creating' do
21     context "with a revision that is a remote branch" do
22       it "should execute 'git clone' and 'git checkout -b'" do
23         resource[:revision] = 'only/remote'
24         Dir.expects(:chdir).with('/').at_least_once.yields
25         Dir.expects(:chdir).with('/tmp/test').at_least_once.yields
26         provider.expects(:git).with('clone', resource.value(:source), resource.value(:path))
27         provider.expects(:update_submodules)
28         provider.expects(:git).with('branch', '-a').returns(resource.value(:revision))
29         provider.expects(:git).with('checkout', '--force', resource.value(:revision))
30         provider.create
31       end
32     end
33
34     context "with a revision that is not a remote branch" do
35       it "should execute 'git clone' and 'git reset --hard'" do
36         resource[:revision] = 'a-commit-or-tag'
37         Dir.expects(:chdir).with('/').at_least_once.yields
38         Dir.expects(:chdir).with('/tmp/test').at_least_once.yields
39         provider.expects(:git).with('clone', resource.value(:source), resource.value(:path))
40         provider.expects(:update_submodules)
41         provider.expects(:git).with('branch', '-a').returns(resource.value(:revision))
42         provider.expects(:git).with('checkout', '--force', resource.value(:revision))
43         provider.create
44       end
45
46       it "should execute 'git clone' and submodule commands" do
47         resource.delete(:revision)
48         provider.expects(:git).with('clone', resource.value(:source), resource.value(:path))
49         provider.expects(:update_submodules)
50         provider.create
51       end
52     end
53
54     context "with an ensure of bare" do
55       context "with revision" do
56         it "should just execute 'git clone --bare'" do
57           resource[:ensure] = :bare
58           provider.expects(:git).with('clone', '--bare', resource.value(:source), resource.value(:path))
59           provider.create
60         end
61       end
62       context "without revision" do
63         it "should just execute 'git clone --bare'" do
64           resource[:ensure] = :bare
65           resource.delete(:revision)
66           provider.expects(:git).with('clone', '--bare', resource.value(:source), resource.value(:path))
67           provider.create
68         end
69       end
70     end
71
72     context "when a source is not given" do
73       context "when the path does not exist" do
74         it "should execute 'git init'" do
75           resource[:ensure] = :present
76           resource.delete(:source)
77           expects_mkdir
78           expects_chdir
79           expects_directory?(false)
80
81           provider.expects(:bare_exists?).returns(false)
82           provider.expects(:git).with('init')
83           provider.create
84         end
85       end
86
87       context "when the path is a bare repository" do
88         it "should convert it to a working copy" do
89           resource[:ensure] = :present
90           resource.delete(:source)
91           provider.expects(:bare_exists?).returns(true)
92           provider.expects(:convert_bare_to_working_copy)
93           provider.create
94         end
95       end
96
97       context "when the path is not empty and not a repository" do
98         it "should raise an exception" do
99           provider.expects(:path_exists?).returns(true)
100           provider.expects(:path_empty?).returns(false)
101           proc { provider.create }.should raise_error(Puppet::Error)
102         end
103       end
104     end
105
106     context "when the path does not exist" do
107       it "should execute 'git init --bare'" do
108         resource[:ensure] = :bare
109         resource.delete(:source)
110         expects_chdir
111         expects_mkdir
112         expects_directory?(false)
113         provider.expects(:working_copy_exists?).returns(false)
114         provider.expects(:git).with('init', '--bare')
115         provider.create
116       end
117     end
118
119     context "when the path is a working copy repository" do
120       it "should convert it to a bare repository" do
121         resource[:ensure] = :bare
122         resource.delete(:source)
123         provider.expects(:working_copy_exists?).returns(true)
124         provider.expects(:convert_working_copy_to_bare)
125         provider.create
126       end
127     end
128
129     context "when the path is not empty and not a repository" do
130       it "should raise an exception" do
131         expects_directory?(true)
132         provider.expects(:path_empty?).returns(false)
133         proc { provider.create }.should raise_error(Puppet::Error)
134       end
135     end
136   end
137
138
139   context 'destroying' do
140     it "it should remove the directory" do
141       #expects_rm_rf
142       provider.destroy
143     end
144   end
145
146   context "checking the revision property" do
147     before do
148       expects_chdir('/tmp/test')
149       resource[:revision] = 'currentsha'
150       resource.delete(:source)
151       provider.expects(:git).with('rev-parse', 'HEAD').returns('currentsha')
152     end
153
154     context "when its SHA is not different than the current SHA" do
155       it "should return the ref" do
156         provider.expects(:git).with('config', 'remote.origin.url').returns('')
157         provider.expects(:git).with('fetch', 'origin') # FIXME
158         provider.expects(:git).with('fetch', '--tags', 'origin')
159         provider.expects(:git).with('rev-parse', '--revs-only', resource.value(:revision)).returns('currentsha')
160         provider.expects(:git).with('tag', '-l').returns("Hello")
161         provider.revision.should == resource.value(:revision)
162       end
163     end
164
165     context "when its SHA is different than the current SHA" do
166       it "should return the current SHA" do
167         provider.expects(:git).with('config', 'remote.origin.url').returns('')
168         provider.expects(:git).with('fetch', 'origin') # FIXME
169         provider.expects(:git).with('fetch', '--tags', 'origin')
170         provider.expects(:git).with('rev-parse', '--revs-only', resource.value(:revision)).returns('othersha')
171         provider.expects(:git).with('tag', '-l').returns("Hello")
172         provider.revision.should == 'currentsha'
173       end
174     end
175
176     context "when its a ref to a remote head" do
177       it "should return the revision" do
178         provider.expects(:git).with('config', 'remote.origin.url').returns('')
179         provider.expects(:git).with('fetch', 'origin') # FIXME
180         provider.expects(:git).with('fetch', '--tags', 'origin')
181         provider.expects(:git).with('tag', '-l').returns("Hello")
182         provider.expects(:git).with('rev-parse', '--revs-only', resource.value(:revision)).returns('')
183         provider.expects(:git).with('ls-remote', '--heads', '--tags', 'origin', resource.value(:revision)).returns("newsha refs/heads/#{resource.value(:revision)}")
184         provider.revision.should == 'currentsha'
185       end
186     end
187
188     context "when its a ref to non existant remote head" do
189       it "should fail" do
190         provider.expects(:git).with('config', 'remote.origin.url').returns('')
191         provider.expects(:git).with('fetch', 'origin') # FIXME
192         provider.expects(:git).with('fetch', '--tags', 'origin')
193         provider.expects(:git).with('tag', '-l').returns("Hello")
194         provider.expects(:git).with('rev-parse', '--revs-only', resource.value(:revision)).returns('')
195         provider.expects(:git).with('ls-remote', '--heads', '--tags', 'origin', resource.value(:revision)).returns('')
196         expect { provider.revision }.to raise_error(Puppet::Error, /not a local or remote ref$/)
197       end
198     end
199
200     context "when the source is modified" do
201       it "should update the origin url" do
202         resource[:source] = 'git://git@foo.com/bar.git'
203         provider.expects(:git).with('config', 'remote.origin.url').returns('old')
204         provider.expects(:git).with('config', 'remote.origin.url', 'git://git@foo.com/bar.git')
205         provider.expects(:git).with('fetch', 'origin') # FIXME
206         provider.expects(:git).with('fetch', '--tags', 'origin')
207         provider.expects(:git).with('rev-parse', '--revs-only', resource.value(:revision)).returns('currentsha')
208         provider.expects(:git).with('tag', '-l').returns("Hello")
209         provider.revision.should == resource.value(:revision)
210       end
211     end
212   end
213
214   context "setting the revision property" do
215     before do
216       expects_chdir
217     end
218     context "when it's an existing local branch" do
219       it "should use 'git fetch' and 'git reset'" do
220         resource[:revision] = 'feature/foo'
221         provider.expects(:update_submodules)
222         provider.expects(:git).with('branch', '-a').returns(resource.value(:revision))
223         provider.expects(:git).with('checkout', '--force', resource.value(:revision))
224         provider.expects(:git).with('branch', '-a').returns(resource.value(:revision))
225         provider.expects(:git).with('reset', '--hard', "origin/#{resource.value(:revision)}")
226         provider.revision = resource.value(:revision)
227       end
228     end
229     context "when it's a remote branch" do
230       it "should use 'git fetch' and 'git reset'" do
231         resource[:revision] = 'only/remote'
232         provider.expects(:update_submodules)
233         provider.expects(:git).with('branch', '-a').returns(resource.value(:revision))
234         provider.expects(:git).with('checkout', '--force', resource.value(:revision))
235         provider.expects(:git).with('branch', '-a').returns(resource.value(:revision))
236         provider.expects(:git).with('reset', '--hard', "origin/#{resource.value(:revision)}")
237         provider.revision = resource.value(:revision)
238       end
239     end
240     context "when it's a commit or tag" do
241       it "should use 'git fetch' and 'git reset'" do
242         resource[:revision] = 'a-commit-or-tag'
243         provider.expects(:git).with('branch', '-a').returns(fixture(:git_branch_a))
244         provider.expects(:git).with('checkout', '--force', resource.value(:revision))
245         provider.expects(:git).with('branch', '-a').returns(fixture(:git_branch_a))
246         provider.expects(:git).with('branch', '-a').returns(fixture(:git_branch_a))
247         provider.expects(:git).with('submodule', 'update', '--init', '--recursive')
248         provider.revision = resource.value(:revision)
249       end
250     end
251   end
252
253   context "updating references" do
254     it "should use 'git fetch --tags'" do
255       resource.delete(:source)
256       expects_chdir
257       provider.expects(:git).with('config', 'remote.origin.url').returns('')
258       provider.expects(:git).with('fetch', 'origin')
259       provider.expects(:git).with('fetch', '--tags', 'origin')
260       provider.update_references
261     end
262   end
263
264   context "checking if revision" do
265     before do
266       expects_chdir
267       provider.expects(:git).with('branch', '-a').returns(fixture(:git_branch_a))
268     end
269     context "is a local branch" do
270       context "when it's listed in 'git branch -a'" do
271         it "should return true" do
272           resource[:revision] = 'feature/foo'
273           provider.should be_local_branch_revision
274         end
275       end
276       context "when it's not listed in 'git branch -a'" do
277         it "should return false" do
278           resource[:revision] = 'feature/notexist'
279           provider.should_not be_local_branch_revision
280         end
281       end
282     end
283     context "is a remote branch" do
284       context "when it's listed in 'git branch -a' with an 'origin/' prefix" do
285         it "should return true" do
286           resource[:revision] = 'only/remote'
287           provider.should be_remote_branch_revision
288         end
289       end
290       context "when it's not listed in 'git branch -a' with an 'origin/' prefix" do
291         it "should return false" do
292           resource[:revision] = 'only/local'
293           provider.should_not be_remote_branch_revision
294         end
295       end
296     end
297   end
298
299 end