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.
Files changed (65) hide show
  1. data/Gemfile.lock +6 -19
  2. data/example/zoo-app/Gemfile +1 -2
  3. data/example/zoo-app/Gemfile.lock +16 -13
  4. data/example/zoo-app/spec/pacts/zoo_app-animal_service.json +6 -6
  5. data/lib/pact/consumer/app_manager.rb +8 -28
  6. data/lib/pact/consumer/consumer_contract_builder.rb +65 -36
  7. data/lib/pact/consumer/dsl.rb +20 -10
  8. data/lib/pact/consumer/interaction_builder.rb +42 -0
  9. data/lib/pact/consumer/interactions_filter.rb +41 -0
  10. data/lib/pact/consumer/mock_service.rb +26 -19
  11. data/lib/pact/consumer/rspec.rb +2 -3
  12. data/lib/pact/consumer/server.rb +90 -0
  13. data/lib/pact/consumer.rb +6 -3
  14. data/lib/pact/consumer_contract/consumer_contract.rb +103 -0
  15. data/lib/pact/consumer_contract/interaction.rb +70 -0
  16. data/lib/pact/consumer_contract/service_consumer.rb +20 -0
  17. data/lib/pact/consumer_contract/service_provider.rb +20 -0
  18. data/lib/pact/consumer_contract.rb +1 -112
  19. data/lib/pact/{producer → provider}/dsl.rb +15 -4
  20. data/lib/pact/{producer → provider}/matchers.rb +0 -0
  21. data/lib/pact/{producer → provider}/pact_spec_runner.rb +2 -2
  22. data/lib/pact/{producer/producer_state.rb → provider/provider_state.rb} +13 -22
  23. data/lib/pact/provider/rspec.rb +128 -1
  24. data/lib/pact/{producer → provider}/test_methods.rb +12 -12
  25. data/lib/pact/{producer.rb → provider.rb} +0 -0
  26. data/lib/pact/verification_task.rb +4 -4
  27. data/lib/pact/version.rb +1 -1
  28. data/lib/pact.rb +1 -1
  29. data/pact.gemspec +1 -2
  30. data/scratchpad.txt +1 -1
  31. data/spec/features/consumption_spec.rb +15 -23
  32. data/spec/features/production_spec.rb +5 -5
  33. data/spec/features/{producer_states → provider_states}/zebras.rb +3 -3
  34. data/spec/integration/pact/consumer_configuration_spec.rb +3 -66
  35. data/spec/integration/pact/provider_configuration_spec.rb +1 -1
  36. data/spec/lib/pact/consumer/consumer_contract_builder_spec.rb +59 -15
  37. data/spec/lib/pact/consumer/dsl_spec.rb +4 -5
  38. data/spec/lib/pact/consumer/interaction_builder_spec.rb +91 -0
  39. data/spec/lib/pact/consumer/interactions_spec.rb +64 -0
  40. data/spec/lib/pact/consumer/mock_service_spec.rb +2 -6
  41. data/spec/lib/pact/consumer/service_consumer_spec.rb +1 -1
  42. data/spec/lib/pact/{consumer_contract_spec.rb → consumer_contract/consumer_contract_spec.rb} +72 -28
  43. data/spec/lib/pact/{consumer → consumer_contract}/interaction_spec.rb +49 -64
  44. data/spec/lib/pact/{producer/configuration_dsl_spec.rb → provider/dsl_spec.rb} +29 -28
  45. data/spec/lib/pact/{producer/producer_state_spec.rb → provider/provider_state_spec.rb} +17 -17
  46. data/spec/lib/pact/{producer → provider}/rspec_spec.rb +1 -1
  47. data/spec/lib/pact/verification_task_spec.rb +3 -3
  48. data/spec/spec_helper.rb +1 -0
  49. data/spec/support/a_consumer-a_producer.json +1 -1
  50. data/spec/support/a_consumer-a_provider.json +34 -0
  51. data/spec/support/consumer_contract_template.json +26 -0
  52. data/spec/support/factories.rb +78 -0
  53. data/spec/support/pact_rake_support.rb +1 -1
  54. data/spec/support/test_app_fail.json +1 -1
  55. data/spec/support/test_app_pass.json +1 -1
  56. data/tasks/pact-test.rake +3 -3
  57. metadata +38 -45
  58. data/lib/pact/consumer/configuration_dsl.rb +0 -73
  59. data/lib/pact/consumer/interaction.rb +0 -74
  60. data/lib/pact/consumer/run_condor.rb +0 -4
  61. data/lib/pact/consumer/run_mock_contract_service.rb +0 -13
  62. data/lib/pact/consumer/service_consumer.rb +0 -22
  63. data/lib/pact/consumer/service_producer.rb +0 -23
  64. data/lib/pact/producer/configuration_dsl.rb +0 -62
  65. data/lib/pact/producer/rspec.rb +0 -129
