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
@@ -0,0 +1,8 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper'
2
+
3
+ describe YARD::CLI::List do
4
+ it "should pass command off to Yardoc with --list" do
5
+ YARD::CLI::Yardoc.should_receive(:run).with('--list', '--foo')
6
+ YARD::CLI::List.run('--foo')
7
+ end
8
+ end
@@ -40,8 +40,8 @@ describe YARD::CLI::Yardoc do
40
40
  @yardoc.use_document_file.should == true
41
41
  end
42
42
 
43
- it "should use lib/**/*.rb and ext/**/*.c as default file glob" do
44
- @yardoc.files.should == ['lib/**/*.rb', 'ext/**/*.c']
43
+ it "should use {lib,app}/**/*.rb and ext/**/*.c as default file glob" do
44
+ @yardoc.files.should == ['{lib,app}/**/*.rb', 'ext/**/*.c']
45
45
  end
46
46
 
47
47
  it "should use rdoc as default markup type (but falls back on none)" do
@@ -116,6 +116,15 @@ describe YARD::CLI::Yardoc do
116
116
  @yardoc.use_yardopts_file.should == true
117
117
  end
118
118
 
119
+ should_accept('--yardopts with filename') do |arg|
120
+ @yardoc = CLI::Yardoc.new
121
+ File.should_receive(:read_binary).with('.foobar').and_return('')
122
+ @yardoc.use_document_file = false
123
+ @yardoc.parse_arguments('--yardopts', '.foobar')
124
+ @yardoc.use_yardopts_file.should == true
125
+ @yardoc.options_file.should == '.foobar'
126
+ end
127
+
119
128
  should_accept('--no-yardopts') do |arg|
120
129
  @yardoc = CLI::Yardoc.new
121
130
  @yardoc.use_document_file = false
@@ -152,7 +161,7 @@ describe YARD::CLI::Yardoc do
152
161
  Templates::Engine.should_not_receive(:generate)
153
162
  @yardoc.run(arg)
154
163
  end
155
-
164
+
156
165
  should_accept('--exclude') do |arg|
157
166
  YARD.should_receive(:parse).with(['a'], ['nota', 'b'])
158
167
  @yardoc.run(arg, 'nota', arg, 'b', 'a')
@@ -183,7 +192,7 @@ describe YARD::CLI::Yardoc do
183
192
  readme = File.join(File.dirname(__FILE__),'..','..','README.md')
184
193
 
185
194
  @yardoc.parse_arguments('--main', readme)
186
- @yardoc.options[:readme].should == readme
195
+ @yardoc.options[:readme].should == CodeObjects::ExtraFileObject.new(readme, '')
187
196
  end
188
197
 
189
198
  it "should select a markup provider when --markup-provider or -mp is set" do
@@ -192,6 +201,13 @@ describe YARD::CLI::Yardoc do
192
201
  @yardoc.parse_arguments("--markup-provider", "test2")
193
202
  @yardoc.options[:markup_provider].should == :test2
194
203
  end
204
+
205
+ it "should select a markup format when -m is set" do
206
+ @yardoc.should_receive(:verify_markup_options).and_return(true)
207
+ @yardoc.generate = true
208
+ @yardoc.parse_arguments('-m', 'markdown')
209
+ @yardoc.options[:markup].should == :markdown
210
+ end
195
211
 
196
212
  it "should accept --default-return" do
197
213
  @yardoc.parse_arguments *%w( --default-return XYZ )
@@ -387,27 +403,36 @@ describe YARD::CLI::Yardoc do
387
403
 
388
404
  describe 'Extra file arguments' do
389
405
  it "should accept extra files if specified after '-' with source files" do
406
+ Dir.should_receive(:glob).with('README*').and_return([])
390
407
  File.should_receive(:file?).with('extra_file1').and_return(true)
391
408
  File.should_receive(:file?).with('extra_file2').and_return(true)
409
+ File.should_receive(:read).with('extra_file1').and_return('')
410
+ File.should_receive(:read).with('extra_file2').and_return('')
392
411
  @yardoc.parse_arguments *%w( file1 file2 - extra_file1 extra_file2 )
