fitting 2.6.0 → 2.7.0

Sign up to get free protection for your applications and to get access to all the features.
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: