yard 0.9.17 → 0.9.22

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 (590) hide show
  1. checksums.yaml +4 -4
  2. data/.dockerignore +2 -0
  3. data/.github/ISSUE_TEMPLATE.md +33 -0
  4. data/.github/PULL_REQUEST_TEMPLATE.md +12 -0
  5. data/.gitignore +14 -0
  6. data/.rspec +2 -0
  7. data/.rubocop.yml +99 -0
  8. data/.travis.yml +52 -0
  9. data/.yardopts +26 -26
  10. data/.yardopts_guide +19 -0
  11. data/.yardopts_i18n +23 -0
  12. data/CHANGELOG.md +774 -728
  13. data/CODE_OF_CONDUCT.md +15 -0
  14. data/CONTRIBUTING.md +140 -0
  15. data/Dockerfile.samus +28 -0
  16. data/Gemfile +32 -0
  17. data/LEGAL +66 -66
  18. data/LICENSE +22 -22
  19. data/README.md +330 -328
  20. data/Rakefile +37 -53
  21. data/SECURITY.md +26 -0
  22. data/benchmarks/builtins_vs_eval.rb +24 -24
  23. data/benchmarks/concat_vs_join.rb +13 -13
  24. data/benchmarks/erb_vs_erubis.rb +54 -54
  25. data/benchmarks/format_args.rb +47 -47
  26. data/benchmarks/generation.rb +38 -38
  27. data/benchmarks/marshal_vs_dbm.rb +64 -64
  28. data/benchmarks/parsing.rb +46 -46
  29. data/benchmarks/pathname_vs_string.rb +50 -50
  30. data/benchmarks/rdoc_vs_yardoc.rb +11 -11
  31. data/benchmarks/registry_store_types.rb +49 -49
  32. data/benchmarks/ri_vs_yri.rb +19 -19
  33. data/benchmarks/ripper_parser.rb +13 -13
  34. data/benchmarks/splat_vs_flatten.rb +13 -13
  35. data/benchmarks/template_erb.rb +23 -23
  36. data/benchmarks/template_format.rb +7 -7
  37. data/benchmarks/template_profile.rb +18 -18
  38. data/benchmarks/yri_cache.rb +20 -20
  39. data/bin/yard +13 -13
  40. data/bin/yardoc +13 -13
  41. data/bin/yri +13 -13
  42. data/docs/CodeObjects.md +115 -115
  43. data/docs/GettingStarted.md +679 -679
  44. data/docs/Handlers.md +152 -152
  45. data/docs/Overview.md +61 -61
  46. data/docs/Parser.md +191 -191
  47. data/docs/Tags.md +283 -283
  48. data/docs/TagsArch.md +123 -123
  49. data/docs/Templates.md +496 -496
  50. data/docs/WhatsNew.md +1245 -1245
  51. data/docs/templates/default/fulldoc/html/full_list_tag.erb +8 -8
  52. data/docs/templates/default/fulldoc/html/setup.rb +6 -6
  53. data/docs/templates/default/layout/html/setup.rb +9 -9
  54. data/docs/templates/default/layout/html/tag_list.erb +11 -11
  55. data/docs/templates/default/yard_tags/html/list.erb +18 -18
  56. data/docs/templates/default/yard_tags/html/setup.rb +26 -26
  57. data/docs/templates/plugin.rb +70 -70
  58. data/lib/rubygems_plugin.rb +9 -9
  59. data/lib/yard.rb +69 -69
  60. data/lib/yard/autoload.rb +308 -303
  61. data/lib/yard/cli/command.rb +85 -85
  62. data/lib/yard/cli/command_parser.rb +93 -93
  63. data/lib/yard/cli/config.rb +198 -198
  64. data/lib/yard/cli/diff.rb +270 -270
  65. data/lib/yard/cli/display.rb +69 -69
  66. data/lib/yard/cli/gems.rb +84 -84
  67. data/lib/yard/cli/graph.rb +125 -125
  68. data/lib/yard/cli/help.rb +20 -20
  69. data/lib/yard/cli/i18n.rb +70 -70
  70. data/lib/yard/cli/list.rb +23 -23
  71. data/lib/yard/cli/markup_types.rb +32 -32
  72. data/lib/yard/cli/server.rb +257 -257
  73. data/lib/yard/cli/stats.rb +231 -231
  74. data/lib/yard/cli/yardoc.rb +789 -788
  75. data/lib/yard/cli/yardopts_command.rb +110 -110
  76. data/lib/yard/cli/yri.rb +215 -215
  77. data/lib/yard/code_objects/base.rb +622 -615
  78. data/lib/yard/code_objects/class_object.rb +146 -146
  79. data/lib/yard/code_objects/class_variable_object.rb +11 -11
  80. data/lib/yard/code_objects/constant_object.rb +16 -16
  81. data/lib/yard/code_objects/extended_method_object.rb +24 -24
  82. data/lib/yard/code_objects/extra_file_object.rb +134 -131
  83. data/lib/yard/code_objects/macro_object.rb +172 -172
  84. data/lib/yard/code_objects/method_object.rb +196 -196
  85. data/lib/yard/code_objects/module_object.rb +21 -21
  86. data/lib/yard/code_objects/namespace_mapper.rb +114 -114
  87. data/lib/yard/code_objects/namespace_object.rb +200 -200
  88. data/lib/yard/code_objects/proxy.rb +244 -240
  89. data/lib/yard/code_objects/root_object.rb +19 -19
  90. data/lib/yard/config.rb +270 -270
  91. data/lib/yard/core_ext/array.rb +16 -16
  92. data/lib/yard/core_ext/file.rb +69 -69
  93. data/lib/yard/core_ext/hash.rb +16 -16
  94. data/lib/yard/core_ext/insertion.rb +63 -63
  95. data/lib/yard/core_ext/module.rb +11 -20
  96. data/lib/yard/core_ext/string.rb +68 -68
  97. data/lib/yard/core_ext/symbol_hash.rb +75 -75
  98. data/lib/yard/docstring.rb +386 -386
  99. data/lib/yard/docstring_parser.rb +345 -345
  100. data/lib/yard/gem_index.rb +29 -29
  101. data/lib/yard/globals.rb +22 -22
  102. data/lib/yard/handlers/base.rb +595 -595
  103. data/lib/yard/handlers/c/alias_handler.rb +16 -16
  104. data/lib/yard/handlers/c/attribute_handler.rb +13 -13
  105. data/lib/yard/handlers/c/base.rb +129 -129
  106. data/lib/yard/handlers/c/class_handler.rb +27 -27
  107. data/lib/yard/handlers/c/constant_handler.rb +13 -13
  108. data/lib/yard/handlers/c/handler_methods.rb +212 -211
  109. data/lib/yard/handlers/c/init_handler.rb +20 -20
  110. data/lib/yard/handlers/c/method_handler.rb +45 -45
  111. data/lib/yard/handlers/c/mixin_handler.rb +21 -21
  112. data/lib/yard/handlers/c/module_handler.rb +17 -17
  113. data/lib/yard/handlers/c/override_comment_handler.rb +31 -31
  114. data/lib/yard/handlers/c/path_handler.rb +11 -11
  115. data/lib/yard/handlers/c/struct_handler.rb +13 -13
  116. data/lib/yard/handlers/c/symbol_handler.rb +8 -8
  117. data/lib/yard/handlers/common/method_handler.rb +19 -0
  118. data/lib/yard/handlers/processor.rb +200 -200
  119. data/lib/yard/handlers/ruby/alias_handler.rb +45 -44
  120. data/lib/yard/handlers/ruby/attribute_handler.rb +87 -87
  121. data/lib/yard/handlers/ruby/base.rb +165 -165
  122. data/lib/yard/handlers/ruby/class_condition_handler.rb +92 -92
  123. data/lib/yard/handlers/ruby/class_handler.rb +119 -119
  124. data/lib/yard/handlers/ruby/class_variable_handler.rb +17 -17
  125. data/lib/yard/handlers/ruby/comment_handler.rb +10 -10
  126. data/lib/yard/handlers/ruby/constant_handler.rb +55 -59
  127. data/lib/yard/handlers/ruby/decorator_handler_methods.rb +123 -123
  128. data/lib/yard/handlers/ruby/dsl_handler.rb +15 -15
  129. data/lib/yard/handlers/ruby/dsl_handler_methods.rb +96 -96
  130. data/lib/yard/handlers/ruby/exception_handler.rb +27 -27
  131. data/lib/yard/handlers/ruby/extend_handler.rb +22 -22
  132. data/lib/yard/handlers/ruby/legacy/alias_handler.rb +37 -37
  133. data/lib/yard/handlers/ruby/legacy/attribute_handler.rb +65 -65
  134. data/lib/yard/handlers/ruby/legacy/base.rb +245 -245
  135. data/lib/yard/handlers/ruby/legacy/class_condition_handler.rb +83 -83
  136. data/lib/yard/handlers/ruby/legacy/class_handler.rb +113 -113
  137. data/lib/yard/handlers/ruby/legacy/class_variable_handler.rb +15 -15
  138. data/lib/yard/handlers/ruby/legacy/comment_handler.rb +10 -10
  139. data/lib/yard/handlers/ruby/legacy/constant_handler.rb +29 -29
  140. data/lib/yard/handlers/ruby/legacy/dsl_handler.rb +17 -17
  141. data/lib/yard/handlers/ruby/legacy/exception_handler.rb +13 -13
  142. data/lib/yard/handlers/ruby/legacy/extend_handler.rb +21 -21
  143. data/lib/yard/handlers/ruby/legacy/method_handler.rb +90 -90
  144. data/lib/yard/handlers/ruby/legacy/mixin_handler.rb +39 -39
  145. data/lib/yard/handlers/ruby/legacy/module_function_handler.rb +19 -19
  146. data/lib/yard/handlers/ruby/legacy/module_handler.rb +12 -12
  147. data/lib/yard/handlers/ruby/legacy/private_class_method_handler.rb +22 -22
  148. data/lib/yard/handlers/ruby/legacy/private_constant_handler.rb +22 -22
  149. data/lib/yard/handlers/ruby/legacy/visibility_handler.rb +17 -17
  150. data/lib/yard/handlers/ruby/legacy/yield_handler.rb +29 -29
  151. data/lib/yard/handlers/ruby/method_condition_handler.rb +9 -9
  152. data/lib/yard/handlers/ruby/method_handler.rb +104 -118
  153. data/lib/yard/handlers/ruby/mixin_handler.rb +49 -37
  154. data/lib/yard/handlers/ruby/module_function_handler.rb +27 -27
  155. data/lib/yard/handlers/ruby/module_handler.rb +12 -12
  156. data/lib/yard/handlers/ruby/private_class_method_handler.rb +14 -14
  157. data/lib/yard/handlers/ruby/private_constant_handler.rb +43 -43
  158. data/lib/yard/handlers/ruby/public_class_method_handler.rb +14 -14
  159. data/lib/yard/handlers/ruby/struct_handler_methods.rb +143 -143
  160. data/lib/yard/handlers/ruby/visibility_handler.rb +22 -22
  161. data/lib/yard/handlers/ruby/yield_handler.rb +31 -31
  162. data/lib/yard/i18n/locale.rb +67 -67
  163. data/lib/yard/i18n/message.rb +57 -57
  164. data/lib/yard/i18n/messages.rb +56 -56
  165. data/lib/yard/i18n/po_parser.rb +61 -61
  166. data/lib/yard/i18n/pot_generator.rb +290 -290
  167. data/lib/yard/i18n/text.rb +173 -173
  168. data/lib/yard/logging.rb +205 -205
  169. data/lib/yard/options.rb +217 -217
  170. data/lib/yard/parser/base.rb +57 -57
  171. data/lib/yard/parser/c/c_parser.rb +235 -235
  172. data/lib/yard/parser/c/comment_parser.rb +134 -134
  173. data/lib/yard/parser/c/statement.rb +66 -64
  174. data/lib/yard/parser/ruby/ast_node.rb +551 -540
  175. data/lib/yard/parser/ruby/legacy/irb/slex.rb +276 -0
  176. data/lib/yard/parser/ruby/legacy/ruby_lex.rb +1345 -1354
  177. data/lib/yard/parser/ruby/legacy/ruby_parser.rb +32 -32
  178. data/lib/yard/parser/ruby/legacy/statement.rb +68 -66
  179. data/lib/yard/parser/ruby/legacy/statement_list.rb +394 -394
  180. data/lib/yard/parser/ruby/legacy/token_list.rb +74 -74
  181. data/lib/yard/parser/ruby/ruby_parser.rb +699 -687
  182. data/lib/yard/parser/ruby/token_resolver.rb +156 -156
  183. data/lib/yard/parser/source_parser.rb +526 -526
  184. data/lib/yard/rake/yardoc_task.rb +81 -81
  185. data/lib/yard/registry.rb +439 -439
  186. data/lib/yard/registry_resolver.rb +231 -189
  187. data/lib/yard/registry_store.rb +342 -337
  188. data/lib/yard/rubygems/backports.rb +10 -10
  189. data/lib/yard/rubygems/backports/LICENSE.txt +57 -57
  190. data/lib/yard/rubygems/backports/MIT.txt +20 -20
  191. data/lib/yard/rubygems/backports/gem.rb +10 -10
  192. data/lib/yard/rubygems/backports/source_index.rb +365 -365
  193. data/lib/yard/rubygems/doc_manager.rb +90 -90
  194. data/lib/yard/rubygems/hook.rb +197 -197
  195. data/lib/yard/rubygems/specification.rb +50 -50
  196. data/lib/yard/serializers/base.rb +83 -83
  197. data/lib/yard/serializers/file_system_serializer.rb +123 -123
  198. data/lib/yard/serializers/process_serializer.rb +24 -24
  199. data/lib/yard/serializers/stdout_serializer.rb +34 -34
  200. data/lib/yard/serializers/yardoc_serializer.rb +152 -152
  201. data/lib/yard/server.rb +13 -13
  202. data/lib/yard/server/adapter.rb +100 -100
  203. data/lib/yard/server/commands/base.rb +209 -209
  204. data/lib/yard/server/commands/display_file_command.rb +29 -29
  205. data/lib/yard/server/commands/display_object_command.rb +65 -65
  206. data/lib/yard/server/commands/frames_command.rb +16 -16
  207. data/lib/yard/server/commands/library_command.rb +187 -187
  208. data/lib/yard/server/commands/library_index_command.rb +28 -28
  209. data/lib/yard/server/commands/list_command.rb +25 -25
  210. data/lib/yard/server/commands/root_request_command.rb +15 -15
  211. data/lib/yard/server/commands/search_command.rb +79 -79
  212. data/lib/yard/server/commands/static_file_command.rb +23 -23
  213. data/lib/yard/server/commands/static_file_helpers.rb +61 -62
  214. data/lib/yard/server/doc_server_helper.rb +91 -91
  215. data/lib/yard/server/doc_server_serializer.rb +39 -39
  216. data/lib/yard/server/library_version.rb +277 -277
  217. data/lib/yard/server/rack_adapter.rb +89 -89
  218. data/lib/yard/server/router.rb +187 -187
  219. data/lib/yard/server/static_caching.rb +46 -46
  220. data/lib/yard/server/templates/default/fulldoc/html/css/custom.css +127 -127
  221. data/lib/yard/server/templates/default/fulldoc/html/js/autocomplete.js +11 -11
  222. data/lib/yard/server/templates/default/layout/html/breadcrumb.erb +37 -37
  223. data/lib/yard/server/templates/default/layout/html/script_setup.erb +7 -7
  224. data/lib/yard/server/templates/default/layout/html/setup.rb +8 -8
  225. data/lib/yard/server/templates/default/method_details/html/permalink.erb +4 -4
  226. data/lib/yard/server/templates/default/method_details/html/setup.rb +5 -5
  227. data/lib/yard/server/templates/doc_server/library_list/html/headers.erb +8 -8
  228. data/lib/yard/server/templates/doc_server/library_list/html/library_list.erb +14 -14
  229. data/lib/yard/server/templates/doc_server/library_list/html/listing.erb +13 -13
  230. data/lib/yard/server/templates/doc_server/library_list/html/setup.rb +6 -6
  231. data/lib/yard/server/templates/doc_server/library_list/html/title.erb +2 -2
  232. data/lib/yard/server/templates/doc_server/processing/html/processing.erb +52 -52
  233. data/lib/yard/server/templates/doc_server/processing/html/setup.rb +4 -4
  234. data/lib/yard/server/templates/doc_server/search/html/search.erb +18 -18
  235. data/lib/yard/server/templates/doc_server/search/html/setup.rb +9 -9
  236. data/lib/yard/server/webrick_adapter.rb +45 -45
  237. data/lib/yard/tags/default_factory.rb +191 -191
  238. data/lib/yard/tags/default_tag.rb +13 -13
  239. data/lib/yard/tags/directives.rb +616 -616
  240. data/lib/yard/tags/library.rb +633 -633
  241. data/lib/yard/tags/option_tag.rb +13 -13
  242. data/lib/yard/tags/overload_tag.rb +71 -71
  243. data/lib/yard/tags/ref_tag.rb +8 -8
  244. data/lib/yard/tags/ref_tag_list.rb +28 -28
  245. data/lib/yard/tags/tag.rb +71 -71
  246. data/lib/yard/tags/tag_format_error.rb +7 -7
  247. data/lib/yard/tags/types_explainer.rb +162 -162
  248. data/lib/yard/templates/engine.rb +186 -186
  249. data/lib/yard/templates/erb_cache.rb +23 -23
  250. data/lib/yard/templates/helpers/base_helper.rb +215 -215
  251. data/lib/yard/templates/helpers/filter_helper.rb +27 -27
  252. data/lib/yard/templates/helpers/html_helper.rb +663 -646
  253. data/lib/yard/templates/helpers/html_syntax_highlight_helper.rb +78 -78
  254. data/lib/yard/templates/helpers/markup/rdoc_markdown.rb +23 -23
  255. data/lib/yard/templates/helpers/markup/rdoc_markup.rb +109 -109
  256. data/lib/yard/templates/helpers/markup_helper.rb +172 -172
  257. data/lib/yard/templates/helpers/method_helper.rb +75 -75
  258. data/lib/yard/templates/helpers/module_helper.rb +21 -21
  259. data/lib/yard/templates/helpers/text_helper.rb +112 -112
  260. data/lib/yard/templates/helpers/uml_helper.rb +47 -47
  261. data/lib/yard/templates/section.rb +105 -105
  262. data/lib/yard/templates/template.rb +418 -418
  263. data/lib/yard/templates/template_options.rb +92 -92
  264. data/lib/yard/verifier.rb +151 -151
  265. data/lib/yard/version.rb +6 -6
  266. data/po/ja.po +31108 -0
  267. data/samus.json +80 -0
  268. data/spec/cli/command_parser_spec.rb +43 -43
  269. data/spec/cli/command_spec.rb +36 -36
  270. data/spec/cli/config_spec.rb +148 -148
  271. data/spec/cli/diff_spec.rb +254 -254
  272. data/spec/cli/display_spec.rb +30 -30
  273. data/spec/cli/gems_spec.rb +81 -81
  274. data/spec/cli/graph_spec.rb +18 -18
  275. data/spec/cli/help_spec.rb +22 -22
  276. data/spec/cli/i18n_spec.rb +107 -107
  277. data/spec/cli/list_spec.rb +8 -8
  278. data/spec/cli/markup_types_spec.rb +22 -22
  279. data/spec/cli/server_spec.rb +324 -324
  280. data/spec/cli/stats_spec.rb +96 -96
  281. data/spec/cli/yard_on_yard_spec.rb +38 -38
  282. data/spec/cli/yardoc_spec.rb +896 -862
  283. data/spec/cli/yri_spec.rb +101 -101
  284. data/spec/code_objects/base_spec.rb +485 -470
  285. data/spec/code_objects/class_object_spec.rb +226 -226
  286. data/spec/code_objects/code_object_list_spec.rb +36 -36
  287. data/spec/code_objects/constants_spec.rb +116 -116
  288. data/spec/code_objects/extra_file_object_spec.rb +161 -160
  289. data/spec/code_objects/macro_object_spec.rb +150 -150
  290. data/spec/code_objects/method_object_spec.rb +184 -184
  291. data/spec/code_objects/module_object_spec.rb +142 -142
  292. data/spec/code_objects/namespace_object_spec.rb +171 -171
  293. data/spec/code_objects/proxy_spec.rb +147 -141
  294. data/spec/code_objects/spec_helper.rb +3 -3
  295. data/spec/config_spec.rb +171 -171
  296. data/spec/core_ext/array_spec.rb +13 -13
  297. data/spec/core_ext/file_spec.rb +72 -72
  298. data/spec/core_ext/hash_spec.rb +14 -14
  299. data/spec/core_ext/insertion_spec.rb +37 -37
  300. data/spec/core_ext/module_spec.rb +9 -15
  301. data/spec/core_ext/string_spec.rb +42 -42
  302. data/spec/core_ext/symbol_hash_spec.rb +89 -89
  303. data/spec/docstring_parser_spec.rb +280 -280
  304. data/spec/docstring_spec.rb +373 -373
  305. data/spec/handlers/alias_handler_spec.rb +82 -82
  306. data/spec/handlers/attribute_handler_spec.rb +96 -96
  307. data/spec/handlers/base_spec.rb +216 -216
  308. data/spec/handlers/c/alias_handler_spec.rb +34 -34
  309. data/spec/handlers/c/attribute_handler_spec.rb +41 -41
  310. data/spec/handlers/c/class_handler_spec.rb +78 -78
  311. data/spec/handlers/c/constant_handler_spec.rb +71 -71
  312. data/spec/handlers/c/init_handler_spec.rb +48 -48
  313. data/spec/handlers/c/method_handler_spec.rb +327 -325
  314. data/spec/handlers/c/mixin_handler_spec.rb +44 -44
  315. data/spec/handlers/c/module_handler_spec.rb +71 -71
  316. data/spec/handlers/c/override_comment_handler_spec.rb +47 -47
  317. data/spec/handlers/c/path_handler_spec.rb +36 -36
  318. data/spec/handlers/c/spec_helper.rb +23 -23
  319. data/spec/handlers/c/struct_handler_spec.rb +16 -16
  320. data/spec/handlers/class_condition_handler_spec.rb +87 -87
  321. data/spec/handlers/class_handler_spec.rb +247 -247
  322. data/spec/handlers/class_method_handler_shared_examples.rb +133 -133
  323. data/spec/handlers/class_variable_handler_spec.rb +12 -12
  324. data/spec/handlers/constant_handler_spec.rb +112 -112
  325. data/spec/handlers/decorator_handler_methods_spec.rb +393 -393
  326. data/spec/handlers/dsl_handler_spec.rb +226 -219
  327. data/spec/handlers/examples/alias_handler_001.rb.txt +45 -45
  328. data/spec/handlers/examples/attribute_handler_001.rb.txt +31 -31
  329. data/spec/handlers/examples/class_condition_handler_001.rb.txt +68 -68
  330. data/spec/handlers/examples/class_handler_001.rb.txt +120 -120
  331. data/spec/handlers/examples/class_variable_handler_001.rb.txt +9 -9
  332. data/spec/handlers/examples/constant_handler_001.rb.txt +35 -35
  333. data/spec/handlers/examples/dsl_handler_001.rb.txt +156 -154
  334. data/spec/handlers/examples/exception_handler_001.rb.txt +58 -58
  335. data/spec/handlers/examples/extend_handler_001.rb.txt +19 -16
  336. data/spec/handlers/examples/method_condition_handler_001.rb.txt +9 -9
  337. data/spec/handlers/examples/method_handler_001.rb.txt +128 -128
  338. data/spec/handlers/examples/mixin_handler_001.rb.txt +40 -37
  339. data/spec/handlers/examples/module_handler_001.rb.txt +29 -29
  340. data/spec/handlers/examples/private_constant_handler_001.rb.txt +8 -8
  341. data/spec/handlers/examples/process_handler_001.rb.txt +11 -11
  342. data/spec/handlers/examples/visibility_handler_001.rb.txt +35 -35
  343. data/spec/handlers/examples/yield_handler_001.rb.txt +54 -54
  344. data/spec/handlers/exception_handler_spec.rb +49 -49
  345. data/spec/handlers/extend_handler_spec.rb +28 -24
  346. data/spec/handlers/legacy_base_spec.rb +128 -128
  347. data/spec/handlers/method_condition_handler_spec.rb +15 -15
  348. data/spec/handlers/method_handler_spec.rb +214 -190
  349. data/spec/handlers/mixin_handler_spec.rb +60 -56
  350. data/spec/handlers/module_function_handler_spec.rb +106 -106
  351. data/spec/handlers/module_handler_spec.rb +35 -35
  352. data/spec/handlers/private_class_method_handler_spec.rb +11 -11
  353. data/spec/handlers/private_constant_handler_spec.rb +25 -25
  354. data/spec/handlers/processor_spec.rb +35 -35
  355. data/spec/handlers/public_class_method_handler_spec.rb +11 -11
  356. data/spec/handlers/ruby/base_spec.rb +95 -95
  357. data/spec/handlers/ruby/legacy/base_spec.rb +84 -84
  358. data/spec/handlers/spec_helper.rb +33 -33
  359. data/spec/handlers/visibility_handler_spec.rb +44 -44
  360. data/spec/handlers/yield_handler_spec.rb +52 -52
  361. data/spec/i18n/locale_spec.rb +81 -81
  362. data/spec/i18n/message_spec.rb +52 -52
  363. data/spec/i18n/messages_spec.rb +67 -67
  364. data/spec/i18n/pot_generator_spec.rb +295 -295
  365. data/spec/i18n/text_spec.rb +184 -184
  366. data/spec/logging_spec.rb +44 -44
  367. data/spec/options_spec.rb +171 -171
  368. data/spec/parser/base_spec.rb +24 -24
  369. data/spec/parser/c_parser_spec.rb +236 -236
  370. data/spec/parser/examples/array.c.txt +6267 -6267
  371. data/spec/parser/examples/example1.rb.txt +7 -7
  372. data/spec/parser/examples/extrafile.c.txt +8 -8
  373. data/spec/parser/examples/file.c.txt +28 -28
  374. data/spec/parser/examples/multifile.c.txt +22 -22
  375. data/spec/parser/examples/namespace.cpp.txt +68 -68
  376. data/spec/parser/examples/override.c.txt +424 -424
  377. data/spec/parser/examples/parse_in_order_001.rb.txt +2 -2
  378. data/spec/parser/examples/parse_in_order_002.rb.txt +1 -1
  379. data/spec/parser/examples/tag_handler_001.rb.txt +7 -7
  380. data/spec/parser/ruby/ast_node_spec.rb +33 -33
  381. data/spec/parser/ruby/legacy/statement_list_spec.rb +299 -299
  382. data/spec/parser/ruby/legacy/token_list_spec.rb +79 -79
  383. data/spec/parser/ruby/ruby_parser_spec.rb +508 -508
  384. data/spec/parser/ruby/token_resolver_spec.rb +165 -165
  385. data/spec/parser/source_parser_spec.rb +727 -727
  386. data/spec/parser/tag_parsing_spec.rb +17 -17
  387. data/spec/rake/yardoc_task_spec.rb +118 -118
  388. data/spec/registry_spec.rb +463 -463
  389. data/spec/registry_store_spec.rb +327 -316
  390. data/spec/rubygems/doc_manager_spec.rb +112 -112
  391. data/spec/serializers/data/serialized_yardoc/checksums +1 -1
  392. data/spec/serializers/file_system_serializer_spec.rb +145 -145
  393. data/spec/serializers/spec_helper.rb +2 -2
  394. data/spec/serializers/yardoc_serializer_spec.rb +78 -78
  395. data/spec/server/adapter_spec.rb +39 -39
  396. data/spec/server/commands/base_spec.rb +91 -91
  397. data/spec/server/commands/library_command_spec.rb +39 -39
  398. data/spec/server/doc_server_helper_spec.rb +72 -72
  399. data/spec/server/doc_server_serializer_spec.rb +60 -60
  400. data/spec/server/rack_adapter_spec.rb +21 -21
  401. data/spec/server/router_spec.rb +123 -123
  402. data/spec/server/spec_helper.rb +22 -22
  403. data/spec/server/static_caching_spec.rb +47 -47
  404. data/spec/server/webrick_servlet_spec.rb +20 -20
  405. data/spec/server_spec.rb +19 -19
  406. data/spec/spec_helper.rb +212 -212
  407. data/spec/tags/default_factory_spec.rb +168 -168
  408. data/spec/tags/default_tag_spec.rb +11 -11
  409. data/spec/tags/directives_spec.rb +463 -463
  410. data/spec/tags/library_spec.rb +48 -48
  411. data/spec/tags/overload_tag_spec.rb +53 -53
  412. data/spec/tags/ref_tag_list_spec.rb +53 -53
  413. data/spec/tags/types_explainer_spec.rb +203 -203
  414. data/spec/templates/class_spec.rb +45 -45
  415. data/spec/templates/constant_spec.rb +41 -41
  416. data/spec/templates/engine_spec.rb +131 -131
  417. data/spec/templates/examples/class001.html +308 -308
  418. data/spec/templates/examples/class001.txt +36 -36
  419. data/spec/templates/examples/class002.html +39 -39
  420. data/spec/templates/examples/constant001.txt +24 -24
  421. data/spec/templates/examples/constant002.txt +6 -6
  422. data/spec/templates/examples/constant003.txt +10 -10
  423. data/spec/templates/examples/method001.html +137 -137
  424. data/spec/templates/examples/method001.txt +35 -35
  425. data/spec/templates/examples/method002.html +91 -91
  426. data/spec/templates/examples/method002.txt +20 -20
  427. data/spec/templates/examples/method003.html +165 -165
  428. data/spec/templates/examples/method003.txt +45 -45
  429. data/spec/templates/examples/method004.html +48 -48
  430. data/spec/templates/examples/method004.txt +10 -10
  431. data/spec/templates/examples/method005.html +105 -105
  432. data/spec/templates/examples/method005.txt +33 -33
  433. data/spec/templates/examples/method006.html +107 -107
  434. data/spec/templates/examples/method006.txt +20 -20
  435. data/spec/templates/examples/module001.dot +33 -33
  436. data/spec/templates/examples/module001.html +833 -833
  437. data/spec/templates/examples/module001.txt +33 -33
  438. data/spec/templates/examples/module002.html +341 -341
  439. data/spec/templates/examples/module003.html +202 -202
  440. data/spec/templates/examples/module004.html +394 -394
  441. data/spec/templates/examples/module005.html +81 -81
  442. data/spec/templates/examples/tag001.txt +82 -82
  443. data/spec/templates/helpers/base_helper_spec.rb +171 -171
  444. data/spec/templates/helpers/html_helper_spec.rb +687 -668
  445. data/spec/templates/helpers/html_syntax_highlight_helper_spec.rb +65 -65
  446. data/spec/templates/helpers/markup/rdoc_markup_spec.rb +84 -84
  447. data/spec/templates/helpers/markup_helper_spec.rb +136 -136
  448. data/spec/templates/helpers/method_helper_spec.rb +107 -107
  449. data/spec/templates/helpers/module_helper_spec.rb +35 -35
  450. data/spec/templates/helpers/shared_signature_examples.rb +126 -126
  451. data/spec/templates/helpers/text_helper_spec.rb +65 -65
  452. data/spec/templates/markup_processor_integrations/asciidoctor_spec.rb +60 -0
  453. data/spec/templates/markup_processor_integrations/integration_spec_helper.rb +46 -0
  454. data/spec/templates/markup_processor_integrations/rdoc_markdown_spec.rb +59 -0
  455. data/spec/templates/markup_processor_integrations/rdoc_spec.rb +39 -0
  456. data/spec/templates/markup_processor_integrations/redcarpet_spec.rb +59 -0
  457. data/spec/templates/markup_processor_integrations/redcloth_spec.rb +48 -0
  458. data/spec/templates/method_spec.rb +118 -118
  459. data/spec/templates/module_spec.rb +203 -203
  460. data/spec/templates/onefile_spec.rb +66 -66
  461. data/spec/templates/section_spec.rb +144 -144
  462. data/spec/templates/spec_helper.rb +76 -76
  463. data/spec/templates/tag_spec.rb +52 -52
  464. data/spec/templates/template_spec.rb +410 -410
  465. data/spec/verifier_spec.rb +106 -106
  466. data/templates/default/class/dot/setup.rb +7 -7
  467. data/templates/default/class/dot/superklass.erb +2 -2
  468. data/templates/default/class/html/constructor_details.erb +8 -8
  469. data/templates/default/class/html/setup.rb +2 -2
  470. data/templates/default/class/html/subclasses.erb +4 -4
  471. data/templates/default/class/setup.rb +36 -36
  472. data/templates/default/class/text/setup.rb +12 -12
  473. data/templates/default/class/text/subclasses.erb +5 -5
  474. data/templates/default/constant/text/header.erb +11 -11
  475. data/templates/default/constant/text/setup.rb +4 -4
  476. data/templates/default/docstring/html/abstract.erb +4 -4
  477. data/templates/default/docstring/html/deprecated.erb +1 -1
  478. data/templates/default/docstring/html/index.erb +5 -5
  479. data/templates/default/docstring/html/note.erb +6 -6
  480. data/templates/default/docstring/html/private.erb +4 -4
  481. data/templates/default/docstring/html/text.erb +1 -1
  482. data/templates/default/docstring/html/todo.erb +6 -6
  483. data/templates/default/docstring/setup.rb +52 -52
  484. data/templates/default/docstring/text/abstract.erb +2 -2
  485. data/templates/default/docstring/text/deprecated.erb +2 -2
  486. data/templates/default/docstring/text/index.erb +2 -2
  487. data/templates/default/docstring/text/note.erb +3 -3
  488. data/templates/default/docstring/text/private.erb +2 -2
  489. data/templates/default/docstring/text/text.erb +1 -1
  490. data/templates/default/docstring/text/todo.erb +3 -3
  491. data/templates/default/fulldoc/html/css/full_list.css +58 -58
  492. data/templates/default/fulldoc/html/css/style.css +496 -496
  493. data/templates/default/fulldoc/html/frames.erb +17 -17
  494. data/templates/default/fulldoc/html/full_list.erb +37 -37
  495. data/templates/default/fulldoc/html/full_list_class.erb +2 -2
  496. data/templates/default/fulldoc/html/full_list_file.erb +7 -7
  497. data/templates/default/fulldoc/html/full_list_method.erb +10 -10
  498. data/templates/default/fulldoc/html/js/app.js +314 -292
  499. data/templates/default/fulldoc/html/js/full_list.js +216 -216
  500. data/templates/default/fulldoc/html/js/jquery.js +3 -3
  501. data/templates/default/fulldoc/html/setup.rb +241 -241
  502. data/templates/default/layout/dot/header.erb +5 -5
  503. data/templates/default/layout/dot/setup.rb +15 -15
  504. data/templates/default/layout/html/breadcrumb.erb +11 -11
  505. data/templates/default/layout/html/files.erb +11 -11
  506. data/templates/default/layout/html/footer.erb +5 -5
  507. data/templates/default/layout/html/headers.erb +15 -15
  508. data/templates/default/layout/html/index.erb +2 -2
  509. data/templates/default/layout/html/layout.erb +23 -23
  510. data/templates/default/layout/html/listing.erb +4 -4
  511. data/templates/default/layout/html/objects.erb +32 -32
  512. data/templates/default/layout/html/script_setup.erb +4 -4
  513. data/templates/default/layout/html/search.erb +12 -12
  514. data/templates/default/layout/html/setup.rb +89 -89
  515. data/templates/default/method/html/header.erb +16 -16
  516. data/templates/default/method/setup.rb +4 -4
  517. data/templates/default/method_details/html/header.erb +2 -2
  518. data/templates/default/method_details/html/method_signature.erb +24 -24
  519. data/templates/default/method_details/html/source.erb +9 -9
  520. data/templates/default/method_details/setup.rb +11 -11
  521. data/templates/default/method_details/text/header.erb +10 -10
  522. data/templates/default/method_details/text/method_signature.erb +12 -12
  523. data/templates/default/method_details/text/setup.rb +11 -11
  524. data/templates/default/module/dot/child.erb +1 -1
  525. data/templates/default/module/dot/dependencies.erb +2 -2
  526. data/templates/default/module/dot/header.erb +6 -6
  527. data/templates/default/module/dot/info.erb +13 -13
  528. data/templates/default/module/dot/setup.rb +15 -15
  529. data/templates/default/module/html/attribute_details.erb +10 -10
  530. data/templates/default/module/html/attribute_summary.erb +8 -8
  531. data/templates/default/module/html/box_info.erb +43 -43
  532. data/templates/default/module/html/children.erb +8 -8
  533. data/templates/default/module/html/constant_summary.erb +17 -17
  534. data/templates/default/module/html/defines.erb +2 -2
  535. data/templates/default/module/html/header.erb +5 -5
  536. data/templates/default/module/html/inherited_attributes.erb +14 -14
  537. data/templates/default/module/html/inherited_constants.erb +8 -8
  538. data/templates/default/module/html/inherited_methods.erb +18 -18
  539. data/templates/default/module/html/item_summary.erb +40 -40
  540. data/templates/default/module/html/method_details_list.erb +9 -9
  541. data/templates/default/module/html/method_summary.erb +13 -13
  542. data/templates/default/module/html/methodmissing.erb +12 -12
  543. data/templates/default/module/setup.rb +167 -167
  544. data/templates/default/module/text/children.erb +9 -9
  545. data/templates/default/module/text/class_meths_list.erb +7 -7
  546. data/templates/default/module/text/extends.erb +7 -7
  547. data/templates/default/module/text/header.erb +7 -7
  548. data/templates/default/module/text/includes.erb +7 -7
  549. data/templates/default/module/text/instance_meths_list.erb +7 -7
  550. data/templates/default/module/text/setup.rb +13 -13
  551. data/templates/default/onefile/html/files.erb +4 -4
  552. data/templates/default/onefile/html/headers.erb +6 -6
  553. data/templates/default/onefile/html/layout.erb +17 -17
  554. data/templates/default/onefile/html/readme.erb +2 -2
  555. data/templates/default/onefile/html/setup.rb +62 -62
  556. data/templates/default/root/dot/child.erb +2 -2
  557. data/templates/default/root/dot/setup.rb +6 -6
  558. data/templates/default/root/html/setup.rb +2 -2
  559. data/templates/default/tags/html/example.erb +10 -10
  560. data/templates/default/tags/html/index.erb +2 -2
  561. data/templates/default/tags/html/option.erb +24 -24
  562. data/templates/default/tags/html/overload.erb +13 -13
  563. data/templates/default/tags/html/see.erb +7 -7
  564. data/templates/default/tags/html/tag.erb +20 -20
  565. data/templates/default/tags/setup.rb +57 -57
  566. data/templates/default/tags/text/example.erb +12 -12
  567. data/templates/default/tags/text/index.erb +1 -1
  568. data/templates/default/tags/text/option.erb +20 -20
  569. data/templates/default/tags/text/overload.erb +19 -19
  570. data/templates/default/tags/text/see.erb +11 -11
  571. data/templates/default/tags/text/tag.erb +13 -13
  572. data/templates/guide/class/html/setup.rb +2 -2
  573. data/templates/guide/docstring/html/setup.rb +2 -2
  574. data/templates/guide/fulldoc/html/css/style.css +108 -108
  575. data/templates/guide/fulldoc/html/js/app.js +33 -33
  576. data/templates/guide/fulldoc/html/setup.rb +74 -74
  577. data/templates/guide/layout/html/layout.erb +81 -81
  578. data/templates/guide/layout/html/setup.rb +25 -25
  579. data/templates/guide/method/html/header.erb +17 -17
  580. data/templates/guide/method/html/setup.rb +22 -22
  581. data/templates/guide/module/html/header.erb +6 -6
  582. data/templates/guide/module/html/method_list.erb +4 -4
  583. data/templates/guide/module/html/setup.rb +27 -27
  584. data/templates/guide/onefile/html/files.erb +4 -4
  585. data/templates/guide/onefile/html/setup.rb +6 -6
  586. data/templates/guide/onefile/html/toc.erb +3 -3
  587. data/templates/guide/tags/html/setup.rb +9 -9
  588. data/yard.gemspec +24 -43
  589. metadata +28 -21
  590. data/spec/examples.txt +0 -1878