393
412
  @yardoc.files.should == %w( file1 file2 )
394
- @yardoc.options[:files].should == %w( extra_file1 extra_file2 )
413
+ @yardoc.options[:files].should ==
414
+ [CodeObjects::ExtraFileObject.new('extra_file1', ''),
415
+ CodeObjects::ExtraFileObject.new('extra_file2', '')]
395
416
  end
396
417
 
397
418
  it "should accept files section only containing extra files" do
398
419
  @yardoc.parse_arguments *%w( - LICENSE )
399
- @yardoc.files.should == %w( lib/**/*.rb ext/**/*.c )
400
- @yardoc.options[:files].should == %w( LICENSE )
420
+ @yardoc.files.should == %w( {lib,app}/**/*.rb ext/**/*.c )
421
+ @yardoc.options[:files].should == [CodeObjects::ExtraFileObject.new('LICENSE', '')]
401
422
  end
402
423
 
403
424
  it "should accept globs as extra files" do
404
425
  Dir.should_receive(:glob).with('README*').and_return []
405
426
  Dir.should_receive(:glob).with('*.txt').and_return ['a.txt', 'b.txt']
427
+ File.should_receive(:read).with('a.txt').and_return('')
428
+ File.should_receive(:read).with('b.txt').and_return('')
406
429
  File.should_receive(:file?).with('a.txt').and_return(true)
407
430
  File.should_receive(:file?).with('b.txt').and_return(true)
408
431
  @yardoc.parse_arguments *%w( file1 file2 - *.txt )
409
432
  @yardoc.files.should == %w( file1 file2 )
410
- @yardoc.options[:files].should == %w( a.txt b.txt )
433
+ @yardoc.options[:files].should ==
434
+ [CodeObjects::ExtraFileObject.new('a.txt', ''),
435
+ CodeObjects::ExtraFileObject.new('b.txt', '')]
411
436
  end
412
437
 
413
438
  it "should warn if extra file is not found" do
@@ -422,9 +447,9 @@ describe YARD::CLI::Yardoc do
422
447
  end
423
448
 
424
449
  describe 'Source file arguments' do
425
- it "should accept no params and parse lib/**/*.rb ext/**/*.c" do
450
+ it "should accept no params and parse {lib,app}/**/*.rb ext/**/*.c" do
426
451
  @yardoc.parse_arguments
427
- @yardoc.files.should == %w( lib/**/*.rb ext/**/*.c )
452
+ @yardoc.files.should == %w( {lib,app}/**/*.rb ext/**/*.c )
428
453
  end
429
454
  end
430
455
 
@@ -529,6 +554,11 @@ describe YARD::CLI::Yardoc do
529
554
  @yardoc.options[:markup].should == :rdoc
530
555
  end
531
556
 
557
+ it "should load rdoc markup even when no output is specified" do
558
+ @yardoc.parse_arguments('--no-output')
559
+ @yardoc.options[:markup].should == :rdoc
560
+ end
561
+
532
562
  it "should warn if rdoc cannot be loaded and fallback to :none" do
533
563
  mod = YARD::Templates::Helpers::MarkupHelper
534
564
  mod.clear_markup_cache
@@ -537,6 +567,24 @@ describe YARD::CLI::Yardoc do
537
567
  @yardoc.generate = true
538
568
  @yardoc.run
539
569
  @yardoc.options[:markup].should == :none
570
+ mod.clear_markup_cache
571
+ end
572
+ end
573
+
574
+ describe '#run' do
575
+ it "should parse_arguments if run() is called" do
576
+ @yardoc.should_receive(:parse_arguments)
577
+ @yardoc.run
578
+ end
579
+
580
+ it "should parse_arguments if run(arg1, arg2, ...) is called" do
581
+ @yardoc.should_receive(:parse_arguments)
582
+ @yardoc.run('--private', '-p', 'foo')
583
+ end
584
+
585
+ it "should not parse_arguments if run(nil) is called" do
586
+ @yardoc.should_not_receive(:parse_arguments)
587
+ @yardoc.run(nil)
540
588
  end
