yard 0.6.8 → 0.7.0

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 (224) hide show
  1. data/.yardopts +1 -0
  2. data/ChangeLog +723 -0
  3. data/README.md +16 -6
  4. data/docs/CodeObjects.md +10 -16
  5. data/docs/GettingStarted.md +232 -32
  6. data/docs/Glossary.md +1 -2
  7. data/docs/Handlers.md +10 -16
  8. data/docs/Overview.md +14 -13
  9. data/docs/Parser.md +13 -22
  10. data/docs/Tags.md +209 -16
  11. data/docs/Templates.md +237 -26
  12. data/docs/WhatsNew.md +178 -2
  13. data/lib/yard.rb +13 -10
  14. data/lib/yard/autoload.rb +22 -18
  15. data/lib/yard/cli/command.rb +13 -12
  16. data/lib/yard/cli/command_parser.rb +20 -19
  17. data/lib/yard/cli/config.rb +19 -19
  18. data/lib/yard/cli/diff.rb +46 -21
  19. data/lib/yard/cli/gems.rb +11 -11
  20. data/lib/yard/cli/graph.rb +13 -13
  21. data/lib/yard/cli/help.rb +1 -1
  22. data/lib/yard/cli/list.rb +22 -0
  23. data/lib/yard/cli/server.rb +17 -17
  24. data/lib/yard/cli/stats.rb +32 -32
  25. data/lib/yard/cli/yardoc.rb +181 -135
  26. data/lib/yard/cli/yri.rb +29 -29
  27. data/lib/yard/code_objects/base.rb +101 -101
  28. data/lib/yard/code_objects/class_object.rb +20 -20
  29. data/lib/yard/code_objects/constant_object.rb +1 -1
  30. data/lib/yard/code_objects/extended_method_object.rb +5 -5
  31. data/lib/yard/code_objects/extra_file_object.rb +89 -0
  32. data/lib/yard/code_objects/macro_object.rb +215 -0
  33. data/lib/yard/code_objects/method_object.rb +30 -30
  34. data/lib/yard/code_objects/module_object.rb +1 -1
  35. data/lib/yard/code_objects/namespace_object.rb +39 -39
  36. data/lib/yard/code_objects/proxy.rb +38 -38
  37. data/lib/yard/code_objects/root_object.rb +1 -1
  38. data/lib/yard/config.rb +40 -40
  39. data/lib/yard/core_ext/array.rb +2 -2
  40. data/lib/yard/core_ext/file.rb +11 -11
  41. data/lib/yard/core_ext/insertion.rb +10 -10
  42. data/lib/yard/core_ext/module.rb +2 -2
  43. data/lib/yard/core_ext/string.rb +2 -2
  44. data/lib/yard/core_ext/symbol_hash.rb +14 -14
  45. data/lib/yard/docstring.rb +122 -54
  46. data/lib/yard/globals.rb +2 -2
  47. data/lib/yard/handlers/base.rb +216 -127
  48. data/lib/yard/handlers/processor.rb +65 -27
  49. data/lib/yard/handlers/ruby/alias_handler.rb +6 -3
  50. data/lib/yard/handlers/ruby/attribute_handler.rb +7 -6
  51. data/lib/yard/handlers/ruby/base.rb +50 -31
  52. data/lib/yard/handlers/ruby/class_condition_handler.rb +11 -11
  53. data/lib/yard/handlers/ruby/class_handler.rb +10 -10
  54. data/lib/yard/handlers/ruby/class_variable_handler.rb +3 -3
  55. data/lib/yard/handlers/ruby/constant_handler.rb +7 -7
  56. data/lib/yard/handlers/ruby/exception_handler.rb +2 -2
  57. data/lib/yard/handlers/ruby/extend_handler.rb +1 -1
  58. data/lib/yard/handlers/ruby/legacy/alias_handler.rb +8 -5
  59. data/lib/yard/handlers/ruby/legacy/attribute_handler.rb +6 -5
  60. data/lib/yard/handlers/ruby/legacy/base.rb +42 -27
  61. data/lib/yard/handlers/ruby/legacy/class_condition_handler.rb +9 -9
  62. data/lib/yard/handlers/ruby/legacy/class_handler.rb +13 -12
  63. data/lib/yard/handlers/ruby/legacy/class_variable_handler.rb +3 -6
  64. data/lib/yard/handlers/ruby/legacy/constant_handler.rb +5 -8
  65. data/lib/yard/handlers/ruby/legacy/exception_handler.rb +1 -1
  66. data/lib/yard/handlers/ruby/legacy/extend_handler.rb +1 -0
  67. data/lib/yard/handlers/ruby/legacy/macro_handler.rb +40 -0
  68. data/lib/yard/handlers/ruby/legacy/method_handler.rb +10 -10
  69. data/lib/yard/handlers/ruby/legacy/mixin_handler.rb +4 -3
  70. data/lib/yard/handlers/ruby/legacy/module_handler.rb +2 -1
  71. data/lib/yard/handlers/ruby/legacy/private_constant_handler.rb +4 -4
  72. data/lib/yard/handlers/ruby/legacy/visibility_handler.rb +2 -1
  73. data/lib/yard/handlers/ruby/legacy/yield_handler.rb +3 -3
  74. data/lib/yard/handlers/ruby/macro_handler.rb +41 -0
  75. data/lib/yard/handlers/ruby/macro_handler_methods.rb +130 -0
  76. data/lib/yard/handlers/ruby/method_condition_handler.rb +1 -1
  77. data/lib/yard/handlers/ruby/method_handler.rb +13 -13
  78. data/lib/yard/handlers/ruby/mixin_handler.rb +4 -4
  79. data/lib/yard/handlers/ruby/module_handler.rb +2 -1
  80. data/lib/yard/handlers/ruby/private_constant_handler.rb +4 -4
  81. data/lib/yard/handlers/ruby/struct_handler_methods.rb +11 -11
  82. data/lib/yard/handlers/ruby/visibility_handler.rb +1 -1
  83. data/lib/yard/handlers/ruby/yield_handler.rb +5 -5
  84. data/lib/yard/logging.rb +11 -11
  85. data/lib/yard/parser/base.rb +8 -8
  86. data/lib/yard/parser/c_parser.rb +42 -33
  87. data/lib/yard/parser/ruby/ast_node.rb +62 -61
  88. data/lib/yard/parser/ruby/legacy/ruby_lex.rb +66 -66
  89. data/lib/yard/parser/ruby/legacy/ruby_parser.rb +4 -4
  90. data/lib/yard/parser/ruby/legacy/statement.rb +11 -11
  91. data/lib/yard/parser/ruby/legacy/statement_list.rb +15 -15
  92. data/lib/yard/parser/ruby/legacy/token_list.rb +9 -9
  93. data/lib/yard/parser/ruby/ruby_parser.rb +51 -37
  94. data/lib/yard/parser/source_parser.rb +271 -46
  95. data/lib/yard/rake/yardoc_task.rb +18 -17
  96. data/lib/yard/registry.rb +64 -64
  97. data/lib/yard/registry_store.rb +34 -34
  98. data/lib/yard/rubygems/backports.rb +8 -0
  99. data/lib/yard/rubygems/backports/LICENSE.txt +57 -0
  100. data/lib/yard/rubygems/backports/MIT.txt +20 -0
  101. data/lib/yard/rubygems/backports/gem.rb +8 -0
  102. data/lib/yard/rubygems/backports/source_index.rb +353 -0
  103. data/lib/yard/rubygems/specification.rb +2 -2
  104. data/lib/yard/serializers/base.rb +20 -20
  105. data/lib/yard/serializers/file_system_serializer.rb +28 -24
  106. data/lib/yard/serializers/process_serializer.rb +3 -3
  107. data/lib/yard/serializers/stdout_serializer.rb +6 -6
  108. data/lib/yard/serializers/yardoc_serializer.rb +17 -17
  109. data/lib/yard/server/adapter.rb +12 -12
  110. data/lib/yard/server/commands/base.rb +26 -26
  111. data/lib/yard/server/commands/display_file_command.rb +3 -2
  112. data/lib/yard/server/commands/display_object_command.rb +5 -5
  113. data/lib/yard/server/commands/frames_command.rb +1 -1
  114. data/lib/yard/server/commands/library_command.rb +7 -7
  115. data/lib/yard/server/commands/library_index_command.rb +2 -2
  116. data/lib/yard/server/commands/list_command.rb +8 -8
  117. data/lib/yard/server/commands/search_command.rb +8 -8
  118. data/lib/yard/server/commands/static_file_command.rb +3 -3
  119. data/lib/yard/server/doc_server_helper.rb +6 -3
  120. data/lib/yard/server/doc_server_serializer.rb +1 -1
  121. data/lib/yard/server/library_version.rb +45 -45
  122. data/lib/yard/server/rack_adapter.rb +10 -10
  123. data/lib/yard/server/router.rb +28 -28
  124. data/lib/yard/server/static_caching.rb +5 -5
  125. data/lib/yard/server/templates/default/fulldoc/html/css/custom.css +3 -3
  126. data/lib/yard/server/templates/default/fulldoc/html/js/live.js +1 -1
  127. data/lib/yard/server/templates/default/layout/html/breadcrumb.erb +2 -2
  128. data/lib/yard/server/templates/default/layout/html/headers.erb +13 -8
  129. data/lib/yard/server/templates/default/layout/html/setup.rb +7 -0
  130. data/lib/yard/server/templates/doc_server/full_list/html/full_list.erb +2 -2
  131. data/lib/yard/server/templates/doc_server/full_list/html/setup.rb +14 -4
  132. data/lib/yard/server/templates/doc_server/library_list/html/contents.erb +2 -2
  133. data/lib/yard/server/templates/doc_server/library_list/html/headers.erb +2 -2
  134. data/lib/yard/server/templates/doc_server/processing/html/processing.erb +1 -1
  135. data/lib/yard/server/templates/doc_server/search/html/search.erb +1 -1
  136. data/lib/yard/server/webrick_adapter.rb +2 -2
  137. data/lib/yard/tags/default_factory.rb +19 -19
  138. data/lib/yard/tags/default_tag.rb +1 -1
  139. data/lib/yard/tags/library.rb +68 -63
  140. data/lib/yard/tags/option_tag.rb +1 -1
  141. data/lib/yard/tags/overload_tag.rb +9 -9
  142. data/lib/yard/tags/ref_tag_list.rb +2 -2
  143. data/lib/yard/tags/tag.rb +7 -7
  144. data/lib/yard/templates/engine.rb +31 -31
  145. data/lib/yard/templates/erb_cache.rb +1 -1
  146. data/lib/yard/templates/helpers/base_helper.rb +46 -32
  147. data/lib/yard/templates/helpers/filter_helper.rb +2 -2
  148. data/lib/yard/templates/helpers/html_helper.rb +120 -81
  149. data/lib/yard/templates/helpers/html_syntax_highlight_helper.rb +4 -4
  150. data/lib/yard/templates/helpers/markup/rdoc_markup.rb +9 -9
  151. data/lib/yard/templates/helpers/markup_helper.rb +37 -30
  152. data/lib/yard/templates/helpers/method_helper.rb +7 -7
  153. data/lib/yard/templates/helpers/text_helper.rb +7 -7
  154. data/lib/yard/templates/helpers/uml_helper.rb +3 -3
  155. data/lib/yard/templates/section.rb +14 -14
  156. data/lib/yard/templates/template.rb +54 -54
  157. data/lib/yard/verifier.rb +27 -27
  158. data/spec/cli/list_spec.rb +8 -0
  159. data/spec/cli/yardoc_spec.rb +58 -10
  160. data/spec/code_objects/extra_file_object_spec.rb +132 -0
  161. data/spec/code_objects/macro_object_spec.rb +154 -0
  162. data/spec/docstring_spec.rb +90 -0
  163. data/spec/handlers/base_spec.rb +22 -0
  164. data/spec/handlers/examples/macro_handler_001.rb.txt +73 -0
  165. data/spec/handlers/examples/method_handler_001.rb.txt +17 -0
  166. data/spec/handlers/macro_handler_spec.rb +140 -0
  167. data/spec/handlers/method_handler_spec.rb +28 -0
  168. data/spec/handlers/processor_spec.rb +4 -0
  169. data/spec/handlers/spec_helper.rb +1 -1
  170. data/spec/parser/c_parser_spec.rb +47 -16
  171. data/spec/parser/examples/extrafile.c.txt +8 -0
  172. data/spec/parser/examples/multifile.c.txt +6 -0
  173. data/spec/parser/ruby/ruby_parser_spec.rb +5 -0
  174. data/spec/parser/source_parser_spec.rb +235 -0
  175. data/spec/rake/yardoc_task_spec.rb +22 -17
  176. data/spec/serializers/file_system_serializer_spec.rb +6 -0
  177. data/spec/server/commands/library_command_spec.rb +39 -0
  178. data/spec/spec_helper.rb +14 -0
  179. data/spec/templates/examples/method001.html +6 -6
  180. data/spec/templates/examples/method002.html +4 -4
  181. data/spec/templates/examples/method003.html +10 -10
  182. data/spec/templates/examples/method005.html +2 -2
  183. data/spec/templates/examples/module001.dot +2 -0
  184. data/spec/templates/examples/module001.html +76 -37
  185. data/spec/templates/examples/module001.txt +1 -1
  186. data/spec/templates/helpers/base_helper_spec.rb +7 -2
  187. data/spec/templates/helpers/html_helper_spec.rb +49 -5
  188. data/spec/templates/helpers/markup_helper_spec.rb +9 -8
  189. data/spec/templates/module_spec.rb +7 -0
  190. data/spec/templates/onefile_spec.rb +47 -0
  191. data/templates/default/fulldoc/html/css/style.css +7 -5
  192. data/templates/default/fulldoc/html/full_list.erb +13 -10
  193. data/templates/default/fulldoc/html/full_list_files.erb +1 -1
  194. data/templates/default/fulldoc/html/js/app.js +16 -14
  195. data/templates/default/fulldoc/html/js/full_list.js +7 -6
  196. data/templates/default/fulldoc/html/setup.rb +78 -17
  197. data/templates/default/layout/html/files.erb +1 -1
  198. data/templates/default/layout/html/headers.erb +11 -7
  199. data/templates/default/layout/html/search.erb +4 -4
  200. data/templates/default/layout/html/setup.rb +28 -8
  201. data/templates/default/module/html/inherited_attributes.erb +17 -0
  202. data/templates/default/module/setup.rb +1 -1
  203. data/templates/default/onefile/html/files.erb +2 -2
  204. data/templates/default/onefile/html/layout.erb +1 -1
  205. data/templates/default/onefile/html/setup.rb +7 -5
  206. data/templates/default/tags/html/option.erb +1 -1
  207. data/templates/default/tags/html/tag.erb +3 -3
  208. data/templates/guide/class/html/setup.rb +1 -0
  209. data/templates/guide/docstring/html/setup.rb +1 -0
  210. data/templates/guide/fulldoc/html/css/style.css +91 -0
  211. data/templates/guide/fulldoc/html/js/app.js +33 -0
  212. data/templates/guide/fulldoc/html/setup.rb +54 -0
  213. data/templates/guide/layout/html/layout.erb +81 -0
  214. data/templates/guide/layout/html/setup.rb +24 -0
  215. data/templates/guide/method/html/header.erb +18 -0
  216. data/templates/guide/method/html/setup.rb +21 -0
  217. data/templates/guide/module/html/header.erb +7 -0
  218. data/templates/guide/module/html/method_list.erb +5 -0
  219. data/templates/guide/module/html/setup.rb +26 -0
  220. data/templates/guide/tags/html/setup.rb +8 -0
  221. metadata +40 -7
  222. data/lib/yard/handlers/ruby/legacy/process_handler.rb +0 -13
  223. data/lib/yard/handlers/ruby/process_handler.rb +0 -18
  224. data/spec/handlers/process_handler_spec.rb +0 -17