@@ -1,165 +1,165 @@
1
- # frozen_string_literal: true
2
-
3
- RSpec.describe YARD::Parser::Ruby::TokenResolver do
4
- before(:all) do
5
- YARD.parse_string <<-eof
6
- module A
7
- def nomatch; end
8
-
9
- module B
10
- class C
11
- def initialize; end
12
-
13
- # @return [A::B::C]
14
- def self.foo; end
15
-
16
- # @return [self]
17
- def self.foo2; end
18
-
19
- def bar; end
20
-
21
- # @return [nil, D<String>]
22
- def baz; end
23
-
24
- # @return [nil]
25
- # @return [D<String>]
26
- def baz2; end
27
-
28
- # @overload qux(a)
29
- # @return [nil]
30
- # @overload qux(b)
31
- # @return [D<String>]
32
- def qux; end
33
- end
34
-
35
- class SubC < C
36
- end
37
- end
38
- end
39
-
40
- module D
41
- def baz; end
42
- end
43
-
44
- class Q
45
- def method; end
46
-
47
- # @return [Q]
48
- def self.q; end
49
- end
50
- eof
51
- end
52
-
53
- def tokens_match
54
- expect(@resolved.map {|t| t.first.last }.join).to eq @src
55
- end
56
-
57
- def objs_match(*objects)
58
- other_objs = @resolved.reject {|_, o| !o }.map {|_, o| o.path }
59
- expect(other_objs).to eq objects.flatten
60
- tokens_match
61
- end
62
-
63
- def tokenize(src, object = nil)
64
- @src = src
65
- @resolver = YARD::Parser::Ruby::TokenResolver.new(src, object)
66
- @resolved = @resolver.map {|t, o| [t[0, 2], o] }
67
- end
68
-
69
- it "returns regular tokens" do
70
- str = "def foo; Z::X::Y end"
71
- tokenize(str)
72
- tokens_match
73
- end
74
-
75
- it "resolves objects in compound constant paths" do
76
- tokenize "A::B::C"
77
- objs_match "A", "A::B", "A::B::C"
78
- end
79
-
80
- it "ignores full constant path if it breaks at beginning" do
81
- tokenize "E::A::B::C"
82
- objs_match []
83
- end
84
-
85
- it "ignores rest of constant path if sub-objects don't match" do
86
- tokenize "D::A::B::C"
87
- objs_match "D"
88
- end
89
-
90
- it "resets parsing at non-op tokens" do
91
- tokenize "A::B::C < Q"
92
- objs_match "A", "A::B", "A::B::C", "Q"
93
- end
94
-
95
- it "does not restart constant path" do
96
- tokenize "A::B::D::A"
97
- objs_match "A", "A::B"
98
- end
99
-
100
- it "resolves objects from base namespace" do
101
- tokenize "A::B::C C", Registry.at("A::B")
102
- objs_match "A", "A::B", "A::B::C", "A::B::C"
103
- end
104
-
105
- it "resolves methods" do
106
- tokenize "A::B::C.foo"
107
- objs_match "A", "A::B", "A::B::C", "A::B::C.foo"
108
- end
109
-
110
- it "supports 'new' constructor method" do
111
- tokenize "A::B::C.new"
112
- objs_match "A", "A::B", "A::B::C", "A::B::C#initialize"
113
- end
114
-
115
- it "skips constructor method if not found but continues resolving" do
116
- tokenize "Q.new.method"
117
- objs_match "Q", "Q#method"
118
- end
119
-
120
- it "resolves methods in inheritance tree" do
121
- tokenize "A::B::SubC.new"
122
- objs_match "A", "A::B", "A::B::SubC", "A::B::C#initialize"
123
- end
124
-
125
- it "parses compound method call chains based on return type" do
126
- tokenize "A::B::C.foo.baz"
127
- objs_match "A", "A::B", "A::B::C", "A::B::C.foo", "A::B::C#baz"
128
- end
129
-
130
- it "stops resolving if return types not found" do
131
- tokenize "A::B::C.foo.bar.baz.baz"
132
- objs_match "A", "A::B", "A::B::C", "A::B::C.foo", "A::B::C#bar"
133
- end
134
-
135
- it "handles multiple return types (returns first valid type match)" do
136
- tokenize "A::B::C.foo.baz.baz"
137
- objs_match "A", "A::B", "A::B::C", "A::B::C.foo", "A::B::C#baz", "D#baz"
138
- end
139
-
140
- it "doesn't perform lexical matching on methods" do
141
- tokenize "A::B::C.nomatch"
142
- objs_match "A", "A::B", "A::B::C"
143
- end
144
-
145
- it "handles multiple return tags (returns first valid type match)" do
146
- tokenize "A::B::C.foo.baz2.baz"
147
- objs_match "A", "A::B", "A::B::C", "A::B::C.foo", "A::B::C#baz2", "D#baz"
148
- end
149
-
150
- it "handles self as return type" do
151
- tokenize "A::B::C.foo2.baz"
152
- objs_match "A", "A::B", "A::B::C", "A::B::C.foo2", "A::B::C#baz"
153
- end
154
-
155
- it "handles multiple return tags inside overload tags" do
156
- tokenize "A::B::C.foo.qux.baz"
157
- objs_match "A", "A::B", "A::B::C", "A::B::C.foo", "A::B::C#qux", "D#baz"
158
- end
159
-
160
- it "resolves method calls with arguments" do
161
- tokenize "Q.q(A::B, A::B::C.foo().bar).q.q"
162
- objs_match "Q", "Q.q", "A", "A::B", "A", "A::B", "A::B::C",
163
- "A::B::C.foo", "A::B::C#bar", "Q.q", "Q.q"
164
- end
165
- end if HAVE_RIPPER
1
+ # frozen_string_literal: true
2
+
3
+ RSpec.describe YARD::Parser::Ruby::TokenResolver do
4
+ before(:all) do
5
+ YARD.parse_string <<-eof
6
+ module A
7
+ def nomatch; end
8
+
9
+ module B
10
+ class C
11
+ def initialize; end
12
+
13
+ # @return [A::B::C]
14
+ def self.foo; end
15
+
16
+ # @return [self]
17
+ def self.foo2; end
18
+
19
+ def bar; end
20
+
21
+ # @return [nil, D<String>]
22
+ def baz; end
23
+
24
+ # @return [nil]
25
+ # @return [D<String>]
26
+ def baz2; end
27
+
28
+ # @overload qux(a)
29
+ # @return [nil]
30
+ # @overload qux(b)
31
+ # @return [D<String>]
32
+ def qux; end
33
+ end
34
+
35
+ class SubC < C
36
+ end
37
+ end
38
+ end
39
+
40
+ module D
41
+ def baz; end
42
+ end
43
+
44
+ class Q
45
+ def method; end
46
+
47
+ # @return [Q]
48
+ def self.q; end
49
+ end
50
+ eof
51
+ end
52
+
53
+ def tokens_match
54
+ expect(@resolved.map {|t| t.first.last }.join).to eq @src
55
+ end
56
+
57
+ def objs_match(*objects)
58
+ other_objs = @resolved.reject {|_, o| !o }.map {|_, o| o.path }
59
+ expect(other_objs).to eq objects.flatten
60
+ tokens_match
61
+ end
62
+
63
+ def tokenize(src, object = nil)
64
+ @src = src
65
+ @resolver = YARD::Parser::Ruby::TokenResolver.new(src, object)
66
+ @resolved = @resolver.map {|t, o| [t[0, 2], o] }
67
+ end
68
+
69
+ it "returns regular tokens" do
70
+ str = "def foo; Z::X::Y end"
71
+ tokenize(str)
72
+ tokens_match
73
+ end
74
+
75
+ it "resolves objects in compound constant paths" do
76
+ tokenize "A::B::C"
77
+ objs_match "A", "A::B", "A::B::C"
78
+ end
79
+
80
+ it "ignores full constant path if it breaks at beginning" do
81
+ tokenize "E::A::B::C"
82
+ objs_match []
83
+ end
84
+
85
+ it "ignores rest of constant path if sub-objects don't match" do
86
+ tokenize "D::A::B::C"
87
+ objs_match "D"
88
+ end
89
+
90
+ it "resets parsing at non-op tokens" do
91
+ tokenize "A::B::C < Q"
92
+ objs_match "A", "A::B", "A::B::C", "Q"
93
+ end
94
+
95
+ it "does not restart constant path" do
96
+ tokenize "A::B::D::A"
97
+ objs_match "A", "A::B"
98
+ end
99
+
100
+ it "resolves objects from base namespace" do
101
+ tokenize "A::B::C C", Registry.at("A::B")
102
+ objs_match "A", "A::B", "A::B::C", "A::B::C"
103
+ end
104
+
105
+ it "resolves methods" do
106
+ tokenize "A::B::C.foo"
107
+ objs_match "A", "A::B", "A::B::C", "A::B::C.foo"
108
+ end
109
+
110
+ it "supports 'new' constructor method" do
111
+ tokenize "A::B::C.new"
112
+ objs_match "A", "A::B", "A::B::C", "A::B::C#initialize"
113
+ end
114
+
115
+ it "skips constructor method if not found but continues resolving" do
116
+ tokenize "Q.new.method"
117
+ objs_match "Q", "Q#method"
118
+ end
119
+
120
+ it "resolves methods in inheritance tree" do
121
+ tokenize "A::B::SubC.new"
122
+ objs_match "A", "A::B", "A::B::SubC", "A::B::C#initialize"
123
+ end
124
+
125
+ it "parses compound method call chains based on return type" do
126
+ tokenize "A::B::C.foo.baz"
127
+ objs_match "A", "A::B", "A::B::C", "A::B::C.foo", "A::B::C#baz"
128
+ end
129
+
130
+ it "stops resolving if return types not found" do
131
+ tokenize "A::B::C.foo.bar.baz.baz"
132
+ objs_match "A", "A::B", "A::B::C", "A::B::C.foo", "A::B::C#bar"
133
+ end
134
+
135
+ it "handles multiple return types (returns first valid type match)" do
136
+ tokenize "A::B::C.foo.baz.baz"
137
+ objs_match "A", "A::B", "A::B::C", "A::B::C.foo", "A::B::C#baz", "D#baz"
138
+ end
139
+
140
+ it "doesn't perform lexical matching on methods" do
141
+ tokenize "A::B::C.nomatch"
142
+ objs_match "A", "A::B", "A::B::C"
143
+ end
144
+
145
+ it "handles multiple return tags (returns first valid type match)" do
146
+ tokenize "A::B::C.foo.baz2.baz"
147
+ objs_match "A", "A::B", "A::B::C", "A::B::C.foo", "A::B::C#baz2", "D#baz"
148
+ end
149
+
150
+ it "handles self as return type" do
151
+ tokenize "A::B::C.foo2.baz"
152
+ objs_match "A", "A::B", "A::B::C", "A::B::C.foo2", "A::B::C#baz"
153
+ end
154
+
155
+ it "handles multiple return tags inside overload tags" do
156
+ tokenize "A::B::C.foo.qux.baz"
157
+ objs_match "A", "A::B", "A::B::C", "A::B::C.foo", "A::B::C#qux", "D#baz"
158
+ end
159
+
160
+ it "resolves method calls with arguments" do
161
+ tokenize "Q.q(A::B, A::B::C.foo().bar).q.q"
162
+ objs_match "Q", "Q.q", "A", "A::B", "A", "A::B", "A::B::C",
163
+ "A::B::C.foo", "A::B::C#bar", "Q.q", "Q.q"
164
+ end
165
+ end if HAVE_RIPPER
@@ -1,727 +1,727 @@
1
- # frozen_string_literal: true
2
-
3
- class MyParser < Parser::Base; end
4
-
5
- RSpec.shared_examples_for "parser type registration" do
6
- after do
7
- Parser::SourceParser.parser_types.delete(:my_parser)
8
- Parser::SourceParser.parser_type_extensions.delete(:my_parser)
9
- end
10
- end
11
-
12
- RSpec.describe YARD::Parser::SourceParser do
13
- before do
14
- Registry.clear
15
- end
16
-
17
- def parse_list(*list)
18
- files = list.map do |v|
19
- filename, source = *v
20
- allow(File).to receive(: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 "handles basic callback support" do
49
- before_list do |files, globals|
50
- expect(files).to eq ['foo.rb', 'bar.rb']
51
- expect(globals).to eq OpenStruct.new
52
- end
53
- parse_list ['foo.rb', 'foo!'], ['bar.rb', 'class Foo; end']
54
- expect(Registry.at('Foo')).not_to be nil
55
- end
56
-
57
- it "supports 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
- expect(Registry.at('Foo')).not_to be nil
63
- expect(checks).to eq [:one, :two]
64
- end
65
-
66
- it "cancels 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
- expect(Registry.at('Foo')).to be nil
73
- expect(checks).to eq [:one]
74
- end
75
-
76
- it "does 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
- expect(Registry.at('Foo')).not_to be nil
83
- expect(checks).to eq [:one, :two]
84
- end
85
-
86
- it "passes 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| expect(g.x).to eq 3 }
91
- parse_list ['file.rb', ''], ['file2.rb', ''], ['file3.rb', 'class Foo; end']
92
- expect(Registry.at('Foo')).not_to 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 "handles basic callback support and maintain files/globals" do
103
- before_list {|_f, g| g.foo = :bar }
104
- after_list do |files, globals|
105
- expect(files).to eq ['foo.rb', 'bar.rb']
106
- expect(globals.foo).to eq :bar
107
- end
108
- parse_list ['foo.rb', 'foo!'], ['bar.rb', 'class Foo; end']
109
- expect(Registry.at('Foo')).not_to be nil
110
- end
111
-
112
- it "supports 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
- expect(Registry.at('Foo')).not_to be nil
118
- expect(checks).to eq [:one, :two]
119
- end
120
-
121
- it "does 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
- expect(Registry.at('Foo')).not_to be nil
128
- expect(checks).to eq [: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 "handles basic callback support" do
139
- before_file do |parser|
140
- expect(parser.contents).to eq 'class Foo; end'
141
- expect(parser.file).to match(/(foo|bar)\.rb/)
142
- end
143
- parse_list ['foo.rb', 'class Foo; end'], ['bar.rb', 'class Foo; end']
144
- expect(Registry.at('Foo')).not_to be nil
145
- end
146
-
147
- it "supports 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
- expect(Registry.at('Foo')).not_to be nil
153
- expect(checks).to eq [:one, :two, :one, :two, :one, :two]
154
- end
155
-
156
- it "cancels 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
- expect(Registry.at('Foo')).to be nil
163
- expect(checks).to eq [:one, :one, :one]
164
- end
165
-
166
- it "does 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
- expect(Registry.at('Foo')).not_to be nil
173
- expect(checks).to eq [: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 "handles basic callback support" do
184
- after_file do |parser|
185
- expect(parser.contents).to eq 'class Foo; end'
186
- expect(parser.file).to match(/(foo|bar)\.rb/)
187
- end
188
- parse_list ['foo.rb', 'class Foo; end'], ['bar.rb', 'class Foo; end']
189
- expect(Registry.at('Foo')).not_to be nil
190
- end
191
-
192
- it "supports 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
- expect(Registry.at('Foo')).not_to be nil
198
- expect(checks).to eq [:one, :two, :one, :two, :one, :two]
199
- end
200
-
201
- it "does 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
- expect(Registry.at('Foo')).not_to be nil
208
- expect(checks).to eq [:one, :three, :one, :three, :one, :three]
209
- end
210
- end
211
-
212
- describe ".register_parser_type" do
213
- it_should_behave_like "parser type registration"
214
-
215
- it "registers a subclass of Parser::Base" do
216
- parser = double(:parser)
217
- expect(parser).to receive(:parse)
218
- expect(MyParser).to receive(:new).with('content', '(stdin)').and_return(parser)
219
- Parser::SourceParser.register_parser_type(:my_parser, MyParser, 'myparser')
220
- Parser::SourceParser.parse_string('content', :my_parser)
221
- end
222
-
223
- it "requires class to be a subclass of Parser::Base" do
224
- expect { Parser::SourceParser.register_parser_type(:my_parser, String) }.to raise_error(ArgumentError)
225
- expect { Parser::SourceParser.register_parser_type(:my_parser, Parser::Base) }.to raise_error(ArgumentError)
226
- end
227
- end
228
-
229
- describe ".parser_type_for_extension" do
230
- it_should_behave_like "parser type registration"
231
-
232
- it "finds an extension in a registered array of extensions" do
233
- Parser::SourceParser.register_parser_type(:my_parser, MyParser, ['a', 'b', 'd'])
234
- expect(Parser::SourceParser.parser_type_for_extension('a')).to eq :my_parser
235
- expect(Parser::SourceParser.parser_type_for_extension('b')).to eq :my_parser
236
- expect(Parser::SourceParser.parser_type_for_extension('d')).to eq :my_parser
237
- expect(Parser::SourceParser.parser_type_for_extension('c')).not_to eq :my_parser
238
- end
239
-
240
- it "finds an extension in a Regexp" do
241
- Parser::SourceParser.register_parser_type(:my_parser, MyParser, /abc$/)
242
- expect(Parser::SourceParser.parser_type_for_extension('dabc')).to eq :my_parser
243
- expect(Parser::SourceParser.parser_type_for_extension('dabcd')).not_to eq :my_parser
244
- end
245
-
246
- it "finds an extension in a list of Regexps" do
247
- Parser::SourceParser.register_parser_type(:my_parser, MyParser, [/ab$/, /abc$/])
248
- expect(Parser::SourceParser.parser_type_for_extension('dabc')).to eq :my_parser
249
- expect(Parser::SourceParser.parser_type_for_extension('dabcd')).not_to eq :my_parser
250
- end
251
-
252
- it "finds an extension in a String" do
253
- Parser::SourceParser.register_parser_type(:my_parser, MyParser, "abc")
254
- expect(Parser::SourceParser.parser_type_for_extension('abc')).to eq :my_parser
255
- expect(Parser::SourceParser.parser_type_for_extension('abcd')).not_to eq :my_parser
256
- end
257
- end
258
-
259
- describe "#parse_string" do
260
- it "parses basic Ruby code" do
261
- YARD.parse_string(<<-eof)
262
- module Hello
263
- class Hi
264
- # Docstring
265
- # Docstring2
266
- def me; "VALUE" end
267
- end
268
- end
269
- eof
270
- expect(Registry.at(:Hello)).not_to eq nil
271
- expect(Registry.at("Hello::Hi#me")).not_to eq nil
272
- expect(Registry.at("Hello::Hi#me").docstring).to eq "Docstring\nDocstring2"
273
- expect(Registry.at("Hello::Hi#me").docstring.line_range).to eq(3..4)
274
- end
275
-
276
- it "parses Ruby code with metaclasses" do
277
- YARD.parse_string(<<-eof)
278
- module Hello
279
- class Hi
280
- class <<self
281
- # Docstring
282
- def me; "VALUE" end
283
- end
284
- end
285
- end
286
- eof
287
- expect(Registry.at(:Hello)).not_to eq nil
288
- expect(Registry.at("Hello::Hi.me")).not_to eq nil
289
- expect(Registry.at("Hello::Hi.me").docstring).to eq "Docstring"
290
- end
291
-
292
- it "only uses prepended comments for an object" do
293
- YARD.parse_string(<<-eof)
294
- # Test
295
-
296
- # PASS
297
- module Hello
298
- end # FAIL
299
- eof
300
- expect(Registry.at(:Hello).docstring).to eq "PASS"
301
- end
302
-
303
- it "does not add comments appended to last line of block" do
304
- YARD.parse_string <<-eof
305
- module Hello2
306
- end # FAIL
307
- eof
308
- expect(Registry.at(:Hello2).docstring).to be_blank
309
- end
310
-
311
- it "adds comments appended to an object's first line" do
312
- YARD.parse_string <<-eof
313
- module Hello # PASS
314
- HELLO
315
- end
316
-
317
- module Hello2 # PASS
318
- # ANOTHER PASS
319
- def x; end
320
- end
321
- eof
322
-
323
- expect(Registry.at(:Hello).docstring).to eq "PASS"
324
- expect(Registry.at(:Hello2).docstring).to eq "PASS"
325
- expect(Registry.at('Hello2#x').docstring).to eq "ANOTHER PASS"
326
- end
327
-
328
- it "takes preceding comments only if they exist" do
329
- YARD.parse_string <<-eof
330
- # PASS
331
- module Hello # FAIL
332
- HELLO
333
- end
334
- eof
335
-
336
- expect(Registry.at(:Hello).docstring).to eq "PASS"
337
- end
338
-
339
- it "strips 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
- expect(Registry.at(:Hello).docstring).to eq "PASS\nPASS\nPASS"
348
- end
349
-
350
- it "handles =begin/=end style comments" do
351
- YARD.parse_string "=begin\nfoo\nbar\n=end\nclass Foo; end\n"
352
- expect(Registry.at(:Foo).docstring).to eq "foo\nbar"
353
-
354
- YARD.parse_string "=begin\n\nfoo\nbar\n=end\nclass Foo; end\n"
355
- expect(Registry.at(:Foo).docstring).to eq "foo\nbar"
356
-
357
- YARD.parse_string "=begin\nfoo\n\nbar\n=end\nclass Foo; end\n"
358
- expect(Registry.at(:Foo).docstring).to eq "foo\n\nbar"
359
- end
360
-
361
- it "knows about docstrings starting with ##" do
362
- {'#' => false, '##' => true}.each do |hash, expected|
363
- YARD.parse_string "#{hash}\n# Foo bar\nclass Foo; end"
364
- expect(Registry.at(:Foo).docstring.hash_flag).to eq expected
365
- end
366
- end
367
-
368
- it "removes shebang from initial file comments" do
369
- YARD.parse_string "#!/bin/ruby\n# this is a comment\nclass Foo; end"
370
- expect(Registry.at(:Foo).docstring).to eq "this is a comment"
371
- end
372
-
373
- it "removes encoding line from initial file comments" do
374
- YARD.parse_string "# encoding: utf-8\n# this is a comment\nclass Foo; end"
375
- expect(Registry.at(:Foo).docstring).to eq "this is a comment"
376
- end
377
-
378
- it "adds 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
- expect(macro.macro_data).to eq "This is a macro\n@return [String] the string"
391
- expect(Registry.at('Foo').docstring.to_raw).to eq macro.macro_data
392
- expect(Registry.at('Foo#foo').docstring.to_raw).to eq macro.macro_data
393
- end
394
-
395
- it "allows directives parsed on lone comments" do
396
- YARD.parse_string(<<-eof)
397
- class Foo
398
- # @!method foo(a = "hello")
399
- # @!scope class
400
- # @!visibility private
401
- # @param [String] a the name of the foo
402
- # @return [Symbol] the symbolized foo
403
-
404
- # @!method bar(value)
405
- end
406
- eof
407
- foo = Registry.at('Foo.foo')
408
- bar = Registry.at('Foo#bar')
409
- expect(foo).not_to be nil
410
- expect(foo.visibility).to eq :private
411
- expect(foo.tag(:param).name).to eq 'a'
412
- expect(foo.tag(:return).types).to eq ['Symbol']
413
- expect(bar).not_to be nil
414
- expect(bar.signature).to eq 'def bar(value)'
415
- end
416
-
417
- it "parses lone comments at end of blocks" do
418
- YARD.parse_string(<<-eof)
419
- class Foo
420
- none
421
-
422
- # @!method foo(a = "hello")
423
- end
424
- eof
425
- foo = Registry.at('Foo#foo')
426
- expect(foo).not_to be nil
427
- expect(foo.signature).to eq 'def foo(a = "hello")'
428
- end
429
-
430
- it "handles lone comment with no code" do
431
- YARD.parse_string '# @!method foo(a = "hello")'
432
- foo = Registry.at('#foo')
433
- expect(foo).not_to be nil
434
- expect(foo.signature).to eq 'def foo(a = "hello")'
435
- end
436
-
437
- it "handles non-ASCII encoding in heredoc" do
438
- YARD.parse_string <<-eof
439
- # encoding: utf-8
440
-
441
- heredoc <<-ending
442
- foo\u{ffe2} bar.
443
- ending
444
-
445
- # Hello \u{ffe2} world
446
- class Foo < Bar
447
- attr_accessor :foo
448
- end
449
- eof
450
- expect(Registry.at('Foo').superclass).to eq P('Bar')
451
- end
452
- end
453
-
454
- describe "#parse" do
455
- it "parses a basic Ruby file" do
456
- parse_file :example1, __FILE__
457
- expect(Registry.at(:Hello)).not_to eq nil
458
- expect(Registry.at("Hello::Hi#me")).not_to eq nil
459
- expect(Registry.at("Hello::Hi#me").docstring).to eq "Docstring"
460
- end
461
-
462
- it "parses a set of file globs" do
463
- expect(Dir).to receive(:[]).with('lib/**/*.rb').and_return([])
464
- YARD.parse('lib/**/*.rb')
465
- end
466
-
467
- it "parses a set of absolute paths" do
468
- expect(Dir).not_to receive(:[])
469
- expect(File).to receive(:file?).with('/path/to/file').and_return(true)
470
- expect(File).to receive(:read_binary).with('/path/to/file').and_return("")
471
- YARD.parse('/path/to/file')
472
- end
473
-
474
- it "cleans paths before parsing" do
475
- expect(File).to receive(:open).and_return("")
476
- parser = Parser::SourceParser.new(:ruby, true)
477
- parser.parse('a//b//c')
478
- expect(parser.file).to eq 'a/b/c'
479
- end
480
-
481
- it "parses files with '*' in them as globs and others as absolute paths" do
482
- expect(Dir).to receive(:[]).with('*.rb').and_return(['a.rb', 'b.rb'])
483
- expect(File).to receive(:file?).with('/path/to/file').and_return(true)
484
- expect(File).to receive(:file?).with('a.rb').and_return(true)
485
- expect(File).to receive(:file?).with('b.rb').and_return(true)
486
- expect(File).to receive(:read_binary).with('/path/to/file').and_return("")
487
- expect(File).to receive(:read_binary).with('a.rb').and_return("")
488
- expect(File).to receive(:read_binary).with('b.rb').and_return("")
489
- YARD.parse ['/path/to/file', '*.rb']
490
- end
491
-
492
- it "converts directories into globs" do
493
- expect(Dir).to receive(:[]).with('foo/**/*.{rb,c,cc,cxx,cpp}').and_return(['foo/a.rb', 'foo/bar/b.rb'])
494
- expect(File).to receive(:directory?).with('foo').and_return(true)
495
- expect(File).to receive(:file?).with('foo/a.rb').and_return(true)
496
- expect(File).to receive(:file?).with('foo/bar/b.rb').and_return(true)
497
- expect(File).to receive(:read_binary).with('foo/a.rb').and_return("")
498
- expect(File).to receive(:read_binary).with('foo/bar/b.rb').and_return("")
499
- YARD.parse ['foo']
500
- end
501
-
502
- it "uses Registry.checksums cache if file is cached" do
503
- data = 'DATA'
504
- hash = Registry.checksum_for(data)
505
- cmock = double(:cmock)
506
- expect(cmock).to receive(:[]).with('foo/bar').and_return(hash)
507
- expect(Registry).to receive(:checksums).and_return(cmock)
508
- expect(File).to receive(:file?).with('foo/bar').and_return(true)
509
- expect(File).to receive(:read_binary).with('foo/bar').and_return(data)
510
- YARD.parse('foo/bar')
511
- end
512
-
513
- it "supports excluded paths" do
514
- expect(File).to receive(:file?).with('foo/bar').and_return(true)
515
- expect(File).to receive(:file?).with('foo/baz').and_return(true)
516
- expect(File).not_to receive(:read_binary)
517
- YARD.parse(["foo/bar", "foo/baz"], ["foo", /baz$/])
518
- end
519
-
520
- it "converts file contents to proper encoding if coding line is present" do
521
- valid = []
522
- valid << "# encoding: sjis"
523
- valid << "# encoding: utf-8"
524
- valid << "# xxxxxencoding: sjis"
525
- valid << "# xxxxxencoding: sjis xxxxxx"
526
- valid << "# ENCODING: sjis"
527
- valid << "#coDiNG: sjis"
528
- valid << "# -*- coding: sjis -*-"
529
- valid << "# -*- coding: utf-8; indent-tabs-mode: nil"
530
- valid << "### coding: sjis"
531
- valid << "# encoding=sjis"
532
- valid << "# encoding:sjis"
533
- valid << "# encoding = sjis"
534
- valid << "# encoding == sjis"
535
- valid << "# encoding : sjis"
536
- valid << "# encoding :: sjis"
537
- valid << "#!/bin/shebang\n# encoding: sjis"
538
- valid << "#!/bin/shebang\r\n# coding: sjis"
539
- invalid = []
540
- invalid << "#\n# encoding: sjis"
541
- invalid << "#!/bin/shebang\n#\n# encoding: sjis"
542
- invalid << "# !/bin/shebang\n# encoding: sjis"
543
- {:to => valid, :not_to => invalid}.each do |msg, list|
544
- list.each do |src|
545
- Registry.clear
546
- parser = Parser::SourceParser.new
547
- expect(File).to receive(:read_binary).with('tmpfile').and_return(src)
548
- result = parser.parse("tmpfile")
549
- if HAVE_RIPPER && YARD.ruby19?
550
- if msg == :not_to
551
- default_encoding = 'UTF-8'
552
- expect(result.enumerator[0].source.encoding.to_s).to eq(default_encoding)
553
- else
554
- expect(['Shift_JIS', 'Windows-31J', 'UTF-8']).send(msg,
555
- include(result.enumerator[0].source.encoding.to_s))
556
- end
557
- end
558
- expect(result.encoding_line).send(msg, eq(src.split("\n").last))
559
- end
560
- end
561
- end
562
-
563
- it "converts C file contents to proper encoding if coding line is present" do
564
- valid = []
565
- valid << "/* coding: utf-8 */"
566
- valid << "/* -*- coding: utf-8; c-file-style: \"ruby\" -*- */"
567
- valid << "// coding: utf-8"
568
- valid << "// -*- coding: utf-8; c-file-style: \"ruby\" -*-"
569
- invalid = []
570
- {:to => valid, :not_to => invalid}.each do |msg, list|
571
- list.each do |src|
572
- Registry.clear
573
- parser = Parser::SourceParser.new
574
- expect(File).to receive(:read_binary).with('tmpfile.c').and_return(src)
575
- result = parser.parse("tmpfile.c")
576
- content = result.instance_variable_get("@content")
577
- expect(['UTF-8']).send(msg, include(content.encoding.to_s))
578
- end
579
- end
580
- end if YARD.ruby19?
581
-
582
- Parser::SourceParser::ENCODING_BYTE_ORDER_MARKS.each do |encoding, bom|
583
- it "understands #{encoding.upcase} BOM" do
584
- parser = Parser::SourceParser.new
585
- src = bom + String.new("class FooBar; end").force_encoding('binary')
586
- src.force_encoding('binary')
587
- expect(File).to receive(:read_binary).with('tmpfile').and_return(src)
588
- result = parser.parse('tmpfile')
589
- expect(Registry.all(:class).first.path).to eq "FooBar"
590
- expect(result.enumerator[0].source.encoding.to_s.downcase).to eq encoding
591
- end
592
- end if HAVE_RIPPER && YARD.ruby19?
593
- end
594
-
595
- describe "#parse_in_order" do
596
- def in_order_parse(*files)
597
- paths = files.map {|f| File.join(File.dirname(__FILE__), 'examples', f.to_s + '.rb.txt') }
598
- YARD::Parser::SourceParser.parse(paths, [], Logger::DEBUG)
599
- end
600
-
601
- it "attempts to parse files in order" do
602
- log.enter_level(Logger::DEBUG) do
603
- msgs = []
604
- expect(log).to receive(:debug) {|m| msgs << m }.at_least(:once)
605
- allow(log).to receive(:<<)
606
- in_order_parse 'parse_in_order_001', 'parse_in_order_002'
607
- expect(msgs[1]).to match(/Parsing .+parse_in_order_001.+/)
608
- expect(msgs[2]).to match(/Missing object MyModule/)
609
- expect(msgs[3]).to match(/Parsing .+parse_in_order_002.+/)
610
- expect(msgs[4]).to match(/Re-processing .+parse_in_order_001.+/)
611
- end
612
- end
613
-
614
- it "attempts to order files by length for globs (process toplevel files first)" do
615
- files = %w(a a/b a/b/c)
616
- files.each do |file|
617
- expect(File).to receive(:file?).with(file).and_return(true)
618
- expect(File).to receive(:read_binary).with(file).ordered.and_return('')
619
- end
620
- expect(Dir).to receive(:[]).with('a/**/*').and_return(files.reverse)
621
- YARD.parse 'a/**/*'
622
- end
623
-
624
- it "allows overriding of length sorting when single file is presented" do
625
- files = %w(a/b/c a a/b)
626
- files.each do |file|
627
- expect(File).to receive(:file?).with(file).at_least(1).times.and_return(true)
628
- expect(File).to receive(:read_binary).with(file).ordered.and_return('')
629
- end
630
- expect(Dir).to receive(:[]).with('a/**/*').and_return(files.reverse)
631
- YARD.parse ['a/b/c', 'a/**/*']
632
- end
633
- end
634
-
635
- describe "#parse_statements" do
636
- before do
637
- Registry.clear
638
- end
639
-
640
- it "displays a warning for invalid parser type" do
641
- expect(log).to receive(:warn).with(/unrecognized file/)
642
- expect(log).to receive(:backtrace)
643
- YARD::Parser::SourceParser.parse_string("int main() { }", :d)
644
- end
645
-
646
- if HAVE_RIPPER
647
- it "displays a warning for a syntax error (with new parser)" do
648
- expect(log).to receive(:warn).with(/Syntax error in/)
649
- expect(log).to receive(:backtrace)
650
- YARD::Parser::SourceParser.parse_string("%!!!", :ruby)
651
- end
652
- end
653
-
654
- it "handles groups" do
655
- YARD.parse_string <<-eof
656
- class A
657
- # @group Group Name
658
- def foo; end
659
- def foo2; end
660
-
661
- # @endgroup
662
-
663
- def bar; end
664
-
665
- # @group Group 2
666
- def baz; end
667
- end
668
- eof
669
-
670
- expect(Registry.at('A').groups).to eq ['Group Name', 'Group 2']
671
- expect(Registry.at('A#bar').group).to be nil
672
- expect(Registry.at('A#foo').group).to eq "Group Name"
673
- expect(Registry.at('A#foo2').group).to eq "Group Name"
674
- expect(Registry.at('A#baz').group).to eq "Group 2"
675
- end
676
-
677
- it "handles multi-line class/module references" do
678
- YARD.parse_string <<-eof
679
- class A::
680
- B::C; end
681
- eof
682
- expect(Registry.all).to eq [P('A::B::C')]
683
- end
684
-
685
- it "handles sclass definitions of multi-line class/module references" do
686
- YARD.parse_string <<-eof
687
- class << A::
688
- B::C
689
- def foo; end
690
- end
691
- eof
692
- expect(Registry.all.size).to eq 2
693
- expect(Registry.at('A::B::C')).not_to be nil
694
- expect(Registry.at('A::B::C.foo')).not_to be nil
695
- end
696
-
697
- it "handles lone comment blocks at the end of a namespace" do
698
- YARD.parse_string <<-eof
699
- module A
700
- class B
701
- def c; end
702
-
703
- # @!method d
704
- end
705
- end
706
- eof
707
- expect(Registry.at('A#d')).to be nil
708
- expect(Registry.at('A::B#d')).not_to be nil
709
- end
710
-
711
- if YARD.ruby2?
712
- it "supports named arguments with default values" do
713
- YARD.parse_string 'def foo(a, b = 1, *c, d, e: 3, **f, &g) end'
714
- args = [['a', nil], ['b', '1'], ['*c', nil], ['d', nil], ['e:', '3'], ['**f', nil], ['&g', nil]]
715
- expect(Registry.at('#foo').parameters).to eq(args)
716
- end
717
- end
718
-
719
- if NAMED_OPTIONAL_ARGUMENTS && !LEGACY_PARSER
720
- it "supports named arguments without default values" do
721
- YARD.parse_string 'def foo(a, b = 1, *c, d, e: 3, f:, **g, &h) end'
722
- args = [['a', nil], ['b', '1'], ['*c', nil], ['d', nil], ['e:', '3'], ['f:', nil], ['**g', nil], ['&h', nil]]
723
- expect(Registry.at('#foo').parameters).to eq(args)
724
- end
725
- end
726
- end
727
- end
1
+ # frozen_string_literal: true
2
+
3
+ class MyParser < Parser::Base; end
4
+
5
+ RSpec.shared_examples_for "parser type registration" do
6
+ after do
7
+ Parser::SourceParser.parser_types.delete(:my_parser)
8
+ Parser::SourceParser.parser_type_extensions.delete(:my_parser)
9
+ end
10
+ end
11
+
12
+ RSpec.describe YARD::Parser::SourceParser do
13
+ before do
14
+ Registry.clear
15
+ end
16
+
17
+ def parse_list(*list)
18
+ files = list.map do |v|
19
+ filename, source = *v
20
+ allow(File).to receive(: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 "handles basic callback support" do
49
+ before_list do |files, globals|
50
+ expect(files).to eq ['foo.rb', 'bar.rb']
51
+ expect(globals).to eq OpenStruct.new
52
+ end
53
+ parse_list ['foo.rb', 'foo!'], ['bar.rb', 'class Foo; end']
54
+ expect(Registry.at('Foo')).not_to be nil
55
+ end
56
+
57
+ it "supports 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
+ expect(Registry.at('Foo')).not_to be nil
63
+ expect(checks).to eq [:one, :two]
64
+ end
65
+
66
+ it "cancels 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
+ expect(Registry.at('Foo')).to be nil
73
+ expect(checks).to eq [:one]
74
+ end
75
+
76
+ it "does 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
+ expect(Registry.at('Foo')).not_to be nil
83
+ expect(checks).to eq [:one, :two]
84
+ end
85
+
86
+ it "passes 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| expect(g.x).to eq 3 }
91
+ parse_list ['file.rb', ''], ['file2.rb', ''], ['file3.rb', 'class Foo; end']
92
+ expect(Registry.at('Foo')).not_to 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 "handles basic callback support and maintain files/globals" do
103
+ before_list {|_f, g| g.foo = :bar }
104
+ after_list do |files, globals|
105
+ expect(files).to eq ['foo.rb', 'bar.rb']
106
+ expect(globals.foo).to eq :bar
107
+ end
108
+ parse_list ['foo.rb', 'foo!'], ['bar.rb', 'class Foo; end']
109
+ expect(Registry.at('Foo')).not_to be nil
110
+ end
111
+
112
+ it "supports 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
+ expect(Registry.at('Foo')).not_to be nil
118
+ expect(checks).to eq [:one, :two]
119
+ end
120
+
121
+ it "does 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
+ expect(Registry.at('Foo')).not_to be nil
128
+ expect(checks).to eq [: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 "handles basic callback support" do
139
+ before_file do |parser|
140
+ expect(parser.contents).to eq 'class Foo; end'
141
+ expect(parser.file).to match(/(foo|bar)\.rb/)
142
+ end
143
+ parse_list ['foo.rb', 'class Foo; end'], ['bar.rb', 'class Foo; end']
144
+ expect(Registry.at('Foo')).not_to be nil
145
+ end
146
+
147
+ it "supports 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
+ expect(Registry.at('Foo')).not_to be nil
153
+ expect(checks).to eq [:one, :two, :one, :two, :one, :two]
154
+ end
155
+
156
+ it "cancels 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
+ expect(Registry.at('Foo')).to be nil
163
+ expect(checks).to eq [:one, :one, :one]
164
+ end
165
+
166
+ it "does 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
+ expect(Registry.at('Foo')).not_to be nil
173
+ expect(checks).to eq [: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 "handles basic callback support" do
184
+ after_file do |parser|
185
+ expect(parser.contents).to eq 'class Foo; end'
186
+ expect(parser.file).to match(/(foo|bar)\.rb/)
187
+ end
188
+ parse_list ['foo.rb', 'class Foo; end'], ['bar.rb', 'class Foo; end']
189
+ expect(Registry.at('Foo')).not_to be nil
190
+ end
191
+
192
+ it "supports 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
+ expect(Registry.at('Foo')).not_to be nil
198
+ expect(checks).to eq [:one, :two, :one, :two, :one, :two]
199
+ end
200
+
201
+ it "does 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
+ expect(Registry.at('Foo')).not_to be nil
208
+ expect(checks).to eq [:one, :three, :one, :three, :one, :three]
209
+ end
210
+ end
211
+
212
+ describe ".register_parser_type" do
213
+ it_should_behave_like "parser type registration"
214
+
215
+ it "registers a subclass of Parser::Base" do
216
+ parser = double(:parser)
217
+ expect(parser).to receive(:parse)
218
+ expect(MyParser).to receive(:new).with('content', '(stdin)').and_return(parser)
219
+ Parser::SourceParser.register_parser_type(:my_parser, MyParser, 'myparser')
220
+ Parser::SourceParser.parse_string('content', :my_parser)
221
+ end
222
+
223
+ it "requires class to be a subclass of Parser::Base" do
224
+ expect { Parser::SourceParser.register_parser_type(:my_parser, String) }.to raise_error(ArgumentError)
225
+ expect { Parser::SourceParser.register_parser_type(:my_parser, Parser::Base) }.to raise_error(ArgumentError)
226
+ end
227
+ end
228
+
229
+ describe ".parser_type_for_extension" do
230
+ it_should_behave_like "parser type registration"
231
+
232
+ it "finds an extension in a registered array of extensions" do
233
+ Parser::SourceParser.register_parser_type(:my_parser, MyParser, ['a', 'b', 'd'])
234
+ expect(Parser::SourceParser.parser_type_for_extension('a')).to eq :my_parser
235
+ expect(Parser::SourceParser.parser_type_for_extension('b')).to eq :my_parser
236
+ expect(Parser::SourceParser.parser_type_for_extension('d')).to eq :my_parser
237
+ expect(Parser::SourceParser.parser_type_for_extension('c')).not_to eq :my_parser
238
+ end
239
+
240
+ it "finds an extension in a Regexp" do
241
+ Parser::SourceParser.register_parser_type(:my_parser, MyParser, /abc$/)
242
+ expect(Parser::SourceParser.parser_type_for_extension('dabc')).to eq :my_parser
243
+ expect(Parser::SourceParser.parser_type_for_extension('dabcd')).not_to eq :my_parser
244
+ end
245
+
246
+ it "finds an extension in a list of Regexps" do
247
+ Parser::SourceParser.register_parser_type(:my_parser, MyParser, [/ab$/, /abc$/])
248
+ expect(Parser::SourceParser.parser_type_for_extension('dabc')).to eq :my_parser
249
+ expect(Parser::SourceParser.parser_type_for_extension('dabcd')).not_to eq :my_parser
250
+ end
251
+
252
+ it "finds an extension in a String" do
253
+ Parser::SourceParser.register_parser_type(:my_parser, MyParser, "abc")
254
+ expect(Parser::SourceParser.parser_type_for_extension('abc')).to eq :my_parser
255
+ expect(Parser::SourceParser.parser_type_for_extension('abcd')).not_to eq :my_parser
256
+ end
257
+ end
258
+
259
+ describe "#parse_string" do
260
+ it "parses basic Ruby code" do
261
+ YARD.parse_string(<<-eof)
262
+ module Hello
263
+ class Hi
264
+ # Docstring
265
+ # Docstring2
266
+ def me; "VALUE" end
267
+ end
268
+ end
269
+ eof
270
+ expect(Registry.at(:Hello)).not_to eq nil
271
+ expect(Registry.at("Hello::Hi#me")).not_to eq nil
272
+ expect(Registry.at("Hello::Hi#me").docstring).to eq "Docstring\nDocstring2"
273
+ expect(Registry.at("Hello::Hi#me").docstring.line_range).to eq(3..4)
274
+ end
275
+
276
+ it "parses Ruby code with metaclasses" do
277
+ YARD.parse_string(<<-eof)
278
+ module Hello
279
+ class Hi
280
+ class <<self
281
+ # Docstring
282
+ def me; "VALUE" end
283
+ end
284
+ end
285
+ end
286
+ eof
287
+ expect(Registry.at(:Hello)).not_to eq nil
288
+ expect(Registry.at("Hello::Hi.me")).not_to eq nil
289
+ expect(Registry.at("Hello::Hi.me").docstring).to eq "Docstring"
290
+ end
291
+
292
+ it "only uses prepended comments for an object" do
293
+ YARD.parse_string(<<-eof)
294
+ # Test
295
+
296
+ # PASS
297
+ module Hello
298
+ end # FAIL
299
+ eof
300
+ expect(Registry.at(:Hello).docstring).to eq "PASS"
301
+ end
302
+
303
+ it "does not add comments appended to last line of block" do
304
+ YARD.parse_string <<-eof
305
+ module Hello2
306
+ end # FAIL
307
+ eof
308
+ expect(Registry.at(:Hello2).docstring).to be_blank
309
+ end
310
+
311
+ it "adds comments appended to an object's first line" do
312
+ YARD.parse_string <<-eof
313
+ module Hello # PASS
314
+ HELLO
315
+ end
316
+
317
+ module Hello2 # PASS
318
+ # ANOTHER PASS
319
+ def x; end
320
+ end
321
+ eof
322
+
323
+ expect(Registry.at(:Hello).docstring).to eq "PASS"
324
+ expect(Registry.at(:Hello2).docstring).to eq "PASS"
325
+ expect(Registry.at('Hello2#x').docstring).to eq "ANOTHER PASS"
326
+ end
327
+
328
+ it "takes preceding comments only if they exist" do
329
+ YARD.parse_string <<-eof
330
+ # PASS
331
+ module Hello # FAIL
332
+ HELLO
333
+ end
334
+ eof
335
+
336
+ expect(Registry.at(:Hello).docstring).to eq "PASS"
337
+ end
338
+
339
+ it "strips 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
+ expect(Registry.at(:Hello).docstring).to eq "PASS\nPASS\nPASS"
348
+ end
349
+
350
+ it "handles =begin/=end style comments" do
351
+ YARD.parse_string "=begin\nfoo\nbar\n=end\nclass Foo; end\n"
352
+ expect(Registry.at(:Foo).docstring).to eq "foo\nbar"
353
+
354
+ YARD.parse_string "=begin\n\nfoo\nbar\n=end\nclass Foo; end\n"
355
+ expect(Registry.at(:Foo).docstring).to eq "foo\nbar"
356
+
357
+ YARD.parse_string "=begin\nfoo\n\nbar\n=end\nclass Foo; end\n"
358
+ expect(Registry.at(:Foo).docstring).to eq "foo\n\nbar"
359
+ end
360
+
361
+ it "knows about docstrings starting with ##" do
362
+ {'#' => false, '##' => true}.each do |hash, expected|
363
+ YARD.parse_string "#{hash}\n# Foo bar\nclass Foo; end"
364
+ expect(Registry.at(:Foo).docstring.hash_flag).to eq expected
365
+ end
366
+ end
367
+
368
+ it "removes shebang from initial file comments" do
369
+ YARD.parse_string "#!/bin/ruby\n# this is a comment\nclass Foo; end"
370
+ expect(Registry.at(:Foo).docstring).to eq "this is a comment"
371
+ end
372
+
373
+ it "removes encoding line from initial file comments" do
374
+ YARD.parse_string "# encoding: utf-8\n# this is a comment\nclass Foo; end"
375
+ expect(Registry.at(:Foo).docstring).to eq "this is a comment"
376
+ end
377
+
378
+ it "adds 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
+ expect(macro.macro_data).to eq "This is a macro\n@return [String] the string"
391
+ expect(Registry.at('Foo').docstring.to_raw).to eq macro.macro_data
392
+ expect(Registry.at('Foo#foo').docstring.to_raw).to eq macro.macro_data
393
+ end
394
+
395
+ it "allows directives parsed on lone comments" do
396
+ YARD.parse_string(<<-eof)
397
+ class Foo
398
+ # @!method foo(a = "hello")
399
+ # @!scope class
400
+ # @!visibility private
401
+ # @param [String] a the name of the foo
402
+ # @return [Symbol] the symbolized foo
403
+
404
+ # @!method bar(value)
405
+ end
406
+ eof
407
+ foo = Registry.at('Foo.foo')
408
+ bar = Registry.at('Foo#bar')
409
+ expect(foo).not_to be nil
410
+ expect(foo.visibility).to eq :private
411
+ expect(foo.tag(:param).name).to eq 'a'
412
+ expect(foo.tag(:return).types).to eq ['Symbol']
413
+ expect(bar).not_to be nil
414
+ expect(bar.signature).to eq 'def bar(value)'
415
+ end
416
+
417
+ it "parses lone comments at end of blocks" do
418
+ YARD.parse_string(<<-eof)
419
+ class Foo
420
+ none
421
+
422
+ # @!method foo(a = "hello")
423
+ end
424
+ eof
425
+ foo = Registry.at('Foo#foo')
426
+ expect(foo).not_to be nil
427
+ expect(foo.signature).to eq 'def foo(a = "hello")'
428
+ end
429
+
430
+ it "handles lone comment with no code" do
431
+ YARD.parse_string '# @!method foo(a = "hello")'
432
+ foo = Registry.at('#foo')
433
+ expect(foo).not_to be nil
434
+ expect(foo.signature).to eq 'def foo(a = "hello")'
435
+ end
436
+
437
+ it "handles non-ASCII encoding in heredoc" do
438
+ YARD.parse_string <<-eof
439
+ # encoding: utf-8
440
+
441
+ heredoc <<-ending
442
+ foo\u{ffe2} bar.
443
+ ending
444
+
445
+ # Hello \u{ffe2} world
446
+ class Foo < Bar
447
+ attr_accessor :foo
448
+ end
449
+ eof
450
+ expect(Registry.at('Foo').superclass).to eq P('Bar')
451
+ end
452
+ end
453
+
454
+ describe "#parse" do
455
+ it "parses a basic Ruby file" do
456
+ parse_file :example1, __FILE__
457
+ expect(Registry.at(:Hello)).not_to eq nil
458
+ expect(Registry.at("Hello::Hi#me")).not_to eq nil
459
+ expect(Registry.at("Hello::Hi#me").docstring).to eq "Docstring"
460
+ end
461
+
462
+ it "parses a set of file globs" do
463
+ expect(Dir).to receive(:[]).with('lib/**/*.rb').and_return([])
464
+ YARD.parse('lib/**/*.rb')
465
+ end
466
+
467
+ it "parses a set of absolute paths" do
468
+ expect(Dir).not_to receive(:[])
469
+ expect(File).to receive(:file?).with('/path/to/file').and_return(true)
470
+ expect(File).to receive(:read_binary).with('/path/to/file').and_return("")
471
+ YARD.parse('/path/to/file')
472
+ end
473
+
474
+ it "cleans paths before parsing" do
475
+ expect(File).to receive(:open).and_return("")
476
+ parser = Parser::SourceParser.new(:ruby, true)
477
+ parser.parse('a//b//c')
478
+ expect(parser.file).to eq 'a/b/c'
479
+ end
480
+
481
+ it "parses files with '*' in them as globs and others as absolute paths" do
482
+ expect(Dir).to receive(:[]).with('*.rb').and_return(['a.rb', 'b.rb'])
483
+ expect(File).to receive(:file?).with('/path/to/file').and_return(true)
484
+ expect(File).to receive(:file?).with('a.rb').and_return(true)
485
+ expect(File).to receive(:file?).with('b.rb').and_return(true)
486
+ expect(File).to receive(:read_binary).with('/path/to/file').and_return("")
487
+ expect(File).to receive(:read_binary).with('a.rb').and_return("")
488
+ expect(File).to receive(:read_binary).with('b.rb').and_return("")
489
+ YARD.parse ['/path/to/file', '*.rb']
490
+ end
491
+
492
+ it "converts directories into globs" do
493
+ expect(Dir).to receive(:[]).with('foo/**/*.{rb,c,cc,cxx,cpp}').and_return(['foo/a.rb', 'foo/bar/b.rb'])
494
+ expect(File).to receive(:directory?).with('foo').and_return(true)
495
+ expect(File).to receive(:file?).with('foo/a.rb').and_return(true)
496
+ expect(File).to receive(:file?).with('foo/bar/b.rb').and_return(true)
497
+ expect(File).to receive(:read_binary).with('foo/a.rb').and_return("")
498
+ expect(File).to receive(:read_binary).with('foo/bar/b.rb').and_return("")
499
+ YARD.parse ['foo']
500
+ end
501
+
502
+ it "uses Registry.checksums cache if file is cached" do
503
+ data = 'DATA'
504
+ hash = Registry.checksum_for(data)
505
+ cmock = double(:cmock)
506
+ expect(cmock).to receive(:[]).with('foo/bar').and_return(hash)
507
+ expect(Registry).to receive(:checksums).and_return(cmock)
508
+ expect(File).to receive(:file?).with('foo/bar').and_return(true)
509
+ expect(File).to receive(:read_binary).with('foo/bar').and_return(data)
510
+ YARD.parse('foo/bar')
511
+ end
512
+
513
+ it "supports excluded paths" do
514
+ expect(File).to receive(:file?).with('foo/bar').and_return(true)
515
+ expect(File).to receive(:file?).with('foo/baz').and_return(true)
516
+ expect(File).not_to receive(:read_binary)
517
+ YARD.parse(["foo/bar", "foo/baz"], ["foo", /baz$/])
518
+ end
519
+
520
+ it "converts file contents to proper encoding if coding line is present" do
521
+ valid = []
522
+ valid << "# encoding: sjis"
523
+ valid << "# encoding: utf-8"
524
+ valid << "# xxxxxencoding: sjis"
525
+ valid << "# xxxxxencoding: sjis xxxxxx"
526
+ valid << "# ENCODING: sjis"
527
+ valid << "#coDiNG: sjis"
528
+ valid << "# -*- coding: sjis -*-"
529
+ valid << "# -*- coding: utf-8; indent-tabs-mode: nil"
530
+ valid << "### coding: sjis"
531
+ valid << "# encoding=sjis"
532
+ valid << "# encoding:sjis"
533
+ valid << "# encoding = sjis"
534
+ valid << "# encoding == sjis"
535
+ valid << "# encoding : sjis"
536
+ valid << "# encoding :: sjis"
537
+ valid << "#!/bin/shebang\n# encoding: sjis"
538
+ valid << "#!/bin/shebang\r\n# coding: sjis"
539
+ invalid = []
540
+ invalid << "#\n# encoding: sjis"
541
+ invalid << "#!/bin/shebang\n#\n# encoding: sjis"
542
+ invalid << "# !/bin/shebang\n# encoding: sjis"
543
+ {:to => valid, :not_to => invalid}.each do |msg, list|
544
+ list.each do |src|
545
+ Registry.clear
546
+ parser = Parser::SourceParser.new
547
+ expect(File).to receive(:read_binary).with('tmpfile').and_return(src)
548
+ result = parser.parse("tmpfile")
549
+ if HAVE_RIPPER && YARD.ruby19?
550
+ if msg == :not_to
551
+ default_encoding = 'UTF-8'
552
+ expect(result.enumerator[0].source.encoding.to_s).to eq(default_encoding)
553
+ else
554
+ expect(['Shift_JIS', 'Windows-31J', 'UTF-8']).send(msg,
555
+ include(result.enumerator[0].source.encoding.to_s))
556
+ end
557
+ end
558
+ expect(result.encoding_line).send(msg, eq(src.split("\n").last))
559
+ end
560
+ end
561
+ end
562
+
563
+ it "converts C file contents to proper encoding if coding line is present" do
564
+ valid = []
565
+ valid << "/* coding: utf-8 */"
566
+ valid << "/* -*- coding: utf-8; c-file-style: \"ruby\" -*- */"
567
+ valid << "// coding: utf-8"
568
+ valid << "// -*- coding: utf-8; c-file-style: \"ruby\" -*-"
569
+ invalid = []
570
+ {:to => valid, :not_to => invalid}.each do |msg, list|
571
+ list.each do |src|
572
+ Registry.clear
573
+ parser = Parser::SourceParser.new
574
+ expect(File).to receive(:read_binary).with('tmpfile.c').and_return(src)
575
+ result = parser.parse("tmpfile.c")
576
+ content = result.instance_variable_get("@content")
577
+ expect(['UTF-8']).send(msg, include(content.encoding.to_s))
578
+ end
579
+ end
580
+ end if YARD.ruby19?
581
+
582
+ Parser::SourceParser::ENCODING_BYTE_ORDER_MARKS.each do |encoding, bom|
583
+ it "understands #{encoding.upcase} BOM" do
584
+ parser = Parser::SourceParser.new
585
+ src = bom + String.new("class FooBar; end").force_encoding('binary')
586
+ src.force_encoding('binary')
587
+ expect(File).to receive(:read_binary).with('tmpfile').and_return(src)
588
+ result = parser.parse('tmpfile')
589
+ expect(Registry.all(:class).first.path).to eq "FooBar"
590
+ expect(result.enumerator[0].source.encoding.to_s.downcase).to eq encoding
591
+ end
592
+ end if HAVE_RIPPER && YARD.ruby19?
593
+ end
594
+
595
+ describe "#parse_in_order" do
596
+ def in_order_parse(*files)
597
+ paths = files.map {|f| File.join(File.dirname(__FILE__), 'examples', f.to_s + '.rb.txt') }
598
+ YARD::Parser::SourceParser.parse(paths, [], Logger::DEBUG)
599
+ end
600
+
601
+ it "attempts to parse files in order" do
602
+ log.enter_level(Logger::DEBUG) do
603
+ msgs = []
604
+ expect(log).to receive(:debug) {|m| msgs << m }.at_least(:once)
605
+ allow(log).to receive(:<<)
606
+ in_order_parse 'parse_in_order_001', 'parse_in_order_002'
607
+ expect(msgs[1]).to match(/Parsing .+parse_in_order_001.+/)
608
+ expect(msgs[2]).to match(/Missing object MyModule/)
609
+ expect(msgs[3]).to match(/Parsing .+parse_in_order_002.+/)
610
+ expect(msgs[4]).to match(/Re-processing .+parse_in_order_001.+/)
611
+ end
612
+ end
613
+
614
+ it "attempts to order files by length for globs (process toplevel files first)" do
615
+ files = %w(a a/b a/b/c)
616
+ files.each do |file|
617
+ expect(File).to receive(:file?).with(file).and_return(true)
618
+ expect(File).to receive(:read_binary).with(file).ordered.and_return('')
619
+ end
620
+ expect(Dir).to receive(:[]).with('a/**/*').and_return(files.reverse)
621
+ YARD.parse 'a/**/*'
622
+ end
623
+
624
+ it "allows overriding of length sorting when single file is presented" do
625
+ files = %w(a/b/c a a/b)
626
+ files.each do |file|
627
+ expect(File).to receive(:file?).with(file).at_least(1).times.and_return(true)
628
+ expect(File).to receive(:read_binary).with(file).ordered.and_return('')
629
+ end
630
+ expect(Dir).to receive(:[]).with('a/**/*').and_return(files.reverse)
631
+ YARD.parse ['a/b/c', 'a/**/*']
632
+ end
633
+ end
634
+
635
+ describe "#parse_statements" do
636
+ before do
637
+ Registry.clear
638
+ end
639
+
640
+ it "displays a warning for invalid parser type" do
641
+ expect(log).to receive(:warn).with(/unrecognized file/)
642
+ expect(log).to receive(:backtrace)
643
+ YARD::Parser::SourceParser.parse_string("int main() { }", :d)
644
+ end
645
+
646
+ if HAVE_RIPPER
647
+ it "displays a warning for a syntax error (with new parser)" do
648
+ expect(log).to receive(:warn).with(/Syntax error in/)
649
+ expect(log).to receive(:backtrace)
650
+ YARD::Parser::SourceParser.parse_string("%!!!", :ruby)
651
+ end
652
+ end
653
+
654
+ it "handles groups" do
655
+ YARD.parse_string <<-eof
656
+ class A
657
+ # @group Group Name
658
+ def foo; end
659
+ def foo2; end
660
+
661
+ # @endgroup
662
+
663
+ def bar; end
664
+
665
+ # @group Group 2
666
+ def baz; end
667
+ end
668
+ eof
669
+
670
+ expect(Registry.at('A').groups).to eq ['Group Name', 'Group 2']
671
+ expect(Registry.at('A#bar').group).to be nil
672
+ expect(Registry.at('A#foo').group).to eq "Group Name"
673
+ expect(Registry.at('A#foo2').group).to eq "Group Name"
674
+ expect(Registry.at('A#baz').group).to eq "Group 2"
675
+ end
676
+
677
+ it "handles multi-line class/module references" do
678
+ YARD.parse_string <<-eof
679
+ class A::
680
+ B::C; end
681
+ eof
682
+ expect(Registry.all).to eq [P('A::B::C')]
683
+ end
684
+
685
+ it "handles sclass definitions of multi-line class/module references" do
686
+ YARD.parse_string <<-eof
687
+ class << A::
688
+ B::C
689
+ def foo; end
690
+ end
691
+ eof
692
+ expect(Registry.all.size).to eq 2
693
+ expect(Registry.at('A::B::C')).not_to be nil
694
+ expect(Registry.at('A::B::C.foo')).not_to be nil
695
+ end
696
+
697
+ it "handles lone comment blocks at the end of a namespace" do
698
+ YARD.parse_string <<-eof
699
+ module A
700
+ class B
701
+ def c; end
702
+
703
+ # @!method d
704
+ end
705
+ end
706
+ eof
707
+ expect(Registry.at('A#d')).to be nil
708
+ expect(Registry.at('A::B#d')).not_to be nil
709
+ end
710
+
711
+ if YARD.ruby2?
712
+ it "supports named arguments with default values" do
713
+ YARD.parse_string 'def foo(a, b = 1, *c, d, e: 3, **f, &g) end'
714
+ args = [['a', nil], ['b', '1'], ['*c', nil], ['d', nil], ['e:', '3'], ['**f', nil], ['&g', nil]]
715
+ expect(Registry.at('#foo').parameters).to eq(args)
716
+ end
717
+ end
718
+
719
+ if NAMED_OPTIONAL_ARGUMENTS && !LEGACY_PARSER
720
+ it "supports named arguments without default values" do
721
+ YARD.parse_string 'def foo(a, b = 1, *c, d, e: 3, f:, **g, &h) end'
722
+ args = [['a', nil], ['b', '1'], ['*c', nil], ['d', nil], ['e:', '3'], ['f:', nil], ['**g', nil], ['&h', nil]]
723
+ expect(Registry.at('#foo').parameters).to eq(args)
724
+ end
725
+ end
726
+ end
727
+ end