yard 0.5.4 → 0.5.5

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 (59) hide show
  1. data/.yardopts +1 -0
  2. data/ChangeLog +181 -0
  3. data/LEGAL +74 -0
  4. data/LICENSE +1 -1
  5. data/README.md +15 -8
  6. data/lib/yard.rb +3 -3
  7. data/lib/yard/cli/yard_graph.rb +10 -10
  8. data/lib/yard/cli/yardoc.rb +29 -9
  9. data/lib/yard/code_objects/base.rb +1 -1
  10. data/lib/yard/code_objects/class_object.rb +1 -1
  11. data/lib/yard/code_objects/module_object.rb +1 -1
  12. data/lib/yard/code_objects/proxy.rb +1 -1
  13. data/lib/yard/docstring.rb +2 -2
  14. data/lib/yard/handlers/ruby/constant_handler.rb +2 -2
  15. data/lib/yard/handlers/ruby/legacy/class_condition_handler.rb +64 -1
  16. data/lib/yard/handlers/ruby/legacy/constant_handler.rb +2 -2
  17. data/lib/yard/handlers/ruby/legacy/method_handler.rb +11 -0
  18. data/lib/yard/handlers/ruby/method_handler.rb +11 -0
  19. data/lib/yard/parser/ruby/legacy/statement_list.rb +3 -3
  20. data/lib/yard/parser/source_parser.rb +2 -2
  21. data/lib/yard/tags/default_factory.rb +9 -6
  22. data/lib/yard/templates/helpers/base_helper.rb +14 -4
  23. data/lib/yard/templates/helpers/html_helper.rb +16 -22
  24. data/lib/yard/templates/helpers/method_helper.rb +1 -1
  25. data/lib/yard/templates/helpers/module_helper.rb +1 -2
  26. data/spec/cli/yardoc_spec.rb +1 -1
  27. data/spec/code_objects/class_object_spec.rb +1 -0
  28. data/spec/code_objects/module_object_spec.rb +1 -0
  29. data/spec/docstring_spec.rb +14 -0
  30. data/spec/handlers/class_condition_handler_spec.rb +8 -10
  31. data/spec/handlers/examples/method_handler_001.rb.txt +4 -0
  32. data/spec/handlers/method_handler_spec.rb +7 -0
  33. data/spec/parser/ruby/legacy/statement_list_spec.rb +14 -0
  34. data/spec/parser/source_parser_spec.rb +7 -0
  35. data/spec/tags/default_factory_spec.rb +1 -0
  36. data/spec/templates/examples/class001.html +5 -5
  37. data/spec/templates/examples/method001.html +1 -1
  38. data/spec/templates/examples/module001.html +4 -4
  39. data/spec/templates/helpers/base_helper_spec.rb +18 -1
  40. data/spec/templates/helpers/html_helper_spec.rb +2 -1
  41. data/spec/templates/module_spec.rb +5 -2
  42. data/templates/default/docstring/html/abstract.erb +2 -2
  43. data/templates/default/docstring/html/deprecated.erb +1 -1
  44. data/templates/default/docstring/html/note.erb +2 -2
  45. data/templates/default/docstring/html/private.erb +4 -0
  46. data/templates/default/docstring/html/todo.erb +2 -2
  47. data/templates/default/docstring/setup.rb +6 -1
  48. data/templates/default/docstring/text/private.erb +2 -0
  49. data/templates/default/fulldoc/html/css/style.css +7 -3
  50. data/templates/default/fulldoc/html/js/app.js +27 -0
  51. data/templates/default/fulldoc/html/setup.rb +1 -1
  52. data/templates/default/module/html/attribute_summary.erb +1 -1
  53. data/templates/default/module/html/box_info.erb +1 -1
  54. data/templates/default/module/html/header.erb +2 -1
  55. data/templates/default/module/html/item_summary.erb +1 -0
  56. data/templates/default/module/html/method_summary.erb +4 -1
  57. data/templates/default/module/text/extends.erb +2 -2
  58. data/templates/default/tags/html/see.erb +1 -1
  59. metadata +5 -2
@@ -74,4 +74,8 @@ end
74
74
 
75
75
  attr_reader :attr_name2
76
76
  def attr_name2=; end