@@ -59,6 +59,28 @@ describe YARD::Handlers::Base do
59
59
  end
60
60
  end
61
61
 
62
+ describe 'sharing global state' do
63
+ it "should allow globals to share global state among handlers" do
64
+ class GlobalStateHandler1 < Handlers::Ruby::Base
65
+ class << self; attr_accessor :state end
66
+ handles :class
67
+ process { self.class.state = globals.foo; globals.foo = :bar }
68
+ end
69
+
70
+ class GlobalStateHandler2 < Handlers::Ruby::Base
71
+ class << self; attr_accessor :state end
72
+ handles :def
73
+ process { self.class.state = globals.foo }
74
+ end
75
+
76
+ 2.times do
77
+ YARD.parse_string 'class Foo; end; def foo; end'
78
+ GlobalStateHandler1.state.should == nil
79
+ GlobalStateHandler2.state.should == :bar
80
+ end
81
+ end
82
+ end if HAVE_RIPPER
83
+
62
84
  describe '#push_state' do
63
85
  def process(klass)
64
86
  state = OpenStruct.new(:namespace => "ROOT", :scope => :instance, :owner => "ROOT")
@@ -0,0 +1,73 @@
1
+ class Foo
2
+ attr_accessor :ignoreme
3
+
4
+ # IMPLICIT METHOD!
5
+ # @return [String]
6
+ just_a_method_for :implicit0
7
+
8
+ # Not recognized
9
+ just_a_method_for :implicit_invalid
10
+
11
+ #
12
+ ## IS NOT RECOGNIZED!
13
+ just_a_method_for :implicit_invalid2
14
+
15
+ ##
16
+ # IS RECOGNIZED!
17
+ just_a_method_for 'implicit_valid'
18
+
19
+ # @attribute [r]
20
+ # @return [Numeric] a number
21
+ a_readable_attribute :attr1
22
+
23
+ # @attribute [w]
24
+ a_writable_attribute :attr2, 'bar'
25
+
26
+ # @attribute
27
+ default_attribute :attr3
28
+
29
+ # @method xyz(a, b, c)
30
+ # The foo method
31
+ # @param [String] a
32
+ # @visibility protected
33
+ # @scope class
34
+ foo_bar
35
+
36
+ # @macro property
37
+ # @method $1(${3-})
38
+ # A $0 that is awesome.
39
+ # @param $3 first parameter
40
+ # @return [$2] the property $1
41
+ property :name, String, :a, :b, :c
42
+
43
+ # @macro property
44
+ property :age, Fixnum, :value
45
+
46
+ # This is just for x
47
+ # @macro [attach] parser
48
+ # @method $1(opts = {})
49
+ # @return NOTHING!
50
+ parser :x
51
+
52
+ parser :c_parser
53
+
54
+ # @macro [attach] none
55
+ # @method none(foo, bar)
56
+ none
57
+
58
+ # @macro something
59
+ # @overload $1(a, b, c)
60
+ something :qux
61
+
62
+ # @overload qux2(a, b, c)
63
+ something
64
+ end
65
+
66
+ class Bar
67
+ parser :x_parser
68
+ end
69
+
70
+ class Baz < Foo
71
+ parser :y_parser
72
+ none { }
73
+ end
@@ -91,3 +91,20 @@ class D
91
91
  # foo bar
