pact-message 0.7.0 → 0.11.1
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 +4 -4
- data/.github/workflows/release_gem.yml +45 -0
- data/.github/workflows/test.yml +23 -0
- data/.gitignore +1 -0
- data/CHANGELOG.md +43 -0
- data/README.md +51 -1
- data/lib/pact/consumer_contract/message.rb +1 -1
- data/lib/pact/consumer_contract/message/contents.rb +16 -3
- data/lib/pact/message/cli.rb +21 -5
- data/lib/pact/message/consumer/configuration/message_builder.rb +7 -6
- data/lib/pact/message/consumer/configuration/message_provider.rb +5 -1
- data/lib/pact/message/consumer/consumer_contract_builder.rb +55 -14
- data/lib/pact/message/consumer/interaction_builder.rb +7 -3
- data/lib/pact/message/consumer/interaction_decorator.rb +11 -4
- data/lib/pact/message/consumer/rspec.rb +9 -1
- data/lib/pact/message/consumer/spec_hooks.rb +13 -0
- data/lib/pact/message/consumer/world.rb +36 -0
- data/lib/pact/message/consumer/{update_pact.rb → write_pact.rb} +11 -10
- data/lib/pact/message/version.rb +1 -1
- data/lib/pact/pact-message.rb +1 -0
- data/pact-message.gemspec +2 -3
- data/script/trigger-release.sh +30 -0
- data/tasks/test.rake +60 -0
- metadata +25 -23
- data/.travis.yml +0 -33
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8ce8daa35756cfc3bf55b364cc91d123ab92be909f37d56fa237bcdb2a4051b2
|
4
|
+
data.tar.gz: d404290cbd697430bc277ef2298e37f17ab8c2770b999d0824cde92f8eafd306
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6b5a5052f06c36a369453082962d74c893ca7a235efbfae622c7fa64b3f156267db773708e3ae0d783cbe39d7d620e97f7ad70f7a728aa7d4322ab11cd148f35
|
7
|
+
data.tar.gz: 551b8239e8bc1374405acfcee1f4dee500df58bd4a6f63bccee2f85fe5231ba680a4df4113685e1e8c30ff4b52cca8ba210d9032399d9ad0dc2c8553e5e7eed8
|
@@ -0,0 +1,45 @@
|
|
1
|
+
---
|
2
|
+
name: "Release gem"
|
3
|
+
|
4
|
+
on:
|
5
|
+
repository_dispatch:
|
6
|
+
types:
|
7
|
+
- release-triggered
|
8
|
+
|
9
|
+
jobs:
|
10
|
+
release:
|
11
|
+
runs-on: ubuntu-latest
|
12
|
+
steps:
|
13
|
+
- uses: actions/checkout@v2
|
14
|
+
with:
|
15
|
+
fetch-depth: 0
|
16
|
+
- id: release-gem
|
17
|
+
uses: pact-foundation/release-gem@v0.0.11
|
18
|
+
env:
|
19
|
+
GEM_HOST_API_KEY: "${{ secrets.RUBYGEMS_API_KEY }}"
|
20
|
+
GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}"
|
21
|
+
INCREMENT: "${{ github.event.client_payload.increment }}"
|
22
|
+
outputs:
|
23
|
+
gem_name: "${{ steps.release-gem.outputs.gem_name }}"
|
24
|
+
version: "${{ steps.release-gem.outputs.version }}"
|
25
|
+
increment: "${{ steps.release-gem.outputs.increment }}"
|
26
|
+
|
27
|
+
notify-gem-released:
|
28
|
+
needs: release
|
29
|
+
strategy:
|
30
|
+
matrix:
|
31
|
+
repository: [pact-foundation/pact-ruby-cli, pact-foundation/pact-ruby-standalone]
|
32
|
+
runs-on: ubuntu-latest
|
33
|
+
steps:
|
34
|
+
- name: Notify ${{ matrix.repository }} of gem release
|
35
|
+
uses: peter-evans/repository-dispatch@v1
|
36
|
+
with:
|
37
|
+
token: ${{ secrets.GHTOKENFORPACTCLIRELEASE }}
|
38
|
+
repository: ${{ matrix.repository }}
|
39
|
+
event-type: gem-released
|
40
|
+
client-payload: |
|
41
|
+
{
|
42
|
+
"name": "${{ needs.release.outputs.gem_name }}",
|
43
|
+
"version": "${{ needs.release.outputs.version }}",
|
44
|
+
"increment": "${{ needs.release.outputs.increment }}"
|
45
|
+
}
|
@@ -0,0 +1,23 @@
|
|
1
|
+
name: Test
|
2
|
+
|
3
|
+
on: [push, pull_request]
|
4
|
+
|
5
|
+
jobs:
|
6
|
+
test:
|
7
|
+
runs-on: "ubuntu-latest"
|
8
|
+
continue-on-error: ${{ matrix.experimental }}
|
9
|
+
strategy:
|
10
|
+
fail-fast: false
|
11
|
+
matrix:
|
12
|
+
ruby_version: ["2.2", "2.7"]
|
13
|
+
experimental: [false]
|
14
|
+
include:
|
15
|
+
- ruby_version: "3.0"
|
16
|
+
experimental: true
|
17
|
+
steps:
|
18
|
+
- uses: actions/checkout@v2
|
19
|
+
- uses: ruby/setup-ruby@v1
|
20
|
+
with:
|
21
|
+
ruby-version: ${{ matrix.ruby_version }}
|
22
|
+
- run: "bundle install"
|
23
|
+
- run: "bundle exec rake"
|
data/.gitignore
CHANGED
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,46 @@
|
|
1
|
+
<a name="v0.11.1"></a>
|
2
|
+
### v0.11.1 (2021-04-20)
|
3
|
+
|
4
|
+
#### Bug Fixes
|
5
|
+
|
6
|
+
* JSON load message document so that the Ruby objects are created properly ([2bab66c](/../../commit/2bab66c))
|
7
|
+
|
8
|
+
<a name="v0.11.0"></a>
|
9
|
+
### v0.11.0 (2021-03-22)
|
10
|
+
|
11
|
+
#### Features
|
12
|
+
|
13
|
+
* update thor dependancy ([87a5f64](/../../commit/87a5f64))
|
14
|
+
|
15
|
+
<a name="v0.10.0"></a>
|
16
|
+
### v0.10.0 (2021-01-22)
|
17
|
+
|
18
|
+
#### Features
|
19
|
+
|
20
|
+
* allow pact-message update to receive JSON via the standard input ([5cbb664](/../../commit/5cbb664))
|
21
|
+
|
22
|
+
<a name="v0.9.0"></a>
|
23
|
+
### v0.9.0 (2020-11-04)
|
24
|
+
|
25
|
+
#### Features
|
26
|
+
|
27
|
+
* allow pact dir to be configured ([f2f9626](/../../commit/f2f9626))
|
28
|
+
* verify that each message has been yielded ([1d4d92c](/../../commit/1d4d92c))
|
29
|
+
|
30
|
+
* **consumer**
|
31
|
+
* only update pact if test suite passes ([e99276d](/../../commit/e99276d))
|
32
|
+
|
33
|
+
<a name="v0.8.0"></a>
|
34
|
+
### v0.8.0 (2020-09-28)
|
35
|
+
|
36
|
+
#### Features
|
37
|
+
|
38
|
+
* reify message when yielding ([d7c0a4a](/../../commit/d7c0a4a))
|
39
|
+
|
40
|
+
#### Bug Fixes
|
41
|
+
|
42
|
+
* fix bug in Message.to_hash ([e354cd2](/../../commit/e354cd2))
|
43
|
+
|
1
44
|
<a name="v0.7.0"></a>
|
2
45
|
### v0.7.0 (2020-02-10)
|
3
46
|
|
data/README.md
CHANGED
@@ -31,6 +31,7 @@ The key to using Message Pact is to completely separate the business logic that
|
|
31
31
|
### Consumer
|
32
32
|
|
33
33
|
Not finished yet as nobody has asked for it. Ping @Beth Skurrie on slack.pact.io if you'd like use this.
|
34
|
+
Update: Done but not documented yet. See https://github.com/pact-foundation/pact-message-ruby/blob/master/spec/features/create_message_pact_spec.rb#L78 for an example.
|
34
35
|
|
35
36
|
### Provider
|
36
37
|
|
@@ -94,7 +95,56 @@ Provider states work the same way for Message Pact as they do for HTTP Pact. Ple
|
|
94
95
|
|
95
96
|
## Development
|
96
97
|
|
97
|
-
|
98
|
+
### Setup
|
99
|
+
|
100
|
+
After checking out the repo, run the following to install dependencies.
|
101
|
+
|
102
|
+
```bash
|
103
|
+
$ bundle exec bin/setup
|
104
|
+
|
105
|
+
bundle install
|
106
|
+
\+ bundle install
|
107
|
+
...
|
108
|
+
Bundle complete! 6 Gemfile dependencies, 29 gems now installed.
|
109
|
+
Use `bundle info [gemname]` to see where a bundled gem is installed.
|
110
|
+
|
111
|
+
Do any other automated setup that you need to do here
|
112
|
+
```
|
113
|
+
|
114
|
+
### Tests
|
115
|
+
|
116
|
+
Run the following command to run the tests.
|
117
|
+
|
118
|
+
```bash
|
119
|
+
$ bundle exec rake spec
|
120
|
+
|
121
|
+
the CLI
|
122
|
+
creates a pact file with the given message
|
123
|
+
creates a pact file with a message from the standard input
|
124
|
+
...
|
125
|
+
Finished in 0.50883 seconds (files took 0.15053 seconds to load)
|
126
|
+
26 examples, 0 failures, 2 pending
|
127
|
+
```
|
128
|
+
|
129
|
+
### Interactive Prompt
|
130
|
+
|
131
|
+
You can run the following command for an for an interactive prompt that will allow you to experiment.
|
132
|
+
|
133
|
+
```bash
|
134
|
+
$ bundle exec bin/console
|
135
|
+
2.6.6 :001 >
|
136
|
+
```
|
137
|
+
|
138
|
+
To execute commands on the CLI run the following command followed by command line arguments as you would with the published version.
|
139
|
+
|
140
|
+
```bash
|
141
|
+
$ bundle exec bin/pact-message
|
142
|
+
Commands:
|
143
|
+
pact-message help [COMMAND] # Describe available commands or one specific command
|
144
|
+
pact-message reify # Take a JSON document with embedded pact matchers and return...
|
145
|
+
pact-message update MESSAGE_JSON --consumer=CONSUMER --pact-dir=PACT_DIR --provider=PROVIDER # Update/create a pact. If MESSAGE_JSON is omitted or '-', it...
|
146
|
+
pact-message version # Show the pact-message gem version
|
147
|
+
```
|
98
148
|
|
99
149
|
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
100
150
|
|
@@ -1,3 +1,4 @@
|
|
1
|
+
require 'pact/reification'
|
1
2
|
module Pact
|
2
3
|
class ConsumerContract
|
3
4
|
class Message
|
@@ -15,13 +16,25 @@ module Pact
|
|
15
16
|
end
|
16
17
|
|
17
18
|
def to_s
|
18
|
-
if
|
19
|
-
|
19
|
+
if contents.is_a?(Hash) || contents.is_a?(Array)
|
20
|
+
contents.to_json
|
20
21
|
else
|
21
|
-
|
22
|
+
contents.to_s
|
22
23
|
end
|
23
24
|
end
|
24
25
|
|
26
|
+
def reified_contents_string
|
27
|
+
if contents.is_a?(Hash) || contents.is_a?(Array)
|
28
|
+
Pact::Reification.from_term(contents).to_json
|
29
|
+
else
|
30
|
+
Pact::Reification.from_term(contents).to_s
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def reified_contents_hash
|
35
|
+
Pact::Reification.from_term(contents)
|
36
|
+
end
|
37
|
+
|
25
38
|
def contents
|
26
39
|
@contents
|
27
40
|
end
|
data/lib/pact/message/cli.rb
CHANGED
@@ -9,13 +9,23 @@ module Pact
|
|
9
9
|
method_option :pact_dir, required: true, desc: "The Pact directory"
|
10
10
|
method_option :pact_specification_version, required: false, default: "2.0.0", desc: "The Pact Specification version"
|
11
11
|
|
12
|
-
|
13
|
-
|
12
|
+
# Update a pact with the given message, or create the pact if it does not exist
|
13
|
+
desc 'update MESSAGE_JSON', "Update/create a pact. If MESSAGE_JSON is omitted or '-', it is read from stdin"
|
14
|
+
long_desc <<-MSG, wrapping: false
|
15
|
+
Update a pact with the given message, or create the pact if it does not exist.
|
16
|
+
The MESSAGE_JSON may be in the legacy Ruby JSON format or the v2+ format.
|
17
|
+
If MESSAGE_JSON is not provided or is '-', the content will be read from
|
18
|
+
standard input.
|
19
|
+
MSG
|
20
|
+
def update(maybe_json = '-')
|
14
21
|
require 'pact/message'
|
15
|
-
require 'pact/message/consumer/
|
22
|
+
require 'pact/message/consumer/write_pact'
|
23
|
+
|
24
|
+
message_object = JSON.load(maybe_json == '-' ? $stdin.read : maybe_json)
|
25
|
+
|
16
26
|
pact_specification_version = Pact::SpecificationVersion.new(options.pact_specification_version)
|
17
|
-
|
18
|
-
Pact::Message::Consumer::
|
27
|
+
message_hash = Pact::Message.from_hash(message_object, { pact_specification_version: pact_specification_version })
|
28
|
+
Pact::Message::Consumer::WritePact.call(message_hash, options.pact_dir, options.consumer, options.provider, options.pact_specification_version, :update)
|
19
29
|
end
|
20
30
|
|
21
31
|
desc 'reify', "Take a JSON document with embedded pact matchers and return a concrete example"
|
@@ -29,6 +39,12 @@ module Pact
|
|
29
39
|
require 'pact/message/version.rb'
|
30
40
|
puts Pact::Message::VERSION
|
31
41
|
end
|
42
|
+
|
43
|
+
no_commands do
|
44
|
+
def self.exit_on_failure?
|
45
|
+
true
|
46
|
+
end
|
47
|
+
end
|
32
48
|
end
|
33
49
|
end
|
34
50
|
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
require 'pact/message/consumer/consumer_contract_builder'
|
2
2
|
require 'pact/message/consumer/consumer_contract_builders'
|
3
|
-
|
3
|
+
require 'pact/message/consumer/world'
|
4
4
|
|
5
5
|
module Pact
|
6
6
|
module Message
|
@@ -40,11 +40,11 @@ module Pact
|
|
40
40
|
|
41
41
|
def create_consumer_contract_builder
|
42
42
|
consumer_contract_builder_fields = {
|
43
|
-
:
|
44
|
-
:
|
43
|
+
consumer_name: consumer_name,
|
44
|
+
provider_name: provider_name,
|
45
|
+
pact_specification_version: pact_specification_version,
|
46
|
+
pact_dir: Pact.configuration.pact_dir
|
45
47
|
}
|
46
|
-
# :pactfile_write_mode => Pact.configuration.pactfile_write_mode,
|
47
|
-
# :pact_dir => Pact.configuration.pact_dir
|
48
48
|
Pact::Message::Consumer::ConsumerContractBuilder.new consumer_contract_builder_fields
|
49
49
|
end
|
50
50
|
|
@@ -58,7 +58,8 @@ module Pact
|
|
58
58
|
Pact::Message::Consumer::ConsumerContractBuilders.send(:define_method, @name.to_sym) do
|
59
59
|
consumer_contract_builder
|
60
60
|
end
|
61
|
-
|
61
|
+
|
62
|
+
Pact::Message.consumer_world.add_consumer_contract_builder consumer_contract_builder
|
62
63
|
end
|
63
64
|
end
|
64
65
|
end
|
@@ -18,9 +18,13 @@ module Pact
|
|
18
18
|
end
|
19
19
|
|
20
20
|
dsl do
|
21
|
-
def
|
21
|
+
def mock_provider(builder_name, &block)
|
22
22
|
self.builder = MessageBuilder.build(builder_name, consumer_name, name, &block)
|
23
23
|
end
|
24
|
+
|
25
|
+
def builder(builder_name, &block)
|
26
|
+
expectation_builder(builder_name, &block)
|
27
|
+
end
|
24
28
|
end
|
25
29
|
|
26
30
|
def finalize
|
@@ -1,5 +1,6 @@
|
|
1
1
|
require 'pact/message/consumer/interaction_builder'
|
2
|
-
require 'pact/message/consumer/
|
2
|
+
require 'pact/message/consumer/write_pact'
|
3
|
+
require 'pact/errors'
|
3
4
|
|
4
5
|
module Pact
|
5
6
|
module Message
|
@@ -10,39 +11,79 @@ module Pact
|
|
10
11
|
@interaction_builder = nil
|
11
12
|
@consumer_name = attributes[:consumer_name]
|
12
13
|
@provider_name = attributes[:provider_name]
|
14
|
+
@pact_specification_version = attributes[:pact_specification_version]
|
15
|
+
@pact_dir = attributes[:pact_dir]
|
13
16
|
@interactions = []
|
17
|
+
@yielded_interaction = false
|
14
18
|
end
|
15
19
|
|
16
|
-
def
|
17
|
-
interaction_builder
|
20
|
+
def reset
|
21
|
+
@interaction_builder = nil
|
22
|
+
@yielded_interaction = false
|
23
|
+
end
|
24
|
+
|
25
|
+
def given(provider_state, params = {})
|
26
|
+
interaction_builder.given(provider_state, params)
|
18
27
|
end
|
19
28
|
|
20
29
|
def is_expected_to_send(description)
|
21
30
|
interaction_builder.is_expected_to_send(provider_state)
|
22
31
|
end
|
23
32
|
|
24
|
-
def
|
25
|
-
|
26
|
-
|
33
|
+
def send_message_string
|
34
|
+
if interaction_builder?
|
35
|
+
if block_given?
|
36
|
+
@yielded_interaction = true
|
37
|
+
yield interaction_builder.interaction.contents.reified_contents_string
|
38
|
+
end
|
39
|
+
else
|
40
|
+
raise Pact::Error.new("No message expectation has been defined")
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
def send_message_hash
|
45
|
+
if interaction_builder?
|
46
|
+
if block_given?
|
47
|
+
@yielded_interaction = true
|
48
|
+
yield interaction_builder.interaction.contents.reified_contents_hash
|
49
|
+
end
|
50
|
+
else
|
51
|
+
raise Pact::Error.new("No message expectation has been defined")
|
52
|
+
end
|
27
53
|
end
|
28
54
|
|
29
55
|
def handle_interaction_fully_defined(interaction)
|
56
|
+
@contents = interaction.contents
|
30
57
|
@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
58
|
end
|
36
59
|
|
37
60
|
def verify example_description
|
38
|
-
#
|
39
|
-
#
|
61
|
+
# There may be multiple message providers defined, and not every one of them
|
62
|
+
# has to define a message for every test.
|
63
|
+
if interaction_builder?
|
64
|
+
if yielded_interaction?
|
65
|
+
interactions << interaction_builder.interaction
|
66
|
+
else
|
67
|
+
raise Pact::Error.new("`send_message_string` was not called for message \"#{interaction_builder.interaction.description}\"")
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
def write_pact
|
73
|
+
Pact::Message::Consumer::WritePact.call(interactions, pact_dir, consumer_name, provider_name, pact_specification_version, :overwrite)
|
40
74
|
end
|
41
75
|
|
42
76
|
private
|
43
77
|
|
44
|
-
|
45
|
-
|
78
|
+
attr_accessor :consumer_name, :provider_name, :consumer_contract_details, :contents, :interactions, :pact_specification_version, :pact_dir
|
79
|
+
|
80
|
+
def interaction_builder?
|
81
|
+
!!@interaction_builder
|
82
|
+
end
|
83
|
+
|
84
|
+
def yielded_interaction?
|
85
|
+
@yielded_interaction
|
86
|
+
end
|
46
87
|
|
47
88
|
def interaction_builder
|
48
89
|
@interaction_builder ||=
|
@@ -17,13 +17,17 @@ module Pact
|
|
17
17
|
self
|
18
18
|
end
|
19
19
|
|
20
|
-
def given
|
21
|
-
|
20
|
+
def given name, params = {}
|
21
|
+
if name
|
22
|
+
@interaction.provider_states << Pact::ProviderState.new(name, params)
|
23
|
+
end
|
22
24
|
self
|
23
25
|
end
|
24
26
|
|
27
|
+
alias_method :and, :given
|
28
|
+
|
25
29
|
def with_metadata(object)
|
26
|
-
|
30
|
+
interaction.metadata = object
|
27
31
|
self
|
28
32
|
end
|
29
33
|
|
@@ -17,7 +17,9 @@ module Pact
|
|
17
17
|
hash[:providerStates] = provider_states
|
18
18
|
hash[:contents] = extract_contents
|
19
19
|
hash[:matchingRules] = extract_matching_rules
|
20
|
-
|
20
|
+
if message.metadata
|
21
|
+
hash[:metaData] = message.metadata
|
22
|
+
end
|
21
23
|
fix_all_the_things hash
|
22
24
|
end
|
23
25
|
|
@@ -42,9 +44,14 @@ module Pact
|
|
42
44
|
end
|
43
45
|
|
44
46
|
def extract_matching_rules
|
45
|
-
|
46
|
-
|
47
|
-
|
47
|
+
body_matching_rules = Pact::MatchingRules.extract(message.contents.contents, pact_specification_version: pact_specification_version)
|
48
|
+
if body_matching_rules.any?
|
49
|
+
{
|
50
|
+
body: body_matching_rules
|
51
|
+
}
|
52
|
+
else
|
53
|
+
{}
|
54
|
+
end
|
48
55
|
end
|
49
56
|
|
50
57
|
def pact_specification_version
|
@@ -20,7 +20,15 @@ hooks = Pact::Message::Consumer::SpecHooks.new
|
|
20
20
|
RSpec.configure do |config|
|
21
21
|
config.include Pact::Message::Consumer::RSpec, :pact => :message
|
22
22
|
|
23
|
-
config.
|
23
|
+
config.before :each, :pact => :message do | example |
|
24
|
+
hooks.before_each Pact::RSpec.full_description(example)
|
25
|
+
end
|
26
|
+
|
27
|
+
config.after :each, :pact => :message do | example |
|
24
28
|
hooks.after_each Pact::RSpec.full_description(example)
|
25
29
|
end
|
30
|
+
|
31
|
+
config.after :all do
|
32
|
+
hooks.after_suite
|
33
|
+
end
|
26
34
|
end
|
@@ -1,12 +1,25 @@
|
|
1
|
+
require 'pact/message/consumer/world'
|
2
|
+
|
1
3
|
module Pact
|
2
4
|
module Message
|
3
5
|
module Consumer
|
4
6
|
class SpecHooks
|
7
|
+
def before_each example_description
|
8
|
+
Pact::Message.consumer_world.register_pact_example_ran
|
9
|
+
Pact::Message.consumer_world.consumer_contract_builders.each(&:reset)
|
10
|
+
end
|
11
|
+
|
5
12
|
def after_each example_description
|
6
13
|
Pact.configuration.message_provider_verifications.each do | message_provider_verification |
|
7
14
|
message_provider_verification.call example_description
|
8
15
|
end
|
9
16
|
end
|
17
|
+
|
18
|
+
def after_suite
|
19
|
+
if Pact::Message.consumer_world.any_pact_examples_ran?
|
20
|
+
Pact::Message.consumer_world.consumer_contract_builders.each(&:write_pact)
|
21
|
+
end
|
22
|
+
end
|
10
23
|
end
|
11
24
|
end
|
12
25
|
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
module Pact
|
2
|
+
module Message
|
3
|
+
def self.consumer_world
|
4
|
+
@consumer_world ||= Consumer::World.new
|
5
|
+
end
|
6
|
+
|
7
|
+
# internal api, for testing only
|
8
|
+
def self.clear_consumer_world
|
9
|
+
@consumer_world = nil
|
10
|
+
end
|
11
|
+
|
12
|
+
module Consumer
|
13
|
+
class World
|
14
|
+
def initialize
|
15
|
+
@any_pact_examples_ran = false
|
16
|
+
end
|
17
|
+
|
18
|
+
def consumer_contract_builders
|
19
|
+
@consumer_contract_builders ||= []
|
20
|
+
end
|
21
|
+
|
22
|
+
def add_consumer_contract_builder consumer_contract_builder
|
23
|
+
consumer_contract_builders << consumer_contract_builder
|
24
|
+
end
|
25
|
+
|
26
|
+
def register_pact_example_ran
|
27
|
+
@any_pact_examples_ran = true
|
28
|
+
end
|
29
|
+
|
30
|
+
def any_pact_examples_ran?
|
31
|
+
@any_pact_examples_ran
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -4,26 +4,27 @@ require 'pact/message/consumer/consumer_contract_decorator'
|
|
4
4
|
module Pact
|
5
5
|
module Message
|
6
6
|
module Consumer
|
7
|
-
class
|
7
|
+
class WritePact
|
8
8
|
|
9
|
-
def initialize
|
9
|
+
def initialize messages, pact_dir, consumer_name, provider_name, pact_specification_version, pactfile_write_mode
|
10
10
|
@pact_dir = pact_dir
|
11
|
-
@
|
11
|
+
@messages = messages
|
12
12
|
@consumer_name = consumer_name
|
13
13
|
@provider_name = provider_name
|
14
14
|
@pact_specification_version = pact_specification_version
|
15
|
+
@pactfile_write_mode = pactfile_write_mode
|
15
16
|
end
|
16
17
|
|
17
|
-
def self.call(
|
18
|
-
new(
|
18
|
+
def self.call(messages, pact_dir, consumer_name, provider_name, pact_specification_version, pactfile_write_mode)
|
19
|
+
new(messages, pact_dir, consumer_name, provider_name, pact_specification_version, pactfile_write_mode).call
|
19
20
|
end
|
20
21
|
|
21
22
|
def call
|
22
23
|
details = {
|
23
|
-
consumer: {name: consumer_name},
|
24
|
-
provider: {name: provider_name},
|
25
|
-
interactions: [
|
26
|
-
pactfile_write_mode:
|
24
|
+
consumer: { name: consumer_name },
|
25
|
+
provider: { name: provider_name },
|
26
|
+
interactions: [*messages],
|
27
|
+
pactfile_write_mode: pactfile_write_mode,
|
27
28
|
pact_dir: pact_dir,
|
28
29
|
pact_specification_version: pact_specification_version,
|
29
30
|
error_stream: StringIO.new,
|
@@ -36,7 +37,7 @@ module Pact
|
|
36
37
|
|
37
38
|
private
|
38
39
|
|
39
|
-
attr_reader :
|
40
|
+
attr_reader :messages, :pact_dir, :consumer_name, :provider_name, :pact_specification_version, :pactfile_write_mode
|
40
41
|
end
|
41
42
|
end
|
42
43
|
end
|
data/lib/pact/message/version.rb
CHANGED
@@ -0,0 +1 @@
|
|
1
|
+
require 'pact/message'
|
data/pact-message.gemspec
CHANGED
@@ -34,10 +34,9 @@ Gem::Specification.new do |spec|
|
|
34
34
|
# and Pact::ConsumerContractWriter. Potentially we should extract
|
35
35
|
# or duplicate these classes to remove the pact-mock_service dependency.
|
36
36
|
spec.add_runtime_dependency "pact-mock_service", "~> 3.1"
|
37
|
-
spec.add_runtime_dependency "thor",
|
37
|
+
spec.add_runtime_dependency "thor", '>= 0.20', '< 2.0'
|
38
38
|
|
39
|
-
spec.add_development_dependency "
|
40
|
-
spec.add_development_dependency "rake", "~> 10.0"
|
39
|
+
spec.add_development_dependency "rake", "~> 12.3", ">= 12.3.3"
|
41
40
|
spec.add_development_dependency "rspec", "~> 3.0"
|
42
41
|
spec.add_development_dependency "pry-byebug"
|
43
42
|
spec.add_development_dependency 'conventional-changelog', '~>1.2'
|
@@ -0,0 +1,30 @@
|
|
1
|
+
#!/bin/sh
|
2
|
+
|
3
|
+
# Script to trigger release of gem via the pact-foundation/release-gem action
|
4
|
+
# Requires a Github API token with repo scope stored in the
|
5
|
+
# environment variable GITHUB_ACCESS_TOKEN_FOR_PF_RELEASES
|
6
|
+
|
7
|
+
: "${GITHUB_ACCESS_TOKEN_FOR_PF_RELEASES:?Please set environment variable GITHUB_ACCESS_TOKEN_FOR_PF_RELEASES}"
|
8
|
+
|
9
|
+
if [ -n "$1" ]; then
|
10
|
+
increment="\"${1}\""
|
11
|
+
else
|
12
|
+
increment="null"
|
13
|
+
fi
|
14
|
+
|
15
|
+
repository_slug=$(git remote get-url origin | cut -d':' -f2 | sed 's/\.git//')
|
16
|
+
|
17
|
+
output=$(curl -v https://api.github.com/repos/${repository_slug}/dispatches \
|
18
|
+
-H 'Accept: application/vnd.github.everest-preview+json' \
|
19
|
+
-H "Authorization: Bearer $GITHUB_ACCESS_TOKEN_FOR_PF_RELEASES" \
|
20
|
+
-d "{\"event_type\": \"release-triggered\", \"client_payload\": {\"increment\": ${increment}}}" 2>&1)
|
21
|
+
|
22
|
+
if ! echo "${output}" | grep "HTTP\/.* 204" > /dev/null; then
|
23
|
+
echo "$output" | sed "s/${GITHUB_ACCESS_TOKEN_FOR_PF_RELEASES}/********/g"
|
24
|
+
echo "Failed to trigger release"
|
25
|
+
exit 1
|
26
|
+
else
|
27
|
+
echo "Release workflow triggered"
|
28
|
+
fi
|
29
|
+
|
30
|
+
echo "See https://github.com/${repository_slug}/actions?query=workflow%3A%22Release+gem%22"
|
data/tasks/test.rake
ADDED
@@ -0,0 +1,60 @@
|
|
1
|
+
require "rspec/core/rake_task"
|
2
|
+
|
3
|
+
ZOO_PACT_FILE_PATH = "spec/pacts/zoo_consumer-zoo_provider.json"
|
4
|
+
|
5
|
+
RSpec::Core::RakeTask.new(:pass) do | task |
|
6
|
+
task.pattern = "spec/features/create_message_pact_spec.rb"
|
7
|
+
end
|
8
|
+
|
9
|
+
RSpec::Core::RakeTask.new(:fail) do | task |
|
10
|
+
task.pattern = "spec/features/create_message_pact_with_failure_test.rb"
|
11
|
+
end
|
12
|
+
|
13
|
+
task :pass_writes_pact_file do
|
14
|
+
require 'json'
|
15
|
+
puts "Ensuring that pact file is written for successful test suites"
|
16
|
+
FileUtils.rm_rf(ZOO_PACT_FILE_PATH)
|
17
|
+
Rake::Task['pass'].execute
|
18
|
+
if !File.exist?(ZOO_PACT_FILE_PATH)
|
19
|
+
raise "Expected pact file to be written at #{ZOO_PACT_FILE_PATH}"
|
20
|
+
end
|
21
|
+
|
22
|
+
pact_hash = JSON.parse(File.read(ZOO_PACT_FILE_PATH))
|
23
|
+
if pact_hash['messages'].size < 2
|
24
|
+
raise "Expected pact file to contain more than 1 message"
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
task :fail_does_not_write_pact_file do
|
29
|
+
puts "Ensuring that pact file is NOT written for failed test suites"
|
30
|
+
FileUtils.rm_rf(ZOO_PACT_FILE_PATH)
|
31
|
+
expect_to_fail('bundle exec rake fail')
|
32
|
+
if File.exist?(ZOO_PACT_FILE_PATH)
|
33
|
+
raise "Expected pact file NOT to be written at #{ZOO_PACT_FILE_PATH}"
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
task :default => [:pass_writes_pact_file, :fail_does_not_write_pact_file]
|
38
|
+
|
39
|
+
def expect_to_fail command, options = {}
|
40
|
+
success = execute_command command, options
|
41
|
+
fail "Expected '#{command}' to fail" if success
|
42
|
+
end
|
43
|
+
|
44
|
+
def execute_command command, options
|
45
|
+
require 'open3'
|
46
|
+
result = nil
|
47
|
+
Open3.popen3(command) {|stdin, stdout, stderr, wait_thr|
|
48
|
+
result = wait_thr.value
|
49
|
+
ensure_patterns_present(command, options, stdout, stderr) if options[:with]
|
50
|
+
}
|
51
|
+
result.success?
|
52
|
+
end
|
53
|
+
|
54
|
+
def ensure_patterns_present command, options, stdout, stderr
|
55
|
+
require 'term/ansicolor'
|
56
|
+
output = stdout.read + stderr.read
|
57
|
+
options[:with].each do | pattern |
|
58
|
+
raise (::Term::ANSIColor.red("Could not find #{pattern.inspect} in output of #{command}") + "\n\n#{output}") unless output =~ pattern
|
59
|
+
end
|
60
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: pact-message
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.11.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Beth Skurrie
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2021-04-20 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: pact-support
|
@@ -42,44 +42,42 @@ dependencies:
|
|
42
42
|
name: thor
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
|
-
- - "
|
45
|
+
- - ">="
|
46
46
|
- !ruby/object:Gem::Version
|
47
47
|
version: '0.20'
|
48
|
+
- - "<"
|
49
|
+
- !ruby/object:Gem::Version
|
50
|
+
version: '2.0'
|
48
51
|
type: :runtime
|
49
52
|
prerelease: false
|
50
53
|
version_requirements: !ruby/object:Gem::Requirement
|
51
54
|
requirements:
|
52
|
-
- - "
|
55
|
+
- - ">="
|
53
56
|
- !ruby/object:Gem::Version
|
54
57
|
version: '0.20'
|
55
|
-
-
|
56
|
-
name: bundler
|
57
|
-
requirement: !ruby/object:Gem::Requirement
|
58
|
-
requirements:
|
59
|
-
- - "~>"
|
58
|
+
- - "<"
|
60
59
|
- !ruby/object:Gem::Version
|
61
|
-
version:
|
62
|
-
type: :development
|
63
|
-
prerelease: false
|
64
|
-
version_requirements: !ruby/object:Gem::Requirement
|
65
|
-
requirements:
|
66
|
-
- - "~>"
|
67
|
-
- !ruby/object:Gem::Version
|
68
|
-
version: 1.17.3
|
60
|
+
version: '2.0'
|
69
61
|
- !ruby/object:Gem::Dependency
|
70
62
|
name: rake
|
71
63
|
requirement: !ruby/object:Gem::Requirement
|
72
64
|
requirements:
|
73
65
|
- - "~>"
|
74
66
|
- !ruby/object:Gem::Version
|
75
|
-
version: '
|
67
|
+
version: '12.3'
|
68
|
+
- - ">="
|
69
|
+
- !ruby/object:Gem::Version
|
70
|
+
version: 12.3.3
|
76
71
|
type: :development
|
77
72
|
prerelease: false
|
78
73
|
version_requirements: !ruby/object:Gem::Requirement
|
79
74
|
requirements:
|
80
75
|
- - "~>"
|
81
76
|
- !ruby/object:Gem::Version
|
82
|
-
version: '
|
77
|
+
version: '12.3'
|
78
|
+
- - ">="
|
79
|
+
- !ruby/object:Gem::Version
|
80
|
+
version: 12.3.3
|
83
81
|
- !ruby/object:Gem::Dependency
|
84
82
|
name: rspec
|
85
83
|
requirement: !ruby/object:Gem::Requirement
|
@@ -146,9 +144,10 @@ executables:
|
|
146
144
|
extensions: []
|
147
145
|
extra_rdoc_files: []
|
148
146
|
files:
|
147
|
+
- ".github/workflows/release_gem.yml"
|
148
|
+
- ".github/workflows/test.yml"
|
149
149
|
- ".gitignore"
|
150
150
|
- ".rspec"
|
151
|
-
- ".travis.yml"
|
152
151
|
- CHANGELOG.md
|
153
152
|
- CONTRIBUTING.md
|
154
153
|
- DEVELOPER_DOCUMENTATION.md
|
@@ -178,17 +177,21 @@ files:
|
|
178
177
|
- lib/pact/message/consumer/interaction_decorator.rb
|
179
178
|
- lib/pact/message/consumer/rspec.rb
|
180
179
|
- lib/pact/message/consumer/spec_hooks.rb
|
181
|
-
- lib/pact/message/consumer/
|
180
|
+
- lib/pact/message/consumer/world.rb
|
181
|
+
- lib/pact/message/consumer/write_pact.rb
|
182
182
|
- lib/pact/message/consumer_contract_parser.rb
|
183
183
|
- lib/pact/message/version.rb
|
184
|
+
- lib/pact/pact-message.rb
|
184
185
|
- pact-message.gemspec
|
185
186
|
- script/docker-functions
|
186
187
|
- script/functions
|
187
188
|
- script/release.sh
|
188
189
|
- script/release/bump-version.sh
|
189
190
|
- script/release/generate-changelog.sh
|
191
|
+
- script/trigger-release.sh
|
190
192
|
- script/update-pact.sh
|
191
193
|
- tasks/release.rake
|
194
|
+
- tasks/test.rake
|
192
195
|
homepage: http://pact.io
|
193
196
|
licenses:
|
194
197
|
- MIT
|
@@ -209,8 +212,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
209
212
|
- !ruby/object:Gem::Version
|
210
213
|
version: '0'
|
211
214
|
requirements: []
|
212
|
-
|
213
|
-
rubygems_version: 2.7.7
|
215
|
+
rubygems_version: 3.2.16
|
214
216
|
signing_key:
|
215
217
|
specification_version: 4
|
216
218
|
summary: Consumer contract library for messages
|
data/.travis.yml
DELETED
@@ -1,33 +0,0 @@
|
|
1
|
-
sudo: false
|
2
|
-
language: ruby
|
3
|
-
rvm:
|
4
|
-
- 2.2.4
|
5
|
-
before_install:
|
6
|
-
- rvm use @global
|
7
|
-
- gem uninstall bundler -x || gem uninstall bundler -a || true
|
8
|
-
- gem install bundler -v 1.17.3
|
9
|
-
- bundler --version
|
10
|
-
script:
|
11
|
-
- rvm use @global
|
12
|
-
- bundle exec rake
|
13
|
-
jobs:
|
14
|
-
include:
|
15
|
-
- stage: gem release
|
16
|
-
rvm: 2.2.4
|
17
|
-
script: echo "Deploying to rubygems.org ..."
|
18
|
-
deploy:
|
19
|
-
provider: rubygems
|
20
|
-
api_key:
|
21
|
-
secure: NEA7BYENheSN8qF/6BP52uQjTS5U43MXsyxBeqxbp1JOkJxVSNzQw14xy41aXX0gphT7wEVHinnWS+1slLKXvu4OzGKKzcUsnekYFZoGW7eTyKUx7lh/XtFejQ/Mm4P5t75GBgMoaIi+Pa1rD4fcE7zYGrgCvTwIrOGb/SPIKILj0yT8UXMFod8yDDmxzivSSKYe4rgWYlq8aiidDZr2M5ypBR4WcOptCrkBCF8XxXzhFMY4QtrXLsLFRyCzCrDHmosCfC/bLJQltlJjLXfB5ksgaImWAD7wZ6Q4uC5QqmPShonQiPlLEh53Q5nkEWPIcsV7FVZqzXUjPN3LYHlRv+7D3AvbHmJggSt7fXr8YxbzVUkviBlKqNmc9cqM6CSO++QT3UShNgH5b03YKI8rRjFMWYKn1DrN5F5rFNDoGFcZtQSjFN5g/fEiSYsdkNsIeTp4YFxMkTztAYT8TxgcBvCnfXox6xDaLaPWh13UrUL2VL7O7uDK06xWUCp9Hm3/AXz0wRzya1tK9dCWamE5BOzk2ScOiLOgmpgwNHFVA1U93rkHq7Ixr11wazP3Dcinv0kWcW7hdMcI7VA0DUesxLKw6mkcQpd3NLgSU4mWtpoVFcmdERQUGsNM1d5NjGjBeyVMpC0I9NXM1Wv6cLENSX9b4GR7lkwGG/IHRFNciHk=
|
22
|
-
gem: pact-message
|
23
|
-
on:
|
24
|
-
tags: true
|
25
|
-
repo: pact-foundation/pact-message-ruby
|
26
|
-
notifications:
|
27
|
-
webhooks:
|
28
|
-
urls:
|
29
|
-
- https://webhooks.gitter.im/e/6523128341fad111ed79
|
30
|
-
on_success: change
|
31
|
-
on_failure: always
|
32
|
-
on_start: never
|
33
|
-
|