yard 0.8.1 → 0.8.2

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 (65) hide show
  1. data/ChangeLog +192 -0
  2. data/README.md +9 -2
  3. data/Rakefile +8 -14
  4. data/lib/yard.rb +1 -1
  5. data/lib/yard/autoload.rb +3 -2
  6. data/lib/yard/cli/graph.rb +28 -10
  7. data/lib/yard/cli/yardoc.rb +4 -1
  8. data/lib/yard/code_objects/proxy.rb +22 -17
  9. data/lib/yard/docstring_parser.rb +7 -7
  10. data/lib/yard/globals.rb +2 -2
  11. data/lib/yard/handlers/base.rb +3 -2
  12. data/lib/yard/handlers/c/handler_methods.rb +1 -0
  13. data/lib/yard/handlers/c/init_handler.rb +7 -5
  14. data/lib/yard/handlers/c/override_comment_handler.rb +9 -1
  15. data/lib/yard/handlers/ruby/class_condition_handler.rb +4 -2
  16. data/lib/yard/handlers/ruby/legacy/class_condition_handler.rb +4 -2
  17. data/lib/yard/handlers/ruby/legacy/mixin_handler.rb +4 -6
  18. data/lib/yard/handlers/ruby/mixin_handler.rb +3 -3
  19. data/lib/yard/handlers/ruby/visibility_handler.rb +1 -1
  20. data/lib/yard/i18n/locale.rb +50 -0
  21. data/lib/yard/i18n/text.rb +110 -9
  22. data/lib/yard/logging.rb +99 -8
  23. data/lib/yard/parser/c/c_parser.rb +1 -1
  24. data/lib/yard/parser/source_parser.rb +5 -4
  25. data/lib/yard/registry.rb +20 -12
  26. data/lib/yard/registry_store.rb +6 -1
  27. data/lib/yard/rubygems/doc_manager.rb +9 -5
  28. data/lib/yard/serializers/yardoc_serializer.rb +1 -0
  29. data/lib/yard/server/commands/base.rb +3 -2
  30. data/lib/yard/server/doc_server_serializer.rb +2 -0
  31. data/lib/yard/server/templates/default/method_details/html/permalink.erb +4 -0
  32. data/lib/yard/server/templates/default/method_details/html/setup.rb +4 -0
  33. data/lib/yard/tags/default_factory.rb +12 -4
  34. data/lib/yard/tags/directives.rb +1 -0
  35. data/lib/yard/templates/engine.rb +13 -6
  36. data/lib/yard/templates/template_options.rb +8 -1
  37. data/spec/cli/graph_spec.rb +10 -0
  38. data/spec/cli/yri_spec.rb +12 -2
  39. data/spec/code_objects/proxy_spec.rb +19 -3
  40. data/spec/handlers/c/class_handler_spec.rb +1 -2
  41. data/spec/handlers/c/init_handler_spec.rb +11 -0
  42. data/spec/handlers/c/override_comment_handler_spec.rb +3 -0
  43. data/spec/handlers/class_condition_handler_spec.rb +5 -0
  44. data/spec/handlers/dsl_handler_spec.rb +1 -0
  45. data/spec/handlers/examples/class_condition_handler_001.rb.txt +8 -0
  46. data/spec/handlers/mixin_handler_spec.rb +2 -1
  47. data/spec/i18n/locale_spec.rb +62 -0
  48. data/spec/i18n/text_spec.rb +144 -35
  49. data/spec/logging_spec.rb +21 -0
  50. data/spec/parser/c_parser_spec.rb +36 -0
  51. data/spec/parser/source_parser_spec.rb +11 -8
  52. data/spec/registry_spec.rb +26 -0
  53. data/spec/rubygems/doc_manager_spec.rb +112 -0
  54. data/spec/tags/default_factory_spec.rb +8 -2
  55. data/spec/tags/directives_spec.rb +7 -0
  56. data/spec/templates/examples/module001.html +0 -4
  57. data/spec/templates/examples/module002.html +0 -1
  58. data/spec/templates/examples/module003.html +0 -1
  59. data/spec/templates/examples/module004.html +171 -172
  60. data/spec/templates/module_spec.rb +4 -0
  61. data/templates/default/fulldoc/html/js/app.js +24 -18
  62. data/templates/default/fulldoc/html/setup.rb +5 -1
  63. data/templates/default/module/html/attribute_details.erb +1 -2
  64. metadata +9 -4
  65. data/lib/yard/server/templates/default/fulldoc/html/js/live.js +0 -17
@@ -4,6 +4,7 @@ describe YARD::Handlers::C::OverrideCommentHandler do
4
4
  [:class, :module].each do |type|
