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