yard 0.8.2.1 → 0.8.3

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of yard might be problematic. Click here for more details.

Files changed (72) hide show
  1. data/ChangeLog +246 -0
  2. data/README.md +12 -2
  3. data/Rakefile +19 -51
  4. data/benchmarks/format_args.rb +3 -3
  5. data/benchmarks/pathname_vs_string.rb +4 -4
  6. data/benchmarks/template_format.rb +1 -1
  7. data/docs/Templates.md +21 -21
  8. data/docs/WhatsNew.md +16 -2
  9. data/lib/yard.rb +23 -3
  10. data/lib/yard/autoload.rb +14 -13
  11. data/lib/yard/cli/command.rb +11 -3
  12. data/lib/yard/cli/command_parser.rb +4 -4
  13. data/lib/yard/cli/config.rb +2 -2
  14. data/lib/yard/cli/diff.rb +60 -16
  15. data/lib/yard/cli/graph.rb +5 -2
  16. data/lib/yard/cli/help.rb +1 -1
  17. data/lib/yard/cli/list.rb +2 -2
  18. data/lib/yard/cli/server.rb +80 -13
  19. data/lib/yard/cli/stats.rb +8 -8
  20. data/lib/yard/cli/yardoc.rb +32 -78
  21. data/lib/yard/cli/yardopts_command.rb +109 -0
  22. data/lib/yard/cli/yri.rb +2 -2
  23. data/lib/yard/code_objects/base.rb +3 -1
  24. data/lib/yard/code_objects/extra_file_object.rb +45 -6
  25. data/lib/yard/core_ext/file.rb +1 -1
  26. data/lib/yard/docstring.rb +10 -1
  27. data/lib/yard/i18n/locale.rb +11 -3
  28. data/lib/yard/i18n/message.rb +1 -1
  29. data/lib/yard/logging.rb +32 -7
  30. data/lib/yard/parser/ruby/ruby_parser.rb +8 -3
  31. data/lib/yard/parser/source_parser.rb +1 -2
  32. data/lib/yard/rake/yardoc_task.rb +1 -2
  33. data/lib/yard/registry.rb +20 -1
  34. data/lib/yard/registry_store.rb +15 -1
  35. data/lib/yard/rubygems/backports/gem.rb +6 -5
  36. data/lib/yard/rubygems/backports/source_index.rb +17 -0
  37. data/lib/yard/rubygems/doc_manager.rb +1 -1
  38. data/lib/yard/server/commands/static_file_command.rb +17 -10
  39. data/lib/yard/server/library_version.rb +2 -2
  40. data/lib/yard/server/rack_adapter.rb +3 -3
  41. data/lib/yard/server/templates/default/layout/html/setup.rb +1 -1
  42. data/lib/yard/tags/directives.rb +1 -1
  43. data/lib/yard/templates/helpers/html_helper.rb +6 -4
  44. data/lib/yard/templates/template.rb +13 -1
  45. data/lib/yard/version.rb +3 -0
  46. data/spec/cli/config_spec.rb +2 -2
  47. data/spec/cli/diff_spec.rb +110 -23
  48. data/spec/cli/graph_spec.rb +12 -5
  49. data/spec/cli/help_spec.rb +1 -1
  50. data/spec/cli/server_spec.rb +243 -153
  51. data/spec/cli/stats_spec.rb +1 -1
  52. data/spec/cli/yardoc_spec.rb +36 -0
  53. data/spec/code_objects/base_spec.rb +15 -0
  54. data/spec/code_objects/constants_spec.rb +1 -1
  55. data/spec/code_objects/extra_file_object_spec.rb +15 -3
  56. data/spec/docstring_parser_spec.rb +4 -0
  57. data/spec/docstring_spec.rb +18 -0
  58. data/spec/handlers/module_function_handler_spec.rb +23 -0
  59. data/spec/i18n/locale_spec.rb +7 -1
  60. data/spec/parser/ruby/ruby_parser_spec.rb +26 -0
  61. data/spec/parser/source_parser_spec.rb +18 -6
  62. data/spec/rake/yardoc_task_spec.rb +28 -19
  63. data/spec/registry_spec.rb +34 -0
  64. data/spec/registry_store_spec.rb +10 -0
  65. data/spec/rubygems/doc_manager_spec.rb +1 -1
  66. data/spec/server/commands/static_file_command_spec.rb +3 -3
  67. data/spec/spec_helper.rb +22 -3
  68. data/spec/templates/helpers/html_helper_spec.rb +10 -8
  69. data/templates/default/fulldoc/html/frames.erb +1 -1
  70. data/templates/default/fulldoc/html/setup.rb +1 -1
  71. data/yard.gemspec +24 -0
  72. metadata +7 -5
