vagrant-unbundled 2.0.0.1 → 2.0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (351) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +2 -2
  3. data/CHANGELOG.md +34 -0
  4. data/Gemfile.lock +10 -10
  5. data/README.md +2 -2
  6. data/contrib/sudoers/linux-suse +6 -7
  7. data/lib/vagrant/plugin/v2/command.rb +3 -0
  8. data/lib/vagrant/plugin/v2/communicator.rb +1 -1
  9. data/lib/vagrant/registry.rb +1 -1
  10. data/lib/vagrant/util/downloader.rb +1 -2
  11. data/lib/vagrant/util/is_port_open.rb +2 -1
  12. data/lib/vagrant/util/keypair.rb +1 -1
  13. data/lib/vagrant/util/platform.rb +39 -23
  14. data/plugins/commands/destroy/command.rb +31 -10
  15. data/plugins/communicators/ssh/communicator.rb +1 -0
  16. data/plugins/communicators/winrm/helper.rb +6 -1
  17. data/plugins/guests/solaris11/cap/change_host_name.rb +0 -2
  18. data/plugins/guests/solaris11/cap/configure_networks.rb +1 -7
  19. data/plugins/guests/solaris11/plugin.rb +5 -35
  20. data/plugins/guests/windows/cap/public_key.rb +2 -0
  21. data/plugins/guests/windows/guest_network.rb +3 -3
  22. data/plugins/guests/windows/scripts/reboot_detect.ps1 +5 -0
  23. data/plugins/providers/docker/driver.rb +1 -1
  24. data/plugins/providers/docker/executor/local.rb +4 -0
  25. data/plugins/providers/docker/executor/vagrant.rb +4 -0
  26. data/plugins/providers/hyperv/scripts/import_vm_vmcx.ps1 +1 -1
  27. data/plugins/providers/virtualbox/driver/meta.rb +1 -0
  28. data/plugins/providers/virtualbox/driver/version_5_2.rb +16 -0
  29. data/plugins/providers/virtualbox/plugin.rb +1 -0
  30. data/plugins/providers/virtualbox/synced_folder.rb +1 -1
  31. data/plugins/provisioners/chef/provisioner/chef_client.rb +30 -23
  32. data/plugins/provisioners/chef/provisioner/chef_solo.rb +26 -19
  33. data/plugins/provisioners/chef/provisioner/chef_zero.rb +29 -22
  34. data/plugins/provisioners/puppet/provisioner/puppet.rb +23 -4
  35. data/plugins/provisioners/salt/bootstrap-salt.ps1 +15 -3
  36. data/plugins/provisioners/salt/bootstrap-salt.sh +2 -0
  37. data/plugins/provisioners/salt/config.rb +11 -0
  38. data/plugins/provisioners/salt/provisioner.rb +10 -7
  39. data/plugins/provisioners/shell/provisioner.rb +1 -1
  40. data/templates/locales/en.yml +5 -0
  41. data/test/unit/base.rb +2 -0
  42. data/test/unit/plugins/commands/destroy/command_test.rb +155 -0
  43. data/test/unit/plugins/communicators/winrm/helper_test.rb +33 -0
  44. data/test/unit/plugins/guests/solaris11/cap/change_host_name_test.rb +36 -0
  45. data/test/unit/plugins/guests/solaris11/cap/configure_networks_test.rb +56 -0
  46. data/test/unit/plugins/providers/virtualbox/synced_folder_test.rb +26 -0
  47. data/test/unit/plugins/provisioners/salt/config_test.rb +42 -0
  48. data/test/unit/plugins/provisioners/salt/provisioner_test.rb +16 -1
  49. data/test/unit/plugins/provisioners/shell/config_test.rb +3 -3
  50. data/test/unit/plugins/pushes/local-exec/config_test.rb +2 -2
  51. data/test/unit/vagrant/util/downloader_test.rb +28 -0
  52. data/test/unit/vagrant/util/platform_test.rb +58 -0
  53. data/vagrant.gemspec +1 -1
  54. data/vendor/bundle/ruby/2.4.0/bin/rwinrmcp +5 -0
  55. data/vendor/bundle/ruby/2.4.0/bin/vagrant +5 -0
  56. data/vendor/bundle/ruby/2.4.0/bin/vagrant-spec +5 -0
  57. data/vendor/bundle/ruby/2.4.0/bundler/gems/vagrant-spec-af86757912f7/vagrant-spec.gemspec +3 -3
  58. data/vendor/bundle/ruby/2.4.0/gems/addressable-2.5.2/CHANGELOG.md +216 -0
  59. data/vendor/bundle/ruby/2.4.0/gems/addressable-2.5.2/Gemfile +32 -0
  60. data/vendor/bundle/ruby/2.4.0/gems/addressable-2.5.2/LICENSE.txt +202 -0
  61. data/vendor/bundle/ruby/2.4.0/gems/addressable-2.5.2/README.md +121 -0
  62. data/vendor/bundle/ruby/2.4.0/gems/addressable-2.5.2/Rakefile +32 -0
  63. data/vendor/bundle/ruby/2.4.0/gems/addressable-2.5.2/data/unicode.data +0 -0
  64. data/vendor/bundle/ruby/2.4.0/gems/addressable-2.5.2/lib/addressable/idna/native.rb +59 -0
  65. data/vendor/bundle/ruby/2.4.0/gems/addressable-2.5.2/lib/addressable/idna/pure.rb +677 -0
  66. data/vendor/bundle/ruby/2.4.0/gems/addressable-2.5.2/lib/addressable/idna.rb +25 -0
  67. data/vendor/bundle/ruby/2.4.0/gems/addressable-2.5.2/lib/addressable/template.rb +1065 -0
  68. data/vendor/bundle/ruby/2.4.0/gems/addressable-2.5.2/lib/addressable/uri.rb +2492 -0
  69. data/vendor/bundle/ruby/2.4.0/gems/addressable-2.5.2/lib/addressable/version.rb +30 -0
  70. data/vendor/bundle/ruby/2.4.0/gems/addressable-2.5.2/lib/addressable.rb +2 -0
  71. data/vendor/bundle/ruby/2.4.0/gems/addressable-2.5.2/spec/addressable/idna_spec.rb +298 -0
  72. data/vendor/bundle/ruby/2.4.0/gems/addressable-2.5.2/spec/addressable/net_http_compat_spec.rb +28 -0
  73. data/vendor/bundle/ruby/2.4.0/gems/addressable-2.5.2/spec/addressable/rack_mount_compat_spec.rb +104 -0
  74. data/vendor/bundle/ruby/2.4.0/gems/addressable-2.5.2/spec/addressable/security_spec.rb +57 -0
  75. data/vendor/bundle/ruby/2.4.0/gems/addressable-2.5.2/spec/addressable/template_spec.rb +1419 -0
  76. data/vendor/bundle/ruby/2.4.0/gems/addressable-2.5.2/spec/addressable/uri_spec.rb +6468 -0
  77. data/vendor/bundle/ruby/2.4.0/gems/addressable-2.5.2/spec/spec_helper.rb +21 -0
  78. data/vendor/bundle/ruby/2.4.0/gems/addressable-2.5.2/tasks/clobber.rake +2 -0
  79. data/vendor/bundle/ruby/2.4.0/gems/addressable-2.5.2/tasks/gem.rake +91 -0
  80. data/vendor/bundle/ruby/2.4.0/gems/addressable-2.5.2/tasks/git.rake +45 -0
  81. data/vendor/bundle/ruby/2.4.0/gems/addressable-2.5.2/tasks/metrics.rake +22 -0
  82. data/vendor/bundle/ruby/2.4.0/gems/addressable-2.5.2/tasks/rspec.rake +21 -0
  83. data/vendor/bundle/ruby/2.4.0/gems/addressable-2.5.2/tasks/yard.rake +27 -0
  84. data/vendor/bundle/ruby/2.4.0/gems/hashdiff-0.3.7/.gitignore +15 -0
  85. data/vendor/bundle/ruby/2.4.0/gems/hashdiff-0.3.7/.rspec +1 -0
  86. data/vendor/bundle/ruby/2.4.0/gems/hashdiff-0.3.7/.travis.yml +13 -0
  87. data/vendor/bundle/ruby/2.4.0/gems/hashdiff-0.3.7/.yardopts +1 -0
  88. data/vendor/bundle/ruby/2.4.0/gems/hashdiff-0.3.7/Gemfile +6 -0
  89. data/vendor/bundle/ruby/2.4.0/gems/hashdiff-0.3.7/LICENSE +19 -0
  90. data/vendor/bundle/ruby/2.4.0/gems/hashdiff-0.3.7/README.md +265 -0
  91. data/vendor/bundle/ruby/2.4.0/gems/hashdiff-0.3.7/Rakefile +13 -0
  92. data/vendor/bundle/ruby/2.4.0/gems/hashdiff-0.3.7/changelog.md +72 -0
  93. data/vendor/bundle/ruby/2.4.0/gems/hashdiff-0.3.7/hashdiff.gemspec +25 -0
  94. data/vendor/bundle/ruby/2.4.0/gems/hashdiff-0.3.7/lib/hashdiff/diff.rb +232 -0
  95. data/vendor/bundle/ruby/2.4.0/gems/hashdiff-0.3.7/lib/hashdiff/lcs.rb +69 -0
  96. data/vendor/bundle/ruby/2.4.0/gems/hashdiff-0.3.7/lib/hashdiff/linear_compare_array.rb +155 -0
  97. data/vendor/bundle/ruby/2.4.0/gems/hashdiff-0.3.7/lib/hashdiff/patch.rb +88 -0
  98. data/vendor/bundle/ruby/2.4.0/gems/hashdiff-0.3.7/lib/hashdiff/util.rb +146 -0
  99. data/vendor/bundle/ruby/2.4.0/gems/hashdiff-0.3.7/lib/hashdiff/version.rb +3 -0
  100. data/vendor/bundle/ruby/2.4.0/gems/hashdiff-0.3.7/lib/hashdiff.rb +6 -0
  101. data/vendor/bundle/ruby/2.4.0/gems/hashdiff-0.3.7/spec/hashdiff/best_diff_spec.rb +74 -0
  102. data/vendor/bundle/ruby/2.4.0/gems/hashdiff-0.3.7/spec/hashdiff/diff_array_spec.rb +60 -0
  103. data/vendor/bundle/ruby/2.4.0/gems/hashdiff-0.3.7/spec/hashdiff/diff_spec.rb +339 -0
  104. data/vendor/bundle/ruby/2.4.0/gems/hashdiff-0.3.7/spec/hashdiff/lcs_spec.rb +75 -0
  105. data/vendor/bundle/ruby/2.4.0/gems/hashdiff-0.3.7/spec/hashdiff/linear_compare_array_spec.rb +48 -0
  106. data/vendor/bundle/ruby/2.4.0/gems/hashdiff-0.3.7/spec/hashdiff/patch_spec.rb +183 -0
  107. data/vendor/bundle/ruby/2.4.0/gems/hashdiff-0.3.7/spec/hashdiff/util_spec.rb +78 -0
  108. data/vendor/bundle/ruby/2.4.0/gems/hashdiff-0.3.7/spec/spec_helper.rb +13 -0
  109. data/vendor/bundle/ruby/2.4.0/gems/multi_json-1.12.2/CHANGELOG.md +250 -0
  110. data/vendor/bundle/ruby/2.4.0/gems/multi_json-1.12.2/CONTRIBUTING.md +46 -0
  111. data/vendor/bundle/ruby/2.4.0/gems/multi_json-1.12.2/LICENSE.md +20 -0
  112. data/vendor/bundle/ruby/2.4.0/gems/multi_json-1.12.2/README.md +122 -0
  113. data/vendor/bundle/ruby/2.4.0/gems/multi_json-1.12.2/lib/multi_json/adapter.rb +49 -0
  114. data/vendor/bundle/ruby/2.4.0/gems/multi_json-1.12.2/lib/multi_json/adapter_error.rb +15 -0
  115. data/vendor/bundle/ruby/2.4.0/gems/multi_json-1.12.2/lib/multi_json/adapters/gson.rb +20 -0
  116. data/vendor/bundle/ruby/2.4.0/gems/multi_json-1.12.2/lib/multi_json/adapters/jr_jackson.rb +25 -0
  117. data/vendor/bundle/ruby/2.4.0/gems/multi_json-1.12.2/lib/multi_json/adapters/json_common.rb +23 -0
  118. data/vendor/bundle/ruby/2.4.0/gems/multi_json-1.12.2/lib/multi_json/adapters/json_gem.rb +11 -0
  119. data/vendor/bundle/ruby/2.4.0/gems/multi_json-1.12.2/lib/multi_json/adapters/json_pure.rb +11 -0
  120. data/vendor/bundle/ruby/2.4.0/gems/multi_json-1.12.2/lib/multi_json/adapters/nsjsonserialization.rb +32 -0
  121. data/vendor/bundle/ruby/2.4.0/gems/multi_json-1.12.2/lib/multi_json/adapters/oj.rb +25 -0
  122. data/vendor/bundle/ruby/2.4.0/gems/multi_json-1.12.2/lib/multi_json/adapters/ok_json.rb +23 -0
  123. data/vendor/bundle/ruby/2.4.0/gems/multi_json-1.12.2/lib/multi_json/adapters/yajl.rb +19 -0
  124. data/vendor/bundle/ruby/2.4.0/gems/multi_json-1.12.2/lib/multi_json/convertible_hash_keys.rb +43 -0
  125. data/vendor/bundle/ruby/2.4.0/gems/multi_json-1.12.2/lib/multi_json/options.rb +39 -0
  126. data/vendor/bundle/ruby/2.4.0/gems/multi_json-1.12.2/lib/multi_json/options_cache.rb +29 -0
  127. data/vendor/bundle/ruby/2.4.0/gems/multi_json-1.12.2/lib/multi_json/parse_error.rb +17 -0
  128. data/vendor/bundle/ruby/2.4.0/gems/multi_json-1.12.2/lib/multi_json/vendor/okjson.rb +606 -0
  129. data/vendor/bundle/ruby/2.4.0/gems/multi_json-1.12.2/lib/multi_json/version.rb +17 -0
  130. data/vendor/bundle/ruby/2.4.0/gems/multi_json-1.12.2/lib/multi_json.rb +161 -0
  131. data/vendor/bundle/ruby/2.4.0/gems/public_suffix-3.0.1/.gitignore +11 -0
  132. data/vendor/bundle/ruby/2.4.0/gems/public_suffix-3.0.1/.rubocop.yml +32 -0
  133. data/vendor/bundle/ruby/2.4.0/gems/public_suffix-3.0.1/.rubocop_defaults.yml +177 -0
  134. data/vendor/bundle/ruby/2.4.0/gems/public_suffix-3.0.1/.travis.yml +24 -0
  135. data/vendor/bundle/ruby/2.4.0/gems/public_suffix-3.0.1/.yardopts +1 -0
  136. data/vendor/bundle/ruby/2.4.0/gems/public_suffix-3.0.1/2.0-Upgrade.md +52 -0
  137. data/vendor/bundle/ruby/2.4.0/gems/public_suffix-3.0.1/CHANGELOG.md +330 -0
  138. data/vendor/bundle/ruby/2.4.0/gems/public_suffix-3.0.1/Gemfile +10 -0
  139. data/vendor/bundle/ruby/2.4.0/gems/public_suffix-3.0.1/LICENSE.txt +22 -0
  140. data/vendor/bundle/ruby/2.4.0/gems/public_suffix-3.0.1/README.md +202 -0
  141. data/vendor/bundle/ruby/2.4.0/gems/public_suffix-3.0.1/Rakefile +49 -0
  142. data/vendor/bundle/ruby/2.4.0/gems/public_suffix-3.0.1/bin/console +14 -0
  143. data/vendor/bundle/ruby/2.4.0/gems/public_suffix-3.0.1/data/list.txt +12288 -0
  144. data/vendor/bundle/ruby/2.4.0/gems/public_suffix-3.0.1/lib/public_suffix/domain.rb +235 -0
  145. data/vendor/bundle/ruby/2.4.0/gems/public_suffix-3.0.1/lib/public_suffix/errors.rb +39 -0
  146. data/vendor/bundle/ruby/2.4.0/gems/public_suffix-3.0.1/lib/public_suffix/list.rb +243 -0
  147. data/vendor/bundle/ruby/2.4.0/gems/public_suffix-3.0.1/lib/public_suffix/rule.rb +348 -0
  148. data/vendor/bundle/ruby/2.4.0/gems/public_suffix-3.0.1/lib/public_suffix/version.rb +10 -0
  149. data/vendor/bundle/ruby/2.4.0/gems/public_suffix-3.0.1/lib/public_suffix.rb +175 -0
  150. data/vendor/bundle/ruby/2.4.0/gems/public_suffix-3.0.1/public_suffix.gemspec +25 -0
  151. data/vendor/bundle/ruby/2.4.0/gems/public_suffix-3.0.1/test/.empty +2 -0
  152. data/vendor/bundle/ruby/2.4.0/gems/public_suffix-3.0.1/test/acceptance_test.rb +127 -0
  153. data/vendor/bundle/ruby/2.4.0/gems/public_suffix-3.0.1/test/benchmarks/bm_find.rb +66 -0
  154. data/vendor/bundle/ruby/2.4.0/gems/public_suffix-3.0.1/test/benchmarks/bm_find_all.rb +102 -0
  155. data/vendor/bundle/ruby/2.4.0/gems/public_suffix-3.0.1/test/benchmarks/bm_names.rb +91 -0
  156. data/vendor/bundle/ruby/2.4.0/gems/public_suffix-3.0.1/test/benchmarks/bm_select.rb +26 -0
  157. data/vendor/bundle/ruby/2.4.0/gems/public_suffix-3.0.1/test/benchmarks/bm_select_incremental.rb +25 -0
  158. data/vendor/bundle/ruby/2.4.0/gems/public_suffix-3.0.1/test/benchmarks/bm_valid.rb +101 -0
  159. data/vendor/bundle/ruby/2.4.0/gems/public_suffix-3.0.1/test/profilers/domain_profiler.rb +12 -0
  160. data/vendor/bundle/ruby/2.4.0/gems/public_suffix-3.0.1/test/profilers/find_profiler.rb +12 -0
  161. data/vendor/bundle/ruby/2.4.0/gems/public_suffix-3.0.1/test/profilers/find_profiler_jp.rb +12 -0
  162. data/vendor/bundle/ruby/2.4.0/gems/public_suffix-3.0.1/test/profilers/initialization_profiler.rb +11 -0
  163. data/vendor/bundle/ruby/2.4.0/gems/public_suffix-3.0.1/test/profilers/list_profsize.rb +11 -0
  164. data/vendor/bundle/ruby/2.4.0/gems/public_suffix-3.0.1/test/profilers/object_binsize.rb +57 -0
  165. data/vendor/bundle/ruby/2.4.0/gems/public_suffix-3.0.1/test/psl_test.rb +49 -0
  166. data/vendor/bundle/ruby/2.4.0/gems/public_suffix-3.0.1/test/test_helper.rb +13 -0
  167. data/vendor/bundle/ruby/2.4.0/gems/public_suffix-3.0.1/test/tests.txt +98 -0
  168. data/vendor/bundle/ruby/2.4.0/gems/public_suffix-3.0.1/test/unit/domain_test.rb +104 -0
  169. data/vendor/bundle/ruby/2.4.0/gems/public_suffix-3.0.1/test/unit/errors_test.rb +23 -0
  170. data/vendor/bundle/ruby/2.4.0/gems/public_suffix-3.0.1/test/unit/list_test.rb +239 -0
  171. data/vendor/bundle/ruby/2.4.0/gems/public_suffix-3.0.1/test/unit/public_suffix_test.rb +186 -0
  172. data/vendor/bundle/ruby/2.4.0/gems/public_suffix-3.0.1/test/unit/rule_test.rb +220 -0
  173. data/vendor/bundle/ruby/2.4.0/gems/webmock-2.3.2/.gemtest +0 -0
  174. data/vendor/bundle/ruby/2.4.0/gems/webmock-2.3.2/.gitignore +34 -0
  175. data/vendor/bundle/ruby/2.4.0/gems/webmock-2.3.2/.rspec-tm +2 -0
  176. data/vendor/bundle/ruby/2.4.0/gems/webmock-2.3.2/.travis.yml +24 -0
  177. data/vendor/bundle/ruby/2.4.0/gems/webmock-2.3.2/CHANGELOG.md +1460 -0
  178. data/vendor/bundle/ruby/2.4.0/gems/webmock-2.3.2/Gemfile +9 -0
  179. data/vendor/bundle/ruby/2.4.0/gems/webmock-2.3.2/LICENSE +20 -0
  180. data/vendor/bundle/ruby/2.4.0/gems/webmock-2.3.2/README.md +1045 -0
  181. data/vendor/bundle/ruby/2.4.0/gems/webmock-2.3.2/Rakefile +30 -0
  182. data/vendor/bundle/ruby/2.4.0/gems/webmock-2.3.2/lib/webmock/api.rb +97 -0
  183. data/vendor/bundle/ruby/2.4.0/gems/webmock-2.3.2/lib/webmock/assertion_failure.rb +11 -0
  184. data/vendor/bundle/ruby/2.4.0/gems/webmock-2.3.2/lib/webmock/callback_registry.rb +35 -0
  185. data/vendor/bundle/ruby/2.4.0/gems/webmock-2.3.2/lib/webmock/config.rb +18 -0
  186. data/vendor/bundle/ruby/2.4.0/gems/webmock-2.3.2/lib/webmock/cucumber.rb +10 -0
  187. data/vendor/bundle/ruby/2.4.0/gems/webmock-2.3.2/lib/webmock/deprecation.rb +9 -0
  188. data/vendor/bundle/ruby/2.4.0/gems/webmock-2.3.2/lib/webmock/errors.rb +17 -0
  189. data/vendor/bundle/ruby/2.4.0/gems/webmock-2.3.2/lib/webmock/http_lib_adapters/curb_adapter.rb +337 -0
  190. data/vendor/bundle/ruby/2.4.0/gems/webmock-2.3.2/lib/webmock/http_lib_adapters/em_http_request_adapter.rb +228 -0
  191. data/vendor/bundle/ruby/2.4.0/gems/webmock-2.3.2/lib/webmock/http_lib_adapters/excon_adapter.rb +162 -0
  192. data/vendor/bundle/ruby/2.4.0/gems/webmock-2.3.2/lib/webmock/http_lib_adapters/http_lib_adapter.rb +7 -0
  193. data/vendor/bundle/ruby/2.4.0/gems/webmock-2.3.2/lib/webmock/http_lib_adapters/http_lib_adapter_registry.rb +19 -0
  194. data/vendor/bundle/ruby/2.4.0/gems/webmock-2.3.2/lib/webmock/http_lib_adapters/http_rb/client.rb +14 -0
  195. data/vendor/bundle/ruby/2.4.0/gems/webmock-2.3.2/lib/webmock/http_lib_adapters/http_rb/request.rb +10 -0
  196. data/vendor/bundle/ruby/2.4.0/gems/webmock-2.3.2/lib/webmock/http_lib_adapters/http_rb/response.rb +43 -0
  197. data/vendor/bundle/ruby/2.4.0/gems/webmock-2.3.2/lib/webmock/http_lib_adapters/http_rb/streamer.rb +25 -0
  198. data/vendor/bundle/ruby/2.4.0/gems/webmock-2.3.2/lib/webmock/http_lib_adapters/http_rb/webmock.rb +68 -0
  199. data/vendor/bundle/ruby/2.4.0/gems/webmock-2.3.2/lib/webmock/http_lib_adapters/http_rb_adapter.rb +37 -0
  200. data/vendor/bundle/ruby/2.4.0/gems/webmock-2.3.2/lib/webmock/http_lib_adapters/httpclient_adapter.rb +240 -0
  201. data/vendor/bundle/ruby/2.4.0/gems/webmock-2.3.2/lib/webmock/http_lib_adapters/manticore_adapter.rb +127 -0
  202. data/vendor/bundle/ruby/2.4.0/gems/webmock-2.3.2/lib/webmock/http_lib_adapters/net_http.rb +362 -0
  203. data/vendor/bundle/ruby/2.4.0/gems/webmock-2.3.2/lib/webmock/http_lib_adapters/net_http_response.rb +34 -0
  204. data/vendor/bundle/ruby/2.4.0/gems/webmock-2.3.2/lib/webmock/http_lib_adapters/patron_adapter.rb +130 -0
  205. data/vendor/bundle/ruby/2.4.0/gems/webmock-2.3.2/lib/webmock/http_lib_adapters/typhoeus_hydra_adapter.rb +174 -0
  206. data/vendor/bundle/ruby/2.4.0/gems/webmock-2.3.2/lib/webmock/matchers/hash_including_matcher.rb +36 -0
  207. data/vendor/bundle/ruby/2.4.0/gems/webmock-2.3.2/lib/webmock/minitest.rb +41 -0
  208. data/vendor/bundle/ruby/2.4.0/gems/webmock-2.3.2/lib/webmock/rack_response.rb +69 -0
  209. data/vendor/bundle/ruby/2.4.0/gems/webmock-2.3.2/lib/webmock/request_body_diff.rb +64 -0
  210. data/vendor/bundle/ruby/2.4.0/gems/webmock-2.3.2/lib/webmock/request_execution_verifier.rb +78 -0
  211. data/vendor/bundle/ruby/2.4.0/gems/webmock-2.3.2/lib/webmock/request_pattern.rb +343 -0
  212. data/vendor/bundle/ruby/2.4.0/gems/webmock-2.3.2/lib/webmock/request_registry.rb +35 -0
  213. data/vendor/bundle/ruby/2.4.0/gems/webmock-2.3.2/lib/webmock/request_signature.rb +54 -0
  214. data/vendor/bundle/ruby/2.4.0/gems/webmock-2.3.2/lib/webmock/request_signature_snippet.rb +61 -0
  215. data/vendor/bundle/ruby/2.4.0/gems/webmock-2.3.2/lib/webmock/request_stub.rb +100 -0
  216. data/vendor/bundle/ruby/2.4.0/gems/webmock-2.3.2/lib/webmock/response.rb +153 -0
  217. data/vendor/bundle/ruby/2.4.0/gems/webmock-2.3.2/lib/webmock/responses_sequence.rb +40 -0
  218. data/vendor/bundle/ruby/2.4.0/gems/webmock-2.3.2/lib/webmock/rspec/matchers/request_pattern_matcher.rb +78 -0
  219. data/vendor/bundle/ruby/2.4.0/gems/webmock-2.3.2/lib/webmock/rspec/matchers/webmock_matcher.rb +52 -0
  220. data/vendor/bundle/ruby/2.4.0/gems/webmock-2.3.2/lib/webmock/rspec/matchers.rb +27 -0
  221. data/vendor/bundle/ruby/2.4.0/gems/webmock-2.3.2/lib/webmock/rspec.rb +35 -0
  222. data/vendor/bundle/ruby/2.4.0/gems/webmock-2.3.2/lib/webmock/stub_registry.rb +67 -0
  223. data/vendor/bundle/ruby/2.4.0/gems/webmock-2.3.2/lib/webmock/stub_request_snippet.rb +34 -0
  224. data/vendor/bundle/ruby/2.4.0/gems/webmock-2.3.2/lib/webmock/test_unit.rb +22 -0
  225. data/vendor/bundle/ruby/2.4.0/gems/webmock-2.3.2/lib/webmock/util/hash_counter.rb +32 -0
  226. data/vendor/bundle/ruby/2.4.0/gems/webmock-2.3.2/lib/webmock/util/hash_keys_stringifier.rb +25 -0
  227. data/vendor/bundle/ruby/2.4.0/gems/webmock-2.3.2/lib/webmock/util/hash_validator.rb +17 -0
  228. data/vendor/bundle/ruby/2.4.0/gems/webmock-2.3.2/lib/webmock/util/headers.rb +49 -0
  229. data/vendor/bundle/ruby/2.4.0/gems/webmock-2.3.2/lib/webmock/util/json.rb +78 -0
  230. data/vendor/bundle/ruby/2.4.0/gems/webmock-2.3.2/lib/webmock/util/query_mapper.rb +279 -0
  231. data/vendor/bundle/ruby/2.4.0/gems/webmock-2.3.2/lib/webmock/util/uri.rb +111 -0
  232. data/vendor/bundle/ruby/2.4.0/gems/webmock-2.3.2/lib/webmock/util/version_checker.rb +111 -0
  233. data/vendor/bundle/ruby/2.4.0/gems/webmock-2.3.2/lib/webmock/version.rb +3 -0
  234. data/vendor/bundle/ruby/2.4.0/gems/webmock-2.3.2/lib/webmock/webmock.rb +156 -0
  235. data/vendor/bundle/ruby/2.4.0/gems/webmock-2.3.2/lib/webmock.rb +54 -0
  236. data/vendor/bundle/ruby/2.4.0/gems/webmock-2.3.2/minitest/test_helper.rb +34 -0
  237. data/vendor/bundle/ruby/2.4.0/gems/webmock-2.3.2/minitest/test_webmock.rb +9 -0
  238. data/vendor/bundle/ruby/2.4.0/gems/webmock-2.3.2/minitest/webmock_spec.rb +60 -0
  239. data/vendor/bundle/ruby/2.4.0/gems/webmock-2.3.2/spec/acceptance/curb/curb_spec.rb +466 -0
  240. data/vendor/bundle/ruby/2.4.0/gems/webmock-2.3.2/spec/acceptance/curb/curb_spec_helper.rb +147 -0
  241. data/vendor/bundle/ruby/2.4.0/gems/webmock-2.3.2/spec/acceptance/em_http_request/em_http_request_spec.rb +406 -0
  242. data/vendor/bundle/ruby/2.4.0/gems/webmock-2.3.2/spec/acceptance/em_http_request/em_http_request_spec_helper.rb +77 -0
  243. data/vendor/bundle/ruby/2.4.0/gems/webmock-2.3.2/spec/acceptance/excon/excon_spec.rb +75 -0
  244. data/vendor/bundle/ruby/2.4.0/gems/webmock-2.3.2/spec/acceptance/excon/excon_spec_helper.rb +50 -0
  245. data/vendor/bundle/ruby/2.4.0/gems/webmock-2.3.2/spec/acceptance/http_rb/http_rb_spec.rb +73 -0
  246. data/vendor/bundle/ruby/2.4.0/gems/webmock-2.3.2/spec/acceptance/http_rb/http_rb_spec_helper.rb +51 -0
  247. data/vendor/bundle/ruby/2.4.0/gems/webmock-2.3.2/spec/acceptance/httpclient/httpclient_spec.rb +209 -0
  248. data/vendor/bundle/ruby/2.4.0/gems/webmock-2.3.2/spec/acceptance/httpclient/httpclient_spec_helper.rb +57 -0
  249. data/vendor/bundle/ruby/2.4.0/gems/webmock-2.3.2/spec/acceptance/manticore/manticore_spec.rb +56 -0
  250. data/vendor/bundle/ruby/2.4.0/gems/webmock-2.3.2/spec/acceptance/manticore/manticore_spec_helper.rb +35 -0
  251. data/vendor/bundle/ruby/2.4.0/gems/webmock-2.3.2/spec/acceptance/net_http/net_http_shared.rb +142 -0
  252. data/vendor/bundle/ruby/2.4.0/gems/webmock-2.3.2/spec/acceptance/net_http/net_http_spec.rb +317 -0
  253. data/vendor/bundle/ruby/2.4.0/gems/webmock-2.3.2/spec/acceptance/net_http/net_http_spec_helper.rb +64 -0
  254. data/vendor/bundle/ruby/2.4.0/gems/webmock-2.3.2/spec/acceptance/net_http/real_net_http_spec.rb +20 -0
  255. data/vendor/bundle/ruby/2.4.0/gems/webmock-2.3.2/spec/acceptance/patron/patron_spec.rb +118 -0
  256. data/vendor/bundle/ruby/2.4.0/gems/webmock-2.3.2/spec/acceptance/patron/patron_spec_helper.rb +54 -0
  257. data/vendor/bundle/ruby/2.4.0/gems/webmock-2.3.2/spec/acceptance/shared/allowing_and_disabling_net_connect.rb +313 -0
  258. data/vendor/bundle/ruby/2.4.0/gems/webmock-2.3.2/spec/acceptance/shared/callbacks.rb +147 -0
  259. data/vendor/bundle/ruby/2.4.0/gems/webmock-2.3.2/spec/acceptance/shared/complex_cross_concern_behaviors.rb +36 -0
  260. data/vendor/bundle/ruby/2.4.0/gems/webmock-2.3.2/spec/acceptance/shared/enabling_and_disabling_webmock.rb +95 -0
  261. data/vendor/bundle/ruby/2.4.0/gems/webmock-2.3.2/spec/acceptance/shared/precedence_of_stubs.rb +15 -0
  262. data/vendor/bundle/ruby/2.4.0/gems/webmock-2.3.2/spec/acceptance/shared/request_expectations.rb +916 -0
  263. data/vendor/bundle/ruby/2.4.0/gems/webmock-2.3.2/spec/acceptance/shared/returning_declared_responses.rb +388 -0
  264. data/vendor/bundle/ruby/2.4.0/gems/webmock-2.3.2/spec/acceptance/shared/stubbing_requests.rb +583 -0
  265. data/vendor/bundle/ruby/2.4.0/gems/webmock-2.3.2/spec/acceptance/typhoeus/typhoeus_hydra_spec.rb +135 -0
  266. data/vendor/bundle/ruby/2.4.0/gems/webmock-2.3.2/spec/acceptance/typhoeus/typhoeus_hydra_spec_helper.rb +60 -0
  267. data/vendor/bundle/ruby/2.4.0/gems/webmock-2.3.2/spec/acceptance/webmock_shared.rb +41 -0
  268. data/vendor/bundle/ruby/2.4.0/gems/webmock-2.3.2/spec/fixtures/test.txt +1 -0
  269. data/vendor/bundle/ruby/2.4.0/gems/webmock-2.3.2/spec/quality_spec.rb +84 -0
  270. data/vendor/bundle/ruby/2.4.0/gems/webmock-2.3.2/spec/spec_helper.rb +48 -0
  271. data/vendor/bundle/ruby/2.4.0/gems/webmock-2.3.2/spec/support/example_curl_output.txt +22 -0
  272. data/vendor/bundle/ruby/2.4.0/gems/webmock-2.3.2/spec/support/failures.rb +9 -0
  273. data/vendor/bundle/ruby/2.4.0/gems/webmock-2.3.2/spec/support/my_rack_app.rb +53 -0
  274. data/vendor/bundle/ruby/2.4.0/gems/webmock-2.3.2/spec/support/network_connection.rb +19 -0
  275. data/vendor/bundle/ruby/2.4.0/gems/webmock-2.3.2/spec/support/webmock_server.rb +69 -0
  276. data/vendor/bundle/ruby/2.4.0/gems/webmock-2.3.2/spec/unit/api_spec.rb +75 -0
  277. data/vendor/bundle/ruby/2.4.0/gems/webmock-2.3.2/spec/unit/errors_spec.rb +129 -0
  278. data/vendor/bundle/ruby/2.4.0/gems/webmock-2.3.2/spec/unit/http_lib_adapters/http_lib_adapter_registry_spec.rb +17 -0
  279. data/vendor/bundle/ruby/2.4.0/gems/webmock-2.3.2/spec/unit/http_lib_adapters/http_lib_adapter_spec.rb +12 -0
  280. data/vendor/bundle/ruby/2.4.0/gems/webmock-2.3.2/spec/unit/matchers/hash_including_matcher_spec.rb +87 -0
  281. data/vendor/bundle/ruby/2.4.0/gems/webmock-2.3.2/spec/unit/rack_response_spec.rb +112 -0
  282. data/vendor/bundle/ruby/2.4.0/gems/webmock-2.3.2/spec/unit/request_body_diff_spec.rb +90 -0
  283. data/vendor/bundle/ruby/2.4.0/gems/webmock-2.3.2/spec/unit/request_execution_verifier_spec.rb +208 -0
  284. data/vendor/bundle/ruby/2.4.0/gems/webmock-2.3.2/spec/unit/request_pattern_spec.rb +590 -0
  285. data/vendor/bundle/ruby/2.4.0/gems/webmock-2.3.2/spec/unit/request_registry_spec.rb +76 -0
  286. data/vendor/bundle/ruby/2.4.0/gems/webmock-2.3.2/spec/unit/request_signature_snippet_spec.rb +89 -0
  287. data/vendor/bundle/ruby/2.4.0/gems/webmock-2.3.2/spec/unit/request_signature_spec.rb +155 -0
  288. data/vendor/bundle/ruby/2.4.0/gems/webmock-2.3.2/spec/unit/request_stub_spec.rb +199 -0
  289. data/vendor/bundle/ruby/2.4.0/gems/webmock-2.3.2/spec/unit/response_spec.rb +282 -0
  290. data/vendor/bundle/ruby/2.4.0/gems/webmock-2.3.2/spec/unit/stub_registry_spec.rb +103 -0
  291. data/vendor/bundle/ruby/2.4.0/gems/webmock-2.3.2/spec/unit/stub_request_snippet_spec.rb +95 -0
  292. data/vendor/bundle/ruby/2.4.0/gems/webmock-2.3.2/spec/unit/util/hash_counter_spec.rb +39 -0
  293. data/vendor/bundle/ruby/2.4.0/gems/webmock-2.3.2/spec/unit/util/hash_keys_stringifier_spec.rb +27 -0
  294. data/vendor/bundle/ruby/2.4.0/gems/webmock-2.3.2/spec/unit/util/headers_spec.rb +28 -0
  295. data/vendor/bundle/ruby/2.4.0/gems/webmock-2.3.2/spec/unit/util/json_spec.rb +33 -0
  296. data/vendor/bundle/ruby/2.4.0/gems/webmock-2.3.2/spec/unit/util/query_mapper_spec.rb +138 -0
  297. data/vendor/bundle/ruby/2.4.0/gems/webmock-2.3.2/spec/unit/util/uri_spec.rb +299 -0
  298. data/vendor/bundle/ruby/2.4.0/gems/webmock-2.3.2/spec/unit/util/version_checker_spec.rb +65 -0
  299. data/vendor/bundle/ruby/2.4.0/gems/webmock-2.3.2/spec/unit/webmock_spec.rb +11 -0
  300. data/vendor/bundle/ruby/2.4.0/gems/webmock-2.3.2/test/http_request.rb +24 -0
  301. data/vendor/bundle/ruby/2.4.0/gems/webmock-2.3.2/test/shared_test.rb +95 -0
  302. data/vendor/bundle/ruby/2.4.0/gems/webmock-2.3.2/test/test_helper.rb +23 -0
  303. data/vendor/bundle/ruby/2.4.0/gems/webmock-2.3.2/test/test_webmock.rb +6 -0
  304. data/vendor/bundle/ruby/2.4.0/gems/webmock-2.3.2/webmock.gemspec +46 -0
  305. data/vendor/bundle/ruby/2.4.0/gems/winrm-fs-1.1.1/.gitignore +11 -0
  306. data/vendor/bundle/ruby/2.4.0/gems/winrm-fs-1.1.1/.rspec +3 -0
  307. data/vendor/bundle/ruby/2.4.0/gems/winrm-fs-1.1.1/.rubocop.yml +9 -0
  308. data/vendor/bundle/ruby/2.4.0/gems/winrm-fs-1.1.1/.travis.yml +9 -0
  309. data/vendor/bundle/ruby/2.4.0/gems/winrm-fs-1.1.1/Gemfile +5 -0
  310. data/vendor/bundle/ruby/2.4.0/gems/winrm-fs-1.1.1/LICENSE +202 -0
  311. data/vendor/bundle/ruby/2.4.0/gems/winrm-fs-1.1.1/README.md +79 -0
  312. data/vendor/bundle/ruby/2.4.0/gems/winrm-fs-1.1.1/Rakefile +28 -0
  313. data/vendor/bundle/ruby/2.4.0/gems/winrm-fs-1.1.1/VERSION +1 -0
  314. data/vendor/bundle/ruby/2.4.0/gems/winrm-fs-1.1.1/Vagrantfile +9 -0
  315. data/vendor/bundle/ruby/2.4.0/gems/winrm-fs-1.1.1/appveyor.yml +38 -0
  316. data/vendor/bundle/ruby/2.4.0/gems/winrm-fs-1.1.1/bin/rwinrmcp +86 -0
  317. data/vendor/bundle/ruby/2.4.0/gems/winrm-fs-1.1.1/changelog.md +60 -0
  318. data/vendor/bundle/ruby/2.4.0/gems/winrm-fs-1.1.1/lib/winrm-fs/core/file_transporter.rb +527 -0
  319. data/vendor/bundle/ruby/2.4.0/gems/winrm-fs-1.1.1/lib/winrm-fs/core/tmp_zip.rb +177 -0
  320. data/vendor/bundle/ruby/2.4.0/gems/winrm-fs-1.1.1/lib/winrm-fs/exceptions.rb +28 -0
  321. data/vendor/bundle/ruby/2.4.0/gems/winrm-fs-1.1.1/lib/winrm-fs/file_manager.rb +118 -0
  322. data/vendor/bundle/ruby/2.4.0/gems/winrm-fs-1.1.1/lib/winrm-fs/scripts/check_files.ps1.erb +49 -0
  323. data/vendor/bundle/ruby/2.4.0/gems/winrm-fs-1.1.1/lib/winrm-fs/scripts/checksum.ps1.erb +13 -0
  324. data/vendor/bundle/ruby/2.4.0/gems/winrm-fs-1.1.1/lib/winrm-fs/scripts/create_dir.ps1.erb +6 -0
  325. data/vendor/bundle/ruby/2.4.0/gems/winrm-fs-1.1.1/lib/winrm-fs/scripts/delete.ps1.erb +6 -0
  326. data/vendor/bundle/ruby/2.4.0/gems/winrm-fs-1.1.1/lib/winrm-fs/scripts/download.ps1.erb +8 -0
  327. data/vendor/bundle/ruby/2.4.0/gems/winrm-fs-1.1.1/lib/winrm-fs/scripts/exists.ps1.erb +10 -0
  328. data/vendor/bundle/ruby/2.4.0/gems/winrm-fs-1.1.1/lib/winrm-fs/scripts/extract_files.ps1.erb +52 -0
  329. data/vendor/bundle/ruby/2.4.0/gems/winrm-fs-1.1.1/lib/winrm-fs/scripts/scripts.rb +31 -0
  330. data/vendor/bundle/ruby/2.4.0/gems/winrm-fs-1.1.1/lib/winrm-fs.rb +28 -0
  331. data/vendor/bundle/ruby/2.4.0/gems/winrm-fs-1.1.1/spec/config-example.yml +3 -0
  332. data/vendor/bundle/ruby/2.4.0/gems/winrm-fs-1.1.1/spec/integration/file_manager_spec.rb +224 -0
  333. data/vendor/bundle/ruby/2.4.0/gems/winrm-fs-1.1.1/spec/integration/tmp_zip_spec.rb +26 -0
  334. data/vendor/bundle/ruby/2.4.0/gems/winrm-fs-1.1.1/spec/matchers.rb +58 -0
  335. data/vendor/bundle/ruby/2.4.0/gems/winrm-fs-1.1.1/spec/spec_helper.rb +71 -0
  336. data/vendor/bundle/ruby/2.4.0/gems/winrm-fs-1.1.1/spec/unit/tmp_zip_spec.rb +79 -0
  337. data/vendor/bundle/ruby/2.4.0/gems/winrm-fs-1.1.1/winrm-fs.gemspec +37 -0
  338. data/vendor/bundle/ruby/2.4.0/specifications/addressable-2.5.2.gemspec +39 -0
  339. data/vendor/bundle/ruby/2.4.0/specifications/hashdiff-0.3.7.gemspec +39 -0
  340. data/vendor/bundle/ruby/2.4.0/specifications/multi_json-1.12.2.gemspec +33 -0
  341. data/vendor/bundle/ruby/2.4.0/specifications/public_suffix-3.0.1.gemspec +41 -0
  342. data/vendor/bundle/ruby/2.4.0/specifications/webmock-2.3.2.gemspec +79 -0
  343. data/vendor/bundle/ruby/2.4.0/specifications/winrm-fs-1.1.1.gemspec +57 -0
  344. data/version.txt +1 -1
  345. metadata +295 -11
  346. data/plugins/guests/solaris11/cap/halt.rb +0 -26
  347. data/plugins/guests/solaris11/cap/insert_public_key.rb +0 -21
  348. data/plugins/guests/solaris11/cap/mount_virtualbox_shared_folder.rb +0 -45
  349. data/plugins/guests/solaris11/cap/remove_public_key.rb +0 -21
  350. data/plugins/guests/solaris11/cap/rsync.rb +0 -29
  351. data/test/unit/plugins/guests/solaris11/cap/halt_test.rb +0 -44
