* subversion/bindings/swig/python/libsvn_swig_py/swigutil_py.c
[svn.git] / subversion / bindings / swig / ruby / test / test_client.rb
blob2084d37bb67cdfb2f408645c66539b2518cd0a0d
1 require "my-assertions"
2 require "util"
4 require "svn/core"
5 require "svn/client"
7 class SvnClientTest < Test::Unit::TestCase
8   include SvnTestUtil
10   def setup
11     setup_basic(true)
12   end
14   def teardown
15     teardown_basic
16   end
18   def test_version
19     assert_equal(Svn::Core.subr_version, Svn::Client.version)
20   end
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}"
29     ctx = make_context(log)
30     FileUtils.mkdir(dir_path)
31     FileUtils.mkdir(path)
32     ctx.add(dir_path, false)
33     ctx.commit(@wc_path)
35     assert_raise(Svn::Error::FS_NOT_FOUND) do
36       ctx.cat(uri)
37     end
38   end
40   def test_add_recurse
41     log = "sample log"
42     file = "hello.txt"
43     src = "Hello"
44     dir = "dir"
45     dir_path = File.join(@wc_path, dir)
46     path = File.join(dir_path, file)
47     uri = "#{@repos_uri}/#{dir}/#{file}"
49     ctx = make_context(log)
50     FileUtils.mkdir(dir_path)
51     File.open(path, "w") {|f| f.print(src)}
52     ctx.add(dir_path)
53     ctx.commit(@wc_path)
55     assert_equal(src, ctx.cat(uri))
56   end
58   def test_add_force
59     log = "sample log"
60     file = "hello.txt"
61     src = "Hello"
62     dir = "dir"
63     dir_path = File.join(@wc_path, dir)
64     path = File.join(dir_path, file)
65     uri = "#{@repos_uri}/#{dir}/#{file}"
67     ctx = make_context(log)
68     FileUtils.mkdir(dir_path)
69     File.open(path, "w") {|f| f.print(src)}
70     ctx.add(dir_path, false)
71     ctx.commit(@wc_path)
73     assert_raise(Svn::Error::ENTRY_EXISTS) do
74       ctx.add(dir_path, true, false)
75     end
77     ctx.add(dir_path, true, true)
78     ctx.commit(@wc_path)
79     assert_equal(src, ctx.cat(uri))
80   end
82   def test_add_no_ignore
83     log = "sample log"
84     file = "hello.txt"
85     src = "Hello"
86     dir = "dir"
87     dir_path = File.join(@wc_path, dir)
88     path = File.join(dir_path, file)
89     uri = "#{@repos_uri}/#{dir}/#{file}"
91     ctx = make_context(log)
92     FileUtils.mkdir(dir_path)
93     ctx.add(dir_path, false)
94     ctx.propset(Svn::Core::PROP_IGNORE, file, dir_path)
95     ctx.commit(@wc_path)
97     File.open(path, "w") {|f| f.print(src)}
99     ctx.add(dir_path, true, true, false)
100     ctx.commit(@wc_path)
101     assert_raise(Svn::Error::FS_NOT_FOUND) do
102       ctx.cat(uri)
103     end
105     ctx.add(dir_path, true, true, true)
106     ctx.commit(@wc_path)
107     assert_equal(src, ctx.cat(uri))
108   end
110   def test_mkdir
111     log = "sample log"
112     dir = "dir"
113     deep_dir = ["d", "e", "e", "p"]
114     dir2 = "dir2"
115     dir_uri = "#{@repos_uri}/#{dir}"
116     deep_dir_uri = "#{@repos_uri}/#{deep_dir.join('/')}"
117     dir2_uri = "#{@repos_uri}/#{dir2}"
118     dir_path = File.join(@wc_path, dir)
119     deep_dir_path = File.join(@wc_path, *deep_dir)
120     dir2_path = File.join(@wc_path, dir2)
122     ctx = make_context(log)
124     assert(!File.exist?(dir_path))
125     ctx.mkdir(dir_path)
126     assert(File.exist?(dir_path))
127     assert_raises(Svn::Error::EntryExists) do
128       ctx.add(dir_path)
129     end
130     old_rev = ctx.commit(@wc_path).revision
132     new_rev = ctx.mkdir(dir2_uri).revision
133     assert_equal(old_rev + 1, new_rev)
134     assert_raises(Svn::Error::FsAlreadyExists) do
135       ctx.mkdir(dir2_uri)
136     end
137     assert(!File.exist?(dir2_path))
138     ctx.update(@wc_path)
139     assert(File.exist?(dir2_path))
141     assert_raises(Svn::Error::SvnError) do
142       ctx.mkdir(deep_dir_path)
143     end
144   end
146   def test_mkdir_multiple
147     log = "sample log"
148     dir = "dir"
149     dir2 = "dir2"
150     dirs = [dir, dir2]
151     dirs_path = dirs.collect{|d| File.join(@wc_path, d)}
152     dirs_uri = dirs.collect{|d| "#{@repos_uri}/#{d}"}
154     ctx = make_context(log)
156     infos = []
157     ctx.set_notify_func do |notify|
158       infos << [notify.path, notify]
159     end
161     dirs_path.each do |path|
162       assert(!File.exist?(path))
163     end
164     ctx.mkdir(dirs_path)
165     assert_equal(dirs_path.sort,
166                  infos.collect{|path, notify| path}.sort)
167     assert_equal(dirs_path.collect{true},
168                  infos.collect{|path, notify| notify.add?})
169     dirs_path.each do |path|
170       assert(File.exist?(path))
171     end
173     infos.clear
174     ctx.commit(@wc_path)
175     assert_equal(dirs_path.sort,
176                  infos.collect{|path, notify| path}.sort)
177     assert_equal(dirs_path.collect{true},
178                  infos.collect{|path, notify| notify.commit_added?})
179   end
181   def test_mkdir_multiple2
182     log = "sample log"
183     dir = "dir"
184     dir2 = "dir2"
185     dirs = [dir, dir2]
186     dirs_path = dirs.collect{|d| File.join(@wc_path, d)}
187     dirs_uri = dirs.collect{|d| "#{@repos_uri}/#{d}"}
189     ctx = make_context(log)
191     infos = []
192     ctx.set_notify_func do |notify|
193       infos << [notify.path, notify]
194     end
196     dirs_path.each do |path|
197       assert(!File.exist?(path))
198     end
199     ctx.mkdir(*dirs_path)
200     assert_equal(dirs_path.sort,
201                  infos.collect{|path, notify| path}.sort)
202     assert_equal(dirs_path.collect{true},
203                  infos.collect{|path, notify| notify.add?})
204     dirs_path.each do |path|
205       assert(File.exist?(path))
206     end
208     infos.clear
209     ctx.commit(@wc_path)
210     assert_equal(dirs_path.sort,
211                  infos.collect{|path, notify| path}.sort)
212     assert_equal(dirs_path.collect{true},
213                  infos.collect{|path, notify| notify.commit_added?})
214   end
216   def test_delete
217     log = "sample log"
218     src = "sample source\n"
219     file = "file.txt"
220     dir = "dir"
221     path = File.join(@wc_path, file)
222     dir_path = File.join(@wc_path, dir)
224     ctx = make_context(log)
226     File.open(path, "w") {|f| f.print(src)}
227     ctx.add(path)
228     ctx.mkdir(dir_path)
229     ctx.commit(@wc_path)
231     ctx.delete([path, dir_path])
232     ctx.commit(@wc_path)
233     assert(!File.exist?(path))
234     assert(!File.exist?(dir_path))
237     File.open(path, "w") {|f| f.print(src)}
238     ctx.add(path)
239     ctx.commit(@wc_path)
241     File.open(path, "w") {|f| f.print(src * 2)}
242     assert_raises(Svn::Error::ClientModified) do
243       ctx.delete(path)
244     end
245     assert_nothing_raised do
246       ctx.delete(path, true)
247       ctx.commit(@wc_path)
248     end
249     assert(!File.exist?(path))
250   end
252   def test_delete_alias
253     log = "sample log"
254     src = "sample source\n"
255     file = "file.txt"
256     dir = "dir"
257     path = File.join(@wc_path, file)
258     dir_path = File.join(@wc_path, dir)
260     ctx = make_context(log)
262     File.open(path, "w") {|f| f.print(src)}
263     ctx.add(path)
264     ctx.mkdir(dir_path)
265     ctx.commit(@wc_path)
267     ctx.rm([path, dir_path])
268     ctx.commit(@wc_path)
269     assert(!File.exist?(path))
270     assert(!File.exist?(dir_path))
273     File.open(path, "w") {|f| f.print(src)}
274     ctx.add(path)
275     ctx.commit(@wc_path)
277     File.open(path, "w") {|f| f.print(src * 2)}
278     assert_raises(Svn::Error::ClientModified) do
279       ctx.rm(path)
280     end
281     assert_nothing_raised do
282       ctx.rm_f(path)
283       ctx.commit(@wc_path)
284     end
285     assert(!File.exist?(path))
287     File.open(path, "w") {|f| f.print(src)}
288     ctx.add(path)
289     ctx.mkdir(dir_path)
290     ctx.commit(@wc_path)
292     ctx.rm_f(path, dir_path)
293     ctx.commit(@wc_path)
294     assert(!File.exist?(path))
295     assert(!File.exist?(dir_path))
296   end
298   def test_import
299     src = "source\n"
300     log = "sample log"
301     deep_dir = File.join(%w(a b c d e))
302     file = "sample.txt"
303     deep_dir_path = File.join(@wc_path, deep_dir)
304     path = File.join(deep_dir_path, file)
305     tmp_deep_dir_path = File.join(@tmp_path, deep_dir)
306     tmp_path = File.join(tmp_deep_dir_path, file)
308     ctx = make_context(log)
310     FileUtils.mkdir_p(tmp_deep_dir_path)
311     File.open(tmp_path, "w") {|f| f.print(src)}
313     ctx.import(@tmp_path, @repos_uri)
315     ctx.up(@wc_path)
316     assert_equal(src, File.open(path){|f| f.read})
317   end
319   def test_commit
320     log = "sample log"
321     dir1 = "dir1"
322     dir2 = "dir2"
323     dir1_path = File.join(@wc_path, dir1)
324     dir2_path = File.join(dir1_path, dir2)
326     ctx = make_context(log)
327     assert_equal(Svn::Core::INVALID_REVNUM,ctx.commit(@wc_path).revision)
328     ctx.mkdir(dir1_path)
329     assert_equal(0, youngest_rev)
330     assert_equal(1, ctx.commit(@wc_path).revision)
331     ctx.mkdir(dir2_path)
332     assert_equal(Svn::Core::INVALID_REVNUM,ctx.commit(@wc_path, false).revision)
333     assert_equal(2, ctx.ci(@wc_path).revision)
334   end
336   def test_status
337     log = "sample log"
338     file1 = "sample1.txt"
339     file2 = "sample2.txt"
340     dir = "dir"
341     dir_path = File.join(@wc_path, dir)
342     path1 = File.join(@wc_path, file1)
343     path2 = File.join(dir_path, file2)
345     ctx = make_context(log)
346     File.open(path1, "w") {}
347     ctx.add(path1)
348     rev1 = ctx.commit(@wc_path).revision
351     ctx.mkdir(dir_path)
352     File.open(path2, "w") {}
354     infos = []
355     rev = ctx.status(@wc_path) do |path, status|
356       infos << [path, status]
357     end
359     assert_equal(youngest_rev, rev)
360     assert_equal([dir_path, path2].sort,
361                  infos.collect{|path, status| path}.sort)
362     dir_status = infos.assoc(dir_path).last
363     assert(dir_status.text_added?)
364     assert(dir_status.entry.dir?)
365     assert(dir_status.entry.add?)
366     path2_status = infos.assoc(path2).last
367     assert(!path2_status.text_added?)
368     assert_nil(path2_status.entry)
371     infos = []
372     rev = ctx.st(@wc_path, rev1, true, true) do |path, status|
373       infos << [path, status]
374     end
376     assert_equal(rev1, rev)
377     assert_equal([@wc_path, dir_path, path1, path2].sort,
378                  infos.collect{|path, status| path}.sort)
379     wc_status = infos.assoc(@wc_path).last
380     assert(wc_status.text_normal?)
381     assert(wc_status.entry.dir?)
382     assert(wc_status.entry.normal?)
383     dir_status = infos.assoc(dir_path).last
384     assert(dir_status.text_added?)
385     assert(dir_status.entry.dir?)
386     assert(dir_status.entry.add?)
387     path1_status = infos.assoc(path1).last
388     assert(path1_status.text_normal?)
389     assert(path1_status.entry.file?)
390     assert(path1_status.entry.normal?)
391     path2_status = infos.assoc(path2).last
392     assert(!path2_status.text_added?)
393     assert_nil(path2_status.entry)
396     ctx.prop_set(Svn::Core::PROP_IGNORE, file2, dir_path)
398     infos = []
399     rev = ctx.status(@wc_path, nil, true, true, true, false) do |path, status|
400       infos << [path, status]
401     end
403     assert_equal(rev1, rev)
404     assert_equal([@wc_path, dir_path, path1].sort,
405                  infos.collect{|path, status| path}.sort)
408     infos = []
409     rev = ctx.status(@wc_path, nil, true, true, true, true) do |path, status|
410       infos << [path, status]
411     end
413     assert_equal(rev1, rev)
414     assert_equal([@wc_path, dir_path, path1, path2].sort,
415                  infos.collect{|path, status| path}.sort)
416   end
418   def test_status_with_depth
419     setup_greek_tree
421     log = "sample log"
422     ctx = make_context(log)
424     # make everything out-of-date
425     ctx.prop_set('propname', 'propvalue', @greek.path(:b), :infinity)
427     recurse_and_depth_choices.each do |rd|
428       ctx.status(@greek.path(:mu), nil, rd) do |path, status|
429         assert_equal @greek.uri(:mu), status.url
430       end
431     end
433     expected_statuses_by_depth = {
434       true => [:beta, :b, :lambda, :e, :f, :alpha],
435       false => [:b, :lambda, :e, :f],
436       'empty' => [:b],
437       'files' => [:b, :lambda],
438       'immediates' => [:b, :lambda, :e, :f],
439       'infinity' => [:beta, :b, :lambda, :e, :f, :alpha],
440     }
442     recurse_and_depth_choices.each do |rd|
443       urls = []
444       ctx.status(@greek.path(:b), nil, rd) do |path, status|
445         urls << status.url
446       end
447       assert_equal(expected_statuses_by_depth[rd].map{|s| @greek.uri(s)}.sort,
448                    urls.sort,
449                    "depth '#{rd}")
450     end
451   end
453   def test_checkout
454     log = "sample log"
455     file = "hello.txt"
456     dir = "dir"
457     dir_path = File.join(@wc_path, dir)
458     path = File.join(dir_path, file)
459     content = "Hello"
461     ctx = make_context(log)
462     ctx.mkdir(dir_path)
463     File.open(path, "w"){|f| f.print(content)}
464     ctx.add(path)
465     ctx.commit(@wc_path)
467     FileUtils.rm_rf(@wc_path)
468     ctx.checkout(@repos_uri, @wc_path)
469     assert(File.exist?(path))
471     FileUtils.rm_rf(@wc_path)
472     ctx.co(@repos_uri, @wc_path, nil, nil, false)
473     assert(!File.exist?(path))
474   end
476   def test_update
477     log = "sample log"
478     file = "hello.txt"
479     path = File.join(@wc_path, file)
480     content = "Hello"
481     File.open(path, "w"){|f| f.print(content)}
483     ctx = make_context(log)
485     assert_nothing_raised do
486       ctx.update(File.join(@wc_path, "non-exist"), youngest_rev)
487     end
489     ctx.add(path)
490     commit_info = ctx.commit(@wc_path)
492     FileUtils.rm(path)
493     assert(!File.exist?(path))
494     assert_equal(commit_info.revision,
495                  ctx.update(path, commit_info.revision))
496     assert_equal(content, File.read(path))
498     FileUtils.rm(path)
499     assert(!File.exist?(path))
500     assert_equal([commit_info.revision],
501                  ctx.update([path], commit_info.revision))
502     assert_equal(content, File.read(path))
504     assert_raise(Svn::Error::FS_NO_SUCH_REVISION) do
505       begin
506         ctx.update(path, commit_info.revision + 1)
507       ensure
508         ctx.cleanup(@wc_path)
509       end
510     end
511     assert_nothing_raised do
512       ctx.update(path + "non-exist", commit_info.revision)
513     end
514   end
516   def test_revert
517     log = "sample log"
518     file1 = "hello1.txt"
519     file2 = "hello2.txt"
520     file3 = "hello3.txt"
521     dir = "dir"
522     dir_path = File.join(@wc_path, dir)
523     path1 = File.join(@wc_path, file1)
524     path2 = File.join(@wc_path, file2)
525     path3 = File.join(dir_path, file3)
526     content = "Hello"
528     ctx = make_context(log)
529     File.open(path1, "w"){|f| f.print(content)}
530     File.open(path2, "w"){|f| f.print(content)}
531     ctx.add(path1)
532     ctx.add(path2)
533     ctx.mkdir(dir_path)
534     File.open(path3, "w"){|f| f.print(content)}
535     ctx.add(path3)
536     commit_info = ctx.commit(@wc_path)
538     File.open(path1, "w"){}
539     assert_equal("", File.open(path1){|f| f.read})
541     ctx.revert(path1)
542     assert_equal(content, File.open(path1){|f| f.read})
544     File.open(path1, "w"){}
545     File.open(path2, "w"){}
546     assert_equal("", File.open(path1){|f| f.read})
547     assert_equal("", File.open(path2){|f| f.read})
548     ctx.revert([path1, path2])
549     assert_equal(content, File.open(path1){|f| f.read})
550     assert_equal(content, File.open(path2){|f| f.read})
552     File.open(path1, "w"){}
553     File.open(path2, "w"){}
554     File.open(path3, "w"){}
555     assert_equal("", File.open(path1){|f| f.read})
556     assert_equal("", File.open(path2){|f| f.read})
557     assert_equal("", File.open(path3){|f| f.read})
558     ctx.revert(@wc_path)
559     assert_equal(content, File.open(path1){|f| f.read})
560     assert_equal(content, File.open(path2){|f| f.read})
561     assert_equal(content, File.open(path3){|f| f.read})
563     File.open(path1, "w"){}
564     File.open(path2, "w"){}
565     File.open(path3, "w"){}
566     assert_equal("", File.open(path1){|f| f.read})
567     assert_equal("", File.open(path2){|f| f.read})
568     assert_equal("", File.open(path3){|f| f.read})
569     ctx.revert(@wc_path, false)
570     assert_equal("", File.open(path1){|f| f.read})
571     assert_equal("", File.open(path2){|f| f.read})
572     assert_equal("", File.open(path3){|f| f.read})
574     File.open(path1, "w"){}
575     File.open(path2, "w"){}
576     File.open(path3, "w"){}
577     assert_equal("", File.open(path1){|f| f.read})
578     assert_equal("", File.open(path2){|f| f.read})
579     assert_equal("", File.open(path3){|f| f.read})
580     ctx.revert(dir_path)
581     assert_equal("", File.open(path1){|f| f.read})
582     assert_equal("", File.open(path2){|f| f.read})
583     assert_equal(content, File.open(path3){|f| f.read})
584   end
586   def test_log
587     log1 = "sample log1"
588     log2 = "sample log2"
589     log3 = "sample log3"
590     src1 = "source1\n"
591     src2 = "source2\n"
592     src3 = "source3\n"
593     file1 = "sample1.txt"
594     file2 = "sample2.txt"
595     file3 = "sample3.txt"
596     path1 = File.join(@wc_path, file1)
597     path2 = File.join(@wc_path, file2)
598     path3 = File.join(@wc_path, file3)
599     abs_path1 = File.join('', file1)
600     abs_path2 = File.join('', file2)
601     abs_path3 = File.join('', file3)
603     ctx = make_context(log1)
604     File.open(path1, "w") {|f| f.print(src1)}
605     ctx.add(path1)
606     rev1 = ctx.ci(@wc_path).revision
608     ctx = make_context(log2)
609     ctx.cp(path1, path2)
610     rev2 = ctx.ci(@wc_path).revision
612     ctx = make_context(log3)
613     ctx.cp(path1, path3)
614     File.open(path1, "w") {|f| f.print(src2)}
615     File.open(path3, "w") {|f| f.print(src3)}
616     rev3 = ctx.ci(@wc_path).revision
618     changed_paths_lists = {}
619     revs = {}
620     messages = {}
621     keys = [@wc_path, path1, path2, path3]
622     keys.each do |key|
623       revs[key] = []
624       changed_paths_lists[key] = []
625       messages[key] = []
626       args = [key, 1, "HEAD", 0, true, nil]
627       ctx.log(*args) do |changed_paths, rev, author, date, message|
628         revs[key] << rev
629         changed_paths_lists[key] << changed_paths
630         messages[key] << message
631       end
632     end
633     changed_paths_list = changed_paths_lists[@wc_path]
635     assert_equal([rev1, rev2, rev3], revs[@wc_path])
636     assert_equal([rev1, rev3], revs[path1])
637     assert_equal([rev1, rev2], revs[path2])
638     assert_equal([rev1, rev3], revs[path3])
639     assert_equal([log1, log2, log3], messages[@wc_path])
641     expected = [[abs_path1], [abs_path2], [abs_path1, abs_path3]]
642     actual = changed_paths_list.collect {|changed_paths| changed_paths.keys}
643     assert_nested_sorted_array(expected, actual)
645     assert_equal('A', changed_paths_list[0][abs_path1].action)
646     assert_false(changed_paths_list[0][abs_path1].copied?)
647     assert_equal('A', changed_paths_list[1][abs_path2].action)
648     assert_true(changed_paths_list[1][abs_path2].copied?)
649     assert_equal(abs_path1, changed_paths_list[1][abs_path2].copyfrom_path)
650     assert_equal(rev1, changed_paths_list[1][abs_path2].copyfrom_rev)
651     assert_equal('M', changed_paths_list[2][abs_path1].action)
652     assert_equal('A', changed_paths_list[2][abs_path3].action)
653   end
655   def test_log_message
656     log = "sample log"
657     file = "hello.txt"
658     path = File.join(@wc_path, file)
659     FileUtils.touch(path)
661     ctx = make_context(log)
662     ctx.add(path)
663     commit_info = ctx.commit(@wc_path)
664     rev = commit_info.revision
666     assert_equal(log, ctx.log_message(path, rev))
667   end
669   def test_blame
670     log = "sample log"
671     file = "hello.txt"
672     srcs = %w(first second third)
673     infos = []
674     path = File.join(@wc_path, file)
676     ctx = make_context(log)
678     File.open(path, "w") {|f| f.puts(srcs[0])}
679     ctx.add(path)
680     commit_info = ctx.commit(@wc_path)
681     infos << [0, commit_info.revision, @author, commit_info.date, srcs[0]]
683     File.open(path, "a") {|f| f.puts(srcs[1])}
684     commit_info = ctx.commit(@wc_path)
685     infos << [1, commit_info.revision, @author, commit_info.date, srcs[1]]
687     File.open(path, "a") {|f| f.puts(srcs[2])}
688     commit_info = ctx.commit(@wc_path)
689     infos << [2, commit_info.revision, @author, commit_info.date, srcs[2]]
691     result = []
692     ctx.blame(path) do |line_no, revision, author, date, line|
693       result << [line_no, revision, author, date, line]
694     end
695     assert_equal(infos, result)
698     ctx.prop_set(Svn::Core::PROP_MIME_TYPE, "image/DUMMY", path)
699     ctx.commit(@wc_path)
701     assert_raise(Svn::Error::CLIENT_IS_BINARY_FILE) do
702       ctx.ann(path) {}
703     end
704   end
706   def test_diff
707     log = "sample log"
708     before = "before\n"
709     after = "after\n"
710     file = "hello.txt"
711     path = File.join(@wc_path, file)
713     File.open(path, "w") {|f| f.print(before)}
715     ctx = make_context(log)
716     ctx.add(path)
717     commit_info = ctx.commit(@wc_path)
718     rev1 = commit_info.revision
720     File.open(path, "w") {|f| f.print(after)}
722     out_file = Tempfile.new("svn")
723     err_file = Tempfile.new("svn")
724     ctx.diff([], path, rev1, path, "WORKING", out_file.path, err_file.path)
725     out_file.open
726     assert_match(/-#{before}\+#{after}\z/, out_file.read)
728     commit_info = ctx.commit(@wc_path)
729     rev2 = commit_info.revision
730     out_file = Tempfile.new("svn")
731     ctx.diff([], path, rev1, path, rev2, out_file.path, err_file.path)
732     out_file.open
733     assert_match(/-#{before}\+#{after}\z/, out_file.read)
734   end
736   def test_diff_peg
737     log = "sample log"
738     before = "before\n"
739     after = "after\n"
740     file = "hello.txt"
741     path = File.join(@wc_path, file)
743     File.open(path, "w") {|f| f.print(before)}
745     ctx = make_context(log)
746     ctx.add(path)
747     commit_info = ctx.commit(@wc_path)
748     rev1 = commit_info.revision
750     File.open(path, "w") {|f| f.print(after)}
752     out_file = Tempfile.new("svn")
753     err_file = Tempfile.new("svn")
754     ctx.diff_peg([], path, rev1, "WORKING", out_file.path, err_file.path)
755     out_file.open
756     assert_match(/-#{before}\+#{after}\z/, out_file.read)
758     commit_info = ctx.commit(@wc_path)
759     rev2 = commit_info.revision
760     out_file = Tempfile.new("svn")
761     ctx.diff_peg([], path, rev1, rev2, out_file.path, err_file.path)
762     out_file.open
763     assert_match(/-#{before}\+#{after}\z/, out_file.read)
764   end
766   def test_diff_summarize
767     log = "sample log"
768     before = "before\n"
769     after = "after\n"
770     file = "hello.txt"
771     path = File.join(@wc_path, file)
773     File.open(path, "w") {|f| f.print(before)}
775     ctx = make_context(log)
776     ctx.add(path)
777     commit_info = ctx.commit(@wc_path)
778     rev1 = commit_info.revision
780     File.open(path, "w") {|f| f.print(after)}
782     commit_info = ctx.commit(@wc_path)
783     rev2 = commit_info.revision
785     diffs = []
786     ctx.diff_summarize(@wc_path, rev1, @wc_path, rev2) do |diff|
787       diffs << diff
788     end
789     assert_equal([file], diffs.collect {|d| d.path})
790     kinds = diffs.collect do |d|
791       [d.kind_normal?, d.kind_added?, d.kind_modified?, d.kind_deleted?]
792     end
793     assert_equal([[false, false, true, false]], kinds)
794     assert_equal([false], diffs.collect {|d| d.prop_changed?})
795     node_kinds = diffs.collect do |d|
796       [d.node_kind_none?, d.node_kind_file?,
797        d.node_kind_dir?, d.node_kind_unknown?]
798     end
799     assert_equal([[false, true, false, false]], node_kinds)
800   end
802   def test_diff_summarize_peg
803     log = "sample log"
804     before = "before\n"
805     after = "after\n"
806     before_file = "before.txt"
807     after_file = "after.txt"
808     moved_file = "moved.txt"
809     before_path = File.join(@wc_path, before_file)
810     after_path = File.join(@wc_path, after_file)
811     moved_path = File.join(@wc_path, moved_file)
813     File.open(before_path, "w") {|f| f.print(before)}
815     ctx = make_context(log)
816     ctx.add(before_path)
817     commit_info = ctx.commit(@wc_path)
818     rev1 = commit_info.revision
820     ctx.mv(before_path, after_path)
821     commit_info = ctx.commit(@wc_path)
822     rev2 = commit_info.revision
824     File.open(after_path, "w") {|f| f.print(after)}
825     commit_info = ctx.commit(@wc_path)
826     rev3 = commit_info.revision
828     File.open(after_path, "w") {|f| f.print(before)}
829     commit_info = ctx.commit(@wc_path)
830     rev4 = commit_info.revision
832     ctx.mv(after_path, moved_path)
833     commit_info = ctx.commit(@wc_path)
834     rev5 = commit_info.revision
836     diffs = []
837     ctx.diff_summarize_peg(@repos_uri, rev3, rev4, rev3) do |diff|
838       diffs << diff
839     end
840     assert_equal([after_file], diffs.collect {|d| d.path})
841     kinds = diffs.collect do |d|
842       [d.kind_normal?, d.kind_added?, d.kind_modified?, d.kind_deleted?]
843     end
844     assert_equal([[false, false, true, false]], kinds)
845     assert_equal([false], diffs.collect {|d| d.prop_changed?})
846     node_kinds = diffs.collect do |d|
847       [d.node_kind_none?, d.node_kind_file?,
848        d.node_kind_dir?, d.node_kind_unknown?]
849     end
850     assert_equal([[false, true, false, false]], node_kinds)
851   end
853   def test_merge
854     log = "sample log"
855     file = "sample.txt"
856     src = "sample\n"
857     trunk = File.join(@wc_path, "trunk")
858     branch = File.join(@wc_path, "branch")
859     trunk_path = File.join(trunk, file)
860     branch_path = File.join(branch, file)
862     ctx = make_context(log)
863     ctx.mkdir(trunk, branch)
864     File.open(trunk_path, "w") {}
865     File.open(branch_path, "w") {}
866     ctx.add(trunk_path)
867     ctx.add(branch_path)
868     rev1 = ctx.commit(@wc_path).revision
870     File.open(branch_path, "w") {|f| f.print(src)}
871     rev2 = ctx.commit(@wc_path).revision
873     assert_nil(ctx.mergeinfo(trunk))
874     ctx.merge(branch, rev1, branch, rev2, trunk)
875     mergeinfo = ctx.mergeinfo(trunk)
876     expected_key = ctx.url_from_path(branch)
877     assert_equal([expected_key], mergeinfo.keys)
878     assert_equal([[1, 2, true]],
879                  mergeinfo[expected_key].collect {|range| range.to_a})
880     rev3 = ctx.commit(@wc_path).revision
882     assert_equal(normalize_line_break(src), ctx.cat(trunk_path, rev3))
884     ctx.rm(branch_path)
885     rev4 = ctx.commit(@wc_path).revision
887     ctx.merge(branch, rev3, branch, rev4, trunk)
888     assert(!File.exist?(trunk_path))
890     mergeinfo = ctx.mergeinfo(trunk, rev4)
891     assert_equal([expected_key], mergeinfo.keys)
892     assert_equal([[1, 2, true], [3, 4, true]],
893                  mergeinfo[expected_key].collect {|range| range.to_a })
894     ctx.propdel("svn:mergeinfo", trunk)
895     assert_nil ctx.mergeinfo(trunk)
897     ctx.revert(trunk_path)
898     File.open(trunk_path, "a") {|f| f.print(src)}
899     ctx.merge(branch, rev3, branch, rev4, trunk)
900     assert(File.exist?(trunk_path))
901     rev5 = ctx.commit(@wc_path).revision
903     File.open(trunk_path, "a") {|f| f.print(src)}
904     ctx.merge(branch, rev3, branch, rev4, trunk, true, false, true, true)
905     assert(File.exist?(trunk_path))
907     ctx.merge(branch, rev3, branch, rev4, trunk, true, false, true)
908     rev6 = ctx.commit(@wc_path).revision
910     assert(!File.exist?(trunk_path))
911   end
913   def test_merge_peg
914     log = "sample log"
915     file = "sample.txt"
916     src = "sample\n"
917     trunk = File.join(@wc_path, "trunk")
918     branch = File.join(@wc_path, "branch")
919     trunk_path = File.join(trunk, file)
920     branch_path = File.join(branch, file)
922     ctx = make_context(log)
923     ctx.mkdir(trunk, branch)
924     File.open(trunk_path, "w") {}
925     File.open(branch_path, "w") {}
926     ctx.add(trunk_path)
927     ctx.add(branch_path)
928     rev1 = ctx.commit(@wc_path).revision
930     File.open(branch_path, "w") {|f| f.print(src)}
931     rev2 = ctx.commit(@wc_path).revision
933     assert_nil(ctx.mergeinfo(trunk))
934     ctx.merge_peg(branch, rev1, rev2, trunk)
935     mergeinfo = ctx.mergeinfo(trunk)
936     expected_key = ctx.url_from_path(branch)
937     assert_equal([expected_key], mergeinfo.keys)
938     assert_equal([[1, 2, true]],
939                  mergeinfo[expected_key].collect {|range| range.to_a})
940     rev3 = ctx.commit(@wc_path).revision
942     assert_equal(normalize_line_break(src), ctx.cat(trunk_path, rev3))
944     ctx.rm(branch_path)
945     rev4 = ctx.commit(@wc_path).revision
947     ctx.merge_peg(branch, rev3, rev4, trunk)
948     assert(!File.exist?(trunk_path))
950     mergeinfo = ctx.mergeinfo(trunk, rev4)
951     assert_equal([expected_key], mergeinfo.keys)
952     assert_equal([[1, 2, true], [3, 4, true]],
953                  mergeinfo[expected_key].collect {|range| range.to_a })
954     ctx.propdel("svn:mergeinfo", trunk)
955     assert_nil(ctx.mergeinfo(trunk))
957     ctx.revert(trunk_path)
958     File.open(trunk_path, "a") {|f| f.print(src)}
959     ctx.merge_peg(branch, rev3, rev4, trunk)
960     assert(File.exist?(trunk_path))
961     rev5 = ctx.commit(@wc_path).revision
963     File.open(trunk_path, "a") {|f| f.print(src)}
964     ctx.merge_peg(branch, rev3, rev4, trunk, nil, true, false, true, true)
965     assert(File.exist?(trunk_path))
967     ctx.merge_peg(branch, rev3, rev4, trunk, nil, true, false, true)
968     rev6 = ctx.commit(@wc_path).revision
970     assert(!File.exist?(trunk_path))
971   end
973   def test_cleanup
974     log = "sample log"
975     file = "sample.txt"
976     src = "sample\n"
977     path = File.join(@wc_path, file)
979     ctx = make_context(log)
980     File.open(path, "w") {|f| f.print(src)}
981     ctx.add(path)
982     rev = ctx.commit(@wc_path).revision
984     ctx.up(@wc_path, rev - 1)
985     File.open(path, "w") {|f| f.print(src)}
987     assert_raise(Svn::Error::WC_OBSTRUCTED_UPDATE) do
988       ctx.up(@wc_path, rev)
989     end
991     Svn::Wc::AdmAccess.open(nil, @wc_path, true, -1) do |access|
992       assert_raise(Svn::Error::WC_LOCKED) do
993         ctx.commit(@wc_path)
994       end
995     end
997     ctx.set_cancel_func do
998       raise Svn::Error::CANCELLED
999     end
1000     Svn::Wc::AdmAccess.open(nil, @wc_path, true, -1) do |access|
1001       assert_raise(Svn::Error::CANCELLED) do
1002         ctx.cleanup(@wc_path)
1003       end
1004       assert_raise(Svn::Error::WC_LOCKED) do
1005         ctx.commit(@wc_path)
1006       end
1007     end
1009     ctx.set_cancel_func(nil)
1010     access = Svn::Wc::AdmAccess.open(nil, @wc_path, true, -1)
1011     assert_nothing_raised do
1012       ctx.cleanup(@wc_path)
1013     end
1014     assert_nothing_raised do
1015       ctx.commit(@wc_path)
1016     end
1017     assert_raises(Svn::Error::SvnError) do
1018       access.close
1019     end
1020   end
1022   def test_relocate
1023     log = "sample log"
1024     file = "sample.txt"
1025     src = "sample\n"
1026     path = File.join(@wc_path, file)
1028     ctx = make_context(log)
1029     File.open(path, "w") {|f| f.print(src)}
1030     ctx.add(path)
1031     ctx.commit(@wc_path)
1033     assert_nothing_raised do
1034       ctx.cat(path)
1035     end
1037     ctx.add_simple_prompt_provider(0) do |cred, realm, username, may_save|
1038       cred.username = @author
1039       cred.password = @password
1040       cred.may_save = true
1041     end
1042     ctx.relocate(@wc_path, @repos_uri, @repos_svnserve_uri)
1044     ctx = make_context(log)
1045     assert_raises(Svn::Error::AuthnNoProvider) do
1046       ctx.cat(path)
1047     end
1048   end
1050   def test_resolved
1051     log = "sample log"
1052     file = "sample.txt"
1053     dir = "dir"
1054     src1 = "before\n"
1055     src2 = "after\n"
1056     dir_path = File.join(@wc_path, dir)
1057     path = File.join(dir_path, file)
1059     ctx = make_context(log)
1060     ctx.mkdir(dir_path)
1061     File.open(path, "w") {}
1062     ctx.add(path)
1063     rev1 = ctx.ci(@wc_path).revision
1065     File.open(path, "w") {|f| f.print(src1)}
1066     rev2 = ctx.ci(@wc_path).revision
1068     ctx.up(@wc_path, rev1)
1070     File.open(path, "w") {|f| f.print(src2)}
1071     ctx.up(@wc_path)
1073     assert_raises(Svn::Error::WcFoundConflict) do
1074       ctx.ci(@wc_path)
1075     end
1077     ctx.resolved(dir_path, false)
1078     assert_raises(Svn::Error::WcFoundConflict) do
1079       ctx.ci(@wc_path)
1080     end
1082     ctx.resolved(dir_path)
1083     info = nil
1084     assert_nothing_raised do
1085       info = ctx.ci(@wc_path)
1086     end
1087     assert_not_nil(info)
1088     assert_equal(rev2 + 1, info.revision)
1089   end
1091   def test_copy
1092     log = "sample log"
1093     src = "source\n"
1094     file1 = "sample1.txt"
1095     file2 = "sample2.txt"
1096     path1 = File.join(@wc_path, file1)
1097     path2 = File.join(@wc_path, file2)
1099     ctx = make_context(log)
1100     File.open(path1, "w") {|f| f.print(src)}
1101     ctx.add(path1)
1103     ctx.ci(@wc_path)
1105     ctx.cp(path1, path2)
1107     infos = []
1108     ctx.set_notify_func do |notify|
1109       infos << [notify.path, notify]
1110     end
1111     ctx.ci(@wc_path)
1113     assert_equal([path2].sort,
1114                  infos.collect{|path, notify| path}.sort)
1115     path2_notify = infos.assoc(path2)[1]
1116     assert(path2_notify.commit_added?)
1117     assert_equal(File.open(path1) {|f| f.read},
1118                  File.open(path2) {|f| f.read})
1119   end
1121   def test_move
1122     log = "sample log"
1123     src = "source\n"
1124     file1 = "sample1.txt"
1125     file2 = "sample2.txt"
1126     path1 = File.join(@wc_path, file1)
1127     path2 = File.join(@wc_path, file2)
1129     ctx = make_context(log)
1130     File.open(path1, "w") {|f| f.print(src)}
1131     ctx.add(path1)
1133     ctx.ci(@wc_path)
1135     ctx.mv(path1, path2)
1137     infos = []
1138     ctx.set_notify_func do |notify|
1139       infos << [notify.path, notify]
1140     end
1141     ctx.ci(@wc_path)
1143     assert_equal([path1, path2].sort,
1144                  infos.collect{|path, notify| path}.sort)
1145     path1_notify = infos.assoc(path1)[1]
1146     assert(path1_notify.commit_deleted?)
1147     path2_notify = infos.assoc(path2)[1]
1148     assert(path2_notify.commit_added?)
1149     assert_equal(src, File.open(path2) {|f| f.read})
1150   end
1152   def test_move_force
1153     log = "sample log"
1154     src1 = "source1\n"
1155     src2 = "source2\n"
1156     file1 = "sample1.txt"
1157     file2 = "sample2.txt"
1158     path1 = File.join(@wc_path, file1)
1159     path2 = File.join(@wc_path, file2)
1161     ctx = make_context(log)
1162     File.open(path1, "w") {|f| f.print(src1)}
1163     ctx.add(path1)
1164     ctx.ci(@wc_path)
1166     File.open(path1, "w") {|f| f.print(src2)}
1167     assert_nothing_raised do
1168       ctx.mv(path1, path2)
1169     end
1170     ctx.revert([path1, path2])
1171     FileUtils.rm(path2)
1173     File.open(path1, "w") {|f| f.print(src2)}
1174     assert_nothing_raised do
1175       ctx.mv_f(path1, path2)
1176     end
1178     notifies = []
1179     ctx.set_notify_func do |notify|
1180       notifies << notify
1181     end
1182     ctx.ci(@wc_path)
1184     paths = notifies.collect do |notify|
1185       notify.path
1186     end
1187     assert_equal([path1, path2, path2].sort, paths.sort)
1189     deleted_paths = notifies.find_all do |notify|
1190       notify.commit_deleted?
1191     end.collect do |notify|
1192       notify.path
1193     end
1194     assert_equal([path1].sort, deleted_paths.sort)
1196     added_paths = notifies.find_all do |notify|
1197       notify.commit_added?
1198     end.collect do |notify|
1199       notify.path
1200     end
1201     assert_equal([path2].sort, added_paths.sort)
1203     postfix_txdelta_paths = notifies.find_all do |notify|
1204       notify.commit_postfix_txdelta?
1205     end.collect do |notify|
1206       notify.path
1207     end
1208     assert_equal([path2].sort, postfix_txdelta_paths.sort)
1210     assert_equal(src2, File.open(path2) {|f| f.read})
1211   end
1213   def test_prop
1214     log = "sample log"
1215     dir = "dir"
1216     file = "sample.txt"
1217     dir_path = File.join(@wc_path, dir)
1218     dir_uri = "#{@repos_uri}/#{dir}"
1219     path = File.join(dir_path, file)
1220     uri = "#{dir_uri}/#{file}"
1221     prop_name = "sample-prop"
1222     prop_value = "sample value"
1223     invalid_mime_type_prop_value = "image"
1225     ctx = make_context(log)
1227     ctx.mkdir(dir_path)
1228     File.open(path, "w") {}
1229     ctx.add(path)
1231     ctx.commit(@wc_path)
1233     assert_equal({}, ctx.prop_get(prop_name, path))
1234     ctx.prop_set(prop_name, prop_value, path)
1235     ctx.commit(@wc_path)
1236     assert_equal({uri => prop_value}, ctx.pget(prop_name, path))
1238     ctx.prop_del(prop_name, path)
1239     ctx.commit(@wc_path)
1240     assert_equal({}, ctx.pg(prop_name, path))
1242     ctx.ps(prop_name, prop_value, path)
1243     ctx.commit(@wc_path)
1244     assert_equal({uri => prop_value}, ctx.pg(prop_name, path))
1246     ctx.ps(prop_name, nil, path)
1247     ctx.commit(@wc_path)
1248     assert_equal({}, ctx.pg(prop_name, path))
1250     ctx.up(@wc_path)
1251     ctx.ps(prop_name, prop_value, dir_path)
1252     ctx.ci(@wc_path)
1253     assert_equal({
1254                    dir_uri => prop_value,
1255                    uri => prop_value,
1256                  },
1257                  ctx.pg(prop_name, dir_path))
1259     ctx.up(@wc_path)
1260     ctx.pdel(prop_name, dir_path, false)
1261     ctx.ci(@wc_path)
1262     assert_equal({uri => prop_value}, ctx.pg(prop_name, dir_path))
1264     ctx.up(@wc_path)
1265     ctx.pd(prop_name, dir_path)
1266     ctx.ci(@wc_path)
1267     assert_equal({}, ctx.pg(prop_name, dir_path))
1269     ctx.up(@wc_path)
1270     ctx.ps(prop_name, prop_value, dir_path, false)
1271     ctx.ci(@wc_path)
1272     assert_equal({dir_uri => prop_value}, ctx.pg(prop_name, dir_path))
1274     assert_raises(Svn::Error::BadMimeType) do
1275       ctx.ps(Svn::Core::PROP_MIME_TYPE,
1276              invalid_mime_type_prop_value,
1277              path)
1278     end
1279     ctx.cleanup(@wc_path)
1281     assert_nothing_raised do
1282       ctx.ps(Svn::Core::PROP_MIME_TYPE,
1283              invalid_mime_type_prop_value,
1284              path, false, true)
1285     end
1286     ctx.commit(@wc_path)
1287     assert_equal({uri => invalid_mime_type_prop_value},
1288                  ctx.pg(Svn::Core::PROP_MIME_TYPE, path))
1289   end
1291   def test_prop_list
1292     log = "sample log"
1293     dir = "dir"
1294     file = "sample.txt"
1295     dir_path = File.join(@wc_path, dir)
1296     path = File.join(dir_path, file)
1297     dir_uri = "#{@repos_uri}/#{dir}"
1298     uri = "#{dir_uri}/#{file}"
1299     name1 = "name1"
1300     name2 = "name2"
1301     value1 = "value1"
1302     value2 = "value2"
1304     ctx = make_context(log)
1306     ctx.mkdir(dir_path)
1307     File.open(path, "w") {}
1308     ctx.add(path)
1310     ctx.ci(@wc_path)
1312     assert_equal([], ctx.prop_list(path))
1314     ctx.ps(name1, value1, path)
1315     ctx.ci(@wc_path)
1316     assert_equal([uri], ctx.prop_list(path).collect{|item| item.node_name})
1317     assert_equal([{name1 => value1}],
1318                  ctx.plist(path).collect{|item| item.prop_hash})
1319     assert_equal([value1], ctx.pl(path).collect{|item| item[name1]})
1321     ctx.up(@wc_path)
1322     ctx.ps(name2, value2, dir_path)
1323     ctx.ci(@wc_path)
1324     assert_equal([uri, dir_uri].sort,
1325                  ctx.prop_list(dir_path).collect{|item| item.name})
1326     prop_list = ctx.plist(dir_path).collect{|item| [item.name, item.props]}
1327     props = prop_list.assoc(uri)[1]
1328     dir_props = prop_list.assoc(dir_uri)[1]
1329     assert_equal({name1 => value1, name2 => value2}, props)
1330     assert_equal({name2 => value2}, dir_props)
1331   end
1333   def recurse_and_depth_choices
1334     [false, true, 'empty', 'files', 'immediates', 'infinity']
1335   end
1337   def test_file_prop
1338     setup_greek_tree
1340     log = "sample log"
1341     ctx = make_context(log)
1343     # when no props set, everything is empty
1344     recurse_and_depth_choices.each do |rd|
1345       assert_equal([],
1346                    ctx.prop_list(@greek.path(:mu), nil, nil, rd),
1347                    "prop_list with Depth '#{rd}'")
1348     end
1350     recurse_and_depth_choices.each do |rd|
1351       assert_equal({},
1352                    ctx.prop_get(rd.to_s, @greek.path(:mu), nil, nil, rd),
1353                    "prop_get with Depth '#{rd}'")
1354     end
1356     # set some props
1357     recurse_and_depth_choices.each do |rd|
1358       ctx.prop_set(rd.to_s, rd.to_s, @greek.path(:mu), rd)
1359     end
1360     ctx.commit(@greek.path(:mu))
1362     # get the props
1363     recurse_and_depth_choices.each do |rd|
1364       assert_equal({@greek.uri(:mu) => rd.to_s},
1365                    ctx.prop_get(rd.to_s, @greek.path(:mu), nil, nil, rd),
1366                    "prop_get with Depth '#{rd}'")
1367     end
1369     prop_hash = {}
1370     recurse_and_depth_choices.each {|rd| prop_hash[rd.to_s] = rd.to_s}
1372     # list the props
1373     recurse_and_depth_choices.each do |rd|
1374       props = ctx.prop_list(@greek.path(:mu), nil, nil, rd)
1375       assert_equal([@greek.uri(:mu)],
1376                    props.collect {|item| item.node_name},
1377                    "prop_list (node_name) with Depth '#{rd}'")
1379       props = ctx.plist(@greek.path(:mu), nil, nil, rd)
1380       assert_equal([prop_hash],
1381                    props.collect {|item| item.prop_hash},
1382                    "prop_list (prop_hash) with Depth '#{rd}'")
1384       recurse_and_depth_choices.each do |rd1|
1385         props = ctx.plist(@greek.path(:mu), nil, nil, rd)
1386         assert_equal([rd1.to_s],
1387                      props.collect {|item| item[rd1.to_s]},
1388                      "prop_list (#{rd1.to_s}]) with Depth '#{rd}'")
1389       end
1390     end
1392   end
1394   def test_dir_prop
1395     setup_greek_tree
1397     log = "sample log"
1398     ctx = make_context(log)
1400     # when no props set, everything is empty
1401     recurse_and_depth_choices.each do |rd|
1402       assert_equal([],
1403                    ctx.prop_list(@greek.path(:b), nil, nil, rd),
1404                    "prop_list with Depth '#{rd}'")
1405     end
1407     recurse_and_depth_choices.each do |rd|
1408       assert_equal({},
1409                    ctx.prop_get(rd.to_s, @greek.path(:b), nil, nil, rd),
1410                    "prop_get with Depth '#{rd}'")
1411     end
1413     # set some props with various depths
1414     recurse_and_depth_choices.each do |rd|
1415       ctx.prop_set(rd.to_s, rd.to_s, @greek.path(:b), rd)
1416     end
1417     ctx.commit(@greek.path(:b))
1419     expected_props = {
1420       true => [:beta, :b, :lambda, :e, :f, :alpha],
1421       false => [:b],
1422       'empty' => [:b],
1423       'files' => [:b, :lambda],
1424       'immediates' => [:b, :lambda, :e, :f],
1425       'infinity' => [:beta, :b, :lambda, :e, :f, :alpha],
1426     }
1428     paths = [:b, :e, :alpha, :beta, :f, :lambda]
1430     # how are the props set?
1431     recurse_and_depth_choices.each do |rd|
1432       paths.each do |path|
1433         if expected_props[rd].include?(path)
1434           expected = {@greek.uri(path) => rd.to_s}
1435         else
1436           expected = {}
1437         end
1438         assert_equal(expected,
1439                      ctx.prop_get(rd.to_s, @greek.path(path), nil, nil, false),
1440                      "prop_get #{@greek.resolve(path)} with Depth '#{rd}'")
1441       end
1442     end
1444     recurse_and_depth_choices.each do |rd_for_prop|
1445       recurse_and_depth_choices.each do |rd_for_depth|
1446         expected = {}
1447         expected_paths = expected_props[rd_for_depth]
1448         expected_paths &= expected_props[rd_for_prop]
1449         expected_paths.each do |path|
1450           expected[@greek.uri(path)] = rd_for_prop.to_s
1451         end
1453         assert_equal(expected,
1454                      ctx.prop_get(rd_for_prop.to_s, @greek.path(:b),
1455                                   nil, nil, rd_for_depth),
1456                      "prop_get '#{rd_for_prop}' with Depth '#{rd_for_depth}'")
1458       end
1459     end
1461     recurse_and_depth_choices.each do |rd|
1462       props = ctx.prop_list(@greek.path(:b), nil, nil, rd)
1463       assert_equal(expected_props[rd].collect {|path| @greek.uri(path)}.sort,
1464                    props.collect {|item| item.node_name}.sort,
1465                    "prop_list (node_name) with Depth '#{rd}'")
1466     end
1467   end
1469   def test_cat
1470     log = "sample log"
1471     src1 = "source1\n"
1472     src2 = "source2\n"
1473     file = "sample.txt"
1474     path = File.join(@wc_path, file)
1476     File.open(path, "w") {|f| f.print(src1)}
1478     ctx = make_context(log)
1479     ctx.add(path)
1480     commit_info = ctx.commit(@wc_path)
1481     rev1 = commit_info.revision
1483     assert_equal(normalize_line_break(src1), ctx.cat(path, rev1))
1484     assert_equal(normalize_line_break(src1), ctx.cat(path))
1486     File.open(path, "w") {|f| f.print(src2)}
1488     commit_info = ctx.commit(@wc_path)
1489     rev2 = commit_info.revision
1491     assert_equal(normalize_line_break(src1), ctx.cat(path, rev1))
1492     assert_equal(normalize_line_break(src2), ctx.cat(path, rev2))
1493     assert_equal(normalize_line_break(src2), ctx.cat(path))
1494   end
1496   def test_lock
1497     log = "sample log"
1498     src = "source\n"
1499     file = "sample.txt"
1500     path = File.join(@wc_path, file)
1502     File.open(path, "w") {|f| f.print(src)}
1504     ctx = make_context(log)
1505     ctx.add(path)
1506     ctx.commit(@wc_path)
1508     infos = []
1509     ctx.set_notify_func do |notify|
1510       infos << [notify.path, notify]
1511     end
1512     ctx.lock(path)
1514     assert_equal([file], infos.collect{|path, notify| path})
1515     file_notify = infos.assoc(file)[1]
1516     assert(file_notify.locked?)
1517   end
1519   def test_unlock
1520     log = "sample log"
1521     src = "source\n"
1522     file = "sample.txt"
1523     path = File.join(@wc_path, file)
1525     File.open(path, "w") {|f| f.print(src)}
1527     ctx = make_context(log)
1528     ctx.add(path)
1529     ctx.commit(@wc_path)
1531     ctx.lock(path)
1533     infos = []
1534     ctx.set_notify_func do |notify|
1535       infos << [notify.path, notify]
1536     end
1537     ctx.unlock(path)
1538     assert_equal([file], infos.collect{|path, notify| path})
1539     file_notify = infos.assoc(file)[1]
1540     assert(file_notify.unlocked?)
1541   end
1543   def test_info
1544     log = "sample log"
1545     ctx = make_context(log)
1546     repos_base = File.basename(@repos_path)
1548     infos = []
1549     ctx.info(@wc_path) do |path, info|
1550       infos << [path, info]
1551     end
1552     assert_equal([repos_base],
1553                  infos.collect{|path, info| path})
1554     top_info = infos.assoc(repos_base)[1]
1555     assert_equal(@repos_uri, top_info.url)
1556   end
1558   def test_info_with_depth
1559     setup_greek_tree
1561     log = "sample log"
1562     ctx = make_context(log)
1564     recurse_and_depth_choices.each do |rd|
1565       ctx.info(@greek.path(:mu),nil,nil,rd) do |path, info|
1566         assert_equal @greek.uri(:mu), info.URL
1567       end
1568     end
1570     expected_info_by_depth = {
1571       true => [:beta, :b, :lambda, :e, :f, :alpha],
1572       false => [:b],
1573       'empty' => [:b],
1574       'files' => [:b, :lambda],
1575       'immediates' => [:b, :lambda, :e, :f],
1576       'infinity' => [:beta, :b, :lambda, :e, :f, :alpha],
1577     }
1579     recurse_and_depth_choices.each do |rd|
1580       urls = []
1581       ctx.info(@greek.path(:b),nil,nil,rd) do |path, info|
1582         urls << info.URL
1583       end
1584       assert_equal expected_info_by_depth[rd].map{|s| @greek.uri(s)}.sort,
1585                    urls.sort,
1586                    "depth '#{rd}"
1587     end
1588   end
1590   def test_url_from_path
1591     log = "sample log"
1592     ctx = make_context(log)
1593     assert_equal(@repos_uri, ctx.url_from_path(@wc_path))
1594     assert_equal(@repos_uri, Svn::Client.url_from_path(@wc_path))
1595   end
1597   def test_uuid
1598     log = "sample log"
1599     ctx = make_context(log)
1600     Svn::Wc::AdmAccess.open(nil, @wc_path, false, 0) do |adm|
1601       assert_equal(ctx.uuid_from_url(@repos_uri),
1602                    ctx.uuid_from_path(@wc_path, adm))
1603     end
1604   end
1606   def test_open_ra_session
1607     log = "sample log"
1608     ctx = make_context(log)
1610     assert_instance_of(Svn::Ra::Session, ctx.open_ra_session(@repos_uri))
1611   end
1613   def test_revprop
1614     log = "sample log"
1615     new_log = "new sample log"
1616     src = "source\n"
1617     file = "sample.txt"
1618     path = File.join(@wc_path, file)
1620     File.open(path, "w") {|f| f.print(src)}
1622     ctx = make_context(log)
1623     ctx.add(path)
1624     info = ctx.commit(@wc_path)
1626     assert_equal([
1627                    {
1628                      Svn::Core::PROP_REVISION_AUTHOR => @author,
1629                      Svn::Core::PROP_REVISION_DATE => info.date,
1630                      Svn::Core::PROP_REVISION_LOG => log,
1631                    },
1632                    info.revision
1633                  ],
1634                  ctx.revprop_list(@repos_uri, info.revision))
1636     assert_equal([log, info.revision],
1637                  ctx.revprop_get(Svn::Core::PROP_REVISION_LOG,
1638                                  @repos_uri, info.revision))
1639     assert_equal(log,
1640                  ctx.revprop(Svn::Core::PROP_REVISION_LOG,
1641                              @repos_uri, info.revision))
1643     assert_equal(info.revision,
1644                  ctx.revprop_set(Svn::Core::PROP_REVISION_LOG, new_log,
1645                                  @repos_uri, info.revision))
1646     assert_equal([new_log, info.revision],
1647                  ctx.rpget(Svn::Core::PROP_REVISION_LOG,
1648                            @repos_uri, info.revision))
1649     assert_equal(new_log,
1650                  ctx.rp(Svn::Core::PROP_REVISION_LOG,
1651                         @repos_uri, info.revision))
1652     assert_equal([
1653                    {
1654                      Svn::Core::PROP_REVISION_AUTHOR => @author,
1655                      Svn::Core::PROP_REVISION_DATE => info.date,
1656                      Svn::Core::PROP_REVISION_LOG => new_log,
1657                    },
1658                    info.revision
1659                  ],
1660                  ctx.rplist(@repos_uri, info.revision))
1662     assert_equal(info.revision,
1663                  ctx.revprop_del(Svn::Core::PROP_REVISION_LOG,
1664                                  @repos_uri, info.revision))
1665     assert_equal([nil, info.revision],
1666                  ctx.rpg(Svn::Core::PROP_REVISION_LOG,
1667                          @repos_uri, info.revision))
1668     assert_equal(nil,
1669                  ctx.rp(Svn::Core::PROP_REVISION_LOG,
1670                         @repos_uri, info.revision))
1672     assert_equal(info.revision,
1673                  ctx.rpset(Svn::Core::PROP_REVISION_LOG, new_log,
1674                            @repos_uri, info.revision))
1675     assert_equal(new_log,
1676                  ctx.rp(Svn::Core::PROP_REVISION_LOG,
1677                         @repos_uri, info.revision))
1678     assert_equal(info.revision,
1679                  ctx.rps(Svn::Core::PROP_REVISION_LOG, nil,
1680                          @repos_uri, info.revision))
1681     assert_equal(nil,
1682                  ctx.rp(Svn::Core::PROP_REVISION_LOG,
1683                         @repos_uri, info.revision))
1685     assert_equal([
1686                    {
1687                      Svn::Core::PROP_REVISION_AUTHOR => @author,
1688                      Svn::Core::PROP_REVISION_DATE => info.date,
1689                    },
1690                    info.revision
1691                  ],
1692                  ctx.rpl(@repos_uri, info.revision))
1693   end
1695   def test_export
1696     log = "sample log"
1697     src = "source\n"
1698     file = "sample.txt"
1699     dir = "sample"
1700     dir_path = File.join(@wc_path, dir)
1701     path = File.join(dir_path, file)
1702     tmp_base_path = File.join(@tmp_path, "tmp")
1703     tmp_dir_path = File.join(tmp_base_path, dir)
1704     tmp_path = File.join(tmp_dir_path, file)
1706     ctx = make_context(log)
1708     ctx.mkdir(dir_path)
1709     File.open(path, "w") {|f| f.print(src)}
1710     ctx.add(path)
1711     rev = ctx.ci(@wc_path).revision
1713     assert_equal(rev, ctx.export(@repos_uri, tmp_base_path))
1714     assert_equal(src, File.open(tmp_path) {|f| f.read})
1715   end
1717   def test_ls
1718     log = "sample log"
1719     src = "source\n"
1720     file = "sample.txt"
1721     dir = "sample"
1722     dir_path = File.join(@wc_path, dir)
1723     path = File.join(@wc_path, file)
1725     ctx = make_context(log)
1727     ctx.mkdir(dir_path)
1728     File.open(path, "w") {|f| f.print(src)}
1729     ctx.add(path)
1730     rev = ctx.ci(@wc_path).revision
1732     dirents, locks = ctx.ls(@wc_path, rev)
1733     assert_equal([dir, file].sort, dirents.keys.sort)
1734     dir_dirent = dirents[dir]
1735     assert(dir_dirent.directory?)
1736     file_dirent = dirents[file]
1737     assert(file_dirent.file?)
1738   end
1740   def test_list
1741     log = "sample log"
1742     src = "source\n"
1743     file = "sample.txt"
1744     dir = "sample"
1745     prop_name = "sample-prop"
1746     prop_value = "sample value"
1747     dir_path = File.join(@wc_path, dir)
1748     path = File.join(@wc_path, file)
1750     ctx = make_context(log)
1752     ctx.mkdir(dir_path)
1753     File.open(path, "w") {|f| f.print(src)}
1754     ctx.add(path)
1755     ctx.prop_set(prop_name, prop_value, path)
1756     rev = ctx.ci(@wc_path).revision
1758     entries = []
1759     ctx.list(@wc_path, rev) do |path, dirent, lock, abs_path|
1760       entries << [path, dirent, lock, abs_path]
1761     end
1762     paths = entries.collect do |path, dirent, lock, abs_path|
1763       [path, abs_path]
1764     end
1765     assert_equal([["", "/"], [dir, "/"], [file, "/"]].sort, paths.sort)
1766     entries.each do |path, dirent, lock, abs_path|
1767       case path
1768       when dir, ""
1769         assert(dirent.directory?)
1770         assert_false(dirent.have_props?)
1771       when file
1772         assert(dirent.file?)
1773         assert_true(dirent.have_props?)
1774       else
1775         flunk
1776       end
1777     end
1778   end
1780   def test_list_with_depth
1781     setup_greek_tree
1783     log = "sample log"
1784     ctx = make_context(log)
1786     expected_lists_by_depth = {
1787       true => [:beta, :b, :lambda, :e, :f, :alpha],
1788       false => [:b, :lambda, :e, :f],
1789       'empty' => [:b],
1790       'files' => [:b, :lambda],
1791       'immediates' => [:b, :lambda, :e, :f],
1792       'infinity' => [:beta, :b, :lambda, :e, :f, :alpha],
1793     }
1795     recurse_and_depth_choices.each do |rd|
1796       paths = []
1797       ctx.list(@greek.path(:b), 'head' ,nil, rd) do |path, dirent, lock, abs_path|
1798         paths << (path.empty? ? abs_path : File.join(abs_path, path))
1799       end
1800       assert_equal(expected_lists_by_depth[rd].map{|s| "/#{@greek.resolve(s)}"}.sort,
1801                    paths.sort,
1802                    "depth '#{rd}")
1803     end
1804   end
1806   def test_switch
1807     log = "sample log"
1808     trunk_src = "trunk source\n"
1809     tag_src = "tag source\n"
1810     file = "sample.txt"
1811     file = "sample.txt"
1812     trunk_dir = "trunk"
1813     tag_dir = "tags"
1814     tag_name = "0.0.1"
1815     trunk_repos_uri = "#{@repos_uri}/#{trunk_dir}"
1816     tag_repos_uri = "#{@repos_uri}/#{tag_dir}/#{tag_name}"
1817     trunk_dir_path = File.join(@wc_path, trunk_dir)
1818     tag_dir_path = File.join(@wc_path, tag_dir)
1819     tag_name_dir_path = File.join(@wc_path, tag_dir, tag_name)
1820     trunk_path = File.join(trunk_dir_path, file)
1821     tag_path = File.join(tag_name_dir_path, file)
1822     path = File.join(@wc_path, file)
1824     ctx = make_context(log)
1826     ctx.mkdir(trunk_dir_path)
1827     File.open(trunk_path, "w") {|f| f.print(trunk_src)}
1828     ctx.add(trunk_path)
1829     trunk_rev = ctx.commit(@wc_path).revision
1831     ctx.mkdir(tag_dir_path, tag_name_dir_path)
1832     File.open(tag_path, "w") {|f| f.print(tag_src)}
1833     ctx.add(tag_path)
1834     tag_rev = ctx.commit(@wc_path).revision
1836     assert_equal(youngest_rev, ctx.switch(@wc_path, trunk_repos_uri))
1837     assert_equal(normalize_line_break(trunk_src), ctx.cat(path))
1839     assert_equal(youngest_rev, ctx.switch(@wc_path, tag_repos_uri))
1840     assert_equal(normalize_line_break(tag_src), ctx.cat(path))
1843     notify_info = []
1844     ctx.set_notify_func do |notify|
1845       notify_info << [notify.path, notify.action]
1846     end
1848     assert_equal(trunk_rev, ctx.switch(@wc_path, trunk_repos_uri, trunk_rev))
1849     assert_equal(normalize_line_break(trunk_src), ctx.cat(path))
1850     assert_equal([
1851                    [path, Svn::Wc::NOTIFY_UPDATE_UPDATE],
1852                    [@wc_path, Svn::Wc::NOTIFY_UPDATE_UPDATE],
1853                    [@wc_path, Svn::Wc::NOTIFY_UPDATE_COMPLETED],
1854                  ],
1855                  notify_info)
1857     notify_info.clear
1858     assert_equal(tag_rev, ctx.switch(@wc_path, tag_repos_uri, tag_rev))
1859     assert_equal(normalize_line_break(tag_src), ctx.cat(path))
1860     assert_equal([
1861                    [path, Svn::Wc::NOTIFY_UPDATE_UPDATE],
1862                    [@wc_path, Svn::Wc::NOTIFY_UPDATE_UPDATE],
1863                    [@wc_path, Svn::Wc::NOTIFY_UPDATE_COMPLETED],
1864                  ],
1865                  notify_info)
1866   end
1868   def test_authentication
1869     log = "sample log"
1870     src = "source\n"
1871     file = "sample.txt"
1872     path = File.join(@wc_path, file)
1873     svnserve_uri = "#{@repos_svnserve_uri}/#{file}"
1875     File.open(path, "w") {|f| f.print(src)}
1877     ctx = make_context(log)
1878     ctx.add(path)
1879     ctx.commit(@wc_path)
1881     ctx = Svn::Client::Context.new
1883     assert_raises(Svn::Error::AuthnNoProvider) do
1884       ctx.cat(svnserve_uri)
1885     end
1887     ctx.add_simple_prompt_provider(0) do |cred, realm, username, may_save|
1888       cred.username = "wrong-#{@author}"
1889       cred.password = @password
1890       cred.may_save = false
1891     end
1892     assert_raises(Svn::Error::RaNotAuthorized) do
1893       ctx.cat(svnserve_uri)
1894     end
1896     ctx.add_simple_prompt_provider(0) do |cred, realm, username, may_save|
1897       cred.username = @author
1898       cred.password = "wrong-#{@password}"
1899       cred.may_save = false
1900     end
1901     assert_raises(Svn::Error::RaNotAuthorized) do
1902       ctx.cat(svnserve_uri)
1903     end
1905     ctx.add_simple_prompt_provider(0) do |cred, realm, username, may_save|
1906       cred.username = @author
1907       cred.password = @password
1908       cred.may_save = false
1909     end
1910     assert_equal(normalize_line_break(src), ctx.cat(svnserve_uri))
1911   end
1913   def assert_simple_provider(method)
1914     log = "sample log"
1915     src = "source\n"
1916     file = "sample.txt"
1917     path = File.join(@wc_path, file)
1918     svnserve_uri = "#{@repos_svnserve_uri}/#{file}"
1920     File.open(path, "w") {|f| f.print(src)}
1922     ctx = make_context(log)
1923     setup_auth_baton(ctx.auth_baton)
1924     ctx.add(path)
1925     ctx.commit(@wc_path)
1927     ctx = Svn::Client::Context.new
1928     setup_auth_baton(ctx.auth_baton)
1929     ctx.send(method)
1930     assert_raises(Svn::Error::RaNotAuthorized) do
1931       ctx.cat(svnserve_uri)
1932     end
1934     ctx = Svn::Client::Context.new
1935     setup_auth_baton(ctx.auth_baton)
1936     ctx.send(method)
1937     ctx.add_simple_prompt_provider(0) do |cred, realm, username, may_save|
1938       cred.username = @author
1939       cred.password = @password
1940     end
1941     assert_equal(normalize_line_break(src), ctx.cat(svnserve_uri))
1942   end
1944   def test_simple_provider
1945     assert_simple_provider(:add_simple_provider)
1946   end
1948   if Svn::Core.respond_to?(:auth_get_windows_simple_provider)
1949     def test_windows_simple_provider
1950       assert_simple_provider(:add_windows_simple_provider)
1951     end
1952   end
1954   if Svn::Core.respond_to?(:auth_get_keychain_simple_provider)
1955     def test_keychain_simple_provider
1956       assert_simple_provider(:add_keychain_simple_provider)
1957     end
1958   end
1960   def test_username_provider
1961     log = "sample log"
1962     new_log = "sample new log"
1963     src = "source\n"
1964     file = "sample.txt"
1965     path = File.join(@wc_path, file)
1966     repos_uri = "#{@repos_uri}/#{file}"
1968     File.open(path, "w") {|f| f.print(src)}
1970     ctx = make_context(log)
1971     ctx.add(path)
1972     info = ctx.commit(@wc_path)
1974     ctx = Svn::Client::Context.new
1975     setup_auth_baton(ctx.auth_baton)
1976     ctx.auth_baton[Svn::Core::AUTH_PARAM_DEFAULT_USERNAME] = @author
1977     ctx.add_username_provider
1978     assert_nothing_raised do
1979       ctx.revprop_set(Svn::Core::PROP_REVISION_LOG, new_log,
1980                       repos_uri, info.revision)
1981     end
1983     ctx = Svn::Client::Context.new
1984     setup_auth_baton(ctx.auth_baton)
1985     ctx.auth_baton[Svn::Core::AUTH_PARAM_DEFAULT_USERNAME] = "#{@author}-NG"
1986     ctx.add_username_provider
1987     assert_raise(Svn::Error::REPOS_HOOK_FAILURE) do
1988       ctx.revprop_set(Svn::Core::PROP_REVISION_LOG, new_log,
1989                       repos_uri, info.revision)
1990     end
1992     ctx = Svn::Client::Context.new
1993     setup_auth_baton(ctx.auth_baton)
1994     ctx.auth_baton[Svn::Core::AUTH_PARAM_DEFAULT_USERNAME] = nil
1995     ctx.add_username_prompt_provider(0) do |cred, realm, may_save|
1996     end
1997     assert_raise(Svn::Error::REPOS_HOOK_FAILURE) do
1998       ctx.revprop_set(Svn::Core::PROP_REVISION_LOG, new_log,
1999                       repos_uri, info.revision)
2000     end
2002     ctx = Svn::Client::Context.new
2003     setup_auth_baton(ctx.auth_baton)
2004     ctx.auth_baton[Svn::Core::AUTH_PARAM_DEFAULT_USERNAME] = nil
2005     ctx.add_username_prompt_provider(0) do |cred, realm, may_save|
2006       cred.username = @author
2007     end
2008     assert_nothing_raised do
2009       ctx.revprop_set(Svn::Core::PROP_REVISION_LOG, new_log,
2010                       repos_uri, info.revision)
2011     end
2012   end
2014   def test_add_providers
2015     ctx = Svn::Client::Context.new
2016     assert_nothing_raised do
2017       ctx.add_ssl_client_cert_file_provider
2018       ctx.add_ssl_client_cert_pw_file_provider
2019       ctx.add_ssl_server_trust_file_provider
2020       if Svn::Core.respond_to?(:auth_get_windows_ssl_server_trust_provider)
2021         ctx.add_windows_ssl_server_trust_provider
2022       end
2023     end
2024   end
2026   def test_commit_item
2027     assert_raise(NoMethodError) do
2028       Svn::Client::CommitItem.new
2029     end
2031     assert_raise(NoMethodError) do
2032       Svn::Client::CommitItem2.new
2033     end
2035     item = Svn::Client::CommitItem3.new
2036     assert_kind_of(Svn::Client::CommitItem3, item)
2038     url = "xxx"
2039     item.url = url
2040     assert_equal(url, item.dup.url)
2041   end
2043   def test_log_msg_func_commit_items
2044     log = "sample log"
2045     file = "file"
2046     file2 = "file2"
2047     src = "source"
2048     path = File.join(@wc_path, file)
2049     repos_uri2 = "#{@repos_uri}/#{file2}"
2051     File.open(path, "w") {|f| f.print(src)}
2053     ctx = make_context(log)
2054     items = nil
2055     ctx.set_log_msg_func do |items|
2056       [true, log]
2057     end
2059     ctx.add(path)
2060     ctx.prop_set(Svn::Core::PROP_MIME_TYPE, "text/plain", path)
2061     ctx.commit(@wc_path)
2062     assert_equal([[]], items.collect {|item| item.wcprop_changes})
2063     assert_equal([[]], items.collect {|item| item.incoming_prop_changes})
2064     assert_equal([nil], items.collect {|item| item.outgoing_prop_changes})
2066     items = nil
2067     ctx.cp(path, repos_uri2)
2068     assert_equal([nil], items.collect {|item| item.wcprop_changes})
2069     assert_equal([nil], items.collect {|item| item.incoming_prop_changes})
2070     assert_equal([nil], items.collect {|item| item.outgoing_prop_changes})
2071   end
2073   def test_log_msg_func_cancel
2074     log = "sample log"
2075     dir = "dir"
2076     dir_path = File.join(@wc_path, dir)
2078     ctx = make_context(log)
2079     ctx.set_log_msg_func do |items|
2080       raise Svn::Error::Cancelled
2081     end
2082     ctx.mkdir(dir_path)
2083     assert_raise(Svn::Error::Cancelled) do
2084       ctx.commit(@wc_path)
2085     end
2086   end
2088   def test_set_config
2089     log = "sample log"
2090     ctx = make_context(log)
2091     options = {
2092       "groups" => {"collabnet" => "svn.collab.net"},
2093       "collabnet" => {
2094         "http-proxy-host" => "proxy",
2095         "http-proxy-port" => "8080",
2096       },
2097     }
2098     servers_config_file = File.join(@config_path,
2099                                     Svn::Core::CONFIG_CATEGORY_SERVERS)
2100     File.open(servers_config_file, "w") do |file|
2101       options.each do |section, values|
2102         file.puts("[#{section}]")
2103         values.each do |key, value|
2104           file.puts("#{key} = #{value}")
2105         end
2106       end
2107     end
2108     config = Svn::Core::Config.config(@config_path)
2109     assert_nil(ctx.config)
2110     assert_equal(options, config[Svn::Core::CONFIG_CATEGORY_SERVERS].to_hash)
2111     ctx.config = config
2112     assert_equal(options,
2113                  ctx.config[Svn::Core::CONFIG_CATEGORY_SERVERS].to_hash)
2114   end
2116   def test_context_mimetypes_map
2117     context = Svn::Client::Context.new
2118     assert_nil(context.mimetypes_map)
2119     context.mimetypes_map = {"txt" => "text/plain"}
2120     assert_equal({"txt" => "text/plain"}, context.mimetypes_map)
2121   end
2123   def test_context_revprop_table
2124     context = Svn::Client::Context.new
2125     assert_nil(context.revprop_table)
2126     context.revprop_table = {"my-prop" => "XXX"}
2127     assert_equal({"my-prop" => "XXX"}, context.revprop_table)
2128   end
2130   def assert_changelists
2131     log = "sample log"
2132     file1 = "hello1.txt"
2133     file2 = "hello2.txt"
2134     src = "Hello"
2135     changelist1 = "XXX"
2136     changelist2 = "YYY"
2137     path1 = File.join(@wc_path, file1)
2138     path2 = File.join(@wc_path, file2)
2140     ctx = make_context(log)
2141     File.open(path1, "w") {|f| f.print(src)}
2142     File.open(path2, "w") {|f| f.print(src)}
2143     ctx.add(path1)
2144     ctx.add(path2)
2145     ctx.commit(@wc_path)
2147     assert_equal({}, yield(ctx, changelist1))
2148     assert_equal({nil=>[@wc_path,path1,path2]}, yield(ctx, nil))
2149     assert_equal({}, yield(ctx, []))
2150     assert_equal({}, yield(ctx, [changelist1]))
2151     assert_equal({}, yield(ctx, [changelist2]))
2152     ctx.add_to_changelist(changelist1, path1)
2153     assert_equal({changelist1=>[path1]}, yield(ctx, changelist1))
2154     assert_equal({changelist1=>[path1],nil=>[@wc_path,path2]}, yield(ctx, nil))
2155     assert_equal({}, yield(ctx, []))
2156     assert_equal({changelist1=>[path1]}, yield(ctx, [changelist1]))
2157     assert_equal({}, yield(ctx, [changelist2]))
2159     assert_equal({}, yield(ctx, changelist2))
2160     ctx.add_to_changelist(changelist2, [path1, path2])
2161     assert_equal({changelist2=>[path1, path2]}, yield(ctx, changelist2))
2162     assert_equal({}, yield(ctx, changelist1))
2164     ctx.add_to_changelist(changelist1, [path1, path2])
2165     assert_equal({changelist1=>[path1, path2]}, yield(ctx, changelist1))
2166     assert_equal({}, yield(ctx, changelist2))
2168     ctx.remove_from_changelists(changelist1, path1)
2169     assert_equal({changelist1=>[path2]}, yield(ctx, changelist1))
2170     ctx.remove_from_changelists(changelist1, [path2])
2171     assert_equal({}, yield(ctx, changelist1))
2173     ctx.add_to_changelist(changelist1, path1)
2174     ctx.add_to_changelist(changelist2, path2)
2175     assert_equal({changelist1=>[path1]}, yield(ctx, changelist1))
2176     assert_equal({changelist2=>[path2]}, yield(ctx, changelist2))
2178     assert_equal({changelist1=>[path1]}, yield(ctx, changelist1))
2179     assert_equal({changelist2=>[path2]}, yield(ctx, changelist2))
2180     assert_equal({changelist1=>[path1]}, yield(ctx, [changelist1]))
2181     assert_equal({changelist2=>[path2]}, yield(ctx, [changelist2]))
2182     assert_equal({changelist1=>[path1],changelist2=>[path2],nil=>[@wc_path]}, yield(ctx, nil))
2183     assert_equal({}, yield(ctx, []))
2184     assert_equal({changelist1=>[path1],changelist2=>[path2]},
2185                  yield(ctx, [changelist1,changelist2]))
2187     ctx.remove_from_changelists(nil, [path1, path2])
2188     assert_equal({}, yield(ctx, changelist1))
2189     assert_equal({}, yield(ctx, changelist2))
2190   end
2192   def test_changelists_get_without_block
2193     assert_changelists do |ctx, changelist_name|
2194       ctx.changelists(changelist_name, @wc_path)
2195     end
2196   end
2198   def test_changelists_get_with_block
2199     assert_changelists do |ctx, changelist_name|
2200       changelists = Hash.new{|h,k| h[k]=[]}
2201       ctx.changelists(changelist_name, @wc_path) do |path,cl_name|
2202         changelists[cl_name] << path
2203       end
2204       changelists
2205     end
2206   end