pact-support 1.15.1 → 1.18.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: 7ccc117840bc0955cb8ffa7568bab96b94ec5d7d51b6bd5233a05b251373e221
4
- data.tar.gz: 66218c13f81e23f76facec82ef95f64038376f3368ae02aa3ce16008288f35fe
3
+ metadata.gz: b3fb2c40a2b73c204a645be5480655e98c5c41698b4958ca1acd1a98aeff1c9b
4
+ data.tar.gz: 2d1c53df9037d026df359c0aa818d62ba00f3e1f0def19f06b350091f54a4706
5
5
  SHA512:
6
- metadata.gz: 4e16a0adf65d235937a123a5a1ee0043ded52ba0e4a2541f6b3a7a0e5e208a681cb405baee555b23c66d46a75dcb388999d1f424b0c7bb9c8055839cbf72f9ac
7
- data.tar.gz: 0dc8fef0d02eaeb5976395c4a0eb33bdc01ac0ba954dad0eab3a7bc8b24d31625224e28c048d31b551ff1bc15a39ba41bd0f275a80f8d578f9077f0193fdfcb0
6
+ metadata.gz: 006d3697dafed4dca50b3c20f6cd3ade9bfc1d430b2681a489a8878cc86e274c2ede6b3976c4a8276bfcb6cd252d751d158c42ef6236273d97ab88d256aabb99
7
+ data.tar.gz: ac8367a3b773c10e927307324d0e5c2fc379c1e727efb2bb69288c0ea0d6548555201bbc6168b52b0dfd55534fa2ba2a25eabeb842c8cadbff3f7a4be5d08f35
data/CHANGELOG.md CHANGED
@@ -1,3 +1,140 @@
1
+ <a name="v1.18.1"></a>
2
+ ### v1.18.1 (2022-08-17)
3
+
4
+ #### Bug Fixes
5
+
6
+ * use send to invoke remove_method when removing as_json from Regexp ([cb29cdd](/../../commit/cb29cdd))
7
+
8
+ <a name="v1.18.0"></a>
9
+ ### v1.18.0 (2022-03-28)
10
+
11
+ #### Features
12
+
13
+ * replace term-ansicolor with rainbow ([e8b6ada](/../../commit/e8b6ada))
14
+
15
+ #### Bug Fixes
16
+
17
+ * Fixup ruby warnings (#96) ([cee7113](/../../commit/cee7113))
18
+
19
+ <a name="v1.17.0"></a>
20
+ ### v1.17.0 (2021-10-01)
21
+
22
+ #### Features
23
+
24
+ * allow SSL verification to be disabled by setting environment variable PACT_DISABLE_SSL_VERIFICATION=true ([dd39c04](/../../commit/dd39c04))
25
+
26
+ <a name="v1.16.10"></a>
27
+ ### v1.16.10 (2021-10-01)
28
+
29
+ #### Bug Fixes
30
+
31
+ * change expgen to a runtime dependency ([da81634](/../../commit/da81634))
32
+
33
+ <a name="v1.16.9"></a>
34
+ ### v1.16.9 (2021-09-30)
35
+
36
+ #### Bug Fixes
37
+
38
+ * remove randexp dependency (#91) ([794fd4e](/../../commit/794fd4e))
39
+
40
+ <a name="v1.16.8"></a>
41
+ ### v1.16.8 (2021-07-27)
42
+
43
+ #### Bug Fixes
44
+
45
+ * log HTTP request for pacts retrieved by URL when requested with verbose=true ([3288b81](/../../commit/3288b81))
46
+
47
+ <a name="v1.16.7"></a>
48
+ ### v1.16.7 (2021-01-28)
49
+
50
+ #### Bug Fixes
51
+
52
+ * dynamically parse actual query to match expected format ([a86a3e3](/../../commit/a86a3e3))
53
+
54
+ <a name="v1.16.6"></a>
55
+ ### v1.16.6 (2021-01-28)
56
+
57
+ #### Bug Fixes
58
+
59
+ * raise Pact::Error not RuntimeError when invalid constructor arguments are supplied to a Pact::Term ([d9fb8ea](/../../commit/d9fb8ea))
60
+ * update active support support for Ruby 3.0 ([6c30d42](/../../commit/6c30d42))
61
+
62
+ <a name="v1.16.5"></a>
63
+ ### v1.16.5 (2020-11-25)
64
+
65
+ #### Bug Fixes
66
+
67
+ * maintain the original string query for the provider verification while also parsing the string query into a hash to allow the matching rules to be applied correctly for use in the mock service on the consumer side ([12105dd](/../../commit/12105dd))
68
+
69
+ <a name="v1.16.4"></a>
70
+ ### v1.16.4 (2020-11-13)
71
+
72
+ #### Bug Fixes
73
+
74
+ * ensure expected and actual query strings are parsed consistently ([4e9ca9c](/../../commit/4e9ca9c))
75
+
76
+ <a name="v1.16.3"></a>
77
+ ### v1.16.3 (2020-11-10)
78
+
79
+ #### Bug Fixes
80
+
81
+ * add missing params_hash_has_key ([700efa7](/../../commit/700efa7))
82
+
83
+ <a name="v1.16.2"></a>
84
+ ### v1.16.2 (2020-11-07)
85
+
86
+ #### Bug Fixes
87
+
88
+ * removed undefined depth from query ([53a373d](/../../commit/53a373d))
89
+
90
+ <a name="v1.16.1"></a>
91
+ ### v1.16.1 (2020-11-06)
92
+
93
+ #### Bug Fixes
94
+
95
+ * add missing params_hash_type? from Rack ([3195b0a](/../../commit/3195b0a))
96
+
97
+ <a name="v1.16.0"></a>
98
+ ### v1.16.0 (2020-11-04)
99
+
100
+ #### Features
101
+
102
+ * remove runtime dependency on rspec ([aca30e2](/../../commit/aca30e2))
103
+
104
+ <a name="v1.15.5"></a>
105
+ ### v1.15.5 (2020-11-04)
106
+
107
+ #### Bug Fixes
108
+
109
+ * add missing outputs to release workflow ([d565d0f](/../../commit/d565d0f))
110
+ * try different output syntax ([b11e8fb](/../../commit/b11e8fb))
111
+
112
+ <a name="v1.15.4"></a>
113
+ ### v1.15.4 (2020-11-04)
114
+
115
+ #### Bug Fixes
116
+
117
+ * update release gem action version ([9dead58](/../../commit/9dead58))
118
+
119
+ <a name="v1.15.3"></a>
120
+ ### v1.15.3 (2020-11-04)
121
+
122
+
123
+ #### Bug Fixes
124
+
125
+ * release workflow ([4bdf8d8](/../../commit/4bdf8d8))
126
+ * not actually a fix, just triggering new release ([74038a5](/../../commit/74038a5))
127
+
128
+
129
+ <a name="v1.15.2"></a>
130
+ ### v1.15.2 (2020-11-04)
131
+
132
+
133
+ #### Bug Fixes
134
+
135
+ * parse query string to hash for v2 interactions ([faff17c](/../../commit/faff17c))
136
+
137
+
1
138
  <a name="v1.15.0"></a>
2
139
  ### v1.15.0 (2020-04-30)
3
140
 
data/README.md CHANGED
@@ -1,5 +1,5 @@
1
1
  # Pact Support
2
2
 
3
- [![Build Status](https://travis-ci.org/pact-foundation/pact-support.svg?branch=master)](https://travis-ci.org/pact-foundation/pact-support)
3
+ ![Build status](https://github.com/pact-foundation/pact-support/workflows/Test/badge.svg)
4
4
 
5
5
  Provides shared code for the Pact gems
@@ -1,6 +1,7 @@
1
1
  require 'pact/consumer_contract/request'
2
2
  require 'pact/consumer_contract/response'
3
3
  require 'pact/consumer_contract/provider_state'
4
+ require 'pact/consumer_contract/query'
4
5
  require 'pact/symbolize_keys'
5
6
  require 'pact/matching_rules'
6
7
  require 'pact/errors'
@@ -15,14 +16,28 @@ module Pact
15
16
  response = parse_response(hash['response'], options)
16
17
  provider_states = parse_provider_states(hash['providerState'] || hash['provider_state'])
17
18
  metadata = parse_metadata(hash['metadata'])
18
- Interaction.new(symbolize_keys(hash).merge(request: request,
19
- response: response,
19
+ Interaction.new(symbolize_keys(hash).merge(request: request,
20
+ response: response,
20
21
  provider_states: provider_states,
21
22
  metadata: metadata))
22
23
  end
23
24
 
24
25
  def self.parse_request request_hash, options
26
+ original_query_string = request_hash['query']
27
+ query_is_string = original_query_string.is_a?(String)
28
+ if query_is_string
29
+ request_hash = request_hash.dup
30
+ request_hash['query'] = Pact::Query.parse_string(request_hash['query'])
31
+ end
32
+ # The query has to be a hash at this stage for the matching rules to be applied
25
33
  request_hash = Pact::MatchingRules.merge(request_hash, request_hash['matchingRules'], options)
34
+ # The original query string needs to be passed in to the constructor so it can be used
35
+ # when the request is replayed. Otherwise, we loose the square brackets because they get lost
36
+ # in the translation between string => structured object, as we don't know/store which
37
+ # query string convention was used.
38
+ if query_is_string
39
+ request_hash['query'] = Pact::QueryHash.new(request_hash['query'], original_query_string, Pact::Query.parsed_as_nested?(request_hash['query']))
40
+ end
26
41
  Pact::Request::Expected.from_hash(request_hash)
27
42
  end
28
43
 
@@ -1,4 +1,6 @@
1
- require 'net/http'
1
+ require "net/http"
2
+ require "pact/configuration"
3
+ require "pact/http/authorization_header_redactor"
2
4
 
3
5
  module Pact
4
6
  module PactFile
@@ -33,7 +35,7 @@ module Pact
33
35
  def save_pactfile_to_tmp pact, name
34
36
  ::FileUtils.mkdir_p Pact.configuration.tmp_dir
35
37
  ::File.open(Pact.configuration.tmp_dir + "/#{name}", "w") { |file| file << pact}
36
- rescue Errno::EROFS => e
38
+ rescue Errno::EROFS
37
39
  # do nothing, probably on RunKit
38
40
  end
39
41
 
@@ -54,9 +56,9 @@ module Pact
54
56
  def get_remote_with_retry(uri_string, options)
55
57
  uri = URI(uri_string)
56
58
  if uri.userinfo
57
- options[:username] = uri.user unless options[:username]
58
- options[:password] = uri.password unless options[:password]
59
- end
59
+ options[:username] = uri.user unless options[:username]
60
+ options[:password] = uri.password unless options[:password]
61
+ end
60
62
  ((options[:retry_limit] || RETRY_LIMIT) + 1).times do |i|
61
63
  begin
62
64
  response = get_remote(uri, options)
@@ -81,7 +83,7 @@ module Pact
81
83
  request = Net::HTTP::Get.new(uri)
82
84
  request = prepare_auth(request, options) if options[:username] || options[:token]
83
85
 
84
- http = prepare_request(uri)
86
+ http = prepare_request(uri, options)
85
87
  response = perform_http_request(http, request, options)
86
88
 
87
89
  if response.is_a?(Net::HTTPRedirection)
@@ -89,7 +91,7 @@ module Pact
89
91
  req = Net::HTTP::Get.new(uri)
90
92
  req = prepare_auth(req, options) if options[:username] || options[:token]
91
93
 
92
- http = prepare_request(uri)
94
+ http = prepare_request(uri, options)
93
95
  response = perform_http_request(http, req, options)
94
96
  end
95
97
  response
@@ -101,11 +103,18 @@ module Pact
101
103
  request
102
104
  end
103
105
 
104
- def prepare_request(uri)
106
+ def prepare_request(uri, options)
105
107
  http = Net::HTTP.new(uri.host, uri.port, :ENV)
106
108
  http.use_ssl = (uri.scheme == 'https')
107
109
  http.ca_file = ENV['SSL_CERT_FILE'] if ENV['SSL_CERT_FILE'] && ENV['SSL_CERT_FILE'] != ''
108
110
  http.ca_path = ENV['SSL_CERT_DIR'] if ENV['SSL_CERT_DIR'] && ENV['SSL_CERT_DIR'] != ''
111
+ http.set_debug_output(Pact::Http::AuthorizationHeaderRedactor.new(Pact.configuration.output_stream)) if verbose?(options)
112
+ if disable_ssl_verification?
113
+ if verbose?(options)
114
+ Pact.configuration.output_stream.puts("SSL verification is disabled")
115
+ end
116
+ http.verify_mode = OpenSSL::SSL::VERIFY_NONE
117
+ end
109
118
  http
110
119
  end
111
120
 
@@ -136,5 +145,13 @@ module Pact
136
145
  def windows_safe(uri)
137
146
  uri.start_with?("http") ? uri : uri.gsub("\\", File::SEPARATOR)
138
147
  end
148
+
149
+ def verbose?(options)
150
+ options[:verbose] || ENV['VERBOSE'] == 'true'
151
+ end
152
+
153
+ def disable_ssl_verification?
154
+ ENV['PACT_DISABLE_SSL_VERIFICATION'] == 'true' || ENV['PACT_BROKER_DISABLE_SSL_VERIFICATION'] == 'true'
155
+ end
139
156
  end
140
157
  end
@@ -3,6 +3,11 @@ require 'pact/consumer_contract/query_string'
3
3
 
4
4
  module Pact
5
5
  class Query
6
+ DEFAULT_SEP = /[&;] */n
7
+ COMMON_SEP = { ";" => /[;] */n, ";," => /[;,] */n, "&" => /[&] */n }
8
+
9
+ class NestedQuery < Hash; end
10
+
6
11
  def self.create query
7
12
  if query.is_a? Hash
8
13
  Pact::QueryHash.new(query)
@@ -10,5 +15,124 @@ module Pact
10
15
  Pact::QueryString.new(query)
11
16
  end
12
17
  end
18
+
19
+ def self.is_a_query_object?(object)
20
+ object.is_a?(Pact::QueryHash) || object.is_a?(Pact::QueryString)
21
+ end
22
+
23
+ def self.parsed_as_nested?(object)
24
+ object.is_a?(NestedQuery)
25
+ end
26
+
27
+ def self.parse_string query_string
28
+ parsed_query = parse_string_as_non_nested_query(query_string)
29
+
30
+ # If Rails nested params...
31
+ if parsed_query.keys.any?{ | key| key =~ /\[.*\]/ }
32
+ parse_string_as_nested_query(query_string)
33
+ else
34
+ parsed_query.each_with_object({}) do | (key, value), new_hash |
35
+ new_hash[key] = [*value]
36
+ end
37
+ end
38
+ end
39
+
40
+ # Ripped from Rack to avoid adding an unnecessary dependency, thank you Rack
41
+ # https://github.com/rack/rack/blob/649c72bab9e7b50d657b5b432d0c205c95c2be07/lib/rack/utils.rb
42
+ def self.parse_string_as_non_nested_query(qs, d = nil, &unescaper)
43
+ unescaper ||= method(:unescape)
44
+
45
+ params = {}
46
+
47
+ (qs || '').split(d ? (COMMON_SEP[d] || /[#{d}] */n) : DEFAULT_SEP).each do |p|
48
+ next if p.empty?
49
+ k, v = p.split('=', 2).map!(&unescaper)
50
+
51
+ if cur = params[k]
52
+ if cur.class == Array
53
+ params[k] << v
54
+ else
55
+ params[k] = [cur, v]
56
+ end
57
+ else
58
+ params[k] = v
59
+ end
60
+ end
61
+
62
+ return params.to_h
63
+ end
64
+
65
+ def self.parse_string_as_nested_query(qs, d = nil)
66
+ params = {}
67
+
68
+ unless qs.nil? || qs.empty?
69
+ (qs || '').split(d ? (COMMON_SEP[d] || /[#{d}] */n) : DEFAULT_SEP).each do |p|
70
+ k, v = p.split('=', 2).map! { |s| unescape(s) }
71
+
72
+ normalize_params(params, k, v)
73
+ end
74
+ end
75
+
76
+ return NestedQuery[params.to_h]
77
+ end
78
+
79
+ def self.normalize_params(params, name, v)
80
+ name =~ %r(\A[\[\]]*([^\[\]]+)\]*)
81
+ k = $1 || ''
82
+ after = $' || ''
83
+
84
+ if k.empty?
85
+ if !v.nil? && name == "[]"
86
+ return Array(v)
87
+ else
88
+ return
89
+ end
90
+ end
91
+
92
+ if after == ''
93
+ params[k] = v
94
+ elsif after == "["
95
+ params[name] = v
96
+ elsif after == "[]"
97
+ params[k] ||= []
98
+ raise ParameterTypeError, "expected Array (got #{params[k].class.name}) for param `#{k}'" unless params[k].is_a?(Array)
99
+ params[k] << v
100
+ elsif after =~ %r(^\[\]\[([^\[\]]+)\]$) || after =~ %r(^\[\](.+)$)
101
+ child_key = $1
102
+ params[k] ||= []
103
+ raise ParameterTypeError, "expected Array (got #{params[k].class.name}) for param `#{k}'" unless params[k].is_a?(Array)
104
+ if params_hash_type?(params[k].last) && !params_hash_has_key?(params[k].last, child_key)
105
+ normalize_params(params[k].last, child_key, v)
106
+ else
107
+ params[k] << normalize_params({}, child_key, v)
108
+ end
109
+ else
110
+ params[k] ||= {}
111
+ raise ParameterTypeError, "expected Hash (got #{params[k].class.name}) for param `#{k}'" unless params_hash_type?(params[k])
112
+ params[k] = normalize_params(params[k], after, v)
113
+ end
114
+
115
+ params
116
+ end
117
+
118
+ def self.params_hash_type?(obj)
119
+ obj.is_a?(Hash)
120
+ end
121
+
122
+ def self.params_hash_has_key?(hash, key)
123
+ return false if key =~ /\[\]/
124
+
125
+ key.split(/[\[\]]+/).inject(hash) do |h, part|
126
+ next h if part == ''
127
+ return false unless params_hash_type?(h) && h.key?(part)
128
+ h[part]
129
+ end
130
+
131
+ true
132
+ end
133
+
134
+ def self.unescape(s, encoding = Encoding::UTF_8)
135
+ URI.decode_www_form_component(s, encoding)
136
+ end
13
137
  end
14
138
  end
@@ -8,8 +8,20 @@ module Pact
8
8
  include ActiveSupportSupport
9
9
  include SymbolizeKeys
10
10
 
11
- def initialize(query)
11
+ attr_reader :original_string
12
+
13
+ def initialize(query, original_string = nil, nested = false)
12
14
  @hash = query.nil? ? query : convert_to_hash_of_arrays(query)
15
+ @original_string = original_string
16
+ @nested = nested
17
+ end
18
+
19
+ def nested?
20
+ @nested
21
+ end
22
+
23
+ def any_key_contains_square_brackets?
24
+ query.keys.any?{ |key| key =~ /\[.*\]/ }
13
25
  end
14
26
 
15
27
  def as_json(opts = {})
@@ -32,7 +44,14 @@ module Pact
32
44
  # from the actual query string.
33
45
  def difference(other)
34
46
  require 'pact/matchers' # avoid recursive loop between this file, pact/reification and pact/matchers
35
- Pact::Matchers.diff(query, symbolize_keys(CGI::parse(other.query)), allow_unexpected_keys: false)
47
+
48
+ if any_key_contains_square_brackets?
49
+ other_query_hash_non_nested = Query.parse_string_as_non_nested_query(other.query)
50
+ Pact::Matchers.diff(query, convert_to_hash_of_arrays(other_query_hash_non_nested), allow_unexpected_keys: false)
51
+ else
52
+ other_query_hash = Query.parse_string(other.query)
53
+ Pact::Matchers.diff(query, symbolize_keys(convert_to_hash_of_arrays(other_query_hash)), allow_unexpected_keys: false)
54
+ end
36
55
  end
37
56
 
38
57
  def query
@@ -0,0 +1,32 @@
1
+ require "delegate"
2
+
3
+ module Pact
4
+ module Http
5
+ class AuthorizationHeaderRedactor < SimpleDelegator
6
+ def puts(*args)
7
+ __getobj__().puts(*redact_args(args))
8
+ end
9
+
10
+ def print(*args)
11
+ __getobj__().puts(*redact_args(args))
12
+ end
13
+
14
+ def <<(*args)
15
+ __getobj__().send(:<<, *redact_args(args))
16
+ end
17
+
18
+ private
19
+
20
+ attr_reader :redactions
21
+
22
+ def redact_args(args)
23
+ args.collect{ | s| redact(s) }
24
+ end
25
+
26
+ def redact(string)
27
+ return string unless string.is_a?(String)
28
+ string.gsub(/Authorization: .*\\r\\n/, "Authorization: [redacted]\\r\\n")
29
+ end
30
+ end
31
+ end
32
+ end
@@ -1,13 +1,11 @@
1
1
  require 'pact/shared/active_support_support'
2
- require 'term/ansicolor'
2
+ require 'rainbow'
3
3
 
4
4
  module Pact
5
5
  module Matchers
6
6
  class EmbeddedDiffFormatter
7
7
 
8
8
  include Pact::ActiveSupportSupport
9
- C = ::Term::ANSIColor
10
-
11
9
 
12
10
  EXPECTED = /"EXPECTED([A-Z_]*)":/
13
11
 
@@ -53,7 +51,7 @@ module Pact
53
51
  end
54
52
 
55
53
  def coloured_key match, colour
56
- '"' + C.color(colour, match.downcase.gsub(/^"|":$/,'')) + '":'
54
+ '"' + Rainbow(match.downcase.gsub(/^"|":$/,'')).send(colour) + '":'
57
55
  end
58
56
 
59
57
  end
@@ -42,7 +42,7 @@ module Pact
42
42
  end
43
43
 
44
44
  def recurse_hash hash, path
45
- recursed = hash.each_with_object({}) do | (k, v), new_hash |
45
+ hash.each_with_object({}) do | (k, v), new_hash |
46
46
  new_path = path + "['#{k}']"
47
47
  new_hash[k] = recurse(v, new_path)
48
48
  end
@@ -1,4 +1,4 @@
1
- require 'randexp'
1
+ require 'expgen'
2
2
  require 'pact/term'
3
3
  require 'pact/something_like'
4
4
  require 'pact/array_like'
@@ -13,8 +13,10 @@ module Pact
13
13
 
14
14
  def self.from_term(term)
15
15
  case term
16
- when Pact::Term, Regexp, Pact::SomethingLike, Pact::ArrayLike
16
+ when Pact::Term, Pact::SomethingLike, Pact::ArrayLike
17
17
  from_term(term.generate)
18
+ when Regexp
19
+ from_term(Expgen.gen(term))
18
20
  when Hash
19
21
  term.inject({}) do |mem, (key,t)|
20
22
  mem[key] = from_term(t)
@@ -27,15 +29,19 @@ module Pact
27
29
  when Pact::QueryString
28
30
  from_term(term.query)
29
31
  when Pact::QueryHash
30
- from_term(term.query).map { |k, v|
31
- if v.nil?
32
- k
33
- elsif v.is_a?(Array) #For cases where there are multiple instance of the same parameter
34
- v.map { |x| "#{k}=#{escape(x)}"}.join('&')
35
- else
36
- "#{k}=#{escape(v)}"
37
- end
38
- }.join('&')
32
+ if term.original_string
33
+ term.original_string
34
+ else
35
+ from_term(term.query).map { |k, v|
36
+ if v.nil?
37
+ k
38
+ elsif v.is_a?(Array) #For cases where there are multiple instance of the same parameter
39
+ v.map { |x| "#{k}=#{escape(x)}"}.join('&')
40
+ else
41
+ "#{k}=#{escape(v)}"
42
+ end
43
+ }.join('&')
44
+ end
39
45
  when Pact::StringWithMatchingRules
40
46
  String.new(term)
41
47
  else
data/lib/pact/rspec.rb CHANGED
@@ -1,4 +1,3 @@
1
- require 'rspec'
2
1
  # This is horrible, must work out a better way of doing this
3
2
  module Pact
4
3
  module RSpec
@@ -19,7 +18,6 @@ module Pact
19
18
  require 'pact/provider/rspec/formatter_rspec_2'
20
19
  Pact::Provider::RSpec::Formatter2
21
20
  end
22
-
23
21
  end
24
22
 
25
23
  def self.full_description example
@@ -31,11 +29,11 @@ module Pact
31
29
  end
32
30
 
33
31
  def self.is_rspec_3
34
- ::RSpec::Core::Formatters.respond_to?(:register)
32
+ defined?(::RSpec) && ::RSpec::Core::Formatters.respond_to?(:register)
35
33
  end
36
34
 
37
35
  def self.is_rspec_2
38
- !is_rspec_3
36
+ defined?(::RSpec) && !is_rspec_3
39
37
  end
40
38
 
41
39
  def self.with_rspec_3
@@ -2,22 +2,28 @@
2
2
 
3
3
  module Pact
4
4
  module ActiveSupportSupport
5
-
6
5
  extend self
7
6
 
8
7
  def fix_all_the_things thing
9
- if thing.is_a?(Regexp)
10
- fix_regexp(thing)
11
- elsif thing.is_a?(Array)
12
- thing.each{ | it | fix_all_the_things it }
13
- elsif thing.is_a?(Hash)
14
- thing.values.each{ | it | fix_all_the_things it }
15
- elsif thing.class.name.start_with?("Pact")
16
- thing.instance_variables.collect{ | iv_name | thing.instance_variable_get(iv_name)}.each do | iv |
17
- fix_all_the_things iv
8
+ if defined?(ActiveSupport)
9
+ if thing.is_a?(Regexp)
10
+ fix_regexp(thing)
11
+ elsif thing.is_a?(Array)
12
+ thing.collect{ | it | fix_all_the_things it }
13
+ elsif thing.is_a?(Hash)
14
+ thing.each_with_object({}) { | (k, v), new_hash | new_hash[k] = fix_all_the_things(v) }
15
+ elsif thing.is_a?(Pact::Term)
16
+ # matcher Regexp is fixed in its own as_json method
17
+ thing
18
+ elsif thing.class.name.start_with?("Pact")
19
+ warn_about_regexp(thing)
20
+ thing
21
+ else
22
+ thing
18
23
  end
24
+ else
25
+ thing
19
26
  end
20
- thing
21
27
  end
22
28
 
23
29
  # ActiveSupport JSON overwrites (i.e. TRAMPLES) the json methods of the Regexp class directly
@@ -27,10 +33,7 @@ module Pact
27
33
  # original as_json to the Regexp instances in the ConsumerContract before we write them to the
28
34
  # pact file. If anyone can find a better way, please submit a pull request ASAP!
29
35
  def fix_regexp regexp
30
- def regexp.as_json options = {}
31
- {:json_class => 'Regexp', "o" => self.options, "s" => self.source }
32
- end
33
- regexp
36
+ {:json_class => 'Regexp', "o" => regexp.options, "s" => regexp.source }
34
37
  end
35
38
 
36
39
  # Having Active Support JSON loaded somehow kills the formatting of pretty_generate for objects.
@@ -49,5 +52,14 @@ module Pact
49
52
  json.gsub(/\\u([0-9A-Za-z]{4})/) {|s| [$1.to_i(16)].pack("U")}
50
53
  end
51
54
 
55
+ def warn_about_regexp(thing)
56
+ thing.instance_variables.each do | iv_name |
57
+ iv = thing.instance_variable_get(iv_name)
58
+ if iv.is_a?(Regexp)
59
+ require 'pact/configuration'
60
+ Pact.configuration.error_stream.puts("WARN: Instance variable #{iv_name} for class #{thing.class.name} is a Regexp and isn't been serialized properly. Please raise an issue at https://github.com/pact-foundation/pact-support/issues/new.")
61
+ end
62
+ end
63
+ end
52
64
  end
53
65
  end
@@ -3,9 +3,7 @@ require 'pact/consumer_contract/headers'
3
3
  require 'pact/consumer_contract/query'
4
4
 
5
5
  module Pact
6
-
7
6
  module Request
8
-
9
7
  class Base
10
8
  include Pact::SymbolizeKeys
11
9
 
@@ -16,7 +14,7 @@ module Pact
16
14
  @path = path
17
15
  @headers = Hash === headers ? Headers.new(headers) : headers # Could be a NullExpectation - TODO make this more elegant
18
16
  @body = body
19
- @query = is_unspecified?(query) ? query : Pact::Query.create(query)
17
+ set_query(query)
20
18
  end
21
19
 
22
20
  def to_hash
@@ -92,6 +90,17 @@ module Pact
92
90
  (query.nil? || query.empty?) ? '' : "?#{Pact::Reification.from_term(query)}"
93
91
  end
94
92
 
93
+ def set_query(query)
94
+ @query = if is_unspecified?(query)
95
+ query
96
+ else
97
+ if Pact::Query.is_a_query_object?(query)
98
+ query
99
+ else
100
+ Pact::Query.create(query)
101
+ end
102
+ end
103
+ end
95
104
  end
96
105
  end
97
- end
106
+ end
@@ -1,5 +1,5 @@
1
1
  module Pact
2
2
  module Support
3
- VERSION = "1.15.1"
3
+ VERSION = "1.18.1"
4
4
  end
5
5
  end
data/lib/pact/term.rb CHANGED
@@ -1,5 +1,7 @@
1
1
  require 'pact/shared/active_support_support'
2
+ Regexp.send(:remove_method, :as_json) if Regexp.method_defined?(:as_json)
2
3
  require 'json/add/regexp'
4
+ require 'pact/errors'
3
5
 
4
6
  module Pact
5
7
  class Term
@@ -25,13 +27,13 @@ module Pact
25
27
  def initialize(attributes = {})
26
28
  @generate = attributes[:generate]
27
29
  @matcher = attributes[:matcher]
28
- raise "Please specify a matcher for the Term" unless @matcher != nil
29
- raise "Please specify a value to generate for the Term" unless @generate != nil
30
- raise "Value to generate \"#{@generate}\" does not match regular expression #{@matcher.inspect}" unless @generate =~ @matcher
30
+ raise Pact::Error.new("Please specify a matcher for the Term") unless @matcher != nil
31
+ raise Pact::Error.new("Please specify a value to generate for the Term") unless @generate != nil
32
+ raise Pact::Error.new("Value to generate \"#{@generate}\" does not match regular expression #{@matcher.inspect}") unless @generate =~ @matcher
31
33
  end
32
34
 
33
35
  def to_hash
34
- { json_class: self.class.name, data: { generate: generate, matcher: fix_regexp(matcher)} }
36
+ { json_class: self.class.name, data: { generate: generate, matcher: fix_regexp(matcher) } }
35
37
  end
36
38
 
37
39
  def as_json(options = {})
data/lib/tasks/pact.rake CHANGED
@@ -15,12 +15,12 @@ namespace :pact do
15
15
 
16
16
  desc "Verifies the pact at the given URI against this service provider."
17
17
  task 'verify:at', :pact_uri do | t, args |
18
- require 'term/ansicolor'
18
+ require 'rainbow'
19
19
  require 'pact/tasks/task_helper'
20
20
 
21
21
  include Pact::TaskHelper
22
22
 
23
- abort(::Term::ANSIColor.red("Please provide a pact URI. eg. rake pact:verify:at[../my-consumer/spec/pacts/my_consumer-my_provider.json]")) unless args[:pact_uri]
23
+ abort(Rainbow("Please provide a pact URI. eg. rake pact:verify:at[../my-consumer/spec/pacts/my_consumer-my_provider.json]").red) unless args[:pact_uri]
24
24
  handle_verification_failure do
25
25
  execute_pact_verify args[:pact_uri]
26
26
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pact-support
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.15.1
4
+ version: 1.18.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - James Fraser
@@ -9,81 +9,101 @@ authors:
9
9
  - Brent Snook
10
10
  - Ronald Holshausen
11
11
  - Beth Skurrie
12
- autorequire:
12
+ autorequire:
13
13
  bindir: bin
14
14
  cert_chain: []
15
- date: 2020-07-16 00:00:00.000000000 Z
15
+ date: 2022-08-16 00:00:00.000000000 Z
16
16
  dependencies:
17
17
  - !ruby/object:Gem::Dependency
18
- name: randexp
18
+ name: rainbow
19
19
  requirement: !ruby/object:Gem::Requirement
20
20
  requirements:
21
21
  - - "~>"
22
22
  - !ruby/object:Gem::Version
23
- version: 0.1.7
23
+ version: 3.1.1
24
24
  type: :runtime
25
25
  prerelease: false
26
26
  version_requirements: !ruby/object:Gem::Requirement
27
27
  requirements:
28
28
  - - "~>"
29
29
  - !ruby/object:Gem::Version
30
- version: 0.1.7
30
+ version: 3.1.1
31
31
  - !ruby/object:Gem::Dependency
32
- name: rspec
32
+ name: awesome_print
33
33
  requirement: !ruby/object:Gem::Requirement
34
34
  requirements:
35
- - - ">="
35
+ - - "~>"
36
36
  - !ruby/object:Gem::Version
37
- version: '2.14'
37
+ version: '1.9'
38
38
  type: :runtime
39
39
  prerelease: false
40
40
  version_requirements: !ruby/object:Gem::Requirement
41
41
  requirements:
42
- - - ">="
42
+ - - "~>"
43
43
  - !ruby/object:Gem::Version
44
- version: '2.14'
44
+ version: '1.9'
45
45
  - !ruby/object:Gem::Dependency
46
- name: term-ansicolor
46
+ name: diff-lcs
47
47
  requirement: !ruby/object:Gem::Requirement
48
48
  requirements:
49
49
  - - "~>"
50
50
  - !ruby/object:Gem::Version
51
- version: '1.0'
51
+ version: '1.4'
52
52
  type: :runtime
53
53
  prerelease: false
54
54
  version_requirements: !ruby/object:Gem::Requirement
55
55
  requirements:
56
56
  - - "~>"
57
57
  - !ruby/object:Gem::Version
58
- version: '1.0'
58
+ version: '1.4'
59
59
  - !ruby/object:Gem::Dependency
60
- name: awesome_print
60
+ name: expgen
61
61
  requirement: !ruby/object:Gem::Requirement
62
62
  requirements:
63
63
  - - "~>"
64
64
  - !ruby/object:Gem::Version
65
- version: '1.1'
65
+ version: '0.1'
66
66
  type: :runtime
67
67
  prerelease: false
68
68
  version_requirements: !ruby/object:Gem::Requirement
69
69
  requirements:
70
70
  - - "~>"
71
71
  - !ruby/object:Gem::Version
72
- version: '1.1'
72
+ version: '0.1'
73
+ - !ruby/object:Gem::Dependency
74
+ name: rspec
75
+ requirement: !ruby/object:Gem::Requirement
76
+ requirements:
77
+ - - ">="
78
+ - !ruby/object:Gem::Version
79
+ version: '2.14'
80
+ - - "<"
81
+ - !ruby/object:Gem::Version
82
+ version: '4.0'
83
+ type: :development
84
+ prerelease: false
85
+ version_requirements: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '2.14'
90
+ - - "<"
91
+ - !ruby/object:Gem::Version
92
+ version: '4.0'
73
93
  - !ruby/object:Gem::Dependency
74
94
  name: rake
75
95
  requirement: !ruby/object:Gem::Requirement
76
96
  requirements:
77
97
  - - "~>"
78
98
  - !ruby/object:Gem::Version
79
- version: 10.0.3
99
+ version: '13.0'
80
100
  type: :development
81
101
  prerelease: false
82
102
  version_requirements: !ruby/object:Gem::Requirement
83
103
  requirements:
84
104
  - - "~>"
85
105
  - !ruby/object:Gem::Version
86
- version: 10.0.3
106
+ version: '13.0'
87
107
  - !ruby/object:Gem::Dependency
88
108
  name: webmock
89
109
  requirement: !ruby/object:Gem::Requirement
@@ -196,7 +216,7 @@ dependencies:
196
216
  - - "~>"
197
217
  - !ruby/object:Gem::Version
198
218
  version: '0.5'
199
- description:
219
+ description:
200
220
  email:
201
221
  - james.fraser@alumni.swinburne.edu
202
222
  - sergei.matheson@gmail.com
@@ -234,6 +254,7 @@ files:
234
254
  - lib/pact/consumer_contract/string_with_matching_rules.rb
235
255
  - lib/pact/errors.rb
236
256
  - lib/pact/helpers.rb
257
+ - lib/pact/http/authorization_header_redactor.rb
237
258
  - lib/pact/logging.rb
238
259
  - lib/pact/matchers.rb
239
260
  - lib/pact/matchers/actual_type.rb
@@ -283,7 +304,7 @@ homepage: https://github.com/pact-foundation/pact-support
283
304
  licenses:
284
305
  - MIT
285
306
  metadata: {}
286
- post_install_message:
307
+ post_install_message:
287
308
  rdoc_options: []
288
309
  require_paths:
289
310
  - lib
@@ -298,8 +319,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
298
319
  - !ruby/object:Gem::Version
299
320
  version: '0'
300
321
  requirements: []
301
- rubygems_version: 3.1.4
302
- signing_key:
322
+ rubygems_version: 3.3.20
323
+ signing_key:
303
324
  specification_version: 4
304
325
  summary: Shared code for Pact gems
305
326
  test_files: []