logstash-output-scalyr 0.1.8 → 0.1.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (320) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +27 -0
  3. data/Gemfile +5 -0
  4. data/README.md +3 -2
  5. data/lib/logstash/outputs/scalyr.rb +226 -138
  6. data/lib/scalyr/common/client.rb +76 -50
  7. data/lib/scalyr/common/util.rb +7 -0
  8. data/lib/scalyr/constants.rb +2 -0
  9. data/logstash-output-scalyr.gemspec +1 -1
  10. data/spec/logstash/outputs/scalyr_integration_spec.rb +148 -8
  11. data/spec/logstash/outputs/scalyr_spec.rb +12 -6
  12. data/vendor/bundle/jruby/2.5.0/bin/htmldiff +1 -1
  13. data/vendor/bundle/jruby/2.5.0/bin/ldiff +1 -1
  14. data/vendor/bundle/jruby/2.5.0/cache/addressable-2.7.0.gem +0 -0
  15. data/vendor/bundle/jruby/2.5.0/cache/crack-0.4.5.gem +0 -0
  16. data/vendor/bundle/jruby/2.5.0/cache/hashdiff-1.0.1.gem +0 -0
  17. data/vendor/bundle/jruby/2.5.0/cache/public_suffix-4.0.6.gem +0 -0
  18. data/vendor/bundle/jruby/2.5.0/cache/rexml-3.2.5.gem +0 -0
  19. data/vendor/bundle/jruby/2.5.0/cache/webmock-3.13.0.gem +0 -0
  20. data/vendor/bundle/jruby/2.5.0/gems/addressable-2.7.0/CHANGELOG.md +235 -0
  21. data/vendor/bundle/jruby/2.5.0/gems/addressable-2.7.0/Gemfile +32 -0
  22. data/vendor/bundle/jruby/2.5.0/gems/addressable-2.7.0/LICENSE.txt +202 -0
  23. data/vendor/bundle/jruby/2.5.0/gems/addressable-2.7.0/README.md +121 -0
  24. data/vendor/bundle/jruby/2.5.0/gems/addressable-2.7.0/Rakefile +34 -0
  25. data/vendor/bundle/jruby/2.5.0/gems/addressable-2.7.0/data/unicode.data +0 -0
  26. data/vendor/bundle/jruby/2.5.0/gems/addressable-2.7.0/lib/addressable.rb +4 -0
  27. data/vendor/bundle/jruby/2.5.0/gems/addressable-2.7.0/lib/addressable/idna.rb +27 -0
  28. data/vendor/bundle/jruby/2.5.0/gems/addressable-2.7.0/lib/addressable/idna/native.rb +61 -0
  29. data/vendor/bundle/jruby/2.5.0/gems/addressable-2.7.0/lib/addressable/idna/pure.rb +676 -0
  30. data/vendor/bundle/jruby/2.5.0/gems/addressable-2.7.0/lib/addressable/template.rb +1045 -0
  31. data/vendor/bundle/jruby/2.5.0/gems/addressable-2.7.0/lib/addressable/uri.rb +2529 -0
  32. data/vendor/bundle/jruby/2.5.0/gems/addressable-2.7.0/lib/addressable/version.rb +32 -0
  33. data/vendor/bundle/jruby/2.5.0/gems/addressable-2.7.0/spec/addressable/idna_spec.rb +300 -0
  34. data/vendor/bundle/jruby/2.5.0/gems/addressable-2.7.0/spec/addressable/net_http_compat_spec.rb +30 -0
  35. data/vendor/bundle/jruby/2.5.0/gems/addressable-2.7.0/spec/addressable/rack_mount_compat_spec.rb +106 -0
  36. data/vendor/bundle/jruby/2.5.0/gems/addressable-2.7.0/spec/addressable/security_spec.rb +59 -0
  37. data/vendor/bundle/jruby/2.5.0/gems/addressable-2.7.0/spec/addressable/template_spec.rb +1451 -0
  38. data/vendor/bundle/jruby/2.5.0/gems/addressable-2.7.0/spec/addressable/uri_spec.rb +6603 -0
  39. data/vendor/bundle/jruby/2.5.0/gems/addressable-2.7.0/spec/spec_helper.rb +24 -0
  40. data/vendor/bundle/jruby/2.5.0/gems/addressable-2.7.0/tasks/clobber.rake +4 -0
  41. data/vendor/bundle/jruby/2.5.0/gems/addressable-2.7.0/tasks/gem.rake +93 -0
  42. data/vendor/bundle/jruby/2.5.0/gems/addressable-2.7.0/tasks/git.rake +47 -0
  43. data/vendor/bundle/jruby/2.5.0/gems/addressable-2.7.0/tasks/metrics.rake +24 -0
  44. data/vendor/bundle/jruby/2.5.0/gems/addressable-2.7.0/tasks/rspec.rake +23 -0
  45. data/vendor/bundle/jruby/2.5.0/gems/addressable-2.7.0/tasks/yard.rake +29 -0
  46. data/vendor/bundle/jruby/2.5.0/gems/crack-0.4.5/lib/crack.rb +7 -0
  47. data/vendor/bundle/jruby/2.5.0/gems/crack-0.4.5/lib/crack/json.rb +98 -0
  48. data/vendor/bundle/jruby/2.5.0/gems/crack-0.4.5/lib/crack/util.rb +17 -0
  49. data/vendor/bundle/jruby/2.5.0/gems/crack-0.4.5/lib/crack/version.rb +3 -0
  50. data/vendor/bundle/jruby/2.5.0/gems/crack-0.4.5/lib/crack/xml.rb +238 -0
  51. data/vendor/bundle/jruby/2.5.0/gems/hashdiff-1.0.1/Gemfile +8 -0
  52. data/vendor/bundle/jruby/2.5.0/gems/hashdiff-1.0.1/LICENSE +19 -0
  53. data/vendor/bundle/jruby/2.5.0/gems/hashdiff-1.0.1/README.md +276 -0
  54. data/vendor/bundle/jruby/2.5.0/gems/hashdiff-1.0.1/Rakefile +18 -0
  55. data/vendor/bundle/jruby/2.5.0/gems/hashdiff-1.0.1/changelog.md +100 -0
  56. data/vendor/bundle/jruby/2.5.0/gems/hashdiff-1.0.1/hashdiff.gemspec +39 -0
  57. data/vendor/bundle/jruby/2.5.0/gems/hashdiff-1.0.1/lib/hashdiff.rb +10 -0
  58. data/vendor/bundle/jruby/2.5.0/gems/hashdiff-1.0.1/lib/hashdiff/compare_hashes.rb +69 -0
  59. data/vendor/bundle/jruby/2.5.0/gems/hashdiff-1.0.1/lib/hashdiff/diff.rb +177 -0
  60. data/vendor/bundle/jruby/2.5.0/gems/hashdiff-1.0.1/lib/hashdiff/lcs.rb +66 -0
  61. data/vendor/bundle/jruby/2.5.0/gems/hashdiff-1.0.1/lib/hashdiff/lcs_compare_arrays.rb +32 -0
  62. data/vendor/bundle/jruby/2.5.0/gems/hashdiff-1.0.1/lib/hashdiff/linear_compare_array.rb +159 -0
  63. data/vendor/bundle/jruby/2.5.0/gems/hashdiff-1.0.1/lib/hashdiff/patch.rb +88 -0
  64. data/vendor/bundle/jruby/2.5.0/gems/hashdiff-1.0.1/lib/hashdiff/util.rb +155 -0
  65. data/vendor/bundle/jruby/2.5.0/gems/hashdiff-1.0.1/lib/hashdiff/version.rb +5 -0
  66. data/vendor/bundle/jruby/2.5.0/gems/hashdiff-1.0.1/spec/hashdiff/best_diff_spec.rb +75 -0
  67. data/vendor/bundle/jruby/2.5.0/gems/hashdiff-1.0.1/spec/hashdiff/diff_array_spec.rb +60 -0
  68. data/vendor/bundle/jruby/2.5.0/gems/hashdiff-1.0.1/spec/hashdiff/diff_spec.rb +360 -0
  69. data/vendor/bundle/jruby/2.5.0/gems/hashdiff-1.0.1/spec/hashdiff/lcs_spec.rb +76 -0
  70. data/vendor/bundle/jruby/2.5.0/gems/hashdiff-1.0.1/spec/hashdiff/linear_compare_array_spec.rb +50 -0
  71. data/vendor/bundle/jruby/2.5.0/gems/hashdiff-1.0.1/spec/hashdiff/patch_spec.rb +185 -0
  72. data/vendor/bundle/jruby/2.5.0/gems/hashdiff-1.0.1/spec/hashdiff/readme_spec.rb +15 -0
  73. data/vendor/bundle/jruby/2.5.0/gems/hashdiff-1.0.1/spec/hashdiff/util_spec.rb +116 -0
  74. data/vendor/bundle/jruby/2.5.0/gems/hashdiff-1.0.1/spec/spec_helper.rb +15 -0
  75. data/vendor/bundle/jruby/2.5.0/gems/public_suffix-4.0.6/2.0-Upgrade.md +52 -0
  76. data/vendor/bundle/jruby/2.5.0/gems/public_suffix-4.0.6/CHANGELOG.md +406 -0
  77. data/vendor/bundle/jruby/2.5.0/gems/public_suffix-4.0.6/Gemfile +15 -0
  78. data/vendor/bundle/jruby/2.5.0/gems/public_suffix-4.0.6/LICENSE.txt +22 -0
  79. data/vendor/bundle/jruby/2.5.0/gems/public_suffix-4.0.6/README.md +207 -0
  80. data/vendor/bundle/jruby/2.5.0/gems/public_suffix-4.0.6/Rakefile +51 -0
  81. data/vendor/bundle/jruby/2.5.0/gems/public_suffix-4.0.6/SECURITY.md +104 -0
  82. data/vendor/bundle/jruby/2.5.0/gems/public_suffix-4.0.6/bin/console +15 -0
  83. data/vendor/bundle/jruby/2.5.0/gems/public_suffix-4.0.6/codecov.yml +12 -0
  84. data/vendor/bundle/jruby/2.5.0/gems/public_suffix-4.0.6/data/list.txt +13380 -0
  85. data/vendor/bundle/jruby/2.5.0/gems/public_suffix-4.0.6/lib/public_suffix.rb +179 -0
  86. data/vendor/bundle/jruby/2.5.0/gems/public_suffix-4.0.6/lib/public_suffix/domain.rb +235 -0
  87. data/vendor/bundle/jruby/2.5.0/gems/public_suffix-4.0.6/lib/public_suffix/errors.rb +41 -0
  88. data/vendor/bundle/jruby/2.5.0/gems/public_suffix-4.0.6/lib/public_suffix/list.rb +247 -0
  89. data/vendor/bundle/jruby/2.5.0/gems/public_suffix-4.0.6/lib/public_suffix/rule.rb +350 -0
  90. data/vendor/bundle/jruby/2.5.0/gems/public_suffix-4.0.6/lib/public_suffix/version.rb +13 -0
  91. data/vendor/bundle/jruby/2.5.0/gems/public_suffix-4.0.6/public_suffix.gemspec +29 -0
  92. data/vendor/bundle/jruby/2.5.0/gems/public_suffix-4.0.6/test/acceptance_test.rb +131 -0
  93. data/vendor/bundle/jruby/2.5.0/gems/public_suffix-4.0.6/test/benchmarks/bm_find.rb +66 -0
  94. data/vendor/bundle/jruby/2.5.0/gems/public_suffix-4.0.6/test/benchmarks/bm_find_all.rb +102 -0
  95. data/vendor/bundle/jruby/2.5.0/gems/public_suffix-4.0.6/test/benchmarks/bm_names.rb +91 -0
  96. data/vendor/bundle/jruby/2.5.0/gems/public_suffix-4.0.6/test/benchmarks/bm_select.rb +26 -0
  97. data/vendor/bundle/jruby/2.5.0/gems/public_suffix-4.0.6/test/benchmarks/bm_select_incremental.rb +25 -0
  98. data/vendor/bundle/jruby/2.5.0/gems/public_suffix-4.0.6/test/benchmarks/bm_valid.rb +101 -0
  99. data/vendor/bundle/jruby/2.5.0/gems/public_suffix-4.0.6/test/profilers/domain_profiler.rb +12 -0
  100. data/vendor/bundle/jruby/2.5.0/gems/public_suffix-4.0.6/test/profilers/find_profiler.rb +12 -0
  101. data/vendor/bundle/jruby/2.5.0/gems/public_suffix-4.0.6/test/profilers/find_profiler_jp.rb +12 -0
  102. data/vendor/bundle/jruby/2.5.0/gems/public_suffix-4.0.6/test/profilers/initialization_profiler.rb +11 -0
  103. data/vendor/bundle/jruby/2.5.0/gems/public_suffix-4.0.6/test/profilers/list_profsize.rb +11 -0
  104. data/vendor/bundle/jruby/2.5.0/gems/public_suffix-4.0.6/test/profilers/object_binsize.rb +57 -0
  105. data/vendor/bundle/jruby/2.5.0/gems/public_suffix-4.0.6/test/psl_test.rb +52 -0
  106. data/vendor/bundle/jruby/2.5.0/gems/public_suffix-4.0.6/test/test_helper.rb +18 -0
  107. data/vendor/bundle/jruby/2.5.0/gems/public_suffix-4.0.6/test/tests.txt +98 -0
  108. data/vendor/bundle/jruby/2.5.0/gems/public_suffix-4.0.6/test/unit/domain_test.rb +106 -0
  109. data/vendor/bundle/jruby/2.5.0/gems/public_suffix-4.0.6/test/unit/errors_test.rb +25 -0
  110. data/vendor/bundle/jruby/2.5.0/gems/public_suffix-4.0.6/test/unit/list_test.rb +241 -0
  111. data/vendor/bundle/jruby/2.5.0/gems/public_suffix-4.0.6/test/unit/public_suffix_test.rb +188 -0
  112. data/vendor/bundle/jruby/2.5.0/gems/public_suffix-4.0.6/test/unit/rule_test.rb +222 -0
  113. data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/LICENSE.txt +22 -0
  114. data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/NEWS.md +178 -0
  115. data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/README.md +48 -0
  116. data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/doc/rexml/context.rdoc +143 -0
  117. data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/doc/rexml/tasks/rdoc/child.rdoc +87 -0
  118. data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/doc/rexml/tasks/rdoc/document.rdoc +276 -0
  119. data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/doc/rexml/tasks/rdoc/element.rdoc +602 -0
  120. data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/doc/rexml/tasks/rdoc/node.rdoc +97 -0
  121. data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/doc/rexml/tasks/rdoc/parent.rdoc +267 -0
  122. data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/doc/rexml/tasks/tocs/child_toc.rdoc +12 -0
  123. data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/doc/rexml/tasks/tocs/document_toc.rdoc +30 -0
  124. data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/doc/rexml/tasks/tocs/element_toc.rdoc +55 -0
  125. data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/doc/rexml/tasks/tocs/master_toc.rdoc +135 -0
  126. data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/doc/rexml/tasks/tocs/node_toc.rdoc +16 -0
  127. data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/doc/rexml/tasks/tocs/parent_toc.rdoc +25 -0
  128. data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/lib/rexml.rb +3 -0
  129. data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/lib/rexml/attlistdecl.rb +63 -0
  130. data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/lib/rexml/attribute.rb +205 -0
  131. data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/lib/rexml/cdata.rb +68 -0
  132. data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/lib/rexml/child.rb +97 -0
  133. data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/lib/rexml/comment.rb +80 -0
  134. data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/lib/rexml/doctype.rb +311 -0
  135. data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/lib/rexml/document.rb +451 -0
  136. data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/lib/rexml/dtd/attlistdecl.rb +11 -0
  137. data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/lib/rexml/dtd/dtd.rb +47 -0
  138. data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/lib/rexml/dtd/elementdecl.rb +18 -0
  139. data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/lib/rexml/dtd/entitydecl.rb +57 -0
  140. data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/lib/rexml/dtd/notationdecl.rb +40 -0
  141. data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/lib/rexml/element.rb +2599 -0
  142. data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/lib/rexml/encoding.rb +51 -0
  143. data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/lib/rexml/entity.rb +171 -0
  144. data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/lib/rexml/formatters/default.rb +116 -0
  145. data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/lib/rexml/formatters/pretty.rb +142 -0
  146. data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/lib/rexml/formatters/transitive.rb +58 -0
  147. data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/lib/rexml/functions.rb +447 -0
  148. data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/lib/rexml/instruction.rb +79 -0
  149. data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/lib/rexml/light/node.rb +188 -0
  150. data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/lib/rexml/namespace.rb +59 -0
  151. data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/lib/rexml/node.rb +76 -0
  152. data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/lib/rexml/output.rb +30 -0
  153. data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/lib/rexml/parent.rb +166 -0
  154. data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/lib/rexml/parseexception.rb +52 -0
  155. data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/lib/rexml/parsers/baseparser.rb +694 -0
  156. data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/lib/rexml/parsers/lightparser.rb +59 -0
  157. data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/lib/rexml/parsers/pullparser.rb +197 -0
  158. data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/lib/rexml/parsers/sax2parser.rb +273 -0
  159. data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/lib/rexml/parsers/streamparser.rb +61 -0
  160. data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/lib/rexml/parsers/treeparser.rb +101 -0
  161. data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/lib/rexml/parsers/ultralightparser.rb +57 -0
  162. data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/lib/rexml/parsers/xpathparser.rb +689 -0
  163. data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/lib/rexml/quickpath.rb +266 -0
  164. data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/lib/rexml/rexml.rb +37 -0
  165. data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/lib/rexml/sax2listener.rb +98 -0
  166. data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/lib/rexml/security.rb +28 -0
  167. data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/lib/rexml/source.rb +298 -0
  168. data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/lib/rexml/streamlistener.rb +93 -0
  169. data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/lib/rexml/text.rb +424 -0
  170. data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/lib/rexml/undefinednamespaceexception.rb +9 -0
  171. data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/lib/rexml/validation/relaxng.rb +539 -0
  172. data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/lib/rexml/validation/validation.rb +144 -0
  173. data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/lib/rexml/validation/validationexception.rb +10 -0
  174. data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/lib/rexml/xmldecl.rb +130 -0
  175. data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/lib/rexml/xmltokens.rb +85 -0
  176. data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/lib/rexml/xpath.rb +81 -0
  177. data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/lib/rexml/xpath_parser.rb +974 -0
  178. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/CHANGELOG.md +1894 -0
  179. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/Gemfile +9 -0
  180. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/LICENSE +20 -0
  181. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/README.md +1176 -0
  182. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/Rakefile +38 -0
  183. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock.rb +59 -0
  184. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock/api.rb +109 -0
  185. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock/assertion_failure.rb +11 -0
  186. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock/callback_registry.rb +35 -0
  187. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock/config.rb +18 -0
  188. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock/cucumber.rb +10 -0
  189. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock/deprecation.rb +9 -0
  190. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock/errors.rb +17 -0
  191. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock/http_lib_adapters/async_http_client_adapter.rb +216 -0
  192. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock/http_lib_adapters/curb_adapter.rb +351 -0
  193. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock/http_lib_adapters/em_http_request_adapter.rb +231 -0
  194. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock/http_lib_adapters/excon_adapter.rb +165 -0
  195. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock/http_lib_adapters/http_lib_adapter.rb +7 -0
  196. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock/http_lib_adapters/http_lib_adapter_registry.rb +19 -0
  197. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock/http_lib_adapters/http_rb/client.rb +17 -0
  198. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock/http_lib_adapters/http_rb/request.rb +16 -0
  199. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock/http_lib_adapters/http_rb/response.rb +64 -0
  200. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock/http_lib_adapters/http_rb/streamer.rb +29 -0
  201. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock/http_lib_adapters/http_rb/webmock.rb +68 -0
  202. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock/http_lib_adapters/http_rb_adapter.rb +37 -0
  203. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock/http_lib_adapters/httpclient_adapter.rb +259 -0
  204. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock/http_lib_adapters/manticore_adapter.rb +145 -0
  205. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock/http_lib_adapters/net_http.rb +385 -0
  206. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock/http_lib_adapters/net_http_response.rb +34 -0
  207. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock/http_lib_adapters/patron_adapter.rb +130 -0
  208. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock/http_lib_adapters/typhoeus_hydra_adapter.rb +174 -0
  209. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock/matchers/any_arg_matcher.rb +13 -0
  210. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock/matchers/hash_argument_matcher.rb +21 -0
  211. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock/matchers/hash_excluding_matcher.rb +15 -0
  212. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock/matchers/hash_including_matcher.rb +17 -0
  213. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock/minitest.rb +41 -0
  214. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock/rack_response.rb +69 -0
  215. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock/request_body_diff.rb +64 -0
  216. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock/request_execution_verifier.rb +77 -0
  217. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock/request_pattern.rb +405 -0
  218. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock/request_registry.rb +35 -0
  219. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock/request_signature.rb +54 -0
  220. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock/request_signature_snippet.rb +61 -0
  221. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock/request_stub.rb +100 -0
  222. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock/response.rb +159 -0
  223. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock/responses_sequence.rb +40 -0
  224. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock/rspec.rb +42 -0
  225. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock/rspec/matchers.rb +27 -0
  226. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock/rspec/matchers/request_pattern_matcher.rb +78 -0
  227. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock/rspec/matchers/webmock_matcher.rb +67 -0
  228. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock/stub_registry.rb +82 -0
  229. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock/stub_request_snippet.rb +38 -0
  230. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock/test_unit.rb +20 -0
  231. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock/util/hash_counter.rb +39 -0
  232. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock/util/hash_keys_stringifier.rb +25 -0
  233. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock/util/hash_validator.rb +17 -0
  234. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock/util/headers.rb +64 -0
  235. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock/util/json.rb +67 -0
  236. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock/util/query_mapper.rb +281 -0
  237. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock/util/uri.rb +111 -0
  238. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock/util/values_stringifier.rb +20 -0
  239. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock/util/version_checker.rb +111 -0
  240. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock/version.rb +3 -0
  241. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock/webmock.rb +163 -0
  242. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/minitest/test_helper.rb +34 -0
  243. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/minitest/test_webmock.rb +9 -0
  244. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/minitest/webmock_spec.rb +60 -0
  245. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/acceptance/async_http_client/async_http_client_spec.rb +375 -0
  246. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/acceptance/async_http_client/async_http_client_spec_helper.rb +73 -0
  247. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/acceptance/curb/curb_spec.rb +499 -0
  248. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/acceptance/curb/curb_spec_helper.rb +147 -0
  249. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/acceptance/em_http_request/em_http_request_spec.rb +462 -0
  250. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/acceptance/em_http_request/em_http_request_spec_helper.rb +77 -0
  251. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/acceptance/excon/excon_spec.rb +77 -0
  252. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/acceptance/excon/excon_spec_helper.rb +52 -0
  253. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/acceptance/http_rb/http_rb_spec.rb +93 -0
  254. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/acceptance/http_rb/http_rb_spec_helper.rb +54 -0
  255. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/acceptance/httpclient/httpclient_spec.rb +217 -0
  256. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/acceptance/httpclient/httpclient_spec_helper.rb +57 -0
  257. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/acceptance/manticore/manticore_spec.rb +107 -0
  258. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/acceptance/manticore/manticore_spec_helper.rb +35 -0
  259. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/acceptance/net_http/net_http_shared.rb +153 -0
  260. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/acceptance/net_http/net_http_spec.rb +369 -0
  261. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/acceptance/net_http/net_http_spec_helper.rb +64 -0
  262. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/acceptance/net_http/real_net_http_spec.rb +20 -0
  263. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/acceptance/patron/patron_spec.rb +125 -0
  264. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/acceptance/patron/patron_spec_helper.rb +54 -0
  265. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/acceptance/shared/allowing_and_disabling_net_connect.rb +313 -0
  266. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/acceptance/shared/callbacks.rb +148 -0
  267. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/acceptance/shared/complex_cross_concern_behaviors.rb +36 -0
  268. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/acceptance/shared/enabling_and_disabling_webmock.rb +95 -0
  269. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/acceptance/shared/precedence_of_stubs.rb +15 -0
  270. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/acceptance/shared/request_expectations.rb +930 -0
  271. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/acceptance/shared/returning_declared_responses.rb +409 -0
  272. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/acceptance/shared/stubbing_requests.rb +678 -0
  273. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/acceptance/typhoeus/typhoeus_hydra_spec.rb +135 -0
  274. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/acceptance/typhoeus/typhoeus_hydra_spec_helper.rb +60 -0
  275. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/acceptance/webmock_shared.rb +41 -0
  276. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/fixtures/test.txt +1 -0
  277. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/quality_spec.rb +84 -0
  278. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/spec_helper.rb +48 -0
  279. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/support/example_curl_output.txt +22 -0
  280. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/support/failures.rb +9 -0
  281. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/support/my_rack_app.rb +53 -0
  282. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/support/network_connection.rb +19 -0
  283. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/support/webmock_server.rb +70 -0
  284. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/unit/api_spec.rb +175 -0
  285. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/unit/errors_spec.rb +129 -0
  286. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/unit/http_lib_adapters/http_lib_adapter_registry_spec.rb +17 -0
  287. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/unit/http_lib_adapters/http_lib_adapter_spec.rb +12 -0
  288. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/unit/matchers/hash_excluding_matcher_spec.rb +61 -0
  289. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/unit/matchers/hash_including_matcher_spec.rb +87 -0
  290. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/unit/rack_response_spec.rb +112 -0
  291. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/unit/request_body_diff_spec.rb +90 -0
  292. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/unit/request_execution_verifier_spec.rb +208 -0
  293. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/unit/request_pattern_spec.rb +736 -0
  294. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/unit/request_registry_spec.rb +95 -0
  295. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/unit/request_signature_snippet_spec.rb +89 -0
  296. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/unit/request_signature_spec.rb +155 -0
  297. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/unit/request_stub_spec.rb +199 -0
  298. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/unit/response_spec.rb +286 -0
  299. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/unit/stub_registry_spec.rb +103 -0
  300. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/unit/stub_request_snippet_spec.rb +115 -0
  301. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/unit/util/hash_counter_spec.rb +39 -0
  302. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/unit/util/hash_keys_stringifier_spec.rb +27 -0
  303. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/unit/util/headers_spec.rb +28 -0
  304. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/unit/util/json_spec.rb +33 -0
  305. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/unit/util/query_mapper_spec.rb +157 -0
  306. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/unit/util/uri_spec.rb +371 -0
  307. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/unit/util/version_checker_spec.rb +65 -0
  308. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/unit/webmock_spec.rb +60 -0
  309. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/test/http_request.rb +24 -0
  310. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/test/shared_test.rb +108 -0
  311. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/test/test_helper.rb +23 -0
  312. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/test/test_webmock.rb +12 -0
  313. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/webmock.gemspec +54 -0
  314. data/vendor/bundle/jruby/2.5.0/specifications/addressable-2.7.0.gemspec +39 -0
  315. data/vendor/bundle/jruby/2.5.0/specifications/crack-0.4.5.gemspec +32 -0
  316. data/vendor/bundle/jruby/2.5.0/specifications/hashdiff-1.0.1.gemspec +46 -0
  317. data/vendor/bundle/jruby/2.5.0/specifications/public_suffix-4.0.6.gemspec +24 -0
  318. data/vendor/bundle/jruby/2.5.0/specifications/rexml-3.2.5.gemspec +42 -0
  319. data/vendor/bundle/jruby/2.5.0/specifications/webmock-3.13.0.gemspec +85 -0
  320. metadata +309 -2
