yard 0.9.16 → 0.9.17

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 (566) hide show
  1. checksums.yaml +5 -5
  2. data/.yardopts +26 -26
  3. data/CHANGELOG.md +728 -728
  4. data/LEGAL +66 -66
  5. data/LICENSE +22 -22
  6. data/README.md +328 -328
  7. data/Rakefile +53 -47
  8. data/benchmarks/builtins_vs_eval.rb +24 -24
  9. data/benchmarks/concat_vs_join.rb +13 -13
  10. data/benchmarks/erb_vs_erubis.rb +54 -54
  11. data/benchmarks/format_args.rb +47 -47
  12. data/benchmarks/generation.rb +38 -38
  13. data/benchmarks/marshal_vs_dbm.rb +64 -64
  14. data/benchmarks/parsing.rb +46 -46
  15. data/benchmarks/pathname_vs_string.rb +50 -50
  16. data/benchmarks/rdoc_vs_yardoc.rb +11 -11
  17. data/benchmarks/registry_store_types.rb +49 -49
  18. data/benchmarks/ri_vs_yri.rb +19 -19
  19. data/benchmarks/ripper_parser.rb +13 -13
  20. data/benchmarks/splat_vs_flatten.rb +13 -13
  21. data/benchmarks/template_erb.rb +23 -23
  22. data/benchmarks/template_format.rb +7 -7
  23. data/benchmarks/template_profile.rb +18 -18
  24. data/benchmarks/yri_cache.rb +20 -20
  25. data/bin/yard +13 -13
  26. data/bin/yardoc +13 -13
  27. data/bin/yri +13 -13
  28. data/docs/CodeObjects.md +115 -115
  29. data/docs/GettingStarted.md +679 -679
  30. data/docs/Handlers.md +152 -152
  31. data/docs/Overview.md +61 -61
  32. data/docs/Parser.md +191 -191
  33. data/docs/Tags.md +283 -283
  34. data/docs/TagsArch.md +123 -123
  35. data/docs/Templates.md +496 -496
  36. data/docs/WhatsNew.md +1245 -1245
  37. data/docs/templates/default/fulldoc/html/full_list_tag.erb +8 -8
  38. data/docs/templates/default/fulldoc/html/setup.rb +6 -6
  39. data/docs/templates/default/layout/html/setup.rb +9 -9
  40. data/docs/templates/default/layout/html/tag_list.erb +11 -11
  41. data/docs/templates/default/yard_tags/html/list.erb +18 -18
  42. data/docs/templates/default/yard_tags/html/setup.rb +26 -26
  43. data/docs/templates/plugin.rb +70 -70
  44. data/lib/rubygems_plugin.rb +9 -9
  45. data/lib/yard.rb +69 -69
  46. data/lib/yard/autoload.rb +303 -303
  47. data/lib/yard/cli/command.rb +85 -85
  48. data/lib/yard/cli/command_parser.rb +93 -93
  49. data/lib/yard/cli/config.rb +198 -198
  50. data/lib/yard/cli/diff.rb +270 -270
  51. data/lib/yard/cli/display.rb +69 -69
  52. data/lib/yard/cli/gems.rb +84 -84
  53. data/lib/yard/cli/graph.rb +125 -125
  54. data/lib/yard/cli/help.rb +20 -20
  55. data/lib/yard/cli/i18n.rb +70 -70
  56. data/lib/yard/cli/list.rb +23 -23
  57. data/lib/yard/cli/markup_types.rb +32 -32
  58. data/lib/yard/cli/server.rb +257 -257
  59. data/lib/yard/cli/stats.rb +231 -231
  60. data/lib/yard/cli/yardoc.rb +788 -788
  61. data/lib/yard/cli/yardopts_command.rb +110 -110
  62. data/lib/yard/cli/yri.rb +215 -215
  63. data/lib/yard/code_objects/base.rb +615 -610
  64. data/lib/yard/code_objects/class_object.rb +146 -146
  65. data/lib/yard/code_objects/class_variable_object.rb +11 -11
  66. data/lib/yard/code_objects/constant_object.rb +16 -16
  67. data/lib/yard/code_objects/extended_method_object.rb +24 -24
  68. data/lib/yard/code_objects/extra_file_object.rb +131 -131
  69. data/lib/yard/code_objects/macro_object.rb +172 -172
  70. data/lib/yard/code_objects/method_object.rb +196 -196
  71. data/lib/yard/code_objects/module_object.rb +21 -21
  72. data/lib/yard/code_objects/namespace_mapper.rb +114 -114
  73. data/lib/yard/code_objects/namespace_object.rb +200 -200
  74. data/lib/yard/code_objects/proxy.rb +240 -240
  75. data/lib/yard/code_objects/root_object.rb +19 -19
  76. data/lib/yard/config.rb +270 -270
  77. data/lib/yard/core_ext/array.rb +16 -16
  78. data/lib/yard/core_ext/file.rb +69 -69
  79. data/lib/yard/core_ext/hash.rb +16 -16
  80. data/lib/yard/core_ext/insertion.rb +63 -63
  81. data/lib/yard/core_ext/module.rb +20 -20
  82. data/lib/yard/core_ext/string.rb +68 -68
  83. data/lib/yard/core_ext/symbol_hash.rb +75 -75
  84. data/lib/yard/docstring.rb +386 -378
  85. data/lib/yard/docstring_parser.rb +345 -345
  86. data/lib/yard/gem_index.rb +29 -29
  87. data/lib/yard/globals.rb +22 -22
  88. data/lib/yard/handlers/base.rb +595 -595
  89. data/lib/yard/handlers/c/alias_handler.rb +16 -16
  90. data/lib/yard/handlers/c/attribute_handler.rb +13 -13
  91. data/lib/yard/handlers/c/base.rb +129 -129
  92. data/lib/yard/handlers/c/class_handler.rb +27 -27
  93. data/lib/yard/handlers/c/constant_handler.rb +13 -13
  94. data/lib/yard/handlers/c/handler_methods.rb +211 -211
  95. data/lib/yard/handlers/c/init_handler.rb +20 -20
  96. data/lib/yard/handlers/c/method_handler.rb +45 -36
  97. data/lib/yard/handlers/c/mixin_handler.rb +21 -21
  98. data/lib/yard/handlers/c/module_handler.rb +17 -17
  99. data/lib/yard/handlers/c/override_comment_handler.rb +31 -31
  100. data/lib/yard/handlers/c/path_handler.rb +11 -11
  101. data/lib/yard/handlers/c/struct_handler.rb +13 -13
  102. data/lib/yard/handlers/c/symbol_handler.rb +8 -8
  103. data/lib/yard/handlers/processor.rb +200 -200
  104. data/lib/yard/handlers/ruby/alias_handler.rb +44 -44
  105. data/lib/yard/handlers/ruby/attribute_handler.rb +87 -87
  106. data/lib/yard/handlers/ruby/base.rb +165 -165
  107. data/lib/yard/handlers/ruby/class_condition_handler.rb +92 -92
  108. data/lib/yard/handlers/ruby/class_handler.rb +119 -119
  109. data/lib/yard/handlers/ruby/class_variable_handler.rb +17 -17
  110. data/lib/yard/handlers/ruby/comment_handler.rb +10 -10
  111. data/lib/yard/handlers/ruby/constant_handler.rb +59 -59
  112. data/lib/yard/handlers/ruby/decorator_handler_methods.rb +123 -123
  113. data/lib/yard/handlers/ruby/dsl_handler.rb +15 -15
  114. data/lib/yard/handlers/ruby/dsl_handler_methods.rb +96 -95
  115. data/lib/yard/handlers/ruby/exception_handler.rb +27 -27
  116. data/lib/yard/handlers/ruby/extend_handler.rb +22 -22
  117. data/lib/yard/handlers/ruby/legacy/alias_handler.rb +37 -37
  118. data/lib/yard/handlers/ruby/legacy/attribute_handler.rb +65 -65
  119. data/lib/yard/handlers/ruby/legacy/base.rb +245 -245
  120. data/lib/yard/handlers/ruby/legacy/class_condition_handler.rb +83 -83
  121. data/lib/yard/handlers/ruby/legacy/class_handler.rb +113 -113
  122. data/lib/yard/handlers/ruby/legacy/class_variable_handler.rb +15 -15
  123. data/lib/yard/handlers/ruby/legacy/comment_handler.rb +10 -10
  124. data/lib/yard/handlers/ruby/legacy/constant_handler.rb +29 -29
  125. data/lib/yard/handlers/ruby/legacy/dsl_handler.rb +17 -17
  126. data/lib/yard/handlers/ruby/legacy/exception_handler.rb +13 -13
  127. data/lib/yard/handlers/ruby/legacy/extend_handler.rb +21 -21
  128. data/lib/yard/handlers/ruby/legacy/method_handler.rb +90 -90
  129. data/lib/yard/handlers/ruby/legacy/mixin_handler.rb +39 -39
  130. data/lib/yard/handlers/ruby/legacy/module_function_handler.rb +19 -19
  131. data/lib/yard/handlers/ruby/legacy/module_handler.rb +12 -12
  132. data/lib/yard/handlers/ruby/legacy/private_class_method_handler.rb +22 -22
  133. data/lib/yard/handlers/ruby/legacy/private_constant_handler.rb +22 -22
  134. data/lib/yard/handlers/ruby/legacy/visibility_handler.rb +17 -17
  135. data/lib/yard/handlers/ruby/legacy/yield_handler.rb +29 -29
  136. data/lib/yard/handlers/ruby/method_condition_handler.rb +9 -9
  137. data/lib/yard/handlers/ruby/method_handler.rb +118 -118
  138. data/lib/yard/handlers/ruby/mixin_handler.rb +37 -37
  139. data/lib/yard/handlers/ruby/module_function_handler.rb +27 -27
  140. data/lib/yard/handlers/ruby/module_handler.rb +12 -12
  141. data/lib/yard/handlers/ruby/private_class_method_handler.rb +14 -14
  142. data/lib/yard/handlers/ruby/private_constant_handler.rb +43 -43
  143. data/lib/yard/handlers/ruby/public_class_method_handler.rb +14 -14
  144. data/lib/yard/handlers/ruby/struct_handler_methods.rb +143 -143
  145. data/lib/yard/handlers/ruby/visibility_handler.rb +22 -22
  146. data/lib/yard/handlers/ruby/yield_handler.rb +31 -31
  147. data/lib/yard/i18n/locale.rb +67 -67
  148. data/lib/yard/i18n/message.rb +57 -57
  149. data/lib/yard/i18n/messages.rb +56 -56
  150. data/lib/yard/i18n/po_parser.rb +61 -61
  151. data/lib/yard/i18n/pot_generator.rb +290 -290
  152. data/lib/yard/i18n/text.rb +173 -173
  153. data/lib/yard/logging.rb +205 -205
  154. data/lib/yard/options.rb +217 -217
  155. data/lib/yard/parser/base.rb +57 -57
  156. data/lib/yard/parser/c/c_parser.rb +235 -235
  157. data/lib/yard/parser/c/comment_parser.rb +134 -134
  158. data/lib/yard/parser/c/statement.rb +64 -64
  159. data/lib/yard/parser/ruby/ast_node.rb +540 -540
  160. data/lib/yard/parser/ruby/legacy/ruby_lex.rb +1354 -1354
  161. data/lib/yard/parser/ruby/legacy/ruby_parser.rb +32 -32
  162. data/lib/yard/parser/ruby/legacy/statement.rb +66 -66
  163. data/lib/yard/parser/ruby/legacy/statement_list.rb +394 -394
  164. data/lib/yard/parser/ruby/legacy/token_list.rb +74 -74
  165. data/lib/yard/parser/ruby/ruby_parser.rb +687 -687
  166. data/lib/yard/parser/ruby/token_resolver.rb +156 -156
  167. data/lib/yard/parser/source_parser.rb +526 -526
  168. data/lib/yard/rake/yardoc_task.rb +81 -81
  169. data/lib/yard/registry.rb +439 -439
  170. data/lib/yard/registry_resolver.rb +189 -189
  171. data/lib/yard/registry_store.rb +337 -337
  172. data/lib/yard/rubygems/backports.rb +10 -10
  173. data/lib/yard/rubygems/backports/LICENSE.txt +57 -57
  174. data/lib/yard/rubygems/backports/MIT.txt +20 -20
  175. data/lib/yard/rubygems/backports/gem.rb +10 -10
  176. data/lib/yard/rubygems/backports/source_index.rb +365 -365
  177. data/lib/yard/rubygems/doc_manager.rb +90 -90
  178. data/lib/yard/rubygems/hook.rb +197 -197
  179. data/lib/yard/rubygems/specification.rb +50 -50
  180. data/lib/yard/serializers/base.rb +83 -83
  181. data/lib/yard/serializers/file_system_serializer.rb +123 -123
  182. data/lib/yard/serializers/process_serializer.rb +24 -24
  183. data/lib/yard/serializers/stdout_serializer.rb +34 -34
  184. data/lib/yard/serializers/yardoc_serializer.rb +152 -152
  185. data/lib/yard/server.rb +13 -13
  186. data/lib/yard/server/adapter.rb +100 -100
  187. data/lib/yard/server/commands/base.rb +209 -209
  188. data/lib/yard/server/commands/display_file_command.rb +29 -29
  189. data/lib/yard/server/commands/display_object_command.rb +65 -65
  190. data/lib/yard/server/commands/frames_command.rb +16 -16
  191. data/lib/yard/server/commands/library_command.rb +187 -187
  192. data/lib/yard/server/commands/library_index_command.rb +28 -28
  193. data/lib/yard/server/commands/list_command.rb +25 -25
  194. data/lib/yard/server/commands/root_request_command.rb +15 -15
  195. data/lib/yard/server/commands/search_command.rb +79 -79
  196. data/lib/yard/server/commands/static_file_command.rb +23 -23
  197. data/lib/yard/server/commands/static_file_helpers.rb +62 -62
  198. data/lib/yard/server/doc_server_helper.rb +91 -91
  199. data/lib/yard/server/doc_server_serializer.rb +39 -39
  200. data/lib/yard/server/library_version.rb +277 -277
  201. data/lib/yard/server/rack_adapter.rb +89 -89
  202. data/lib/yard/server/router.rb +187 -187
  203. data/lib/yard/server/static_caching.rb +46 -46
  204. data/lib/yard/server/templates/default/fulldoc/html/css/custom.css +127 -127
  205. data/lib/yard/server/templates/default/fulldoc/html/js/autocomplete.js +11 -11
  206. data/lib/yard/server/templates/default/layout/html/breadcrumb.erb +37 -37
  207. data/lib/yard/server/templates/default/layout/html/script_setup.erb +7 -7
  208. data/lib/yard/server/templates/default/layout/html/setup.rb +8 -8
  209. data/lib/yard/server/templates/default/method_details/html/permalink.erb +4 -4
  210. data/lib/yard/server/templates/default/method_details/html/setup.rb +5 -5
  211. data/lib/yard/server/templates/doc_server/library_list/html/headers.erb +8 -8
  212. data/lib/yard/server/templates/doc_server/library_list/html/library_list.erb +14 -14
  213. data/lib/yard/server/templates/doc_server/library_list/html/listing.erb +13 -13
  214. data/lib/yard/server/templates/doc_server/library_list/html/setup.rb +6 -6
  215. data/lib/yard/server/templates/doc_server/library_list/html/title.erb +2 -2
  216. data/lib/yard/server/templates/doc_server/processing/html/processing.erb +52 -52
  217. data/lib/yard/server/templates/doc_server/processing/html/setup.rb +4 -4
  218. data/lib/yard/server/templates/doc_server/search/html/search.erb +18 -18
  219. data/lib/yard/server/templates/doc_server/search/html/setup.rb +9 -9
  220. data/lib/yard/server/webrick_adapter.rb +45 -45
  221. data/lib/yard/tags/default_factory.rb +191 -191
  222. data/lib/yard/tags/default_tag.rb +13 -13
  223. data/lib/yard/tags/directives.rb +616 -616
  224. data/lib/yard/tags/library.rb +633 -633
  225. data/lib/yard/tags/option_tag.rb +13 -13
  226. data/lib/yard/tags/overload_tag.rb +71 -71
  227. data/lib/yard/tags/ref_tag.rb +8 -8
  228. data/lib/yard/tags/ref_tag_list.rb +28 -28
  229. data/lib/yard/tags/tag.rb +71 -71
  230. data/lib/yard/tags/tag_format_error.rb +7 -7
  231. data/lib/yard/tags/types_explainer.rb +162 -162
  232. data/lib/yard/templates/engine.rb +186 -186
  233. data/lib/yard/templates/erb_cache.rb +23 -23
  234. data/lib/yard/templates/helpers/base_helper.rb +215 -215
  235. data/lib/yard/templates/helpers/filter_helper.rb +27 -27
  236. data/lib/yard/templates/helpers/html_helper.rb +646 -642
  237. data/lib/yard/templates/helpers/html_syntax_highlight_helper.rb +78 -78
  238. data/lib/yard/templates/helpers/markup/rdoc_markdown.rb +23 -23
  239. data/lib/yard/templates/helpers/markup/rdoc_markup.rb +109 -109
  240. data/lib/yard/templates/helpers/markup_helper.rb +172 -172
  241. data/lib/yard/templates/helpers/method_helper.rb +75 -75
  242. data/lib/yard/templates/helpers/module_helper.rb +21 -21
  243. data/lib/yard/templates/helpers/text_helper.rb +112 -112
  244. data/lib/yard/templates/helpers/uml_helper.rb +47 -47
  245. data/lib/yard/templates/section.rb +105 -105
  246. data/lib/yard/templates/template.rb +418 -418
  247. data/lib/yard/templates/template_options.rb +92 -92
  248. data/lib/yard/verifier.rb +151 -151
  249. data/lib/yard/version.rb +3 -1
  250. data/spec/cli/command_parser_spec.rb +43 -43
  251. data/spec/cli/command_spec.rb +36 -36
  252. data/spec/cli/config_spec.rb +148 -148
  253. data/spec/cli/diff_spec.rb +254 -254
  254. data/spec/cli/display_spec.rb +30 -30
  255. data/spec/cli/gems_spec.rb +81 -81
  256. data/spec/cli/graph_spec.rb +18 -18
  257. data/spec/cli/help_spec.rb +22 -22
  258. data/spec/cli/i18n_spec.rb +107 -107
  259. data/spec/cli/list_spec.rb +8 -8
  260. data/spec/cli/markup_types_spec.rb +22 -22
  261. data/spec/cli/server_spec.rb +324 -324
  262. data/spec/cli/stats_spec.rb +96 -96
  263. data/spec/cli/yard_on_yard_spec.rb +38 -38
  264. data/spec/cli/yardoc_spec.rb +862 -849
  265. data/spec/cli/yri_spec.rb +101 -101
  266. data/spec/code_objects/base_spec.rb +470 -460
  267. data/spec/code_objects/class_object_spec.rb +226 -226
  268. data/spec/code_objects/code_object_list_spec.rb +36 -36
  269. data/spec/code_objects/constants_spec.rb +116 -116
  270. data/spec/code_objects/extra_file_object_spec.rb +160 -160
  271. data/spec/code_objects/macro_object_spec.rb +150 -150
  272. data/spec/code_objects/method_object_spec.rb +184 -184
  273. data/spec/code_objects/module_object_spec.rb +142 -142
  274. data/spec/code_objects/namespace_object_spec.rb +171 -171
  275. data/spec/code_objects/proxy_spec.rb +141 -141
  276. data/spec/code_objects/spec_helper.rb +3 -3
  277. data/spec/config_spec.rb +171 -171
  278. data/spec/core_ext/array_spec.rb +13 -13
  279. data/spec/core_ext/file_spec.rb +72 -72
  280. data/spec/core_ext/hash_spec.rb +14 -14
  281. data/spec/core_ext/insertion_spec.rb +37 -37
  282. data/spec/core_ext/module_spec.rb +15 -15
  283. data/spec/core_ext/string_spec.rb +42 -42
  284. data/spec/core_ext/symbol_hash_spec.rb +89 -89
  285. data/spec/docstring_parser_spec.rb +280 -262
  286. data/spec/docstring_spec.rb +373 -364
  287. data/spec/examples.txt +1875 -1871
  288. data/spec/handlers/alias_handler_spec.rb +82 -82
  289. data/spec/handlers/attribute_handler_spec.rb +96 -96
  290. data/spec/handlers/base_spec.rb +216 -216
  291. data/spec/handlers/c/alias_handler_spec.rb +34 -34
  292. data/spec/handlers/c/attribute_handler_spec.rb +41 -41
  293. data/spec/handlers/c/class_handler_spec.rb +78 -78
  294. data/spec/handlers/c/constant_handler_spec.rb +71 -71
  295. data/spec/handlers/c/init_handler_spec.rb +48 -48
  296. data/spec/handlers/c/method_handler_spec.rb +325 -325
  297. data/spec/handlers/c/mixin_handler_spec.rb +44 -44
  298. data/spec/handlers/c/module_handler_spec.rb +71 -71
  299. data/spec/handlers/c/override_comment_handler_spec.rb +47 -47
  300. data/spec/handlers/c/path_handler_spec.rb +36 -36
  301. data/spec/handlers/c/spec_helper.rb +23 -23
  302. data/spec/handlers/c/struct_handler_spec.rb +16 -16
  303. data/spec/handlers/class_condition_handler_spec.rb +87 -87
  304. data/spec/handlers/class_handler_spec.rb +247 -247
  305. data/spec/handlers/class_method_handler_shared_examples.rb +133 -133
  306. data/spec/handlers/class_variable_handler_spec.rb +12 -12
  307. data/spec/handlers/constant_handler_spec.rb +112 -112
  308. data/spec/handlers/decorator_handler_methods_spec.rb +393 -393
  309. data/spec/handlers/dsl_handler_spec.rb +219 -219
  310. data/spec/handlers/examples/alias_handler_001.rb.txt +45 -45
  311. data/spec/handlers/examples/attribute_handler_001.rb.txt +31 -31
  312. data/spec/handlers/examples/class_condition_handler_001.rb.txt +68 -68
  313. data/spec/handlers/examples/class_handler_001.rb.txt +120 -120
  314. data/spec/handlers/examples/class_variable_handler_001.rb.txt +9 -9
  315. data/spec/handlers/examples/constant_handler_001.rb.txt +35 -35
  316. data/spec/handlers/examples/dsl_handler_001.rb.txt +154 -154
  317. data/spec/handlers/examples/exception_handler_001.rb.txt +58 -58
  318. data/spec/handlers/examples/extend_handler_001.rb.txt +15 -15
  319. data/spec/handlers/examples/method_condition_handler_001.rb.txt +9 -9
  320. data/spec/handlers/examples/method_handler_001.rb.txt +128 -128
  321. data/spec/handlers/examples/mixin_handler_001.rb.txt +37 -37
  322. data/spec/handlers/examples/module_handler_001.rb.txt +29 -29
  323. data/spec/handlers/examples/private_constant_handler_001.rb.txt +8 -8
  324. data/spec/handlers/examples/process_handler_001.rb.txt +11 -11
  325. data/spec/handlers/examples/visibility_handler_001.rb.txt +35 -35
  326. data/spec/handlers/examples/yield_handler_001.rb.txt +54 -54
  327. data/spec/handlers/exception_handler_spec.rb +49 -49
  328. data/spec/handlers/extend_handler_spec.rb +24 -24
  329. data/spec/handlers/legacy_base_spec.rb +128 -128
  330. data/spec/handlers/method_condition_handler_spec.rb +15 -15
  331. data/spec/handlers/method_handler_spec.rb +190 -190
  332. data/spec/handlers/mixin_handler_spec.rb +56 -56
  333. data/spec/handlers/module_function_handler_spec.rb +106 -106
  334. data/spec/handlers/module_handler_spec.rb +35 -35
  335. data/spec/handlers/private_class_method_handler_spec.rb +11 -11
  336. data/spec/handlers/private_constant_handler_spec.rb +25 -25
  337. data/spec/handlers/processor_spec.rb +35 -35
  338. data/spec/handlers/public_class_method_handler_spec.rb +11 -11
  339. data/spec/handlers/ruby/base_spec.rb +95 -95
  340. data/spec/handlers/ruby/legacy/base_spec.rb +84 -84
  341. data/spec/handlers/spec_helper.rb +33 -33
  342. data/spec/handlers/visibility_handler_spec.rb +44 -44
  343. data/spec/handlers/yield_handler_spec.rb +52 -52
  344. data/spec/i18n/locale_spec.rb +81 -81
  345. data/spec/i18n/message_spec.rb +52 -52
  346. data/spec/i18n/messages_spec.rb +67 -67
  347. data/spec/i18n/pot_generator_spec.rb +295 -295
  348. data/spec/i18n/text_spec.rb +184 -184
  349. data/spec/logging_spec.rb +44 -44
  350. data/spec/options_spec.rb +171 -171
  351. data/spec/parser/base_spec.rb +24 -24
  352. data/spec/parser/c_parser_spec.rb +236 -223
  353. data/spec/parser/examples/array.c.txt +6267 -6267
  354. data/spec/parser/examples/example1.rb.txt +7 -7
  355. data/spec/parser/examples/extrafile.c.txt +8 -8
  356. data/spec/parser/examples/file.c.txt +28 -0
  357. data/spec/parser/examples/multifile.c.txt +22 -22
  358. data/spec/parser/examples/namespace.cpp.txt +68 -68
  359. data/spec/parser/examples/override.c.txt +424 -424
  360. data/spec/parser/examples/parse_in_order_001.rb.txt +2 -2
  361. data/spec/parser/examples/parse_in_order_002.rb.txt +1 -1
  362. data/spec/parser/examples/tag_handler_001.rb.txt +7 -7
  363. data/spec/parser/ruby/ast_node_spec.rb +33 -33
  364. data/spec/parser/ruby/legacy/statement_list_spec.rb +299 -299
  365. data/spec/parser/ruby/legacy/token_list_spec.rb +79 -79
  366. data/spec/parser/ruby/ruby_parser_spec.rb +508 -508
  367. data/spec/parser/ruby/token_resolver_spec.rb +165 -165
  368. data/spec/parser/source_parser_spec.rb +727 -727
  369. data/spec/parser/tag_parsing_spec.rb +17 -17
  370. data/spec/rake/yardoc_task_spec.rb +118 -118
  371. data/spec/registry_spec.rb +463 -463
  372. data/spec/registry_store_spec.rb +316 -316
  373. data/spec/rubygems/doc_manager_spec.rb +112 -112
  374. data/spec/serializers/data/serialized_yardoc/checksums +1 -1
  375. data/spec/serializers/file_system_serializer_spec.rb +145 -145
  376. data/spec/serializers/spec_helper.rb +2 -2
  377. data/spec/serializers/yardoc_serializer_spec.rb +78 -78
  378. data/spec/server/adapter_spec.rb +39 -39
  379. data/spec/server/commands/base_spec.rb +91 -91
  380. data/spec/server/commands/library_command_spec.rb +39 -39
  381. data/spec/server/doc_server_helper_spec.rb +72 -72
  382. data/spec/server/doc_server_serializer_spec.rb +60 -60
  383. data/spec/server/rack_adapter_spec.rb +21 -21
  384. data/spec/server/router_spec.rb +123 -123
  385. data/spec/server/spec_helper.rb +22 -22
  386. data/spec/server/static_caching_spec.rb +47 -47
  387. data/spec/server/webrick_servlet_spec.rb +20 -20
  388. data/spec/server_spec.rb +19 -19
  389. data/spec/spec_helper.rb +212 -212
  390. data/spec/tags/default_factory_spec.rb +168 -168
  391. data/spec/tags/default_tag_spec.rb +11 -11
  392. data/spec/tags/directives_spec.rb +463 -463
  393. data/spec/tags/library_spec.rb +48 -48
  394. data/spec/tags/overload_tag_spec.rb +53 -53
  395. data/spec/tags/ref_tag_list_spec.rb +53 -53
  396. data/spec/tags/types_explainer_spec.rb +203 -203
  397. data/spec/templates/class_spec.rb +45 -45
  398. data/spec/templates/constant_spec.rb +41 -41
  399. data/spec/templates/engine_spec.rb +131 -131
  400. data/spec/templates/examples/class001.html +308 -308
  401. data/spec/templates/examples/class001.txt +36 -36
  402. data/spec/templates/examples/class002.html +39 -39
  403. data/spec/templates/examples/constant001.txt +24 -24
  404. data/spec/templates/examples/constant002.txt +6 -6
  405. data/spec/templates/examples/constant003.txt +10 -10
  406. data/spec/templates/examples/method001.html +137 -137
  407. data/spec/templates/examples/method001.txt +35 -35
  408. data/spec/templates/examples/method002.html +91 -91
  409. data/spec/templates/examples/method002.txt +20 -20
  410. data/spec/templates/examples/method003.html +165 -165
  411. data/spec/templates/examples/method003.txt +45 -45
  412. data/spec/templates/examples/method004.html +48 -48
  413. data/spec/templates/examples/method004.txt +10 -10
  414. data/spec/templates/examples/method005.html +105 -105
  415. data/spec/templates/examples/method005.txt +33 -33
  416. data/spec/templates/examples/method006.html +107 -107
  417. data/spec/templates/examples/method006.txt +20 -20
  418. data/spec/templates/examples/module001.dot +33 -33
  419. data/spec/templates/examples/module001.html +833 -833
  420. data/spec/templates/examples/module001.txt +33 -33
  421. data/spec/templates/examples/module002.html +341 -341
  422. data/spec/templates/examples/module003.html +202 -202
  423. data/spec/templates/examples/module004.html +394 -394
  424. data/spec/templates/examples/module005.html +81 -81
  425. data/spec/templates/examples/tag001.txt +82 -82
  426. data/spec/templates/helpers/base_helper_spec.rb +171 -171
  427. data/spec/templates/helpers/html_helper_spec.rb +668 -653
  428. data/spec/templates/helpers/html_syntax_highlight_helper_spec.rb +65 -65
  429. data/spec/templates/helpers/markup/rdoc_markup_spec.rb +84 -84
  430. data/spec/templates/helpers/markup_helper_spec.rb +136 -136
  431. data/spec/templates/helpers/method_helper_spec.rb +107 -107
  432. data/spec/templates/helpers/module_helper_spec.rb +35 -35
  433. data/spec/templates/helpers/shared_signature_examples.rb +126 -126
  434. data/spec/templates/helpers/text_helper_spec.rb +65 -65
  435. data/spec/templates/method_spec.rb +118 -118
  436. data/spec/templates/module_spec.rb +203 -203
  437. data/spec/templates/onefile_spec.rb +66 -66
  438. data/spec/templates/section_spec.rb +144 -144
  439. data/spec/templates/spec_helper.rb +76 -76
  440. data/spec/templates/tag_spec.rb +52 -52
  441. data/spec/templates/template_spec.rb +410 -410
  442. data/spec/verifier_spec.rb +106 -106
  443. data/templates/default/class/dot/setup.rb +7 -7
  444. data/templates/default/class/dot/superklass.erb +2 -2
  445. data/templates/default/class/html/constructor_details.erb +8 -8
  446. data/templates/default/class/html/setup.rb +2 -2
  447. data/templates/default/class/html/subclasses.erb +4 -4
  448. data/templates/default/class/setup.rb +36 -36
  449. data/templates/default/class/text/setup.rb +12 -12
  450. data/templates/default/class/text/subclasses.erb +5 -5
  451. data/templates/default/constant/text/header.erb +11 -11
  452. data/templates/default/constant/text/setup.rb +4 -4
  453. data/templates/default/docstring/html/abstract.erb +4 -4
  454. data/templates/default/docstring/html/deprecated.erb +1 -1
  455. data/templates/default/docstring/html/index.erb +5 -5
  456. data/templates/default/docstring/html/note.erb +6 -6
  457. data/templates/default/docstring/html/private.erb +4 -4
  458. data/templates/default/docstring/html/text.erb +1 -1
  459. data/templates/default/docstring/html/todo.erb +6 -6
  460. data/templates/default/docstring/setup.rb +52 -52
  461. data/templates/default/docstring/text/abstract.erb +2 -2
  462. data/templates/default/docstring/text/deprecated.erb +2 -2
  463. data/templates/default/docstring/text/index.erb +2 -2
  464. data/templates/default/docstring/text/note.erb +3 -3
  465. data/templates/default/docstring/text/private.erb +2 -2
  466. data/templates/default/docstring/text/text.erb +1 -1
  467. data/templates/default/docstring/text/todo.erb +3 -3
  468. data/templates/default/fulldoc/html/css/full_list.css +58 -58
  469. data/templates/default/fulldoc/html/css/style.css +496 -496
  470. data/templates/default/fulldoc/html/frames.erb +17 -17
  471. data/templates/default/fulldoc/html/full_list.erb +37 -37
  472. data/templates/default/fulldoc/html/full_list_class.erb +2 -2
  473. data/templates/default/fulldoc/html/full_list_file.erb +7 -7
  474. data/templates/default/fulldoc/html/full_list_method.erb +10 -10
  475. data/templates/default/fulldoc/html/js/app.js +292 -292
  476. data/templates/default/fulldoc/html/js/full_list.js +216 -216
  477. data/templates/default/fulldoc/html/js/jquery.js +3 -3
  478. data/templates/default/fulldoc/html/setup.rb +241 -241
  479. data/templates/default/layout/dot/header.erb +5 -5
  480. data/templates/default/layout/dot/setup.rb +15 -15
  481. data/templates/default/layout/html/breadcrumb.erb +11 -11
  482. data/templates/default/layout/html/files.erb +11 -11
  483. data/templates/default/layout/html/footer.erb +5 -5
  484. data/templates/default/layout/html/headers.erb +15 -15
  485. data/templates/default/layout/html/index.erb +2 -2
  486. data/templates/default/layout/html/layout.erb +23 -23
  487. data/templates/default/layout/html/listing.erb +4 -4
  488. data/templates/default/layout/html/objects.erb +32 -32
  489. data/templates/default/layout/html/script_setup.erb +4 -4
  490. data/templates/default/layout/html/search.erb +12 -12
  491. data/templates/default/layout/html/setup.rb +89 -89
  492. data/templates/default/method/html/header.erb +16 -16
  493. data/templates/default/method/setup.rb +4 -4
  494. data/templates/default/method_details/html/header.erb +2 -2
  495. data/templates/default/method_details/html/method_signature.erb +24 -24
  496. data/templates/default/method_details/html/source.erb +9 -9
  497. data/templates/default/method_details/setup.rb +11 -11
  498. data/templates/default/method_details/text/header.erb +10 -10
  499. data/templates/default/method_details/text/method_signature.erb +12 -12
  500. data/templates/default/method_details/text/setup.rb +11 -11
  501. data/templates/default/module/dot/child.erb +1 -1
  502. data/templates/default/module/dot/dependencies.erb +2 -2
  503. data/templates/default/module/dot/header.erb +6 -6
  504. data/templates/default/module/dot/info.erb +13 -13
  505. data/templates/default/module/dot/setup.rb +15 -15
  506. data/templates/default/module/html/attribute_details.erb +10 -10
  507. data/templates/default/module/html/attribute_summary.erb +8 -8
  508. data/templates/default/module/html/box_info.erb +43 -43
  509. data/templates/default/module/html/children.erb +8 -8
  510. data/templates/default/module/html/constant_summary.erb +17 -17
  511. data/templates/default/module/html/defines.erb +2 -2
  512. data/templates/default/module/html/header.erb +5 -5
  513. data/templates/default/module/html/inherited_attributes.erb +14 -14
  514. data/templates/default/module/html/inherited_constants.erb +8 -8
  515. data/templates/default/module/html/inherited_methods.erb +18 -18
  516. data/templates/default/module/html/item_summary.erb +40 -40
  517. data/templates/default/module/html/method_details_list.erb +9 -9
  518. data/templates/default/module/html/method_summary.erb +13 -13
  519. data/templates/default/module/html/methodmissing.erb +12 -12
  520. data/templates/default/module/setup.rb +167 -167
  521. data/templates/default/module/text/children.erb +9 -9
  522. data/templates/default/module/text/class_meths_list.erb +7 -7
  523. data/templates/default/module/text/extends.erb +7 -7
  524. data/templates/default/module/text/header.erb +7 -7
  525. data/templates/default/module/text/includes.erb +7 -7
  526. data/templates/default/module/text/instance_meths_list.erb +7 -7
  527. data/templates/default/module/text/setup.rb +13 -13
  528. data/templates/default/onefile/html/files.erb +4 -4
  529. data/templates/default/onefile/html/headers.erb +6 -6
  530. data/templates/default/onefile/html/layout.erb +17 -17
  531. data/templates/default/onefile/html/readme.erb +2 -2
  532. data/templates/default/onefile/html/setup.rb +62 -62
  533. data/templates/default/root/dot/child.erb +2 -2
  534. data/templates/default/root/dot/setup.rb +6 -6
  535. data/templates/default/root/html/setup.rb +2 -2
  536. data/templates/default/tags/html/example.erb +10 -10
  537. data/templates/default/tags/html/index.erb +2 -2
  538. data/templates/default/tags/html/option.erb +24 -24
  539. data/templates/default/tags/html/overload.erb +13 -13
  540. data/templates/default/tags/html/see.erb +7 -7
  541. data/templates/default/tags/html/tag.erb +20 -20
  542. data/templates/default/tags/setup.rb +57 -57
  543. data/templates/default/tags/text/example.erb +12 -12
  544. data/templates/default/tags/text/index.erb +1 -1
  545. data/templates/default/tags/text/option.erb +20 -20
  546. data/templates/default/tags/text/overload.erb +19 -19
  547. data/templates/default/tags/text/see.erb +11 -11
  548. data/templates/default/tags/text/tag.erb +13 -13
  549. data/templates/guide/class/html/setup.rb +2 -2
  550. data/templates/guide/docstring/html/setup.rb +2 -2
  551. data/templates/guide/fulldoc/html/css/style.css +108 -108
  552. data/templates/guide/fulldoc/html/js/app.js +33 -33
  553. data/templates/guide/fulldoc/html/setup.rb +74 -74
  554. data/templates/guide/layout/html/layout.erb +81 -81
  555. data/templates/guide/layout/html/setup.rb +25 -25
  556. data/templates/guide/method/html/header.erb +17 -17
  557. data/templates/guide/method/html/setup.rb +22 -22
  558. data/templates/guide/module/html/header.erb +6 -6
  559. data/templates/guide/module/html/method_list.erb +4 -4
  560. data/templates/guide/module/html/setup.rb +27 -27
  561. data/templates/guide/onefile/html/files.erb +4 -4
  562. data/templates/guide/onefile/html/setup.rb +6 -6
  563. data/templates/guide/onefile/html/toc.erb +3 -3
  564. data/templates/guide/tags/html/setup.rb +9 -9
  565. data/yard.gemspec +43 -43
  566. metadata +4 -4
