workable-pact-message 0.6.2
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.
- checksums.yaml +7 -0
- data/.gitignore +14 -0
- data/.rspec +3 -0
- data/.travis.yml +12 -0
- data/CHANGELOG.md +88 -0
- data/CONTRIBUTING.md +1 -0
- data/DEVELOPER_DOCUMENTATION.md +33 -0
- data/Gemfile +11 -0
- data/LICENSE.txt +21 -0
- data/QUESTIONS.md +3 -0
- data/README.md +41 -0
- data/Rakefile +8 -0
- data/bin/pact-message +3 -0
- data/bin/setup +8 -0
- data/lib/pact/consumer_contract/message.rb +142 -0
- data/lib/pact/consumer_contract/message/contents.rb +49 -0
- data/lib/pact/message.rb +4 -0
- data/lib/pact/message/cli.rb +34 -0
- data/lib/pact/message/consumer/configuration.rb +4 -0
- data/lib/pact/message/consumer/configuration/configuration_extensions.rb +19 -0
- data/lib/pact/message/consumer/configuration/message_builder.rb +67 -0
- data/lib/pact/message/consumer/configuration/message_consumer.rb +38 -0
- data/lib/pact/message/consumer/configuration/message_provider.rb +39 -0
- data/lib/pact/message/consumer/consumer_contract_builder.rb +59 -0
- data/lib/pact/message/consumer/consumer_contract_builders.rb +12 -0
- data/lib/pact/message/consumer/consumer_contract_decorator.rb +25 -0
- data/lib/pact/message/consumer/dsl.rb +13 -0
- data/lib/pact/message/consumer/interaction_builder.rb +38 -0
- data/lib/pact/message/consumer/interaction_decorator.rb +56 -0
- data/lib/pact/message/consumer/rspec.rb +26 -0
- data/lib/pact/message/consumer/spec_hooks.rb +13 -0
- data/lib/pact/message/consumer/update_pact.rb +43 -0
- data/lib/pact/message/consumer_contract_parser.rb +38 -0
- data/lib/pact/message/version.rb +5 -0
- data/pact-message.gemspec +45 -0
- data/script/release.sh +13 -0
- data/script/update-pact.sh +15 -0
- data/tasks/release.rake +15 -0
- metadata +209 -0
data/lib/pact/message.rb
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
require 'thor'
|
2
|
+
|
3
|
+
module Pact
|
4
|
+
module Message
|
5
|
+
class CLI < Thor
|
6
|
+
|
7
|
+
method_option :consumer, required: true, desc: "The Consumer name"
|
8
|
+
method_option :provider, required: true, desc: "The Provider name"
|
9
|
+
method_option :pact_dir, required: true, desc: "The Pact directory"
|
10
|
+
method_option :pact_specification_version, required: false, default: "2.0.0", desc: "The Pact Specification version"
|
11
|
+
|
12
|
+
desc 'update MESSAGE_JSON', 'Update a pact with the given message, or create the pact if it does not exist. The MESSAGE_JSON may be in the legacy Ruby JSON format or the v2+ format.'
|
13
|
+
def update(message)
|
14
|
+
require 'pact/message'
|
15
|
+
require 'pact/message/consumer/update_pact'
|
16
|
+
pact_specification_version = Pact::SpecificationVersion.new(options.pact_specification_version)
|
17
|
+
message = Pact::Message.from_hash(JSON.load(message), { pact_specification_version: pact_specification_version })
|
18
|
+
Pact::Message::Consumer::UpdatePact.call(message, options.pact_dir, options.consumer, options.provider, options.pact_specification_version)
|
19
|
+
end
|
20
|
+
|
21
|
+
desc 'reify', "Take a JSON document with embedded pact matchers and return a concrete example"
|
22
|
+
def reify(json)
|
23
|
+
require 'pact/support'
|
24
|
+
puts Pact::Reification.from_term(JSON.load(json)).to_json
|
25
|
+
end
|
26
|
+
|
27
|
+
desc 'version', "Show the pact-message gem version"
|
28
|
+
def version
|
29
|
+
require 'pact/message/version.rb'
|
30
|
+
puts Pact::Message::VERSION
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'pact/configuration'
|
2
|
+
|
3
|
+
module Pact
|
4
|
+
module Message
|
5
|
+
module Consumer
|
6
|
+
module Configuration
|
7
|
+
module ConfigurationExtensions
|
8
|
+
def add_message_provider_verification &block
|
9
|
+
message_provider_verifications << block
|
10
|
+
end
|
11
|
+
|
12
|
+
def message_provider_verifications
|
13
|
+
@message_provider_verifications ||= []
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
require 'pact/message/consumer/consumer_contract_builder'
|
2
|
+
require 'pact/message/consumer/consumer_contract_builders'
|
3
|
+
# require 'pact/consumer/world'
|
4
|
+
|
5
|
+
module Pact
|
6
|
+
module Message
|
7
|
+
module Consumer
|
8
|
+
module Configuration
|
9
|
+
class MessageBuilder
|
10
|
+
|
11
|
+
extend Pact::DSL
|
12
|
+
|
13
|
+
attr_accessor :provider_name, :consumer_name, :pact_specification_version
|
14
|
+
|
15
|
+
def initialize name, consumer_name, provider_name
|
16
|
+
@name = name
|
17
|
+
@consumer_name = consumer_name
|
18
|
+
@provider_name = provider_name
|
19
|
+
@pact_specification_version = nil
|
20
|
+
end
|
21
|
+
|
22
|
+
dsl do
|
23
|
+
def pact_specification_version pact_specification_version
|
24
|
+
self.pact_specification_version = pact_specification_version
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def finalize
|
29
|
+
configure_consumer_contract_builder
|
30
|
+
end
|
31
|
+
|
32
|
+
private
|
33
|
+
|
34
|
+
def configure_consumer_contract_builder
|
35
|
+
consumer_contract_builder = create_consumer_contract_builder
|
36
|
+
create_consumer_contract_builders_method consumer_contract_builder
|
37
|
+
setup_verification(consumer_contract_builder)
|
38
|
+
consumer_contract_builder
|
39
|
+
end
|
40
|
+
|
41
|
+
def create_consumer_contract_builder
|
42
|
+
consumer_contract_builder_fields = {
|
43
|
+
:consumer_name => consumer_name,
|
44
|
+
:provider_name => provider_name,
|
45
|
+
}
|
46
|
+
# :pactfile_write_mode => Pact.configuration.pactfile_write_mode,
|
47
|
+
# :pact_dir => Pact.configuration.pact_dir
|
48
|
+
Pact::Message::Consumer::ConsumerContractBuilder.new consumer_contract_builder_fields
|
49
|
+
end
|
50
|
+
|
51
|
+
def setup_verification consumer_contract_builder
|
52
|
+
Pact.configuration.add_message_provider_verification do | example_description |
|
53
|
+
consumer_contract_builder.verify example_description
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
def create_consumer_contract_builders_method consumer_contract_builder
|
58
|
+
Pact::Message::Consumer::ConsumerContractBuilders.send(:define_method, @name.to_sym) do
|
59
|
+
consumer_contract_builder
|
60
|
+
end
|
61
|
+
# Pact.consumer_world.add_consumer_contract_builder consumer_contract_builder
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
require 'pact/shared/dsl'
|
2
|
+
require 'pact/message/consumer/configuration/message_provider'
|
3
|
+
|
4
|
+
module Pact
|
5
|
+
module Message
|
6
|
+
module Consumer
|
7
|
+
module Configuration
|
8
|
+
class MessageConsumer
|
9
|
+
|
10
|
+
extend Pact::DSL
|
11
|
+
|
12
|
+
attr_accessor :builder, :name
|
13
|
+
|
14
|
+
def initialize name
|
15
|
+
@name = name
|
16
|
+
end
|
17
|
+
|
18
|
+
dsl do
|
19
|
+
def has_pact_with message_provider_name, &block
|
20
|
+
MessageProvider.build(message_provider_name, self.name, &block)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def finalize
|
25
|
+
validate
|
26
|
+
register_consumer_app if @app
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
|
31
|
+
def validate
|
32
|
+
raise "Please provide a consumer name" unless (name && !name.empty?)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require 'pact/shared/dsl'
|
2
|
+
require 'pact/message/consumer/configuration/message_builder'
|
3
|
+
|
4
|
+
module Pact
|
5
|
+
module Message
|
6
|
+
module Consumer
|
7
|
+
module Configuration
|
8
|
+
class MessageProvider
|
9
|
+
|
10
|
+
extend Pact::DSL
|
11
|
+
|
12
|
+
attr_accessor :builder, :consumer_name, :name
|
13
|
+
|
14
|
+
def initialize name, consumer_name
|
15
|
+
@name = name
|
16
|
+
@builder = nil
|
17
|
+
@consumer_name = consumer_name
|
18
|
+
end
|
19
|
+
|
20
|
+
dsl do
|
21
|
+
def builder builder_name, &block
|
22
|
+
self.builder = MessageBuilder.build(builder_name, consumer_name, name, &block)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def finalize
|
27
|
+
validate
|
28
|
+
end
|
29
|
+
|
30
|
+
private
|
31
|
+
|
32
|
+
def validate
|
33
|
+
raise "Please configure a name for the message provider" unless name
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
require 'pact/message/consumer/interaction_builder'
|
2
|
+
require 'pact/message/consumer/update_pact'
|
3
|
+
|
4
|
+
module Pact
|
5
|
+
module Message
|
6
|
+
module Consumer
|
7
|
+
class ConsumerContractBuilder
|
8
|
+
|
9
|
+
def initialize(attributes)
|
10
|
+
@interaction_builder = nil
|
11
|
+
@consumer_name = attributes[:consumer_name]
|
12
|
+
@provider_name = attributes[:provider_name]
|
13
|
+
@interactions = []
|
14
|
+
end
|
15
|
+
|
16
|
+
def given(provider_state)
|
17
|
+
interaction_builder.given(provider_state)
|
18
|
+
end
|
19
|
+
|
20
|
+
def is_expected_to_send(description)
|
21
|
+
interaction_builder.is_expected_to_send(provider_state)
|
22
|
+
end
|
23
|
+
|
24
|
+
def send_message
|
25
|
+
# TODO handle matchers
|
26
|
+
yield @contents_string if block_given?
|
27
|
+
end
|
28
|
+
|
29
|
+
def handle_interaction_fully_defined(interaction)
|
30
|
+
@contents_string = interaction.contents.to_s
|
31
|
+
@interactions << interaction
|
32
|
+
@interaction_builder = nil
|
33
|
+
# TODO pull these from pact config
|
34
|
+
Pact::Message::Consumer::UpdatePact.call(interaction, "./spec/pacts", consumer_name, provider_name, "2.0.0")
|
35
|
+
end
|
36
|
+
|
37
|
+
def verify example_description
|
38
|
+
#
|
39
|
+
# TODO check that message was actually yielded
|
40
|
+
end
|
41
|
+
|
42
|
+
private
|
43
|
+
|
44
|
+
attr_writer :interaction_builder
|
45
|
+
attr_accessor :consumer_name, :provider_name, :consumer_contract_details
|
46
|
+
|
47
|
+
def interaction_builder
|
48
|
+
@interaction_builder ||=
|
49
|
+
begin
|
50
|
+
interaction_builder = InteractionBuilder.new do | interaction |
|
51
|
+
handle_interaction_fully_defined(interaction)
|
52
|
+
end
|
53
|
+
interaction_builder
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'pact/consumer_contract/consumer_contract_decorator'
|
2
|
+
require 'pact/message/consumer/interaction_decorator'
|
3
|
+
|
4
|
+
module Pact
|
5
|
+
module Message
|
6
|
+
module Consumer
|
7
|
+
class ConsumerContractDecorator < Pact::ConsumerContractDecorator
|
8
|
+
|
9
|
+
|
10
|
+
def as_json(options = {})
|
11
|
+
fix_all_the_things(
|
12
|
+
consumer: consumer_contract.consumer.as_json,
|
13
|
+
provider: consumer_contract.provider.as_json,
|
14
|
+
messages: sorted_interactions.collect{ |i| InteractionDecorator.new(i, @decorator_options).as_json},
|
15
|
+
metadata: {
|
16
|
+
pactSpecification: {
|
17
|
+
version: pact_specification_version
|
18
|
+
}
|
19
|
+
}
|
20
|
+
)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
require 'pact/reification'
|
2
|
+
|
3
|
+
module Pact
|
4
|
+
module Message
|
5
|
+
module Consumer
|
6
|
+
class InteractionBuilder
|
7
|
+
|
8
|
+
attr_reader :interaction
|
9
|
+
|
10
|
+
def initialize &block
|
11
|
+
@interaction = Pact::Message.new
|
12
|
+
@callback = block
|
13
|
+
end
|
14
|
+
|
15
|
+
def is_expected_to_send description
|
16
|
+
@interaction.description = description
|
17
|
+
self
|
18
|
+
end
|
19
|
+
|
20
|
+
def given provider_state
|
21
|
+
@interaction.provider_state = provider_state.nil? ? nil : provider_state.to_s
|
22
|
+
self
|
23
|
+
end
|
24
|
+
|
25
|
+
def with_metadata(object)
|
26
|
+
# TODO implement this
|
27
|
+
self
|
28
|
+
end
|
29
|
+
|
30
|
+
def with_content(object)
|
31
|
+
interaction.contents = Pact::Message::Contents.from_hash(object)
|
32
|
+
@callback.call interaction
|
33
|
+
self
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
require 'pact/shared/active_support_support'
|
2
|
+
|
3
|
+
module Pact
|
4
|
+
module Message
|
5
|
+
module Consumer
|
6
|
+
class InteractionDecorator
|
7
|
+
|
8
|
+
include ActiveSupportSupport
|
9
|
+
|
10
|
+
def initialize message, decorator_options = {}
|
11
|
+
@message = message
|
12
|
+
@decorator_options = decorator_options
|
13
|
+
end
|
14
|
+
|
15
|
+
def as_json options = {}
|
16
|
+
hash = { :description => message.description }
|
17
|
+
hash[:providerStates] = provider_states
|
18
|
+
hash[:contents] = extract_contents
|
19
|
+
hash[:matchingRules] = extract_matching_rules
|
20
|
+
hash[:metaData] = message.metadata || {}
|
21
|
+
fix_all_the_things hash
|
22
|
+
end
|
23
|
+
|
24
|
+
def to_json(options = {})
|
25
|
+
as_json(options).to_json(options)
|
26
|
+
end
|
27
|
+
|
28
|
+
private
|
29
|
+
|
30
|
+
attr_reader :message
|
31
|
+
|
32
|
+
def decorate_contents
|
33
|
+
message.contents.as_json
|
34
|
+
end
|
35
|
+
|
36
|
+
def extract_contents
|
37
|
+
Pact::Reification.from_term(message.contents.contents)
|
38
|
+
end
|
39
|
+
|
40
|
+
def provider_states
|
41
|
+
message.provider_states.collect(&:as_json)
|
42
|
+
end
|
43
|
+
|
44
|
+
def extract_matching_rules
|
45
|
+
{
|
46
|
+
body: Pact::MatchingRules.extract(message.contents.contents, pact_specification_version: pact_specification_version)
|
47
|
+
}
|
48
|
+
end
|
49
|
+
|
50
|
+
def pact_specification_version
|
51
|
+
Pact::SpecificationVersion.new(@decorator_options[:pact_specification_version])
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'rspec'
|
2
|
+
require 'pact/rspec'
|
3
|
+
require 'pact/message/consumer/consumer_contract_builders'
|
4
|
+
require 'pact/message/consumer/spec_hooks'
|
5
|
+
require 'pact/helpers'
|
6
|
+
|
7
|
+
module Pact
|
8
|
+
module Message
|
9
|
+
module Consumer
|
10
|
+
module RSpec
|
11
|
+
include Pact::Message::Consumer::ConsumerContractBuilders
|
12
|
+
include Pact::Helpers
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
hooks = Pact::Message::Consumer::SpecHooks.new
|
19
|
+
|
20
|
+
RSpec.configure do |config|
|
21
|
+
config.include Pact::Message::Consumer::RSpec, :pact => :message
|
22
|
+
|
23
|
+
config.after :each, :pact => true do | example |
|
24
|
+
hooks.after_each Pact::RSpec.full_description(example)
|
25
|
+
end
|
26
|
+
end
|