pact 1.0.22 → 1.0.23

Sign up to get free protection for your applications and to get access to all the features.
@@ -2,6 +2,10 @@ Do this to generate your change history
2
2
 
3
3
  git log --date=relative --pretty=format:' * %h - %s (%an, %ad)'
4
4
 
5
+ ### 1.0.23 (29 November 2013)
6
+
7
+ * a978654 - Improving the display of verification errors in the consumer project. (Beth Skurrie, 2 days ago)
8
+
5
9
  ### 1.0.22 (25 November 2013)
6
10
 
7
11
  * f742833 - Updating README (Beth Skurrie, 36 seconds ago)
data/Gemfile CHANGED
@@ -1,5 +1,5 @@
1
1
  source 'https://rubygems.org'
2
-
2
+ source 'http://rea-rubygems'
3
3
  # Specify your gem's dependencies in pact.gemspec
4
4
  gemspec
5
5
 
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- pact (1.0.22)
4
+ pact (1.0.23)
5
5
  awesome_print (~> 1.1.0)
6
6
  find_a_port (~> 1.0.1)
7
7
  json
@@ -13,6 +13,7 @@ PATH
13
13
 
14
14
  GEM
15
15
  remote: https://rubygems.org/
16
+ remote: http://rea-rubygems/
16
17
  specs:
17
18
  activesupport (4.0.0)
18
19
  i18n (~> 0.6, >= 0.6.4)
@@ -4,6 +4,7 @@ module Pact
4
4
 
5
5
  attr_reader :interactions
6
6
  attr_reader :unexpected_requests
7
+ attr_reader :interaction_mismatches
7
8
 
8
9
  def initialize
9
10
  clear
@@ -13,6 +14,7 @@ module Pact
13
14
  def clear
14
15
  @interactions = []
15
16
  @matched_interactions = []
17
+ @interaction_mismatches = []
16
18
  @unexpected_requests = []
17
19
  end
18
20
 
@@ -28,18 +30,35 @@ module Pact
28
30
  @unexpected_requests << request
29
31
  end
30
32
 
33
+ def register_interaction_mismatch interaction_mismatch
34
+ @interaction_mismatches << interaction_mismatch
35
+ end
36
+
31
37
  def all_matched?
32
38
  interaction_diffs.empty?
33
39
  end
34
40
 
35
41
  def missing_interactions
36
- @interactions - @matched_interactions
42
+ @interactions - @matched_interactions - @interaction_mismatches.collect(&:candidate_interactions).flatten
43
+ end
44
+
45
+ def missing_interactions_summaries
46
+ missing_interactions.collect(&:request).collect(&:method_and_path)
47
+ end
48
+
49
+ def interaction_mismatches_summaries
50
+ interaction_mismatches.collect(&:short_summary)
51
+ end
52
+
53
+ def unexpected_requests_summaries
54
+ unexpected_requests.collect(&:method_and_path)
37
55
  end
38
56
 
39
57
  def interaction_diffs
40
58
  {
41
- :missing_interactions => missing_interactions.collect(&:as_json),
42
- :unexpected_requests => unexpected_requests.collect(&:as_json)
59
+ :missing_interactions => missing_interactions_summaries,
60
+ :interaction_mismatches => interaction_mismatches_summaries,
61
+ :unexpected_requests => unexpected_requests_summaries
43
62
  }.inject({}) do | hash, pair |
44
63
  hash[pair.first] = pair.last if pair.last.any?
45
64
  hash
@@ -49,9 +68,9 @@ module Pact
49
68
  def find_candidate_interactions actual_request
50
69
  interactions.select do | interaction |
51
70
  interaction.request.matches_route? actual_request
52
- end
53
- end
71
+ end
72
+ end
54
73
 
55
- end
74
+ end
56
75
  end
57
76
  end
