pact 2.1.0 → 2.1.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5981192ff0284632e39d26660bf25cb35109ab17f8e6da065114b46a77e8bf77
4
- data.tar.gz: 57c68d0b0217c0c51b55d5ef7d37a56b2fb2db1211de1693cd4020455614a3c2
3
+ metadata.gz: 8e137113e8536b4b90aa2f7797511680e7ece3b71f8ab5d9b79b55dafc88b326
4
+ data.tar.gz: e3f74756da104c116691133610e8f8dfcfa0abe5abc1bd26bceaaef3e98f5253
5
5
  SHA512:
6
- metadata.gz: 5af0dcba077273ed185fd2793c4f2183d301d4ae826860cd2e57503d06970ef8dbb36d8c9a4fac266429f847feaee5706fb728e18293201ea4ea285561eb0602
7
- data.tar.gz: 6c7cff40d5dac6a7c1ae2d7095486ed73455219b5b03e9fc70c0bc68cb44c7d71f04a6810855ac85586a66d0f52f7b7b9f5a5e2210d367e6902451e3dcbc3ec8
6
+ metadata.gz: 5656437ede72b86ff539d7c767f50ee0a55414df06e4d81c02cb87c24b27aca3e59eafdb4ed97eb76f2acc46aef69102f44a62c2366db5b81c975de32c2c721a
7
+ data.tar.gz: bf032fb5bfbd5e9a9fadc2fe60658ff4de346b62c5e4e94d8d52a835db9792885fb98258203ba721619c9ffe6839877e4538fd2e9a66df53bafbbb53fed36b1d
data/CHANGELOG.md CHANGED
@@ -1,3 +1,18 @@
1
+ <a name="v2.1.2"></a>
2
+ ### v2.1.2 (2026-10-21)
3
+
4
+ #### Bug Fixes
5
+
6
+ * support plugin message contents without a transport ([c3e4844](/../../commit/c3e4844))
7
+ * remove pact bin for cli no longer packaged in v2 ([fc5b182](/../../commit/fc5b182))
8
+
9
+ <a name="v2.1.1"></a>
10
+ ### v2.1.1 (2026-10-19)
11
+
12
+ #### Bug Fixes
13
+
14
+ * add interaction references to the interaction, not the pact ([c79cba5](/../../commit/c79cba5))
15
+
1
16
  <a name="v2.1.0"></a>
2
17
  ### v2.1.0 (2026-09-14)
3
18
 
@@ -148,7 +148,9 @@ module Pact
148
148
  end
149
149
 
150
150
  @references.each do |group, name, value|
151
- PactFfi.add_interaction_reference(pact_handle, group, name, value)
151
+ next if PactFfi.add_interaction_reference(message_pact, group, name, value)
152
+
153
+ raise InteractionBuilderError.new("could not add reference #{group}/#{name}")
152
154
  end
153
155
 
154
156
  result = PactFfi::PluginConsumer.interaction_contents(message_pact, 0, GRPC_CONTENT_TYPE, interaction_json)
@@ -116,7 +116,9 @@ module Pact
116
116
  raise InteractionBuilderError.new("interaction is designed to be used one-time only") if defined?(@used)
117
117
 
118
118
  @references.each do |group, name, value|
119
- PactFfi.add_interaction_reference(pact_handle, group, name, value)
119
+ next if PactFfi.add_interaction_reference(pact_interaction, group, name, value)
120
+
121
+ raise InteractionBuilderError.new("could not add reference #{group}/#{name}")
120
122
  end
121
123
 