@@ -28,7 +28,7 @@ describe YARD::CLI::Stats do
28
28
  @stats = CLI::Stats.new(false)
29
29
  @stats.stub!(:support_rdoc_document_file!).and_return([])
30
30
  @stats.stub!(:yardopts).and_return([])
31
- @stats.stub!(:puts) {|*args| @output << args.join("\n") << "\n" }
31
+ log.stub!(:puts) {|*args| @output << args.join("\n") << "\n" }
32
32
  end
33
33
 
34
34
  it "should list undocumented objects with --list-undoc" do
@@ -77,6 +77,10 @@ describe YARD::CLI::Yardoc do
77
77
  it "should not embed mixins by default" do
78
78
  @yardoc.options.embed_mixins.should be_empty
79
79
  end
80
+
81
+ it "should not set any locale by default" do
82
+ @yardoc.options.locale.should be_nil
83
+ end
80
84
  end
81
85
 
82
86
  describe 'General options' do
@@ -303,6 +307,32 @@ describe YARD::CLI::Yardoc do
303
307
  end
304
308
  end
305
309
  end
310
+
311
+ describe '--locale' do
312
+ it 'should apply specified locale to all extra file objects' do
313
+ File.stub!(:read).with('extra_file1').and_return('')
314
+ File.stub!(:read).with('extra_file2').and_return('')
315
+
316
+ extra_file_object1 = CodeObjects::ExtraFileObject.new('extra_file1')
317
+ extra_file_object2 = CodeObjects::ExtraFileObject.new('extra_file2')
318
+ extra_file_object1.should_receive(:locale=).with('fr')
319
+ extra_file_object2.should_receive(:locale=).with('fr')
320
+
321
+ CodeObjects::ExtraFileObject.stub!(:new).with('extra_file1').and_return(extra_file_object1)
322
+ CodeObjects::ExtraFileObject.stub!(:new).with('extra_file2').and_return(extra_file_object2)
323
+ Dir.stub!(:glob).with('README*').and_return([])
324
+ File.stub!(:file?).with('extra_file1').and_return(true)
325
+ File.stub!(:file?).with('extra_file2').and_return(true)
326
+ @yardoc.run('--locale=fr', '-', 'extra_file1', 'extra_file2')
327
+ end
328
+ end
329
+
330
+ describe '--po-dir' do
331
+ it 'should set Registry.po_dir' do
332
+ Registry.should_receive(:po_dir=).with("locale")
333
+ @yardoc.run('--po-dir=locale')
334
+ end
335
+ end
306
336
  end
307
337
 
308
338
  describe '--[no-]api' do
@@ -651,6 +681,12 @@ describe YARD::CLI::Yardoc do
651
681
  @yardoc.parse_arguments('--transitive-tag', 'foo')
652
682
  Tags::Library.transitive_tags.should include(:foo)
653
683
  end
684
+
685
+ it "should accept --non-transitive-tag" do
686
+ Tags::Library.transitive_tags |= [:foo]
687
+ @yardoc.parse_arguments('--non-transitive-tag', 'foo')
688
+ Tags::Library.transitive_tags.should_not include(:foo)
689
+ end
654
690
  end
655
691
 
656
692
  describe 'Safe mode' do
