fitting 2.13.1 → 2.16.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (51) hide show
  1. checksums.yaml +5 -5
  2. data/.github/workflows/ruby.yml +33 -0
  3. data/.rubocop.yml +1 -1
  4. data/.ruby-version +1 -1
  5. data/.tool-versions +1 -1
  6. data/CHANGELOG.md +51 -0
  7. data/README.md +89 -256
  8. data/example.png +0 -0
  9. data/example2.png +0 -0
  10. data/fitting.gemspec +4 -4
  11. data/lib/fitting/records/spherical/requests.rb +3 -1
  12. data/lib/fitting/report/action.rb +53 -0
  13. data/lib/fitting/report/actions.rb +51 -0
  14. data/lib/fitting/report/combination.rb +37 -0
  15. data/lib/fitting/report/combinations.rb +47 -0
  16. data/lib/fitting/report/console.rb +41 -0
  17. data/lib/fitting/report/prefix.rb +88 -0
  18. data/lib/fitting/report/prefixes.rb +56 -0
  19. data/lib/fitting/report/response.rb +71 -0
  20. data/lib/fitting/report/responses.rb +48 -0
  21. data/lib/fitting/report/test.rb +75 -0
  22. data/lib/fitting/report/tests.rb +69 -0
  23. data/lib/fitting/tests.rb +0 -1
  24. data/lib/fitting/version.rb +1 -1
  25. data/lib/tasks/fitting.rake +68 -31
  26. data/lib/templates/bomboniere/.gitignore +21 -0
  27. data/lib/templates/bomboniere/.tool-versions +1 -0
  28. data/lib/templates/bomboniere/README.md +19 -0
  29. data/lib/templates/bomboniere/dist/css/app.aa2bcd8a.css +1 -0
  30. data/lib/templates/bomboniere/dist/css/chunk-vendors.ec5f6c3f.css +1 -0
  31. data/lib/templates/bomboniere/dist/favicon.ico +0 -0
  32. data/lib/templates/bomboniere/dist/index.html +1 -0
  33. data/lib/templates/bomboniere/dist/js/app.e5f1a5ec.js +2 -0
  34. data/lib/templates/bomboniere/dist/js/app.e5f1a5ec.js.map +1 -0
  35. data/lib/templates/bomboniere/dist/js/chunk-vendors.0f99b670.js +13 -0
  36. data/lib/templates/bomboniere/dist/js/chunk-vendors.0f99b670.js.map +1 -0
  37. data/lib/templates/bomboniere/package-lock.json +9277 -0
  38. data/lib/templates/bomboniere/package.json +27 -0
  39. data/lib/templates/bomboniere/public/favicon.ico +0 -0
  40. data/lib/templates/bomboniere/public/index.html +17 -0
  41. data/lib/templates/bomboniere/src/App.vue +102 -0
  42. data/lib/templates/bomboniere/src/assets/logo.png +0 -0
  43. data/lib/templates/bomboniere/src/components/HelloWorld.vue +201 -0
  44. data/lib/templates/bomboniere/src/main.js +10 -0
  45. data/lib/templates/bomboniere/src/router/index.js +31 -0
  46. data/lib/templates/bomboniere/src/views/About.vue +5 -0
  47. data/lib/templates/bomboniere/src/views/Action.vue +173 -0
  48. data/lib/templates/bomboniere/src/views/Home.vue +17 -0
  49. data/lib/templates/bomboniere/vue.config.js +3 -0
  50. metadata +64 -27
  51. 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 = 'Validation in the rspec of API Blueprint'
12
- spec.description = 'Validation responses in the rspec with the help of API Blueprint'
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,8 +20,8 @@ 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', '~> 2.0', '>= 2.2.0'
24
- spec.add_development_dependency 'bundler', '~> 1.12'
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
26
  spec.add_development_dependency 'rake', '>= 12.3.3'
27
27
  spec.add_development_dependency 'rspec', '~> 3.4', '>= 3.4.0'
