source: valtobtest/subversion-1.6.2/subversion/bindings/swig/ruby/test/test_client.rb @ 3

Last change on this file since 3 was 3, checked in by valtob, 15 years ago

subversion source 1.6.2 as test

File size: 70.1 KB
Line 
1require "my-assertions"
2require "util"
3
4require "svn/core"
5require "svn/client"
6
7class SvnClientTest < Test::Unit::TestCase
8  include SvnTestUtil
9
10  def setup
11    setup_basic(true)
12  end
13
14  def teardown
15    teardown_basic
16  end
17
18  def test_version
19    assert_equal(Svn::Core.subr_version, Svn::Client.version)
20  end
21
22  def test_add_not_recurse
23    log = "sample log"
24    dir = "dir"
25    dir_path = File.join(@wc_path, dir)
26    path = File.join(dir_path, dir)
27    uri = "#{@repos_uri}/#{dir}/#{dir}"
28
29    make_context(log) do |ctx|
30      FileUtils.mkdir(dir_path)
31      FileUtils.mkdir(path)
32      ctx.add(dir_path, false)
33      ctx.commit(@wc_path)
34
35      assert_raise(Svn::Error::FS_NOT_FOUND) do
36        ctx.cat(uri)
37      end
38    end
39  end
40
41  def test_add_recurse
42    log = "sample log"
43    file = "hello.txt"
44    src = "Hello"
45    dir = "dir"
46    dir_path = File.join(@wc_path, dir)
47    path = File.join(dir_path, file)
48    uri = "#{@repos_uri}/#{dir}/#{file}"
49
50    make_context(log) do |ctx|
51      FileUtils.mkdir(dir_path)
52      File.open(path, "w") {|f| f.print(src)}
53      ctx.add(dir_path)
54      ctx.commit(@wc_path)
55
56      assert_equal(src, ctx.cat(uri))
57    end
58  end
59
60  def test_add_force
61    log = "sample log"
62    file = "hello.txt"
63    src = "Hello"
64    dir = "dir"
65    dir_path = File.join(@wc_path, dir)
66    path = File.join(dir_path, file)
67    uri = "#{@repos_uri}/#{dir}/#{file}"
68
69    make_context(log) do |ctx|
70      FileUtils.mkdir(dir_path)
71      File.open(path, "w") {|f| f.print(src)}
72      ctx.add(dir_path, false)
73      ctx.commit(@wc_path)
74
75      assert_raise(Svn::Error::ENTRY_EXISTS) do
76        ctx.add(dir_path, true, false)
77      end
78
79      ctx.add(dir_path, true, true)
80      ctx.commit(@wc_path)
81      assert_equal(src, ctx.cat(uri))
82    end
83  end
84
85  def test_add_no_ignore
86    log = "sample log"
87    file = "hello.txt"
88    src = "Hello"
89    dir = "dir"
90    dir_path = File.join(@wc_path, dir)
91    path = File.join(dir_path, file)
92    uri = "#{@repos_uri}/#{dir}/#{file}"
93
94    make_context(log) do |ctx|
95      FileUtils.mkdir(dir_path)
96      ctx.add(dir_path, false)
97      ctx.propset(Svn::Core::PROP_IGNORE, file, dir_path)
98      ctx.commit(@wc_path)
99
100      File.open(path, "w") {|f| f.print(src)}
101
102      ctx.add(dir_path, true, true, false)
103      ctx.commit(@wc_path)
104      assert_raise(Svn::Error::FS_NOT_FOUND) do
105        ctx.cat(uri)
106      end
107
108      ctx.add(dir_path, true, true, true)
109      ctx.commit(@wc_path)
110      assert_equal(src, ctx.cat(uri))
111    end
112  end
113
114  def test_mkdir
115    log = "sample log"
116    dir = "dir"
117    deep_dir = ["d", "e", "e", "p"]
118    dir2 = "dir2"
119    dir_uri = "#{@repos_uri}/#{dir}"
120    deep_dir_uri = "#{@repos_uri}/#{deep_dir.join('/')}"
121    dir2_uri = "#{@repos_uri}/#{dir2}"
122    dir_path = File.join(@wc_path, dir)
123    deep_dir_path = File.join(@wc_path, *deep_dir)
124    dir2_path = File.join(@wc_path, dir2)
125
126    make_context(log) do |ctx|
127
128      assert(!File.exist?(dir_path))
129      ctx.mkdir(dir_path)
130      assert(File.exist?(dir_path))
131      assert_raises(Svn::Error::EntryExists) do
132        ctx.add(dir_path)
133      end
134      old_rev = ctx.commit(@wc_path).revision
135
136      new_rev = ctx.mkdir(dir2_uri).revision
137      assert_equal(old_rev + 1, new_rev)
138      assert_raises(Svn::Error::FsAlreadyExists) do
139        ctx.mkdir(dir2_uri)
140      end
141      assert(!File.exist?(dir2_path))
142      ctx.update(@wc_path)
143      assert(File.exist?(dir2_path))
144
145      assert_raises(Svn::Error::SvnError) do
146        ctx.mkdir(deep_dir_path)
147      end
148    end
149  end
150
151  def assert_mkdir_with_multiple_paths
152    log = "sample log"
153    dir = "dir"
154    dir2 = "dir2"
155    dirs = [dir, dir2]
156    dirs_path = dirs.collect {|d| Pathname.new(@wc_path) + d}
157    dirs_full_path = dirs_path.collect {|path| path.expand_path}
158
159    make_context(log) do |ctx|
160
161      infos = []
162      ctx.set_notify_func do |notify|
163        infos << [notify.path, notify]
164      end
165
166      assert_equal([false, false], dirs_path.collect {|path| path.exist?})
167      yield(ctx, dirs_path.collect {|path| path.to_s})
168      assert_equal(dirs_path.collect {|path| path.to_s}.sort,
169                   infos.collect{|path, notify| path}.sort)
170      assert_equal([true] * dirs_path.size,
171                   infos.collect{|path, notify| notify.add?})
172      assert_equal([true, true], dirs_path.collect {|path| path.exist?})
173
174      infos.clear
175      ctx.commit(@wc_path)
176      assert_equal(dirs_full_path.collect {|path| path.to_s}.sort,
177                   infos.collect{|path, notify| path}.sort)
178      assert_equal([true] * dirs_path.size,
179                   infos.collect{|path, notify| notify.commit_added?})
180    end
181  end
182
183  def test_mkdir_with_multiple_paths
184    assert_mkdir_with_multiple_paths do |ctx, dirs|
185      ctx.mkdir(*dirs)
186    end
187  end
188
189  def test_mkdir_with_multiple_paths_as_array
190    assert_mkdir_with_multiple_paths do |ctx, dirs|
191      ctx.mkdir(dirs)
192    end
193  end
194
195  def test_mkdir_p
196    log = "sample log"
197    dir = "parent"
198    child_dir = "parent/child"
199    dir_path = Pathname.new(@wc_path) + dir
200    child_dir_path = dir_path + "child"
201    full_paths = [dir_path, child_dir_path].collect {|path| path.expand_path}
202
203    make_context(log) do |ctx|
204
205      infos = []
206      ctx.set_notify_func do |notify|
207        infos << [notify.path, notify]
208      end
209
210      assert_equal([false, false], [dir_path.exist?, child_dir_path.exist?])
211      ctx.mkdir_p(child_dir_path.to_s)
212      assert_equal(full_paths.collect {|path| path.to_s}.sort,
213                   infos.collect{|path, notify| path}.sort)
214      assert_equal([true, true],
215                   infos.collect{|path, notify| notify.add?})
216      assert_equal([true, true], [dir_path.exist?, child_dir_path.exist?])
217
218      infos.clear
219      ctx.commit(@wc_path)
220      assert_equal(full_paths.collect {|path| path.to_s}.sort,
221                   infos.collect{|path, notify| path}.sort)
222      assert_equal([true, true],
223                   infos.collect{|path, notify| notify.commit_added?})
224    end
225  end
226
227  def test_delete
228    log = "sample log"
229    src = "sample source\n"
230    file = "file.txt"
231    dir = "dir"
232    path = File.join(@wc_path, file)
233    dir_path = File.join(@wc_path, dir)
234
235    make_context(log) do |ctx|
236
237      File.open(path, "w") {|f| f.print(src)}
238      ctx.add(path)
239      ctx.mkdir(dir_path)
240      ctx.commit(@wc_path)
241
242      ctx.delete([path, dir_path])
243      ctx.commit(@wc_path)
244      assert(!File.exist?(path))
245      assert(!File.exist?(dir_path))
246
247
248      File.open(path, "w") {|f| f.print(src)}
249      ctx.add(path)
250      ctx.commit(@wc_path)
251
252      File.open(path, "w") {|f| f.print(src * 2)}
253      assert_raises(Svn::Error::ClientModified) do
254        ctx.delete(path)
255      end
256      assert_nothing_raised do
257        ctx.delete(path, true)
258        ctx.commit(@wc_path)
259      end
260      assert(!File.exist?(path))
261    end
262  end
263
264  def test_delete_alias
265    log = "sample log"
266    src = "sample source\n"
267    file = "file.txt"
268    dir = "dir"
269    path = File.join(@wc_path, file)
270    dir_path = File.join(@wc_path, dir)
271
272    make_context(log) do |ctx|
273
274      File.open(path, "w") {|f| f.print(src)}
275      ctx.add(path)
276      ctx.mkdir(dir_path)
277      ctx.commit(@wc_path)
278
279      ctx.rm([path, dir_path])
280      ctx.commit(@wc_path)
281      assert(!File.exist?(path))
282      assert(!File.exist?(dir_path))
283
284
285      File.open(path, "w") {|f| f.print(src)}
286      ctx.add(path)
287      ctx.commit(@wc_path)
288
289      File.open(path, "w") {|f| f.print(src * 2)}
290      assert_raises(Svn::Error::ClientModified) do
291        ctx.rm(path)
292      end
293      assert_nothing_raised do
294        ctx.rm_f(path)
295        ctx.commit(@wc_path)
296      end
297      assert(!File.exist?(path))
298
299      File.open(path, "w") {|f| f.print(src)}
300      ctx.add(path)
301      ctx.mkdir(dir_path)
302      ctx.commit(@wc_path)
303
304      ctx.rm_f(path, dir_path)
305      ctx.commit(@wc_path)
306      assert(!File.exist?(path))
307      assert(!File.exist?(dir_path))
308    end
309  end
310
311  def test_import
312    src = "source\n"
313    log = "sample log"
314    deep_dir = File.join(%w(a b c d e))
315    file = "sample.txt"
316    deep_dir_path = File.join(@wc_path, deep_dir)
317    path = File.join(deep_dir_path, file)
318    tmp_deep_dir_path = File.join(@tmp_path, deep_dir)
319    tmp_path = File.join(tmp_deep_dir_path, file)
320
321    make_context(log) do |ctx|
322
323      FileUtils.mkdir_p(tmp_deep_dir_path)
324      File.open(tmp_path, "w") {|f| f.print(src)}
325
326      ctx.import(@tmp_path, @repos_uri)
327
328      ctx.up(@wc_path)
329      assert_equal(src, File.open(path){|f| f.read})
330    end
331  end
332
333  def test_import_custom_revprops
334    src = "source\n"
335    log = "sample log"
336    deep_dir = File.join(%w(a b c d e))
337    file = "sample.txt"
338    deep_dir_path = File.join(@wc_path, deep_dir)
339    path = File.join(deep_dir_path, file)
340    tmp_deep_dir_path = File.join(@tmp_path, deep_dir)
341    tmp_path = File.join(tmp_deep_dir_path, file)
342
343    make_context(log) do |ctx|
344
345      FileUtils.mkdir_p(tmp_deep_dir_path)
346      File.open(tmp_path, "w") {|f| f.print(src)}
347
348      new_rev = ctx.import(@tmp_path, @repos_uri, true, false,
349                           {"custom-prop" => "some-value"}).revision
350      assert_equal(["some-value", new_rev],
351                   ctx.revprop_get("custom-prop", @repos_uri, new_rev))
352
353      ctx.up(@wc_path)
354      assert_equal(src, File.open(path){|f| f.read})
355    end
356  end
357
358  def test_commit
359    log = "sample log"
360    dir1 = "dir1"
361    dir2 = "dir2"
362    dir1_path = File.join(@wc_path, dir1)
363    dir2_path = File.join(dir1_path, dir2)
364
365    make_context(log) do |ctx|
366      assert_equal(Svn::Core::INVALID_REVNUM,ctx.commit(@wc_path).revision)
367      ctx.mkdir(dir1_path)
368      assert_equal(0, youngest_rev)
369      assert_equal(1, ctx.commit(@wc_path).revision)
370      ctx.mkdir(dir2_path)
371      assert_equal(Svn::Core::INVALID_REVNUM,ctx.commit(@wc_path, false).revision)
372      assert_equal(2, ctx.ci(@wc_path).revision)
373    end
374  end
375
376  def test_status
377    log = "sample log"
378    file1 = "sample1.txt"
379    file2 = "sample2.txt"
380    dir = "dir"
381    dir_path = File.join(@wc_path, dir)
382    path1 = File.join(@wc_path, file1)
383    path2 = File.join(dir_path, file2)
384
385    make_context(log) do |ctx|
386      File.open(path1, "w") {}
387      ctx.add(path1)
388      rev1 = ctx.commit(@wc_path).revision
389
390
391      ctx.mkdir(dir_path)
392      File.open(path2, "w") {}
393
394      infos = []
395      rev = ctx.status(@wc_path) do |path, status|
396        infos << [path, status]
397      end
398
399      assert_equal(youngest_rev, rev)
400      assert_equal([dir_path, path2].sort,
401                   infos.collect{|path, status| path}.sort)
402      dir_status = infos.assoc(dir_path).last
403      assert(dir_status.text_added?)
404      assert(dir_status.entry.dir?)
405      assert(dir_status.entry.add?)
406      path2_status = infos.assoc(path2).last
407      assert(!path2_status.text_added?)
408      assert_nil(path2_status.entry)
409
410
411      infos = []
412      rev = ctx.st(@wc_path, rev1, true, true) do |path, status|
413        infos << [path, status]
414      end
415
416      assert_equal(rev1, rev)
417      assert_equal([@wc_path, dir_path, path1, path2].sort,
418                   infos.collect{|path, status| path}.sort)
419      wc_status = infos.assoc(@wc_path).last
420      assert(wc_status.text_normal?)
421      assert(wc_status.entry.dir?)
422      assert(wc_status.entry.normal?)
423      dir_status = infos.assoc(dir_path).last
424      assert(dir_status.text_added?)
425      assert(dir_status.entry.dir?)
426      assert(dir_status.entry.add?)
427      path1_status = infos.assoc(path1).last
428      assert(path1_status.text_normal?)
429      assert(path1_status.entry.file?)
430      assert(path1_status.entry.normal?)
431      path2_status = infos.assoc(path2).last
432      assert(!path2_status.text_added?)
433      assert_nil(path2_status.entry)
434
435
436      ctx.prop_set(Svn::Core::PROP_IGNORE, file2, dir_path)
437
438      infos = []
439      rev = ctx.status(@wc_path, nil, true, true, true, false) do |path, status|
440        infos << [path, status]
441      end
442
443      assert_equal(rev1, rev)
444      assert_equal([@wc_path, dir_path, path1].sort,
445                   infos.collect{|path, status| path}.sort)
446
447
448      infos = []
449      rev = ctx.status(@wc_path, nil, true, true, true, true) do |path, status|
450        infos << [path, status]
451      end
452
453      assert_equal(rev1, rev)
454      assert_equal([@wc_path, dir_path, path1, path2].sort,
455                   infos.collect{|path, status| path}.sort)
456      end
457  end
458
459  def test_status_with_depth
460    setup_greek_tree
461
462    log = "sample log"
463      make_context(log) do |ctx|
464
465      # make everything out-of-date
466      ctx.prop_set('propname', 'propvalue', @greek.path(:b), :infinity)
467
468      recurse_and_depth_choices.each do |rd|
469        ctx.status(@greek.path(:mu), nil, rd) do |path, status|
470          assert_equal @greek.uri(:mu), status.url
471        end
472      end
473
474      expected_statuses_by_depth = {
475        true => [:beta, :b, :lambda, :e, :f, :alpha],
476        false => [:b, :lambda, :e, :f],
477        'empty' => [:b],
478        'files' => [:b, :lambda],
479        'immediates' => [:b, :lambda, :e, :f],
480        'infinity' => [:beta, :b, :lambda, :e, :f, :alpha],
481      }
482
483      recurse_and_depth_choices.each do |rd|
484        urls = []
485        ctx.status(@greek.path(:b), nil, rd) do |path, status|
486          urls << status.url
487        end
488        assert_equal(expected_statuses_by_depth[rd].map{|s| @greek.uri(s)}.sort,
489                     urls.sort,
490                     "depth '#{rd}")
491      end
492    end
493  end
494
495  def test_checkout
496    log = "sample log"
497    file = "hello.txt"
498    dir = "dir"
499    dir_path = File.join(@wc_path, dir)
500    path = File.join(dir_path, file)
501    content = "Hello"
502
503    make_context(log) do |ctx|
504      ctx.mkdir(dir_path)
505      File.open(path, "w"){|f| f.print(content)}
506      ctx.add(path)
507      ctx.commit(@wc_path)
508
509      FileUtils.rm_rf(@wc_path)
510      ctx.checkout(@repos_uri, @wc_path)
511      assert(File.exist?(path))
512
513      FileUtils.rm_rf(@wc_path)
514      ctx.co(@repos_uri, @wc_path, nil, nil, false)
515      assert(!File.exist?(path))
516    end
517  end
518
519  def test_update
520    log = "sample log"
521    file = "hello.txt"
522    path = File.join(@wc_path, file)
523    content = "Hello"
524    File.open(path, "w"){|f| f.print(content)}
525
526    make_context(log) do |ctx|
527
528      assert_nothing_raised do
529        ctx.update(File.join(@wc_path, "non-exist"), youngest_rev)
530      end
531
532      ctx.add(path)
533      commit_info = ctx.commit(@wc_path)
534
535      FileUtils.rm(path)
536      assert(!File.exist?(path))
537      assert_equal(commit_info.revision,
538                   ctx.update(path, commit_info.revision))
539      assert_equal(content, File.read(path))
540
541      FileUtils.rm(path)
542      assert(!File.exist?(path))
543      assert_equal([commit_info.revision],
544                   ctx.update([path], commit_info.revision))
545      assert_equal(content, File.read(path))
546
547      assert_raise(Svn::Error::FS_NO_SUCH_REVISION) do
548        begin
549          ctx.update(path, commit_info.revision + 1)
550        ensure
551          ctx.cleanup(@wc_path)
552        end
553      end
554      assert_nothing_raised do
555        ctx.update(path + "non-exist", commit_info.revision)
556      end
557    end
558  end
559
560  def test_revert
561    log = "sample log"
562    file1 = "hello1.txt"
563    file2 = "hello2.txt"
564    file3 = "hello3.txt"
565    dir = "dir"
566    dir_path = File.join(@wc_path, dir)
567    path1 = File.join(@wc_path, file1)
568    path2 = File.join(@wc_path, file2)
569    path3 = File.join(dir_path, file3)
570    content = "Hello"
571
572    make_context(log) do |ctx|
573      File.open(path1, "w"){|f| f.print(content)}
574      File.open(path2, "w"){|f| f.print(content)}
575      ctx.add(path1)
576      ctx.add(path2)
577      ctx.mkdir(dir_path)
578      File.open(path3, "w"){|f| f.print(content)}
579      ctx.add(path3)
580      commit_info = ctx.commit(@wc_path)
581
582      File.open(path1, "w"){}
583      assert_equal("", File.open(path1){|f| f.read})
584
585      ctx.revert(path1)
586      assert_equal(content, File.open(path1){|f| f.read})
587
588      File.open(path1, "w"){}
589      File.open(path2, "w"){}
590      assert_equal("", File.open(path1){|f| f.read})
591      assert_equal("", File.open(path2){|f| f.read})
592      ctx.revert([path1, path2])
593      assert_equal(content, File.open(path1){|f| f.read})
594      assert_equal(content, File.open(path2){|f| f.read})
595
596      File.open(path1, "w"){}
597      File.open(path2, "w"){}
598      File.open(path3, "w"){}
599      assert_equal("", File.open(path1){|f| f.read})
600      assert_equal("", File.open(path2){|f| f.read})
601      assert_equal("", File.open(path3){|f| f.read})
602      ctx.revert(@wc_path)
603      assert_equal(content, File.open(path1){|f| f.read})
604      assert_equal(content, File.open(path2){|f| f.read})
605      assert_equal(content, File.open(path3){|f| f.read})
606
607      File.open(path1, "w"){}
608      File.open(path2, "w"){}
609      File.open(path3, "w"){}
610      assert_equal("", File.open(path1){|f| f.read})
611      assert_equal("", File.open(path2){|f| f.read})
612      assert_equal("", File.open(path3){|f| f.read})
613      ctx.revert(@wc_path, false)
614      assert_equal("", File.open(path1){|f| f.read})
615      assert_equal("", File.open(path2){|f| f.read})
616      assert_equal("", File.open(path3){|f| f.read})
617
618      File.open(path1, "w"){}
619      File.open(path2, "w"){}
620      File.open(path3, "w"){}
621      assert_equal("", File.open(path1){|f| f.read})
622      assert_equal("", File.open(path2){|f| f.read})
623      assert_equal("", File.open(path3){|f| f.read})
624      ctx.revert(dir_path)
625      assert_equal("", File.open(path1){|f| f.read})
626      assert_equal("", File.open(path2){|f| f.read})
627      assert_equal(content, File.open(path3){|f| f.read})
628    end
629  end
630
631  def test_log
632    log1 = "sample log1"
633    log2 = "sample log2"
634    log3 = "sample log3"
635    src1 = "source1\n"
636    src2 = "source2\n"
637    src3 = "source3\n"
638    file1 = "sample1.txt"
639    file2 = "sample2.txt"
640    file3 = "sample3.txt"
641    path1 = File.join(@wc_path, file1)
642    path2 = File.join(@wc_path, file2)
643    path3 = File.join(@wc_path, file3)
644    abs_path1 = File.join('', file1)
645    abs_path2 = File.join('', file2)
646    abs_path3 = File.join('', file3)
647
648    rev1 = make_context(log1) do |ctx|
649      File.open(path1, "w") {|f| f.print(src1)}
650      ctx.add(path1)
651      rev1 = ctx.ci(@wc_path).revision
652    end
653
654    rev2 = make_context(log2) do |ctx|
655      ctx.cp(path1, path2)
656      rev2 = ctx.ci(@wc_path).revision
657    end
658
659    make_context(log3) do |ctx|
660      ctx.cp(path1, path3)
661      File.open(path1, "w") {|f| f.print(src2)}
662      File.open(path3, "w") {|f| f.print(src3)}
663      rev3 = ctx.ci(@wc_path).revision
664
665      changed_paths_lists = {}
666      revs = {}
667      messages = {}
668      keys = [@wc_path, path1, path2, path3]
669      keys.each do |key|
670        revs[key] = []
671        changed_paths_lists[key] = []
672        messages[key] = []
673        args = [key, 1, "HEAD", 0, true, nil]
674        ctx.log(*args) do |changed_paths, rev, author, date, message|
675          revs[key] << rev
676          changed_paths_lists[key] << changed_paths
677          messages[key] << message
678        end
679      end
680      changed_paths_list = changed_paths_lists[@wc_path]
681
682      assert_equal([rev1, rev2, rev3], revs[@wc_path])
683      assert_equal([rev1, rev3], revs[path1])
684      assert_equal([rev1, rev2], revs[path2])
685      assert_equal([rev1, rev3], revs[path3])
686      assert_equal([log1, log2, log3], messages[@wc_path])
687
688      expected = [[abs_path1], [abs_path2], [abs_path1, abs_path3]]
689      actual = changed_paths_list.collect {|changed_paths| changed_paths.keys}
690      assert_nested_sorted_array(expected, actual)
691
692      assert_equal('A', changed_paths_list[0][abs_path1].action)
693      assert_false(changed_paths_list[0][abs_path1].copied?)
694      assert_equal('A', changed_paths_list[1][abs_path2].action)
695      assert_true(changed_paths_list[1][abs_path2].copied?)
696      assert_equal(abs_path1, changed_paths_list[1][abs_path2].copyfrom_path)
697      assert_equal(rev1, changed_paths_list[1][abs_path2].copyfrom_rev)
698      assert_equal('M', changed_paths_list[2][abs_path1].action)
699      assert_equal('A', changed_paths_list[2][abs_path3].action)
700    end
701  end
702
703  def test_log_message
704    log = "sample log"
705    file = "hello.txt"
706    path = File.join(@wc_path, file)
707    FileUtils.touch(path)
708
709    make_context(log) do |ctx|
710      ctx.add(path)
711      commit_info = ctx.commit(@wc_path)
712      rev = commit_info.revision
713
714      assert_equal(log, ctx.log_message(path, rev))
715    end
716  end
717
718  def test_blame
719    log = "sample log"
720    file = "hello.txt"
721    srcs = %w(first second third)
722    infos = []
723    path = File.join(@wc_path, file)
724
725    make_context(log) do |ctx|
726
727      File.open(path, "w") {|f| f.puts(srcs[0])}
728      ctx.add(path)
729      commit_info = ctx.commit(@wc_path)
730      infos << [0, commit_info.revision, @author, commit_info.date, srcs[0]]
731
732      File.open(path, "a") {|f| f.puts(srcs[1])}
733      commit_info = ctx.commit(@wc_path)
734      infos << [1, commit_info.revision, @author, commit_info.date, srcs[1]]
735
736      File.open(path, "a") {|f| f.puts(srcs[2])}
737      commit_info = ctx.commit(@wc_path)
738      infos << [2, commit_info.revision, @author, commit_info.date, srcs[2]]
739
740      result = []
741      ctx.blame(path) do |line_no, revision, author, date, line|
742        result << [line_no, revision, author, date, line]
743      end
744      assert_equal(infos, result)
745
746
747      ctx.prop_set(Svn::Core::PROP_MIME_TYPE, "image/DUMMY", path)
748      ctx.commit(@wc_path)
749
750      assert_raise(Svn::Error::CLIENT_IS_BINARY_FILE) do
751        ctx.ann(path) {}
752      end
753    end
754  end
755
756  def test_diff
757    log = "sample log"
758    before = "before\n"
759    after = "after\n"
760    file = "hello.txt"
761    path = File.join(@wc_path, file)
762
763    File.open(path, "w") {|f| f.print(before)}
764
765    make_context(log) do |ctx|
766      ctx.add(path)
767      commit_info = ctx.commit(@wc_path)
768      rev1 = commit_info.revision
769
770      File.open(path, "w") {|f| f.print(after)}
771
772      out_file = Tempfile.new("svn")
773      err_file = Tempfile.new("svn")
774      ctx.diff([], path, rev1, path, "WORKING", out_file.path, err_file.path)
775      out_file.open
776      assert_match(/-#{before}\+#{after}\z/, out_file.read)
777
778      commit_info = ctx.commit(@wc_path)
779      rev2 = commit_info.revision
780      out_file = Tempfile.new("svn")
781      ctx.diff([], path, rev1, path, rev2, out_file.path, err_file.path)
782      out_file.open
783      assert_match(/-#{before}\+#{after}\z/, out_file.read)
784    end
785  end
786
787  def test_diff_peg
788    log = "sample log"
789    before = "before\n"
790    after = "after\n"
791    file = "hello.txt"
792    path = File.join(@wc_path, file)
793
794    File.open(path, "w") {|f| f.print(before)}
795
796    make_context(log) do |ctx|
797      ctx.add(path)
798      commit_info = ctx.commit(@wc_path)
799      rev1 = commit_info.revision
800
801      File.open(path, "w") {|f| f.print(after)}
802
803      out_file = Tempfile.new("svn")
804      err_file = Tempfile.new("svn")
805      ctx.diff_peg([], path, rev1, "WORKING", out_file.path, err_file.path)
806      out_file.open
807      assert_match(/-#{before}\+#{after}\z/, out_file.read)
808
809      commit_info = ctx.commit(@wc_path)
810      rev2 = commit_info.revision
811      out_file = Tempfile.new("svn")
812      ctx.diff_peg([], path, rev1, rev2, out_file.path, err_file.path)
813      out_file.open
814      assert_match(/-#{before}\+#{after}\z/, out_file.read)
815    end
816  end
817
818  def test_diff_summarize
819    log = "sample log"
820    before = "before\n"
821    after = "after\n"
822    file = "hello.txt"
823    path = File.join(@wc_path, file)
824
825    File.open(path, "w") {|f| f.print(before)}
826
827    make_context(log) do |ctx|
828      ctx.add(path)
829      commit_info = ctx.commit(@wc_path)
830      rev1 = commit_info.revision
831
832      File.open(path, "w") {|f| f.print(after)}
833
834      commit_info = ctx.commit(@wc_path)
835      rev2 = commit_info.revision
836
837      diffs = []
838      ctx.diff_summarize(@wc_path, rev1, @wc_path, rev2) do |diff|
839        diffs << diff
840      end
841      assert_equal([file], diffs.collect {|d| d.path})
842      kinds = diffs.collect do |d|
843        [d.kind_normal?, d.kind_added?, d.kind_modified?, d.kind_deleted?]
844      end
845      assert_equal([[false, false, true, false]], kinds)
846      assert_equal([false], diffs.collect {|d| d.prop_changed?})
847      node_kinds = diffs.collect do |d|
848        [d.node_kind_none?, d.node_kind_file?,
849         d.node_kind_dir?, d.node_kind_unknown?]
850      end
851      assert_equal([[false, true, false, false]], node_kinds)
852    end
853  end
854
855  def test_diff_summarize_peg
856    log = "sample log"
857    before = "before\n"
858    after = "after\n"
859    before_file = "before.txt"
860    after_file = "after.txt"
861    moved_file = "moved.txt"
862    before_path = File.join(@wc_path, before_file)
863    after_path = File.join(@wc_path, after_file)
864    moved_path = File.join(@wc_path, moved_file)
865
866    File.open(before_path, "w") {|f| f.print(before)}
867
868    make_context(log) do |ctx|
869      ctx.add(before_path)
870      commit_info = ctx.commit(@wc_path)
871      rev1 = commit_info.revision
872
873      ctx.mv(before_path, after_path)
874      commit_info = ctx.commit(@wc_path)
875      rev2 = commit_info.revision
876
877      File.open(after_path, "w") {|f| f.print(after)}
878      commit_info = ctx.commit(@wc_path)
879      rev3 = commit_info.revision
880
881      File.open(after_path, "w") {|f| f.print(before)}
882      commit_info = ctx.commit(@wc_path)
883      rev4 = commit_info.revision
884
885      ctx.mv(after_path, moved_path)
886      commit_info = ctx.commit(@wc_path)
887      rev5 = commit_info.revision
888
889      diffs = []
890      ctx.diff_summarize_peg(@repos_uri, rev3, rev4, rev3) do |diff|
891        diffs << diff
892      end
893      assert_equal([after_file], diffs.collect {|d| d.path})
894      kinds = diffs.collect do |d|
895        [d.kind_normal?, d.kind_added?, d.kind_modified?, d.kind_deleted?]
896      end
897      assert_equal([[false, false, true, false]], kinds)
898      assert_equal([false], diffs.collect {|d| d.prop_changed?})
899      node_kinds = diffs.collect do |d|
900        [d.node_kind_none?, d.node_kind_file?,
901         d.node_kind_dir?, d.node_kind_unknown?]
902      end
903      assert_equal([[false, true, false, false]], node_kinds)
904    end
905  end
906
907  def assert_changed(ctx, path)
908    statuses = []
909    ctx.status(path) do |_, status|
910      statuses << status
911    end
912    assert_not_equal([], statuses)
913  end
914
915  def assert_not_changed(ctx, path)
916    statuses = []
917    ctx.status(path) do |_, status|
918      statuses << status
919    end
920    assert_equal([], statuses)
921  end
922
923  def assert_merge
924    log = "sample log"
925    file = "sample.txt"
926    src = "sample\n"
927    trunk = File.join(@wc_path, "trunk")
928    branch = File.join(@wc_path, "branch")
929    branch_relative_uri = "/branch"
930    branch_uri = "#{@repos_uri}#{branch_relative_uri}"
931    trunk_path = File.join(trunk, file)
932    trunk_path_uri = "#{@repos_uri}/trunk/#{file}"
933    branch_path = File.join(branch, file)
934    branch_path_relative_uri = "#{branch_relative_uri}/#{file}"
935    branch_path_uri = "#{@repos_uri}#{branch_path_relative_uri}"
936
937    make_context(log) do |ctx|
938      ctx.mkdir(trunk, branch)
939      File.open(trunk_path, "w") {}
940      File.open(branch_path, "w") {}
941      ctx.add(trunk_path)
942      ctx.add(branch_path)
943      rev1 = ctx.commit(@wc_path).revision
944
945      File.open(branch_path, "w") {|f| f.print(src)}
946      rev2 = ctx.commit(@wc_path).revision
947
948      merged_entries = []
949      ctx.log_merged(trunk, nil, branch_uri, nil) do |entry|
950        merged_entries << entry
951      end
952      assert_equal_log_entries([], merged_entries)
953      assert_nil(ctx.merged(trunk))
954
955      merged_entries = []
956      yield(ctx, branch, rev1, rev2, trunk)
957      ctx.log_merged(trunk, nil, branch_uri, nil) do |entry|
958        merged_entries << entry
959      end
960      assert_equal_log_entries([
961                                [
962                                 {branch_path_relative_uri => ["M", nil, -1]},
963                                 rev2,
964                                 {
965                                   "svn:author" => @author,
966                                   "svn:log" => log,
967                                 },
968                                 false,
969                                ]
970                               ],
971                               merged_entries)
972      mergeinfo = ctx.merged(trunk)
973      assert_not_nil(mergeinfo)
974      assert_equal([branch_uri], mergeinfo.keys)
975      ranges = mergeinfo[branch_uri].collect {|range| range.to_a}
976      assert_equal([[1, 2, true]], ranges)
977
978      rev3 = ctx.commit(@wc_path).revision
979
980      assert_equal(normalize_line_break(src), ctx.cat(trunk_path, rev3))
981
982      ctx.rm(branch_path)
983      rev4 = ctx.commit(@wc_path).revision
984
985      yield(ctx, branch, rev3, rev4, trunk)
986      assert(!File.exist?(trunk_path))
987
988      merged_entries = []
989      ctx.log_merged(trunk, rev4, branch_uri, rev4) do |entry|
990        merged_entries << entry
991      end
992      assert_equal_log_entries([
993                                [
994                                 {branch_path_relative_uri => ["D", nil, -1]},
995                                 rev4,
996                                 {
997                                   "svn:author" => @author,
998                                   "svn:log" => log,
999                                 },
1000                                 false,
1001                                ]
1002                               ] * 2, merged_entries)
1003
1004      ctx.propdel("svn:mergeinfo", trunk)
1005      merged_entries = []
1006      ctx.log_merged(trunk, rev4, branch_uri, rev4) do |entry|
1007        merged_entries << entry
1008      end
1009      assert_equal_log_entries([], merged_entries)
1010
1011      ctx.revert(trunk)
1012      File.open(trunk_path, "a") {|f| f.print(src)}
1013      yield(ctx, branch, rev3, rev4, trunk)
1014      ctx.revert(trunk, false)
1015      ctx.resolve(:path=>trunk_path,
1016                  :conflict_choice=>Svn::Wc::CONFLICT_CHOOSE_MINE_FULL)
1017      rev5 = ctx.commit(@wc_path).revision
1018      assert(File.exist?(trunk_path))
1019      ctx.up(@wc_path)
1020
1021      yield(ctx, branch, rev3, rev4, trunk, nil, false, true)
1022      assert_changed(ctx, trunk)
1023
1024      ctx.propdel("svn:mergeinfo", trunk)
1025      rev6 = ctx.commit(@wc_path).revision
1026
1027      yield(ctx, branch, rev3, rev4, trunk, nil, false, true, true)
1028      assert_not_changed(ctx, trunk)
1029
1030      yield(ctx, branch, rev3, rev4, trunk, nil, false, true)
1031      assert_changed(ctx, trunk)
1032    end
1033  end
1034
1035  def test_merge
1036    assert_merge do |ctx, from, from_rev1, from_rev2, to, *rest|
1037      ctx.merge(from, from_rev1, from, from_rev2, to, *rest)
1038    end
1039  end
1040
1041  def test_merge_peg
1042    assert_merge do |ctx, from, from_rev1, from_rev2, to, *rest|
1043      ctx.merge_peg(from, from_rev1, from_rev2, to, nil, *rest)
1044    end
1045  end
1046
1047  def test_cleanup
1048    log = "sample log"
1049    file = "sample.txt"
1050    src = "sample\n"
1051    path = File.join(@wc_path, file)
1052
1053    make_context(log) do |ctx|
1054      File.open(path, "w") {|f| f.print(src)}
1055      ctx.add(path)
1056      rev = ctx.commit(@wc_path).revision
1057
1058      ctx.up(@wc_path, rev - 1)
1059      File.open(path, "w") {|f| f.print(src)}
1060
1061      assert_raise(Svn::Error::WC_OBSTRUCTED_UPDATE) do
1062        ctx.up(@wc_path, rev)
1063      end
1064
1065      Svn::Wc::AdmAccess.open(nil, @wc_path, true, -1) do |access|
1066        assert_raise(Svn::Error::WC_LOCKED) do
1067          ctx.commit(@wc_path)
1068        end
1069      end
1070
1071      ctx.set_cancel_func do
1072        raise Svn::Error::CANCELLED
1073      end
1074      Svn::Wc::AdmAccess.open(nil, @wc_path, true, -1) do |access|
1075        assert_raise(Svn::Error::CANCELLED) do
1076          ctx.cleanup(@wc_path)
1077        end
1078        assert_raise(Svn::Error::WC_LOCKED) do
1079          ctx.commit(@wc_path)
1080        end
1081      end
1082
1083      ctx.set_cancel_func(nil)
1084      access = Svn::Wc::AdmAccess.open(nil, @wc_path, true, -1)
1085      assert_nothing_raised do
1086        ctx.cleanup(@wc_path)
1087      end
1088      assert_nothing_raised do
1089        ctx.commit(@wc_path)
1090      end
1091      assert_raises(Svn::Error::SvnError) do
1092        access.close
1093      end
1094    end
1095  end
1096
1097  def test_relocate
1098    log = "sample log"
1099    file = "sample.txt"
1100    src = "sample\n"
1101    path = File.join(@wc_path, file)
1102
1103    make_context(log) do |ctx|
1104      File.open(path, "w") {|f| f.print(src)}
1105      ctx.add(path)
1106      ctx.commit(@wc_path)
1107
1108      assert_nothing_raised do
1109        ctx.cat(path)
1110      end
1111
1112      ctx.add_simple_prompt_provider(0) do |cred, realm, username, may_save|
1113        cred.username = @author
1114        cred.password = @password
1115        cred.may_save = true
1116      end
1117      ctx.relocate(@wc_path, @repos_uri, @repos_svnserve_uri)
1118
1119      make_context(log) do |ctx|
1120        assert_raises(Svn::Error::AuthnNoProvider) do
1121          ctx.cat(path)
1122        end
1123      end
1124    end
1125  end
1126
1127  def test_resolved
1128    log = "sample log"
1129    file = "sample.txt"
1130    dir = "dir"
1131    src1 = "before\n"
1132    src2 = "after\n"
1133    dir_path = File.join(@wc_path, dir)
1134    path = File.join(dir_path, file)
1135
1136    make_context(log) do |ctx|
1137      ctx.mkdir(dir_path)
1138      File.open(path, "w") {}
1139      ctx.add(path)
1140      rev1 = ctx.ci(@wc_path).revision
1141
1142      File.open(path, "w") {|f| f.print(src1)}
1143      rev2 = ctx.ci(@wc_path).revision
1144
1145      ctx.up(@wc_path, rev1)
1146
1147      File.open(path, "w") {|f| f.print(src2)}
1148      ctx.up(@wc_path)
1149
1150      assert_raises(Svn::Error::WcFoundConflict) do
1151        ctx.ci(@wc_path)
1152      end
1153
1154      ctx.resolved(dir_path, false)
1155      assert_raises(Svn::Error::WcFoundConflict) do
1156        ctx.ci(@wc_path)
1157      end
1158
1159      ctx.resolved(dir_path)
1160      info = nil
1161      assert_nothing_raised do
1162        info = ctx.ci(@wc_path)
1163      end
1164      assert_not_nil(info)
1165      assert_equal(rev2 + 1, info.revision)
1166    end
1167  end
1168
1169  def test_copy
1170    log = "sample log"
1171    src = "source\n"
1172    file1 = "sample1.txt"
1173    file2 = "sample2.txt"
1174    path1 = Pathname.new(@wc_path) + file1
1175    path2 = Pathname.new(@wc_path) + file2
1176    full_path2 = path2.expand_path
1177
1178    make_context(log) do |ctx|
1179      File.open(path1, "w") {|f| f.print(src)}
1180      ctx.add(path1.to_s)
1181
1182      ctx.ci(@wc_path)
1183
1184      ctx.cp(path1.to_s, path2.to_s)
1185
1186      infos = []
1187      ctx.set_notify_func do |notify|
1188        infos << [notify.path, notify]
1189      end
1190      ctx.ci(@wc_path)
1191
1192      assert_equal([full_path2.to_s].sort,
1193                   infos.collect{|path, notify| path}.sort)
1194      path2_notify = infos.assoc(full_path2.to_s)[1]
1195      assert(path2_notify.commit_added?)
1196      assert_equal(File.open(path1) {|f| f.read},
1197                   File.open(path2) {|f| f.read})
1198    end
1199  end
1200
1201  def test_move
1202    log = "sample log"
1203    src = "source\n"
1204    file1 = "sample1.txt"
1205    file2 = "sample2.txt"
1206    path1 = File.join(@wc_path, file1)
1207    path2 = File.join(@wc_path, file2)
1208
1209    make_context(log) do |ctx|
1210      File.open(path1, "w") {|f| f.print(src)}
1211      ctx.add(path1)
1212
1213      ctx.ci(@wc_path)
1214
1215      ctx.mv(path1, path2)
1216
1217      infos = []
1218      ctx.set_notify_func do |notify|
1219        infos << [notify.path, notify]
1220      end
1221      ctx.ci(@wc_path)
1222
1223      assert_equal([path1, path2].sort.collect{|p|File.expand_path(p)},
1224                   infos.collect{|path, notify| path}.sort)
1225      path1_notify = infos.assoc(File.expand_path(path1))[1]
1226      assert(path1_notify.commit_deleted?)
1227      path2_notify = infos.assoc(File.expand_path(path2))[1]
1228      assert(path2_notify.commit_added?)
1229      assert_equal(src, File.open(path2) {|f| f.read})
1230    end
1231  end
1232
1233  def test_move_force
1234    log = "sample log"
1235    src1 = "source1\n"
1236    src2 = "source2\n"
1237    file1 = "sample1.txt"
1238    file2 = "sample2.txt"
1239    path1 = File.join(@wc_path, file1)
1240    path2 = File.join(@wc_path, file2)
1241
1242    make_context(log) do |ctx|
1243      File.open(path1, "w") {|f| f.print(src1)}
1244      ctx.add(path1)
1245      ctx.ci(@wc_path)
1246
1247      File.open(path1, "w") {|f| f.print(src2)}
1248      assert_nothing_raised do
1249        ctx.mv(path1, path2)
1250      end
1251      ctx.revert([path1, path2])
1252      FileUtils.rm(path2)
1253
1254      File.open(path1, "w") {|f| f.print(src2)}
1255      assert_nothing_raised do
1256        ctx.mv_f(path1, path2)
1257      end
1258
1259      notifies = []
1260      ctx.set_notify_func do |notify|
1261        notifies << notify
1262      end
1263      ctx.ci(@wc_path)
1264
1265      paths = notifies.collect do |notify|
1266        notify.path
1267      end
1268      assert_equal([path1, path2, path2].sort.collect{|p|File.expand_path(p)},
1269                   paths.sort)
1270
1271      deleted_paths = notifies.find_all do |notify|
1272        notify.commit_deleted?
1273      end.collect do |notify|
1274        notify.path
1275      end
1276      assert_equal([path1].sort.collect{|p|File.expand_path(p)},
1277                   deleted_paths.sort)
1278
1279      added_paths = notifies.find_all do |notify|
1280        notify.commit_added?
1281      end.collect do |notify|
1282        notify.path
1283      end
1284      assert_equal([path2].sort.collect{|p|File.expand_path(p)},
1285                   added_paths.sort)
1286
1287      postfix_txdelta_paths = notifies.find_all do |notify|
1288        notify.commit_postfix_txdelta?
1289      end.collect do |notify|
1290        notify.path
1291      end
1292      assert_equal([path2].sort.collect{|p|File.expand_path(p)},
1293                   postfix_txdelta_paths.sort)
1294
1295      assert_equal(src2, File.open(path2) {|f| f.read})
1296    end
1297  end
1298
1299  def test_prop
1300    log = "sample log"
1301    dir = "dir"
1302    file = "sample.txt"
1303    dir_path = File.join(@wc_path, dir)
1304    dir_uri = "#{@repos_uri}/#{dir}"
1305    path = File.join(dir_path, file)
1306    uri = "#{dir_uri}/#{file}"
1307    prop_name = "sample-prop"
1308    prop_value = "sample value"
1309    invalid_mime_type_prop_value = "image"
1310
1311    make_context(log) do |ctx|
1312
1313      ctx.mkdir(dir_path)
1314      File.open(path, "w") {}
1315      ctx.add(path)
1316
1317      ctx.commit(@wc_path)
1318
1319      assert_equal({}, ctx.prop_get(prop_name, path))
1320      ctx.prop_set(prop_name, prop_value, path)
1321      ctx.commit(@wc_path)
1322      assert_equal({uri => prop_value}, ctx.pget(prop_name, path))
1323
1324      ctx.prop_del(prop_name, path)
1325      ctx.commit(@wc_path)
1326      assert_equal({}, ctx.pg(prop_name, path))
1327
1328      ctx.ps(prop_name, prop_value, path)
1329      ctx.commit(@wc_path)
1330      assert_equal({uri => prop_value}, ctx.pg(prop_name, path))
1331
1332      ctx.ps(prop_name, nil, path)
1333      ctx.commit(@wc_path)
1334      assert_equal({}, ctx.pg(prop_name, path))
1335
1336      ctx.up(@wc_path)
1337      ctx.ps(prop_name, prop_value, dir_path)
1338      ctx.ci(@wc_path)
1339      assert_equal({
1340                     dir_uri => prop_value,
1341                     uri => prop_value,
1342                   },
1343                   ctx.pg(prop_name, dir_path))
1344
1345      ctx.up(@wc_path)
1346      ctx.pdel(prop_name, dir_path, false)
1347      ctx.ci(@wc_path)
1348      assert_equal({uri => prop_value}, ctx.pg(prop_name, dir_path))
1349
1350      ctx.up(@wc_path)
1351      ctx.pd(prop_name, dir_path)
1352      ctx.ci(@wc_path)
1353      assert_equal({}, ctx.pg(prop_name, dir_path))
1354
1355      ctx.up(@wc_path)
1356      ctx.ps(prop_name, prop_value, dir_path, false)
1357      ctx.ci(@wc_path)
1358      assert_equal({dir_uri => prop_value}, ctx.pg(prop_name, dir_path))
1359
1360      assert_raises(Svn::Error::BadMimeType) do
1361        ctx.ps(Svn::Core::PROP_MIME_TYPE,
1362               invalid_mime_type_prop_value,
1363               path)
1364      end
1365      ctx.cleanup(@wc_path)
1366
1367      assert_nothing_raised do
1368        ctx.ps(Svn::Core::PROP_MIME_TYPE,
1369               invalid_mime_type_prop_value,
1370               path, false, true)
1371      end
1372      ctx.commit(@wc_path)
1373      assert_equal({uri => invalid_mime_type_prop_value},
1374                   ctx.pg(Svn::Core::PROP_MIME_TYPE, path))
1375    end
1376  end
1377
1378  def test_prop_list
1379    log = "sample log"
1380    dir = "dir"
1381    file = "sample.txt"
1382    dir_path = File.join(@wc_path, dir)
1383    path = File.join(dir_path, file)
1384    dir_uri = "#{@repos_uri}/#{dir}"
1385    uri = "#{dir_uri}/#{file}"
1386    name1 = "name1"
1387    name2 = "name2"
1388    value1 = "value1"
1389    value2 = "value2"
1390
1391    make_context(log) do |ctx|
1392
1393      ctx.mkdir(dir_path)
1394      File.open(path, "w") {}
1395      ctx.add(path)
1396
1397      ctx.ci(@wc_path)
1398
1399      assert_equal([], ctx.prop_list(path))
1400
1401      ctx.ps(name1, value1, path)
1402      ctx.ci(@wc_path)
1403      assert_equal([uri], ctx.prop_list(path).collect{|item| item.node_name})
1404      assert_equal([{name1 => value1}],
1405                   ctx.plist(path).collect{|item| item.prop_hash})
1406      assert_equal([value1], ctx.pl(path).collect{|item| item[name1]})
1407
1408      ctx.up(@wc_path)
1409      ctx.ps(name2, value2, dir_path)
1410      ctx.ci(@wc_path)
1411      assert_equal([uri, dir_uri].sort,
1412                   ctx.prop_list(dir_path).collect{|item| item.name})
1413      prop_list = ctx.plist(dir_path).collect{|item| [item.name, item.props]}
1414      props = prop_list.assoc(uri)[1]
1415      dir_props = prop_list.assoc(dir_uri)[1]
1416      assert_equal({name1 => value1, name2 => value2}, props)
1417      assert_equal({name2 => value2}, dir_props)
1418    end
1419  end
1420
1421  def recurse_and_depth_choices
1422    [false, true, 'empty', 'files', 'immediates', 'infinity']
1423  end
1424
1425  def test_file_prop
1426    setup_greek_tree
1427
1428    log = "sample log"
1429    make_context(log) do |ctx|
1430
1431      # when no props set, everything is empty
1432      recurse_and_depth_choices.each do |rd|
1433        assert_equal([],
1434                     ctx.prop_list(@greek.path(:mu), nil, nil, rd),
1435                     "prop_list with Depth '#{rd}'")
1436      end
1437
1438      recurse_and_depth_choices.each do |rd|
1439        assert_equal({},
1440                     ctx.prop_get(rd.to_s, @greek.path(:mu), nil, nil, rd),
1441                     "prop_get with Depth '#{rd}'")
1442      end
1443
1444      # set some props
1445      recurse_and_depth_choices.each do |rd|
1446        ctx.prop_set(rd.to_s, rd.to_s, @greek.path(:mu), rd)
1447      end
1448      ctx.commit(@greek.path(:mu))
1449
1450      # get the props
1451      recurse_and_depth_choices.each do |rd|
1452        assert_equal({@greek.uri(:mu) => rd.to_s},
1453                     ctx.prop_get(rd.to_s, @greek.path(:mu), nil, nil, rd),
1454                     "prop_get with Depth '#{rd}'")
1455      end
1456
1457      prop_hash = {}
1458      recurse_and_depth_choices.each {|rd| prop_hash[rd.to_s] = rd.to_s}
1459
1460      # list the props
1461      recurse_and_depth_choices.each do |rd|
1462        props = ctx.prop_list(@greek.path(:mu), nil, nil, rd)
1463        assert_equal([@greek.uri(:mu)],
1464                     props.collect {|item| item.node_name},
1465                     "prop_list (node_name) with Depth '#{rd}'")
1466
1467        props = ctx.plist(@greek.path(:mu), nil, nil, rd)
1468        assert_equal([prop_hash],
1469                     props.collect {|item| item.prop_hash},
1470                     "prop_list (prop_hash) with Depth '#{rd}'")
1471
1472        recurse_and_depth_choices.each do |rd1|
1473          props = ctx.plist(@greek.path(:mu), nil, nil, rd)
1474          assert_equal([rd1.to_s],
1475                       props.collect {|item| item[rd1.to_s]},
1476                       "prop_list (#{rd1.to_s}]) with Depth '#{rd}'")
1477        end
1478      end
1479    end
1480  end
1481
1482  def test_dir_prop
1483    setup_greek_tree
1484
1485    log = "sample log"
1486    make_context(log) do |ctx|
1487
1488      # when no props set, everything is empty
1489      recurse_and_depth_choices.each do |rd|
1490        assert_equal([],
1491                     ctx.prop_list(@greek.path(:b), nil, nil, rd),
1492                     "prop_list with Depth '#{rd}'")
1493      end
1494
1495      recurse_and_depth_choices.each do |rd|
1496        assert_equal({},
1497                     ctx.prop_get(rd.to_s, @greek.path(:b), nil, nil, rd),
1498                     "prop_get with Depth '#{rd}'")
1499      end
1500
1501      # set some props with various depths
1502      recurse_and_depth_choices.each do |rd|
1503        ctx.prop_set(rd.to_s, rd.to_s, @greek.path(:b), rd)
1504      end
1505      ctx.commit(@greek.path(:b))
1506
1507      expected_props = {
1508        true => [:beta, :b, :lambda, :e, :f, :alpha],
1509        false => [:b],
1510        'empty' => [:b],
1511        'files' => [:b, :lambda],
1512        'immediates' => [:b, :lambda, :e, :f],
1513        'infinity' => [:beta, :b, :lambda, :e, :f, :alpha],
1514      }
1515
1516      paths = [:b, :e, :alpha, :beta, :f, :lambda]
1517
1518      # how are the props set?
1519      recurse_and_depth_choices.each do |rd|
1520        paths.each do |path|
1521          if expected_props[rd].include?(path)
1522            expected = {@greek.uri(path) => rd.to_s}
1523          else
1524            expected = {}
1525          end
1526          assert_equal(expected,
1527                       ctx.prop_get(rd.to_s, @greek.path(path), nil, nil, false),
1528                       "prop_get #{@greek.resolve(path)} with Depth '#{rd}'")
1529        end
1530      end
1531
1532      recurse_and_depth_choices.each do |rd_for_prop|
1533        recurse_and_depth_choices.each do |rd_for_depth|
1534          expected = {}
1535          expected_paths = expected_props[rd_for_depth]
1536          expected_paths &= expected_props[rd_for_prop]
1537          expected_paths.each do |path|
1538            expected[@greek.uri(path)] = rd_for_prop.to_s
1539          end
1540
1541          assert_equal(expected,
1542                       ctx.prop_get(rd_for_prop.to_s, @greek.path(:b),
1543                                    nil, nil, rd_for_depth),
1544                       "prop_get '#{rd_for_prop}' with Depth '#{rd_for_depth}'")
1545
1546        end
1547      end
1548
1549      recurse_and_depth_choices.each do |rd|
1550        props = ctx.prop_list(@greek.path(:b), nil, nil, rd)
1551        assert_equal(expected_props[rd].collect {|path| @greek.uri(path)}.sort,
1552                     props.collect {|item| item.node_name}.sort,
1553                     "prop_list (node_name) with Depth '#{rd}'")
1554        end
1555    end
1556  end
1557
1558  def test_cat
1559    log = "sample log"
1560    src1 = "source1\n"
1561    src2 = "source2\n"
1562    file = "sample.txt"
1563    path = File.join(@wc_path, file)
1564
1565    File.open(path, "w") {|f| f.print(src1)}
1566
1567    make_context(log) do |ctx|
1568      ctx.add(path)
1569      commit_info = ctx.commit(@wc_path)
1570      rev1 = commit_info.revision
1571
1572      assert_equal(normalize_line_break(src1), ctx.cat(path, rev1))
1573      assert_equal(normalize_line_break(src1), ctx.cat(path))
1574
1575      File.open(path, "w") {|f| f.print(src2)}
1576
1577      commit_info = ctx.commit(@wc_path)
1578      rev2 = commit_info.revision
1579
1580      assert_equal(normalize_line_break(src1), ctx.cat(path, rev1))
1581      assert_equal(normalize_line_break(src2), ctx.cat(path, rev2))
1582      assert_equal(normalize_line_break(src2), ctx.cat(path))
1583    end
1584  end
1585
1586  def test_lock
1587    log = "sample log"
1588    src = "source\n"
1589    file = "sample.txt"
1590    path = File.join(@wc_path, file)
1591    absolute_path = File.expand_path(path)
1592
1593    File.open(path, "w") {|f| f.print(src)}
1594
1595    make_context(log) do |ctx|
1596      ctx.add(path)
1597      ctx.commit(@wc_path)
1598
1599      infos = []
1600      ctx.set_notify_func do |notify|
1601        infos << [notify.path, notify]
1602      end
1603      ctx.lock(path)
1604
1605      assert_equal([absolute_path], infos.collect{|_path, notify| _path})
1606      file_notify = infos.assoc(absolute_path)[1]
1607      assert(file_notify.locked?)
1608    end
1609  end
1610
1611  def test_unlock
1612    log = "sample log"
1613    src = "source\n"
1614    file = "sample.txt"
1615    path = File.join(@wc_path, file)
1616    absolute_path = File.expand_path(path)
1617
1618    File.open(path, "w") {|f| f.print(src)}
1619
1620    make_context(log) do |ctx|
1621      ctx.add(path)
1622      ctx.commit(@wc_path)
1623
1624      ctx.lock(path)
1625
1626      infos = []
1627      ctx.set_notify_func do |notify|
1628        infos << [notify.path, notify]
1629      end
1630      ctx.unlock(path)
1631
1632      assert_equal([absolute_path], infos.collect{|_path, notify| _path})
1633      file_notify = infos.assoc(absolute_path)[1]
1634      assert(file_notify.unlocked?)
1635    end
1636  end
1637
1638  def test_info
1639    log = "sample log"
1640    make_context(log) do |ctx|
1641      repos_base = File.basename(@repos_path)
1642
1643      infos = []
1644      ctx.info(@wc_path) do |path, info|
1645        infos << [path, info]
1646      end
1647      assert_equal([repos_base],
1648                   infos.collect{|path, info| path})
1649      top_info = infos.assoc(repos_base)[1]
1650      assert_equal(@repos_uri, top_info.url)
1651    end
1652  end
1653
1654  def test_info_with_depth
1655    setup_greek_tree
1656
1657    log = "sample log"
1658    make_context(log) do |ctx|
1659
1660      recurse_and_depth_choices.each do |rd|
1661        ctx.info(@greek.path(:mu),nil,nil,rd) do |path, info|
1662          assert_equal @greek.uri(:mu), info.URL
1663        end
1664      end
1665
1666      expected_info_by_depth = {
1667        true => [:beta, :b, :lambda, :e, :f, :alpha],
1668        false => [:b],
1669        'empty' => [:b],
1670        'files' => [:b, :lambda],
1671        'immediates' => [:b, :lambda, :e, :f],
1672        'infinity' => [:beta, :b, :lambda, :e, :f, :alpha],
1673      }
1674
1675      recurse_and_depth_choices.each do |rd|
1676        urls = []
1677        ctx.info(@greek.path(:b),nil,nil,rd) do |path, info|
1678          urls << info.URL
1679        end
1680        assert_equal expected_info_by_depth[rd].map{|s| @greek.uri(s)}.sort,
1681                     urls.sort,
1682                     "depth '#{rd}"
1683      end
1684    end
1685  end
1686
1687  def test_url_from_path
1688    log = "sample log"
1689    make_context(log) do |ctx|
1690      assert_equal(@repos_uri, ctx.url_from_path(@wc_path))
1691      assert_equal(@repos_uri, Svn::Client.url_from_path(@wc_path))
1692    end
1693  end
1694
1695  def test_uuid
1696    log = "sample log"
1697    make_context(log) do |ctx|
1698      Svn::Wc::AdmAccess.open(nil, @wc_path, false, 0) do |adm|
1699        assert_equal(ctx.uuid_from_url(@repos_uri),
1700                     ctx.uuid_from_path(@wc_path, adm))
1701      end
1702    end
1703  end
1704
1705  def test_open_ra_session
1706    log = "sample log"
1707    make_context(log) do |ctx|
1708      assert_instance_of(Svn::Ra::Session, ctx.open_ra_session(@repos_uri))
1709    end
1710  end
1711
1712  def test_revprop
1713    log = "sample log"
1714    new_log = "new sample log"
1715    src = "source\n"
1716    file = "sample.txt"
1717    path = File.join(@wc_path, file)
1718
1719    File.open(path, "w") {|f| f.print(src)}
1720
1721    make_context(log) do |ctx|
1722      ctx.add(path)
1723      info = ctx.commit(@wc_path)
1724
1725      assert_equal([
1726                     {
1727                       Svn::Core::PROP_REVISION_AUTHOR => @author,
1728                       Svn::Core::PROP_REVISION_DATE => info.date,
1729                       Svn::Core::PROP_REVISION_LOG => log,
1730                     },
1731                     info.revision
1732                   ],
1733                   ctx.revprop_list(@repos_uri, info.revision))
1734
1735      assert_equal([log, info.revision],
1736                   ctx.revprop_get(Svn::Core::PROP_REVISION_LOG,
1737                                   @repos_uri, info.revision))
1738      assert_equal(log,
1739                   ctx.revprop(Svn::Core::PROP_REVISION_LOG,
1740                               @repos_uri, info.revision))
1741
1742      assert_equal(info.revision,
1743                   ctx.revprop_set(Svn::Core::PROP_REVISION_LOG, new_log,
1744                                   @repos_uri, info.revision))
1745      assert_equal([new_log, info.revision],
1746                   ctx.rpget(Svn::Core::PROP_REVISION_LOG,
1747                             @repos_uri, info.revision))
1748      assert_equal(new_log,
1749                   ctx.rp(Svn::Core::PROP_REVISION_LOG,
1750                          @repos_uri, info.revision))
1751      assert_equal([
1752                     {
1753                       Svn::Core::PROP_REVISION_AUTHOR => @author,
1754                       Svn::Core::PROP_REVISION_DATE => info.date,
1755                       Svn::Core::PROP_REVISION_LOG => new_log,
1756                     },
1757                     info.revision
1758                   ],
1759                   ctx.rplist(@repos_uri, info.revision))
1760
1761      assert_equal(info.revision,
1762                   ctx.revprop_del(Svn::Core::PROP_REVISION_LOG,
1763                                   @repos_uri, info.revision))
1764      assert_equal([nil, info.revision],
1765                   ctx.rpg(Svn::Core::PROP_REVISION_LOG,
1766                           @repos_uri, info.revision))
1767      assert_equal(nil,
1768                   ctx.rp(Svn::Core::PROP_REVISION_LOG,
1769                          @repos_uri, info.revision))
1770
1771      assert_equal(info.revision,
1772                   ctx.rpset(Svn::Core::PROP_REVISION_LOG, new_log,
1773                             @repos_uri, info.revision))
1774      assert_equal(new_log,
1775                   ctx.rp(Svn::Core::PROP_REVISION_LOG,
1776                          @repos_uri, info.revision))
1777      assert_equal(info.revision,
1778                   ctx.rps(Svn::Core::PROP_REVISION_LOG, nil,
1779                           @repos_uri, info.revision))
1780      assert_equal(nil,
1781                   ctx.rp(Svn::Core::PROP_REVISION_LOG,
1782                          @repos_uri, info.revision))
1783
1784      assert_equal([
1785                     {
1786                       Svn::Core::PROP_REVISION_AUTHOR => @author,
1787                       Svn::Core::PROP_REVISION_DATE => info.date,
1788                     },
1789                     info.revision
1790                   ],
1791                   ctx.rpl(@repos_uri, info.revision))
1792    end
1793  end
1794
1795  def test_export
1796    log = "sample log"
1797    src = "source\n"
1798    file = "sample.txt"
1799    dir = "sample"
1800    dir_path = File.join(@wc_path, dir)
1801    path = File.join(dir_path, file)
1802    tmp_base_path = File.join(@tmp_path, "tmp")
1803    tmp_dir_path = File.join(tmp_base_path, dir)
1804    tmp_path = File.join(tmp_dir_path, file)
1805
1806    make_context(log) do |ctx|
1807
1808      ctx.mkdir(dir_path)
1809      File.open(path, "w") {|f| f.print(src)}
1810      ctx.add(path)
1811      rev = ctx.ci(@wc_path).revision
1812
1813      assert_equal(rev, ctx.export(@repos_uri, tmp_base_path))
1814      assert_equal(src, File.open(tmp_path) {|f| f.read})
1815    end
1816  end
1817
1818  def test_ls
1819    log = "sample log"
1820    src = "source\n"
1821    file = "sample.txt"
1822    dir = "sample"
1823    dir_path = File.join(@wc_path, dir)
1824    path = File.join(@wc_path, file)
1825
1826    make_context(log) do |ctx|
1827
1828      ctx.mkdir(dir_path)
1829      File.open(path, "w") {|f| f.print(src)}
1830      ctx.add(path)
1831      rev = ctx.ci(@wc_path).revision
1832
1833      dirents, locks = ctx.ls(@wc_path, rev)
1834      assert_equal([dir, file].sort, dirents.keys.sort)
1835      dir_dirent = dirents[dir]
1836      assert(dir_dirent.directory?)
1837      file_dirent = dirents[file]
1838      assert(file_dirent.file?)
1839    end
1840  end
1841
1842  def test_list
1843    log = "sample log"
1844    src = "source\n"
1845    file = "sample.txt"
1846    dir = "sample"
1847    prop_name = "sample-prop"
1848    prop_value = "sample value"
1849    dir_path = File.join(@wc_path, dir)
1850    path = File.join(@wc_path, file)
1851
1852    make_context(log) do |ctx|
1853
1854      ctx.mkdir(dir_path)
1855      File.open(path, "w") {|f| f.print(src)}
1856      ctx.add(path)
1857      ctx.prop_set(prop_name, prop_value, path)
1858      rev = ctx.ci(@wc_path).revision
1859
1860      entries = []
1861      ctx.list(@wc_path, rev) do |path, dirent, lock, abs_path|
1862        entries << [path, dirent, lock, abs_path]
1863      end
1864      paths = entries.collect do |path, dirent, lock, abs_path|
1865        [path, abs_path]
1866      end
1867      assert_equal([["", "/"], [dir, "/"], [file, "/"]].sort, paths.sort)
1868      entries.each do |path, dirent, lock, abs_path|
1869        case path
1870        when dir, ""
1871          assert(dirent.directory?)
1872          assert_false(dirent.have_props?)
1873        when file
1874          assert(dirent.file?)
1875          assert_true(dirent.have_props?)
1876        else
1877          flunk
1878        end
1879      end
1880    end
1881  end
1882
1883  def test_list_with_depth
1884    setup_greek_tree
1885
1886    log = "sample log"
1887    make_context(log) do |ctx|
1888
1889      expected_lists_by_depth = {
1890        true => [:beta, :b, :lambda, :e, :f, :alpha],
1891        false => [:b, :lambda, :e, :f],
1892        'empty' => [:b],
1893        'files' => [:b, :lambda],
1894        'immediates' => [:b, :lambda, :e, :f],
1895        'infinity' => [:beta, :b, :lambda, :e, :f, :alpha],
1896      }
1897
1898      recurse_and_depth_choices.each do |rd|
1899        paths = []
1900        ctx.list(@greek.path(:b), 'head' ,nil, rd) do |path, dirent, lock, abs_path|
1901          paths << (path.empty? ? abs_path : File.join(abs_path, path))
1902        end
1903        assert_equal(expected_lists_by_depth[rd].map{|s| "/#{@greek.resolve(s)}"}.sort,
1904                     paths.sort,
1905                     "depth '#{rd}")
1906      end
1907    end
1908  end
1909
1910  def test_switch
1911    log = "sample log"
1912    trunk_src = "trunk source\n"
1913    tag_src = "tag source\n"
1914    file = "sample.txt"
1915    file = "sample.txt"
1916    trunk_dir = "trunk"
1917    tag_dir = "tags"
1918    tag_name = "0.0.1"
1919    trunk_repos_uri = "#{@repos_uri}/#{trunk_dir}"
1920    tag_repos_uri = "#{@repos_uri}/#{tag_dir}/#{tag_name}"
1921    trunk_dir_path = File.join(@wc_path, trunk_dir)
1922    tag_dir_path = File.join(@wc_path, tag_dir)
1923    tag_name_dir_path = File.join(@wc_path, tag_dir, tag_name)
1924    trunk_path = File.join(trunk_dir_path, file)
1925    tag_path = File.join(tag_name_dir_path, file)
1926    path = File.join(@wc_path, file)
1927
1928    make_context(log) do |ctx|
1929
1930      ctx.mkdir(trunk_dir_path)
1931      File.open(trunk_path, "w") {|f| f.print(trunk_src)}
1932      ctx.add(trunk_path)
1933      trunk_rev = ctx.commit(@wc_path).revision
1934
1935      ctx.mkdir(tag_dir_path, tag_name_dir_path)
1936      File.open(tag_path, "w") {|f| f.print(tag_src)}
1937      ctx.add(tag_path)
1938      tag_rev = ctx.commit(@wc_path).revision
1939
1940      assert_equal(youngest_rev, ctx.switch(@wc_path, trunk_repos_uri))
1941      assert_equal(normalize_line_break(trunk_src), ctx.cat(path))
1942
1943      assert_equal(youngest_rev, ctx.switch(@wc_path, tag_repos_uri))
1944      assert_equal(normalize_line_break(tag_src), ctx.cat(path))
1945
1946
1947      notify_info = []
1948      ctx.set_notify_func do |notify|
1949        notify_info << [notify.path, notify.action]
1950      end
1951
1952      assert_equal(trunk_rev, ctx.switch(@wc_path, trunk_repos_uri, trunk_rev))
1953      assert_equal(normalize_line_break(trunk_src), ctx.cat(path))
1954      assert_equal([
1955                     [path, Svn::Wc::NOTIFY_UPDATE_UPDATE],
1956                     [@wc_path, Svn::Wc::NOTIFY_UPDATE_UPDATE],
1957                     [@wc_path, Svn::Wc::NOTIFY_UPDATE_COMPLETED],
1958                   ],
1959                   notify_info)
1960
1961      notify_info.clear
1962      assert_equal(tag_rev, ctx.switch(@wc_path, tag_repos_uri, tag_rev))
1963      assert_equal(normalize_line_break(tag_src), ctx.cat(path))
1964      assert_equal([
1965                     [path, Svn::Wc::NOTIFY_UPDATE_UPDATE],
1966                     [@wc_path, Svn::Wc::NOTIFY_UPDATE_UPDATE],
1967                     [@wc_path, Svn::Wc::NOTIFY_UPDATE_COMPLETED],
1968                   ],
1969                   notify_info)
1970    end
1971  end
1972
1973  def test_authentication
1974    log = "sample log"
1975    src = "source\n"
1976    file = "sample.txt"
1977    path = File.join(@wc_path, file)
1978    svnserve_uri = "#{@repos_svnserve_uri}/#{file}"
1979
1980    File.open(path, "w") {|f| f.print(src)}
1981
1982    make_context(log) do |ctx|
1983      ctx.add(path)
1984      ctx.commit(@wc_path)
1985    end
1986
1987    Svn::Client::Context.new do |ctx|
1988      assert_raises(Svn::Error::AuthnNoProvider) do
1989        ctx.cat(svnserve_uri)
1990      end
1991
1992      ctx.add_simple_prompt_provider(0) do |cred, realm, username, may_save|
1993        cred.username = "wrong-#{@author}"
1994        cred.password = @password
1995        cred.may_save = false
1996      end
1997      assert_raises(Svn::Error::RaNotAuthorized) do
1998        ctx.cat(svnserve_uri)
1999      end
2000
2001      ctx.add_simple_prompt_provider(0) do |cred, realm, username, may_save|
2002        cred.username = @author
2003        cred.password = "wrong-#{@password}"
2004        cred.may_save = false
2005      end
2006      assert_raises(Svn::Error::RaNotAuthorized) do
2007        ctx.cat(svnserve_uri)
2008      end
2009
2010      ctx.add_simple_prompt_provider(0) do |cred, realm, username, may_save|
2011        cred.username = @author
2012        cred.password = @password
2013        cred.may_save = false
2014      end
2015      assert_equal(normalize_line_break(src), ctx.cat(svnserve_uri))
2016    end
2017  end
2018
2019  def assert_simple_provider(method)
2020    log = "sample log"
2021    src = "source\n"
2022    file = "sample.txt"
2023    path = File.join(@wc_path, file)
2024    svnserve_uri = "#{@repos_svnserve_uri}/#{file}"
2025
2026    File.open(path, "w") {|f| f.print(src)}
2027
2028    make_context(log) do |ctx|
2029      setup_auth_baton(ctx.auth_baton)
2030      ctx.add(path)
2031      ctx.commit(@wc_path)
2032    end
2033
2034    ctx = Svn::Client::Context.new
2035    setup_auth_baton(ctx.auth_baton)
2036    ctx.send(method)
2037    assert_raises(Svn::Error::RaNotAuthorized) do
2038      ctx.cat(svnserve_uri)
2039    end
2040
2041    ctx = Svn::Client::Context.new
2042    setup_auth_baton(ctx.auth_baton)
2043    ctx.send(method)
2044    ctx.add_simple_prompt_provider(0) do |cred, realm, username, may_save|
2045      cred.username = @author
2046      cred.password = @password
2047    end
2048    assert_equal(normalize_line_break(src), ctx.cat(svnserve_uri))
2049  end
2050
2051  def test_simple_provider
2052    assert_simple_provider(:add_simple_provider)
2053  end
2054
2055  if Svn::Core.respond_to?(:auth_get_windows_simple_provider)
2056    def test_windows_simple_provider
2057      assert_simple_provider(:add_windows_simple_provider)
2058    end
2059  end
2060
2061  if Svn::Core.respond_to?(:auth_get_keychain_simple_provider)
2062    def test_keychain_simple_provider
2063      assert_simple_provider(:add_keychain_simple_provider)
2064    end
2065  end
2066
2067  def test_username_provider
2068    log = "sample log"
2069    new_log = "sample new log"
2070    src = "source\n"
2071    file = "sample.txt"
2072    path = File.join(@wc_path, file)
2073    repos_uri = "#{@repos_uri}/#{file}"
2074
2075    File.open(path, "w") {|f| f.print(src)}
2076
2077    info_revision = make_context(log) do |ctx|
2078      ctx.add(path)
2079      info = ctx.commit(@wc_path)
2080      info.revision
2081    end
2082
2083    Svn::Client::Context.new do |ctx|
2084      setup_auth_baton(ctx.auth_baton)
2085      ctx.auth_baton[Svn::Core::AUTH_PARAM_DEFAULT_USERNAME] = @author
2086      ctx.add_username_provider
2087      assert_nothing_raised do
2088        ctx.revprop_set(Svn::Core::PROP_REVISION_LOG, new_log,
2089                        repos_uri, info_revision)
2090      end
2091    end
2092
2093    Svn::Client::Context.new do |ctx|
2094      setup_auth_baton(ctx.auth_baton)
2095      ctx.auth_baton[Svn::Core::AUTH_PARAM_DEFAULT_USERNAME] = "#{@author}-NG"
2096      ctx.add_username_provider
2097      assert_raise(Svn::Error::REPOS_HOOK_FAILURE) do
2098        ctx.revprop_set(Svn::Core::PROP_REVISION_LOG, new_log,
2099                        repos_uri, info_revision)
2100      end
2101    end
2102
2103    Svn::Client::Context.new do |ctx|
2104      setup_auth_baton(ctx.auth_baton)
2105      ctx.auth_baton[Svn::Core::AUTH_PARAM_DEFAULT_USERNAME] = nil
2106      ctx.add_username_prompt_provider(0) do |cred, realm, may_save|
2107      end
2108      assert_raise(Svn::Error::REPOS_HOOK_FAILURE) do
2109        ctx.revprop_set(Svn::Core::PROP_REVISION_LOG, new_log,
2110                        repos_uri, info_revision)
2111      end
2112    end
2113
2114    Svn::Client::Context.new do |ctx|
2115      setup_auth_baton(ctx.auth_baton)
2116      ctx.auth_baton[Svn::Core::AUTH_PARAM_DEFAULT_USERNAME] = nil
2117      ctx.add_username_prompt_provider(0) do |cred, realm, may_save|
2118        cred.username = @author
2119      end
2120      assert_nothing_raised do
2121        ctx.revprop_set(Svn::Core::PROP_REVISION_LOG, new_log,
2122                        repos_uri, info_revision)
2123      end
2124    end
2125  end
2126
2127  def test_add_providers
2128    Svn::Client::Context.new do |ctx|
2129      assert_nothing_raised do
2130        ctx.add_ssl_client_cert_file_provider
2131        ctx.add_ssl_client_cert_pw_file_provider
2132        ctx.add_ssl_server_trust_file_provider
2133        if Svn::Core.respond_to?(:auth_get_windows_ssl_server_trust_provider)
2134          ctx.add_windows_ssl_server_trust_provider
2135        end
2136      end
2137    end
2138  end
2139
2140  def test_commit_item
2141    assert_raise(NoMethodError) do
2142      Svn::Client::CommitItem.new
2143    end
2144
2145    assert_raise(NoMethodError) do
2146      Svn::Client::CommitItem2.new
2147    end
2148
2149    item = Svn::Client::CommitItem3.new
2150    assert_kind_of(Svn::Client::CommitItem3, item)
2151
2152    url = "xxx"
2153    item.url = url
2154    assert_equal(url, item.dup.url)
2155  end
2156
2157  def test_log_msg_func_commit_items
2158    log = "sample log"
2159    file = "file"
2160    file2 = "file2"
2161    src = "source"
2162    path = File.join(@wc_path, file)
2163    repos_uri2 = "#{@repos_uri}/#{file2}"
2164
2165    File.open(path, "w") {|f| f.print(src)}
2166
2167    make_context(log) do |ctx|
2168      items = nil
2169      ctx.set_log_msg_func do |items|
2170        [true, log]
2171      end
2172
2173      ctx.add(path)
2174      ctx.prop_set(Svn::Core::PROP_MIME_TYPE, "text/plain", path)
2175      ctx.commit(@wc_path)
2176      assert_equal([[]], items.collect {|item| item.wcprop_changes})
2177      assert_equal([[]], items.collect {|item| item.incoming_prop_changes})
2178      assert_equal([nil], items.collect {|item| item.outgoing_prop_changes})
2179
2180      items = nil
2181      ctx.cp(path, repos_uri2)
2182      assert_equal([nil], items.collect {|item| item.wcprop_changes})
2183      assert_equal([nil], items.collect {|item| item.incoming_prop_changes})
2184      assert_equal([nil], items.collect {|item| item.outgoing_prop_changes})
2185    end
2186  end
2187
2188  def test_log_msg_func_cancel
2189    log = "sample log"
2190    dir = "dir"
2191    dir_path = File.join(@wc_path, dir)
2192
2193    make_context(log) do |ctx|
2194      ctx.set_log_msg_func do |items|
2195        raise Svn::Error::Cancelled
2196      end
2197      ctx.mkdir(dir_path)
2198      assert_raise(Svn::Error::Cancelled) do
2199        ctx.commit(@wc_path)
2200      end
2201    end
2202  end
2203
2204  def test_set_config
2205    log = "sample log"
2206    make_context(log) do |ctx|
2207      options = {
2208        "groups" => {"collabnet" => "svn.collab.net"},
2209        "collabnet" => {
2210          "http-proxy-host" => "proxy",
2211          "http-proxy-port" => "8080",
2212        },
2213      }
2214      servers_config_file = File.join(@config_path,
2215                                      Svn::Core::CONFIG_CATEGORY_SERVERS)
2216      File.open(servers_config_file, "w") do |file|
2217        options.each do |section, values|
2218          file.puts("[#{section}]")
2219          values.each do |key, value|
2220            file.puts("#{key} = #{value}")
2221          end
2222        end
2223      end
2224      config = Svn::Core::Config.config(@config_path)
2225      assert_nil(ctx.config)
2226      assert_equal(options, config[Svn::Core::CONFIG_CATEGORY_SERVERS].to_hash)
2227      ctx.config = config
2228      assert_equal(options,
2229                   ctx.config[Svn::Core::CONFIG_CATEGORY_SERVERS].to_hash)
2230    end
2231  end
2232
2233  def test_context_mimetypes_map
2234    Svn::Client::Context.new do |context|
2235      assert_nil(context.mimetypes_map)
2236      context.mimetypes_map = {"txt" => "text/plain"}
2237      assert_equal({"txt" => "text/plain"}, context.mimetypes_map)
2238    end
2239  end
2240
2241  def assert_changelists
2242    log = "sample log"
2243    file1 = "hello1.txt"
2244    file2 = "hello2.txt"
2245    src = "Hello"
2246    changelist1 = "XXX"
2247    changelist2 = "YYY"
2248    path1 = File.join(@wc_path, file1)
2249    path2 = File.join(@wc_path, file2)
2250
2251    make_context(log) do |ctx|
2252      File.open(path1, "w") {|f| f.print(src)}
2253      File.open(path2, "w") {|f| f.print(src)}
2254      ctx.add(path1)
2255      ctx.add(path2)
2256      ctx.commit(@wc_path)
2257
2258      assert_equal({}, yield(ctx, changelist1))
2259      assert_equal({nil=>[@wc_path,path1,path2]}, yield(ctx, nil))
2260      assert_equal({}, yield(ctx, []))
2261      assert_equal({}, yield(ctx, [changelist1]))
2262      assert_equal({}, yield(ctx, [changelist2]))
2263      ctx.add_to_changelist(changelist1, path1)
2264      assert_equal({changelist1=>[path1]}, yield(ctx, changelist1))
2265      assert_equal({changelist1=>[path1],nil=>[@wc_path,path2]}, yield(ctx, nil))
2266      assert_equal({}, yield(ctx, []))
2267      assert_equal({changelist1=>[path1]}, yield(ctx, [changelist1]))
2268      assert_equal({}, yield(ctx, [changelist2]))
2269
2270      assert_equal({}, yield(ctx, changelist2))
2271      ctx.add_to_changelist(changelist2, [path1, path2])
2272      assert_equal({changelist2=>[path1, path2]}, yield(ctx, changelist2))
2273      assert_equal({}, yield(ctx, changelist1))
2274
2275      ctx.add_to_changelist(changelist1, [path1, path2])
2276      assert_equal({changelist1=>[path1, path2]}, yield(ctx, changelist1))
2277      assert_equal({}, yield(ctx, changelist2))
2278
2279      ctx.remove_from_changelists(changelist1, path1)
2280      assert_equal({changelist1=>[path2]}, yield(ctx, changelist1))
2281      ctx.remove_from_changelists(changelist1, [path2])
2282      assert_equal({}, yield(ctx, changelist1))
2283
2284      ctx.add_to_changelist(changelist1, path1)
2285      ctx.add_to_changelist(changelist2, path2)
2286      assert_equal({changelist1=>[path1]}, yield(ctx, changelist1))
2287      assert_equal({changelist2=>[path2]}, yield(ctx, changelist2))
2288
2289      assert_equal({changelist1=>[path1]}, yield(ctx, changelist1))
2290      assert_equal({changelist2=>[path2]}, yield(ctx, changelist2))
2291      assert_equal({changelist1=>[path1]}, yield(ctx, [changelist1]))
2292      assert_equal({changelist2=>[path2]}, yield(ctx, [changelist2]))
2293      assert_equal({changelist1=>[path1],changelist2=>[path2],nil=>[@wc_path]}, yield(ctx, nil))
2294      assert_equal({}, yield(ctx, []))
2295      assert_equal({changelist1=>[path1],changelist2=>[path2]},
2296                   yield(ctx, [changelist1,changelist2]))
2297
2298      ctx.remove_from_changelists(nil, [path1, path2])
2299      assert_equal({}, yield(ctx, changelist1))
2300      assert_equal({}, yield(ctx, changelist2))
2301    end
2302  end
2303
2304  def test_changelists_get_without_block
2305    assert_changelists do |ctx, changelist_name|
2306      ctx.changelists(changelist_name, @wc_path)
2307    end
2308  end
2309
2310  def test_changelists_get_with_block
2311    assert_changelists do |ctx, changelist_name|
2312      changelists = Hash.new{|h,k| h[k]=[]}
2313      ctx.changelists(changelist_name, @wc_path) do |path,cl_name|
2314        changelists[cl_name] << path
2315      end
2316      changelists
2317    end
2318  end
2319
2320  def test_set_revision_by_date
2321    log = "sample log"
2322    file = "hello.txt"
2323    src = "Hello"
2324    src_after = "Hello World"
2325    path = File.join(@wc_path, file)
2326    uri = "#{@repos_uri}/#{file}"
2327
2328    make_context(log) do |ctx|
2329      File.open(path, "w") {|f| f.print(src)}
2330      ctx.add(path)
2331      ctx.commit(@wc_path)
2332
2333      first_commit_time = Time.now
2334      sleep(1)
2335
2336      File.open(path, "w") {|f| f.print(src_after)}
2337      ctx.commit(@wc_path)
2338
2339      assert_equal(src, ctx.cat(uri, first_commit_time))
2340    end
2341  end
2342
2343  def assert_resolve(choice)
2344    log = "sample log"
2345    file = "sample.txt"
2346    srcs = ["before\n","after\n"]
2347    dir = "dir"
2348    dir_path = File.join(@wc_path, dir)
2349    path = File.join(dir_path, file)
2350
2351    make_context(log) do |ctx|
2352      ctx.mkdir(dir_path)
2353      File.open(path, "w") {}
2354      ctx.add(path)
2355      rev1 = ctx.ci(@wc_path).revision
2356
2357      File.open(path, "w") {|f| f.print(srcs[0])}
2358      rev2 = ctx.ci(@wc_path).revision
2359
2360      ctx.up(@wc_path, rev1)
2361
2362      File.open(path, "w") {|f| f.print(srcs[1])}
2363      ctx.up(@wc_path)
2364
2365      assert_raises(Svn::Error::WcFoundConflict) do
2366        ctx.ci(@wc_path)
2367      end
2368
2369      ctx.resolve(:path=>dir_path, :depth=>:empty, :conflict_choice=>choice)
2370      assert_raises(Svn::Error::WcFoundConflict) do
2371        ctx.ci(@wc_path)
2372      end
2373
2374      ctx.resolve(:path=>dir_path, :depth=>:infinite, :conflict_choice=>choice)
2375      yield ctx, path
2376    end
2377  end
2378
2379  def test_resolve_base
2380    assert_resolve(Svn::Wc::CONFLICT_CHOOSE_BASE) do |ctx,path|
2381      info = nil
2382      assert_nothing_raised do
2383        info = ctx.ci(@wc_path)
2384      end
2385      assert_not_nil(info)
2386      assert_equal(3, info.revision)
2387
2388      assert_equal("", File.read(path))
2389    end
2390  end
2391
2392  def test_resolve_theirs_full
2393    assert_resolve(Svn::Wc::CONFLICT_CHOOSE_THEIRS_FULL) do |ctx,path|
2394      info = nil
2395      assert_nothing_raised do
2396        info = ctx.ci(@wc_path)
2397      end
2398      assert_not_nil(info)
2399      assert_equal(-1, info.revision)
2400
2401      assert_equal("before\n", File.read(path))
2402    end
2403  end
2404
2405  def test_resolve_mine_full
2406    assert_resolve(Svn::Wc::CONFLICT_CHOOSE_MINE_FULL) do |ctx,path|
2407      info = nil
2408      assert_nothing_raised do
2409        info = ctx.ci(@wc_path)
2410      end
2411      assert_not_nil(info)
2412      assert_equal(3, info.revision)
2413
2414      assert_equal("after\n", File.read(path))
2415    end
2416  end
2417
2418  def test_resolve_theirs_conflict
2419    assert_resolve(Svn::Wc::CONFLICT_CHOOSE_THEIRS_FULL) do |ctx,path|
2420      info = nil
2421      assert_nothing_raised do
2422        info = ctx.ci(@wc_path)
2423      end
2424      assert_not_nil(info)
2425      assert_equal(-1, info.revision)
2426
2427      assert_equal("before\n", File.read(path))
2428    end
2429  end
2430
2431  def test_resolve_mine_conflict
2432    assert_resolve(Svn::Wc::CONFLICT_CHOOSE_MINE_FULL) do |ctx,path|
2433      info = nil
2434      assert_nothing_raised do
2435        info = ctx.ci(@wc_path)
2436      end
2437      assert_not_nil(info)
2438      assert_equal(3, info.revision)
2439
2440      assert_equal("after\n", File.read(path))
2441    end
2442  end
2443
2444  def test_resolve_merged
2445    assert_resolve(Svn::Wc::CONFLICT_CHOOSE_MERGED) do |ctx,path|
2446      info = nil
2447      assert_nothing_raised do
2448        info = ctx.ci(@wc_path)
2449      end
2450      assert_not_nil(info)
2451      assert_equal(3, info.revision)
2452
2453      assert_equal("<<<<<<< .mine\nafter\n=======\nbefore\n>>>>>>> .r2\n",
2454                   File.read(path))
2455    end
2456  end
2457end
Note: See TracBrowser for help on using the repository browser.