ruby_clone 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,222 @@
1
+ require 'spec_helper'
2
+
3
+ module RubyClone
4
+
5
+ describe FromFolder do
6
+
7
+ describe "#ssh?" do
8
+
9
+ it "should return true if it has the option ssh set up" do
10
+ from_folder = FromFolder.new('/from_folder', ssh: 'user@server')
11
+ from_folder.ssh?.should be_true
12
+ end
13
+
14
+ it "should return false if it doesn't have the option ssh set up" do
15
+ from_folder = FromFolder.new('/from_folder')
16
+ from_folder.ssh?.should be_false
17
+ end
18
+ end
19
+
20
+ describe "#to_command" do
21
+
22
+ it "should as default return empty string" do
23
+ from_folder = FromFolder.new('/from_folder')
24
+ from_folder.to_command.should be_empty
25
+ end
26
+
27
+ it "should return '--exclude=/exclude_path1 --exclude=/exclude_path2' when exclude_paths are added" do
28
+ from_folder = FromFolder.new('/from_folder')
29
+ from_folder.exclude_pattern = '/exclude_pattern1'
30
+ from_folder.exclude_pattern = '/exclude_pattern2'
31
+
32
+ from_folder.to_command.should == '--exclude=/exclude_pattern1 --exclude=/exclude_pattern2'
33
+ end
34
+
35
+ it "should return '--include=/include_path1 --include=/include_path2' when include_paths are added" do
36
+ from_folder = FromFolder.new('/from_folder')
37
+ from_folder.include_pattern = '/include_pattern1'
38
+ from_folder.include_pattern = '/include_pattern2'
39
+
40
+ from_folder.to_command.should == '--include=/include_pattern1 --include=/include_pattern2'
41
+ end
42
+
43
+ it "should have --include before --exclude" do
44
+ from_folder = FromFolder.new('/from_folder')
45
+ from_folder.include_pattern = '/include_pattern'
46
+ from_folder.exclude_pattern = '/exclude_pattern'
47
+
48
+ from_folder.to_command.should == '--include=/include_pattern --exclude=/exclude_pattern'
49
+ end
50
+ end
51
+
52
+ describe "#to_s" do
53
+
54
+ it "should return just the path name if ssh is not set up" do
55
+ from_folder = FromFolder.new('/from_folder')
56
+ from_folder.to_s.should == '/from_folder'
57
+ end
58
+
59
+ it "should return just the path name if ssh is set up" do
60
+ from_folder = FromFolder.new('/from_folder', ssh: 'user@server')
61
+ from_folder.to_s.should == 'user@server:/from_folder'
62
+ end
63
+ end
64
+ end
65
+
66
+ describe ToFolder do
67
+
68
+ describe "#delete_files" do
69
+
70
+ it "should call BackupUtils#delete_files if @backup exist" do
71
+ backup = double(:backup_backup)
72
+ backup.should_receive(:delete_files)
73
+
74
+ to_folder = ToFolder.new('/to_folder/')
75
+ to_folder.instance_eval { @backup = backup }
76
+
77
+ to_folder.delete_files
78
+ end
79
+
80
+ it "should not call BackupUtils#delete_files if @backup doesn't exist" do
81
+ backup = double(:backup_backup)
82
+ backup.should_not_receive(:delete_files)
83
+
84
+ to_folder = ToFolder.new('/to_folder/')
85
+ to_folder.delete_files
86
+ end
87
+
88
+ end
89
+
90
+ describe "#ssh?" do
91
+
92
+ it "should return true if it has the option ssh set up" do
93
+ to_folder = ToFolder.new('/to_folder', ssh: 'user@server')
94
+ to_folder.ssh?.should be_true
95
+ end
96
+
97
+ it "should return false if it doesn't have the option ssh set up" do
98
+ to_folder = ToFolder.new('/to_folder')
99
+ to_folder.ssh?.should be_false
100
+ end
101
+ end
102
+
103
+ describe "#to_command" do
104
+
105
+ it "should as default return empty string" do
106
+ to_folder = ToFolder.new('/to_folder/')
107
+ to_folder.to_command.should be_empty
108
+ end
109
+
110
+ it "should return '--delete' when the options delete is true" do
111
+ to_folder = ToFolder.new('/to_folder/', delete: true)
112
+ to_folder.to_command.should == "--delete"
113
+ end
114
+
115
+ it "should return '--delete-excluded' when the options delete_excluded is true" do
116
+ to_folder = ToFolder.new('/to_folder/', delete_excluded: true)
117
+ to_folder.to_command.should == "--delete-excluded"
118
+ end
119
+
120
+ describe "Backup association" do
121
+
122
+ it "should call the backup#to_command when it's associated" do
123
+ to_folder = ToFolder.new('/to_folder/', delete: true)
124
+
125
+ backup = double(:backup)
126
+ to_folder.backup = backup
127
+
128
+ backup.should_receive(:to_command).and_return('backup called')
129
+ to_folder.to_command
130
+ end
131
+
132
+ end
133
+ end
134
+
135
+ describe "#to_s" do
136
+
137
+ it "should return just the path name if ssh is not set up" do
138
+ to_folder = ToFolder.new('/to_folder')
139
+ to_folder.to_s.should == '/to_folder'
140
+ end
141
+
142
+ it "should return just the path name if ssh is set up" do
143
+ to_folder = ToFolder.new('/to_folder', ssh: 'user@server')
144
+ to_folder.to_s.should == 'user@server:/to_folder'
145
+ end
146
+ end
147
+ end
148
+
149
+ describe Backup do
150
+
151
+ describe "options" do
152
+
153
+ it "should have an empty suffix" do
154
+ backup = Backup.new("/backup")
155
+ backup.instance_eval { @options[:suffix] }.should be_false
156
+ end
157
+
158
+ it "should have disable_suffix as false" do
159
+ backup = Backup.new("/backup")
160
+ backup.instance_eval { @options[:disable_suffix] }.should be_false
161
+ end
162
+
163
+ it "should have 5 as limit" do
164
+ backup = Backup.new("/backup")
165
+ backup.instance_eval { @options[:limit] }.should == 5
166
+ end
167
+
168
+ it "should keep the defaults value with only one options is changed " do
169
+ backup = Backup.new("/backup", suffix: "_my_suffix")
170
+
171
+ options = backup.instance_eval { @options }
172
+ options[:disable_suffix].should be_false
173
+ options[:limit].should == 5
174
+ options[:suffix].should == '_my_suffix'
175
+ end
176
+ end
177
+
178
+ describe "#delete_files" do
179
+
180
+ it "should call BackupUtils#delete_files" do
181
+ BackupUtils.should_receive(:delete_files).with('/backup', "_rbcl", 5)
182
+
183
+ backup = Backup.new("/backup")
184
+ backup.delete_files
185
+ end
186
+
187
+ it "should call with 10 as limit if limit is set up with 10" do
188
+ BackupUtils.should_receive(:delete_files).with('/backup', "_rbcl", 10)
189
+
190
+ backup = Backup.new("/backup", limit: 10)
191
+ backup.delete_files
192
+ end
193
+
194
+ it "should not call it if the limit options is :unlimited " do
195
+ BackupUtils.should_not_receive(:delete_files)
196
+
197
+ backup = Backup.new("/backup", limit: :unlimited)
198
+ backup.delete_files
199
+ end
200
+ end
201
+
202
+ describe "#to_command" do
203
+
204
+ it "should as default create the command '-b --suffix=rbcl_Date --backup-dir=/backup' with the ruby_clone suffix and the Date" do
205
+ backup = Backup.new("/backup")
206
+ backup.instance_eval { @time = '20120923'}
207
+ backup.to_command.should == "-b --suffix=_rbcl_20120923 --backup-dir=/backup"
208
+ end
209
+
210
+ it "should not override the default ruby_clone suffix when using suffix option" do
211
+ backup = Backup.new("/backup", suffix: "_my_suffix")
212
+ backup.to_command.should == "-b --suffix=_rbcl_my_suffix --backup-dir=/backup"
213
+ end
214
+
215
+ it "should not create any suffix if the disable_suffix is true" do
216
+ backup = Backup.new("/backup", suffix: "_my_suffix", disable_suffix: true)
217
+ backup.to_command.should == "-b --backup-dir=/backup"
218
+ end
219
+ end
220
+
221
+ end
222
+ end
@@ -0,0 +1,309 @@
1
+ require 'spec_helper'
2
+ require 'stringio'
3
+
4
+ class FakerPTY
5
+ class << self
6
+ attr_accessor :r, :w, :pid
7
+
8
+ def spawn(command, &block)
9
+ block.call @r, @w, @pid
10
+ end
11
+ end
12
+ end
13
+
14
+ module RubyClone
15
+
16
+ describe RSync do
17
+
18
+ before(:each) do
19
+ @from_folder = FromFolder.new "/from_folder"
20
+ @to_folder = ToFolder.new "/to_folder"
21
+
22
+ @profile = Profile.new 'test_profile'
23
+ @profile.from_folder = @from_folder
24
+ @profile.to_folder = @to_folder
25
+
26
+ @output = StringIO.new
27
+ @rsync = RSync.new(@output)
28
+ @rsync.profiles = @profile
29
+
30
+ @rsync_options = '-Cavh --stats --progress'
31
+ @rsync_command = "rsync #{@rsync_options}"
32
+ @folders = "/from_folder /to_folder"
33
+ end
34
+
35
+ describe "#configurations" do
36
+
37
+ it "should as default have '-Cav --stats' in options" do
38
+ @rsync.instance_eval { @configurations[:options] }.should == "#{@rsync_options}"
39
+ end
40
+
41
+ it "should as default have 'true' in show_command" do
42
+ @rsync.instance_eval { @configurations[:show_command] }.should be_true
43
+ end
44
+
45
+ it "should as default have 'true' in show_output" do
46
+ @rsync.instance_eval { @configurations[:show_output] }.should be_true
47
+ end
48
+ end
49
+
50
+ describe "#rsync_command" do
51
+
52
+ describe "profile invalid" do
53
+
54
+ it "should raise ArgumentError when trying to run a profile that doesn't exist" do
55
+ lambda do
56
+ @rsync.run 'my_profile'
57
+ end.should raise_error(ArgumentError, "Profile my_profile not found")
58
+ end
59
+
60
+ it "should raise SyntaxError with message 'Empty Profile not allowed for profile no_from_folder with no 'from folder''" do
61
+ lambda do
62
+ profile = Profile.new 'no_from_folder'
63
+ profile.to_folder = @to_folder
64
+ @rsync.profiles = profile
65
+
66
+ @rsync.run 'no_from_folder'
67
+ end.should raise_error(SyntaxError, "Empty Profile not allowed for profile no_from_folder with no 'from folder'")
68
+ end
69
+
70
+ it "should raise SyntaxError with message 'Empty Profile not allowed for profile no_to_folder with no 'to folder''" do
71
+ lambda do
72
+ profile = Profile.new 'no_to_folder'
73
+ profile.from_folder = @from_folder
74
+ @rsync.profiles = profile
75
+
76
+ @rsync.run 'no_to_folder'
77
+ end.should raise_error(SyntaxError, "Empty Profile not allowed for profile no_to_folder with no 'to folder'")
78
+ end
79
+ end
80
+
81
+ it "should as default create the command 'rsync -Cav --stats /from_folder /to_folder'" do
82
+ command = @rsync.rsync_command "test_profile"
83
+ command.should == "#{@rsync_command} #{@folders}"
84
+ end
85
+
86
+ describe "appending commands" do
87
+
88
+ it "should create with '--exclude=/exclude_path1 --exclude=/exclude_path2' options when set up the excluded path" do
89
+ @rsync.exclude_pattern = '/exclude_pattern1'
90
+ @rsync.exclude_pattern = '/exclude_pattern2'
91
+
92
+ command = @rsync.rsync_command "test_profile"
93
+ command.should == "#{@rsync_command} --exclude=/exclude_pattern1 --exclude=/exclude_pattern2 #{@folders}"
94
+ end
95
+
96
+ it "should create with '--include' when set up the include pattern" do
97
+ @rsync.include_pattern = '/include_pattern1'
98
+ @rsync.include_pattern = '/include_pattern2'
99
+
100
+ command = @rsync.rsync_command "test_profile"
101
+ command.should == "#{@rsync_command} --include=/include_pattern1 --include=/include_pattern2 #{@folders}"
102
+ end
103
+
104
+ it "should have --include before the --exclude" do
105
+ @rsync.exclude_pattern = '/exclude_pattern'
106
+ @rsync.include_pattern = '/include_pattern'
107
+
108
+ command = @rsync.rsync_command "test_profile"
109
+ command.should == "#{@rsync_command} --include=/include_pattern --exclude=/exclude_pattern #{@folders}"
110
+ end
111
+
112
+ describe "FromFolder association" do
113
+
114
+ it "should appends the commands from 'from_folder#to_commands'" do
115
+ @rsync.exclude_pattern = '/exclude_pattern1'
116
+ @rsync.exclude_pattern = '/exclude_pattern2'
117
+
118
+ from_folder = double(:from_folder).as_null_object
119
+ from_folder.stub(:ssh?).and_return false
120
+ from_folder.stub(:to_s).and_return '/from_folder'
121
+ from_folder.should_receive(:to_command).and_return('from_folder#to_command')
122
+
123
+ @profile.from_folder = from_folder
124
+
125
+ command = @rsync.rsync_command "test_profile"
126
+ command.should == "#{@rsync_command} --exclude=/exclude_pattern1 --exclude=/exclude_pattern2 from_folder#to_command #{@folders}"
127
+ end
128
+ end
129
+
130
+ describe "ToFolder association" do
131
+
132
+ it "should call to_folder#to_commands" do
133
+ @rsync.exclude_pattern = '/exclude_pattern1'
134
+ @rsync.exclude_pattern = '/exclude_pattern2'
135
+
136
+ to_folder = double(:to_folder).as_null_object
137
+ to_folder.stub(:ssh?).and_return false
138
+ to_folder.stub(:to_s).and_return '/to_folder'
139
+ to_folder.should_receive(:to_command).and_return('to_folder#to_command')
140
+
141
+ @profile.to_folder = to_folder
142
+
143
+ command = @rsync.rsync_command "test_profile"
144
+ command.should == "#{@rsync_command} --exclude=/exclude_pattern1 --exclude=/exclude_pattern2 to_folder#to_command #{@folders}"
145
+ end
146
+
147
+ end
148
+ end
149
+
150
+ describe "using ssh" do
151
+
152
+ it "should have the ssh in the rsync command when FromFolder is using ssh" do
153
+ from_folder = FromFolder.new "/from_folder", ssh: "user@server"
154
+ @profile.from_folder = from_folder
155
+
156
+ command = @rsync.rsync_command "test_profile"
157
+ command.should == "#{@rsync_command} -e ssh user@server:/from_folder /to_folder"
158
+ end
159
+
160
+ it "should have the ssh in the rsync command when ToFolder is using ssh" do
161
+ to_folder = ToFolder.new "/to_folder", ssh: "user@server"
162
+ @profile.to_folder = to_folder
163
+
164
+ command = @rsync.rsync_command "test_profile"
165
+ command.should == "#{@rsync_command} -e ssh /from_folder user@server:/to_folder"
166
+ end
167
+
168
+ it "should raise SyntaxError if the source and destination is ssh" do
169
+ lambda do
170
+ from_folder = FromFolder.new "/from_folder", ssh: "user@server"
171
+ @profile.from_folder = from_folder
172
+
173
+ to_folder = ToFolder.new "/to_folder", ssh: "user@server"
174
+ @profile.to_folder = to_folder
175
+
176
+ @rsync.rsync_command "test_profile"
177
+ end.should raise_error(SyntaxError, 'The source and destination cannot both be remote.')
178
+ end
179
+ end
180
+ end
181
+
182
+ describe "#last_profile" do
183
+
184
+ it "should return the last profile added" do
185
+ @rsync.last_profile.should == @profile
186
+
187
+ other_profile = Profile.new 'other_profile'
188
+
189
+ @rsync.profiles = other_profile
190
+ @rsync.last_profile.should == other_profile
191
+ end
192
+ end
193
+
194
+ describe "#run" do
195
+
196
+
197
+ before(:each) do
198
+ @rsync.instance_eval { @pty = FakerPTY }
199
+
200
+ FakerPTY.methods(false).grep(/(.*)=$/) do
201
+ double_object = double($1)
202
+ FakerPTY.send "#{$1}=", double_object
203
+ end
204
+
205
+ FakerPTY.r.stub(:each).and_yield(nil)
206
+ end
207
+
208
+ describe "profile of string type" do
209
+
210
+ before(:each) do
211
+ profile = Profile.new 'profile_string'
212
+ profile.from_folder = @from_folder
213
+ profile.to_folder = @to_folder
214
+
215
+ @rsync.profiles = profile
216
+ end
217
+
218
+ it "should run using profile as string" do
219
+ @rsync.run 'profile_string'
220
+ end
221
+
222
+ it "should run using profile as symbol" do
223
+ @rsync.run :profile_string
224
+ end
225
+ end
226
+
227
+ describe "profile of symbol type" do
228
+
229
+ before(:each) do
230
+ profile = Profile.new :profile_symbol
231
+ profile.from_folder = @from_folder
232
+ profile.to_folder = @to_folder
233
+
234
+ @rsync.profiles = profile
235
+ end
236
+
237
+ it "should run using profile as string" do
238
+ @rsync.run 'profile_symbol'
239
+ end
240
+
241
+ it "should run using profile as symbol" do
242
+ @rsync.run :profile_symbol
243
+ end
244
+
245
+ end
246
+
247
+ describe "changing configurations" do
248
+
249
+ it "should change the rsync options when configurations has 'optionas' as '-a'" do
250
+ @rsync.update_configurations options: "-a"
251
+ @rsync.run 'test_profile'
252
+
253
+ @output.seek 0
254
+ @output.read.should == "\nrsync -a #{@folders}\n\n"
255
+ end
256
+
257
+ it "should as default show the rsync command in console" do
258
+ @rsync.run 'test_profile'
259
+
260
+ @output.seek 0
261
+ @output.read.should == "\n#{@rsync_command} #{@folders}\n\n"
262
+ end
263
+
264
+ it "should not print the rsync command in console when configurations has 'show_command' as false" do
265
+ @rsync.update_configurations show_command: false
266
+ @rsync.run 'test_profile'
267
+
268
+ @output.seek 0
269
+ @output.read.should == ""
270
+ end
271
+
272
+ it "should as default output the rsync results in console" do
273
+ FakerPTY.r.should_receive(:each)
274
+
275
+ @rsync.run 'test_profile'
276
+
277
+ @output.seek 0
278
+ @output.read.should == "\n#{@rsync_command} #{@folders}\n\n"
279
+ end
280
+
281
+ it "should not output the rsync results in console when configurations has 'show_output' as false" do
282
+ FakerPTY.r.should_not_receive(:each)
283
+
284
+ @rsync.update_configurations show_output: false
285
+ @rsync.run 'test_profile'
286
+
287
+ @output.seek 0
288
+ @output.read.should == "\n#{@rsync_command} #{@folders}\n\n"
289
+ end
290
+ end
291
+
292
+ it "should not run when it's in dry-run mode" do
293
+ @rsync.dry_run = true
294
+
295
+ @rsync.run 'test_profile'
296
+
297
+ @output.seek 0
298
+ @output.read.should == "\n#{@rsync_command} -n #{@folders}\n\n"
299
+ end
300
+
301
+ it "should call profile#to_folder#delete_files" do
302
+ @to_folder.should_receive(:delete_files)
303
+
304
+ @rsync.run 'test_profile'
305
+ end
306
+ end
307
+
308
+ end
309
+ end
@@ -0,0 +1 @@
1
+ require 'ruby_clone'
metadata ADDED
@@ -0,0 +1,106 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: ruby_clone
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Frederico Benevides
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-09-24 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: guard
16
+ requirement: &70295966492060 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: 1.3.2
22
+ type: :development
23
+ prerelease: false
24
+ version_requirements: *70295966492060
25
+ - !ruby/object:Gem::Dependency
26
+ name: guard-rspec
27
+ requirement: &70295966491280 !ruby/object:Gem::Requirement
28
+ none: false
29
+ requirements:
30
+ - - ~>
31
+ - !ruby/object:Gem::Version
32
+ version: 1.2.1
33
+ type: :development
34
+ prerelease: false
35
+ version_requirements: *70295966491280
36
+ - !ruby/object:Gem::Dependency
37
+ name: rspec
38
+ requirement: &70295966490740 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ~>
42
+ - !ruby/object:Gem::Version
43
+ version: 2.11.0
44
+ type: :development
45
+ prerelease: false
46
+ version_requirements: *70295966490740
47
+ description: Ruby clone is a command line tool to work with Rsync using DSL!
48
+ email:
49
+ - fredbene@gmail.com
50
+ executables:
51
+ - ruby_clone
52
+ extensions: []
53
+ extra_rdoc_files: []
54
+ files:
55
+ - .gitignore
56
+ - Gemfile
57
+ - Guardfile
58
+ - LICENSE
59
+ - README.md
60
+ - Rakefile
61
+ - bin/ruby_clone
62
+ - lib/ruby_clone.rb
63
+ - lib/ruby_clone/backup_utils.rb
64
+ - lib/ruby_clone/dsl.rb
65
+ - lib/ruby_clone/options.rb
66
+ - lib/ruby_clone/profile.rb
67
+ - lib/ruby_clone/rsync.rb
68
+ - lib/ruby_clone/version.rb
69
+ - ruby_clone.gemspec
70
+ - spec/ruby_clone/backup_utils_spec.rb
71
+ - spec/ruby_clone/dsl_spec.rb
72
+ - spec/ruby_clone/options_spec.rb
73
+ - spec/ruby_clone/profile_spec.rb
74
+ - spec/ruby_clone/rsync_spec.rb
75
+ - spec/spec_helper.rb
76
+ homepage: http://github.com/fredericobenevides/ruby_clone
77
+ licenses: []
78
+ post_install_message:
79
+ rdoc_options: []
80
+ require_paths:
81
+ - lib
82
+ required_ruby_version: !ruby/object:Gem::Requirement
83
+ none: false
84
+ requirements:
85
+ - - ! '>='
86
+ - !ruby/object:Gem::Version
87
+ version: '0'
88
+ required_rubygems_version: !ruby/object:Gem::Requirement
89
+ none: false
90
+ requirements:
91
+ - - ! '>='
92
+ - !ruby/object:Gem::Version
93
+ version: '0'
94
+ requirements: []
95
+ rubyforge_project:
96
+ rubygems_version: 1.8.11
97
+ signing_key:
98
+ specification_version: 3
99
+ summary: Ruby_clone is high level script of Rsync. Use Ruby DSL to work with RSync!
100
+ test_files:
101
+ - spec/ruby_clone/backup_utils_spec.rb
102
+ - spec/ruby_clone/dsl_spec.rb
103
+ - spec/ruby_clone/options_spec.rb
104
+ - spec/ruby_clone/profile_spec.rb
105
+ - spec/ruby_clone/rsync_spec.rb
106
+ - spec/spec_helper.rb