create_tests 0.6.4 → 1.0.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: f3f0e8e09a105574c13b50cd631e049f4c4cfc84d0178fb0fa06e85a11a28166
4
- data.tar.gz: 49ca6ca2c2f91b2e0eb21326523b4df3726553850eaa7b3cdf1a98e71725d1c2
3
+ metadata.gz: d22c903c194de3b4c00a889073f9bdf72ba97f7a68c083f871f5fd60905df812
4
+ data.tar.gz: 638d9efe9d13847ef0c918a2505aea709f6df4a7cb29bea6027fe4e081a96c57
5
5
  SHA512:
6
- metadata.gz: d532e448bb0c496345cce12042e579d4d72b3926604a8046da7c1724529a821219f5a57669ebfece1057c35ce4ad7f3f4ff940dc4dbf6801718a2d9d1c849d05
7
- data.tar.gz: 57f374308e2752d1149b13d482a72bad589a50d0d67513cce2f3f74f252275bd36269b9b0ca2b268c4d8c4782150d7f3dddf625209a4a4dcefdf60ef91cc3c71
6
+ metadata.gz: d8c090b7c8195479424bee5b5b0b41e3581deaa34b23e8a8736ff15bb2a548ab0a71f5f1da6b9dabb59bcd63100d8ffd31c353aadadbe9c178ccd69c486d1f4e
7
+ data.tar.gz: 533123ae7baaf838f831fe93e80ac076ab9dfee262af60029d2c8d442dea4193a660fdd1937fdc972556d89b60d1a903d611effc068d9fdd85cd69793470f55a
data/README.md CHANGED
@@ -1,15 +1,17 @@
1
1
  # CreateTests
2
2
 