@@ -1,73 +0,0 @@
1
- require_relative 'service_consumer'
2
- require_relative 'consumer_contract_builders'
3
- require_relative '../configuration'
4
-
5
- module Pact
6
- module Consumer
7
-
8
-
9
- module Configuration
10
- def add_producer_verification &block
11
- producer_verifications << block
12
- end
13
- def producer_verifications
14
- @producer_verifications ||= []
15
- end
16
- end
17
-
18
- module ConfigurationDSL
19
-
20
- def consumer &block
21
- if block_given?
22
- @consumer = ConsumerDSL.new(&block).create_service_consumer
23
- elsif @consumer
24
- @consumer
25
- else
26
- raise "Please configure a consumer before configuring producers"
27
- end
28
- end
29
-
30
- alias_method :service_consumer, :consumer
31
-
32
- class ConsumerDSL
33
-
34
- def initialize &block
35
- @app = nil
36
- @port = nil
37
- @name = nil
38
- instance_eval(&block)
39
- end
40
-
41
- def validate
42
- raise "Please provide a consumer name" unless @name
43
- raise "Please provide a port for the consumer app" if @app && !@port
44
- end
45
-
46
- def name name
47
- @name = name
48
- end
49
-
50
- def app app
51
- @app = app
52
- end
53
-
54
- def port port
55
- @port = port
56
- end
57
-
58
- def create_service_consumer
59
- validate
60
- register_consumer_app if @app
61
- Pact::Consumer::ServiceConsumer.new name: @name
62
- end
63
-
64
- def register_consumer_app
65
- Pact::Consumer::AppManager.instance.register @app, @port
66
- end
67
- end
68
- end
69
- end
70
- end
71
-
72
- Pact::Configuration.send(:include, Pact::Consumer::ConfigurationDSL)
73
- Pact::Configuration.send(:include, Pact::Consumer::Configuration)
@@ -1,74 +0,0 @@
1
- require 'net/http'
2
- require 'pact/reification'
3
- require 'pact/request'
4
- #require 'json/add/core'
5
-
6
- module Pact
7
- module Consumer
8
-
9
- class Interaction
10
-
11
- attr_accessor :description, :request, :response, :producer_state
12
-
13
- def initialize attributes
14
- @description = attributes[:description]
15
- @request = attributes[:request]
16
- @response = attributes[:response]
17
- @producer_state = attributes[:producer_state]
18
- end
19
-
20
- def self.from_hash hash
21
- new(:description => hash['description'],
22
- :producer_state => hash['producer_state'],
23
- :request => Pact::Request::Expected.from_hash(hash['request']),
24
- :response => hash['response']
25
- )
26
- end
27
-
28
- def as_json
29
- {
30
- :description => @description,
31
- :request => @request.as_json,
32
- :response => @response,
33
- }.tap{ | hash | hash[:producer_state] = @producer_state if @producer_state }
34
- end
35
-
36
- def to_json(options = {})
37
- as_json.to_json(options)
38
- end
39
-
40
- def as_json_for_mock_service
41
- {:response => Reification.from_term(response), :request => @request.as_json_with_options, :description => description }.
42
- tap{ | hash | hash[:producer_state] = @producer_state if @producer_state }
43
- end
44
-
45
- def to_json_for_mock_service
46
- as_json_for_mock_service.to_json
47
- end
48
- end
49
-
50
- class InteractionBuilder
51
-
52
- attr_reader :interaction
53
-
54
- def initialize(description, producer_state)
55
- producer_state = producer_state.nil? ? nil : producer_state.to_s
56
- @interaction = Interaction.new(:description => description, :producer_state => producer_state)
57
- end
58
-
59
- def with(request_details)
60
- interaction.request = Request::Expected.from_hash(request_details)
61
- self
62
- end
63
-
64
- def will_respond_with(response)
65
- interaction.response = response
66
- @callback.call interaction
67
- end
68
-
69
- def on_interaction_fully_defined &block
70
- @callback = block
71
- end
72
- end
73
- end
74
- end
@@ -1,4 +0,0 @@
1
- require_relative 'spawn_app'
2
- require_relative '../../../boot'
3
-
4
- spawn_app CondorAppAssets.new, APP_PORT
@@ -1,13 +0,0 @@
1
- require 'net/http'
2
- require_relative 'spawn_app'
3
- require_relative 'mock_service'
4
-
5
- spawn_app MockService.new, 1234
6
-
7
- RSpec.configure do |c|
8
- c.before(:each, :type => :feature) do
9
- http = Net::HTTP.new('localhost', 1234)
10
- request = Net::HTTP::Delete.new('/interactions')
11
- response = http.request(request)
12
- end
13
- end
@@ -1,22 +0,0 @@
1
- module Pact
2
- module Consumer
3
- class ServiceConsumer
4
- attr_accessor :name
5
- def initialize options
6
- @name = options[:name]
7
- end
8
-
9
- def to_s
10
- name
11
- end
12
-
13
- def as_json options = {}
14
- {name: name}
15
- end
16
-
17
- def self.from_hash obj
18
- ServiceConsumer.new(:name => obj['name'])
19
- end
20
- end
21
- end
22
- end
@@ -1,23 +0,0 @@
1
- module Pact
2
- module Consumer
3
- # This is a crap name, it's really just a object for serializing to JSON
4
- class ServiceProducer
5
- attr_accessor :name
6
- def initialize options
7
- @name = options[:name] || '[producer name unknown - please update the pact gem in the consumer project to the latest version and regenerate the pacts]'
8
- end
9
-
10
- def to_s
11
- name
12
- end
13
-
14
- def as_json options = {}
15
- {name: name}
16
- end
17
-
18
- def self.from_hash obj
19
- ServiceProducer.new(:name => obj['name'])
20
- end
21
- end
22
- end
23
- end
@@ -1,62 +0,0 @@
1
- require 'ostruct'
2
-
3
-
4
- module Pact
5
- module Producer
6
- module ConfigurationDSL
7
-
8
- def producer &block
9
- @producer ||= nil
10
- if block_given?
11
- @producer = ProducerDSL.new(&block).create_producer_config
12
- elsif @producer
13
- @producer
14
- else
15
- raise "Please configure your producer. See the Producer section in the README for examples."
16
- end
17
- end
18
-
19
- class ProducerConfig
20
- attr_accessor :name
21
-
22
- def initialize name, &app_block
23
- @name = name
24
- @app_block = app_block
25
- end
26
-
27
- def app
28
- @app_block.call
29
- end
30
- end
31
-
32
- class ProducerDSL
33
-
34
- def initialize &block
35
- @app = nil
36
- @name = nil
37
- instance_eval(&block)
38
- end
39
-
40
- def validate
41
- raise "Please provide a name for the Producer" unless @name
42
- raise "Please configure an app for the Producer" unless @app_block
43
- end
44
-
45
- def name name
46
- @name = name
47
- end
48
-
49
- def app &block
50
- @app_block = block
51
- end
52
-
53
- def create_producer_config
54
- validate
55
- ProducerConfig.new(@name, &@app_block)
56
- end
57
- end
58
- end
59
- end
60
- end
61
-
62
- Pact::Configuration.send(:include, Pact::Producer::ConfigurationDSL)
@@ -1,129 +0,0 @@
1
- require 'open-uri'
2
- require 'pact/consumer_contract'
3
- require 'pact/json_warning'
4
- require_relative 'matchers'
5
- require_relative 'test_methods'
6
- require_relative 'configuration_dsl'
7
- require_relative 'dsl'
8
-
9
- module Pact
10
- module Producer
11
- module RSpec
12
-
13
- module InstanceMethods
14
- def app
15
- Pact.configuration.producer.app
16
- end
17
- end
18
-
19
- module ClassMethods
20
-
21
- include Pact::JsonWarning
22
-
23
- def honour_pactfile pactfile_uri, options = {}
24
- describe "Pact in #{pactfile_uri}" do
25
- consumer_contract = Pact::ConsumerContract.from_json(read_pact_from(pactfile_uri, options))
26
- honour_consumer_contract consumer_contract, options
27
- end
28
- end
29
-
30
- def honour_consumer_contract consumer_contract, options = {}
31
- check_for_active_support_json
32
- describe_consumer_contract consumer_contract, options.merge({:consumer => consumer_contract.consumer.name})
33
- end
34
-
35
- private
36
-
37
- def describe_consumer_contract consumer_contract, options
38
- consumer_contract.interactions.each do |interaction|
39
- describe_interaction_with_producer_state interaction, options
40
- end
41
- end
42
-
43
- def describe_interaction_with_producer_state interaction, options
44
- if interaction.producer_state
45
- describe "Given #{interaction.producer_state}" do
46
- describe_interaction interaction, options
47
- end
48
- else
49
- describe_interaction interaction, options
50
- end
51
- end
52
-
53
- def describe_interaction interaction, options
54
-
55
- describe description_for(interaction) do
56
-
57
- before do
58
- set_up_producer_state interaction.producer_state, options[:consumer]
59
- replay_interaction interaction
60
- end
61
-
62
- after do
63
- tear_down_producer_state interaction.producer_state, options[:consumer]
64
- end
65
-
66
- describe_response interaction.response
67
- end
68
-
69
- end
70
-
71
- def describe_response response
72
- describe "returns a response which" do
73
- if response['status']
74
- it "has status code #{response['status']}" do
75
- expect(last_response.status).to eql response['status']
76
- end
77
- end
78
-
79
- if response['headers']
80
- describe "includes headers" do
81
- response['headers'].each do |name, value|
82
- it "\"#{name}\" with value \"#{value}\"" do
83
- expect(last_response.headers[name]).to match_term value
84
- end
85
- end
86
- end
87
- end
88
-
89
- if response['body']
90
- it "has a matching body" do
91
- logger.debug "Response body is #{last_response.body}"
92
- expect(parse_entity_from_response(last_response)).to match_term response['body']
93
- end
94
- end
95
- end
96
- end
97
-
98
- def description_for interaction
99
- "#{interaction.description} to #{interaction.request.path}"
100
- end
101
-
102
- def read_pact_from uri, options = {}
103
- pact = open(uri) { | file | file.read }
104
- if options[:save_pactfile_to_tmp]
105
- save_pactfile_to_tmp pact, File.basename(uri)
106
- end
107
- pact
108
- rescue StandardError => e
109
- $stderr.puts "Error reading file from #{uri}"
110
- $stderr.puts "#{e.to_s} #{e.backtrace.join("\n")}"
111
- raise e
112
- end
113
-
114
- def save_pactfile_to_tmp pact, name
115
- FileUtils.mkdir_p Pact.configuration.tmp_dir
116
- File.open(Pact.configuration.tmp_dir + "/#{name}", "w") { |file| file << pact}
117
- end
118
-
119
- end
120
- end
121
- end
122
- end
123
-
124
- RSpec.configure do |config|
125
- config.extend Pact::Producer::RSpec::ClassMethods
126
- config.include Pact::Producer::RSpec::InstanceMethods
127
- config.include Pact::Producer::TestMethods
128
- config.include Pact::Producer::TestMethods
129
- end