pact 2.0.0 → 2.0.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 4bc90d8d648301d05847644f43969759221c0eafa6e85823937cfad612eb3684
4
- data.tar.gz: b8e556a7f488cd74bea3ff7dab38c26f90904fabfe812c48d3f415da92749eed
3
+ metadata.gz: ae64ff5080cc286c9a913c8ad1e06d99c35961f687eabe3e99c5bcaac6078aeb
4
+ data.tar.gz: 8fdbd4c74eb3e5c2cf57300ce269cb7e48f52fb83e5886f8e7aee08e97274d9a
5
5
  SHA512:
6
- metadata.gz: cdc816cbd75713eeaadb1546602d80f3b0eae0acde1dc6f760ce95424f429aaa305baa269510a63e6bf6594d344d60356de21755e31ec8088174912012619939
7
- data.tar.gz: 67723d32775313b7266e4f44e9bb947ea881dfa0bc0b4908bf1bf391cdac283c8bf77550529421a65c73bd47328801518f9ed47d0a958a3e0dbfd8f4b1057319
6
+ metadata.gz: 7b01cb166524d3fdc62d7a34ecacd922281d63885cb4cc48cc4ba3d4d5007511d5b2263b6697060cc443fda3efcdec45d2d54d182e6b9f1e9a9d9f3ac593cb36
7
+ data.tar.gz: acbf67bc8d3b23c85fbbcda46cdbf29297fd2eb859430536d58537ff055fb64ac4d6f9c28d6fee78324ebd33b9e534c6dd2e26dd454376dea9b8ea8aa28eb7e6
data/CHANGELOG.md CHANGED
@@ -1,3 +1,17 @@
1
+ <a name="v2.0.1"></a>
2
+ ### v2.0.1 (2026-05-29)
3
+
4
+ #### Bug Fixes
5
+
6
+ * **example**
7
+ * remove combustion dependency from examples ([281b284](/../../commit/281b284))
8
+
9
+ * align core_ext polyfills more closely with active_support implementations ([f08b8ce](/../../commit/f08b8ce))
10
+ * correct Object#blank? and Object#present? polyfill implementations ([53580b9](/../../commit/53580b9))
11
+ * add deep_dup polyfill alongside blank?/present? ([b116e14](/../../commit/b116e14))
12
+ * remove hard requirements on active_support and webmock ([e77cd34](/../../commit/e77cd34))
13
+ * support scalar request and response bodies in InteractionContents ([5440ed1](/../../commit/5440ed1))
14
+
1
15
  <a name="v2.0.0"></a>
2
16
  ### v2.0.0 (2026-03-18)
3
17
 
@@ -82,7 +82,7 @@ module Pact
82
82
  end
83
83
 
84
84
  if body
85
- PactFfi.with_body(pact_interaction, interaction_part, "application/json", format_value(InteractionContents.basic(body)))
85
+ PactFfi.with_body(pact_interaction, interaction_part, "application/json", format_value(InteractionContents.basic(body).value))
86
86
  end
87
87
 
88
88
  self
@@ -97,7 +97,7 @@ module Pact
97
97
  end
98
98
 
99
99
  if body
100
- PactFfi.with_body(pact_interaction, interaction_part, "application/json", format_value(InteractionContents.basic(body)))
100
+ PactFfi.with_body(pact_interaction, interaction_part, "application/json", format_value(InteractionContents.basic(body).value))
101
101
  end
102
102
 
103
103
  self
@@ -17,36 +17,38 @@ module Pact
17
17
  end
18
18
 
19
19
  def initialize(contents_hash, format)
20
- init_hash(contents_hash, format).each_pair { |k, v| self[k] = v }
20
+ serialized = init_hash(contents_hash, format)
21
+ # A scalar body (plain string, integer, etc.) serializes to a non-Hash
22
+ # value that cannot be merged pair by pair; expose it via #value instead.
23
+ if serialized.is_a?(Hash)
24
+ serialized.each_pair { |k, v| self[k] = v }
25
+ else
26
+ @value = serialized
27
+ end
21
28
  @format = format
22
29
  end
23
30
 
31
+ def value
32
+ defined?(@value) ? @value : self
33
+ end
34
+
24
35
  private
25
36
 
26
37
  def serialize(hash, format)
27
38
  # serialize recursively
28
- return hash if hash.is_a?(String)
29
-
30
- if hash.is_a?(Pact::Matchers::Base)
31
- return hash.as_basic if format == :basic
32
- return hash.as_plugin if format == :plugin
33
- end
34
- if hash.is_a?(Pact::Generators::Base)
39
+ if hash.is_a?(Pact::Matchers::Base) || hash.is_a?(Pact::Generators::Base)
35
40
  return hash.as_basic if format == :basic
36
41
  return hash.as_plugin if format == :plugin
37
42
  end
43
+
44
+ return hash.map { |value| serialize(value, format) } if hash.is_a?(Array)
45
+
46
+ # A value that is not a collection or a matcher/generator has nothing to
47
+ # recurse into, so return it unchanged (string, integer, boolean, nil, ...).
48
+ return hash unless hash.is_a?(Hash)
49
+
38
50
  hash.each_pair do |key, value|
39
- next serialize(value, format) if value.is_a?(Hash)
40
- next hash[key] = value.map { |v| serialize(v, format) } if value.is_a?(Array)
41
-
42
- if value.is_a?(Pact::Matchers::Base)
43
- hash[key] = value.as_basic if format == :basic
44
- hash[key] = value.as_plugin if format == :plugin
45
- end
46
- if value.is_a?(Pact::Generators::Base)
47
- hash[key] = value.as_basic if format == :basic
48
- hash[key] = value.as_plugin if format == :plugin
49
- end
51
+ hash[key] = serialize(value, format)
50
52
  end
