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 +4 -4
- data/README.md +6 -3
- data/lib/create-tests/create_test.rb +57 -16
- data/lib/create-tests/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 754317e21adff9283ea8d3424b46ee09de1f5a53d9e875b9388014e261f6d561
|
|
4
|
+
data.tar.gz: e70d64dddd1f4312c67149e7ca3761e1d5038332252e9c8a191427e53627c3b9
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 10f9687590b335bd26ab6bc039d9ad05eed6ca780608363c934db2a929f11ea229e267d95498935ac9755c4eb6bb4eec437b985d114efe747870e7371fc50dd5
|
|
7
|
+
data.tar.gz: '048048f6f02865499ee314d55841e9e3259fad8c9edcb74c6fb3937e508eb2ccbdebe9b49c6870fe1e8984a466410aa61f0ea7a6b03ef2dfbbe1f1eeabadd752'
|
data/README.md
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
[](https://rubygems.org/gems/create_tests)
|
|
4
4
|
[](https://github.com/MarioRuiz/create_tests/actions/workflows/ci.yml)
|
|
5
|
+
[](https://github.com/MarioRuiz/create_tests/actions/workflows/ci.yml)
|
|
5
6
|

|
|
6
7
|

|
|
7
8
|

|
|
@@ -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
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
128
|
-
|
|
129
|
-
|
|
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
|
|
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[
|
|
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
|
|
236
|
+
if payload_source
|
|
201
237
|
title = "it 'returns error when individual data fields are invalid' "
|
|
202
238
|
tests[title] = "do
|
|
203
|
-
wrong = @request[
|
|
204
|
-
NiceHash.change_one_by_one([@request[
|
|
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?(:
|
|
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)
|
data/lib/create-tests/version.rb
CHANGED