@@ -28,6 +28,21 @@ describe YARD::CodeObjects::Base do
28
28
  YARD::Registry.at("MYMODULE").should be_instance_of(ClassObject)
29
29
  end
30
30
 
31
+ it "should simplify complex namespace paths" do
32
+ obj = ClassObject.new(:root, "A::B::C::D")
33
+ obj.name.should == :D
34
+ obj.path.should == "A::B::C::D"
35
+ obj.namespace.should == P("A::B::C")
36
+ end
37
+
38
+ # @bug gh-552
39
+ it "should simplify complex namespace paths when path starts with ::" do
40
+ obj = ClassObject.new(:root, "::A::B::C::D")
41
+ obj.name.should == :D
42
+ obj.path.should == "A::B::C::D"
43
+ obj.namespace.should == P("A::B::C")
44
+ end
45
+
31
46
  it "should recall the block if #new is called on an existing object" do
32
47
  o1 = ClassObject.new(:root, :Me) do |o|
33
48
  o.docstring = "DOCSTRING"
@@ -75,7 +75,7 @@ end
75
75
  describe YARD::CodeObjects, "BUILTIN_MODULES" do
76
76
  it "should include all base modules" do
77
77
  YARD::CodeObjects::BUILTIN_MODULES.each do |name|
78
- next if RUBY19 && ["Precision"].include?(name)
78
+ next if YARD.ruby19? && ["Precision"].include?(name)
79
79
  eval(name).should be_instance_of(Module)
80
80
  end
81
81
  end
@@ -71,7 +71,7 @@ describe YARD::CodeObjects::ExtraFileObject do
71
71
  data.force_encoding('binary')
72
72
  file = ExtraFileObject.new('file.txt', data)
73
73
  ['Shift_JIS', 'Windows-31J'].should include(file.contents.encoding.to_s)
74
- end if RUBY19
74
+ end if YARD.ruby19?
75
75
 
76
76
  it "should warn if @encoding is invalid" do
77
77
  log.should_receive(:warn).with("Invalid encoding `INVALID' in file.txt")
@@ -79,12 +79,12 @@ describe YARD::CodeObjects::ExtraFileObject do
79
79
  encoding = data.encoding
80
80
  file = ExtraFileObject.new('file.txt', data)
81
81
  file.contents.encoding.should == encoding
82
- end if RUBY19
82
+ end if YARD.ruby19?
83
83
 
84
84
  it "should ignore encoding in 1.8.x (or encoding-unaware platforms)" do
85
85
  log.should_not_receive(:warn)
86
86
  file = ExtraFileObject.new('file.txt', "# @encoding INVALID\nFOO")
87
- end if RUBY18
87
+ end if YARD.ruby18?
88
88
 
89
89
  it "should attempt to re-parse data as 8bit ascii if parsing fails" do
90
90
  log.should_not_receive(:warn)
@@ -114,6 +114,18 @@ describe YARD::CodeObjects::ExtraFileObject do
114
114
  end
115
115
  end
116
116
 
117
+ describe '#locale=' do
118
+ it "should translate contents" do
119
+ file = ExtraFileObject.new('file.txt', 'Hello')
120
+ file.locale = 'fr'
121
+ fr_locale = I18n::Locale.new('fr')
122
+ fr_messages = fr_locale.instance_variable_get(:@messages)
123
+ fr_messages["Hello"] = 'Bonjour'
124
+ Registry.should_receive(:locale).with('fr').and_return(fr_locale)
125
+ file.contents.should == 'Bonjour'
126
+ end
127
+ end
128
+
117
129
  describe '#==' do
118
130
  it "should define equality on filename alone" do
119
131
  file1 = ExtraFileObject.new('file.txt', 'A')
@@ -1,6 +1,10 @@
1
1
  require File.dirname(__FILE__) + "/spec_helper"
2
2
 
3
3
  describe YARD::DocstringParser do
4
+ after(:all) do
5
+ YARD::Registry.clear
6
+ end
7
+
4
8
  def parse(content, object = nil, handler = nil)