@@ -0,0 +1,51 @@
1
+ module Pact
2
+ module Consumer
3
+ class InteractionMismatch
4
+
5
+ attr_accessor :candidate_interactions, :actual_request
6
+
7
+ # Assumes the method and path matches...
8
+
9
+ def initialize candidate_interactions, actual_request
10
+ @candidate_interactions = candidate_interactions
11
+ @actual_request = actual_request
12
+ @candiate_diffs = candidate_interactions.collect{ | candidate_interaction| CandidateDiff.new(candidate_interaction, actual_request)}
13
+ end
14
+
15
+ def diffs
16
+ candiate_diffs.collect(&:diff_summary)
17
+ end
18
+
19
+ def short_summary
20
+ mismatched_attributes = candiate_diffs.collect(&:mismatched_attributes).flatten.uniq.join(", ").reverse.sub(",", "dna ").reverse #OMG what a hack!
21
+ actual_request.method_and_path + " (#{mismatched_attributes} did not match)"
22
+ end
23
+
24
+ private
25
+
26
+ attr_accessor :candiate_diffs
27
+
28
+ class CandidateDiff
29
+ attr_accessor :candidate_interaction, :actual_request
30
+ def initialize candidate_interaction, actual_request
31
+ @candidate_interaction = candidate_interaction
32
+ @actual_request = actual_request
33
+ end
34
+
35
+ def mismatched_attributes
36
+ diff.keys
37
+ end
38
+
39
+ def diff_summary
40
+ summary = {:description => candidate_interaction.description}
41
+ summary[:provider_state] = candidate_interaction.provider_state if candidate_interaction.provider_state
42
+ summary.merge(diff)
43
+ end
44
+
45
+ def diff
46
+ @diff ||= candidate_interaction.request.difference(actual_request)
47
+ end
48
+ end
49
+ end
50
+ end
51
+ end
@@ -1,5 +1,6 @@
1
1
  require 'pact/matchers'
2
2
  require 'pact/consumer/mock_service/rack_request_helper'
3
+ require 'pact/consumer/mock_service/interaction_mismatch'
3
4
 
4
5
  module Pact
5
6
  module Consumer
@@ -70,11 +71,8 @@ module Pact
70
71
  multiple_interactions_found_response actual_request, matching_interactions
71
72
  end
72
73
 
73
- def interaction_diffs actual_request, candidate_interactions
74
- candidate_interactions.collect do | candidate_interaction |
75
- diff = candidate_interaction.request.difference(actual_request)
76
- diff_summary_for candidate_interaction, diff
77
- end
74
+ def interaction_mismatch actual_request, candidate_interactions
75
+ InteractionMismatch.new(candidate_interactions, actual_request)
78
76
  end
79
77
 
80
78
  def diff_summary_for interaction, diff
@@ -90,25 +88,29 @@ module Pact
90
88
  summary
91
89
  end
92
90
 
93
- def unrecognised_request_response actual_request, interaction_diffs
91
+ def unrecognised_request_response interaction_mismatch
94
92
  response = {
95
- message: "No interaction found for #{actual_request.method_and_path}",
96
- interaction_diffs: interaction_diffs
93
+ message: "No interaction found for #{interaction_mismatch.actual_request.method_and_path}",
94
+ interaction_diffs: interaction_mismatch.diffs
97
95
  }
98
96
  [500, {'Content-Type' => 'application/json'}, [response.to_json]]
99
97
  end
100
98
 
101
- def log_unrecognised_request_and_interaction_diff actual_request, interaction_diffs, candidate_interactions
102
- logger.error "No interaction found on #{name} for #{actual_request.method_and_path}"
99
+ def log_unrecognised_request_and_interaction_diff interaction_mismatch
100
+ logger.error "No interaction found on #{name} for #{interaction_mismatch.actual_request.method_and_path}"
103
101
  logger.error 'Interaction diffs for that route:'
104
- logger.ap(interaction_diffs, :error)
102
+ logger.ap(interaction_mismatch.diffs, :error)
105
103
  end
106
104
 
107
105
  def handle_unrecognised_request actual_request, candidate_interactions
108
- interaction_list.register_unexpected_request actual_request
109
- interaction_diffs = interaction_diffs(actual_request, candidate_interactions)
110
- log_unrecognised_request_and_interaction_diff actual_request, interaction_diffs, candidate_interactions
111
- unrecognised_request_response actual_request, interaction_diffs
106
+ interaction_mismatch = interaction_mismatch(actual_request, candidate_interactions)
107
+ if candidate_interactions.any?
108
+ interaction_list.register_interaction_mismatch interaction_mismatch
109
+ else
110
+ interaction_list.register_unexpected_request actual_request
111
+ end
112
+ log_unrecognised_request_and_interaction_diff interaction_mismatch
113
+ unrecognised_request_response interaction_mismatch
112
114
  end
113
115
 
114
116
  def response_from response
@@ -26,9 +26,19 @@ module Pact
26
26
  logger.info "Verifying - interactions matched for example \"#{example_description(env)}\""
27
27
  [200, {}, ['Interactions matched']]
28
28
  else