122
124
  mock_server = MockServer.create_for_http!(
@@ -55,6 +55,10 @@ module Pact
55
55
  @proto_path = nil
56
56
  @proto_message_class = nil
57
57
  @proto_include_dirs = []
58
+ @plugin_name = nil
59
+ @plugin_version = nil
60
+ @plugin_content_type = nil
61
+ @plugin_contents = nil
58
62
  @meta = {}
59
63
  @headers = {}
60
64
  @provider_state_meta = nil
@@ -106,6 +110,25 @@ module Pact
106
110
  self
107
111
  end
108
112
 
113
+ # Any content plugin that needs no transport (e.g. avro), see #with_plugin_contents
114
+ def with_plugin(plugin_name, plugin_version)
115
+ raise InteractionBuilderError.new("plugin_name is required") if plugin_name.blank?
116
+ raise InteractionBuilderError.new("plugin_version is required") if plugin_version.blank?
117
+
118
+ @plugin_name = plugin_name
119
+ @plugin_version = plugin_version
120
+ self
121
+ end
122
+
123
+ # contents_hash is passed to the plugin as-is, e.g. {"pact:avro" => path, "pact:record-name" => "Order", ...}
124
+ def with_plugin_contents(content_type, contents_hash)
125
+ raise InteractionBuilderError.new("content_type is required") if content_type.blank?
126
+
127
+ @plugin_content_type = content_type
128
+ @plugin_contents = InteractionContents.plugin(contents_hash)
129
+ self
130
+ end
131
+
109
132
  def with_metadata(meta_hash)
110
133
  @meta = InteractionContents.basic(meta_hash)
111
134
  self
@@ -122,7 +145,10 @@ module Pact
122
145
  end
123
146
 
124
147
  def validate!
125
- if proto_interaction?
148
+ if custom_plugin_interaction?
149
+ raise InteractionBuilderError.new("plugin is not defined, please set one with #with_plugin") if @plugin_name.blank? || @plugin_version.blank?
150
+ raise InteractionBuilderError.new("invalid request format, should be a hash") unless @plugin_contents.is_a?(Hash)
151
+ elsif proto_interaction?
126
152
  raise InteractionBuilderError.new("proto_path / proto_message are not defined, please set ones with #with_proto_message") if @proto_contents.blank? || @proto_message_class.blank?
127
153
  raise InteractionBuilderError.new("invalid request format, should be a hash") unless @proto_contents.is_a?(Hash)
128
154
  else
@@ -136,12 +162,14 @@ module Pact
136
162
 
137
163
  validate!
138
164
  pact_handle = init_pact
139
- init_plugin!(pact_handle) if proto_interaction?
165
+ init_plugin!(pact_handle) if plugin_interaction?
140
166
 
141
167
  message_pact = PactFfi::MessageConsumer.new_message_interaction(pact_handle, @description)
142
168
 
143
169
  @references.each do |group, name, value|
144
- PactFfi.add_interaction_reference(pact_handle, group, name, value)
170
+ next if PactFfi.add_interaction_reference(message_pact, group, name, value)
171
+
172
+ raise InteractionBuilderError.new("could not add reference #{group}/#{name}")
145
173
  end
146
174
 
147
175
  configure_interaction!(message_pact)
@@ -161,6 +189,7 @@ module Pact
161
189
  end
162
190
 
163
191
  def build_interaction_json
192
+ return JSON.dump({"pact:content-type" => @plugin_content_type}.merge(@plugin_contents.transform_keys(&:to_s))) if custom_plugin_interaction?
164
193
  return JSON.dump(@json_contents) unless proto_interaction?
165
194
 
166
195
  contents = {
@@ -238,7 +267,7 @@ module Pact
238
267
  end
239
268
 
240
269
  def fetch_reified_message_body(message_handle)
241
- if proto_interaction?
270
+ if plugin_interaction?
242
271
  len = PactFfi::MessageConsumer.get_contents_length(message_handle)
243
272
  ptr = PactFfi::MessageConsumer.get_contents_bin(message_handle)
244
273
  return nil if ptr.blank? || len == 0
@@ -255,8 +284,8 @@ module Pact
255
284
  def configure_interaction!(message_pact)
256
285
  interaction_json = build_interaction_json
257
286
 
258
- if proto_interaction?
259
- result = PactFfi::PluginConsumer.interaction_contents(message_pact, 0, PROTO_CONTENT_TYPE, interaction_json)
287
+ if plugin_interaction?
288
+ result = PactFfi::PluginConsumer.interaction_contents(message_pact, 0, plugin_content_type, interaction_json)
260
289
  if CREATE_INTERACTION_ERRORS[result].present?
261
290
  error = CREATE_INTERACTION_ERRORS[result]
262
291
  raise CreateInteractionError.new("There was an error while trying to add interaction \"#{@description}\"", error[:reason], error[:status])
@@ -275,11 +304,12 @@ module Pact
275
304
  end
276
305
 
277
306
  def init_plugin!(pact_handle)
278
- result = PactFfi::PluginConsumer.using_plugin(pact_handle, PROTOBUF_PLUGIN_NAME, @proto_plugin_version || PROTOBUF_PLUGIN_VERSION)
307
+ name, version = custom_plugin_interaction? ? [@plugin_name, @plugin_version] : [PROTOBUF_PLUGIN_NAME, @proto_plugin_version || PROTOBUF_PLUGIN_VERSION]
308
+ result = PactFfi::PluginConsumer.using_plugin(pact_handle, name, version)
279
309
  return result if INIT_PLUGIN_ERRORS[result].blank?
280
310
 
281
311
  error = INIT_PLUGIN_ERRORS[result]
282
- raise PluginInitError.new("There was an error while trying to initialize plugin #{PROTOBUF_PLUGIN_NAME}/#{@proto_plugin_version || PROTOBUF_PLUGIN_VERSION}", error[:reason], error[:status])
312
+ raise PluginInitError.new("There was an error while trying to initialize plugin #{name}/#{version}", error[:reason], error[:status])
283
313
  end
284
314
 
285
315
  def serialize_metadata(metadata_hash)
@@ -292,6 +322,18 @@ module Pact
292
322
  def proto_interaction?
293
323
  @proto_contents.present?
294
324
  end
325
+
326
+ def custom_plugin_interaction?
327
+ @plugin_contents.present?
328
+ end
329
+
330
+ def plugin_interaction?
331
+ proto_interaction? || custom_plugin_interaction?
332
+ end
333
+
334
+ def plugin_content_type
335
+ custom_plugin_interaction? ? @plugin_content_type : PROTO_CONTENT_TYPE
336
+ end
295
337
  end
296
338
  end
297
339
  end
@@ -111,7 +111,9 @@ module Pact
111
111
  interaction = PactFfi::AsyncMessageConsumer.new(pact_handle, @description)
112
112
 
113
113
  @references.each do |group, name, value|
114
- PactFfi.add_interaction_reference(pact_handle, group, name, value)
114
+ next if PactFfi.add_interaction_reference(interaction, group, name, value)
115
+
116
+ raise InteractionBuilderError.new("could not add reference #{group}/#{name}")
115
117
  end
116
118
 
117
119
  @provider_state_meta&.each_pair do |provider_state, meta|
@@ -129,7 +129,9 @@ module Pact
129
129
  interaction = PactFfi.new_interaction(pact_handle, @description)
130
130
 
131
131
  @references.each do |group, name, value|
132
- PactFfi.add_interaction_reference(pact_handle, group, name, value)
132
+ next if PactFfi.add_interaction_reference(interaction, group, name, value)
133
+
134
+ raise InteractionBuilderError.new("could not add reference #{group}/#{name}")
133
135
  end
134
136
 
135
137
  @provider_state_meta&.each_pair do |provider_state, meta|
@@ -128,7 +128,9 @@ module Pact
128
128
  message_pact = PactFfi::SyncMessageConsumer.new_interaction(pact_handle, @description)
129
129
 
130
130
  @references.each do |group, name, value|
131
- PactFfi.add_interaction_reference(pact_handle, group, name, value)
131
+ next if PactFfi.add_interaction_reference(message_pact, group, name, value)
132
+
133
+ raise InteractionBuilderError.new("could not add reference #{group}/#{name}")
132
134
  end
133
135
 
134
136
  @provider_state_meta&.each_pair do |provider_state, meta|
data/lib/pact/version.rb CHANGED
@@ -1,4 +1,4 @@
1
1
  # Remember to bump pact-provider-proxy when this changes major version
2
2
  module Pact
3
- VERSION = "2.1.0"
3
+ VERSION = "2.1.2"
4
4
  end
data/pact.gemspec CHANGED
@@ -14,8 +14,7 @@ Gem::Specification.new do |gem|
14
14
 
15
15
  gem.required_ruby_version = '>= 2.0'
16
16
 
17
- gem.files = `git ls-files bin lib pact.gemspec CHANGELOG.md LICENSE.txt`.split($/)
18
- gem.executables = gem.files.grep(%r{^bin/}).map { |f| File.basename(f) }
17
+ gem.files = `git ls-files lib pact.gemspec CHANGELOG.md LICENSE.txt`.split($/)
19
18
  gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
20
19
  gem.require_paths = ['lib']
21
20
  gem.license = 'MIT'
@@ -48,12 +47,8 @@ Gem::Specification.new do |gem|
48
47
  # For Kafka support
49
48
  unless RUBY_PLATFORM =~ /win32|x64-mingw32|x64-mingw-ucrt/
50
49
  # windows does not support librdkafka
51
- gem.add_development_dependency 'sbmt-kafka_consumer', '>= 2.0.1'
52
- gem.add_development_dependency 'sbmt-kafka_producer', '>= 1.0'
53
- end
54
- if ENV['X_PACT_DEVELOPMENT_RDKAFKA'] == 'true'
55
- # darwin-arm64 prebuilt gems available from 0.20.0
56
- gem.add_development_dependency 'karafka-rdkafka', '>= 0.20.0'
50
+ gem.add_development_dependency 'sbmt-kafka_consumer', '>= 3.0.0'
51
+ gem.add_development_dependency 'sbmt-kafka_producer', '>= 3.0.0'
57
52
  end
58
53
  # For gRPC support
59
54
  gem.add_development_dependency 'gruf', '>= 2.18'
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: 2.1.0
4
+ version: 2.1.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - James Fraser
@@ -117,28 +117,28 @@ dependencies:
117
117
  requirements:
118
118
  - - ">="
119
119
  - !ruby/object:Gem::Version
120
- version: 2.0.1
120
+ version: 3.0.0
121
121
  type: :development
122
122
  prerelease: false
123
123
  version_requirements: !ruby/object:Gem::Requirement
124
124
  requirements:
125
125
  - - ">="
126
126
  - !ruby/object:Gem::Version
127
- version: 2.0.1
127
+ version: 3.0.0
128
128
  - !ruby/object:Gem::Dependency
129
129
  name: sbmt-kafka_producer
130
130
  requirement: !ruby/object:Gem::Requirement
131
131
  requirements:
132
132
  - - ">="
133
133
  - !ruby/object:Gem::Version
134
- version: '1.0'
134
+ version: 3.0.0
135
135
  type: :development
136
136
  prerelease: false
137
137
  version_requirements: !ruby/object:Gem::Requirement
138
138
  requirements:
139
139
  - - ">="
140
140
  - !ruby/object:Gem::Version
141
- version: '1.0'
141
+ version: 3.0.0
142
142
  - !ruby/object:Gem::Dependency
143
143
  name: gruf
144
144
  requirement: !ruby/object:Gem::Requirement
@@ -406,14 +406,12 @@ email:
406
406
  - brent@fuglylogic.com
407
407
  - uglyog@gmail.com
408
408
  - bskurrie@dius.com.au
409
- executables:
410
- - pact
409
+ executables: []
411
410
  extensions: []
412
411
  extra_rdoc_files: []
413
412
  files:
414
413
  - CHANGELOG.md
415
414
  - LICENSE.txt
416
- - bin/pact
417
415
  - lib/pact.rb
418
416
  - lib/pact/configuration.rb
419
417
  - lib/pact/consumer.rb
@@ -513,7 +511,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
513
511
  - !ruby/object:Gem::Version
514
512
  version: '0'
515
513
  requirements: []
516
- rubygems_version: 4.0.20
514
+ rubygems_version: 4.0.23
517
515
  specification_version: 4
518
516
  summary: Enables consumer driven contract testing, providing a mock service and DSL
519
517
  for the consumer project, and interaction playback and verification for the service
data/bin/pact DELETED
@@ -1,4 +0,0 @@
1
- #!/usr/bin/env ruby
2
-
3
- require 'pact/cli'
4
- Pact::CLI.start