fitting 2.6.0 → 2.7.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: 0f803f26bbe2cb7472a2ca8077aa7a00754ec755
4
- data.tar.gz: 38f77aec3f07b3aed3f82ebcae34549a953d45f5
3
+ metadata.gz: 058ccfba8eb94e0929f24473e00684c70d39fe19
4
+ data.tar.gz: 1a3395ec6ea7e9dd577671a523f85042773a025f
5
5
  SHA512:
6
- metadata.gz: 3a3619063602e165398a68ea20e4630be7d3877119f11cbead7fdc05a38b4f436e2d06039b75c3d09a55b069498e0f2e043d7acb14151342a90c7282378cc580
7
- data.tar.gz: 7c2ec1512bc655dbd816b3ba9665ec6af4bbf7e9c68deb8f3d1f608396ac1e24389bb5099621c732aeb0f895c019cd7e54725e825015bfe8d94829dda00586f1
6
+ metadata.gz: a6fcea3482af2fec8090fed3306af166d8c98699f18d1c629c13d2f8027fe95a42edf22ffb6ddbe0e15e883e446839450fea817273f18ddb5a0f986912ed9f33
7
+ data.tar.gz: a4ffbd091060c642052b2d4e5d9d5b33fcd3d3204622d86397b7407a6b8fdcb17527ee74ebe9d6ba759efb41fe3ecee0145b4cac27a80045a6b79fd0b6abed43
data/README.md CHANGED
@@ -39,30 +39,52 @@ In your `spec_helper.rb`:
39
39
  ```ruby
40
40
  require 'fitting'
41
41
 
42
- Fitting.statistics
42
+ Fitting.save_test_data
43
43
  ```
44
44
 
45
- or
45
+ The tests.json file will be created
46
46
 