@@ -0,0 +1,57 @@
1
+ # coding: utf-8
2
+ # Copyright (C) Bob Aman
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+
16
+
17
+ require "spec_helper"
18
+
19
+ require "addressable/uri"
20
+
21
+ describe Addressable::URI, "when created with a URI known to cause crashes " +
22
+ "in certain browsers" do
23
+ it "should parse correctly" do
24
+ uri = Addressable::URI.parse('%%30%30')
25
+ expect(uri.path).to eq('%%30%30')
26
+ expect(uri.normalize.path).to eq('%2500')
27
+ end
28
+
29
+ it "should parse correctly as a full URI" do
30
+ uri = Addressable::URI.parse('http://www.example.com/%%30%30')
31
+ expect(uri.path).to eq('/%%30%30')
32
+ expect(uri.normalize.path).to eq('/%2500')
33
+ end
34
+ end
35
+
36
+ describe Addressable::URI, "when created with a URI known to cause crashes " +
37
+ "in certain browsers" do
38
+ it "should parse correctly" do
39
+ uri = Addressable::URI.parse('لُصّبُلُلصّبُررً ॣ ॣh ॣ ॣ 冗')
40
+ expect(uri.path).to eq('لُصّبُلُلصّبُررً ॣ ॣh ॣ ॣ 冗')
41
+ expect(uri.normalize.path).to eq(
42
+ '%D9%84%D9%8F%D8%B5%D9%91%D8%A8%D9%8F%D9%84%D9%8F%D9%84%D8%B5%D9%91' +
43
+ '%D8%A8%D9%8F%D8%B1%D8%B1%D9%8B%20%E0%A5%A3%20%E0%A5%A3h%20%E0%A5' +
44
+ '%A3%20%E0%A5%A3%20%E5%86%97'
45
+ )
46
+ end
47
+
48
+ it "should parse correctly as a full URI" do
49
+ uri = Addressable::URI.parse('http://www.example.com/لُصّبُلُلصّبُررً ॣ ॣh ॣ ॣ 冗')
50
+ expect(uri.path).to eq('/لُصّبُلُلصّبُررً ॣ ॣh ॣ ॣ 冗')
51
+ expect(uri.normalize.path).to eq(
52
+ '/%D9%84%D9%8F%D8%B5%D9%91%D8%A8%D9%8F%D9%84%D9%8F%D9%84%D8%B5%D9%91' +
53
+ '%D8%A8%D9%8F%D8%B1%D8%B1%D9%8B%20%E0%A5%A3%20%E0%A5%A3h%20%E0%A5' +
54
+ '%A3%20%E0%A5%A3%20%E5%86%97'
55
+ )
56
+ end
57
+ end
@@ -0,0 +1,1419 @@
1
+ # coding: utf-8
2
+ # Copyright (C) Bob Aman
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+
16
+
17
+ require "spec_helper"
18
+
19
+ require "bigdecimal"
20
+ require "addressable/template"
21
+
22
+ shared_examples_for 'expands' do |tests|
23
+ tests.each do |template, expansion|
24
+ exp = expansion.is_a?(Array) ? expansion.first : expansion
25
+ it "#{template} to #{exp}" do
26
+ tmpl = Addressable::Template.new(template).expand(subject)
27
+ if expansion.is_a?(Array)
28
+ expect(expansion.any?{|i| i == tmpl.to_str}).to be true
29
+ else
30
+ expect(tmpl.to_str).to eq(expansion)
31
+ end
32
+ end
33
+ end
34
+ end
35
+
36
+ describe "eql?" do
37
+ let(:template) { Addressable::Template.new('https://www.example.com/{foo}') }
38
+ it 'is equal when the pattern matches' do
39
+ other_template = Addressable::Template.new('https://www.example.com/{foo}')
40
+ expect(template).to be_eql(other_template)
41
+ expect(other_template).to be_eql(template)
42
+ end
43
+ it 'is not equal when the pattern differs' do
44
+ other_template = Addressable::Template.new('https://www.example.com/{bar}')
45
+ expect(template).to_not be_eql(other_template)
46
+ expect(other_template).to_not be_eql(template)
47
+ end
48
+ it 'is not equal to non-templates' do
49
+ uri = 'https://www.example.com/foo/bar'
50
+ addressable_template = Addressable::Template.new uri
51
+ addressable_uri = Addressable::URI.parse uri
52
+ expect(addressable_template).to_not be_eql(addressable_uri)
53
+ expect(addressable_uri).to_not be_eql(addressable_template)
54
+ end
55
+ end
56
+
57
+ describe "==" do
58
+ let(:template) { Addressable::Template.new('https://www.example.com/{foo}') }
59
+ it 'is equal when the pattern matches' do
60
+ other_template = Addressable::Template.new('https://www.example.com/{foo}')
61
+ expect(template).to eq other_template
62
+ expect(other_template).to eq template
63
+ end
64
+ it 'is not equal when the pattern differs' do
65
+ other_template = Addressable::Template.new('https://www.example.com/{bar}')
66
+ expect(template).not_to eq other_template
67
+ expect(other_template).not_to eq template
68
+ end
69
+ it 'is not equal to non-templates' do
70
+ uri = 'https://www.example.com/foo/bar'
71
+ addressable_template = Addressable::Template.new uri
72
+ addressable_uri = Addressable::URI.parse uri
73
+ expect(addressable_template).not_to eq addressable_uri
74
+ expect(addressable_uri).not_to eq addressable_template
75
+ end
76
+ end
77
+
78
+ describe "Type conversion" do
79
+ subject {
80
+ {
81
+ :var => true,
82
+ :hello => 1234,
83
+ :nothing => nil,
84
+ :sym => :symbolic,
85
+ :decimal => BigDecimal.new('1')
86
+ }
87
+ }
88
+
89
+ it_behaves_like 'expands', {
90
+ '{var}' => 'true',
91
+ '{hello}' => '1234',
92
+ '{nothing}' => '',
93
+ '{sym}' => 'symbolic',
94
+ '{decimal}' => RUBY_VERSION < '2.4.0' ? '0.1E1' : '0.1e1'
95
+ }
96
+ end
97
+
98
+ describe "Level 1:" do
99
+ subject {
100
+ {:var => "value", :hello => "Hello World!"}
101
+ }
102
+ it_behaves_like 'expands', {
103
+ '{var}' => 'value',
104
+ '{hello}' => 'Hello%20World%21'
105
+ }
106
+ end
107
+
108
+ describe "Level 2" do
109
+ subject {
110
+ {
111
+ :var => "value",
112
+ :hello => "Hello World!",
113
+ :path => "/foo/bar"
114
+ }
115
+ }
116
+ context "Operator +:" do
117
+ it_behaves_like 'expands', {
118
+ '{+var}' => 'value',
119
+ '{+hello}' => 'Hello%20World!',
120
+ '{+path}/here' => '/foo/bar/here',
121
+ 'here?ref={+path}' => 'here?ref=/foo/bar'
122
+ }
123
+ end
124
+ context "Operator #:" do
125
+ it_behaves_like 'expands', {
126
+ 'X{#var}' => 'X#value',
127
+ 'X{#hello}' => 'X#Hello%20World!'
128
+ }
129
+ end
130
+ end
131
+
132
+ describe "Level 3" do
133
+ subject {
134
+ {
135
+ :var => "value",
136
+ :hello => "Hello World!",
137
+ :empty => "",
138
+ :path => "/foo/bar",
139
+ :x => "1024",
140
+ :y => "768"
141
+ }
142
+ }
143
+ context "Operator nil (multiple vars):" do
144
+ it_behaves_like 'expands', {
145
+ 'map?{x,y}' => 'map?1024,768',
146
+ '{x,hello,y}' => '1024,Hello%20World%21,768'
147
+ }
148
+ end
149
+ context "Operator + (multiple vars):" do
150
+ it_behaves_like 'expands', {
151
+ '{+x,hello,y}' => '1024,Hello%20World!,768',
152
+ '{+path,x}/here' => '/foo/bar,1024/here'
153
+ }
154
+ end
155
+ context "Operator # (multiple vars):" do
156
+ it_behaves_like 'expands', {
157
+ '{#x,hello,y}' => '#1024,Hello%20World!,768',
158
+ '{#path,x}/here' => '#/foo/bar,1024/here'
159
+ }
160
+ end
161
+ context "Operator ." do
162
+ it_behaves_like 'expands', {
163
+ 'X{.var}' => 'X.value',
164
+ 'X{.x,y}' => 'X.1024.768'
165
+ }
166
+ end
167
+ context "Operator /" do
168
+ it_behaves_like 'expands', {
169
+ '{/var}' => '/value',
170
+ '{/var,x}/here' => '/value/1024/here'
171
+ }
172
+ end
173
+ context "Operator ;" do
174
+ it_behaves_like 'expands', {
175
+ '{;x,y}' => ';x=1024;y=768',
176
+ '{;x,y,empty}' => ';x=1024;y=768;empty'
177
+ }
178
+ end
179
+ context "Operator ?" do
180
+ it_behaves_like 'expands', {
181
+ '{?x,y}' => '?x=1024&y=768',
182
+ '{?x,y,empty}' => '?x=1024&y=768&empty='
183
+ }
184
+ end
185
+ context "Operator &" do
186
+ it_behaves_like 'expands', {
187
+ '?fixed=yes{&x}' => '?fixed=yes&x=1024',
188
+ '{&x,y,empty}' => '&x=1024&y=768&empty='
189
+ }
190
+ end
191
+ end
192
+
193
+ describe "Level 4" do
194
+ subject {
195
+ {
196
+ :var => "value",
197
+ :hello => "Hello World!",
198
+ :path => "/foo/bar",
199
+ :semi => ";",
200
+ :list => %w(red green blue),
201
+ :keys => {"semi" => ';', "dot" => '.', "comma" => ','}
202
+ }
203
+ }
204
+ context "Expansion with value modifiers" do
205
+ it_behaves_like 'expands', {
206
+ '{var:3}' => 'val',
207
+ '{var:30}' => 'value',
208
+ '{list}' => 'red,green,blue',
209
+ '{list*}' => 'red,green,blue',
210
+ '{keys}' => [
211
+ 'semi,%3B,dot,.,comma,%2C',
212
+ 'dot,.,semi,%3B,comma,%2C',
213
+ 'comma,%2C,semi,%3B,dot,.',
214
+ 'semi,%3B,comma,%2C,dot,.',
215
+ 'dot,.,comma,%2C,semi,%3B',
216
+ 'comma,%2C,dot,.,semi,%3B'
217
+ ],
218
+ '{keys*}' => [
219
+ 'semi=%3B,dot=.,comma=%2C',
220
+ 'dot=.,semi=%3B,comma=%2C',
221
+ 'comma=%2C,semi=%3B,dot=.',
222
+ 'semi=%3B,comma=%2C,dot=.',
223
+ 'dot=.,comma=%2C,semi=%3B',
224
+ 'comma=%2C,dot=.,semi=%3B'
225
+ ]
226
+ }
227
+ end
228
+ context "Operator + with value modifiers" do
229
+ it_behaves_like 'expands', {
230
+ '{+path:6}/here' => '/foo/b/here',
231
+ '{+list}' => 'red,green,blue',
232
+ '{+list*}' => 'red,green,blue',
233
+ '{+keys}' => [
234
+ 'semi,;,dot,.,comma,,',
235
+ 'dot,.,semi,;,comma,,',
236
+ 'comma,,,semi,;,dot,.',
237
+ 'semi,;,comma,,,dot,.',
238
+ 'dot,.,comma,,,semi,;',
239
+ 'comma,,,dot,.,semi,;'
240
+ ],
241
+ '{+keys*}' => [
242
+ 'semi=;,dot=.,comma=,',
243
+ 'dot=.,semi=;,comma=,',
244
+ 'comma=,,semi=;,dot=.',
245
+ 'semi=;,comma=,,dot=.',
246
+ 'dot=.,comma=,,semi=;',
247
+ 'comma=,,dot=.,semi=;'
248
+ ]
249
+ }
250
+ end
251
+ context "Operator # with value modifiers" do
252
+ it_behaves_like 'expands', {
253
+ '{#path:6}/here' => '#/foo/b/here',
254
+ '{#list}' => '#red,green,blue',
255
+ '{#list*}' => '#red,green,blue',
256
+ '{#keys}' => [
257
+ '#semi,;,dot,.,comma,,',
258
+ '#dot,.,semi,;,comma,,',
259
+ '#comma,,,semi,;,dot,.',
260
+ '#semi,;,comma,,,dot,.',
261
+ '#dot,.,comma,,,semi,;',
262
+ '#comma,,,dot,.,semi,;'
263
+ ],
264
+ '{#keys*}' => [
265
+ '#semi=;,dot=.,comma=,',
266
+ '#dot=.,semi=;,comma=,',
267
+ '#comma=,,semi=;,dot=.',
268
+ '#semi=;,comma=,,dot=.',
269
+ '#dot=.,comma=,,semi=;',
270
+ '#comma=,,dot=.,semi=;'
271
+ ]
272
+ }
273
+ end
274
+ context "Operator . with value modifiers" do
275
+ it_behaves_like 'expands', {
276
+ 'X{.var:3}' => 'X.val',
277
+ 'X{.list}' => 'X.red,green,blue',
278
+ 'X{.list*}' => 'X.red.green.blue',
279
+ 'X{.keys}' => [
280
+ 'X.semi,%3B,dot,.,comma,%2C',
281
+ 'X.dot,.,semi,%3B,comma,%2C',
282
+ 'X.comma,%2C,semi,%3B,dot,.',
283
+ 'X.semi,%3B,comma,%2C,dot,.',
284
+ 'X.dot,.,comma,%2C,semi,%3B',
285
+ 'X.comma,%2C,dot,.,semi,%3B'
286
+ ],
287
+ 'X{.keys*}' => [
288
+ 'X.semi=%3B.dot=..comma=%2C',
289
+ 'X.dot=..semi=%3B.comma=%2C',
290
+ 'X.comma=%2C.semi=%3B.dot=.',
291
+ 'X.semi=%3B.comma=%2C.dot=.',
292
+ 'X.dot=..comma=%2C.semi=%3B',
293
+ 'X.comma=%2C.dot=..semi=%3B'
294
+ ]
295
+ }
296
+ end
297
+ context "Operator / with value modifiers" do
298
+ it_behaves_like 'expands', {
299
+ '{/var:1,var}' => '/v/value',
300
+ '{/list}' => '/red,green,blue',
301
+ '{/list*}' => '/red/green/blue',
302
+ '{/list*,path:4}' => '/red/green/blue/%2Ffoo',
303
+ '{/keys}' => [
304
+ '/semi,%3B,dot,.,comma,%2C',
305
+ '/dot,.,semi,%3B,comma,%2C',
306
+ '/comma,%2C,semi,%3B,dot,.',
307
+ '/semi,%3B,comma,%2C,dot,.',
308
+ '/dot,.,comma,%2C,semi,%3B',
309
+ '/comma,%2C,dot,.,semi,%3B'
310
+ ],
311
+ '{/keys*}' => [
312
+ '/semi=%3B/dot=./comma=%2C',
313
+ '/dot=./semi=%3B/comma=%2C',
314
+ '/comma=%2C/semi=%3B/dot=.',
315
+ '/semi=%3B/comma=%2C/dot=.',
316
+ '/dot=./comma=%2C/semi=%3B',
317
+ '/comma=%2C/dot=./semi=%3B'
318
+ ]
319
+ }
320
+ end
321
+ context "Operator ; with value modifiers" do
322
+ it_behaves_like 'expands', {
323
+ '{;hello:5}' => ';hello=Hello',
324
+ '{;list}' => ';list=red,green,blue',
325
+ '{;list*}' => ';list=red;list=green;list=blue',
326
+ '{;keys}' => [
327
+ ';keys=semi,%3B,dot,.,comma,%2C',
328
+ ';keys=dot,.,semi,%3B,comma,%2C',
329
+ ';keys=comma,%2C,semi,%3B,dot,.',
330
+ ';keys=semi,%3B,comma,%2C,dot,.',
331
+ ';keys=dot,.,comma,%2C,semi,%3B',
332
+ ';keys=comma,%2C,dot,.,semi,%3B'
333
+ ],
334
+ '{;keys*}' => [
335
+ ';semi=%3B;dot=.;comma=%2C',
336
+ ';dot=.;semi=%3B;comma=%2C',
337
+ ';comma=%2C;semi=%3B;dot=.',
338
+ ';semi=%3B;comma=%2C;dot=.',
339
+ ';dot=.;comma=%2C;semi=%3B',
340
+ ';comma=%2C;dot=.;semi=%3B'
341
+ ]
342
+ }
343
+ end
344
+ context "Operator ? with value modifiers" do
345
+ it_behaves_like 'expands', {
346
+ '{?var:3}' => '?var=val',
347
+ '{?list}' => '?list=red,green,blue',
348
+ '{?list*}' => '?list=red&list=green&list=blue',
349
+ '{?keys}' => [
350
+ '?keys=semi,%3B,dot,.,comma,%2C',
351
+ '?keys=dot,.,semi,%3B,comma,%2C',
352
+ '?keys=comma,%2C,semi,%3B,dot,.',
353
+ '?keys=semi,%3B,comma,%2C,dot,.',
354
+ '?keys=dot,.,comma,%2C,semi,%3B',
355
+ '?keys=comma,%2C,dot,.,semi,%3B'
356
+ ],
357
+ '{?keys*}' => [
358
+ '?semi=%3B&dot=.&comma=%2C',
359
+ '?dot=.&semi=%3B&comma=%2C',
360
+ '?comma=%2C&semi=%3B&dot=.',
361
+ '?semi=%3B&comma=%2C&dot=.',
362
+ '?dot=.&comma=%2C&semi=%3B',
363
+ '?comma=%2C&dot=.&semi=%3B'
364
+ ]
365
+ }
366
+ end
367
+ context "Operator & with value modifiers" do
368
+ it_behaves_like 'expands', {
369
+ '{&var:3}' => '&var=val',
370
+ '{&list}' => '&list=red,green,blue',
371
+ '{&list*}' => '&list=red&list=green&list=blue',
372
+ '{&keys}' => [
373
+ '&keys=semi,%3B,dot,.,comma,%2C',
374
+ '&keys=dot,.,semi,%3B,comma,%2C',
375
+ '&keys=comma,%2C,semi,%3B,dot,.',
376
+ '&keys=semi,%3B,comma,%2C,dot,.',
377
+ '&keys=dot,.,comma,%2C,semi,%3B',
378
+ '&keys=comma,%2C,dot,.,semi,%3B'
379
+ ],
380
+ '{&keys*}' => [
381
+ '&semi=%3B&dot=.&comma=%2C',
382
+ '&dot=.&semi=%3B&comma=%2C',
383
+ '&comma=%2C&semi=%3B&dot=.',
384
+ '&semi=%3B&comma=%2C&dot=.',
385
+ '&dot=.&comma=%2C&semi=%3B',
386
+ '&comma=%2C&dot=.&semi=%3B'
387
+ ]
388
+ }
389
+ end
390
+ end
391
+ describe "Modifiers" do
392
+ subject {
393
+ {
394
+ :var => "value",
395
+ :semi => ";",
396
+ :year => %w(1965 2000 2012),
397
+ :dom => %w(example com)
398
+ }
399
+ }
400
+ context "length" do
401
+ it_behaves_like 'expands', {
402
+ '{var:3}' => 'val',
403
+ '{var:30}' => 'value',
404
+ '{var}' => 'value',
405
+ '{semi}' => '%3B',
406
+ '{semi:2}' => '%3B'
407
+ }
408
+ end
409
+ context "explode" do
410
+ it_behaves_like 'expands', {
411
+ 'find{?year*}' => 'find?year=1965&year=2000&year=2012',
412
+ 'www{.dom*}' => 'www.example.com',
413
+ }
414
+ end
415
+ end
416
+ describe "Expansion" do
417
+ subject {
418
+ {
419
+ :count => ["one", "two", "three"],
420
+ :dom => ["example", "com"],
421
+ :dub => "me/too",
422
+ :hello => "Hello World!",
423
+ :half => "50%",
424
+ :var => "value",
425
+ :who => "fred",
426
+ :base => "http://example.com/home/",
427
+ :path => "/foo/bar",
428
+ :list => ["red", "green", "blue"],
429
+ :keys => {"semi" => ";","dot" => ".","comma" => ","},
430
+ :v => "6",
431
+ :x => "1024",
432
+ :y => "768",
433
+ :empty => "",
434
+ :empty_keys => {},
435
+ :undef => nil
436
+ }
437
+ }
438
+ context "concatenation" do
439
+ it_behaves_like 'expands', {
440
+ '{count}' => 'one,two,three',
441
+ '{count*}' => 'one,two,three',
442
+ '{/count}' => '/one,two,three',
443
+ '{/count*}' => '/one/two/three',
444
+ '{;count}' => ';count=one,two,three',
445
+ '{;count*}' => ';count=one;count=two;count=three',
446
+ '{?count}' => '?count=one,two,three',
447
+ '{?count*}' => '?count=one&count=two&count=three',
448
+ '{&count*}' => '&count=one&count=two&count=three'
449
+ }
450
+ end
451
+ context "simple expansion" do
452
+ it_behaves_like 'expands', {
453
+ '{var}' => 'value',
454
+ '{hello}' => 'Hello%20World%21',
455
+ '{half}' => '50%25',
456
+ 'O{empty}X' => 'OX',
457
+ 'O{undef}X' => 'OX',
458
+ '{x,y}' => '1024,768',
459
+ '{x,hello,y}' => '1024,Hello%20World%21,768',
460
+ '?{x,empty}' => '?1024,',
461
+ '?{x,undef}' => '?1024',
462
+ '?{undef,y}' => '?768',
463
+ '{var:3}' => 'val',
464
+ '{var:30}' => 'value',
465
+ '{list}' => 'red,green,blue',
466
+ '{list*}' => 'red,green,blue',
467
+ '{keys}' => [
468
+ 'semi,%3B,dot,.,comma,%2C',
469
+ 'dot,.,semi,%3B,comma,%2C',
470
+ 'comma,%2C,semi,%3B,dot,.',
471
+ 'semi,%3B,comma,%2C,dot,.',
472
+ 'dot,.,comma,%2C,semi,%3B',
473
+ 'comma,%2C,dot,.,semi,%3B'
474
+ ],
475
+ '{keys*}' => [
476
+ 'semi=%3B,dot=.,comma=%2C',
477
+ 'dot=.,semi=%3B,comma=%2C',
478
+ 'comma=%2C,semi=%3B,dot=.',
479
+ 'semi=%3B,comma=%2C,dot=.',
480
+ 'dot=.,comma=%2C,semi=%3B',
481
+ 'comma=%2C,dot=.,semi=%3B'
482
+ ]
483
+ }
484
+ end
485
+ context "reserved expansion (+)" do
486
+ it_behaves_like 'expands', {
487
+ '{+var}' => 'value',
488
+ '{+hello}' => 'Hello%20World!',
489
+ '{+half}' => '50%25',
490
+ '{base}index' => 'http%3A%2F%2Fexample.com%2Fhome%2Findex',
491
+ '{+base}index' => 'http://example.com/home/index',
492
+ 'O{+empty}X' => 'OX',
493
+ 'O{+undef}X' => 'OX',
494
+ '{+path}/here' => '/foo/bar/here',
495
+ 'here?ref={+path}' => 'here?ref=/foo/bar',
496
+ 'up{+path}{var}/here' => 'up/foo/barvalue/here',
497
+ '{+x,hello,y}' => '1024,Hello%20World!,768',
498
+ '{+path,x}/here' => '/foo/bar,1024/here',
499
+ '{+path:6}/here' => '/foo/b/here',
500
+ '{+list}' => 'red,green,blue',
501
+ '{+list*}' => 'red,green,blue',
502
+ '{+keys}' => [
503
+ 'semi,;,dot,.,comma,,',
504
+ 'dot,.,semi,;,comma,,',
505
+ 'comma,,,semi,;,dot,.',
506
+ 'semi,;,comma,,,dot,.',
507
+ 'dot,.,comma,,,semi,;',
508
+ 'comma,,,dot,.,semi,;'
509
+ ],
510
+ '{+keys*}' => [
511
+ 'semi=;,dot=.,comma=,',
512
+ 'dot=.,semi=;,comma=,',
513
+ 'comma=,,semi=;,dot=.',
514
+ 'semi=;,comma=,,dot=.',
515
+ 'dot=.,comma=,,semi=;',
516
+ 'comma=,,dot=.,semi=;'
517
+ ]
518
+ }
519
+ end
520
+ context "fragment expansion (#)" do
521
+ it_behaves_like 'expands', {
522
+ '{#var}' => '#value',
523
+ '{#hello}' => '#Hello%20World!',
524
+ '{#half}' => '#50%25',
525
+ 'foo{#empty}' => 'foo#',
526
+ 'foo{#undef}' => 'foo',
527
+ '{#x,hello,y}' => '#1024,Hello%20World!,768',
528
+ '{#path,x}/here' => '#/foo/bar,1024/here',
529
+ '{#path:6}/here' => '#/foo/b/here',
530
+ '{#list}' => '#red,green,blue',
531
+ '{#list*}' => '#red,green,blue',
532
+ '{#keys}' => [
533
+ '#semi,;,dot,.,comma,,',
534
+ '#dot,.,semi,;,comma,,',
535
+ '#comma,,,semi,;,dot,.',
536
+ '#semi,;,comma,,,dot,.',
537
+ '#dot,.,comma,,,semi,;',
538
+ '#comma,,,dot,.,semi,;'
539
+ ],
540
+ '{#keys*}' => [
541
+ '#semi=;,dot=.,comma=,',
542
+ '#dot=.,semi=;,comma=,',
543
+ '#comma=,,semi=;,dot=.',
544
+ '#semi=;,comma=,,dot=.',
545
+ '#dot=.,comma=,,semi=;',
546
+ '#comma=,,dot=.,semi=;'
547
+ ]
548
+ }
549
+ end
550
+ context "label expansion (.)" do
551
+ it_behaves_like 'expands', {
552
+ '{.who}' => '.fred',
553
+ '{.who,who}' => '.fred.fred',
554
+ '{.half,who}' => '.50%25.fred',
555
+ 'www{.dom*}' => 'www.example.com',
556
+ 'X{.var}' => 'X.value',
557
+ 'X{.empty}' => 'X.',
558
+ 'X{.undef}' => 'X',
559
+ 'X{.var:3}' => 'X.val',
560
+ 'X{.list}' => 'X.red,green,blue',
561
+ 'X{.list*}' => 'X.red.green.blue',
562
+ 'X{.keys}' => [
563
+ 'X.semi,%3B,dot,.,comma,%2C',
564
+ 'X.dot,.,semi,%3B,comma,%2C',
565
+ 'X.comma,%2C,semi,%3B,dot,.',
566
+ 'X.semi,%3B,comma,%2C,dot,.',
567
+ 'X.dot,.,comma,%2C,semi,%3B',
568
+ 'X.comma,%2C,dot,.,semi,%3B'
569
+ ],
570
+ 'X{.keys*}' => [
571
+ 'X.semi=%3B.dot=..comma=%2C',
572
+ 'X.dot=..semi=%3B.comma=%2C',
573
+ 'X.comma=%2C.semi=%3B.dot=.',
574
+ 'X.semi=%3B.comma=%2C.dot=.',
575
+ 'X.dot=..comma=%2C.semi=%3B',
576
+ 'X.comma=%2C.dot=..semi=%3B'
577
+ ],
578
+ 'X{.empty_keys}' => 'X',
579
+ 'X{.empty_keys*}' => 'X'
580
+ }
581
+ end
582
+ context "path expansion (/)" do
583
+ it_behaves_like 'expands', {
584
+ '{/who}' => '/fred',
585
+ '{/who,who}' => '/fred/fred',
586
+ '{/half,who}' => '/50%25/fred',
587
+ '{/who,dub}' => '/fred/me%2Ftoo',
588
+ '{/var}' => '/value',
589
+ '{/var,empty}' => '/value/',
590
+ '{/var,undef}' => '/value',
591
+ '{/var,x}/here' => '/value/1024/here',
592
+ '{/var:1,var}' => '/v/value',
593
+ '{/list}' => '/red,green,blue',
594
+ '{/list*}' => '/red/green/blue',
595
+ '{/list*,path:4}' => '/red/green/blue/%2Ffoo',
596
+ '{/keys}' => [
597
+ '/semi,%3B,dot,.,comma,%2C',
598
+ '/dot,.,semi,%3B,comma,%2C',
599
+ '/comma,%2C,semi,%3B,dot,.',
600
+ '/semi,%3B,comma,%2C,dot,.',
601
+ '/dot,.,comma,%2C,semi,%3B',
602
+ '/comma,%2C,dot,.,semi,%3B'
603
+ ],
604
+ '{/keys*}' => [
605
+ '/semi=%3B/dot=./comma=%2C',
606
+ '/dot=./semi=%3B/comma=%2C',
607
+ '/comma=%2C/semi=%3B/dot=.',
608
+ '/semi=%3B/comma=%2C/dot=.',
609
+ '/dot=./comma=%2C/semi=%3B',
610
+ '/comma=%2C/dot=./semi=%3B'
611
+ ]
612
+ }
613
+ end
614
+ context "path-style expansion (;)" do
615
+ it_behaves_like 'expands', {
616
+ '{;who}' => ';who=fred',
617
+ '{;half}' => ';half=50%25',
618
+ '{;empty}' => ';empty',
619
+ '{;v,empty,who}' => ';v=6;empty;who=fred',
620
+ '{;v,bar,who}' => ';v=6;who=fred',
621
+ '{;x,y}' => ';x=1024;y=768',
622
+ '{;x,y,empty}' => ';x=1024;y=768;empty',
623
+ '{;x,y,undef}' => ';x=1024;y=768',
624
+ '{;hello:5}' => ';hello=Hello',
625
+ '{;list}' => ';list=red,green,blue',
626
+ '{;list*}' => ';list=red;list=green;list=blue',
627
+ '{;keys}' => [
628
+ ';keys=semi,%3B,dot,.,comma,%2C',
629
+ ';keys=dot,.,semi,%3B,comma,%2C',
630
+ ';keys=comma,%2C,semi,%3B,dot,.',
631
+ ';keys=semi,%3B,comma,%2C,dot,.',
632
+ ';keys=dot,.,comma,%2C,semi,%3B',
633
+ ';keys=comma,%2C,dot,.,semi,%3B'
634
+ ],
635
+ '{;keys*}' => [
636
+ ';semi=%3B;dot=.;comma=%2C',
637
+ ';dot=.;semi=%3B;comma=%2C',
638
+ ';comma=%2C;semi=%3B;dot=.',
639
+ ';semi=%3B;comma=%2C;dot=.',
640
+ ';dot=.;comma=%2C;semi=%3B',
641
+ ';comma=%2C;dot=.;semi=%3B'
642
+ ]
643
+ }
644
+ end
645
+ context "form query expansion (?)" do
646
+ it_behaves_like 'expands', {
647
+ '{?who}' => '?who=fred',
648
+ '{?half}' => '?half=50%25',
649
+ '{?x,y}' => '?x=1024&y=768',
650
+ '{?x,y,empty}' => '?x=1024&y=768&empty=',
651
+ '{?x,y,undef}' => '?x=1024&y=768',
652
+ '{?var:3}' => '?var=val',
653
+ '{?list}' => '?list=red,green,blue',
654
+ '{?list*}' => '?list=red&list=green&list=blue',
655
+ '{?keys}' => [
656
+ '?keys=semi,%3B,dot,.,comma,%2C',
657
+ '?keys=dot,.,semi,%3B,comma,%2C',
658
+ '?keys=comma,%2C,semi,%3B,dot,.',
659
+ '?keys=semi,%3B,comma,%2C,dot,.',
660
+ '?keys=dot,.,comma,%2C,semi,%3B',
661
+ '?keys=comma,%2C,dot,.,semi,%3B'
662
+ ],
663
+ '{?keys*}' => [
664
+ '?semi=%3B&dot=.&comma=%2C',
665
+ '?dot=.&semi=%3B&comma=%2C',
666
+ '?comma=%2C&semi=%3B&dot=.',
667
+ '?semi=%3B&comma=%2C&dot=.',
668
+ '?dot=.&comma=%2C&semi=%3B',
669
+ '?comma=%2C&dot=.&semi=%3B'
670
+ ]
671
+ }
672
+ end
673
+ context "form query expansion (&)" do
674
+ it_behaves_like 'expands', {
675
+ '{&who}' => '&who=fred',
676
+ '{&half}' => '&half=50%25',
677
+ '?fixed=yes{&x}' => '?fixed=yes&x=1024',
678
+ '{&x,y,empty}' => '&x=1024&y=768&empty=',
679
+ '{&x,y,undef}' => '&x=1024&y=768',
680
+ '{&var:3}' => '&var=val',
681
+ '{&list}' => '&list=red,green,blue',
682
+ '{&list*}' => '&list=red&list=green&list=blue',
683
+ '{&keys}' => [
684
+ '&keys=semi,%3B,dot,.,comma,%2C',
685
+ '&keys=dot,.,semi,%3B,comma,%2C',
686
+ '&keys=comma,%2C,semi,%3B,dot,.',
687
+ '&keys=semi,%3B,comma,%2C,dot,.',
688
+ '&keys=dot,.,comma,%2C,semi,%3B',
689
+ '&keys=comma,%2C,dot,.,semi,%3B'
690
+ ],
691
+ '{&keys*}' => [
692
+ '&semi=%3B&dot=.&comma=%2C',
693
+ '&dot=.&semi=%3B&comma=%2C',
694
+ '&comma=%2C&semi=%3B&dot=.',
695
+ '&semi=%3B&comma=%2C&dot=.',
696
+ '&dot=.&comma=%2C&semi=%3B',
697
+ '&comma=%2C&dot=.&semi=%3B'
698
+ ]
699
+ }
700
+ end
701
+ context "non-string key in match data" do
702
+ subject {Addressable::Template.new("http://example.com/{one}")}
703
+
704
+ it "raises TypeError" do
705
+ expect { subject.expand(Object.new => "1") }.to raise_error TypeError
706
+ end
707
+ end
708
+ end
709
+
710
+ class ExampleTwoProcessor
711
+ def self.restore(name, value)
712
+ return value.gsub(/-/, " ") if name == "query"
713
+ return value
714
+ end
715
+
716
+ def self.match(name)
717
+ return ".*?" if name == "first"
718
+ return ".*"
719
+ end
720
+ def self.validate(name, value)
721
+ return !!(value =~ /^[\w ]+$/) if name == "query"
722
+ return true
723
+ end
724
+
725
+ def self.transform(name, value)
726
+ return value.gsub(/ /, "+") if name == "query"
727
+ return value
728
+ end
729
+ end
730
+
731
+ class DumbProcessor
732
+ def self.match(name)
733
+ return ".*?" if name == "first"
734
+ end
735
+ end
736
+
737
+ describe Addressable::Template do
738
+ describe 'initialize' do
739
+ context 'with a non-string' do
740
+ it 'raises a TypeError' do
741
+ expect { Addressable::Template.new(nil) }.to raise_error(TypeError)
742
+ end
743
+ end
744
+ end
745
+
746
+ describe 'freeze' do
747
+ subject { Addressable::Template.new("http://example.com/{first}/{+second}/") }
748
+ it 'freezes the template' do
749
+ expect(subject.freeze).to be_frozen
750
+ end
751
+ end
752
+
753
+ describe "Matching" do
754
+ let(:uri){
755
+ Addressable::URI.parse(
756
+ "http://example.com/search/an-example-search-query/"
757
+ )
758
+ }
759
+ let(:uri2){
760
+ Addressable::URI.parse("http://example.com/a/b/c/")
761
+ }
762
+ let(:uri3){
763
+ Addressable::URI.parse("http://example.com/;a=1;b=2;c=3;first=foo")
764
+ }
765
+ let(:uri4){
766
+ Addressable::URI.parse("http://example.com/?a=1&b=2&c=3&first=foo")
767
+ }
768
+ let(:uri5){
769
+ "http://example.com/foo"
770
+ }
771
+ context "first uri with ExampleTwoProcessor" do
772
+ subject {
773
+ Addressable::Template.new(
774
+ "http://example.com/search/{query}/"
775
+ ).match(uri, ExampleTwoProcessor)
776
+ }
777
+ its(:variables){ should == ["query"] }
778
+ its(:captures){ should == ["an example search query"] }
779
+ end
780
+
781
+ context "second uri with ExampleTwoProcessor" do
782
+ subject {
783
+ Addressable::Template.new(
784
+ "http://example.com/{first}/{+second}/"
785
+ ).match(uri2, ExampleTwoProcessor)
786
+ }
787
+ its(:variables){ should == ["first", "second"] }
788
+ its(:captures){ should == ["a", "b/c"] }
789
+ end
790
+
791
+ context "second uri with DumbProcessor" do
792
+ subject {
793
+ Addressable::Template.new(
794
+ "http://example.com/{first}/{+second}/"
795
+ ).match(uri2, DumbProcessor)
796
+ }
797
+ its(:variables){ should == ["first", "second"] }
798
+ its(:captures){ should == ["a", "b/c"] }
799
+ end
800
+
801
+ context "second uri" do
802
+ subject {
803
+ Addressable::Template.new(
804
+ "http://example.com/{first}{/second*}/"
805
+ ).match(uri2)
806
+ }
807
+ its(:variables){ should == ["first", "second"] }
808
+ its(:captures){ should == ["a", ["b","c"]] }
809
+ end
810
+ context "third uri" do
811
+ subject {
812
+ Addressable::Template.new(
813
+ "http://example.com/{;hash*,first}"
814
+ ).match(uri3)
815
+ }
816
+ its(:variables){ should == ["hash", "first"] }
817
+ its(:captures){ should == [
818
+ {"a" => "1", "b" => "2", "c" => "3", "first" => "foo"}, nil] }
819
+ end
820
+ # Note that this expansion is impossible to revert deterministically - the
821
+ # * operator means first could have been a key of hash or a separate key.
822
+ # Semantically, a separate key is more likely, but both are possible.
823
+ context "fourth uri" do
824
+ subject {
825
+ Addressable::Template.new(
826
+ "http://example.com/{?hash*,first}"
827
+ ).match(uri4)
828
+ }
829
+ its(:variables){ should == ["hash", "first"] }
830
+ its(:captures){ should == [
831
+ {"a" => "1", "b" => "2", "c" => "3", "first"=> "foo"}, nil] }
832
+ end
833
+ context "fifth uri" do
834
+ subject {
835
+ Addressable::Template.new(
836
+ "http://example.com/{path}{?hash*,first}"
837
+ ).match(uri5)
838
+ }
839
+ its(:variables){ should == ["path", "hash", "first"] }
840
+ its(:captures){ should == ["foo", nil, nil] }
841
+ end
842
+ end
843
+
844
+ describe 'match' do
845
+ subject { Addressable::Template.new('http://example.com/first/second/') }
846
+ context 'when the URI is the same as the template' do
847
+ it 'returns the match data itself with an empty mapping' do
848
+ uri = Addressable::URI.parse('http://example.com/first/second/')
849
+ match_data = subject.match(uri)
850
+ expect(match_data).to be_an Addressable::Template::MatchData
851
+ expect(match_data.uri).to eq(uri)
852
+ expect(match_data.template).to eq(subject)
853
+ expect(match_data.mapping).to be_empty
854
+ expect(match_data.inspect).to be_an String
855
+ end
856
+ end
857
+ end
858
+
859
+ describe "extract" do
860
+ let(:template) {
861
+ Addressable::Template.new(
862
+ "http://{host}{/segments*}/{?one,two,bogus}{#fragment}"
863
+ )
864
+ }
865
+ let(:uri){ "http://example.com/a/b/c/?one=1&two=2#foo" }
866
+ let(:uri2){ "http://example.com/a/b/c/#foo" }
867
+ it "should be able to extract with queries" do
868
+ expect(template.extract(uri)).to eq({
869
+ "host" => "example.com",
870
+ "segments" => %w(a b c),
871
+ "one" => "1",
872
+ "bogus" => nil,
873
+ "two" => "2",
874
+ "fragment" => "foo"
875
+ })
876
+ end
877
+ it "should be able to extract without queries" do
878
+ expect(template.extract(uri2)).to eq({
879
+ "host" => "example.com",
880
+ "segments" => %w(a b c),
881
+ "one" => nil,
882
+ "bogus" => nil,
883
+ "two" => nil,
884
+ "fragment" => "foo"
885
+ })
886
+ end
887
+
888
+ context "issue #137" do
889
+ subject { Addressable::Template.new('/path{?page,per_page}') }
890
+
891
+ it "can match empty" do
892
+ data = subject.extract("/path")
893
+ expect(data["page"]).to eq(nil)
894
+ expect(data["per_page"]).to eq(nil)
895
+ expect(data.keys.sort).to eq(['page', 'per_page'])
896
+ end
897
+
898
+ it "can match first var" do
899
+ data = subject.extract("/path?page=1")
900
+ expect(data["page"]).to eq("1")
901
+ expect(data["per_page"]).to eq(nil)
902
+ expect(data.keys.sort).to eq(['page', 'per_page'])
903
+ end
904
+
905
+ it "can match second var" do
906
+ data = subject.extract("/path?per_page=1")
907
+ expect(data["page"]).to eq(nil)
908
+ expect(data["per_page"]).to eq("1")
909
+ expect(data.keys.sort).to eq(['page', 'per_page'])
910
+ end
911
+
912
+ it "can match both vars" do
913
+ data = subject.extract("/path?page=2&per_page=1")
914
+ expect(data["page"]).to eq("2")
915
+ expect(data["per_page"]).to eq("1")
916
+ expect(data.keys.sort).to eq(['page', 'per_page'])
917
+ end
918
+ end
919
+ end
920
+
921
+ describe "Partial expand with symbols" do
922
+ context "partial_expand with two simple values" do
923
+ subject {
924
+ Addressable::Template.new("http://example.com/{one}/{two}/")
925
+ }
926
+ it "builds a new pattern" do
927
+ expect(subject.partial_expand(:one => "1").pattern).to eq(
928
+ "http://example.com/1/{two}/"
929
+ )
930
+ end
931
+ end
932
+ context "partial_expand query with missing param in middle" do
933
+ subject {
934
+ Addressable::Template.new("http://example.com/{?one,two,three}/")
935
+ }
936
+ it "builds a new pattern" do
937
+ expect(subject.partial_expand(:one => "1", :three => "3").pattern).to eq(
938
+ "http://example.com/?one=1{&two}&three=3/"
939
+ )
940
+ end
941
+ end
942
+ context "partial_expand form style query with missing param at beginning" do
943
+ subject {
944
+ Addressable::Template.new("http://example.com/{?one,two}/")
945
+ }
946
+ it "builds a new pattern" do
947
+ expect(subject.partial_expand(:two => "2").pattern).to eq(
948
+ "http://example.com/?two=2{&one}/"
949
+ )
950
+ end
951
+ end
952
+ context "partial_expand with query string" do
953
+ subject {
954
+ Addressable::Template.new("http://example.com/{?two,one}/")
955
+ }
956
+ it "builds a new pattern" do
957
+ expect(subject.partial_expand(:one => "1").pattern).to eq(
958
+ "http://example.com/?one=1{&two}/"
959
+ )
960
+ end
961
+ end
962
+ context "partial_expand with path operator" do
963
+ subject {
964
+ Addressable::Template.new("http://example.com{/one,two}/")
965
+ }
966
+ it "builds a new pattern" do
967
+ expect(subject.partial_expand(:one => "1").pattern).to eq(
968
+ "http://example.com/1{/two}/"
969
+ )
970
+ end
971
+ end
972
+ context "partial expand with unicode values" do
973
+ subject do
974
+ Addressable::Template.new("http://example.com/{resource}/{query}/")
975
+ end
976
+ it "normalizes unicode by default" do
977
+ template = subject.partial_expand("query" => "Cafe\u0301")
978
+ expect(template.pattern).to eq(
979
+ "http://example.com/{resource}/Caf%C3%A9/"
980
+ )
981
+ end
982
+
983
+ it "does not normalize unicode when byte semantics requested" do
984
+ template = subject.partial_expand({"query" => "Cafe\u0301"}, nil, false)
985
+ expect(template.pattern).to eq(
986
+ "http://example.com/{resource}/Cafe%CC%81/"
987
+ )
988
+ end
989
+ end
990
+ end
991
+ describe "Partial expand with strings" do
992
+ context "partial_expand with two simple values" do
993
+ subject {
994
+ Addressable::Template.new("http://example.com/{one}/{two}/")
995
+ }
996
+ it "builds a new pattern" do
997
+ expect(subject.partial_expand("one" => "1").pattern).to eq(
998
+ "http://example.com/1/{two}/"
999
+ )
1000
+ end
1001
+ end
1002
+ context "partial_expand query with missing param in middle" do
1003
+ subject {
1004
+ Addressable::Template.new("http://example.com/{?one,two,three}/")
1005
+ }
1006
+ it "builds a new pattern" do
1007
+ expect(subject.partial_expand("one" => "1", "three" => "3").pattern).to eq(
1008
+ "http://example.com/?one=1{&two}&three=3/"
1009
+ )
1010
+ end
1011
+ end
1012
+ context "partial_expand with query string" do
1013
+ subject {
1014
+ Addressable::Template.new("http://example.com/{?two,one}/")
1015
+ }
1016
+ it "builds a new pattern" do
1017
+ expect(subject.partial_expand("one" => "1").pattern).to eq(
1018
+ "http://example.com/?one=1{&two}/"
1019
+ )
1020
+ end
1021
+ end
1022
+ context "partial_expand with path operator" do
1023
+ subject {
1024
+ Addressable::Template.new("http://example.com{/one,two}/")
1025
+ }
1026
+ it "builds a new pattern" do
1027
+ expect(subject.partial_expand("one" => "1").pattern).to eq(
1028
+ "http://example.com/1{/two}/"
1029
+ )
1030
+ end
1031
+ end
1032
+ end
1033
+ describe "Expand" do
1034
+ context "expand with unicode values" do
1035
+ subject do
1036
+ Addressable::Template.new("http://example.com/search/{query}/")
1037
+ end
1038
+ it "normalizes unicode by default" do
1039
+ uri = subject.expand("query" => "Cafe\u0301").to_str
1040
+ expect(uri).to eq("http://example.com/search/Caf%C3%A9/")
1041
+ end
1042
+
1043
+ it "does not normalize unicode when byte semantics requested" do
1044
+ uri = subject.expand({ "query" => "Cafe\u0301" }, nil, false).to_str
1045
+ expect(uri).to eq("http://example.com/search/Cafe%CC%81/")
1046
+ end
1047
+ end
1048
+ context "expand with a processor" do
1049
+ subject {
1050
+ Addressable::Template.new("http://example.com/search/{query}/")
1051
+ }
1052
+ it "processes spaces" do
1053
+ expect(subject.expand({"query" => "an example search query"},
1054
+ ExampleTwoProcessor).to_str).to eq(
1055
+ "http://example.com/search/an+example+search+query/"
1056
+ )
1057
+ end
1058
+ it "validates" do
1059
+ expect{
1060
+ subject.expand({"query" => "Bogus!"},
1061
+ ExampleTwoProcessor).to_str
1062
+ }.to raise_error(Addressable::Template::InvalidTemplateValueError)
1063
+ end
1064
+ end
1065
+ context "partial_expand query with missing param in middle" do
1066
+ subject {
1067
+ Addressable::Template.new("http://example.com/{?one,two,three}/")
1068
+ }
1069
+ it "builds a new pattern" do
1070
+ expect(subject.partial_expand("one" => "1", "three" => "3").pattern).to eq(
1071
+ "http://example.com/?one=1{&two}&three=3/"
1072
+ )
1073
+ end
1074
+ end
1075
+ context "partial_expand with query string" do
1076
+ subject {
1077
+ Addressable::Template.new("http://example.com/{?two,one}/")
1078
+ }
1079
+ it "builds a new pattern" do
1080
+ expect(subject.partial_expand("one" => "1").pattern).to eq(
1081
+ "http://example.com/?one=1{&two}/"
1082
+ )
1083
+ end
1084
+ end
1085
+ context "partial_expand with path operator" do
1086
+ subject {
1087
+ Addressable::Template.new("http://example.com{/one,two}/")
1088
+ }
1089
+ it "builds a new pattern" do
1090
+ expect(subject.partial_expand("one" => "1").pattern).to eq(
1091
+ "http://example.com/1{/two}/"
1092
+ )
1093
+ end
1094
+ end
1095
+ end
1096
+ context "Matching with operators" do
1097
+ describe "Level 1:" do
1098
+ subject { Addressable::Template.new("foo{foo}/{bar}baz") }
1099
+ it "can match" do
1100
+ data = subject.match("foofoo/bananabaz")
1101
+ expect(data.mapping["foo"]).to eq("foo")
1102
+ expect(data.mapping["bar"]).to eq("banana")
1103
+ end
1104
+ it "can fail" do
1105
+ expect(subject.match("bar/foo")).to be_nil
1106
+ expect(subject.match("foobaz")).to be_nil
1107
+ end
1108
+ it "can match empty" do
1109
+ data = subject.match("foo/baz")
1110
+ expect(data.mapping["foo"]).to eq(nil)
1111
+ expect(data.mapping["bar"]).to eq(nil)
1112
+ end
1113
+ it "lists vars" do
1114
+ expect(subject.variables).to eq(["foo", "bar"])
1115
+ end
1116
+ end
1117
+
1118
+ describe "Level 2:" do
1119
+ subject { Addressable::Template.new("foo{+foo}{#bar}baz") }
1120
+ it "can match" do
1121
+ data = subject.match("foo/test/banana#bazbaz")
1122
+ expect(data.mapping["foo"]).to eq("/test/banana")
1123
+ expect(data.mapping["bar"]).to eq("baz")
1124
+ end
1125
+ it "can match empty level 2 #" do
1126
+ data = subject.match("foo/test/bananabaz")
1127
+ expect(data.mapping["foo"]).to eq("/test/banana")
1128
+ expect(data.mapping["bar"]).to eq(nil)
1129
+ data = subject.match("foo/test/banana#baz")
1130
+ expect(data.mapping["foo"]).to eq("/test/banana")
1131
+ expect(data.mapping["bar"]).to eq("")
1132
+ end
1133
+ it "can match empty level 2 +" do
1134
+ data = subject.match("foobaz")
1135
+ expect(data.mapping["foo"]).to eq(nil)
1136
+ expect(data.mapping["bar"]).to eq(nil)
1137
+ data = subject.match("foo#barbaz")
1138
+ expect(data.mapping["foo"]).to eq(nil)
1139
+ expect(data.mapping["bar"]).to eq("bar")
1140
+ end
1141
+ it "lists vars" do
1142
+ expect(subject.variables).to eq(["foo", "bar"])
1143
+ end
1144
+ end
1145
+
1146
+ describe "Level 3:" do
1147
+ context "no operator" do
1148
+ subject { Addressable::Template.new("foo{foo,bar}baz") }
1149
+ it "can match" do
1150
+ data = subject.match("foofoo,barbaz")
1151
+ expect(data.mapping["foo"]).to eq("foo")
1152
+ expect(data.mapping["bar"]).to eq("bar")
1153
+ end
1154
+ it "lists vars" do
1155
+ expect(subject.variables).to eq(["foo", "bar"])
1156
+ end
1157
+ end
1158
+ context "+ operator" do
1159
+ subject { Addressable::Template.new("foo{+foo,bar}baz") }
1160
+ it "can match" do
1161
+ data = subject.match("foofoo/bar,barbaz")
1162
+ expect(data.mapping["bar"]).to eq("foo/bar,bar")
1163
+ expect(data.mapping["foo"]).to eq("")
1164
+ end
1165
+ it "lists vars" do
1166
+ expect(subject.variables).to eq(["foo", "bar"])
1167
+ end
1168
+ end
1169
+ context ". operator" do
1170
+ subject { Addressable::Template.new("foo{.foo,bar}baz") }
1171
+ it "can match" do
1172
+ data = subject.match("foo.foo.barbaz")
1173
+ expect(data.mapping["foo"]).to eq("foo")
1174
+ expect(data.mapping["bar"]).to eq("bar")
1175
+ end
1176
+ it "lists vars" do
1177
+ expect(subject.variables).to eq(["foo", "bar"])
1178
+ end
1179
+ end
1180
+ context "/ operator" do
1181
+ subject { Addressable::Template.new("foo{/foo,bar}baz") }
1182
+ it "can match" do
1183
+ data = subject.match("foo/foo/barbaz")
1184
+ expect(data.mapping["foo"]).to eq("foo")
1185
+ expect(data.mapping["bar"]).to eq("bar")
1186
+ end
1187
+ it "lists vars" do
1188
+ expect(subject.variables).to eq(["foo", "bar"])
1189
+ end
1190
+ end
1191
+ context "; operator" do
1192
+ subject { Addressable::Template.new("foo{;foo,bar,baz}baz") }
1193
+ it "can match" do
1194
+ data = subject.match("foo;foo=bar%20baz;bar=foo;bazbaz")
1195
+ expect(data.mapping["foo"]).to eq("bar baz")
1196
+ expect(data.mapping["bar"]).to eq("foo")
1197
+ expect(data.mapping["baz"]).to eq("")
1198
+ end
1199
+ it "lists vars" do
1200
+ expect(subject.variables).to eq(%w(foo bar baz))
1201
+ end
1202
+ end
1203
+ context "? operator" do
1204
+ context "test" do
1205
+ subject { Addressable::Template.new("foo{?foo,bar}baz") }
1206
+ it "can match" do
1207
+ data = subject.match("foo?foo=bar%20baz&bar=foobaz")
1208
+ expect(data.mapping["foo"]).to eq("bar baz")
1209
+ expect(data.mapping["bar"]).to eq("foo")
1210
+ end
1211
+ it "lists vars" do
1212
+ expect(subject.variables).to eq(%w(foo bar))
1213
+ end
1214
+ end
1215
+
1216
+ context "issue #137" do
1217
+ subject { Addressable::Template.new('/path{?page,per_page}') }
1218
+
1219
+ it "can match empty" do
1220
+ data = subject.match("/path")
1221
+ expect(data.mapping["page"]).to eq(nil)
1222
+ expect(data.mapping["per_page"]).to eq(nil)
1223
+ expect(data.mapping.keys.sort).to eq(['page', 'per_page'])
1224
+ end
1225
+
1226
+ it "can match first var" do
1227
+ data = subject.match("/path?page=1")
1228
+ expect(data.mapping["page"]).to eq("1")
1229
+ expect(data.mapping["per_page"]).to eq(nil)
1230
+ expect(data.mapping.keys.sort).to eq(['page', 'per_page'])
1231
+ end
1232
+
1233
+ it "can match second var" do
1234
+ data = subject.match("/path?per_page=1")
1235
+ expect(data.mapping["page"]).to eq(nil)
1236
+ expect(data.mapping["per_page"]).to eq("1")
1237
+ expect(data.mapping.keys.sort).to eq(['page', 'per_page'])
1238
+ end
1239
+
1240
+ it "can match both vars" do
1241
+ data = subject.match("/path?page=2&per_page=1")
1242
+ expect(data.mapping["page"]).to eq("2")
1243
+ expect(data.mapping["per_page"]).to eq("1")
1244
+ expect(data.mapping.keys.sort).to eq(['page', 'per_page'])
1245
+ end
1246
+ end
1247
+
1248
+ context "issue #71" do
1249
+ subject { Addressable::Template.new("http://cyberscore.dev/api/users{?username}") }
1250
+ it "can match" do
1251
+ data = subject.match("http://cyberscore.dev/api/users?username=foobaz")
1252
+ expect(data.mapping["username"]).to eq("foobaz")
1253
+ end
1254
+ it "lists vars" do
1255
+ expect(subject.variables).to eq(%w(username))
1256
+ expect(subject.keys).to eq(%w(username))
1257
+ end
1258
+ end
1259
+ end
1260
+ context "& operator" do
1261
+ subject { Addressable::Template.new("foo{&foo,bar}baz") }
1262
+ it "can match" do
1263
+ data = subject.match("foo&foo=bar%20baz&bar=foobaz")
1264
+ expect(data.mapping["foo"]).to eq("bar baz")
1265
+ expect(data.mapping["bar"]).to eq("foo")
1266
+ end
1267
+ it "lists vars" do
1268
+ expect(subject.variables).to eq(%w(foo bar))
1269
+ end
1270
+ end
1271
+ end
1272
+ end
1273
+
1274
+ context "support regexes:" do
1275
+ context "EXPRESSION" do
1276
+ subject { Addressable::Template::EXPRESSION }
1277
+ it "should be able to match an expression" do
1278
+ expect(subject).to match("{foo}")
1279
+ expect(subject).to match("{foo,9}")
1280
+ expect(subject).to match("{foo.bar,baz}")
1281
+ expect(subject).to match("{+foo.bar,baz}")
1282
+ expect(subject).to match("{foo,foo%20bar}")
1283
+ expect(subject).to match("{#foo:20,baz*}")
1284
+ expect(subject).to match("stuff{#foo:20,baz*}things")
1285
+ end
1286
+ it "should fail on non vars" do
1287
+ expect(subject).not_to match("!{foo")
1288
+ expect(subject).not_to match("{foo.bar.}")
1289
+ expect(subject).not_to match("!{}")
1290
+ end
1291
+ end
1292
+ context "VARNAME" do
1293
+ subject { Addressable::Template::VARNAME }
1294
+ it "should be able to match a variable" do
1295
+ expect(subject).to match("foo")
1296
+ expect(subject).to match("9")
1297
+ expect(subject).to match("foo.bar")
1298
+ expect(subject).to match("foo_bar")
1299
+ expect(subject).to match("foo_bar.baz")
1300
+ expect(subject).to match("foo%20bar")
1301
+ expect(subject).to match("foo%20bar.baz")
1302
+ end
1303
+ it "should fail on non vars" do
1304
+ expect(subject).not_to match("!foo")
1305
+ expect(subject).not_to match("foo.bar.")
1306
+ expect(subject).not_to match("foo%2%00bar")
1307
+ expect(subject).not_to match("foo_ba%r")
1308
+ expect(subject).not_to match("foo_bar*")
1309
+ expect(subject).not_to match("foo_bar:20")
1310
+ end
1311
+ end
1312
+ context "VARIABLE_LIST" do
1313
+ subject { Addressable::Template::VARIABLE_LIST }
1314
+ it "should be able to match a variable list" do
1315
+ expect(subject).to match("foo,bar")
1316
+ expect(subject).to match("foo")
1317
+ expect(subject).to match("foo,bar*,baz")
1318
+ expect(subject).to match("foo.bar,bar_baz*,baz:12")
1319
+ end
1320
+ it "should fail on non vars" do
1321
+ expect(subject).not_to match(",foo,bar*,baz")
1322
+ expect(subject).not_to match("foo,*bar,baz")
1323
+ expect(subject).not_to match("foo,,bar*,baz")
1324
+ end
1325
+ end
1326
+ context "VARSPEC" do
1327
+ subject { Addressable::Template::VARSPEC }
1328
+ it "should be able to match a variable with modifier" do
1329
+ expect(subject).to match("9:8")
1330
+ expect(subject).to match("foo.bar*")
1331
+ expect(subject).to match("foo_bar:12")
1332
+ expect(subject).to match("foo_bar.baz*")
1333
+ expect(subject).to match("foo%20bar:12")
1334
+ expect(subject).to match("foo%20bar.baz*")
1335
+ end
1336
+ it "should fail on non vars" do
1337
+ expect(subject).not_to match("!foo")
1338
+ expect(subject).not_to match("*foo")
1339
+ expect(subject).not_to match("fo*o")
1340
+ expect(subject).not_to match("fo:o")
1341
+ expect(subject).not_to match("foo:")
1342
+ end
1343
+ end
1344
+ end
1345
+ end
1346
+
1347
+ describe Addressable::Template::MatchData do
1348
+ let(:template) { Addressable::Template.new('{foo}/{bar}') }
1349
+ subject(:its) { template.match('ab/cd') }
1350
+ its(:uri) { should == Addressable::URI.parse('ab/cd') }
1351
+ its(:template) { should == template }
1352
+ its(:mapping) { should == { 'foo' => 'ab', 'bar' => 'cd' } }
1353
+ its(:variables) { should == ['foo', 'bar'] }
1354
+ its(:keys) { should == ['foo', 'bar'] }
1355
+ its(:names) { should == ['foo', 'bar'] }
1356
+ its(:values) { should == ['ab', 'cd'] }
1357
+ its(:captures) { should == ['ab', 'cd'] }
1358
+ its(:to_a) { should == ['ab/cd', 'ab', 'cd'] }
1359
+ its(:to_s) { should == 'ab/cd' }
1360
+ its(:string) { should == its.to_s }
1361
+ its(:pre_match) { should == "" }
1362
+ its(:post_match) { should == "" }
1363
+
1364
+ describe 'values_at' do
1365
+ it 'returns an array with the values' do
1366
+ expect(its.values_at(0, 2)).to eq(['ab/cd', 'cd'])
1367
+ end
1368
+ it 'allows mixing integer an string keys' do
1369
+ expect(its.values_at('foo', 1)).to eq(['ab', 'ab'])
1370
+ end
1371
+ it 'accepts unknown keys' do
1372
+ expect(its.values_at('baz', 'foo')).to eq([nil, 'ab'])
1373
+ end
1374
+ end
1375
+
1376
+ describe '[]' do
1377
+ context 'string key' do
1378
+ it 'returns the corresponding capture' do
1379
+ expect(its['foo']).to eq('ab')
1380
+ expect(its['bar']).to eq('cd')
1381
+ end
1382
+ it 'returns nil for unknown keys' do
1383
+ expect(its['baz']).to be_nil
1384
+ end
1385
+ end
1386
+ context 'symbol key' do
1387
+ it 'returns the corresponding capture' do
1388
+ expect(its[:foo]).to eq('ab')
1389
+ expect(its[:bar]).to eq('cd')
1390
+ end
1391
+ it 'returns nil for unknown keys' do
1392
+ expect(its[:baz]).to be_nil
1393
+ end
1394
+ end
1395
+ context 'integer key' do
1396
+ it 'returns the full URI for index 0' do
1397
+ expect(its[0]).to eq('ab/cd')
1398
+ end
1399
+ it 'returns the corresponding capture' do
1400
+ expect(its[1]).to eq('ab')
1401
+ expect(its[2]).to eq('cd')
1402
+ end
1403
+ it 'returns nil for unknown keys' do
1404
+ expect(its[3]).to be_nil
1405
+ end
1406
+ end
1407
+ context 'other key' do
1408
+ it 'raises an exception' do
1409
+ expect { its[Object.new] }.to raise_error(TypeError)
1410
+ end
1411
+ end
1412
+ context 'with length' do
1413
+ it 'returns an array starting at index with given length' do
1414
+ expect(its[0, 2]).to eq(['ab/cd', 'ab'])
1415
+ expect(its[2, 1]).to eq(['cd'])
1416
+ end
1417
+ end
1418
+ end
1419
+ end