5
5
  it "should handle Document-#{type}" do
6
6
  parse(<<-eof)
7
+ void something;
7
8
  /* Document-#{type}: A
8
9
  * Foo bar baz
9
10
  */
@@ -11,6 +12,8 @@ describe YARD::Handlers::C::OverrideCommentHandler do
11
12
  eof
12
13
  Registry.at('A').type.should == type
13
14
  Registry.at('A').docstring.should == 'Foo bar baz'
15
+ Registry.at('A').file.should == '(stdin)'
16
+ Registry.at('A').line.should == 2
14
17
  end
15
18
  end
16
19
 
@@ -48,6 +48,11 @@ describe "YARD::Handlers::Ruby::#{LEGACY_PARSER ? "Legacy::" : ""}ClassCondition
48
48
  verify_method :n
49
49
  end
50
50
 
51
+ it "should maintain visibility and scope state inside condition" do
52
+ Registry.at('A#m').visibility.should == :private
53
+ Registry.at('A#mnot').visibility.should == :private
54
+ end
55
+
51
56
  it "should not fail on complex conditions" do
52
57
  log.should_not_receive(:warn)
53
58
  log.should_not_receive(:error)
@@ -61,6 +61,7 @@ describe "YARD::Handlers::Ruby::#{LEGACY_PARSER ? "Legacy::" : ""}DSLHandler" do
61
61
  obj = Registry.at('Foo.xyz')
62
62
  obj.should_not be_nil
63
63
  obj.signature.should == 'def xyz(a, b, c)'
64
+ obj.parameters.should == [[:a, nil], [:b, nil], [:c, nil]]
64
65
  obj.source.should == 'foo_bar'
65
66
  obj.docstring.should == 'The foo method'
66
67
  end
@@ -58,4 +58,12 @@ class A
58
58
  else
59
59
  def q; end
60
60
  end
61
+
62
+ private
63
+
64
+ if a == 1
65
+ def m; end
66
+ else
67
+ def mnot; end
68
+ end
61
69
  end
@@ -17,7 +17,8 @@ describe "YARD::Handlers::Ruby::#{LEGACY_PARSER ? "Legacy::" : ""}MixinHandler"
17
17
  end
18
18
 
19
19
  it "should set the type of non-existing modules to :module" do
20
- P(:NOTEXIST).type.should == :module
20
+ o = Registry.at(:X).instance_mixins.find {|o| o.name == :NOTEXIST }
21
+ o.type.should == :module
21
22
  end
22
23
 
23
24
  it "should handle includes with multiple parameters" do
@@ -0,0 +1,62 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper'
2
+
3
+ describe YARD::I18n::Locale do
4
+ def locale(name)
5
+ YARD::I18n::Locale.new(name)
6
+ end
7
+
8
+ before do
9
+ @locale = locale("fr")
10
+ end
11
+
12
+ describe "#name" do
13
+ it "should return name" do
14
+ locale("fr").name.should == "fr"
15
+ end
16
+ end
17
+
18
+ describe "#load" do
19
+ it "should return false for nonexistent PO" do
20
+ File.should_receive(:exist?).with('foo/fr.po').and_return(false)
21
+ @locale.load('foo').should == false
22
+ end
23
+
24
+ it "should return true for existent PO" do
25
+ data = <<-eop
26
+ msgid ""
27
+ msgstr ""
28
+ "Language: fr\n"
29
+ "MIME-Version: 1.0\n"
30
+ "Content-Type: text/plain; charset=UTF-8\n"
31
+ "Content-Transfer-Encoding: 8bit\n"
32
+
33
+ msgid "Hello"
34
+ msgstr "Bonjour"
35
+ eop
36
+ parser = GetText::PoParser.new
37
+ File.should_receive(:exist?).with('foo/fr.po').and_return(true)
38
+ GetText::PoParser.should_receive(:new).and_return(parser)
39
+ parser.should_receive(:parse_file) do |file, hash|
40
+ file.should == 'foo/fr.po'
41
+ parser.parse(data, hash)
42
+ end
43
+ @locale.load('foo').should == true
44
+ @locale.translate('Hello').should == "Bonjour"
45
+ end
46
+ end
47
+
48
+ describe "#translate" do
49
+ before do
50
+ messages = @locale.instance_variable_get(:@messages)
51
+ messages["Hello"] = "Bonjour"
52
+ end
53
+
54
+ it "should return translated string for existent string" do
55
+ @locale.translate("Hello") == "Bonjour"
56
+ end
57
+
58
+ it "should return original string for nonexistent string" do
59
+ @locale.translate("nonexistent") == "nonexistent"
60
+ end
61
+ end
62
+ end
@@ -1,71 +1,180 @@
1
1
  require File.dirname(__FILE__) + '/../spec_helper'
