webmock 3.7.1

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 (142) hide show
  1. checksums.yaml +7 -0
  2. data/.gemtest +0 -0
  3. data/.gitignore +34 -0
  4. data/.rspec-tm +2 -0
  5. data/.travis.yml +19 -0
  6. data/CHANGELOG.md +1698 -0
  7. data/Gemfile +9 -0
  8. data/LICENSE +20 -0
  9. data/README.md +1125 -0
  10. data/Rakefile +28 -0
  11. data/lib/webmock.rb +59 -0
  12. data/lib/webmock/api.rb +109 -0
  13. data/lib/webmock/assertion_failure.rb +11 -0
  14. data/lib/webmock/callback_registry.rb +35 -0
  15. data/lib/webmock/config.rb +18 -0
  16. data/lib/webmock/cucumber.rb +10 -0
  17. data/lib/webmock/deprecation.rb +9 -0
  18. data/lib/webmock/errors.rb +17 -0
  19. data/lib/webmock/http_lib_adapters/async_http_client_adapter.rb +214 -0
  20. data/lib/webmock/http_lib_adapters/curb_adapter.rb +347 -0
  21. data/lib/webmock/http_lib_adapters/em_http_request_adapter.rb +228 -0
  22. data/lib/webmock/http_lib_adapters/excon_adapter.rb +162 -0
  23. data/lib/webmock/http_lib_adapters/http_lib_adapter.rb +7 -0
  24. data/lib/webmock/http_lib_adapters/http_lib_adapter_registry.rb +19 -0
  25. data/lib/webmock/http_lib_adapters/http_rb/client.rb +14 -0
  26. data/lib/webmock/http_lib_adapters/http_rb/request.rb +16 -0
  27. data/lib/webmock/http_lib_adapters/http_rb/response.rb +43 -0
  28. data/lib/webmock/http_lib_adapters/http_rb/streamer.rb +29 -0
  29. data/lib/webmock/http_lib_adapters/http_rb/webmock.rb +68 -0
  30. data/lib/webmock/http_lib_adapters/http_rb_adapter.rb +37 -0
  31. data/lib/webmock/http_lib_adapters/httpclient_adapter.rb +242 -0
  32. data/lib/webmock/http_lib_adapters/manticore_adapter.rb +130 -0
  33. data/lib/webmock/http_lib_adapters/net_http.rb +361 -0
  34. data/lib/webmock/http_lib_adapters/net_http_response.rb +34 -0
  35. data/lib/webmock/http_lib_adapters/patron_adapter.rb +130 -0
  36. data/lib/webmock/http_lib_adapters/typhoeus_hydra_adapter.rb +174 -0
  37. data/lib/webmock/matchers/any_arg_matcher.rb +13 -0
  38. data/lib/webmock/matchers/hash_argument_matcher.rb +21 -0
  39. data/lib/webmock/matchers/hash_excluding_matcher.rb +15 -0
  40. data/lib/webmock/matchers/hash_including_matcher.rb +17 -0
  41. data/lib/webmock/minitest.rb +41 -0
  42. data/lib/webmock/rack_response.rb +69 -0
  43. data/lib/webmock/request_body_diff.rb +64 -0
  44. data/lib/webmock/request_execution_verifier.rb +77 -0
  45. data/lib/webmock/request_pattern.rb +370 -0
  46. data/lib/webmock/request_registry.rb +35 -0
  47. data/lib/webmock/request_signature.rb +54 -0
  48. data/lib/webmock/request_signature_snippet.rb +61 -0
  49. data/lib/webmock/request_stub.rb +100 -0
  50. data/lib/webmock/response.rb +153 -0
  51. data/lib/webmock/responses_sequence.rb +40 -0
  52. data/lib/webmock/rspec.rb +41 -0
  53. data/lib/webmock/rspec/matchers.rb +27 -0
  54. data/lib/webmock/rspec/matchers/request_pattern_matcher.rb +78 -0
  55. data/lib/webmock/rspec/matchers/webmock_matcher.rb +67 -0
  56. data/lib/webmock/stub_registry.rb +67 -0
  57. data/lib/webmock/stub_request_snippet.rb +38 -0
  58. data/lib/webmock/test_unit.rb +22 -0
  59. data/lib/webmock/util/hash_counter.rb +39 -0
  60. data/lib/webmock/util/hash_keys_stringifier.rb +25 -0
  61. data/lib/webmock/util/hash_validator.rb +17 -0
  62. data/lib/webmock/util/headers.rb +64 -0
  63. data/lib/webmock/util/json.rb +67 -0
  64. data/lib/webmock/util/query_mapper.rb +281 -0
  65. data/lib/webmock/util/uri.rb +110 -0
  66. data/lib/webmock/util/values_stringifier.rb +20 -0
  67. data/lib/webmock/util/version_checker.rb +111 -0
  68. data/lib/webmock/version.rb +3 -0
  69. data/lib/webmock/webmock.rb +161 -0
  70. data/minitest/test_helper.rb +34 -0
  71. data/minitest/test_webmock.rb +9 -0
  72. data/minitest/webmock_spec.rb +60 -0
  73. data/spec/acceptance/async_http_client/async_http_client_spec.rb +349 -0
  74. data/spec/acceptance/async_http_client/async_http_client_spec_helper.rb +73 -0
  75. data/spec/acceptance/curb/curb_spec.rb +492 -0
  76. data/spec/acceptance/curb/curb_spec_helper.rb +147 -0
  77. data/spec/acceptance/em_http_request/em_http_request_spec.rb +406 -0
  78. data/spec/acceptance/em_http_request/em_http_request_spec_helper.rb +77 -0
  79. data/spec/acceptance/excon/excon_spec.rb +77 -0
  80. data/spec/acceptance/excon/excon_spec_helper.rb +50 -0
  81. data/spec/acceptance/http_rb/http_rb_spec.rb +82 -0
  82. data/spec/acceptance/http_rb/http_rb_spec_helper.rb +54 -0
  83. data/spec/acceptance/httpclient/httpclient_spec.rb +217 -0
  84. data/spec/acceptance/httpclient/httpclient_spec_helper.rb +57 -0
  85. data/spec/acceptance/manticore/manticore_spec.rb +56 -0
  86. data/spec/acceptance/manticore/manticore_spec_helper.rb +35 -0
  87. data/spec/acceptance/net_http/net_http_shared.rb +153 -0
  88. data/spec/acceptance/net_http/net_http_spec.rb +331 -0
  89. data/spec/acceptance/net_http/net_http_spec_helper.rb +64 -0
  90. data/spec/acceptance/net_http/real_net_http_spec.rb +20 -0
  91. data/spec/acceptance/patron/patron_spec.rb +125 -0
  92. data/spec/acceptance/patron/patron_spec_helper.rb +54 -0
  93. data/spec/acceptance/shared/allowing_and_disabling_net_connect.rb +313 -0
  94. data/spec/acceptance/shared/callbacks.rb +148 -0
  95. data/spec/acceptance/shared/complex_cross_concern_behaviors.rb +36 -0
  96. data/spec/acceptance/shared/enabling_and_disabling_webmock.rb +95 -0
  97. data/spec/acceptance/shared/precedence_of_stubs.rb +15 -0
  98. data/spec/acceptance/shared/request_expectations.rb +930 -0
  99. data/spec/acceptance/shared/returning_declared_responses.rb +409 -0
  100. data/spec/acceptance/shared/stubbing_requests.rb +643 -0
  101. data/spec/acceptance/typhoeus/typhoeus_hydra_spec.rb +135 -0
  102. data/spec/acceptance/typhoeus/typhoeus_hydra_spec_helper.rb +60 -0
  103. data/spec/acceptance/webmock_shared.rb +41 -0
  104. data/spec/fixtures/test.txt +1 -0
  105. data/spec/quality_spec.rb +84 -0
  106. data/spec/spec_helper.rb +48 -0
  107. data/spec/support/example_curl_output.txt +22 -0
  108. data/spec/support/failures.rb +9 -0
  109. data/spec/support/my_rack_app.rb +53 -0
  110. data/spec/support/network_connection.rb +19 -0
  111. data/spec/support/webmock_server.rb +70 -0
  112. data/spec/unit/api_spec.rb +175 -0
  113. data/spec/unit/errors_spec.rb +129 -0
  114. data/spec/unit/http_lib_adapters/http_lib_adapter_registry_spec.rb +17 -0
  115. data/spec/unit/http_lib_adapters/http_lib_adapter_spec.rb +12 -0
  116. data/spec/unit/matchers/hash_excluding_matcher_spec.rb +61 -0
  117. data/spec/unit/matchers/hash_including_matcher_spec.rb +87 -0
  118. data/spec/unit/rack_response_spec.rb +112 -0
  119. data/spec/unit/request_body_diff_spec.rb +90 -0
  120. data/spec/unit/request_execution_verifier_spec.rb +208 -0
  121. data/spec/unit/request_pattern_spec.rb +601 -0
  122. data/spec/unit/request_registry_spec.rb +95 -0
  123. data/spec/unit/request_signature_snippet_spec.rb +89 -0
  124. data/spec/unit/request_signature_spec.rb +155 -0
  125. data/spec/unit/request_stub_spec.rb +199 -0
  126. data/spec/unit/response_spec.rb +282 -0
  127. data/spec/unit/stub_registry_spec.rb +103 -0
  128. data/spec/unit/stub_request_snippet_spec.rb +115 -0
  129. data/spec/unit/util/hash_counter_spec.rb +39 -0
  130. data/spec/unit/util/hash_keys_stringifier_spec.rb +27 -0
  131. data/spec/unit/util/headers_spec.rb +28 -0
  132. data/spec/unit/util/json_spec.rb +33 -0
  133. data/spec/unit/util/query_mapper_spec.rb +157 -0
  134. data/spec/unit/util/uri_spec.rb +361 -0
  135. data/spec/unit/util/version_checker_spec.rb +65 -0
  136. data/spec/unit/webmock_spec.rb +19 -0
  137. data/test/http_request.rb +24 -0
  138. data/test/shared_test.rb +108 -0
  139. data/test/test_helper.rb +23 -0
  140. data/test/test_webmock.rb +6 -0
  141. data/webmock.gemspec +45 -0
  142. metadata +496 -0
