create_tests 1.0.0 → 1.1.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: d22c903c194de3b4c00a889073f9bdf72ba97f7a68c083f871f5fd60905df812
4
- data.tar.gz: 638d9efe9d13847ef0c918a2505aea709f6df4a7cb29bea6027fe4e081a96c57
3
+ metadata.gz: 754317e21adff9283ea8d3424b46ee09de1f5a53d9e875b9388014e261f6d561
4
+ data.tar.gz: e70d64dddd1f4312c67149e7ca3761e1d5038332252e9c8a191427e53627c3b9
5
5
  SHA512:
6
- metadata.gz: d8c090b7c8195479424bee5b5b0b41e3581deaa34b23e8a8736ff15bb2a548ab0a71f5f1da6b9dabb59bcd63100d8ffd31c353aadadbe9c178ccd69c486d1f4e
7
- data.tar.gz: 533123ae7baaf838f831fe93e80ac076ab9dfee262af60029d2c8d442dea4193a660fdd1937fdc972556d89b60d1a903d611effc068d9fdd85cd69793470f55a
6
+ metadata.gz: 10f9687590b335bd26ab6bc039d9ad05eed6ca780608363c934db2a929f11ea229e267d95498935ac9755c4eb6bb4eec437b985d114efe747870e7371fc50dd5
7
+ data.tar.gz: '048048f6f02865499ee314d55841e9e3259fad8c9edcb74c6fb3937e508eb2ccbdebe9b49c6870fe1e8984a466410aa61f0ea7a6b03ef2dfbbe1f1eeabadd752'
data/README.md CHANGED
@@ -2,6 +2,7 @@
2
2
 