92
92
  def a; end
93
93
  end
94
+
95
+ class E
96
+ # @macro prop
97
+ # @method $1(value)
98
+ # $3
99
+ # @return [$2]
100
+ def self.property(name, ret_type, docstring)
101
+ end
102
+
103
+ property :foo, String, "create a foo"
104
+
105
+ # @macro xyz
106
+ # @method $1
107
+ def xyz; end
108
+
109
+ xyz :a
110
+ end
@@ -0,0 +1,140 @@
1
+ require File.dirname(__FILE__) + '/spec_helper'
2
+ require 'ostruct'
3
+
4
+ describe "YARD::Handlers::Ruby::#{LEGACY_PARSER ? "Legacy::" : ""}MacroHandler" do
5
+ before(:all) { parse_file :macro_handler_001, __FILE__ }
6
+
7
+ it "should create a readable attribute when @attribute r is found" do
8
+ obj = Registry.at('Foo#attr1')
9
+ obj.should_not be_nil
10
+ obj.should be_reader
11
+ obj.tag(:return).types.should == ['Numeric']
12
+ Registry.at('Foo#attr1=').should be_nil
13
+ end
14
+
15
+ it "should create a writable attribute when @attribute w is found" do
16
+ obj = Registry.at('Foo#attr2=')
17
+ obj.should_not be_nil
18
+ obj.should be_writer
19
+ Registry.at('Foo#attr2').should be_nil
20
+ end
21
+
22
+ it "should default to readwrite @attribute" do
23
+ obj = Registry.at('Foo#attr3')
24
+ obj.should_not be_nil
25
+ obj.should be_reader
26
+ obj = Registry.at('Foo#attr3=')
27
+ obj.should_not be_nil
28
+ obj.should be_writer
29
+ end
30
+
31
+ it "should default to creating an instance method for any DSL method with tags" do
32
+ obj = Registry.at('Foo#implicit0')
33
+ obj.should_not be_nil
34
+ obj.docstring.should == "IMPLICIT METHOD!"
35
+ obj.tag(:return).types.should == ['String']
36
+ end
37
+
38
+ it "should set the method name when using @method" do
39
+ obj = Registry.at('Foo.xyz')
40
+ obj.should_not be_nil
41
+ obj.signature.should == 'def xyz(a, b, c)'
42
+ obj.source.should == 'foo_bar'
43
+ obj.docstring.should == 'The foo method'
44
+ end
45
+
46
+ it "should create hidden overlaod tag when @method has signature" do
47
+ obj = Registry.at('Foo.xyz')
48
+ obj.docstring.tag(:overload).signature.should == 'xyz(a, b, c)'
49
+ obj.docstring.tag(:overload).object.should == obj
50
+ end
51
+
52
+ it "should set the method name when using @overload" do
53
+ obj = Registry.at('Foo#qux2')
54
+ obj.should_not be_nil
55
+ obj.signature.should == 'def qux2(a, b, c)'
56
+ obj.source.should == 'something'
57
+ obj.docstring.tag(:overload).name.should == :qux2
58
+ obj.docstring.tag(:overload).object.should == obj
59
+ end
60
+
61
+ it "should set the method object when using @overload" do
62
+ obj = Registry.at('Foo#qux')
63
+ obj.should_not be_nil
64
+ obj.signature.should == 'def qux(a, b, c)'
65
+ obj.source.should == 'something :qux'
66
+ obj.docstring.tag(:overload).name.should == :qux
67
+ obj.docstring.tag(:overload).object.should == obj
68
+ end
69
+
70
+ it "should allow setting of @scope" do
71
+ Registry.at('Foo.xyz').scope.should == :class
72
+ end
73
+
74
+ it "should allow setting of @visibility" do
75
+ Registry.at('Foo.xyz').visibility.should == :protected
76
+ end
77
+
78
+ it "should ignore DSL methods without tags" do
79
+ Registry.at('Foo#implicit_invalid').should be_nil
80
+ end
81
+
82
+ it "should accept a DSL method without tags if it has hash_flag (##)" do
83
+ Registry.at('Foo#implicit_valid').should_not be_nil
84
+ Registry.at('Foo#implicit_invalid2').should be_nil
85
+ end
86
+
87
+ it "should allow creation of macros" do
88
+ macro = CodeObjects::MacroObject.find('property')
89
+ macro.should_not be_nil
90
+ macro.should_not be_attached
91
+ macro.method_object.should be_nil
92
+ end
93
+
94
+ it "should handle macros with no parameters to expand" do
95
+ Registry.at('Foo#none').should_not be_nil
96
+ Registry.at('Baz#none').signature.should == 'def none(foo, bar)'
97
+ end
98
+
99
+ it "should apply new macro docstrings on new objects" do
100
+ obj = Registry.at('Foo#name')
101
+ obj.should_not be_nil
102
+ obj.source.should == 'property :name, String, :a, :b, :c'
103
+ obj.signature.should == 'def name(a, b, c)'
104
+ obj.docstring.should == 'A property that is awesome.'
105
+ obj.tag(:param).name.should == 'a'
106
+ obj.tag(:param).text.should == 'first parameter'
107
+ obj.tag(:return).types.should == ['String']
108
+ obj.tag(:return).text.should == 'the property name'
109
+ end
110
+
111
+ it "should allow reuse of named macros" do
112
+ obj = Registry.at('Foo#age')
113
+ obj.should_not be_nil
114
+ obj.source.should == 'property :age, Fixnum, :value'
115
+ obj.signature.should == 'def age(value)'
116
+ obj.docstring.should == 'A property that is awesome.'
117
+ obj.tag(:param).name.should == 'value'
118
+ obj.tag(:param).text.should == 'first parameter'
119
+ obj.tag(:return).types.should == ['Fixnum']
120
+ obj.tag(:return).text.should == 'the property age'
121
+ end
122
+
123
+ it "should use implicitly named macros" do
124
+ macro = CodeObjects::MacroObject.find('parser')
125
+ macro.macro_data.should == "@method $1(opts = {})\n@return NOTHING!"
126
+ macro.should_not be_nil
127
+ macro.should be_attached
128
+ macro.method_object.should == P('Foo.parser')
129
+ obj = Registry.at('Foo#c_parser')
130
+ obj.should_not be_nil
131
+ obj.docstring.should == ""
132
+ obj.signature.should == "def c_parser(opts = {})"
133
+ obj.docstring.tag(:return).text.should == "NOTHING!"
134
+ end
135
+
136
+ it "should only use implicit macros on methods defined in inherited hierarchy" do
137
+ Registry.at('Bar#x_parser').should be_nil
138
+ Registry.at('Baz#y_parser').should_not be_nil
139
+ end
140
+ end
@@ -138,4 +138,32 @@ describe "YARD::Handlers::Ruby::#{LEGACY_PARSER ? "Legacy::" : ""}MethodHandler"
138
138
  Registry.at('D#b').is_alias?.should == false