77
+
78
+ # @option opts :bar [String] It's bar!
79
+ def auto_opts(opts)
80
+ end
77
81
  end
@@ -115,4 +115,11 @@ describe "YARD::Handlers::Ruby::#{RUBY18 ? "Legacy::" : ""}MethodHandler" do
115
115
  Registry.at('Foo#attr_name2').should be_reader
116
116
  Registry.at('Foo#attr_name2=').should be_writer
117
117
  end
118
+
119
+ it "should generate an options parameter if @option refers to an undocumented parameter" do
120
+ meth = P('Foo#auto_opts')
121
+ meth.should have_tag(:param)
122
+ meth.tag(:param).name.should == "opts"
123
+ meth.tag(:param).types.should == ["Hash"]
124
+ end
118
125
  end
@@ -256,4 +256,18 @@ eof
256
256
  s = stmts("require 'foo'\r\n\r\n# Test Test\r\n# \r\n# Example:\r\n# example code\r\ndef test\r\nend\r\n")
257
257
  s[1].comments.should == ['Test Test', '', 'Example:', ' example code']
258
258
  end
259
+
260
+ it "should handle elsif blocks" do
261
+ s = stmts(stmt("if 0\n foo\nelsif 2\n bar\nend\nbaz").block)
262
+ s.size.should == 2
263
+ s[1].tokens.to_s.should == "elsif 2"
264
+ s[1].block.to_s.should == "bar"
265
+ end
266
+
267
+ it "should handle else blocks" do
268
+ s = stmts(stmt("if 0\n foo\nelse\n bar\nend\nbaz").block)
269
+ s.size.should == 2
270
+ s[1].tokens.to_s.should == "else"
271
+ s[1].block.to_s.should == "bar"
272
+ end
259
273
  end
@@ -89,6 +89,13 @@ describe YARD::Parser::SourceParser do
89
89
  File.should_receive(:read_binary).with('/path/to/file').and_return("")
90
90
  YARD.parse('/path/to/file')
91
91
  end
92
+
93
+ it "should clean paths before parsing" do
94
+ File.should_receive(:open).and_return("")
95
+ parser = Parser::SourceParser.new(:ruby, true)
96
+ parser.parse('a//b//c')
97
+ parser.file.should == 'a/b/c'
98
+ end
92
99
 
93
100
  it "should parse files with '*' in them as globs and others as absolute paths" do
94
101
  Dir.should_receive(:[]).with('*.rb').and_return(['a.rb', 'b.rb'])
@@ -17,6 +17,7 @@ describe YARD::Tags::DefaultFactory, "extract_types_and_name_from_text" do
17
17
 
18
18
  it "should return the text before and after the type list" do
19
19
  parse_types(' b <String> description').should == ['b', ['String'], 'description']
20
+ parse_types('b c <String> description (test)').should == [nil, nil, 'b c <String> description (test)']
20
21
  end
21
22
 
22
23
  it "should handle a complex list of types" do
@@ -36,10 +36,10 @@
36
36
 
37
37
  <h2>Overview</h2><div class="docstring">
38
38
  <div class="discussion">
39
- <p class="note abstract">
39
+ <div class="note abstract">
40
40
  <strong>This class is abstract.</strong>
41
41
  <div class='inline'>override this class</div>
42
- </p>
42
+ </div>
43
43
  Comments
44
44
 
45
45
  </div>
@@ -51,7 +51,7 @@ Comments
51
51
 
52
52
  <li>A</li>
53
53
 
54
- <li><a href="http://example.com" title="Example">Example</a></li>
54
+ <li><a href="http://example.com" target="_parent" title="Example">Example</a></li>
55
55
 
56
56
  </ul>
57
57
  <h3>Author:</h3>
@@ -92,7 +92,7 @@ Comments
92
92
 
93
93
 
94
94
 
95
- <h2>Instance Method Summary</h2>
95
+ <h2>Instance Method Summary <small>(<a href="#" class="summary_toggle">collapse</a>)</small></h2>
96
96
 
97
97
  <ul class="summary">
98
98
 
@@ -253,7 +253,7 @@ def method_missing(*args) end</pre>
253
253
 
254
254
  </p><div class="docstring">
255
255
  <div class="discussion">
