8 class SvnDeltaTest < Test::Unit::TestCase
20 assert_equal(Svn::Core.subr_version, Svn::Delta.version)
23 def test_txdelta_window
24 s = ("a\nb\nc\nd\ne" + "\n" * 100) * 1000
25 t = ("a\nb\nX\nd\ne" + "\n" * 100) * 1000
26 source = StringIO.new(s)
27 target = StringIO.new(t)
28 stream = Svn::Delta::TextDeltaStream.new(source, target)
29 assert_nil(stream.md5_digest)
31 stream.each do |window|
32 window.ops.each do |op|
33 op_size = op.offset + op.length
35 when Svn::Delta::TXDELTA_SOURCE
36 assert_operator(op_size, :<=, window.sview_len)
37 when Svn::Delta::TXDELTA_NEW
38 assert_operator(op_size, :<=, window.new_data.length)
39 when Svn::Delta::TXDELTA_TARGET
40 assert_operator(op_size, :<=, window.tview_len)
47 assert_equal(MD5.new(t).hexdigest, stream.md5_digest)
50 def test_txdelta_window_compose
51 s = ("a\nb\nc\nd\ne" + "\n" * 100) * 1000
52 t = ("a\nb\nX\nd\ne" + "\n" * 100) * 1000
53 source = StringIO.new(s)
54 target = StringIO.new(t)
55 stream = Svn::Delta::TextDeltaStream.new(source, target)
57 stream.each do |window|
58 if composed_window.nil?
59 composed_window = window
61 composed_window = composed_window.compose(window)
66 composed_window.ops.each do |op|
67 op_size = op.offset + op.length
69 when Svn::Delta::TXDELTA_SOURCE
70 assert_operator(op_size, :<=, composed_window.sview_len)
71 when Svn::Delta::TXDELTA_NEW
72 assert_operator(op_size, :<=, composed_window.new_data.length)
73 when Svn::Delta::TXDELTA_TARGET
74 assert_operator(op_size, :<=, composed_window.tview_len)
82 def test_txdelta_apply_instructions
83 s = ("a\nb\nc\nd\ne" + "\n" * 100) * 1000
84 t = ("a\nb\nX\nd\ne" + "\n" * 100) * 1000
85 source = StringIO.new(s)
86 target = StringIO.new(t)
87 stream = Svn::Delta::TextDeltaStream.new(source, target)
91 stream.each do |window|
92 result << window.apply_instructions(s[offset, window.sview_len])
93 offset += window.sview_len
95 assert_equal(t, result)
99 source = StringIO.new("abcde")
100 target_content = "ZZZ" * 100
103 handler = Proc.new do |window|
105 data << window.new_data
110 target = Svn::Delta::TextDeltaStream.push_target(source, &handler)
111 target.write(target_content)
115 assert_equal(target_content, data)
119 source_text = "abcde"
120 target_text = "abXde"
121 source = StringIO.new(source_text)
122 target = StringIO.new(target_text)
123 stream = Svn::Delta::TextDeltaStream.new(source, target)
125 apply_source = StringIO.new(source_text)
126 apply_result = StringIO.new("")
128 handler, digest = Svn::Delta.apply(apply_source, apply_result)
131 assert_equal(target_text, apply_result.read)
133 handler, digest = Svn::Delta.apply(apply_source, apply_result)
134 handler.send(target_text)
136 assert_equal(target_text * 2, apply_result.read)
138 handler, digest = Svn::Delta.apply(apply_source, apply_result)
139 handler.send(StringIO.new(target_text))
141 assert_equal(target_text * 3, apply_result.read)
145 source_text = "abcde"
146 target_text = "abXde"
147 source = StringIO.new(source_text)
148 target = StringIO.new(target_text)
149 stream = Svn::Delta::TextDeltaStream.new(source, target)
151 output = StringIO.new("")
152 handler = Svn::Delta.svndiff_handler(output)
154 Svn::Delta.send(target_text, handler)
157 assert_match(/\ASVN.*#{target_text}\z/, result)
159 # skip svndiff window
160 input = StringIO.new(result[4..-1])
161 window = Svn::Delta.read_svndiff_window(input, 0)
162 assert_equal(target_text, window.new_data)
166 stream = Svn::Delta.parse_svndiff do |window|
168 data << window.new_data
176 assert_equal(target_text, data)
180 editor = Svn::Delta::BaseEditor.new
182 callback = Proc.new do |parent_baton, path|
195 x = rand(targets.size)
196 y = rand(targets.size)
197 targets[x], targets[y] = targets[y], targets[x]
199 Svn::Delta.path_driver(editor, 0, targets, &callback)
200 assert_equal(targets.sort, sorted_paths)
205 dir1 = "changed_dir1"
206 dir2 = "changed_dir2"
207 dir_path = File.join(@wc_path, dir)
208 dir1_path = File.join(@wc_path, dir1)
209 dir2_path = File.join(@wc_path, dir2)
214 log = "added 3 dirs\nanded 5 files"
215 ctx = make_context(log)
217 ctx.mkdir([dir_path, dir1_path, dir2_path])
219 file1 = "changed1.txt"
220 file2 = "changed2.txt"
221 file3 = "changed3.txt"
222 file4 = "changed4.txt"
223 file5 = "changed5.txt"
224 file1_path = File.join(@wc_path, file1)
225 file2_path = File.join(dir_path, file2)
226 file3_path = File.join(@wc_path, file3)
227 file4_path = File.join(dir_path, file4)
228 file5_path = File.join(@wc_path, file5)
229 file1_svn_path = file1
230 file2_svn_path = [dir_svn_path, file2].join("/")
231 file3_svn_path = file3
232 file4_svn_path = [dir_svn_path, file4].join("/")
233 file5_svn_path = file5
234 FileUtils.touch(file1_path)
235 FileUtils.touch(file2_path)
236 FileUtils.touch(file3_path)
237 FileUtils.touch(file4_path)
238 FileUtils.touch(file5_path)
245 commit_info = ctx.commit(@wc_path)
246 first_rev = commit_info.revision
248 editor = traverse(Svn::Delta::ChangedEditor, commit_info.revision, true)
250 file1_svn_path, file2_svn_path,
251 file3_svn_path, file4_svn_path,
255 assert_equal([], editor.updated_files)
256 assert_equal([], editor.deleted_files)
257 assert_equal([].sort, editor.updated_dirs)
258 assert_equal([].sort, editor.deleted_dirs)
267 log = "deleted 2 dirs\nchanged 3 files\ndeleted 2 files\nadded 3 files"
268 ctx = make_context(log)
270 dir3 = "changed_dir3"
271 dir4 = "changed_dir4"
272 dir3_path = File.join(dir_path, dir3)
273 dir4_path = File.join(@wc_path, dir4)
274 dir3_svn_path = [dir_svn_path, dir3].join("/")
277 file6 = "changed6.txt"
278 file7 = "changed7.txt"
279 file8 = "changed8.txt"
280 file9 = "changed9.txt"
281 file10 = "changed10.txt"
282 file6_path = File.join(dir_path, file6)
283 file7_path = File.join(@wc_path, file7)
284 file8_path = File.join(dir_path, file8)
285 file9_path = File.join(dir_path, file9)
286 file10_path = File.join(dir_path, file10)
287 file6_svn_path = [dir_svn_path, file6].join("/")
288 file7_svn_path = file7
289 file8_svn_path = [dir_svn_path, file8].join("/")
290 file9_svn_path = [dir_svn_path, file9].join("/")
291 file10_svn_path = [dir_svn_path, file10].join("/")
293 File.open(file1_path, "w") {|f| f.puts "changed"}
294 File.open(file2_path, "w") {|f| f.puts "changed"}
295 File.open(file3_path, "w") {|f| f.puts "changed"}
296 ctx.rm_f([file4_path, file5_path])
297 FileUtils.touch(file6_path)
298 FileUtils.touch(file7_path)
299 FileUtils.touch(file8_path)
303 ctx.cp(file1_path, file9_path)
304 ctx.cp(file2_path, file10_path)
306 ctx.mv(dir2_path, dir3_path)
307 ctx.cp(dir1_path, dir4_path)
309 commit_info = ctx.commit(@wc_path)
310 second_rev = commit_info.revision
312 editor = traverse(Svn::Delta::ChangedEditor, commit_info.revision, true)
313 assert_equal([file1_svn_path, file2_svn_path, file3_svn_path].sort,
314 editor.updated_files)
315 assert_equal([file4_svn_path, file5_svn_path].sort,
316 editor.deleted_files)
317 assert_equal([file6_svn_path, file7_svn_path, file8_svn_path].sort,
319 assert_equal([].sort, editor.updated_dirs)
321 [file9_svn_path, file1_svn_path, first_rev],
322 [file10_svn_path, file2_svn_path, first_rev],
326 ["#{dir3_svn_path}/", "#{dir2_svn_path}/", first_rev],
327 ["#{dir4_svn_path}/", "#{dir1_svn_path}/", first_rev],
330 assert_equal(["#{dir1_svn_path}/", "#{dir2_svn_path}/"].sort,
332 assert_equal([].sort, editor.added_dirs)
340 dir_path = File.join(@wc_path, dir)
343 log = "added 1 dirs\nanded 2 files"
344 ctx = make_context(log)
346 ctx.mkdir([dir_path])
350 file1_path = File.join(@wc_path, file1)
351 file2_path = File.join(dir_path, file2)
352 file1_svn_path = file1
353 file2_svn_path = [dir_svn_path, file2].join("/")
354 FileUtils.touch(file1_path)
355 FileUtils.touch(file2_path)
359 ctx.propset(prop_name, prop_value, dir_path)
361 commit_info = ctx.commit(@wc_path)
363 editor = traverse(Svn::Delta::ChangedDirsEditor, commit_info.revision)
364 assert_equal(["", dir_svn_path].collect{|path| "#{path}/"}.sort,
369 ctx = make_context(log)
371 ctx.propdel(prop_name, dir_path)
373 commit_info = ctx.commit(@wc_path)
375 editor = traverse(Svn::Delta::ChangedDirsEditor, commit_info.revision)
376 assert_equal([dir_svn_path].collect{|path| "#{path}/"}.sort,
380 ctx.propset(prop_name, prop_value, file1_path)
382 commit_info = ctx.commit(@wc_path)
384 editor = traverse(Svn::Delta::ChangedDirsEditor, commit_info.revision)
385 assert_equal([""].collect{|path| "#{path}/"}.sort,
389 ctx.propdel(prop_name, file1_path)
390 ctx.propset(prop_name, prop_value, file2_path)
392 commit_info = ctx.commit(@wc_path)
394 editor = traverse(Svn::Delta::ChangedDirsEditor, commit_info.revision)
395 assert_equal(["", dir_svn_path].collect{|path| "#{path}/"}.sort,
402 dir1_path = File.join(@wc_path, dir1)
403 dir2_path = File.join(dir1_path, dir2)
405 dir2_svn_path = [dir1, dir2].join("/")
407 log = "added 2 dirs\nanded 3 files"
408 ctx = make_context(log)
410 ctx.mkdir([dir1_path, dir2_path])
415 file1_path = File.join(@wc_path, file1)
416 file2_path = File.join(dir1_path, file2)
417 file3_path = File.join(dir2_path, file3)
418 file1_svn_path = file1
419 file2_svn_path = [dir1_svn_path, file2].join("/")
420 file3_svn_path = [dir2_svn_path, file3].join("/")
421 FileUtils.touch(file1_path)
422 FileUtils.touch(file2_path)
423 FileUtils.touch(file3_path)
428 commit_info = ctx.commit(@wc_path)
429 first_rev = commit_info.revision
431 editor = traverse(Svn::Delta::ChangedEditor, commit_info.revision, true)
433 file1_svn_path, file2_svn_path,
437 assert_equal([].sort, editor.updated_files)
438 assert_equal([].sort, editor.deleted_files)
439 assert_equal([].sort, editor.updated_dirs)
440 assert_equal([].sort, editor.deleted_dirs)
448 log = "copied top dir"
449 ctx = make_context(log)
452 dir3_path = File.join(@wc_path, dir3)
455 ctx.cp(dir1_path, dir3_path)
457 commit_info = ctx.commit(@wc_path)
458 second_rev = commit_info.revision
460 editor = traverse(Svn::Delta::ChangedEditor, commit_info.revision, true)
461 assert_equal([].sort, editor.updated_files)
462 assert_equal([].sort, editor.deleted_files)
463 assert_equal([].sort, editor.added_files)
464 assert_equal([].sort, editor.updated_dirs)
465 assert_equal([].sort, editor.copied_files)
467 ["#{dir3_svn_path}/", "#{dir1_svn_path}/", first_rev]
470 assert_equal([].sort, editor.deleted_dirs)
471 assert_equal([].sort, editor.added_dirs)
475 def traverse(editor_class, rev, pass_root=false)
478 base_root = @fs.root(base_rev)
480 editor = editor_class.new(root, base_root)
482 editor = editor_class.new
484 base_root.dir_delta("", "", root, "", editor)