simple-client 0.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (297) hide show
  1. data/.bundle/config +4 -0
  2. data/Gemfile +7 -0
  3. data/Gemfile.lock +23 -0
  4. data/bin/rake +16 -0
  5. data/lib/simple-client/simple-client.rb +229 -0
  6. data/lib/simple-client/version.rb +4 -0
  7. data/lib/simple-client.rb +1 -0
  8. data/test/test_simple-client.rb +236 -0
  9. data/vendor/bundle/ruby/1.8/bin/rake +19 -0
  10. data/vendor/bundle/ruby/1.8/cache/addressable-2.2.8.gem +0 -0
  11. data/vendor/bundle/ruby/1.8/cache/crack-0.3.1.gem +0 -0
  12. data/vendor/bundle/ruby/1.8/cache/rake-0.9.2.2.gem +0 -0
  13. data/vendor/bundle/ruby/1.8/cache/webmock-1.8.8.gem +0 -0
  14. data/vendor/bundle/ruby/1.8/gems/addressable-2.2.8/CHANGELOG.md +126 -0
  15. data/vendor/bundle/ruby/1.8/gems/addressable-2.2.8/Gemfile +17 -0
  16. data/vendor/bundle/ruby/1.8/gems/addressable-2.2.8/Gemfile.lock +35 -0
  17. data/vendor/bundle/ruby/1.8/gems/addressable-2.2.8/LICENSE.txt +202 -0
  18. data/vendor/bundle/ruby/1.8/gems/addressable-2.2.8/README.md +83 -0
  19. data/vendor/bundle/ruby/1.8/gems/addressable-2.2.8/Rakefile +37 -0
  20. data/vendor/bundle/ruby/1.8/gems/addressable-2.2.8/lib/addressable/idna/native.rb +43 -0
  21. data/vendor/bundle/ruby/1.8/gems/addressable-2.2.8/lib/addressable/idna/pure.rb +4886 -0
  22. data/vendor/bundle/ruby/1.8/gems/addressable-2.2.8/lib/addressable/idna.rb +25 -0
  23. data/vendor/bundle/ruby/1.8/gems/addressable-2.2.8/lib/addressable/template.rb +1047 -0
  24. data/vendor/bundle/ruby/1.8/gems/addressable-2.2.8/lib/addressable/uri.rb +2288 -0
  25. data/vendor/bundle/ruby/1.8/gems/addressable-2.2.8/lib/addressable/version.rb +30 -0
  26. data/vendor/bundle/ruby/1.8/gems/addressable-2.2.8/spec/addressable/idna_spec.rb +216 -0
  27. data/vendor/bundle/ruby/1.8/gems/addressable-2.2.8/spec/addressable/net_http_compat_spec.rb +26 -0
  28. data/vendor/bundle/ruby/1.8/gems/addressable-2.2.8/spec/addressable/template_spec.rb +2144 -0
  29. data/vendor/bundle/ruby/1.8/gems/addressable-2.2.8/spec/addressable/uri_spec.rb +4928 -0
  30. data/vendor/bundle/ruby/1.8/gems/addressable-2.2.8/tasks/clobber.rake +2 -0
  31. data/vendor/bundle/ruby/1.8/gems/addressable-2.2.8/tasks/gem.rake +85 -0
  32. data/vendor/bundle/ruby/1.8/gems/addressable-2.2.8/tasks/git.rake +45 -0
  33. data/vendor/bundle/ruby/1.8/gems/addressable-2.2.8/tasks/metrics.rake +22 -0
  34. data/vendor/bundle/ruby/1.8/gems/addressable-2.2.8/tasks/rspec.rake +58 -0
  35. data/vendor/bundle/ruby/1.8/gems/addressable-2.2.8/tasks/rubyforge.rake +89 -0
  36. data/vendor/bundle/ruby/1.8/gems/addressable-2.2.8/tasks/yard.rake +27 -0
  37. data/vendor/bundle/ruby/1.8/gems/addressable-2.2.8/website/index.html +110 -0
  38. data/vendor/bundle/ruby/1.8/gems/crack-0.3.1/History +25 -0
  39. data/vendor/bundle/ruby/1.8/gems/crack-0.3.1/LICENSE +20 -0
  40. data/vendor/bundle/ruby/1.8/gems/crack-0.3.1/README.rdoc +42 -0
  41. data/vendor/bundle/ruby/1.8/gems/crack-0.3.1/Rakefile +32 -0
  42. data/vendor/bundle/ruby/1.8/gems/crack-0.3.1/crack.gemspec +53 -0
  43. data/vendor/bundle/ruby/1.8/gems/crack-0.3.1/lib/crack/json.rb +79 -0
  44. data/vendor/bundle/ruby/1.8/gems/crack-0.3.1/lib/crack/util.rb +17 -0
  45. data/vendor/bundle/ruby/1.8/gems/crack-0.3.1/lib/crack/xml.rb +232 -0
  46. data/vendor/bundle/ruby/1.8/gems/crack-0.3.1/lib/crack.rb +8 -0
  47. data/vendor/bundle/ruby/1.8/gems/crack-0.3.1/test/crack_test.rb +4 -0
  48. data/vendor/bundle/ruby/1.8/gems/crack-0.3.1/test/data/twittersearch-firefox.json +1 -0
  49. data/vendor/bundle/ruby/1.8/gems/crack-0.3.1/test/data/twittersearch-ie.json +1 -0
  50. data/vendor/bundle/ruby/1.8/gems/crack-0.3.1/test/hash_test.rb +28 -0
  51. data/vendor/bundle/ruby/1.8/gems/crack-0.3.1/test/json_test.rb +82 -0
  52. data/vendor/bundle/ruby/1.8/gems/crack-0.3.1/test/parser_test.rb +27 -0
  53. data/vendor/bundle/ruby/1.8/gems/crack-0.3.1/test/string_test.rb +31 -0
  54. data/vendor/bundle/ruby/1.8/gems/crack-0.3.1/test/test_helper.rb +12 -0
  55. data/vendor/bundle/ruby/1.8/gems/crack-0.3.1/test/xml_test.rb +499 -0
  56. data/vendor/bundle/ruby/1.8/gems/rake-0.9.2.2/CHANGES +522 -0
  57. data/vendor/bundle/ruby/1.8/gems/rake-0.9.2.2/MIT-LICENSE +21 -0
  58. data/vendor/bundle/ruby/1.8/gems/rake-0.9.2.2/README.rdoc +197 -0
  59. data/vendor/bundle/ruby/1.8/gems/rake-0.9.2.2/Rakefile +369 -0
  60. data/vendor/bundle/ruby/1.8/gems/rake-0.9.2.2/TODO +20 -0
  61. data/vendor/bundle/ruby/1.8/gems/rake-0.9.2.2/bin/rake +33 -0
  62. data/vendor/bundle/ruby/1.8/gems/rake-0.9.2.2/doc/command_line_usage.rdoc +114 -0
  63. data/vendor/bundle/ruby/1.8/gems/rake-0.9.2.2/doc/example/Rakefile1 +38 -0
  64. data/vendor/bundle/ruby/1.8/gems/rake-0.9.2.2/doc/example/Rakefile2 +35 -0
  65. data/vendor/bundle/ruby/1.8/gems/rake-0.9.2.2/doc/example/a.c +6 -0
  66. data/vendor/bundle/ruby/1.8/gems/rake-0.9.2.2/doc/example/b.c +6 -0
  67. data/vendor/bundle/ruby/1.8/gems/rake-0.9.2.2/doc/example/main.c +11 -0
  68. data/vendor/bundle/ruby/1.8/gems/rake-0.9.2.2/doc/glossary.rdoc +51 -0
  69. data/vendor/bundle/ruby/1.8/gems/rake-0.9.2.2/doc/jamis.rb +591 -0
  70. data/vendor/bundle/ruby/1.8/gems/rake-0.9.2.2/doc/proto_rake.rdoc +127 -0
  71. data/vendor/bundle/ruby/1.8/gems/rake-0.9.2.2/doc/rake.1.gz +0 -0
  72. data/vendor/bundle/ruby/1.8/gems/rake-0.9.2.2/doc/rakefile.rdoc +557 -0
  73. data/vendor/bundle/ruby/1.8/gems/rake-0.9.2.2/doc/rational.rdoc +151 -0
  74. data/vendor/bundle/ruby/1.8/gems/rake-0.9.2.2/doc/release_notes/rake-0.4.14.rdoc +23 -0
  75. data/vendor/bundle/ruby/1.8/gems/rake-0.9.2.2/doc/release_notes/rake-0.4.15.rdoc +35 -0
  76. data/vendor/bundle/ruby/1.8/gems/rake-0.9.2.2/doc/release_notes/rake-0.5.0.rdoc +53 -0
  77. data/vendor/bundle/ruby/1.8/gems/rake-0.9.2.2/doc/release_notes/rake-0.5.3.rdoc +78 -0
  78. data/vendor/bundle/ruby/1.8/gems/rake-0.9.2.2/doc/release_notes/rake-0.5.4.rdoc +46 -0
  79. data/vendor/bundle/ruby/1.8/gems/rake-0.9.2.2/doc/release_notes/rake-0.6.0.rdoc +141 -0
  80. data/vendor/bundle/ruby/1.8/gems/rake-0.9.2.2/doc/release_notes/rake-0.7.0.rdoc +119 -0
  81. data/vendor/bundle/ruby/1.8/gems/rake-0.9.2.2/doc/release_notes/rake-0.7.1.rdoc +59 -0
  82. data/vendor/bundle/ruby/1.8/gems/rake-0.9.2.2/doc/release_notes/rake-0.7.2.rdoc +121 -0
  83. data/vendor/bundle/ruby/1.8/gems/rake-0.9.2.2/doc/release_notes/rake-0.7.3.rdoc +47 -0
  84. data/vendor/bundle/ruby/1.8/gems/rake-0.9.2.2/doc/release_notes/rake-0.8.0.rdoc +114 -0
  85. data/vendor/bundle/ruby/1.8/gems/rake-0.9.2.2/doc/release_notes/rake-0.8.2.rdoc +165 -0
  86. data/vendor/bundle/ruby/1.8/gems/rake-0.9.2.2/doc/release_notes/rake-0.8.3.rdoc +112 -0
  87. data/vendor/bundle/ruby/1.8/gems/rake-0.9.2.2/doc/release_notes/rake-0.8.4.rdoc +147 -0
  88. data/vendor/bundle/ruby/1.8/gems/rake-0.9.2.2/doc/release_notes/rake-0.8.5.rdoc +53 -0
  89. data/vendor/bundle/ruby/1.8/gems/rake-0.9.2.2/doc/release_notes/rake-0.8.6.rdoc +55 -0
  90. data/vendor/bundle/ruby/1.8/gems/rake-0.9.2.2/doc/release_notes/rake-0.8.7.rdoc +55 -0
  91. data/vendor/bundle/ruby/1.8/gems/rake-0.9.2.2/doc/release_notes/rake-0.9.0.rdoc +112 -0
  92. data/vendor/bundle/ruby/1.8/gems/rake-0.9.2.2/doc/release_notes/rake-0.9.1.rdoc +52 -0
  93. data/vendor/bundle/ruby/1.8/gems/rake-0.9.2.2/doc/release_notes/rake-0.9.2.rdoc +49 -0
  94. data/vendor/bundle/ruby/1.8/gems/rake-0.9.2.2/install.rb +90 -0
  95. data/vendor/bundle/ruby/1.8/gems/rake-0.9.2.2/lib/rake/alt_system.rb +109 -0
  96. data/vendor/bundle/ruby/1.8/gems/rake-0.9.2.2/lib/rake/application.rb +595 -0
  97. data/vendor/bundle/ruby/1.8/gems/rake-0.9.2.2/lib/rake/classic_namespace.rb +11 -0
  98. data/vendor/bundle/ruby/1.8/gems/rake-0.9.2.2/lib/rake/clean.rb +32 -0
  99. data/vendor/bundle/ruby/1.8/gems/rake-0.9.2.2/lib/rake/cloneable.rb +25 -0
  100. data/vendor/bundle/ruby/1.8/gems/rake-0.9.2.2/lib/rake/contrib/compositepublisher.rb +21 -0
  101. data/vendor/bundle/ruby/1.8/gems/rake-0.9.2.2/lib/rake/contrib/ftptools.rb +150 -0
  102. data/vendor/bundle/ruby/1.8/gems/rake-0.9.2.2/lib/rake/contrib/publisher.rb +73 -0
  103. data/vendor/bundle/ruby/1.8/gems/rake-0.9.2.2/lib/rake/contrib/rubyforgepublisher.rb +16 -0
  104. data/vendor/bundle/ruby/1.8/gems/rake-0.9.2.2/lib/rake/contrib/sshpublisher.rb +50 -0
  105. data/vendor/bundle/ruby/1.8/gems/rake-0.9.2.2/lib/rake/contrib/sys.rb +191 -0
  106. data/vendor/bundle/ruby/1.8/gems/rake-0.9.2.2/lib/rake/default_loader.rb +10 -0
  107. data/vendor/bundle/ruby/1.8/gems/rake-0.9.2.2/lib/rake/dsl_definition.rb +176 -0
  108. data/vendor/bundle/ruby/1.8/gems/rake-0.9.2.2/lib/rake/early_time.rb +18 -0
  109. data/vendor/bundle/ruby/1.8/gems/rake-0.9.2.2/lib/rake/ext/core.rb +27 -0
  110. data/vendor/bundle/ruby/1.8/gems/rake-0.9.2.2/lib/rake/ext/module.rb +39 -0
  111. data/vendor/bundle/ruby/1.8/gems/rake-0.9.2.2/lib/rake/ext/string.rb +167 -0
  112. data/vendor/bundle/ruby/1.8/gems/rake-0.9.2.2/lib/rake/ext/time.rb +14 -0
  113. data/vendor/bundle/ruby/1.8/gems/rake-0.9.2.2/lib/rake/file_creation_task.rb +24 -0
  114. data/vendor/bundle/ruby/1.8/gems/rake-0.9.2.2/lib/rake/file_list.rb +403 -0
  115. data/vendor/bundle/ruby/1.8/gems/rake-0.9.2.2/lib/rake/file_task.rb +47 -0
  116. data/vendor/bundle/ruby/1.8/gems/rake-0.9.2.2/lib/rake/file_utils.rb +114 -0
  117. data/vendor/bundle/ruby/1.8/gems/rake-0.9.2.2/lib/rake/file_utils_ext.rb +145 -0
  118. data/vendor/bundle/ruby/1.8/gems/rake-0.9.2.2/lib/rake/gempackagetask.rb +15 -0
  119. data/vendor/bundle/ruby/1.8/gems/rake-0.9.2.2/lib/rake/invocation_chain.rb +51 -0
  120. data/vendor/bundle/ruby/1.8/gems/rake-0.9.2.2/lib/rake/invocation_exception_mixin.rb +16 -0
  121. data/vendor/bundle/ruby/1.8/gems/rake-0.9.2.2/lib/rake/loaders/makefile.rb +40 -0
  122. data/vendor/bundle/ruby/1.8/gems/rake-0.9.2.2/lib/rake/multi_task.rb +16 -0
  123. data/vendor/bundle/ruby/1.8/gems/rake-0.9.2.2/lib/rake/name_space.rb +25 -0
  124. data/vendor/bundle/ruby/1.8/gems/rake-0.9.2.2/lib/rake/packagetask.rb +185 -0
  125. data/vendor/bundle/ruby/1.8/gems/rake-0.9.2.2/lib/rake/pathmap.rb +1 -0
  126. data/vendor/bundle/ruby/1.8/gems/rake-0.9.2.2/lib/rake/pseudo_status.rb +24 -0
  127. data/vendor/bundle/ruby/1.8/gems/rake-0.9.2.2/lib/rake/rake_module.rb +29 -0
  128. data/vendor/bundle/ruby/1.8/gems/rake-0.9.2.2/lib/rake/rake_test_loader.rb +22 -0
  129. data/vendor/bundle/ruby/1.8/gems/rake-0.9.2.2/lib/rake/rdoctask.rb +234 -0
  130. data/vendor/bundle/ruby/1.8/gems/rake-0.9.2.2/lib/rake/ruby182_test_unit_fix.rb +25 -0
  131. data/vendor/bundle/ruby/1.8/gems/rake-0.9.2.2/lib/rake/rule_recursion_overflow_error.rb +20 -0
  132. data/vendor/bundle/ruby/1.8/gems/rake-0.9.2.2/lib/rake/runtest.rb +21 -0
  133. data/vendor/bundle/ruby/1.8/gems/rake-0.9.2.2/lib/rake/task.rb +327 -0
  134. data/vendor/bundle/ruby/1.8/gems/rake-0.9.2.2/lib/rake/task_argument_error.rb +7 -0
  135. data/vendor/bundle/ruby/1.8/gems/rake-0.9.2.2/lib/rake/task_arguments.rb +78 -0
  136. data/vendor/bundle/ruby/1.8/gems/rake-0.9.2.2/lib/rake/task_manager.rb +307 -0
  137. data/vendor/bundle/ruby/1.8/gems/rake-0.9.2.2/lib/rake/tasklib.rb +22 -0
  138. data/vendor/bundle/ruby/1.8/gems/rake-0.9.2.2/lib/rake/testtask.rb +191 -0
  139. data/vendor/bundle/ruby/1.8/gems/rake-0.9.2.2/lib/rake/version.rb +8 -0
  140. data/vendor/bundle/ruby/1.8/gems/rake-0.9.2.2/lib/rake/win32.rb +55 -0
  141. data/vendor/bundle/ruby/1.8/gems/rake-0.9.2.2/lib/rake.rb +69 -0
  142. data/vendor/bundle/ruby/1.8/gems/rake-0.9.2.2/test/file_creation.rb +34 -0
  143. data/vendor/bundle/ruby/1.8/gems/rake-0.9.2.2/test/helper.rb +492 -0
  144. data/vendor/bundle/ruby/1.8/gems/rake-0.9.2.2/test/test_rake.rb +40 -0
  145. data/vendor/bundle/ruby/1.8/gems/rake-0.9.2.2/test/test_rake_application.rb +489 -0
  146. data/vendor/bundle/ruby/1.8/gems/rake-0.9.2.2/test/test_rake_application_options.rb +335 -0
  147. data/vendor/bundle/ruby/1.8/gems/rake-0.9.2.2/test/test_rake_clean.rb +14 -0
  148. data/vendor/bundle/ruby/1.8/gems/rake-0.9.2.2/test/test_rake_definitions.rb +80 -0
  149. data/vendor/bundle/ruby/1.8/gems/rake-0.9.2.2/test/test_rake_directory_task.rb +46 -0
  150. data/vendor/bundle/ruby/1.8/gems/rake-0.9.2.2/test/test_rake_dsl.rb +77 -0
  151. data/vendor/bundle/ruby/1.8/gems/rake-0.9.2.2/test/test_rake_early_time.rb +31 -0
  152. data/vendor/bundle/ruby/1.8/gems/rake-0.9.2.2/test/test_rake_extension.rb +59 -0
  153. data/vendor/bundle/ruby/1.8/gems/rake-0.9.2.2/test/test_rake_file_creation_task.rb +56 -0
  154. data/vendor/bundle/ruby/1.8/gems/rake-0.9.2.2/test/test_rake_file_list.rb +628 -0
  155. data/vendor/bundle/ruby/1.8/gems/rake-0.9.2.2/test/test_rake_file_list_path_map.rb +8 -0
  156. data/vendor/bundle/ruby/1.8/gems/rake-0.9.2.2/test/test_rake_file_task.rb +102 -0
  157. data/vendor/bundle/ruby/1.8/gems/rake-0.9.2.2/test/test_rake_file_utils.rb +305 -0
  158. data/vendor/bundle/ruby/1.8/gems/rake-0.9.2.2/test/test_rake_ftp_file.rb +59 -0
  159. data/vendor/bundle/ruby/1.8/gems/rake-0.9.2.2/test/test_rake_functional.rb +450 -0
  160. data/vendor/bundle/ruby/1.8/gems/rake-0.9.2.2/test/test_rake_invocation_chain.rb +52 -0
  161. data/vendor/bundle/ruby/1.8/gems/rake-0.9.2.2/test/test_rake_makefile_loader.rb +44 -0
  162. data/vendor/bundle/ruby/1.8/gems/rake-0.9.2.2/test/test_rake_multi_task.rb +51 -0
  163. data/vendor/bundle/ruby/1.8/gems/rake-0.9.2.2/test/test_rake_name_space.rb +43 -0
  164. data/vendor/bundle/ruby/1.8/gems/rake-0.9.2.2/test/test_rake_package_task.rb +79 -0
  165. data/vendor/bundle/ruby/1.8/gems/rake-0.9.2.2/test/test_rake_path_map.rb +157 -0
  166. data/vendor/bundle/ruby/1.8/gems/rake-0.9.2.2/test/test_rake_path_map_explode.rb +34 -0
  167. data/vendor/bundle/ruby/1.8/gems/rake-0.9.2.2/test/test_rake_path_map_partial.rb +18 -0
  168. data/vendor/bundle/ruby/1.8/gems/rake-0.9.2.2/test/test_rake_pseudo_status.rb +21 -0
  169. data/vendor/bundle/ruby/1.8/gems/rake-0.9.2.2/test/test_rake_rake_test_loader.rb +21 -0
  170. data/vendor/bundle/ruby/1.8/gems/rake-0.9.2.2/test/test_rake_rdoc_task.rb +83 -0
  171. data/vendor/bundle/ruby/1.8/gems/rake-0.9.2.2/test/test_rake_require.rb +40 -0
  172. data/vendor/bundle/ruby/1.8/gems/rake-0.9.2.2/test/test_rake_rules.rb +327 -0
  173. data/vendor/bundle/ruby/1.8/gems/rake-0.9.2.2/test/test_rake_task.rb +267 -0
  174. data/vendor/bundle/ruby/1.8/gems/rake-0.9.2.2/test/test_rake_task_argument_parsing.rb +103 -0
  175. data/vendor/bundle/ruby/1.8/gems/rake-0.9.2.2/test/test_rake_task_arguments.rb +88 -0
  176. data/vendor/bundle/ruby/1.8/gems/rake-0.9.2.2/test/test_rake_task_lib.rb +9 -0
  177. data/vendor/bundle/ruby/1.8/gems/rake-0.9.2.2/test/test_rake_task_manager.rb +157 -0
  178. data/vendor/bundle/ruby/1.8/gems/rake-0.9.2.2/test/test_rake_task_manager_argument_resolution.rb +36 -0
  179. data/vendor/bundle/ruby/1.8/gems/rake-0.9.2.2/test/test_rake_task_with_arguments.rb +173 -0
  180. data/vendor/bundle/ruby/1.8/gems/rake-0.9.2.2/test/test_rake_test_task.rb +120 -0
  181. data/vendor/bundle/ruby/1.8/gems/rake-0.9.2.2/test/test_rake_top_level_functions.rb +111 -0
  182. data/vendor/bundle/ruby/1.8/gems/rake-0.9.2.2/test/test_rake_win32.rb +72 -0
  183. data/vendor/bundle/ruby/1.8/gems/rake-0.9.2.2/test/test_sys.rb +20 -0
  184. data/vendor/bundle/ruby/1.8/gems/webmock-1.8.8/CHANGELOG.md +749 -0
  185. data/vendor/bundle/ruby/1.8/gems/webmock-1.8.8/Gemfile +21 -0
  186. data/vendor/bundle/ruby/1.8/gems/webmock-1.8.8/Guardfile +24 -0
  187. data/vendor/bundle/ruby/1.8/gems/webmock-1.8.8/LICENSE +20 -0
  188. data/vendor/bundle/ruby/1.8/gems/webmock-1.8.8/README.md +728 -0
  189. data/vendor/bundle/ruby/1.8/gems/webmock-1.8.8/Rakefile +65 -0
  190. data/vendor/bundle/ruby/1.8/gems/webmock-1.8.8/lib/webmock/api.rb +63 -0
  191. data/vendor/bundle/ruby/1.8/gems/webmock-1.8.8/lib/webmock/assertion_failure.rb +11 -0
  192. data/vendor/bundle/ruby/1.8/gems/webmock-1.8.8/lib/webmock/callback_registry.rb +35 -0
  193. data/vendor/bundle/ruby/1.8/gems/webmock-1.8.8/lib/webmock/config.rb +10 -0
  194. data/vendor/bundle/ruby/1.8/gems/webmock-1.8.8/lib/webmock/cucumber.rb +8 -0
  195. data/vendor/bundle/ruby/1.8/gems/webmock-1.8.8/lib/webmock/deprecation.rb +9 -0
  196. data/vendor/bundle/ruby/1.8/gems/webmock-1.8.8/lib/webmock/errors.rb +33 -0
  197. data/vendor/bundle/ruby/1.8/gems/webmock-1.8.8/lib/webmock/http_lib_adapters/curb_adapter.rb +287 -0
  198. data/vendor/bundle/ruby/1.8/gems/webmock-1.8.8/lib/webmock/http_lib_adapters/em_http_request/em_http_request_0_x.rb +151 -0
  199. data/vendor/bundle/ruby/1.8/gems/webmock-1.8.8/lib/webmock/http_lib_adapters/em_http_request/em_http_request_1_x.rb +212 -0
  200. data/vendor/bundle/ruby/1.8/gems/webmock-1.8.8/lib/webmock/http_lib_adapters/em_http_request_adapter.rb +11 -0
  201. data/vendor/bundle/ruby/1.8/gems/webmock-1.8.8/lib/webmock/http_lib_adapters/excon_adapter.rb +95 -0
  202. data/vendor/bundle/ruby/1.8/gems/webmock-1.8.8/lib/webmock/http_lib_adapters/http_lib_adapter.rb +7 -0
  203. data/vendor/bundle/ruby/1.8/gems/webmock-1.8.8/lib/webmock/http_lib_adapters/http_lib_adapter_registry.rb +19 -0
  204. data/vendor/bundle/ruby/1.8/gems/webmock-1.8.8/lib/webmock/http_lib_adapters/httpclient_adapter.rb +193 -0
  205. data/vendor/bundle/ruby/1.8/gems/webmock-1.8.8/lib/webmock/http_lib_adapters/net_http.rb +279 -0
  206. data/vendor/bundle/ruby/1.8/gems/webmock-1.8.8/lib/webmock/http_lib_adapters/net_http_response.rb +34 -0
  207. data/vendor/bundle/ruby/1.8/gems/webmock-1.8.8/lib/webmock/http_lib_adapters/patron_adapter.rb +129 -0
  208. data/vendor/bundle/ruby/1.8/gems/webmock-1.8.8/lib/webmock/http_lib_adapters/typhoeus_hydra_adapter.rb +180 -0
  209. data/vendor/bundle/ruby/1.8/gems/webmock-1.8.8/lib/webmock/matchers/hash_including_matcher.rb +25 -0
  210. data/vendor/bundle/ruby/1.8/gems/webmock-1.8.8/lib/webmock/minitest.rb +15 -0
  211. data/vendor/bundle/ruby/1.8/gems/webmock-1.8.8/lib/webmock/rack_response.rb +63 -0
  212. data/vendor/bundle/ruby/1.8/gems/webmock-1.8.8/lib/webmock/request_execution_verifier.rb +56 -0
  213. data/vendor/bundle/ruby/1.8/gems/webmock-1.8.8/lib/webmock/request_pattern.rb +282 -0
  214. data/vendor/bundle/ruby/1.8/gems/webmock-1.8.8/lib/webmock/request_registry.rb +35 -0
  215. data/vendor/bundle/ruby/1.8/gems/webmock-1.8.8/lib/webmock/request_signature.rb +50 -0
  216. data/vendor/bundle/ruby/1.8/gems/webmock-1.8.8/lib/webmock/request_stub.rb +97 -0
  217. data/vendor/bundle/ruby/1.8/gems/webmock-1.8.8/lib/webmock/response.rb +144 -0
  218. data/vendor/bundle/ruby/1.8/gems/webmock-1.8.8/lib/webmock/responses_sequence.rb +40 -0
  219. data/vendor/bundle/ruby/1.8/gems/webmock-1.8.8/lib/webmock/rspec/matchers/request_pattern_matcher.rb +42 -0
  220. data/vendor/bundle/ruby/1.8/gems/webmock-1.8.8/lib/webmock/rspec/matchers/webmock_matcher.rb +46 -0
  221. data/vendor/bundle/ruby/1.8/gems/webmock-1.8.8/lib/webmock/rspec/matchers.rb +28 -0
  222. data/vendor/bundle/ruby/1.8/gems/webmock-1.8.8/lib/webmock/rspec.rb +33 -0
  223. data/vendor/bundle/ruby/1.8/gems/webmock-1.8.8/lib/webmock/stub_registry.rb +61 -0
  224. data/vendor/bundle/ruby/1.8/gems/webmock-1.8.8/lib/webmock/stub_request_snippet.rb +30 -0
  225. data/vendor/bundle/ruby/1.8/gems/webmock-1.8.8/lib/webmock/test_unit.rb +20 -0
  226. data/vendor/bundle/ruby/1.8/gems/webmock-1.8.8/lib/webmock/util/hash_counter.rb +25 -0
  227. data/vendor/bundle/ruby/1.8/gems/webmock-1.8.8/lib/webmock/util/hash_keys_stringifier.rb +23 -0
  228. data/vendor/bundle/ruby/1.8/gems/webmock-1.8.8/lib/webmock/util/headers.rb +43 -0
  229. data/vendor/bundle/ruby/1.8/gems/webmock-1.8.8/lib/webmock/util/json.rb +54 -0
  230. data/vendor/bundle/ruby/1.8/gems/webmock-1.8.8/lib/webmock/util/uri.rb +101 -0
  231. data/vendor/bundle/ruby/1.8/gems/webmock-1.8.8/lib/webmock/util/version_checker.rb +73 -0
  232. data/vendor/bundle/ruby/1.8/gems/webmock-1.8.8/lib/webmock/version.rb +3 -0
  233. data/vendor/bundle/ruby/1.8/gems/webmock-1.8.8/lib/webmock/webmock.rb +124 -0
  234. data/vendor/bundle/ruby/1.8/gems/webmock-1.8.8/lib/webmock.rb +49 -0
  235. data/vendor/bundle/ruby/1.8/gems/webmock-1.8.8/minitest/test_helper.rb +29 -0
  236. data/vendor/bundle/ruby/1.8/gems/webmock-1.8.8/minitest/test_webmock.rb +6 -0
  237. data/vendor/bundle/ruby/1.8/gems/webmock-1.8.8/minitest/webmock_spec.rb +50 -0
  238. data/vendor/bundle/ruby/1.8/gems/webmock-1.8.8/spec/acceptance/curb/curb_spec.rb +340 -0
  239. data/vendor/bundle/ruby/1.8/gems/webmock-1.8.8/spec/acceptance/curb/curb_spec_helper.rb +144 -0
  240. data/vendor/bundle/ruby/1.8/gems/webmock-1.8.8/spec/acceptance/em_http_request/em_http_request_spec.rb +183 -0
  241. data/vendor/bundle/ruby/1.8/gems/webmock-1.8.8/spec/acceptance/em_http_request/em_http_request_spec_helper.rb +72 -0
  242. data/vendor/bundle/ruby/1.8/gems/webmock-1.8.8/spec/acceptance/excon/excon_spec.rb +15 -0
  243. data/vendor/bundle/ruby/1.8/gems/webmock-1.8.8/spec/acceptance/excon/excon_spec_helper.rb +38 -0
  244. data/vendor/bundle/ruby/1.8/gems/webmock-1.8.8/spec/acceptance/httpclient/httpclient_spec.rb +76 -0
  245. data/vendor/bundle/ruby/1.8/gems/webmock-1.8.8/spec/acceptance/httpclient/httpclient_spec_helper.rb +48 -0
  246. data/vendor/bundle/ruby/1.8/gems/webmock-1.8.8/spec/acceptance/net_http/net_http_shared.rb +125 -0
  247. data/vendor/bundle/ruby/1.8/gems/webmock-1.8.8/spec/acceptance/net_http/net_http_spec.rb +255 -0
  248. data/vendor/bundle/ruby/1.8/gems/webmock-1.8.8/spec/acceptance/net_http/net_http_spec_helper.rb +55 -0
  249. data/vendor/bundle/ruby/1.8/gems/webmock-1.8.8/spec/acceptance/net_http/real_net_http_spec.rb +20 -0
  250. data/vendor/bundle/ruby/1.8/gems/webmock-1.8.8/spec/acceptance/patron/patron_spec.rb +136 -0
  251. data/vendor/bundle/ruby/1.8/gems/webmock-1.8.8/spec/acceptance/patron/patron_spec_helper.rb +50 -0
  252. data/vendor/bundle/ruby/1.8/gems/webmock-1.8.8/spec/acceptance/shared/allowing_and_disabling_net_connect.rb +142 -0
  253. data/vendor/bundle/ruby/1.8/gems/webmock-1.8.8/spec/acceptance/shared/callbacks.rb +146 -0
  254. data/vendor/bundle/ruby/1.8/gems/webmock-1.8.8/spec/acceptance/shared/complex_cross_concern_behaviors.rb +36 -0
  255. data/vendor/bundle/ruby/1.8/gems/webmock-1.8.8/spec/acceptance/shared/enabling_and_disabling_webmock.rb +95 -0
  256. data/vendor/bundle/ruby/1.8/gems/webmock-1.8.8/spec/acceptance/shared/precedence_of_stubs.rb +15 -0
  257. data/vendor/bundle/ruby/1.8/gems/webmock-1.8.8/spec/acceptance/shared/request_expectations.rb +666 -0
  258. data/vendor/bundle/ruby/1.8/gems/webmock-1.8.8/spec/acceptance/shared/returning_declared_responses.rb +367 -0
  259. data/vendor/bundle/ruby/1.8/gems/webmock-1.8.8/spec/acceptance/shared/stubbing_requests.rb +447 -0
  260. data/vendor/bundle/ruby/1.8/gems/webmock-1.8.8/spec/acceptance/typhoeus/typhoeus_hydra_spec.rb +74 -0
  261. data/vendor/bundle/ruby/1.8/gems/webmock-1.8.8/spec/acceptance/typhoeus/typhoeus_hydra_spec_helper.rb +56 -0
  262. data/vendor/bundle/ruby/1.8/gems/webmock-1.8.8/spec/acceptance/webmock_shared.rb +41 -0
  263. data/vendor/bundle/ruby/1.8/gems/webmock-1.8.8/spec/quality_spec.rb +60 -0
  264. data/vendor/bundle/ruby/1.8/gems/webmock-1.8.8/spec/spec_helper.rb +57 -0
  265. data/vendor/bundle/ruby/1.8/gems/webmock-1.8.8/spec/support/example_curl_output.txt +22 -0
  266. data/vendor/bundle/ruby/1.8/gems/webmock-1.8.8/spec/support/my_rack_app.rb +48 -0
  267. data/vendor/bundle/ruby/1.8/gems/webmock-1.8.8/spec/support/network_connection.rb +25 -0
  268. data/vendor/bundle/ruby/1.8/gems/webmock-1.8.8/spec/support/webmock_server.rb +65 -0
  269. data/vendor/bundle/ruby/1.8/gems/webmock-1.8.8/spec/unit/errors_spec.rb +32 -0
  270. data/vendor/bundle/ruby/1.8/gems/webmock-1.8.8/spec/unit/http_lib_adapters/http_lib_adapter_registry_spec.rb +17 -0
  271. data/vendor/bundle/ruby/1.8/gems/webmock-1.8.8/spec/unit/http_lib_adapters/http_lib_adapter_spec.rb +12 -0
  272. data/vendor/bundle/ruby/1.8/gems/webmock-1.8.8/spec/unit/rack_response_spec.rb +74 -0
  273. data/vendor/bundle/ruby/1.8/gems/webmock-1.8.8/spec/unit/request_execution_verifier_spec.rb +100 -0
  274. data/vendor/bundle/ruby/1.8/gems/webmock-1.8.8/spec/unit/request_pattern_spec.rb +479 -0
  275. data/vendor/bundle/ruby/1.8/gems/webmock-1.8.8/spec/unit/request_registry_spec.rb +75 -0
  276. data/vendor/bundle/ruby/1.8/gems/webmock-1.8.8/spec/unit/request_signature_spec.rb +113 -0
  277. data/vendor/bundle/ruby/1.8/gems/webmock-1.8.8/spec/unit/request_stub_spec.rb +198 -0
  278. data/vendor/bundle/ruby/1.8/gems/webmock-1.8.8/spec/unit/response_spec.rb +267 -0
  279. data/vendor/bundle/ruby/1.8/gems/webmock-1.8.8/spec/unit/stub_registry_spec.rb +86 -0
  280. data/vendor/bundle/ruby/1.8/gems/webmock-1.8.8/spec/unit/stub_request_snippet_spec.rb +95 -0
  281. data/vendor/bundle/ruby/1.8/gems/webmock-1.8.8/spec/unit/util/hash_counter_spec.rb +39 -0
  282. data/vendor/bundle/ruby/1.8/gems/webmock-1.8.8/spec/unit/util/hash_keys_stringifier_spec.rb +27 -0
  283. data/vendor/bundle/ruby/1.8/gems/webmock-1.8.8/spec/unit/util/headers_spec.rb +28 -0
  284. data/vendor/bundle/ruby/1.8/gems/webmock-1.8.8/spec/unit/util/json_spec.rb +7 -0
  285. data/vendor/bundle/ruby/1.8/gems/webmock-1.8.8/spec/unit/util/uri_spec.rb +257 -0
  286. data/vendor/bundle/ruby/1.8/gems/webmock-1.8.8/spec/unit/util/version_checker_spec.rb +59 -0
  287. data/vendor/bundle/ruby/1.8/gems/webmock-1.8.8/spec/unit/webmock_spec.rb +7 -0
  288. data/vendor/bundle/ruby/1.8/gems/webmock-1.8.8/test/http_request.rb +24 -0
  289. data/vendor/bundle/ruby/1.8/gems/webmock-1.8.8/test/shared_test.rb +76 -0
  290. data/vendor/bundle/ruby/1.8/gems/webmock-1.8.8/test/test_helper.rb +23 -0
  291. data/vendor/bundle/ruby/1.8/gems/webmock-1.8.8/test/test_webmock.rb +6 -0
  292. data/vendor/bundle/ruby/1.8/gems/webmock-1.8.8/webmock.gemspec +35 -0
  293. data/vendor/bundle/ruby/1.8/specifications/addressable-2.2.8.gemspec +38 -0
  294. data/vendor/bundle/ruby/1.8/specifications/crack-0.3.1.gemspec +25 -0
  295. data/vendor/bundle/ruby/1.8/specifications/rake-0.9.2.2.gemspec +33 -0
  296. data/vendor/bundle/ruby/1.8/specifications/webmock-1.8.8.gemspec +61 -0
  297. metadata +390 -0