256
- <p class="note deprecated"><strong>Deprecated.</strong> <div class='inline'></div></p>
256
+ <div class="note deprecated"><strong>Deprecated.</strong> <div class='inline'></div></div>
257
257
 
258
258
 
259
259
  </div>
@@ -22,7 +22,7 @@
22
22
 
23
23
  </p><div class="docstring">
24
24
  <div class="discussion">
25
- <p class="note deprecated"><strong>Deprecated.</strong> <div class='inline'>for great justice</div></p>
25
+ <div class="note deprecated"><strong>Deprecated.</strong> <div class='inline'>for great justice</div></div>
26
26
  Comments
27
27
 
28
28
  </div>
@@ -68,7 +68,7 @@ and newlines.
68
68
  <dt id="cvar-classvariable" class="deprecated">@@cvar =
69
69
  <div class="docstring">
70
70
  <div class="discussion">
71
- <p class="note deprecated"><strong>Deprecated.</strong> <div class='inline'></div></p>
71
+ <div class="note deprecated"><strong>Deprecated.</strong> <div class='inline'></div></div>
72
72
 
73
73
 
74
74
  </div>
@@ -87,7 +87,7 @@ and newlines.
87
87
 
88
88
 
89
89
 
90
- <h2>Instance Attribute Summary</h2>
90
+ <h2>Instance Attribute Summary <small>(<a href="#" class="summary_toggle">collapse</a>)</small></h2>
91
91
  <ul class="summary">
92
92
 
93
93
  <li class="public ">
@@ -186,7 +186,7 @@ and newlines.
186
186
 
187
187
 
188
188
 
189
- <h2>Class Method Summary</h2>
189
+ <h2>Class Method Summary <small>(<a href="#" class="summary_toggle">collapse</a>)</small></h2>
190
190
 
191
191
  <ul class="summary">
192
192
 
@@ -212,7 +212,7 @@ and newlines.
212
212
 
213
213
  </ul>
214
214
 
215
- <h2>Instance Method Summary</h2>
215
+ <h2>Instance Method Summary <small>(<a href="#" class="summary_toggle">collapse</a>)</small></h2>
216
216
 
217
217
  <ul class="summary">
218
218
 
@@ -63,6 +63,23 @@ describe YARD::Templates::Helpers::BaseHelper do
63
63
  end
64
64
  end
65
65
 
66
+ describe '#linkify' do
67
+ it "should call #link_url for mailto: links" do
68
+ should_receive(:link_url)
69
+ linkify("mailto:steve@example.com")
70
+ end
71
+
72
+ it "should call #link_url for URL schemes (http://)" do
73
+ should_receive(:link_url)
74
+ linkify("http://example.com")
75
+ end
76
+
77
+ it "should call #link_file for file: links" do
78
+ should_receive(:link_file).with('Filename', 'Filename', 'anchor')
79
+ linkify("file:Filename#anchor")
80
+ end
81
+ end
82
+
66
83
  describe '#format_types' do
67
84
  it "should return the list of types separated by commas surrounded by brackets" do
68
85
  format_types(['a', 'b', 'c']).should == '(a, b, c)'
@@ -122,7 +139,7 @@ describe YARD::Templates::Helpers::BaseHelper do
122
139
 
123
140
  it "should pass off to #link_url if argument is recognized as a URL" do
124
141
  url = "http://yardoc.org/"
125
- should_receive(:link_url).with(url)
142
+ should_receive(:link_url).with(url, nil, {:target => '_parent'})
126
143
  linkify url
127
144
  end
128
145
  end
@@ -2,6 +2,7 @@ require File.dirname(__FILE__) + '/../../spec_helper'
2
2
  require File.dirname(__FILE__) + "/shared_signature_examples"
3
3
 
4
4
  describe YARD::Templates::Helpers::HtmlHelper do
5
+ include YARD::Templates::Helpers::BaseHelper
5
6
  include YARD::Templates::Helpers::HtmlHelper
6
7
  include YARD::Templates::Helpers::MethodHelper
7
8
 
@@ -100,7 +101,7 @@ describe YARD::Templates::Helpers::HtmlHelper do
100
101
  htmlify("A\nB", :textile).should_not include("<br")
101
102
  end
102
103
  end
103
-
104
+
104
105
  describe "#link_object" do