2
2
 
3
3
  describe YARD::I18n::Text do
4
- def extract_messages(input, options={})
5
- text = YARD::I18n::Text.new(StringIO.new(input), options)
6
- messages = []
7
- text.extract_messages do |*message|
8
- messages << message
4
+ describe "#extract_messages" do
5
+ def extract_messages(input, options={})
6
+ text = YARD::I18n::Text.new(StringIO.new(input), options)
7
+ messages = []
8
+ text.extract_messages do |*message|
9
+ messages << message
10
+ end
11
+ messages
9
12
  end
10
- messages
11
- end
12
13
 
13
- describe "Header" do
14
- it "should extract attribute" do
15
- text = <<-eot
14
+ describe "Header" do
15
+ it "should extract attribute" do
16
+ text = <<-eot
16
17
  # @title Getting Started Guide
17
18
 
18
19
  # Getting Started with YARD
19
20
  eot
20
- extract_messages(text, :have_header => true).should ==
21
- [[:attribute, "title", "Getting Started Guide", 1],
22
- [:paragraph, "# Getting Started with YARD", 3]]
23
- end
21
+ extract_messages(text, :have_header => true).should ==
22
+ [[:attribute, "title", "Getting Started Guide", 1],
23
+ [:paragraph, "# Getting Started with YARD", 3]]
24
+ end
24
25
 
25
- it "should ignore markup line" do
26
- text = <<-eot
26
+ it "should ignore markup line" do
27
+ text = <<-eot
27
28
  #!markdown
28
29
  # @title Getting Started Guide
29
30
 
30
31
  # Getting Started with YARD
31
32
  eot
32
- extract_messages(text, :have_header => true).should ==
33
- [[:attribute, "title", "Getting Started Guide", 2],
34
- [:paragraph, "# Getting Started with YARD", 4]]
35
- end
33
+ extract_messages(text, :have_header => true).should ==
34
+ [[:attribute, "title", "Getting Started Guide", 2],
35
+ [:paragraph, "# Getting Started with YARD", 4]]
36
+ end
36
37
 
37
- it "should terminate header block by markup line not at the first line" do
38
- text = <<-eot
38
+ it "should terminate header block by markup line not at the first line" do
39
+ text = <<-eot
39
40
  # @title Getting Started Guide
40
41
  #!markdown
41
42
 
42
43
  # Getting Started with YARD
43
44
  eot
44
- extract_messages(text, :have_header => true).should ==
45
- [[:attribute, "title", "Getting Started Guide", 1],
46
- [:paragraph, "#!markdown", 2],
47
- [:paragraph, "# Getting Started with YARD", 4]]
45
+ extract_messages(text, :have_header => true).should ==
46
+ [[:attribute, "title", "Getting Started Guide", 1],
47
+ [:paragraph, "#!markdown", 2],
48
+ [:paragraph, "# Getting Started with YARD", 4]]
49
+ end
48
50
  end
49
- end
50
51
 
51
- describe "Body" do
52
- it "should split to paragraphs" do
53
- paragraph1 = <<-eop.strip
52
+ describe "Body" do
53
+ it "should split to paragraphs" do
54
+ paragraph1 = <<-eop.strip
54
55
  Note that class methods must not be referred to with the "::" namespace
55
56
  separator. Only modules, classes and constants should use "::".
56
57
  eop
57
- paragraph2 = <<-eop.strip
58
+ paragraph2 = <<-eop.strip
58
59
  You can also do lookups on any installed gems. Just make sure to build the
59
60
  .yardoc databases for installed gems with:
60
61
  eop
61
- text = <<-eot
62
+ text = <<-eot
62
63
  #{paragraph1}
63
64
 
64
65
  #{paragraph2}
65
66
  eot