29
- logger.warn "Verifying - actual interactions do not match expected interactions for example \"#{example_description(env)}\". Interaction diffs:"
30
- logger.ap interaction_list.interaction_diffs, :warn
31
- [500, {}, ["Actual interactions do not match expected interactions for mock #{name}. See #{log_description} for details."]]
29
+
30
+ missing_interactions_summaries = interaction_list.missing_interactions_summaries
31
+ interaction_mismatches_summaries = interaction_list.interaction_mismatches_summaries
32
+ unexpected_requests_summaries = interaction_list.unexpected_requests_summaries
33
+ error_message = "Missing requests:
34
+ #{missing_interactions_summaries.join("\n ")}
35
+ Incorrect requests:
36
+ #{interaction_mismatches_summaries.join("\n ")}
37
+ Unexpected requests:
38
+ #{unexpected_requests_summaries.join("\n ")}"
39
+ logger.warn "Verifying - actual interactions do not match expected interactions for example \"#{example_description(env)}\". \n#{error_message}"
40
+ logger.warn error_message
41
+ [500, {}, ["Actual interactions do not match expected interactions for mock #{name}.\n#{error_message}\nSee #{log_description} for details."]]
32
42
  end
33
43
  end
34
44
 
@@ -12,7 +12,7 @@ module Pact
12
12
 
13
13
  def verify example_description
14
14
  response = http.request_get("/verify?example_description=#{URI.encode(example_description)}", MOCK_SERVICE_ADMINISTRATON_HEADERS)
15
- raise response.body unless response.is_a? Net::HTTPSuccess
15
+ raise "\e[31m#{response.body}\e[m" unless response.is_a? Net::HTTPSuccess
16
16
  end
17
17
 
18
18
  def log msg
@@ -20,8 +20,8 @@ module Pact
20
20
 
21
21
  def self.key_not_found
22
22
  nil
23
- end
24
- end
23
+ end
24
+ end
25
25
  end
26
26
  end
27
27
  end
@@ -1,3 +1,3 @@
1
1
  module Pact
2
- VERSION = "1.0.22"
2
+ VERSION = "1.0.23"
3
3
  end
@@ -6,18 +6,21 @@ module Pact::Consumer
6
6
  describe InteractionList do
7
7
  shared_context "unexpected requests and missed interactions" do
8
8
  let(:expected_interaction) { InteractionFactory.create }
9
- let(:unexpected_request) { RequestFactory.create_actual }
9
+ let(:unexpected_request) { RequestFactory.create_actual method: 'put' }
10
+ let(:candidate_interaction) { double("Pact::Interaction") }
11
+ let(:candidate_interactions) { [candidate_interaction] }
12
+ let(:interaction_mismatch) { instance_double("Pact::Consumer::InteractionMismatch", :short_summary => 'blah', :candidate_interactions => candidate_interactions)}
10
13
  subject {
11
14
  interactionList = InteractionList.new
12
15
  interactionList.add expected_interaction
13
16
  interactionList.register_unexpected_request unexpected_request
17
+ interactionList.register_interaction_mismatch interaction_mismatch
14
18
  interactionList
15
19
  }
16
20
  end
17
21
 
18
22
  shared_context "no unexpected requests or missed interactions exist" do
19
23
  let(:expected_interaction) { InteractionFactory.create }