139
139
  Registry.at('D#a').is_alias?.should == false
140
140
  end
141
+
142
+ it "should add macros for class methods" do
143
+ macro = CodeObjects::MacroObject.find('prop')
144
+ macro.should_not be_nil
145
+ macro.macro_data.should == "@method $1(value)\n$3\n@return [$2]"
146
+ macro.method_object.should == Registry.at('E.property')
147
+ macro.should be_attached
148
+ obj = Registry.at('E#foo')
149
+ obj.should_not be_nil
150
+ obj.docstring.should == 'create a foo'
151
+ obj.signature.should == 'def foo(value)'
152
+ obj.tag(:return).types.should == ['String']
153
+ end
154
+
155
+ it "should handle macros on any object" do
156
+ macro = CodeObjects::MacroObject.find('xyz')
157
+ macro.should_not be_nil
158
+ macro.macro_data.should == '@method $1'
159
+ end
160
+
161
+ it "should skip macros on instance methods" do
162
+ Registry.at('E#a').should be_nil
163
+ end
164
+
165
+ it "should warn if the macro name is invalid" do
166
+ log.should_receive(:warn).with(/Invalid.+macro name.+Foo\.foo/)
167
+ YARD.parse_string "class Foo\n# @macro\ndef self.foo; end\nend"
168
+ end
141
169
  end
