logstash-output-scalyr 0.1.10.beta → 0.1.11.beta

Sign up to get free protection for your applications and to get access to all the features.
Files changed (317) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +4 -0
  3. data/Gemfile +4 -0
  4. data/README.md +2 -2
  5. data/lib/logstash/outputs/scalyr.rb +94 -73
  6. data/lib/scalyr/common/client.rb +3 -1
  7. data/lib/scalyr/constants.rb +2 -0
  8. data/logstash-output-scalyr.gemspec +1 -1
  9. data/spec/logstash/outputs/scalyr_integration_spec.rb +119 -8
  10. data/spec/logstash/outputs/scalyr_spec.rb +9 -6
  11. data/vendor/bundle/jruby/2.5.0/cache/addressable-2.7.0.gem +0 -0
  12. data/vendor/bundle/jruby/2.5.0/cache/crack-0.4.5.gem +0 -0
  13. data/vendor/bundle/jruby/2.5.0/cache/hashdiff-1.0.1.gem +0 -0
  14. data/vendor/bundle/jruby/2.5.0/cache/public_suffix-4.0.6.gem +0 -0
  15. data/vendor/bundle/jruby/2.5.0/cache/rexml-3.2.5.gem +0 -0
  16. data/vendor/bundle/jruby/2.5.0/cache/webmock-3.13.0.gem +0 -0
  17. data/vendor/bundle/jruby/2.5.0/gems/addressable-2.7.0/CHANGELOG.md +235 -0
  18. data/vendor/bundle/jruby/2.5.0/gems/addressable-2.7.0/Gemfile +32 -0
  19. data/vendor/bundle/jruby/2.5.0/gems/addressable-2.7.0/LICENSE.txt +202 -0
  20. data/vendor/bundle/jruby/2.5.0/gems/addressable-2.7.0/README.md +121 -0
  21. data/vendor/bundle/jruby/2.5.0/gems/addressable-2.7.0/Rakefile +34 -0
  22. data/vendor/bundle/jruby/2.5.0/gems/addressable-2.7.0/data/unicode.data +0 -0
  23. data/vendor/bundle/jruby/2.5.0/gems/addressable-2.7.0/lib/addressable.rb +4 -0
  24. data/vendor/bundle/jruby/2.5.0/gems/addressable-2.7.0/lib/addressable/idna.rb +27 -0
  25. data/vendor/bundle/jruby/2.5.0/gems/addressable-2.7.0/lib/addressable/idna/native.rb +61 -0
  26. data/vendor/bundle/jruby/2.5.0/gems/addressable-2.7.0/lib/addressable/idna/pure.rb +676 -0
  27. data/vendor/bundle/jruby/2.5.0/gems/addressable-2.7.0/lib/addressable/template.rb +1045 -0
  28. data/vendor/bundle/jruby/2.5.0/gems/addressable-2.7.0/lib/addressable/uri.rb +2529 -0
  29. data/vendor/bundle/jruby/2.5.0/gems/addressable-2.7.0/lib/addressable/version.rb +32 -0
  30. data/vendor/bundle/jruby/2.5.0/gems/addressable-2.7.0/spec/addressable/idna_spec.rb +300 -0
  31. data/vendor/bundle/jruby/2.5.0/gems/addressable-2.7.0/spec/addressable/net_http_compat_spec.rb +30 -0
  32. data/vendor/bundle/jruby/2.5.0/gems/addressable-2.7.0/spec/addressable/rack_mount_compat_spec.rb +106 -0
  33. data/vendor/bundle/jruby/2.5.0/gems/addressable-2.7.0/spec/addressable/security_spec.rb +59 -0
  34. data/vendor/bundle/jruby/2.5.0/gems/addressable-2.7.0/spec/addressable/template_spec.rb +1451 -0
  35. data/vendor/bundle/jruby/2.5.0/gems/addressable-2.7.0/spec/addressable/uri_spec.rb +6603 -0
  36. data/vendor/bundle/jruby/2.5.0/gems/addressable-2.7.0/spec/spec_helper.rb +24 -0
  37. data/vendor/bundle/jruby/2.5.0/gems/addressable-2.7.0/tasks/clobber.rake +4 -0
  38. data/vendor/bundle/jruby/2.5.0/gems/addressable-2.7.0/tasks/gem.rake +93 -0
  39. data/vendor/bundle/jruby/2.5.0/gems/addressable-2.7.0/tasks/git.rake +47 -0
  40. data/vendor/bundle/jruby/2.5.0/gems/addressable-2.7.0/tasks/metrics.rake +24 -0
  41. data/vendor/bundle/jruby/2.5.0/gems/addressable-2.7.0/tasks/rspec.rake +23 -0
  42. data/vendor/bundle/jruby/2.5.0/gems/addressable-2.7.0/tasks/yard.rake +29 -0
  43. data/vendor/bundle/jruby/2.5.0/gems/crack-0.4.5/lib/crack.rb +7 -0
  44. data/vendor/bundle/jruby/2.5.0/gems/crack-0.4.5/lib/crack/json.rb +98 -0
  45. data/vendor/bundle/jruby/2.5.0/gems/crack-0.4.5/lib/crack/util.rb +17 -0
  46. data/vendor/bundle/jruby/2.5.0/gems/crack-0.4.5/lib/crack/version.rb +3 -0
  47. data/vendor/bundle/jruby/2.5.0/gems/crack-0.4.5/lib/crack/xml.rb +238 -0
  48. data/vendor/bundle/jruby/2.5.0/gems/hashdiff-1.0.1/Gemfile +8 -0
  49. data/vendor/bundle/jruby/2.5.0/gems/hashdiff-1.0.1/LICENSE +19 -0
  50. data/vendor/bundle/jruby/2.5.0/gems/hashdiff-1.0.1/README.md +276 -0
  51. data/vendor/bundle/jruby/2.5.0/gems/hashdiff-1.0.1/Rakefile +18 -0
  52. data/vendor/bundle/jruby/2.5.0/gems/hashdiff-1.0.1/changelog.md +100 -0
  53. data/vendor/bundle/jruby/2.5.0/gems/hashdiff-1.0.1/hashdiff.gemspec +39 -0
  54. data/vendor/bundle/jruby/2.5.0/gems/hashdiff-1.0.1/lib/hashdiff.rb +10 -0
  55. data/vendor/bundle/jruby/2.5.0/gems/hashdiff-1.0.1/lib/hashdiff/compare_hashes.rb +69 -0
  56. data/vendor/bundle/jruby/2.5.0/gems/hashdiff-1.0.1/lib/hashdiff/diff.rb +177 -0
  57. data/vendor/bundle/jruby/2.5.0/gems/hashdiff-1.0.1/lib/hashdiff/lcs.rb +66 -0
  58. data/vendor/bundle/jruby/2.5.0/gems/hashdiff-1.0.1/lib/hashdiff/lcs_compare_arrays.rb +32 -0
  59. data/vendor/bundle/jruby/2.5.0/gems/hashdiff-1.0.1/lib/hashdiff/linear_compare_array.rb +159 -0
  60. data/vendor/bundle/jruby/2.5.0/gems/hashdiff-1.0.1/lib/hashdiff/patch.rb +88 -0
  61. data/vendor/bundle/jruby/2.5.0/gems/hashdiff-1.0.1/lib/hashdiff/util.rb +155 -0
  62. data/vendor/bundle/jruby/2.5.0/gems/hashdiff-1.0.1/lib/hashdiff/version.rb +5 -0
  63. data/vendor/bundle/jruby/2.5.0/gems/hashdiff-1.0.1/spec/hashdiff/best_diff_spec.rb +75 -0
  64. data/vendor/bundle/jruby/2.5.0/gems/hashdiff-1.0.1/spec/hashdiff/diff_array_spec.rb +60 -0
  65. data/vendor/bundle/jruby/2.5.0/gems/hashdiff-1.0.1/spec/hashdiff/diff_spec.rb +360 -0
  66. data/vendor/bundle/jruby/2.5.0/gems/hashdiff-1.0.1/spec/hashdiff/lcs_spec.rb +76 -0
  67. data/vendor/bundle/jruby/2.5.0/gems/hashdiff-1.0.1/spec/hashdiff/linear_compare_array_spec.rb +50 -0
  68. data/vendor/bundle/jruby/2.5.0/gems/hashdiff-1.0.1/spec/hashdiff/patch_spec.rb +185 -0
  69. data/vendor/bundle/jruby/2.5.0/gems/hashdiff-1.0.1/spec/hashdiff/readme_spec.rb +15 -0
  70. data/vendor/bundle/jruby/2.5.0/gems/hashdiff-1.0.1/spec/hashdiff/util_spec.rb +116 -0
  71. data/vendor/bundle/jruby/2.5.0/gems/hashdiff-1.0.1/spec/spec_helper.rb +15 -0
  72. data/vendor/bundle/jruby/2.5.0/gems/public_suffix-4.0.6/2.0-Upgrade.md +52 -0
  73. data/vendor/bundle/jruby/2.5.0/gems/public_suffix-4.0.6/CHANGELOG.md +406 -0
  74. data/vendor/bundle/jruby/2.5.0/gems/public_suffix-4.0.6/Gemfile +15 -0
  75. data/vendor/bundle/jruby/2.5.0/gems/public_suffix-4.0.6/LICENSE.txt +22 -0
  76. data/vendor/bundle/jruby/2.5.0/gems/public_suffix-4.0.6/README.md +207 -0
  77. data/vendor/bundle/jruby/2.5.0/gems/public_suffix-4.0.6/Rakefile +51 -0
  78. data/vendor/bundle/jruby/2.5.0/gems/public_suffix-4.0.6/SECURITY.md +104 -0
  79. data/vendor/bundle/jruby/2.5.0/gems/public_suffix-4.0.6/bin/console +15 -0
  80. data/vendor/bundle/jruby/2.5.0/gems/public_suffix-4.0.6/codecov.yml +12 -0
  81. data/vendor/bundle/jruby/2.5.0/gems/public_suffix-4.0.6/data/list.txt +13380 -0
  82. data/vendor/bundle/jruby/2.5.0/gems/public_suffix-4.0.6/lib/public_suffix.rb +179 -0
  83. data/vendor/bundle/jruby/2.5.0/gems/public_suffix-4.0.6/lib/public_suffix/domain.rb +235 -0
  84. data/vendor/bundle/jruby/2.5.0/gems/public_suffix-4.0.6/lib/public_suffix/errors.rb +41 -0
  85. data/vendor/bundle/jruby/2.5.0/gems/public_suffix-4.0.6/lib/public_suffix/list.rb +247 -0
  86. data/vendor/bundle/jruby/2.5.0/gems/public_suffix-4.0.6/lib/public_suffix/rule.rb +350 -0
  87. data/vendor/bundle/jruby/2.5.0/gems/public_suffix-4.0.6/lib/public_suffix/version.rb +13 -0
  88. data/vendor/bundle/jruby/2.5.0/gems/public_suffix-4.0.6/public_suffix.gemspec +29 -0
  89. data/vendor/bundle/jruby/2.5.0/gems/public_suffix-4.0.6/test/acceptance_test.rb +131 -0
  90. data/vendor/bundle/jruby/2.5.0/gems/public_suffix-4.0.6/test/benchmarks/bm_find.rb +66 -0
  91. data/vendor/bundle/jruby/2.5.0/gems/public_suffix-4.0.6/test/benchmarks/bm_find_all.rb +102 -0
  92. data/vendor/bundle/jruby/2.5.0/gems/public_suffix-4.0.6/test/benchmarks/bm_names.rb +91 -0
  93. data/vendor/bundle/jruby/2.5.0/gems/public_suffix-4.0.6/test/benchmarks/bm_select.rb +26 -0
  94. data/vendor/bundle/jruby/2.5.0/gems/public_suffix-4.0.6/test/benchmarks/bm_select_incremental.rb +25 -0
  95. data/vendor/bundle/jruby/2.5.0/gems/public_suffix-4.0.6/test/benchmarks/bm_valid.rb +101 -0
  96. data/vendor/bundle/jruby/2.5.0/gems/public_suffix-4.0.6/test/profilers/domain_profiler.rb +12 -0
  97. data/vendor/bundle/jruby/2.5.0/gems/public_suffix-4.0.6/test/profilers/find_profiler.rb +12 -0
  98. data/vendor/bundle/jruby/2.5.0/gems/public_suffix-4.0.6/test/profilers/find_profiler_jp.rb +12 -0
  99. data/vendor/bundle/jruby/2.5.0/gems/public_suffix-4.0.6/test/profilers/initialization_profiler.rb +11 -0
  100. data/vendor/bundle/jruby/2.5.0/gems/public_suffix-4.0.6/test/profilers/list_profsize.rb +11 -0
  101. data/vendor/bundle/jruby/2.5.0/gems/public_suffix-4.0.6/test/profilers/object_binsize.rb +57 -0
  102. data/vendor/bundle/jruby/2.5.0/gems/public_suffix-4.0.6/test/psl_test.rb +52 -0
  103. data/vendor/bundle/jruby/2.5.0/gems/public_suffix-4.0.6/test/test_helper.rb +18 -0
  104. data/vendor/bundle/jruby/2.5.0/gems/public_suffix-4.0.6/test/tests.txt +98 -0
  105. data/vendor/bundle/jruby/2.5.0/gems/public_suffix-4.0.6/test/unit/domain_test.rb +106 -0
  106. data/vendor/bundle/jruby/2.5.0/gems/public_suffix-4.0.6/test/unit/errors_test.rb +25 -0
  107. data/vendor/bundle/jruby/2.5.0/gems/public_suffix-4.0.6/test/unit/list_test.rb +241 -0
  108. data/vendor/bundle/jruby/2.5.0/gems/public_suffix-4.0.6/test/unit/public_suffix_test.rb +188 -0
  109. data/vendor/bundle/jruby/2.5.0/gems/public_suffix-4.0.6/test/unit/rule_test.rb +222 -0
  110. data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/LICENSE.txt +22 -0
  111. data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/NEWS.md +178 -0
  112. data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/README.md +48 -0
  113. data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/doc/rexml/context.rdoc +143 -0
  114. data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/doc/rexml/tasks/rdoc/child.rdoc +87 -0
  115. data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/doc/rexml/tasks/rdoc/document.rdoc +276 -0
  116. data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/doc/rexml/tasks/rdoc/element.rdoc +602 -0
  117. data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/doc/rexml/tasks/rdoc/node.rdoc +97 -0
  118. data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/doc/rexml/tasks/rdoc/parent.rdoc +267 -0
  119. data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/doc/rexml/tasks/tocs/child_toc.rdoc +12 -0
  120. data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/doc/rexml/tasks/tocs/document_toc.rdoc +30 -0
  121. data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/doc/rexml/tasks/tocs/element_toc.rdoc +55 -0
  122. data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/doc/rexml/tasks/tocs/master_toc.rdoc +135 -0
  123. data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/doc/rexml/tasks/tocs/node_toc.rdoc +16 -0
  124. data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/doc/rexml/tasks/tocs/parent_toc.rdoc +25 -0
  125. data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/lib/rexml.rb +3 -0
  126. data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/lib/rexml/attlistdecl.rb +63 -0
  127. data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/lib/rexml/attribute.rb +205 -0
  128. data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/lib/rexml/cdata.rb +68 -0
  129. data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/lib/rexml/child.rb +97 -0
  130. data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/lib/rexml/comment.rb +80 -0
  131. data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/lib/rexml/doctype.rb +311 -0
  132. data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/lib/rexml/document.rb +451 -0
  133. data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/lib/rexml/dtd/attlistdecl.rb +11 -0
  134. data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/lib/rexml/dtd/dtd.rb +47 -0
  135. data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/lib/rexml/dtd/elementdecl.rb +18 -0
  136. data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/lib/rexml/dtd/entitydecl.rb +57 -0
  137. data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/lib/rexml/dtd/notationdecl.rb +40 -0
  138. data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/lib/rexml/element.rb +2599 -0
  139. data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/lib/rexml/encoding.rb +51 -0
  140. data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/lib/rexml/entity.rb +171 -0
  141. data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/lib/rexml/formatters/default.rb +116 -0
  142. data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/lib/rexml/formatters/pretty.rb +142 -0
  143. data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/lib/rexml/formatters/transitive.rb +58 -0
  144. data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/lib/rexml/functions.rb +447 -0
  145. data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/lib/rexml/instruction.rb +79 -0
  146. data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/lib/rexml/light/node.rb +188 -0
  147. data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/lib/rexml/namespace.rb +59 -0
  148. data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/lib/rexml/node.rb +76 -0
  149. data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/lib/rexml/output.rb +30 -0
  150. data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/lib/rexml/parent.rb +166 -0
  151. data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/lib/rexml/parseexception.rb +52 -0
  152. data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/lib/rexml/parsers/baseparser.rb +694 -0
  153. data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/lib/rexml/parsers/lightparser.rb +59 -0
  154. data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/lib/rexml/parsers/pullparser.rb +197 -0
  155. data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/lib/rexml/parsers/sax2parser.rb +273 -0
  156. data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/lib/rexml/parsers/streamparser.rb +61 -0
  157. data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/lib/rexml/parsers/treeparser.rb +101 -0
  158. data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/lib/rexml/parsers/ultralightparser.rb +57 -0
  159. data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/lib/rexml/parsers/xpathparser.rb +689 -0
  160. data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/lib/rexml/quickpath.rb +266 -0
  161. data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/lib/rexml/rexml.rb +37 -0
  162. data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/lib/rexml/sax2listener.rb +98 -0
  163. data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/lib/rexml/security.rb +28 -0
  164. data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/lib/rexml/source.rb +298 -0
  165. data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/lib/rexml/streamlistener.rb +93 -0
  166. data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/lib/rexml/text.rb +424 -0
  167. data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/lib/rexml/undefinednamespaceexception.rb +9 -0
  168. data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/lib/rexml/validation/relaxng.rb +539 -0
  169. data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/lib/rexml/validation/validation.rb +144 -0
  170. data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/lib/rexml/validation/validationexception.rb +10 -0
  171. data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/lib/rexml/xmldecl.rb +130 -0
  172. data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/lib/rexml/xmltokens.rb +85 -0
  173. data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/lib/rexml/xpath.rb +81 -0
  174. data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/lib/rexml/xpath_parser.rb +974 -0
  175. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/CHANGELOG.md +1894 -0
  176. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/Gemfile +9 -0
  177. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/LICENSE +20 -0
  178. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/README.md +1176 -0
  179. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/Rakefile +38 -0
  180. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock.rb +59 -0
  181. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock/api.rb +109 -0
  182. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock/assertion_failure.rb +11 -0
  183. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock/callback_registry.rb +35 -0
  184. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock/config.rb +18 -0
  185. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock/cucumber.rb +10 -0
  186. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock/deprecation.rb +9 -0
  187. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock/errors.rb +17 -0
  188. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock/http_lib_adapters/async_http_client_adapter.rb +216 -0
  189. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock/http_lib_adapters/curb_adapter.rb +351 -0
  190. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock/http_lib_adapters/em_http_request_adapter.rb +231 -0
  191. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock/http_lib_adapters/excon_adapter.rb +165 -0
  192. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock/http_lib_adapters/http_lib_adapter.rb +7 -0
  193. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock/http_lib_adapters/http_lib_adapter_registry.rb +19 -0
  194. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock/http_lib_adapters/http_rb/client.rb +17 -0
  195. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock/http_lib_adapters/http_rb/request.rb +16 -0
  196. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock/http_lib_adapters/http_rb/response.rb +64 -0
  197. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock/http_lib_adapters/http_rb/streamer.rb +29 -0
  198. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock/http_lib_adapters/http_rb/webmock.rb +68 -0
  199. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock/http_lib_adapters/http_rb_adapter.rb +37 -0
  200. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock/http_lib_adapters/httpclient_adapter.rb +259 -0
  201. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock/http_lib_adapters/manticore_adapter.rb +145 -0
  202. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock/http_lib_adapters/net_http.rb +385 -0
  203. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock/http_lib_adapters/net_http_response.rb +34 -0
  204. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock/http_lib_adapters/patron_adapter.rb +130 -0
  205. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock/http_lib_adapters/typhoeus_hydra_adapter.rb +174 -0
  206. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock/matchers/any_arg_matcher.rb +13 -0
  207. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock/matchers/hash_argument_matcher.rb +21 -0
  208. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock/matchers/hash_excluding_matcher.rb +15 -0
  209. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock/matchers/hash_including_matcher.rb +17 -0
  210. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock/minitest.rb +41 -0
  211. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock/rack_response.rb +69 -0
  212. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock/request_body_diff.rb +64 -0
  213. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock/request_execution_verifier.rb +77 -0
  214. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock/request_pattern.rb +405 -0
  215. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock/request_registry.rb +35 -0
  216. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock/request_signature.rb +54 -0
  217. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock/request_signature_snippet.rb +61 -0
  218. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock/request_stub.rb +100 -0
  219. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock/response.rb +159 -0
  220. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock/responses_sequence.rb +40 -0
  221. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock/rspec.rb +42 -0
  222. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock/rspec/matchers.rb +27 -0
  223. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock/rspec/matchers/request_pattern_matcher.rb +78 -0
  224. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock/rspec/matchers/webmock_matcher.rb +67 -0
  225. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock/stub_registry.rb +82 -0
  226. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock/stub_request_snippet.rb +38 -0
  227. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock/test_unit.rb +20 -0
  228. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock/util/hash_counter.rb +39 -0
  229. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock/util/hash_keys_stringifier.rb +25 -0
  230. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock/util/hash_validator.rb +17 -0
  231. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock/util/headers.rb +64 -0
  232. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock/util/json.rb +67 -0
  233. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock/util/query_mapper.rb +281 -0
  234. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock/util/uri.rb +111 -0
  235. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock/util/values_stringifier.rb +20 -0
  236. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock/util/version_checker.rb +111 -0
  237. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock/version.rb +3 -0
  238. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock/webmock.rb +163 -0
  239. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/minitest/test_helper.rb +34 -0
  240. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/minitest/test_webmock.rb +9 -0
  241. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/minitest/webmock_spec.rb +60 -0
  242. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/acceptance/async_http_client/async_http_client_spec.rb +375 -0
  243. 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
  244. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/acceptance/curb/curb_spec.rb +499 -0
  245. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/acceptance/curb/curb_spec_helper.rb +147 -0
  246. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/acceptance/em_http_request/em_http_request_spec.rb +462 -0
  247. 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
  248. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/acceptance/excon/excon_spec.rb +77 -0
  249. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/acceptance/excon/excon_spec_helper.rb +52 -0
  250. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/acceptance/http_rb/http_rb_spec.rb +93 -0
  251. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/acceptance/http_rb/http_rb_spec_helper.rb +54 -0
  252. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/acceptance/httpclient/httpclient_spec.rb +217 -0
  253. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/acceptance/httpclient/httpclient_spec_helper.rb +57 -0
  254. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/acceptance/manticore/manticore_spec.rb +107 -0
  255. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/acceptance/manticore/manticore_spec_helper.rb +35 -0
  256. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/acceptance/net_http/net_http_shared.rb +153 -0
  257. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/acceptance/net_http/net_http_spec.rb +369 -0
  258. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/acceptance/net_http/net_http_spec_helper.rb +64 -0
  259. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/acceptance/net_http/real_net_http_spec.rb +20 -0
  260. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/acceptance/patron/patron_spec.rb +125 -0
  261. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/acceptance/patron/patron_spec_helper.rb +54 -0
  262. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/acceptance/shared/allowing_and_disabling_net_connect.rb +313 -0
  263. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/acceptance/shared/callbacks.rb +148 -0
  264. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/acceptance/shared/complex_cross_concern_behaviors.rb +36 -0
  265. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/acceptance/shared/enabling_and_disabling_webmock.rb +95 -0
  266. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/acceptance/shared/precedence_of_stubs.rb +15 -0
  267. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/acceptance/shared/request_expectations.rb +930 -0
  268. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/acceptance/shared/returning_declared_responses.rb +409 -0
  269. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/acceptance/shared/stubbing_requests.rb +678 -0
  270. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/acceptance/typhoeus/typhoeus_hydra_spec.rb +135 -0
  271. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/acceptance/typhoeus/typhoeus_hydra_spec_helper.rb +60 -0
  272. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/acceptance/webmock_shared.rb +41 -0
  273. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/fixtures/test.txt +1 -0
  274. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/quality_spec.rb +84 -0
  275. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/spec_helper.rb +48 -0
  276. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/support/example_curl_output.txt +22 -0
  277. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/support/failures.rb +9 -0
  278. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/support/my_rack_app.rb +53 -0
  279. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/support/network_connection.rb +19 -0
  280. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/support/webmock_server.rb +70 -0
  281. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/unit/api_spec.rb +175 -0
  282. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/unit/errors_spec.rb +129 -0
  283. 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
  284. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/unit/http_lib_adapters/http_lib_adapter_spec.rb +12 -0
  285. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/unit/matchers/hash_excluding_matcher_spec.rb +61 -0
  286. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/unit/matchers/hash_including_matcher_spec.rb +87 -0
  287. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/unit/rack_response_spec.rb +112 -0
  288. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/unit/request_body_diff_spec.rb +90 -0
  289. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/unit/request_execution_verifier_spec.rb +208 -0
  290. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/unit/request_pattern_spec.rb +736 -0
  291. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/unit/request_registry_spec.rb +95 -0
  292. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/unit/request_signature_snippet_spec.rb +89 -0
  293. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/unit/request_signature_spec.rb +155 -0
  294. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/unit/request_stub_spec.rb +199 -0
  295. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/unit/response_spec.rb +286 -0
  296. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/unit/stub_registry_spec.rb +103 -0
  297. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/unit/stub_request_snippet_spec.rb +115 -0
  298. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/unit/util/hash_counter_spec.rb +39 -0
  299. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/unit/util/hash_keys_stringifier_spec.rb +27 -0
  300. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/unit/util/headers_spec.rb +28 -0
  301. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/unit/util/json_spec.rb +33 -0
  302. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/unit/util/query_mapper_spec.rb +157 -0
  303. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/unit/util/uri_spec.rb +371 -0
  304. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/unit/util/version_checker_spec.rb +65 -0
  305. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/unit/webmock_spec.rb +60 -0
  306. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/test/http_request.rb +24 -0
  307. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/test/shared_test.rb +108 -0
  308. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/test/test_helper.rb +23 -0
  309. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/test/test_webmock.rb +12 -0
  310. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/webmock.gemspec +54 -0
  311. data/vendor/bundle/jruby/2.5.0/specifications/addressable-2.7.0.gemspec +39 -0
  312. data/vendor/bundle/jruby/2.5.0/specifications/crack-0.4.5.gemspec +32 -0
  313. data/vendor/bundle/jruby/2.5.0/specifications/hashdiff-1.0.1.gemspec +46 -0
  314. data/vendor/bundle/jruby/2.5.0/specifications/public_suffix-4.0.6.gemspec +24 -0
  315. data/vendor/bundle/jruby/2.5.0/specifications/rexml-3.2.5.gemspec +42 -0
  316. data/vendor/bundle/jruby/2.5.0/specifications/webmock-3.13.0.gemspec +85 -0
  317. 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