1require File.expand_path '../xref_test_case', __FILE__ 2 3class TestRDocStore < XrefTestCase 4 5 OBJECT_ANCESTORS = defined?(::BasicObject) ? %w[BasicObject] : [] 6 7 def setup 8 super 9 10 @tmpdir = File.join Dir.tmpdir, "test_rdoc_ri_store_#{$$}" 11 @s = RDoc::RI::Store.new @tmpdir 12 13 @top_level = @s.add_file 'file.rb' 14 15 @page = @s.add_file 'README.txt' 16 @page.parser = RDoc::Parser::Simple 17 @page.comment = RDoc::Comment.new 'This is a page', @page 18 19 @klass = @top_level.add_class RDoc::NormalClass, 'Object' 20 @klass.add_comment 'original', @top_level 21 @klass.record_location @top_level 22 23 @cmeth = RDoc::AnyMethod.new nil, 'cmethod' 24 @cmeth.singleton = true 25 @cmeth.record_location @top_level 26 27 @meth_comment = RDoc::Comment.new 'method comment' 28 @meth_comment.location = @top_level 29 30 @meth = RDoc::AnyMethod.new nil, 'method' 31 @meth.record_location @top_level 32 @meth.comment = @meth_comment 33 34 @meth_bang = RDoc::AnyMethod.new nil, 'method!' 35 @meth_bang.record_location @top_level 36 37 @meth_bang_alias = RDoc::Alias.new nil, 'method!', 'method_bang', '' 38 @meth_bang_alias.record_location @top_level 39 40 @meth_bang.add_alias @meth_bang_alias, @klass 41 42 @attr_comment = RDoc::Comment.new 'attribute comment' 43 @attr_comment.location = @top_level 44 45 @attr = RDoc::Attr.new nil, 'attr', 'RW', '' 46 @attr.record_location @top_level 47 @attr.comment = @attr_comment 48 49 @klass.add_method @cmeth 50 @klass.add_method @meth 51 @klass.add_method @meth_bang 52 @klass.add_attribute @attr 53 54 @nest_klass = @klass.add_class RDoc::NormalClass, 'SubClass' 55 @nest_meth = RDoc::AnyMethod.new nil, 'method' 56 @nest_meth.record_location @top_level 57 58 @nest_incl = RDoc::Include.new 'Incl', '' 59 @nest_incl.record_location @top_level 60 61 @nest_klass.add_method @nest_meth 62 @nest_klass.add_include @nest_incl 63 64 @mod = @top_level.add_module RDoc::NormalModule, 'Mod' 65 @mod.record_location @top_level 66 end 67 68 def teardown 69 super 70 71 FileUtils.rm_rf @tmpdir 72 end 73 74 def mu_pp obj 75 s = '' 76 s = PP.pp obj, s 77 s.force_encoding Encoding.default_external if defined? Encoding 78 s.chomp 79 end 80 81 def assert_cache imethods, cmethods, attrs, modules, 82 ancestors = {}, pages = [], main = nil, title = nil 83 imethods ||= { 'Object' => %w[method method! method_bang] } 84 cmethods ||= { 'Object' => %w[cmethod] } 85 attrs ||= { 'Object' => ['attr_accessor attr'] } 86 87 # this is sort-of a hack 88 @s.clean_cache_collection ancestors 89 90 expected = { 91 :ancestors => ancestors, 92 :attributes => attrs, 93 :class_methods => cmethods, 94 :c_class_variables => {}, 95 :c_singleton_class_variables => {}, 96 :encoding => nil, 97 :instance_methods => imethods, 98 :modules => modules, 99 :pages => pages, 100 :main => main, 101 :title => title, 102 } 103 104 @s.save_cache 105 106 assert_equal expected, @s.cache 107 end 108 109 def assert_directory path 110 assert File.directory?(path), "#{path} is not a directory" 111 end 112 113 def assert_file path 114 assert File.file?(path), "#{path} is not a file" 115 end 116 117 def refute_file path 118 refute File.exist?(path), "#{path} exists" 119 end 120 121 def test_add_c_enclosure 122 @s.add_c_enclosure 'cC1', @c1 123 124 expected = { 'cC1' => @c1 } 125 126 assert_equal expected, @s.c_enclosure_classes 127 end 128 129 def test_add_c_variables 130 options = RDoc::Options.new 131 132 c_file = @s.add_file 'ext.c' 133 134 some_ext = c_file.add_class RDoc::NormalClass, 'SomeExt' 135 c_file.add_class RDoc::SingleClass, 'SomeExtSingle' 136 137 c_parser = RDoc::Parser::C.new c_file, 'ext.c', '', options, nil 138 139 c_parser.classes['cSomeExt'] = some_ext 140 c_parser.singleton_classes['s_cSomeExt'] = 'SomeExtSingle' 141 142 @s.add_c_variables c_parser 143 144 expected = { 'ext.c' => { 'cSomeExt' => 'SomeExt' } } 145 146 assert_equal expected, @s.c_class_variables 147 148 expected = { 'ext.c' => { 's_cSomeExt' => 'SomeExtSingle' } } 149 150 assert_equal expected, @s.c_singleton_class_variables 151 end 152 153 def test_add_file 154 top_level = @store.add_file 'file.rb' 155 156 assert_kind_of RDoc::TopLevel, top_level 157 assert_equal @store, top_level.store 158 assert_equal 'file.rb', top_level.name 159 assert_includes @store.all_files, top_level 160 161 assert_same top_level, @store.add_file('file.rb') 162 refute_same top_level, @store.add_file('other.rb') 163 end 164 165 def test_add_file_relative 166 top_level = @store.add_file 'path/file.rb', 'file.rb' 167 168 assert_kind_of RDoc::TopLevel, top_level 169 assert_equal @store, top_level.store 170 171 assert_equal 'path/file.rb', top_level.absolute_name 172 assert_equal 'file.rb', top_level.relative_name 173 174 assert_includes @store.all_files, top_level 175 176 assert_same top_level, @store.add_file('file.rb') 177 refute_same top_level, @store.add_file('other.rb') 178 end 179 180 def test_all_classes_and_modules 181 expected = %w[ 182 C1 C2 C2::C3 C2::C3::H1 C3 C3::H1 C3::H2 C4 C4::C4 C5 C5::C1 183 Child 184 M1 M1::M2 185 Parent 186 ] 187 188 assert_equal expected, 189 @store.all_classes_and_modules.map { |m| m.full_name }.sort 190 end 191 192 def test_all_files 193 assert_equal %w[xref_data.rb], 194 @store.all_files.map { |m| m.full_name }.sort 195 end 196 197 def test_all_modules 198 assert_equal %w[M1 M1::M2], 199 @store.all_modules.map { |m| m.full_name }.sort 200 end 201 202 def test_attributes 203 @s.cache[:attributes]['Object'] = %w[attr] 204 205 expected = { 'Object' => %w[attr] } 206 207 assert_equal expected, @s.attributes 208 end 209 210 def test_class_file 211 assert_equal File.join(@tmpdir, 'Object', 'cdesc-Object.ri'), 212 @s.class_file('Object') 213 assert_equal File.join(@tmpdir, 'Object', 'SubClass', 'cdesc-SubClass.ri'), 214 @s.class_file('Object::SubClass') 215 end 216 217 def test_class_methods 218 @s.cache[:class_methods]['Object'] = %w[method] 219 220 expected = { 'Object' => %w[method] } 221 222 assert_equal expected, @s.class_methods 223 end 224 225 def test_class_path 226 assert_equal File.join(@tmpdir, 'Object'), @s.class_path('Object') 227 assert_equal File.join(@tmpdir, 'Object', 'SubClass'), 228 @s.class_path('Object::SubClass') 229 end 230 231 def test_classes 232 expected = %w[ 233 C1 C2 C2::C3 C2::C3::H1 C3 C3::H1 C3::H2 C4 C4::C4 C5 C5::C1 234 Child 235 Parent 236 ] 237 238 assert_equal expected, @store.all_classes.map { |m| m.full_name }.sort 239 end 240 241 def test_complete 242 @c2.add_module_alias @c2_c3, 'A1', @top_level 243 244 @store.complete :public 245 246 a1 = @xref_data.find_class_or_module 'C2::A1' 247 248 assert_equal 'C2::A1', a1.full_name 249 refute_empty a1.aliases 250 end 251 252 def test_find_c_enclosure 253 assert_nil @s.find_c_enclosure 'cC1' 254 255 @s.add_c_enclosure 'cC1', @c1 256 257 assert_equal @c1, @s.find_c_enclosure('cC1') 258 end 259 260 def test_find_c_enclosure_from_cache 261 @s.save_class @klass 262 @s.classes_hash.clear 263 264 assert_nil @s.find_c_enclosure 'cObject' 265 266 @s.c_enclosure_names['cObject'] = 'Object' 267 268 klass = @s.find_c_enclosure('cObject') 269 assert_equal @klass, klass 270 271 assert_empty klass.comment_location 272 assert_equal @top_level, klass.parent 273 274 assert_includes @s.c_enclosure_classes, 'cObject' 275 end 276 277 def test_find_c_enclosure_from_cache_legacy 278 @klass.in_files.clear 279 @s.save_class @klass 280 @s.classes_hash.clear 281 282 assert_nil @s.find_c_enclosure 'cObject' 283 284 @s.c_enclosure_names['cObject'] = 'Object' 285 286 assert_nil @s.find_c_enclosure('cObject') 287 end 288 289 def test_find_class_named 290 assert_equal @c1, @store.find_class_named('C1') 291 292 assert_equal @c2_c3, @store.find_class_named('C2::C3') 293 end 294 295 def test_find_class_named_from 296 assert_equal @c5_c1, @store.find_class_named_from('C1', 'C5') 297 298 assert_equal @c1, @store.find_class_named_from('C1', 'C4') 299 end 300 301 def test_find_class_or_module 302 assert_equal @m1, @store.find_class_or_module('M1') 303 assert_equal @c1, @store.find_class_or_module('C1') 304 305 assert_equal @m1, @store.find_class_or_module('::M1') 306 assert_equal @c1, @store.find_class_or_module('::C1') 307 end 308 309 def test_find_file_named 310 assert_equal @xref_data, @store.find_file_named(@file_name) 311 end 312 313 def test_find_module_named 314 assert_equal @m1, @store.find_module_named('M1') 315 assert_equal @m1_m2, @store.find_module_named('M1::M2') 316 end 317 318 def test_find_text_page 319 page = @store.add_file 'PAGE.txt' 320 page.parser = RDoc::Parser::Simple 321 322 assert_nil @store.find_text_page 'no such page' 323 324 assert_equal page, @store.find_text_page('PAGE.txt') 325 end 326 327 def test_friendly_path 328 @s.path = @tmpdir 329 @s.type = nil 330 assert_equal @s.path, @s.friendly_path 331 332 @s.type = :extra 333 assert_equal @s.path, @s.friendly_path 334 335 @s.type = :system 336 assert_equal "ruby core", @s.friendly_path 337 338 @s.type = :site 339 assert_equal "ruby site", @s.friendly_path 340 341 @s.type = :home 342 assert_equal "~/.rdoc", @s.friendly_path 343 344 @s.type = :gem 345 @s.path = "#{@tmpdir}/gem_repository/doc/gem_name-1.0/ri" 346 assert_equal "gem gem_name-1.0", @s.friendly_path 347 end 348 349 def test_dry_run 350 refute @s.dry_run 351 352 @s.dry_run = true 353 354 assert @s.dry_run 355 end 356 357 def test_instance_methods 358 @s.cache[:instance_methods]['Object'] = %w[method] 359 360 expected = { 'Object' => %w[method] } 361 362 assert_equal expected, @s.instance_methods 363 end 364 365 def test_load_all 366 FileUtils.mkdir_p @tmpdir 367 368 @s.save 369 370 s = RDoc::Store.new @tmpdir 371 372 s.load_all 373 374 assert_equal [@klass, @nest_klass], s.all_classes.sort 375 assert_equal [@mod], s.all_modules.sort 376 assert_equal [@page, @top_level], s.all_files.sort 377 378 methods = s.all_classes_and_modules.map do |mod| 379 mod.method_list 380 end.flatten.sort 381 382 _meth_bang_alias = RDoc::AnyMethod.new nil, 'method_bang' 383 _meth_bang_alias.parent = @klass 384 385 assert_equal [@meth, @meth_bang, _meth_bang_alias, @nest_meth, @cmeth], 386 methods.sort_by { |m| m.full_name } 387 388 method = methods.find { |m| m == @meth } 389 assert_equal @meth_comment.parse, method.comment 390 391 assert_equal @klass, methods.last.parent 392 393 attributes = s.all_classes_and_modules.map do |mod| 394 mod.attributes 395 end.flatten.sort 396 397 assert_equal [@attr], attributes 398 399 assert_equal @attr_comment.parse, attributes.first.comment 400 end 401 402 def test_load_cache 403 cache = { 404 :c_class_variables => 405 { 'file.c' => { 'cKlass' => 'Klass' } }, 406 :c_singleton_class_variables => 407 { 'file.c' => { 'sKlass' => 'KlassSingle' } }, 408 :encoding => :encoding_value, 409 :methods => { "Object" => %w[Object#method] }, 410 :main => @page.full_name, 411 :modules => %w[Object], 412 :pages => [], 413 } 414 415 Dir.mkdir @tmpdir 416 417 open File.join(@tmpdir, 'cache.ri'), 'wb' do |io| 418 Marshal.dump cache, io 419 end 420 421 @s.load_cache 422 423 assert_equal cache, @s.cache 424 425 assert_equal :encoding_value, @s.encoding 426 assert_equal 'README.txt', @s.main 427 428 expected = { 'file.c' => { 'cKlass' => 'Klass' } } 429 assert_equal expected, @s.cache[:c_class_variables] 430 431 expected = { 'file.c' => { 'sKlass' => 'KlassSingle' } } 432 assert_equal expected, @s.cache[:c_singleton_class_variables] 433 434 expected = { 'cKlass' => 'Klass' } 435 assert_equal expected, @s.c_enclosure_names 436 end 437 438 def test_load_cache_encoding_differs 439 skip "Encoding not implemented" unless Object.const_defined? :Encoding 440 441 cache = { 442 :c_class_variables => {}, 443 :c_singleton_class_variables => {}, 444 :encoding => Encoding::ISO_8859_1, 445 :main => nil, 446 :methods => { "Object" => %w[Object#method] }, 447 :modules => %w[Object], 448 :pages => [], 449 } 450 451 Dir.mkdir @tmpdir 452 453 open File.join(@tmpdir, 'cache.ri'), 'wb' do |io| 454 Marshal.dump cache, io 455 end 456 457 @s.encoding = Encoding::UTF_8 458 459 @s.load_cache 460 461 assert_equal cache, @s.cache 462 463 assert_equal Encoding::UTF_8, @s.encoding 464 end 465 466 def test_load_cache_no_cache 467 cache = { 468 :ancestors => {}, 469 :attributes => {}, 470 :class_methods => {}, 471 :c_class_variables => {}, 472 :c_singleton_class_variables => {}, 473 :encoding => nil, 474 :instance_methods => {}, 475 :main => nil, 476 :modules => [], 477 :pages => [], 478 :title => nil, 479 } 480 481 @s.load_cache 482 483 assert_equal cache, @s.cache 484 end 485 486 def test_load_cache_legacy 487 cache = { 488 :ancestors => {}, 489 :attributes => {}, 490 :class_methods => {}, 491 :encoding => :encoding_value, 492 :instance_methods => { "Object" => %w[Object#method] }, 493 :modules => %w[Object], 494 # no :pages 495 # no :main 496 # no :c_class_variables 497 # no :c_singleton_class_variables 498 } 499 500 Dir.mkdir @tmpdir 501 502 open File.join(@tmpdir, 'cache.ri'), 'wb' do |io| 503 Marshal.dump cache, io 504 end 505 506 @s.load_cache 507 508 expected = { 509 :ancestors => {}, 510 :attributes => {}, 511 :class_methods => {}, 512 :c_class_variables => {}, 513 :c_singleton_class_variables => {}, 514 :encoding => :encoding_value, 515 :instance_methods => { "Object" => %w[Object#method] }, 516 :main => nil, 517 :modules => %w[Object], 518 :pages => [], 519 } 520 521 assert_equal expected, @s.cache 522 523 assert_equal :encoding_value, @s.encoding 524 assert_nil @s.main 525 end 526 527 def test_load_class 528 @s.save_class @klass 529 @s.classes_hash.clear 530 531 assert_equal @klass, @s.load_class('Object') 532 533 assert_includes @s.classes_hash, 'Object' 534 end 535 536 def test_load_method 537 @s.save_method @klass, @meth_bang 538 539 meth = @s.load_method('Object', '#method!') 540 assert_equal @meth_bang, meth 541 assert_equal @klass, meth.parent 542 assert_equal @s, meth.store 543 end 544 545 def test_load_method_legacy 546 @s.save_method @klass, @meth 547 548 file = @s.method_file @klass.full_name, @meth.full_name 549 550 open file, 'wb' do |io| 551 io.write "\x04\bU:\x14RDoc::AnyMethod[\x0Fi\x00I" + 552 "\"\vmethod\x06:\x06EF\"\x11Klass#method0:\vpublic" + 553 "o:\eRDoc::Markup::Document\x06:\v@parts[\x06" + 554 "o:\x1CRDoc::Markup::Paragraph\x06;\t[\x06I" + 555 "\"\x16this is a comment\x06;\x06FI" + 556 "\"\rcall_seq\x06;\x06FI\"\x0Fsome_block\x06;\x06F" + 557 "[\x06[\aI\"\faliased\x06;\x06Fo;\b\x06;\t[\x06" + 558 "o;\n\x06;\t[\x06I\"\x12alias comment\x06;\x06FI" + 559 "\"\nparam\x06;\x06F" 560 end 561 562 meth = @s.load_method('Object', '#method') 563 assert_equal 'Klass#method', meth.full_name 564 assert_equal @klass, meth.parent 565 assert_equal @s, meth.store 566 end 567 568 def test_load_page 569 @s.save_page @page 570 571 assert_equal @page, @s.load_page('README.txt') 572 end 573 574 def test_main 575 assert_equal nil, @s.main 576 577 @s.main = 'README.txt' 578 579 assert_equal 'README.txt', @s.main 580 end 581 582 def test_method_file 583 assert_equal File.join(@tmpdir, 'Object', 'method-i.ri'), 584 @s.method_file('Object', 'Object#method') 585 586 assert_equal File.join(@tmpdir, 'Object', 'method%21-i.ri'), 587 @s.method_file('Object', 'Object#method!') 588 589 assert_equal File.join(@tmpdir, 'Object', 'SubClass', 'method%21-i.ri'), 590 @s.method_file('Object::SubClass', 'Object::SubClass#method!') 591 592 assert_equal File.join(@tmpdir, 'Object', 'method-c.ri'), 593 @s.method_file('Object', 'Object::method') 594 end 595 596 def test_module_names 597 @s.save_class @klass 598 599 assert_equal %w[Object], @s.module_names 600 end 601 602 def test_page 603 page = @store.add_file 'PAGE.txt' 604 page.parser = RDoc::Parser::Simple 605 606 assert_nil @store.page 'no such page' 607 608 assert_equal page, @store.page('PAGE') 609 end 610 611 def test_save 612 FileUtils.mkdir_p @tmpdir 613 614 @s.save 615 616 assert_directory File.join(@tmpdir, 'Object') 617 618 assert_file File.join(@tmpdir, 'Object', 'cdesc-Object.ri') 619 assert_file File.join(@tmpdir, 'Object', 'method-i.ri') 620 assert_file File.join(@tmpdir, 'page-README_txt.ri') 621 622 assert_file File.join(@tmpdir, 'cache.ri') 623 624 expected = { 625 :ancestors => { 626 'Object::SubClass' => %w[Incl Object], 627 }, 628 :attributes => { 'Object' => ['attr_accessor attr'] }, 629 :class_methods => { 'Object' => %w[cmethod] }, 630 :c_class_variables => {}, 631 :c_singleton_class_variables => {}, 632 :instance_methods => { 633 'Object' => %w[attr method method! method_bang], 634 'Object::SubClass' => %w[method], 635 }, 636 :main => nil, 637 :modules => %w[Mod Object Object::SubClass], 638 :encoding => nil, 639 :pages => %w[README.txt], 640 :title => nil, 641 } 642 643 expected[:ancestors]['Object'] = %w[BasicObject] if defined?(::BasicObject) 644 645 open File.join(@tmpdir, 'cache.ri'), 'rb' do |io| 646 cache = Marshal.load io.read 647 648 assert_equal expected, cache 649 end 650 end 651 652 def test_save_cache 653 @s.save_class @klass 654 @s.save_method @klass, @meth 655 @s.save_method @klass, @cmeth 656 @s.save_class @nest_klass 657 @s.save_page @page 658 @s.encoding = :encoding_value 659 @s.main = @page.full_name 660 @s.title = 'title' 661 662 options = RDoc::Options.new 663 664 c_file = @s.add_file 'ext.c' 665 666 some_ext = c_file.add_class RDoc::NormalClass, 'SomeExt' 667 c_file.add_class RDoc::SingleClass, 'SomeExtSingle' 668 669 c_parser = RDoc::Parser::C.new c_file, 'ext.c', '', options, nil 670 671 c_parser.classes['cSomeExt'] = some_ext 672 c_parser.singleton_classes['s_cSomeExt'] = 'SomeExtSingle' 673 674 @s.add_c_variables c_parser 675 676 @s.save_cache 677 678 assert_file File.join(@tmpdir, 'cache.ri') 679 680 c_class_variables = { 681 'ext.c' => { 682 'cSomeExt' => 'SomeExt' 683 } 684 } 685 686 c_singleton_class_variables = { 687 'ext.c' => { 688 's_cSomeExt' => 'SomeExtSingle' 689 } 690 } 691 692 expected = { 693 :ancestors => { 694 'Object::SubClass' => %w[Incl Object], 695 }, 696 :attributes => { 'Object' => ['attr_accessor attr'] }, 697 :class_methods => { 'Object' => %w[cmethod] }, 698 :c_class_variables => c_class_variables, 699 :c_singleton_class_variables => c_singleton_class_variables, 700 :instance_methods => { 701 'Object' => %w[method method! method_bang], 702 'Object::SubClass' => %w[method], 703 }, 704 :main => @page.full_name, 705 :modules => %w[Object Object::SubClass], 706 :encoding => :encoding_value, 707 :pages => %w[README.txt], 708 :title => 'title', 709 } 710 711 expected[:ancestors]['Object'] = %w[BasicObject] if defined?(::BasicObject) 712 713 open File.join(@tmpdir, 'cache.ri'), 'rb' do |io| 714 cache = Marshal.load io.read 715 716 assert_equal expected, cache 717 end 718 end 719 720 def test_save_cache_dry_run 721 @s.dry_run = true 722 723 @s.save_class @klass 724 @s.save_method @klass, @meth 725 @s.save_method @klass, @cmeth 726 @s.save_class @nest_klass 727 728 @s.save_cache 729 730 refute_file File.join(@tmpdir, 'cache.ri') 731 end 732 733 def test_save_cache_duplicate_methods 734 @s.save_method @klass, @meth 735 @s.save_method @klass, @meth 736 737 @s.save_cache 738 739 assert_cache({ 'Object' => %w[method] }, {}, {}, []) 740 end 741 742 def test_save_cache_duplicate_pages 743 @s.save_page @page 744 @s.save_page @page 745 746 @s.save_cache 747 748 assert_cache({}, {}, {}, [], {}, %w[README.txt]) 749 end 750 751 def test_save_class 752 @s.save_class @klass 753 754 assert_directory File.join(@tmpdir, 'Object') 755 assert_file File.join(@tmpdir, 'Object', 'cdesc-Object.ri') 756 757 assert_cache nil, nil, nil, %w[Object], 'Object' => OBJECT_ANCESTORS 758 759 assert_equal @klass, @s.load_class('Object') 760 end 761 762 def test_save_class_basic_object 763 @klass.instance_variable_set :@superclass, nil 764 765 @s.save_class @klass 766 767 assert_directory File.join(@tmpdir, 'Object') 768 assert_file File.join(@tmpdir, 'Object', 'cdesc-Object.ri') 769 770 assert_cache(nil, nil, nil, %w[Object]) 771 772 assert_equal @klass, @s.load_class('Object') 773 end 774 775 def test_save_class_delete 776 # save original 777 @s.save_class @klass 778 @s.save_method @klass, @meth 779 @s.save_method @klass, @meth_bang 780 @s.save_method @klass, @cmeth 781 @s.save_method @klass, @attr 782 @s.save_cache 783 784 klass = RDoc::NormalClass.new 'Object' 785 786 meth = klass.add_method RDoc::AnyMethod.new(nil, 'replace') 787 meth.record_location @top_level 788 789 # load original, save newly updated class 790 @s = RDoc::RI::Store.new @tmpdir 791 @s.load_cache 792 @s.save_class klass 793 @s.save_cache 794 795 # load from disk again 796 @s = RDoc::RI::Store.new @tmpdir 797 @s.load_cache 798 799 @s.load_class 'Object' 800 801 assert_cache({ 'Object' => %w[replace] }, {}, 802 { 'Object' => %w[attr_accessor\ attr] }, %w[Object], 803 'Object' => OBJECT_ANCESTORS) 804 805 # assert these files were deleted 806 refute_file @s.method_file(@klass.full_name, @meth.full_name) 807 refute_file @s.method_file(@klass.full_name, @meth_bang.full_name) 808 refute_file @s.method_file(@klass.full_name, @cmeth.full_name) 809 810 # assert these files were not deleted 811 assert_file @s.method_file(@klass.full_name, @attr.full_name) 812 end 813 814 def test_save_class_dry_run 815 @s.dry_run = true 816 817 @s.save_class @klass 818 819 refute_file File.join(@tmpdir, 'Object') 820 refute_file File.join(@tmpdir, 'Object', 'cdesc-Object.ri') 821 end 822 823 def test_save_class_loaded 824 @s.save 825 826 assert_directory File.join(@tmpdir, 'Object') 827 assert_file File.join(@tmpdir, 'Object', 'cdesc-Object.ri') 828 829 assert_file @s.method_file(@klass.full_name, @attr.full_name) 830 assert_file @s.method_file(@klass.full_name, @cmeth.full_name) 831 assert_file @s.method_file(@klass.full_name, @meth.full_name) 832 assert_file @s.method_file(@klass.full_name, @meth_bang.full_name) 833 834 s = RDoc::Store.new @s.path 835 s.load_cache 836 837 loaded = s.load_class 'Object' 838 839 assert_equal @klass, loaded 840 841 s.save_class loaded 842 843 s = RDoc::Store.new @s.path 844 s.load_cache 845 846 reloaded = s.load_class 'Object' 847 848 assert_equal @klass, reloaded 849 850 # assert these files were not deleted. Bug #171 851 assert_file s.method_file(@klass.full_name, @attr.full_name) 852 assert_file s.method_file(@klass.full_name, @cmeth.full_name) 853 assert_file s.method_file(@klass.full_name, @meth.full_name) 854 assert_file s.method_file(@klass.full_name, @meth_bang.full_name) 855 end 856 857 def test_save_class_merge 858 @s.save_class @klass 859 860 klass = RDoc::NormalClass.new 'Object' 861 klass.add_comment 'new comment', @top_level 862 863 s = RDoc::RI::Store.new @tmpdir 864 s.save_class klass 865 866 s = RDoc::RI::Store.new @tmpdir 867 868 inner = @RM::Document.new @RM::Paragraph.new 'new comment' 869 inner.file = @top_level 870 871 document = @RM::Document.new inner 872 873 assert_equal document, s.load_class('Object').comment_location 874 end 875 876 # This is a functional test 877 def test_save_class_merge_constant 878 store = RDoc::Store.new 879 tl = store.add_file 'file.rb' 880 881 klass = tl.add_class RDoc::NormalClass, 'C' 882 klass.add_comment 'comment', tl 883 884 const = klass.add_constant RDoc::Constant.new('CONST', nil, nil) 885 const.record_location tl 886 887 @s.save_class klass 888 889 # separate parse run, independent store 890 store = RDoc::Store.new 891 tl = store.add_file 'file.rb' 892 klass2 = tl.add_class RDoc::NormalClass, 'C' 893 klass2.record_location tl 894 895 s = RDoc::RI::Store.new @tmpdir 896 s.save_class klass2 897 898 # separate `ri` run, independent store 899 s = RDoc::RI::Store.new @tmpdir 900 901 result = s.load_class 'C' 902 903 assert_empty result.constants 904 end 905 906 def test_save_class_methods 907 @s.save_class @klass 908 909 assert_directory File.join(@tmpdir, 'Object') 910 assert_file File.join(@tmpdir, 'Object', 'cdesc-Object.ri') 911 912 assert_cache nil, nil, nil, %w[Object], 'Object' => OBJECT_ANCESTORS 913 914 assert_equal @klass, @s.load_class('Object') 915 end 916 917 def test_save_class_nested 918 @s.save_class @nest_klass 919 920 assert_directory File.join(@tmpdir, 'Object', 'SubClass') 921 assert_file File.join(@tmpdir, 'Object', 'SubClass', 'cdesc-SubClass.ri') 922 923 assert_cache({ 'Object::SubClass' => %w[method] }, {}, {}, 924 %w[Object::SubClass], 'Object::SubClass' => %w[Incl Object]) 925 end 926 927 def test_save_method 928 @s.save_method @klass, @meth 929 930 assert_directory File.join(@tmpdir, 'Object') 931 assert_file File.join(@tmpdir, 'Object', 'method-i.ri') 932 933 assert_cache({ 'Object' => %w[method] }, {}, {}, []) 934 935 assert_equal @meth, @s.load_method('Object', '#method') 936 end 937 938 def test_save_method_dry_run 939 @s.dry_run = true 940 941 @s.save_method @klass, @meth 942 943 refute_file File.join(@tmpdir, 'Object') 944 refute_file File.join(@tmpdir, 'Object', 'method-i.ri') 945 end 946 947 def test_save_method_nested 948 @s.save_method @nest_klass, @nest_meth 949 950 assert_directory File.join(@tmpdir, 'Object', 'SubClass') 951 assert_file File.join(@tmpdir, 'Object', 'SubClass', 'method-i.ri') 952 953 assert_cache({ 'Object::SubClass' => %w[method] }, {}, {}, []) 954 end 955 956 def test_save_page 957 @s.save_page @page 958 959 assert_file File.join(@tmpdir, 'page-README_txt.ri') 960 961 assert_cache({}, {}, {}, [], {}, %w[README.txt]) 962 end 963 964 def test_save_page_file 965 @s.save_page @top_level 966 967 refute_file File.join(@tmpdir, 'page-file_rb.ri') 968 end 969 970 def test_source 971 @s.path = @tmpdir 972 @s.type = nil 973 assert_equal @s.path, @s.source 974 975 @s.type = :extra 976 assert_equal @s.path, @s.source 977 978 @s.type = :system 979 assert_equal "ruby", @s.source 980 981 @s.type = :site 982 assert_equal "site", @s.source 983 984 @s.type = :home 985 assert_equal "home", @s.source 986 987 @s.type = :gem 988 @s.path = "#{@tmpdir}/gem_repository/doc/gem_name-1.0/ri" 989 assert_equal "gem_name-1.0", @s.source 990 end 991 992 def test_title 993 assert_equal nil, @s.title 994 995 @s.title = 'rdoc' 996 997 assert_equal 'rdoc', @s.title 998 end 999 1000end 1001 1002