@@ -16,4 +16,8 @@ describe YARD::Handlers::Processor do
16
16
  it "should start in root namespace" do
17
17
  @proc.namespace.should == Registry.root
18
18
  end
19
+
20
+ it "should have a globals structure" do
21
+ @proc.globals.should be_a(OpenStruct)
22
+ end
19
23
  end
@@ -27,7 +27,7 @@ end
27
27
  class StubbedSourceParser < Parser::SourceParser
28
28
  StubbedSourceParser.parser_type = :ruby
29
29
  def post_process
30
- post = StubbedProcessor.new(@file, @load_order_errors, @parser_type)
30
+ post = StubbedProcessor.new(@file, @load_order_errors, @parser_type, @globals)
31
31
  post.process(@parser.enumerator)
32
32
  end
33
33
  end
@@ -2,29 +2,60 @@ require File.join(File.dirname(__FILE__), '..', 'spec_helper')
2
2
  begin require 'continuation'; rescue LoadError; end unless RUBY18
3
3
 
4
4
  describe YARD::Parser::CParser do
5
- before(:all) do
6
- file = File.join(File.dirname(__FILE__), 'examples', 'array.c.txt')
7
- @parser = Parser::CParser.new(IO.read(file)).parse
8
-
9
- override_file = File.join(File.dirname(__FILE__), 'examples', 'override.c.txt')
10
- @override_parser = Parser::CParser.new(IO.read(override_file)).parse
11
- end
12
-
13
5
  describe '#parse' do
