fitting 1.4.0 → 1.5.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
  SHA1:
3
- metadata.gz: 56f3f0f488cdee6be583ce31472dafab117afb58
4
- data.tar.gz: 3e082349195724b60655350d648b726420118bdb
3
+ metadata.gz: 7d1997d69b352bcdbba93f00c3e50cba25eb4d70
4
+ data.tar.gz: c39ea9c0cc9ee2c81d506f83c4f85ab614accb4f
5
5
  SHA512:
6
- metadata.gz: b0084485379e61b738e6afb271fcfd6817dc10e6884ee16282b7186a4e342a0612318223c3e80abc932e711dd376d84a54a4c91ace4ad7d5561327e38e78344e
7
- data.tar.gz: 0440e437b56e83c8450408b3ac0fb9dba4217c57960e736d73a55e715e8a7fd7ac5e882a30d674002655b4f39acddd59690c013c30e316095faf22776de4bcd9
6
+ metadata.gz: 68b687226ff3b178bb8fb774cc011a4c5a285ee13b246362dab05e15a71b18bbfee1b406a7f9a88494c8bd7a786fad4b43373382fa93495d3d86dc9cffa37402
7
+ data.tar.gz: 74928dc7e164fdad8fd68bc96fcf88753665cb49024fbb56db5bf68f706385f8a492254c4b1efec7960fbd6c0188a5264faca35af20e015bc2b78667fd272898
data/README.md CHANGED
@@ -78,6 +78,10 @@ config.white_list = {
78
78
 
79
79
  Empty array `[]` means all methods.
80
80
 
81
+ ### create_report_with_name
82
+
83
+ Create report with name.
84
+
81
85
  ## Report
82
86
 
83
87
  Autogenerate `report_request_by_response.yaml` and `report_response.yaml reports`.
data/lib/fitting.rb CHANGED
@@ -1,13 +1,11 @@
1
1
  require 'fitting/version'
2
2
  require 'fitting/configuration'
3
- require 'fitting/documentation/response/route'
4
- require 'fitting/documentation/response/routes'
5
- require 'fitting/documentation/request/route'
6
- require 'fitting/storage/responses'
7
3
  require 'fitting/storage/documentation'
8
4
  require 'fitting/storage/skip'
9
5
  require 'fitting/matchers/response_matcher'
10
6
  require 'rspec/core'
7
+ require 'fitting/statistics'
8
+ require 'fitting/documentation'
11
9
 
12
10
  ERROR_EXIT_CODE = 1
13
11
 
@@ -34,28 +32,17 @@ module RSpec
34
32
 
35
33
  return returned_exit_code if Fitting::Storage::Skip.get
36
34
 
37
- responses_routes = Fitting::Documentation::Response::Routes.new(
38
- Fitting::Storage::Documentation.hash,
39
- Fitting.configuration.white_list
40
- )
41
-
42
- puts '[Black list]'
43
- response_routes_black = Fitting::Documentation::Response::Route.new(
44
- Fitting::Storage::Responses.all,
45
- responses_routes.black
46
- )
47
- response_routes_black.statistics
48
-
49
- puts '[White list]'
50
- response_routes_white = Fitting::Documentation::Response::Route.new(
51
- Fitting::Storage::Responses.all,
52
- responses_routes.white
53
- )
54
- response_routes_white.statistics_with_conformity_lists
35
+ statistics = Fitting::Statistics.new(
36
+ Fitting::Documentation.new(Fitting.configuration.tomogram, Fitting.configuration.white_list),
37
+ Fitting::Storage::Responses.all)
38
+ puts statistics
39
+ if Fitting.configuration.create_report_with_name
40
+ statistics.save(Fitting.configuration.create_report_with_name)
41
+ end
55
42
 
56
43
  if Fitting.configuration.necessary_fully_implementation_of_responses &&
57
44
  returned_exit_code == 0 &&
58
- response_routes_white.not_coverage.present?
45
+ response.not_coverage?
59
46
  return ERROR_EXIT_CODE
60
47
  end
61
48
  returned_exit_code
@@ -2,7 +2,8 @@ module Fitting
2
2
  class Configuration
3
3
  attr_accessor :tomogram,
4
4
  :necessary_fully_implementation_of_responses,
5
- :white_list
5
+ :white_list,
6
+ :create_report_with_name
6
7
 
7
8
  def initialize
8
9
  @necessary_fully_implementation_of_responses = true
@@ -0,0 +1,48 @@
1
+ require 'multi_json'
2
+
3
+ module Fitting
4
+ class Documentation
5
+ def initialize(tomogram, white_list)
6
+ @tomogram = tomogram
7
+ @white_list = white_list
8
+ end
9
+
10
+ def black
11
+ if @white_list
12
+ all.select do |response|
13
+ data = response.split(' ')
14
+ data[1] && !@white_list[data[1]] || (@white_list[data[1]] != [] && !@white_list[data[1]].include?(data[0]))
15
+ end
16
+ else
17
+ []
18
+ end
19
+ end
20
+
21
+ def white
22
+ if @white_list
23
+ all.select do |response|
24
+ data = response.split(' ')
25
+ data[1] && @white_list[data[1]] && (@white_list[data[1]] == [] || @white_list[data[1]].include?(data[0]))
26
+ end
27
+ else
28
+ all
29
+ end
30
+ end
31
+
32
+ def all
33
+ @all ||= MultiJson.load(@tomogram).inject([]) do |routes, request|
34
+ request['responses'].inject({}) do |responses, response|
35
+ responses[response['status']] ||= 0
36
+ responses[response['status']] += 1
37
+ responses
38
+ end.map do |status, indexes|
39
+ indexes.times do |index|
40
+ route = "#{request['method']}\t#{request['path']} #{status} #{index}"
41
+ routes.push(route)
42
+ end
43
+ end
44
+ routes
45
+ end.uniq
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,21 @@
1
+ require 'fitting/route/coverage'
2
+ require 'fitting/route/requests'
3
+ require 'fitting/route/responses'
4
+
5
+ module Fitting
6
+ class Route
7
+ def initialize(all_responses, routes)
8
+ coverage = Fitting::Route::Coverage.new(all_responses, routes)
9
+ @requests = Fitting::Route::Requests.new(coverage)
10
+ @responses = Fitting::Route::Responses.new(routes, coverage)
11
+ end
12
+
13
+ def statistics
14
+ [@requests.statistics, @responses.statistics].join("\n\n")
15
+ end
16
+
17
+ def statistics_with_conformity_lists
18
+ [@requests.conformity_lists, statistics].join("\n\n")
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,38 @@
1
+ require 'multi_json'
2
+ module Fitting
3
+ class Route
4
+ class Coverage
5
+ def initialize(coverage_responses, responses_routes)
6
+ @coverage_responses = coverage_responses
7
+ @responses_routes = responses_routes
8
+ end
9
+
10
+ def coverage
11
+ @coverage ||= @responses_routes - (@responses_routes - full_coverage)
12
+ end
13
+
14
+ def not_coverage
15
+ @not_coverage ||= @responses_routes - coverage
16
+ end
17
+
18
+ def cover_ratio
19
+ @cover_ratio ||= (coverage.size.to_f / @responses_routes.size.to_f * 100.0).round(2)
20
+ end
21
+
22
+ def to_hash
23
+ {
24
+ 'coverage' => coverage,
25
+ 'not coverage' => not_coverage
26
+ }
27
+ end
28
+
29
+ private
30
+
31
+ def full_coverage
32
+ @coverage_responses.map do |response|
33
+ response.route if response.documented? && response.valid?
34
+ end.compact.uniq
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,148 @@
1
+ require 'multi_json'
2
+
3
+ module Fitting
4
+ class Route
5
+ class Requests
6
+ def initialize(coverage)
7
+ @coverage = coverage
8
+ end
9
+
10
+ def coverage_statistic
11
+ stat = {}
12
+ @coverage.coverage.map do |route|
13
+ macro_key = route.split(' ')[0..1].join(' ')
14
+ micro_key = route.split(' ')[2..3].join(' ')
15
+ stat[macro_key] ||= {}
16
+ stat[macro_key]['cover'] ||= []
17
+ stat[macro_key]['not_cover'] ||= []
18
+ stat[macro_key]['cover'].push(micro_key)
19
+ stat[macro_key]['all'] ||= []
20
+ stat[macro_key]['all'].push("✔ #{route.split(' ')[2..3].join(' ')}")
21
+ end
22
+ @coverage.not_coverage.map do |route|
23
+ macro_key = route.split(' ')[0..1].join(' ')
24
+ micro_key = route.split(' ')[2..3].join(' ')
25
+ stat[macro_key] ||= {}
26
+ stat[macro_key]['cover'] ||= []
27
+ stat[macro_key]['not_cover'] ||= []
28
+ stat[macro_key]['not_cover'].push(micro_key)
29
+ stat[macro_key]['all'] ||= []
30
+ stat[macro_key]['all'].push("✖ #{route.split(' ')[2..3].join(' ')}")
31
+ end
32
+ @stat = stat.inject(
33
+ {
34
+ 'full cover' => [],
35
+ 'partial cover' => [],
36
+ 'no cover' => []
37
+ }
38
+ ) do |res, date|
39
+ ratio = date.last['cover_ratio'] =
40
+ (date.last['cover'].size.to_f /
41
+ (date.last['cover'].size + date.last['not_cover'].size).to_f * 100.0).round(2)
42
+ info = {date.first => {
43
+ 'cover' => date.last['cover'],
44
+ 'not_cover' => date.last['not_cover'],
45
+ 'all' => "#{beautiful_output(date.last)}"
46
+ }}
47
+ if ratio == 100.0
48
+ res['full cover'].push(info)
49
+ elsif ratio == 0.0
50
+ res['no cover'].push(info)
51
+ else
52
+ res['partial cover'].push(info)
53
+ end
54
+ path = date.first.split(' ')[1].size / 8
55
+ @max ||= 1
56
+ if path.size > @max
57
+ @max = path.size
58
+ end
59
+ res
60
+ end
61
+ end
62
+
63
+ def to_hash
64
+ @stat ||= coverage_statistic
65
+ end
66
+
67
+ def fully_implemented
68
+ @stat ||= coverage_statistic
69
+ @fully_implemented ||= @stat['full cover'].map do |response|
70
+ "#{response.first.to_a.first.split(' ').join("\t")}#{"\t"*(@max-response.first.to_a.first.split(' ')[1].size/8)}#{response.first.to_a.last['all']}"
71
+ end.sort do |first, second|
72
+ first.split("\t")[1] <=> second.split("\t")[1]
73
+ end
74
+ end
75
+
76
+ def partially_implemented
77
+ @stat ||= coverage_statistic
78
+ @partially_implemented ||= @stat['partial cover'].map do |response|
79
+ "#{response.first.to_a.first.split(' ').join("\t")}#{"\t"*(@max-response.first.to_a.first.split(' ')[1].size/8)}#{response.first.to_a.last['all']}"
80
+ end.sort do |first, second|
81
+ first.split("\t")[1] <=> second.split("\t")[1]
82
+ end
83
+ end
84
+
85
+ def no_implemented
86
+ @stat ||= coverage_statistic
87
+ @no_implemented ||= @stat['no cover'].map do |response|
88
+ "#{response.first.to_a.first.split(' ').join("\t")}#{"\t"*(@max-response.first.to_a.first.split(' ')[1].size/8)}#{response.first.to_a.last['all']}"
89
+ end.sort do |first, second|
90
+ first.split("\t")[1] <=> second.split("\t")[1]
91
+ end
92
+ end
93
+
94
+ def statistics
95
+ @stat ||= coverage_statistic
96
+ full_count = @stat.to_hash['full cover'].size
97
+ part_count = @stat.to_hash['partial cover'].size
98
+ no_count = @stat.to_hash['no cover'].size
99
+ total_count = full_count + part_count + no_count
100
+ full_percentage = (full_count.to_f / total_count.to_f * 100.0).round(2)
101
+ part_percentage = (part_count.to_f / total_count.to_f * 100.0).round(2)
102
+ no_percentage = (no_count.to_f / total_count.to_f * 100.0).round(2)
103
+
104
+ [
105
+ "API requests with fully implemented responses: #{full_count} (#{full_percentage}% of #{total_count}).",
106
+ "API requests with partially implemented responses: #{part_count} (#{part_percentage}% of #{total_count}).",
107
+ "API requests with no implemented responses: #{no_count} (#{no_percentage}% of #{total_count})."
108
+ ].join("\n")
109
+ end
110
+
111
+ def conformity_lists
112
+ @stat ||= coverage_statistic
113
+ fully_implemented ||= self.fully_implemented.join("\n")
114
+ partially_implemented ||= self.partially_implemented.join("\n")
115
+ no_implemented ||= self.no_implemented.join("\n")
116
+
117
+ [
118
+ ['Fully conforming requests:', fully_implemented].join("\n"),
119
+ ['Partially conforming requests:', partially_implemented].join("\n"),
120
+ ['Non-conforming requests:', no_implemented].join("\n")
121
+ ].join("\n\n")
122
+ end
123
+
124
+ private
125
+
126
+ def beautiful_output(hash)
127
+ methods = {}
128
+ res = []
129
+ hash['cover'].map do |response|
130
+ method, index = response.split(' ')
131
+ methods[method] ||= []
132
+ methods[method][index.to_i] = {'method' => method, 'cover' => true}
133
+ end
134
+ hash['not_cover'].map do |response|
135
+ method, index = response.split(' ')
136
+ methods[method] ||= []
137
+ methods[method][index.to_i] = {'method' => method, 'cover' => false}
138
+ end
139
+ methods.map do |method|
140
+ method.last.size.times do |index|
141
+ res.push("#{method.last[index]['cover'] ? '✔' : '✖'} #{method.first}")
142
+ end
143
+ end
144
+ res.join(' ')
145
+ end
146
+ end
147
+ end
148
+ end
@@ -0,0 +1,23 @@
1
+ module Fitting
2
+ class Route
3
+ class Responses
4
+ def initialize(routes, coverage)
5
+ @routes = routes
6
+ @coverage = coverage
7
+ end
8
+
9
+ def statistics
10
+ valid_count = @coverage.coverage.size
11
+ valid_percentage = @coverage.cover_ratio
12
+ total_count = @routes.size
13
+ invalid_count = @coverage.not_coverage.size
14
+ invalid_percentage = (100.0 - @coverage.cover_ratio).round(2)
15
+
16
+ [
17
+ "API responses conforming to the blueprint: #{valid_count} (#{valid_percentage}% of #{total_count}).",
18
+ "API responses with validation errors or untested: #{invalid_count} (#{invalid_percentage}% of #{total_count})."
19
+ ].join("\n")
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,31 @@
1
+ require 'fitting/route'
2
+
3
+ module Fitting
4
+ class Statistics
5
+ def initialize(documentation, all_responses)
6
+ @documentation = documentation
7
+ @black_route = Fitting::Route.new(all_responses, @documentation.black)
8
+ @white_route = Fitting::Route.new(all_responses, @documentation.white)
9
+ end
10
+
11
+ def not_coverage?
12
+ @white_route.not_coverage.present?
13
+ end
14
+
15
+ def save(name)
16
+ File.open(name, 'w') { |file| file.write(to_s) }
17
+ end
18
+
19
+ def to_s
20
+ if @documentation.black.any?
21
+ [
22
+ ['[Black list]', @black_route.statistics].join("\n"),
23
+ ['[White list]', @white_route.statistics_with_conformity_lists].join("\n"),
24
+ ""
25
+ ].join("\n\n")
26
+ else
27
+ [@white_route.statistics_with_conformity_lists, "\n\n"].join
28
+ end
29
+ end
30
+ end
31
+ end
@@ -1,15 +1,12 @@
1
1
  require 'tomogram_routing'
2
+ require 'fitting/configuration'
2
3
 
3
4
  module Fitting
4
5
  module Storage
5
6
  module Documentation
6
7
  class << self
7
8
  def tomogram
8
- @tomogram ||= TomogramRouting::Tomogram.craft(hash)
9
- end
10
-
11
- def hash
12
- Fitting.configuration.tomogram
9
+ @tomogram ||= TomogramRouting::Tomogram.craft(Fitting.configuration.tomogram)
13
10
  end
14
11
  end
15
12
  end
@@ -1,3 +1,3 @@
1
1
  module Fitting
2
- VERSION = '1.4.0'.freeze
2
+ VERSION = '1.5.0'.freeze
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fitting
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.4.0
4
+ version: 1.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - d.efimov
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2017-03-10 00:00:00.000000000 Z
11
+ date: 2017-03-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: json-schema
@@ -212,12 +212,15 @@ files:
212
212
  - fitting.gemspec
213
213
  - lib/fitting.rb
214
214
  - lib/fitting/configuration.rb
215
- - lib/fitting/documentation/request/route.rb
216
- - lib/fitting/documentation/response/route.rb
217
- - lib/fitting/documentation/response/routes.rb
215
+ - lib/fitting/documentation.rb
218
216
  - lib/fitting/matchers/response_matcher.rb
219
217
  - lib/fitting/request.rb
220
218
  - lib/fitting/response.rb
219
+ - lib/fitting/route.rb
220
+ - lib/fitting/route/coverage.rb
221
+ - lib/fitting/route/requests.rb
222
+ - lib/fitting/route/responses.rb
223
+ - lib/fitting/statistics.rb
221
224
  - lib/fitting/storage/documentation.rb
222
225
  - lib/fitting/storage/responses.rb
223
226
  - lib/fitting/storage/skip.rb
@@ -1,143 +0,0 @@
1
- require 'multi_json'
2
-
3
- module Fitting
4
- module Documentation
5
- module Request
6
- class Route
7
- def initialize(response_routes)
8
- @response_routes = response_routes
9
- end
10
-
11
- def coverage_statistic
12
- stat = {}
13
- @response_routes.coverage.map do |route|
14
- macro_key = route.split(' ')[0..1].join(' ')
15
- micro_key = route.split(' ')[2..3].join(' ')
16
- stat[macro_key] ||= {}
17
- stat[macro_key]['cover'] ||= []
18
- stat[macro_key]['not_cover'] ||= []
19
- stat[macro_key]['cover'].push(micro_key)
20
- stat[macro_key]['all'] ||= []
21
- stat[macro_key]['all'].push("✔ #{route.split(' ')[2..3].join(' ')}")
22
- end
23
- @response_routes.not_coverage.map do |route|
24
- macro_key = route.split(' ')[0..1].join(' ')
25
- micro_key = route.split(' ')[2..3].join(' ')
26
- stat[macro_key] ||= {}
27
- stat[macro_key]['cover'] ||= []
28
- stat[macro_key]['not_cover'] ||= []
29
- stat[macro_key]['not_cover'].push(micro_key)
30
- stat[macro_key]['all'] ||= []
31
- stat[macro_key]['all'].push("✖ #{route.split(' ')[2..3].join(' ')}")
32
- end
33
- @stat = stat.inject(
34
- {
35
- 'full cover' => [],
36
- 'partial cover' => [],
37
- 'no cover' => []
38
- }
39
- ) do |res, date|
40
- ratio = date.last['cover_ratio'] =
41
- (date.last['cover'].size.to_f /
42
- (date.last['cover'].size + date.last['not_cover'].size).to_f * 100.0).round(2)
43
- info = {date.first => {
44
- 'cover' => date.last['cover'],
45
- 'not_cover' => date.last['not_cover'],
46
- 'all' => "#{beautiful_output(date.last)}"
47
- }}
48
- if ratio == 100.0
49
- res['full cover'].push(info)
50
- elsif ratio == 0.0
51
- res['no cover'].push(info)
52
- else
53
- res['partial cover'].push(info)
54
- end
55
- path = date.first.split(' ')[1].size / 8
56
- @max ||= 1
57
- if path.size > @max
58
- @max = path.size
59
- end
60
- res
61
- end
62
- end
63
-
64
- def to_hash
65
- @stat ||= coverage_statistic
66
- end
67
-
68
- def fully_implemented
69
- @stat ||= coverage_statistic
70
- @fully_implemented ||= @stat['full cover'].map do |response|
71
- "#{response.first.to_a.first.split(' ').join("\t")}#{"\t"*(@max-response.first.to_a.first.split(' ')[1].size/8)}#{response.first.to_a.last['all']}"
72
- end.sort do |first, second|
73
- first.split("\t")[1] <=> second.split("\t")[1]
74
- end
75
- end
76
-
77
- def partially_implemented
78
- @stat ||= coverage_statistic
79
- @partially_implemented ||= @stat['partial cover'].map do |response|
80
- "#{response.first.to_a.first.split(' ').join("\t")}#{"\t"*(@max-response.first.to_a.first.split(' ')[1].size/8)}#{response.first.to_a.last['all']}"
81
- end.sort do |first, second|
82
- first.split("\t")[1] <=> second.split("\t")[1]
83
- end
84
- end
85
-
86
- def no_implemented
87
- @stat ||= coverage_statistic
88
- @no_implemented ||= @stat['no cover'].map do |response|
89
- "#{response.first.to_a.first.split(' ').join("\t")}#{"\t"*(@max-response.first.to_a.first.split(' ')[1].size/8)}#{response.first.to_a.last['all']}"
90
- end.sort do |first, second|
91
- first.split("\t")[1] <=> second.split("\t")[1]
92
- end
93
- end
94
-
95
- def conformity_lists
96
- puts "Fully conforming requests: \n#{fully_implemented.join("\n")}"
97
- puts
98
- puts "Partially conforming requests: \n#{partially_implemented.join("\n")}"
99
- puts
100
- puts "Non-conforming requests: \n#{no_implemented.join("\n")}"
101
- puts
102
- end
103
-
104
- def statistics
105
- full_count = to_hash['full cover'].size
106
- part_count = to_hash['partial cover'].size
107
- no_count = to_hash['no cover'].size
108
- total_count = full_count + part_count + no_count
109
- full_percentage = (full_count.to_f / total_count.to_f * 100.0).round(2)
110
- part_percentage = (part_count.to_f / total_count.to_f * 100.0).round(2)
111
- no_percentage = (no_count.to_f / total_count.to_f * 100.0).round(2)
112
- puts "API requests with fully implemented responses: #{full_count} (#{full_percentage}% of #{total_count})."
113
- puts "API requests with partially implemented responses: #{part_count} (#{part_percentage}% of #{total_count})."
114
- puts "API requests with no implemented responses: #{no_count} (#{no_percentage}% of #{total_count})."
115
- puts
116
- end
117
-
118
- private
119
-
120
- def beautiful_output(hash)
121
- methods = {}
122
- res = []
123
- hash['cover'].map do |response|
124
- method, index = response.split(' ')
125
- methods[method] ||= []
126
- methods[method][index.to_i] = {'method' => method, 'cover' => true}
127
- end
128
- hash['not_cover'].map do |response|
129
- method, index = response.split(' ')
130
- methods[method] ||= []
131
- methods[method][index.to_i] = {'method' => method, 'cover' => false}
132
- end
133
- methods.map do |method|
134
- method.last.size.times do |index|
135
- res.push("#{method.last[index]['cover'] ? '✔' : '✖'} #{method.first}")
136
- end
137
- end
138
- res.join(' ')
139
- end
140
- end
141
- end
142
- end
143
- end
@@ -1,62 +0,0 @@
1
- require 'multi_json'
2
- require 'fitting/documentation/request/route'
3
-
4
- module Fitting
5
- module Documentation
6
- module Response
7
- class Route
8
- def initialize(coverage_responses, responses_routes)
9
- @coverage_responses = coverage_responses
10
- @responses_routes = responses_routes
11
- end
12
-
13
- def coverage
14
- @coverage ||= @responses_routes - (@responses_routes - full_coverage)
15
- end
16
-
17
- def not_coverage
18
- @not_coverage ||= @responses_routes - coverage
19
- end
20
-
21
- def cover_ratio
22
- @cover_ratio ||= (coverage.size.to_f / @responses_routes.size.to_f * 100.0).round(2)
23
- end
24
-
25
- def to_hash
26
- {
27
- 'coverage' => coverage,
28
- 'not coverage' => not_coverage
29
- }
30
- end
31
-
32
- def statistics_with_conformity_lists
33
- @request_routes ||= Fitting::Documentation::Request::Route.new(self)
34
- @request_routes.conformity_lists
35
- statistics
36
- end
37
-
38
- def statistics
39
- @request_routes ||= Fitting::Documentation::Request::Route.new(self)
40
- @request_routes.statistics
41
-
42
- valid_count = coverage.size
43
- valid_percentage = cover_ratio
44
- total_count = @responses_routes.size
45
- invalid_count = not_coverage.size
46
- invalid_percentage = 100.0 - cover_ratio
47
- puts "API responses conforming to the blueprint: #{valid_count} (#{valid_percentage}% of #{total_count})."
48
- puts "API responses with validation errors or untested: #{invalid_count} (#{invalid_percentage}% of #{total_count})."
49
- puts
50
- end
51
-
52
- private
53
-
54
- def full_coverage
55
- @coverage_responses.map do |response|
56
- response.route if response.documented? && response.valid?
57
- end.compact.uniq
58
- end
59
- end
60
- end
61
- end
62
- end
@@ -1,53 +0,0 @@
1
- require 'multi_json'
2
- require 'fitting/documentation/request/route'
3
-
4
- module Fitting
5
- module Documentation
6
- module Response
7
- class Routes
8
- def initialize(tomogram, white_list)
9
- @tomogram = tomogram
10
- @white_list = white_list
11
- end
12
-
13
- def black
14
- if @white_list
15
- all.select do |response|
16
- data = response.split(' ')
17
- data[1] && !@white_list[data[1]] || (@white_list[data[1]] != [] && !@white_list[data[1]].include?(data[0]))
18
- end
19
- else
20
- []
21
- end
22
- end
23
-
24
- def white
25
- if @white_list
26
- all.select do |response|
27
- data = response.split(' ')
28
- data[1] && @white_list[data[1]] && (@white_list[data[1]] == [] || @white_list[data[1]].include?(data[0]))
29
- end
30
- else
31
- all
32
- end
33
- end
34
-
35
- def all
36
- @all ||= MultiJson.load(@tomogram).inject([]) do |routes, request|
37
- request['responses'].inject({}) do |responses, response|
38
- responses[response['status']] ||= 0
39
- responses[response['status']] += 1
40
- responses
41
- end.map do |status, indexes|
42
- indexes.times do |index|
43
- route = "#{request['method']}\t#{request['path']} #{status} #{index}"
44
- routes.push(route)
45
- end
46
- end
47
- routes
48
- end.uniq
49
- end
50
- end
51
- end
52
- end
53
- end