541
589
  end
542
590
  end
@@ -0,0 +1,132 @@
1
+ require File.dirname(__FILE__) + '/spec_helper'
2
+
3
+ describe YARD::CodeObjects::ExtraFileObject do
4
+ describe '#initialize' do
5
+ it "should attempt to read contents from filesystem if contents=nil" do
6
+ File.should_receive(:read).with('file.txt').and_return('')
7
+ ExtraFileObject.new('file.txt')
8
+ end
9
+
10
+ it "should raise Errno::ENOENT if contents=nil and file does not exist" do
11
+ lambda { ExtraFileObject.new('file.txt') }.should raise_error(Errno::ENOENT)
12
+ end
13
+
14
+ it "should not attempt to read from disk if contents are provided" do
15
+ ExtraFileObject.new('file.txt', 'CONTENTS')
16
+ end
17
+
18
+ it "should set filename to filename" do
19
+ file = ExtraFileObject.new('a/b/c/file.txt', 'CONTENTS')
20
+ file.filename.should == "a/b/c/file.txt"
21
+ end
22
+
23
+ it "should parse out attributes at top of the file" do
24
+ file = ExtraFileObject.new('file.txt', "# @title X\n# @some_attribute Y\nFOO BAR")
25
+ file.attributes[:title].should == "X"
26
+ file.attributes[:some_attribute].should == "Y"
27
+ file.contents.should == "FOO BAR"
28
+ end
29
+
30
+ it "should allow whitespace prior to '#' marker when parsing attributes" do
31
+ file = ExtraFileObject.new('file.txt', " \t # @title X\nFOO BAR")
32
+ file.attributes[:title].should == "X"
33
+ file.contents.should == "FOO BAR"
34
+ end
35
+
36
+ it "should parse out old-style #!markup shebang format" do
37
+ file = ExtraFileObject.new('file.txt', "#!foobar\nHello")
38
+ file.attributes[:markup].should == "foobar"
39
+ end
40
+
41
+ it "should not parse old-style #!markup if any whitespace is found" do
42
+ file = ExtraFileObject.new('file.txt', " #!foobar\nHello")
43
+ file.attributes[:markup].should be_nil
44
+ file.contents.should == " #!foobar\nHello"
45
+ end
46
+
47
+ it "should not parse out attributes if there are newlines prior to attributes" do
48
+ file = ExtraFileObject.new('file.txt', "\n# @title\nFOO BAR")
49
+ file.attributes.should be_empty
50
+ file.contents.should == "\n# @title\nFOO BAR"
51
+ end
52
+
53
+ it "should set contents to data after attributes" do
54
+ file = ExtraFileObject.new('file.txt', "# @title\nFOO BAR")
55
+ file.contents.should == "FOO BAR"
56
+ end
57
+
58
+ it "should preserve newlines" do
59
+ file = ExtraFileObject.new('file.txt', "FOO\r\nBAR\nBAZ")
60
+ file.contents.should == "FOO\r\nBAR\nBAZ"
61
+ end
62
+
63
+ it "should not include newlines in attribute data" do
64
+ file = ExtraFileObject.new('file.txt', "# @title FooBar\r\nHello world")
65
+ file.attributes[:title].should == "FooBar"
66
+ end
67
+
68
+ it "should force encoding to @encoding attribute if present" do
69
+ log.should_not_receive(:warn)
70
+ data = "# @encoding sjis\nFOO"
71
+ data.force_encoding('binary')
72
+ file = ExtraFileObject.new('file.txt', data)
73
+ file.contents.encoding.to_s.should == 'Shift_JIS'
74
+ end if RUBY19
75
+
76
+ it "should warn if @encoding is invalid" do
77
+ log.should_receive(:warn).with("Invalid encoding `INVALID' in file.txt")
78
+ data = "# @encoding INVALID\nFOO"
79
+ encoding = data.encoding
80
+ file = ExtraFileObject.new('file.txt', data)
81
+ file.contents.encoding.should == encoding
82
+ end if RUBY19
83
+
84
+ it "should ignore encoding in 1.8.x (or encoding-unaware platforms)" do
85
+ log.should_not_receive(:warn)
86
+ file = ExtraFileObject.new('file.txt', "# @encoding INVALID\nFOO")
87
+ end if RUBY18
88
+
89
+ it "should attempt to re-parse data as 8bit ascii if parsing fails" do
90
+ log.should_not_receive(:warn)
91
+ str = "\xB0"
92
+ str.force_encoding('utf-8') if str.respond_to?(:force_encoding)
93
+ file = ExtraFileObject.new('file.txt', str)
94
+ file.contents.should == "\xB0"
95
+ end
96
+ end
97
+
98
+ describe '#name' do
99
+ it "should be set to basename (not extension) of filename" do
100
+ file = ExtraFileObject.new('file.txt', '')
101
+ file.name.should == 'file'
102
+ end
103
+ end
104
+
105
+ describe '#title' do
106
+ it "should return @title attribute if present" do
107
+ file = ExtraFileObject.new('file.txt', '# @title FOO')
108
+ file.title.should == 'FOO'
109
+ end
110
+
111
+ it "should return #name if no @title attribute exists" do
112
+ file = ExtraFileObject.new('file.txt', '')
113
+ file.title.should == 'file'
114
+ end
115
+ end
116
+
117
+ describe '#==' do
118
+ it "should define equality on filename alone" do
119
+ file1 = ExtraFileObject.new('file.txt', 'A')
120
+ file2 = ExtraFileObject.new('file.txt', 'B')
121
+ file1.should == file2
122
+ file1.should be_eql(file2)
123
+ file1.should be_equal(file2)
124
+
125
+ # Another way to test the equality interface
126
+ a = [file1]
127
+ a |= [file2]
128
+ a.size.should == 1
129
+ end
130
+
131
+ end
132
+ end
@@ -0,0 +1,154 @@
1
+ require File.dirname(__FILE__) + '/spec_helper'
2
+
3
+ describe YARD::CodeObjects::MacroObject do
4
+ before do
5
+ Registry.clear
6
+ end
7
+
8
+ describe '.create' do
9
+ def create(*args) MacroObject.create(*args) end
10
+
11
+ it "should create an object" do
12
+ create('foo', '')
13
+ obj = Registry.at('.macro.foo')
14
+ obj.should_not be_nil
15
+ end
16
+
17
+ it "should use identity map" do
18
+ obj1 = create('foo', '')
19
+ obj2 = create('foo', '')
20
+ obj1.object_id.should == obj2.object_id
21
+ end
22
+
23
+ it "should allow specifying of macro data" do
24
+ obj = create('foo', 'MACRODATA')
25
+ obj.macro_data.should == 'MACRODATA'
26
+ end
27
+
28
+ it "should attach if a method object is provided" do
29
+ obj = create('foo', 'MACRODATA', P('Foo.property'))
30
+ obj.method_object.should == P('Foo.property')
31
+ obj.should be_attached
32
+ end
33
+ end
34
+
35
+ describe '.find' do
36
+ before { MacroObject.create('foo', 'DATA') }
37
+
38
+ it "should search for an object by name" do
39
+ MacroObject.find('foo').macro_data.should == 'DATA'
40
+ end
41
+
42
+ it "should accept Symbol" do
43
+ MacroObject.find(:foo).macro_data.should == 'DATA'
44
+ end
45
+ end
46
+
47
+ describe '.find_or_create' do
48
+ it "should look up name if @macro is present and find object" do
49
+ macro1 = MacroObject.create('foo', 'FOO')
50
+ macro2 = MacroObject.find_or_create("@macro foo\na b c")
51
+ macro1.should == macro2
52
+ end
53
+
54
+ it "should create new macro if macro by that name does not exist" do
55
+ MacroObject.find_or_create("@macro foo\n @method $1\nEXTRA")
56
+ MacroObject.find('foo').macro_data.should == "@method $1"
57
+ end
58
+
59
+ it "should use full docstring if no text block is present in @macro" do
60
+ MacroObject.find_or_create("@macro foo\n@method $1\nEXTRA")
61
+ MacroObject.find('foo').macro_data.should == "EXTRA\n@method $1"
62
+ end
63
+ end
64
+
65
+ describe '.apply' do
66
+ before do
67
+ @args = %w(foo a b c)
68
+ end
69
+
70
+ def apply(comments)
71
+ MacroObject.apply(comments, @args)
72
+ end
73
+
74
+ it "should only expand macros if @macro is present" do
75
+ apply("$1$2$3").should == "$1$2$3"
76
+ end
77
+
78
+ it "should handle macro text inside block" do
79
+ apply("@macro name\n foo$1$2$3\nfoobaz").should == "fooabc\nfoobaz"
80
+ end
81
+
82
+ it "should append docstring to existing macro" do
83
+ macro = MacroObject.create('name', '$3$2$1')
84
+ result = MacroObject.apply("@macro name\nfoobar", @args)
85
+ result.should == "cba\nfoobar"
86
+ end
87
+
88
+ it "should use only non macro data if docstring is an existing macro" do
89
+ data = "@macro name\n $3$2$1\nEXTRA"
90
+ MacroObject.find_or_create(data)
91
+ result = MacroObject.apply(data, @args)
92
+ result.should == "cba\nEXTRA"
93
+ MacroObject.apply("@macro name\nFOO", @args).should == "cba\nFOO"
94
+ end
95
+
96
+ it "should create macros if they don't exist" do
97
+ result = MacroObject.apply("@macro name\n foo!$1", @args)
98
+ result.should == "foo!a"
99
+ MacroObject.find('name').macro_data.should == 'foo!$1'
100
+ end
101
+
102
+ it "should keep other tags" do
103
+ apply("@macro name\n foo$1$2$3\n@param name foo\nfoo").should ==
104
+ "fooabc\nfoo\n@param name\n foo"
105
+ end
106
+ end
107
+
108
+ describe '.expand' do
109
+ def expand(comments)
110
+ args = %w(foo a b c)
111
+ full_line = 'foo :bar, :baz'
112
+ MacroObject.expand(comments, args, full_line)
113
+ end
114
+
115
+ it "should allow escaping of macro syntax" do
116
+ expand("$1\\$2$3").should == "a$2c"
117
+ end
118
+
119
+ it "should replace $* with the whole statement" do
120
+ expand("$* ${*}").should == "foo :bar, :baz foo :bar, :baz"
121
+ end
122
+
123
+ it "should replace $0 with method name" do
124
+ expand("$0 ${0}").should == "foo foo"
125
+ end
126
+
127
+ it "should replace all $N values with the Nth argument in the method call" do
128
+ expand("$1$2$3${3}\nfoobar").should == "abcc\nfoobar"
129
+ end
130
+
131
+ it "should replace ${N-M} ranges with N-M arguments (incl. commas)" do
132
+ expand("${1-2}x").should == "a, bx"
133
+ end
134
+
135
+ it "should handle open ended ranges (${N-})" do
136
+ expand("${2-}").should == "b, c"
137
+ end
138
+
139
+ it "should handle negative indexes ($-N)" do
140
+ expand("$-1 ${-2-} ${-2--2}").should == "c b, c b"
141
+ end
142
+
143
+ it "should accept Docstring objects" do
144
+ expand(Docstring.new("$1\n@param name foo")).should == "a\n@param name foo"
145
+ end
146
+ end
147
+
148
+ describe '#expand' do
149
+ it "should expand macro given its data" do
150
+ macro = MacroObject.create_docstring("@macro foo\n $1 $2 THREE!")
151
+ macro.expand(['NAME', 'ONE', 'TWO']).should == "ONE TWO THREE!"
152
+ end
153
+ end
154
+ end
@@ -29,6 +29,18 @@ describe YARD::Docstring do
29
29
  end