105
106
  before do
106
107
  stub!(:object).and_return(CodeObjects::NamespaceObject.new(nil, :YARD))
@@ -63,7 +63,10 @@ describe YARD::Templates::Engine.template(:default, :module) do
63
63
  end
64
64
 
65
65
  it "should render html format correctly" do
66
- html_equals(Registry.at('A').format(:format => :html, :no_highlight => true, :hide_void_return => true, :visibilities => [:public]), :module001)
66
+ html_equals(Registry.at('A').format(
67
+ :format => :html, :no_highlight => true, :hide_void_return => true,
68
+ :verifier => Verifier.new('object.type != :method || object.visibility == :public')),
69
+ :module001)
67
70
  end
68
71
 
69
72
  it "should render text format correctly" do
@@ -79,4 +82,4 @@ describe YARD::Templates::Engine.template(:default, :module) do
79
82
  it "should render dot format correctly" do
80
83
  Registry.at('A').format(:format => :dot, :dependencies => true, :full => true).should == example(:module001, 'dot')
81
84
  end
82
- end
85
+ end
@@ -1,4 +1,4 @@
1
- <p class="note abstract">
1
+ <div class="note abstract">
2
2
  <strong>This <%= object.type %> is abstract.</strong>
3
3
  <%= htmlify_line object.tag(:abstract).text %>
4
- </p>
4
+ </div>
@@ -1 +1 @@
1
- <p class="note deprecated"><strong>Deprecated.</strong> <%= htmlify_line object.tag(:deprecated).text %></p>
1
+ <div class="note deprecated"><strong>Deprecated.</strong> <%= htmlify_line object.tag(:deprecated).text %></div>
@@ -1,6 +1,6 @@
1
1
  <% object.tags(:note).each do |tag| %>
2
- <p class="note notetag">
2
+ <div class="note notetag">
3
3
  <strong>Note:</strong>
4
4
  <%= htmlify_line tag.text %>
5
- </p>
5
+ </div>
6
6
  <% end %>
@@ -0,0 +1,4 @@
1
+ <p class="note private">
2
+ <strong>This <%= object.type %> is part of a private API.</strong>
3
+ You should avoid using this <%= object.type %> if possible, as it may be removed or be changed in the future.
4
+ </p>
@@ -1,6 +1,6 @@
1
1
  <% object.tags(:todo).each do |tag| %>
2
- <p class="note todo">
2
+ <div class="note todo">
3
3
  <strong>TODO:</strong>
4
4
  <%= htmlify_line tag.text %>
5
- </p>
5
+ </div>
6
6
  <% end %>
@@ -1,6 +1,11 @@
1
1
  def init
2
2
  return if object.docstring.blank?
3
- sections :index, [:deprecated, :abstract, :todo, :note, :returns_void, :text], T('tags')
3
+ sections :index, [:private, :deprecated, :abstract, :todo, :note, :returns_void, :text], T('tags')
4
+ end
5
+
6
+ def private
7
+ return unless object.has_tag?(:api) && object.tag(:api).text == 'private'
8
+ erb(:private)
4
9
  end
5
10
 
6
11
  def abstract
@@ -0,0 +1,2 @@
1
+ <%= indent(wrap("This #{object.type} is part of a private API.")) %>
2
+
@@ -15,6 +15,7 @@ h2 {
15
15
  font-size: 1.4em;
16
16
  margin: 1.8em 0 0.5em;
17
17
  }
18
+ h2 small { font-weight: normal; font-size: 0.7em; display: block; float: right; }
18
19
  .clear { clear: both; }
19
20
  .inline { display: inline; }
20
21
  .inline p:first-child { display: inline; }