3
3
  [![Gem Version](https://badge.fury.io/rb/create_tests.svg)](https://rubygems.org/gems/create_tests)
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
+ ![Gem](https://img.shields.io/gem/dt/create_tests)
6
+ ![GitHub commit activity](https://img.shields.io/github/commit-activity/y/MarioRuiz/create_tests)
7
+ ![GitHub last commit](https://img.shields.io/github/last-commit/MarioRuiz/create_tests)
8
+ ![GitHub code size in bytes](https://img.shields.io/github/languages/code-size/MarioRuiz/create_tests)
4
9
 
5
- Create Tests automatically from a Requests file. Perfect to be used with the result from importing a Swagger file using the open_api_import gem. Now we are supporting RSpec.
10
+ Create RSpec tests automatically from Request Hash files. Perfect to be used with the result from importing a Swagger / OpenAPI file using the [open_api_import](https://github.com/MarioRuiz/open_api_import) gem.
6
11
 
7
- More info about the Request Hashes: https://github.com/MarioRuiz/Request-Hash
8
-
9
- If you want to know how to import Swagger / Open API files in just a couple of seconds and transform them into Request Ruby Hashes: https://github.com/MarioRuiz/open_api_import
10
-
11
- We strongly recommend to use nice_http gem for your tests: https://github.com/MarioRuiz/nice_http
12
+ We strongly recommend using [nice_http](https://github.com/MarioRuiz/nice_http) for your tests together with [nice_hash](https://github.com/MarioRuiz/nice_hash) and [string_pattern](https://github.com/MarioRuiz/string_pattern).
12
13
 
14
+ More info about Request Hashes: https://github.com/MarioRuiz/Request-Hash
13
15
 
14
16
  ## Installation
15
17
 
@@ -17,51 +19,205 @@ Install it yourself as:
17
19
 
18
20
  $ gem install create_tests
19
21
 
22
+ **Requirements:** Ruby >= 3.0
20
23
 
21
- Take in consideration create_tests gem is using the 'rufo' gem that executes in command line the `rufo` command. In case you experience any trouble with it, visit: https://github.com/ruby-formatter/rufo
24
+ The gem uses [rufo](https://github.com/ruby-formatter/rufo) to format generated files. In case you experience any trouble with it, visit: https://github.com/ruby-formatter/rufo
22
25
 
23
26
  ## Usage
24
27
 
25
- After installation you can run using command line executable or just from Ruby.
28
+ After installation you can run using the command line executable or from Ruby code.
26
29
 
27
- The execution will create an spec folder where you will have all the RSpec tests. Also it will be added to that file a `helper.rb` file.
30
+ The execution will create:
31
+ - A `spec/` folder with one RSpec test file per API endpoint
32
+ - A `spec/helper.rb` with stub methods for required parameters
33
+ - A `settings/general.rb` with NiceHttp configuration boilerplate
28
34
 
29
- Also a `settings` folder that will contain a `general.rb` file that will be required by the tests.
35
+ ### Command line
30
36
 
31
- ### Executable
37
+ ```
38
+ Usage: create_tests [requests_file] [options]
39
+
40
+ -n, --dont_overwrite In case the test file exists it won't change anything
41
+ -w, --overwrite In case the test file exists it will be overwritten
42
+ -a, --append Only missing tests will be appended (default)
43
+ -d, --dry_run Preview which files would be created or modified
44
+ --cleanup_each Generate cleanup in after(:each) instead of after(:all)
45
+ --no_cleanup Do not generate setup/cleanup hooks
46
+ -v, --version Show version
47
+ ```
32
48
 
33
- For help and see the options, run in command line / bash: `create_tests -h`
49
+ Example:
34
50
 
35
- Example:
36
51
  ```bash
37
- create_tests ./requests/uber.yaml.rb
52
+ create_tests ./requests/uber.yaml.rb
38
53
  ```
39
54
 
40
- ### Ruby file
41
- Write your ruby code on a file and in command line/bash: `ruby my_file.rb`
55
+ Dry run (preview without writing files):
56
+
57
+ ```bash
58
+ create_tests ./requests/uber.yaml.rb --dry_run
59
+ ```
42
60
 
43
- This is an example:
61
+ ### Ruby API
44
62
 
45
63
  ```ruby
46
- require 'create_tests'
47
-
48
- CreateTests.from "./requests/uber.yaml.rb"
64
+ require 'create_tests'
49
65
 
66
+ CreateTests.from "./requests/uber.yaml.rb"
50
67
  ```
51
68
 
69
+ ## Generated tests
70
+
71
+ For each API endpoint, `create_tests` generates up to 7 test types:
72
+
73
+ 1. **"has correct structure in successful response"** -- Calls the endpoint and validates the response structure using `NiceHttp.validate_response` with diff details on failure.
74
+
75
+ 2. **"doesn't retrieve data if not authenticated"** -- Calls with empty headers and asserts a 4xx response.
76
+
77
+ 3. **"returns error if required parameter empty"** -- For each required parameter, sends an empty string and expects a 4xx response.
78
+
79
+ 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
+ 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
+
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
+
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
+
87
+ ## Parameters
88
+
89
+ ### mode
90
+
91
+ Accepts three options: `:overwrite`, `:dont_overwrite` and `:append`. Default: `:append`.
92
+
93
+ - **append**: If the test file already exists, only missing tests will be added. Existing content is preserved, including `helper/setup.rb` and `helper/cleanup.rb`. If the file doesn't exist, it will be created with all tests.
94
+
95
+ - **dont_overwrite**: If the test file exists, no changes will be made. If it doesn't exist, it will be created.
96
+
97
+ - **overwrite**: The test file will be recreated from scratch. All previous content will be deleted.
98
+
99
+ ```ruby
100
+ CreateTests.from "./requests/uber.yaml.rb", mode: :overwrite
101
+ ```
102
+
103
+ ### dry_run
104
+
105
+ Preview which files would be created or modified without writing anything to disk.
106
+
107
+ ```ruby
108
+ CreateTests.from "./requests/uber.yaml.rb", dry_run: true
109
+ ```
110
+
111
+ ### return_data
112
+
113
+ Return the generated code as a Hash (`{ filepath => content }`) without writing files. Useful for programmatic use.
114
+
115
+ ```ruby
116
+ result = CreateTests.from "./requests/uber.yaml.rb", return_data: true
117
+ result.each { |path, content| puts "#{path}: #{content.length} bytes" }
118
+ ```
119
+
120
+ ### spec_dir / settings_dir
121
+
122
+ Custom output directories (default: `./spec` and `./settings`).
123
+
124
+ ```ruby
125
+ CreateTests.from "./requests/uber.yaml.rb", spec_dir: "./test/spec", settings_dir: "./test/config"
126
+ ```
127
+
128
+ ### cleanup
129
+
130
+ Controls whether and how prerequisite setup/cleanup hooks are generated. Default: `:after_all`.
131
+
132
+ When API endpoints have hierarchical paths (e.g. `/accounts/{account}/pools/{pool}/volumes/{volume}`), `create_tests` infers the dependency chain and generates production-ready test scaffolding with setup expectations, unique naming, and conditional cleanup.
133
+
134
+ ```ruby
135
+ CreateTests.from "./requests/netapp.json.rb" # cleanup in after(:all) (default)
136
+ CreateTests.from "./requests/netapp.json.rb", cleanup: :after_each # move after(:all) cleanup into after(:each)
137
+ CreateTests.from "./requests/netapp.json.rb", cleanup: false # no cleanup generation
138
+ ```
139
+
140
+ **For PUT/POST (create) endpoints** -- parents are set up, test creates the target:
141
+
142
+ ```ruby
143
+ before(:all) do
144
+ @http = NiceHttp.new()
145
+ @volume_name = @volume_name + "-cre"
146
+ expect(Helper.setup_capacity_pools(@http, ...).state).to eq "Succeeded"
147
+ @request = Volumes.create_or_update(...)
148
+ end
149
+ after(:all) do
150
+ unless defined?(DONT_DELETE) && DONT_DELETE
151
+ Helper.cleanup_capacity_pools(@http, ...)
152
+ end
153
+ end
154
+ ```
155
+
156
+ **For DELETE endpoints** -- target is recreated before each test (since each test deletes it):
157
+
158
+ ```ruby
159
+ before(:all) do
160
+ @snapshot_name = @snapshot_name + "-del"
161
+ expect(Helper.setup_volumes(@http, ...).state).to eq "Succeeded"
162
+ @request = Snapshots.delete(...)
163
+ end
164
+ before(:each) do |example|
165
+ @http = NiceHttp.new()
166
+ expect(Helper.setup_snapshots(@http, ...).state).to eq "Succeeded"
167
+ end
168
+ after(:each) do
169
+ Helper.cleanup_snapshots(@http, ...)
170
+ end
171
+ after(:all) do
172
+ unless defined?(DONT_DELETE) && DONT_DELETE
173
+ Helper.cleanup_volumes(@http, ...)
174
+ end
175
+ end
176
+ ```
177
+
178
+ **For GET/PATCH endpoints** -- target is set up once in `before(:all)`.
179
+
180
+ Each setup method cascades to create its parents first (in `helper/setup.rb`):
181
+
182
+ ```ruby
183
+ def self.setup_snapshots(http, ...)
184
+ setup_capacity_pools(http, ...)
185
+ # TODO: Create the snapshots resource
186
+ OpenStruct.new(state: "Succeeded")
187
+ end
188
+ ```
189
+
190
+ Cleanup cascades in reverse (in `helper/cleanup.rb`):
191
+
192
+ ```ruby
193
+ def self.cleanup_snapshots(http, ...)
194
+ # TODO: Delete the snapshots resource
195
+ cleanup_capacity_pools(http, ...)
196
+ end
197
+ ```
198
+
199
+ Set `DONT_DELETE=true` in your environment to keep resources for debugging.
200
+
52
201
  ## Example
53
202
 
54
- On this example we will be creating tests for the Uber API using the Swagger / Open API file.
203
+ Creating tests for the Uber API using a Swagger / OpenAPI file:
55
204
 
56
- 1. Create a folder in your computer called for example `create_tests_example`
205
+ 1. Create a project folder:
57
206
 
58
- 2. Copy the file that we have on `./example/requests/uber.yaml` into a folder called `requests` inside `create_tests_example folder`.
207
+ ```bash
208
+ mkdir create_tests_example && cd create_tests_example
209
+ ```
210
+
211
+ 2. Copy the Swagger file into a `requests` folder (see `./example/requests/uber.yaml` in this repo).
212
+
213
+ 3. Convert the Swagger file into Request Hashes using [open_api_import](https://github.com/MarioRuiz/open_api_import):
59
214
 
60
- 3. First we will convert this Swagger file into Requests Hashes by running from `create_tests_example` folder:
61
215
  ```bash
62
216
  open_api_import ./requests/uber.yaml -fT
63
217
  ```
64
- Now all the Request files were created on the `requests` folder:
218
+
219
+ Output:
220
+
65
221
  ```
66
222
  ** Generated files that contain the code of the requests after importing the Swagger file:
67
223
  - requests/uber.yaml_Products.rb
@@ -71,15 +227,16 @@ Now all the Request files were created on the `requests` folder:
71
227
  - requests/uber.yaml.rb
72
228
  ```
73
229
 
74
- 4. Now we will create the tests by running:
230
+ 4. Generate the tests:
231
+
75
232
  ```bash
76
233
  create_tests ./requests/uber.yaml.rb
77
234
  ```
78
235
 
79
- 5. All your tests will be on `spec` folder, and a `general.rb` file inside `settings` folder was created and also take a look at your `helper.rb` file on `spec` folder.
236
+ Output:
237
+
80
238
  ```
81
239
  - Logs: ./requests/uber.yaml.rb_create_tests.log
82
- ** Pay attention, if any of the test files exist or the help file exist only will be added the tests, methods that are missing.
83
240
  - Settings: ./settings/general.rb
84
241
  - Test created: ./spec/User/profile_user_spec.rb
85
242
  - Test created: ./spec/User/activity_user_spec.rb
@@ -89,36 +246,18 @@ create_tests ./requests/uber.yaml.rb
89
246
  - Helper: ./spec/helper.rb
90
247
  ```
91
248
 
92
- You can see a reproduction of what we did before on here: https://github.com/MarioRuiz/create_tests/tree/master/example
93
-
94
- ## Parameters
95
-
96
- The parameters can be supplied alone or with other parameters. In case a parameter is not supplied then it will be used the default value.
97
-
98
- ### mode
99
-
100
- Accepts three different options: :overwrite, :dont_overwrite and :append. By default :append.
101
-
102
- append: In case the test file already exists will be only adding those tests that are missing from that file. If the test file doesn't exist, will be created and added all tests.
103
-
104
- dont_overwrite: In case the test file exists any change will be done. If it doesn't exist then it will be created.
105
-
106
- overwrite: In case the file exist you will loose the current code and a new code will be created. Take in consideration that all previous content will be deleted.
107
- If it doesn't exist the test file then it will be created.
108
-
109
- ```ruby
110
- require 'create_tests'
111
-
112
- CreateTests.from "./requests/uber.yaml.rb", mode: :overwrite
249
+ 5. Review `settings/general.rb` to configure your host and authentication, fill in the Helper methods in `spec/helper.rb`, then run:
113
250
 
251
+ ```bash
252
+ rspec spec/ --format documentation
114
253
  ```
115
254
 
255
+ See the full example: https://github.com/MarioRuiz/create_tests/tree/master/example
116
256
 
117
257
  ## Contributing
118
258
 
119
- Bug reports and pull requests are welcome on GitHub at https://github.com/marioruiz/create_tests.
120
-
259
+ Bug reports and pull requests are welcome on GitHub at https://github.com/MarioRuiz/create_tests.
121
260
 
122
261
  ## License
123
262
 
124
- The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
263
+ The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
data/bin/create_tests CHANGED
@@ -17,14 +17,31 @@ optparse = OptionParser.new do |opts|
17
17
  options[:mode] = :dont_overwrite
18
18
  end
19
19
 
20
- opts.on("-w", "--overwrite", "In case the test file exists it will be ovewritten, so the previous content will deleted") do
20
+ opts.on("-w", "--overwrite", "In case the test file exists it will be overwritten, so the previous content will be deleted") do
21
21
  options[:mode] = :overwrite
22
22
  end
23
23
 
24
- opts.on("-a", "--append", "In case the test file exists it will be ovewritten, so the previous content will deleted") do
24
+ opts.on("-a", "--append", "In case the test file exists only missing tests will be appended, existing content is preserved") do
25
25
  options[:mode] = :append
26
26
  end
27
27
 
28
+ opts.on("-d", "--dry_run", "Preview which files would be created or modified without writing anything") do
29
+ options[:dry_run] = true
30
+ end
31
+
32
+ opts.on("--cleanup_each", "Generate cleanup in after(:each) instead of after(:all)") do
33
+ options[:cleanup] = :after_each
34
+ end
35
+
36
+ opts.on("--no_cleanup", "Do not generate setup/cleanup hooks") do
37
+ options[:cleanup] = false
38
+ end
39
+
40
+ opts.on("-v", "--version", "Show version") do
41
+ puts "create_tests #{CreateTests::VERSION}"
42
+ exit
43
+ end
44
+
28
45
  end
29
46
 
30
47
  optparse.parse!
@@ -3,19 +3,30 @@ class CreateTests
3
3
 
4
4
  class << self
5
5
 
6
- # Create the helper file
7
- private def create_helper(params, helper_txt)
6
+ # Create the helper file (param stubs only).
7
+ # chain_requires: relative paths (from the helper file) for setup/cleanup, included only when those files are generated.
8
+ private def create_helper(params, helper_txt, settings_relative_path: '../settings/general', chain_requires: [])
9
+ chain_lines = chain_requires.map { |rel| "require_relative '#{rel}'\n" }.join
8
10
  if helper_txt == ""
9
11
  output = "# for the case we want to use it standalone, not inside the project
10
- require_relative '../settings/general' unless defined?(ROOT_DIR)
11
-
12
+ require_relative '#{settings_relative_path}' unless defined?(ROOT_DIR)
13
+ #{chain_lines}
12
14
  # On the methods you can pass the active http connection or none, then it will be created a new one.
13
15
  # Examples from tests:
14
16
  # Helper.the_method_i_call(@http)
15
17
  # Helper.the_method_i_call()
16
18
  module Helper\n"
17
19
  else
18
- output = helper_txt
20
+ output = helper_txt.dup
21
+ missing = chain_requires.reject { |rel| output.include?("require_relative '#{rel}'") }
22
+ unless missing.empty?
23
+ insert = missing.map { |rel| "require_relative '#{rel}'\n" }.join
24
+ if output.include?("module Helper")
25
+ output.sub!("module Helper", "#{insert}module Helper")
26
+ else
27
+ output = insert + output
28
+ end
29
+ end
19
30
  output.gsub!(/\s*end\s*\Z/,"\n")
20
31
  end
21
32
 
@@ -33,5 +44,86 @@ class CreateTests
33
44
  output += "\nend"
34
45
 
35
46
  end
47
+
48
+ # Generate helper/setup.rb with cascading setup methods
49
+ private def create_setup_file(setup_cleanup_resources)
50
+ output = "require 'ostruct'\nmodule Helper\n"
51
+
52
+ ordered = deduplicate_resources(setup_cleanup_resources)
53
+
54
+ ordered.each do |res|
55
+ param_list = res[:params_up_to].map { |p| p.gsub("@", "") }.join(", ")
56
+ parent = find_parent_resource(res, ordered)
57
+
58
+ output += "# TODO: Create the #{res[:resource]} resource needed as prerequisite\n"
59
+ output += "def self.setup_#{res[:resource]}(http, #{param_list})\n"
60
+ if parent
61
+ parent_params = parent[:params_up_to].map { |p| p.gsub("@", "") }.join(", ")
62
+ output += "parent_result = setup_#{parent[:resource]}(http, #{parent_params})\n"
63
+ output += "return parent_result unless parent_result[:state] == 'Succeeded'\n"
64
+ end
65
+ output += 'http.logger.info "Helper.#{__method__}"'
66
+ output += "\n"
67
+ output += "OpenStruct.new(state: 'Succeeded')\n"
68
+ output += "end\n"
69
+ end
70
+
71
+ output += "\nend\n"
72
+ end
73
+
74
+ # Generate helper/cleanup.rb with cascading cleanup methods
75
+ private def create_cleanup_file(setup_cleanup_resources)
76
+ output = "module Helper\n"
77
+
78
+ ordered = deduplicate_resources(setup_cleanup_resources)
79
+
80
+ ordered.each do |res|
81
+ param_list = res[:params_up_to].map { |p| p.gsub("@", "") }.join(", ")
82
+ parent = find_parent_resource(res, ordered)
83
+
84
+ output += "# TODO: Delete the #{res[:resource]} resource after tests\n"
85
+ output += "def self.cleanup_#{res[:resource]}(http, #{param_list})\n"
86
+ output += 'http.logger.info "Helper.#{__method__}"'
87
+ output += "\n"
88
+ if parent
89
+ parent_params = parent[:params_up_to].map { |p| p.gsub("@", "") }.join(", ")
90
+ output += "cleanup_#{parent[:resource]}(http, #{parent_params})\n"
91
+ end
92
+ output += "end\n"
93
+ end
94
+
95
+ output += "\nend\n"
96
+ end
97
+
98
+ private def deduplicate_resources(resources)
99
+ seen = []
100
+ resources.each_with_object([]) do |res, arr|
101
+ next if seen.include?(res[:resource])
102
+ seen << res[:resource]
103
+ arr << res
104
+ end
105
+ end
106
+
107
+ # Find the actual parent resource by matching params_up_to as a proper prefix
108
+ private def find_parent_resource(resource, all_resources)
109
+ my_params = resource[:params_up_to]
110
+ return nil if my_params.size <= 1
111
+
112
+ parent_params = my_params[0..-2]
113
+ all_resources.reverse_each do |candidate|
114
+ return candidate if candidate[:params_up_to] == parent_params
115
+ end
116
+
117
+ best = nil
118
+ all_resources.each do |candidate|
119
+ next if candidate[:resource] == resource[:resource]
120
+ next unless candidate[:params_up_to].size < my_params.size
121
+ next unless candidate[:params_up_to] == my_params[0, candidate[:params_up_to].size]
122
+ if best.nil? || candidate[:params_up_to].size > best[:params_up_to].size
123
+ best = candidate
124
+ end
125
+ end
126
+ best
127
+ end
36
128
  end
37
129
  end
@@ -4,7 +4,7 @@ class CreateTests
4
4
  class << self
5
5
 
6
6
  # Create the settings file
7
- private def create_settings(requests_file_orig, modules_to_include)
7
+ private def create_settings(requests_relative_path, modules_to_include, helper_relative_path: '../spec/helper.rb')
8
8
  output = "# required libraries
9
9
  require 'nice_http'
10
10
  require 'nice_hash'
@@ -22,12 +22,12 @@ class CreateTests
22
22
  NiceHttp.log = :file_run
23
23
  # Add here the headers for authentication for example
24
24
  NiceHttp.headers = {
25
- Auhentication: 'Token'
25
+ Authentication: 'Token'
26
26
  }
27
27
 
28
28
  # Requests
29
- require_relative '.#{requests_file_orig}'\n
30
- require_relative '../spec/helper.rb'\n"
29
+ require_relative '#{requests_relative_path}'\n
30
+ require_relative '#{helper_relative_path}'\n"
31
31
 
32
32
  modules_to_include.each do |m|
33
33
  output += "include #{m}\n"
@@ -4,7 +4,12 @@ class CreateTests
4
4
  class << self
5
5
 
6
6
  # Return true or false and the test source code
7
- private def create_test(module_txt, method_txt, method_obj, test_txt)
7
+ private def create_test(module_txt, method_txt, method_obj, test_txt, settings_relative_path: '../../settings/general', cleanup: :after_all)
8
+ unless cleanup == false || [:after_all, :after_each].include?(cleanup)
9
+ message = "** Wrong cleanup parameter: #{cleanup}"
10
+ raise message
11
+ end
12
+
8
13
  modified = false
9
14
  mod_name = module_txt.scan(/::(\w+)$/).join
10
15
  req_txt = "#{method_txt}("
@@ -13,13 +18,14 @@ class CreateTests
13
18
  method_obj.parameters.each do |p|
14
19
  if p[0] == :req #required
15
20
  params << "@#{p[1]}"
16
- elsif p[0] == :key and Object.const_defined?(p[1].to_s.upcase)
21
+ elsif p[0] == :key and p[1].to_s.match?(/^[a-z]/i) and Object.const_defined?(p[1].to_s.upcase)
17
22
  keywords_required << p[1]
18
23
  end
19
24
  end
20
25
  req_txt += params.join(", ")
21
26
  req_txt += ")"
22
- request = eval("require 'nice_hash';#{module_txt}.#{req_txt}")
27
+ require 'nice_hash'
28
+ request = method_obj.call(*Array.new(params.size))
23
29
 
24
30
  req_txt = "#{mod_name}.#{req_txt}"
25
31
  params_declaration_txt = ""
@@ -29,20 +35,75 @@ class CreateTests
29
35
  @params << p
30
36
  end
31
37
 
38
+ all_params_for_chain = params + keywords_required.map { |k| "@#{k}" }
39
+ resource_chain, target_resource = extract_resource_chain(request, all_params_for_chain)
40
+ @setup_cleanup_resources ||= []
41
+ @setup_cleanup_resources.concat(resource_chain) unless resource_chain.empty?
42
+ @setup_cleanup_resources << target_resource if target_resource
43
+
44
+ is_delete = request[:method] == :delete
45
+ needs_target_setup = target_resource && [:delete, :get, :patch].include?(request[:method])
46
+ parent_resource = resource_chain.last
47
+
48
+ method_suffix = method_txt.to_s.split("_").map { |w| w[0..2] }.join[0..2]
49
+ method_suffix = "-#{method_suffix}"
50
+
51
+ setup_before_all_txt = ""
52
+ setup_before_each_txt = ""
53
+ after_each_txt = ""
54
+ after_all_txt = ""
55
+
56
+ if is_delete && target_resource && parent_resource
57
+ setup_before_all_txt = "expect(Helper.setup_#{parent_resource[:resource]}(@http, #{parent_resource[:params_up_to].join(', ')}).state).to eq 'Succeeded'\n"
58
+ setup_before_each_txt = "expect(Helper.setup_#{target_resource[:resource]}(@http, #{target_resource[:params_up_to].join(', ')}).state).to eq 'Succeeded'\n"
59
+ if cleanup
60
+ after_each_txt = "after(:each) do\nHelper.cleanup_#{target_resource[:resource]}(@http, #{target_resource[:params_up_to].join(', ')})\nend\n"
61
+ after_all_txt = "after(:all) do\nunless defined?(DONT_DELETE) && DONT_DELETE\nHelper.cleanup_#{parent_resource[:resource]}(@http, #{parent_resource[:params_up_to].join(', ')})\nend\nend\n"
62
+ end
63
+ elsif needs_target_setup && target_resource
64
+ setup_before_all_txt = "expect(Helper.setup_#{target_resource[:resource]}(@http, #{target_resource[:params_up_to].join(', ')}).state).to eq 'Succeeded'\n"
65
+ if cleanup
66
+ after_all_txt = "after(:all) do\nunless defined?(DONT_DELETE) && DONT_DELETE\nHelper.cleanup_#{target_resource[:resource]}(@http, #{target_resource[:params_up_to].join(', ')})\nend\nend\n"
67
+ end
68
+ elsif parent_resource
69
+ setup_before_all_txt = "expect(Helper.setup_#{parent_resource[:resource]}(@http, #{parent_resource[:params_up_to].join(', ')}).state).to eq 'Succeeded'\n"
70
+ if cleanup && target_resource
71
+ after_each_txt = "after(:each) do\nHelper.cleanup_#{target_resource[:resource]}(@http, #{target_resource[:params_up_to].join(', ')})\nend\n"
72
+ after_all_txt = "after(:all) do\nunless defined?(DONT_DELETE) && DONT_DELETE\nHelper.cleanup_#{parent_resource[:resource]}(@http, #{parent_resource[:params_up_to].join(', ')})\nend\nend\n"
73
+ elsif cleanup
74
+ after_all_txt = "after(:all) do\nunless defined?(DONT_DELETE) && DONT_DELETE\nHelper.cleanup_#{parent_resource[:resource]}(@http, #{parent_resource[:params_up_to].join(', ')})\nend\nend\n"
75
+ end
76
+ end
77
+
78
+ if cleanup == :after_each && !after_all_txt.empty?
79
+ after_each_txt += after_all_txt.sub("after(:all)", "after(:each)")
80
+ after_all_txt = ""
81
+ end
82
+
32
83
  if test_txt ==""
33
84
  modified = true
85
+
86
+ suffix_txt = ""
87
+ if target_resource
88
+ target_param = target_resource[:params_up_to].last
89
+ suffix_txt = "#{target_param} = #{target_param} + \"#{method_suffix}\"\n"
90
+ end
91
+
92
+ before_each_block = "before(:each) do |example|\n"
93
+ before_each_block << "@http = NiceHttp.new()\n" if is_delete && target_resource
94
+ before_each_block << setup_before_each_txt
95
+ before_each_block << "@http.logger.info(\"\\n\\n\#{'='*100}\\nTest: \#{example.description}\\n\#{'-'*100}\")\nend\n"
96
+
34
97
  output = "
35
- require_relative '../../settings/general'
98
+ require_relative '#{settings_relative_path}'
36
99
  if defined?(#{mod_name}) and defined?(#{mod_name}.#{method_txt})
37
100
  RSpec.describe #{mod_name}, '##{method_txt}' do
38
101
  before(:all) do
39
102
  @http = NiceHttp.new()
40
- #{params_declaration_txt}@request = #{req_txt}
103
+ #{params_declaration_txt}#{suffix_txt}#{setup_before_all_txt}@request = #{req_txt}
41
104
  @http.logger.info(\"\\n\#{'+'*50} Before All ends \#{'+'*50}\")
42
105
  end
43
- before(:each) do |example|
44
- @http.logger.info(\"\\n\\n\#{'='*100}\\nTest: \#{example.description}\\n\#{'-'*100}\")
45
- end\n"
106
+ #{after_all_txt}#{after_each_txt}#{before_each_block}\n"
46
107
  else
47
108
  output = test_txt
48
109
  if output.match?(/\s*end\s*end\s*end\s*\Z/)
@@ -64,11 +125,8 @@ class CreateTests
64
125
  expect(resp.code).to eq #{code}\n"
65
126
 
66
127
  if request[:responses][code].is_a?(Hash) and request[:responses][code].key?(:data)
67
- if request.key?(:data_pattern)
68
- tests[title] +="expect(NiceHash.compare_structure(@request.responses._#{code}.data, resp.data.json, true, @request.data_pattern)).to be true\n"
69
- else
70
- tests[title] +="expect(NiceHash.compare_structure(@request.responses._#{code}.data, resp.data.json, true)).to be true\n"
71
- end
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"
72
130
  end
73
131
  tests[title] += "end\n"
74
132
  end
@@ -113,6 +171,45 @@ class CreateTests
113
171
  tests["it 'returns error if required parameter empty' "] = "do\n#{empty_param}"
114
172
  end
115
173
 
174
+ if request.key?(:mock_response)
175
+ title = "it 'returns expected mock response' "
176
+ tests[title] = "do
177
+ @http_mock = NiceHttp.new()
178
+ @http_mock.use_mocks = true
179
+ resp = @http_mock.#{request[:method]}(@request)
180
+ expect(resp.code).to eq @request[:mock_response][:code]
181
+ expect(resp.message).to eq @request[:mock_response][:message]\n"
182
+ if request[:mock_response].key?(:data)
183
+ tests[title] += "expect(NiceHash.compare_structure(@request[:mock_response][:data], resp.data.json, true)).to be true\n"
184
+ end
185
+ tests[title] += "end\n"
186
+ end
187
+
188
+ if request.key?(:data) and [:post, :put, :patch].include?(request[:method])
189
+ title = "it 'handles multiple valid data variations' "
190
+ tests[title] = "do
191
+ @request[:data].generate_n(5, :correct).each do |generated_data|
192
+ request = @request.deep_copy
193
+ request[:data] = generated_data
194
+ resp = @http.#{request[:method]}(request)
195
+ expect(resp.code.to_i).to be_between(200, 299)
196
+ end
197
+ end\n"
198
+ end
199
+
200
+ if request.key?(:data)
201
+ title = "it 'returns error when individual data fields are invalid' "
202
+ 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|
205
+ request = @request.deep_copy
206
+ request[:data] = one_wrong
207
+ resp = @http.#{request[:method]}(request)
208
+ expect(resp.code.to_i).not_to be_between(200, 299)
209
+ end
210
+ end\n"
211
+ end
212
+
116
213
  if request.key?(:data) and request.key?(:data_required)
117
214
  empty_param_data = ""
118
215
  empty_param_data += "
@@ -11,20 +11,27 @@ class CreateTests
11
11
  # :overwrite, it will overwrite the test, settings, helper... files in case they exist so you will loose your original source code.
12
12
  # :dont_overwrite, it will create only the files that don't exist previously
13
13
  # :append, it will append or create the tests or helpers that corrently don't exist on every file, but it won't modify any other code.
14
+ # @param dry_run [Boolean]. (default false). Preview which files would be created or modified without writing anything.
15
+ # @param return_data [Boolean]. (default false). Return a Hash with generated file paths as keys and content as values, without writing files.
16
+ # @param spec_dir [String]. (default './spec'). Output directory for generated test files.
17
+ # @param settings_dir [String]. (default './settings'). Output directory for generated settings files.
18
+ # @param cleanup [Symbol, false]. (default :after_all). :after_all, :after_each, or false. Controls cleanup hook generation.
14
19
  ##############################################################################
15
- def self.from(requests_file, type: :request_hash, test: :rspec, mode: :append)
20
+ def self.from(requests_file, type: :request_hash, test: :rspec, mode: :append, dry_run: false, return_data: false, spec_dir: './spec', settings_dir: './settings', cleanup: :after_all)
21
+ no_write = dry_run || return_data
22
+ @generated_data = {} if return_data
23
+
16
24
  begin
17
- f = File.new("#{requests_file}_create_tests.log", "w")
18
- f.sync = true
19
- @logger = Logger.new f
20
- puts "- Logs: #{requests_file}_create_tests.log"
25
+ f = File.new("#{requests_file}_create_tests.log", "w") unless no_write
26
+ f.sync = true if f
27
+ @logger = Logger.new(f)
28
+ puts "- Logs: #{requests_file}_create_tests.log" unless no_write
21
29
  rescue StandardError => e
22
30
  warn "** Not possible to create the Logger file"
23
31
  warn e
24
32
  @logger = Logger.new nil
25
33
  end
26
34
  @logger.info "requests_file: #{requests_file}, type: #{type}, test: #{test}, mode: #{mode}"
27
- requests_file_orig = requests_file
28
35
 
29
36
  requests_file = if requests_file["./"].nil?
30
37
  requests_file
@@ -55,12 +62,18 @@ class CreateTests
55
62
  raise message
56
63
  end
57
64
 
65
+ unless cleanup == false || [:after_all, :after_each].include?(cleanup)
66
+ message = "** Wrong cleanup parameter: #{cleanup}"
67
+ @logger.fatal message
68
+ raise message
69
+ end
70
+
58
71
  if mode == :overwrite
59
72
  message = "** Pay attention, if any of the files exist, will be overwritten"
60
73
  @logger.warn message
61
74
  warn message
62
75
  elsif mode == :append
63
- if Dir["./spec/*/**_spec.rb"].size > 0
76
+ if Dir["#{spec_dir}/*/**_spec.rb"].size > 0
64
77
  message = "** Pay attention, if any of the test files exist or the help file exist only will be added the tests, methods that are missing."
65
78
  @logger.warn message
66
79
  warn message
@@ -68,13 +81,25 @@ class CreateTests
68
81
  end
69
82
 
70
83
  @params = Array.new
84
+ @setup_cleanup_resources = Array.new
85
+
86
+ require 'pathname'
87
+ # Resolve symlinks (e.g. macOS /tmp -> /private/tmp) so require_relative
88
+ # paths stay valid when settings/spec dirs live outside the project tree.
89
+ resolved_settings_dir = resolve_pathname(settings_dir)
90
+ resolved_spec_dir = resolve_pathname(spec_dir)
91
+ settings_path = resolved_settings_dir.join('general')
92
+ helper_path = resolved_spec_dir.join('helper.rb')
93
+ settings_from_helper = settings_path.relative_path_from(resolved_spec_dir).to_s
94
+ helper_from_settings = helper_path.relative_path_from(resolved_settings_dir).to_s
95
+ requests_from_settings = resolve_pathname(requests_file).relative_path_from(resolved_settings_dir).to_s
71
96
 
72
- Dir.mkdir "./spec" unless test != :rspec or Dir.exist?("./spec")
97
+ Dir.mkdir spec_dir unless no_write or test != :rspec or Dir.exist?(spec_dir)
73
98
 
74
99
  add_settings = true
75
- settings_file = "./settings/general.rb"
76
- helper_file = './spec/helper.rb'
77
- Dir.mkdir "./settings" unless Dir.exist?("./settings")
100
+ settings_file = "#{settings_dir}/general.rb"
101
+ helper_file = "#{spec_dir}/helper.rb"
102
+ Dir.mkdir settings_dir unless no_write or Dir.exist?(settings_dir)
78
103
  if File.exist?(settings_file) and mode!=:overwrite
79
104
  message = "** The file #{settings_file} already exists so no content will be added to it.\n"
80
105
  message += " Remove the settings file to be able to be generated by create_tests or set mode: :overwrite"
@@ -97,8 +122,8 @@ class CreateTests
97
122
  end
98
123
 
99
124
  begin
100
- eval("require '#{requests_file}'")
101
- rescue Exception => stack
125
+ require requests_file
126
+ rescue StandardError => stack
102
127
  message = "\n\n** Error evaluating the ruby file containing the requests: \n" + stack.to_s
103
128
  @logger.fatal message
104
129
  raise message
@@ -126,22 +151,28 @@ class CreateTests
126
151
  mods_to_include << m.scan(/^(.+)::/).join
127
152
  end
128
153
  mods_to_include.uniq!
129
- File.open(settings_file, "w") { |file| file.write(create_settings(requests_file_orig, mods_to_include)) }
154
+ settings_content = create_settings(requests_from_settings, mods_to_include, helper_relative_path: helper_from_settings)
155
+ if no_write
156
+ @generated_data[settings_file] = settings_content if return_data
157
+ puts "- Settings (dry run): #{settings_file}" if dry_run
158
+ else
159
+ File.open(settings_file, "w") { |file| file.write(settings_content) }
160
+ system("rufo", settings_file, out: File::NULL, err: File::NULL)
161
+ end
130
162
  message = "- Settings: #{settings_file}"
131
163
  @logger.info message
132
- puts message
133
- `rufo #{settings_file}`
164
+ puts message unless no_write
134
165
  end
135
166
 
136
167
  modules.each do |mod_txt|
137
168
  mod_name = mod_txt.scan(/::(\w+)$/).join
138
- folder = "./spec/#{mod_name}"
139
- unless Dir.exist?(folder)
169
+ folder = "#{spec_dir}/#{mod_name}"
170
+ unless no_write or Dir.exist?(folder)
140
171
  Dir.mkdir folder
141
172
  @logger.info "Created folder: #{folder}"
142
173
  end
143
- mod_obj = eval("#{mod_txt}")
144
- mod_methods_txt = eval ("#{mod_txt}.methods(false)")
174
+ mod_obj = Object.const_get(mod_txt)
175
+ mod_methods_txt = mod_obj.methods(false)
145
176
  mod_methods_txt.each do |method_txt|
146
177
  test_file = "#{folder}/#{method_txt}_spec.rb"
147
178
  if File.exist?(test_file) and mode==:dont_overwrite
@@ -155,13 +186,18 @@ class CreateTests
155
186
  else
156
187
  test_txt = ''
157
188
  end
158
- modified, txt = create_test(mod_txt, method_txt, mod_obj.method(method_txt),test_txt)
159
- File.open(test_file, "w") { |file| file.write(txt) }
160
- `rufo #{test_file}`
189
+ settings_from_test = settings_path.relative_path_from(resolve_pathname(folder)).to_s
190
+ modified, txt = create_test(mod_txt, method_txt, mod_obj.method(method_txt), test_txt, settings_relative_path: settings_from_test, cleanup: cleanup)
191
+ if no_write
192
+ @generated_data[test_file] = txt if return_data
193
+ else
194
+ File.open(test_file, "w") { |file| file.write(txt) }
195
+ system("rufo", test_file, out: File::NULL, err: File::NULL)
196
+ end
161
197
  if test_txt == ""
162
- message = "- Test created: #{test_file}"
198
+ message = "- Test #{no_write ? 'would be created' : 'created'}: #{test_file}"
163
199
  elsif modified
164
- message = "- Test updated: #{test_file}"
200
+ message = "- Test #{no_write ? 'would be updated' : 'updated'}: #{test_file}"
165
201
  else
166
202
  message = "- Test without changes: #{test_file}"
167
203
  end
@@ -175,11 +211,72 @@ class CreateTests
175
211
 
176
212
  if add_helper
177
213
  @params.uniq!
178
- File.open(helper_file, "w") { |file| file.write(create_helper(@params, helper_txt)) }
179
- message = "- Helper: #{helper_file}"
180
- @logger.info message
181
- puts message
182
- `rufo #{helper_file}`
214
+ helper_dir = "./helper"
215
+ chain_requires = []
216
+ if @setup_cleanup_resources.size > 0
217
+ spec_pathname = Pathname.new(spec_dir)
218
+ chain_requires = [
219
+ Pathname.new("#{helper_dir}/setup").relative_path_from(spec_pathname).to_s,
220
+ Pathname.new("#{helper_dir}/cleanup").relative_path_from(spec_pathname).to_s,
221
+ ]
222
+ end
223
+ helper_content = create_helper(@params, helper_txt, settings_relative_path: settings_from_helper, chain_requires: chain_requires)
224
+ if no_write
225
+ @generated_data[helper_file] = helper_content if return_data
226
+ puts "- Helper (dry run): #{helper_file}" if dry_run
227
+ else
228
+ File.open(helper_file, "w") { |file| file.write(helper_content) }
229
+ system("rufo", helper_file, out: File::NULL, err: File::NULL)
230
+ message = "- Helper: #{helper_file}"
231
+ @logger.info message
232
+ puts message
233
+ end
234
+
235
+ if @setup_cleanup_resources.size > 0
236
+ write_chain_file = lambda do |path, content, label|
237
+ if File.exist?(path) && mode != :overwrite
238
+ message = "** The file #{path} already exists so it will be left unchanged.\n"
239
+ message += " Remove the file to regenerate it or set mode: :overwrite"
240
+ @logger.warn message
241
+ warn message
242
+ return
243
+ end
244
+ if no_write
245
+ @generated_data[path] = content if return_data
246
+ puts "- #{label} (dry run): #{path}" if dry_run
247
+ else
248
+ Dir.mkdir helper_dir unless Dir.exist?(helper_dir)
249
+ File.open(path, "w") { |file| file.write(content) }
250
+ system("rufo", path, out: File::NULL, err: File::NULL)
251
+ message = "- #{label}: #{path}"
252
+ @logger.info message
253
+ puts message
254
+ end
255
+ end
256
+
257
+ write_chain_file.call("#{helper_dir}/setup.rb", create_setup_file(@setup_cleanup_resources), "Helper setup")
258
+ write_chain_file.call("#{helper_dir}/cleanup.rb", create_cleanup_file(@setup_cleanup_resources), "Helper cleanup")
259
+ end
260
+ end
261
+
262
+ return @generated_data if return_data
263
+ end
264
+
265
+ # Expand path and resolve symlinks for existing ancestors so relative
266
+ # require paths stay valid across mounts like macOS /tmp -> /private/tmp.
267
+ def self.resolve_pathname(path)
268
+ pn = Pathname.new(File.expand_path(path.to_s))
269
+ return pn.realpath if pn.exist?
270
+
271
+ missing = []
272
+ current = pn
273
+ until current.exist? || current.root?
274
+ missing.unshift(current.basename)
275
+ current = current.dirname
183
276
  end
277
+ resolved = current.exist? ? current.realpath : current
278
+ missing.each { |part| resolved += part }
279
+ resolved
184
280
  end
281
+ private_class_method :resolve_pathname
185
282
  end
@@ -6,13 +6,13 @@ class CreateTests
6
6
  # fex: ['Swagger::UberApi::V1_0_0::Products', 'Swagger::UberApi::V1_0_0::Cities']
7
7
  private def get_modules(mod)
8
8
  modules = []
9
- mod = eval(mod) if mod.kind_of?(String)
9
+ mod = Object.const_get(mod) if mod.is_a?(String)
10
10
  mod.constants.each do |m|
11
- o = eval ("#{mod}::#{m}.constants")
12
- if o.size == 0
11
+ child = mod.const_get(m)
12
+ if child.constants.empty?
13
13
  modules << "#{mod}::#{m}"
14
14
  else
15
- modules = get_modules("#{mod}::#{m}")
15
+ modules += get_modules("#{mod}::#{m}")
16
16
  end
17
17
  end
18
18
  modules
@@ -0,0 +1,88 @@
1
+
2
+ class CreateTests
3
+
4
+ class << self
5
+
6
+ # Extracts the resource dependency chain from a request path.
7
+ # Works with both placeholder paths ({param}) and interpolated paths
8
+ # (where params are resolved, possibly to empty strings).
9
+ #
10
+ # @param request [Hash] Request hash containing :path and :method keys
11
+ # @param params [Array<String>] Positional parameter names (e.g. ["@subscription_id", "@pool_name"])
12
+ # @return [Array<Hash>, Hash|nil] Two values: prerequisite chain array and target resource hash (or nil).
13
+ # Each hash has keys: resource (String), param (String), params_up_to (Array)
14
+ private def extract_resource_chain(request, params)
15
+ return [], nil unless request.key?(:path)
16
+ return [], nil if params.size < 2
17
+
18
+ path = request[:path].split("?").first
19
+ param_names = params.map { |p| p.gsub("@", "") }
20
+
21
+ placeholder_mode = path.include?("{")
22
+
23
+ if placeholder_mode
24
+ segments = path.split("/").reject(&:empty?)
25
+ resource_pairs = []
26
+ i = 0
27
+ while i < segments.size
28
+ seg = segments[i]
29
+ next_seg = segments[i + 1]
30
+ if next_seg && next_seg.match?(/\A\{.+\}\z/)
31
+ placeholder = next_seg.gsub(/[{}]/, "")
32
+ resource_pairs << { segment: seg, placeholder: placeholder }
33
+ i += 2
34
+ else
35
+ i += 1
36
+ end
37
+ end
38
+ else
39
+ segments = path.split("/")
40
+ segments.shift if segments.first == ""
41
+
42
+ resource_pairs = []
43
+ param_idx = 0
44
+ i = 0
45
+ while i < segments.size && param_idx < param_names.size
46
+ seg = segments[i]
47
+ next_seg = segments[i + 1]
48
+ if seg != "" && (next_seg.nil? || next_seg == "")
49
+ resource_pairs << { segment: seg, placeholder: param_names[param_idx] }
50
+ param_idx += 1
51
+ i += 2
52
+ else
53
+ i += 1
54
+ end
55
+ end
56
+ end
57
+
58
+ return [], nil if resource_pairs.size <= 1
59
+
60
+ all_entries = resource_pairs.each_with_index.map do |pair, idx|
61
+ resource_name = to_snake_case(pair[:segment])
62
+
63
+ matching_param = param_names.find { |p| p == pair[:placeholder] || p.end_with?("_#{pair[:placeholder]}") || p.include?(pair[:placeholder]) }
64
+ matching_param ||= pair[:placeholder]
65
+
66
+ params_up_to = []
67
+ (0..idx).each do |j|
68
+ ph = resource_pairs[j][:placeholder]
69
+ mp = param_names.find { |p| p == ph || p.end_with?("_#{ph}") || p.include?(ph) }
70
+ params_up_to << "@#{mp || ph}"
71
+ end
72
+
73
+ { resource: resource_name, param: matching_param, params_up_to: params_up_to }
74
+ end
75
+
76
+ prerequisites = all_entries[0..-2]
77
+ target = all_entries.last
78
+
79
+ return prerequisites, target
80
+ end
81
+
82
+ private def to_snake_case(str)
83
+ str.gsub(/([A-Z]+)([A-Z][a-z])/, '\1_\2')
84
+ .gsub(/([a-z\d])([A-Z])/, '\1_\2')
85
+ .downcase
86
+ end
87
+ end
88
+ end
@@ -0,0 +1,3 @@
1
+ class CreateTests
2
+ VERSION = "1.0.0"
3
+ end
data/lib/create_tests.rb CHANGED
@@ -1,8 +1,10 @@
1
1
 
2
2
  require "logger"
3
3
 
4
+ require_relative 'create-tests/version'
4
5
  require_relative 'create-tests/create_helper'
5
6
  require_relative 'create-tests/create_settings'
6
7
  require_relative 'create-tests/create_test'
7
8
  require_relative 'create-tests/from'
8
9
  require_relative 'create-tests/get_modules'
10
+ require_relative 'create-tests/resource_chain'
metadata CHANGED
@@ -1,14 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: create_tests
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.4
4
+ version: 1.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mario Ruiz
8
- autorequire:
9
8
  bindir: bin
10
9
  cert_chain: []
11
- date: 2022-10-19 00:00:00.000000000 Z
10
+ date: 1980-01-02 00:00:00.000000000 Z
12
11
  dependencies:
13
12
  - !ruby/object:Gem::Dependency
14
13
  name: rufo
@@ -16,28 +15,28 @@ dependencies:
16
15
  requirements:
17
16
  - - "~>"
18
17
  - !ruby/object:Gem::Version
19
- version: '0.13'
18
+ version: '0.16'
20
19
  type: :runtime
21
20
  prerelease: false
22
21
  version_requirements: !ruby/object:Gem::Requirement
23
22
  requirements:
24
23
  - - "~>"
25
24
  - !ruby/object:Gem::Version
26
- version: '0.13'
25
+ version: '0.16'
27
26
  - !ruby/object:Gem::Dependency
28
27
  name: nice_hash
29
28
  requirement: !ruby/object:Gem::Requirement
30
29
  requirements:
31
30
  - - "~>"
32
31
  - !ruby/object:Gem::Version
33
- version: '1.17'
32
+ version: '1.19'
34
33
  type: :runtime
35
34
  prerelease: false
36
35
  version_requirements: !ruby/object:Gem::Requirement
37
36
  requirements:
38
37
  - - "~>"
39
38
  - !ruby/object:Gem::Version
40
- version: '1.17'
39
+ version: '1.19'
41
40
  - !ruby/object:Gem::Dependency
42
41
  name: rspec
43
42
  requirement: !ruby/object:Gem::Requirement
@@ -59,25 +58,19 @@ dependencies:
59
58
  - !ruby/object:Gem::Version
60
59
  version: 3.8.0
61
60
  - !ruby/object:Gem::Dependency
62
- name: coveralls
61
+ name: simplecov
63
62
  requirement: !ruby/object:Gem::Requirement
64
63
  requirements:
65
64
  - - "~>"
66
65
  - !ruby/object:Gem::Version
67
- version: '0.8'
68
- - - ">="
69
- - !ruby/object:Gem::Version
70
- version: 0.8.22
66
+ version: '0.22'
71
67
  type: :development
72
68
  prerelease: false
73
69
  version_requirements: !ruby/object:Gem::Requirement
74
70
  requirements:
75
71
  - - "~>"
76
72
  - !ruby/object:Gem::Version
77
- version: '0.8'
78
- - - ">="
79
- - !ruby/object:Gem::Version
80
- version: 0.8.22
73
+ version: '0.22'
81
74
  description: CreateTests -- Create Tests automatically from a Requests file. Perfect
82
75
  to be used with the result from importing a Swagger file using the open_api_import
83
76
  gem
@@ -98,6 +91,8 @@ files:
98
91
  - lib/create-tests/create_test.rb
99
92
  - lib/create-tests/from.rb
100
93
  - lib/create-tests/get_modules.rb
94
+ - lib/create-tests/resource_chain.rb
95
+ - lib/create-tests/version.rb
101
96
  - lib/create_tests.rb
102
97
  homepage: https://github.com/MarioRuiz/create_tests
103
98
  licenses:
@@ -111,15 +106,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
111
106
  requirements:
112
107
  - - ">="
113
108
  - !ruby/object:Gem::Version
114
- version: '2.7'
109
+ version: '3.0'
115
110
  required_rubygems_version: !ruby/object:Gem::Requirement
116
111
  requirements:
117
112
  - - ">="
118
113
  - !ruby/object:Gem::Version
119
114
  version: '0'
120
115
  requirements: []
121
- rubygems_version: 3.2.15
122
- signing_key:
116
+ rubygems_version: 4.0.6
123
117
  specification_version: 4
124
118
  summary: CreateTests -- Create Tests automatically from a Requests file. Perfect to
125
119
  be used with the result from importing a Swagger file using the open_api_import