pact 0.1.37 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/Gemfile.lock +6 -19
- data/example/zoo-app/Gemfile +1 -2
- data/example/zoo-app/Gemfile.lock +16 -13
- data/example/zoo-app/spec/pacts/zoo_app-animal_service.json +6 -6
- data/lib/pact/consumer/app_manager.rb +8 -28
- data/lib/pact/consumer/consumer_contract_builder.rb +65 -36
- data/lib/pact/consumer/dsl.rb +20 -10
- data/lib/pact/consumer/interaction_builder.rb +42 -0
- data/lib/pact/consumer/interactions_filter.rb +41 -0
- data/lib/pact/consumer/mock_service.rb +26 -19
- data/lib/pact/consumer/rspec.rb +2 -3
- data/lib/pact/consumer/server.rb +90 -0
- data/lib/pact/consumer.rb +6 -3
- data/lib/pact/consumer_contract/consumer_contract.rb +103 -0
- data/lib/pact/consumer_contract/interaction.rb +70 -0
- data/lib/pact/consumer_contract/service_consumer.rb +20 -0
- data/lib/pact/consumer_contract/service_provider.rb +20 -0
- data/lib/pact/consumer_contract.rb +1 -112
- data/lib/pact/{producer → provider}/dsl.rb +15 -4
- data/lib/pact/{producer → provider}/matchers.rb +0 -0
- data/lib/pact/{producer → provider}/pact_spec_runner.rb +2 -2
- data/lib/pact/{producer/producer_state.rb → provider/provider_state.rb} +13 -22
- data/lib/pact/provider/rspec.rb +128 -1
- data/lib/pact/{producer → provider}/test_methods.rb +12 -12
- data/lib/pact/{producer.rb → provider.rb} +0 -0
- data/lib/pact/verification_task.rb +4 -4
- data/lib/pact/version.rb +1 -1
- data/lib/pact.rb +1 -1
- data/pact.gemspec +1 -2
- data/scratchpad.txt +1 -1
- data/spec/features/consumption_spec.rb +15 -23
- data/spec/features/production_spec.rb +5 -5
- data/spec/features/{producer_states → provider_states}/zebras.rb +3 -3
- data/spec/integration/pact/consumer_configuration_spec.rb +3 -66
- data/spec/integration/pact/provider_configuration_spec.rb +1 -1
- data/spec/lib/pact/consumer/consumer_contract_builder_spec.rb +59 -15
- data/spec/lib/pact/consumer/dsl_spec.rb +4 -5
- data/spec/lib/pact/consumer/interaction_builder_spec.rb +91 -0
- data/spec/lib/pact/consumer/interactions_spec.rb +64 -0
- data/spec/lib/pact/consumer/mock_service_spec.rb +2 -6
- data/spec/lib/pact/consumer/service_consumer_spec.rb +1 -1
- data/spec/lib/pact/{consumer_contract_spec.rb → consumer_contract/consumer_contract_spec.rb} +72 -28
- data/spec/lib/pact/{consumer → consumer_contract}/interaction_spec.rb +49 -64
- data/spec/lib/pact/{producer/configuration_dsl_spec.rb → provider/dsl_spec.rb} +29 -28
- data/spec/lib/pact/{producer/producer_state_spec.rb → provider/provider_state_spec.rb} +17 -17
- data/spec/lib/pact/{producer → provider}/rspec_spec.rb +1 -1
- data/spec/lib/pact/verification_task_spec.rb +3 -3
- data/spec/spec_helper.rb +1 -0
- data/spec/support/a_consumer-a_producer.json +1 -1
- data/spec/support/a_consumer-a_provider.json +34 -0
- data/spec/support/consumer_contract_template.json +26 -0
- data/spec/support/factories.rb +78 -0
- data/spec/support/pact_rake_support.rb +1 -1
- data/spec/support/test_app_fail.json +1 -1
- data/spec/support/test_app_pass.json +1 -1
- data/tasks/pact-test.rake +3 -3
- metadata +38 -45
- data/lib/pact/consumer/configuration_dsl.rb +0 -73
- data/lib/pact/consumer/interaction.rb +0 -74
- data/lib/pact/consumer/run_condor.rb +0 -4
- data/lib/pact/consumer/run_mock_contract_service.rb +0 -13
- data/lib/pact/consumer/service_consumer.rb +0 -22
- data/lib/pact/consumer/service_producer.rb +0 -23
- data/lib/pact/producer/configuration_dsl.rb +0 -62
- data/lib/pact/producer/rspec.rb +0 -129
data/Gemfile.lock
CHANGED
@@ -1,11 +1,10 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
pact (0.
|
4
|
+
pact (2.0.0)
|
5
5
|
awesome_print (~> 1.1.0)
|
6
|
-
capybara (~> 2.1.0)
|
7
6
|
find_a_port (~> 1.0.1)
|
8
|
-
hashie (~> 2.0
|
7
|
+
hashie (~> 2.0)
|
9
8
|
json
|
10
9
|
rack-test (~> 0.6.2)
|
11
10
|
randexp (~> 0.1.7)
|
@@ -19,14 +18,8 @@ GEM
|
|
19
18
|
specs:
|
20
19
|
addressable (2.3.5)
|
21
20
|
awesome_print (1.1.0)
|
22
|
-
capybara (2.1.0)
|
23
|
-
mime-types (>= 1.16)
|
24
|
-
nokogiri (>= 1.3.3)
|
25
|
-
rack (>= 1.0.0)
|
26
|
-
rack-test (>= 0.5.4)
|
27
|
-
xpath (~> 2.0)
|
28
21
|
coderay (1.0.9)
|
29
|
-
crack (0.4.
|
22
|
+
crack (0.4.1)
|
30
23
|
safe_yaml (~> 0.9.0)
|
31
24
|
daemons (1.1.9)
|
32
25
|
diff-lcs (1.2.4)
|
@@ -36,12 +29,8 @@ GEM
|
|
36
29
|
multipart-post
|
37
30
|
hashie (2.0.5)
|
38
31
|
json (1.8.0)
|
39
|
-
method_source (0.8.
|
40
|
-
mime-types (1.24)
|
41
|
-
mini_portile (0.5.1)
|
32
|
+
method_source (0.8.2)
|
42
33
|
multipart-post (1.2.0)
|
43
|
-
nokogiri (1.6.0)
|
44
|
-
mini_portile (~> 0.5.0)
|
45
34
|
pry (0.9.12.2)
|
46
35
|
coderay (~> 1.0.5)
|
47
36
|
method_source (~> 0.8)
|
@@ -59,8 +48,8 @@ GEM
|
|
59
48
|
rspec-expectations (2.14.2)
|
60
49
|
diff-lcs (>= 1.1.3, < 2.0)
|
61
50
|
rspec-mocks (2.14.3)
|
62
|
-
safe_yaml (0.9.
|
63
|
-
slop (3.4.
|
51
|
+
safe_yaml (0.9.5)
|
52
|
+
slop (3.4.6)
|
64
53
|
thin (1.5.1)
|
65
54
|
daemons (>= 1.0.9)
|
66
55
|
eventmachine (>= 0.12.6)
|
@@ -69,8 +58,6 @@ GEM
|
|
69
58
|
webmock (1.9.3)
|
70
59
|
addressable (>= 2.2.7)
|
71
60
|
crack (>= 0.3.2)
|
72
|
-
xpath (2.0.0)
|
73
|
-
nokogiri (~> 1.3)
|
74
61
|
|
75
62
|
PLATFORMS
|
76
63
|
ruby
|
data/example/zoo-app/Gemfile
CHANGED
@@ -1,6 +1,20 @@
|
|
1
|
+
PATH
|
2
|
+
remote: ../../
|
3
|
+
specs:
|
4
|
+
pact (0.1.37)
|
5
|
+
awesome_print (~> 1.1.0)
|
6
|
+
capybara (~> 2.1.0)
|
7
|
+
find_a_port (~> 1.0.1)
|
8
|
+
hashie (~> 2.0.5)
|
9
|
+
json
|
10
|
+
rack-test (~> 0.6.2)
|
11
|
+
randexp (~> 0.1.7)
|
12
|
+
rspec (~> 2.12)
|
13
|
+
thin
|
14
|
+
thor
|
15
|
+
|
1
16
|
GEM
|
2
17
|
remote: https://rubygems.org/
|
3
|
-
remote: http://rea-rubygems/
|
4
18
|
specs:
|
5
19
|
awesome_print (1.1.0)
|
6
20
|
capybara (2.1.0)
|
@@ -26,17 +40,6 @@ GEM
|
|
26
40
|
multi_xml (0.5.5)
|
27
41
|
nokogiri (1.6.0)
|
28
42
|
mini_portile (~> 0.5.0)
|
29
|
-
pact (0.1.32)
|
30
|
-
awesome_print (~> 1.1.0)
|
31
|
-
capybara (~> 2.1.0)
|
32
|
-
find_a_port (~> 1.0.1)
|
33
|
-
hashie (~> 2.0.5)
|
34
|
-
json
|
35
|
-
rack-test (~> 0.6.2)
|
36
|
-
randexp (~> 0.1.7)
|
37
|
-
rspec (~> 2.12)
|
38
|
-
thin
|
39
|
-
thor
|
40
43
|
pry (0.9.12.2)
|
41
44
|
coderay (~> 1.0.5)
|
42
45
|
method_source (~> 0.8)
|
@@ -70,7 +73,7 @@ DEPENDENCIES
|
|
70
73
|
bundler (~> 1.3.0)
|
71
74
|
httparty
|
72
75
|
json (~> 1.6.8)
|
73
|
-
pact
|
76
|
+
pact!
|
74
77
|
pry
|
75
78
|
rack (~> 1.5.2)
|
76
79
|
rake
|
@@ -1,5 +1,5 @@
|
|
1
1
|
{
|
2
|
-
"
|
2
|
+
"provider": {
|
3
3
|
"name": "Animal Service"
|
4
4
|
},
|
5
5
|
"consumer": {
|
@@ -25,7 +25,7 @@
|
|
25
25
|
]
|
26
26
|
}
|
27
27
|
},
|
28
|
-
"
|
28
|
+
"provider_state": "there are alligators"
|
29
29
|
},
|
30
30
|
{
|
31
31
|
"description": "a request for alligators",
|
@@ -47,7 +47,7 @@
|
|
47
47
|
}
|
48
48
|
]
|
49
49
|
},
|
50
|
-
"
|
50
|
+
"provider_state": "there are alligators"
|
51
51
|
},
|
52
52
|
{
|
53
53
|
"description": "a request for alligator Mary",
|
@@ -69,7 +69,7 @@
|
|
69
69
|
}
|
70
70
|
]
|
71
71
|
},
|
72
|
-
"
|
72
|
+
"provider_state": "there is an alligator named Mary"
|
73
73
|
},
|
74
74
|
{
|
75
75
|
"description": "a request for alligators",
|
@@ -89,12 +89,12 @@
|
|
89
89
|
"error": "Argh!!!"
|
90
90
|
}
|
91
91
|
},
|
92
|
-
"
|
92
|
+
"provider_state": "an error has occurred"
|
93
93
|
}
|
94
94
|
],
|
95
95
|
"metadata": {
|
96
96
|
"pact_gem": {
|
97
|
-
"version": "0.1.
|
97
|
+
"version": "0.1.37"
|
98
98
|
}
|
99
99
|
}
|
100
100
|
}
|
@@ -1,10 +1,10 @@
|
|
1
1
|
require 'thwait'
|
2
|
-
require 'capybara'
|
3
2
|
|
4
3
|
require 'net/http'
|
5
4
|
require 'uri'
|
6
5
|
require 'find_a_port'
|
7
6
|
require 'pact/logging'
|
7
|
+
require 'pact/consumer/server'
|
8
8
|
|
9
9
|
module Pact
|
10
10
|
module Consumer
|
@@ -110,9 +110,11 @@ module Pact
|
|
110
110
|
end
|
111
111
|
|
112
112
|
def kill
|
113
|
-
|
114
|
-
|
115
|
-
Process.
|
113
|
+
# TODO: need to work out how to kill
|
114
|
+
# logger.info "Killing #{self}"
|
115
|
+
# Process.kill(9, pid)
|
116
|
+
# Process.wait(pid)
|
117
|
+
# self.pid = nil
|
116
118
|
self.pid = nil
|
117
119
|
end
|
118
120
|
|
@@ -133,31 +135,9 @@ module Pact
|
|
133
135
|
end
|
134
136
|
|
135
137
|
def spawn
|
136
|
-
# following stolen from https://github.com/jwilger/kookaburra
|
137
138
|
logger.info "Starting app #{self}..."
|
138
|
-
|
139
|
-
|
140
|
-
Capybara.server_port = port
|
141
|
-
Capybara::Server.new(app).boot
|
142
|
-
|
143
|
-
# This ensures that this forked process keeps running, because the
|
144
|
-
# actual server is started in a thread by Capybara.
|
145
|
-
ThreadsWait.all_waits(Thread.list)
|
146
|
-
rescue Exception => e
|
147
|
-
logger.error "Error starting up #{self}"
|
148
|
-
$stderr.puts "Error starting up #{self}"
|
149
|
-
raise e
|
150
|
-
end
|
151
|
-
end
|
152
|
-
|
153
|
-
|
154
|
-
wait_until do
|
155
|
-
begin
|
156
|
-
Net::HTTP.get_response(URI.parse("http://localhost:#{port}/index.html"))
|
157
|
-
rescue Errno::ECONNREFUSED
|
158
|
-
false
|
159
|
-
end
|
160
|
-
end
|
139
|
+
Pact::Server.new(app, port).boot
|
140
|
+
self.pid = 'unknown'
|
161
141
|
logger.info "Started with pid #{pid}"
|
162
142
|
end
|
163
143
|
|
@@ -2,6 +2,7 @@ require 'uri'
|
|
2
2
|
require 'json/add/regexp'
|
3
3
|
require 'pact/logging'
|
4
4
|
require 'pact/consumer/mock_service_client'
|
5
|
+
require_relative 'interactions_filter'
|
5
6
|
|
6
7
|
module Pact
|
7
8
|
module Consumer
|
@@ -11,52 +12,35 @@ module Pact
|
|
11
12
|
include Pact::Logging
|
12
13
|
|
13
14
|
attr_reader :consumer_contract
|
14
|
-
attr_reader :mock_service_client
|
15
15
|
|
16
16
|
def initialize(attributes)
|
17
|
-
@
|
18
|
-
@
|
17
|
+
@interaction_builder = nil
|
18
|
+
@mock_service_client = MockServiceClient.new(attributes[:provider_name], attributes[:port])
|
19
19
|
@consumer_contract = Pact::ConsumerContract.new(
|
20
20
|
:consumer => ServiceConsumer.new(name: attributes[:consumer_name]),
|
21
|
-
:
|
21
|
+
:provider => ServiceProvider.new(name: attributes[:provider_name])
|
22
22
|
)
|
23
|
-
@
|
24
|
-
|
25
|
-
load_existing_interactions
|
26
|
-
end
|
27
|
-
end
|
28
|
-
|
29
|
-
def load_existing_interactions
|
30
|
-
json = File.read(consumer_contract.pactfile_path)
|
31
|
-
if json.size > 0
|
32
|
-
existing_consumer_contract = Pact::ConsumerContract.from_json json
|
33
|
-
existing_consumer_contract.interactions.each do | interaction |
|
34
|
-
@interactions["#{interaction.description} given #{interaction.producer_state}"] = interaction
|
35
|
-
end
|
36
|
-
consumer_contract.interactions = @interactions.values
|
37
|
-
end
|
23
|
+
@consumer_contract.interactions = interactions_for_new_consumer_contract(attributes[:pactfile_write_mode])
|
24
|
+
@interactions_filter = filter(@consumer_contract.interactions, attributes[:pactfile_write_mode])
|
38
25
|
end
|
39
26
|
|
40
|
-
def given(
|
41
|
-
|
42
|
-
self
|
27
|
+
def given(provider_state)
|
28
|
+
interaction_builder.given(provider_state)
|
43
29
|
end
|
44
30
|
|
45
31
|
def upon_receiving(description)
|
46
|
-
interaction_builder
|
47
|
-
producer = self
|
48
|
-
interaction_builder.on_interaction_fully_defined do | interaction |
|
49
|
-
producer.handle_interaction_fully_defined(interaction)
|
50
|
-
end
|
51
|
-
@interactions["#{description} given #{@producer_state}"] ||= interaction_builder.interaction
|
52
|
-
consumer_contract.interactions = @interactions.values
|
53
|
-
interaction_builder
|
32
|
+
interaction_builder.upon_receiving(description)
|
54
33
|
end
|
55
34
|
|
56
|
-
def
|
57
|
-
|
58
|
-
|
59
|
-
|
35
|
+
def interaction_builder
|
36
|
+
@interaction_builder ||=
|
37
|
+
begin
|
38
|
+
interaction_builder = InteractionBuilder.new
|
39
|
+
interaction_builder.on_interaction_fully_defined do | interaction |
|
40
|
+
self.handle_interaction_fully_defined(interaction)
|
41
|
+
end
|
42
|
+
interaction_builder
|
43
|
+
end
|
60
44
|
end
|
61
45
|
|
62
46
|
def verify example_description
|
@@ -69,10 +53,55 @@ module Pact
|
|
69
53
|
mock_service_client.wait_for_interactions wait_max_seconds, poll_interval
|
70
54
|
end
|
71
55
|
|
56
|
+
def handle_interaction_fully_defined interaction
|
57
|
+
interactions_filter << interaction
|
58
|
+
mock_service_client.add_expected_interaction interaction #TODO: What will happen if duplicate added?
|
59
|
+
consumer_contract.update_pactfile
|
60
|
+
self.interaction_builder = nil
|
61
|
+
end
|
62
|
+
|
72
63
|
private
|
73
64
|
|
74
|
-
|
75
|
-
|
65
|
+
attr_reader :mock_service_client
|
66
|
+
attr_reader :interactions_filter
|
67
|
+
attr_writer :interaction_builder
|
68
|
+
|
69
|
+
def interactions_for_new_consumer_contract pactfile_write_mode
|
70
|
+
pactfile_write_mode == :update ? existing_interactions : []
|
71
|
+
end
|
72
|
+
|
73
|
+
def filter interactions, pactfile_write_mode
|
74
|
+
if pactfile_write_mode == :update
|
75
|
+
UpdatableInteractionsFilter.new(interactions)
|
76
|
+
else
|
77
|
+
DistinctInteractionsFilter.new(interactions)
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
def log_and_puts msg
|
82
|
+
$stderr.puts msg
|
83
|
+
logger.warn msg
|
84
|
+
end
|
85
|
+
|
86
|
+
def existing_interactions
|
87
|
+
interactions = []
|
88
|
+
if pactfile_exists?
|
89
|
+
begin
|
90
|
+
interactions = existing_consumer_contract.interactions
|
91
|
+
rescue StandardError => e
|
92
|
+
log_and_puts "Could not load existing consumer contract from #{consumer_contract.pactfile_path} due to #{e}"
|
93
|
+
log_and_puts "Creating a new file."
|
94
|
+
end
|
95
|
+
end
|
96
|
+
interactions
|
97
|
+
end
|
98
|
+
|
99
|
+
def pactfile_exists?
|
100
|
+
File.exist?(consumer_contract.pactfile_path)
|
101
|
+
end
|
102
|
+
|
103
|
+
def existing_consumer_contract
|
104
|
+
Pact::ConsumerContract.from_json(File.read(consumer_contract.pactfile_path))
|
76
105
|
end
|
77
106
|
|
78
107
|
end
|
data/lib/pact/consumer/dsl.rb
CHANGED
@@ -3,6 +3,15 @@ require_relative 'consumer_contract_builders'
|
|
3
3
|
module Pact::Consumer
|
4
4
|
module DSL
|
5
5
|
|
6
|
+
module Configuration
|
7
|
+
def add_provider_verification &block
|
8
|
+
provider_verifications << block
|
9
|
+
end
|
10
|
+
def provider_verifications
|
11
|
+
@provider_verifications ||= []
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
6
15
|
def service_consumer name, &block
|
7
16
|
ServiceConsumerDSL.new(name, &block).create_service_consumer
|
8
17
|
end
|
@@ -11,7 +20,7 @@ module Pact::Consumer
|
|
11
20
|
|
12
21
|
def initialize name, &block
|
13
22
|
@name = name
|
14
|
-
consumer = Pact::
|
23
|
+
consumer = Pact::ServiceConsumer.new name: @name
|
15
24
|
@app = nil
|
16
25
|
@port = nil
|
17
26
|
instance_eval(&block)
|
@@ -31,7 +40,7 @@ module Pact::Consumer
|
|
31
40
|
end
|
32
41
|
|
33
42
|
def has_pact_with service_provider_name, &block
|
34
|
-
|
43
|
+
Provider.new(service_provider_name, @name, &block).create_consumer_contract_builder
|
35
44
|
end
|
36
45
|
|
37
46
|
def create_service_consumer
|
@@ -48,13 +57,13 @@ module Pact::Consumer
|
|
48
57
|
|
49
58
|
|
50
59
|
#OLD ####
|
51
|
-
def
|
52
|
-
|
60
|
+
def with_provider name, &block
|
61
|
+
Provider.new(name, &block).create_consumer_contract_builder
|
53
62
|
end
|
54
63
|
|
55
|
-
alias_method :with_service_provider, :
|
64
|
+
alias_method :with_service_provider, :with_provider
|
56
65
|
|
57
|
-
class
|
66
|
+
class Provider
|
58
67
|
def initialize name, consumer_name = Pact.configuration.consumer.name, &block
|
59
68
|
@name = name
|
60
69
|
@service = nil
|
@@ -80,7 +89,7 @@ module Pact::Consumer
|
|
80
89
|
def consumer_contract_builder_from_attributes
|
81
90
|
consumer_contract_builder_fields = {
|
82
91
|
:consumer_name => @consumer_name,
|
83
|
-
:
|
92
|
+
:provider_name => @name,
|
84
93
|
:pactfile_write_mode => Pact.configuration.pactfile_write_mode
|
85
94
|
}
|
86
95
|
@service.configure_consumer_contract_builder consumer_contract_builder_fields
|
@@ -111,7 +120,7 @@ module Pact::Consumer
|
|
111
120
|
def configure_consumer_contract_builder consumer_contract_builder_fields
|
112
121
|
validate
|
113
122
|
unless @standalone
|
114
|
-
AppManager.instance.register_mock_service_for consumer_contract_builder_fields[:
|
123
|
+
AppManager.instance.register_mock_service_for consumer_contract_builder_fields[:provider_name], "http://localhost:#{@port}"
|
115
124
|
end
|
116
125
|
consumer_contract_builder = Pact::Consumer::ConsumerContractBuilder.new consumer_contract_builder_fields.merge({port: @port})
|
117
126
|
create_mock_services_module_method consumer_contract_builder
|
@@ -121,7 +130,7 @@ module Pact::Consumer
|
|
121
130
|
|
122
131
|
|
123
132
|
def setup_verification consumer_contract_builder
|
124
|
-
Pact.configuration.
|
133
|
+
Pact.configuration.add_provider_verification do | example_description |
|
125
134
|
consumer_contract_builder.verify example_description
|
126
135
|
end
|
127
136
|
end
|
@@ -144,4 +153,5 @@ module Pact::Consumer
|
|
144
153
|
end
|
145
154
|
end
|
146
155
|
|
147
|
-
Pact.send(:extend, Pact::Consumer::DSL)
|
156
|
+
Pact.send(:extend, Pact::Consumer::DSL)
|
157
|
+
Pact::Configuration.send(:include, Pact::Consumer::DSL::Configuration)
|
@@ -0,0 +1,42 @@
|
|
1
|
+
require 'net/http'
|
2
|
+
require 'pact/reification'
|
3
|
+
require 'pact/request'
|
4
|
+
require 'pact/consumer_contract/interaction'
|
5
|
+
|
6
|
+
module Pact
|
7
|
+
module Consumer
|
8
|
+
class InteractionBuilder
|
9
|
+
|
10
|
+
attr_reader :interaction
|
11
|
+
|
12
|
+
def initialize
|
13
|
+
@interaction = Interaction.new
|
14
|
+
end
|
15
|
+
|
16
|
+
def upon_receiving description
|
17
|
+
@interaction.description = description
|
18
|
+
self
|
19
|
+
end
|
20
|
+
|
21
|
+
def given provider_state
|
22
|
+
@interaction.provider_state = provider_state.nil? ? nil : provider_state.to_s
|
23
|
+
self
|
24
|
+
end
|
25
|
+
|
26
|
+
def with(request_details)
|
27
|
+
interaction.request = Request::Expected.from_hash(request_details)
|
28
|
+
self
|
29
|
+
end
|
30
|
+
|
31
|
+
def will_respond_with(response)
|
32
|
+
interaction.response = response
|
33
|
+
@callback.call interaction
|
34
|
+
self
|
35
|
+
end
|
36
|
+
|
37
|
+
def on_interaction_fully_defined &block
|
38
|
+
@callback = block
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
module Pact
|
2
|
+
module Consumer
|
3
|
+
|
4
|
+
#TODO: think of a better word than filter
|
5
|
+
class InteractionsFilter
|
6
|
+
def initialize interactions = []
|
7
|
+
@interactions = interactions
|
8
|
+
end
|
9
|
+
|
10
|
+
def index_of interaction
|
11
|
+
@interactions.find_index{ |i| i.matches_criteria?(description: interaction.description, provider_state: interaction.provider_state)}
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
class UpdatableInteractionsFilter < InteractionsFilter
|
16
|
+
|
17
|
+
def << interaction
|
18
|
+
if (ndx = index_of(interaction))
|
19
|
+
@interactions[ndx] = interaction
|
20
|
+
else
|
21
|
+
@interactions << interaction
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
26
|
+
|
27
|
+
class DistinctInteractionsFilter < InteractionsFilter
|
28
|
+
|
29
|
+
def << interaction
|
30
|
+
if (ndx = index_of(interaction))
|
31
|
+
if @interactions[ndx] != interaction
|
32
|
+
raise "Interaction with same description (#{interaction.description}) and provider state (#{interaction.provider_state}) already exists"
|
33
|
+
end
|
34
|
+
else
|
35
|
+
@interactions << interaction
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
41
|
+
end
|