30
30
  end
31
31
 
32
+ describe '#line' do
33
+ it "should return nil if #line_range is not set" do
34
+ Docstring.new('foo').line.should be_nil
35
+ end
36
+
37
+ it "should return line_range.first if #line_range is set" do
38
+ doc = Docstring.new('foo')
39
+ doc.line_range = (1..10)
40
+ doc.line.should == doc.line_range.first
41
+ end
42
+ end
43
+
32
44
  describe '#summary' do
33
45
  it "should handle empty docstrings" do
34
46
  o1 = Docstring.new
@@ -307,4 +319,82 @@ eof
307
319
  doc.tag(:api).text.should == "private"
308
320
  end
309
321
  end
322
+
323
+ describe '#delete_tags' do
324
+ it "should delete tags by a given tag name" do
325
+ doc = Docstring.new("@param name x\n@param name2 y\n@return foo")
326
+ doc.delete_tags(:param)
327
+ doc.tags.size.should == 1
328
+ end
329
+ end
330
+
331
+ describe '#delete_tag_if' do
332
+ it "should delete tags for a given block" do
333
+ doc = Docstring.new("@param name x\n@param name2 y\n@return foo")
334
+ doc.delete_tag_if {|t| t.name == 'name2' }
335
+ doc.tags.size.should == 2
336
+ end
337
+ end
338
+
339
+ describe '#to_raw' do
340
+ it "should return a clean representation of tags" do
341
+ doc = Docstring.new("Hello world\n@return [String, X] foobar\n@param name<Array> the name\nBYE!")
342
+ doc.to_raw.should == "Hello world\nBYE!\n@param [Array] name\n the name\n@return [String, X] foobar"
343
+ end
344
+
345
+ it "should handle tags with newlines and indentation" do
346
+ doc = Docstring.new("@example TITLE\n the \n example\n @foo\n@param [X] name\n the name")
347
+ doc.to_raw.should == "@example TITLE\n the \n example\n @foo\n@param [X] name\n the name"
348
+ end
349
+
350
+ it "should handle deleted tags" do
351
+ doc = Docstring.new("@example TITLE\n the \n example\n @foo\n@param [X] name\n the name")
352
+ doc.delete_tags(:param)
353
+ doc.to_raw.should == "@example TITLE\n the \n example\n @foo"
354
+ end
355
+
356
+ it "should handle added tags" do
357
+ doc = Docstring.new("@example TITLE\n the \n example\n @foo")
358
+ doc.add_tag(Tags::Tag.new('foo', 'foo'))
359
+ doc.to_raw.should == "@example TITLE\n the \n example\n @foo\n@foo foo"
360
+ end
361
+
362
+ it "should be equal to .all if not modified" do
363
+ doc = Docstring.new("123\n@param")
364
+ doc.to_raw.should == doc.all
365
+ end
366
+ end
367
+
368
+ describe '#dup' do
369
+ it "should duplicate docstring text" do
370
+ doc = Docstring.new("foo")
371
+ doc.dup.should == doc
372
+ doc.dup.all.should == doc
373
+ end
374
+
375
+ it "should duplicate tags to new list" do
376
+ doc = Docstring.new("@param x\n@return y")
377
+ doc2 = doc.dup
378
+ doc2.delete_tags(:param)
379
+ doc.tags.size.should == 2
380
+ doc2.tags.size.should == 1
381
+ end
382
+
383
+ it "should preserve summary" do
384
+ doc = Docstring.new("foo. bar")
385
+ doc.dup.summary.should == doc.summary
386
+ end
387
+
388
+ it "should preserve hash_flag" do
389
+ doc = Docstring.new
390
+ doc.hash_flag = 'foo'
391
+ doc.dup.hash_flag.should == doc.hash_flag
392
+ end
393
+
394
+ it "should preserve line_range" do
395
+ doc = Docstring.new
396
+ doc.line_range = (1..2)
397
+ doc.dup.line_range.should == doc.line_range
398
+ end
399
+ end
310
400
  end