nice_http 1.10.1 → 1.11.0

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: eba012b6fef9f47963dc8d88eef3f56138ce1ccdbd90a781d4aa0c399069b71f
4
- data.tar.gz: 0a0c45f8082eb7fe65a6aa68eec0a7af0425502a911ec60d972e5621a2b9d7b9
3
+ metadata.gz: '08a3b0309aabfc6296d1bb905ae4dda3ea550702a08d6f5bc96aae80acbaf8b3'
4
+ data.tar.gz: c4b6b1b7e01b548d369b0acff34acf8a36f1b0cb9bad682aa4e293a52a2296ad
5
5
  SHA512:
6
- metadata.gz: 0ee35fad14ffd5afee69bad03e927c860495d92b6772ab3060572e3353d07a124bf46ae366fa82217b6a076c693d10135cc40dc26f9c69368c72de31e591ef79
7
- data.tar.gz: b67acb7553b2968bec31567578da6513e3819d274ae443a2f6ab30b9614bbe2782c81d0684324c4a3cd15f7ba01b0656fa0bbda0c8a59f03885df695180597b7
6
+ metadata.gz: 013f23c8d0df421fa63f8c00cd6948930040d0e4743d9a40a36c529e3b8a37243e8d6d5dd7017f3141e68a5e53c8b9d3ae044980074f91bf23ff2e367d67ee28
7
+ data.tar.gz: 02353a935cf0674d0ca05e3166f61775087debdb4595258d8508b17f5a99d0106c96f827c4dee9532e777a61f74c08236097754b75e6b1f714687e0a39d29891
data/README.md CHANGED
@@ -20,7 +20,7 @@ NiceHttp is able to use hashes as requests data and uses the Request Hash struct
20
20
 
21
21
  **On the next link you have a full example using nice_http and RSpec to test REST APIs, Uber API and Reqres API: https://github.com/MarioRuiz/api-testing-example**
22
22
 