5
9
  @library ||= Tags::Library.instance
6
10
  @parser = DocstringParser.new(@library)
@@ -83,6 +83,12 @@ describe YARD::Docstring do
83
83
  doc.summary.should == "Returns a list of tags specified by +name+ or all tags if +name+ is not specified."
84
84
  end
85
85
 
86
+ it "should not attach period if entire summary is include" do
87
+ YARD.parse_string "# docstring\ndef foo; end"
88
+ Docstring.new("{include:#foo}").summary.should == '{include:#foo}'
89
+ Registry.clear
90
+ end
91
+
86
92
  it "should handle references embedded in summary" do
87
93
  Docstring.new("Aliasing {Test.test}. Done.").summary.should == "Aliasing {Test.test}."
88
94
  end
@@ -250,6 +256,18 @@ describe YARD::Docstring do
250
256
  doc = Docstring.new("123\n@param")
251
257
  doc.to_raw.should == doc.all
252
258
  end
259
+
260
+ # @bug gh-563
261
+ it "should handle full @option tags" do
262
+ doc = Docstring.new("@option foo [String] bar (nil) baz")
263
+ doc.to_raw.should == "@option foo [String] bar (nil) baz"
264
+ end
265
+
266
+ # @bug gh-563
267
+ it "should handle simple @option tags" do
268
+ doc = Docstring.new("@option foo :key bar")
269
+ doc.to_raw.should == "@option foo :key bar"
270
+ end
253
271
  end
254
272
 
255
273
  describe '#dup' do
@@ -43,6 +43,29 @@ describe "YARD::Handlers::Ruby::#{LEGACY_PARSER ? "Legacy::" : ""}VisibilityHand
43
43
  assert_module_function('Foo', 'baz')
44
44
  end
45
45
 
46
+ # @bug gh-563
47
+ it "should copy tags to module function properly" do
48
+ YARD.parse_string <<-eof
49
+ module Foo
50
+ # @param [String] foo bar
51
+ # @option foo [String] bar (nil) baz
52
+ # @return [void]
53
+ def bar(foo); end
54
+ module_function :bar
55
+ end
56
+ eof
57
+ assert_module_function('Foo', 'bar')
58
+ o = Registry.at('Foo.bar')
59
+ o.tag(:param).types.should == ['String']
60
+ o.tag(:param).name.should == 'foo'
61
+ o.tag(:param).text.should == 'bar'
62
+ o.tag(:option).name.should == 'foo'
63
+ o.tag(:option).pair.types.should == ['String']
64
+ o.tag(:option).pair.defaults.should == ['nil']
65
+ o.tag(:option).pair.text.should == 'baz'
66
+ o.tag(:return).types.should == ['void']
67
+ end
68
+
46
69
  it "should handle all method names in parameters" do
47
70
  YARD.parse_string <<-eof
48
71
  module Foo
@@ -21,7 +21,13 @@ describe YARD::I18n::Locale do
21
21
  @locale.load('foo').should == false
22
22
  end
23
23
 
24
- it "should return true for existent PO" do
24
+ have_gettext_gem = true
25
+ begin
26
+ require "gettext/tools/poparser"
27
+ rescue LoadError
28
+ have_gettext_gem = false
29
+ end
30
+ it "should return true for existent PO", :if => have_gettext_gem do
25
31
  data = <<-eop
26
32
  msgid ""
27
33
  msgstr ""
@@ -87,6 +87,32 @@ describe YARD::Parser::Ruby::RubyParser do
87
87
  ss[2].comments.should == 'hello'
88
88
  end
89
89
 
90
+ it "should handle block comment followed by line comment" do
91
+ ss = stmts <<-eof
92
+ # comments1
93
+
94
+ =begin
95
+ comments2
96
+ =end
97
+ # comments3
98
+ def hello; end
99
+ eof
100
+ ss.last.comments.should == "comments3"
101
+ end
102
+
103
+ it "should handle block comment followed by block comment" do
104
+ ss = stmts <<-eof
105
+ =begin
106
+ comments1
107
+ =end
108
+ =begin
109
+ comments2
110
+ =end
111
+ def hello; end
112
+ eof
113
+ ss.last.comments.strip.should == "comments2"
114
+ end
115
+
90
116
  it "should handle 1.9 lambda syntax with args" do