@@ -1,653 +1,668 @@
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
- end
218
-
219
- describe "#link_object" do
220
- let(:object) { CodeObjects::NamespaceObject.new(nil, :YARD) }
221
-
222
- it "returns the object path if there's no serializer and no title" do
223
- allow(self).to receive(:serializer).and_return(nil)
224
- expect(link_object(CodeObjects::NamespaceObject.new(nil, :YARD))).to eq "YARD"
225
- end
226
-
227
- it "returns the title if there's a title but no serializer" do
228
- allow(self).to receive(:serializer).and_return(nil)
229
- expect(link_object(CodeObjects::NamespaceObject.new(nil, :YARD), 'title')).to eq "title"
230
- end
231
-
232
- it "links objects from overload tag" do
233
- YARD.parse_string <<-'eof'
234
- module Foo
235
- class Bar; def a; end end
236
- class Baz
237
- # @overload a
238
- def a; end
239
- end
240
- end
241
- eof
242
- obj = Registry.at('Foo::Baz#a').tag(:overload)
243
- allow(self).to receive(:serializer).and_return(Serializers::FileSystemSerializer.new)
244
- allow(self).to receive(:object).and_return(obj)
245
- expect(link_object("Bar#a")).to match(/href="Bar.html#a-instance_method"/)
246
- end
247
-
248
- it "uses relative path in title" do
249
- CodeObjects::ModuleObject.new(:root, :YARD)
250
- CodeObjects::ClassObject.new(P('YARD'), :Bar)
251
- allow(self).to receive(:object).and_return(CodeObjects::ModuleObject.new(P('YARD'), :Foo))
252
- allow(self).to receive(:serializer).and_return(Serializers::FileSystemSerializer.new)
253
- expect(link_object("Bar")).to match %r{>Bar</a>}
254
- end
255
-
256
- it "uses #title if overridden" do
257
- CodeObjects::ModuleObject.new(:root, :YARD)
258
- CodeObjects::ClassObject.new(P('YARD'), :Bar)
259
- allow(Registry.at('YARD::Bar')).to receive(:title).and_return('TITLE!')
260
- allow(self).to receive(:object).and_return(Registry.at('YARD::Bar'))
261
- allow(self).to receive(:serializer).and_return(Serializers::FileSystemSerializer.new)
262
- expect(link_object("Bar")).to match %r{>TITLE!</a>}
263
- end
264
-
265
- it "uses relative path to parent class in title" do
266
- root = CodeObjects::ModuleObject.new(:root, :YARD)
267
- obj = CodeObjects::ModuleObject.new(root, :SubModule)
268
- allow(self).to receive(:object).and_return(obj)
269
- allow(self).to receive(:serializer).and_return(Serializers::FileSystemSerializer.new)
270
- expect(link_object("YARD")).to match %r{>YARD</a>}
271
- end
272
-
273
- it "uses Klass.foo when linking to class method in current namespace" do
274
- root = CodeObjects::ModuleObject.new(:root, :Klass)
275
- CodeObjects::MethodObject.new(root, :foo, :class)
276
- allow(self).to receive(:object).and_return(root)
277
- allow(self).to receive(:serializer).and_return(Serializers::FileSystemSerializer.new)
278
- expect(link_object("foo")).to match %r{>Klass.foo</a>}
279
- end
280
-
281
- it "escapes method name in title" do
282
- YARD.parse_string <<-'eof'
283
- class Array
284
- def &(other)
285
- end
286
- end
287
- eof
288
- obj = Registry.at('Array#&')
289
- allow(self).to receive(:serializer).and_return(Serializers::FileSystemSerializer.new)
290
- allow(self).to receive(:object).and_return(obj)
291
- expect(link_object("Array#&")).to match(/title="Array#&amp; \(method\)"/)
292
- end
293
- end
294
-
295
- describe "#url_for" do
296
- before { Registry.clear }
297
-
298
- it "returns nil if serializer is nil" do
299
- allow(self).to receive(:serializer).and_return nil
300
- allow(self).to receive(:object).and_return Registry.root
301
- expect(url_for(P("Mod::Class#meth"))).to be nil
302
- end
303
-
304
- it "returns nil if object is hidden" do
305
- yard = CodeObjects::ModuleObject.new(:root, :YARD)
306
-
307
- allow(self).to receive(:serializer).and_return(Serializers::FileSystemSerializer.new)
308
- allow(self).to receive(:object).and_return Registry.root
309
- allow(self).to receive(:options).and_return OpenStruct.new(:verifier => Verifier.new('false'))
310
-
311
- expect(url_for(yard)).to be nil
312
- end
313
-
314
- it "returns nil if serializer does not implement #serialized_path" do
315
- allow(self).to receive(:serializer).and_return Serializers::Base.new
316
- allow(self).to receive(:object).and_return Registry.root
317
- expect(url_for(P("Mod::Class#meth"))).to be nil
318
- end
319
-
320
- it "links to a path/file for a namespace object" do
321
- allow(self).to receive(:serializer).and_return Serializers::FileSystemSerializer.new
322
- allow(self).to receive(:object).and_return Registry.root
323
-
324
- yard = CodeObjects::ModuleObject.new(:root, :YARD)
325
- expect(url_for(yard)).to eq 'YARD.html'
326
- end
327
-
328
- it "links to the object's namespace path/file and use the object as the anchor" do
329
- allow(self).to receive(:serializer).and_return Serializers::FileSystemSerializer.new
330
- allow(self).to receive(:object).and_return Registry.root
331
-
332
- yard = CodeObjects::ModuleObject.new(:root, :YARD)
333
- meth = CodeObjects::MethodObject.new(yard, :meth)
334
- expect(url_for(meth)).to eq 'YARD.html#meth-instance_method'
335
- end
336
-
337
- it "properly urlencodes methods with punctuation in links" do
338
- obj = CodeObjects::MethodObject.new(nil, :/)
339
- serializer = double(:serializer, :serialized_path => "file.html")
340
- allow(self).to receive(:serializer).and_return serializer
341
- allow(self).to receive(:object).and_return obj
342
- expect(url_for(obj)).to eq "#%2F-instance_method"
343
- end
344
- end
345
-
346
- describe "#anchor_for" do
347
- it "does not urlencode data when called directly" do
348
- obj = CodeObjects::MethodObject.new(nil, :/)
349
- expect(anchor_for(obj)).to eq "/-instance_method"
350
- end
351
- end
352
-
353
- describe "#resolve_links" do
354
- def parse_link(link)
355
- results = {}
356
- link =~ %r{<a (.+?)>(.+?)</a>}m
357
- params = $1
358
- results[:inner_text] = $2
359
- params.scan(/\s*(\S+?)=['"](.+?)['"]\s*/).each do |key, value|
360
- results[key.to_sym] = value.gsub(/^["'](.+)["']$/, '\1')
361
- end
362
- results
363
- end
364
-
365
- it "escapes {} syntax with backslash (\\{foo bar})" do
366
- input = '\{foo bar} \{XYZ} \{file:FOO} $\{N-M}'
367
- output = '{foo bar} {XYZ} {file:FOO} ${N-M}'
368
- expect(resolve_links(input)).to eq output
369
- end
370
-
371
- it "escapes {} syntax with ! (!{foo bar})" do
372
- input = '!{foo bar} !{XYZ} !{file:FOO} $!{N-M}'
373
- output = '{foo bar} {XYZ} {file:FOO} ${N-M}'
374
- expect(resolve_links(input)).to eq output
375
- end
376
-
377
- it "links static files with file: prefix" do
378
- allow(self).to receive(:serializer).and_return Serializers::FileSystemSerializer.new
379
- allow(self).to receive(:object).and_return Registry.root
380
-
381
- expect(parse_link(resolve_links("{file:TEST.txt#abc}"))).to eq(
382
- :inner_text => "TEST",
383
- :title => "TEST",
384
- :href => "file.TEST.html#abc"
385
- )
386
- expect(parse_link(resolve_links("{file:TEST.txt title}"))).to eq(
387
- :inner_text => "title",
388
- :title => "title",
389
- :href => "file.TEST.html"
390
- )
391
- end
392
-
393
- it "creates regular links with http:// or https:// prefixes" do
394
- expect(parse_link(resolve_links("{http://example.com}"))).to eq(
395
- :inner_text => "http://example.com",
396
- :target => "_parent",
397
- :href => "http://example.com",
398
- :title => "http://example.com"
399
- )
400
- expect(parse_link(resolve_links("{http://example.com title}"))).to eq(
401
- :inner_text => "title",
402
- :target => "_parent",
403
- :href => "http://example.com",
404
- :title => "title"
405
- )
406
- end
407
-
408
- it "creates mailto links with mailto: prefixes" do
409
- expect(parse_link(resolve_links('{mailto:joanna@example.com}'))).to eq(
410
- :inner_text => 'mailto:joanna@example.com',
411
- :target => '_parent',
412
- :href => 'mailto:joanna@example.com',
413
- :title => 'mailto:joanna@example.com'
414
- )
415
- expect(parse_link(resolve_links('{mailto:steve@example.com Steve}'))).to eq(
416
- :inner_text => 'Steve',
417
- :target => '_parent',
418
- :href => 'mailto:steve@example.com',
419
- :title => 'Steve'
420
- )
421
- end
422
-
423
- it "ignores {links} that begin with |...|" do
424
- expect(resolve_links("{|x|x == 1}")).to eq "{|x|x == 1}"
425
- end
426
-
427
- it "gracefully ignores {} in links" do
428
- allow(self).to receive(:linkify).with('Foo', 'Foo').and_return('FOO')
429
- expect(resolve_links("{} {} {Foo Foo}")).to eq '{} {} FOO'
430
- end
431
-
432
- %w(tt code pre).each do |tag|
433
- it "ignores links in <#{tag}>" do
434
- text = "<#{tag}>{Foo}</#{tag}>"
435
- expect(resolve_links(text)).to eq text
436
- end
437
- end
438
-
439
- it "resolves {Name}" do
440
- expect(self).to receive(:link_file).with('TEST', nil, nil).and_return('')
441
- resolve_links("{file:TEST}")
442
- end
443
-
444
- it "resolves ({Name})" do
445
- expect(self).to receive(:link_file).with('TEST', nil, nil).and_return('')
446
- resolve_links("({file:TEST})")
447
- end
448
-
449
- it "resolves link with newline in title-part" do
450
- expect(parse_link(resolve_links("{http://example.com foo\nbar}"))).to eq(
451
- :inner_text => "foo bar",
452
- :target => "_parent",
453
- :href => "http://example.com",
454
- :title => "foo bar"
455
- )
456
- end
457
-
458
- it "resolves links to methods whose names have been escaped" do
459
- expect(self).to receive(:linkify).with('Object#<<', nil).and_return('')
460
- resolve_links("{Object#&lt;&lt;}")
461
- end
462
-
463
- it "warns about missing reference at right file location for object" do
464
- YARD.parse_string <<-eof
465
- # Comments here
466
- # And a reference to {InvalidObject}
467
- class MyObject; end
468
- eof
469
- logger = double(:log)
470
- expect(logger).to receive(:warn).ordered.with(
471
- "In file `(stdin)':2: Cannot resolve link to InvalidObject from text:\n\t...{InvalidObject}"
472
- )
473
- allow(self).to receive(:log).and_return(logger)
474
- allow(self).to receive(:object).and_return(Registry.at('MyObject'))
475
- resolve_links(object.docstring)
476
- end
477
-
478
- it "shows ellipsis on either side if there is more on the line in a reference warning" do
479
- YARD.parse_string <<-eof
480
- # {InvalidObject1} beginning of line
481
- # end of line {InvalidObject2}
482
- # Middle of {InvalidObject3} line
483
- # {InvalidObject4}
484
- class MyObject; end
485
- eof
486
- logger = double(:log)
487
- expect(logger).to receive(:warn).ordered.with("In file `(stdin)':1: Cannot resolve link to InvalidObject1 from text:\n\t{InvalidObject1}...")
488
- expect(logger).to receive(:warn).ordered.with("In file `(stdin)':2: Cannot resolve link to InvalidObject2 from text:\n\t...{InvalidObject2}")
489
- expect(logger).to receive(:warn).ordered.with("In file `(stdin)':3: Cannot resolve link to InvalidObject3 from text:\n\t...{InvalidObject3}...")
490
- expect(logger).to receive(:warn).ordered.with("In file `(stdin)':4: Cannot resolve link to InvalidObject4 from text:\n\t{InvalidObject4}")
491
- allow(self).to receive(:log).and_return(logger)
492
- allow(self).to receive(:object).and_return(Registry.at('MyObject'))
493
- resolve_links(object.docstring)
494
- end
495
-
496
- it "warns about missing reference for file template (no object)" do
497
- @file = CodeObjects::ExtraFileObject.new('myfile.txt', '')
498
- logger = double(:log)
499
- expect(logger).to receive(:warn).ordered.with("In file `myfile.txt':3: Cannot resolve link to InvalidObject from text:\n\t...{InvalidObject Some Title}")
500
- allow(self).to receive(:log).and_return(logger)
501
- allow(self).to receive(:object).and_return(Registry.root)
502
- resolve_links(<<-eof)
503
- Hello world
504
- This is a line
505
- And {InvalidObject Some Title}
506
- And more.
507
- eof
508
- end
509
- end
510
-
511
- describe "#signature" do
512
- before do
513
- arrow = "&#x21d2;"
514
- @results = {
515
- :regular => "#<strong>foo</strong> #{arrow} Object",
516
- :default_return => "#<strong>foo</strong> #{arrow} Hello",
517
- :no_default_return => "#<strong>foo</strong>",
518
- :private_class => ".<strong>foo</strong> #{arrow} Object <span class=\"extras\">(private)</span>",
519
- :single => "#<strong>foo</strong> #{arrow} String",
520
- :two_types => "#<strong>foo</strong> #{arrow} String, Symbol",
521
- :two_types_multitag => "#<strong>foo</strong> #{arrow} String, Symbol",
522
- :type_nil => "#<strong>foo</strong> #{arrow} Type<sup>?</sup>",
523
- :type_array => "#<strong>foo</strong> #{arrow} Type<sup>+</sup>",
524
- :multitype => "#<strong>foo</strong> #{arrow} Type, ...",
525
- :void => "#<strong>foo</strong> #{arrow} void",
526
- :hide_void => "#<strong>foo</strong>",
527
- :block => "#<strong>foo</strong> {|a, b, c| ... } #{arrow} Object",
528
- :empty_overload => "#<strong>foobar</strong> #{arrow} String"
529
- }
530
- end
531
-
532
- def format_types(types, _brackets = false) types.join(", ") end
533
- def signature(obj, link = false) super(obj, link).strip end
534
-
535
- it_should_behave_like "signature"
536
-
537
- it "links to regular method if overload name does not have the same method name" do
538
- YARD.parse_string <<-eof
539
- class Foo
540
- # @overload bar(a, b, c)
541
- def foo; end
542
- end
543
- eof
544
- serializer = double(:serializer)
545
- allow(serializer).to receive(:serialized_path).with(Registry.at('Foo')).and_return('')
546
- allow(self).to receive(:serializer).and_return(serializer)
547
- allow(self).to receive(:object).and_return(Registry.at('Foo'))
548
- expect(signature(Registry.at('Foo#foo').tag(:overload), true)).to eq(
549
- "<a href=\"#foo-instance_method\" title=\"#bar (instance method)\">#<strong>bar</strong>(a, b, c) </a>"
550
- )
551
- end
552
- end
553
-
554
- describe "#html_syntax_highlight" do
555
- subject do
556
- obj = OpenStruct.new
557
- obj.options = options
558
- obj.object = Registry.root
559
- obj.extend(Templates::Helpers::HtmlHelper)
560
- obj
561
- end
562
-
563
- it "returns empty string on nil input" do
564
- expect(subject.html_syntax_highlight(nil)).to eq ''
565
- end
566
-
567
- it "calls #html_syntax_highlight_ruby by default" do
568
- Registry.root.source_type = nil
569
- expect(subject).to receive(:html_syntax_highlight_ruby).with('def x; end')
570
- subject.html_syntax_highlight('def x; end')
571
- end
572
-
573
- it "calls #html_syntax_highlight_NAME if there's an object with a #source_type" do
574
- subject.object = OpenStruct.new(:source_type => :NAME)
575
- expect(subject).to receive(:html_markup_html) {|text| text }
576
- expect(subject).to receive(:html_syntax_highlight_NAME).and_return("foobar")
577
- expect(subject.htmlify('<pre><code>def x; end</code></pre>', :html)).to eq(
578
- '<pre class="code NAME"><code class="NAME">foobar</code></pre>'
579
- )
580
- end
581
-
582
- it "adds !!!LANG to className in outputted pre tag" do
583
- subject.object = OpenStruct.new(:source_type => :LANG)
584
- expect(subject).to receive(:html_markup_html) {|text| text }
585
- expect(subject).to receive(:html_syntax_highlight_LANG).and_return("foobar")
586
- expect(subject.htmlify("<pre><code>!!!LANG\ndef x; end</code></pre>", :html)).to eq(
587
- '<pre class="code LANG"><code class="LANG">foobar</code></pre>'
588
- )
589
- end
590
-
591
- it "calls html_syntax_highlight_NAME if source starts with !!!NAME" do
592
- expect(subject).to receive(:html_syntax_highlight_NAME).and_return("foobar")
593
- expect(subject.html_syntax_highlight(<<-eof
594
- !!!NAME
595
- def x; end
596
- eof
597
- )).to eq "foobar"
598
- end
599
-
600
- it "does not highlight if highlight option is false" do
601
- subject.options.highlight = false
602
- expect(subject).not_to receive(:html_syntax_highlight_ruby)
603
- expect(subject.html_syntax_highlight('def x; end')).to eq 'def x; end'
604
- end
605
-
606
- it "does not highlight if there is no highlight method specified by !!!NAME" do
607
- def subject.respond_to?(method, include_all = false)
608
- return false if method == 'html_syntax_highlight_NAME'
609
- super
610
- end
611
- expect(subject).not_to receive(:html_syntax_highlight_NAME)
612
- expect(subject.html_syntax_highlight("!!!NAME\ndef x; end")).to eq "def x; end"
613
- end
614
-
615
- it "highlights as ruby if htmlify(text, :ruby) is called" do
616
- expect(subject).to receive(:html_syntax_highlight_ruby).with('def x; end').and_return('x')
617
- expect(subject.htmlify('def x; end', :ruby)).to eq '<pre class="code ruby">x</pre>'
618
- end
619
-
620
- it "does not prioritize object source type when called directly" do
621
- expect(subject).to receive(:html_syntax_highlight_ruby).with('def x; end').and_return('x')
622
- subject.object = OpenStruct.new(:source_type => :c)
623
- expect(subject.html_syntax_highlight("def x; end")).to eq "x"
624
- end
625
-
626
- it "doesn't escape code snippets twice" do
627
- expect(subject.htmlify('<pre lang="foo"><code>{"foo" => 1}</code></pre>', :html)).to eq(
628
- '<pre class="code foo"><code class="foo">{&quot;foo&quot; =&gt; 1}</code></pre>'
629
- )
630
- end
631
-
632
- it "highlights source when matching a pre lang= tag" do
633
- expect(subject.htmlify('<pre lang="foo"><code>x = 1</code></pre>', :html)).to eq(
634
- '<pre class="code foo"><code class="foo">x = 1</code></pre>'
635
- )
636
- end
637
-
638
- it "highlights source when matching a code class= tag" do
639
- expect(subject.htmlify('<pre><code class="foo">x = 1</code></pre>', :html)).to eq(
640
- '<pre class="code foo"><code class="foo">x = 1</code></pre>'
641
- )
642
- end
643
- end
644
-
645
- describe "#link_url" do
646
- it "adds target if scheme is provided" do
647
- expect(link_url("http://url.com")).to include(" target=\"_parent\"")
648
- expect(link_url("https://url.com")).to include(" target=\"_parent\"")
649
- expect(link_url("irc://url.com")).to include(" target=\"_parent\"")
650
- expect(link_url("../not/scheme")).not_to include("target")
651
- end
652
- end
653
- 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(/^\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