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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +27 -0
- data/Gemfile +5 -0
- data/README.md +3 -2
- data/lib/logstash/outputs/scalyr.rb +226 -138
- data/lib/scalyr/common/client.rb +76 -50
- data/lib/scalyr/common/util.rb +7 -0
- data/lib/scalyr/constants.rb +2 -0
- data/logstash-output-scalyr.gemspec +1 -1
- data/spec/logstash/outputs/scalyr_integration_spec.rb +148 -8
- data/spec/logstash/outputs/scalyr_spec.rb +12 -6
- data/vendor/bundle/jruby/2.5.0/bin/htmldiff +1 -1
- data/vendor/bundle/jruby/2.5.0/bin/ldiff +1 -1
- data/vendor/bundle/jruby/2.5.0/cache/addressable-2.7.0.gem +0 -0
- data/vendor/bundle/jruby/2.5.0/cache/crack-0.4.5.gem +0 -0
- data/vendor/bundle/jruby/2.5.0/cache/hashdiff-1.0.1.gem +0 -0
- data/vendor/bundle/jruby/2.5.0/cache/public_suffix-4.0.6.gem +0 -0
- data/vendor/bundle/jruby/2.5.0/cache/rexml-3.2.5.gem +0 -0
- data/vendor/bundle/jruby/2.5.0/cache/webmock-3.13.0.gem +0 -0
- data/vendor/bundle/jruby/2.5.0/gems/addressable-2.7.0/CHANGELOG.md +235 -0
- data/vendor/bundle/jruby/2.5.0/gems/addressable-2.7.0/Gemfile +32 -0
- data/vendor/bundle/jruby/2.5.0/gems/addressable-2.7.0/LICENSE.txt +202 -0
- data/vendor/bundle/jruby/2.5.0/gems/addressable-2.7.0/README.md +121 -0
- data/vendor/bundle/jruby/2.5.0/gems/addressable-2.7.0/Rakefile +34 -0
- data/vendor/bundle/jruby/2.5.0/gems/addressable-2.7.0/data/unicode.data +0 -0
- data/vendor/bundle/jruby/2.5.0/gems/addressable-2.7.0/lib/addressable.rb +4 -0
- data/vendor/bundle/jruby/2.5.0/gems/addressable-2.7.0/lib/addressable/idna.rb +27 -0
- data/vendor/bundle/jruby/2.5.0/gems/addressable-2.7.0/lib/addressable/idna/native.rb +61 -0
- data/vendor/bundle/jruby/2.5.0/gems/addressable-2.7.0/lib/addressable/idna/pure.rb +676 -0
- data/vendor/bundle/jruby/2.5.0/gems/addressable-2.7.0/lib/addressable/template.rb +1045 -0
- data/vendor/bundle/jruby/2.5.0/gems/addressable-2.7.0/lib/addressable/uri.rb +2529 -0
- data/vendor/bundle/jruby/2.5.0/gems/addressable-2.7.0/lib/addressable/version.rb +32 -0
- data/vendor/bundle/jruby/2.5.0/gems/addressable-2.7.0/spec/addressable/idna_spec.rb +300 -0
- data/vendor/bundle/jruby/2.5.0/gems/addressable-2.7.0/spec/addressable/net_http_compat_spec.rb +30 -0
- data/vendor/bundle/jruby/2.5.0/gems/addressable-2.7.0/spec/addressable/rack_mount_compat_spec.rb +106 -0
- data/vendor/bundle/jruby/2.5.0/gems/addressable-2.7.0/spec/addressable/security_spec.rb +59 -0
- data/vendor/bundle/jruby/2.5.0/gems/addressable-2.7.0/spec/addressable/template_spec.rb +1451 -0
- data/vendor/bundle/jruby/2.5.0/gems/addressable-2.7.0/spec/addressable/uri_spec.rb +6603 -0
- data/vendor/bundle/jruby/2.5.0/gems/addressable-2.7.0/spec/spec_helper.rb +24 -0
- data/vendor/bundle/jruby/2.5.0/gems/addressable-2.7.0/tasks/clobber.rake +4 -0
- data/vendor/bundle/jruby/2.5.0/gems/addressable-2.7.0/tasks/gem.rake +93 -0
- data/vendor/bundle/jruby/2.5.0/gems/addressable-2.7.0/tasks/git.rake +47 -0
- data/vendor/bundle/jruby/2.5.0/gems/addressable-2.7.0/tasks/metrics.rake +24 -0
- data/vendor/bundle/jruby/2.5.0/gems/addressable-2.7.0/tasks/rspec.rake +23 -0
- data/vendor/bundle/jruby/2.5.0/gems/addressable-2.7.0/tasks/yard.rake +29 -0
- data/vendor/bundle/jruby/2.5.0/gems/crack-0.4.5/lib/crack.rb +7 -0
- data/vendor/bundle/jruby/2.5.0/gems/crack-0.4.5/lib/crack/json.rb +98 -0
- data/vendor/bundle/jruby/2.5.0/gems/crack-0.4.5/lib/crack/util.rb +17 -0
- data/vendor/bundle/jruby/2.5.0/gems/crack-0.4.5/lib/crack/version.rb +3 -0
- data/vendor/bundle/jruby/2.5.0/gems/crack-0.4.5/lib/crack/xml.rb +238 -0
- data/vendor/bundle/jruby/2.5.0/gems/hashdiff-1.0.1/Gemfile +8 -0
- data/vendor/bundle/jruby/2.5.0/gems/hashdiff-1.0.1/LICENSE +19 -0
- data/vendor/bundle/jruby/2.5.0/gems/hashdiff-1.0.1/README.md +276 -0
- data/vendor/bundle/jruby/2.5.0/gems/hashdiff-1.0.1/Rakefile +18 -0
- data/vendor/bundle/jruby/2.5.0/gems/hashdiff-1.0.1/changelog.md +100 -0
- data/vendor/bundle/jruby/2.5.0/gems/hashdiff-1.0.1/hashdiff.gemspec +39 -0
- data/vendor/bundle/jruby/2.5.0/gems/hashdiff-1.0.1/lib/hashdiff.rb +10 -0
- data/vendor/bundle/jruby/2.5.0/gems/hashdiff-1.0.1/lib/hashdiff/compare_hashes.rb +69 -0
- data/vendor/bundle/jruby/2.5.0/gems/hashdiff-1.0.1/lib/hashdiff/diff.rb +177 -0
- data/vendor/bundle/jruby/2.5.0/gems/hashdiff-1.0.1/lib/hashdiff/lcs.rb +66 -0
- data/vendor/bundle/jruby/2.5.0/gems/hashdiff-1.0.1/lib/hashdiff/lcs_compare_arrays.rb +32 -0
- data/vendor/bundle/jruby/2.5.0/gems/hashdiff-1.0.1/lib/hashdiff/linear_compare_array.rb +159 -0
- data/vendor/bundle/jruby/2.5.0/gems/hashdiff-1.0.1/lib/hashdiff/patch.rb +88 -0
- data/vendor/bundle/jruby/2.5.0/gems/hashdiff-1.0.1/lib/hashdiff/util.rb +155 -0
- data/vendor/bundle/jruby/2.5.0/gems/hashdiff-1.0.1/lib/hashdiff/version.rb +5 -0
- data/vendor/bundle/jruby/2.5.0/gems/hashdiff-1.0.1/spec/hashdiff/best_diff_spec.rb +75 -0
- data/vendor/bundle/jruby/2.5.0/gems/hashdiff-1.0.1/spec/hashdiff/diff_array_spec.rb +60 -0
- data/vendor/bundle/jruby/2.5.0/gems/hashdiff-1.0.1/spec/hashdiff/diff_spec.rb +360 -0
- data/vendor/bundle/jruby/2.5.0/gems/hashdiff-1.0.1/spec/hashdiff/lcs_spec.rb +76 -0
- data/vendor/bundle/jruby/2.5.0/gems/hashdiff-1.0.1/spec/hashdiff/linear_compare_array_spec.rb +50 -0
- data/vendor/bundle/jruby/2.5.0/gems/hashdiff-1.0.1/spec/hashdiff/patch_spec.rb +185 -0
- data/vendor/bundle/jruby/2.5.0/gems/hashdiff-1.0.1/spec/hashdiff/readme_spec.rb +15 -0
- data/vendor/bundle/jruby/2.5.0/gems/hashdiff-1.0.1/spec/hashdiff/util_spec.rb +116 -0
- data/vendor/bundle/jruby/2.5.0/gems/hashdiff-1.0.1/spec/spec_helper.rb +15 -0
- data/vendor/bundle/jruby/2.5.0/gems/public_suffix-4.0.6/2.0-Upgrade.md +52 -0
- data/vendor/bundle/jruby/2.5.0/gems/public_suffix-4.0.6/CHANGELOG.md +406 -0
- data/vendor/bundle/jruby/2.5.0/gems/public_suffix-4.0.6/Gemfile +15 -0
- data/vendor/bundle/jruby/2.5.0/gems/public_suffix-4.0.6/LICENSE.txt +22 -0
- data/vendor/bundle/jruby/2.5.0/gems/public_suffix-4.0.6/README.md +207 -0
- data/vendor/bundle/jruby/2.5.0/gems/public_suffix-4.0.6/Rakefile +51 -0
- data/vendor/bundle/jruby/2.5.0/gems/public_suffix-4.0.6/SECURITY.md +104 -0
- data/vendor/bundle/jruby/2.5.0/gems/public_suffix-4.0.6/bin/console +15 -0
- data/vendor/bundle/jruby/2.5.0/gems/public_suffix-4.0.6/codecov.yml +12 -0
- data/vendor/bundle/jruby/2.5.0/gems/public_suffix-4.0.6/data/list.txt +13380 -0
- data/vendor/bundle/jruby/2.5.0/gems/public_suffix-4.0.6/lib/public_suffix.rb +179 -0
- data/vendor/bundle/jruby/2.5.0/gems/public_suffix-4.0.6/lib/public_suffix/domain.rb +235 -0
- data/vendor/bundle/jruby/2.5.0/gems/public_suffix-4.0.6/lib/public_suffix/errors.rb +41 -0
- data/vendor/bundle/jruby/2.5.0/gems/public_suffix-4.0.6/lib/public_suffix/list.rb +247 -0
- data/vendor/bundle/jruby/2.5.0/gems/public_suffix-4.0.6/lib/public_suffix/rule.rb +350 -0
- data/vendor/bundle/jruby/2.5.0/gems/public_suffix-4.0.6/lib/public_suffix/version.rb +13 -0
- data/vendor/bundle/jruby/2.5.0/gems/public_suffix-4.0.6/public_suffix.gemspec +29 -0
- data/vendor/bundle/jruby/2.5.0/gems/public_suffix-4.0.6/test/acceptance_test.rb +131 -0
- data/vendor/bundle/jruby/2.5.0/gems/public_suffix-4.0.6/test/benchmarks/bm_find.rb +66 -0
- data/vendor/bundle/jruby/2.5.0/gems/public_suffix-4.0.6/test/benchmarks/bm_find_all.rb +102 -0
- data/vendor/bundle/jruby/2.5.0/gems/public_suffix-4.0.6/test/benchmarks/bm_names.rb +91 -0
- data/vendor/bundle/jruby/2.5.0/gems/public_suffix-4.0.6/test/benchmarks/bm_select.rb +26 -0
- data/vendor/bundle/jruby/2.5.0/gems/public_suffix-4.0.6/test/benchmarks/bm_select_incremental.rb +25 -0
- data/vendor/bundle/jruby/2.5.0/gems/public_suffix-4.0.6/test/benchmarks/bm_valid.rb +101 -0
- data/vendor/bundle/jruby/2.5.0/gems/public_suffix-4.0.6/test/profilers/domain_profiler.rb +12 -0
- data/vendor/bundle/jruby/2.5.0/gems/public_suffix-4.0.6/test/profilers/find_profiler.rb +12 -0
- data/vendor/bundle/jruby/2.5.0/gems/public_suffix-4.0.6/test/profilers/find_profiler_jp.rb +12 -0
- data/vendor/bundle/jruby/2.5.0/gems/public_suffix-4.0.6/test/profilers/initialization_profiler.rb +11 -0
- data/vendor/bundle/jruby/2.5.0/gems/public_suffix-4.0.6/test/profilers/list_profsize.rb +11 -0
- data/vendor/bundle/jruby/2.5.0/gems/public_suffix-4.0.6/test/profilers/object_binsize.rb +57 -0
- data/vendor/bundle/jruby/2.5.0/gems/public_suffix-4.0.6/test/psl_test.rb +52 -0
- data/vendor/bundle/jruby/2.5.0/gems/public_suffix-4.0.6/test/test_helper.rb +18 -0
- data/vendor/bundle/jruby/2.5.0/gems/public_suffix-4.0.6/test/tests.txt +98 -0
- data/vendor/bundle/jruby/2.5.0/gems/public_suffix-4.0.6/test/unit/domain_test.rb +106 -0
- data/vendor/bundle/jruby/2.5.0/gems/public_suffix-4.0.6/test/unit/errors_test.rb +25 -0
- data/vendor/bundle/jruby/2.5.0/gems/public_suffix-4.0.6/test/unit/list_test.rb +241 -0
- data/vendor/bundle/jruby/2.5.0/gems/public_suffix-4.0.6/test/unit/public_suffix_test.rb +188 -0
- data/vendor/bundle/jruby/2.5.0/gems/public_suffix-4.0.6/test/unit/rule_test.rb +222 -0
- data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/LICENSE.txt +22 -0
- data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/NEWS.md +178 -0
- data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/README.md +48 -0
- data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/doc/rexml/context.rdoc +143 -0
- data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/doc/rexml/tasks/rdoc/child.rdoc +87 -0
- data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/doc/rexml/tasks/rdoc/document.rdoc +276 -0
- data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/doc/rexml/tasks/rdoc/element.rdoc +602 -0
- data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/doc/rexml/tasks/rdoc/node.rdoc +97 -0
- data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/doc/rexml/tasks/rdoc/parent.rdoc +267 -0
- data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/doc/rexml/tasks/tocs/child_toc.rdoc +12 -0
- data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/doc/rexml/tasks/tocs/document_toc.rdoc +30 -0
- data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/doc/rexml/tasks/tocs/element_toc.rdoc +55 -0
- data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/doc/rexml/tasks/tocs/master_toc.rdoc +135 -0
- data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/doc/rexml/tasks/tocs/node_toc.rdoc +16 -0
- data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/doc/rexml/tasks/tocs/parent_toc.rdoc +25 -0
- data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/lib/rexml.rb +3 -0
- data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/lib/rexml/attlistdecl.rb +63 -0
- data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/lib/rexml/attribute.rb +205 -0
- data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/lib/rexml/cdata.rb +68 -0
- data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/lib/rexml/child.rb +97 -0
- data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/lib/rexml/comment.rb +80 -0
- data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/lib/rexml/doctype.rb +311 -0
- data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/lib/rexml/document.rb +451 -0
- data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/lib/rexml/dtd/attlistdecl.rb +11 -0
- data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/lib/rexml/dtd/dtd.rb +47 -0
- data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/lib/rexml/dtd/elementdecl.rb +18 -0
- data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/lib/rexml/dtd/entitydecl.rb +57 -0
- data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/lib/rexml/dtd/notationdecl.rb +40 -0
- data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/lib/rexml/element.rb +2599 -0
- data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/lib/rexml/encoding.rb +51 -0
- data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/lib/rexml/entity.rb +171 -0
- data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/lib/rexml/formatters/default.rb +116 -0
- data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/lib/rexml/formatters/pretty.rb +142 -0
- data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/lib/rexml/formatters/transitive.rb +58 -0
- data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/lib/rexml/functions.rb +447 -0
- data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/lib/rexml/instruction.rb +79 -0
- data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/lib/rexml/light/node.rb +188 -0
- data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/lib/rexml/namespace.rb +59 -0
- data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/lib/rexml/node.rb +76 -0
- data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/lib/rexml/output.rb +30 -0
- data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/lib/rexml/parent.rb +166 -0
- data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/lib/rexml/parseexception.rb +52 -0
- data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/lib/rexml/parsers/baseparser.rb +694 -0
- data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/lib/rexml/parsers/lightparser.rb +59 -0
- data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/lib/rexml/parsers/pullparser.rb +197 -0
- data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/lib/rexml/parsers/sax2parser.rb +273 -0
- data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/lib/rexml/parsers/streamparser.rb +61 -0
- data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/lib/rexml/parsers/treeparser.rb +101 -0
- data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/lib/rexml/parsers/ultralightparser.rb +57 -0
- data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/lib/rexml/parsers/xpathparser.rb +689 -0
- data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/lib/rexml/quickpath.rb +266 -0
- data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/lib/rexml/rexml.rb +37 -0
- data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/lib/rexml/sax2listener.rb +98 -0
- data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/lib/rexml/security.rb +28 -0
- data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/lib/rexml/source.rb +298 -0
- data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/lib/rexml/streamlistener.rb +93 -0
- data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/lib/rexml/text.rb +424 -0
- data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/lib/rexml/undefinednamespaceexception.rb +9 -0
- data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/lib/rexml/validation/relaxng.rb +539 -0
- data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/lib/rexml/validation/validation.rb +144 -0
- data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/lib/rexml/validation/validationexception.rb +10 -0
- data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/lib/rexml/xmldecl.rb +130 -0
- data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/lib/rexml/xmltokens.rb +85 -0
- data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/lib/rexml/xpath.rb +81 -0
- data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/lib/rexml/xpath_parser.rb +974 -0
- data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/CHANGELOG.md +1894 -0
- data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/Gemfile +9 -0
- data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/LICENSE +20 -0
- data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/README.md +1176 -0
- data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/Rakefile +38 -0
- data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock.rb +59 -0
- data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock/api.rb +109 -0
- data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock/assertion_failure.rb +11 -0
- data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock/callback_registry.rb +35 -0
- data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock/config.rb +18 -0
- data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock/cucumber.rb +10 -0
- data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock/deprecation.rb +9 -0
- data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock/errors.rb +17 -0
- data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock/http_lib_adapters/async_http_client_adapter.rb +216 -0
- data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock/http_lib_adapters/curb_adapter.rb +351 -0
- data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock/http_lib_adapters/em_http_request_adapter.rb +231 -0
- data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock/http_lib_adapters/excon_adapter.rb +165 -0
- data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock/http_lib_adapters/http_lib_adapter.rb +7 -0
- data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock/http_lib_adapters/http_lib_adapter_registry.rb +19 -0
- data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock/http_lib_adapters/http_rb/client.rb +17 -0
- data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock/http_lib_adapters/http_rb/request.rb +16 -0
- data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock/http_lib_adapters/http_rb/response.rb +64 -0
- data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock/http_lib_adapters/http_rb/streamer.rb +29 -0
- data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock/http_lib_adapters/http_rb/webmock.rb +68 -0
- data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock/http_lib_adapters/http_rb_adapter.rb +37 -0
- data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock/http_lib_adapters/httpclient_adapter.rb +259 -0
- data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock/http_lib_adapters/manticore_adapter.rb +145 -0
- data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock/http_lib_adapters/net_http.rb +385 -0
- data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock/http_lib_adapters/net_http_response.rb +34 -0
- data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock/http_lib_adapters/patron_adapter.rb +130 -0
- data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock/http_lib_adapters/typhoeus_hydra_adapter.rb +174 -0
- data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock/matchers/any_arg_matcher.rb +13 -0
- data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock/matchers/hash_argument_matcher.rb +21 -0
- data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock/matchers/hash_excluding_matcher.rb +15 -0
- data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock/matchers/hash_including_matcher.rb +17 -0
- data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock/minitest.rb +41 -0
- data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock/rack_response.rb +69 -0
- data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock/request_body_diff.rb +64 -0
- data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock/request_execution_verifier.rb +77 -0
- data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock/request_pattern.rb +405 -0
- data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock/request_registry.rb +35 -0
- data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock/request_signature.rb +54 -0
- data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock/request_signature_snippet.rb +61 -0
- data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock/request_stub.rb +100 -0
- data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock/response.rb +159 -0
- data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock/responses_sequence.rb +40 -0
- data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock/rspec.rb +42 -0
- data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock/rspec/matchers.rb +27 -0
- data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock/rspec/matchers/request_pattern_matcher.rb +78 -0
- data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock/rspec/matchers/webmock_matcher.rb +67 -0
- data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock/stub_registry.rb +82 -0
- data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock/stub_request_snippet.rb +38 -0
- data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock/test_unit.rb +20 -0
- data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock/util/hash_counter.rb +39 -0
- data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock/util/hash_keys_stringifier.rb +25 -0
- data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock/util/hash_validator.rb +17 -0
- data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock/util/headers.rb +64 -0
- data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock/util/json.rb +67 -0
- data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock/util/query_mapper.rb +281 -0
- data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock/util/uri.rb +111 -0
- data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock/util/values_stringifier.rb +20 -0
- data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock/util/version_checker.rb +111 -0
- data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock/version.rb +3 -0
- data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock/webmock.rb +163 -0
- data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/minitest/test_helper.rb +34 -0
- data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/minitest/test_webmock.rb +9 -0
- data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/minitest/webmock_spec.rb +60 -0
- data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/acceptance/async_http_client/async_http_client_spec.rb +375 -0
- 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
- data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/acceptance/curb/curb_spec.rb +499 -0
- data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/acceptance/curb/curb_spec_helper.rb +147 -0
- data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/acceptance/em_http_request/em_http_request_spec.rb +462 -0
- 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
- data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/acceptance/excon/excon_spec.rb +77 -0
- data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/acceptance/excon/excon_spec_helper.rb +52 -0
- data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/acceptance/http_rb/http_rb_spec.rb +93 -0
- data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/acceptance/http_rb/http_rb_spec_helper.rb +54 -0
- data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/acceptance/httpclient/httpclient_spec.rb +217 -0
- data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/acceptance/httpclient/httpclient_spec_helper.rb +57 -0
- data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/acceptance/manticore/manticore_spec.rb +107 -0
- data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/acceptance/manticore/manticore_spec_helper.rb +35 -0
- data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/acceptance/net_http/net_http_shared.rb +153 -0
- data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/acceptance/net_http/net_http_spec.rb +369 -0
- data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/acceptance/net_http/net_http_spec_helper.rb +64 -0
- data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/acceptance/net_http/real_net_http_spec.rb +20 -0
- data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/acceptance/patron/patron_spec.rb +125 -0
- data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/acceptance/patron/patron_spec_helper.rb +54 -0
- data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/acceptance/shared/allowing_and_disabling_net_connect.rb +313 -0
- data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/acceptance/shared/callbacks.rb +148 -0
- data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/acceptance/shared/complex_cross_concern_behaviors.rb +36 -0
- data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/acceptance/shared/enabling_and_disabling_webmock.rb +95 -0
- data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/acceptance/shared/precedence_of_stubs.rb +15 -0
- data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/acceptance/shared/request_expectations.rb +930 -0
- data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/acceptance/shared/returning_declared_responses.rb +409 -0
- data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/acceptance/shared/stubbing_requests.rb +678 -0
- data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/acceptance/typhoeus/typhoeus_hydra_spec.rb +135 -0
- data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/acceptance/typhoeus/typhoeus_hydra_spec_helper.rb +60 -0
- data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/acceptance/webmock_shared.rb +41 -0
- data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/fixtures/test.txt +1 -0
- data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/quality_spec.rb +84 -0
- data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/spec_helper.rb +48 -0
- data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/support/example_curl_output.txt +22 -0
- data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/support/failures.rb +9 -0
- data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/support/my_rack_app.rb +53 -0
- data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/support/network_connection.rb +19 -0
- data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/support/webmock_server.rb +70 -0
- data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/unit/api_spec.rb +175 -0
- data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/unit/errors_spec.rb +129 -0
- 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
- data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/unit/http_lib_adapters/http_lib_adapter_spec.rb +12 -0
- data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/unit/matchers/hash_excluding_matcher_spec.rb +61 -0
- data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/unit/matchers/hash_including_matcher_spec.rb +87 -0
- data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/unit/rack_response_spec.rb +112 -0
- data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/unit/request_body_diff_spec.rb +90 -0
- data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/unit/request_execution_verifier_spec.rb +208 -0
- data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/unit/request_pattern_spec.rb +736 -0
- data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/unit/request_registry_spec.rb +95 -0
- data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/unit/request_signature_snippet_spec.rb +89 -0
- data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/unit/request_signature_spec.rb +155 -0
- data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/unit/request_stub_spec.rb +199 -0
- data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/unit/response_spec.rb +286 -0
- data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/unit/stub_registry_spec.rb +103 -0
- data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/unit/stub_request_snippet_spec.rb +115 -0
- data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/unit/util/hash_counter_spec.rb +39 -0
- data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/unit/util/hash_keys_stringifier_spec.rb +27 -0
- data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/unit/util/headers_spec.rb +28 -0
- data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/unit/util/json_spec.rb +33 -0
- data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/unit/util/query_mapper_spec.rb +157 -0
- data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/unit/util/uri_spec.rb +371 -0
- data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/unit/util/version_checker_spec.rb +65 -0
- data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/unit/webmock_spec.rb +60 -0
- data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/test/http_request.rb +24 -0
- data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/test/shared_test.rb +108 -0
- data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/test/test_helper.rb +23 -0
- data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/test/test_webmock.rb +12 -0
- data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/webmock.gemspec +54 -0
- data/vendor/bundle/jruby/2.5.0/specifications/addressable-2.7.0.gemspec +39 -0
- data/vendor/bundle/jruby/2.5.0/specifications/crack-0.4.5.gemspec +32 -0
- data/vendor/bundle/jruby/2.5.0/specifications/hashdiff-1.0.1.gemspec +46 -0
- data/vendor/bundle/jruby/2.5.0/specifications/public_suffix-4.0.6.gemspec +24 -0
- data/vendor/bundle/jruby/2.5.0/specifications/rexml-3.2.5.gemspec +42 -0
- data/vendor/bundle/jruby/2.5.0/specifications/webmock-3.13.0.gemspec +85 -0
- 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
|