@@ -0,0 +1,41 @@
1
+ require 'webmock'
2
+
3
+ # RSpec 1.x and 2.x compatibility
4
+ if defined?(RSpec::Expectations::ExpectationNotMetError)
5
+ RSPEC_NAMESPACE = RSPEC_CONFIGURER = RSpec
6
+ elsif defined?(Spec) && defined?(Spec.configure)
7
+ RSPEC_NAMESPACE = Spec
8
+ RSPEC_CONFIGURER = Spec::Runner
9
+ else
10
+ begin
11
+ require 'rspec/core'
12
+ require 'rspec/expectations'
13
+ RSPEC_NAMESPACE = RSPEC_CONFIGURER = RSpec
14
+ rescue LoadError
15
+ require 'spec'
16
+ RSPEC_NAMESPACE = Spec
17
+ RSPEC_CONFIGURER = Spec::Runner
18
+ end
19
+ end
20
+
21
+ require 'webmock/rspec/matchers'
22
+
23
+ RSPEC_CONFIGURER.configure { |config|
24
+
25
+ config.include WebMock::API
26
+ config.include WebMock::Matchers
27
+
28
+ config.before(:suite) do
29
+ WebMock.enable!
30
+ end
31
+
32
+ config.after(:suite) do
33
+ WebMock.disable!
34
+ end
35
+
36
+ config.after(:each) do
37
+ WebMock.reset!
38
+ end
39
+ }
40
+
41
+ WebMock::AssertionFailure.error_class = RSPEC_NAMESPACE::Expectations::ExpectationNotMetError
@@ -0,0 +1,27 @@
1
+ require 'webmock'
2
+ require 'webmock/rspec/matchers/request_pattern_matcher'
3
+ require 'webmock/rspec/matchers/webmock_matcher'
4
+
5
+ module WebMock
6
+ module Matchers
7
+ def have_been_made
8
+ WebMock::RequestPatternMatcher.new
9
+ end
10
+
11
+ def have_been_requested
12
+ WebMock::RequestPatternMatcher.new
13
+ end
14
+
15
+ def have_not_been_made
16
+ WebMock::RequestPatternMatcher.new.times(0)
17
+ end
18
+
19
+ def have_requested(method, uri)
20
+ WebMock::WebMockMatcher.new(method, uri)
21
+ end
22
+
23
+ def have_not_requested(method, uri)
24
+ WebMock::WebMockMatcher.new(method, uri).times(0)
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,78 @@
1
+ module WebMock
2
+ class RequestPatternMatcher
3
+
4
+ def initialize
5
+ @request_execution_verifier = RequestExecutionVerifier.new
6
+ end
7
+
8
+ def once
9
+ @request_execution_verifier.expected_times_executed = 1
10
+ self
11
+ end
12
+
13
+ def twice
14
+ @request_execution_verifier.expected_times_executed = 2
15
+ self
16
+ end
17
+
18
+ def times(times)
19
+ @request_execution_verifier.expected_times_executed = times.to_i
20
+ self
21
+ end
22
+
23
+ def at_least_once
24
+ @request_execution_verifier.at_least_times_executed = 1
25
+ self
26
+ end
27
+
28
+ def at_least_twice
29
+ @request_execution_verifier.at_least_times_executed = 2
30
+ self
31
+ end
32
+
33
+ def at_least_times(times)
34
+ @request_execution_verifier.at_least_times_executed = times.to_i
35
+ self
36
+ end
37
+
38
+ def at_most_once
39
+ @request_execution_verifier.at_most_times_executed = 1
40
+ self
41
+ end
42
+
43
+ def at_most_twice
44
+ @request_execution_verifier.at_most_times_executed = 2
45
+ self
46
+ end
47
+
48
+ def at_most_times(times)
49
+ @request_execution_verifier.at_most_times_executed = times.to_i
50
+ self
51
+ end
52
+
53
+ def matches?(request_pattern)
54
+ @request_execution_verifier.request_pattern = request_pattern
55
+ @request_execution_verifier.matches?
56
+ end
57
+
58
+ def does_not_match?(request_pattern)
59
+ @request_execution_verifier.request_pattern = request_pattern
60
+ @request_execution_verifier.does_not_match?
61
+ end
62
+
63
+ def failure_message
64
+ @request_execution_verifier.failure_message
65
+ end
66
+
67
+ def failure_message_when_negated
68
+ @request_execution_verifier.failure_message_when_negated
69
+ end
70
+
71
+ def description
72
+ @request_execution_verifier.description
73
+ end
74
+
75
+ # RSpec 2 compatibility:
76
+ alias_method :negative_failure_message, :failure_message_when_negated
77
+ end
78
+ end
@@ -0,0 +1,67 @@
1
+ module WebMock
2
+ class WebMockMatcher
3
+
4
+ def initialize(method, uri)
5
+ @request_execution_verifier = RequestExecutionVerifier.new
6
+ @request_execution_verifier.request_pattern = RequestPattern.new(method, uri)
7
+ end
8
+
9
+ def once
10
+ @request_execution_verifier.expected_times_executed = 1
11
+ self
12
+ end
13
+
14
+ def twice
15
+ @request_execution_verifier.expected_times_executed = 2
16
+ self
17
+ end
18
+
19
+ def at_least_once
20
+ @request_execution_verifier.at_least_times_executed = 1
21
+ self
22
+ end
23
+
24
+ def at_least_twice
25
+ @request_execution_verifier.at_least_times_executed = 2
26
+ self
27
+ end
28
+
29
+ def at_least_times(times)
30
+ @request_execution_verifier.at_least_times_executed = times
31
+ self
32
+ end
33
+
34
+ def with(options = {}, &block)
35
+ @request_execution_verifier.request_pattern.with(options, &block)
36
+ self
37
+ end
38
+
39
+ def times(times)
40
+ @request_execution_verifier.expected_times_executed = times.to_i
41
+ self
42
+ end
43
+
44
+ def matches?(webmock)
45
+ @request_execution_verifier.matches?
46
+ end
47
+
48
+ def does_not_match?(webmock)
49
+ @request_execution_verifier.does_not_match?
50
+ end
51
+
52
+ def failure_message
53
+ @request_execution_verifier.failure_message
54
+ end
55
+
56
+ def failure_message_when_negated
57
+ @request_execution_verifier.failure_message_when_negated
58
+ end
59
+
60
+ def description
61
+ @request_execution_verifier.description
62
+ end
63
+
64
+ # RSpec 2 compatibility:
65
+ alias_method :negative_failure_message, :failure_message_when_negated
66
+ end
67
+ end
@@ -0,0 +1,67 @@
1
+ module WebMock
2
+
3
+ class StubRegistry
4
+ include Singleton
5
+
6
+ attr_accessor :request_stubs
7
+
8
+ def initialize
9
+ reset!
10
+ end
11
+
12
+ def global_stubs
13
+ @global_stubs ||= []
14
+ end
15
+
16
+ def reset!
17
+ self.request_stubs = []
18
+ end
19
+
20
+ def register_global_stub(&block)
21
+ # This hash contains the responses returned by the block,
22
+ # keyed by the exact request (using the object_id).
23
+ # That way, there's no race condition in case #to_return
24
+ # doesn't run immediately after stub.with.
25
+ responses = {}
26
+
27
+ stub = ::WebMock::RequestStub.new(:any, /.*/).with { |request|
28
+ responses[request.object_id] = yield(request)
29
+ }.to_return(lambda { |request| responses.delete(request.object_id) })
30
+
31
+ global_stubs.push stub
32
+ end
33
+
34
+ def register_request_stub(stub)
35
+ request_stubs.insert(0, stub)
36
+ stub
37
+ end
38
+
39
+ def remove_request_stub(stub)
40
+ if not request_stubs.delete(stub)
41
+ raise "Request stub \n\n #{stub.to_s} \n\n is not registered."
42
+ end
43
+ end
44
+
45
+ def registered_request?(request_signature)
46
+ request_stub_for(request_signature)
47
+ end
48
+
49
+ def response_for_request(request_signature)
50
+ stub = request_stub_for(request_signature)
51
+ stub ? evaluate_response_for_request(stub.response, request_signature) : nil
52
+ end
53
+
54
+ private
55
+
56
+ def request_stub_for(request_signature)
57
+ (global_stubs + request_stubs).detect { |registered_request_stub|
58
+ registered_request_stub.request_pattern.matches?(request_signature)
59
+ }
60
+ end
61
+
62
+ def evaluate_response_for_request(response, request_signature)
63
+ response.dup.evaluate(request_signature)
64
+ end
65
+
66
+ end
67
+ end
@@ -0,0 +1,38 @@
1
+ module WebMock
2
+ class StubRequestSnippet
3
+ def initialize(request_stub)
4
+ @request_stub = request_stub
5
+ end
6
+
7
+ def body_pattern
8
+ request_pattern.body_pattern
9
+ end
10
+
11
+ def to_s(with_response = true)
12
+ request_pattern = @request_stub.request_pattern
13
+ string = "stub_request(:#{request_pattern.method_pattern.to_s},".dup
14
+ string << " \"#{request_pattern.uri_pattern.to_s}\")"
15
+
16
+ with = "".dup
17
+
18
+ if (request_pattern.body_pattern)
19
+ with << "\n body: #{request_pattern.body_pattern.to_s}"
20
+ end
21
+
22
+ if (request_pattern.headers_pattern)
23
+ with << "," unless with.empty?
24
+
25
+ with << "\n headers: #{request_pattern.headers_pattern.pp_to_s}"
26
+ end
27
+ string << ".\n with(#{with})" unless with.empty?
28
+ if with_response
29
+ if request_pattern.headers_pattern && request_pattern.headers_pattern.matches?({ 'Accept' => "application/json" })
30
+ string << ".\n to_return(status: 200, body: \"{}\", headers: {})"
31
+ else
32
+ string << ".\n to_return(status: 200, body: \"\", headers: {})"
33
+ end
34
+ end
35
+ string
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,22 @@
1
+ require 'test/unit'
2
+ require 'webmock'
3
+
4
+ WebMock.enable!
5
+
6
+ module Test
7
+ module Unit
8
+ class TestCase
9
+ include WebMock::API
10
+
11
+ alias_method :teardown_without_webmock, :teardown
12
+ def teardown_with_webmock
13
+ teardown_without_webmock
14
+ WebMock.reset!
15
+ end
16
+ alias_method :teardown, :teardown_with_webmock
17
+
18
+ end
19
+ end
20
+ end
21
+
22
+ WebMock::AssertionFailure.error_class = Test::Unit::AssertionFailedError
@@ -0,0 +1,39 @@
1
+ require 'thread'
2
+
3
+ module WebMock
4
+ module Util
5
+ class HashCounter
6
+ attr_accessor :hash
7
+ def initialize
8
+ self.hash = {}
9
+ @order = {}
10
+ @max = 0
11
+ @lock = ::Mutex.new
12
+ end
13
+ def put key, num=1
14
+ @lock.synchronize do
15
+ hash[key] = (hash[key] || 0) + num
16
+ @order[key] = @max = @max + 1
17
+ end
18
+ end
19
+ def get key
20
+ @lock.synchronize do
21
+ hash[key] || 0
22
+ end
23
+ end
24
+
25
+ def select(&block)
26
+ return unless block_given?
27
+ @lock.synchronize do
28
+ hash.select(&block)
29
+ end
30
+ end
31
+
32
+ def each(&block)
33
+ @order.to_a.sort_by { |a| a[1] }.each do |a|
34
+ yield(a[0], hash[a[0]])
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,25 @@
1
+ module WebMock
2
+ module Util
3
+ class HashKeysStringifier
4
+
5
+ def self.stringify_keys!(arg, options = {})
6
+ case arg
7
+ when Array
8
+ arg.map { |elem|
9
+ options[:deep] ? stringify_keys!(elem, options) : elem
10
+ }
11
+ when Hash
12
+ Hash[
13
+ *arg.map { |key, value|
14
+ k = key.is_a?(Symbol) ? key.to_s : key
15
+ v = (options[:deep] ? stringify_keys!(value, options) : value)
16
+ [k,v]
17
+ }.inject([]) {|r,x| r + x}]
18
+ else
19
+ arg
20
+ end
21
+ end
22
+
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,17 @@
1
+ module WebMock
2
+ class HashValidator
3
+ def initialize(hash)
4
+ @hash = hash
5
+ end
6
+
7
+ #This code is based on https://github.com/rails/rails/blob/master/activesupport/lib/active_support/core_ext/hash/keys.rb
8
+ def validate_keys(*valid_keys)
9
+ valid_keys.flatten!
10
+ @hash.each_key do |k|
11
+ unless valid_keys.include?(k)
12
+ raise ArgumentError.new("Unknown key: #{k.inspect}. Valid keys are: #{valid_keys.map(&:inspect).join(', ')}")
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,64 @@
1
+ require 'base64'
2
+
3
+ module WebMock
4
+
5
+ module Util
6
+
7
+ class Headers
8
+
9
+ def self.normalize_headers(headers)
10
+ return nil unless headers
11
+ array = headers.map { |name, value|
12
+ [name.to_s.split(/_|-/).map { |segment| segment.capitalize }.join("-"),
13
+ case value
14
+ when Regexp then value
15
+ when Array then (value.size == 1) ? value.first.to_s : value.map {|v| v.to_s}.sort
16
+ else value.to_s
17
+ end
18
+ ]
19
+ }
20
+ Hash[*array.inject([]) {|r,x| r + x}]
21
+ end
22
+
23
+ def self.sorted_headers_string(headers)
24
+ headers = WebMock::Util::Headers.normalize_headers(headers)
25
+ str = '{'.dup
26
+ str << headers.map do |k,v|
27
+ v = case v
28
+ when Regexp then v.inspect
29
+ when Array then "["+v.map{|w| "'#{w.to_s}'"}.join(", ")+"]"
30
+ else "'#{v.to_s}'"
31
+ end
32
+ "'#{k}'=>#{v}"
33
+ end.sort.join(", ")
34
+ str << '}'
35
+ end
36
+
37
+ def self.pp_headers_string(headers)
38
+ headers = WebMock::Util::Headers.normalize_headers(headers)
39
+ seperator = "\n\t "
40
+ str = "{#{seperator} ".dup
41
+ str << headers.map do |k,v|
42
+ v = case v
43
+ when Regexp then v.inspect
44
+ when Array then "["+v.map{|w| "'#{w.to_s}'"}.join(", ")+"]"
45
+ else "'#{v.to_s}'"
46
+ end
47
+ "'#{k}'=>#{v}"
48
+ end.sort.join(",#{seperator} ")
49
+ str << "\n }"
50
+ end
51
+
52
+ def self.decode_userinfo_from_header(header)
53
+ header.sub(/^Basic /, "").unpack("m").first
54
+ end
55
+
56
+ def self.basic_auth_header(*credentials)
57
+ "Basic #{Base64.strict_encode64(credentials.join(':')).chomp}"
58
+ end
59
+
60
+ end
61
+
62
+ end
63
+
64
+ end