pact 1.3.0 → 1.3.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.
- data/.travis.yml +1 -1
- data/CHANGELOG.md +14 -0
- data/Gemfile.lock +5 -5
- data/README.md +25 -29
- data/documentation/README.md +9 -7
- data/lib/pact/configuration.rb +83 -12
- data/lib/pact/consumer/mock_service/interaction_mismatch.rb +5 -1
- data/lib/pact/consumer/spec_hooks.rb +7 -4
- data/lib/pact/consumer/world.rb +12 -0
- data/lib/pact/consumer_contract/headers.rb +51 -0
- data/lib/pact/consumer_contract/request.rb +6 -1
- data/lib/pact/provider/configuration/service_provider_dsl.rb +6 -1
- data/lib/pact/provider/matchers/messages.rb +2 -2
- data/lib/pact/provider/rspec.rb +7 -1
- data/lib/pact/provider/rspec/backtrace_formatter.rb +30 -6
- data/lib/pact/provider/rspec/matchers.rb +9 -6
- data/lib/pact/shared/json_differ.rb +15 -0
- data/lib/pact/shared/request.rb +11 -2
- data/lib/pact/shared/text_differ.rb +14 -0
- data/lib/pact/version.rb +1 -1
- data/spec/lib/pact/configuration_spec.rb +127 -5
- data/spec/lib/pact/consumer/mock_service/interaction_mismatch_spec.rb +8 -5
- data/spec/lib/pact/consumer_contract/headers_spec.rb +107 -0
- data/spec/lib/pact/consumer_contract/request_spec.rb +9 -0
- data/spec/lib/pact/matchers/matchers_spec.rb +35 -0
- data/spec/lib/pact/provider/configuration/service_provider_dsl_spec.rb +16 -0
- data/spec/lib/pact/provider/matchers/messages_spec.rb +5 -4
- data/spec/lib/pact/provider/rspec_spec.rb +15 -11
- data/spec/lib/pact/shared/json_differ_spec.rb +36 -0
- data/spec/lib/pact/shared/request_spec.rb +25 -1
- data/spec/lib/pact/shared/text_differ_spec.rb +54 -0
- data/spec/support/pact_helper.rb +2 -0
- data/spec/support/test_app_with_right_content_type_differ.json +23 -0
- data/tasks/pact-test.rake +6 -0
- metadata +72 -30
- checksums.yaml +0 -7
- data/documentation/Testing with pact.png +0 -0
- data/documentation/best-practices.md +0 -33
- data/documentation/development-workflow.md +0 -22
- data/documentation/faq.md +0 -81
- data/documentation/provider-states.md +0 -178
- data/documentation/raq.md +0 -39
- data/documentation/terminology.md +0 -25
- data/documentation/troubleshooting.md +0 -4
- data/documentation/verifying-pacts.md +0 -106
@@ -13,7 +13,12 @@ module Pact
|
|
13
13
|
|
14
14
|
attr_accessor :name, :app_block
|
15
15
|
|
16
|
-
CONFIG_RU_APP = lambda {
|
16
|
+
CONFIG_RU_APP = lambda {
|
17
|
+
unless File.exist? Pact.configuration.config_ru_path
|
18
|
+
raise "Could not find config.ru file at #{Pact.configuration.config_ru_path} Please configure the service provider app or create a config.ru file in the root directory of the project. See https://github.com/realestate-com-au/pact/blob/master/documentation/verifying-pacts.md for more information."
|
19
|
+
end
|
20
|
+
Rack::Builder.parse_file(Pact.configuration.config_ru_path).first
|
21
|
+
}
|
17
22
|
|
18
23
|
def initialize name
|
19
24
|
@name = name
|
@@ -5,9 +5,9 @@ module Pact
|
|
5
5
|
module Matchers
|
6
6
|
module Messages
|
7
7
|
|
8
|
-
def match_term_failure_message diff, actual, color_enabled
|
8
|
+
def match_term_failure_message diff, actual, diff_formatter, color_enabled
|
9
9
|
message = "Actual: #{(String === actual ? actual : actual.to_json)}\n\n"
|
10
|
-
formatted_diff =
|
10
|
+
formatted_diff = diff_formatter.call(diff)
|
11
11
|
message + colorize_if_enabled(formatted_diff, color_enabled)
|
12
12
|
end
|
13
13
|
|
data/lib/pact/provider/rspec.rb
CHANGED
@@ -106,6 +106,12 @@ module Pact
|
|
106
106
|
let(:response) { interaction_context.last_response }
|
107
107
|
let(:response_status) { response.status }
|
108
108
|
let(:response_body) { parse_body_from_response(response) }
|
109
|
+
let(:differ) { Pact.configuration.body_differ_for_content_type diff_content_type }
|
110
|
+
let(:diff_formatter) { Pact.configuration.diff_formatter_for_content_type diff_content_type }
|
111
|
+
let(:expected_content_type) { Pact::Headers.new(expected_response['headers'] || {})['Content-Type'] }
|
112
|
+
let(:actual_content_type) { response.headers['Content-Type']}
|
113
|
+
let(:diff_content_type) { String === expected_content_type ? expected_content_type : actual_content_type } # expected_content_type may be a Regexp
|
114
|
+
let(:options) { { with: differ, diff_formatter: diff_formatter } }
|
109
115
|
|
110
116
|
if expected_response['status']
|
111
117
|
it "has status code #{expected_response['status']}" do
|
@@ -126,7 +132,7 @@ module Pact
|
|
126
132
|
|
127
133
|
if expected_response['body']
|
128
134
|
it "has a matching body" do
|
129
|
-
expect(response_body).to match_term expected_response_body
|
135
|
+
expect(response_body).to match_term expected_response_body, options
|
130
136
|
end
|
131
137
|
end
|
132
138
|
end
|
@@ -1,19 +1,43 @@
|
|
1
1
|
module RSpec
|
2
2
|
module Core
|
3
3
|
|
4
|
+
# RSpec 3 has a hardwired @system_exclusion_patterns which removes everything matching /bin\//
|
5
|
+
# This causes *all* the backtrace lines to be cleaned, as rake pact:verify now shells out
|
6
|
+
# to the executable `pact verify ...`
|
7
|
+
# which then causes *all* the lines to be included as the BacktraceFormatter will
|
8
|
+
# include all lines of the backtrace if all lines were filtered out.
|
9
|
+
# This monkey patch only shows lines including bin/pact and removes the
|
10
|
+
# "show all lines if no lines would otherwise be shown" logic.
|
11
|
+
|
4
12
|
class BacktraceFormatter
|
5
13
|
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
14
|
+
|
15
|
+
def format_backtrace(backtrace, options = {})
|
16
|
+
return backtrace if options[:full_backtrace]
|
17
|
+
backtrace.map { |l| backtrace_line(l) }.compact
|
18
|
+
end
|
19
|
+
|
20
|
+
def backtrace_line(line)
|
21
|
+
relative_path(line) unless exclude?(line)
|
22
|
+
rescue SecurityError
|
23
|
+
nil
|
24
|
+
end
|
10
25
|
|
11
26
|
def exclude?(line)
|
12
27
|
return false if @full_backtrace
|
13
|
-
|
14
|
-
|
28
|
+
relative_line = relative_path(line)
|
29
|
+
return true unless /bin\/pact/ =~ relative_line
|
15
30
|
end
|
16
31
|
|
32
|
+
# Copied from Metadata so a refactor can't break this overridden class
|
33
|
+
def relative_path(line)
|
34
|
+
line = line.sub(File.expand_path("."), ".")
|
35
|
+
line = line.sub(/\A([^:]+:\d+)$/, '\\1')
|
36
|
+
return nil if line == '-e:1'
|
37
|
+
line
|
38
|
+
rescue SecurityError
|
39
|
+
nil
|
40
|
+
end
|
17
41
|
end
|
18
42
|
end
|
19
43
|
end
|
@@ -2,6 +2,8 @@ require 'rspec'
|
|
2
2
|
require 'pact/matchers'
|
3
3
|
require 'pact/provider/matchers/messages'
|
4
4
|
require 'pact/rspec'
|
5
|
+
require 'pact/shared/json_differ'
|
6
|
+
|
5
7
|
|
6
8
|
module Pact
|
7
9
|
module RSpec
|
@@ -20,27 +22,28 @@ module Pact
|
|
20
22
|
|
21
23
|
class MatchTerm
|
22
24
|
|
23
|
-
include Pact::Matchers
|
24
25
|
include Pact::Matchers::Messages
|
25
26
|
include RSpec2Delegator
|
26
27
|
|
27
|
-
def initialize expected
|
28
|
+
def initialize expected, differ, diff_formatter
|
28
29
|
@expected = expected
|
30
|
+
@differ = differ
|
31
|
+
@diff_formatter = diff_formatter
|
29
32
|
end
|
30
33
|
|
31
34
|
def matches? actual
|
32
35
|
@actual = actual
|
33
|
-
(@difference =
|
36
|
+
(@difference = @differ.call(@expected, @actual)).empty?
|
34
37
|
end
|
35
38
|
|
36
39
|
def failure_message
|
37
|
-
match_term_failure_message @difference, @actual, Pact::RSpec.color_enabled?
|
40
|
+
match_term_failure_message @difference, @actual, @diff_formatter, Pact::RSpec.color_enabled?
|
38
41
|
end
|
39
42
|
|
40
43
|
end
|
41
44
|
|
42
|
-
def match_term expected
|
43
|
-
MatchTerm.new(expected)
|
45
|
+
def match_term expected, options
|
46
|
+
MatchTerm.new(expected, options.fetch(:with), options.fetch(:diff_formatter))
|
44
47
|
end
|
45
48
|
|
46
49
|
class MatchHeader
|
data/lib/pact/shared/request.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
require 'pact/matchers'
|
2
2
|
require 'pact/symbolize_keys'
|
3
|
+
require 'pact/consumer_contract/headers'
|
3
4
|
|
4
5
|
module Pact
|
5
6
|
|
@@ -15,7 +16,7 @@ module Pact
|
|
15
16
|
def initialize(method, path, headers, body, query)
|
16
17
|
@method = method.to_s
|
17
18
|
@path = path.chomp('/')
|
18
|
-
@headers = headers
|
19
|
+
@headers = Hash === headers ? Headers.new(headers) : headers # Could be a NullExpectation - TODO make this more elegant
|
19
20
|
@body = body
|
20
21
|
@query = query
|
21
22
|
end
|
@@ -48,6 +49,11 @@ module Pact
|
|
48
49
|
display_path + display_query
|
49
50
|
end
|
50
51
|
|
52
|
+
def content_type
|
53
|
+
return nil if headers.is_a? self.class.key_not_found.class
|
54
|
+
headers['Content-Type']
|
55
|
+
end
|
56
|
+
|
51
57
|
protected
|
52
58
|
|
53
59
|
def self.key_not_found
|
@@ -56,7 +62,9 @@ module Pact
|
|
56
62
|
|
57
63
|
def to_hash_without_body
|
58
64
|
keep_keys = [:method, :path, :headers, :query]
|
59
|
-
as_json.reject{ |key, value| !keep_keys.include? key }
|
65
|
+
as_json.reject{ |key, value| !keep_keys.include? key }.tap do | hash |
|
66
|
+
hash[:method] = method.upcase
|
67
|
+
end
|
60
68
|
end
|
61
69
|
|
62
70
|
def display_path
|
@@ -66,6 +74,7 @@ module Pact
|
|
66
74
|
def display_query
|
67
75
|
(query.nil? || query.empty?) ? '' : "?#{Pact::Reification.from_term(query)}"
|
68
76
|
end
|
77
|
+
|
69
78
|
end
|
70
79
|
end
|
71
80
|
end
|
data/lib/pact/version.rb
CHANGED
@@ -83,12 +83,12 @@ describe Pact do
|
|
83
83
|
|
84
84
|
end
|
85
85
|
|
86
|
-
describe "#
|
86
|
+
describe "#diff_formatter_for_content_type" do
|
87
87
|
|
88
88
|
let(:subject) { Pact::Configuration.new }
|
89
89
|
|
90
90
|
it "returns the Pact::Matchers::UnixDiffFormatter by default" do
|
91
|
-
expect(subject.
|
91
|
+
expect(subject.diff_formatter_for_content_type 'anything').to eq(Pact::Matchers::UnixDiffFormatter)
|
92
92
|
end
|
93
93
|
|
94
94
|
Pact::Configuration::DIFF_FORMATTERS.each_pair do | key, diff_formatter |
|
@@ -100,7 +100,7 @@ describe Pact do
|
|
100
100
|
end
|
101
101
|
|
102
102
|
it "sets the diff_formatter to #{diff_formatter}" do
|
103
|
-
expect(subject.
|
103
|
+
expect(subject.diff_formatter_for_content_type nil).to be diff_formatter
|
104
104
|
end
|
105
105
|
end
|
106
106
|
|
@@ -115,18 +115,140 @@ describe Pact do
|
|
115
115
|
end
|
116
116
|
|
117
117
|
it "sets the diff_formatter to the object" do
|
118
|
-
expect(subject.
|
118
|
+
expect(subject.diff_formatter_for_content_type nil).to be diff_formatter
|
119
119
|
end
|
120
120
|
end
|
121
121
|
|
122
122
|
context "when set to an object that does not respond to call and isn't a known default option" do
|
123
123
|
it "raises an error" do
|
124
|
-
expect { subject.diff_formatter = Object.new }.to raise_error "Pact
|
124
|
+
expect { subject.diff_formatter = Object.new }.to raise_error "Pact diff_formatter needs to respond to call, or be in the preconfigured list: [:embedded, :unix, :list]"
|
125
|
+
expect { subject.diff_formatter = Object.new }.to raise_error "Pact diff_formatter needs to respond to call, or be in the preconfigured list: [:embedded, :unix, :list]"
|
125
126
|
end
|
126
127
|
end
|
127
128
|
|
128
129
|
end
|
129
130
|
|
131
|
+
describe "diff_formatter_for_content_type" do
|
132
|
+
let(:diff_formatter) { lambda { |expected, actual| }}
|
133
|
+
context "with the default configuration" do
|
134
|
+
context "when the content type is nil" do
|
135
|
+
it "returns the UnixDiffFormatter" do
|
136
|
+
expect(Pact.configuration.diff_formatter_for_content_type nil).to eq Pact::Matchers::UnixDiffFormatter
|
137
|
+
end
|
138
|
+
end
|
139
|
+
context "when the content type is application/json" do
|
140
|
+
it "returns the UnixDiffFormatter" do
|
141
|
+
expect(Pact.configuration.diff_formatter_for_content_type nil).to eq Pact::Matchers::UnixDiffFormatter
|
142
|
+
end
|
143
|
+
end
|
144
|
+
context "when the content type is text/plain" do
|
145
|
+
it "returns the UnixDiffFormatter" do
|
146
|
+
expect(Pact.configuration.diff_formatter_for_content_type nil).to eq Pact::Matchers::UnixDiffFormatter
|
147
|
+
end
|
148
|
+
end
|
149
|
+
end
|
150
|
+
context "with a custom diff_formatter registered for nil content type" do
|
151
|
+
context "when the content_type is nil" do
|
152
|
+
it "returns the custom diff_formatter" do
|
153
|
+
Pact.configuration.register_diff_formatter nil, diff_formatter
|
154
|
+
expect(Pact.configuration.diff_formatter_for_content_type nil).to eq diff_formatter
|
155
|
+
end
|
156
|
+
end
|
157
|
+
end
|
158
|
+
context "with a custom diff_formatter registered for json content type" do
|
159
|
+
context "when the content_type is application/json" do
|
160
|
+
it "returns the custom diff_formatter" do
|
161
|
+
Pact.configuration.register_diff_formatter /json/, diff_formatter
|
162
|
+
expect(Pact.configuration.diff_formatter_for_content_type 'application/json').to eq diff_formatter
|
163
|
+
end
|
164
|
+
end
|
165
|
+
end
|
166
|
+
end
|
167
|
+
|
168
|
+
describe "register_body_differ" do
|
169
|
+
|
170
|
+
let(:differ) { lambda{ |expected, actual| } }
|
171
|
+
|
172
|
+
context "with a string for a content type" do
|
173
|
+
it "configures the differ for the given content type" do
|
174
|
+
Pact.configure do | config |
|
175
|
+
config.register_body_differ 'application/xml', differ
|
176
|
+
end
|
177
|
+
|
178
|
+
expect(Pact.configuration.body_differ_for_content_type 'application/xml').to be differ
|
179
|
+
end
|
180
|
+
end
|
181
|
+
|
182
|
+
context "with a regexp for a content type" do
|
183
|
+
it "returns a matching differ" do
|
184
|
+
Pact.configuration.register_body_differ /application\/.*xml/, differ
|
185
|
+
expect(Pact.configuration.body_differ_for_content_type 'application/hal+xml').to be differ
|
186
|
+
end
|
187
|
+
end
|
188
|
+
|
189
|
+
context "when a non string or regexp is used to register a differ" do
|
190
|
+
it "raises an error" do
|
191
|
+
expect { Pact.configuration.register_body_differ 1, differ }.to raise_error /Invalid/
|
192
|
+
end
|
193
|
+
end
|
194
|
+
|
195
|
+
context "when something that does not respond to call is sumbitted as a differ" do
|
196
|
+
it "raises an error" do
|
197
|
+
expect { Pact.configuration.register_body_differ 'thing', Object.new }.to raise_error /responds to call/
|
198
|
+
end
|
199
|
+
end
|
200
|
+
|
201
|
+
context "when a nil content type is registered for responses without a content type header" do
|
202
|
+
it "returns that differ if the differ for a nil content type is requested" do
|
203
|
+
Pact.configuration.register_body_differ nil, differ
|
204
|
+
expect(Pact.configuration.body_differ_for_content_type(nil)).to be differ
|
205
|
+
end
|
206
|
+
end
|
207
|
+
|
208
|
+
end
|
209
|
+
|
210
|
+
describe "body_differ_for_content_type" do
|
211
|
+
|
212
|
+
let(:differ) { lambda { |expected, actual| }}
|
213
|
+
|
214
|
+
context "when 2 potentially matching content types have a differ registered" do
|
215
|
+
let(:differ_1) { lambda{ |expected, actual| } }
|
216
|
+
let(:differ_2) { lambda{ |expected, actual| } }
|
217
|
+
|
218
|
+
it "returns the differ that was configured first" do
|
219
|
+
Pact.configuration.register_body_differ /application\/.*xml/, differ_2
|
220
|
+
Pact.configuration.register_body_differ /application\/hal\+xml/, differ_1
|
221
|
+
expect(Pact.configuration.body_differ_for_content_type 'application/hal+xml').to be differ_2
|
222
|
+
end
|
223
|
+
end
|
224
|
+
|
225
|
+
context "when a nil content type is given" do
|
226
|
+
it "returns the text differ" do
|
227
|
+
expect(Pact.configuration.body_differ_for_content_type nil).to be Pact::TextDiffer
|
228
|
+
end
|
229
|
+
end
|
230
|
+
|
231
|
+
context "when no matching content type is found" do
|
232
|
+
it "returns the text differ" do
|
233
|
+
expect(Pact.configuration.body_differ_for_content_type 'blah').to be Pact::TextDiffer
|
234
|
+
end
|
235
|
+
end
|
236
|
+
|
237
|
+
context "when the nil content type has a custom differ configured" do
|
238
|
+
it "returns the custom differ" do
|
239
|
+
Pact.configuration.register_body_differ nil, differ
|
240
|
+
expect(Pact.configuration.body_differ_for_content_type(nil)).to be differ
|
241
|
+
end
|
242
|
+
end
|
243
|
+
|
244
|
+
context "when a custom differ is registered for a content type that has a default differ" do
|
245
|
+
it "returns the custom differ" do
|
246
|
+
Pact.configuration.register_body_differ /application\/json/, differ
|
247
|
+
expect(Pact.configuration.body_differ_for_content_type 'application/json').to be differ
|
248
|
+
end
|
249
|
+
end
|
250
|
+
end
|
251
|
+
|
130
252
|
describe "pactfile_write_mode" do
|
131
253
|
context "when @pactfile_write_mode is :overwrite" do
|
132
254
|
it 'returns :overwrite' do
|
@@ -4,9 +4,10 @@ require 'pact/consumer/mock_service/interaction_mismatch'
|
|
4
4
|
module Pact
|
5
5
|
module Consumer
|
6
6
|
describe InteractionMismatch do
|
7
|
+
let(:content_type) { 'some/content' }
|
7
8
|
let(:actual_request) { instance_double('Pact::Consumer::Request::Actual', :method_and_path => 'GET /path') }
|
8
|
-
let(:expected_request_1) { instance_double('Pact::Request::Expected') }
|
9
|
-
let(:expected_request_2) { instance_double('Pact::Request::Expected') }
|
9
|
+
let(:expected_request_1) { instance_double('Pact::Request::Expected', :content_type => content_type) }
|
10
|
+
let(:expected_request_2) { instance_double('Pact::Request::Expected', :content_type => content_type) }
|
10
11
|
let(:candidate_1) { instance_double('Pact::Interaction', request: expected_request_1, description_with_provider_state_quoted: "desc 1") }
|
11
12
|
let(:candidate_2) { instance_double('Pact::Interaction', request: expected_request_2, description_with_provider_state_quoted: "desc 2") }
|
12
13
|
let(:candidate_interactions) { [candidate_1, candidate_2] }
|
@@ -48,13 +49,15 @@ module Pact
|
|
48
49
|
describe "to_s" do
|
49
50
|
let(:expected_message) { "Diff with interaction: desc 1\ndiff 1\nDiff with interaction: desc 2\ndiff 2" }
|
50
51
|
|
52
|
+
let(:diff_formatter) { double("diff_formatter")}
|
51
53
|
before do
|
52
|
-
allow(Pact.configuration
|
54
|
+
allow(Pact.configuration).to receive(:diff_formatter_for_content_type).with(content_type).and_return(diff_formatter)
|
55
|
+
allow(diff_formatter).to receive(:call).and_return("diff 1", "diff 2")
|
53
56
|
end
|
54
57
|
|
55
58
|
it "creates diff output using the configured diff_formatter" do
|
56
|
-
expect(
|
57
|
-
expect(
|
59
|
+
expect(diff_formatter).to receive(:call).with(diff_1, colour: false)
|
60
|
+
expect(diff_formatter).to receive(:call).with(diff_2, colour: false)
|
58
61
|
subject.to_s
|
59
62
|
end
|
60
63
|
|
@@ -0,0 +1,107 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'pact/consumer_contract/headers'
|
3
|
+
|
4
|
+
module Pact
|
5
|
+
describe Headers do
|
6
|
+
|
7
|
+
describe "initialize" do
|
8
|
+
|
9
|
+
context "with duplicate headers" do
|
10
|
+
|
11
|
+
subject { Headers.new('Content-Type' => 'application/hippo', 'CONTENT-TYPE' => 'application/giraffe') }
|
12
|
+
|
13
|
+
it "raises an error" do
|
14
|
+
expect { subject }.to raise_error DuplicateHeaderError, /Content\-Type.*CONTENT\-TYPE/
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
18
|
+
|
19
|
+
context "with a symbol as a header name" do
|
20
|
+
|
21
|
+
subject { Headers.new(:'content-type' => 'application/hippo') }
|
22
|
+
|
23
|
+
it "converts the header name to a String" do
|
24
|
+
expect( subject.to_hash ).to eq 'content-type' => 'application/hippo'
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
|
29
|
+
context "with a nil header name" do
|
30
|
+
|
31
|
+
subject { Headers.new(nil => 'application/hippo') }
|
32
|
+
|
33
|
+
it "raises an error" do
|
34
|
+
expect{ subject }.to raise_error InvalidHeaderNameTypeError
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
38
|
+
|
39
|
+
context "with a boolean header name" do
|
40
|
+
|
41
|
+
subject { Headers.new(false => 'application/hippo') }
|
42
|
+
|
43
|
+
it "raises an error" do
|
44
|
+
expect{ subject }.to raise_error InvalidHeaderNameTypeError
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|
48
|
+
|
49
|
+
end
|
50
|
+
|
51
|
+
describe "[]" do
|
52
|
+
|
53
|
+
subject { Headers.new 'Content-Type' => 'application/hippo' }
|
54
|
+
|
55
|
+
it "is case insensitive as HTTP headers are case insensitive" do
|
56
|
+
expect(subject['Content-Type']).to eq('application/hippo')
|
57
|
+
expect(subject['CONTENT-TYPE']).to eq('application/hippo')
|
58
|
+
expect(subject['content-type']).to eq('application/hippo')
|
59
|
+
end
|
60
|
+
|
61
|
+
end
|
62
|
+
|
63
|
+
describe "fetch" do
|
64
|
+
|
65
|
+
subject { Headers.new 'Content-Type' => 'application/hippo' }
|
66
|
+
|
67
|
+
it "is case insensitive as HTTP headers are case insensitive" do
|
68
|
+
expect(subject.fetch('Content-Type')).to eq('application/hippo')
|
69
|
+
expect(subject.fetch('CONTENT-TYPE')).to eq('application/hippo')
|
70
|
+
expect(subject.fetch('content-type')).to eq('application/hippo')
|
71
|
+
expect(subject.fetch('Content-Length','1')).to eq('1')
|
72
|
+
expect { subject.fetch('Content-Length')}.to raise_error KeyError
|
73
|
+
end
|
74
|
+
|
75
|
+
end
|
76
|
+
|
77
|
+
describe "key?" do
|
78
|
+
|
79
|
+
subject { Headers.new 'Content-Type' => 'application/hippo' }
|
80
|
+
|
81
|
+
it "is case insensitive as HTTP headers are case insensitive" do
|
82
|
+
expect(subject.key?('CONTENT-TYPE')).to be true
|
83
|
+
expect(subject.key?('CONTENT-LENGTH')).to be false
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
describe "has_key?" do
|
88
|
+
|
89
|
+
subject { Headers.new 'Content-Type' => 'application/hippo' }
|
90
|
+
|
91
|
+
it "is case insensitive as HTTP headers are case insensitive" do
|
92
|
+
expect(subject.has_key?('CONTENT-TYPE')).to be true
|
93
|
+
expect(subject.has_key?('CONTENT-LENGTH')).to be false
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
describe "[]=" do
|
98
|
+
|
99
|
+
subject { Headers.new }
|
100
|
+
|
101
|
+
it "does not allow modification" do
|
102
|
+
expect{ subject['Content-Type'] = 'application/hippo' }.to raise_error /frozen/
|
103
|
+
end
|
104
|
+
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|