47
- ```ruby
48
- require 'fitting'
47
+ Example:
49
48
 
50
- responses = Fitting::Storage::Responses.new
49
+ ```
50
+ [
51
+ {
52
+ "method": "GET",
53
+ "path": "/api/v1/book",
54
+ "body": {},
55
+ "response": {
56
+ "status": 200,
57
+ "body": {
58
+ "title": "The Martian Chronicles"
59
+ }
60
+ },
61
+ "title": "/spec/controllers/api/v1/books_controller_spec.rb:11",
62
+ "group": "/spec/controllers/api/v1/books_controller_spec.rb"
63
+ },
64
+ {
65
+ "method": "POST",
66
+ "path": "/api/v1/book",
67
+ "body": {},
68
+ "response": {
69
+ "status": 200,
70
+ "body": {
71
+ "title": "The Old Man and the Sea"
72
+ }
73
+ },
74
+ "title": "/spec/controllers/api/v1/books_controller_spec.rb:22",
75
+ "group": "/spec/controllers/api/v1/books_controller_spec.rb"
76
+ },
77
+ ...
78
+ ```
51
79
 
52
- RSpec.configure do |config|
53
- config.after(:each, type: :controller) do
54
- responses.add(response)
55
- end
56
80
 
57
- config.after(:suite) do
58
- responses.statistics.save
59
- end
60
- end
61
- ```
81
+ ## Check documentation cover
82
+
83
+ ### xs size
62
84
 
63
- ## Example output
85
+ For match routes and valid json-schemas run `rake fitting:documentation_responses[xs]`
64
86
 
65
- After running tests you will get statistics in the file `fitting/stats`:
87
+ You will get statistics:
66
88
 
67
89
  ```
68
90
  Fully conforming requests:
@@ -88,31 +110,50 @@ API responses conforming to the blueprint: 16 (64.00% of 25).
88
110
  API responses with validation errors or untested: 9 (36.00% of 25).
89
111
  ```
90
112
 
91
- Also you will get not covered responses in the file `fitting/not_covered`.
92
-
93
- ## Matchers
113
+ ### s size
94
114
 
95
- If you want to know why you get crosses instead of checkmarks you can use matchers for RSpec.
115
+ In addition to the previous comand, you will learn the coverage json-schemas with task `rake fitting:documentation_responses[s]`
96
116
 
97
- ```ruby
98
- config.include Fitting::Matchers, type: :controller
99
117
  ```
118
+ Fully conforming requests:
119
+ DELETE /api/v1/book 100% 200 100% 201 100% 404
120
+ DELETE /api/v1/book/{id} 100% 200 100% 201 100% 404
121
+ GET /api/v1/book/{id}/seller 100% 200 100% 201 100% 404
100
122
 
101
- ### match_schema
123
+ Partially conforming requests:
124
+ GET /api/v1/book 0% 200 66% 404
125
+ POST /api/v1/book 0% 200 90% 201 100% 404
126
+ GET /api/v1/book/{id} 0% 200 88% 404 10% 200
127
+ PATCH /api/v1/book/{id} 0% 200 100% 201 10% 404
102
128
 
103
- Makes a simple validation against JSON Schema.
129
+ Non-conforming requests:
130
+ GET /api/v1/seller 0% 200 0% 201 0 404
131
+ GET /api/v1/buyer 0% 200 0% 404
104
132
 
105
- ```ruby
106
- expect(response).to match_schema
107
- ```
133
+ API requests with fully implemented responses: 3 (33.33% of 9).
134
+ API requests with partially implemented responses: 4 (44.44% of 9).
135
+ API requests with no implemented responses: 2 (22.22% of 9).
108
136
 
109
- ### strictly_match_schema
137
+ API responses conforming to the blueprint: 16 (64.00% of 25).
138
+ API responses with validation errors or untested: 9 (36.00% of 25).
139
+ ```
110
140
 
111
- Makes a strict validation against JSON Schema. All properties are considered to have `"required": true` and all objects `"additionalProperties": false`.
141
+ For details `rake fitting:documentation_responses_error[s]`
112
142
 
113
- ```ruby
114
- expect(response).to strictly_match_schema
115
143
  ```
144
+ request metohd: GET
145
+ request path: /api/v1/book
146
+ response staus: 200
147
+ source json-schema: {"$schema"=>"http://json-schema.org/draft-04/schema#", "type"=>"object", ...}
148
+ combination: ["required", "pages"]
149
+ new json-schema: {"$schema"=>"http://json-schema.org/draft-04/schema#", "type"=>"object", ...}
150
+ ```
151
+
152
+ ## Check tests cover
153
+
154
+ ### xs size
155
+
156
+ `rake fitting:tests_responses[xs]`
116
157
 
117
158
  ## Config
118
159
 
@@ -176,6 +217,11 @@ resource_white_list:
176
217
 
177
218
  Empty array `[]` means all methods.
178
219
 
220
+ ### json_schema_cover
221
+
222
+ Default: false. Json-schema covering becomes mandatory.
223
+ Or you can call `responses.statistics.cover_save` if you don't use call `Fitting.statistics`.
224
+
179
225
  ### include_resources
180
226
 
181
227
  Default: all resources if `include_resources` and `include_actions` is not used.
data/fitting.gemspec CHANGED
@@ -23,6 +23,7 @@ Gem::Specification.new do |spec|
23
23
  spec.add_runtime_dependency 'json-schema', '~> 2.6', '>= 2.6.2'
24
24
  spec.add_runtime_dependency 'multi_json'
25
25
  spec.add_runtime_dependency 'tomograph', '~> 2.0', '>= 2.2.0'
26
+ spec.add_runtime_dependency 'haml'
26
27
  spec.add_development_dependency 'bundler', '~> 1.12'
27
28
  spec.add_development_dependency 'rake', '~> 10.0'
28
29
  spec.add_development_dependency 'byebug', '~> 8.2', '>= 8.2.1'
@@ -0,0 +1,66 @@
1
+ require 'fitting/cover/response'
2
+ require 'haml'
3
+ require 'json'
4
+
5
+ module Fitting
6
+ class Cover
7
+ def initialize(all_responses, coverage)
8
+ @all_responses = all_responses
9
+ @coverage = coverage
10
+ @list = {}
11
+ end
12
+
13
+ def to_hash
14
+ return @list unless @list == {}
15
+ @all_responses.each_with_object({}) do |response, res|
16
+ next res unless response.documented?
17
+ if res.key?(response.route)
18
+ res[response.route].update(response)
19
+ else
20
+ res[response.route] = Fitting::Cover::Response.new(response)
21
+ end
22
+ end.map do |key, value|
23
+ @list[key] = value.to_hash
24
+ end
25
+ @list
26
+ end
27
+
28
+ def template
29
+ return @template if @template
30
+ @template = {}
31
+ to_hash.each do |key, value|
32
+ @template[key] = value
33
+ @template[key]['cover'] = 100.0
34
+ if value['flags'] == []
35
+ @template[key]['type'] = 'passed'
36
+ else
37
+ flag_true = value['flags'].find_all{|flag| flag == true}
38
+ flag_false = value['flags'].find_all{|flag| flag == false}
39
+ if flag_false.size == 0
40
+ @template[key]['type'] = 'passed'
41
+ else
42
+ if flag_true.size == 0
43
+ @template[key]['cover'] = 0.0
44
+ else
45
+ @template[key]['cover'] = flag_false.size / flag_true.size
46
+ end
47
+ @template[key]['type'] = 'failed'
48
+ end
49
+ end
50
+ @template[key]['json_schema'] = JSON.pretty_generate(value['json_schemas'].last)
51
+ end
52
+ @template
53
+ end
54
+
55
+ def save
56
+ to_hash
57
+ contents = File.read(File.expand_path('../view/report.html.haml', __FILE__))
58
+ html = "<style>\n#{File.read(File.expand_path('../view/style.css', __FILE__))}\n</style>\n"
59
+ html += Haml::Engine.new(contents).render(
60
+ Object.new,
61
+ :@to_hash => template
62
+ )
63
+ html
64
+ end
65
+ end
66
+ end
@@ -0,0 +1,106 @@
1
+ module Fitting
2
+ class Cover
3
+ class JSONSchema
4
+ def initialize(json_schema)
5
+ @json_schema = json_schema
6
+ end
7
+
8
+ def json_schemas
9
+ return @json_schemas if @json_schemas
10
+ @json_schemas, @combinations = required(@json_schema)
11
+
12
+ return @json_schemas unless @json_schema['properties']
13
+ super_each(@json_schema['properties'], 'properties' => nil)
14
+
15
+ @json_schemas
16
+ end
17
+
18
+ def super_each(json_schema, old_keys_hash)
19
+ json_schema.each do |key, value|
20
+ new_keys_hash = clone_hash(old_keys_hash)
21
+ add_super_key(new_keys_hash, key)
22
+ if value.is_a?(Hash)
23
+ modify_json_shema(value, new_keys_hash)
24
+ super_each(value, new_keys_hash)
25
+ end
26
+ end
27
+ end
28
+
29
+ def add_super_key(vbn, new_key)
30
+ vbn.each do |key, value|
31
+ if value
32
+ add_super_key(value, new_key)
33
+ else
34
+ vbn[key] = { new_key => nil }
35
+ end
36
+ end
37
+ end
38
+
39
+ def super_merge(vbn, asd, old_json_schema)
40
+ vbn.each do |key, value|
41
+ if value
42
+ super_merge(value, asd, old_json_schema[key])
43
+ else
44
+ old_json_schema[key].merge!(asd)
45
+ end
46
+ end
47
+ old_json_schema
48
+ end
49
+
50
+ def modify_json_shema(value, vbn)
51
+ qwe = required(value)
52
+ qwe[0].map do |asd|
53
+ new_json_shema = clone_hash(@json_schema)
54
+ super_merge(vbn, asd, new_json_shema)
55
+ @json_schemas += [new_json_shema]
56
+ end
57
+ @combinations += qwe[1]
58
+ end
59
+
60
+ def clone_hash(old_json_schema)
61
+ new_json_schema = {}
62
+ old_json_schema.each do |key, value|
63
+ if value.is_a?(Hash)
64
+ new_json_schema.merge!(key => clone_hash(value))
65
+ elsif value
66
+ new_json_schema.merge!(key => value.clone)
67
+ else
68
+ new_json_schema.merge!(key => nil)
69
+ end
70
+ end
71
+ new_json_schema
72
+ end
73
+
74
+ def combinations
75
+ json_schemas
76
+ @combinations
77
+ end
78
+
79
+ def required(json_schema)
80
+ combinations = []
81
+ json_schemas = new_keys(json_schema).inject([]) do |new_json_shemas, new_key|
82
+ new_json_shema = json_schema.dup
83
+ if new_json_shema['required']
84
+ new_json_shema['required'] += [new_key]
85
+ else
86
+ new_json_shema['required'] = [new_key]
87
+ end
88
+ combinations.push(['required', new_key])
89
+ new_json_shemas.push(new_json_shema)
90
+ end
91
+ [json_schemas, combinations]
92
+ end
93
+
94
+ def new_keys(json_schema)
95
+ return [] unless json_schema && json_schema['properties']
96
+ all = json_schema['properties'].keys.map(&:to_s)
97
+ old = json_schema['required']
98
+ if old
99
+ all - old
100
+ else
101
+ all
102
+ end
103
+ end
104
+ end
105
+ end
106
+ end
@@ -0,0 +1,41 @@
1
+ require 'fitting/cover/json_schema'
2
+ require 'json-schema'
3
+
4
+ module Fitting
5
+ class Cover
6
+ class Response
7
+ def initialize(response)
8
+ @cover_json_schemas = Fitting::Cover::JSONSchema.new(response.json_schema)
9
+ @json_schemas = @cover_json_schemas.json_schemas + [response.json_schema]
10
+ @combinations = @cover_json_schemas.combinations
11
+ @flags = @cover_json_schemas.json_schemas.map do |json_schema|
12
+ JSON::Validator.validate(json_schema, response.body)
13
+ end
14
+ end
15
+
16
+ attr_reader :json_schemas
17
+
18
+ attr_reader :combinations
19
+
20
+ attr_reader :flags
21
+
22
+ def update(response)
23
+ index = 0
24
+ @cover_json_schemas.json_schemas.map do |json_schema|
25
+ flag = JSON::Validator.validate(json_schema, response.body)
26
+ @flags[index] = @flags[index] || flag
27
+ index += 1
28
+ end
29
+ self
30
+ end
31
+
32
+ def to_hash
33
+ {
34
+ 'json_schemas' => json_schemas,
35
+ 'combinations' => combinations,
36
+ 'flags' => flags
37
+ }
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,28 @@
1
+ require 'json-schema'
2
+
3
+ module Fitting
4
+ class Records
5
+ class Unit
6
+ class Combination
7
+ attr_reader :description, :json_schema, :bodies
8
+
9
+ def initialize(description, json_schema, bodies)
10
+ @description = description
11
+ @json_schema = json_schema
12
+ @bodies = bodies
13
+ end
14
+
15
+ def valid_bodies
16
+ @valid_bodies ||= @bodies.inject([]) do |res, tested_body|
17
+ begin
18
+ next res unless JSON::Validator.validate(@json_schema, tested_body)
19
+ res.push(tested_body)
20
+ rescue JSON::Schema::UriError
21
+ res.push(tested_body)
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
@@ -1,9 +1,13 @@
1
1
  require 'json-schema'
2
+ require 'fitting/cover/json_schema'
3
+ require 'fitting/records/unit/combination'
2
4
 
3
5
  module Fitting
4
6
  class Records
5
7
  class Unit
6
8
  class JsonSchema
9
+ attr_reader :json_schema
10
+
7
11
  def initialize(json_schema, tested_bodies)
8
12
  @json_schema = json_schema
9
13
  @tested_bodies = tested_bodies
@@ -19,6 +23,32 @@ module Fitting
19
23
  end
20
24
  end
21
25
  end
26
+
27
+ def combinations
28
+ return @combinations if @combinations
29
+ @combinations = []
30
+ cover_json_schema = Fitting::Cover::JSONSchema.new(@json_schema)
31
+ cover_json_schema.json_schemas.each_index do |index|
32
+ @combinations.push(Fitting::Records::Unit::Combination.new(
33
+ cover_json_schema.combinations[index],
34
+ cover_json_schema.json_schemas[index],
35
+ bodies
36
+ ))
37
+ end
38
+ @combinations
39
+ end
40
+
41
+ def cover
42
+ @cover ||= if bodies == []
43
+ 0
44
+ else
45
+ count = 0
46
+ combinations.map do |combination|
47
+ count += 1 unless combination.valid_bodies == []
48
+ end
49
+ (count + 1) * 100 / (combinations.size + 1)
50
+ end
51
+ end
22
52
  end
23
53
  end
24
54
  end
@@ -5,6 +5,8 @@ require 'multi_json'
5
5
 
6
6
  module Fitting
7
7
  class Response
8
+ attr_reader :body
9
+
8
10
  def initialize(env_response, tomogram)
9
11
  @request = Fitting::Request.new(env_response.request, tomogram)
10
12
  @status = env_response.status
@@ -54,6 +56,10 @@ module Fitting
54
56
  end.join("\n\n")
55
57
  end
56
58
 
59
+ def json_schema
60
+ @schemas[index.first]
61
+ end
62
+
57
63
  def ignored?(ignore_list)
58
64
  @request.ignored?(ignore_list)
59
65
  end
@@ -7,13 +7,14 @@ require 'fitting/statistics/not_covered_responses'
7
7
  module Fitting
8
8
  class Statistics
9
9
  class Analysis
10
- def initialize(measurement)
10
+ def initialize(measurement, depth)
11
11
  @measurement = measurement
12
+ @depth = depth
12
13
  end
13
14
 
14
15
  def to_s
15
16
  [
16
- Fitting::Statistics::Lists.new(@measurement).to_s,
17
+ Fitting::Statistics::Lists.new(@measurement, @depth).to_s,
17
18
  Fitting::Statistics::RequestsStats.new(@measurement).to_s,
18
19
  Fitting::Statistics::ResponsesStats.new(@measurement).to_s,
19
20
  Fitting::Statistics::Great.new(@measurement).to_s
@@ -0,0 +1,31 @@
1
+ module Fitting
2
+ class Statistics
3
+ class CoverError
4
+ def initialize(request_unit)
5
+ @request_unit = request_unit
6
+ end
7
+
8
+ def to_s
9
+ res = ''
10
+ @request_unit.map do |request|
11
+ request.responses.map do |response|
12
+ if response.tested_bodies == []
13
+ return 'Error, not all responses valid without cover!'
14
+ else
15
+ response.json_schemas.map do |json_schema|
16
+ json_schema.combinations.map do |combination|
17
+ if combination.valid_bodies == []
18
+ res += "request metohd: #{request.method}\nrequest path: #{request.path}\n"\
19
+ "response staus: #{response.status}\nsource json-schema: #{json_schema.json_schema}\n"\
20
+ "combination: #{combination.description}\nnew json-schema: #{combination.json_schema}\n\n"
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
27
+ res
28
+ end
29
+ end
30
+ end
31
+ end
@@ -1,9 +1,10 @@
1
1
  module Fitting
2
2
  class Statistics
3
3
  class List
4
- def initialize(coverage, max_response_path)
4
+ def initialize(coverage, max_response_path, depth)
5
5
  @coverage = coverage
6
6
  @max_response_path = max_response_path
7
+ @depth = depth
7
8
  end
8
9
 
9
10
  def to_s
@@ -34,10 +35,14 @@ module Fitting
34
35
  end
35
36
 
36
37
  def json_schema_stat(res, json_schema, response)
37
- if json_schema.bodies == []
38
- res.push("✖ #{response.status}")
38
+ if @depth == 'valid'
39
+ if json_schema.bodies == []
40
+ res.push("✖ #{response.status}")
41
+ else
42
+ res.push("✔ #{response.status}")
43
+ end
39
44
  else
40
- res.push(" #{response.status}")
45
+ res.push("#{json_schema.cover}% #{response.status}")
41
46
  end
42
47
  end
43
48
  end
@@ -3,8 +3,9 @@ require 'fitting/statistics/list'
3
3
  module Fitting
4
4
  class Statistics
5
5
  class Lists
6
- def initialize(measurement)
6
+ def initialize(measurement, depth)
7
7
  @measurement = measurement
8
+ @depth = depth
8
9
  end
9
10
 
10
11
  def to_s
@@ -21,7 +22,7 @@ module Fitting
21
22
  else
22
23
  [
23
24
  'Fully conforming requests:',
24
- Fitting::Statistics::List.new(@measurement.coverage_fully, @measurement.max_response_path).to_s
25
+ Fitting::Statistics::List.new(@measurement.coverage_fully, @measurement.max_response_path, @depth).to_s
25
26
  ].join("\n")
26
27
  end
27
28
  end
@@ -32,7 +33,7 @@ module Fitting
32
33
  else
33
34
  [
34
35
  'Partially conforming requests:',
35
- Fitting::Statistics::List.new(@measurement.coverage_partially, @measurement.max_response_path).to_s
36
+ Fitting::Statistics::List.new(@measurement.coverage_partially, @measurement.max_response_path, @depth).to_s
36
37
  ].join("\n")
37
38
  end
38
39
  end
@@ -43,7 +44,7 @@ module Fitting
43
44
  else
44
45
  [
45
46
  'Non-conforming requests:',
46
- Fitting::Statistics::List.new(@measurement.coverage_non, @measurement.max_response_path).to_s
47
+ Fitting::Statistics::List.new(@measurement.coverage_non, @measurement.max_response_path, @depth).to_s
47
48
  ].join("\n")
48
49
  end
49
50
  end
@@ -0,0 +1,94 @@
1
+ module Fitting
2
+ class Statistics
3
+ class MeasurementCover
4
+ attr_reader :requests, :all_responses, :cover_responses, :not_cover_responses, :max_response_path,
5
+ :coverage_fully, :coverage_non, :coverage_partially, :not_covered_responses
6
+
7
+ def initialize(requests)
8
+ @requests = requests
9
+ @all_responses = 0
10
+ @cover_responses = 0
11
+ @not_cover_responses = 0
12
+ @max_response_path = 0
13
+ @coverage_fully = []
14
+ @coverage_non = []
15
+ @coverage_partially = []
16
+ @not_covered_responses = []
17
+ check_responses
18
+ end
19
+
20
+ def check_responses
21
+ return if @ready
22
+
23
+ @requests.map do |request|
24
+ chech_request(request)
25
+ end
26
+
27
+ @ready = true
28
+ end
29
+
30
+ private
31
+
32
+ def chech_request(request)
33
+ check_cover(request)
34
+ coverage_push(request)
35
+
36
+ if request.path.to_s.size / 8 > @max_response_path
37
+ @max_response_path = request.path.to_s.size / 8
38
+ end
39
+ request.responses.map do |response|
40
+ check_response(response, request)
41
+ end
42
+ end
43
+
44
+ def check_response(response, request)
45
+ json_schema_index = 0
46
+ response.json_schemas.map do |json_schema|
47
+ json_schema_index = check_json_schema(json_schema, request, response, json_schema_index)
48
+ end
49
+ end
50
+
51
+ def check_json_schema(json_schema, request, response, json_schema_index)
52
+ if json_schema.cover != 100
53
+ @not_cover_responses += 1
54
+ @not_covered_responses.push("#{request.method}\t#{request.path} #{response.status} #{json_schema_index}")
55
+ else
56
+ @cover_responses += 1
57
+ end
58
+ @all_responses += 1
59
+ json_schema_index + 1
60
+ end
61
+
62
+ def coverage_push(request)
63
+ if @all == @cover
64
+ @coverage_fully.push(request)
65
+ elsif @all == @not_cover
66
+ @coverage_non.push(request)
67
+ else
68
+ @coverage_partially.push(request)
69
+ end
70
+ end
71
+
72
+ def check_cover(request)
73
+ @all = 0
74
+ @cover = 0
75
+ @not_cover = 0
76
+
77
+ request.responses.map do |response|
78
+ response.json_schemas.map do |json_schema|
79
+ count_cover(json_schema)
80
+ end
81
+ end
82
+ end
83
+
84
+ def count_cover(json_schema)
85
+ @all += 1
86
+ if json_schema.cover != 100
87
+ @not_cover += 1
88
+ else
89
+ @cover += 1
90
+ end
91
+ end
92
+ end
93
+ end
94
+ end
@@ -1,6 +1,7 @@
1
1
  require 'fitting/statistics/not_covered_responses'
2
2
  require 'fitting/statistics/analysis'
3
3
  require 'fitting/statistics/measurement'
4
+ require 'fitting/statistics/measurement_cover'
4
5
  require 'fitting/records/unit/request'
5
6
  require 'fitting/storage/white_list'
6
7
  require 'fitting/records/documented/request'
@@ -8,9 +9,10 @@ require 'fitting/records/documented/request'
8
9
  module Fitting
9
10
  class Statistics
10
11
  class Template
11
- def initialize(tested_requests, config)
12
+ def initialize(tested_requests, config, depth = 'valid')
12
13
  @tested_requests = tested_requests
13
14
  @config = config
15
+ @depth = depth
14
16
  end
15
17
 
16
18
  def save
@@ -35,19 +37,29 @@ module Fitting
35
37
  end
36
38
 
37
39
  def white_statistics
38
- @white_statistics ||= Fitting::Statistics::Analysis.new(white_measurement)
40
+ @white_statistics ||= Fitting::Statistics::Analysis.new(white_measurement, @depth)
39
41
  end
40
42
 
41
43
  def black_statistics
42
- @black_statistics ||= Fitting::Statistics::Analysis.new(black_measurement)
44
+ @black_statistics ||= Fitting::Statistics::Analysis.new(black_measurement, @depth)
43
45
  end
44
46
 
45
47
  def white_measurement
46
- @white_measurement ||= Fitting::Statistics::Measurement.new(white_unit)
48
+ @white_measurement ||=
49
+ if @depth == 'valid'
50
+ Fitting::Statistics::Measurement.new(white_unit)
51
+ else
52
+ Fitting::Statistics::MeasurementCover.new(white_unit)
53
+ end
47
54
  end
48
55
 
49
56
  def black_measurement
50
- @black_measurement ||= Fitting::Statistics::Measurement.new(black_unit)
57
+ @black_measurement ||=
58
+ if @depth == 'valid'
59
+ Fitting::Statistics::Measurement.new(black_unit)
60
+ else
61
+ Fitting::Statistics::MeasurementCover.new(black_unit)
62
+ end
51
63
  end
52
64
 
53
65
  def white_unit
@@ -0,0 +1,54 @@
1
+ require 'fitting/statistics/cover_error'
2
+ require 'fitting/records/unit/request'
3
+ require 'fitting/storage/white_list'
4
+ require 'fitting/records/documented/request'
5
+
6
+ module Fitting
7
+ class Statistics
8
+ class TemplateCoverError
9
+ def initialize(tested_requests, config)
10
+ @tested_requests = tested_requests
11
+ @config = config
12
+ end
13
+
14
+ def stats
15
+ [
16
+ ['[White list]', white_statistics].join("\n"),
17
+ ''
18
+ ].join("\n\n")
19
+ end
20
+
21
+
22
+ def white_statistics
23
+ @white_statistics ||= Fitting::Statistics::CoverError.new(white_unit)
24
+ end
25
+
26
+ def white_unit
27
+ @white_unit_requests ||= documented_requests_white.inject([]) do |res, documented_request|
28
+ res.push(Fitting::Records::Unit::Request.new(documented_request, @tested_requests))
29
+ end
30
+ end
31
+
32
+ def documented_requests_white
33
+ @documented_requests_white ||= documented.find_all(&:white)
34
+ end
35
+
36
+ def documented
37
+ @documented_requests ||= @config.tomogram.to_a.inject([]) do |res, tomogram_request|
38
+ res.push(Fitting::Records::Documented::Request.new(tomogram_request, white_list.to_a))
39
+ end
40
+ end
41
+
42
+ def white_list
43
+ @white_list ||= Fitting::Storage::WhiteList.new(
44
+ @config.prefix,
45
+ @config.white_list,
46
+ @config.resource_white_list,
47
+ @config.include_resources,
48
+ @config.include_actions,
49
+ @config.tomogram.to_resources
50
+ )
51
+ end
52
+ end
53
+ end
54
+ end
@@ -1,3 +1,3 @@
1
1
  module Fitting
2
- VERSION = '2.6.0'.freeze
2
+ VERSION = '2.7.0'.freeze
3
3
  end
@@ -0,0 +1,16 @@
1
+ !!! 5
2
+ %html
3
+ %head
4
+ %title= Time.now
5
+ %meta{charset: "utf-8"}
6
+ %body
7
+ - @to_hash.each do |key, value|
8
+ %details
9
+ %summary{class: "collapse #{value['type']}"}
10
+ = "#{key} #{value['cover']}"
11
+ %div{class: 'group'}
12
+ %div{class: 'section'}
13
+ %div
14
+ %b main json-schema
15
+ %xmp
16
+ = value['json_schema']
@@ -0,0 +1,47 @@
1
+ summary {
2
+ margin: 10px;
3
+ }
4
+
5
+ summary:hover {
6
+ background: #e1e1e1;
7
+ }
8
+
9
+ .passed {
10
+ color: green;
11
+ }
12
+
13
+ .failed {
14
+ color: red;
15
+ }
16
+
17
+ .pending {
18
+ color: orange;
19
+ }
20
+
21
+ .collapse {
22
+ cursor: pointer;
23
+ display: block;
24
+ background: white;
25
+ }
26
+
27
+ .collapse + input {
28
+ display: none; /* hide the checkboxes */
29
+ }
30
+
31
+ .collapse + input + div {
32
+ display: none;
33
+ }
34
+
35
+ .collapse + input:checked + div {
36
+ display: block;
37
+ }
38
+
39
+ .section {
40
+ padding-top: 10px;
41
+ }
42
+
43
+ .group {
44
+ border: 1px solid black;
45
+ margin: 5px 0px;
46
+ padding: 0px 5px;
47
+ }
@@ -2,6 +2,7 @@ require 'fitting/records/spherical/requests'
2
2
  require 'fitting/configuration'
3
3
  require 'fitting/records/realized_unit'
4
4
  require 'fitting/templates/realized_template'
5
+ require 'fitting/statistics/template_cover_error'
5
6
 
6
7
  namespace :fitting do
7
8
  desc 'Fitting documentation'
@@ -18,6 +19,49 @@ namespace :fitting do
18
19
  end
19
20
  end
20
21
 
22
+ desc 'Fitting documentation responses cover'
23
+ task :documentation_responses, [:size] => :environment do |_, args|
24
+ if args.size == 'xs'
25
+ documented_unit = Fitting::Statistics::Template.new(
26
+ Fitting::Records::Spherical::Requests.new,
27
+ Fitting.configuration
28
+ )
29
+ puts documented_unit.stats
30
+
31
+ unless documented_unit.not_covered == "\n"
32
+ puts 'Not all responses from the whitelist are covered!'
33
+ exit 1
34
+ end
35
+ elsif args.size == 's'
36
+ documented_unit = Fitting::Statistics::Template.new(
37
+ Fitting::Records::Spherical::Requests.new,
38
+ Fitting.configuration,
39
+ 'cover'
40
+ )
41
+ puts documented_unit.stats
42
+
43
+ unless documented_unit.not_covered == "\n"
44
+ puts 'Not all responses from the whitelist are covered!'
45
+ exit 1
46
+ end
47
+ else
48
+ puts 'need key xs or s'
49
+ end
50
+ end
51
+
52
+ desc 'Fitting documentation responses cover error'
53
+ task :documentation_responses_error, [:size] => :environment do |_, args|
54
+ if args.size == 's'
55
+ documented_unit = Fitting::Statistics::TemplateCoverError.new(
56
+ Fitting::Records::Spherical::Requests.new,
57
+ Fitting.configuration
58
+ )
59
+ puts documented_unit.stats
60
+ else
61
+ puts 'need key s'
62
+ end
63
+ end
64
+
21
65
  desc 'Fitting tests'
22
66
  task :tests do
23
67
  realized_unit = Fitting::Records::RealizedUnit.new(
@@ -31,4 +75,22 @@ namespace :fitting do
31
75
  exit 1
32
76
  end
33
77
  end
78
+
79
+ desc 'Fitting tests'
80
+ task :tests_responses, [:size] => :environment do |_, args|
81
+ if args.size == 'xs'
82
+ realized_unit = Fitting::Records::RealizedUnit.new(
83
+ Fitting::Records::Spherical::Requests.new,
84
+ Fitting.configuration.tomogram
85
+ )
86
+ puts Fitting::Templates::RealizedTemplate.new(realized_unit).to_s
87
+
88
+ unless realized_unit.fully_covered?
89
+ puts 'Not all responses from the whitelist are covered!'
90
+ exit 1
91
+ end
92
+ else
93
+ puts 'need key xs'
94
+ end
95
+ end
34
96
  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: 2.6.0
4
+ version: 2.7.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: 2018-08-28 00:00:00.000000000 Z
11
+ date: 2018-09-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: json-schema
@@ -64,6 +64,20 @@ dependencies:
64
64
  - - ">="
65
65
  - !ruby/object:Gem::Version
66
66
  version: 2.2.0
67
+ - !ruby/object:Gem::Dependency
68
+ name: haml
69
+ requirement: !ruby/object:Gem::Requirement
70
+ requirements:
71
+ - - ">="
72
+ - !ruby/object:Gem::Version
73
+ version: '0'
74
+ type: :runtime
75
+ prerelease: false
76
+ version_requirements: !ruby/object:Gem::Requirement
77
+ requirements:
78
+ - - ">="
79
+ - !ruby/object:Gem::Version
80
+ version: '0'
67
81
  - !ruby/object:Gem::Dependency
68
82
  name: bundler
69
83
  requirement: !ruby/object:Gem::Requirement
@@ -195,6 +209,9 @@ files:
195
209
  - lib/fitting/configuration.rb
196
210
  - lib/fitting/configuration/legacy.rb
197
211
  - lib/fitting/configuration/yaml.rb
212
+ - lib/fitting/cover.rb
213
+ - lib/fitting/cover/json_schema.rb
214
+ - lib/fitting/cover/response.rb
198
215
  - lib/fitting/documentation.rb
199
216
  - lib/fitting/matchers/response_matcher.rb
200
217
  - lib/fitting/railtie.rb
@@ -206,6 +223,7 @@ files:
206
223
  - lib/fitting/records/test_unit/request.rb
207
224
  - lib/fitting/records/tested/request.rb
208
225
  - lib/fitting/records/tested/response.rb
226
+ - lib/fitting/records/unit/combination.rb
209
227
  - lib/fitting/records/unit/json_schema.rb
210
228
  - lib/fitting/records/unit/request.rb
211
229
  - lib/fitting/records/unit/response.rb
@@ -214,20 +232,25 @@ files:
214
232
  - lib/fitting/response/fully_validates.rb
215
233
  - lib/fitting/statistics.rb
216
234
  - lib/fitting/statistics/analysis.rb
235
+ - lib/fitting/statistics/cover_error.rb
217
236
  - lib/fitting/statistics/great.rb
218
237
  - lib/fitting/statistics/list.rb
219
238
  - lib/fitting/statistics/lists.rb
220
239
  - lib/fitting/statistics/measurement.rb
240
+ - lib/fitting/statistics/measurement_cover.rb
221
241
  - lib/fitting/statistics/not_covered_responses.rb
222
242
  - lib/fitting/statistics/percent.rb
223
243
  - lib/fitting/statistics/requests_stats.rb
224
244
  - lib/fitting/statistics/responses_stats.rb
225
245
  - lib/fitting/statistics/template.rb
246
+ - lib/fitting/statistics/template_cover_error.rb
226
247
  - lib/fitting/storage/responses.rb
227
248
  - lib/fitting/storage/white_list.rb
228
249
  - lib/fitting/templates/realized_template.rb
229
250
  - lib/fitting/tests.rb
230
251
  - lib/fitting/version.rb
252
+ - lib/fitting/view/report.html.haml
253
+ - lib/fitting/view/style.css
231
254
  - lib/tasks/fitting.rake
232
255
  homepage: https://github.com/funbox/fitting
233
256
  licenses: