-
Notifications
You must be signed in to change notification settings - Fork 47
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(publish pacts): merge pact files with same consumer/provider bef…
…ore publishing
- Loading branch information
Showing
10 changed files
with
219 additions
and
43 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
module PactBroker | ||
module Client | ||
class Error < StandardError; end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
require 'json' | ||
require 'pact_broker/client/error' | ||
|
||
module PactBroker | ||
module Client | ||
|
||
class PactMergeError < PactBroker::Client::Error; end | ||
|
||
module MergePacts | ||
extend self | ||
|
||
def call pact_hashes | ||
pact_hashes.reduce{|p1, p2| merge(p1, p2) } | ||
end | ||
|
||
# Accepts two hashes representing pacts, outputs a merged hash | ||
# Does not make any guarantees about order of interactions | ||
def merge original, additional | ||
new_pact = JSON.parse(original.to_json, symbolize_names: true) | ||
|
||
additional[:interactions].each do |new_interaction| | ||
# check to see if this interaction matches an existing interaction | ||
overwrite_index = original[:interactions].find_index do |original_interaction| | ||
same_description_and_state?(original_interaction, new_interaction) | ||
end | ||
|
||
# overwrite existing interaction if a match is found, otherwise appends the new interaction | ||
if overwrite_index | ||
if new_interaction == original[:interactions][overwrite_index] | ||
new_pact[:interactions][overwrite_index] = new_interaction | ||
else | ||
raise PactMergeError, almost_duplicate_message(original[:interactions][overwrite_index], new_interaction) | ||
end | ||
else | ||
new_pact[:interactions] << new_interaction | ||
end | ||
end | ||
|
||
new_pact | ||
end | ||
|
||
private | ||
|
||
def almost_duplicate_message(original, new_interaction) | ||
"An interaction with same description (#{new_interaction[:description].inspect}) and provider state (#{new_interaction[:providerState].inspect}) but a different request or response has already been used. " + | ||
"Please use a different description or provider state, or hard-code any random data.\n" + | ||
original.to_json + "\n\n" | ||
new_interaction.to_json | ||
end | ||
|
||
def same_description_and_state? original, additional | ||
original[:description] == additional[:description] && | ||
original[:providerState] == additional[:providerState] | ||
end | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
require 'json' | ||
|
||
module PactBroker | ||
module Client | ||
class PactHash < ::Hash | ||
def pact_name | ||
"#{consumer_name}/#{provider_name} pact" | ||
end | ||
|
||
def consumer_name | ||
self[:consumer][:name] | ||
end | ||
|
||
def provider_name | ||
self[:provider][:name] | ||
end | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
require 'pact_broker/client/merge_pacts' | ||
|
||
module PactBroker | ||
module Client | ||
describe MergePacts do | ||
describe ".call" do | ||
let(:pact_hash_1) do | ||
{ | ||
other: 'info', | ||
interactions: [ | ||
{providerState: 1, description: 1, foo: 'bar' } | ||
] | ||
} | ||
end | ||
|
||
let(:pact_hash_2) do | ||
{ | ||
interactions: [ | ||
{providerState: 2, description: 2, foo: 'wiffle' } | ||
] | ||
} | ||
end | ||
|
||
let(:pact_hash_3) do | ||
{ | ||
interactions: [ | ||
{providerState: 3, description: 3, foo: 'meep' }, | ||
{providerState: 1, description: 1, foo: 'bar' } | ||
] | ||
} | ||
end | ||
|
||
let(:pact_hashes) { [pact_hash_1, pact_hash_2, pact_hash_3] } | ||
|
||
let(:expected_merge) do | ||
{ | ||
other: 'info', | ||
interactions: [ | ||
{providerState: 1, description: 1, foo: 'bar' }, | ||
{providerState: 2, description: 2, foo: 'wiffle' }, | ||
{providerState: 3, description: 3, foo: 'meep' } | ||
] | ||
} | ||
end | ||
|
||
subject { MergePacts.call(pact_hashes) } | ||
|
||
it "merges the interactions by consumer/provider" do | ||
expect(subject).to eq expected_merge | ||
end | ||
|
||
context "when an interaction is found with the same state and description but has a difference elsewhere" do | ||
let(:pact_hash_3) do | ||
{ | ||
interactions: [ | ||
{providerState: 3, description: 3, foo: 'meep' }, | ||
{providerState: 1, description: 1, foo: 'different' } | ||
] | ||
} | ||
end | ||
|
||
it "raises an error" do | ||
expect { subject }.to raise_error PactMergeError | ||
end | ||
end | ||
end | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.