66
- extract_messages(text).should ==
67
- [[:paragraph, paragraph1, 1],
68
- [:paragraph, paragraph2, 4]]
67
+ extract_messages(text).should ==
68
+ [[:paragraph, paragraph1, 1],
69
+ [:paragraph, paragraph2, 4]]
70
+ end
71
+ end
72
+ end
73
+
74
+ describe "#translate" do
75
+ def locale
76
+ locale = YARD::I18n::Locale.new("fr")
77
+ messages = locale.instance_variable_get(:@messages)
78
+ messages["markdown"] = "markdown (markdown in fr)"
79
+ messages["Hello"] = "Bonjour (Hello in fr)"
80
+ messages["Paragraph 1."] = "Paragraphe 1."
81
+ messages["Paragraph 2."] = "Paragraphe 2."
82
+ locale
83
+ end
84
+
85
+ def translate(input, options={})
86
+ text = YARD::I18n::Text.new(StringIO.new(input), options)
87
+ text.translate(locale)
88
+ end
89
+
90
+ describe "Header" do
91
+ it "should extract attribute" do
92
+ text = <<-eot
93
+ # @title Hello
94
+
95
+ # Getting Started with YARD
96
+
97
+ Paragraph.
98
+ eot
99
+ translate(text, :have_header => true).should == <<-eot
100
+ # @title Bonjour (Hello in fr)
101
+
102
+ # Getting Started with YARD
103
+
104
+ Paragraph.
105
+ eot
106
+ end
107
+
108
+ it "should ignore markup line" do
109
+ text = <<-eot
110
+ #!markdown
111
+ # @title Hello
112
+
113
+ # Getting Started with YARD
114
+
115
+ Paragraph.
116
+ eot
117
+ translate(text, :have_header => true).should == <<-eot
118
+ #!markdown
119
+ # @title Bonjour (Hello in fr)
120
+
121
+ # Getting Started with YARD
122
+
123
+ Paragraph.
124
+ eot
125
+ end
126
+ end
127
+
128
+ describe "Body" do
129
+ it "should split to paragraphs" do
130
+ paragraph1 = <<-eop.strip
131
+ Paragraph 1.
132
+ eop
133
+ paragraph2 = <<-eop.strip
134
+ Paragraph 2.
135
+ eop
136
+ text = <<-eot
137
+ #{paragraph1}
138
+
139
+ #{paragraph2}
140
+ eot
141
+ translate(text).should == <<-eot
142
+ Paragraphe 1.
143
+
144
+ Paragraphe 2.
145
+ eot
146
+ end
147
+
148
+ it "should not modified non-translated message" do
149
+ nonexistent_paragraph = <<-eop.strip
150
+ Nonexsitent paragraph.
151
+ eop
152
+ text = <<-eot
153
+ #{nonexistent_paragraph}
154
+ eot
155
+ translate(text).should == <<-eot
156
+ #{nonexistent_paragraph}
157
+ eot
158
+ end
159
+
160
+ it "should keep empty lines" do
161
+ text = <<-eot
162
+ Paragraph 1.
163
+
164
+
165
+
166
+
167
+ Paragraph 2.
168
+ eot
169
+ translate(text).should == <<-eot
170
+ Paragraphe 1.
171
+
172
+
173
+
174
+
175
+ Paragraphe 2.
176
+ eot
177
+ end
69
178
  end
70
179
  end
71
180
  end
@@ -11,4 +11,25 @@ describe YARD::Logger do
11
11
  log.show_backtraces.should == false
12
12
  end
13
13
  end
14
+
15
+ describe '#backtrace' do
16
+ before { log.show_backtraces = true }
17
+ after { log.show_backtraces = false }
18
+
19
+ it "should log backtrace in error by default" do
20
+ log.should_receive(:error).with("RuntimeError: foo")
21
+ log.should_receive(:error).with("Stack trace:\n\tline1\n\tline2\n")
22
+ exc = RuntimeError.new("foo")
23
+ exc.set_backtrace(['line1', 'line2'])
24
+ log.enter_level(Logger::INFO) { log.backtrace(exc) }
25
+ end
26
+
27
+ it "should allow backtrace to be entered in other modes" do
28
+ log.should_receive(:warn).with("RuntimeError: foo")
29
+ log.should_receive(:warn).with("Stack trace:\n\tline1\n\tline2\n")
30
+ exc = RuntimeError.new("foo")
31
+ exc.set_backtrace(['line1', 'line2'])
32
+ log.enter_level(Logger::INFO) { log.backtrace(exc, :warn) }
33
+ end
34
+ end
14
35
  end
@@ -85,6 +85,42 @@ describe YARD::Parser::C::CParser do
85
85
  constant.docstring.should == "This constant is frequently used to indicate a\nsoftware crash or deadlock in embedded systems."
86
86
  end
87
87
  end