20
- let(:unexpected_request) { RequestFactory.create_actual }
21
24
  subject {
22
25
  interactionList = InteractionList.new
23
26
  interactionList.add expected_interaction
@@ -30,7 +33,9 @@ module Pact::Consumer
30
33
  context "when unexpected requests and missed interactions exist" do
31
34
  include_context "unexpected requests and missed interactions"
32
35
  let(:expected_diff) {
33
- {:missing_interactions=>[expected_interaction.as_json], :unexpected_requests=>[unexpected_request.as_json]}
36
+ {:missing_interactions=>["GET /path"],
37
+ :unexpected_requests=>["PUT /path"],
38
+ :interaction_mismatches => ['blah']}
34
39
  }
35
40
  it "returns the unexpected requests and missed interactions" do
36
41
  expect(subject.interaction_diffs).to eq expected_diff
@@ -62,5 +67,12 @@ module Pact::Consumer
62
67
  end
63
68
  end
64
69
  end
70
+
71
+ describe "missing_interactions_summaries" do
72
+ include_context "unexpected requests and missed interactions"
73
+ it "returns a list of the method and paths for each missing interaction" do
74
+ expect(subject.missing_interactions_summaries).to eq ["GET /path"]
75
+ end
76
+ end
65
77
  end
66
78
  end
@@ -0,0 +1,49 @@
1
+ require 'spec_helper'
2
+ require 'pact/consumer/mock_service/interaction_mismatch'
3
+
4
+ module Pact
5
+ module Consumer
6
+ describe InteractionMismatch do
7
+ 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') }
10
+ let(:candidate_1) { instance_double('Pact::Interaction', request: expected_request_1) }
11
+ let(:candidate_2) { instance_double('Pact::Interaction', request: expected_request_2) }
12
+ let(:candidate_interactions) { [candidate_1, candidate_2] }
13
+ subject { InteractionMismatch.new(candidate_interactions, actual_request) }
14
+ let(:diff_1) { {body: nil} }
15
+ let(:diff_2) { {} }
16
+
17
+ before do
18
+ expected_request_1.stub(:difference).with(actual_request).and_return(diff_1)
19
+ expected_request_2.stub(:difference).with(actual_request).and_return(diff_2)
20
+ end
21
+
22
+ describe "short_summary" do
23
+ it "includes the method and path" do
24
+ expect(subject.short_summary).to match /GET \/path \(.*\)/
25
+ end
26
+ context "when the body does not match" do
27
+ let(:diff_1) { {body: nil} }
28
+
29
+ it "returns a message indicating that the body does not match" do
30
+ expect(subject.short_summary).to include "(body did not match)"
31
+ end
32
+ end
33
+ context "when the headers do not match" do
34
+ let(:diff_1) { {headers: nil} }
35
+ it "returns a message indicating that the body does not match" do
36
+ expect(subject.short_summary).to include "(headers did not match)"
37
+ end
38
+ end
39
+ context "when the headers and body do not match" do
40
+ let(:diff_1) { {body: nil, headers: nil} }
41
+ let(:diff_2) { {body: nil, headers: nil} }
42
+ it "returns a message indicating that the headers and body do not match" do
43
+ expect(subject.short_summary).to include "(body and headers did not match)"
44
+ end
45
+ end
46
+ end
47
+ end
48
+ end
49
+ end
@@ -76,7 +76,7 @@ class RequestFactory
76
76
  deep_merge(DEFAULTS, overrides)
77
77
  end
78
78
 
79
- def self.create_actual
80
- Pact::Consumer::Request::Actual.from_hash(create_hash)
79
+ def self.create_actual overrides = {}
80
+ Pact::Consumer::Request::Actual.from_hash(create_hash(overrides))
81
81
  end
82
82
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pact
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.22
4
+ version: 1.0.23
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -13,7 +13,7 @@ authors:
13
13
  autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
- date: 2013-11-25 00:00:00.000000000 Z
16
+ date: 2013-11-28 00:00:00.000000000 Z
17
17
  dependencies:
18
18
  - !ruby/object:Gem::Dependency
19
19
  name: randexp
@@ -307,6 +307,7 @@ files:
307
307
  - lib/pact/consumer/mock_service/app.rb
308
308
  - lib/pact/consumer/mock_service/interaction_delete.rb
309
309
  - lib/pact/consumer/mock_service/interaction_list.rb
310
+ - lib/pact/consumer/mock_service/interaction_mismatch.rb
310
311
  - lib/pact/consumer/mock_service/interaction_post.rb
311
312
  - lib/pact/consumer/mock_service/interaction_replay.rb
312
313
  - lib/pact/consumer/mock_service/log_get.rb
@@ -372,6 +373,8 @@ files:
372
373
  - spec/lib/pact/consumer/interaction_builder_spec.rb
373
374
  - spec/lib/pact/consumer/interactions_spec.rb
374
375
  - spec/lib/pact/consumer/mock_service/interaction_list_spec.rb
376
+ - spec/lib/pact/consumer/mock_service/interaction_mismatch_spec.rb
377
+ - spec/lib/pact/consumer/mock_service/interaction_replay_spec.rb
375
378
  - spec/lib/pact/consumer/mock_service/rack_request_helper_spec.rb
376
379
  - spec/lib/pact/consumer/mock_service_interaction_expectation_spec.rb
377
380
  - spec/lib/pact/consumer/request_spec.rb
@@ -421,7 +424,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
421
424
  version: '0'
422
425
  segments:
423
426
  - 0
424
- hash: 1182047425998304532
427
+ hash: -1054460629994905299
425
428
  required_rubygems_version: !ruby/object:Gem::Requirement
426
429
  none: false
427
430
  requirements:
@@ -430,7 +433,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
430
433
  version: '0'
431
434
  segments:
432
435
  - 0
433
- hash: 1182047425998304532
436
+ hash: -1054460629994905299
434
437
  requirements: []
435
438
  rubyforge_project:
436
439
  rubygems_version: 1.8.23
@@ -453,6 +456,8 @@ test_files:
453
456
  - spec/lib/pact/consumer/interaction_builder_spec.rb
454
457
  - spec/lib/pact/consumer/interactions_spec.rb
455
458
  - spec/lib/pact/consumer/mock_service/interaction_list_spec.rb
459
+ - spec/lib/pact/consumer/mock_service/interaction_mismatch_spec.rb
460
+ - spec/lib/pact/consumer/mock_service/interaction_replay_spec.rb
456
461
  - spec/lib/pact/consumer/mock_service/rack_request_helper_spec.rb
457
462
  - spec/lib/pact/consumer/mock_service_interaction_expectation_spec.rb
458
463
  - spec/lib/pact/consumer/request_spec.rb