14
- it "should parse Array class" do
15
- obj = YARD::Registry.at('Array')
16
- obj.should_not be_nil
17
- obj.docstring.should_not be_blank
6
+ before(:all) do
7
+ file = File.join(File.dirname(__FILE__), 'examples', 'array.c.txt')
8
+ @parser = Parser::CParser.new(IO.read(file)).parse
9
+ end
10
+
11
+ describe 'Array class' do
12
+ it "should parse Array class" do
13
+ obj = YARD::Registry.at('Array')
14
+ obj.should_not be_nil
15
+ obj.docstring.should_not be_blank
16
+ end
17
+
18
+ it "should parse method" do
19
+ obj = YARD::Registry.at('Array#initialize')
20
+ obj.docstring.should_not be_blank
21
+ obj.tags(:overload).size.should > 1
22
+ end
18
23
  end
19
24
 
20
- it "should parse method" do
21
- obj = YARD::Registry.at('Array#initialize')
22
- obj.docstring.should_not be_blank
23
- obj.tags(:overload).size.should > 1
25
+ describe 'Source located in extra files' do
26
+ before(:all) do
27
+ @multifile = File.join(File.dirname(__FILE__), 'examples', 'multifile.c.txt')
28
+ @extrafile = File.join(File.dirname(__FILE__), 'examples', 'extrafile.c.txt')
29
+ @contents = File.read(@multifile)
30
+ end
31
+
32
+ def parse
33
+ Registry.clear
34
+ Parser::CParser.new(@contents).parse
35
+ end
36
+
37
+ it "should look for methods in extra files (if 'in' comment is found)" do
38
+ extra_contents = File.read(@extrafile)
39
+ File.should_receive(:read).with('extra.c').and_return(extra_contents)
40
+ parse
41
+ Registry.at('Multifile#extra').docstring.should == 'foo'
42
+ end
43
+
44
+ it "should stop searching for extra source file gracefully if file is not found" do
45
+ File.should_receive(:read).with('extra.c').and_raise(Errno::ENOENT)
46
+ log.should_receive(:warn).with("Missing source file `extra.c' when parsing Multifile#extra")
47
+ parse
48
+ Registry.at('Multifile#extra').docstring.should == ''
49
+ end
24
50
  end
25
51
  end
26
52
 
27
53
  describe '#find_override_comment' do
54
+ before(:all) do
55
+ override_file = File.join(File.dirname(__FILE__), 'examples', 'override.c.txt')
56
+ @override_parser = Parser::CParser.new(IO.read(override_file)).parse
57
+ end
58
+
28
59
  it "should parse GMP::Z class" do
29
60
  z = YARD::Registry.at('GMP::Z')
30
61
  z.should_not be_nil
@@ -0,0 +1,8 @@
1
+ /*
2
+ * foo
3
+ */
4
+ VALUE
5
+ rb_extra(VALUE obj, VALUE n)
6
+ {
7
+ return Qtrue;
8
+ }
@@ -0,0 +1,6 @@
1
+ void
2
+ Init_Multifile(void)
3
+ {
4
+ rb_cMultifile = rb_define_class("Multifile", rb_cObject);
5
+ rb_define_method(rb_cMultifile, "extra", rb_extra, 1); /* in extra.c */
6
+ }
@@ -198,5 +198,10 @@ describe YARD::Parser::Ruby::RubyParser do
198
198
  src = '("this is a string")'
199
199
  stmt(src).jump(:string_literal).source.should == '"this is a string"'
200
200
  end
201
+
202
+ it "should show proper source for %w() array" do
203
+ src = "%w(\na b c\n d e f\n)"
204
+ stmt(src).jump(:qwords_literal).source.should == src
205
+ end
201
206
  end
