Skip to content

Commit a69b5e6

Browse files
committed
feat: parse pacts without a specification version as v2
1 parent 0ae9b71 commit a69b5e6

8 files changed

+67
-17
lines changed

lib/pact/consumer_contract/http_consumer_contract_parser.rb

+4-1
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
1+
require 'pact/specification_version'
2+
13
module Pact
24
class HttpConsumerContractParser
35
include SymbolizeKeys
46

57
def call(hash)
68
hash = symbolize_keys(hash)
79
options = { pact_specification_version: pact_specification_version(hash) }
10+
811
interactions = hash[:interactions].collect { |hash| Interaction.from_hash(hash, options) }
912
ConsumerContract.new(
1013
:consumer => ServiceConsumer.from_hash(hash[:consumer]),
@@ -19,7 +22,7 @@ def pact_specification_version hash
1922
maybe_pact_specification_version_1 = hash[:metadata] && hash[:metadata]['pactSpecification'] && hash[:metadata]['pactSpecification']['version']
2023
maybe_pact_specification_version_2 = hash[:metadata] && hash[:metadata]['pactSpecificationVersion']
2124
pact_specification_version = maybe_pact_specification_version_1 || maybe_pact_specification_version_2
22-
Gem::Version.new(pact_specification_version)
25+
Pact::SpecificationVersion.new(pact_specification_version)
2326
end
2427

2528
def can_parse?(hash)

lib/pact/consumer_contract/interaction.rb

+4-3
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
require 'pact/shared/active_support_support'
55
require 'pact/matching_rules'
66
require 'pact/errors'
7+
require 'pact/specification_version'
78

89
module Pact
910
class Interaction
@@ -20,9 +21,9 @@ def initialize attributes = {}
2021
end
2122

2223
def self.from_hash hash, options = {}
23-
pact_specification_version = options[:pact_specification_version] || Gem::Version.new("") # use some global default
24-
case pact_specification_version.segments.first
25-
when 1, 2 then parse_v2_interaction(hash, pact_specification_version: pact_specification_version)
24+
pact_specification_version = options[:pact_specification_version] || Pact::SpecificationVersion::NIL_VERSION
25+
case pact_specification_version.major
26+
when nil, 1, 2 then parse_v2_interaction(hash, pact_specification_version: pact_specification_version)
2627
else parse_v3_interaction(hash, pact_specification_version: pact_specification_version)
2728
end
2829
end

lib/pact/matching_rules.rb

+3-6
Original file line numberDiff line numberDiff line change
@@ -11,16 +11,13 @@ def self.extract object_graph, options = {}
1111
end
1212

1313
def self.merge object_graph, matching_rules, options = {}
14-
case options[:pact_specification_version].segments.first
15-
when nil
16-
Pact.configuration.error_stream.puts "No pact specification version found, using v2 code to parse contract"
17-
Merge.(object_graph, matching_rules)
18-
when 1, 2
14+
case options[:pact_specification_version].major
15+
when nil, 1, 2
1916
Merge.(object_graph, matching_rules)
2017
when 3
2118
V3::Merge.(object_graph, matching_rules)
2219
else
23-
Pact.configuration.error_stream.puts "This code only knows how to parse v3 pacts, attempting to parse v#{options[:pact_specification_version]} pact using v3 code."
20+
Pact.configuration.error_stream.puts "WARN: This code only knows how to parse v3 pacts, attempting to parse v#{options[:pact_specification_version]} pact using v3 code."
2421
V3::Merge.(object_graph, matching_rules)
2522
end
2623
end

lib/pact/specification_version.rb

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
module Pact
2+
class SpecificationVersion < Gem::Version
3+
4+
NIL_VERSION = SpecificationVersion.new('')
5+
6+
def major
7+
segments.first
8+
end
9+
end
10+
end

spec/fixtures/pact-http-v2.json

+36
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
{
2+
"consumer": {
3+
"name": "some-test-consumer"
4+
},
5+
"provider": {
6+
"name": "an unknown provider"
7+
},
8+
"interactions": [
9+
{
10+
"description": "a test request",
11+
"request": {
12+
"method": "get",
13+
"path": "/weather",
14+
"query": ""
15+
},
16+
"response": {
17+
"matchingRules": {
18+
"$.headers.Content-Type" : {
19+
"match": "regex", "regex": "json"
20+
},
21+
"$.body.message" : {
22+
"match": "regex", "regex": "sun"
23+
}
24+
},
25+
"status": 200,
26+
"headers" : {
27+
"Content-Type": "foo/json"
28+
},
29+
"body": {
30+
"message" : "sunful"
31+
}
32+
},
33+
"provider_state": "the weather is sunny"
34+
}
35+
]
36+
}

spec/lib/pact/consumer_contract/http_consumer_contract_parser_spec.rb

+8
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,14 @@ module Pact
55
describe "#call integration test" do
66
subject { HttpConsumerContractParser.new.call(pact_hash) }
77

8+
context "with a v2 pact" do
9+
let(:pact_hash) { load_json_fixture('pact-http-v2.json') }
10+
11+
it "correctly parses the pact" do
12+
expect(subject.interactions.first.response.headers['Content-Type']).to be_a(Pact::Term)
13+
end
14+
end
15+
816
context "with a v3 pact" do
917
let(:pact_hash) { load_json_fixture('pact-http-v3.json') }
1018

spec/lib/pact/consumer_contract/interaction_spec.rb

+1-1
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ module Consumer
6565
context "when there are matching rules" do
6666
let(:hash) { load_json_fixture 'interaction-with-matching-rules.json' }
6767

68-
subject { Interaction.from_hash hash, pact_specification_version: Gem::Version.new("2") }
68+
subject { Interaction.from_hash hash, pact_specification_version: Pact::SpecificationVersion.new("2") }
6969

7070
it "merges the rules with the example for the request" do
7171
expect(subject.request.body['name']).to be_instance_of(Pact::Term)

spec/lib/pact/matching_rules_spec.rb

+1-6
Original file line numberDiff line numberDiff line change
@@ -11,18 +11,13 @@ module MatchingRules
1111

1212
let(:object) { double('object') }
1313
let(:rules) { double('rules') }
14-
let(:options) { { pact_specification_version: Gem::Version.new(pact_specification_version) } }
14+
let(:options) { { pact_specification_version: Pact::SpecificationVersion.new(pact_specification_version) } }
1515

1616
subject { MatchingRules.merge(object, rules, options)}
1717

1818
context "when the pact_specification_version is nil" do
1919
let(:pact_specification_version) { nil }
2020

21-
it "prints a warning" do
22-
expect(Pact.configuration.error_stream).to receive(:puts).with(/No pact specification version found/)
23-
subject
24-
end
25-
2621
it "calls Merge" do
2722
expect(Merge).to receive(:call)
2823
subject

0 commit comments

Comments
 (0)