91
117
  src = "->(a,b,c=1,*args,&block) { hello_world }"
92
118
  stmt(src).source.should == src
@@ -546,7 +546,7 @@ describe YARD::Parser::SourceParser do
546
546
  parser = Parser::SourceParser.new
547
547
  File.should_receive(:read_binary).with('tmpfile').and_return(src)
548
548
  result = parser.parse("tmpfile")
549
- if HAVE_RIPPER && RUBY19
549
+ if HAVE_RIPPER && YARD.ruby19?
550
550
  ['Shift_JIS', 'Windows-31J', 'UTF-8'].send(msg, include(
551
551
  result.enumerator[0].source.encoding.to_s))
552
552
  end
@@ -572,7 +572,7 @@ describe YARD::Parser::SourceParser do
572
572
  ['UTF-8'].send(msg, include(content.encoding.to_s))
573
573
  end
574
574
  end
575
- end if RUBY19
575
+ end if YARD.ruby19?
576
576
 
577
577
  Parser::SourceParser::ENCODING_BYTE_ORDER_MARKS.each do |encoding, bom|
578
578
  it "should understand #{encoding.upcase} BOM" do
@@ -584,7 +584,7 @@ describe YARD::Parser::SourceParser do
584
584
  Registry.all(:class).first.path.should == "FooBar"
585
585
  result.enumerator[0].source.encoding.to_s.downcase.should == encoding
586
586
  end
587
- end if HAVE_RIPPER && RUBY19
587
+ end if HAVE_RIPPER && YARD.ruby19?
588
588
  end
589
589
 
590
590
  describe '#parse_in_order' do
@@ -606,12 +606,24 @@ describe YARD::Parser::SourceParser do
606
606
  end
607
607
  end
608
608
 
609
- it "should attempt to order files by length (process toplevel files first)" do
610
- %w(a a/b a/b/c).each do |file|
609
+ it "should attempt to order files by length for globs (process toplevel files first)" do
610
+ files = %w(a a/b a/b/c)
611
+ files.each do |file|
611
612
  File.should_receive(:file?).with(file).and_return(true)
612
613
  File.should_receive(:read_binary).with(file).ordered.and_return('')
613
614
  end
614
- YARD.parse %w(a/b/c a/b a)
615
+ Dir.should_receive(:[]).with('a/**/*').and_return(files.reverse)
616
+ YARD.parse 'a/**/*'
617
+ end
618
+
619
+ it "should allow overriding of length sorting when single file is presented" do
620
+ files = %w(a/b/c a a/b)
621
+ files.each do |file|
622
+ File.should_receive(:file?).with(file).at_least(1).times.and_return(true)
623
+ File.should_receive(:read_binary).with(file).ordered.and_return('')
624
+ end
625
+ Dir.should_receive(:[]).with('a/**/*').and_return(files.reverse)
626
+ YARD.parse ['a/b/c', 'a/**/*']
615
627
  end
616
628
  end
617
629
 
@@ -45,6 +45,15 @@ describe YARD::Rake::YardocTask do
45
45
  run
46
46
  @yardoc.visibilities.should == [:public, :private, :protected]
47
47
  end
48
+
49
+ it "should allow --api and --no-api" do
50
+ YARD::Rake::YardocTask.new do |t|
51
+ t.options = %w(--api public --no-api)
52
+ end
53
+ run
54
+ @yardoc.options.verifier.expressions.
55
+ should include('["public"].include?(@api.text) || !@api')
56
+ end
48
57
  end
49
58
 
50
59
  describe '#before' do
@@ -65,28 +74,28 @@ describe YARD::Rake::YardocTask do
65
74
  YARD::Rake::YardocTask.new {|t| t.after = proc }
