yard 0.9.18 → 0.9.19

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 (567) hide show
  1. checksums.yaml +4 -4
  2. data/.yardopts +26 -26
  3. data/CHANGELOG.md +742 -728
  4. data/LEGAL +66 -66
  5. data/LICENSE +22 -22
  6. data/README.md +328 -328
  7. data/Rakefile +42 -53
  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 +308 -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 +789 -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 -615
  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 +134 -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 +11 -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 -386
  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 +212 -211
  95. data/lib/yard/handlers/c/init_handler.rb +20 -20
  96. data/lib/yard/handlers/c/method_handler.rb +45 -45
  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/common/method_handler.rb +19 -0
  104. data/lib/yard/handlers/processor.rb +200 -200
  105. data/lib/yard/handlers/ruby/alias_handler.rb +44 -44
  106. data/lib/yard/handlers/ruby/attribute_handler.rb +87 -87
  107. data/lib/yard/handlers/ruby/base.rb +165 -165
  108. data/lib/yard/handlers/ruby/class_condition_handler.rb +92 -92
  109. data/lib/yard/handlers/ruby/class_handler.rb +119 -119
  110. data/lib/yard/handlers/ruby/class_variable_handler.rb +17 -17
  111. data/lib/yard/handlers/ruby/comment_handler.rb +10 -10
  112. data/lib/yard/handlers/ruby/constant_handler.rb +59 -59
  113. data/lib/yard/handlers/ruby/decorator_handler_methods.rb +123 -123
  114. data/lib/yard/handlers/ruby/dsl_handler.rb +15 -15
  115. data/lib/yard/handlers/ruby/dsl_handler_methods.rb +96 -96
  116. data/lib/yard/handlers/ruby/exception_handler.rb +27 -27
  117. data/lib/yard/handlers/ruby/extend_handler.rb +22 -22
  118. data/lib/yard/handlers/ruby/legacy/alias_handler.rb +37 -37
  119. data/lib/yard/handlers/ruby/legacy/attribute_handler.rb +65 -65
  120. data/lib/yard/handlers/ruby/legacy/base.rb +245 -245
  121. data/lib/yard/handlers/ruby/legacy/class_condition_handler.rb +83 -83
  122. data/lib/yard/handlers/ruby/legacy/class_handler.rb +113 -113
  123. data/lib/yard/handlers/ruby/legacy/class_variable_handler.rb +15 -15
  124. data/lib/yard/handlers/ruby/legacy/comment_handler.rb +10 -10
  125. data/lib/yard/handlers/ruby/legacy/constant_handler.rb +29 -29
  126. data/lib/yard/handlers/ruby/legacy/dsl_handler.rb +17 -17
  127. data/lib/yard/handlers/ruby/legacy/exception_handler.rb +13 -13
  128. data/lib/yard/handlers/ruby/legacy/extend_handler.rb +21 -21
  129. data/lib/yard/handlers/ruby/legacy/method_handler.rb +90 -90
  130. data/lib/yard/handlers/ruby/legacy/mixin_handler.rb +39 -39
  131. data/lib/yard/handlers/ruby/legacy/module_function_handler.rb +19 -19
  132. data/lib/yard/handlers/ruby/legacy/module_handler.rb +12 -12
  133. data/lib/yard/handlers/ruby/legacy/private_class_method_handler.rb +22 -22
  134. data/lib/yard/handlers/ruby/legacy/private_constant_handler.rb +22 -22
  135. data/lib/yard/handlers/ruby/legacy/visibility_handler.rb +17 -17
  136. data/lib/yard/handlers/ruby/legacy/yield_handler.rb +29 -29
  137. data/lib/yard/handlers/ruby/method_condition_handler.rb +9 -9
  138. data/lib/yard/handlers/ruby/method_handler.rb +114 -118
  139. data/lib/yard/handlers/ruby/mixin_handler.rb +37 -37
  140. data/lib/yard/handlers/ruby/module_function_handler.rb +27 -27
  141. data/lib/yard/handlers/ruby/module_handler.rb +12 -12
  142. data/lib/yard/handlers/ruby/private_class_method_handler.rb +14 -14
  143. data/lib/yard/handlers/ruby/private_constant_handler.rb +43 -43
  144. data/lib/yard/handlers/ruby/public_class_method_handler.rb +14 -14
  145. data/lib/yard/handlers/ruby/struct_handler_methods.rb +143 -143
  146. data/lib/yard/handlers/ruby/visibility_handler.rb +22 -22
  147. data/lib/yard/handlers/ruby/yield_handler.rb +31 -31
  148. data/lib/yard/i18n/locale.rb +67 -67
  149. data/lib/yard/i18n/message.rb +57 -57
  150. data/lib/yard/i18n/messages.rb +56 -56
  151. data/lib/yard/i18n/po_parser.rb +61 -61
  152. data/lib/yard/i18n/pot_generator.rb +290 -290
  153. data/lib/yard/i18n/text.rb +173 -173
  154. data/lib/yard/logging.rb +205 -205
  155. data/lib/yard/options.rb +217 -217
  156. data/lib/yard/parser/base.rb +57 -57
  157. data/lib/yard/parser/c/c_parser.rb +235 -235
  158. data/lib/yard/parser/c/comment_parser.rb +134 -134
  159. data/lib/yard/parser/c/statement.rb +64 -64
  160. data/lib/yard/parser/ruby/ast_node.rb +540 -540
  161. data/lib/yard/parser/ruby/legacy/ruby_lex.rb +1354 -1354
  162. data/lib/yard/parser/ruby/legacy/ruby_parser.rb +32 -32
  163. data/lib/yard/parser/ruby/legacy/statement.rb +66 -66
  164. data/lib/yard/parser/ruby/legacy/statement_list.rb +394 -394
  165. data/lib/yard/parser/ruby/legacy/token_list.rb +74 -74
  166. data/lib/yard/parser/ruby/ruby_parser.rb +687 -687
  167. data/lib/yard/parser/ruby/token_resolver.rb +156 -156
  168. data/lib/yard/parser/source_parser.rb +526 -526
  169. data/lib/yard/rake/yardoc_task.rb +81 -81
  170. data/lib/yard/registry.rb +439 -439
  171. data/lib/yard/registry_resolver.rb +189 -189
  172. data/lib/yard/registry_store.rb +337 -337
  173. data/lib/yard/rubygems/backports.rb +10 -10
  174. data/lib/yard/rubygems/backports/LICENSE.txt +57 -57
  175. data/lib/yard/rubygems/backports/MIT.txt +20 -20
  176. data/lib/yard/rubygems/backports/gem.rb +10 -10
  177. data/lib/yard/rubygems/backports/source_index.rb +365 -365
  178. data/lib/yard/rubygems/doc_manager.rb +90 -90
  179. data/lib/yard/rubygems/hook.rb +197 -197
  180. data/lib/yard/rubygems/specification.rb +50 -50
  181. data/lib/yard/serializers/base.rb +83 -83
  182. data/lib/yard/serializers/file_system_serializer.rb +123 -123
  183. data/lib/yard/serializers/process_serializer.rb +24 -24
  184. data/lib/yard/serializers/stdout_serializer.rb +34 -34
  185. data/lib/yard/serializers/yardoc_serializer.rb +152 -152
  186. data/lib/yard/server.rb +13 -13
  187. data/lib/yard/server/adapter.rb +100 -100
  188. data/lib/yard/server/commands/base.rb +209 -209
  189. data/lib/yard/server/commands/display_file_command.rb +29 -29
  190. data/lib/yard/server/commands/display_object_command.rb +65 -65
  191. data/lib/yard/server/commands/frames_command.rb +16 -16
  192. data/lib/yard/server/commands/library_command.rb +187 -187
  193. data/lib/yard/server/commands/library_index_command.rb +28 -28
  194. data/lib/yard/server/commands/list_command.rb +25 -25
  195. data/lib/yard/server/commands/root_request_command.rb +15 -15
  196. data/lib/yard/server/commands/search_command.rb +79 -79
  197. data/lib/yard/server/commands/static_file_command.rb +23 -23
  198. data/lib/yard/server/commands/static_file_helpers.rb +62 -62
  199. data/lib/yard/server/doc_server_helper.rb +91 -91
  200. data/lib/yard/server/doc_server_serializer.rb +39 -39
  201. data/lib/yard/server/library_version.rb +277 -277
  202. data/lib/yard/server/rack_adapter.rb +89 -89
  203. data/lib/yard/server/router.rb +187 -187
  204. data/lib/yard/server/static_caching.rb +46 -46
  205. data/lib/yard/server/templates/default/fulldoc/html/css/custom.css +127 -127
  206. data/lib/yard/server/templates/default/fulldoc/html/js/autocomplete.js +11 -11
  207. data/lib/yard/server/templates/default/layout/html/breadcrumb.erb +37 -37
  208. data/lib/yard/server/templates/default/layout/html/script_setup.erb +7 -7
  209. data/lib/yard/server/templates/default/layout/html/setup.rb +8 -8
  210. data/lib/yard/server/templates/default/method_details/html/permalink.erb +4 -4
  211. data/lib/yard/server/templates/default/method_details/html/setup.rb +5 -5
  212. data/lib/yard/server/templates/doc_server/library_list/html/headers.erb +8 -8
  213. data/lib/yard/server/templates/doc_server/library_list/html/library_list.erb +14 -14
  214. data/lib/yard/server/templates/doc_server/library_list/html/listing.erb +13 -13
  215. data/lib/yard/server/templates/doc_server/library_list/html/setup.rb +6 -6
  216. data/lib/yard/server/templates/doc_server/library_list/html/title.erb +2 -2
  217. data/lib/yard/server/templates/doc_server/processing/html/processing.erb +52 -52
  218. data/lib/yard/server/templates/doc_server/processing/html/setup.rb +4 -4
  219. data/lib/yard/server/templates/doc_server/search/html/search.erb +18 -18
  220. data/lib/yard/server/templates/doc_server/search/html/setup.rb +9 -9
  221. data/lib/yard/server/webrick_adapter.rb +45 -45
  222. data/lib/yard/tags/default_factory.rb +191 -191
  223. data/lib/yard/tags/default_tag.rb +13 -13
  224. data/lib/yard/tags/directives.rb +616 -616
  225. data/lib/yard/tags/library.rb +633 -633
  226. data/lib/yard/tags/option_tag.rb +13 -13
  227. data/lib/yard/tags/overload_tag.rb +71 -71
  228. data/lib/yard/tags/ref_tag.rb +8 -8
  229. data/lib/yard/tags/ref_tag_list.rb +28 -28
  230. data/lib/yard/tags/tag.rb +71 -71
  231. data/lib/yard/tags/tag_format_error.rb +7 -7
  232. data/lib/yard/tags/types_explainer.rb +162 -162
  233. data/lib/yard/templates/engine.rb +186 -186
  234. data/lib/yard/templates/erb_cache.rb +23 -23
  235. data/lib/yard/templates/helpers/base_helper.rb +215 -215
  236. data/lib/yard/templates/helpers/filter_helper.rb +27 -27
  237. data/lib/yard/templates/helpers/html_helper.rb +646 -646
  238. data/lib/yard/templates/helpers/html_syntax_highlight_helper.rb +78 -78
  239. data/lib/yard/templates/helpers/markup/rdoc_markdown.rb +23 -23
  240. data/lib/yard/templates/helpers/markup/rdoc_markup.rb +109 -109
  241. data/lib/yard/templates/helpers/markup_helper.rb +172 -172
  242. data/lib/yard/templates/helpers/method_helper.rb +75 -75
  243. data/lib/yard/templates/helpers/module_helper.rb +21 -21
  244. data/lib/yard/templates/helpers/text_helper.rb +112 -112
  245. data/lib/yard/templates/helpers/uml_helper.rb +47 -47
  246. data/lib/yard/templates/section.rb +105 -105
  247. data/lib/yard/templates/template.rb +418 -418
  248. data/lib/yard/templates/template_options.rb +92 -92
  249. data/lib/yard/verifier.rb +151 -151
  250. data/lib/yard/version.rb +6 -6
  251. data/spec/cli/command_parser_spec.rb +43 -43
  252. data/spec/cli/command_spec.rb +36 -36
  253. data/spec/cli/config_spec.rb +148 -148
  254. data/spec/cli/diff_spec.rb +254 -254
  255. data/spec/cli/display_spec.rb +30 -30
  256. data/spec/cli/gems_spec.rb +81 -81
  257. data/spec/cli/graph_spec.rb +18 -18
  258. data/spec/cli/help_spec.rb +22 -22
  259. data/spec/cli/i18n_spec.rb +107 -107
  260. data/spec/cli/list_spec.rb +8 -8
  261. data/spec/cli/markup_types_spec.rb +22 -22
  262. data/spec/cli/server_spec.rb +324 -324
  263. data/spec/cli/stats_spec.rb +96 -96
  264. data/spec/cli/yard_on_yard_spec.rb +38 -38
  265. data/spec/cli/yardoc_spec.rb +896 -862
  266. data/spec/cli/yri_spec.rb +101 -101
  267. data/spec/code_objects/base_spec.rb +470 -470
  268. data/spec/code_objects/class_object_spec.rb +226 -226
  269. data/spec/code_objects/code_object_list_spec.rb +36 -36
  270. data/spec/code_objects/constants_spec.rb +116 -116
  271. data/spec/code_objects/extra_file_object_spec.rb +160 -160
  272. data/spec/code_objects/macro_object_spec.rb +150 -150
  273. data/spec/code_objects/method_object_spec.rb +184 -184
  274. data/spec/code_objects/module_object_spec.rb +142 -142
  275. data/spec/code_objects/namespace_object_spec.rb +171 -171
  276. data/spec/code_objects/proxy_spec.rb +141 -141
  277. data/spec/code_objects/spec_helper.rb +3 -3
  278. data/spec/config_spec.rb +171 -171
  279. data/spec/core_ext/array_spec.rb +13 -13
  280. data/spec/core_ext/file_spec.rb +72 -72
  281. data/spec/core_ext/hash_spec.rb +14 -14
  282. data/spec/core_ext/insertion_spec.rb +37 -37
  283. data/spec/core_ext/module_spec.rb +9 -15
  284. data/spec/core_ext/string_spec.rb +42 -42
  285. data/spec/core_ext/symbol_hash_spec.rb +89 -89
  286. data/spec/docstring_parser_spec.rb +280 -280
  287. data/spec/docstring_spec.rb +373 -373
  288. data/spec/examples.txt +1883 -1875
  289. data/spec/handlers/alias_handler_spec.rb +82 -82
  290. data/spec/handlers/attribute_handler_spec.rb +96 -96
  291. data/spec/handlers/base_spec.rb +216 -216
  292. data/spec/handlers/c/alias_handler_spec.rb +34 -34
  293. data/spec/handlers/c/attribute_handler_spec.rb +41 -41
  294. data/spec/handlers/c/class_handler_spec.rb +78 -78
  295. data/spec/handlers/c/constant_handler_spec.rb +71 -71
  296. data/spec/handlers/c/init_handler_spec.rb +48 -48
  297. data/spec/handlers/c/method_handler_spec.rb +327 -325
  298. data/spec/handlers/c/mixin_handler_spec.rb +44 -44
  299. data/spec/handlers/c/module_handler_spec.rb +71 -71
  300. data/spec/handlers/c/override_comment_handler_spec.rb +47 -47
  301. data/spec/handlers/c/path_handler_spec.rb +36 -36
  302. data/spec/handlers/c/spec_helper.rb +23 -23
  303. data/spec/handlers/c/struct_handler_spec.rb +16 -16
  304. data/spec/handlers/class_condition_handler_spec.rb +87 -87
  305. data/spec/handlers/class_handler_spec.rb +247 -247
  306. data/spec/handlers/class_method_handler_shared_examples.rb +133 -133
  307. data/spec/handlers/class_variable_handler_spec.rb +12 -12
  308. data/spec/handlers/constant_handler_spec.rb +112 -112
  309. data/spec/handlers/decorator_handler_methods_spec.rb +393 -393
  310. data/spec/handlers/dsl_handler_spec.rb +219 -219
  311. data/spec/handlers/examples/alias_handler_001.rb.txt +45 -45
  312. data/spec/handlers/examples/attribute_handler_001.rb.txt +31 -31
  313. data/spec/handlers/examples/class_condition_handler_001.rb.txt +68 -68
  314. data/spec/handlers/examples/class_handler_001.rb.txt +120 -120
  315. data/spec/handlers/examples/class_variable_handler_001.rb.txt +9 -9
  316. data/spec/handlers/examples/constant_handler_001.rb.txt +35 -35
  317. data/spec/handlers/examples/dsl_handler_001.rb.txt +154 -154
  318. data/spec/handlers/examples/exception_handler_001.rb.txt +58 -58
  319. data/spec/handlers/examples/extend_handler_001.rb.txt +15 -15
  320. data/spec/handlers/examples/method_condition_handler_001.rb.txt +9 -9
  321. data/spec/handlers/examples/method_handler_001.rb.txt +128 -128
  322. data/spec/handlers/examples/mixin_handler_001.rb.txt +37 -37
  323. data/spec/handlers/examples/module_handler_001.rb.txt +29 -29
  324. data/spec/handlers/examples/private_constant_handler_001.rb.txt +8 -8
  325. data/spec/handlers/examples/process_handler_001.rb.txt +11 -11
  326. data/spec/handlers/examples/visibility_handler_001.rb.txt +35 -35
  327. data/spec/handlers/examples/yield_handler_001.rb.txt +54 -54
  328. data/spec/handlers/exception_handler_spec.rb +49 -49
  329. data/spec/handlers/extend_handler_spec.rb +24 -24
  330. data/spec/handlers/legacy_base_spec.rb +128 -128
  331. data/spec/handlers/method_condition_handler_spec.rb +15 -15
  332. data/spec/handlers/method_handler_spec.rb +190 -190
  333. data/spec/handlers/mixin_handler_spec.rb +56 -56
  334. data/spec/handlers/module_function_handler_spec.rb +106 -106
  335. data/spec/handlers/module_handler_spec.rb +35 -35
  336. data/spec/handlers/private_class_method_handler_spec.rb +11 -11
  337. data/spec/handlers/private_constant_handler_spec.rb +25 -25
  338. data/spec/handlers/processor_spec.rb +35 -35
  339. data/spec/handlers/public_class_method_handler_spec.rb +11 -11
  340. data/spec/handlers/ruby/base_spec.rb +95 -95
  341. data/spec/handlers/ruby/legacy/base_spec.rb +84 -84
  342. data/spec/handlers/spec_helper.rb +33 -33
  343. data/spec/handlers/visibility_handler_spec.rb +44 -44
  344. data/spec/handlers/yield_handler_spec.rb +52 -52
  345. data/spec/i18n/locale_spec.rb +81 -81
  346. data/spec/i18n/message_spec.rb +52 -52
  347. data/spec/i18n/messages_spec.rb +67 -67
  348. data/spec/i18n/pot_generator_spec.rb +295 -295
  349. data/spec/i18n/text_spec.rb +184 -184
  350. data/spec/logging_spec.rb +44 -44
  351. data/spec/options_spec.rb +171 -171
  352. data/spec/parser/base_spec.rb +24 -24
  353. data/spec/parser/c_parser_spec.rb +236 -236
  354. data/spec/parser/examples/array.c.txt +6267 -6267
  355. data/spec/parser/examples/example1.rb.txt +7 -7
  356. data/spec/parser/examples/extrafile.c.txt +8 -8
  357. data/spec/parser/examples/file.c.txt +28 -28
  358. data/spec/parser/examples/multifile.c.txt +22 -22
  359. data/spec/parser/examples/namespace.cpp.txt +68 -68
  360. data/spec/parser/examples/override.c.txt +424 -424
  361. data/spec/parser/examples/parse_in_order_001.rb.txt +2 -2
  362. data/spec/parser/examples/parse_in_order_002.rb.txt +1 -1
  363. data/spec/parser/examples/tag_handler_001.rb.txt +7 -7
  364. data/spec/parser/ruby/ast_node_spec.rb +33 -33
  365. data/spec/parser/ruby/legacy/statement_list_spec.rb +299 -299
  366. data/spec/parser/ruby/legacy/token_list_spec.rb +79 -79
  367. data/spec/parser/ruby/ruby_parser_spec.rb +508 -508
  368. data/spec/parser/ruby/token_resolver_spec.rb +165 -165
  369. data/spec/parser/source_parser_spec.rb +727 -727
  370. data/spec/parser/tag_parsing_spec.rb +17 -17
  371. data/spec/rake/yardoc_task_spec.rb +118 -118
  372. data/spec/registry_spec.rb +463 -463
  373. data/spec/registry_store_spec.rb +316 -316
  374. data/spec/rubygems/doc_manager_spec.rb +112 -112
  375. data/spec/serializers/data/serialized_yardoc/checksums +1 -1
  376. data/spec/serializers/file_system_serializer_spec.rb +145 -145
  377. data/spec/serializers/spec_helper.rb +2 -2
  378. data/spec/serializers/yardoc_serializer_spec.rb +78 -78
  379. data/spec/server/adapter_spec.rb +39 -39
  380. data/spec/server/commands/base_spec.rb +91 -91
  381. data/spec/server/commands/library_command_spec.rb +39 -39
  382. data/spec/server/doc_server_helper_spec.rb +72 -72
  383. data/spec/server/doc_server_serializer_spec.rb +60 -60
  384. data/spec/server/rack_adapter_spec.rb +21 -21
  385. data/spec/server/router_spec.rb +123 -123
  386. data/spec/server/spec_helper.rb +22 -22
  387. data/spec/server/static_caching_spec.rb +47 -47
  388. data/spec/server/webrick_servlet_spec.rb +20 -20
  389. data/spec/server_spec.rb +19 -19
  390. data/spec/spec_helper.rb +212 -212
  391. data/spec/tags/default_factory_spec.rb +168 -168
  392. data/spec/tags/default_tag_spec.rb +11 -11
  393. data/spec/tags/directives_spec.rb +463 -463
  394. data/spec/tags/library_spec.rb +48 -48
  395. data/spec/tags/overload_tag_spec.rb +53 -53
  396. data/spec/tags/ref_tag_list_spec.rb +53 -53
  397. data/spec/tags/types_explainer_spec.rb +203 -203
  398. data/spec/templates/class_spec.rb +45 -45
  399. data/spec/templates/constant_spec.rb +41 -41
  400. data/spec/templates/engine_spec.rb +131 -131
  401. data/spec/templates/examples/class001.html +308 -308
  402. data/spec/templates/examples/class001.txt +36 -36
  403. data/spec/templates/examples/class002.html +39 -39
  404. data/spec/templates/examples/constant001.txt +24 -24
  405. data/spec/templates/examples/constant002.txt +6 -6
  406. data/spec/templates/examples/constant003.txt +10 -10
  407. data/spec/templates/examples/method001.html +137 -137
  408. data/spec/templates/examples/method001.txt +35 -35
  409. data/spec/templates/examples/method002.html +91 -91
  410. data/spec/templates/examples/method002.txt +20 -20
  411. data/spec/templates/examples/method003.html +165 -165
  412. data/spec/templates/examples/method003.txt +45 -45
  413. data/spec/templates/examples/method004.html +48 -48
  414. data/spec/templates/examples/method004.txt +10 -10
  415. data/spec/templates/examples/method005.html +105 -105
  416. data/spec/templates/examples/method005.txt +33 -33
  417. data/spec/templates/examples/method006.html +107 -107
  418. data/spec/templates/examples/method006.txt +20 -20
  419. data/spec/templates/examples/module001.dot +33 -33
  420. data/spec/templates/examples/module001.html +833 -833
  421. data/spec/templates/examples/module001.txt +33 -33
  422. data/spec/templates/examples/module002.html +341 -341
  423. data/spec/templates/examples/module003.html +202 -202
  424. data/spec/templates/examples/module004.html +394 -394
  425. data/spec/templates/examples/module005.html +81 -81
  426. data/spec/templates/examples/tag001.txt +82 -82
  427. data/spec/templates/helpers/base_helper_spec.rb +171 -171
  428. data/spec/templates/helpers/html_helper_spec.rb +687 -668
  429. data/spec/templates/helpers/html_syntax_highlight_helper_spec.rb +65 -65
  430. data/spec/templates/helpers/markup/rdoc_markup_spec.rb +84 -84
  431. data/spec/templates/helpers/markup_helper_spec.rb +136 -136
  432. data/spec/templates/helpers/method_helper_spec.rb +107 -107
  433. data/spec/templates/helpers/module_helper_spec.rb +35 -35
  434. data/spec/templates/helpers/shared_signature_examples.rb +126 -126
  435. data/spec/templates/helpers/text_helper_spec.rb +65 -65
  436. data/spec/templates/method_spec.rb +118 -118
  437. data/spec/templates/module_spec.rb +203 -203
  438. data/spec/templates/onefile_spec.rb +66 -66
  439. data/spec/templates/section_spec.rb +144 -144
  440. data/spec/templates/spec_helper.rb +76 -76
  441. data/spec/templates/tag_spec.rb +52 -52
  442. data/spec/templates/template_spec.rb +410 -410
  443. data/spec/verifier_spec.rb +106 -106
  444. data/templates/default/class/dot/setup.rb +7 -7
  445. data/templates/default/class/dot/superklass.erb +2 -2
  446. data/templates/default/class/html/constructor_details.erb +8 -8
  447. data/templates/default/class/html/setup.rb +2 -2
  448. data/templates/default/class/html/subclasses.erb +4 -4
  449. data/templates/default/class/setup.rb +36 -36
  450. data/templates/default/class/text/setup.rb +12 -12
  451. data/templates/default/class/text/subclasses.erb +5 -5
  452. data/templates/default/constant/text/header.erb +11 -11
  453. data/templates/default/constant/text/setup.rb +4 -4
  454. data/templates/default/docstring/html/abstract.erb +4 -4
  455. data/templates/default/docstring/html/deprecated.erb +1 -1
  456. data/templates/default/docstring/html/index.erb +5 -5
  457. data/templates/default/docstring/html/note.erb +6 -6
  458. data/templates/default/docstring/html/private.erb +4 -4
  459. data/templates/default/docstring/html/text.erb +1 -1
  460. data/templates/default/docstring/html/todo.erb +6 -6
  461. data/templates/default/docstring/setup.rb +52 -52
  462. data/templates/default/docstring/text/abstract.erb +2 -2
  463. data/templates/default/docstring/text/deprecated.erb +2 -2
  464. data/templates/default/docstring/text/index.erb +2 -2
  465. data/templates/default/docstring/text/note.erb +3 -3
  466. data/templates/default/docstring/text/private.erb +2 -2
  467. data/templates/default/docstring/text/text.erb +1 -1
  468. data/templates/default/docstring/text/todo.erb +3 -3
  469. data/templates/default/fulldoc/html/css/full_list.css +58 -58
  470. data/templates/default/fulldoc/html/css/style.css +496 -496
  471. data/templates/default/fulldoc/html/frames.erb +17 -17
  472. data/templates/default/fulldoc/html/full_list.erb +37 -37
  473. data/templates/default/fulldoc/html/full_list_class.erb +2 -2
  474. data/templates/default/fulldoc/html/full_list_file.erb +7 -7
  475. data/templates/default/fulldoc/html/full_list_method.erb +10 -10
  476. data/templates/default/fulldoc/html/js/app.js +303 -292
  477. data/templates/default/fulldoc/html/js/full_list.js +216 -216
  478. data/templates/default/fulldoc/html/js/jquery.js +3 -3
  479. data/templates/default/fulldoc/html/setup.rb +241 -241
  480. data/templates/default/layout/dot/header.erb +5 -5
  481. data/templates/default/layout/dot/setup.rb +15 -15
  482. data/templates/default/layout/html/breadcrumb.erb +11 -11
  483. data/templates/default/layout/html/files.erb +11 -11
  484. data/templates/default/layout/html/footer.erb +5 -5
  485. data/templates/default/layout/html/headers.erb +15 -15
  486. data/templates/default/layout/html/index.erb +2 -2
  487. data/templates/default/layout/html/layout.erb +23 -23
  488. data/templates/default/layout/html/listing.erb +4 -4
  489. data/templates/default/layout/html/objects.erb +32 -32
  490. data/templates/default/layout/html/script_setup.erb +4 -4
  491. data/templates/default/layout/html/search.erb +12 -12
  492. data/templates/default/layout/html/setup.rb +89 -89
  493. data/templates/default/method/html/header.erb +16 -16
  494. data/templates/default/method/setup.rb +4 -4
  495. data/templates/default/method_details/html/header.erb +2 -2
  496. data/templates/default/method_details/html/method_signature.erb +24 -24
  497. data/templates/default/method_details/html/source.erb +9 -9
  498. data/templates/default/method_details/setup.rb +11 -11
  499. data/templates/default/method_details/text/header.erb +10 -10
  500. data/templates/default/method_details/text/method_signature.erb +12 -12
  501. data/templates/default/method_details/text/setup.rb +11 -11
  502. data/templates/default/module/dot/child.erb +1 -1
  503. data/templates/default/module/dot/dependencies.erb +2 -2
  504. data/templates/default/module/dot/header.erb +6 -6
  505. data/templates/default/module/dot/info.erb +13 -13
  506. data/templates/default/module/dot/setup.rb +15 -15
  507. data/templates/default/module/html/attribute_details.erb +10 -10
  508. data/templates/default/module/html/attribute_summary.erb +8 -8
  509. data/templates/default/module/html/box_info.erb +43 -43
  510. data/templates/default/module/html/children.erb +8 -8
  511. data/templates/default/module/html/constant_summary.erb +17 -17
  512. data/templates/default/module/html/defines.erb +2 -2
  513. data/templates/default/module/html/header.erb +5 -5
  514. data/templates/default/module/html/inherited_attributes.erb +14 -14
  515. data/templates/default/module/html/inherited_constants.erb +8 -8
  516. data/templates/default/module/html/inherited_methods.erb +18 -18
  517. data/templates/default/module/html/item_summary.erb +40 -40
  518. data/templates/default/module/html/method_details_list.erb +9 -9
  519. data/templates/default/module/html/method_summary.erb +13 -13
  520. data/templates/default/module/html/methodmissing.erb +12 -12
  521. data/templates/default/module/setup.rb +167 -167
  522. data/templates/default/module/text/children.erb +9 -9
  523. data/templates/default/module/text/class_meths_list.erb +7 -7
  524. data/templates/default/module/text/extends.erb +7 -7
  525. data/templates/default/module/text/header.erb +7 -7
  526. data/templates/default/module/text/includes.erb +7 -7
  527. data/templates/default/module/text/instance_meths_list.erb +7 -7
  528. data/templates/default/module/text/setup.rb +13 -13
  529. data/templates/default/onefile/html/files.erb +4 -4
  530. data/templates/default/onefile/html/headers.erb +6 -6
  531. data/templates/default/onefile/html/layout.erb +17 -17
  532. data/templates/default/onefile/html/readme.erb +2 -2
  533. data/templates/default/onefile/html/setup.rb +62 -62
  534. data/templates/default/root/dot/child.erb +2 -2
  535. data/templates/default/root/dot/setup.rb +6 -6
  536. data/templates/default/root/html/setup.rb +2 -2
  537. data/templates/default/tags/html/example.erb +10 -10
  538. data/templates/default/tags/html/index.erb +2 -2
  539. data/templates/default/tags/html/option.erb +24 -24
  540. data/templates/default/tags/html/overload.erb +13 -13
  541. data/templates/default/tags/html/see.erb +7 -7
  542. data/templates/default/tags/html/tag.erb +20 -20
  543. data/templates/default/tags/setup.rb +57 -57
  544. data/templates/default/tags/text/example.erb +12 -12
  545. data/templates/default/tags/text/index.erb +1 -1
  546. data/templates/default/tags/text/option.erb +20 -20
  547. data/templates/default/tags/text/overload.erb +19 -19
  548. data/templates/default/tags/text/see.erb +11 -11
  549. data/templates/default/tags/text/tag.erb +13 -13
  550. data/templates/guide/class/html/setup.rb +2 -2
  551. data/templates/guide/docstring/html/setup.rb +2 -2
  552. data/templates/guide/fulldoc/html/css/style.css +108 -108
  553. data/templates/guide/fulldoc/html/js/app.js +33 -33
  554. data/templates/guide/fulldoc/html/setup.rb +74 -74
  555. data/templates/guide/layout/html/layout.erb +81 -81
  556. data/templates/guide/layout/html/setup.rb +25 -25
  557. data/templates/guide/method/html/header.erb +17 -17
  558. data/templates/guide/method/html/setup.rb +22 -22
  559. data/templates/guide/module/html/header.erb +6 -6
  560. data/templates/guide/module/html/method_list.erb +4 -4
  561. data/templates/guide/module/html/setup.rb +27 -27
  562. data/templates/guide/onefile/html/files.erb +4 -4
  563. data/templates/guide/onefile/html/setup.rb +6 -6
  564. data/templates/guide/onefile/html/toc.erb +3 -3
  565. data/templates/guide/tags/html/setup.rb +9 -9
  566. data/yard.gemspec +43 -43
  567. metadata +4 -3
@@ -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