subwrap 0.3.5

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,72 @@
1
+ require File.dirname(__FILE__) + '/test_helper'
2
+ require 'subversion_extensions'
3
+
4
+ Subversion.color = false # Makes testing simpler. We can just test that the *colorization* features are working via *manual* tests.
5
+
6
+ class SubversionExtensionsTest < Test::Unit::TestCase
7
+ def setup
8
+ end
9
+
10
+ def test_status_lines_filter
11
+
12
+ #String.any_instance.stubs(:underline).returns(lambda {|a| a}) # Doesn't work! Lame! So we can't make the return value depend on the input?
13
+ String.any_instance.stubs(:underline).returns(lambda {' externals '})
14
+
15
+ input = <<End
16
+ M gemables/calculator/test/calculator_test.rb
17
+ X gemables/calculator/tasks/shared
18
+ ? gemables/calculator/lib/calculator_extensions.rb
19
+
20
+ Performing status on external item at 'plugins/flubber/tasks/shared'
21
+
22
+ Performing status on external item at 'applications/underlord/vendor/plugins/nifty'
23
+ X applications/underlord/vendor/plugins/nifty/tasks/shared
24
+ X applications/underlord/vendor/plugins/nifty/doc_include/template
25
+
26
+ Performing status on external item at 'applications/underlord/vendor/plugins/nifty/tasks/shared'
27
+ M applications/underlord/vendor/plugins/nifty/tasks/shared/base.rake
28
+ End
29
+ expected = <<End
30
+ M gemables/calculator/test/calculator_test.rb
31
+ ? gemables/calculator/lib/calculator_extensions.rb
32
+ ________________________________________ externals ________________________________________
33
+ M applications/underlord/vendor/plugins/nifty/tasks/shared/base.rake
34
+ End
35
+
36
+ assert_equal expected, out = Subversion::Extensions.status_lines_filter( input ), out.inspect
37
+ end
38
+
39
+ def test_update_lines_filter
40
+ input = <<End
41
+ U gemables/calculator/test/calculator_test.rb
42
+ U gemables/calculator/tasks/shared
43
+ U gemables/calculator/lib/calculator_extensions.rb
44
+
45
+ Fetching external item into 'plugins/flubber/tasks/shared'
46
+ U plugins/flubber/tasks/shared/blah.rb
47
+ External at revision 134143078
48
+ End
49
+ expected = <<End
50
+ U gemables/calculator/test/calculator_test.rb
51
+ U gemables/calculator/tasks/shared
52
+ U gemables/calculator/lib/calculator_extensions.rb
53
+ U plugins/flubber/tasks/shared/blah.rb
54
+ End
55
+
56
+ assert_equal expected, out = Subversion::Extensions.update_lines_filter( input ), out.inspect
57
+ end
58
+
59
+ def test_unadded_filter
60
+ input = <<End
61
+ M gemables/calculator/test/calculator_test.rb
62
+ X gemables/calculator/tasks/shared
63
+ ? gemables/calculator/lib/calculator_extensions.rb
64
+ End
65
+ expected = <<End
66
+ ? gemables/calculator/lib/calculator_extensions.rb
67
+ End
68
+
69
+ assert_equal expected, out = Subversion::Extensions.unadded_lines_filter( input ), out.inspect
70
+ assert_equal ['gemables/calculator/lib/calculator_extensions.rb'], out = Subversion::Extensions.unadded_filter( input ), out.inspect
71
+ end
72
+ end
@@ -0,0 +1,132 @@
1
+ $mock_subversion = true
2
+ require File.dirname(__FILE__) + '/test_helper'
3
+
4
+ class SubversionTest < Test::Unit::TestCase
5
+ def setup
6
+ Subversion.reset_executed
7
+ end
8
+
9
+ def test_add
10
+ Subversion.add('foo', 'bar', 'hello', 'world')
11
+ assert_equal 'svn add foo bar hello world', Subversion.executed.first
12
+ end
13
+
14
+ def test_ignore
15
+ Subversion.ignore('foo', 'some/path/foo')
16
+ assert_equal "svn propset svn:ignore 'foo' ./", Subversion.executed[1]
17
+ assert_equal "svn propset svn:ignore 'foo' some/path", Subversion.executed[3]
18
+ end
19
+
20
+ def test_externalize
21
+ Subversion.externalize('some/repo/path')
22
+ Subversion.externalize('some/repo/path', :as => 'foo')
23
+ Subversion.externalize('some/repo/path', :as => 'foo', :local_path => 'local/path')
24
+ Subversion.externalize('some/repo/path', :as => 'vendor/plugins/foo')
25
+
26
+ assert_equal "svn propset svn:externals '#{'path'} some/repo/path' .", Subversion.executed[1] # Used to be 'path'.ljust(29)
27
+ assert_equal "svn propset svn:externals '#{'foo'} some/repo/path' .", Subversion.executed[3]
28
+ assert_equal "svn propset svn:externals '#{'foo'} some/repo/path' local/path", Subversion.executed[5]
29
+ assert_equal "svn propset svn:externals '#{'foo'} some/repo/path' vendor/plugins", Subversion.executed[7]
30
+ end
31
+
32
+ def test_remove
33
+ Subversion.remove 'foo', 'bar', 'hello/world'
34
+ assert_equal 'svn rm foo bar hello/world', Subversion.executed.first
35
+ end
36
+
37
+ def test_remove_without_delete
38
+ tmpdir = "tmp#{$$}"
39
+ entries = "#{tmpdir}/.svn/entries"
40
+ FileUtils.mkdir_p "#{tmpdir}/.svn", :mode => 0755
41
+ File.open entries, 'w' do |file|
42
+ file.write <<-EOS
43
+ <?xml version="1.0" encoding="utf-8"?>
44
+ <wc-entries
45
+ xmlns="svn:">
46
+ <entry
47
+ name="existing_file"
48
+ kind="file"/>
49
+ <entry
50
+ name="just_added_file"
51
+ schedule="add"
52
+ kind="file"/>
53
+ <entry
54
+ name="unchanging_file"
55
+ kind="file"/>
56
+ </wc-entries>
57
+ EOS
58
+ end
59
+ File.chmod(0444, entries)
60
+ FileUtils.touch ["#{tmpdir}/existing_file", "#{tmpdir}/just_added_file", "#{tmpdir}/unchanging_file"]
61
+
62
+ begin
63
+ doc = REXML::Document.new(IO.read(entries))
64
+ assert_not_nil REXML::XPath.first(doc, '//entry[@name="existing_file"]')
65
+ Subversion.remove_without_delete "#{tmpdir}/existing_file"
66
+ # the element should now be scheduled for delete
67
+ doc = REXML::Document.new(IO.read(entries))
68
+ assert_not_nil REXML::XPath.first(doc, '//entry[@name="existing_file"][@schedule="delete"]')
69
+
70
+ doc = REXML::Document.new(IO.read(entries))
71
+ assert_not_nil REXML::XPath.first(doc, '//entry[@name="just_added_file"][@schedule="add"]')
72
+ Subversion.remove_without_delete "#{tmpdir}/just_added_file"
73
+ doc = REXML::Document.new(IO.read(entries))
74
+ # the element should now be gone
75
+ assert_nil REXML::XPath.first(doc, '//entry[@name="just_added_file"]')
76
+ ensure
77
+ FileUtils.rm_r tmpdir
78
+ end
79
+ end
80
+ end
81
+
82
+ class DiffsParserTest < Test::Unit::TestCase
83
+ # def test_diff_class_acts_like_hash
84
+ # diff = Subversion::Diff['file.rb' => "some differences"]
85
+ # assert_equal 'some differences', diff['file.rb']
86
+ # end
87
+ def test_parser_error
88
+ assert_raise(Subversion::DiffsParser::ParseError) { Subversion::DiffsParser.new('what').parse }
89
+ end
90
+ def test_parser
91
+ diffs = Subversion::DiffsParser.new(<<End).parse
92
+ Index: lib/test_extensions.rb
93
+ ===================================================================
94
+ --- lib/test_extensions.rb (revision 2871)
95
+ +++ lib/test_extensions.rb (revision 2872)
96
+ @@ -6,6 +6,7 @@
97
+ require_local 'some_file'
98
+
99
+ gem 'quality_extensions'
100
+ +require 'quality_extensions/regexp/join'
101
+ require 'quality_extensions/kernel/capture_output.rb'
102
+ require 'quality_extensions/kernel/simulate_input.rb'
103
+
104
+ Index: Readme
105
+ ===================================================================
106
+ --- Readme (revision 0)
107
+ +++ Readme (revision 2872)
108
+ @@ -0,0 +1,2 @@
109
+ +* Blah blah blah
110
+ +* Blah blah blah
111
+ End
112
+ assert_equal Subversion::Diffs, diffs.class
113
+ assert diffs.frozen?
114
+ assert_equal 2, diffs.keys.size
115
+ assert_equal 2, diffs.values.size
116
+ assert_equal <<End, diffs['lib/test_extensions.rb'].diff
117
+ require_local 'some_file'
118
+
119
+ gem 'quality_extensions'
120
+ +require 'quality_extensions/regexp/join'
121
+ require 'quality_extensions/kernel/capture_output.rb'
122
+ require 'quality_extensions/kernel/simulate_input.rb'
123
+
124
+ End
125
+ assert_equal <<End, diffs['Readme'].diff
126
+ +* Blah blah blah
127
+ +* Blah blah blah
128
+ End
129
+
130
+ end
131
+
132
+ end
@@ -0,0 +1,649 @@
1
+ $mock_subversion = true
2
+ require File.dirname(__FILE__) + '/test_helper'
3
+ require_local '../lib/subwrap/svn_command.rb'
4
+ require 'facets/core/string/to_re'
5
+ require 'yaml'
6
+ require 'facets/core/module/alias_method_chain'
7
+ require 'quality_extensions/colored/toggleability'
8
+ require 'quality_extensions/regexp/join'
9
+
10
+
11
+
12
+ # Makes testing simpler. We can test all the *colorization* features via *manual* testing (since they're not as critical).
13
+ Subversion.color = false
14
+ String.color_on! false
15
+
16
+ #pp Subversion::SvnCommand.instance_methods.sort
17
+
18
+ # Since this doesn't work: Subversion::SvnCommand.any_instance.stubs(:system).returns(Proc.new {|a| p a; puts "Tried to call system(#{a})" })
19
+ class Subversion::SvnCommand
20
+ def system(*args)
21
+ Subversion::SvnCommand.executed_system << args.join(' ')
22
+ end
23
+ def self.executed_system
24
+ @@executed_system ||= []
25
+ end
26
+ def self.reset_executed_system(as = [])
27
+ @@executed_system = as
28
+ end
29
+ end
30
+ module Kernel
31
+ def exit_code
32
+ o = Object.new
33
+ class << o
34
+ def success?
35
+ true
36
+ end
37
+ end
38
+ o
39
+ end
40
+ end
41
+
42
+
43
+ module Subversion
44
+ class BaseSvnCommandTest < Test::Unit::TestCase
45
+ def setup
46
+ Subversion.reset_executed
47
+ end
48
+ def test_dummy_test
49
+ # Because it tries to run this base class too!
50
+ end
51
+ # When we don't care what the output is -- we just don't want to see it while running the test!
52
+ def silence(&block)
53
+ capture_output(&block)
54
+ nil
55
+ end
56
+ end
57
+
58
+
59
+ class SvnCommandTest < BaseSvnCommandTest
60
+ def test_invalid_quotes_gives_informative_error
61
+ assert_exception(ArgumentError, lambda { |exception|
62
+ assert_equal "Unmatched single quote: '", exception.message
63
+ }) do
64
+ SvnCommand.execute("foo -m 'stuff''")
65
+ end
66
+ end
67
+ def test_unrecognized_option
68
+ output = capture_output($stderr) do
69
+ assert_exception(SystemExit, lambda { |exception|
70
+ }) do
71
+ SvnCommand.execute("status --blarg")
72
+ end
73
+ end
74
+ assert_match /Unknown option '--blarg'/, output
75
+ end
76
+ end
77
+
78
+ class ArgEscapingTest < BaseSvnCommandTest
79
+ def test_argument_escaping
80
+ args = nil
81
+ silence { SvnCommand.execute( args = %q{commit -m 'a message with lots of !&`$0 |()<> garbage'} ) }
82
+ assert_equal "svn #{args} --force-log", Subversion.executed[0]
83
+ end
84
+ def test_asterisk
85
+ # Don't worry, this'll never happen, because the shell will expand the * *before* it gets to SvnCommand. But if you *did* sneak in an asterisk to SvnCommand.execute somehow, this is what would happen...
86
+ SvnCommand.execute("add dir/* --non-recursive")
87
+ assert_equal "svn add --non-recursive 'dir/*'", Subversion.executed[0]
88
+ # Actually, I lied... The * will *not* be expanded in the (rather uncommon) case that there are *no files matching the glob*. But that seems like a bash/shell problem, not our concern. Demo:
89
+ # > mkdir foo
90
+ # > echo foo/*
91
+ # foo/*
92
+ # > touch foo/file
93
+ # > echo foo/*
94
+ # foo/file
95
+ end
96
+ def test_multiline
97
+ args = nil
98
+ silence { SvnCommand.execute(args = "commit -m 'This is a
99
+ |multi-line
100
+ |message'".margin) }
101
+ assert_equal "svn #{args} --force-log", Subversion.executed[0]
102
+ end
103
+ def test_multiword_arg_preserved_even_for_passthrough_subcommands
104
+ # foo, for instance is entirely a passthrough subcommand; no 'def foo' exists, so it's handled entirely through method_missing.
105
+ args = nil
106
+ silence { SvnCommand.execute( args = %q{foo -m 'a multi-word message' --something-else 'something else'} ) }
107
+ assert_equal "svn #{args}", Subversion.executed[0]
108
+ end
109
+ end
110
+
111
+ #-----------------------------------------------------------------------------------------------------------------------------
112
+ # Built-in subcommands
113
+
114
+ # Test method_missing. Can we still call svn info, rm, etc. even if we haven't written subcommand modules for them?
115
+ class SubcommandPassThroughTest < BaseSvnCommandTest
116
+ def test_1
117
+ SvnCommand.execute("rm -q file1 file2 --force")
118
+ assert_equal "svn rm -q file1 file2 --force", Subversion.executed[0]
119
+ end
120
+ def test_2
121
+ SvnCommand.execute("info -q file1 file2 --force")
122
+ assert_equal "svn info -q file1 file2 --force", Subversion.executed[0]
123
+ end
124
+ end
125
+
126
+ class SvnAddTest < BaseSvnCommandTest
127
+ def test_1
128
+ end
129
+ def test_2
130
+ SvnCommand.execute('add "a b"')
131
+ assert_equal "svn add 'a b'", Subversion.executed[0]
132
+ end
133
+ def test_3
134
+ SvnCommand.execute('add a b')
135
+ assert_equal "svn add a b", Subversion.executed[0]
136
+ end
137
+ end
138
+
139
+ class SvnCommitTest < BaseSvnCommandTest
140
+ def test_1
141
+ silence { SvnCommand.execute("commit -m 'just an ordinary commit message!'") }
142
+ assert_equal "svn commit -m 'just an ordinary commit message!' --force-log", Subversion.executed[0]
143
+ end
144
+ def test_lots_of_options
145
+ silence { SvnCommand.execute("commit --non-recursive -q -m '' --targets some_file ") }
146
+ assert_equal "svn commit --non-recursive -q -m '' --targets some_file --force-log", Subversion.executed[0]
147
+ end
148
+ def test_that_complex_quoting_doesnt_confuse_it
149
+ original_message = "Can't decide how many \"'quotes'\" to use!"
150
+ silence { SvnCommand.execute(%Q{commit -m "#{original_message.gsub('"', '\"')}"}) }
151
+
152
+ expected_escaped_part = %q{'Can'\\''t decide how many "'\\''quotes'\\''" to use!'}
153
+ assert_equal "svn commit -m #{expected_escaped_part} --force-log", Subversion.executed[0]
154
+ assert_equal original_message, `echo #{expected_escaped_part}`.chomp # We should have gotten back exactly what we put in originally
155
+ end
156
+ end
157
+
158
+ class SvnDiffTest < BaseSvnCommandTest
159
+ def test_1
160
+ SvnCommand.execute("diff -r 123:125")
161
+ assert_equal [
162
+ "svn diff -r 123:125 ./",
163
+ "svn status ./"
164
+ ], Subversion.executed
165
+ end
166
+ def test_2
167
+ #:fixme:
168
+ #capture_output { SvnCommand.execute("diff -r { 2006-07-01 }") }
169
+ #p Subversion.executed
170
+ # Currently does this, since it thinks the arity is 1: 2006-07-01 } -r '{'
171
+ #assert_equal "svn diff -r { 2006-07-01 }", Subversion.executed[0]
172
+ end
173
+ end
174
+
175
+ class SvnHelpTest < BaseSvnCommandTest
176
+ def test_1
177
+ output = capture_output { SvnCommand.execute("help") }
178
+ assert_equal "svn help ", Subversion.executed[0]
179
+ assert_match /wrapper/, output
180
+ end
181
+ end
182
+
183
+ class SvnLogTest < BaseSvnCommandTest
184
+ def test_1
185
+ capture_output { SvnCommand.execute("log") }
186
+ assert_equal "svn log ", Subversion.executed[0]
187
+ end
188
+ end
189
+
190
+ class SvnStatusTest < BaseSvnCommandTest
191
+ # Duplicates a test in subversion_extensions_test.rb -- maybe can abbreviate this and leave the detailed filter tests to the other TestCase
192
+ def test_status_does_some_filtering
193
+ Subversion.stubs(:status).returns("
194
+ M gemables/calculator/test/calculator_test.rb
195
+ X gemables/calculator/tasks/shared
196
+ ? gemables/calculator/lib/calculator_extensions.rb
197
+
198
+ Performing status on external item at 'plugins/flubber/tasks/shared'
199
+
200
+ Performing status on external item at 'applications/underlord/vendor/plugins/nifty'
201
+ X applications/underlord/vendor/plugins/nifty/tasks/shared
202
+ X applications/underlord/vendor/plugins/nifty/lib/calculator
203
+ X applications/underlord/vendor/plugins/nifty/doc_include/template
204
+
205
+ Performing status on external item at 'applications/underlord/vendor/plugins/nifty/tasks/shared'
206
+ M applications/underlord/vendor/plugins/nifty/tasks/shared/base.rake
207
+ ")
208
+ String.any_instance.stubs(:underline).returns(lambda {' externals '})
209
+
210
+ expected = <<End
211
+ M gemables/calculator/test/calculator_test.rb
212
+ ? gemables/calculator/lib/calculator_extensions.rb
213
+ ________________________________________ externals ________________________________________
214
+ M applications/underlord/vendor/plugins/nifty/tasks/shared/base.rake
215
+ End
216
+
217
+ assert_equal expected, out = capture_output { Subversion::SvnCommand.execute('st') }
218
+ end
219
+
220
+ def test_status_accepts_arguments
221
+ SvnCommand.execute('st -u /path/to/file1 file2')
222
+ assert_equal "svn status -u /path/to/file1 file2", Subversion.executed[0]
223
+
224
+ Subversion.reset_executed
225
+ SvnCommand.execute('st dir --no-ignore')
226
+ # It will reorder some of the args (it puts all pass-through options and their args at the *beginning*), but that's okay...
227
+ assert_equal "svn status --no-ignore dir", Subversion.executed[0]
228
+
229
+ end
230
+ end #class SvnStatusTest
231
+
232
+ class SvnUpdateTest < BaseSvnCommandTest
233
+ def test_1
234
+ capture_output { SvnCommand.execute("up -q file1 file2 -r 17") }
235
+ assert_equal "svn update -q -r 17 file1 file2", Subversion.executed[0]
236
+ end
237
+ end
238
+
239
+ #-----------------------------------------------------------------------------------------------------------------------------
240
+ # Custom subcommands
241
+
242
+ #-----------------------------------------------------------------------------------------------------------------------------
243
+
244
+ # Notes about this test:
245
+ # If you start seeing errors like this:
246
+ # NoMethodError: undefined method `chr' for nil:NilClass
247
+ # coming from one of the $stdin.getc.chr lines, it means that you didn't feed it enough simulated input! It was expectin to get
248
+ # another character from stdin but you didn't supply one!
249
+
250
+ class SvnEachUnaddedTest < BaseSvnCommandTest
251
+ def setup
252
+ super
253
+ FileUtils.rm_rf('temp_dir/')
254
+ FileUtils.mkdir_p('temp_dir/calculator/lib/')
255
+ File.open(@filename = 'temp_dir/calculator/lib/unused.rb', 'w') { |file| file.puts "line 1 of unused.rb" }
256
+ end
257
+ def teardown
258
+ FileUtils.rm_rf('temp_dir/')
259
+ end
260
+
261
+ def stub_status_1
262
+ Subversion.stubs(:status).returns("
263
+ M temp_dir/calculator/test/calculator_test.rb
264
+ X temp_dir/calculator/tasks/shared
265
+ ? temp_dir/calculator/lib/unused.rb
266
+ ")
267
+ end
268
+ def test_add
269
+ stub_status_1
270
+ output = simulate_input('a') do
271
+ capture_output { SvnCommand.execute('each_unadded dir') }
272
+ end
273
+ assert_match /What do you want to do with .*unused\.rb/, output
274
+ assert_match /Adding/, output
275
+ assert_equal "svn add temp_dir/calculator/lib/unused.rb", Subversion.executed[0]
276
+ end
277
+ def test_ignore
278
+ stub_status_1
279
+ output = simulate_input('i') do
280
+ capture_output { SvnCommand.execute('each_unadded dir') }
281
+ end
282
+ assert_match /What do you want to do with .*unused\.rb/, output
283
+ assert_match /Ignoring/, output
284
+ assert_equal [
285
+ "svn propget svn:ignore temp_dir/calculator/lib",
286
+ "svn propset svn:ignore 'unused.rb' temp_dir/calculator/lib"
287
+ ], Subversion.executed
288
+ end
289
+ def test_preview_is_now_automatic
290
+ stub_status_1
291
+ output = simulate_input(
292
+ #"p" + # Preview
293
+ "\n" + # Blank line to do nothing (and exit loop)
294
+ "\n" # Blank line to do nothing (and exit loop)
295
+ ) do
296
+ capture_output { SvnCommand.execute('each_unadded dir') }
297
+ end
298
+ assert_match /What do you want to do with .*unused\.rb/, output
299
+ assert_match "line 1 of unused.rb".to_re, output
300
+ end
301
+ def test_delete
302
+ Subversion.stubs(:status).returns("
303
+ M temp_dir/calculator/test/calculator_test.rb
304
+ X temp_dir/calculator/tasks/shared
305
+ ? temp_dir/calculator/lib/unused.rb
306
+ ? temp_dir/calculator/lib/useless_directory
307
+ ")
308
+ FileUtils.mkdir_p(@dirname = 'temp_dir/calculator/lib/useless_directory')
309
+ File.open( 'temp_dir/calculator/lib/useless_directory/foo', 'w') { |file| file.puts "line 1 of foo" }
310
+
311
+ assert File.exist?( @dirname )
312
+ assert File.exist?( @filename )
313
+ output = simulate_input(
314
+ 'd' + # Delete
315
+ # (The file doesn't require confirmation.)
316
+ 'd' + # Delete
317
+ 'y' # Yes I'm sure (The non-empty directory does.)
318
+ ) do
319
+ capture_output { SvnCommand.execute('each_unadded dir') }
320
+ end
321
+ assert_match /What do you want to do with .*unused\.rb/, output
322
+ assert_match /What do you want to do with .*useless_directory/, output
323
+ assert_match /Are you .*SURE/, output
324
+ assert_match /Deleting.*Deleting/m, output
325
+ assert !File.exist?( @filename )
326
+ assert !File.exist?( @dirname )
327
+ end
328
+ end #class
329
+
330
+ #-----------------------------------------------------------------------------------------------------------------------------
331
+ # Ignore
332
+ class SvnIgnoreTest < BaseSvnCommandTest
333
+ def test_svn_ignore_relative_to_wd
334
+ output = capture_output { SvnCommand.execute('ignore log') }
335
+ assert_equal '', output
336
+ assert_equal [
337
+ "svn propget svn:ignore ./",
338
+ "svn propset svn:ignore 'log' ./"
339
+ ], Subversion.executed
340
+ end
341
+ def test_svn_ignore_relative_to_other_path
342
+ output = capture_output { SvnCommand.execute('ignore log/*') }
343
+ assert_equal '', output
344
+ assert_equal [
345
+ "svn propget svn:ignore log",
346
+ "svn propset svn:ignore '*' log"
347
+ ], Subversion.executed
348
+ end
349
+ end
350
+
351
+ #-----------------------------------------------------------------------------------------------------------------------------
352
+ # Externals
353
+
354
+ class SvnExternalsTest < BaseSvnCommandTest
355
+
356
+ # Causes .stub to break??
357
+ #def setup
358
+ #end
359
+ def set_up_stubs # This ought to just go in the normal "setup", but that caused weird errors. Ideas?
360
+ yaml = %q{
361
+ - !ruby/object:Subversion::ExternalsContainer
362
+ container_dir: /home/tyler/code/gemables/subwrap/test
363
+ entries: |+
364
+ shared http://code.qualitysmith.com/gemables/test_extensions/lib
365
+
366
+ - !ruby/object:Subversion::ExternalsContainer
367
+ container_dir: /home/tyler/code/gemables/subwrap/tasks
368
+ entries: |+
369
+ shared http://code.qualitysmith.com/gemables/shared_tasks/tasks
370
+
371
+ - !ruby/object:Subversion::ExternalsContainer
372
+ container_dir: /home/tyler/code/gemables/subwrap/doc_include
373
+ entries: |+
374
+ template http://code.qualitysmith.com/gemables/template/doc/template
375
+ }
376
+ external_containers = YAML.load yaml
377
+ Subversion.stubs(:externals_containers).returns(external_containers)
378
+ end
379
+
380
+ def test_svn_externalize
381
+ set_up_stubs
382
+ output = capture_output { SvnCommand.execute('externalize http://imaginethat.com/a/repo') }
383
+ assert_equal '', output
384
+ assert_equal [
385
+ "svn propget svn:externals .",
386
+ "svn propset svn:externals 'repo http://imaginethat.com/a/repo' ."
387
+ ], Subversion.executed
388
+ end
389
+
390
+
391
+ def test_svn_externals_outline
392
+ set_up_stubs
393
+ output = capture_output { SvnCommand.execute('externals_outline') }
394
+
395
+ assert_contains output, %q(
396
+ |/home/tyler/code/gemables/subwrap/test
397
+ | * shared http://code.qualitysmith.com/gemables/test_extensions/lib
398
+ |/home/tyler/code/gemables/subwrap/tasks
399
+ | * shared http://code.qualitysmith.com/gemables/shared_tasks/tasks
400
+ |/home/tyler/code/gemables/subwrap/doc_include
401
+ | * template http://code.qualitysmith.com/gemables/template/doc/template
402
+ ).margin
403
+ assert_equal [], Subversion.executed
404
+ end
405
+
406
+ def test_svn_externals_items
407
+ set_up_stubs
408
+ output = capture_output { SvnCommand.execute('externals_items') }
409
+
410
+ # :todo:
411
+
412
+ assert_equal [], Subversion.executed
413
+ end
414
+
415
+ def test_svn_externals_containers
416
+ set_up_stubs
417
+ output = capture_output { SvnCommand.execute('externals_containers') }
418
+
419
+ assert_contains output, %q(
420
+ |/home/tyler/code/gemables/subwrap/test
421
+ |/home/tyler/code/gemables/subwrap/tasks
422
+ |/home/tyler/code/gemables/subwrap/doc_include
423
+ ).margin
424
+ assert_equal [], Subversion.executed
425
+ end
426
+
427
+ def test_svn_edit_externals
428
+ set_up_stubs
429
+ output = simulate_input('yyy') do
430
+ capture_output { SvnCommand.execute('edit_externals') }
431
+ end
432
+ assert_match "No directory specified. Editing externals for *all*".to_re, output
433
+
434
+ assert_match /Do you want to edit svn:externals for this directory/, output
435
+ assert_equal [
436
+ "svn propedit svn:externals /home/tyler/code/gemables/subwrap/test",
437
+ "svn propedit svn:externals /home/tyler/code/gemables/subwrap/tasks",
438
+ "svn propedit svn:externals /home/tyler/code/gemables/subwrap/doc_include"
439
+ ], Subversion.executed
440
+ end
441
+ end
442
+
443
+ #-----------------------------------------------------------------------------------------------------------------------------
444
+ # Commit messages
445
+
446
+ class SvnGetMessageTest < BaseSvnCommandTest
447
+ def test_1
448
+ Subversion.stubs(:status_against_server).returns("Status against revision: 56")
449
+ output = simulate_input('i') do
450
+ capture_output { SvnCommand.execute('get_message') }
451
+ end
452
+ assert_match "Message for r56 :".to_re, output
453
+ assert_equal ["svn propget --revprop svn:log -r head"], Subversion.executed
454
+ end
455
+ end
456
+
457
+ class SvnSetMessageTest < BaseSvnCommandTest
458
+ def test_1
459
+ Subversion.stubs(:status_against_server).returns("Status against revision: 56")
460
+ output = simulate_input('i') do
461
+ capture_output { SvnCommand.execute('set_message "this is my message"') }
462
+ end
463
+ assert_match "Message before changing:".to_re, output
464
+ assert_match "Message for r56 :".to_re, output
465
+ assert_equal [
466
+ "svn propget --revprop svn:log -r head",
467
+ "svn propset --revprop svn:log -r head 'this is my message'"
468
+ ], Subversion.executed
469
+ end
470
+ end
471
+
472
+ class SvnEditMessageTest < BaseSvnCommandTest
473
+ def test_1
474
+ Subversion.stubs(:status_against_server).returns("Status against revision: 56")
475
+ Subversion.stubs(:get_revision_property).returns("The value I just set it to using vim, my favorite editor")
476
+ output = simulate_input('i') do
477
+ capture_output { SvnCommand.execute('edit_message') }
478
+ end
479
+ assert_equal ["svn propedit --revprop svn:log ./ -r head"], Subversion.executed
480
+ end
481
+ end
482
+
483
+ class SvnEditMessageTest < BaseSvnCommandTest
484
+ def test_can_actually_delete_property_too
485
+ Subversion.stubs(:status_against_server).returns("Status against revision: 56")
486
+ Subversion.stubs(:get_revision_property).returns("")
487
+ output = simulate_input(
488
+ 'y' # Yes I'm sure I want to delete the svn:fooo property for this revision.
489
+ ) do
490
+ capture_output { SvnCommand.execute('edit_revision_property svn:foo') }
491
+ end
492
+ assert_match /Are you sure you want to delete/, output
493
+ assert_equal [
494
+ "svn propedit --revprop svn:foo ./ -r head",
495
+ "svn propdel --revprop svn:foo -r head"
496
+ ], Subversion.executed
497
+ end
498
+ end
499
+
500
+ #-----------------------------------------------------------------------------------------------------------------------------
501
+
502
+ class SvnViewCommitsTest < BaseSvnCommandTest
503
+ def test_parse_revision_ranges
504
+ assert_equal [134], SvnCommand.parse_revision_ranges(["134"])
505
+ assert_equal [134, 135, 136], SvnCommand.parse_revision_ranges(["134-136"])
506
+ assert_equal [134, 135, 136], SvnCommand.parse_revision_ranges(["134:136"])
507
+ assert_equal [134, 135, 136], SvnCommand.parse_revision_ranges(["134..136"])
508
+ assert_equal [134, 135, 136, 139], SvnCommand.parse_revision_ranges(["134-136", "139"])
509
+ end
510
+ def test_1
511
+ messages = Dictionary[
512
+ 14, "Committed a bunch of really important stuff.",
513
+ 15, "Fixed a typo.",
514
+ 30, "Injected a horrible defect."
515
+ ]
516
+ Subversion.stubs(:log).with("-r 14 -v ").returns(messages[14])
517
+ Subversion.stubs(:log).with("-r 15 -v ").returns(messages[15])
518
+ Subversion.stubs(:log).with("-r 30 -v ").returns(messages[30])
519
+ Subversion.stubs(:diff).returns(combined_diff = %q(
520
+ |Index: lib/svn_command.rb
521
+ |===================================================================
522
+ |--- lib/svn_command.rb (revision 2327)
523
+ |+++ lib/svn_command.rb (revision 2342)
524
+ |@@ -3,9 +3,11 @@
525
+ | require 'facets/more/command'
526
+ | require 'facets/core/string/margin'
527
+ | require 'facets/core/kernel/require_local'
528
+ |+require 'extensions/symbol'
529
+ | require 'pp'
530
+ | require 'termios'
531
+ | require 'stringio'
532
+ |+require 'escape' # http://www.a-k-r.org/escape/
533
+ ).margin)
534
+ output = capture_output { SvnCommand.execute('view-commits -r 14:15 30') }
535
+ assert_equal %Q(
536
+ |#{messages.values.join("\n")}
537
+ |#{combined_diff}
538
+ |
539
+ ).margin, output
540
+ end
541
+ end
542
+
543
+ #-----------------------------------------------------------------------------------------------------------------------------
544
+ # Changeset/commit/log Browser
545
+
546
+ class SvnRevisionsTest < BaseSvnCommandTest
547
+ def set_up_stubs
548
+ Subversion.stubs(:revisions).returns(
549
+ begin
550
+ RSCM::Revisions.class_eval do
551
+ attr_accessor :revisions
552
+ end
553
+ RSCM::Revision.class_eval do
554
+ attr_accessor :files
555
+ end
556
+
557
+ file1 = RSCM::RevisionFile.new
558
+ file1.status = 'added'.upcase
559
+ file1.path = 'dir/file1'
560
+ file2 = RSCM::RevisionFile.new
561
+ file2.status = 'modified'.upcase
562
+ file2.path = 'dir/file2'
563
+
564
+ revision1 = RSCM::Revision.new
565
+ revision1.identifier = 1800
566
+ revision1.developer = 'tyler'
567
+ revision1.time = Time.utc(2007, 12, 01)
568
+ revision1.message = 'I say! Quite the storm, what!'
569
+ revision1.files = [file1, file2]
570
+
571
+ revision2 = RSCM::Revision.new
572
+ revision2.identifier = 1801
573
+ revision2.developer = 'tyler'
574
+ revision2.time = Time.utc(2007, 12, 02)
575
+ revision2.message = 'These Romans are crazy!'
576
+ revision2.files = [file2]
577
+
578
+ revisions = RSCM::Revisions.new
579
+ revisions.revisions = [revision1, revision2]
580
+ end
581
+ )
582
+ Subversion.stubs(:latest_revision).returns(42)
583
+ Subversion.stubs(:latest_revision_for_path).returns(42)
584
+ Subversion.stubs(:diff).returns("the diff")
585
+ end
586
+
587
+ def test_view_changeset
588
+ set_up_stubs
589
+
590
+ output = simulate_input(
591
+ 'v' + # View this changeset
592
+ "\n" + # Continue to revision 1800
593
+ "\n" # Try to continue, but of course there won't be any more revisions, so it will exit.
594
+ ) do
595
+ capture_output { SvnCommand.execute('revisions') }
596
+ end
597
+ #puts output
598
+ #require 'unroller'
599
+ #Unroller::trace :exclude_classes => /PP|PrettyPrint/ do
600
+
601
+ assert_match Regexp.loose_join(
602
+ "Getting list of revisions for './' ...
603
+ 2 revisions found. Starting with most recent revision and going backward in time...",
604
+
605
+ # Show 1800
606
+ "2. r1800 | tyler | 2007-12-01 00:00:00
607
+ I say! Quite the storm, what!
608
+
609
+ A dir/file1
610
+ M dir/file2
611
+ r1800: View this changeset, Diff against specific revision, Grep the changeset, List or Edit revision properties, svn Cat all files, grep the cat,
612
+ mark as Reviewed, edit log Message, or browse using Up/Down/Enter keys >",
613
+
614
+ # Show the diff
615
+ "Diffing 1799:1800...",
616
+ "the diff",
617
+
618
+ # Show 1800 again
619
+ "r1800: View this changeset, Diff against specific revision, Grep the changeset, List or Edit revision properties, svn Cat all files, grep the cat,
620
+ mark as Reviewed, edit log Message, or browse using Up/Down/Enter keys > Next...",
621
+
622
+ # Now show 1801
623
+ "1. r1801 | tyler | 2007-12-02 00:00:00
624
+ These Romans are crazy!
625
+
626
+ M dir/file2
627
+ r1801: View this changeset, Diff against specific revision, Grep the changeset, List or Edit revision properties, svn Cat all files, grep the cat,
628
+ mark as Reviewed, edit log Message, or browse using Up/Down/Enter keys > Next...",
629
+ :multi_line => true
630
+ ), output
631
+
632
+
633
+ =begin
634
+ /.*/
635
+ }.*
636
+ =end
637
+
638
+
639
+ assert_equal [
640
+ #"svn status -u ./" # To find head
641
+ ], Subversion.executed
642
+ end
643
+ end
644
+
645
+
646
+ #-----------------------------------------------------------------------------------------------------------------------------
647
+ end #module Subversion
648
+
649
+