yard 0.9.18 → 0.9.23

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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 +781 -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 -1875
@@ -1,668 +1,687 @@
1
- # frozen_string_literal: true
2
- require File.dirname(__FILE__) + "/shared_signature_examples"
3
- require 'ostruct'
4
-
5
- RSpec.describe YARD::Templates::Helpers::HtmlHelper do
6
- include YARD::Templates::Helpers::BaseHelper
7
- include YARD::Templates::Helpers::HtmlHelper
8
- include YARD::Templates::Helpers::MethodHelper
9
-
10
- def options
11
- Templates::TemplateOptions.new.tap do |o|
12
- o.reset_defaults
13
- o.default_return = nil
14
- end
15
- end
16
-
17
- describe "#h" do
18
- it "uses #h to escape HTML" do
19
- expect(h('Usage: foo "bar" <baz>')).to eq "Usage: foo &quot;bar&quot; &lt;baz&gt;"
20
- end
21
- end
22
-
23
- describe "#charset" do
24
- it "returns foo if LANG=foo" do
25
- expect(ENV).to receive(:[]).with('LANG').and_return('shift_jis') if YARD.ruby18?
26
- expect(Encoding.default_external).to receive(:name).and_return('shift_jis') if defined?(Encoding)
27
- expect(charset).to eq 'shift_jis'
28
- end
29
-
30
- ['US-ASCII', 'ASCII-7BIT', 'ASCII-8BIT'].each do |type|
31
- it "converts #{type} to iso-8859-1" do
32
- expect(ENV).to receive(:[]).with('LANG').and_return(type) if YARD.ruby18?
33
- expect(Encoding.default_external).to receive(:name).and_return(type) if defined?(Encoding)
34
- expect(charset).to eq 'iso-8859-1'
35
- end
36
- end
37
-
38
- it "supports utf8 as an encoding value for utf-8" do
39
- type = 'utf8'
40
- expect(ENV).to receive(:[]).with('LANG').and_return(type) if YARD.ruby18?
41
- expect(Encoding.default_external).to receive(:name).and_return(type) if defined?(Encoding)
42
- expect(charset).to eq 'utf-8'
43
- end
44
-
45
- it "takes file encoding if there is a file" do
46
- @file = OpenStruct.new(:contents => String.new('foo').force_encoding('sjis'))
47
- # not the correct charset name, but good enough
48
- expect(['Shift_JIS', 'Windows-31J']).to include(charset)
49
- end if YARD.ruby19?
50
-
51
- it "takes file encoding if there is a file" do
52
- allow(ENV).to receive(:[]).with('LANG').and_return('utf-8') if YARD.ruby18?
53
- @file = OpenStruct.new(:contents => 'foo')
54
- expect(charset).to eq 'utf-8'
55
- end if YARD.ruby18?
56
-
57
- if YARD.ruby18?
58
- it "returns utf-8 if no LANG env is set" do
59
- expect(ENV).to receive(:[]).with('LANG').and_return(nil)
60
- expect(charset).to eq 'utf-8'
61
- end
62
-
63
- it "only returns charset part of lang" do
64
- expect(ENV).to receive(:[]).with('LANG').and_return('en_US.UTF-8')
65
- expect(charset).to eq 'utf-8'
66
- end
67
- end
68
- end
69
-
70
- describe "#format_types" do
71
- it "includes brackets by default" do
72
- text = ["String"]
73
- expect(self).to receive(:linkify).at_least(1).times.with("String", "String").and_return("String")
74
- expect(format_types(text)).to eq format_types(text, true)
75
- expect(format_types(text)).to eq "(<tt>String</tt>)"
76
- end
77
-
78
- it "avoids brackets if brackets=false" do
79
- expect(self).to receive(:linkify).with("String", "String").and_return("String")
80
- expect(self).to receive(:linkify).with("Symbol", "Symbol").and_return("Symbol")
81
- expect(format_types(["String", "Symbol"], false)).to eq "<tt>String</tt>, <tt>Symbol</tt>"
82
- end
83
-
84
- {"String" => [["String"],
85
- "<tt><a href=''>String</a></tt>"],
86
- "A::B::C" => [["A::B::C"],
87
- "<tt><a href=''>A::B::C</a></tt>"],
88
- "Array<String>" => [["Array", "String"],
89
- "<tt><a href=''>Array</a>&lt;<a href=''>String</a>&gt;</tt>"],
90
- "Array<String, Symbol>" => [["Array", "String", "Symbol"],
91
- "<tt><a href=''>Array</a>&lt;<a href=''>String</a>, <a href=''>Symbol</a>&gt;</tt>"],
92
- "Array<{String => Array<Symbol>}>" => [["Array", "String", "Array", "Symbol"],
93
- "<tt><a href=''>Array</a>&lt;{<a href=''>String</a> =&gt; " \
94
- "<a href=''>Array</a>&lt;<a href=''>Symbol</a>&gt;}&gt;</tt>"]}.each do |text, values|
95
- it "links all classes in #{text}" do
96
- if text.count('<') > 0
97
- expect(self).to receive(:h).with('<').at_least(text.count('<')).times.and_return("&lt;")
98
- end
99
- if text.count('>') > 0
100
- expect(self).to receive(:h).with('>').at_least(text.count('>')).times.and_return("&gt;")
101
- end
102
- values[0].each {|v| expect(self).to receive(:linkify).with(v, v).and_return("<a href=''>#{v}</a>") }
103
- expect(format_types([text], false)).to eq values[1]
104
- end
105
- end
106
- end
107
-
108
- describe "#htmlify" do
109
- it "does not use hard breaks for textile markup (RedCloth specific)" do
110
- begin; require 'redcloth'; rescue LoadError; pending 'test requires redcloth gem' end
111
- expect(htmlify("A\nB", :textile)).not_to include("<br")
112
- end
113
-
114
- it "uses hard breaks for textile_strict markup (RedCloth specific)" do
115
- begin; require 'redcloth'; rescue LoadError; pending 'test requires redcloth gem' end
116
- expect(htmlify("A\nB", :textile_strict)).to include("<br")
117
- end
118
-
119
- it "handles various encodings" do
120
- allow(self).to receive(:object).and_return(Registry.root)
121
- text = String.new("\xB0\xB1")
122
- if defined?(Encoding)
123
- utf8 = Encoding.find('utf-8')
124
-
125
- Encoding.default_internal = utf8 unless Encoding.default_internal == utf8
126
- text = text.force_encoding('binary')
127
- end
128
- htmlify(text, :text)
129
- # TODO: add more encoding tests
130
- end
131
-
132
- it "returns pre-formatted text with :pre markup" do
133
- expect(htmlify("fo\no\n\nbar<>", :pre)).to eq "<pre>fo\no\n\nbar&lt;&gt;</pre>"
134
- end
135
-
136
- it "returns regular text with :text markup" do
137
- expect(htmlify("fo\no\n\nbar<>", :text)).to eq "fo<br/>o<br/><br/>bar&lt;&gt;"
138
- end
139
-
140
- it "returns unmodified text with :none markup" do
141
- expect(htmlify("fo\no\n\nbar<>", :none)).to eq "fo\no\n\nbar&lt;&gt;"
142
- end
143
-
144
- it "highlights ruby if markup is :ruby" do
145
- expect(htmlify("class Foo; end", :ruby)).to match(/\A<pre class="code ruby"><span/)
146
- end
147
-
148
- it "includes file and htmlifies it" do
149
- load_markup_provider(:rdoc)
150
- expect(File).to receive(:file?).with('foo.rdoc').and_return(true)
151
- expect(File).to receive(:read).with('foo.rdoc').and_return('HI')
152
- expect(htmlify("{include:file:foo.rdoc}", :rdoc).gsub(/\s+/, '')).to eq "<p>HI</p>"
153
- end
154
-
155
- it "allows inline includes for {include:} in the middle of a line" do
156
- load_markup_provider(:rdoc)
157
- expect(File).to receive(:file?).with('foo.rdoc').and_return(true)
158
- expect(File).to receive(:read).with('foo.rdoc').and_return('HI')
159
- expect(htmlify("test {include:file:foo.rdoc}", :rdoc).gsub(/[\r?\n]+/, '')).to eq '<p>test HI</p>'
160
- end
161
-
162
- it "autolinks URLs (markdown specific)" do
163
- log.enter_level(Logger::FATAL) do
164
- unless markup_class(:markdown).to_s == "RedcarpetCompat"
165
- pending 'This test depends on a markdown engine that supports autolinking'
166
- end
167
- end
168
- expect(htmlify('http://example.com', :markdown).chomp.gsub('&#47;', '/')).to eq(
169
- '<p><a href="http://example.com">http://example.com</a></p>'
170
- )
171
- end
172
-
173
- it "does not autolink URLs inside of {} (markdown specific)" do
174
- log.enter_level(Logger::FATAL) do
175
- pending 'This test depends on markdown' unless markup_class(:markdown)
176
- end
177
- expect(htmlify('{http://example.com Title}', :markdown).chomp).to match(
178
- %r{<p><a href="http://example.com".*>Title</a></p>}
179
- )
180
- expect(htmlify('{http://example.com}', :markdown).chomp).to match(
181
- %r{<p><a href="http://example.com".*>http://example.com</a></p>}
182
- )
183
- end
184
-
185
- it "creates tables (markdown specific)" do
186
- log.enter_level(Logger::FATAL) do
187
- supports_table = %w(RedcarpetCompat Kramdown::Document)
188
- unless supports_table.include?(markup_class(:markdown).to_s)
189
- pending "This test depends on a markdown engine that supports tables"
190
- end
191
- end
192
-
193
- markdown = <<-EOF.strip
194
- City | State | Country
195
- --------|-------|--------
196
- Raleigh | NC | US
197
- Seattle | WA | US
198
- EOF
199
-
200
- html = htmlify(markdown, :markdown)
201
- expect(html).to match(/<table>/)
202
- expect(html).to match %r{<th>City</th>}
203
- expect(html).to match %r{<td>NC</td>}
204
- end
205
-
206
- it "handles fenced code blocks (Redcarpet specific)" do
207
- log.enter_level(Logger::FATAL) do
208
- unless markup_class(:markdown).to_s == 'RedcarpetCompat'
209
- pending 'This test is Redcarpet specific'
210
- end
211
- end
212
-
213
- markdown = "Introduction:\n```ruby\nputs\n\nputs\n```"
214
- html = htmlify(markdown, :markdown)
215
- expect(html).to match %r{^<p>Introduction:</p>.*<code class="ruby">}m
216
- end
217
-
218
- it "sets env and env-yard attributes (AsciiDoc specific)" do
219
- adoc = <<-EOF.strip.gsub(/^\s+/, "") # strip and unindent
220
- ifdef::env[]
221
- Attribute "env" is set, and its value is "{env}".
222
- endif::[]
223
-
224
- ifdef::env-yard[]
225
- Attribute "env-yard" is set, and its value is "{env-yard}".
226
- endif::[]
227
- EOF
228
- html = htmlify(adoc, :asciidoc)
229
- expect(html).to match(/"env" is set, and its value is "yard"./)
230
- expect(html).to match(/"env-yard" is set, and its value is ""./)
231
- end
232
- end
233
-
234
- describe "#link_object" do
235
- let(:object) { CodeObjects::NamespaceObject.new(nil, :YARD) }
236
-
237
- it "returns the object path if there's no serializer and no title" do
238
- allow(self).to receive(:serializer).and_return(nil)
239
- expect(link_object(CodeObjects::NamespaceObject.new(nil, :YARD))).to eq "YARD"
240
- end
241
-
242
- it "returns the title if there's a title but no serializer" do
243
- allow(self).to receive(:serializer).and_return(nil)
244
- expect(link_object(CodeObjects::NamespaceObject.new(nil, :YARD), 'title')).to eq "title"
245
- end
246
-
247
- it "links objects from overload tag" do
248
- YARD.parse_string <<-'eof'
249
- module Foo
250
- class Bar; def a; end end
251
- class Baz
252
- # @overload a
253
- def a; end
254
- end
255
- end
256
- eof
257
- obj = Registry.at('Foo::Baz#a').tag(:overload)
258
- allow(self).to receive(:serializer).and_return(Serializers::FileSystemSerializer.new)
259
- allow(self).to receive(:object).and_return(obj)
260
- expect(link_object("Bar#a")).to match(/href="Bar.html#a-instance_method"/)
261
- end
262
-
263
- it "uses relative path in title" do
264
- CodeObjects::ModuleObject.new(:root, :YARD)
265
- CodeObjects::ClassObject.new(P('YARD'), :Bar)
266
- allow(self).to receive(:object).and_return(CodeObjects::ModuleObject.new(P('YARD'), :Foo))
267
- allow(self).to receive(:serializer).and_return(Serializers::FileSystemSerializer.new)
268
- expect(link_object("Bar")).to match %r{>Bar</a>}
269
- end
270
-
271
- it "uses #title if overridden" do
272
- CodeObjects::ModuleObject.new(:root, :YARD)
273
- CodeObjects::ClassObject.new(P('YARD'), :Bar)
274
- allow(Registry.at('YARD::Bar')).to receive(:title).and_return('TITLE!')
275
- allow(self).to receive(:object).and_return(Registry.at('YARD::Bar'))
276
- allow(self).to receive(:serializer).and_return(Serializers::FileSystemSerializer.new)
277
- expect(link_object("Bar")).to match %r{>TITLE!</a>}
278
- end
279
-
280
- it "uses relative path to parent class in title" do
281
- root = CodeObjects::ModuleObject.new(:root, :YARD)
282
- obj = CodeObjects::ModuleObject.new(root, :SubModule)
283
- allow(self).to receive(:object).and_return(obj)
284
- allow(self).to receive(:serializer).and_return(Serializers::FileSystemSerializer.new)
285
- expect(link_object("YARD")).to match %r{>YARD</a>}
286
- end
287
-
288
- it "uses Klass.foo when linking to class method in current namespace" do
289
- root = CodeObjects::ModuleObject.new(:root, :Klass)
290
- CodeObjects::MethodObject.new(root, :foo, :class)
291
- allow(self).to receive(:object).and_return(root)
292
- allow(self).to receive(:serializer).and_return(Serializers::FileSystemSerializer.new)
293
- expect(link_object("foo")).to match %r{>Klass.foo</a>}
294
- end
295
-
296
- it "escapes method name in title" do
297
- YARD.parse_string <<-'eof'
298
- class Array
299
- def &(other)
300
- end
301
- end
302
- eof
303
- obj = Registry.at('Array#&')
304
- allow(self).to receive(:serializer).and_return(Serializers::FileSystemSerializer.new)
305
- allow(self).to receive(:object).and_return(obj)
306
- expect(link_object("Array#&")).to match(/title="Array#&amp; \(method\)"/)
307
- end
308
- end
309
-
310
- describe "#url_for" do
311
- before { Registry.clear }
312
-
313
- it "returns nil if serializer is nil" do
314
- allow(self).to receive(:serializer).and_return nil
315
- allow(self).to receive(:object).and_return Registry.root
316
- expect(url_for(P("Mod::Class#meth"))).to be nil
317
- end
318
-
319
- it "returns nil if object is hidden" do
320
- yard = CodeObjects::ModuleObject.new(:root, :YARD)
321
-
322
- allow(self).to receive(:serializer).and_return(Serializers::FileSystemSerializer.new)
323
- allow(self).to receive(:object).and_return Registry.root
324
- allow(self).to receive(:options).and_return OpenStruct.new(:verifier => Verifier.new('false'))
325
-
326
- expect(url_for(yard)).to be nil
327
- end
328
-
329
- it "returns nil if serializer does not implement #serialized_path" do
330
- allow(self).to receive(:serializer).and_return Serializers::Base.new
331
- allow(self).to receive(:object).and_return Registry.root
332
- expect(url_for(P("Mod::Class#meth"))).to be nil
333
- end
334
-
335
- it "links to a path/file for a namespace object" do
336
- allow(self).to receive(:serializer).and_return Serializers::FileSystemSerializer.new
337
- allow(self).to receive(:object).and_return Registry.root
338
-
339
- yard = CodeObjects::ModuleObject.new(:root, :YARD)
340
- expect(url_for(yard)).to eq 'YARD.html'
341
- end
342
-
343
- it "links to the object's namespace path/file and use the object as the anchor" do
344
- allow(self).to receive(:serializer).and_return Serializers::FileSystemSerializer.new
345
- allow(self).to receive(:object).and_return Registry.root
346
-
347
- yard = CodeObjects::ModuleObject.new(:root, :YARD)
348
- meth = CodeObjects::MethodObject.new(yard, :meth)
349
- expect(url_for(meth)).to eq 'YARD.html#meth-instance_method'
350
- end
351
-
352
- it "properly urlencodes methods with punctuation in links" do
353
- obj = CodeObjects::MethodObject.new(nil, :/)
354
- serializer = double(:serializer, :serialized_path => "file.html")
355
- allow(self).to receive(:serializer).and_return serializer
356
- allow(self).to receive(:object).and_return obj
357
- expect(url_for(obj)).to eq "#%2F-instance_method"
358
- end
359
- end
360
-
361
- describe "#anchor_for" do
362
- it "does not urlencode data when called directly" do
363
- obj = CodeObjects::MethodObject.new(nil, :/)
364
- expect(anchor_for(obj)).to eq "/-instance_method"
365
- end
366
- end
367
-
368
- describe "#resolve_links" do
369
- def parse_link(link)
370
- results = {}
371
- link =~ %r{<a (.+?)>(.+?)</a>}m
372
- params = $1
373
- results[:inner_text] = $2
374
- params.scan(/\s*(\S+?)=['"](.+?)['"]\s*/).each do |key, value|
375
- results[key.to_sym] = value.gsub(/^["'](.+)["']$/, '\1')
376
- end
377
- results
378
- end
379
-
380
- it "escapes {} syntax with backslash (\\{foo bar})" do
381
- input = '\{foo bar} \{XYZ} \{file:FOO} $\{N-M}'
382
- output = '{foo bar} {XYZ} {file:FOO} ${N-M}'
383
- expect(resolve_links(input)).to eq output
384
- end
385
-
386
- it "escapes {} syntax with ! (!{foo bar})" do
387
- input = '!{foo bar} !{XYZ} !{file:FOO} $!{N-M}'
388
- output = '{foo bar} {XYZ} {file:FOO} ${N-M}'
389
- expect(resolve_links(input)).to eq output
390
- end
391
-
392
- it "links static files with file: prefix" do
393
- allow(self).to receive(:serializer).and_return Serializers::FileSystemSerializer.new
394
- allow(self).to receive(:object).and_return Registry.root
395
-
396
- expect(parse_link(resolve_links("{file:TEST.txt#abc}"))).to eq(
397
- :inner_text => "TEST",
398
- :title => "TEST",
399
- :href => "file.TEST.html#abc"
400
- )
401
- expect(parse_link(resolve_links("{file:TEST.txt title}"))).to eq(
402
- :inner_text => "title",
403
- :title => "title",
404
- :href => "file.TEST.html"
405
- )
406
- end
407
-
408
- it "creates regular links with http:// or https:// prefixes" do
409
- expect(parse_link(resolve_links("{http://example.com}"))).to eq(
410
- :inner_text => "http://example.com",
411
- :target => "_parent",
412
- :href => "http://example.com",
413
- :title => "http://example.com"
414
- )
415
- expect(parse_link(resolve_links("{http://example.com title}"))).to eq(
416
- :inner_text => "title",
417
- :target => "_parent",
418
- :href => "http://example.com",
419
- :title => "title"
420
- )
421
- end
422
-
423
- it "creates mailto links with mailto: prefixes" do
424
- expect(parse_link(resolve_links('{mailto:joanna@example.com}'))).to eq(
425
- :inner_text => 'mailto:joanna@example.com',
426
- :target => '_parent',
427
- :href => 'mailto:joanna@example.com',
428
- :title => 'mailto:joanna@example.com'
429
- )
430
- expect(parse_link(resolve_links('{mailto:steve@example.com Steve}'))).to eq(
431
- :inner_text => 'Steve',
432
- :target => '_parent',
433
- :href => 'mailto:steve@example.com',
434
- :title => 'Steve'
435
- )
436
- end
437
-
438
- it "ignores {links} that begin with |...|" do
439
- expect(resolve_links("{|x|x == 1}")).to eq "{|x|x == 1}"
440
- end
441
-
442
- it "gracefully ignores {} in links" do
443
- allow(self).to receive(:linkify).with('Foo', 'Foo').and_return('FOO')
444
- expect(resolve_links("{} {} {Foo Foo}")).to eq '{} {} FOO'
445
- end
446
-
447
- %w(tt code pre).each do |tag|
448
- it "ignores links in <#{tag}>" do
449
- text = "<#{tag}>{Foo}</#{tag}>"
450
- expect(resolve_links(text)).to eq text
451
- end
452
- end
453
-
454
- it "resolves {Name}" do
455
- expect(self).to receive(:link_file).with('TEST', nil, nil).and_return('')
456
- resolve_links("{file:TEST}")
457
- end
458
-
459
- it "resolves ({Name})" do
460
- expect(self).to receive(:link_file).with('TEST', nil, nil).and_return('')
461
- resolve_links("({file:TEST})")
462
- end
463
-
464
- it "resolves link with newline in title-part" do
465
- expect(parse_link(resolve_links("{http://example.com foo\nbar}"))).to eq(
466
- :inner_text => "foo bar",
467
- :target => "_parent",
468
- :href => "http://example.com",
469
- :title => "foo bar"
470
- )
471
- end
472
-
473
- it "resolves links to methods whose names have been escaped" do
474
- expect(self).to receive(:linkify).with('Object#<<', nil).and_return('')
475
- resolve_links("{Object#&lt;&lt;}")
476
- end
477
-
478
- it "warns about missing reference at right file location for object" do
479
- YARD.parse_string <<-eof
480
- # Comments here
481
- # And a reference to {InvalidObject}
482
- class MyObject; end
483
- eof
484
- logger = double(:log)
485
- expect(logger).to receive(:warn).ordered.with(
486
- "In file `(stdin)':2: Cannot resolve link to InvalidObject from text:\n\t...{InvalidObject}"
487
- )
488
- allow(self).to receive(:log).and_return(logger)
489
- allow(self).to receive(:object).and_return(Registry.at('MyObject'))
490
- resolve_links(object.docstring)
491
- end
492
-
493
- it "shows ellipsis on either side if there is more on the line in a reference warning" do
494
- YARD.parse_string <<-eof
495
- # {InvalidObject1} beginning of line
496
- # end of line {InvalidObject2}
497
- # Middle of {InvalidObject3} line
498
- # {InvalidObject4}
499
- class MyObject; end
500
- eof
501
- logger = double(:log)
502
- expect(logger).to receive(:warn).ordered.with("In file `(stdin)':1: Cannot resolve link to InvalidObject1 from text:\n\t{InvalidObject1}...")
503
- expect(logger).to receive(:warn).ordered.with("In file `(stdin)':2: Cannot resolve link to InvalidObject2 from text:\n\t...{InvalidObject2}")
504
- expect(logger).to receive(:warn).ordered.with("In file `(stdin)':3: Cannot resolve link to InvalidObject3 from text:\n\t...{InvalidObject3}...")
505
- expect(logger).to receive(:warn).ordered.with("In file `(stdin)':4: Cannot resolve link to InvalidObject4 from text:\n\t{InvalidObject4}")
506
- allow(self).to receive(:log).and_return(logger)
507
- allow(self).to receive(:object).and_return(Registry.at('MyObject'))
508
- resolve_links(object.docstring)
509
- end
510
-
511
- it "warns about missing reference for file template (no object)" do
512
- @file = CodeObjects::ExtraFileObject.new('myfile.txt', '')
513
- logger = double(:log)
514
- expect(logger).to receive(:warn).ordered.with("In file `myfile.txt':3: Cannot resolve link to InvalidObject from text:\n\t...{InvalidObject Some Title}")
515
- allow(self).to receive(:log).and_return(logger)
516
- allow(self).to receive(:object).and_return(Registry.root)
517
- resolve_links(<<-eof)
518
- Hello world
519
- This is a line
520
- And {InvalidObject Some Title}
521
- And more.
522
- eof
523
- end
524
- end
525
-
526
- describe "#signature" do
527
- before do
528
- arrow = "&#x21d2;"
529
- @results = {
530
- :regular => "#<strong>foo</strong> #{arrow} Object",
531
- :default_return => "#<strong>foo</strong> #{arrow} Hello",
532
- :no_default_return => "#<strong>foo</strong>",
533
- :private_class => ".<strong>foo</strong> #{arrow} Object <span class=\"extras\">(private)</span>",
534
- :single => "#<strong>foo</strong> #{arrow} String",
535
- :two_types => "#<strong>foo</strong> #{arrow} String, Symbol",
536
- :two_types_multitag => "#<strong>foo</strong> #{arrow} String, Symbol",
537
- :type_nil => "#<strong>foo</strong> #{arrow} Type<sup>?</sup>",
538
- :type_array => "#<strong>foo</strong> #{arrow} Type<sup>+</sup>",
539
- :multitype => "#<strong>foo</strong> #{arrow} Type, ...",
540
- :void => "#<strong>foo</strong> #{arrow} void",
541
- :hide_void => "#<strong>foo</strong>",
542
- :block => "#<strong>foo</strong> {|a, b, c| ... } #{arrow} Object",
543
- :empty_overload => "#<strong>foobar</strong> #{arrow} String"
544
- }
545
- end
546
-
547
- def format_types(types, _brackets = false) types.join(", ") end
548
- def signature(obj, link = false) super(obj, link).strip end
549
-
550
- it_should_behave_like "signature"
551
-
552
- it "links to regular method if overload name does not have the same method name" do
553
- YARD.parse_string <<-eof
554
- class Foo
555
- # @overload bar(a, b, c)
556
- def foo; end
557
- end
558
- eof
559
- serializer = double(:serializer)
560
- allow(serializer).to receive(:serialized_path).with(Registry.at('Foo')).and_return('')
561
- allow(self).to receive(:serializer).and_return(serializer)
562
- allow(self).to receive(:object).and_return(Registry.at('Foo'))
563
- expect(signature(Registry.at('Foo#foo').tag(:overload), true)).to eq(
564
- "<a href=\"#foo-instance_method\" title=\"#bar (instance method)\">#<strong>bar</strong>(a, b, c) </a>"
565
- )
566
- end
567
- end
568
-
569
- describe "#html_syntax_highlight" do
570
- subject do
571
- obj = OpenStruct.new
572
- obj.options = options
573
- obj.object = Registry.root
574
- obj.extend(Templates::Helpers::HtmlHelper)
575
- obj
576
- end
577
-
578
- it "returns empty string on nil input" do
579
- expect(subject.html_syntax_highlight(nil)).to eq ''
580
- end
581
-
582
- it "calls #html_syntax_highlight_ruby by default" do
583
- Registry.root.source_type = nil
584
- expect(subject).to receive(:html_syntax_highlight_ruby).with('def x; end')
585
- subject.html_syntax_highlight('def x; end')
586
- end
587
-
588
- it "calls #html_syntax_highlight_NAME if there's an object with a #source_type" do
589
- subject.object = OpenStruct.new(:source_type => :NAME)
590
- expect(subject).to receive(:html_markup_html) {|text| text }
591
- expect(subject).to receive(:html_syntax_highlight_NAME).and_return("foobar")
592
- expect(subject.htmlify('<pre><code>def x; end</code></pre>', :html)).to eq(
593
- '<pre class="code NAME"><code class="NAME">foobar</code></pre>'
594
- )
595
- end
596
-
597
- it "adds !!!LANG to className in outputted pre tag" do
598
- subject.object = OpenStruct.new(:source_type => :LANG)
599
- expect(subject).to receive(:html_markup_html) {|text| text }
600
- expect(subject).to receive(:html_syntax_highlight_LANG).and_return("foobar")
601
- expect(subject.htmlify("<pre><code>!!!LANG\ndef x; end</code></pre>", :html)).to eq(
602
- '<pre class="code LANG"><code class="LANG">foobar</code></pre>'
603
- )
604
- end
605
-
606
- it "calls html_syntax_highlight_NAME if source starts with !!!NAME" do
607
- expect(subject).to receive(:html_syntax_highlight_NAME).and_return("foobar")
608
- expect(subject.html_syntax_highlight(<<-eof
609
- !!!NAME
610
- def x; end
611
- eof
612
- )).to eq "foobar"
613
- end
614
-
615
- it "does not highlight if highlight option is false" do
616
- subject.options.highlight = false
617
- expect(subject).not_to receive(:html_syntax_highlight_ruby)
618
- expect(subject.html_syntax_highlight('def x; end')).to eq 'def x; end'
619
- end
620
-
621
- it "does not highlight if there is no highlight method specified by !!!NAME" do
622
- def subject.respond_to?(method, include_all = false)
623
- return false if method == 'html_syntax_highlight_NAME'
624
- super
625
- end
626
- expect(subject).not_to receive(:html_syntax_highlight_NAME)
627
- expect(subject.html_syntax_highlight("!!!NAME\ndef x; end")).to eq "def x; end"
628
- end
629
-
630
- it "highlights as ruby if htmlify(text, :ruby) is called" do
631
- expect(subject).to receive(:html_syntax_highlight_ruby).with('def x; end').and_return('x')
632
- expect(subject.htmlify('def x; end', :ruby)).to eq '<pre class="code ruby">x</pre>'
633
- end
634
-
635
- it "does not prioritize object source type when called directly" do
636
- expect(subject).to receive(:html_syntax_highlight_ruby).with('def x; end').and_return('x')
637
- subject.object = OpenStruct.new(:source_type => :c)
638
- expect(subject.html_syntax_highlight("def x; end")).to eq "x"
639
- end
640
-
641
- it "doesn't escape code snippets twice" do
642
- expect(subject.htmlify('<pre lang="foo"><code>{"foo" => 1}</code></pre>', :html)).to eq(
643
- '<pre class="code foo"><code class="foo">{&quot;foo&quot; =&gt; 1}</code></pre>'
644
- )
645
- end
646
-
647
- it "highlights source when matching a pre lang= tag" do
648
- expect(subject.htmlify('<pre lang="foo"><code>x = 1</code></pre>', :html)).to eq(
649
- '<pre class="code foo"><code class="foo">x = 1</code></pre>'
650
- )
651
- end
652
-
653
- it "highlights source when matching a code class= tag" do
654
- expect(subject.htmlify('<pre><code class="foo">x = 1</code></pre>', :html)).to eq(
655
- '<pre class="code foo"><code class="foo">x = 1</code></pre>'
656
- )
657
- end
658
- end
659
-
660
- describe "#link_url" do
661
- it "adds target if scheme is provided" do
662
- expect(link_url("http://url.com")).to include(" target=\"_parent\"")
663
- expect(link_url("https://url.com")).to include(" target=\"_parent\"")
664
- expect(link_url("irc://url.com")).to include(" target=\"_parent\"")
665
- expect(link_url("../not/scheme")).not_to include("target")
666
- end
667
- end
668
- end
1
+ # frozen_string_literal: true
2
+ require File.dirname(__FILE__) + "/shared_signature_examples"
3
+ require 'ostruct'
4
+
5
+ RSpec.describe YARD::Templates::Helpers::HtmlHelper do
6
+ include YARD::Templates::Helpers::BaseHelper
7
+ include YARD::Templates::Helpers::HtmlHelper
8
+ include YARD::Templates::Helpers::MethodHelper
9
+
10
+ def options
11
+ Templates::TemplateOptions.new.tap do |o|
12
+ o.reset_defaults
13
+ o.default_return = nil
14
+ end
15
+ end
16
+
17
+ describe "#h" do
18
+ it "uses #h to escape HTML" do
19
+ expect(h('Usage: foo "bar" <baz>')).to eq "Usage: foo &quot;bar&quot; &lt;baz&gt;"
20
+ end
21
+ end
22
+
23
+ describe "#charset" do
24
+ it "returns foo if LANG=foo" do
25
+ expect(ENV).to receive(:[]).with('LANG').and_return('shift_jis') if YARD.ruby18?
26
+ expect(Encoding.default_external).to receive(:name).and_return('shift_jis') if defined?(Encoding)
27
+ expect(charset).to eq 'shift_jis'
28
+ end
29
+
30
+ ['US-ASCII', 'ASCII-7BIT', 'ASCII-8BIT'].each do |type|
31
+ it "converts #{type} to iso-8859-1" do
32
+ expect(ENV).to receive(:[]).with('LANG').and_return(type) if YARD.ruby18?
33
+ expect(Encoding.default_external).to receive(:name).and_return(type) if defined?(Encoding)
34
+ expect(charset).to eq 'iso-8859-1'
35
+ end
36
+ end
37
+
38
+ it "supports utf8 as an encoding value for utf-8" do
39
+ type = 'utf8'
40
+ expect(ENV).to receive(:[]).with('LANG').and_return(type) if YARD.ruby18?
41
+ expect(Encoding.default_external).to receive(:name).and_return(type) if defined?(Encoding)
42
+ expect(charset).to eq 'utf-8'
43
+ end
44
+
45
+ it "takes file encoding if there is a file" do
46
+ @file = OpenStruct.new(:contents => String.new('foo').force_encoding('sjis'))
47
+ # not the correct charset name, but good enough
48
+ expect(['Shift_JIS', 'Windows-31J']).to include(charset)
49
+ end if YARD.ruby19?
50
+
51
+ it "takes file encoding if there is a file" do
52
+ allow(ENV).to receive(:[]).with('LANG').and_return('utf-8') if YARD.ruby18?
53
+ @file = OpenStruct.new(:contents => 'foo')
54
+ expect(charset).to eq 'utf-8'
55
+ end if YARD.ruby18?
56
+
57
+ if YARD.ruby18?
58
+ it "returns utf-8 if no LANG env is set" do
59
+ expect(ENV).to receive(:[]).with('LANG').and_return(nil)
60
+ expect(charset).to eq 'utf-8'
61
+ end
62
+
63
+ it "only returns charset part of lang" do
64
+ expect(ENV).to receive(:[]).with('LANG').and_return('en_US.UTF-8')
65
+ expect(charset).to eq 'utf-8'
66
+ end
67
+ end
68
+ end
69
+
70
+ describe "#format_types" do
71
+ it "includes brackets by default" do
72
+ text = ["String"]
73
+ expect(self).to receive(:linkify).at_least(1).times.with("String", "String").and_return("String")
74
+ expect(format_types(text)).to eq format_types(text, true)
75
+ expect(format_types(text)).to eq "(<tt>String</tt>)"
76
+ end
77
+
78
+ it "avoids brackets if brackets=false" do
79
+ expect(self).to receive(:linkify).with("String", "String").and_return("String")
80
+ expect(self).to receive(:linkify).with("Symbol", "Symbol").and_return("Symbol")
81
+ expect(format_types(["String", "Symbol"], false)).to eq "<tt>String</tt>, <tt>Symbol</tt>"
82
+ end
83
+
84
+ {"String" => [["String"],
85
+ "<tt><a href=''>String</a></tt>"],
86
+ "A::B::C" => [["A::B::C"],
87
+ "<tt><a href=''>A::B::C</a></tt>"],
88
+ "Array<String>" => [["Array", "String"],
89
+ "<tt><a href=''>Array</a>&lt;<a href=''>String</a>&gt;</tt>"],
90
+ "Array<String, Symbol>" => [["Array", "String", "Symbol"],
91
+ "<tt><a href=''>Array</a>&lt;<a href=''>String</a>, <a href=''>Symbol</a>&gt;</tt>"],
92
+ "Array<{String => Array<Symbol>}>" => [["Array", "String", "Array", "Symbol"],
93
+ "<tt><a href=''>Array</a>&lt;{<a href=''>String</a> =&gt; " \
94
+ "<a href=''>Array</a>&lt;<a href=''>Symbol</a>&gt;}&gt;</tt>"]}.each do |text, values|
95
+ it "links all classes in #{text}" do
96
+ if text.count('<') > 0
97
+ expect(self).to receive(:h).with('<').at_least(text.count('<')).times.and_return("&lt;")
98
+ end
99
+ if text.count('>') > 0
100
+ expect(self).to receive(:h).with('>').at_least(text.count('>')).times.and_return("&gt;")
101
+ end
102
+ values[0].each {|v| expect(self).to receive(:linkify).with(v, v).and_return("<a href=''>#{v}</a>") }
103
+ expect(format_types([text], false)).to eq values[1]
104
+ end
105
+ end
106
+ end
107
+
108
+ describe "#htmlify" do
109
+ it "does not use hard breaks for textile markup (RedCloth specific)" do
110
+ begin; require 'redcloth'; rescue LoadError; pending 'test requires redcloth gem' end
111
+ expect(htmlify("A\nB", :textile)).not_to include("<br")
112
+ end
113
+
114
+ it "uses hard breaks for textile_strict markup (RedCloth specific)" do
115
+ begin; require 'redcloth'; rescue LoadError; pending 'test requires redcloth gem' end
116
+ expect(htmlify("A\nB", :textile_strict)).to include("<br")
117
+ end
118
+
119
+ it "handles various encodings" do
120
+ allow(self).to receive(:object).and_return(Registry.root)
121
+ text = String.new("\xB0\xB1")
122
+ if defined?(Encoding)
123
+ utf8 = Encoding.find('utf-8')
124
+
125
+ Encoding.default_internal = utf8 unless Encoding.default_internal == utf8
126
+ text = text.force_encoding('binary')
127
+ end
128
+ htmlify(text, :text)
129
+ # TODO: add more encoding tests
130
+ end
131
+
132
+ it "returns pre-formatted text with :pre markup" do
133
+ expect(htmlify("fo\no\n\nbar<>", :pre)).to eq "<pre>fo\no\n\nbar&lt;&gt;</pre>"
134
+ end
135
+
136
+ it "returns regular text with :text markup" do
137
+ expect(htmlify("fo\no\n\nbar<>", :text)).to eq "fo<br/>o<br/><br/>bar&lt;&gt;"
138
+ end
139
+
140
+ it "returns unmodified text with :none markup" do
141
+ expect(htmlify("fo\no\n\nbar<>", :none)).to eq "fo\no\n\nbar&lt;&gt;"
142
+ end
143
+
144
+ it "highlights ruby if markup is :ruby" do
145
+ expect(htmlify("class Foo; end", :ruby)).to match(/\A<pre class="code ruby"><span/)
146
+ end
147
+
148
+ it "includes file and htmlifies it" do
149
+ load_markup_provider(:rdoc)
150
+ expect(File).to receive(:file?).with('foo.rdoc').and_return(true)
151
+ expect(File).to receive(:read).with('foo.rdoc').and_return('HI')
152
+ expect(htmlify("{include:file:foo.rdoc}", :rdoc).gsub(/\s+/, '')).to eq "<p>HI</p>"
153
+ end
154
+
155
+ it "allows inline includes for {include:} in the middle of a line" do
156
+ load_markup_provider(:rdoc)
157
+ expect(File).to receive(:file?).with('foo.rdoc').and_return(true)
158
+ expect(File).to receive(:read).with('foo.rdoc').and_return('HI')
159
+ expect(htmlify("test {include:file:foo.rdoc}", :rdoc).gsub(/[\r?\n]+/, '')).to eq '<p>test HI</p>'
160
+ end
161
+
162
+ it "autolinks URLs (markdown specific)" do
163
+ log.enter_level(Logger::FATAL) do
164
+ unless markup_class(:markdown).to_s == "RedcarpetCompat"
165
+ pending 'This test depends on a markdown engine that supports autolinking'
166
+ end
167
+ end
168
+ expect(htmlify('http://example.com', :markdown).chomp.gsub('&#47;', '/')).to eq(
169
+ '<p><a href="http://example.com">http://example.com</a></p>'
170
+ )
171
+ end
172
+
173
+ it "does not autolink URLs inside of {} (markdown specific)" do
174
+ log.enter_level(Logger::FATAL) do
175
+ pending 'This test depends on markdown' unless markup_class(:markdown)
176
+ end
177
+ expect(htmlify('{http://example.com Title}', :markdown).chomp).to match(
178
+ %r{<p><a href="http://example.com".*>Title</a></p>}
179
+ )
180
+ expect(htmlify('{http://example.com}', :markdown).chomp).to match(
181
+ %r{<p><a href="http://example.com".*>http://example.com</a></p>}
182
+ )
183
+ end
184
+
185
+ it "creates tables (markdown specific)" do
186
+ log.enter_level(Logger::FATAL) do
187
+ supports_table = %w(RedcarpetCompat Kramdown::Document)
188
+ unless supports_table.include?(markup_class(:markdown).to_s)
189
+ pending "This test depends on a markdown engine that supports tables"
190
+ end
191
+ end
192
+
193
+ markdown = <<-EOF.strip
194
+ City | State | Country
195
+ --------|-------|--------
196
+ Raleigh | NC | US
197
+ Seattle | WA | US
198
+ EOF
199
+
200
+ html = htmlify(markdown, :markdown)
201
+ expect(html).to match(/<table>/)
202
+ expect(html).to match %r{<th>City</th>}
203
+ expect(html).to match %r{<td>NC</td>}
204
+ end
205
+
206
+ it "handles fenced code blocks (Redcarpet specific)" do
207
+ log.enter_level(Logger::FATAL) do
208
+ unless markup_class(:markdown).to_s == 'RedcarpetCompat'
209
+ pending 'This test is Redcarpet specific'
210
+ end
211
+ end
212
+
213
+ markdown = "Introduction:\n```ruby\nputs\n\nputs\n```"
214
+ html = htmlify(markdown, :markdown)
215
+ expect(html).to match %r{^<p>Introduction:</p>.*<code class="ruby">}m
216
+ end
217
+
218
+ it "sets env and env-yard attributes (AsciiDoc specific)" do
219
+ adoc = <<-EOF.strip.gsub(/^ +/, "") # strip and unindent
220
+ ifdef::env[]
221
+ Attribute "env" is set, and its value is "{env}".
222
+ endif::[]
223
+
224
+ ifdef::env-yard[]
225
+ Attribute "env-yard" is set, and its value is "{env-yard}".
226
+ endif::[]
227
+ EOF
228
+ html = htmlify(adoc, :asciidoc)
229
+ expect(html).to match(/"env" is set, and its value is "yard"./)
230
+ expect(html).to match(/"env-yard" is set, and its value is ""./)
231
+ end
232
+
233
+ it "should not include the document title from the AsciiDoc header" do
234
+ adoc = <<-EOF.strip.gsub(/^ +/, "") # strip and unindent
235
+ = Project Name
236
+
237
+ Introduction.
238
+
239
+ == Installation
240
+
241
+ Installation instructions.
242
+
243
+ == Usage
244
+
245
+ Usage instructions.
246
+ EOF
247
+ html = htmlify(adoc, :asciidoc)
248
+ expect(html).to_not match(/Project Name/)
249
+ expect(html).to include(%(<h2 id="_installation">Installation</h2>))
250
+ end
251
+ end
252
+
253
+ describe "#link_object" do
254
+ let(:object) { CodeObjects::NamespaceObject.new(nil, :YARD) }
255
+
256
+ it "returns the object path if there's no serializer and no title" do
257
+ allow(self).to receive(:serializer).and_return(nil)
258
+ expect(link_object(CodeObjects::NamespaceObject.new(nil, :YARD))).to eq "YARD"
259
+ end
260
+
261
+ it "returns the title if there's a title but no serializer" do
262
+ allow(self).to receive(:serializer).and_return(nil)
263
+ expect(link_object(CodeObjects::NamespaceObject.new(nil, :YARD), 'title')).to eq "title"
264
+ end
265
+
266
+ it "links objects from overload tag" do
267
+ YARD.parse_string <<-'eof'
268
+ module Foo
269
+ class Bar; def a; end end
270
+ class Baz
271
+ # @overload a
272
+ def a; end
273
+ end
274
+ end
275
+ eof
276
+ obj = Registry.at('Foo::Baz#a').tag(:overload)
277
+ allow(self).to receive(:serializer).and_return(Serializers::FileSystemSerializer.new)
278
+ allow(self).to receive(:object).and_return(obj)
279
+ expect(link_object("Bar#a")).to match(/href="Bar.html#a-instance_method"/)
280
+ end
281
+
282
+ it "uses relative path in title" do
283
+ CodeObjects::ModuleObject.new(:root, :YARD)
284
+ CodeObjects::ClassObject.new(P('YARD'), :Bar)
285
+ allow(self).to receive(:object).and_return(CodeObjects::ModuleObject.new(P('YARD'), :Foo))
286
+ allow(self).to receive(:serializer).and_return(Serializers::FileSystemSerializer.new)
287
+ expect(link_object("Bar")).to match %r{>Bar</a>}
288
+ end
289
+
290
+ it "uses #title if overridden" do
291
+ CodeObjects::ModuleObject.new(:root, :YARD)
292
+ CodeObjects::ClassObject.new(P('YARD'), :Bar)
293
+ allow(Registry.at('YARD::Bar')).to receive(:title).and_return('TITLE!')
294
+ allow(self).to receive(:object).and_return(Registry.at('YARD::Bar'))
295
+ allow(self).to receive(:serializer).and_return(Serializers::FileSystemSerializer.new)
296
+ expect(link_object("Bar")).to match %r{>TITLE!</a>}
297
+ end
298
+
299
+ it "uses relative path to parent class in title" do
300
+ root = CodeObjects::ModuleObject.new(:root, :YARD)
301
+ obj = CodeObjects::ModuleObject.new(root, :SubModule)
302
+ allow(self).to receive(:object).and_return(obj)
303
+ allow(self).to receive(:serializer).and_return(Serializers::FileSystemSerializer.new)
304
+ expect(link_object("YARD")).to match %r{>YARD</a>}
305
+ end
306
+
307
+ it "uses Klass.foo when linking to class method in current namespace" do
308
+ root = CodeObjects::ModuleObject.new(:root, :Klass)
309
+ CodeObjects::MethodObject.new(root, :foo, :class)
310
+ allow(self).to receive(:object).and_return(root)
311
+ allow(self).to receive(:serializer).and_return(Serializers::FileSystemSerializer.new)
312
+ expect(link_object("foo")).to match %r{>Klass.foo</a>}
313
+ end
314
+
315
+ it "escapes method name in title" do
316
+ YARD.parse_string <<-'eof'
317
+ class Array
318
+ def &(other)
319
+ end
320
+ end
321
+ eof
322
+ obj = Registry.at('Array#&')
323
+ allow(self).to receive(:serializer).and_return(Serializers::FileSystemSerializer.new)
324
+ allow(self).to receive(:object).and_return(obj)
325
+ expect(link_object("Array#&")).to match(/title="Array#&amp; \(method\)"/)
326
+ end
327
+ end
328
+
329
+ describe "#url_for" do
330
+ before { Registry.clear }
331
+
332
+ it "returns nil if serializer is nil" do
333
+ allow(self).to receive(:serializer).and_return nil
334
+ allow(self).to receive(:object).and_return Registry.root
335
+ expect(url_for(P("Mod::Class#meth"))).to be nil
336
+ end
337
+
338
+ it "returns nil if object is hidden" do
339
+ yard = CodeObjects::ModuleObject.new(:root, :YARD)
340
+
341
+ allow(self).to receive(:serializer).and_return(Serializers::FileSystemSerializer.new)
342
+ allow(self).to receive(:object).and_return Registry.root
343
+ allow(self).to receive(:options).and_return OpenStruct.new(:verifier => Verifier.new('false'))
344
+
345
+ expect(url_for(yard)).to be nil
346
+ end
347
+
348
+ it "returns nil if serializer does not implement #serialized_path" do
349
+ allow(self).to receive(:serializer).and_return Serializers::Base.new
350
+ allow(self).to receive(:object).and_return Registry.root
351
+ expect(url_for(P("Mod::Class#meth"))).to be nil
352
+ end
353
+
354
+ it "links to a path/file for a namespace object" do
355
+ allow(self).to receive(:serializer).and_return Serializers::FileSystemSerializer.new
356
+ allow(self).to receive(:object).and_return Registry.root
357
+
358
+ yard = CodeObjects::ModuleObject.new(:root, :YARD)
359
+ expect(url_for(yard)).to eq 'YARD.html'
360
+ end
361
+
362
+ it "links to the object's namespace path/file and use the object as the anchor" do
363
+ allow(self).to receive(:serializer).and_return Serializers::FileSystemSerializer.new
364
+ allow(self).to receive(:object).and_return Registry.root
365
+
366
+ yard = CodeObjects::ModuleObject.new(:root, :YARD)
367
+ meth = CodeObjects::MethodObject.new(yard, :meth)
368
+ expect(url_for(meth)).to eq 'YARD.html#meth-instance_method'
369
+ end
370
+
371
+ it "properly urlencodes methods with punctuation in links" do
372
+ obj = CodeObjects::MethodObject.new(nil, :/)
373
+ serializer = double(:serializer, :serialized_path => "file.html")
374
+ allow(self).to receive(:serializer).and_return serializer
375
+ allow(self).to receive(:object).and_return obj
376
+ expect(url_for(obj)).to eq "#%2F-instance_method"
377
+ end
378
+ end
379
+
380
+ describe "#anchor_for" do
381
+ it "does not urlencode data when called directly" do
382
+ obj = CodeObjects::MethodObject.new(nil, :/)
383
+ expect(anchor_for(obj)).to eq "/-instance_method"
384
+ end
385
+ end
386
+
387
+ describe "#resolve_links" do
388
+ def parse_link(link)
389
+ results = {}
390
+ link =~ %r{<a (.+?)>(.+?)</a>}m
391
+ params = $1
392
+ results[:inner_text] = $2
393
+ params.scan(/\s*(\S+?)=['"](.+?)['"]\s*/).each do |key, value|
394
+ results[key.to_sym] = value.gsub(/^["'](.+)["']$/, '\1')
395
+ end
396
+ results
397
+ end
398
+
399
+ it "escapes {} syntax with backslash (\\{foo bar})" do
400
+ input = '\{foo bar} \{XYZ} \{file:FOO} $\{N-M}'
401
+ output = '{foo bar} {XYZ} {file:FOO} ${N-M}'
402
+ expect(resolve_links(input)).to eq output
403
+ end
404
+
405
+ it "escapes {} syntax with ! (!{foo bar})" do
406
+ input = '!{foo bar} !{XYZ} !{file:FOO} $!{N-M}'
407
+ output = '{foo bar} {XYZ} {file:FOO} ${N-M}'
408
+ expect(resolve_links(input)).to eq output
409
+ end
410
+
411
+ it "links static files with file: prefix" do
412
+ allow(self).to receive(:serializer).and_return Serializers::FileSystemSerializer.new
413
+ allow(self).to receive(:object).and_return Registry.root
414
+
415
+ expect(parse_link(resolve_links("{file:TEST.txt#abc}"))).to eq(
416
+ :inner_text => "TEST",
417
+ :title => "TEST",
418
+ :href => "file.TEST.html#abc"
419
+ )
420
+ expect(parse_link(resolve_links("{file:TEST.txt title}"))).to eq(
421
+ :inner_text => "title",
422
+ :title => "title",
423
+ :href => "file.TEST.html"
424
+ )
425
+ end
426
+
427
+ it "creates regular links with http:// or https:// prefixes" do
428
+ expect(parse_link(resolve_links("{http://example.com}"))).to eq(
429
+ :inner_text => "http://example.com",
430
+ :target => "_parent",
431
+ :href => "http://example.com",
432
+ :title => "http://example.com"
433
+ )
434
+ expect(parse_link(resolve_links("{http://example.com title}"))).to eq(
435
+ :inner_text => "title",
436
+ :target => "_parent",
437
+ :href => "http://example.com",
438
+ :title => "title"
439
+ )
440
+ end
441
+
442
+ it "creates mailto links with mailto: prefixes" do
443
+ expect(parse_link(resolve_links('{mailto:joanna@example.com}'))).to eq(
444
+ :inner_text => 'mailto:joanna@example.com',
445
+ :target => '_parent',
446
+ :href => 'mailto:joanna@example.com',
447
+ :title => 'mailto:joanna@example.com'
448
+ )
449
+ expect(parse_link(resolve_links('{mailto:steve@example.com Steve}'))).to eq(
450
+ :inner_text => 'Steve',
451
+ :target => '_parent',
452
+ :href => 'mailto:steve@example.com',
453
+ :title => 'Steve'
454
+ )
455
+ end
456
+
457
+ it "ignores {links} that begin with |...|" do
458
+ expect(resolve_links("{|x|x == 1}")).to eq "{|x|x == 1}"
459
+ end
460
+
461
+ it "gracefully ignores {} in links" do
462
+ allow(self).to receive(:linkify).with('Foo', 'Foo').and_return('FOO')
463
+ expect(resolve_links("{} {} {Foo Foo}")).to eq '{} {} FOO'
464
+ end
465
+
466
+ %w(tt code pre).each do |tag|
467
+ it "ignores links in <#{tag}>" do
468
+ text = "<#{tag}>{Foo}</#{tag}>"
469
+ expect(resolve_links(text)).to eq text
470
+ end
471
+ end
472
+
473
+ it "resolves {Name}" do
474
+ expect(self).to receive(:link_file).with('TEST', nil, nil).and_return('')
475
+ resolve_links("{file:TEST}")
476
+ end
477
+
478
+ it "resolves ({Name})" do
479
+ expect(self).to receive(:link_file).with('TEST', nil, nil).and_return('')
480
+ resolve_links("({file:TEST})")
481
+ end
482
+
483
+ it "resolves link with newline in title-part" do
484
+ expect(parse_link(resolve_links("{http://example.com foo\nbar}"))).to eq(
485
+ :inner_text => "foo bar",
486
+ :target => "_parent",
487
+ :href => "http://example.com",
488
+ :title => "foo bar"
489
+ )
490
+ end
491
+
492
+ it "resolves links to methods whose names have been escaped" do
493
+ expect(self).to receive(:linkify).with('Object#<<', nil).and_return('')
494
+ resolve_links("{Object#&lt;&lt;}")
495
+ end
496
+
497
+ it "warns about missing reference at right file location for object" do
498
+ YARD.parse_string <<-eof
499
+ # Comments here
500
+ # And a reference to {InvalidObject}
501
+ class MyObject; end
502
+ eof
503
+ logger = double(:log)
504
+ expect(logger).to receive(:warn).ordered.with(
505
+ "In file `(stdin)':2: Cannot resolve link to InvalidObject from text:\n\t...{InvalidObject}"
506
+ )
507
+ allow(self).to receive(:log).and_return(logger)
508
+ allow(self).to receive(:object).and_return(Registry.at('MyObject'))
509
+ resolve_links(object.docstring)
510
+ end
511
+
512
+ it "shows ellipsis on either side if there is more on the line in a reference warning" do
513
+ YARD.parse_string <<-eof
514
+ # {InvalidObject1} beginning of line
515
+ # end of line {InvalidObject2}
516
+ # Middle of {InvalidObject3} line
517
+ # {InvalidObject4}
518
+ class MyObject; end
519
+ eof
520
+ logger = double(:log)
521
+ expect(logger).to receive(:warn).ordered.with("In file `(stdin)':1: Cannot resolve link to InvalidObject1 from text:\n\t{InvalidObject1}...")
522
+ expect(logger).to receive(:warn).ordered.with("In file `(stdin)':2: Cannot resolve link to InvalidObject2 from text:\n\t...{InvalidObject2}")
523
+ expect(logger).to receive(:warn).ordered.with("In file `(stdin)':3: Cannot resolve link to InvalidObject3 from text:\n\t...{InvalidObject3}...")
524
+ expect(logger).to receive(:warn).ordered.with("In file `(stdin)':4: Cannot resolve link to InvalidObject4 from text:\n\t{InvalidObject4}")
525
+ allow(self).to receive(:log).and_return(logger)
526
+ allow(self).to receive(:object).and_return(Registry.at('MyObject'))
527
+ resolve_links(object.docstring)
528
+ end
529
+
530
+ it "warns about missing reference for file template (no object)" do
531
+ @file = CodeObjects::ExtraFileObject.new('myfile.txt', '')
532
+ logger = double(:log)
533
+ expect(logger).to receive(:warn).ordered.with("In file `myfile.txt':3: Cannot resolve link to InvalidObject from text:\n\t...{InvalidObject Some Title}")
534
+ allow(self).to receive(:log).and_return(logger)
535
+ allow(self).to receive(:object).and_return(Registry.root)
536
+ resolve_links(<<-eof)
537
+ Hello world
538
+ This is a line
539
+ And {InvalidObject Some Title}
540
+ And more.
541
+ eof
542
+ end
543
+ end
544
+
545
+ describe "#signature" do
546
+ before do
547
+ arrow = "&#x21d2;"
548
+ @results = {
549
+ :regular => "#<strong>foo</strong> #{arrow} Object",
550
+ :default_return => "#<strong>foo</strong> #{arrow} Hello",
551
+ :no_default_return => "#<strong>foo</strong>",
552
+ :private_class => ".<strong>foo</strong> #{arrow} Object <span class=\"extras\">(private)</span>",
553
+ :single => "#<strong>foo</strong> #{arrow} String",
554
+ :two_types => "#<strong>foo</strong> #{arrow} String, Symbol",
555
+ :two_types_multitag => "#<strong>foo</strong> #{arrow} String, Symbol",
556
+ :type_nil => "#<strong>foo</strong> #{arrow} Type<sup>?</sup>",
557
+ :type_array => "#<strong>foo</strong> #{arrow} Type<sup>+</sup>",
558
+ :multitype => "#<strong>foo</strong> #{arrow} Type, ...",
559
+ :void => "#<strong>foo</strong> #{arrow} void",
560
+ :hide_void => "#<strong>foo</strong>",
561
+ :block => "#<strong>foo</strong> {|a, b, c| ... } #{arrow} Object",
562
+ :empty_overload => "#<strong>foobar</strong> #{arrow} String"
563
+ }
564
+ end
565
+
566
+ def format_types(types, _brackets = false) types.join(", ") end
567
+ def signature(obj, link = false) super(obj, link).strip end
568
+
569
+ it_should_behave_like "signature"
570
+
571
+ it "links to regular method if overload name does not have the same method name" do
572
+ YARD.parse_string <<-eof
573
+ class Foo
574
+ # @overload bar(a, b, c)
575
+ def foo; end
576
+ end
577
+ eof
578
+ serializer = double(:serializer)
579
+ allow(serializer).to receive(:serialized_path).with(Registry.at('Foo')).and_return('')
580
+ allow(self).to receive(:serializer).and_return(serializer)
581
+ allow(self).to receive(:object).and_return(Registry.at('Foo'))
582
+ expect(signature(Registry.at('Foo#foo').tag(:overload), true)).to eq(
583
+ "<a href=\"#foo-instance_method\" title=\"#bar (instance method)\">#<strong>bar</strong>(a, b, c) </a>"
584
+ )
585
+ end
586
+ end
587
+
588
+ describe "#html_syntax_highlight" do
589
+ subject do
590
+ obj = OpenStruct.new
591
+ obj.options = options
592
+ obj.object = Registry.root
593
+ obj.extend(Templates::Helpers::HtmlHelper)
594
+ obj
595
+ end
596
+
597
+ it "returns empty string on nil input" do
598
+ expect(subject.html_syntax_highlight(nil)).to eq ''
599
+ end
600
+
601
+ it "calls #html_syntax_highlight_ruby by default" do
602
+ Registry.root.source_type = nil
603
+ expect(subject).to receive(:html_syntax_highlight_ruby).with('def x; end')
604
+ subject.html_syntax_highlight('def x; end')
605
+ end
606
+
607
+ it "calls #html_syntax_highlight_NAME if there's an object with a #source_type" do
608
+ subject.object = OpenStruct.new(:source_type => :NAME)
609
+ expect(subject).to receive(:html_markup_html) {|text| text }
610
+ expect(subject).to receive(:html_syntax_highlight_NAME).and_return("foobar")
611
+ expect(subject.htmlify('<pre><code>def x; end</code></pre>', :html)).to eq(
612
+ '<pre class="code NAME"><code class="NAME">foobar</code></pre>'
613
+ )
614
+ end
615
+
616
+ it "adds !!!LANG to className in outputted pre tag" do
617
+ subject.object = OpenStruct.new(:source_type => :LANG)
618
+ expect(subject).to receive(:html_markup_html) {|text| text }
619
+ expect(subject).to receive(:html_syntax_highlight_LANG).and_return("foobar")
620
+ expect(subject.htmlify("<pre><code>!!!LANG\ndef x; end</code></pre>", :html)).to eq(
621
+ '<pre class="code LANG"><code class="LANG">foobar</code></pre>'
622
+ )
623
+ end
624
+
625
+ it "calls html_syntax_highlight_NAME if source starts with !!!NAME" do
626
+ expect(subject).to receive(:html_syntax_highlight_NAME).and_return("foobar")
627
+ expect(subject.html_syntax_highlight(<<-eof
628
+ !!!NAME
629
+ def x; end
630
+ eof
631
+ )).to eq "foobar"
632
+ end
633
+
634
+ it "does not highlight if highlight option is false" do
635
+ subject.options.highlight = false
636
+ expect(subject).not_to receive(:html_syntax_highlight_ruby)
637
+ expect(subject.html_syntax_highlight('def x; end')).to eq 'def x; end'
638
+ end
639
+
640
+ it "does not highlight if there is no highlight method specified by !!!NAME" do
641
+ def subject.respond_to?(method, include_all = false)
642
+ return false if method == 'html_syntax_highlight_NAME'
643
+ super
644
+ end
645
+ expect(subject).not_to receive(:html_syntax_highlight_NAME)
646
+ expect(subject.html_syntax_highlight("!!!NAME\ndef x; end")).to eq "def x; end"
647
+ end
648
+
649
+ it "highlights as ruby if htmlify(text, :ruby) is called" do
650
+ expect(subject).to receive(:html_syntax_highlight_ruby).with('def x; end').and_return('x')
651
+ expect(subject.htmlify('def x; end', :ruby)).to eq '<pre class="code ruby">x</pre>'
652
+ end
653
+
654
+ it "does not prioritize object source type when called directly" do
655
+ expect(subject).to receive(:html_syntax_highlight_ruby).with('def x; end').and_return('x')
656
+ subject.object = OpenStruct.new(:source_type => :c)
657
+ expect(subject.html_syntax_highlight("def x; end")).to eq "x"
658
+ end
659
+
660
+ it "doesn't escape code snippets twice" do
661
+ expect(subject.htmlify('<pre lang="foo"><code>{"foo" => 1}</code></pre>', :html)).to eq(
662
+ '<pre class="code foo"><code class="foo">{&quot;foo&quot; =&gt; 1}</code></pre>'
663
+ )
664
+ end
665
+
666
+ it "highlights source when matching a pre lang= tag" do
667
+ expect(subject.htmlify('<pre lang="foo"><code>x = 1</code></pre>', :html)).to eq(
668
+ '<pre class="code foo"><code class="foo">x = 1</code></pre>'
669
+ )
670
+ end
671
+
672
+ it "highlights source when matching a code class= tag" do
673
+ expect(subject.htmlify('<pre><code class="foo">x = 1</code></pre>', :html)).to eq(
674
+ '<pre class="code foo"><code class="foo">x = 1</code></pre>'
675
+ )
676
+ end
677
+ end
678
+
679
+ describe "#link_url" do
680
+ it "adds target if scheme is provided" do
681
+ expect(link_url("http://url.com")).to include(" target=\"_parent\"")
682
+ expect(link_url("https://url.com")).to include(" target=\"_parent\"")
683
+ expect(link_url("irc://url.com")).to include(" target=\"_parent\"")
684
+ expect(link_url("../not/scheme")).not_to include("target")
685
+ end
686
+ end
687
+ end