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