@@ -0,0 +1,1045 @@
1
+ # frozen_string_literal: true
2
+
3
+ # encoding:utf-8
4
+ #--
5
+ # Copyright (C) Bob Aman
6
+ #
7
+ # Licensed under the Apache License, Version 2.0 (the "License");
8
+ # you may not use this file except in compliance with the License.
9
+ # You may obtain a copy of the License at
10
+ #
11
+ # http://www.apache.org/licenses/LICENSE-2.0
12
+ #
13
+ # Unless required by applicable law or agreed to in writing, software
14
+ # distributed under the License is distributed on an "AS IS" BASIS,
15
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
+ # See the License for the specific language governing permissions and
17
+ # limitations under the License.
18
+ #++
19
+
20
+
21
+ require "addressable/version"
22
+ require "addressable/uri"
23
+
24
+ module Addressable
25
+ ##
26
+ # This is an implementation of a URI template based on
27
+ # RFC 6570 (http://tools.ietf.org/html/rfc6570).
28
+ class Template
29
+ # Constants used throughout the template code.
30
+ anything =
31
+ Addressable::URI::CharacterClasses::RESERVED +
32
+ Addressable::URI::CharacterClasses::UNRESERVED
33
+
34
+
35
+ variable_char_class =
36
+ Addressable::URI::CharacterClasses::ALPHA +
37
+ Addressable::URI::CharacterClasses::DIGIT + '_'
38
+
39
+ var_char =
40
+ "(?:(?:[#{variable_char_class}]|%[a-fA-F0-9][a-fA-F0-9])+)"
41
+ RESERVED =
42
+ "(?:[#{anything}]|%[a-fA-F0-9][a-fA-F0-9])"
43
+ UNRESERVED =
44
+ "(?:[#{
45
+ Addressable::URI::CharacterClasses::UNRESERVED
46
+ }]|%[a-fA-F0-9][a-fA-F0-9])"
47
+ variable =
48
+ "(?:#{var_char}(?:\\.?#{var_char})*)"
49
+ varspec =
50
+ "(?:(#{variable})(\\*|:\\d+)?)"
51
+ VARNAME =
52
+ /^#{variable}$/
53
+ VARSPEC =
54
+ /^#{varspec}$/
55
+ VARIABLE_LIST =
56
+ /^#{varspec}(?:,#{varspec})*$/
57
+ operator =
58
+ "+#./;?&=,!@|"
59
+ EXPRESSION =
60
+ /\{([#{operator}])?(#{varspec}(?:,#{varspec})*)\}/
61
+
62
+
63
+ LEADERS = {
64
+ '?' => '?',
65
+ '/' => '/',
66
+ '#' => '#',
67
+ '.' => '.',
68
+ ';' => ';',
69
+ '&' => '&'
70
+ }
71
+ JOINERS = {
72
+ '?' => '&',
73
+ '.' => '.',
74
+ ';' => ';',
75
+ '&' => '&',
76
+ '/' => '/'
77
+ }
78
+
79
+ ##
80
+ # Raised if an invalid template value is supplied.
81
+ class InvalidTemplateValueError < StandardError
82
+ end
83
+
84
+ ##
85
+ # Raised if an invalid template operator is used in a pattern.
86
+ class InvalidTemplateOperatorError < StandardError
87
+ end
88
+
89
+ ##
90
+ # Raised if an invalid template operator is used in a pattern.
91
+ class TemplateOperatorAbortedError < StandardError
92
+ end
93
+
94
+ ##
95
+ # This class represents the data that is extracted when a Template
96
+ # is matched against a URI.
97
+ class MatchData
98
+ ##
99
+ # Creates a new MatchData object.
100
+ # MatchData objects should never be instantiated directly.
101
+ #
102
+ # @param [Addressable::URI] uri
103
+ # The URI that the template was matched against.
104
+ def initialize(uri, template, mapping)
105
+ @uri = uri.dup.freeze
106
+ @template = template
107
+ @mapping = mapping.dup.freeze
108
+ end
109
+
110
+ ##
111
+ # @return [Addressable::URI]
112
+ # The URI that the Template was matched against.
113
+ attr_reader :uri
114
+
115
+ ##
116
+ # @return [Addressable::Template]
117
+ # The Template used for the match.
118
+ attr_reader :template
119
+
120
+ ##
121
+ # @return [Hash]
122
+ # The mapping that resulted from the match.
123
+ # Note that this mapping does not include keys or values for
124
+ # variables that appear in the Template, but are not present
125
+ # in the URI.
126
+ attr_reader :mapping
127
+
128
+ ##
129
+ # @return [Array]
130
+ # The list of variables that were present in the Template.
131
+ # Note that this list will include variables which do not appear
132
+ # in the mapping because they were not present in URI.
133
+ def variables
134
+ self.template.variables
135
+ end
136
+ alias_method :keys, :variables
137
+ alias_method :names, :variables
138
+
139
+ ##
140
+ # @return [Array]
141
+ # The list of values that were captured by the Template.
142
+ # Note that this list will include nils for any variables which
143
+ # were in the Template, but did not appear in the URI.
144
+ def values
145
+ @values ||= self.variables.inject([]) do |accu, key|
146
+ accu << self.mapping[key]
147
+ accu
148
+ end
149
+ end
150
+ alias_method :captures, :values
151
+
152
+ ##
153
+ # Accesses captured values by name or by index.
154
+ #
155
+ # @param [String, Symbol, Fixnum] key
156
+ # Capture index or name. Note that when accessing by with index
157
+ # of 0, the full URI will be returned. The intention is to mimic
158
+ # the ::MatchData#[] behavior.
159
+ #
160
+ # @param [#to_int, nil] len
161
+ # If provided, an array of values will be returend with the given
162
+ # parameter used as length.
163
+ #
164
+ # @return [Array, String, nil]
165
+ # The captured value corresponding to the index or name. If the
166
+ # value was not provided or the key is unknown, nil will be
167
+ # returned.
168
+ #
169
+ # If the second parameter is provided, an array of that length will
170
+ # be returned instead.
171
+ def [](key, len = nil)
172
+ if len
173
+ to_a[key, len]
174
+ elsif String === key or Symbol === key
175
+ mapping[key.to_s]
176
+ else
177
+ to_a[key]
178
+ end
179
+ end
180
+
181
+ ##
182
+ # @return [Array]
183
+ # Array with the matched URI as first element followed by the captured
184
+ # values.
185
+ def to_a
186
+ [to_s, *values]
187
+ end
188
+
189
+ ##
190
+ # @return [String]
191
+ # The matched URI as String.
192
+ def to_s
193
+ uri.to_s
194
+ end
195
+ alias_method :string, :to_s
196
+
197
+ # Returns multiple captured values at once.
198
+ #
199
+ # @param [String, Symbol, Fixnum] *indexes
200
+ # Indices of the captures to be returned
201
+ #
202
+ # @return [Array]
203
+ # Values corresponding to given indices.
204
+ #
205
+ # @see Addressable::Template::MatchData#[]
206
+ def values_at(*indexes)
207
+ indexes.map { |i| self[i] }
208
+ end
209
+
210
+ ##
211
+ # Returns a <tt>String</tt> representation of the MatchData's state.
212
+ #
213
+ # @return [String] The MatchData's state, as a <tt>String</tt>.
214
+ def inspect
215
+ sprintf("#<%s:%#0x RESULT:%s>",
216
+ self.class.to_s, self.object_id, self.mapping.inspect)
217
+ end
218
+
219
+ ##
220
+ # Dummy method for code expecting a ::MatchData instance
221
+ #
222
+ # @return [String] An empty string.
223
+ def pre_match
224
+ ""
225
+ end
226
+ alias_method :post_match, :pre_match
227
+ end
228
+
229
+ ##
230
+ # Creates a new <tt>Addressable::Template</tt> object.
231
+ #
232
+ # @param [#to_str] pattern The URI Template pattern.
233
+ #
234
+ # @return [Addressable::Template] The initialized Template object.
235
+ def initialize(pattern)
236
+ if !pattern.respond_to?(:to_str)
237
+ raise TypeError, "Can't convert #{pattern.class} into String."
238
+ end
239
+ @pattern = pattern.to_str.dup.freeze
240
+ end
241
+
242
+ ##
243
+ # Freeze URI, initializing instance variables.
244
+ #
245
+ # @return [Addressable::URI] The frozen URI object.
246
+ def freeze
247
+ self.variables
248
+ self.variable_defaults
249
+ self.named_captures
250
+ super
251
+ end
252
+
253
+ ##
254
+ # @return [String] The Template object's pattern.
255
+ attr_reader :pattern
256
+
257
+ ##
258
+ # Returns a <tt>String</tt> representation of the Template object's state.
259
+ #
260
+ # @return [String] The Template object's state, as a <tt>String</tt>.
261
+ def inspect
262
+ sprintf("#<%s:%#0x PATTERN:%s>",
263
+ self.class.to_s, self.object_id, self.pattern)
264
+ end
265
+
266
+ ##
267
+ # Returns <code>true</code> if the Template objects are equal. This method
268
+ # does NOT normalize either Template before doing the comparison.
269
+ #
270
+ # @param [Object] template The Template to compare.
271
+ #
272
+ # @return [TrueClass, FalseClass]
273
+ # <code>true</code> if the Templates are equivalent, <code>false</code>
274
+ # otherwise.
275
+ def ==(template)
276
+ return false unless template.kind_of?(Template)
277
+ return self.pattern == template.pattern
278
+ end
279
+
280
+ ##
281
+ # Addressable::Template makes no distinction between `==` and `eql?`.
282
+ #
283
+ # @see #==
284
+ alias_method :eql?, :==
285
+
286
+ ##
287
+ # Extracts a mapping from the URI using a URI Template pattern.
288
+ #
289
+ # @param [Addressable::URI, #to_str] uri
290
+ # The URI to extract from.
291
+ #
292
+ # @param [#restore, #match] processor
293
+ # A template processor object may optionally be supplied.
294
+ #
295
+ # The object should respond to either the <tt>restore</tt> or
296
+ # <tt>match</tt> messages or both. The <tt>restore</tt> method should
297
+ # take two parameters: `[String] name` and `[String] value`.
298
+ # The <tt>restore</tt> method should reverse any transformations that
299
+ # have been performed on the value to ensure a valid URI.
300
+ # The <tt>match</tt> method should take a single
301
+ # parameter: `[String] name`. The <tt>match</tt> method should return
302
+ # a <tt>String</tt> containing a regular expression capture group for
303
+ # matching on that particular variable. The default value is `".*?"`.
304
+ # The <tt>match</tt> method has no effect on multivariate operator
305
+ # expansions.
306
+ #
307
+ # @return [Hash, NilClass]
308
+ # The <tt>Hash</tt> mapping that was extracted from the URI, or
309
+ # <tt>nil</tt> if the URI didn't match the template.
310
+ #
311
+ # @example
312
+ # class ExampleProcessor
313
+ # def self.restore(name, value)
314
+ # return value.gsub(/\+/, " ") if name == "query"
315
+ # return value
316
+ # end
317
+ #
318
+ # def self.match(name)
319
+ # return ".*?" if name == "first"
320
+ # return ".*"
321
+ # end
322
+ # end
323
+ #
324
+ # uri = Addressable::URI.parse(
325
+ # "http://example.com/search/an+example+search+query/"
326
+ # )
327
+ # Addressable::Template.new(
328
+ # "http://example.com/search/{query}/"
329
+ # ).extract(uri, ExampleProcessor)
330
+ # #=> {"query" => "an example search query"}
331
+ #
332
+ # uri = Addressable::URI.parse("http://example.com/a/b/c/")
333
+ # Addressable::Template.new(
334
+ # "http://example.com/{first}/{second}/"
335
+ # ).extract(uri, ExampleProcessor)
336
+ # #=> {"first" => "a", "second" => "b/c"}
337
+ #
338
+ # uri = Addressable::URI.parse("http://example.com/a/b/c/")
339
+ # Addressable::Template.new(
340
+ # "http://example.com/{first}/{-list|/|second}/"
341
+ # ).extract(uri)
342
+ # #=> {"first" => "a", "second" => ["b", "c"]}
343
+ def extract(uri, processor=nil)
344
+ match_data = self.match(uri, processor)
345
+ return (match_data ? match_data.mapping : nil)
346
+ end
347
+
348
+ ##
349
+ # Extracts match data from the URI using a URI Template pattern.
350
+ #
351
+ # @param [Addressable::URI, #to_str] uri
352
+ # The URI to extract from.
353
+ #
354
+ # @param [#restore, #match] processor
355
+ # A template processor object may optionally be supplied.
356
+ #
357
+ # The object should respond to either the <tt>restore</tt> or
358
+ # <tt>match</tt> messages or both. The <tt>restore</tt> method should
359
+ # take two parameters: `[String] name` and `[String] value`.
360
+ # The <tt>restore</tt> method should reverse any transformations that
361
+ # have been performed on the value to ensure a valid URI.
362
+ # The <tt>match</tt> method should take a single
363
+ # parameter: `[String] name`. The <tt>match</tt> method should return
364
+ # a <tt>String</tt> containing a regular expression capture group for
365
+ # matching on that particular variable. The default value is `".*?"`.
366
+ # The <tt>match</tt> method has no effect on multivariate operator
367
+ # expansions.
368
+ #
369
+ # @return [Hash, NilClass]
370
+ # The <tt>Hash</tt> mapping that was extracted from the URI, or
371
+ # <tt>nil</tt> if the URI didn't match the template.
372
+ #
373
+ # @example
374
+ # class ExampleProcessor
375
+ # def self.restore(name, value)
376
+ # return value.gsub(/\+/, " ") if name == "query"
377
+ # return value
378
+ # end
379
+ #
380
+ # def self.match(name)
381
+ # return ".*?" if name == "first"
382
+ # return ".*"
383
+ # end
384
+ # end
385
+ #
386
+ # uri = Addressable::URI.parse(
387
+ # "http://example.com/search/an+example+search+query/"
388
+ # )
389
+ # match = Addressable::Template.new(
390
+ # "http://example.com/search/{query}/"
391
+ # ).match(uri, ExampleProcessor)
392
+ # match.variables
393
+ # #=> ["query"]
394
+ # match.captures
395
+ # #=> ["an example search query"]
396
+ #
397
+ # uri = Addressable::URI.parse("http://example.com/a/b/c/")
398
+ # match = Addressable::Template.new(
399
+ # "http://example.com/{first}/{+second}/"
400
+ # ).match(uri, ExampleProcessor)
401
+ # match.variables
402
+ # #=> ["first", "second"]
403
+ # match.captures
404
+ # #=> ["a", "b/c"]
405
+ #
406
+ # uri = Addressable::URI.parse("http://example.com/a/b/c/")
407
+ # match = Addressable::Template.new(
408
+ # "http://example.com/{first}{/second*}/"
409
+ # ).match(uri)
410
+ # match.variables
411
+ # #=> ["first", "second"]
412
+ # match.captures
413
+ # #=> ["a", ["b", "c"]]
414
+ def match(uri, processor=nil)
415
+ uri = Addressable::URI.parse(uri)
416
+ mapping = {}
417
+
418
+ # First, we need to process the pattern, and extract the values.
419
+ expansions, expansion_regexp =
420
+ parse_template_pattern(pattern, processor)
421
+
422
+ return nil unless uri.to_str.match(expansion_regexp)
423
+ unparsed_values = uri.to_str.scan(expansion_regexp).flatten
424
+
425
+ if uri.to_str == pattern
426
+ return Addressable::Template::MatchData.new(uri, self, mapping)
427
+ elsif expansions.size > 0
428
+ index = 0
429
+ expansions.each do |expansion|
430
+ _, operator, varlist = *expansion.match(EXPRESSION)
431
+ varlist.split(',').each do |varspec|
432
+ _, name, modifier = *varspec.match(VARSPEC)
433
+ mapping[name] ||= nil
434
+ case operator
435
+ when nil, '+', '#', '/', '.'
436
+ unparsed_value = unparsed_values[index]
437
+ name = varspec[VARSPEC, 1]
438
+ value = unparsed_value
439
+ value = value.split(JOINERS[operator]) if value && modifier == '*'
440
+ when ';', '?', '&'
441
+ if modifier == '*'
442
+ if unparsed_values[index]
443
+ value = unparsed_values[index].split(JOINERS[operator])
444
+ value = value.inject({}) do |acc, v|
445
+ key, val = v.split('=')
446
+ val = "" if val.nil?
447
+ acc[key] = val
448
+ acc
449
+ end
450
+ end
451
+ else
452
+ if (unparsed_values[index])
453
+ name, value = unparsed_values[index].split('=')
454
+ value = "" if value.nil?
455
+ end
456
+ end
457
+ end
458
+ if processor != nil && processor.respond_to?(:restore)
459
+ value = processor.restore(name, value)
460
+ end
461
+ if processor == nil
462
+ if value.is_a?(Hash)
463
+ value = value.inject({}){|acc, (k, v)|
464
+ acc[Addressable::URI.unencode_component(k)] =
465
+ Addressable::URI.unencode_component(v)
466
+ acc
467
+ }
468
+ elsif value.is_a?(Array)
469
+ value = value.map{|v| Addressable::URI.unencode_component(v) }
470
+ else
471
+ value = Addressable::URI.unencode_component(value)
472
+ end
473
+ end
474
+ if !mapping.has_key?(name) || mapping[name].nil?
475
+ # Doesn't exist, set to value (even if value is nil)
476
+ mapping[name] = value
477
+ end
478
+ index = index + 1
479
+ end
480
+ end
481
+ return Addressable::Template::MatchData.new(uri, self, mapping)
482
+ else
483
+ return nil
484
+ end
485
+ end
486
+
487
+ ##
488
+ # Expands a URI template into another URI template.
489
+ #
490
+ # @param [Hash] mapping The mapping that corresponds to the pattern.
491
+ # @param [#validate, #transform] processor
492
+ # An optional processor object may be supplied.
493
+ # @param [Boolean] normalize_values
494
+ # Optional flag to enable/disable unicode normalization. Default: true
495
+ #
496
+ # The object should respond to either the <tt>validate</tt> or
497
+ # <tt>transform</tt> messages or both. Both the <tt>validate</tt> and
498
+ # <tt>transform</tt> methods should take two parameters: <tt>name</tt> and
499
+ # <tt>value</tt>. The <tt>validate</tt> method should return <tt>true</tt>
500
+ # or <tt>false</tt>; <tt>true</tt> if the value of the variable is valid,
501
+ # <tt>false</tt> otherwise. An <tt>InvalidTemplateValueError</tt>
502
+ # exception will be raised if the value is invalid. The <tt>transform</tt>
503
+ # method should return the transformed variable value as a <tt>String</tt>.
504
+ # If a <tt>transform</tt> method is used, the value will not be percent
505
+ # encoded automatically. Unicode normalization will be performed both
506
+ # before and after sending the value to the transform method.
507
+ #
508
+ # @return [Addressable::Template] The partially expanded URI template.
509
+ #
510
+ # @example
511
+ # Addressable::Template.new(
512
+ # "http://example.com/{one}/{two}/"
513
+ # ).partial_expand({"one" => "1"}).pattern
514
+ # #=> "http://example.com/1/{two}/"
515
+ #
516
+ # Addressable::Template.new(
517
+ # "http://example.com/{?one,two}/"
518
+ # ).partial_expand({"one" => "1"}).pattern
519
+ # #=> "http://example.com/?one=1{&two}/"
520
+ #
521
+ # Addressable::Template.new(
522
+ # "http://example.com/{?one,two,three}/"
523
+ # ).partial_expand({"one" => "1", "three" => 3}).pattern
524
+ # #=> "http://example.com/?one=1{&two}&three=3"
525
+ def partial_expand(mapping, processor=nil, normalize_values=true)
526
+ result = self.pattern.dup
527
+ mapping = normalize_keys(mapping)
528
+ result.gsub!( EXPRESSION ) do |capture|
529
+ transform_partial_capture(mapping, capture, processor, normalize_values)
530
+ end
531
+ return Addressable::Template.new(result)
532
+ end
533
+
534
+ ##
535
+ # Expands a URI template into a full URI.
536
+ #
537
+ # @param [Hash] mapping The mapping that corresponds to the pattern.
538
+ # @param [#validate, #transform] processor
539
+ # An optional processor object may be supplied.
540
+ # @param [Boolean] normalize_values
541
+ # Optional flag to enable/disable unicode normalization. Default: true
542
+ #
543
+ # The object should respond to either the <tt>validate</tt> or
544
+ # <tt>transform</tt> messages or both. Both the <tt>validate</tt> and
545
+ # <tt>transform</tt> methods should take two parameters: <tt>name</tt> and
546
+ # <tt>value</tt>. The <tt>validate</tt> method should return <tt>true</tt>
547
+ # or <tt>false</tt>; <tt>true</tt> if the value of the variable is valid,
548
+ # <tt>false</tt> otherwise. An <tt>InvalidTemplateValueError</tt>
549
+ # exception will be raised if the value is invalid. The <tt>transform</tt>
550
+ # method should return the transformed variable value as a <tt>String</tt>.
551
+ # If a <tt>transform</tt> method is used, the value will not be percent
552
+ # encoded automatically. Unicode normalization will be performed both
553
+ # before and after sending the value to the transform method.
554
+ #
555
+ # @return [Addressable::URI] The expanded URI template.
556
+ #
557
+ # @example
558
+ # class ExampleProcessor
559
+ # def self.validate(name, value)
560
+ # return !!(value =~ /^[\w ]+$/) if name == "query"
561
+ # return true
562
+ # end
563
+ #
564
+ # def self.transform(name, value)
565
+ # return value.gsub(/ /, "+") if name == "query"
566
+ # return value
567
+ # end
568
+ # end
569
+ #
570
+ # Addressable::Template.new(
571
+ # "http://example.com/search/{query}/"
572
+ # ).expand(
573
+ # {"query" => "an example search query"},
574
+ # ExampleProcessor
575
+ # ).to_str
576
+ # #=> "http://example.com/search/an+example+search+query/"
577
+ #
578
+ # Addressable::Template.new(
579
+ # "http://example.com/search/{query}/"
580
+ # ).expand(
581
+ # {"query" => "an example search query"}
582
+ # ).to_str
583
+ # #=> "http://example.com/search/an%20example%20search%20query/"
584
+ #
585
+ # Addressable::Template.new(
586
+ # "http://example.com/search/{query}/"
587
+ # ).expand(
588
+ # {"query" => "bogus!"},
589
+ # ExampleProcessor
590
+ # ).to_str
591
+ # #=> Addressable::Template::InvalidTemplateValueError
592
+ def expand(mapping, processor=nil, normalize_values=true)
593
+ result = self.pattern.dup
594
+ mapping = normalize_keys(mapping)
595
+ result.gsub!( EXPRESSION ) do |capture|
596
+ transform_capture(mapping, capture, processor, normalize_values)
597
+ end
598
+ return Addressable::URI.parse(result)
599
+ end
600
+
601
+ ##
602
+ # Returns an Array of variables used within the template pattern.
603
+ # The variables are listed in the Array in the order they appear within
604
+ # the pattern. Multiple occurrences of a variable within a pattern are
605
+ # not represented in this Array.
606
+ #
607
+ # @return [Array] The variables present in the template's pattern.
608
+ def variables
609
+ @variables ||= ordered_variable_defaults.map { |var, val| var }.uniq
610
+ end
611
+ alias_method :keys, :variables
612
+ alias_method :names, :variables
613
+
614
+ ##
615
+ # Returns a mapping of variables to their default values specified
616
+ # in the template. Variables without defaults are not returned.
617
+ #
618
+ # @return [Hash] Mapping of template variables to their defaults
619
+ def variable_defaults
620
+ @variable_defaults ||=
621
+ Hash[*ordered_variable_defaults.reject { |k, v| v.nil? }.flatten]
622
+ end
623
+
624
+ ##
625
+ # Coerces a template into a `Regexp` object. This regular expression will
626
+ # behave very similarly to the actual template, and should match the same
627
+ # URI values, but it cannot fully handle, for example, values that would
628
+ # extract to an `Array`.
629
+ #
630
+ # @return [Regexp] A regular expression which should match the template.
631
+ def to_regexp
632
+ _, source = parse_template_pattern(pattern)
633
+ Regexp.new(source)
634
+ end
635
+
636
+ ##
637
+ # Returns the source of the coerced `Regexp`.
638
+ #
639
+ # @return [String] The source of the `Regexp` given by {#to_regexp}.
640
+ #
641
+ # @api private
642
+ def source
643
+ self.to_regexp.source
644
+ end
645
+
646
+ ##
647
+ # Returns the named captures of the coerced `Regexp`.
648
+ #
649
+ # @return [Hash] The named captures of the `Regexp` given by {#to_regexp}.
650
+ #
651
+ # @api private
652
+ def named_captures
653
+ self.to_regexp.named_captures
654
+ end
655
+
656
+ ##
657
+ # Generates a route result for a given set of parameters.
658
+ # Should only be used by rack-mount.
659
+ #
660
+ # @param params [Hash] The set of parameters used to expand the template.
661
+ # @param recall [Hash] Default parameters used to expand the template.
662
+ # @param options [Hash] Either a `:processor` or a `:parameterize` block.
663
+ #
664
+ # @api private
665
+ def generate(params={}, recall={}, options={})
666
+ merged = recall.merge(params)
667
+ if options[:processor]
668
+ processor = options[:processor]
669
+ elsif options[:parameterize]
670
+ # TODO: This is sending me into fits trying to shoe-horn this into
671
+ # the existing API. I think I've got this backwards and processors
672
+ # should be a set of 4 optional blocks named :validate, :transform,
673
+ # :match, and :restore. Having to use a singleton here is a huge
674
+ # code smell.
675
+ processor = Object.new
676
+ class <<processor
677
+ attr_accessor :block
678
+ def transform(name, value)
679
+ block.call(name, value)
680
+ end
681
+ end
682
+ processor.block = options[:parameterize]
683
+ else
684
+ processor = nil
685
+ end
686
+ result = self.expand(merged, processor)
687
+ result.to_s if result
688
+ end
689
+
690
+ private
691
+ def ordered_variable_defaults
692
+ @ordered_variable_defaults ||= begin
693
+ expansions, _ = parse_template_pattern(pattern)
694
+ expansions.map do |capture|
695
+ _, _, varlist = *capture.match(EXPRESSION)
696
+ varlist.split(',').map do |varspec|
697
+ varspec[VARSPEC, 1]
698
+ end
699
+ end.flatten
700
+ end
701
+ end
702
+
703
+
704
+ ##
705
+ # Loops through each capture and expands any values available in mapping
706
+ #
707
+ # @param [Hash] mapping
708
+ # Set of keys to expand
709
+ # @param [String] capture
710
+ # The expression to expand
711
+ # @param [#validate, #transform] processor
712
+ # An optional processor object may be supplied.
713
+ # @param [Boolean] normalize_values
714
+ # Optional flag to enable/disable unicode normalization. Default: true
715
+ #
716
+ # The object should respond to either the <tt>validate</tt> or
717
+ # <tt>transform</tt> messages or both. Both the <tt>validate</tt> and
718
+ # <tt>transform</tt> methods should take two parameters: <tt>name</tt> and
719
+ # <tt>value</tt>. The <tt>validate</tt> method should return <tt>true</tt>
720
+ # or <tt>false</tt>; <tt>true</tt> if the value of the variable is valid,
721
+ # <tt>false</tt> otherwise. An <tt>InvalidTemplateValueError</tt> exception
722
+ # will be raised if the value is invalid. The <tt>transform</tt> method
723
+ # should return the transformed variable value as a <tt>String</tt>. If a
724
+ # <tt>transform</tt> method is used, the value will not be percent encoded
725
+ # automatically. Unicode normalization will be performed both before and
726
+ # after sending the value to the transform method.
727
+ #
728
+ # @return [String] The expanded expression
729
+ def transform_partial_capture(mapping, capture, processor = nil,
730
+ normalize_values = true)
731
+ _, operator, varlist = *capture.match(EXPRESSION)
732
+
733
+ vars = varlist.split(",")
734
+
735
+ if operator == "?"
736
+ # partial expansion of form style query variables sometimes requires a
737
+ # slight reordering of the variables to produce a valid url.
738
+ first_to_expand = vars.find { |varspec|
739
+ _, name, _ = *varspec.match(VARSPEC)
740
+ mapping.key?(name) && !mapping[name].nil?
741
+ }
742
+
743
+ vars = [first_to_expand] + vars.reject {|varspec| varspec == first_to_expand} if first_to_expand
744
+ end
745
+
746
+ vars.
747
+ inject("".dup) do |acc, varspec|
748
+ _, name, _ = *varspec.match(VARSPEC)
749
+ next_val = if mapping.key? name
750
+ transform_capture(mapping, "{#{operator}#{varspec}}",
751
+ processor, normalize_values)
752
+ else
753
+ "{#{operator}#{varspec}}"
754
+ end
755
+ # If we've already expanded at least one '?' operator with non-empty
756
+ # value, change to '&'
757
+ operator = "&" if (operator == "?") && (next_val != "")
758
+ acc << next_val
759
+ end
760
+ end
761
+
762
+ ##
763
+ # Transforms a mapped value so that values can be substituted into the
764
+ # template.
765
+ #
766
+ # @param [Hash] mapping The mapping to replace captures
767
+ # @param [String] capture
768
+ # The expression to replace
769
+ # @param [#validate, #transform] processor
770
+ # An optional processor object may be supplied.
771
+ # @param [Boolean] normalize_values
772
+ # Optional flag to enable/disable unicode normalization. Default: true
773
+ #
774
+ #
775
+ # The object should respond to either the <tt>validate</tt> or
776
+ # <tt>transform</tt> messages or both. Both the <tt>validate</tt> and
777
+ # <tt>transform</tt> methods should take two parameters: <tt>name</tt> and
778
+ # <tt>value</tt>. The <tt>validate</tt> method should return <tt>true</tt>
779
+ # or <tt>false</tt>; <tt>true</tt> if the value of the variable is valid,
780
+ # <tt>false</tt> otherwise. An <tt>InvalidTemplateValueError</tt> exception
781
+ # will be raised if the value is invalid. The <tt>transform</tt> method
782
+ # should return the transformed variable value as a <tt>String</tt>. If a
783
+ # <tt>transform</tt> method is used, the value will not be percent encoded
784
+ # automatically. Unicode normalization will be performed both before and
785
+ # after sending the value to the transform method.
786
+ #
787
+ # @return [String] The expanded expression
788
+ def transform_capture(mapping, capture, processor=nil,
789
+ normalize_values=true)
790
+ _, operator, varlist = *capture.match(EXPRESSION)
791
+ return_value = varlist.split(',').inject([]) do |acc, varspec|
792
+ _, name, modifier = *varspec.match(VARSPEC)
793
+ value = mapping[name]
794
+ unless value == nil || value == {}
795
+ allow_reserved = %w(+ #).include?(operator)
796
+ # Common primitives where the .to_s output is well-defined
797
+ if Numeric === value || Symbol === value ||
798
+ value == true || value == false
799
+ value = value.to_s
800
+ end
801
+ length = modifier.gsub(':', '').to_i if modifier =~ /^:\d+/
802
+
803
+ unless (Hash === value) ||
804
+ value.respond_to?(:to_ary) || value.respond_to?(:to_str)
805
+ raise TypeError,
806
+ "Can't convert #{value.class} into String or Array."
807
+ end
808
+
809
+ value = normalize_value(value) if normalize_values
810
+
811
+ if processor == nil || !processor.respond_to?(:transform)
812
+ # Handle percent escaping
813
+ if allow_reserved
814
+ encode_map =
815
+ Addressable::URI::CharacterClasses::RESERVED +
816
+ Addressable::URI::CharacterClasses::UNRESERVED
817
+ else
818
+ encode_map = Addressable::URI::CharacterClasses::UNRESERVED
819
+ end
820
+ if value.kind_of?(Array)
821
+ transformed_value = value.map do |val|
822
+ if length
823
+ Addressable::URI.encode_component(val[0...length], encode_map)
824
+ else
825
+ Addressable::URI.encode_component(val, encode_map)
826
+ end
827
+ end
828
+ unless modifier == "*"
829
+ transformed_value = transformed_value.join(',')
830
+ end
831
+ elsif value.kind_of?(Hash)
832
+ transformed_value = value.map do |key, val|
833
+ if modifier == "*"
834
+ "#{
835
+ Addressable::URI.encode_component( key, encode_map)
836
+ }=#{
837
+ Addressable::URI.encode_component( val, encode_map)
838
+ }"
839
+ else
840
+ "#{
841
+ Addressable::URI.encode_component( key, encode_map)
842
+ },#{
843
+ Addressable::URI.encode_component( val, encode_map)
844
+ }"
845
+ end
846
+ end
847
+ unless modifier == "*"
848
+ transformed_value = transformed_value.join(',')
849
+ end
850
+ else
851
+ if length
852
+ transformed_value = Addressable::URI.encode_component(
853
+ value[0...length], encode_map)
854
+ else
855
+ transformed_value = Addressable::URI.encode_component(
856
+ value, encode_map)
857
+ end
858
+ end
859
+ end
860
+
861
+ # Process, if we've got a processor
862
+ if processor != nil
863
+ if processor.respond_to?(:validate)
864
+ if !processor.validate(name, value)
865
+ display_value = value.kind_of?(Array) ? value.inspect : value
866
+ raise InvalidTemplateValueError,
867
+ "#{name}=#{display_value} is an invalid template value."
868
+ end
869
+ end
870
+ if processor.respond_to?(:transform)
871
+ transformed_value = processor.transform(name, value)
872
+ if normalize_values
873
+ transformed_value = normalize_value(transformed_value)
874
+ end
875
+ end
876
+ end
877
+ acc << [name, transformed_value]
878
+ end
879
+ acc
880
+ end
881
+ return "" if return_value.empty?
882
+ join_values(operator, return_value)
883
+ end
884
+
885
+ ##
886
+ # Takes a set of values, and joins them together based on the
887
+ # operator.
888
+ #
889
+ # @param [String, Nil] operator One of the operators from the set
890
+ # (?,&,+,#,;,/,.), or nil if there wasn't one.
891
+ # @param [Array] return_value
892
+ # The set of return values (as [variable_name, value] tuples) that will
893
+ # be joined together.
894
+ #
895
+ # @return [String] The transformed mapped value
896
+ def join_values(operator, return_value)
897
+ leader = LEADERS.fetch(operator, '')
898
+ joiner = JOINERS.fetch(operator, ',')
899
+ case operator
900
+ when '&', '?'
901
+ leader + return_value.map{|k,v|
902
+ if v.is_a?(Array) && v.first =~ /=/
903
+ v.join(joiner)
904
+ elsif v.is_a?(Array)
905
+ v.map{|inner_value| "#{k}=#{inner_value}"}.join(joiner)
906
+ else
907
+ "#{k}=#{v}"
908
+ end
909
+ }.join(joiner)
910
+ when ';'
911
+ return_value.map{|k,v|
912
+ if v.is_a?(Array) && v.first =~ /=/
913
+ ';' + v.join(";")
914
+ elsif v.is_a?(Array)
915
+ ';' + v.map{|inner_value| "#{k}=#{inner_value}"}.join(";")
916
+ else
917
+ v && v != '' ? ";#{k}=#{v}" : ";#{k}"
918
+ end
919
+ }.join
920
+ else
921
+ leader + return_value.map{|k,v| v}.join(joiner)
922
+ end
923
+ end
924
+
925
+ ##
926
+ # Takes a set of values, and joins them together based on the
927
+ # operator.
928
+ #
929
+ # @param [Hash, Array, String] value
930
+ # Normalizes keys and values with IDNA#unicode_normalize_kc
931
+ #
932
+ # @return [Hash, Array, String] The normalized values
933
+ def normalize_value(value)
934
+ unless value.is_a?(Hash)
935
+ value = value.respond_to?(:to_ary) ? value.to_ary : value.to_str
936
+ end
937
+
938
+ # Handle unicode normalization
939
+ if value.kind_of?(Array)
940
+ value.map! { |val| Addressable::IDNA.unicode_normalize_kc(val) }
941
+ elsif value.kind_of?(Hash)
942
+ value = value.inject({}) { |acc, (k, v)|
943
+ acc[Addressable::IDNA.unicode_normalize_kc(k)] =
944
+ Addressable::IDNA.unicode_normalize_kc(v)
945
+ acc
946
+ }
947
+ else
948
+ value = Addressable::IDNA.unicode_normalize_kc(value)
949
+ end
950
+ value
951
+ end
952
+
953
+ ##
954
+ # Generates a hash with string keys
955
+ #
956
+ # @param [Hash] mapping A mapping hash to normalize
957
+ #
958
+ # @return [Hash]
959
+ # A hash with stringified keys
960
+ def normalize_keys(mapping)
961
+ return mapping.inject({}) do |accu, pair|
962
+ name, value = pair
963
+ if Symbol === name
964
+ name = name.to_s
965
+ elsif name.respond_to?(:to_str)
966
+ name = name.to_str
967
+ else
968
+ raise TypeError,
969
+ "Can't convert #{name.class} into String."
970
+ end
971
+ accu[name] = value
972
+ accu
973
+ end
974
+ end
975
+
976
+ ##
977
+ # Generates the <tt>Regexp</tt> that parses a template pattern.
978
+ #
979
+ # @param [String] pattern The URI template pattern.
980
+ # @param [#match] processor The template processor to use.
981
+ #
982
+ # @return [Regexp]
983
+ # A regular expression which may be used to parse a template pattern.
984
+ def parse_template_pattern(pattern, processor=nil)
985
+ # Escape the pattern. The two gsubs restore the escaped curly braces
986
+ # back to their original form. Basically, escape everything that isn't
987
+ # within an expansion.
988
+ escaped_pattern = Regexp.escape(
989
+ pattern
990
+ ).gsub(/\\\{(.*?)\\\}/) do |escaped|
991
+ escaped.gsub(/\\(.)/, "\\1")
992
+ end
993
+
994
+ expansions = []
995
+
996
+ # Create a regular expression that captures the values of the
997
+ # variables in the URI.
998
+ regexp_string = escaped_pattern.gsub( EXPRESSION ) do |expansion|
999
+
1000
+ expansions << expansion
1001
+ _, operator, varlist = *expansion.match(EXPRESSION)
1002
+ leader = Regexp.escape(LEADERS.fetch(operator, ''))
1003
+ joiner = Regexp.escape(JOINERS.fetch(operator, ','))
1004
+ combined = varlist.split(',').map do |varspec|
1005
+ _, name, modifier = *varspec.match(VARSPEC)
1006
+
1007
+ result = processor && processor.respond_to?(:match) ? processor.match(name) : nil
1008
+ if result
1009
+ "(?<#{name}>#{ result })"
1010
+ else
1011
+ group = case operator
1012
+ when '+'
1013
+ "#{ RESERVED }*?"
1014
+ when '#'
1015
+ "#{ RESERVED }*?"
1016
+ when '/'
1017
+ "#{ UNRESERVED }*?"
1018
+ when '.'
1019
+ "#{ UNRESERVED.gsub('\.', '') }*?"
1020
+ when ';'
1021
+ "#{ UNRESERVED }*=?#{ UNRESERVED }*?"
1022
+ when '?'
1023
+ "#{ UNRESERVED }*=#{ UNRESERVED }*?"
1024
+ when '&'
1025
+ "#{ UNRESERVED }*=#{ UNRESERVED }*?"
1026
+ else
1027
+ "#{ UNRESERVED }*?"
1028
+ end
1029
+ if modifier == '*'
1030
+ "(?<#{name}>#{group}(?:#{joiner}?#{group})*)?"
1031
+ else
1032
+ "(?<#{name}>#{group})?"
1033
+ end
1034
+ end
1035
+ end.join("#{joiner}?")
1036
+ "(?:|#{leader}#{combined})"
1037
+ end
1038
+
1039
+ # Ensure that the regular expression matches the whole URI.
1040
+ regexp_string = "^#{regexp_string}$"
1041
+ return expansions, Regexp.new(regexp_string)
1042
+ end
1043
+
1044
+ end
1045
+ end