3
3
  [![Gem Version](https://badge.fury.io/rb/create_tests.svg)](https://rubygems.org/gems/create_tests)
4
4
  [![CI](https://github.com/MarioRuiz/create_tests/actions/workflows/ci.yml/badge.svg)](https://github.com/MarioRuiz/create_tests/actions/workflows/ci.yml)
5
+ [![coverage](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/MarioRuiz/create_tests/master/.github/badges/coverage.json)](https://github.com/MarioRuiz/create_tests/actions/workflows/ci.yml)
5
6
  ![Gem](https://img.shields.io/gem/dt/create_tests)
6
7
  ![GitHub commit activity](https://img.shields.io/github/commit-activity/y/MarioRuiz/create_tests)
7
8
  ![GitHub last commit](https://img.shields.io/github/last-commit/MarioRuiz/create_tests)
@@ -78,11 +79,13 @@ For each API endpoint, `create_tests` generates up to 7 test types:
78
79
 
79
80
  4. **"returns expected mock response"** -- For endpoints with `mock_response` data (from `open_api_import`), validates the mock response matches the expected code, message, and structure.
80
81
 
81
- 5. **"handles multiple valid data variations"** -- For POST/PUT/PATCH endpoints with data, uses `generate_n(5, :correct)` from nice_hash to test 5 different valid payload variations.
82
+ 5. **"handles multiple valid data variations"** -- For POST/PUT/PATCH endpoints with a payload source, uses `generate_n(5, :correct)` from nice_hash to test 5 different valid payload variations. Prefers `:data_pattern` when present (real string_pattern / enum / range values from open_api_import); otherwise uses `:data`. Generated values are assigned to `request[:data]` before the call.
82
83
 
83
- 6. **"returns error when individual data fields are invalid"** -- Uses `NiceHash.change_one_by_one` to systematically test each data field being wrong one at a time, asserting the server rejects each one.
84
+ 6. **"returns error when individual data fields are invalid"** -- Uses `NiceHash.change_one_by_one` on `:data_pattern` (preferred) or `:data` to systematically test each field being wrong one at a time, asserting the server rejects each one.
84
85
 
85
- 7. **"returns error if required parameter on data empty/missing"** -- For endpoints with `data_required`, tests both empty and missing values for each required data field.
86
+ 7. **"returns error if required parameter on data empty/missing"** -- For endpoints with `data_required`, tests both empty and missing values for each required data field. When `:data` is absent but `:data_examples` is present (common for form uploads), the first example is used as the body for success and required-data tests.
87
+
88
+ Required keyword parameters from open_api_import `create_constants: true` (e.g. `def self.get_item(id: ID)`) get Helper stubs and are called as keywords (`id: @id`), same as positional required args.
86
89
 
87
90
  ## Parameters
88
91
 
@@ -15,17 +15,26 @@ class CreateTests
15
15
  req_txt = "#{method_txt}("
16
16
  params = []
17
17
  keywords_required = []
18
+ keyreq_kwargs = {}
18
19
  method_obj.parameters.each do |p|
19
- if p[0] == :req #required
20
+ if p[0] == :req #required positional
20
21
  params << "@#{p[1]}"
22
+ elsif p[0] == :keyreq
23
+ keywords_required << p[1]
24
+ keyreq_kwargs[p[1]] = nil
21
25
  elsif p[0] == :key and p[1].to_s.match?(/^[a-z]/i) and Object.const_defined?(p[1].to_s.upcase)
26
+ # create_constants: required path/query as keyword with UPCASE constant default
22
27
  keywords_required << p[1]
23
28
  end
24
29
  end
25
- req_txt += params.join(", ")
30
+ call_parts = params.dup
31
+ keywords_required.each { |k| call_parts << "#{k}: @#{k}" }
32
+ req_txt += call_parts.join(", ")
26
33
  req_txt += ")"
27
34
  require 'nice_hash'
28
- request = method_obj.call(*Array.new(params.size))
35
+ # Keyword-only methods (create_constants) must not receive nil positionals;
36
+ # :keyreq needs an explicit keyword so Method#call succeeds.
37
+ request = method_obj.call(*Array.new(params.size), **keyreq_kwargs)
29
38
 
30
39
  req_txt = "#{mod_name}.#{req_txt}"
31
40
  params_declaration_txt = ""
@@ -34,6 +43,10 @@ class CreateTests
34
43
  params_declaration_txt << "#{p} = Helper.#{p.gsub('@','')}(@http)\n"
35
44
  @params << p
36
45
  end
46
+ keywords_required.each do |k|
47
+ params_declaration_txt << "@#{k} = Helper.#{k}(@http)\n"
48
+ @params << "@#{k}"
49
+ end
37
50
 
38
51
  all_params_for_chain = params + keywords_required.map { |k| "@#{k}" }
39
52
  resource_chain, target_resource = extract_resource_chain(request, all_params_for_chain)
@@ -116,19 +129,42 @@ class CreateTests
116
129
 
117
130
  tests = Hash.new()
118
131
 
132
+ has_data_examples = request.key?(:data_examples) &&
133
+ request[:data_examples].is_a?(Array) &&
134
+ !request[:data_examples].empty?
135
+ # Prefer data_pattern for variation/invalid-field tests; fall back to :data
136
+ payload_source = if request.key?(:data_pattern)
137
+ ":data_pattern"
138
+ elsif request.key?(:data)
139
+ ":data"
140
+ end
141
+
119
142
  # first response on responses is the one expected to be returned when success
120
143
  if request.key?(:responses) and request[:responses].size > 0
121
144
  code = request[:responses].keys[0]
122
145
  title="it 'has correct structure in successful response' "
123
- tests[title] = "do
146
+ if !request.key?(:data) && has_data_examples
147
+ tests[title] = "do
148
+ request = @request.deep_copy
149
+ request[:data] = @request[:data_examples].first
150
+ resp = @http.#{request[:method]}(request)
151
+ expect(resp.code).to eq #{code}\n"
152
+ if request[:responses][code].is_a?(Hash) and request[:responses][code].key?(:data)
153
+ tests[title] +="result = NiceHttp.validate_response(resp, @request.responses._#{code}.data, include_diff: true)\n"
154
+ tests[title] +="expect(result[:ok]).to be(true), \"Structure mismatch: \#{result[:diff]}\"\n"
155
+ end
156
+ tests[title] += "end\n"
157
+ else
158
+ tests[title] = "do
124
159
  resp = @http.#{request[:method]}(@request)
125
160
  expect(resp.code).to eq #{code}\n"
126
161
 
127
- if request[:responses][code].is_a?(Hash) and request[:responses][code].key?(:data)
128
- tests[title] +="result = NiceHttp.validate_response(resp, @request.responses._#{code}.data, include_diff: true)\n"
129
- tests[title] +="expect(result[:ok]).to be(true), \"Structure mismatch: \#{result[:diff]}\"\n"
162
+ if request[:responses][code].is_a?(Hash) and request[:responses][code].key?(:data)
163
+ tests[title] +="result = NiceHttp.validate_response(resp, @request.responses._#{code}.data, include_diff: true)\n"
164
+ tests[title] +="expect(result[:ok]).to be(true), \"Structure mismatch: \#{result[:diff]}\"\n"
165
+ end
166
+ tests[title] += "end\n"
130
167
  end
131
- tests[title] += "end\n"
132
168
  end
133
169
 
134
170
  title = "it 'doesn\\'t retrieve data if not authenticated'"
@@ -185,10 +221,10 @@ class CreateTests
185
221
  tests[title] += "end\n"
186
222
  end
187
223
 
188
- if request.key?(:data) and [:post, :put, :patch].include?(request[:method])
224
+ if payload_source && [:post, :put, :patch].include?(request[:method])
189
225
  title = "it 'handles multiple valid data variations' "
190
226
  tests[title] = "do
191
- @request[:data].generate_n(5, :correct).each do |generated_data|
227
+ @request[#{payload_source}].generate_n(5, :correct).each do |generated_data|
192
228
  request = @request.deep_copy
193
229
  request[:data] = generated_data
194
230
  resp = @http.#{request[:method]}(request)
@@ -197,11 +233,11 @@ class CreateTests
197
233
  end\n"
198
234
  end
199
235
 
200
- if request.key?(:data)
236
+ if payload_source
201
237
  title = "it 'returns error when individual data fields are invalid' "
202
238
  tests[title] = "do
203
- wrong = @request[:data].generate(:correct, errors: :min_length)
204
- NiceHash.change_one_by_one([@request[:data], :correct], wrong).each do |one_wrong|
239
+ wrong = @request[#{payload_source}].generate(:correct, errors: :min_length)
240
+ NiceHash.change_one_by_one([@request[#{payload_source}], :correct], wrong).each do |one_wrong|
205
241
  request = @request.deep_copy
206
242
  request[:data] = one_wrong
207
243
  resp = @http.#{request[:method]}(request)
@@ -210,12 +246,17 @@ class CreateTests
210
246
  end\n"
211
247
  end
212
248
 
213
- if request.key?(:data) and request.key?(:data_required)
249
+ if request.key?(:data_required) && (request.key?(:data) || has_data_examples)
250
+ seed_data_line = if !request.key?(:data) && has_data_examples
251
+ "request[:data] = request[:data_examples].first\n "
252
+ else
253
+ ""
254
+ end
214
255
  empty_param_data = ""
215
256
  empty_param_data += "
216
257
  @request[:data_required].each do |p|
217
258
  request = @request.deep_copy
218
- request.values_for[p] = ''
259
+ #{seed_data_line}request.values_for[p] = ''
219
260
  resp = @http.#{request[:method]}(request)
220
261
  expect(resp.code).not_to be_between('200', '299')
221
262
  if request.responses.key?(resp.code.to_sym)
@@ -230,7 +271,7 @@ class CreateTests
230
271
  missing_param_data += "
231
272
  @request[:data_required].each do |p|
232
273
  request = @request.deep_copy
233
- NiceHash.delete_nested(request[:data], p)
274
+ #{seed_data_line}NiceHash.delete_nested(request[:data], p)
234
275
  resp = @http.#{request[:method]}(request)
235
276
  expect(resp.code).not_to be_between('200', '299')
236
277
  if request.responses.key?(resp.code.to_sym)
@@ -1,3 +1,3 @@
1
1
  class CreateTests
2
- VERSION = "1.0.0"
2
+ VERSION = "1.1.0"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: create_tests
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mario Ruiz