@@ -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
- res.push(Fitting::Records::Spherical::Request.load(tested_request))
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
@@ -0,0 +1,56 @@
1
+ require 'fitting/report/prefix'
2
+
3
+ module Fitting
4
+ module Report
5
+ class Prefixes
6
+ def initialize(config_path)
7
+ @prefixes = []
8
+ YAML.safe_load(File.read(config_path))['prefixes'].map do |prefix|
9
+ @prefixes.push(
10
+ Fitting::Report::Prefix.new(
11
+ name: prefix['name'],
12
+ openapi2_json_path: prefix['openapi2_json_path'],
13
+ openapi3_yaml_path: prefix['openapi3_yaml_path'],
14
+ drafter_yaml_path: prefix['drafter_yaml_path'],
15
+ tomogram_json_path: prefix['tomogram_json_path'],
16
+ crafter_yaml_path: prefix['crafter_yaml_path'],
17
+ skip: prefix['skip']
18
+ )
19
+ )
20
+ end
21
+ end
22
+
23
+ def is_there_a_suitable_prefix?(test_path)
24
+ @prefixes.map do |prefix|
25
+ return true if prefix.name.nil?
26
+ return true if prefix.name == ''
27
+ return true if test_path[0..prefix.name.size - 1] == prefix.name
28
+ end
29
+
30
+ false
31
+ end
32
+
33
+ def cram_into_the_appropriate_prefix(test)
34
+ @prefixes.map do |prefix|
35
+ if prefix.name.nil? || prefix.name == '' || test.path[0..prefix.name.size - 1] == prefix.name
36
+ prefix.add_test(test)
37
+ return
38
+ end
39
+ end
40
+ end
41
+
42
+ def join(tests)
43
+ tests.to_a.map do |test|
44
+ if is_there_a_suitable_prefix?(test.path)
45
+ cram_into_the_appropriate_prefix(test)
46
+ test.mark_prefix
47
+ end
48
+ end
49
+ end
50
+
51
+ def to_a
52
+ @prefixes
53
+ end
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,71 @@
1
+ require 'fitting/statistics/template_cover_error'
2
+ require 'fitting/statistics/template_cover_error_enum'
3
+ require 'fitting/statistics/template_cover_error_one_of'
4
+ require 'fitting/report/combinations'
5
+ require 'fitting/report/combination'
6
+
7
+ module Fitting
8
+ module Report
9
+ class Response
10
+ def initialize(response)
11
+ @response = response
12
+ @tests = Fitting::Report::Tests.new([])
13
+ @id = SecureRandom.hex
14
+ end
15
+
16
+ def status
17
+ @response['status'] || @response[:status]
18
+ end
19
+
20
+ def body
21
+ @response['body'] || @response[:body]
22
+ end
23
+
24
+ def id
25
+ @id
26
+ end
27
+
28
+ def add_test(test)
29
+ @tests.push(test)
30
+ end
31
+
32
+ def tests
33
+ @tests
34
+ end
35
+
36
+ def combinations
37
+ return @combinations if @combinations
38
+
39
+ cmbntns = []
40
+ combinations = Fitting::Cover::JSONSchema.new(body).combi + Fitting::Cover::JSONSchemaEnum.new(body).combi + Fitting::Cover::JSONSchemaOneOf.new(body).combi
41
+ if combinations != []
42
+ combinations.map do |combination|
43
+ cmbntns.push(
44
+ Fitting::Report::Combination.new(
45
+ json_schema: combination[0],
46
+ type: combination[1][0],
47
+ combination: combination[1][1]
48
+ )
49
+ )
50
+ end
51
+ end
52
+
53
+ @combinations = Fitting::Report::Combinations.new(cmbntns)
54
+ end
55
+
56
+ def cover_percent
57
+ return '0%' if @tests.size == 0
58
+ return '100%' if @combinations.size == 0
59
+ "#{(@combinations.size_with_tests + 1) * 100 / (@combinations.size + 1)}%"
60
+ end
61
+
62
+ def details
63
+ {
64
+ cover_percent: cover_percent,
65
+ tests_without_combinations: @tests.without_combinations,
66
+ combinations_details: @combinations.to_a.map { |c| {json_schema: c.id, tests_size: c.tests.size, type: c.type, name: c.name} }
67
+ }
68
+ end
69
+ end
70
+ end
71
+ end