auto-rswag 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/Gemfile +6 -0
- data/Gemfile.lock +63 -0
- data/lib/auto_rswag.rb +21 -0
- data/lib/auto_rswag_helper.rb +68 -0
- data/lib/doc_writer.rb +38 -0
- data/lib/printer.rb +103 -0
- data/rubocop.yml +8 -0
- metadata +107 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 7bd7f5d1bb6327a80a89497075356aafd2cdcba798b8d7258f2d31c682666a95
|
4
|
+
data.tar.gz: b509baea5844020859126427811398fa40e79496a0d5e66ef3a881c08c841c39
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: db3929e25c816dcd3710c081eed70c089112149d1befb1570de3a84b9306dd4897191b6643a1c47e4c74e9391a4d1b150195172be6d2fbf05f50e33bbc5fdc2e
|
7
|
+
data.tar.gz: 4ba7b0c799057de66e6ed2c8cc852cd67e8c15053344da60a453c0aa3dfeae861e4bacf14e07161cfd876d8f2a138145234afff7efc31cec7d741afc000992ef
|
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,63 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
auto-rswag (0.1.0)
|
5
|
+
|
6
|
+
GEM
|
7
|
+
remote: https://rubygems.org/
|
8
|
+
specs:
|
9
|
+
ast (2.4.0)
|
10
|
+
coderay (1.1.2)
|
11
|
+
coveralls (0.8.23)
|
12
|
+
json (>= 1.8, < 3)
|
13
|
+
simplecov (~> 0.16.1)
|
14
|
+
term-ansicolor (~> 1.3)
|
15
|
+
thor (>= 0.19.4, < 2.0)
|
16
|
+
tins (~> 1.6)
|
17
|
+
docile (1.3.2)
|
18
|
+
jaro_winkler (1.5.4)
|
19
|
+
json (2.3.0)
|
20
|
+
method_source (1.0.0)
|
21
|
+
parallel (1.19.1)
|
22
|
+
parser (2.7.0.5)
|
23
|
+
ast (~> 2.4.0)
|
24
|
+
pry (0.13.0)
|
25
|
+
coderay (~> 1.1)
|
26
|
+
method_source (~> 1.0)
|
27
|
+
rainbow (3.0.0)
|
28
|
+
rexml (3.2.4)
|
29
|
+
rspec (0.9.4)
|
30
|
+
rubocop (0.80.1)
|
31
|
+
jaro_winkler (~> 1.5.1)
|
32
|
+
parallel (~> 1.10)
|
33
|
+
parser (>= 2.7.0.1)
|
34
|
+
rainbow (>= 2.2.2, < 4.0)
|
35
|
+
rexml
|
36
|
+
ruby-progressbar (~> 1.7)
|
37
|
+
unicode-display_width (>= 1.4.0, < 1.7)
|
38
|
+
ruby-progressbar (1.10.1)
|
39
|
+
simplecov (0.16.1)
|
40
|
+
docile (~> 1.1)
|
41
|
+
json (>= 1.8, < 3)
|
42
|
+
simplecov-html (~> 0.10.0)
|
43
|
+
simplecov-html (0.10.2)
|
44
|
+
sync (0.5.0)
|
45
|
+
term-ansicolor (1.7.1)
|
46
|
+
tins (~> 1.0)
|
47
|
+
thor (1.0.1)
|
48
|
+
tins (1.24.1)
|
49
|
+
sync
|
50
|
+
unicode-display_width (1.6.1)
|
51
|
+
|
52
|
+
PLATFORMS
|
53
|
+
ruby
|
54
|
+
|
55
|
+
DEPENDENCIES
|
56
|
+
auto-rswag!
|
57
|
+
coveralls (>= 0.8.23)
|
58
|
+
pry (~> 0)
|
59
|
+
rspec (~> 0)
|
60
|
+
rubocop (>= 0.80.1)
|
61
|
+
|
62
|
+
BUNDLED WITH
|
63
|
+
2.0.2
|
data/lib/auto_rswag.rb
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'json'
|
4
|
+
require_relative 'printer.rb'
|
5
|
+
require_relative 'auto_rswag_helper.rb'
|
6
|
+
require_relative 'doc_writer.rb'
|
7
|
+
|
8
|
+
# This module hooks into the Rspec test to retrieve useful
|
9
|
+
# metadata and submit it to AutoRswagHelper for conversion.
|
10
|
+
module AutoRswag
|
11
|
+
def update_documentation
|
12
|
+
$title = metadata[:response][:schema]['$ref'].split('/').last
|
13
|
+
|
14
|
+
after do
|
15
|
+
payload = AutoRswagHelper.convert_response(response)
|
16
|
+
AutoRswagHelper.map_fields(payload)
|
17
|
+
docs = SwaggerPrinter.print_swagger(payload, $title)
|
18
|
+
DocWriter.write_docs(docs, $title)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,68 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# This class performs conversions of the response data
|
4
|
+
# based on test metadata.
|
5
|
+
class AutoRswagHelper
|
6
|
+
class << self
|
7
|
+
def convert_response(response)
|
8
|
+
return response if [Array, Hash].include?(response.class)
|
9
|
+
|
10
|
+
body = response.body
|
11
|
+
body = body.respond_to?(:read) ? body.read : body
|
12
|
+
|
13
|
+
JSON.parse(body)
|
14
|
+
rescue StandardError
|
15
|
+
body
|
16
|
+
end
|
17
|
+
|
18
|
+
def map_fields(object)
|
19
|
+
if object.is_a? Array
|
20
|
+
object = {
|
21
|
+
type: :array,
|
22
|
+
items: map_fields(object.first)
|
23
|
+
}
|
24
|
+
elsif object.is_a?(Hash)
|
25
|
+
object = {
|
26
|
+
type: :object,
|
27
|
+
properties: map_object_keys(object)
|
28
|
+
}
|
29
|
+
end
|
30
|
+
object
|
31
|
+
end
|
32
|
+
|
33
|
+
def map_object_keys(object)
|
34
|
+
object.keys.each do |key|
|
35
|
+
value = object.delete(key)
|
36
|
+
converted_key = convert(key)
|
37
|
+
if value.is_a? Hash
|
38
|
+
object[converted_key] = {
|
39
|
+
type: :object,
|
40
|
+
properties: value
|
41
|
+
}
|
42
|
+
map_fields(value)
|
43
|
+
elsif value.is_a? Array
|
44
|
+
object[converted_key] = {
|
45
|
+
type: :array,
|
46
|
+
items: [value.first]
|
47
|
+
}
|
48
|
+
map_fields(value)
|
49
|
+
else
|
50
|
+
object[converted_key] = parse_field(value)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
def convert(key)
|
56
|
+
key.to_sym
|
57
|
+
end
|
58
|
+
|
59
|
+
def parse_field(value)
|
60
|
+
type = value.nil? ? :string : value.class.to_s.downcase.to_sym
|
61
|
+
{
|
62
|
+
type: type,
|
63
|
+
example: value,
|
64
|
+
'x-nullable' => true
|
65
|
+
}
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
data/lib/doc_writer.rb
ADDED
@@ -0,0 +1,38 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# This class writes the parsed documenation to the swagger_helper file.
|
4
|
+
class DocWriter
|
5
|
+
class << self
|
6
|
+
def default_docs_path
|
7
|
+
Rails.root.join('spec', 'swagger_helper.rb').to_s
|
8
|
+
end
|
9
|
+
|
10
|
+
def write_docs(docs, fragment_title)
|
11
|
+
old_documentation = File.read(default_docs_path)
|
12
|
+
new_documentation_fragment = example_hash(fragment_title, old_documentation)
|
13
|
+
return if new_documentation_fragment.nil?
|
14
|
+
|
15
|
+
new_documentation = old_documentation.sub(new_documentation_fragment, docs)
|
16
|
+
File.open(default_docs_path, 'w') { |f| f.write(new_documentation) }
|
17
|
+
end
|
18
|
+
|
19
|
+
def example_hash(fragment_title, old_documentation)
|
20
|
+
match = ''
|
21
|
+
iterator = 1
|
22
|
+
while true do
|
23
|
+
regex = /(#{fragment_title})(.*?\}){#{iterator}}/
|
24
|
+
new_match_data = old_documentation.match(regex)
|
25
|
+
new_match = new_match_data.present? ? new_match_data[0] : nil
|
26
|
+
return unless new_match != match
|
27
|
+
|
28
|
+
match = new_match
|
29
|
+
begin
|
30
|
+
return match if eval("{#{match}}")
|
31
|
+
rescue SyntaxError
|
32
|
+
end
|
33
|
+
|
34
|
+
iterator += 1
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
data/lib/printer.rb
ADDED
@@ -0,0 +1,103 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# This class walks through the payload object and
|
4
|
+
# builds a prettified representation in rswag format.
|
5
|
+
class SwaggerPrinter
|
6
|
+
class << self
|
7
|
+
def print_swagger(object, test_title)
|
8
|
+
@indent ||= 2
|
9
|
+
line = "#{test_title}: {\n"
|
10
|
+
line += print_values(object)
|
11
|
+
line + end_wrap
|
12
|
+
end
|
13
|
+
|
14
|
+
def wrap_hash
|
15
|
+
line = ' ' * @indent + "type: :object,\n"
|
16
|
+
line += ' ' * @indent + "properties: {\n"
|
17
|
+
@indent += 2
|
18
|
+
line
|
19
|
+
end
|
20
|
+
|
21
|
+
def wrap_array
|
22
|
+
line = ' ' * @indent + "type: :array,\n"
|
23
|
+
line += ' ' * @indent + "items: {\n"
|
24
|
+
@indent += 2
|
25
|
+
line
|
26
|
+
end
|
27
|
+
|
28
|
+
def end_wrap
|
29
|
+
line = ''
|
30
|
+
while @indent > 2
|
31
|
+
@indent -= 2
|
32
|
+
line += ' ' * @indent + "}\n"
|
33
|
+
end
|
34
|
+
line + '}'
|
35
|
+
end
|
36
|
+
|
37
|
+
def print_values(object)
|
38
|
+
return wrap_array + print_values(object.first) if object.is_a?(Array)
|
39
|
+
|
40
|
+
output = wrap_hash
|
41
|
+
object.each_with_index do |(key, val), i|
|
42
|
+
line = if val[:type] == :object
|
43
|
+
print_hash(key, val)
|
44
|
+
elsif val[:type] == :array
|
45
|
+
print_array(key, val)
|
46
|
+
else
|
47
|
+
print_line(key, val)
|
48
|
+
end
|
49
|
+
comma = i == object.keys.size - 1 ? '' : ','
|
50
|
+
line += "#{comma}\n"
|
51
|
+
output += line
|
52
|
+
end
|
53
|
+
output
|
54
|
+
end
|
55
|
+
|
56
|
+
def print_hash(key, val)
|
57
|
+
line = ' ' * @indent + "#{key}: {\n"
|
58
|
+
@indent += 2
|
59
|
+
line += print_values(val[:properties])
|
60
|
+
@indent -= 2
|
61
|
+
line += ' ' * @indent + "}\n"
|
62
|
+
@indent -= 2
|
63
|
+
line += ' ' * @indent + '}'
|
64
|
+
line
|
65
|
+
end
|
66
|
+
|
67
|
+
def print_array(key, val)
|
68
|
+
line = ' ' * @indent + "#{key}: {\n"
|
69
|
+
@indent += 2
|
70
|
+
line += wrap_array
|
71
|
+
line += print_values(val[:items].first)
|
72
|
+
@indent -= 2
|
73
|
+
line += ' ' * @indent + "}\n"
|
74
|
+
@indent -= 2
|
75
|
+
line += ' ' * @indent + '}'
|
76
|
+
line
|
77
|
+
end
|
78
|
+
|
79
|
+
def print_line(key, val)
|
80
|
+
line = ' ' * @indent + "#{key}: { "
|
81
|
+
val.each_with_index do |(val_key, val_val), j|
|
82
|
+
next if val_key == :type && val.any? { |k, v| k == :example && v == nil }
|
83
|
+
val_comma = j == val.keys.size - 1 ? '' : ','
|
84
|
+
line += "#{escape_key(val_key)}: #{prettify_value(val, val_key, val_val)}#{val_comma} "
|
85
|
+
end
|
86
|
+
line + '}'
|
87
|
+
end
|
88
|
+
|
89
|
+
def escape_key(key)
|
90
|
+
return key unless key.to_s.include?('-')
|
91
|
+
|
92
|
+
"'#{key.to_s}'"
|
93
|
+
end
|
94
|
+
|
95
|
+
def prettify_value(type, key, val)
|
96
|
+
return ':' + val.to_s if key == :type
|
97
|
+
return val if key != :example
|
98
|
+
return 'nil' if val.nil?
|
99
|
+
|
100
|
+
type[:type] == :string ? "'#{val}'" : val
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
data/rubocop.yml
ADDED
metadata
ADDED
@@ -0,0 +1,107 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: auto-rswag
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Tyler Porter
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2020-03-22 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: coveralls
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 0.8.23
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 0.8.23
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: pry
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rspec
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rubocop
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: 0.80.1
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: 0.80.1
|
69
|
+
description: Convert raw JSON payloads to Rswag configuration to automate endpoint
|
70
|
+
documentation
|
71
|
+
email: tyler.b.porter@gmail.com
|
72
|
+
executables: []
|
73
|
+
extensions: []
|
74
|
+
extra_rdoc_files: []
|
75
|
+
files:
|
76
|
+
- Gemfile
|
77
|
+
- Gemfile.lock
|
78
|
+
- lib/auto_rswag.rb
|
79
|
+
- lib/auto_rswag_helper.rb
|
80
|
+
- lib/doc_writer.rb
|
81
|
+
- lib/printer.rb
|
82
|
+
- rubocop.yml
|
83
|
+
homepage: https://rubygems.org/gems/auto-rswag
|
84
|
+
licenses:
|
85
|
+
- MIT
|
86
|
+
metadata:
|
87
|
+
source_code_uri: https://github.com/pawptart/auto-rswag
|
88
|
+
post_install_message:
|
89
|
+
rdoc_options: []
|
90
|
+
require_paths:
|
91
|
+
- lib
|
92
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
97
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
98
|
+
requirements:
|
99
|
+
- - ">="
|
100
|
+
- !ruby/object:Gem::Version
|
101
|
+
version: '0'
|
102
|
+
requirements: []
|
103
|
+
rubygems_version: 3.0.3
|
104
|
+
signing_key:
|
105
|
+
specification_version: 4
|
106
|
+
summary: JSON to Rswag configuration
|
107
|
+
test_files: []
|