66
75
  run
67
76
  end
77
+ end
68
78
 
69
- describe '#verifier' do
70
- it "should allow a verifier proc to be set" do
71
- verifier = Verifier.new
72
- @yardoc.should_receive(:run) do
73
- @yardoc.options[:verifier].should == verifier
74
- end
75
- YARD::Rake::YardocTask.new {|t| t.verifier = verifier }
76
- run
79
+ describe '#verifier' do
80
+ it "should allow a verifier proc to be set" do
81
+ verifier = Verifier.new
82
+ @yardoc.should_receive(:run) do
83
+ @yardoc.options[:verifier].should == verifier
77
84
  end
85
+ YARD::Rake::YardocTask.new {|t| t.verifier = verifier }
86
+ run
87
+ end
78
88
 
79
- it "should override --query options" do
80
- verifier = Verifier.new
81
- @yardoc.should_receive(:run) do
82
- @yardoc.options[:verifier].should == verifier
83
- end
84
- YARD::Rake::YardocTask.new do |t|
85
- t.options += ['--query', '@return']
86
- t.verifier = verifier
87
- end
88
- run
89
+ it "should override --query options" do
90
+ verifier = Verifier.new
91
+ @yardoc.should_receive(:run) do
92
+ @yardoc.options[:verifier].should == verifier
89
93
  end
94
+ YARD::Rake::YardocTask.new do |t|
95
+ t.options += ['--query', '@return']
96
+ t.verifier = verifier
97
+ end
98
+ run
90
99
  end
91
100
  end
92
- end
101
+ end
@@ -81,6 +81,15 @@ describe YARD::Registry do
81
81
  end
82
82
  end
83
83
 
84
+ describe '.locale' do
85
+ it "should load locale object" do
86
+ fr_locale = I18n::Locale.new("fr")
87
+ store = Registry.send(:thread_local_store)
88
+ store.should_receive(:locale).with("fr").and_return(fr_locale)
89
+ Registry.locale("fr").should == fr_locale
90
+ end
91
+ end
92
+
84
93
  describe '.resolve' do
85
94
  it "should resolve any existing namespace" do
86
95
  o1 = ModuleObject.new(:root, :A)
@@ -355,5 +364,30 @@ describe YARD::Registry do
355
364
  it "should automatically clear in new threads" do
356
365
  Thread.new { Registry.all.should be_empty }.join
357
366
  end
367
+
368
+ it "should allow setting of po_dir in separate threads" do
369
+ barrier = 0
370
+ mutex = Mutex.new
371
+ threads = []
372
+ threads << Thread.new do
373
+ Registry.po_dir.should == 'po'
374
+ Registry.po_dir = 'locale'
375
+ mutex.synchronize { barrier += 1 }
376
+ while barrier == 1 do
377
+ s = "barrier = 1, spinning"
378
+ end
379
+ Registry.po_dir.should == 'locale'
380
+ end
381
+ threads << Thread.new do
382
+ while barrier == 0 do
383
+ s = "barrier = 0, spinning"
384
+ end
385
+ Registry.po_dir.should == 'po'
386
+ mutex.synchronize { barrier += 1 }
387
+ Registry.po_dir = '.'
388
+ end
389
+ threads.each {|t| t.join }
390
+ Registry.po_dir = Registry::DEFAULT_PO_DIR
391
+ end
358
392
  end
359
393
  end
@@ -302,4 +302,14 @@ describe YARD::RegistryStore do
302
302
  @store.destroy(true).should == true
303
303
  end
304
304
  end
305
+
306
+ describe '#locale' do
307
+ it "should load ./po/LOCALE_NAME.po" do
308
+ fr_locale = I18n::Locale.new("fr")
309
+ I18n::Locale.should_receive(:new).with("fr").and_return(fr_locale)
310
+ Registry.should_receive(:po_dir).and_return("po")
311
+ fr_locale.should_receive(:load).with("po")
312
+ @store.locale("fr").should == fr_locale
313
+ end
314
+ end
305
315
  end