23
- **Related gems:** NiceHttp uses [nice_hash](https://github.com/MarioRuiz/nice_hash) (v1.19+) for request/response hashes (e.g. `resp.data.json`, `set_values`, `nice_merge`) and for generating headers. [string_pattern](https://github.com/MarioRuiz/string_pattern) (v2.4+) is used by nice_hash for pattern-based string generation and validation. To generate random or pattern-based request data, see the [nice_hash documentation](https://github.com/MarioRuiz/nice_hash). Example: 1000 valid requests + 800 with one wrong field to test validation — [gist](https://gist.github.com/MarioRuiz/824d7a462b62fd85f02c1a09455deefb).
23
+ **Related gems:** NiceHttp uses [nice_hash](https://github.com/MarioRuiz/nice_hash) (v1.21+) for request/response hashes (e.g. `resp.data.json`, `set_values`, `nice_merge`) and for generating headers. [string_pattern](https://github.com/MarioRuiz/string_pattern) (v2.5+) is used by nice_hash for pattern-based string generation and validation. To generate random or pattern-based request data, see the [nice_hash documentation](https://github.com/MarioRuiz/nice_hash). Example: 1000 valid requests + 800 with one wrong field to test validation — [gist](https://gist.github.com/MarioRuiz/824d7a462b62fd85f02c1a09455deefb). Upgrading from nice_http 1.10: see [Compatibility with nice_hash 1.21](#compatibility-with-nice_hash-121).
24
24
 
25
25
  # Table of Contents
26
26
 
@@ -44,6 +44,7 @@ NiceHttp is able to use hashes as requests data and uses the Request Hash struct
44
44
  - [Http stats](#http-stats)
45
45
  - [Testing with generated data](#testing-with-generated-data)
46
46
  - [Validating API responses](#validating-api-responses)
47
+ - [Compatibility with nice_hash 1.21](#compatibility-with-nice_hash-121)
47
48
  - [Tips](#tips)
48
49
  - [Download a file](#download-a-file)
49
50
  - [Send multipart content](#send-multipart-content)
@@ -758,7 +759,7 @@ This will generate an items key that will contain an array of the values you add
758
759
 
759
760
  When you build request hashes with [nice_hash](https://github.com/MarioRuiz/nice_hash) patterns (in `data`, `headers`, or `values_for`), you can:
760
761
 
761
- * **Reproducible tests:** Use `seed` so the same request is generated every time:
762
+ * **Reproducible tests:** Use `seed` so the same request is generated every time. Strings from a seed in nice_hash 1.19 will not match 1.21. `:uuid`, `:iban` and `:luhn` are not produced from the seed.
762
763
  ```ruby
763
764
  req = { path: "/api/users", data: { name: :"10-20:L", email: :"20-40:@" } }
764
765
  resp = http.post req.generate(seed: 42) # same payload every run
@@ -771,10 +772,26 @@ When you build request hashes with [nice_hash](https://github.com/MarioRuiz/nice
771
772
  requests.each { |r| http.post r }
772
773
  ```
773
774
 
774
- * **UUIDs:** Use the `:uuid` shorthand (string_pattern 2.4+) in your request data:
775
+ * **Shorthands on send:** A pattern symbol in `data`, in a nested hash, in an array of hashes, or in that request's headers is expanded on each call. Strings are left as written, so `"10:N"` is sent as the characters `10:N`. A symbol that is not a pattern, such as `:admin`, is sent as the text `"admin"`.
775
776
  ```ruby
776
- resp = http.post(path: "/api/items", data: { id: :uuid, name: "Item" })
777
+ resp = http.post({
778
+ path: "/api/items",
779
+ data: {
780
+ id: :uuid,
781
+ email: :email,
782
+ iban: [:iban, "DE"],
783
+ card: [:luhn, 15],
784
+ tags: [:"3:L"],
785
+ age: 18..30,
786
+ created: DateTime,
787
+ active: Boolean,
788
+ token: /[A-Z0-9]{8}/,
789
+ code: "10:N",
790
+ role: :admin
791
+ }
792
+ })
777
793
  ```
794
+ The same values inside `values_for` are expanded after they are copied into `data`. Connection headers are still generated once, when the client is created, so a pattern there stays the same for every request on that client. A one-element pattern array in those headers becomes 1 to 5 strings for the life of the connection. A pattern header passed on a single request is generated again on the next request.
778
795
 
779
796
  ## Validating API responses
780
797
 
@@ -792,7 +809,23 @@ You can validate JSON responses against a structure or patterns using [nice_hash
792
809
  # => { "user.name" => { expected: "Alice", got: "Bob" } } or {}
793
810
  ```
794
811
 
795
- * **Pattern validation:** If your expected structure uses nice_hash patterns (e.g. `:"10:N"`, ranges), use `validate` to check that response values match those patterns.
812
+ * **Pattern validation:** `NiceHttp.validate_response` compares the shape and, when the expected value is a pattern symbol, shorthand (`:uuid`, `:email`, `:iban`, `:luhn`), checksum pair (`[:iban, "DE"]`, `[:luhn, 15]`), one-element pattern array, range, regexp, `DateTime` or `Boolean`, checks that the response value matches. String keys and symbol keys are equivalent. A plain string in the expected structure is not treated as a pattern. A missing key still fails. `explain:` is present only when a pattern fails.
813
+ ```ruby
814
+ result = NiceHttp.validate_response(resp, { "id" => :uuid, email: :email }, explain: true)
815
+ result[:ok] # => true / false
816
+ result[:explain] # only when a pattern fails: { email: { valid:, errors:, message:, index: } }
817
+ ```
818
+
819
+ ## Compatibility with nice_hash 1.21
820
+
821
+ nice_http 1.11 requires nice_hash 1.21 and string_pattern 2.5 (Ruby >= 3.0).
822
+
823
+ * `generate(seed:)` / `generate_n(seed:)` do not repeat the strings from nice_hash 1.19. Do not assert `:uuid`, `:iban` or `:luhn` from a seed.
824
+ * `StringPattern.block_list` matches literals. Set `StringPattern.block_list_regexp = true` when the list holds regular expressions.
825
+ * A `Regexp` pattern must match the whole value.
826
+ * `[:"3:L"]` generates 1 to 5 strings, including in connection headers.
827
+ * Pattern symbols and shorthands in a request body or request header are expanded when the request is sent. `"10:N"` and `"a|b"` are not.
828
+ * `validate_response` can return `ok: true` for string keys, and for pattern placeholders whose value matches, where 1.10 returned `ok: false`.
796
829
 
797
830
  ## Tips
798
831
 
@@ -11,7 +11,7 @@ module NiceHttpManageRequest
11
11
  ######################################################
12
12
  def manage_request(*arguments_param)
13
13
  if arguments_param.size == 1 and arguments_param[0].kind_of?(Hash)
14
- arguments = [arguments_param[0].deep_copy()]
14
+ arguments = [NiceHttpUtils.copy_request(arguments_param[0])]
15
15
  else
16
16
  arguments = arguments_param
17
17
  end
@@ -146,16 +146,16 @@ module NiceHttpManageRequest
146
146
  values_for_orig = {}
147
147
  if @defaults_request.key?(:values_for) and @defaults_request.is_a?(Hash) and @defaults_request[:values_for].size > 0
148
148
  if arguments[0].include?(:values_for)
149
- values_for_orig = arguments[0][:values_for].deep_copy
149
+ values_for_orig = NiceHttpUtils.copy_request(arguments[0][:values_for])
150
150
  arguments[0][:values_for] = @defaults_request[:values_for].nice_merge(arguments[0][:values_for])
151
151
  else
152
- arguments[0][:values_for] = @defaults_request[:values_for].deep_copy
152
+ arguments[0][:values_for] = NiceHttpUtils.copy_request(@defaults_request[:values_for])
153
153
  end
154
154
  end
155
155
 
156
156
  if @values_for.size > 0
157
157
  if arguments[0][:values_for].nil?
158
- arguments[0][:values_for] = @values_for.deep_copy
158
+ arguments[0][:values_for] = NiceHttpUtils.copy_request(@values_for)
159
159
  else
160
160
  arguments[0][:values_for] = @values_for.nice_merge(arguments[0][:values_for])
161
161
  end
@@ -186,13 +186,14 @@ module NiceHttpManageRequest
186
186
  }
187
187
  end
188
188
  elsif data.kind_of?(Hash)
189
- data_orig = data.deep_copy
189
+ data_orig = NiceHttpUtils.copy_request(data)
190
190
  data.nice_merge!(@defaults_request[:data]) if @defaults_request.key?(:data)
191
191
  data = NiceHttpUtils.set_lambdas(data, data_orig)
192
192
 
193
193
  if arguments[0].include?(:values_for)
194
194
  data = data.set_values(arguments[0][:values_for])
195
195
  end
196
+ data = NiceHttpUtils.expand_patterns(data)
196
197
  data = data.to_json()
197
198
 
198
199
  elsif data.kind_of?(Array)
@@ -213,7 +214,7 @@ module NiceHttpManageRequest
213
214
  end
214
215
  data_arr.push(data_n)
215
216
  }
216
- data = data_arr.to_json()
217
+ data = NiceHttpUtils.expand_patterns(data_arr).to_json()
217
218
  else
218
219
  @logger.fatal("Wrong format on request application/json, be sure is a Hash, Array of Hashes or JSON string")
219
220
  return :error, :error, :error
@@ -254,6 +255,7 @@ module NiceHttpManageRequest
254
255
  end
255
256
  data_s = data_s.to_s().gsub("<", "&lt;")
256
257
  end
258
+ headers_t = NiceHttpUtils.expand_patterns(headers_t) if headers_t.is_a?(Hash)
257
259
  if headers_t.keys.include?("Accept-Encoding")
258
260
  headers_t["Accept-Encoding"].gsub!("gzip", "") #removed so the response is in plain text
259
261
  end
@@ -90,12 +90,13 @@ module NiceHttpManageResponse
90
90
  value_orig = value
91
91
  if key.kind_of?(Symbol)
92
92
  if key == :code or key == :data or key == :header or key == :message
93
- if key == :data and !@response[:'content-type'].to_s.include?("text/html")
94
- if key == :data and
95
- (!@response[:'content-type'].include?("text") and
96
- !@response[:'content-type'].include?("json") and
97
- !@response[:'content-type'].include?("xml") and
98
- !@response[:'content-type'].include?("charset=utf-8"))
93
+ content_type = @response[:'content-type'].to_s
94
+ if key == :data and !content_type.include?("text/html")
95
+ if key == :data and content_type != "" and
96
+ (!content_type.include?("text") and
97
+ !content_type.include?("json") and
98
+ !content_type.include?("xml") and
99
+ !content_type.include?("charset=utf-8"))
99
100
  message += "\n data: It's not text data so won't be in the logs."
100
101
  else
101
102
  begin
@@ -94,7 +94,8 @@ module NiceHttpHttpMethods
94
94
  @http.start()
95
95
  @headers_orig.each { |k, v| headers_t[k] = v.call if v.is_a?(Proc) and headers_t.key?(k) }
96
96
  @start_time_net = Time.now if @start_time_net.nil?
97
- resp, data = @http.delete(path, headers_t)
97
+ resp = @http.delete(path, headers_t)
98
+ data = resp.body
98
99
  end
99
100
  end
100
101
  manage_response(resp, data)
@@ -59,7 +59,8 @@ module NiceHttpHttpMethods
59
59
  @http.start()
60
60
  @headers_orig.each { |k, v| headers_t[k] = v.call if v.is_a?(Proc) and headers_t.key?(k) }
61
61
  @start_time_net = Time.now if @start_time_net.nil?
62
- resp, data = @http.head(path, headers_t)
62
+ resp = @http.head(path, headers_t)
63
+ data = resp.body
63
64
  end
64
65
  end
65
66
  manage_response(resp, data)
@@ -74,7 +74,8 @@ module NiceHttpHttpMethods
74
74
  @http.start()
75
75
  @headers_orig.each { |k, v| headers_t[k] = v.call if v.is_a?(Proc) and headers_t.key?(k) }
76
76
  @start_time_net = Time.now if @start_time_net.nil?
77
- resp, data = @http.patch(path, data, headers_t)
77
+ resp = @http.patch(path, data, headers_t)
78
+ data = resp.body
78
79
  end
79
80
  end
80
81
  manage_response(resp, data)
@@ -93,7 +93,8 @@ module NiceHttpHttpMethods
93
93
  @http.start()
94
94
  @start_time_net = Time.now if @start_time_net.nil?
95
95
  @headers_orig.each { |k, v| headers_t[k] = v.call if v.is_a?(Proc) and headers_t.key?(k) }
96
- resp, data = @http.post(path, data, headers_t)
96
+ resp = @http.post(path, data, headers_t)
97
+ data = resp.body
97
98
  end
98
99
  end
99
100
  manage_response(resp, data)
@@ -73,7 +73,8 @@ module NiceHttpHttpMethods
73
73
  @http.start()
74
74
  @headers_orig.each { |k, v| headers_t[k] = v.call if v.is_a?(Proc) and headers_t.key?(k) }
75
75
  @start_time_net = Time.now if @start_time_net.nil?
76
- resp, data = @http.send_request("PUT", path, data, headers_t)
76
+ resp = @http.send_request("PUT", path, data, headers_t)
77
+ data = resp.body
77
78
  end
78
79
  end
79
80
  manage_response(resp, data)
@@ -0,0 +1,130 @@
1
+ module NiceHttpUtils
2
+ PATTERN_SYMBOL = /\A!?\d+-?\d*:.+/
3
+ SELECTOR_SYMBOL = /\A(?:[\w\s\-]+\|)+[\w\s\-]+\z/
4
+ SHORTHANDS = [:uuid, :email, :iban, :luhn].freeze
5
+
6
+ # A value NiceHttp expands before sending, or that validate_response checks as a pattern.
7
+ # Plain strings are never patterns here, even when they look like "10:N" or "a|b".
8
+ def self.pattern_value?(value)
9
+ return true if pattern_symbol?(value)
10
+ return true if value.is_a?(Range) || value.is_a?(Regexp)
11
+ return true if defined?(DateTime) && value.is_a?(Class) && value == DateTime
12
+ return true if defined?(Boolean) && value.is_a?(Module) && value == Boolean
13
+ return true if checksum_array?(value)
14
+ return true if one_pattern_array?(value)
15
+
16
+ false
17
+ end
18
+
19
+ def self.contains_pattern?(obj)
20
+ return true if pattern_value?(obj)
21
+
22
+ case obj
23
+ when Hash
24
+ obj.any? { |_key, value| contains_pattern?(value) }
25
+ when Array
26
+ obj.any? { |value| contains_pattern?(value) }
27
+ else
28
+ false
29
+ end
30
+ end
31
+
32
+ # Copy of expected where pattern placeholders are replaced by the actual value,
33
+ # so compare_structure checks shape and leaves pattern checks to NiceHash.validate.
34
+ def self.structure_without_patterns(expected, actual)
35
+ if pattern_value?(expected)
36
+ return actual.nil? ? expected : actual
37
+ end
38
+
39
+ case expected
40
+ when Hash
41
+ expected.each_with_object({}) do |(key, value), copy|
42
+ child = actual.is_a?(Hash) ? actual[key] : nil
43
+ copy[key] = structure_without_patterns(value, child)
44
+ end
45
+ when Array
46
+ if expected.empty?
47
+ expected
48
+ else
49
+ child = actual.is_a?(Array) ? actual[0] : nil
50
+ [structure_without_patterns(expected[0], child)]
51
+ end
52
+ else
53
+ expected
54
+ end
55
+ end
56
+
57
+ # Copy a request without cloning Class or Module.
58
+ # DateTime.clone is an anonymous class and Boolean.clone is an anonymous module,
59
+ # so NiceHash.generate would no longer recognize them.
60
+ def self.copy_request(obj)
61
+ case obj
62
+ when Hash
63
+ obj.each_with_object({}) { |(key, value), copy| copy[key] = copy_request(value) }
64
+ when Array
65
+ obj.map { |value| copy_request(value) }
66
+ else
67
+ return obj if obj.is_a?(Module)
68
+
69
+ obj.clone
70
+ end
71
+ rescue StandardError
72
+ obj
73
+ end
74
+
75
+ # New hash or array. Strings, numbers, booleans, nil and procs are copied as they are.
76
+ def self.expand_patterns(obj)
77
+ case obj
78
+ when Hash
79
+ obj.each_with_object({}) { |(key, value), copy| copy[key] = expand_pattern_value(value) }
80
+ when Array
81
+ if pattern_value?(obj)
82
+ generate_pattern(obj)
83
+ else
84
+ obj.map { |value| expand_pattern_value(value) }
85
+ end
86
+ else
87
+ expand_pattern_value(obj)
88
+ end
89
+ end
90
+
91
+ def self.expand_pattern_value(value)
92
+ if pattern_value?(value)
93
+ generate_pattern(value)
94
+ elsif value.is_a?(Hash) || value.is_a?(Array)
95
+ expand_patterns(value)
96
+ else
97
+ value
98
+ end
99
+ end
100
+
101
+ def self.generate_pattern(value)
102
+ NiceHash.generate({ pattern: value })[:pattern]
103
+ end
104
+
105
+ def self.pattern_symbol?(value)
106
+ return false unless value.is_a?(Symbol)
107
+ return true if SHORTHANDS.include?(value)
108
+
109
+ text = value.to_s
110
+ text.match?(PATTERN_SYMBOL) || text.match?(SELECTOR_SYMBOL)
111
+ end
112
+
113
+ def self.checksum_array?(value)
114
+ value.is_a?(Array) && value.size.between?(1, 2) && [:iban, :luhn].include?(value[0])
115
+ end
116
+
117
+ def self.one_pattern_array?(value)
118
+ return false unless value.is_a?(Array) && value.size == 1
119
+ return false if checksum_array?(value)
120
+
121
+ element = value[0]
122
+ return false unless element.is_a?(Symbol)
123
+
124
+ StringPattern.analyze(element, silent: true).is_a?(StringPattern::Pattern)
125
+ rescue StandardError
126
+ false
127
+ end
128
+
129
+ private_class_method :expand_pattern_value, :generate_pattern, :pattern_symbol?, :checksum_array?, :one_pattern_array?
130
+ end
@@ -5,8 +5,13 @@ class NiceHttp
5
5
  #
6
6
  # @param resp [Hash] Response object (e.g. from get/post). Must have :data (body string or Hash/Array).
7
7
  # @param expected_structure [Hash, Array] Structure with expected keys and nesting (values can be placeholders).
8
- # @param options [Hash] Optional. :include_diff => true to add a diff in the result when validation fails.
9
- # @return [Hash] { ok: true } when structure matches, or { ok: false } or { ok: false, diff: Hash } when it does not.
8
+ # @param options [Hash] Optional. :include_diff => true adds a diff when validation fails.
9
+ # :explain => true adds NiceHash pattern errors when a pattern in expected_structure does not match.
10
+ # String keys in expected_structure are treated the same as symbol keys.
11
+ # Pattern checks run only when expected_structure contains pattern symbols, shorthands
12
+ # (:uuid, :email, :iban, :luhn), checksum pairs, a one-element pattern array, a Range, a Regexp, DateTime or Boolean.
13
+ # A plain string such as "10:N" stays a literal and is not validated as a pattern.
14
+ # @return [Hash] { ok: true } when it matches, or { ok: false } with optional :diff and :explain.
10
15
  # @example
11
16
  # resp = http.get("/api/users/1")
12
17
  # result = NiceHttp.validate_response(resp, { user: { name: "xxx", id: 1 } })
@@ -14,6 +19,9 @@ class NiceHttp
14
19
  # @example
15
20
  # result = NiceHttp.validate_response(resp, expected, include_diff: true)
16
21
  # puts result[:diff] unless result[:ok]
22
+ # @example
23
+ # result = NiceHttp.validate_response(resp, { email: :email }, explain: true)
24
+ # result[:explain][:email][:message] unless result[:ok]
17
25
  ######################################################
18
26
  def self.validate_response(resp, expected_structure, options = {})
19
27
  data = resp.is_a?(Hash) ? resp[:data] : resp.data
@@ -30,14 +38,31 @@ class NiceHttp
30
38
  return { ok: false, error: "response data is missing or not JSON" }
31
39
  end
32
40
 
33
- # Normalize to symbol keys so compare_structure/diff match typical expected_structure (symbol keys)
41
+ # Normalize to symbol keys so compare_structure/diff match either string or symbol keys
34
42
  parsed = deep_symbolize(parsed) if parsed.is_a?(Hash) || parsed.is_a?(Array)
43
+ expected = if expected_structure.is_a?(Hash) || expected_structure.is_a?(Array)
44
+ deep_symbolize(expected_structure)
45
+ else
46
+ expected_structure
47
+ end
35
48
 
36
- ok = NiceHash.compare_structure(expected_structure, parsed)
49
+ pattern_errors = {}
50
+ if NiceHttpUtils.contains_pattern?(expected)
51
+ comparable = NiceHttpUtils.structure_without_patterns(expected, parsed)
52
+ ok = NiceHash.compare_structure(comparable, parsed)
53
+ wrapped = NiceHash.validate({ root: expected }, { root: parsed }, only_patterns: true, explain: options[:explain] ? true : false)
54
+ pattern_errors = wrapped.is_a?(Hash) && wrapped.key?(:root) ? wrapped[:root] : wrapped
55
+ ok &&= pattern_errors.respond_to?(:empty?) && pattern_errors.empty?
56
+ else
57
+ ok = NiceHash.compare_structure(expected, parsed)
58
+ end
37
59
 
38
60
  result = { ok: ok }
39
61
  if !ok && options[:include_diff]
40
- result[:diff] = NiceHash.diff(expected_structure, parsed)
62
+ result[:diff] = NiceHash.diff(expected, parsed)
63
+ end
64
+ if !ok && options[:explain] && pattern_errors.respond_to?(:empty?) && !pattern_errors.empty?
65
+ result[:explain] = pattern_errors
41
66
  end
42
67
  result
43
68
  end
data/lib/nice_http.rb CHANGED
@@ -16,6 +16,7 @@ require_relative "nice_http/utils/basic_authentication"
16
16
  require_relative "nice_http/utils/get_value_xml_tag"
17
17
  require_relative "nice_http/utils/set_value_xml_tag"
18
18
  require_relative "nice_http/utils/set_lambdas"
19
+ require_relative "nice_http/utils/expand_patterns"
19
20
  require_relative "nice_http/reset"
20
21
  require_relative "nice_http/add_stats"
21
22
  require_relative "nice_http/defaults"
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: nice_http
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.10.1
4
+ version: 1.11.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mario Ruiz
@@ -15,20 +15,20 @@ dependencies:
15
15
  requirements:
16
16
  - - "~>"
17
17
  - !ruby/object:Gem::Version
18
- version: '1.19'
18
+ version: '1.21'
19
19
  - - ">="
20
20
  - !ruby/object:Gem::Version
21
- version: 1.19.0
21
+ version: 1.21.0
22
22
  type: :runtime
23
23
  prerelease: false
24
24
  version_requirements: !ruby/object:Gem::Requirement
25
25
  requirements:
26
26
  - - "~>"
27
27
  - !ruby/object:Gem::Version
28
- version: '1.19'
28
+ version: '1.21'
29
29
  - - ">="
30
30
  - !ruby/object:Gem::Version
31
- version: 1.19.0
31
+ version: 1.21.0
32
32
  - !ruby/object:Gem::Dependency
33
33
  name: rspec
34
34
  requirement: !ruby/object:Gem::Requirement
@@ -83,6 +83,7 @@ files:
83
83
  - lib/nice_http/reset.rb
84
84
  - lib/nice_http/save_stats.rb
85
85
  - lib/nice_http/utils/basic_authentication.rb
86
+ - lib/nice_http/utils/expand_patterns.rb
86
87
  - lib/nice_http/utils/get_value_xml_tag.rb
87
88
  - lib/nice_http/utils/set_lambdas.rb
88
89
  - lib/nice_http/utils/set_value_xml_tag.rb
@@ -99,7 +100,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
99
100
  requirements:
100
101
  - - ">="
101
102
  - !ruby/object:Gem::Version
102
- version: '2.7'
103
+ version: '3.0'
103
104
  required_rubygems_version: !ruby/object:Gem::Requirement
104
105
  requirements:
105
106
  - - ">="