202
207
  end if HAVE_RIPPER
@@ -14,6 +14,201 @@ describe YARD::Parser::SourceParser do
14
14
  Registry.clear
15
15
  end
16
16
 
17
+ def parse_list(*list)
18
+ files = list.map do |v|
19
+ filename, source = *v
20
+ File.stub!(:read_binary).with(filename).and_return(source)
21
+ filename
22
+ end
23
+ Parser::SourceParser.send(:parse_in_order, *files)
24
+ end
25
+
26
+ def before_list(&block)
27
+ Parser::SourceParser.before_parse_list(&block)
28
+ end
29
+
30
+ def after_list(&block)
31
+ Parser::SourceParser.after_parse_list(&block)
32
+ end
33
+
34
+ def before_file(&block)
35
+ Parser::SourceParser.before_parse_file(&block)
36
+ end
37
+
38
+ def after_file(&block)
39
+ Parser::SourceParser.after_parse_file(&block)
40
+ end
41
+
42
+ describe '.before_parse_list' do
43
+ before do
44
+ Parser::SourceParser.before_parse_list_callbacks.clear
45
+ Parser::SourceParser.after_parse_list_callbacks.clear
46
+ end
47
+
48
+ it "should handle basic callback support" do
49
+ before_list do |files, globals|
50
+ files.should == ['foo.rb', 'bar.rb']
51
+ globals.should == OpenStruct.new
52
+ end
53
+ parse_list ['foo.rb', 'foo!'], ['bar.rb', 'class Foo; end']
54
+ Registry.at('Foo').should_not be_nil
55
+ end
56
+
57
+ it "should support multiple callbacks" do
58
+ checks = []
59
+ before_list { checks << :one }
60
+ before_list { checks << :two }
61
+ parse_list ['file.rb', ''], ['file2.rb', ''], ['file3.rb', 'class Foo; end']
62
+ Registry.at('Foo').should_not be_nil
63
+ checks.should == [:one, :two]
64
+ end
65
+
66
+ it "should cancel parsing if it returns false" do
67
+ checks = []
68
+ before_list { checks << :one }
69
+ before_list { false }
70
+ before_list { checks << :three }
71
+ parse_list ['file.rb', ''], ['file2.rb', ''], ['file3.rb', 'class Foo; end']
72
+ Registry.at('Foo').should be_nil
73
+ checks.should == [:one]
74
+ end
75
+
76
+ it "should not cancel on nil" do
77
+ checks = []
78
+ before_list { checks << :one }
79
+ before_list { nil }
80
+ before_list { checks << :two }
81
+ parse_list ['file.rb', ''], ['file2.rb', ''], ['file3.rb', 'class Foo; end']
82
+ Registry.at('Foo').should_not be_nil
83
+ checks.should == [:one, :two]
84
+ end
85
+
86
+ it "should pass in globals" do
87
+ before_list {|f,g| g.x = 1 }
88
+ before_list {|f,g| g.x += 1 }
89
+ before_list {|f,g| g.x += 1 }
90
+ after_list {|f,g| g.x.should == 3 }
91
+ parse_list ['file.rb', ''], ['file2.rb', ''], ['file3.rb', 'class Foo; end']
92
+ Registry.at('Foo').should_not be_nil
93
+ end
94
+ end
95
+
96
+ describe '.after_parse_list' do
97
+ before do
98
+ Parser::SourceParser.before_parse_list_callbacks.clear
99
+ Parser::SourceParser.after_parse_list_callbacks.clear
100
+ end
101
+
102
+ it "should handle basic callback support and maintain files/globals" do
103
+ before_list do |f,g| g.foo = :bar end
104
+ after_list do |files, globals|
105
+ files.should == ['foo.rb', 'bar.rb']
106
+ globals.foo.should == :bar
107
+ end
108
+ parse_list ['foo.rb', 'foo!'], ['bar.rb', 'class Foo; end']
109
+ Registry.at('Foo').should_not be_nil
110
+ end
111
+
112
+ it "should support multiple callbacks" do
113
+ checks = []
114
+ after_list { checks << :one }
115
+ after_list { checks << :two }
116
+ parse_list ['file.rb', ''], ['file2.rb', ''], ['file3.rb', 'class Foo; end']
117
+ Registry.at('Foo').should_not be_nil
118
+ checks.should == [:one, :two]
119
+ end
120
+
121
+ it "should not cancel parsing if it returns false" do
122
+ checks = []
123
+ after_list { checks << :one }
124
+ after_list { false }
125
+ after_list { checks << :three }
126
+ parse_list ['file.rb', ''], ['file2.rb', ''], ['file3.rb', 'class Foo; end']
127
+ Registry.at('Foo').should_not be_nil
128
+ checks.should == [:one, :three]
129
+ end
130
+ end
131
+
132
+ describe '.before_parse_file' do
133
+ before do
134
+ Parser::SourceParser.before_parse_file_callbacks.clear
135
+ Parser::SourceParser.after_parse_file_callbacks.clear
136
+ end
137
+
138
+ it "should handle basic callback support" do
139
+ before_file do |parser|
140
+ parser.contents.should == 'class Foo; end'
141
+ parser.file.should =~ /(foo|bar)\.rb/
142
+ end
143
+ parse_list ['foo.rb', 'class Foo; end'], ['bar.rb', 'class Foo; end']
144
+ Registry.at('Foo').should_not be_nil
145
+ end
146
+
147
+ it "should support multiple callbacks" do
148
+ checks = []
149
+ before_file { checks << :one }
150
+ before_file { checks << :two }
151
+ parse_list ['file.rb', ''], ['file2.rb', ''], ['file3.rb', 'class Foo; end']
152
+ Registry.at('Foo').should_not be_nil
153
+ checks.should == [:one, :two, :one, :two, :one, :two]
154
+ end
155
+
156
+ it "should cancel parsing if it returns false" do
157
+ checks = []
158
+ before_file { checks << :one }
159
+ before_file { false }
160
+ before_file { checks << :three }
161
+ parse_list ['file.rb', ''], ['file2.rb', ''], ['file3.rb', 'class Foo; end']
162
+ Registry.at('Foo').should be_nil
163
+ checks.should == [:one, :one, :one]
164
+ end
165
+
166
+ it "should not cancel on nil" do
167
+ checks = []
168
+ before_file { checks << :one }
169
+ before_file { nil }
170
+ before_file { checks << :two }
171
+ parse_list ['file.rb', ''], ['file2.rb', ''], ['file3.rb', 'class Foo; end']
172
+ Registry.at('Foo').should_not be_nil
173
+ checks.should == [:one, :two, :one, :two, :one, :two]
174
+ end
175
+ end
176
+
177
+ describe '.after_parse_file' do
178
+ before do
179
+ Parser::SourceParser.before_parse_file_callbacks.clear
180
+ Parser::SourceParser.after_parse_file_callbacks.clear
181
+ end
182
+
183
+ it "should handle basic callback support" do
184
+ after_file do |parser|
185
+ parser.contents.should == 'class Foo; end'
186
+ parser.file.should =~ /(foo|bar)\.rb/
187
+ end
188
+ parse_list ['foo.rb', 'class Foo; end'], ['bar.rb', 'class Foo; end']
189
+ Registry.at('Foo').should_not be_nil
190
+ end
191
+
192
+ it "should support multiple callbacks" do
193
+ checks = []
194
+ after_file { checks << :one }
195
+ after_file { checks << :two }
196
+ parse_list ['file.rb', ''], ['file2.rb', ''], ['file3.rb', 'class Foo; end']
197
+ Registry.at('Foo').should_not be_nil
198
+ checks.should == [:one, :two, :one, :two, :one, :two]
199
+ end
200
+
201
+ it "should not cancel parsing if it returns false" do
202
+ checks = []
203
+ after_file { checks << :one }
204
+ after_file { false }
205
+ after_file { checks << :three }
206
+ parse_list ['file.rb', ''], ['file2.rb', ''], ['file3.rb', 'class Foo; end']
207
+ Registry.at('Foo').should_not be_nil
208
+ checks.should == [:one, :three, :one, :three, :one, :three]
209
+ end
210
+ end
211
+
17
212
  describe '.register_parser_type' do