@@ -0,0 +1,1047 @@
1
+ # encoding:utf-8
2
+ #--
3
+ # Copyright (C) 2006-2011 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
+ # <a href="http://tinyurl.com/uritemplatedraft03">URI Template draft 03</a>.
26
+ class Template
27
+ # Constants used throughout the template code.
28
+ anything =
29
+ Addressable::URI::CharacterClasses::RESERVED +
30
+ Addressable::URI::CharacterClasses::UNRESERVED
31
+ OPERATOR_EXPANSION =
32
+ /\{-([a-zA-Z]+)\|([#{anything}]+)\|([#{anything}]+)\}/
33
+ VARIABLE_EXPANSION = /\{([#{anything}]+?)(?:=([#{anything}]+))?\}/
34
+
35
+ ##
36
+ # Raised if an invalid template value is supplied.
37
+ class InvalidTemplateValueError < StandardError
38
+ end
39
+
40
+ ##
41
+ # Raised if an invalid template operator is used in a pattern.
42
+ class InvalidTemplateOperatorError < StandardError
43
+ end
44
+
45
+ ##
46
+ # Raised if an invalid template operator is used in a pattern.
47
+ class TemplateOperatorAbortedError < StandardError
48
+ end
49
+
50
+ ##
51
+ # This class represents the data that is extracted when a Template
52
+ # is matched against a URI.
53
+ class MatchData
54
+ ##
55
+ # Creates a new MatchData object.
56
+ # MatchData objects should never be instantiated directly.
57
+ #
58
+ # @param [Addressable::URI] uri
59
+ # The URI that the template was matched against.
60
+ def initialize(uri, template, mapping)
61
+ @uri = uri.dup.freeze
62
+ @template = template
63
+ @mapping = mapping.dup.freeze
64
+ end
65
+
66
+ ##
67
+ # @return [Addressable::URI]
68
+ # The URI that the Template was matched against.
69
+ attr_reader :uri
70
+
71
+ ##
72
+ # @return [Addressable::Template]
73
+ # The Template used for the match.
74
+ attr_reader :template
75
+
76
+ ##
77
+ # @return [Hash]
78
+ # The mapping that resulted from the match.
79
+ # Note that this mapping does not include keys or values for
80
+ # variables that appear in the Template, but are not present
81
+ # in the URI.
82
+ attr_reader :mapping
83
+
84
+ ##
85
+ # @return [Array]
86
+ # The list of variables that were present in the Template.
87
+ # Note that this list will include variables which do not appear
88
+ # in the mapping because they were not present in URI.
89
+ def variables
90
+ self.template.variables
91
+ end
92
+ alias_method :keys, :variables
93
+
94
+ ##
95
+ # @return [Array]
96
+ # The list of values that were captured by the Template.
97
+ # Note that this list will include nils for any variables which
98
+ # were in the Template, but did not appear in the URI.
99
+ def values
100
+ @values ||= self.variables.inject([]) do |accu, key|
101
+ accu << self.mapping[key]
102
+ accu
103
+ end
104
+ end
105
+ alias_method :captures, :values
106
+
107
+ ##
108
+ # Returns a <tt>String</tt> representation of the MatchData's state.
109
+ #
110
+ # @return [String] The MatchData's state, as a <tt>String</tt>.
111
+ def inspect
112
+ sprintf("#<%s:%#0x RESULT:%s>",
113
+ self.class.to_s, self.object_id, self.mapping.inspect)
114
+ end
115
+ end
116
+
117
+ ##
118
+ # Creates a new <tt>Addressable::Template</tt> object.
119
+ #
120
+ # @param [#to_str] pattern The URI Template pattern.
121
+ #
122
+ # @return [Addressable::Template] The initialized Template object.
123
+ def initialize(pattern)
124
+ if !pattern.respond_to?(:to_str)
125
+ raise TypeError, "Can't convert #{pattern.class} into String."
126
+ end
127
+ @pattern = pattern.to_str.freeze
128
+ end
129
+
130
+ ##
131
+ # @return [String] The Template object's pattern.
132
+ attr_reader :pattern
133
+
134
+ ##
135
+ # Returns a <tt>String</tt> representation of the Template object's state.
136
+ #
137
+ # @return [String] The Template object's state, as a <tt>String</tt>.
138
+ def inspect
139
+ sprintf("#<%s:%#0x PATTERN:%s>",
140
+ self.class.to_s, self.object_id, self.pattern)
141
+ end
142
+
143
+ ##
144
+ # Extracts a mapping from the URI using a URI Template pattern.
145
+ #
146
+ # @param [Addressable::URI, #to_str] uri
147
+ # The URI to extract from.
148
+ #
149
+ # @param [#restore, #match] processor
150
+ # A template processor object may optionally be supplied.
151
+ #
152
+ # The object should respond to either the <tt>restore</tt> or
153
+ # <tt>match</tt> messages or both. The <tt>restore</tt> method should
154
+ # take two parameters: `[String] name` and `[String] value`.
155
+ # The <tt>restore</tt> method should reverse any transformations that
156
+ # have been performed on the value to ensure a valid URI.
157
+ # The <tt>match</tt> method should take a single
158
+ # parameter: `[String] name`. The <tt>match</tt> method should return
159
+ # a <tt>String</tt> containing a regular expression capture group for
160
+ # matching on that particular variable. The default value is `".*?"`.
161
+ # The <tt>match</tt> method has no effect on multivariate operator
162
+ # expansions.
163
+ #
164
+ # @return [Hash, NilClass]
165
+ # The <tt>Hash</tt> mapping that was extracted from the URI, or
166
+ # <tt>nil</tt> if the URI didn't match the template.
167
+ #
168
+ # @example
169
+ # class ExampleProcessor
170
+ # def self.restore(name, value)
171
+ # return value.gsub(/\+/, " ") if name == "query"
172
+ # return value
173
+ # end
174
+ #
175
+ # def self.match(name)
176
+ # return ".*?" if name == "first"
177
+ # return ".*"
178
+ # end
179
+ # end
180
+ #
181
+ # uri = Addressable::URI.parse(
182
+ # "http://example.com/search/an+example+search+query/"
183
+ # )
184
+ # Addressable::Template.new(
185
+ # "http://example.com/search/{query}/"
186
+ # ).extract(uri, ExampleProcessor)
187
+ # #=> {"query" => "an example search query"}
188
+ #
189
+ # uri = Addressable::URI.parse("http://example.com/a/b/c/")
190
+ # Addressable::Template.new(
191
+ # "http://example.com/{first}/{second}/"
192
+ # ).extract(uri, ExampleProcessor)
193
+ # #=> {"first" => "a", "second" => "b/c"}
194
+ #
195
+ # uri = Addressable::URI.parse("http://example.com/a/b/c/")
196
+ # Addressable::Template.new(
197
+ # "http://example.com/{first}/{-list|/|second}/"
198
+ # ).extract(uri)
199
+ # #=> {"first" => "a", "second" => ["b", "c"]}
200
+ def extract(uri, processor=nil)
201
+ match_data = self.match(uri, processor)
202
+ return (match_data ? match_data.mapping : nil)
203
+ end
204
+
205
+ ##
206
+ # Extracts match data from the URI using a URI Template pattern.
207
+ #
208
+ # @param [Addressable::URI, #to_str] uri
209
+ # The URI to extract from.
210
+ #
211
+ # @param [#restore, #match] processor
212
+ # A template processor object may optionally be supplied.
213
+ #
214
+ # The object should respond to either the <tt>restore</tt> or
215
+ # <tt>match</tt> messages or both. The <tt>restore</tt> method should
216
+ # take two parameters: `[String] name` and `[String] value`.
217
+ # The <tt>restore</tt> method should reverse any transformations that
218
+ # have been performed on the value to ensure a valid URI.
219
+ # The <tt>match</tt> method should take a single
220
+ # parameter: `[String] name`. The <tt>match</tt> method should return
221
+ # a <tt>String</tt> containing a regular expression capture group for
222
+ # matching on that particular variable. The default value is `".*?"`.
223
+ # The <tt>match</tt> method has no effect on multivariate operator
224
+ # expansions.
225
+ #
226
+ # @return [Hash, NilClass]
227
+ # The <tt>Hash</tt> mapping that was extracted from the URI, or
228
+ # <tt>nil</tt> if the URI didn't match the template.
229
+ #
230
+ # @example
231
+ # class ExampleProcessor
232
+ # def self.restore(name, value)
233
+ # return value.gsub(/\+/, " ") if name == "query"
234
+ # return value
235
+ # end
236
+ #
237
+ # def self.match(name)
238
+ # return ".*?" if name == "first"
239
+ # return ".*"
240
+ # end
241
+ # end
242
+ #
243
+ # uri = Addressable::URI.parse(
244
+ # "http://example.com/search/an+example+search+query/"
245
+ # )
246
+ # match = Addressable::Template.new(
247
+ # "http://example.com/search/{query}/"
248
+ # ).match(uri, ExampleProcessor)
249
+ # match.variables
250
+ # #=> ["query"]
251
+ # match.captures
252
+ # #=> ["an example search query"]
253
+ #
254
+ # uri = Addressable::URI.parse("http://example.com/a/b/c/")
255
+ # match = Addressable::Template.new(
256
+ # "http://example.com/{first}/{second}/"
257
+ # ).match(uri, ExampleProcessor)
258
+ # match.variables
259
+ # #=> ["first", "second"]
260
+ # match.captures
261
+ # #=> ["a", "b/c"]
262
+ #
263
+ # uri = Addressable::URI.parse("http://example.com/a/b/c/")
264
+ # match = Addressable::Template.new(
265
+ # "http://example.com/{first}/{-list|/|second}/"
266
+ # ).match(uri)
267
+ # match.variables
268
+ # #=> ["first", "second"]
269
+ # match.captures
270
+ # #=> ["a", ["b", "c"]]
271
+ def match(uri, processor=nil)
272
+ uri = Addressable::URI.parse(uri)
273
+ mapping = {}
274
+
275
+ # First, we need to process the pattern, and extract the values.
276
+ expansions, expansion_regexp =
277
+ parse_template_pattern(pattern, processor)
278
+ unparsed_values = uri.to_str.scan(expansion_regexp).flatten
279
+
280
+ if uri.to_str == pattern
281
+ return Addressable::Template::MatchData.new(uri, self, mapping)
282
+ elsif expansions.size > 0 && expansions.size == unparsed_values.size
283
+ expansions.each_with_index do |expansion, index|
284
+ unparsed_value = unparsed_values[index]
285
+ if expansion =~ OPERATOR_EXPANSION
286
+ operator, argument, variables =
287
+ parse_template_expansion(expansion)
288
+ extract_method = "extract_#{operator}_operator"
289
+ if ([extract_method, extract_method.to_sym] &
290
+ private_methods).empty?
291
+ raise InvalidTemplateOperatorError,
292
+ "Invalid template operator: #{operator}"
293
+ else
294
+ begin
295
+ send(
296
+ extract_method.to_sym, unparsed_value, processor,
297
+ argument, variables, mapping
298
+ )
299
+ rescue TemplateOperatorAbortedError
300
+ return nil
301
+ end
302
+ end
303
+ else
304
+ name = expansion[VARIABLE_EXPANSION, 1]
305
+ value = unparsed_value
306
+ if processor != nil && processor.respond_to?(:restore)
307
+ value = processor.restore(name, value)
308
+ end
309
+ if mapping[name] == nil || mapping[name] == value
310
+ mapping[name] = value
311
+ else
312
+ return nil
313
+ end
314
+ end
315
+ end
316
+ return Addressable::Template::MatchData.new(uri, self, mapping)
317
+ else
318
+ return nil
319
+ end
320
+ end
321
+
322
+ ##
323
+ # Expands a URI template into another URI template.
324
+ #
325
+ # @param [Hash] mapping The mapping that corresponds to the pattern.
326
+ # @param [#validate, #transform] processor
327
+ # An optional processor object may be supplied.
328
+ #
329
+ # The object should respond to either the <tt>validate</tt> or
330
+ # <tt>transform</tt> messages or both. Both the <tt>validate</tt> and
331
+ # <tt>transform</tt> methods should take two parameters: <tt>name</tt> and
332
+ # <tt>value</tt>. The <tt>validate</tt> method should return <tt>true</tt>
333
+ # or <tt>false</tt>; <tt>true</tt> if the value of the variable is valid,
334
+ # <tt>false</tt> otherwise. An <tt>InvalidTemplateValueError</tt>
335
+ # exception will be raised if the value is invalid. The <tt>transform</tt>
336
+ # method should return the transformed variable value as a <tt>String</tt>.
337
+ # If a <tt>transform</tt> method is used, the value will not be percent
338
+ # encoded automatically. Unicode normalization will be performed both
339
+ # before and after sending the value to the transform method.
340
+ #
341
+ # @return [Addressable::Template] The partially expanded URI template.
342
+ #
343
+ # @example
344
+ # Addressable::Template.new(
345
+ # "http://example.com/{one}/{two}/"
346
+ # ).partial_expand({"one" => "1"}).pattern
347
+ # #=> "http://example.com/1/{two}/"
348
+ #
349
+ # Addressable::Template.new(
350
+ # "http://example.com/search/{-list|+|query}/"
351
+ # ).partial_expand(
352
+ # {"query" => "an example search query".split(" ")}
353
+ # ).pattern
354
+ # #=> "http://example.com/search/an+example+search+query/"
355
+ #
356
+ # Addressable::Template.new(
357
+ # "http://example.com/{-join|&|one,two}/"
358
+ # ).partial_expand({"one" => "1"}).pattern
359
+ # #=> "http://example.com/?one=1{-prefix|&two=|two}"
360
+ #
361
+ # Addressable::Template.new(
362
+ # "http://example.com/{-join|&|one,two,three}/"
363
+ # ).partial_expand({"one" => "1", "three" => 3}).pattern
364
+ # #=> "http://example.com/?one=1{-prefix|&two=|two}&three=3"
365
+ def partial_expand(mapping, processor=nil)
366
+ result = self.pattern.dup
367
+ transformed_mapping = transform_mapping(mapping, processor)
368
+ result.gsub!(
369
+ /#{OPERATOR_EXPANSION}|#{VARIABLE_EXPANSION}/
370
+ ) do |capture|
371
+ if capture =~ OPERATOR_EXPANSION
372
+ operator, argument, variables, default_mapping =
373
+ parse_template_expansion(capture, transformed_mapping)
374
+ expand_method = "expand_#{operator}_operator"
375
+ if ([expand_method, expand_method.to_sym] & private_methods).empty?
376
+ raise InvalidTemplateOperatorError,
377
+ "Invalid template operator: #{operator}"
378
+ else
379
+ send(
380
+ expand_method.to_sym, argument, variables,
381
+ default_mapping, true
382
+ )
383
+ end
384
+ else
385
+ varname, _, vardefault = capture.scan(/^\{(.+?)(=(.*))?\}$/)[0]
386
+ if transformed_mapping[varname]
387
+ transformed_mapping[varname]
388
+ elsif vardefault
389
+ "{#{varname}=#{vardefault}}"
390
+ else
391
+ "{#{varname}}"
392
+ end
393
+ end
394
+ end
395
+ return Addressable::Template.new(result)
396
+ end
397
+
398
+ ##
399
+ # Expands a URI template into a full URI.
400
+ #
401
+ # @param [Hash] mapping The mapping that corresponds to the pattern.
402
+ # @param [#validate, #transform] processor
403
+ # An optional processor object may be supplied.
404
+ #
405
+ # The object should respond to either the <tt>validate</tt> or
406
+ # <tt>transform</tt> messages or both. Both the <tt>validate</tt> and
407
+ # <tt>transform</tt> methods should take two parameters: <tt>name</tt> and
408
+ # <tt>value</tt>. The <tt>validate</tt> method should return <tt>true</tt>
409
+ # or <tt>false</tt>; <tt>true</tt> if the value of the variable is valid,
410
+ # <tt>false</tt> otherwise. An <tt>InvalidTemplateValueError</tt>
411
+ # exception will be raised if the value is invalid. The <tt>transform</tt>
412
+ # method should return the transformed variable value as a <tt>String</tt>.
413
+ # If a <tt>transform</tt> method is used, the value will not be percent
414
+ # encoded automatically. Unicode normalization will be performed both
415
+ # before and after sending the value to the transform method.
416
+ #
417
+ # @return [Addressable::URI] The expanded URI template.
418
+ #
419
+ # @example
420
+ # class ExampleProcessor
421
+ # def self.validate(name, value)
422
+ # return !!(value =~ /^[\w ]+$/) if name == "query"
423
+ # return true
424
+ # end
425
+ #
426
+ # def self.transform(name, value)
427
+ # return value.gsub(/ /, "+") if name == "query"
428
+ # return value
429
+ # end
430
+ # end
431
+ #
432
+ # Addressable::Template.new(
433
+ # "http://example.com/search/{query}/"
434
+ # ).expand(
435
+ # {"query" => "an example search query"},
436
+ # ExampleProcessor
437
+ # ).to_str
438
+ # #=> "http://example.com/search/an+example+search+query/"
439
+ #
440
+ # Addressable::Template.new(
441
+ # "http://example.com/search/{-list|+|query}/"
442
+ # ).expand(
443
+ # {"query" => "an example search query".split(" ")}
444
+ # ).to_str
445
+ # #=> "http://example.com/search/an+example+search+query/"
446
+ #
447
+ # Addressable::Template.new(
448
+ # "http://example.com/search/{query}/"
449
+ # ).expand(
450
+ # {"query" => "bogus!"},
451
+ # ExampleProcessor
452
+ # ).to_str
453
+ # #=> Addressable::Template::InvalidTemplateValueError
454
+ def expand(mapping, processor=nil)
455
+ result = self.pattern.dup
456
+ transformed_mapping = transform_mapping(mapping, processor)
457
+ result.gsub!(
458
+ /#{OPERATOR_EXPANSION}|#{VARIABLE_EXPANSION}/
459
+ ) do |capture|
460
+ if capture =~ OPERATOR_EXPANSION
461
+ operator, argument, variables, default_mapping =
462
+ parse_template_expansion(capture, transformed_mapping)
463
+ expand_method = "expand_#{operator}_operator"
464
+ if ([expand_method, expand_method.to_sym] & private_methods).empty?
465
+ raise InvalidTemplateOperatorError,
466
+ "Invalid template operator: #{operator}"
467
+ else
468
+ send(expand_method.to_sym, argument, variables, default_mapping)
469
+ end
470
+ else
471
+ varname, _, vardefault = capture.scan(/^\{(.+?)(=(.*))?\}$/)[0]
472
+ transformed_mapping[varname] || vardefault
473
+ end
474
+ end
475
+ return Addressable::URI.parse(result)
476
+ end
477
+
478
+ ##
479
+ # Returns an Array of variables used within the template pattern.
480
+ # The variables are listed in the Array in the order they appear within
481
+ # the pattern. Multiple occurrences of a variable within a pattern are
482
+ # not represented in this Array.
483
+ #
484
+ # @return [Array] The variables present in the template's pattern.
485
+ def variables
486
+ @variables ||= ordered_variable_defaults.map { |var, val| var }.uniq
487
+ end
488
+ alias_method :keys, :variables
489
+
490
+ ##
491
+ # Returns a mapping of variables to their default values specified
492
+ # in the template. Variables without defaults are not returned.
493
+ #
494
+ # @return [Hash] Mapping of template variables to their defaults
495
+ def variable_defaults
496
+ @variable_defaults ||=
497
+ Hash[*ordered_variable_defaults.reject { |k, v| v.nil? }.flatten]
498
+ end
499
+
500
+ private
501
+ def ordered_variable_defaults
502
+ @ordered_variable_defaults ||= (begin
503
+ expansions, expansion_regexp = parse_template_pattern(pattern)
504
+
505
+ expansions.inject([]) do |result, expansion|
506
+ case expansion
507
+ when OPERATOR_EXPANSION
508
+ _, _, variables, mapping = parse_template_expansion(expansion)
509
+ result.concat variables.map { |var| [var, mapping[var]] }
510
+ when VARIABLE_EXPANSION
511
+ result << [$1, $2]
512
+ end
513
+ result
514
+ end
515
+ end)
516
+ end
517
+
518
+ ##
519
+ # Transforms a mapping so that values can be substituted into the
520
+ # template.
521
+ #
522
+ # @param [Hash] mapping The mapping of variables to values.
523
+ # @param [#validate, #transform] processor
524
+ # An optional processor object may be supplied.
525
+ #
526
+ # The object should respond to either the <tt>validate</tt> or
527
+ # <tt>transform</tt> messages or both. Both the <tt>validate</tt> and
528
+ # <tt>transform</tt> methods should take two parameters: <tt>name</tt> and
529
+ # <tt>value</tt>. The <tt>validate</tt> method should return <tt>true</tt>
530
+ # or <tt>false</tt>; <tt>true</tt> if the value of the variable is valid,
531
+ # <tt>false</tt> otherwise. An <tt>InvalidTemplateValueError</tt> exception
532
+ # will be raised if the value is invalid. The <tt>transform</tt> method
533
+ # should return the transformed variable value as a <tt>String</tt>. If a
534
+ # <tt>transform</tt> method is used, the value will not be percent encoded
535
+ # automatically. Unicode normalization will be performed both before and
536
+ # after sending the value to the transform method.
537
+ #
538
+ # @return [Hash] The transformed mapping.
539
+ def transform_mapping(mapping, processor=nil)
540
+ return mapping.inject({}) do |accu, pair|
541
+ name, value = pair
542
+ value = value.to_s if Numeric === value || Symbol === value
543
+
544
+ unless value.respond_to?(:to_ary) || value.respond_to?(:to_str)
545
+ raise TypeError,
546
+ "Can't convert #{value.class} into String or Array."
547
+ end
548
+
549
+ if Symbol === name
550
+ name = name.to_s
551
+ elsif name.respond_to?(:to_str)
552
+ name = name.to_str
553
+ else
554
+ raise TypeError,
555
+ "Can't convert #{name.class} into String."
556
+ end
557
+ value = value.respond_to?(:to_ary) ? value.to_ary : value.to_str
558
+
559
+ # Handle unicode normalization
560
+ if value.kind_of?(Array)
561
+ value.map! { |val| Addressable::IDNA.unicode_normalize_kc(val) }
562
+ else
563
+ value = Addressable::IDNA.unicode_normalize_kc(value)
564
+ end
565
+
566
+ if processor == nil || !processor.respond_to?(:transform)
567
+ # Handle percent escaping
568
+ if value.kind_of?(Array)
569
+ transformed_value = value.map do |val|
570
+ Addressable::URI.encode_component(
571
+ val, Addressable::URI::CharacterClasses::UNRESERVED)
572
+ end
573
+ else
574
+ transformed_value = Addressable::URI.encode_component(
575
+ value, Addressable::URI::CharacterClasses::UNRESERVED)
576
+ end
577
+ end
578
+
579
+ # Process, if we've got a processor
580
+ if processor != nil
581
+ if processor.respond_to?(:validate)
582
+ if !processor.validate(name, value)
583
+ display_value = value.kind_of?(Array) ? value.inspect : value
584
+ raise InvalidTemplateValueError,
585
+ "#{name}=#{display_value} is an invalid template value."
586
+ end
587
+ end
588
+ if processor.respond_to?(:transform)
589
+ transformed_value = processor.transform(name, value)
590
+ if transformed_value.kind_of?(Array)
591
+ transformed_value.map! do |val|
592
+ Addressable::IDNA.unicode_normalize_kc(val)
593
+ end
594
+ else
595
+ transformed_value =
596
+ Addressable::IDNA.unicode_normalize_kc(transformed_value)
597
+ end
598
+ end
599
+ end
600
+
601
+ accu[name] = transformed_value
602
+ accu
603
+ end
604
+ end
605
+
606
+ ##
607
+ # Expands a URI Template opt operator.
608
+ #
609
+ # @param [String] argument The argument to the operator.
610
+ # @param [Array] variables The variables the operator is working on.
611
+ # @param [Hash] mapping The mapping of variables to values.
612
+ #
613
+ # @return [String] The expanded result.
614
+ def expand_opt_operator(argument, variables, mapping, partial=false)
615
+ variables_present = variables.any? do |variable|
616
+ mapping[variable] != [] &&
617
+ mapping[variable]
618
+ end
619
+ if partial && !variables_present
620
+ "{-opt|#{argument}|#{variables.join(",")}}"
621
+ elsif variables_present
622
+ argument
623
+ else
624
+ ""
625
+ end
626
+ end
627
+
628
+ ##
629
+ # Expands a URI Template neg operator.
630
+ #
631
+ # @param [String] argument The argument to the operator.
632
+ # @param [Array] variables The variables the operator is working on.
633
+ # @param [Hash] mapping The mapping of variables to values.
634
+ #
635
+ # @return [String] The expanded result.
636
+ def expand_neg_operator(argument, variables, mapping, partial=false)
637
+ variables_present = variables.any? do |variable|
638
+ mapping[variable] != [] &&
639
+ mapping[variable]
640
+ end
641
+ if partial && !variables_present
642
+ "{-neg|#{argument}|#{variables.join(",")}}"
643
+ elsif variables_present
644
+ ""
645
+ else
646
+ argument
647
+ end
648
+ end
649
+
650
+ ##
651
+ # Expands a URI Template prefix operator.
652
+ #
653
+ # @param [String] argument The argument to the operator.
654
+ # @param [Array] variables The variables the operator is working on.
655
+ # @param [Hash] mapping The mapping of variables to values.
656
+ #
657
+ # @return [String] The expanded result.
658
+ def expand_prefix_operator(argument, variables, mapping, partial=false)
659
+ if variables.size != 1
660
+ raise InvalidTemplateOperatorError,
661
+ "Template operator 'prefix' takes exactly one variable."
662
+ end
663
+ value = mapping[variables.first]
664
+ if !partial || value
665
+ if value.kind_of?(Array)
666
+ (value.map { |list_value| argument + list_value }).join("")
667
+ elsif value
668
+ argument + value.to_s
669
+ end
670
+ else
671
+ "{-prefix|#{argument}|#{variables.first}}"
672
+ end
673
+ end
674
+
675
+ ##
676
+ # Expands a URI Template suffix operator.
677
+ #
678
+ # @param [String] argument The argument to the operator.
679
+ # @param [Array] variables The variables the operator is working on.
680
+ # @param [Hash] mapping The mapping of variables to values.
681
+ #
682
+ # @return [String] The expanded result.
683
+ def expand_suffix_operator(argument, variables, mapping, partial=false)
684
+ if variables.size != 1
685
+ raise InvalidTemplateOperatorError,
686
+ "Template operator 'suffix' takes exactly one variable."
687
+ end
688
+ value = mapping[variables.first]
689
+ if !partial || value
690
+ if value.kind_of?(Array)
691
+ (value.map { |list_value| list_value + argument }).join("")
692
+ elsif value
693
+ value.to_s + argument
694
+ end
695
+ else
696
+ "{-suffix|#{argument}|#{variables.first}}"
697
+ end
698
+ end
699
+
700
+ ##
701
+ # Expands a URI Template join operator.
702
+ #
703
+ # @param [String] argument The argument to the operator.
704
+ # @param [Array] variables The variables the operator is working on.
705
+ # @param [Hash] mapping The mapping of variables to values.
706
+ #
707
+ # @return [String] The expanded result.
708
+ def expand_join_operator(argument, variables, mapping, partial=false)
709
+ if !partial
710
+ variable_values = variables.inject([]) do |accu, variable|
711
+ if !mapping[variable].kind_of?(Array)
712
+ if mapping[variable]
713
+ accu << variable + "=" + (mapping[variable])
714
+ end
715
+ else
716
+ raise InvalidTemplateOperatorError,
717
+ "Template operator 'join' does not accept Array values."
718
+ end
719
+ accu
720
+ end
721
+ variable_values.join(argument)
722
+ else
723
+ buffer = ""
724
+ state = :suffix
725
+ variables.each_with_index do |variable, index|
726
+ if !mapping[variable].kind_of?(Array)
727
+ if mapping[variable]
728
+ if buffer.empty? || buffer[-1..-1] == "}"
729
+ buffer << (variable + "=" + (mapping[variable]))
730
+ elsif state == :suffix
731
+ buffer << argument
732
+ buffer << (variable + "=" + (mapping[variable]))
733
+ else
734
+ buffer << (variable + "=" + (mapping[variable]))
735
+ end
736
+ else
737
+ if !buffer.empty? && (buffer[-1..-1] != "}" || state == :prefix)
738
+ buffer << "{-opt|#{argument}|#{variable}}"
739
+ state = :prefix
740
+ end
741
+ if buffer.empty? && variables.size == 1
742
+ # Evaluates back to itself
743
+ buffer << "{-join|#{argument}|#{variable}}"
744
+ else
745
+ buffer << "{-prefix|#{variable}=|#{variable}}"
746
+ end
747
+ if (index != (variables.size - 1) && state == :suffix)
748
+ buffer << "{-opt|#{argument}|#{variable}}"
749
+ elsif index != (variables.size - 1) &&
750
+ mapping[variables[index + 1]]
751
+ buffer << argument
752
+ state = :prefix
753
+ end
754
+ end
755
+ else
756
+ raise InvalidTemplateOperatorError,
757
+ "Template operator 'join' does not accept Array values."
758
+ end
759
+ end
760
+ buffer
761
+ end
762
+ end
763
+
764
+ ##
765
+ # Expands a URI Template list operator.
766
+ #
767
+ # @param [String] argument The argument to the operator.
768
+ # @param [Array] variables The variables the operator is working on.
769
+ # @param [Hash] mapping The mapping of variables to values.
770
+ #
771
+ # @return [String] The expanded result.
772
+ def expand_list_operator(argument, variables, mapping, partial=false)
773
+ if variables.size != 1
774
+ raise InvalidTemplateOperatorError,
775
+ "Template operator 'list' takes exactly one variable."
776
+ end
777
+ if !partial || mapping[variables.first]
778
+ values = mapping[variables.first]
779
+ if values
780
+ if values.kind_of?(Array)
781
+ values.join(argument)
782
+ else
783
+ raise InvalidTemplateOperatorError,
784
+ "Template operator 'list' only accepts Array values."
785
+ end
786
+ end
787
+ else
788
+ "{-list|#{argument}|#{variables.first}}"
789
+ end
790
+ end
791
+
792
+ ##
793
+ # Parses a URI template expansion <tt>String</tt>.
794
+ #
795
+ # @param [String] expansion The operator <tt>String</tt>.
796
+ # @param [Hash] mapping An optional mapping to merge defaults into.
797
+ #
798
+ # @return [Array]
799
+ # A tuple of the operator, argument, variables, and mapping.
800
+ def parse_template_expansion(capture, mapping={})
801
+ operator, argument, variables = capture[1...-1].split("|", -1)
802
+ operator.gsub!(/^\-/, "")
803
+ variables = variables.split(",", -1)
804
+ mapping = (variables.inject({}) do |accu, var|
805
+ varname, _, vardefault = var.scan(/^(.+?)(=(.*))?$/)[0]
806
+ accu[varname] = vardefault
807
+ accu
808
+ end).merge(mapping)
809
+ variables = variables.map { |var| var.gsub(/=.*$/, "") }
810
+ return operator, argument, variables, mapping
811
+ end
812
+
813
+ ##
814
+ # Generates the <tt>Regexp</tt> that parses a template pattern.
815
+ #
816
+ # @param [String] pattern The URI template pattern.
817
+ # @param [#match] processor The template processor to use.
818
+ #
819
+ # @return [Regexp]
820
+ # A regular expression which may be used to parse a template pattern.
821
+ def parse_template_pattern(pattern, processor=nil)
822
+ # Escape the pattern. The two gsubs restore the escaped curly braces
823
+ # back to their original form. Basically, escape everything that isn't
824
+ # within an expansion.
825
+ escaped_pattern = Regexp.escape(
826
+ pattern
827
+ ).gsub(/\\\{(.*?)\\\}/) do |escaped|
828
+ escaped.gsub(/\\(.)/, "\\1")
829
+ end
830
+
831
+ expansions = []
832
+
833
+ # Create a regular expression that captures the values of the
834
+ # variables in the URI.
835
+ regexp_string = escaped_pattern.gsub(
836
+ /#{OPERATOR_EXPANSION}|#{VARIABLE_EXPANSION}/
837
+ ) do |expansion|
838
+ expansions << expansion
839
+ if expansion =~ OPERATOR_EXPANSION
840
+ capture_group = "(.*)"
841
+ operator, argument, names, _ =
842
+ parse_template_expansion(expansion)
843
+ if processor != nil && processor.respond_to?(:match)
844
+ # We can only lookup the match values for single variable
845
+ # operator expansions. Besides, ".*" is usually the only
846
+ # reasonable value for multivariate operators anyways.
847
+ if ["prefix", "suffix", "list"].include?(operator)
848
+ capture_group = "(#{processor.match(names.first)})"
849
+ end
850
+ elsif operator == "prefix"
851
+ capture_group = "(#{Regexp.escape(argument)}.*?)"
852
+ elsif operator == "suffix"
853
+ capture_group = "(.*?#{Regexp.escape(argument)})"
854
+ end
855
+ capture_group
856
+ else
857
+ capture_group = "(.*?)"
858
+ if processor != nil && processor.respond_to?(:match)
859
+ name = expansion[/\{([^\}=]+)(=[^\}]+)?\}/, 1]
860
+ capture_group = "(#{processor.match(name)})"
861
+ end
862
+ capture_group
863
+ end
864
+ end
865
+
866
+ # Ensure that the regular expression matches the whole URI.
867
+ regexp_string = "^#{regexp_string}$"
868
+
869
+ return expansions, Regexp.new(regexp_string)
870
+ end
871
+
872
+ ##
873
+ # Extracts a URI Template opt operator.
874
+ #
875
+ # @param [String] value The unparsed value to extract from.
876
+ # @param [#restore] processor The processor object.
877
+ # @param [String] argument The argument to the operator.
878
+ # @param [Array] variables The variables the operator is working on.
879
+ # @param [Hash] mapping The mapping of variables to values.
880
+ #
881
+ # @return [String] The extracted result.
882
+ def extract_opt_operator(
883
+ value, processor, argument, variables, mapping)
884
+ if value != "" && value != argument
885
+ raise TemplateOperatorAbortedError,
886
+ "Value for template operator 'opt' was unexpected."
887
+ end
888
+ end
889
+
890
+ ##
891
+ # Extracts a URI Template neg operator.
892
+ #
893
+ # @param [String] value The unparsed value to extract from.
894
+ # @param [#restore] processor The processor object.
895
+ # @param [String] argument The argument to the operator.
896
+ # @param [Array] variables The variables the operator is working on.
897
+ # @param [Hash] mapping The mapping of variables to values.
898
+ #
899
+ # @return [String] The extracted result.
900
+ def extract_neg_operator(
901
+ value, processor, argument, variables, mapping)
902
+ if value != "" && value != argument
903
+ raise TemplateOperatorAbortedError,
904
+ "Value for template operator 'neg' was unexpected."
905
+ end
906
+ end
907
+
908
+ ##
909
+ # Extracts a URI Template prefix operator.
910
+ #
911
+ # @param [String] value The unparsed value to extract from.
912
+ # @param [#restore] processor The processor object.
913
+ # @param [String] argument The argument to the operator.
914
+ # @param [Array] variables The variables the operator is working on.
915
+ # @param [Hash] mapping The mapping of variables to values.
916
+ #
917
+ # @return [String] The extracted result.
918
+ def extract_prefix_operator(
919
+ value, processor, argument, variables, mapping)
920
+ if variables.size != 1
921
+ raise InvalidTemplateOperatorError,
922
+ "Template operator 'prefix' takes exactly one variable."
923
+ end
924
+ if value[0...argument.size] != argument
925
+ raise TemplateOperatorAbortedError,
926
+ "Value for template operator 'prefix' missing expected prefix."
927
+ end
928
+ values = value.split(argument, -1)
929
+ values << "" if value[-argument.size..-1] == argument
930
+ values.shift if values[0] == ""
931
+ values.pop if values[-1] == ""
932
+
933
+ if processor && processor.respond_to?(:restore)
934
+ values.map! { |val| processor.restore(variables.first, val) }
935
+ end
936
+ values = values.first if values.size == 1
937
+ if mapping[variables.first] == nil || mapping[variables.first] == values
938
+ mapping[variables.first] = values
939
+ else
940
+ raise TemplateOperatorAbortedError,
941
+ "Value mismatch for repeated variable."
942
+ end
943
+ end
944
+
945
+ ##
946
+ # Extracts a URI Template suffix operator.
947
+ #
948
+ # @param [String] value The unparsed value to extract from.
949
+ # @param [#restore] processor The processor object.
950
+ # @param [String] argument The argument to the operator.
951
+ # @param [Array] variables The variables the operator is working on.
952
+ # @param [Hash] mapping The mapping of variables to values.
953
+ #
954
+ # @return [String] The extracted result.
955
+ def extract_suffix_operator(
956
+ value, processor, argument, variables, mapping)
957
+ if variables.size != 1
958
+ raise InvalidTemplateOperatorError,
959
+ "Template operator 'suffix' takes exactly one variable."
960
+ end
961
+ if value[-argument.size..-1] != argument
962
+ raise TemplateOperatorAbortedError,
963
+ "Value for template operator 'suffix' missing expected suffix."
964
+ end
965
+ values = value.split(argument, -1)
966
+ values.pop if values[-1] == ""
967
+ if processor && processor.respond_to?(:restore)
968
+ values.map! { |val| processor.restore(variables.first, val) }
969
+ end
970
+ values = values.first if values.size == 1
971
+ if mapping[variables.first] == nil || mapping[variables.first] == values
972
+ mapping[variables.first] = values
973
+ else
974
+ raise TemplateOperatorAbortedError,
975
+ "Value mismatch for repeated variable."
976
+ end
977
+ end
978
+
979
+ ##
980
+ # Extracts a URI Template join operator.
981
+ #
982
+ # @param [String] value The unparsed value to extract from.
983
+ # @param [#restore] processor The processor object.
984
+ # @param [String] argument The argument to the operator.
985
+ # @param [Array] variables The variables the operator is working on.
986
+ # @param [Hash] mapping The mapping of variables to values.
987
+ #
988
+ # @return [String] The extracted result.
989
+ def extract_join_operator(value, processor, argument, variables, mapping)
990
+ unparsed_values = value.split(argument)
991
+ parsed_variables = []
992
+ for unparsed_value in unparsed_values
993
+ name = unparsed_value[/^(.+?)=(.+)$/, 1]
994
+ parsed_variables << name
995
+ parsed_value = unparsed_value[/^(.+?)=(.+)$/, 2]
996
+ if processor && processor.respond_to?(:restore)
997
+ parsed_value = processor.restore(name, parsed_value)
998
+ end
999
+ if mapping[name] == nil || mapping[name] == parsed_value
1000
+ mapping[name] = parsed_value
1001
+ else
1002
+ raise TemplateOperatorAbortedError,
1003
+ "Value mismatch for repeated variable."
1004
+ end
1005
+ end
1006
+ for variable in variables
1007
+ if !parsed_variables.include?(variable) && mapping[variable] != nil
1008
+ raise TemplateOperatorAbortedError,
1009
+ "Value mismatch for repeated variable."
1010
+ end
1011
+ end
1012
+ if (parsed_variables & variables) != parsed_variables
1013
+ raise TemplateOperatorAbortedError,
1014
+ "Template operator 'join' variable mismatch: " +
1015
+ "#{parsed_variables.inspect}, #{variables.inspect}"
1016
+ end
1017
+ end
1018
+
1019
+ ##
1020
+ # Extracts a URI Template list operator.
1021
+ #
1022
+ # @param [String] value The unparsed value to extract from.
1023
+ # @param [#restore] processor The processor object.
1024
+ # @param [String] argument The argument to the operator.
1025
+ # @param [Array] variables The variables the operator is working on.
1026
+ # @param [Hash] mapping The mapping of variables to values.
1027
+ #
1028
+ # @return [String] The extracted result.
1029
+ def extract_list_operator(value, processor, argument, variables, mapping)
1030
+ if variables.size != 1
1031
+ raise InvalidTemplateOperatorError,
1032
+ "Template operator 'list' takes exactly one variable."
1033
+ end
1034
+ values = value.split(argument, -1)
1035
+ values.pop if values[-1] == ""
1036
+ if processor && processor.respond_to?(:restore)
1037
+ values.map! { |val| processor.restore(variables.first, val) }
1038
+ end
1039
+ if mapping[variables.first] == nil || mapping[variables.first] == values
1040
+ mapping[variables.first] = values
1041
+ else
1042
+ raise TemplateOperatorAbortedError,
1043
+ "Value mismatch for repeated variable."
1044
+ end
1045
+ end
1046
+ end
1047
+ end