dotty 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/spec/app_spec.rb ADDED
@@ -0,0 +1,328 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+
3
+
4
+ describe Dotty::App do
5
+ describe "#add" do
6
+ it "should invoke Dotty::Repository.add" do
7
+ name = 'repo'
8
+ url = 'url'
9
+ Dotty::Repository.stub!(:add_existing_repository)
10
+ Dotty::Repository.should_receive(:add_existing_repository).with(name, url)
11
+ subject.add(name, url)
12
+ end
13
+ end
14
+
15
+ describe "#create" do
16
+ it "should invoke Dotty::Repository.create" do
17
+ Dotty::Repository.stub!(:create_repository).and_return(Dotty::Repository.new('name', 'url'))
18
+ Dotty::Repository.should_receive(:create_repository).with('name', 'url')
19
+ suppress_output do
20
+ subject.invoke :create, %w(name url)
21
+ end
22
+ end
23
+
24
+ it "should copy the README.md to the repo dir" do
25
+ suppress_output do
26
+ subject.invoke :create, %w(name url)
27
+ end
28
+ File.file?(File.join Dotty::Repository.list.first.local_path, 'README.md').should be_true
29
+ end
30
+
31
+ it "should create a dotfiles/ directory" do
32
+ suppress_output do
33
+ subject.invoke :create, %w(name url)
34
+ end
35
+ File.directory?(File.join Dotty::Repository.list.first.local_path, 'dotfiles').should be_true
36
+ end
37
+
38
+ end
39
+
40
+ describe "#remove" do
41
+ it "should invoke #destroy on the Repository instance with the given name" do
42
+ repo = Dotty::Repository.new('name', 'url')
43
+ repo.stub!(:destroy)
44
+ repo.should_receive(:destroy)
45
+ Dotty::Repository.repositories = [repo]
46
+ suppress_output do
47
+ subject.invoke :remove, %w(name)
48
+ end
49
+ end
50
+ end
51
+
52
+ describe "#update" do
53
+ include_context "two in memory repositories"
54
+
55
+ before do
56
+ subject.send(:actions).stub!(:update)
57
+ end
58
+
59
+ it "should invoke update action with the specified repo" do
60
+ subject.send(:actions).should_receive(:update).with(@repo1).once
61
+ suppress_output do
62
+ subject.update 'repo1name'
63
+ end
64
+ end
65
+
66
+ it "should invoke update action for all repos if no repo is specified" do
67
+ subject.send(:actions).should_receive(:update).with(@repo1).once
68
+ subject.send(:actions).should_receive(:update).with(@repo2).once
69
+ suppress_output do
70
+ subject.update
71
+ end
72
+ end
73
+ end
74
+
75
+ describe "#bootstrap" do
76
+ include_context "two in memory repositories"
77
+
78
+ before do
79
+ subject.send(:actions).stub!(:bootstrap)
80
+ end
81
+
82
+ it "should invoke bootstrap action with the specified repo" do
83
+ subject.send(:actions).should_receive(:bootstrap).with(@repo1).once
84
+ suppress_output do
85
+ subject.bootstrap 'repo1name'
86
+ end
87
+ end
88
+
89
+ it "should invoke bootstrap action for all repos if no repo is specified" do
90
+ subject.send(:actions).should_receive(:bootstrap).with(@repo1).once
91
+ subject.send(:actions).should_receive(:bootstrap).with(@repo2).once
92
+ suppress_output do
93
+ subject.bootstrap
94
+ end
95
+ end
96
+ end
97
+
98
+ describe "#implode" do
99
+ include_context "two in memory repositories"
100
+
101
+ before do
102
+ subject.send(:actions).stub!(:implode)
103
+ end
104
+
105
+ it "should invoke implode action with the specified repo" do
106
+ subject.send(:actions).should_receive(:implode).with(@repo1).once
107
+ suppress_output do
108
+ subject.implode 'repo1name'
109
+ end
110
+ end
111
+
112
+ it "should invoke implode action for all repos if no repo is specified" do
113
+ subject.send(:actions).should_receive(:implode).with(@repo1).once
114
+ subject.send(:actions).should_receive(:implode).with(@repo2).once
115
+ suppress_output do
116
+ subject.implode
117
+ end
118
+ end
119
+ end
120
+
121
+ describe "#update_submodules" do
122
+ # TODO add these when I figure out how to make multiple should_receive + thor work
123
+ end
124
+
125
+ describe "#execute" do
126
+ include_context "two in memory repositories"
127
+
128
+ it "should run the given command inside the the specified repository's directory" do
129
+ subject.stub(:run) do
130
+ subject.destination_root.should == @repo1.local_path
131
+ end
132
+ subject.should_receive(:run).once.with('ls')
133
+ suppress_output do
134
+ subject.execute @repo1.name, 'ls'
135
+ end
136
+ end
137
+
138
+ it "should run the given command in each repositories directroy if no repository is specified" do
139
+ paths = [@repo1.local_path, @repo2.local_path]
140
+ i = 0
141
+ subject.stub(:run) do
142
+ subject.destination_root.should == paths[i]
143
+ i += 1
144
+ end
145
+ subject.should_receive(:run).twice.with('ls')
146
+ suppress_output do
147
+ subject.execute 'ls'
148
+ end
149
+ end
150
+ end
151
+
152
+ describe "#import_repos" do
153
+ it "should invoke Dotty::Repository.import" do
154
+ Dotty::Repository.stub!(:import)
155
+ Dotty::Repository.should_receive(:import).with('location')
156
+ suppress_output do
157
+ subject.import_repos('location')
158
+ end
159
+ end
160
+ end
161
+
162
+ describe "#find_repo!" do
163
+ include_context "two in memory repositories"
164
+
165
+ it "should return the correct repo instance if it exists" do
166
+ subject.send(:find_repo!, 'repo1name').should == @repo1
167
+ end
168
+
169
+ it "should raise an exception when the given repository does not exist" do
170
+ expect {
171
+ subject.send(:find_repo!, 'nonexistant')
172
+ }.to raise_error Dotty::RepositoryNotFoundError, "The specified repository does not exist"
173
+ end
174
+ end
175
+
176
+ describe "#actions" do
177
+ it "should return an instance of Dotty::RepositoryActions" do
178
+ subject.send(:actions).should be_kind_of Dotty::RepositoryActions
179
+ end
180
+
181
+ it "should cache it" do
182
+ app = subject
183
+ app.send(:actions).should == app.send(:actions)
184
+ end
185
+ end
186
+
187
+ describe "#for_specified_or_all_repos" do
188
+ include_context "two in memory repositories"
189
+
190
+ it "should yield the two registered repos" do
191
+ subject.should_receive(:for_specified_or_all_repos).and_yield(Dotty::Repository.list)
192
+ subject.send(:for_specified_or_all_repos) { |r| }
193
+ end
194
+ end
195
+
196
+ describe "#create_profile" do
197
+ it "should invoke Profile.create" do
198
+ Dotty::Profile.stub(:create)
199
+ Dotty::Profile.should_receive(:create).once.with('name')
200
+ suppress_output do
201
+ subject.create_profile 'name'
202
+ end
203
+ end
204
+ end
205
+
206
+ describe "#remove_profile" do
207
+ it "should invoke Profile.remove" do
208
+ Dotty::Profile.stub(:remove)
209
+ Dotty::Profile.should_receive(:remove).once.with('my_repo')
210
+ suppress_output do
211
+ subject.remove_profile 'my_repo'
212
+ end
213
+ end
214
+ end
215
+
216
+ describe "#profiles" do
217
+ include_context "profile data"
218
+ it "should list existing proiles" do
219
+ output = capture :stdout do
220
+ subject.invoke :profiles
221
+ end
222
+ output.should == "\e[34mDOTTY PROFILES\n\e[0m\n \e[32m* my_profile\e[0m\n other_profile\n"
223
+ end
224
+ end
225
+
226
+ describe "#profile" do
227
+ include_context "profile data"
228
+
229
+ it "should print the current profile if no profile name is given" do
230
+ output = capture :stdout do
231
+ subject.invoke :profile
232
+ end
233
+ output.gsub!(/\e\[\d+\w/, '') # Remove colors and shit
234
+ output.should == "Current dotty profile: my_profile\n"
235
+ end
236
+
237
+ it "should change Profile.current_profile when given a valid profile name" do
238
+ suppress_output do
239
+ subject.invoke :profile, %w(other_profile)
240
+ end
241
+ Dotty::Profile.current_profile.should == 'other_profile'
242
+ end
243
+
244
+ it "should invoke Profile.write_yaml" do
245
+ Dotty::Profile.should_receive(:write_yaml)
246
+ suppress_output do
247
+ subject.invoke :profile, %w(other_profile)
248
+ end
249
+ end
250
+
251
+ it "should call Profile.find!" do
252
+ Dotty::Profile.should_receive(:find!).with('other_profile')
253
+ suppress_output do
254
+ subject.invoke :profile, %w(other_profile)
255
+ end
256
+ end
257
+
258
+ it "should invoke implode then bootstrap" do
259
+ subject.should_receive(:implode).once.ordered
260
+ subject.should_receive(:bootstrap).once.ordered
261
+ suppress_output do
262
+ subject.profile 'other_profile'
263
+ end
264
+ end
265
+
266
+ end
267
+
268
+ describe "#list" do
269
+
270
+ context "with some repositories" do
271
+ include_context "profile data"
272
+
273
+ before do
274
+ Dotty::Repository.list.each do |repo|
275
+ %x(git init #{repo.local_path})
276
+ end
277
+ end
278
+
279
+ it "should display a list of repositories" do
280
+ output = capture(:stdout) do
281
+ subject.list
282
+ end
283
+ output.gsub!(/\e\[\d+\w/, '') # Remove colors and shit
284
+ output.should == <<-EXPECTED_OUTPUT
285
+ Installed dotty repositories for profile 'my_profile'
286
+
287
+ my_repo git://github.com/me/my_repo
288
+ other_repo git://github.com/me/other_repo
289
+
290
+ EXPECTED_OUTPUT
291
+ end
292
+
293
+ it "should display git changes" do
294
+ %x(cd #{Dotty::Repository.list.first.local_path} && touch newfile)
295
+ Dotty::Repository.list.first.stub!(:unpushed_changes?).and_return(true)
296
+ output = capture(:stdout) do
297
+ subject.list
298
+ end
299
+ output.gsub!(/\e\[\d+\w/, '') # Remove colors and shit
300
+ output.should == <<-EXPECTED_OUTPUT
301
+ Installed dotty repositories for profile 'my_profile'
302
+
303
+ my_repo git://github.com/me/my_repo [1 uncomitted changes] [unpushed commits]
304
+ other_repo git://github.com/me/other_repo
305
+
306
+ EXPECTED_OUTPUT
307
+ end
308
+
309
+ end
310
+
311
+ it "should display a message if there are no repositories" do
312
+ Dotty::Repository.repositories = []
313
+ output = capture(:stdout) do
314
+ subject.list
315
+ end
316
+ output.gsub!(/\e\[\d+\w/, '') # Remove colors and shit
317
+ output.should == <<-EXPECTED_OUTPUT
318
+ Installed dotty repositories for profile 'default'
319
+
320
+ No repositories here. Use 'create', 'add' or 'import_repos' to get going.
321
+
322
+ EXPECTED_OUTPUT
323
+
324
+ end
325
+
326
+ end
327
+
328
+ end
@@ -0,0 +1,188 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+
3
+ describe Dotty::Profile do
4
+
5
+ describe ".create" do
6
+ it "should add the profile to profile_data" do
7
+ Dotty::Profile.create 'name'
8
+ Dotty::Profile.profile_data['profiles'].should have_key 'name'
9
+ end
10
+
11
+ it "should invoke .write_yaml" do
12
+ Dotty::Profile.stub!(:write_yaml)
13
+ Dotty::Profile.should_receive(:write_yaml)
14
+ Dotty::Profile.create 'name'
15
+ end
16
+ end
17
+
18
+ describe ".remove" do
19
+ include_context "profile data"
20
+
21
+ it "should remove the profile from profile_data" do
22
+ Dotty::Profile.remove 'my_profile'
23
+ Dotty::Profile.profile_data['profiles'].should_not have_key 'my_profile'
24
+ end
25
+
26
+ it "should invoke .write_yaml" do
27
+ Dotty::Profile.should_receive(:write_yaml)
28
+ Dotty::Profile.remove 'my_profile'
29
+ end
30
+
31
+ it "should set current_profile to the first existing profile" do
32
+ Dotty::Profile.current_profile = 'my_profile'
33
+ Dotty::Profile.remove 'my_profile'
34
+ Dotty::Profile.current_profile.should == 'other_profile'
35
+ end
36
+ end
37
+
38
+ describe ".profile_data" do
39
+ it "should return data by calling .read_yaml the first time" do
40
+ Dotty::Profile.should_receive(:read_yaml).once.and_return(:test)
41
+ Dotty::Profile.profile_data.should == :test
42
+ end
43
+
44
+ it "should use cached data when available" do
45
+ Dotty::Profile.stub!(:read_yaml).and_return(:test)
46
+ Dotty::Profile.profile_data # cache data
47
+ Dotty::Profile.should_not_receive(:read_yaml)
48
+ Dotty::Profile.profile_data.should == :test
49
+ end
50
+ end
51
+
52
+ describe ".current_profile" do
53
+ it "should return 'default' if no data is set and there are no profiles" do
54
+ Dotty::Profile.instance_variable_set '@profile_data', {}
55
+ Dotty::Profile.current_profile.should == 'default'
56
+ end
57
+
58
+ it "should use the value from @profile_data if its set and @current_profile isnt" do
59
+ Dotty::Profile.instance_variable_set('@profile_data', { 'current_profile' => 'myprofile' })
60
+ Dotty::Profile.current_profile.should == 'myprofile'
61
+ end
62
+
63
+ it "should use @current_profile when its set" do
64
+ Dotty::Profile.instance_variable_set('@profile_data', { 'current_profile' => 'myprofile' })
65
+ Dotty::Profile.instance_variable_set('@current_profile', 'banana')
66
+ Dotty::Profile.current_profile.should == 'banana'
67
+ end
68
+
69
+ context "with profiles" do
70
+ include_context "profile data"
71
+ it "should use the first repo when profile_data does not have a current_profile set" do
72
+ Dotty::Profile.profile_data['current_profile'] = nil
73
+ Dotty::Profile.current_profile.should == 'my_profile'
74
+ end
75
+ end
76
+ end
77
+
78
+ describe ".current_profile_data" do
79
+ include_context "profile data"
80
+
81
+ it "should return the profile's section in profile_data" do
82
+ Dotty::Profile.stub!(:profile_data).and_return(@profile_data)
83
+ Dotty::Profile.current_profile_data.should == {
84
+ 'repositories' => {
85
+ 'my_repo' => {
86
+ 'url' => 'git://github.com/me/my_repo'
87
+ },
88
+ 'other_repo' => {
89
+ 'url' => 'git://github.com/me/other_repo'
90
+ }
91
+ }
92
+ }
93
+ end
94
+
95
+ it "should return empty hash when there is no profile data" do
96
+ FileUtils.rm Dotty::Profile::YAML_PATH
97
+ Dotty::Profile.current_profile_data.should == {}
98
+ end
99
+ end
100
+
101
+ describe ".read_yaml" do
102
+ include_context "profile data"
103
+
104
+ it "should return the data structure defined in the yaml" do
105
+ Dotty::Profile.read_yaml.should == @profile_data
106
+ end
107
+
108
+ it "should return false if there is no ~/.dotty/.profiles.yml" do
109
+ FileUtils.rm Dotty::Profile::YAML_PATH
110
+ Dotty::Profile.read_yaml.should == false
111
+ end
112
+
113
+ end
114
+
115
+ describe ".write_yaml" do
116
+ include_context "profile data"
117
+
118
+ it "should create the file when it doesnt exist" do
119
+ FileUtils.rm Dotty::Profile::YAML_PATH
120
+ Dotty::Profile.write_yaml
121
+ File.exist?(Dotty::Profile::YAML_PATH).should be_true
122
+ end
123
+
124
+ it "should write data so that .read_yaml returns identical data" do
125
+ Dotty::Profile.instance_variable_set '@profile_data', @profile_data
126
+ Dotty::Profile.write_yaml
127
+ Dotty::Profile.read_yaml.should == @profile_data
128
+ end
129
+
130
+ it "should write updated repository data" do
131
+ repo = Dotty::Repository.list.first
132
+ repo.name = 'newreponame'
133
+ Dotty::Profile.write_yaml
134
+ Dotty::Profile.read_yaml.should == {
135
+ "current_profile" => "my_profile",
136
+ "profiles" => {
137
+ "my_profile" => {
138
+ "repositories" =>{
139
+ "newreponame" => { "url"=>"git://github.com/me/my_repo" },
140
+ "other_repo" => { "url"=>"git://github.com/me/other_repo" }
141
+ }
142
+ },
143
+ "other_profile" => {
144
+ "repositories" => {
145
+ "my_repo" => { "url"=>"git://github.com/me/my_repo" },
146
+ "other_repo" => { "url"=>"git://github.com/me/other_repo"}
147
+ }
148
+ }
149
+ }
150
+ }
151
+ end
152
+ end
153
+
154
+ describe ".find" do
155
+ include_context "profile data"
156
+ it "should raise an error if the given profile name does not exist" do
157
+ expect {
158
+ Dotty::Profile.find! 'non_existant_profile'
159
+ }.to raise_error(Dotty::Error, "Profile 'non_existant_profile' does not exist")
160
+ end
161
+
162
+ it "should return the profile data if the profile exists" do
163
+ Dotty::Profile.find!('other_profile').should == {
164
+ 'repositories' => {
165
+ 'my_repo' => { 'url' => 'git://github.com/me/my_repo' },
166
+ 'other_repo' => { 'url' => 'git://github.com/me/other_repo' }
167
+ }
168
+ }
169
+ end
170
+ end
171
+
172
+ #describe "#new" do
173
+ #it "should return an instance of Dotty::Profile" do
174
+ #profile = Dotty::Profile.new('name')
175
+ #profile.should be_instance_of Dotty::Profile
176
+ #end
177
+ #end
178
+
179
+ #describe "#name" do
180
+ #it "should return the given name" do
181
+ #profile = Dotty::Profile.new('name')
182
+ #profile.name.should == 'name'
183
+ #end
184
+ #end
185
+
186
+ end
187
+
188
+