51
53
 
52
54
  hash
@@ -2,7 +2,7 @@
2
2
 
3
3
  module WebmockHelpers
4
4
  def self.turned_off
5
- yield unless defined?(::WebMock)
5
+ return yield unless defined?(::WebMock)
6
6
 
7
7
  allow_net_connect = WebMock::Config.instance.allow_net_connect
8
8
  allow_localhost = WebMock::Config.instance.allow_localhost
@@ -0,0 +1,93 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Minimal active_support polyfills for blank?/present? and deep_dup.
4
+ # Each block is skipped entirely if the method is already defined
5
+ # (e.g. active_support is loaded by the host application).
6
+
7
+ unless Object.method_defined?(:blank?)
8
+ class NilClass
9
+ def blank? = true
10
+ def present? = false
11
+ end
12
+
13
+ class FalseClass
14
+ def blank? = true
15
+ def present? = false
16
+ end
17
+
18
+ class TrueClass
19
+ def blank? = false
20
+ def present? = true
21
+ end
22
+
23
+ class String
24
+ BLANK_RE = /\A[[:space:]]*\z/
25
+
26
+ def blank?
27
+ empty? || BLANK_RE.match?(self)
28
+ end
29
+
30
+ def present? = !blank?
31
+ end
32
+
33
+ class Symbol
34
+ alias_method :blank?, :empty?
35
+ def present? = !blank?
36
+ end
37
+
38
+ class Array
39
+ alias_method :blank?, :empty?
40
+ def present? = !empty?
41
+ end
42
+
43
+ class Hash
44
+ alias_method :blank?, :empty?
45
+ def present? = !empty?
46
+ end
47
+
48
+ class Object
49
+ def blank? = respond_to?(:empty?) ? !!empty? : false
50
+ def present? = !blank?
51
+
52
+ def presence
53
+ self if present?
54
+ end
55
+ end
56
+ end
57
+
58
+ unless Object.method_defined?(:deep_dup)
59
+ class Object
60
+ def deep_dup
61
+ dup
62
+ rescue TypeError
63
+ self
64
+ end
65
+ end
66
+
67
+ class Array
68
+ def deep_dup
69
+ map(&:deep_dup)
70
+ end
71
+ end
72
+
73
+ class Hash
74
+ def deep_dup
75
+ hash = dup
76
+ each_pair do |key, value|
77
+ if ::String === key || ::Symbol === key
78
+ hash[key] = value.deep_dup
79
+ else
80
+ hash.delete(key)
81
+ hash[key.deep_dup] = value.deep_dup
82
+ end
83
+ end
84
+ hash
85
+ end
86
+ end
87
+
88
+ class Module
89
+ def deep_dup
90
+ name.nil? ? super : self
91
+ end
92
+ end
93
+ end
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.0.0"
3
+ VERSION = "2.0.1"
4
4
  end
data/lib/pact.rb CHANGED
@@ -5,6 +5,11 @@ require 'pact/ffi'
5
5
 
6
6
  require 'pact/railtie' if defined?(Rails::Railtie)
7
7
 
8
+ # Load core_ext polyfills (blank?/present?, deep_dup) before Zeitwerk eager-loads
9
+ # the rest of the gem. Each polyfill is skipped if already defined by active_support
10
+ # or any other library loaded by the host application.
11
+ require 'pact/support/core_ext'
12
+
8
13
  module Pact
9
14
  class Error < StandardError; end
10
15
 
@@ -41,6 +46,7 @@ loader.tag = 'pact'
41
46
  loader.ignore("#{__dir__}/pact/version.rb")
42
47
  loader.ignore("#{__dir__}/pact/rspec.rb")
43
48
  loader.ignore("#{__dir__}/pact/rspec")
49
+ loader.ignore("#{__dir__}/pact/support/core_ext.rb")
44
50
  loader.ignore("#{__dir__}/pact/railtie.rb") unless defined?(Rails::Railtie)
45
51
 
46
52
  loader.setup
data/pact.gemspec CHANGED
@@ -27,6 +27,12 @@ Gem::Specification.new do |gem|
27
27
  'documentation_uri' => 'https://github.com/pact-foundation/pact-ruby/blob/master/README.md'
28
28
  }
29
29
 
30
+ # Optional runtime dependencies (not required by pact itself):
31
+ # active_support — if already loaded, its blank?/present? take precedence over
32
+ # pact's built-in polyfill (lib/pact/support/blank.rb).
33
+ # webmock — only needed for WebMock integration via WebmockHelpers.
34
+ # Require it yourself before using that helper.
35
+
30
36
  # Core dependencies (code loading)
31
37
  gem.add_dependency 'zeitwerk', '~> 2.3'
32
38
  # For Pact support via Pact Rust Core
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.0.0
4
+ version: 2.0.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - James Fraser
@@ -487,6 +487,7 @@ files:
487
487
  - lib/pact/rspec/support/pact_provider_helpers.rb
488
488
  - lib/pact/rspec/support/waterdrop/pact_waterdrop_client.rb
489
489
  - lib/pact/rspec/support/webmock/webmock_helpers.rb
490
+ - lib/pact/support/core_ext.rb
490
491
  - lib/pact/tasks/pact.rake
491
492
  - lib/pact/version.rb
492
493
  - pact.gemspec
@@ -512,7 +513,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
512
513
  - !ruby/object:Gem::Version
513
514
  version: '0'
514
515
  requirements: []
515
- rubygems_version: 4.0.8
516
+ rubygems_version: 4.0.14
516
517
  specification_version: 4
517
518
  summary: Enables consumer driven contract testing, providing a mock service and DSL
518
519
  for the consumer project, and interaction playback and verification for the service