fitting 2.13.0 → 2.16.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 +5 -5
- data/.github/workflows/ruby.yml +33 -0
- data/.rubocop.yml +1 -1
- data/.ruby-version +1 -1
- data/.tool-versions +1 -1
- data/CHANGELOG.md +52 -0
- data/README.md +83 -259
- data/example.png +0 -0
- data/example2.png +0 -0
- data/fitting.gemspec +5 -5
- data/lib/fitting/cover/json_schema.rb +8 -6
- data/lib/fitting/cover/json_schema_enum.rb +8 -6
- data/lib/fitting/cover/json_schema_one_of.rb +7 -5
- data/lib/fitting/records/spherical/requests.rb +3 -1
- data/lib/fitting/report/action.rb +53 -0
- data/lib/fitting/report/actions.rb +51 -0
- data/lib/fitting/report/combination.rb +37 -0
- data/lib/fitting/report/combinations.rb +47 -0
- data/lib/fitting/report/console.rb +41 -0
- data/lib/fitting/report/prefix.rb +88 -0
- data/lib/fitting/report/prefixes.rb +54 -0
- data/lib/fitting/report/response.rb +71 -0
- data/lib/fitting/report/responses.rb +48 -0
- data/lib/fitting/report/test.rb +75 -0
- data/lib/fitting/report/tests.rb +69 -0
- data/lib/fitting/tests.rb +0 -1
- data/lib/fitting/version.rb +1 -1
- data/lib/tasks/fitting.rake +130 -0
- data/lib/templates/bomboniere/.gitignore +21 -0
- data/lib/templates/bomboniere/.tool-versions +1 -0
- data/lib/templates/bomboniere/README.md +19 -0
- data/lib/templates/bomboniere/dist/css/app.aa2bcd8a.css +1 -0
- data/lib/templates/bomboniere/dist/css/chunk-vendors.ec5f6c3f.css +1 -0
- data/lib/templates/bomboniere/dist/favicon.ico +0 -0
- data/lib/templates/bomboniere/dist/index.html +1 -0
- data/lib/templates/bomboniere/dist/js/app.e5f1a5ec.js +2 -0
- data/lib/templates/bomboniere/dist/js/app.e5f1a5ec.js.map +1 -0
- data/lib/templates/bomboniere/dist/js/chunk-vendors.0f99b670.js +13 -0
- data/lib/templates/bomboniere/dist/js/chunk-vendors.0f99b670.js.map +1 -0
- data/lib/templates/bomboniere/package-lock.json +9277 -0
- data/lib/templates/bomboniere/package.json +27 -0
- data/lib/templates/bomboniere/public/favicon.ico +0 -0
- data/lib/templates/bomboniere/public/index.html +17 -0
- data/lib/templates/bomboniere/src/App.vue +102 -0
- data/lib/templates/bomboniere/src/assets/logo.png +0 -0
- data/lib/templates/bomboniere/src/components/HelloWorld.vue +201 -0
- data/lib/templates/bomboniere/src/main.js +10 -0
- data/lib/templates/bomboniere/src/router/index.js +31 -0
- data/lib/templates/bomboniere/src/views/About.vue +5 -0
- data/lib/templates/bomboniere/src/views/Action.vue +173 -0
- data/lib/templates/bomboniere/src/views/Home.vue +17 -0
- data/lib/templates/bomboniere/vue.config.js +3 -0
- metadata +68 -31
- data/.travis.yml +0 -4
data/example.png
ADDED
Binary file
|
data/example2.png
ADDED
Binary file
|
data/fitting.gemspec
CHANGED
@@ -8,8 +8,8 @@ Gem::Specification.new do |spec|
|
|
8
8
|
spec.authors = ['d.efimov']
|
9
9
|
spec.email = ['d.efimov@fun-box.ru']
|
10
10
|
|
11
|
-
spec.summary = '
|
12
|
-
spec.description = '
|
11
|
+
spec.summary = 'Coverage API Blueprint, Swagger and OpenAPI with rspec tests'
|
12
|
+
spec.description = 'Coverage API Blueprint, Swagger and OpenAPI with rspec tests for easily make high-quality API and documenatiton.'
|
13
13
|
spec.homepage = 'https://github.com/funbox/fitting'
|
14
14
|
spec.license = 'MIT'
|
15
15
|
|
@@ -20,10 +20,10 @@ Gem::Specification.new do |spec|
|
|
20
20
|
|
21
21
|
spec.add_runtime_dependency 'json-schema', '~> 2.6', '>= 2.6.2'
|
22
22
|
spec.add_runtime_dependency 'multi_json', '~> 1.11'
|
23
|
-
spec.add_runtime_dependency 'tomograph', '~>
|
24
|
-
spec.add_development_dependency 'bundler', '~>
|
23
|
+
spec.add_runtime_dependency 'tomograph', '~> 3.1', '>= 3.1.0'
|
24
|
+
spec.add_development_dependency 'bundler', '~> 2.0'
|
25
25
|
spec.add_development_dependency 'byebug', '~> 8.2', '>= 8.2.1'
|
26
|
-
spec.add_development_dependency 'rake', '
|
26
|
+
spec.add_development_dependency 'rake', '>= 12.3.3'
|
27
27
|
spec.add_development_dependency 'rspec', '~> 3.4', '>= 3.4.0'
|
28
28
|
spec.add_development_dependency 'rubocop', '~> 0.49.1', '>= 0.49.1'
|
29
29
|
spec.add_development_dependency 'simplecov', '~> 0.11', '>= 0.11.2'
|
@@ -16,17 +16,19 @@ module Fitting
|
|
16
16
|
def inception(json_schema, combinations)
|
17
17
|
json_schema.each do |key, value|
|
18
18
|
if key == 'properties' and json_schema['required'] != value.keys
|
19
|
-
|
20
|
-
|
19
|
+
schema = json_schema.dup
|
20
|
+
one_of = schema.delete('required') || []
|
21
|
+
schema['properties'].each_key do |property|
|
21
22
|
next if one_of.include?(property)
|
22
|
-
combinations.push([
|
23
|
+
combinations.push([schema.merge('required' => one_of + [property]), "required.#{property}"])
|
23
24
|
end
|
24
25
|
elsif value.is_a?(Hash)
|
25
|
-
inception(value,
|
26
|
-
|
27
|
-
combination[0] = { key => combination[0]}
|
26
|
+
com = inception(value, [])
|
27
|
+
com.each do |combination|
|
28
|
+
combination[0] = { key => value.merge(combination[0])}
|
28
29
|
combination[1] = "#{key}.#{combination[1]}"
|
29
30
|
end
|
31
|
+
combinations += com
|
30
32
|
end
|
31
33
|
end
|
32
34
|
|
@@ -15,17 +15,19 @@ module Fitting
|
|
15
15
|
|
16
16
|
def inception(json_schema, combinations)
|
17
17
|
json_schema.each do |key, value|
|
18
|
-
if key == 'enum'
|
19
|
-
|
18
|
+
if key == 'enum' && value.size > 1
|
19
|
+
schema = json_schema.dup
|
20
|
+
one_of = schema.delete('enum')
|
20
21
|
one_of.each_index do |index|
|
21
|
-
combinations.push([
|
22
|
+
combinations.push([schema.merge('enum' => [one_of[index]]), "enum.#{one_of[index]}"])
|
22
23
|
end
|
23
24
|
elsif value.is_a?(Hash)
|
24
|
-
inception(value,
|
25
|
-
|
26
|
-
combination[0] = { key => combination[0]}
|
25
|
+
com = inception(value, [])
|
26
|
+
com.each do |combination|
|
27
|
+
combination[0] = { key => value.merge(combination[0])}
|
27
28
|
combination[1] = "#{key}.#{combination[1]}"
|
28
29
|
end
|
30
|
+
combinations += com
|
29
31
|
end
|
30
32
|
end
|
31
33
|
|
@@ -16,16 +16,18 @@ module Fitting
|
|
16
16
|
def inception(json_schema, combinations)
|
17
17
|
json_schema.each do |key, value|
|
18
18
|
if key == 'oneOf'
|
19
|
-
|
19
|
+
schema = json_schema.dup
|
20
|
+
one_of = schema.delete('oneOf')
|
20
21
|
one_of.each_index do |index|
|
21
|
-
combinations.push([
|
22
|
+
combinations.push([schema.merge('oneOf' => [one_of[index]]), "oneOf.#{index}"])
|
22
23
|
end
|
23
24
|
elsif value.is_a?(Hash)
|
24
|
-
inception(value,
|
25
|
-
|
26
|
-
combination[0] = { key => combination[0]}
|
25
|
+
com = inception(value, [])
|
26
|
+
com.each do |combination|
|
27
|
+
combination[0] = { key => value.merge(combination[0])}
|
27
28
|
combination[1] = "#{key}.#{combination[1]}"
|
28
29
|
end
|
30
|
+
combinations += com
|
29
31
|
end
|
30
32
|
end
|
31
33
|
|
@@ -13,7 +13,9 @@ module Fitting
|
|
13
13
|
array += JSON.load(File.read(file))
|
14
14
|
end
|
15
15
|
@to_a = array.inject([]) do |res, tested_request|
|
16
|
-
|
16
|
+
request = Fitting::Records::Spherical::Request.load(tested_request)
|
17
|
+
next res unless request.path.to_s.start_with?(Fitting.configuration.prefix)
|
18
|
+
res.push(request)
|
17
19
|
end
|
18
20
|
end
|
19
21
|
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
require 'fitting/report/responses'
|
2
|
+
|
3
|
+
module Fitting
|
4
|
+
module Report
|
5
|
+
class Action
|
6
|
+
def initialize(action)
|
7
|
+
@action = action
|
8
|
+
@tests = Fitting::Report::Tests.new([])
|
9
|
+
@responses = Fitting::Report::Responses.new(@action.responses)
|
10
|
+
end
|
11
|
+
|
12
|
+
def method
|
13
|
+
@action.method
|
14
|
+
end
|
15
|
+
|
16
|
+
def path
|
17
|
+
@action.path.to_s
|
18
|
+
end
|
19
|
+
|
20
|
+
def responses
|
21
|
+
@responses
|
22
|
+
end
|
23
|
+
|
24
|
+
def add_test(test)
|
25
|
+
@tests.push(test)
|
26
|
+
end
|
27
|
+
|
28
|
+
def path_match(find_path)
|
29
|
+
regexp =~ find_path
|
30
|
+
end
|
31
|
+
|
32
|
+
def regexp
|
33
|
+
return @regexp if @regexp
|
34
|
+
|
35
|
+
str = Regexp.escape(path)
|
36
|
+
str = str.gsub(/\\{\w+\\}/, '[^&=\/]+')
|
37
|
+
str = "\\A#{str}\\z"
|
38
|
+
@regexp = Regexp.new(str)
|
39
|
+
end
|
40
|
+
|
41
|
+
def tests
|
42
|
+
@tests
|
43
|
+
end
|
44
|
+
|
45
|
+
def details
|
46
|
+
{
|
47
|
+
tests_without_responses: @tests.without_responses,
|
48
|
+
responses_details: @responses.to_a.map { |r| {method: r.status, tests_size: r.tests.size, json_schema: r.id, combinations: r.details} }
|
49
|
+
}
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
require 'fitting/report/action'
|
2
|
+
|
3
|
+
module Fitting
|
4
|
+
module Report
|
5
|
+
class Actions
|
6
|
+
def initialize(actions)
|
7
|
+
@actions = []
|
8
|
+
actions.to_a.map do |action|
|
9
|
+
@actions.push(Fitting::Report::Action.new(action))
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
def to_a
|
14
|
+
@actions
|
15
|
+
end
|
16
|
+
|
17
|
+
def join(tests)
|
18
|
+
tests.to_a.map do |test|
|
19
|
+
if is_there_a_suitable_action?(test)
|
20
|
+
cram_into_the_appropriate_action(test)
|
21
|
+
test.mark_action
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def is_there_a_suitable_action?(test)
|
27
|
+
@actions.map do |action|
|
28
|
+
return true if test.method == action.method && action.path_match(test.path)
|
29
|
+
end
|
30
|
+
|
31
|
+
false
|
32
|
+
end
|
33
|
+
|
34
|
+
def cram_into_the_appropriate_action(test)
|
35
|
+
@actions.map do |action|
|
36
|
+
if test.method == action.method && action.path_match(test.path)
|
37
|
+
action.add_test(test)
|
38
|
+
return
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def details(prefix)
|
44
|
+
{
|
45
|
+
tests_without_actions: prefix.tests.without_actions,
|
46
|
+
actions_details: @actions.map { |a| {method: a.method, path: a.path, tests_size: a.tests.size, responses: a.details} }
|
47
|
+
}
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
module Fitting
|
2
|
+
module Report
|
3
|
+
class Combination
|
4
|
+
def initialize(json_schema:, type:, combination:)
|
5
|
+
@json_schema = json_schema
|
6
|
+
@type = type
|
7
|
+
@combination = combination
|
8
|
+
@tests = Fitting::Report::Tests.new([])
|
9
|
+
@id = SecureRandom.hex
|
10
|
+
end
|
11
|
+
|
12
|
+
def json_schema
|
13
|
+
@json_schema
|
14
|
+
end
|
15
|
+
|
16
|
+
def id
|
17
|
+
@id
|
18
|
+
end
|
19
|
+
|
20
|
+
def type
|
21
|
+
@type
|
22
|
+
end
|
23
|
+
|
24
|
+
def name
|
25
|
+
@combination
|
26
|
+
end
|
27
|
+
|
28
|
+
def tests
|
29
|
+
@tests
|
30
|
+
end
|
31
|
+
|
32
|
+
def add_test(test)
|
33
|
+
@tests.push(test)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
module Fitting
|
2
|
+
module Report
|
3
|
+
class Combinations
|
4
|
+
def initialize(combinations)
|
5
|
+
@combinations = combinations
|
6
|
+
end
|
7
|
+
|
8
|
+
def to_a
|
9
|
+
@combinations
|
10
|
+
end
|
11
|
+
|
12
|
+
def size
|
13
|
+
@combinations.size
|
14
|
+
end
|
15
|
+
|
16
|
+
def size_with_tests
|
17
|
+
@combinations.count { |c| c.tests.size != 0 }
|
18
|
+
end
|
19
|
+
|
20
|
+
def join(tests)
|
21
|
+
tests.to_a.map do |test|
|
22
|
+
if is_there_a_suitable_combination?(test)
|
23
|
+
cram_into_the_appropriate_combinations(test)
|
24
|
+
test.mark_combination
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def is_there_a_suitable_combination?(test)
|
30
|
+
return false if @combinations.nil?
|
31
|
+
@combinations.map do |combination|
|
32
|
+
return true if JSON::Validator.fully_validate(combination.json_schema, test.body) == []
|
33
|
+
end
|
34
|
+
|
35
|
+
false
|
36
|
+
end
|
37
|
+
|
38
|
+
def cram_into_the_appropriate_combinations(test)
|
39
|
+
@combinations.map do |combination|
|
40
|
+
if JSON::Validator.fully_validate(combination.json_schema, test.body) == []
|
41
|
+
combination.add_test(test)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
module Fitting
|
2
|
+
module Report
|
3
|
+
class Console
|
4
|
+
def initialize(tests_without_prefixes, prefixes_details)
|
5
|
+
@tests_without_prefixes = tests_without_prefixes
|
6
|
+
@prefixes_details = prefixes_details
|
7
|
+
@good = true
|
8
|
+
@tests_without_actions = []
|
9
|
+
@tests_without_responses = []
|
10
|
+
end
|
11
|
+
|
12
|
+
def output
|
13
|
+
doc_res = @prefixes_details.inject('') do |res, prefix_details|
|
14
|
+
res += "#{prefix_details[:name]}\n"
|
15
|
+
@tests_without_actions += prefix_details[:actions][:tests_without_actions]
|
16
|
+
res += prefix_details[:actions][:actions_details].inject('') do |res_actions, action|
|
17
|
+
res_actions += "#{action[:method]}\t#{action[:path]}"
|
18
|
+
tab = "\t" * (8 - action[:path].size / 8)
|
19
|
+
@tests_without_responses += action[:responses][:tests_without_responses]
|
20
|
+
res_actions += tab + action[:responses][:responses_details].inject('') do |res_responses, response|
|
21
|
+
@good = false if response[:combinations][:cover_percent] != '100%'
|
22
|
+
res_responses += " #{response[:combinations][:cover_percent]} #{response[:method]}"
|
23
|
+
end
|
24
|
+
res_actions += "\n"
|
25
|
+
end
|
26
|
+
end
|
27
|
+
doc_res += "\n"
|
28
|
+
doc_res += "tests_without_prefixes: #{@tests_without_prefixes.size}\n"
|
29
|
+
doc_res += "tests_without_actions: #{@tests_without_actions.size}\n"
|
30
|
+
doc_res += "tests_without_responses: #{@tests_without_responses.size}\n"
|
31
|
+
end
|
32
|
+
|
33
|
+
def good?
|
34
|
+
return false if @tests_without_prefixes.size != 0
|
35
|
+
return false if @tests_without_actions.size != 0
|
36
|
+
return false if @tests_without_responses.size != 0
|
37
|
+
@good
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,88 @@
|
|
1
|
+
require 'fitting/report/actions'
|
2
|
+
|
3
|
+
module Fitting
|
4
|
+
module Report
|
5
|
+
class Prefix
|
6
|
+
def initialize(name: '', openapi2_json_path: nil, openapi3_yaml_path: nil, drafter_yaml_path: nil, tomogram_json_path: nil, crafter_yaml_path: nil, skip: false)
|
7
|
+
@name = name
|
8
|
+
@tomogram_json_path = tomogram_json_path
|
9
|
+
@tests = Fitting::Report::Tests.new([])
|
10
|
+
@skip = skip
|
11
|
+
unless skip
|
12
|
+
@actions = if openapi2_json_path
|
13
|
+
Fitting::Report::Actions.new(
|
14
|
+
Tomograph::Tomogram.new(
|
15
|
+
prefix: name,
|
16
|
+
openapi2_json_path: openapi2_json_path
|
17
|
+
)
|
18
|
+
)
|
19
|
+
elsif openapi3_yaml_path
|
20
|
+
Fitting::Report::Actions.new(
|
21
|
+
Tomograph::Tomogram.new(
|
22
|
+
prefix: name,
|
23
|
+
openapi3_yaml_path: openapi3_yaml_path
|
24
|
+
)
|
25
|
+
)
|
26
|
+
elsif drafter_yaml_path
|
27
|
+
Fitting::Report::Actions.new(
|
28
|
+
Tomograph::Tomogram.new(
|
29
|
+
prefix: name,
|
30
|
+
drafter_yaml_path: drafter_yaml_path
|
31
|
+
)
|
32
|
+
)
|
33
|
+
elsif crafter_yaml_path
|
34
|
+
Fitting::Report::Actions.new(
|
35
|
+
Tomograph::Tomogram.new(
|
36
|
+
prefix: name,
|
37
|
+
crafter_yaml_path: crafter_yaml_path
|
38
|
+
)
|
39
|
+
)
|
40
|
+
else
|
41
|
+
Fitting::Report::Actions.new(
|
42
|
+
Tomograph::Tomogram.new(
|
43
|
+
prefix: name,
|
44
|
+
tomogram_json_path: tomogram_json_path
|
45
|
+
)
|
46
|
+
)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def name
|
52
|
+
@name
|
53
|
+
end
|
54
|
+
|
55
|
+
def tests
|
56
|
+
@tests
|
57
|
+
end
|
58
|
+
|
59
|
+
def skip?
|
60
|
+
@skip
|
61
|
+
end
|
62
|
+
|
63
|
+
def actions
|
64
|
+
@actions
|
65
|
+
end
|
66
|
+
|
67
|
+
def details
|
68
|
+
if @skip
|
69
|
+
{
|
70
|
+
name: @name,
|
71
|
+
tests_size: @tests.size,
|
72
|
+
actions: {tests_without_actions: [], actions_details: []}
|
73
|
+
}
|
74
|
+
else
|
75
|
+
{
|
76
|
+
name: @name,
|
77
|
+
tests_size: @tests.size,
|
78
|
+
actions: @actions.details(self)
|
79
|
+
}
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
def add_test(test)
|
84
|
+
@tests.push(test)
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|