swagger_autogenerate 1.2.4 → 1.2.6
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/CHANGELOG.md +2 -0
- data/Gemfile.lock +1 -1
- data/README.md +2 -2
- data/lib/swagger_autogenerate/swagger_trace.rb +159 -72
- data/lib/swagger_autogenerate/version.rb +1 -1
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 711b43ae4aa65205938e96a052bcbc97afe0320ae62608c864b85ca7a5a8c5c1
|
4
|
+
data.tar.gz: 389a4adf130cb3c09bf1575ac5e1f2916dc38b47021ea5e7396b38bb482fa052
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d472c6a346336bd81902c6da48b1b1e814bcc0153f2a7bb71df92239aa85b3f1d1e70c307fa1872814e7657412f6234e0fd870c7196a36f3f12ff164dda9a535
|
7
|
+
data.tar.gz: 36dffa08dfcc34b94aee951b867e5ba383eb79f5327d53d0e3c403e29841cc27f772cc691ad526cc85ab4e7b38e67fff6fcf24319a701342536b20e8119c5b86
|
data/CHANGELOG.md
CHANGED
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -47,8 +47,8 @@ To configure the swagger_autogenerate gem in your Rails application, follow thes
|
|
47
47
|
```
|
48
48
|
SwaggerAutogenerate.configure do |config|
|
49
49
|
config.with_config = true
|
50
|
-
config.with_example_description = true
|
51
50
|
config.with_multiple_examples = true
|
51
|
+
action_for_old_examples = :append # :replace or :append
|
52
52
|
config.with_response_description = true
|
53
53
|
end
|
54
54
|
|
@@ -64,7 +64,7 @@ This file should contain the test scenarios for each action (e.g., index, show,
|
|
64
64
|
|
65
65
|
3) Run the spec code using the rspec command and set the environment variable SWAGGER to the desired YAML file name. For example:
|
66
66
|
```
|
67
|
-
|
67
|
+
SWAGGER_GENERATE_PATH='employee_apis.yaml' rspec spec/your_path/employees_controller_spec.rb
|
68
68
|
```
|
69
69
|
4) This command runs the spec file and instructs the swagger_autogenerate gem to generate Swagger YAML documentation and save it to the file named employee_apis.yaml.
|
70
70
|
5) Once the command finishes executing, you will have the Swagger YAML documentation generated based on the test scenarios in the employees_controller_spec.rb file.
|
@@ -7,6 +7,7 @@ module SwaggerAutogenerate
|
|
7
7
|
@with_multiple_examples = ::SwaggerAutogenerate.configuration.with_multiple_examples
|
8
8
|
@with_rspec_examples = ::SwaggerAutogenerate.configuration.with_rspec_examples
|
9
9
|
@with_response_description = ::SwaggerAutogenerate.configuration.with_response_description
|
10
|
+
@with_payload_properties = ::SwaggerAutogenerate.configuration.with_payload_properties
|
10
11
|
@security = ::SwaggerAutogenerate.configuration.security
|
11
12
|
@swagger_config = ::SwaggerAutogenerate.configuration.swagger_config
|
12
13
|
@response_status = ::SwaggerAutogenerate.configuration.response_status
|
@@ -50,7 +51,7 @@ module SwaggerAutogenerate
|
|
50
51
|
|
51
52
|
attr_reader :request, :response, :current_path, :yaml_file, :configuration,
|
52
53
|
:with_config, :with_multiple_examples, :with_rspec_examples,
|
53
|
-
:with_response_description, :security, :response_status, :swagger_config,
|
54
|
+
:with_response_description, :with_payload_properties, :security, :response_status, :swagger_config,
|
54
55
|
:default_path, :action_for_old_examples
|
55
56
|
|
56
57
|
# main methods
|
@@ -59,7 +60,10 @@ module SwaggerAutogenerate
|
|
59
60
|
path = request.path
|
60
61
|
|
61
62
|
request.path_parameters.except(:controller, :format, :action).each do |k, v|
|
62
|
-
|
63
|
+
path_array = path.split('/')
|
64
|
+
index = path_array.rindex(v)
|
65
|
+
path_array[index] = "{#{k}}"
|
66
|
+
path.replace(path_array.join('/'))
|
63
67
|
end
|
64
68
|
|
65
69
|
@current_path = path
|
@@ -75,7 +79,7 @@ module SwaggerAutogenerate
|
|
75
79
|
'requestBody' => request_body,
|
76
80
|
'parameters' => parameters,
|
77
81
|
'responses' => {},
|
78
|
-
'security' =>
|
82
|
+
'security' => current_security
|
79
83
|
}
|
80
84
|
}
|
81
85
|
|
@@ -98,6 +102,7 @@ module SwaggerAutogenerate
|
|
98
102
|
|
99
103
|
def create_file
|
100
104
|
File.open(swagger_location, 'w') do |file|
|
105
|
+
return file.write(YAML.dump({ 'paths' => {} })) if paths.blank?
|
101
106
|
data = with_config ? swagger_config : {}
|
102
107
|
data['paths'] = paths
|
103
108
|
organize_result(data['paths'])
|
@@ -108,18 +113,21 @@ module SwaggerAutogenerate
|
|
108
113
|
current_example = old_examples[example_title]
|
109
114
|
new_example(example_title, current_example, old_examples, data['paths'], true)
|
110
115
|
# result
|
111
|
-
|
112
|
-
result =
|
116
|
+
result = reformat_dates_in_hash(data)
|
117
|
+
result = convert_to_hash(result)
|
118
|
+
result = YAML.dump(result)
|
113
119
|
file.write(result)
|
114
120
|
end
|
115
121
|
end
|
116
122
|
|
117
123
|
def edit_file
|
118
|
-
@yaml_file =
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
124
|
+
@yaml_file = \
|
125
|
+
YAML.safe_load(
|
126
|
+
File.read(swagger_location),
|
127
|
+
aliases: true,
|
128
|
+
permitted_classes: [Symbol, DateTime, Date, Time, ActiveSupport::HashWithIndifferentAccess],
|
129
|
+
permitted_symbols: []
|
130
|
+
)
|
123
131
|
|
124
132
|
return create_file if yaml_file.nil? || yaml_file['paths'].nil?
|
125
133
|
|
@@ -129,7 +137,9 @@ module SwaggerAutogenerate
|
|
129
137
|
organize_result(yaml_file['paths'])
|
130
138
|
@yaml_file = convert_to_hash(yaml_file)
|
131
139
|
File.open(swagger_location, 'w') do |file|
|
132
|
-
result =
|
140
|
+
result = reformat_dates_in_hash(yaml_file)
|
141
|
+
result = convert_to_hash(result)
|
142
|
+
result = YAML.dump(result)
|
133
143
|
file.write(result)
|
134
144
|
end
|
135
145
|
end
|
@@ -137,6 +147,7 @@ module SwaggerAutogenerate
|
|
137
147
|
# Helpers
|
138
148
|
|
139
149
|
def process_replacing_examples
|
150
|
+
create_file_if_not_exist
|
140
151
|
$removed_examples ||= []
|
141
152
|
if action_for_old_examples == :replace && !$removed_examples.include?({ @current_path => request.method.to_s.downcase })
|
142
153
|
current_yaml_file = YAML.load(
|
@@ -145,10 +156,13 @@ module SwaggerAutogenerate
|
|
145
156
|
permitted_classes: [Symbol, Date, ActiveSupport::HashWithIndifferentAccess]
|
146
157
|
)
|
147
158
|
|
148
|
-
|
159
|
+
hash = { "paths" => { @current_path => { request.method.to_s.downcase => {} } } }
|
149
160
|
|
161
|
+
current_yaml_file&.merge!(hash)
|
150
162
|
File.open(swagger_location, 'w') do |file|
|
151
|
-
result =
|
163
|
+
result = reformat_dates_in_hash(current_yaml_file)
|
164
|
+
result = convert_to_hash(result)
|
165
|
+
result = YAML.dump(result)
|
152
166
|
file.write(result)
|
153
167
|
end
|
154
168
|
|
@@ -156,13 +170,23 @@ module SwaggerAutogenerate
|
|
156
170
|
end
|
157
171
|
end
|
158
172
|
|
159
|
-
def
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
173
|
+
def reformat_dates_in_hash(data)
|
174
|
+
case data
|
175
|
+
when Hash
|
176
|
+
data.each do |key, value|
|
177
|
+
data[key] = reformat_dates_in_hash(value)
|
178
|
+
end
|
179
|
+
when Array
|
180
|
+
data.map! { |element| reformat_dates_in_hash(element) }
|
181
|
+
when String
|
182
|
+
if is_valid_date?(data)
|
183
|
+
convert_to_date(data).to_s
|
184
|
+
else
|
185
|
+
data
|
186
|
+
end
|
187
|
+
else
|
188
|
+
data
|
189
|
+
end
|
166
190
|
end
|
167
191
|
|
168
192
|
def convert_to_hash(obj)
|
@@ -198,6 +222,15 @@ module SwaggerAutogenerate
|
|
198
222
|
hash
|
199
223
|
end
|
200
224
|
|
225
|
+
def schema_type(value)
|
226
|
+
return 'integer' if number?(value)
|
227
|
+
return 'boolean' if (value.try(:downcase) == 'true') || (value.try(:downcase) == 'false')
|
228
|
+
return 'string' if value.instance_of?(String) || value.instance_of?(Symbol)
|
229
|
+
return 'array' if value.instance_of?(Array)
|
230
|
+
|
231
|
+
'object'
|
232
|
+
end
|
233
|
+
|
201
234
|
def set_parameters(parameters, parameter, required: false)
|
202
235
|
return if parameter.blank?
|
203
236
|
|
@@ -222,11 +255,41 @@ module SwaggerAutogenerate
|
|
222
255
|
end
|
223
256
|
|
224
257
|
def tags
|
225
|
-
[ENV['tag'] || controller_name]
|
258
|
+
[yaml_file&.dig('paths', current_path, request.method.downcase, 'tags')&.last&.capitalize || ENV['tag'] || controller_name&.capitalize]
|
226
259
|
end
|
227
260
|
|
228
261
|
def summary
|
229
|
-
|
262
|
+
yaml_file&.dig('paths', current_path, request.method.downcase, 'summary') || handel_summary(request.method.downcase, current_path)
|
263
|
+
end
|
264
|
+
|
265
|
+
def handel_summary(method, path)
|
266
|
+
path_segments = path.split('/')
|
267
|
+
resource = format_path_to_title(path)&.gsub(' ', ' ')
|
268
|
+
id_segment = path.include?('{')
|
269
|
+
|
270
|
+
case method.upcase
|
271
|
+
when 'GET'
|
272
|
+
id_segment ? "Get #{resource}" : "Get All #{resource&.pluralize}"
|
273
|
+
when 'POST'
|
274
|
+
"Create #{resource}"
|
275
|
+
when 'PUT'
|
276
|
+
"Update #{resource}"
|
277
|
+
when 'DELETE'
|
278
|
+
"Delete #{resource}"
|
279
|
+
else
|
280
|
+
""
|
281
|
+
end
|
282
|
+
end
|
283
|
+
|
284
|
+
def format_path_to_title(path)
|
285
|
+
cleaned_path = path.sub(%r{^/v\d+/}, '')
|
286
|
+
cleaned_path.gsub!(/\{[^}]+\}/, '')
|
287
|
+
title = cleaned_path.split('/').map(&:capitalize).join(' ')
|
288
|
+
title
|
289
|
+
end
|
290
|
+
|
291
|
+
def current_security
|
292
|
+
yaml_file&.dig('paths', current_path, request.method.downcase, 'security') || security
|
230
293
|
end
|
231
294
|
|
232
295
|
def response_description
|
@@ -328,8 +391,12 @@ module SwaggerAutogenerate
|
|
328
391
|
{ 'type' => 'array', 'items' => { 'oneOf' => item_schemas.uniq } }
|
329
392
|
end
|
330
393
|
when String
|
331
|
-
if
|
332
|
-
{ 'type' => '
|
394
|
+
if integer?(json)
|
395
|
+
{ 'type' => 'integer', 'example' => json.to_i }
|
396
|
+
elsif number?(json)
|
397
|
+
{ 'type' => 'number', 'example' => json.to_f }
|
398
|
+
elsif is_valid_date?(json)
|
399
|
+
{ 'type' => 'string', 'example' => json.to_date.to_s }
|
333
400
|
else
|
334
401
|
{ 'type' => 'string', 'example' => json.to_s }
|
335
402
|
end
|
@@ -340,7 +407,7 @@ module SwaggerAutogenerate
|
|
340
407
|
when TrueClass, FalseClass
|
341
408
|
{ 'type' => 'boolean', 'example' => json }
|
342
409
|
when Date, Time, DateTime
|
343
|
-
{ 'type' => '
|
410
|
+
{ 'type' => 'string', 'example' => json.to_date.to_s }
|
344
411
|
else
|
345
412
|
{ 'type' => 'string', 'example' => json.to_s }
|
346
413
|
end
|
@@ -403,13 +470,10 @@ module SwaggerAutogenerate
|
|
403
470
|
false
|
404
471
|
end
|
405
472
|
|
406
|
-
def
|
407
|
-
|
408
|
-
|
409
|
-
|
410
|
-
return 'array' if value.instance_of?(Array)
|
411
|
-
|
412
|
-
'object'
|
473
|
+
def integer?(value)
|
474
|
+
true if Integer(value)
|
475
|
+
rescue StandardError
|
476
|
+
false
|
413
477
|
end
|
414
478
|
|
415
479
|
def example(value)
|
@@ -428,8 +492,9 @@ module SwaggerAutogenerate
|
|
428
492
|
end
|
429
493
|
|
430
494
|
def convert_to_date(string)
|
431
|
-
datetime =
|
432
|
-
|
495
|
+
datetime = Date.strptime(string)
|
496
|
+
return Date.parse(string).strftime('%Y/%m/%d') if datetime.year == 1
|
497
|
+
datetime.strftime('%Y/%m/%d')
|
433
498
|
rescue ArgumentError
|
434
499
|
string
|
435
500
|
end
|
@@ -474,13 +539,13 @@ module SwaggerAutogenerate
|
|
474
539
|
if ENV[generate_swagger_environment_variable].present?
|
475
540
|
directory_path = Rails.root.join(default_path).to_s
|
476
541
|
FileUtils.mkdir_p(directory_path) unless File.directory?(directory_path)
|
477
|
-
@swagger_location = "#{directory_path}/#{tags
|
542
|
+
@swagger_location = "#{directory_path}/#{snake_case(tags&.first)}.yaml"
|
478
543
|
elsif ENV[swagger_path_environment_variable].include?('.yaml') || ENV[swagger_path_environment_variable].include?('.yml')
|
479
544
|
@swagger_location = Rails.root.join(ENV.fetch(swagger_path_environment_variable, nil).to_s).to_s
|
480
545
|
else
|
481
546
|
directory_path = Rails.root.join(ENV.fetch(swagger_path_environment_variable, nil).to_s).to_s
|
482
547
|
FileUtils.mkdir_p(directory_path) unless File.directory?(directory_path)
|
483
|
-
@swagger_location = "#{directory_path}/#{tags
|
548
|
+
@swagger_location = "#{directory_path}/#{snake_case(tags&.first)}.yaml"
|
484
549
|
end
|
485
550
|
end
|
486
551
|
|
@@ -539,14 +604,17 @@ module SwaggerAutogenerate
|
|
539
604
|
end
|
540
605
|
|
541
606
|
def new_example(example_title, current_example, old_examples, all_paths = yaml_file['paths'], with_schema_properties = false)
|
542
|
-
if
|
543
|
-
|
544
|
-
|
545
|
-
|
546
|
-
|
547
|
-
|
548
|
-
|
549
|
-
|
607
|
+
if with_multiple_examples || old_examples&.keys&.count.to_i <= 1
|
608
|
+
if !old_examples&.value?(current_example)
|
609
|
+
last_example = handel_name_last_example(old_examples)
|
610
|
+
last_example ||= example_title
|
611
|
+
last_example = example_title
|
612
|
+
hash = { 'examples' => { last_example => current_example } }
|
613
|
+
all_paths[current_path][request.method.downcase]['responses'][response.status.to_s]['content']['application/json'].deep_merge!(hash)
|
614
|
+
add_properties_to_schema(last_example, all_paths[current_path])
|
615
|
+
elsif with_schema_properties
|
616
|
+
add_properties_to_schema(full_rspec_description.present? ? full_rspec_description : 'example-0', all_paths[current_path])
|
617
|
+
end
|
550
618
|
end
|
551
619
|
|
552
620
|
true
|
@@ -554,32 +622,34 @@ module SwaggerAutogenerate
|
|
554
622
|
|
555
623
|
def handel_name_last_example(old_examples)
|
556
624
|
last_example = full_rspec_description || old_examples.keys.last
|
557
|
-
if old_examples
|
625
|
+
if old_examples&.keys&.include?(last_example)
|
558
626
|
last_example += '-1'
|
559
627
|
json_example_plus_one(last_example)
|
560
628
|
end
|
561
629
|
end
|
562
630
|
|
563
631
|
def add_properties_to_schema(last_example, main_path = yaml_file['paths'][current_path])
|
564
|
-
|
565
|
-
|
566
|
-
|
567
|
-
|
568
|
-
|
632
|
+
if with_payload_properties
|
633
|
+
parameters = {}
|
634
|
+
parameters.merge!(request_parameters.values.first, query_parameters.values.first, path_parameters.values.first)
|
635
|
+
hash = {
|
636
|
+
last_example => build_properties(parameters.as_json)
|
637
|
+
}
|
569
638
|
|
570
|
-
|
571
|
-
|
572
|
-
|
573
|
-
|
574
|
-
|
575
|
-
|
576
|
-
|
577
|
-
|
639
|
+
main_path[request.method.downcase]['responses'][response.status.to_s].deep_merge!(
|
640
|
+
{
|
641
|
+
'content' => {
|
642
|
+
'application/json' => {
|
643
|
+
'schema' => {
|
644
|
+
'description' => 'These are the payloads for each example',
|
645
|
+
'type' => 'object',
|
646
|
+
'properties' => hash
|
647
|
+
}
|
578
648
|
}
|
579
649
|
}
|
580
650
|
}
|
581
|
-
|
582
|
-
|
651
|
+
)
|
652
|
+
end
|
583
653
|
end
|
584
654
|
|
585
655
|
def apply_yaml_file_changes
|
@@ -595,16 +665,19 @@ module SwaggerAutogenerate
|
|
595
665
|
# checks
|
596
666
|
|
597
667
|
def organize_result(current_paths)
|
598
|
-
|
599
|
-
|
600
|
-
|
601
|
-
|
602
|
-
|
603
|
-
|
604
|
-
|
605
|
-
|
668
|
+
if current_paths.dig(current_path, request.method.downcase).present?
|
669
|
+
new_hash = {
|
670
|
+
'tags' => tags,
|
671
|
+
'summary' => summary
|
672
|
+
}
|
673
|
+
|
674
|
+
new_hash['parameters'] = current_paths[current_path][request.method.downcase]['parameters'] if current_paths.dig(current_path, request.method.downcase, 'parameters')
|
675
|
+
new_hash['requestBody'] = current_paths[current_path][request.method.downcase]['requestBody'] if current_paths.dig(current_path, request.method.downcase, 'requestBody')
|
676
|
+
new_hash['responses'] = current_paths[current_path][request.method.downcase]['responses']
|
677
|
+
new_hash['security'] = current_security
|
606
678
|
|
607
|
-
|
679
|
+
current_paths[current_path][request.method.downcase] = new_hash
|
680
|
+
end
|
608
681
|
end
|
609
682
|
|
610
683
|
def check_path
|
@@ -637,13 +710,13 @@ module SwaggerAutogenerate
|
|
637
710
|
end
|
638
711
|
|
639
712
|
def check_parameters
|
640
|
-
if old_paths[current_path][request.method.downcase]['parameters'].blank?
|
641
|
-
yaml_file['paths'][current_path][request.method.downcase]['parameters'] = paths
|
713
|
+
if old_paths[current_path][request.method.downcase]['parameters'].blank? || old_paths.dig(current_path, request.method.downcase, 'responses')&.key?('200')
|
714
|
+
yaml_file['paths'][current_path][request.method.downcase]['parameters'] = paths.dig(current_path, request.method.downcase, 'parameters') if paths.dig(current_path, request.method.downcase, 'parameters').present?
|
642
715
|
end
|
643
716
|
end
|
644
717
|
|
645
718
|
def check_parameter
|
646
|
-
param_names = paths[current_path][request.method.downcase]['parameters']
|
719
|
+
param_names = Array.wrap(paths[current_path][request.method.downcase]['parameters']&.pluck('name')) - Array.wrap(yaml_file['paths'][current_path][request.method.downcase]['parameters']&.pluck('name'))
|
647
720
|
param_names.each do |param_name|
|
648
721
|
param = paths[current_path][request.method.downcase]['parameters'].find { |parameter| parameter['name'] == param_name }
|
649
722
|
yaml_file['paths'][current_path][request.method.downcase]['parameters'].push(param)
|
@@ -681,6 +754,20 @@ module SwaggerAutogenerate
|
|
681
754
|
with_rspec_examples ? SwaggerAutogenerate::SwaggerTrace.rspec_description : nil
|
682
755
|
end
|
683
756
|
|
757
|
+
def create_file_if_not_exist
|
758
|
+
create_file unless File.exist?(swagger_location)
|
759
|
+
end
|
760
|
+
|
761
|
+
def snake_case(text)
|
762
|
+
return text&.downcase if text&.match?(/\A[A-Z]+\z/)
|
763
|
+
|
764
|
+
text
|
765
|
+
.gsub(/([A-Z]+)([A-Z][a-z])/, '\1_\2')
|
766
|
+
.gsub(/([a-z])([A-Z])/, '\1_\2')
|
767
|
+
.downcase
|
768
|
+
.tr(' ', '_')
|
769
|
+
end
|
770
|
+
|
684
771
|
class << self
|
685
772
|
attr_accessor :rspec_description
|
686
773
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: swagger_autogenerate
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.2.
|
4
|
+
version: 1.2.6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- MohammedBuraiah
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-
|
11
|
+
date: 2024-11-05 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: Generating Swagger YAML Automatically Based on Existing Test Cases in
|
14
14
|
Ruby on Rails
|
@@ -56,7 +56,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
56
56
|
- !ruby/object:Gem::Version
|
57
57
|
version: '0'
|
58
58
|
requirements: []
|
59
|
-
rubygems_version: 3.
|
59
|
+
rubygems_version: 3.1.6
|
60
60
|
signing_key:
|
61
61
|
specification_version: 4
|
62
62
|
summary: Automating Swagger YAML generation in Ruby on Rails offers a range of benefits
|