@@ -31,6 +32,7 @@ h2 {
31
32
  .note.todo { background: #ffffc5; border-color: #ececaa; }
32
33
  .note.returns_void { background: #efefef; }
33
34
  .note.deprecated { background: #ffe5e5; border-color: #e9dada; }
35
+ .note.private { background: #ffffc5; border-color: #ececaa; }
34
36
  .note.title { text-transform: lowercase; padding: 1px 5px; margin-left: 5px; font-size: 0.9em; font-family: "Lucida Sans", "Lucida Grande", Verdana, Arial, sans-serif; }
35
37
  h1 .note.title { font-size: 0.5em; font-weight: normal; padding: 3px 5px; position: relative; top: -3px; text-transform: capitalize; }
36
38
  .note.title.constructor { color: #fff; background: #6a98d6; border-color: #6689d6; }
@@ -118,7 +120,7 @@ p.signature .aliases .names { font-family: Monaco, Consolas, Courier, monospace;
118
120
  .tags ul { margin-top: 5px; padding-left: 30px; list-style: square; }
119
121
  .tags ul li { margin-bottom: 3px; }
120
122
  .tags ul .name { font-family: monospace; font-weight: bold; }
121
- .tags ul p.note { padding: 3px 6px; }
123
+ .tags ul .note { padding: 3px 6px; }
122
124
  .tags { margin-bottom: 12px; }
123
125
 
124
126
  .tags .examples h3 { margin-bottom: 10px; }
@@ -159,6 +161,8 @@ ul.summary li { margin-bottom: 5px; }
159
161
  -moz-border-radius: 3px; -webkit-border-radius: 3px;
160
162
  }
161
163
  .summary_signature:hover { background: #eeeeff; cursor: pointer; }
164
+ ul.summary.compact li { display: inline; margin-right: 5px; line-height: 2.6em;}
165
+ ul.summary.compact .summary_signature { padding: 5px 7px; padding-right: 4px; }
162
166
  #content .summary_signature:hover a:link,
163
167
  #content .summary_signature:hover a:visited {
164
168
  background: transparent;
@@ -229,8 +233,8 @@ li.r2 { background: #fafafa; }
229
233
  overflow-y: scroll;
230
234
  border: 1px solid #999;
231
235
  border-collapse: collapse;
232
- -webkit-box-shadow: -2px 5px 25px #aaa;
233
- -moz-box-shadow: -2px 5px 25px #aaa;
236
+ -webkit-box-shadow: -7px 5px 25px #aaa;
237
+ -moz-box-shadow: -7px 5px 25px #aaa;
234
238
  -moz-border-radius: 2px;
235
239
  -webkit-border-radius: 2px;
236
240
  }
@@ -91,8 +91,11 @@ function framesInit() {
91
91
  }
92
92
 
93
93
  function keyboardShortcuts() {
94
+ if (window.top.frames.main) return;
94
95
  $(document).keypress(function(evt) {
95
96
  if (evt.altKey || evt.ctrlKey || evt.metaKey || evt.shiftKey) return;
97
+ if (evt.originalTarget.nodeName == "INPUT" ||
98
+ evt.originalTarget.nodeName == "TEXTAREA") return;
96
99
  switch (evt.charCode) {
97
100
  case 67: case 99: $('#class_list_link').click(); break; // 'c'
98
101
  case 77: case 109: $('#method_list_link').click(); break; // 'm'
@@ -101,6 +104,29 @@ function keyboardShortcuts() {
101
104
  });
102
105
  }
103
106
 
107
+ function summaryToggle() {
108
+ $('.summary_toggle').click(function() {
109
+ $(this).text($(this).text() == "collapse" ? "expand" : "collapse");
110
+ var next = $(this).parent().parent().next();
111
+ if (next.hasClass('compact')) {
112
+ next.toggle();
113
+ next.next().toggle();
114
+ }
115
+ else if (next.hasClass('summary')) {
116
+ var list = $('<ul class="summary compact" />');
117
+ list.html(next.html());
118
+ list.find('.summary_desc, .note').remove();
119
+ list.find('a').each(function() {
120
+ $(this).html($(this).find('strong').html());
121
+ $(this).parent().html($(this)[0].outerHTML);
122
+ });
123
+ next.before(list);
124
+ next.toggle();
125
+ }
126
+ return false;
127
+ })
128
+ }
129
+
104
130
  $(framesInit);
105
131
  $(createSourceLinks);
106
132
  $(createDefineLinks);
@@ -109,3 +135,4 @@ $(fixBoxInfoHeights);
109
135
  $(searchFrameLinks);
110
136
  $(linkSummaries);
111
137
  $(keyboardShortcuts);
138
+ $(summaryToggle);
@@ -107,7 +107,7 @@ def class_list(root = Registry.root)
107
107
  if root == Registry.root
108
108
  children += @items.select {|o| o.namespace.is_a?(CodeObjects::Proxy) }
109
109
  end
110
- children.sort_by {|child| child.path }.map do |child|
110
+ children.reject {|c| c.nil? }.sort_by {|child| child.path }.map do |child|
111
111
  if child.is_a?(CodeObjects::NamespaceObject)
112
112
  name = child.namespace.is_a?(CodeObjects::Proxy) ? child.path : child.name
113
113
  has_children = child.children.any? {|o| o.is_a?(CodeObjects::NamespaceObject) }
@@ -1,5 +1,5 @@
1
1
  <% scopes(attr_listing) do |list, scope| %>
2
- <h2><%= scope.to_s.capitalize %> Attribute Summary</h2>
2
+ <h2><%= scope.to_s.capitalize %> Attribute Summary <small>(<a href="#" class="summary_toggle">collapse</a>)</small></h2>
3
3
  <ul class="summary">
4
4
  <% list.each do |meth| %>
5
5
  <%= yieldall :item => meth %>
@@ -16,7 +16,7 @@
16
16
  </dd>
17
17
  <% n = 2 %>
18
18
  <% end %>
19
- <% [[:class, "Extends"], [:instance, "Includes"]].each do |scope, name| %>
19
+ <% [[:class, "Extended by"], [:instance, "Includes"]].each do |scope, name| %>
20
20
  <% if (mix = object.mixins(scope)).size > 0 %>
21
21
  <dt class="r<%=n%>"><%= name %>:</dt>
22
22
  <dd class="r<%=n%>"><%= mix.sort_by {|o| o.path }.map {|o| linkify(o) }.join(", ") %></dd>
@@ -1,4 +1,5 @@
1
- <h1><%= format_object_title(object) %>
1
+ <h1><%= format_object_title(object) %>
2
2
  <% if object.has_tag?(:abstract) %><span class="abstract note title">Abstract</span><% end %>
3
3
  <% if object.has_tag?(:deprecated) %><span class="deprecated note title">Deprecated</span><% end %>
4
+ <% if object.has_tag?(:api) && object.tag(:api).text == 'private' %><span class="private note title">Private</span><% end %>
4
5
  </h1>
@@ -20,6 +20,7 @@
20
20
  <% if @item.visibility != :public %><span class="note title <%= @item.visibility %>"><%= @item.visibility %></span><% end %>
21
21
  <% if @item.has_tag?(:abstract) %><span class="abstract note title">Abstract</span><% end %>
22
22
  <% if @item.has_tag?(:deprecated) %><span class="deprecated note title">Deprecated</span><% end %>
23
+ <% if @item.has_tag?(:api) && @item.tag(:api).text == 'private' %><span class="private note title">Private</span><% end %>
23
24
 
24
25
  <% if @item.has_tag?(:deprecated) %>
25
26
  <span class="summary_desc"><strong>Deprecated.</strong> <%= htmlify_line @item.tag(:deprecated).text %></span>
@@ -1,6 +1,9 @@
1
1
  <% if method_listing.size > 0 %>
2
2
  <% scopes(method_listing) do |list, scope| %>
3
- <h2><%= scope.to_s.capitalize %> Method Summary</h2>
3
+ <h2>
4
+ <%= scope.to_s.capitalize %> Method Summary
5
+ <small>(<a href="#" class="summary_toggle">collapse</a>)</small>
6
+ </h2>
4
7
 
5
8
  <ul class="summary">
6
9
  <% list.each do |meth| %>
@@ -1,6 +1,6 @@
1
1
  <% if object.mixins(:class).size > 0 %>
2
- Extends:
3
- --------
2
+ Extended by:
3
+ ------------
4
4
 
5
5
  <%= indent wrap(object.mixins(:class).join(", "), 68) %>
6
6
 
@@ -2,7 +2,7 @@
2
2
  <h3>See Also:</h3>
3
3
  <ul class="see">
4
4
  <% for tag in object.tags(:see) %>
5
- <li><%= linkify(tag.name, tag.text || tag.name) %></li>
5
+ <li><%= linkify(tag.name, tag.text) %></li>
6
6
  <% end %>
7
7
  </ul>
8
8
  <% end %>