18
213
  it_should_behave_like "parser type registration"
19
214
 
@@ -141,6 +336,17 @@ describe YARD::Parser::SourceParser do
141
336
  Registry.at(:Hello).docstring.should == "PASS"
142
337
  end
143
338
 
339
+ it "should strip all hashes prefixed on comment line" do
340
+ YARD.parse_string(<<-eof)
341
+ ### PASS
342
+ #### PASS
343
+ ##### PASS
344
+ module Hello
345
+ end
346
+ eof
347
+ Registry.at(:Hello).docstring.should == "PASS\nPASS\nPASS"
348
+ end
349
+
144
350
  it "should handle =begin/=end style comments" do
145
351
  YARD.parse_string "=begin\nfoo\nbar\n=end\nclass Foo; end\n"
146
352
  Registry.at(:Foo).docstring.should == "foo\nbar"
@@ -168,6 +374,23 @@ describe YARD::Parser::SourceParser do
168
374
  YARD.parse_string "# encoding: utf-8\n# this is a comment\nclass Foo; end"
169
375
  Registry.at(:Foo).docstring.should == "this is a comment"
170
376
  end
377
+
378
+ it "should add macros on any object" do
379
+ YARD.parse_string <<-eof
380
+ # @macro [new] foo
381
+ # This is a macro
382
+ # @return [String] the string
383
+ class Foo
384
+ # @macro foo
385
+ def foo; end
386
+ end
387
+ eof
388
+
389
+ macro = CodeObjects::MacroObject.find('foo')
390
+ macro.macro_data.should == "This is a macro\n@return [String] the string"
391
+ Registry.at('Foo').docstring.all.should == macro.macro_data
392
+ Registry.at('Foo#foo').docstring.all.should == macro.macro_data
393
+ end
171
394
  end
172
395
 
173
396
  describe '#parse' do
@@ -270,6 +493,18 @@ describe YARD::Parser::SourceParser do
270
493
  end
271
494
  end
272
495
  end
496
+
497
+ Parser::SourceParser::ENCODING_BYTE_ORDER_MARKS.each do |encoding, bom|
498
+ it "should understand #{encoding.upcase} BOM" do
499
+ parser = Parser::SourceParser.new
500
+ src = bom + "class FooBar; end".force_encoding('binary')
501
+ src.force_encoding('binary')
502
+ File.should_receive(:read_binary).with('tmpfile').and_return(src)
503
+ result = parser.parse('tmpfile')
504
+ Registry.all(:class).first.path.should == "FooBar"
505
+ result.enumerator[0].source.encoding.to_s.downcase.should == encoding
506
+ end
507
+ end if HAVE_RIPPER && RUBY19
273
508
  end
274
509
 
275
510
  describe '#parse_in_order' do