1require 'rdoc/test_case' 2 3class TestRDocRIDriver < RDoc::TestCase 4 5 def setup 6 super 7 8 @tmpdir = File.join Dir.tmpdir, "test_rdoc_ri_driver_#{$$}" 9 @home_ri = File.join @tmpdir, 'dot_ri' 10 11 FileUtils.mkdir_p @tmpdir 12 FileUtils.mkdir_p @home_ri 13 14 @orig_ri = ENV['RI'] 15 @orig_home = ENV['HOME'] 16 ENV['HOME'] = @tmpdir 17 ENV.delete 'RI' 18 19 @options = RDoc::RI::Driver.default_options 20 @options[:use_system] = false 21 @options[:use_site] = false 22 @options[:use_home] = false 23 @options[:use_gems] = false 24 25 @options[:home] = @tmpdir 26 @options[:use_stdout] = true 27 @options[:formatter] = @RM::ToRdoc 28 29 @driver = RDoc::RI::Driver.new @options 30 end 31 32 def teardown 33 super 34 35 ENV['HOME'] = @orig_home 36 ENV['RI'] = @orig_ri 37 FileUtils.rm_rf @tmpdir 38 end 39 40 DUMMY_PAGER = ":;\n" 41 42 def with_dummy_pager 43 pager_env, ENV['RI_PAGER'] = ENV['RI_PAGER'], DUMMY_PAGER 44 yield 45 ensure 46 ENV['RI_PAGER'] = pager_env 47 end 48 49 def mu_pp(obj) 50 s = '' 51 s = PP.pp obj, s 52 s = s.force_encoding(Encoding.default_external) if defined? Encoding 53 s.chomp 54 end 55 56 def test_self_dump 57 util_store 58 59 out, = capture_io do 60 RDoc::RI::Driver.dump @store1.cache_path 61 end 62 63 assert_match %r%:class_methods%, out 64 assert_match %r%:modules%, out 65 assert_match %r%:instance_methods%, out 66 assert_match %r%:ancestors%, out 67 end 68 69 def test_add_also_in_empty 70 out = @RM::Document.new 71 72 @driver.add_also_in out, [] 73 74 assert_empty out 75 end 76 77 def test_add_also_in 78 util_multi_store 79 @store1.type = :system 80 @store2.type = :home 81 82 out = @RM::Document.new 83 84 @driver.add_also_in out, [@store1, @store2] 85 86 expected = @RM::Document.new( 87 @RM::Rule.new(1), 88 @RM::Paragraph.new('Also found in:'), 89 @RM::Verbatim.new("ruby core", "\n", 90 "~/.rdoc", "\n")) 91 92 assert_equal expected, out 93 end 94 95 def test_add_class 96 util_multi_store 97 98 out = @RM::Document.new 99 100 @driver.add_class out, 'Bar', [@cBar] 101 102 expected = @RM::Document.new( 103 @RM::Heading.new(1, 'Bar < Foo'), 104 @RM::BlankLine.new) 105 106 assert_equal expected, out 107 end 108 109 def test_add_from 110 util_store 111 @store1.type = :system 112 113 out = @RM::Document.new 114 115 @driver.add_from out, @store1 116 117 expected = @RM::Document.new @RM::Paragraph.new("(from ruby core)") 118 119 assert_equal expected, out 120 end 121 122 def test_add_extends 123 util_store 124 125 out = @RM::Document.new 126 127 @driver.add_extends out, [[[@cFooExt], @store1]] 128 129 expected = @RM::Document.new( 130 @RM::Rule.new(1), 131 @RM::Heading.new(1, "Extended by:"), 132 @RM::Paragraph.new("Ext (from #{@store1.friendly_path})"), 133 @RM::BlankLine.new, 134 @RM::Paragraph.new("Extend thingy"), 135 @RM::BlankLine.new) 136 137 assert_equal expected, out 138 end 139 140 def test_add_extension_modules_empty 141 out = @RM::Document.new 142 143 @driver.add_extension_modules out, 'Includes', [] 144 145 assert_empty out 146 end 147 148 def test_add_extension_modules_many 149 util_store 150 151 out = @RM::Document.new 152 153 enum = RDoc::Include.new 'Enumerable', nil 154 @cFoo.add_include enum 155 156 @driver.add_extension_modules out, 'Includes', [[[@cFooInc, enum], @store1]] 157 158 expected = @RM::Document.new( 159 @RM::Rule.new(1), 160 @RM::Heading.new(1, "Includes:"), 161 @RM::Paragraph.new("(from #{@store1.friendly_path})"), 162 @RM::BlankLine.new, 163 @RM::Paragraph.new("Inc"), 164 @RM::BlankLine.new, 165 @RM::Paragraph.new("Include thingy"), 166 @RM::BlankLine.new, 167 @RM::Verbatim.new("Enumerable", "\n")) 168 169 assert_equal expected, out 170 end 171 172 def test_add_extension_modules_many_no_doc 173 util_store 174 175 out = @RM::Document.new 176 177 enum = RDoc::Include.new 'Enumerable', nil 178 @cFoo.add_include enum 179 @cFooInc.instance_variable_set :@comment, '' 180 181 @driver.add_extension_modules out, 'Includes', [[[@cFooInc, enum], @store1]] 182 183 expected = @RM::Document.new( 184 @RM::Rule.new(1), 185 @RM::Heading.new(1, "Includes:"), 186 @RM::Paragraph.new("(from #{@store1.friendly_path})"), 187 @RM::Verbatim.new("Inc", "\n", 188 "Enumerable", "\n")) 189 190 assert_equal expected, out 191 end 192 193 def test_add_extension_modules_one 194 util_store 195 196 out = @RM::Document.new 197 198 @driver.add_extension_modules out, 'Includes', [[[@cFooInc], @store1]] 199 200 expected = @RM::Document.new( 201 @RM::Rule.new(1), 202 @RM::Heading.new(1, "Includes:"), 203 @RM::Paragraph.new("Inc (from #{@store1.friendly_path})"), 204 @RM::BlankLine.new, 205 @RM::Paragraph.new("Include thingy"), 206 @RM::BlankLine.new) 207 208 assert_equal expected, out 209 end 210 211 def test_add_includes 212 util_store 213 214 out = @RM::Document.new 215 216 @driver.add_includes out, [[[@cFooInc], @store1]] 217 218 expected = @RM::Document.new( 219 @RM::Rule.new(1), 220 @RM::Heading.new(1, "Includes:"), 221 @RM::Paragraph.new("Inc (from #{@store1.friendly_path})"), 222 @RM::BlankLine.new, 223 @RM::Paragraph.new("Include thingy"), 224 @RM::BlankLine.new) 225 226 assert_equal expected, out 227 end 228 229 def test_add_method 230 util_store 231 232 out = doc 233 234 @driver.add_method out, 'Foo::Bar#blah' 235 236 expected = 237 doc( 238 head(1, 'Foo::Bar#blah'), 239 blank_line, 240 para('(from ~/.rdoc)'), 241 head(3, 'Implementation from Bar'), 242 rule(1), 243 verb("blah(5) => 5\n", 244 "blah(6) => 6\n"), 245 rule(1), 246 blank_line, 247 blank_line) 248 249 assert_equal expected, out 250 end 251 252 def test_add_method_attribute 253 util_store 254 255 out = doc 256 257 @driver.add_method out, 'Foo::Bar#attr' 258 259 expected = 260 doc( 261 head(1, 'Foo::Bar#attr'), 262 blank_line, 263 para('(from ~/.rdoc)'), 264 rule(1), 265 blank_line, 266 blank_line) 267 268 assert_equal expected, out 269 end 270 271 def test_add_method_inherited 272 util_multi_store 273 274 out = doc 275 276 @driver.add_method out, 'Bar#inherit' 277 278 expected = 279 doc( 280 head(1, 'Bar#inherit'), 281 blank_line, 282 para('(from ~/.rdoc)'), 283 head(3, 'Implementation from Foo'), 284 rule(1), 285 blank_line, 286 blank_line) 287 288 assert_equal expected, out 289 end 290 291 def test_add_method_overriden 292 util_multi_store 293 294 out = doc 295 296 @driver.add_method out, 'Bar#override' 297 298 expected = 299 doc( 300 head(1, 'Bar#override'), 301 blank_line, 302 para("(from #{@store2.path})"), 303 rule(1), 304 blank_line, 305 para('must be displayed'), 306 blank_line, 307 blank_line) 308 309 assert_equal expected, out 310 end 311 312 def test_add_method_documentation 313 util_store 314 315 out = doc() 316 317 missing = RDoc::AnyMethod.new nil, 'missing' 318 @cFoo.add_method missing 319 320 @driver.add_method_documentation out, @cFoo 321 322 expected = 323 doc( 324 head(1, 'Foo#inherit'), 325 blank_line, 326 para('(from ~/.rdoc)'), 327 rule(1), 328 blank_line, 329 blank_line, 330 head(1, 'Foo#override'), 331 blank_line, 332 para('(from ~/.rdoc)'), 333 rule(1), 334 blank_line, 335 para('must not be displayed in Bar#override'), 336 blank_line, 337 blank_line) 338 339 assert_equal expected, out 340 end 341 342 def test_add_method_list 343 out = @RM::Document.new 344 345 @driver.add_method_list out, %w[new parse], 'Class methods' 346 347 expected = @RM::Document.new( 348 @RM::Heading.new(1, 'Class methods:'), 349 @RM::BlankLine.new, 350 @RM::Verbatim.new('new'), 351 @RM::Verbatim.new('parse'), 352 @RM::BlankLine.new) 353 354 assert_equal expected, out 355 end 356 357 def test_add_method_list_interative 358 @options[:interactive] = true 359 driver = RDoc::RI::Driver.new @options 360 361 out = @RM::Document.new 362 363 driver.add_method_list out, %w[new parse], 'Class methods' 364 365 expected = @RM::Document.new( 366 @RM::Heading.new(1, 'Class methods:'), 367 @RM::BlankLine.new, 368 @RM::IndentedParagraph.new(2, 'new, parse'), 369 @RM::BlankLine.new) 370 371 assert_equal expected, out 372 end 373 374 def test_add_method_list_none 375 out = @RM::Document.new 376 377 @driver.add_method_list out, [], 'Class' 378 379 assert_equal @RM::Document.new, out 380 end 381 382 def test_ancestors_of 383 util_ancestors_store 384 385 assert_equal %w[X Mixin Object Foo], @driver.ancestors_of('Foo::Bar') 386 end 387 388 def test_classes 389 util_multi_store 390 391 expected = { 392 'Ambiguous' => [@store1, @store2], 393 'Bar' => [@store2], 394 'Ext' => [@store1], 395 'Foo' => [@store1, @store2], 396 'Foo::Bar' => [@store1], 397 'Foo::Baz' => [@store1, @store2], 398 'Inc' => [@store1], 399 } 400 401 classes = @driver.classes 402 403 assert_equal expected.keys.sort, classes.keys.sort 404 405 expected.each do |klass, stores| 406 assert_equal stores, classes[klass].sort_by { |store| store.path }, 407 "mismatch for #{klass}" 408 end 409 end 410 411 def test_class_document 412 util_store 413 414 tl1 = @store1.add_file 'one.rb' 415 tl2 = @store1.add_file 'two.rb' 416 417 @cFoo.add_comment 'one', tl1 418 @cFoo.add_comment 'two', tl2 419 420 @store1.save_class @cFoo 421 422 found = [ 423 [@store1, @store1.load_class(@cFoo.full_name)] 424 ] 425 426 extends = [[[@cFooExt], @store1]] 427 includes = [[[@cFooInc], @store1]] 428 429 out = @driver.class_document @cFoo.full_name, found, [], includes, extends 430 431 expected = @RM::Document.new 432 @driver.add_class expected, 'Foo', [] 433 @driver.add_includes expected, includes 434 @driver.add_extends expected, extends 435 @driver.add_from expected, @store1 436 expected << @RM::Rule.new(1) 437 438 doc = @RM::Document.new(@RM::Paragraph.new('one')) 439 doc.file = 'one.rb' 440 expected.push doc 441 expected << @RM::BlankLine.new 442 doc = @RM::Document.new(@RM::Paragraph.new('two')) 443 doc.file = 'two.rb' 444 expected.push doc 445 446 expected << @RM::Rule.new(1) 447 expected << @RM::Heading.new(1, 'Instance methods:') 448 expected << @RM::BlankLine.new 449 expected << @RM::Verbatim.new('inherit') 450 expected << @RM::Verbatim.new('override') 451 expected << @RM::BlankLine.new 452 453 assert_equal expected, out 454 end 455 456 def test_complete 457 store = RDoc::RI::Store.new @home_ri 458 store.cache[:ancestors] = { 459 'Foo' => %w[Object], 460 'Foo::Bar' => %w[Object], 461 } 462 store.cache[:class_methods] = { 463 'Foo' => %w[bar] 464 } 465 store.cache[:instance_methods] = { 466 'Foo' => %w[Bar] 467 } 468 store.cache[:modules] = %w[ 469 Foo 470 Foo::Bar 471 ] 472 473 @driver.stores = [store] 474 475 assert_equal %w[Foo ], @driver.complete('F') 476 assert_equal %w[ Foo::Bar], @driver.complete('Foo::B') 477 478 assert_equal %w[Foo#Bar], @driver.complete('Foo#'), 'Foo#' 479 assert_equal %w[Foo#Bar Foo::bar], @driver.complete('Foo.'), 'Foo.' 480 assert_equal %w[Foo::Bar Foo::bar], @driver.complete('Foo::'), 'Foo::' 481 482 assert_equal %w[ Foo::bar], @driver.complete('Foo::b'), 'Foo::b' 483 end 484 485 def test_complete_ancestor 486 util_ancestors_store 487 488 assert_equal %w[Foo::Bar#i_method], @driver.complete('Foo::Bar#') 489 490 assert_equal %w[Foo::Bar#i_method Foo::Bar::c_method Foo::Bar::new], 491 @driver.complete('Foo::Bar.') 492 end 493 494 def test_complete_classes 495 util_store 496 497 assert_equal %w[ ], @driver.complete('[') 498 assert_equal %w[ ], @driver.complete('[::') 499 assert_equal %w[Foo ], @driver.complete('F') 500 assert_equal %w[Foo:: Foo::Bar Foo::Baz], @driver.complete('Foo::') 501 assert_equal %w[ Foo::Bar Foo::Baz], @driver.complete('Foo::B') 502 end 503 504 def test_complete_multistore 505 util_multi_store 506 507 assert_equal %w[Bar], @driver.complete('B') 508 assert_equal %w[Foo], @driver.complete('F') 509 assert_equal %w[Foo::Bar Foo::Baz], @driver.complete('Foo::B') 510 end 511 512 def test_display 513 doc = @RM::Document.new( 514 @RM::Paragraph.new('hi')) 515 516 out, = capture_io do 517 @driver.display doc 518 end 519 520 assert_equal "hi\n", out 521 end 522 523 def test_display_class 524 util_store 525 526 out, = capture_io do 527 @driver.display_class 'Foo::Bar' 528 end 529 530 assert_match %r%^= Foo::Bar%, out 531 assert_match %r%^\(from%, out 532 533 assert_match %r%^= Class methods:%, out 534 assert_match %r%^ new%, out 535 assert_match %r%^= Instance methods:%, out 536 assert_match %r%^ blah%, out 537 assert_match %r%^= Attributes:%, out 538 assert_match %r%^ attr_accessor attr%, out 539 540 assert_equal 1, out.scan(/-\n/).length 541 542 refute_match %r%Foo::Bar#blah%, out 543 end 544 545 def test_display_class_all 546 util_store 547 548 @driver.show_all = true 549 550 out, = capture_io do 551 @driver.display_class 'Foo::Bar' 552 end 553 554 assert_match %r%^= Foo::Bar%, out 555 assert_match %r%^\(from%, out 556 557 assert_match %r%^= Class methods:%, out 558 assert_match %r%^ new%, out 559 assert_match %r%^= Instance methods:%, out 560 assert_match %r%^ blah%, out 561 assert_match %r%^= Attributes:%, out 562 assert_match %r%^ attr_accessor attr%, out 563 564 assert_equal 6, out.scan(/-\n/).length 565 566 assert_match %r%Foo::Bar#blah%, out 567 end 568 569 def test_display_class_ambiguous 570 util_multi_store 571 572 out, = capture_io do 573 @driver.display_class 'Ambiguous' 574 end 575 576 assert_match %r%^= Ambiguous < Object$%, out 577 end 578 579 def test_display_class_multi_no_doc 580 util_multi_store 581 582 out, = capture_io do 583 @driver.display_class 'Foo::Baz' 584 end 585 586 assert_match %r%^= Foo::Baz%, out 587 assert_match %r%-\n%, out 588 assert_match %r%Also found in:%, out 589 assert_match %r%#{Regexp.escape @home_ri}%, out 590 assert_match %r%#{Regexp.escape @home_ri2}%, out 591 end 592 593 def test_display_class_superclass 594 util_multi_store 595 596 out, = capture_io do 597 @driver.display_class 'Bar' 598 end 599 600 assert_match %r%^= Bar < Foo%, out 601 end 602 603 def test_display_class_module 604 util_store 605 606 out, = capture_io do 607 @driver.display_class 'Inc' 608 end 609 610 assert_match %r%^= Inc$%, out 611 end 612 613 def test_display_class_page 614 out, = capture_io do 615 @driver.display_class 'ruby:README' 616 end 617 618 assert_empty out 619 end 620 621 def test_display_method 622 util_store 623 624 out, = capture_io do 625 @driver.display_method 'Foo::Bar#blah' 626 end 627 628 assert_match %r%Foo::Bar#blah%, out 629 assert_match %r%blah.5%, out 630 assert_match %r%blah.6%, out 631 end 632 633 def test_display_method_attribute 634 util_store 635 636 out, = capture_io do 637 @driver.display_method 'Foo::Bar#attr' 638 end 639 640 assert_match %r%Foo::Bar#attr%, out 641 refute_match %r%Implementation from%, out 642 end 643 644 def test_display_method_inherited 645 util_multi_store 646 647 out, = capture_io do 648 @driver.display_method 'Bar#inherit' 649 end 650 651 assert_match %r%^= Bar#inherit%, out 652 assert_match %r%^=== Implementation from Foo%, out 653 end 654 655 def test_display_method_overriden 656 util_multi_store 657 658 out, = capture_io do 659 @driver.display_method 'Bar#override' 660 end 661 662 refute_match %r%must not be displayed%, out 663 end 664 665 def test_display_name_not_found_class 666 util_store 667 668 out, = capture_io do 669 assert_equal false, @driver.display_name('Foo::B') 670 end 671 672 expected = <<-EXPECTED 673Foo::B not found, maybe you meant: 674 675Foo::Bar 676Foo::Baz 677 EXPECTED 678 679 assert_equal expected, out 680 end 681 682 def test_display_name_not_found_method 683 util_store 684 685 out, = capture_io do 686 assert_equal false, @driver.display_name('Foo::Bar#b') 687 end 688 689 expected = <<-EXPECTED 690Foo::Bar#b not found, maybe you meant: 691 692Foo::Bar#blah 693Foo::Bar#bother 694 EXPECTED 695 696 assert_equal expected, out 697 end 698 699 def test_display_method_params 700 util_store 701 702 out, = capture_io do 703 @driver.display_method 'Foo::Bar#bother' 704 end 705 706 assert_match %r%things.*stuff%, out 707 end 708 709 def test_display_page 710 util_store 711 712 out, = capture_io do 713 @driver.display_page 'home:README.rdoc' 714 end 715 716 assert_match %r%= README%, out 717 end 718 719 def test_display_page_add_extension 720 util_store 721 722 out, = capture_io do 723 @driver.display_page 'home:README' 724 end 725 726 assert_match %r%= README%, out 727 end 728 729 def test_display_page_ambiguous 730 util_store 731 732 other = @store1.add_file 'README.md' 733 other.parser = RDoc::Parser::Simple 734 other.comment = 735 doc( 736 head(1, 'README.md'), 737 para('This is the other README')) 738 739 @store1.save_page other 740 741 out, = capture_io do 742 @driver.display_page 'home:README' 743 end 744 745 assert_match %r%= README pages in ~/\.rdoc%, out 746 assert_match %r%README\.rdoc%, out 747 assert_match %r%README\.md%, out 748 end 749 750 def test_display_page_extension 751 util_store 752 753 other = @store1.add_file 'README.EXT' 754 other.parser = RDoc::Parser::Simple 755 other.comment = 756 doc( 757 head(1, 'README.EXT'), 758 para('This is the other README')) 759 760 @store1.save_page other 761 762 out, = capture_io do 763 @driver.display_page 'home:README.EXT' 764 end 765 766 assert_match 'other README', out 767 end 768 769 def test_display_page_ignore_directory 770 util_store 771 772 other = @store1.add_file 'doc/globals.rdoc' 773 other.parser = RDoc::Parser::Simple 774 other.comment = 775 doc( 776 head(1, 'globals.rdoc'), 777 para('Globals go here')) 778 779 @store1.save_page other 780 781 out, = capture_io do 782 @driver.display_page 'home:globals' 783 end 784 785 assert_match %r%= globals\.rdoc%, out 786 end 787 788 def test_display_page_missing 789 util_store 790 791 out, = capture_io do 792 @driver.display_page 'home:missing' 793 end 794 795 out, = capture_io do 796 @driver.display_page_list @store1 797 end 798 799 assert_match %r%= Pages in ~/\.rdoc%, out 800 assert_match %r%README\.rdoc%, out 801 end 802 803 def test_display_page_list 804 util_store 805 806 other = @store1.add_file 'OTHER.rdoc' 807 other.parser = RDoc::Parser::Simple 808 other.comment = 809 doc( 810 head(1, 'OTHER'), 811 para('This is OTHER')) 812 813 @store1.save_page other 814 815 out, = capture_io do 816 @driver.display_page_list @store1 817 end 818 819 assert_match %r%= Pages in ~/\.rdoc%, out 820 assert_match %r%README\.rdoc%, out 821 assert_match %r%OTHER\.rdoc%, out 822 end 823 824 def test_expand_class 825 util_store 826 827 assert_equal 'Foo', @driver.expand_class('F') 828 assert_equal 'Foo::Bar', @driver.expand_class('F::Bar') 829 830 assert_raises RDoc::RI::Driver::NotFoundError do 831 @driver.expand_class 'F::B' 832 end 833 end 834 835 def test_expand_name 836 util_store 837 838 assert_equal '.b', @driver.expand_name('b') 839 assert_equal 'Foo', @driver.expand_name('F') 840 assert_equal 'Foo::Bar#', @driver.expand_name('F::Bar#') 841 842 e = assert_raises RDoc::RI::Driver::NotFoundError do 843 @driver.expand_name 'Z' 844 end 845 846 assert_equal 'Z', e.name 847 848 @driver.stores << RDoc::Store.new(nil, :system) 849 850 assert_equal 'ruby:README', @driver.expand_name('ruby:README') 851 assert_equal 'ruby:', @driver.expand_name('ruby:') 852 853 e = assert_raises RDoc::RI::Driver::NotFoundError do 854 @driver.expand_name 'nonexistent_gem:' 855 end 856 857 assert_equal 'nonexistent_gem', e.name 858 end 859 860 def test_find_methods 861 util_store 862 863 items = [] 864 865 @driver.find_methods 'Foo::Bar.' do |store, klass, ancestor, types, method| 866 items << [store, klass, ancestor, types, method] 867 end 868 869 expected = [ 870 [@store1, 'Foo::Bar', 'Foo::Bar', :both, nil], 871 ] 872 873 assert_equal expected, items 874 end 875 876 def test_find_methods_method 877 util_store 878 879 items = [] 880 881 @driver.find_methods '.blah' do |store, klass, ancestor, types, method| 882 items << [store, klass, ancestor, types, method] 883 end 884 885 expected = [ 886 [@store1, 'Ambiguous', 'Ambiguous', :both, 'blah'], 887 [@store1, 'Ext', 'Ext', :both, 'blah'], 888 [@store1, 'Foo', 'Foo', :both, 'blah'], 889 [@store1, 'Foo::Bar', 'Foo::Bar', :both, 'blah'], 890 [@store1, 'Foo::Baz', 'Foo::Baz', :both, 'blah'], 891 [@store1, 'Inc', 'Inc', :both, 'blah'], 892 ] 893 894 assert_equal expected, items 895 end 896 897 def test_filter_methods 898 util_multi_store 899 900 name = 'Bar#override' 901 902 found = @driver.load_methods_matching name 903 904 sorted = @driver.filter_methods found, name 905 906 expected = [[@store2, [@override]]] 907 908 assert_equal expected, sorted 909 end 910 911 def test_filter_methods_not_found 912 util_multi_store 913 914 name = 'Bar#inherit' 915 916 found = @driver.load_methods_matching name 917 918 sorted = @driver.filter_methods found, name 919 920 assert_equal found, sorted 921 end 922 923 def test_find_store 924 @driver.stores << RDoc::Store.new(nil, :system) 925 @driver.stores << RDoc::Store.new('doc/gem-1.0/ri', :gem) 926 927 assert_equal 'ruby', @driver.find_store('ruby') 928 assert_equal 'gem-1.0', @driver.find_store('gem-1.0') 929 assert_equal 'gem-1.0', @driver.find_store('gem') 930 931 e = assert_raises RDoc::RI::Driver::NotFoundError do 932 @driver.find_store 'nonexistent' 933 end 934 935 assert_equal 'nonexistent', e.name 936 end 937 938 def test_formatter 939 tty = Object.new 940 def tty.tty?() true; end 941 942 driver = RDoc::RI::Driver.new 943 944 assert_instance_of @RM::ToAnsi, driver.formatter(tty) 945 946 assert_instance_of @RM::ToBs, driver.formatter(StringIO.new) 947 948 driver.instance_variable_set :@paging, true 949 950 assert_instance_of @RM::ToBs, driver.formatter(StringIO.new) 951 end 952 953 def test_in_path_eh 954 path = ENV['PATH'] 955 956 test_path = File.expand_path '..', __FILE__ 957 958 temp_dir do |dir| 959 nonexistent = File.join dir, 'nonexistent' 960 refute @driver.in_path?(nonexistent) 961 962 ENV['PATH'] = test_path 963 964 assert @driver.in_path?(File.basename(__FILE__)) 965 end 966 ensure 967 ENV['PATH'] = path 968 end 969 970 def test_method_type 971 assert_equal :both, @driver.method_type(nil) 972 assert_equal :both, @driver.method_type('.') 973 assert_equal :instance, @driver.method_type('#') 974 assert_equal :class, @driver.method_type('::') 975 end 976 977 def test_name_regexp 978 assert_equal %r%^RDoc::AnyMethod#new$%, 979 @driver.name_regexp('RDoc::AnyMethod#new') 980 981 assert_equal %r%^RDoc::AnyMethod::new$%, 982 @driver.name_regexp('RDoc::AnyMethod::new') 983 984 assert_equal %r%^RDoc::AnyMethod(#|::)new$%, 985 @driver.name_regexp('RDoc::AnyMethod.new') 986 987 assert_equal %r%^Hash(#|::)\[\]$%, 988 @driver.name_regexp('Hash.[]') 989 990 assert_equal %r%^Hash::\[\]$%, 991 @driver.name_regexp('Hash::[]') 992 end 993 994 def test_list_known_classes 995 util_store 996 997 out, = capture_io do 998 @driver.list_known_classes 999 end 1000 1001 assert_equal "Ambiguous\nExt\nFoo\nFoo::Bar\nFoo::Baz\nInc\n", out 1002 end 1003 1004 def test_list_known_classes_name 1005 util_store 1006 1007 out, = capture_io do 1008 @driver.list_known_classes %w[F I] 1009 end 1010 1011 assert_equal "Foo\nFoo::Bar\nFoo::Baz\nInc\n", out 1012 end 1013 1014 def test_list_methods_matching 1015 util_store 1016 1017 assert_equal %w[ 1018 Foo::Bar#attr 1019 Foo::Bar#blah 1020 Foo::Bar#bother 1021 Foo::Bar::new 1022 ], 1023 @driver.list_methods_matching('Foo::Bar.').sort 1024 end 1025 1026 def test_list_methods_matching_inherit 1027 util_multi_store 1028 1029 assert_equal %w[ 1030 Bar#baz 1031 Bar#inherit 1032 Bar#override 1033 ], 1034 @driver.list_methods_matching('Bar.').sort 1035 end 1036 1037 def test_list_methods_matching_regexp 1038 util_store 1039 1040 index = RDoc::AnyMethod.new nil, '[]' 1041 index.record_location @top_level 1042 @cFoo.add_method index 1043 @store1.save_method @cFoo, index 1044 1045 c_index = RDoc::AnyMethod.new nil, '[]' 1046 c_index.singleton = true 1047 c_index.record_location @top_level 1048 @cFoo.add_method c_index 1049 @store1.save_method @cFoo, c_index 1050 1051 @store1.save_cache 1052 1053 assert_equal %w[Foo#[]], @driver.list_methods_matching('Foo#[]') 1054 assert_equal %w[Foo::[]], @driver.list_methods_matching('Foo::[]') 1055 end 1056 1057 def test_load_method 1058 util_store 1059 1060 method = @driver.load_method(@store1, :instance_methods, 'Foo', '#', 1061 'inherit') 1062 1063 assert_equal @inherit, method 1064 end 1065 1066 def test_load_method_inherited 1067 util_multi_store 1068 1069 method = @driver.load_method(@store2, :instance_methods, 'Bar', '#', 1070 'inherit') 1071 1072 assert_equal nil, method 1073 end 1074 1075 def test_load_methods_matching 1076 util_store 1077 1078 expected = [[@store1, [@inherit]]] 1079 1080 assert_equal expected, @driver.load_methods_matching('Foo#inherit') 1081 1082 expected = [[@store1, [@blah]]] 1083 1084 assert_equal expected, @driver.load_methods_matching('.blah') 1085 1086 assert_empty @driver.load_methods_matching('.b') 1087 end 1088 1089 def test_load_methods_matching_inherited 1090 util_multi_store 1091 1092 expected = [[@store1, [@inherit]]] 1093 1094 assert_equal expected, @driver.load_methods_matching('Bar#inherit') 1095 end 1096 1097 def _test_page # this test doesn't do anything anymore :( 1098 @driver.use_stdout = false 1099 1100 with_dummy_pager do 1101 @driver.page do |io| 1102 skip "couldn't find a standard pager" if io == $stdout 1103 1104 assert @driver.paging? 1105 end 1106 end 1107 1108 refute @driver.paging? 1109 end 1110 1111 # this test is too fragile. Perhaps using Process.spawn will make this 1112 # reliable 1113 def _test_page_in_presence_of_child_status 1114 skip 'this test hangs on travis-ci.org' if ENV['CI'] 1115 @driver.use_stdout = false 1116 1117 with_dummy_pager do 1118 @driver.page do |io| 1119 refute_equal $stdout, io 1120 assert @driver.paging? 1121 end 1122 end 1123 end 1124 1125 def test_page_stdout 1126 @driver.use_stdout = true 1127 1128 @driver.page do |io| 1129 assert_equal $stdout, io 1130 end 1131 1132 refute @driver.paging? 1133 end 1134 1135 def test_parse_name_method 1136 klass, type, meth = @driver.parse_name 'foo' 1137 1138 assert_equal '', klass, 'foo class' 1139 assert_equal '.', type, 'foo type' 1140 assert_equal 'foo', meth, 'foo method' 1141 1142 klass, type, meth = @driver.parse_name '#foo' 1143 1144 assert_equal '', klass, '#foo class' 1145 assert_equal '#', type, '#foo type' 1146 assert_equal 'foo', meth, '#foo method' 1147 1148 klass, type, meth = @driver.parse_name '::foo' 1149 1150 assert_equal '', klass, '::foo class' 1151 assert_equal '::', type, '::foo type' 1152 assert_equal 'foo', meth, '::foo method' 1153 end 1154 1155 def test_parse_name_page 1156 klass, type, meth = @driver.parse_name 'ruby:README' 1157 1158 assert_equal 'ruby', klass, 'ruby project' 1159 assert_equal ':', type, 'ruby type' 1160 assert_equal 'README', meth, 'ruby page' 1161 1162 klass, type, meth = @driver.parse_name 'ruby:' 1163 1164 assert_equal 'ruby', klass, 'ruby project' 1165 assert_equal ':', type, 'ruby type' 1166 assert_equal nil, meth, 'ruby page' 1167 end 1168 1169 def test_parse_name_page_extenson 1170 klass, type, meth = @driver.parse_name 'ruby:README.EXT' 1171 1172 assert_equal 'ruby', klass, 'ruby project' 1173 assert_equal ':', type, 'ruby type' 1174 assert_equal 'README.EXT', meth, 'ruby page' 1175 end 1176 1177 def test_parse_name_single_class 1178 klass, type, meth = @driver.parse_name 'Foo' 1179 1180 assert_equal 'Foo', klass, 'Foo class' 1181 assert_equal nil, type, 'Foo type' 1182 assert_equal nil, meth, 'Foo method' 1183 1184 klass, type, meth = @driver.parse_name 'Foo#' 1185 1186 assert_equal 'Foo', klass, 'Foo# class' 1187 assert_equal '#', type, 'Foo# type' 1188 assert_equal nil, meth, 'Foo# method' 1189 1190 klass, type, meth = @driver.parse_name 'Foo::' 1191 1192 assert_equal 'Foo', klass, 'Foo:: class' 1193 assert_equal '::', type, 'Foo:: type' 1194 assert_equal nil, meth, 'Foo:: method' 1195 1196 klass, type, meth = @driver.parse_name 'Foo.' 1197 1198 assert_equal 'Foo', klass, 'Foo. class' 1199 assert_equal '.', type, 'Foo. type' 1200 assert_equal nil, meth, 'Foo. method' 1201 1202 klass, type, meth = @driver.parse_name 'Foo#Bar' 1203 1204 assert_equal 'Foo', klass, 'Foo#Bar class' 1205 assert_equal '#', type, 'Foo#Bar type' 1206 assert_equal 'Bar', meth, 'Foo#Bar method' 1207 1208 klass, type, meth = @driver.parse_name 'Foo.Bar' 1209 1210 assert_equal 'Foo', klass, 'Foo.Bar class' 1211 assert_equal '.', type, 'Foo.Bar type' 1212 assert_equal 'Bar', meth, 'Foo.Bar method' 1213 1214 klass, type, meth = @driver.parse_name 'Foo::bar' 1215 1216 assert_equal 'Foo', klass, 'Foo::bar class' 1217 assert_equal '::', type, 'Foo::bar type' 1218 assert_equal 'bar', meth, 'Foo::bar method' 1219 end 1220 1221 def test_parse_name_namespace 1222 klass, type, meth = @driver.parse_name 'Foo::Bar' 1223 1224 assert_equal 'Foo::Bar', klass, 'Foo::Bar class' 1225 assert_equal nil, type, 'Foo::Bar type' 1226 assert_equal nil, meth, 'Foo::Bar method' 1227 1228 klass, type, meth = @driver.parse_name 'Foo::Bar#' 1229 1230 assert_equal 'Foo::Bar', klass, 'Foo::Bar# class' 1231 assert_equal '#', type, 'Foo::Bar# type' 1232 assert_equal nil, meth, 'Foo::Bar# method' 1233 1234 klass, type, meth = @driver.parse_name 'Foo::Bar#baz' 1235 1236 assert_equal 'Foo::Bar', klass, 'Foo::Bar#baz class' 1237 assert_equal '#', type, 'Foo::Bar#baz type' 1238 assert_equal 'baz', meth, 'Foo::Bar#baz method' 1239 end 1240 1241 def test_parse_name_special 1242 specials = %w[ 1243 % 1244 & 1245 * 1246 + 1247 +@ 1248 - 1249 -@ 1250 / 1251 < 1252 << 1253 <= 1254 <=> 1255 == 1256 === 1257 => 1258 =~ 1259 > 1260 >> 1261 [] 1262 []= 1263 ^ 1264 ` 1265 | 1266 ~ 1267 ~@ 1268 ] 1269 1270 specials.each do |special| 1271 parsed = @driver.parse_name special 1272 1273 assert_equal ['', '.', special], parsed 1274 end 1275 end 1276 1277 def _test_setup_pager # this test doesn't do anything anymore :( 1278 @driver.use_stdout = false 1279 1280 pager = with_dummy_pager do @driver.setup_pager end 1281 1282 skip "couldn't find a standard pager" unless pager 1283 1284 assert @driver.paging? 1285 ensure 1286 pager.close if pager 1287 end 1288 1289 def util_ancestors_store 1290 store1 = RDoc::RI::Store.new @home_ri 1291 store1.cache[:ancestors] = { 1292 'Foo' => %w[Object], 1293 'Foo::Bar' => %w[Foo], 1294 } 1295 store1.cache[:class_methods] = { 1296 'Foo' => %w[c_method new], 1297 'Foo::Bar' => %w[new], 1298 } 1299 store1.cache[:instance_methods] = { 1300 'Foo' => %w[i_method], 1301 } 1302 store1.cache[:modules] = %w[ 1303 Foo 1304 Foo::Bar 1305 ] 1306 1307 store2 = RDoc::RI::Store.new @home_ri 1308 store2.cache[:ancestors] = { 1309 'Foo' => %w[Mixin Object], 1310 'Mixin' => %w[], 1311 'Object' => %w[X Object], 1312 'X' => %w[Object], 1313 } 1314 store2.cache[:class_methods] = { 1315 'Foo' => %w[c_method new], 1316 'Mixin' => %w[], 1317 'X' => %w[], 1318 'Object' => %w[], 1319 } 1320 store2.cache[:instance_methods] = { 1321 'Foo' => %w[i_method], 1322 'Mixin' => %w[], 1323 } 1324 store2.cache[:modules] = %w[ 1325 Foo 1326 Mixin 1327 Object 1328 X 1329 ] 1330 1331 @driver.stores = store1, store2 1332 end 1333 1334 def util_multi_store 1335 util_store 1336 1337 @home_ri2 = "#{@home_ri}2" 1338 @store2 = RDoc::RI::Store.new @home_ri2 1339 1340 @top_level = @store2.add_file 'file.rb' 1341 1342 # as if seen in a namespace like class Ambiguous::Other 1343 @mAmbiguous = @top_level.add_module RDoc::NormalModule, 'Ambiguous' 1344 1345 @cFoo = @top_level.add_class RDoc::NormalClass, 'Foo' 1346 1347 @cBar = @top_level.add_class RDoc::NormalClass, 'Bar', 'Foo' 1348 @cFoo_Baz = @cFoo.add_class RDoc::NormalClass, 'Baz' 1349 1350 @baz = @cBar.add_method RDoc::AnyMethod.new(nil, 'baz') 1351 @baz.record_location @top_level 1352 1353 @override = @cBar.add_method RDoc::AnyMethod.new(nil, 'override') 1354 @override.comment = 'must be displayed' 1355 @override.record_location @top_level 1356 1357 @store2.save 1358 1359 @driver.stores = [@store1, @store2] 1360 end 1361 1362 def util_store 1363 @store1 = RDoc::RI::Store.new @home_ri, :home 1364 1365 @top_level = @store1.add_file 'file.rb' 1366 1367 @readme = @store1.add_file 'README.rdoc' 1368 @readme.parser = RDoc::Parser::Simple 1369 @readme.comment = 1370 doc( 1371 head(1, 'README'), 1372 para('This is a README')) 1373 1374 @cFoo = @top_level.add_class RDoc::NormalClass, 'Foo' 1375 @mExt = @top_level.add_module RDoc::NormalModule, 'Ext' 1376 @mInc = @top_level.add_module RDoc::NormalModule, 'Inc' 1377 @cAmbiguous = @top_level.add_class RDoc::NormalClass, 'Ambiguous' 1378 1379 doc = @RM::Document.new @RM::Paragraph.new('Extend thingy') 1380 @cFooExt = @cFoo.add_extend RDoc::Extend.new('Ext', doc) 1381 @cFooExt.record_location @top_level 1382 doc = @RM::Document.new @RM::Paragraph.new('Include thingy') 1383 @cFooInc = @cFoo.add_include RDoc::Include.new('Inc', doc) 1384 @cFooInc.record_location @top_level 1385 1386 @cFoo_Bar = @cFoo.add_class RDoc::NormalClass, 'Bar' 1387 1388 @blah = @cFoo_Bar.add_method RDoc::AnyMethod.new(nil, 'blah') 1389 @blah.call_seq = "blah(5) => 5\nblah(6) => 6\n" 1390 @blah.record_location @top_level 1391 1392 @bother = @cFoo_Bar.add_method RDoc::AnyMethod.new(nil, 'bother') 1393 @bother.block_params = "stuff" 1394 @bother.params = "(things)" 1395 @bother.record_location @top_level 1396 1397 @new = @cFoo_Bar.add_method RDoc::AnyMethod.new nil, 'new' 1398 @new.record_location @top_level 1399 @new.singleton = true 1400 1401 @attr = @cFoo_Bar.add_attribute RDoc::Attr.new nil, 'attr', 'RW', '' 1402 @attr.record_location @top_level 1403 1404 @cFoo_Baz = @cFoo.add_class RDoc::NormalClass, 'Baz' 1405 @cFoo_Baz.record_location @top_level 1406 1407 @inherit = @cFoo.add_method RDoc::AnyMethod.new(nil, 'inherit') 1408 @inherit.record_location @top_level 1409 1410 # overriden by Bar in multi_store 1411 @overriden = @cFoo.add_method RDoc::AnyMethod.new(nil, 'override') 1412 @overriden.comment = 'must not be displayed in Bar#override' 1413 @overriden.record_location @top_level 1414 1415 @store1.save 1416 1417 @driver.stores = [@store1] 1418 end 1419 1420end 1421 1422