88
+
89
+ describe 'Macros' do
90
+ it "should handle param## inside of macros" do
91
+ thr = Thread.new do
92
+ parse <<-eof
93
+ void
94
+ Init_gobject_gparamspecs(void)
95
+ {
96
+ VALUE cParamSpec = GTYPE2CLASS(G_TYPE_PARAM);
97
+ VALUE c;
98
+
99
+ #define DEF_NUMERIC_PSPEC_METHODS(c, typename) \
100
+ G_STMT_START {\
101
+ rbg_define_method(c, "initialize", typename##_initialize, 7); \
102
+ rbg_define_method(c, "minimum", typename##_minimum, 0); \
103
+ rbg_define_method(c, "maximum", typename##_maximum, 0); \
104
+ rbg_define_method(c, "range", typename##_range, 0); \
105
+ } G_STMT_END
106
+
107
+ #if 0
108
+ rbg_define_method(c, "default_value", typename##_default_value, 0); \
109
+ rb_define_alias(c, "default", "default_value"); \
110
+
111
+ #endif
112
+
113
+ c = G_DEF_CLASS(G_TYPE_PARAM_CHAR, "Char", cParamSpec);
114
+ DEF_NUMERIC_PSPEC_METHODS(c, char);
115
+ eof
116
+ end
117
+ thr.join(5)
118
+ if thr.alive?
119
+ fail "Did not parse in time"
120
+ thr.kill
121
+ end
122
+ end
123
+ end
88
124
  end
89
125
 
90
126
  describe 'Override comments' do
@@ -465,7 +465,7 @@ describe YARD::Parser::SourceParser do
465
465
  end
466
466
 
467
467
  it "should parse a set of absolute paths" do
468
- Dir.should_not_receive(:[]).and_return([])
468
+ Dir.should_not_receive(:[])
469
469
  File.should_receive(:file?).with('/path/to/file').and_return(true)
470
470
  File.should_receive(:read_binary).with('/path/to/file').and_return("")
471
471
  YARD.parse('/path/to/file')
@@ -594,13 +594,16 @@ describe YARD::Parser::SourceParser do
594
594
  end
595
595
 
596
596
  it "should attempt to parse files in order" do
597
- msgs = []
598
- log.should_receive(:debug) {|m| msgs << m }.at_least(:once)
599
- in_order_parse 'parse_in_order_001', 'parse_in_order_002'
600
- msgs[1].should =~ /Processing .+parse_in_order_001.+/
601
- msgs[2].should =~ /Missing object MyModule/
602
- msgs[3].should =~ /Processing .+parse_in_order_002.+/
603
- msgs[4].should =~ /Re-processing .+parse_in_order_001.+/
597
+ log.enter_level(Logger::DEBUG) do
598
+ msgs = []
599
+ log.should_receive(:debug) {|m| msgs << m }.at_least(:once)
600
+ log.stub(:<<)
601
+ in_order_parse 'parse_in_order_001', 'parse_in_order_002'
602
+ msgs[1].should =~ /Parsing .+parse_in_order_001.+/
603
+ msgs[2].should =~ /Missing object MyModule/
604
+ msgs[3].should =~ /Parsing .+parse_in_order_002.+/
605
+ msgs[4].should =~ /Re-processing .+parse_in_order_001.+/
606
+ end
604
607
  end
605
608
 
606
609
  it "should attempt to order files by length (process toplevel files first)" do
@@ -169,6 +169,32 @@ describe YARD::Registry do
169
169
  Registry.resolve(P('MyObject'), '#foo', true).should be_nil
170
170
  end
171
171
 
172
+ it "should allow type=:typename to ensure resolved object is of a certain type" do
173
+ YARD.parse_string "class Foo; end"
174
+ Registry.resolve(Registry.root, 'Foo').should == Registry.at('Foo')
175
+ Registry.resolve(Registry.root, 'Foo', false, false, :method).should be_nil
176
+ end
177
+
178
+ it "should allow keep trying to find obj where type equals object type" do
179
+ YARD.parse_string <<-eof
180
+ module Foo
181
+ class Bar; end
182
+ def self.Bar; end
183
+ end
184
+ eof
185
+ Registry.resolve(P('Foo'), 'Bar').should == Registry.at('Foo::Bar')
186
+ Registry.resolve(P('Foo'), 'Bar', false, false, :method).should ==
187
+ Registry.at('Foo.Bar')
188
+ end
189
+
190
+ it "should return proxy fallback with given type if supplied" do
191
+ YARD.parse_string "module Foo; end"
192
+ proxy = Registry.resolve(P('Foo'), 'Bar', false, true, :method)
193
+ proxy.type.should == :method
194
+ proxy = Registry.resolve(P('Qux'), 'Bar', false, true, :method)
195
+ proxy.type.should == :method
196
+ end
197
+
172
198
  it "should only check 'Path' in lookup on root namespace" do
173
199
  Registry.should_receive(:at).once.with('Test').and_return(true)
174
200
  Registry.resolve(Registry.root, "Test")