dotty 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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
+