Skip to content

Commit

Permalink
feat: parse pacts without a specification version as v2
Browse files Browse the repository at this point in the history
  • Loading branch information
bethesque committed Mar 23, 2018
1 parent 0ae9b71 commit a69b5e6
Show file tree
Hide file tree
Showing 8 changed files with 67 additions and 17 deletions.
5 changes: 4 additions & 1 deletion lib/pact/consumer_contract/http_consumer_contract_parser.rb
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
require 'pact/specification_version'

module Pact
class HttpConsumerContractParser
include SymbolizeKeys

def call(hash)
hash = symbolize_keys(hash)
options = { pact_specification_version: pact_specification_version(hash) }

interactions = hash[:interactions].collect { |hash| Interaction.from_hash(hash, options) }
ConsumerContract.new(
:consumer => ServiceConsumer.from_hash(hash[:consumer]),
Expand All @@ -19,7 +22,7 @@ def pact_specification_version hash
maybe_pact_specification_version_1 = hash[:metadata] && hash[:metadata]['pactSpecification'] && hash[:metadata]['pactSpecification']['version']
maybe_pact_specification_version_2 = hash[:metadata] && hash[:metadata]['pactSpecificationVersion']
pact_specification_version = maybe_pact_specification_version_1 || maybe_pact_specification_version_2
Gem::Version.new(pact_specification_version)
Pact::SpecificationVersion.new(pact_specification_version)
end

def can_parse?(hash)
Expand Down
7 changes: 4 additions & 3 deletions lib/pact/consumer_contract/interaction.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
require 'pact/shared/active_support_support'
require 'pact/matching_rules'
require 'pact/errors'
require 'pact/specification_version'

module Pact
class Interaction
Expand All @@ -20,9 +21,9 @@ def initialize attributes = {}
end

def self.from_hash hash, options = {}
pact_specification_version = options[:pact_specification_version] || Gem::Version.new("") # use some global default
case pact_specification_version.segments.first
when 1, 2 then parse_v2_interaction(hash, pact_specification_version: pact_specification_version)
pact_specification_version = options[:pact_specification_version] || Pact::SpecificationVersion::NIL_VERSION
case pact_specification_version.major
when nil, 1, 2 then parse_v2_interaction(hash, pact_specification_version: pact_specification_version)
else parse_v3_interaction(hash, pact_specification_version: pact_specification_version)
end
end
Expand Down
9 changes: 3 additions & 6 deletions lib/pact/matching_rules.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,13 @@ def self.extract object_graph, options = {}
end

def self.merge object_graph, matching_rules, options = {}
case options[:pact_specification_version].segments.first
when nil
Pact.configuration.error_stream.puts "No pact specification version found, using v2 code to parse contract"
Merge.(object_graph, matching_rules)
when 1, 2
case options[:pact_specification_version].major
when nil, 1, 2
Merge.(object_graph, matching_rules)
when 3
V3::Merge.(object_graph, matching_rules)
else
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."
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."
V3::Merge.(object_graph, matching_rules)
end
end
Expand Down
10 changes: 10 additions & 0 deletions lib/pact/specification_version.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
module Pact
class SpecificationVersion < Gem::Version

NIL_VERSION = SpecificationVersion.new('')

def major
segments.first
end
end
end
36 changes: 36 additions & 0 deletions spec/fixtures/pact-http-v2.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
{
"consumer": {
"name": "some-test-consumer"
},
"provider": {
"name": "an unknown provider"
},
"interactions": [
{
"description": "a test request",
"request": {
"method": "get",
"path": "/weather",
"query": ""
},
"response": {
"matchingRules": {
"$.headers.Content-Type" : {
"match": "regex", "regex": "json"
},
"$.body.message" : {
"match": "regex", "regex": "sun"
}
},
"status": 200,
"headers" : {
"Content-Type": "foo/json"
},
"body": {
"message" : "sunful"
}
},
"provider_state": "the weather is sunny"
}
]
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,14 @@ module Pact
describe "#call integration test" do
subject { HttpConsumerContractParser.new.call(pact_hash) }

context "with a v2 pact" do
let(:pact_hash) { load_json_fixture('pact-http-v2.json') }

it "correctly parses the pact" do
expect(subject.interactions.first.response.headers['Content-Type']).to be_a(Pact::Term)
end
end

context "with a v3 pact" do
let(:pact_hash) { load_json_fixture('pact-http-v3.json') }

Expand Down
2 changes: 1 addition & 1 deletion spec/lib/pact/consumer_contract/interaction_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ module Consumer
context "when there are matching rules" do
let(:hash) { load_json_fixture 'interaction-with-matching-rules.json' }

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

it "merges the rules with the example for the request" do
expect(subject.request.body['name']).to be_instance_of(Pact::Term)
Expand Down
7 changes: 1 addition & 6 deletions spec/lib/pact/matching_rules_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,18 +11,13 @@ module MatchingRules

let(:object) { double('object') }
let(:rules) { double('rules') }
let(:options) { { pact_specification_version: Gem::Version.new(pact_specification_version) } }
let(:options) { { pact_specification_version: Pact::SpecificationVersion.new(pact_specification_version) } }

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

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

it "prints a warning" do
expect(Pact.configuration.error_stream).to receive(:puts).with(/No pact specification version found/)
subject
end

it "calls Merge" do
expect(Merge).to receive(:call)
subject
Expand Down

0 comments on commit a69b5e6

Please sign in to comment.