Skip to content

Commit 5440ed1

Browse files
SAY-5YOU54F
authored andcommitted
fix: support scalar request and response bodies in InteractionContents
Signed-off-by: Sai Asish Y <say.apm35@gmail.com>
1 parent aa7e274 commit 5440ed1

3 files changed

Lines changed: 39 additions & 21 deletions

File tree

lib/pact/consumer/http_interaction_builder.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ def with_request(method: nil, path: nil, query: {}, headers: {}, body: nil)
8282
end
8383

8484
if body
85-
PactFfi.with_body(pact_interaction, interaction_part, "application/json", format_value(InteractionContents.basic(body)))
85+
PactFfi.with_body(pact_interaction, interaction_part, "application/json", format_value(InteractionContents.basic(body).value))
8686
end
8787

8888
self
@@ -97,7 +97,7 @@ def will_respond_with(status: nil, headers: {}, body: nil)
9797
end
9898

9999
if body
100-
PactFfi.with_body(pact_interaction, interaction_part, "application/json", format_value(InteractionContents.basic(body)))
100+
PactFfi.with_body(pact_interaction, interaction_part, "application/json", format_value(InteractionContents.basic(body).value))
101101
end
102102

103103
self

lib/pact/consumer/interaction_contents.rb

Lines changed: 21 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -17,36 +17,38 @@ def self.plugin(contents_hash)
1717
end
1818

1919
def initialize(contents_hash, format)
20-
init_hash(contents_hash, format).each_pair { |k, v| self[k] = v }
20+
serialized = init_hash(contents_hash, format)
21+
# A scalar body (plain string, integer, etc.) serializes to a non-Hash
22+
# value that cannot be merged pair by pair; expose it via #value instead.
23+
if serialized.is_a?(Hash)
24+
serialized.each_pair { |k, v| self[k] = v }
25+
else
26+
@value = serialized
27+
end
2128
@format = format
2229
end
2330

31+
def value
32+
defined?(@value) ? @value : self
33+
end
34+
2435
private
2536

2637
def serialize(hash, format)
2738
# serialize recursively
28-
return hash if hash.is_a?(String)
29-
30-
if hash.is_a?(Pact::Matchers::Base)
31-
return hash.as_basic if format == :basic
32-
return hash.as_plugin if format == :plugin
33-
end
34-
if hash.is_a?(Pact::Generators::Base)
39+
if hash.is_a?(Pact::Matchers::Base) || hash.is_a?(Pact::Generators::Base)
3540
return hash.as_basic if format == :basic
3641
return hash.as_plugin if format == :plugin
3742
end
43+
44+
return hash.map { |value| serialize(value, format) } if hash.is_a?(Array)
45+
46+
# A value that is not a collection or a matcher/generator has nothing to
47+
# recurse into, so return it unchanged (string, integer, boolean, nil, ...).
48+
return hash unless hash.is_a?(Hash)
49+
3850
hash.each_pair do |key, value|
39-
next serialize(value, format) if value.is_a?(Hash)
40-
next hash[key] = value.map { |v| serialize(v, format) } if value.is_a?(Array)
41-
42-
if value.is_a?(Pact::Matchers::Base)
43-
hash[key] = value.as_basic if format == :basic
44-
hash[key] = value.as_plugin if format == :plugin
45-
end
46-
if value.is_a?(Pact::Generators::Base)
47-
hash[key] = value.as_basic if format == :basic
48-
hash[key] = value.as_plugin if format == :plugin
49-
end
51+
hash[key] = serialize(value, format)
5052
end
5153

5254
hash

spec/lib/consumer/interaction_contents_spec.rb

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,4 +30,20 @@
3030
.to eq('{"str":{"pact:matcher:type":"regex","value":"str","regex":"(?-mix:.*)"},"bool":{"pact:matcher:type":"boolean","value":true},"num":{"pact:matcher:type":"number","value":1},"nested":{"pact:matcher:type":"type","value":[{"a":1,"b":"2"}],"min":1}}') # rubocop:disable Layout/LineLength
3131
end
3232
end
33+
34+
context 'with a scalar body' do
35+
it 'returns a plain string unchanged' do
36+
expect(described_class.basic('plain text').value).to eq('plain text')
37+
end
38+
39+
it 'returns an integer unchanged' do
40+
expect(described_class.basic(42).value).to eq(42)
41+
end
42+
end
43+
44+
context 'with an array of scalars nested in a hash' do
45+
it 'serializes without raising' do
46+
expect(described_class.basic({ some_array: [42] }).to_json).to eq('{"some_array":[42]}')
47+
end
48+
end
3349
end

0 commit comments

Comments
 (0)