fitting 2.18.3 → 3.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (63) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +2 -11
  3. data/CHANGELOG.md +6 -0
  4. data/README.md +46 -6
  5. data/fitting.gemspec +1 -1
  6. data/lib/fitting/configuration.rb +12 -6
  7. data/lib/fitting/cover/json_schema.rb +4 -2
  8. data/lib/fitting/cover/json_schema_enum.rb +4 -2
  9. data/lib/fitting/cover/json_schema_one_of.rb +4 -2
  10. data/lib/fitting/railtie.rb +1 -0
  11. data/lib/fitting/records/documented/request.rb +1 -15
  12. data/lib/fitting/records/spherical/requests.rb +1 -1
  13. data/lib/fitting/records/tested/request.rb +11 -11
  14. data/lib/fitting/records/tested/response.rb +4 -4
  15. data/lib/fitting/report/actions.rb +4 -0
  16. data/lib/fitting/report/prefix.rb +20 -41
  17. data/lib/fitting/report/prefixes.rb +7 -8
  18. data/lib/fitting/report/response.rb +0 -3
  19. data/lib/fitting/report/tests.rb +23 -10
  20. data/lib/fitting/storage/responses.rb +5 -9
  21. data/lib/fitting/tests.rb +12 -4
  22. data/lib/fitting/version.rb +1 -1
  23. data/lib/fitting.rb +38 -43
  24. data/lib/tasks/fitting.rake +2 -186
  25. data/lib/tasks/fitting_outgoing.rake +91 -0
  26. metadata +5 -41
  27. data/lib/fitting/configuration/yaml.rb +0 -89
  28. data/lib/fitting/cover/response.rb +0 -37
  29. data/lib/fitting/documentation.rb +0 -56
  30. data/lib/fitting/matchers/response_matcher.rb +0 -88
  31. data/lib/fitting/records/realized_unit.rb +0 -52
  32. data/lib/fitting/records/test_unit/request.rb +0 -98
  33. data/lib/fitting/records/unit/combination.rb +0 -27
  34. data/lib/fitting/records/unit/json_schema.rb +0 -111
  35. data/lib/fitting/records/unit/request.rb +0 -37
  36. data/lib/fitting/records/unit/response.rb +0 -32
  37. data/lib/fitting/request.rb +0 -38
  38. data/lib/fitting/response/fully_validates.rb +0 -34
  39. data/lib/fitting/response.rb +0 -88
  40. data/lib/fitting/statistics/analysis.rb +0 -25
  41. data/lib/fitting/statistics/cover_error.rb +0 -29
  42. data/lib/fitting/statistics/cover_error_enum.rb +0 -29
  43. data/lib/fitting/statistics/cover_error_one_of.rb +0 -29
  44. data/lib/fitting/statistics/great.rb +0 -13
  45. data/lib/fitting/statistics/list.rb +0 -55
  46. data/lib/fitting/statistics/lists.rb +0 -53
  47. data/lib/fitting/statistics/measurement.rb +0 -92
  48. data/lib/fitting/statistics/measurement_cover.rb +0 -92
  49. data/lib/fitting/statistics/measurement_cover_enum.rb +0 -92
  50. data/lib/fitting/statistics/measurement_cover_one_of.rb +0 -92
  51. data/lib/fitting/statistics/not_covered_responses.rb +0 -13
  52. data/lib/fitting/statistics/percent.rb +0 -20
  53. data/lib/fitting/statistics/requests_stats.rb +0 -40
  54. data/lib/fitting/statistics/responses_stats.rb +0 -32
  55. data/lib/fitting/statistics/template.rb +0 -117
  56. data/lib/fitting/statistics/template_cover_error.rb +0 -50
  57. data/lib/fitting/statistics/template_cover_error_enum.rb +0 -50
  58. data/lib/fitting/statistics/template_cover_error_one_of.rb +0 -50
  59. data/lib/fitting/statistics.rb +0 -25
  60. data/lib/fitting/storage/white_list.rb +0 -158
  61. data/lib/fitting/templates/realized_template.rb +0 -49
  62. data/lib/fitting/view/report.html.haml +0 -16
  63. data/lib/fitting/view/style.css +0 -47
@@ -1,88 +0,0 @@
1
- require 'fitting/response'
2
- require 'fitting/configuration'
3
-
4
- module Fitting
5
- module Matchers
6
- class Response
7
- def matches?(response)
8
- if Fitting.configuration.is_a?(Array)
9
- Fitting.configuration.all? do |config|
10
- one_match(response, config)
11
- end
12
- else
13
- one_match(response, Fitting.configuration)
14
- end
15
- end
16
-
17
- def ===(other)
18
- matches?(other)
19
- end
20
-
21
- def failure_message
22
- unless @response.documented?
23
- return "response not documented\n"\
24
- "got: #{@response.real_request_with_status}"
25
- end
26
-
27
- return nil if @response.fully_validates.valid?
28
-
29
- "response does not conform to json-schema\n"\
30
- "schemas: \n#{@response.expected}\n\n"\
31
- "got: #{@response.got}\n\n"\
32
- "errors: \n#{@response.fully_validates}\n"
33
- end
34
-
35
- private
36
-
37
- def one_match(response, config)
38
- response = Fitting::Response.new(response, config.tomogram)
39
- if response.within_prefix?(config.prefix)
40
- @response = response
41
- return true if @response.ignored?(config.ignore_list)
42
-
43
- @response.fully_validates.valid?
44
- else
45
- true
46
- end
47
- end
48
- end
49
-
50
- class StrictResponse
51
- def matches?(response)
52
- if Fitting.configuration.is_a?(Array)
53
- one_match(response, Fitting.configuration[0])
54
- else
55
- one_match(response, Fitting.configuration)
56
- end
57
- end
58
-
59
- def ===(other)
60
- matches?(other)
61
- end
62
-
63
- def failure_message
64
- unless @response.documented?
65
- return "response not documented\n"\
66
- "got: #{@response.real_request_with_status}"
67
- end
68
-
69
- return nil if @response.strict_fully_validates.valid?
70
-
71
- "response does not conform to json-schema\n"\
72
- "schemas: \n#{@response.expected}\n\n"\
73
- "got: #{@response.got}\n\n"\
74
- "errors: \n#{@response.strict_fully_validates}\n"
75
- end
76
-
77
- private
78
-
79
- def one_match(response, config)
80
- @response = Fitting::Response.new(
81
- response,
82
- config.tomogram
83
- )
84
- @response.strict_fully_validates.valid?
85
- end
86
- end
87
- end
88
- end
@@ -1,52 +0,0 @@
1
- require 'fitting/records/test_unit/request'
2
-
3
- module Fitting
4
- class Records
5
- class RealizedUnit
6
- def initialize(realized_requests, documented_requests)
7
- @realized_requests = realized_requests
8
- @documented_requests = documented_requests
9
- end
10
-
11
- def fully_covered?
12
- all_good_documented = false
13
- all_good_response_documented = false
14
- all_good_response_json_schemas = false
15
- all_good_valid_json_schemas = false
16
-
17
- test_file_paths.each do |_key, requests|
18
- all_good_documented = requests.all?(&:documented?)
19
- all_good_response_documented = requests.all?(&:response_documented?)
20
- all_good_response_json_schemas = requests.all?(&:response_json_schemas?)
21
- all_good_valid_json_schemas = requests.all?(&:valid_json_schemas?)
22
- end
23
-
24
- all_good_documented && all_good_response_documented &&
25
- all_good_response_json_schemas && all_good_valid_json_schemas
26
- end
27
-
28
- def test_file_paths
29
- return @test_file_paths if @test_file_paths
30
-
31
- @test_file_paths = {}
32
- white_unit.map do |request|
33
- @test_file_paths[request.test_file_path] ||= []
34
- @test_file_paths[request.test_file_path].push(request)
35
- end
36
- @test_file_paths
37
- end
38
-
39
- def all_documented_requests
40
- @all_documented_requests ||= @documented_requests.to_a.inject([]) do |res, tomogram_request|
41
- res.push(Fitting::Records::Documented::Request.new(tomogram_request, nil))
42
- end
43
- end
44
-
45
- def white_unit
46
- @white_unit_requests ||= @realized_requests.to_a.inject([]) do |res, tested_request|
47
- res.push(Fitting::Records::TestUnit::Request.new(tested_request, all_documented_requests))
48
- end
49
- end
50
- end
51
- end
52
- end
@@ -1,98 +0,0 @@
1
- require 'json-schema'
2
-
3
- module Fitting
4
- class Records
5
- class TestUnit
6
- class Request
7
- def initialize(tested_request, all_documented_requests)
8
- @tested_request = tested_request
9
- @all_documented_requests = all_documented_requests
10
- end
11
-
12
- def method
13
- @method ||= @tested_request.method
14
- end
15
-
16
- def path
17
- @path ||= @tested_request.path
18
- end
19
-
20
- def body
21
- @body ||= @tested_request.body
22
- end
23
-
24
- def response
25
- @response ||= @tested_request.response
26
- end
27
-
28
- def test_path
29
- @test_path ||= @tested_request.title
30
- end
31
-
32
- def test_file_path
33
- @test_file_path ||= @tested_request.group
34
- end
35
-
36
- def documented_requests
37
- @documented_requests ||= @all_documented_requests.inject([]) do |res, documented_request|
38
- next res unless @tested_request.method == documented_request.method &&
39
- documented_request.path.match(@tested_request.path.to_s)
40
-
41
- res.push(documented_request)
42
- end
43
- end
44
-
45
- def documented?
46
- @documented ||= documented_requests.present?
47
- end
48
-
49
- def documented_responses
50
- @documented_responses ||= documented_requests.inject([]) do |res, documented_request|
51
- documented_request.responses.map do |documented_response|
52
- next unless documented_response['status'] == response.status.to_s
53
-
54
- res.push(documented_response)
55
- end
56
- end.flatten.compact
57
- end
58
-
59
- def response_documented?
60
- @response_documented ||= documented_responses.present?
61
- end
62
-
63
- def response_json_schemas
64
- @response_json_schemas ||= documented_responses.inject([]) do |res, documented_response|
65
- res.push(documented_response['json_schemas'])
66
- end.flatten
67
- end
68
-
69
- def response_json_schemas?
70
- @response_json_schemas_present ||= response_json_schemas.present?
71
- end
72
-
73
- def valid_json_schemas
74
- @valid_json_schemas ||= response_json_schemas.inject([]) do |res, json_schema|
75
- next res unless JSON::Validator.validate(json_schema, response.body)
76
-
77
- res.push(json_schema)
78
- end.flatten
79
- end
80
-
81
- def invalid_json_schemas
82
- @invalid_json_schemas ||= response_json_schemas.inject([]) do |res, json_schema|
83
- next res if JSON::Validator.validate(json_schema, response.body)
84
-
85
- res.push(
86
- json_schema: json_schema,
87
- fully_validate: JSON::Validator.fully_validate(json_schema, response.body)
88
- )
89
- end.flatten
90
- end
91
-
92
- def valid_json_schemas?
93
- @valid_json_schemas_present ||= valid_json_schemas.present?
94
- end
95
- end
96
- end
97
- end
98
- end
@@ -1,27 +0,0 @@
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(comb, bodies)
10
- @description = comb[1]
11
- @json_schema = comb[0]
12
- @bodies = bodies
13
- end
14
-
15
- def valid_bodies
16
- @valid_bodies ||= @bodies.inject([]) do |res, tested_body|
17
- next res unless JSON::Validator.validate(@json_schema, tested_body)
18
-
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
@@ -1,111 +0,0 @@
1
- require 'json-schema'
2
- require 'fitting/cover/json_schema'
3
- require 'fitting/cover/json_schema_enum'
4
- require 'fitting/cover/json_schema_one_of'
5
- require 'fitting/records/unit/combination'
6
-
7
- module Fitting
8
- class Records
9
- class Unit
10
- class JsonSchema
11
- attr_reader :json_schema
12
-
13
- def initialize(json_schema, tested_bodies)
14
- @json_schema = json_schema
15
- @tested_bodies = tested_bodies
16
- end
17
-
18
- def bodies
19
- @bodies ||= @tested_bodies.inject([]) do |res, tested_body|
20
- next res unless JSON::Validator.validate(@json_schema, tested_body)
21
-
22
- res.push(tested_body)
23
- rescue JSON::Schema::UriError
24
- res.push(tested_body)
25
- end
26
- end
27
-
28
- def combinations
29
- return @combinations if @combinations
30
-
31
- @combinations = []
32
- cover_json_schema = Fitting::Cover::JSONSchema.new(@json_schema)
33
- cover_json_schema.combi.map do |comb|
34
- @combinations.push(Fitting::Records::Unit::Combination.new(
35
- comb,
36
- bodies
37
- ))
38
- end
39
- @combinations
40
- end
41
-
42
- def combinations_with_enum
43
- return @combinations_with_enum if @combinations_with_enum
44
-
45
- @combinations_with_enum = []
46
- qwe = Fitting::Cover::JSONSchema.new(@json_schema).combi +
47
- Fitting::Cover::JSONSchemaEnum.new(@json_schema).combi
48
- qwe.map do |comb|
49
- @combinations_with_enum.push(Fitting::Records::Unit::Combination.new(
50
- comb,
51
- bodies
52
- ))
53
- end
54
- @combinations_with_enum
55
- end
56
-
57
- def combinations_with_one_of
58
- return @combinations_with_one_of if @combinations_with_one_of
59
-
60
- @combinations_with_one_of = []
61
- qwe = Fitting::Cover::JSONSchema.new(@json_schema).combi +
62
- Fitting::Cover::JSONSchemaEnum.new(@json_schema).combi +
63
- Fitting::Cover::JSONSchemaOneOf.new(@json_schema).combi
64
- qwe.map do |comb|
65
- @combinations_with_one_of.push(Fitting::Records::Unit::Combination.new(
66
- comb,
67
- bodies
68
- ))
69
- end
70
- @combinations_with_one_of
71
- end
72
-
73
- def cover
74
- @cover ||= if bodies == []
75
- 0
76
- else
77
- count = 0
78
- combinations.map do |combination|
79
- count += 1 unless combination.valid_bodies == []
80
- end
81
- (count + 1) * 100 / (combinations.size + 1)
82
- end
83
- end
84
-
85
- def cover_enum
86
- @cover_enum ||= if bodies == []
87
- 0
88
- else
89
- count = 0
90
- combinations_with_enum.map do |combination|
91
- count += 1 unless combination.valid_bodies == []
92
- end
93
- (count + 1) * 100 / (combinations_with_enum.size + 1)
94
- end
95
- end
96
-
97
- def cover_one_of
98
- @cover_one_of ||= if bodies == []
99
- 0
100
- else
101
- count = 0
102
- combinations_with_one_of.map do |combination|
103
- count += 1 unless combination.valid_bodies == []
104
- end
105
- (count + 1) * 100 / (combinations_with_one_of.size + 1)
106
- end
107
- end
108
- end
109
- end
110
- end
111
- end
@@ -1,37 +0,0 @@
1
- require 'fitting/records/unit/response'
2
-
3
- module Fitting
4
- class Records
5
- class Unit
6
- class Request
7
- def initialize(documented_request, tested_requests)
8
- @documented_request = documented_request
9
- @tested_requests = tested_requests
10
- end
11
-
12
- def path
13
- @path ||= @documented_request.path
14
- end
15
-
16
- def method
17
- @method ||= @documented_request.method
18
- end
19
-
20
- def responses
21
- @responses ||= @documented_request.responses.to_a.inject([]) do |res, documented_response|
22
- res.push(Fitting::Records::Unit::Response.new(documented_response, tested_responses))
23
- end
24
- end
25
-
26
- def tested_responses
27
- @tested_responses ||= @tested_requests.to_a.inject([]) do |res, tested_request|
28
- next res unless @documented_request.method == tested_request.method &&
29
- @documented_request.path.match(tested_request.path.to_s)
30
-
31
- res.push(tested_request.response)
32
- end
33
- end
34
- end
35
- end
36
- end
37
- end
@@ -1,32 +0,0 @@
1
- require 'fitting/records/unit/json_schema'
2
-
3
- module Fitting
4
- class Records
5
- class Unit
6
- class Response
7
- def initialize(documented_response, tested_responses)
8
- @documented_response = documented_response
9
- @tested_responses = tested_responses
10
- end
11
-
12
- def status
13
- @status ||= @documented_response['status']
14
- end
15
-
16
- def json_schemas
17
- @json_schemas ||= @documented_response['json_schemas'].inject([]) do |res, documented_json_schema|
18
- res.push(Fitting::Records::Unit::JsonSchema.new(documented_json_schema, tested_bodies))
19
- end
20
- end
21
-
22
- def tested_bodies
23
- @tested_bodies ||= @tested_responses.inject([]) do |res, tested_response|
24
- next res unless status == tested_response.status.to_s
25
-
26
- res.push(tested_response.body)
27
- end
28
- end
29
- end
30
- end
31
- end
32
- end
@@ -1,38 +0,0 @@
1
- require 'json-schema'
2
-
3
- module Fitting
4
- class Request
5
- def initialize(env_request, tomogram)
6
- @method = env_request.request_method
7
- @path = env_request.env['PATH_INFO'] || env_request.fullpath
8
- @body = env_request.env['action_dispatch.request.request_parameters']
9
- @schema = tomogram.find_request(method: @method, path: @path)
10
- end
11
-
12
- def route
13
- "#{@schema.method}\t#{@schema.path}"
14
- end
15
-
16
- def real_method_with_path
17
- "#{@method}\t#{@path}"
18
- end
19
-
20
- def schemas_of_possible_responses(status:)
21
- return nil unless @schema
22
-
23
- @schema.find_responses(status: status).map do |response|
24
- response['body']
25
- end
26
- end
27
-
28
- def within_prefix?(prefix)
29
- @path.start_with?(prefix)
30
- end
31
-
32
- def ignored?(ignore_list)
33
- ignore_list.any? do |regexp|
34
- regexp.match(@path)
35
- end
36
- end
37
- end
38
- end
@@ -1,34 +0,0 @@
1
- require 'json-schema'
2
-
3
- module Fitting
4
- class Response
5
- class FullyValidates < Array
6
- def self.craft(schemas, body, strict)
7
- if schemas
8
- new(schemas.inject([]) do |res, schema|
9
- res.push(fully_validate(schema, body, strict))
10
- end)
11
- else
12
- @valid = false
13
- new
14
- end
15
- end
16
-
17
- def valid?
18
- @valid ||= any? { |fully_validate| fully_validate == [] }
19
- end
20
-
21
- def to_s
22
- @to_s ||= join("\n\n")
23
- end
24
-
25
- class << self
26
- def fully_validate(schema, body, strict)
27
- JSON::Validator.fully_validate(schema, body, strict: strict)
28
- rescue JSON::Schema::UriError
29
- []
30
- end
31
- end
32
- end
33
- end
34
- end
@@ -1,88 +0,0 @@
1
- require 'fitting/request'
2
- require 'fitting/response/fully_validates'
3
- require 'json'
4
-
5
- module Fitting
6
- class Response
7
- attr_reader :body
8
-
9
- def initialize(env_response, tomogram)
10
- @request = Fitting::Request.new(env_response.request, tomogram)
11
- @status = env_response.status
12
- @body = env_response.body
13
- @schemas = @request.schemas_of_possible_responses(status: @status)
14
- end
15
-
16
- def within_prefix?(prefix)
17
- @request.within_prefix?(prefix)
18
- end
19
-
20
- def fully_validates
21
- @fully_validates ||= Fitting::Response::FullyValidates.craft(@schemas, @body, false)
22
- end
23
-
24
- def strict_fully_validates
25
- @strict_fully_validates ||= Fitting::Response::FullyValidates.craft(@schemas, @body, true)
26
- end
27
-
28
- def documented?
29
- @schemas&.present?
30
- end
31
-
32
- def route
33
- index.map do |i|
34
- "#{@request.route} #{@status} #{i}"
35
- end
36
- end
37
-
38
- def strict_route
39
- strict_index.map do |i|
40
- "#{@request.route} #{@status} #{i}"
41
- end
42
- end
43
-
44
- def real_request_with_status
45
- "#{@request.real_method_with_path} #{@status}"
46
- end
47
-
48
- def got
49
- JSON.pretty_generate(JSON.parse(@body))
50
- end
51
-
52
- def expected
53
- @expected ||= @schemas.inject([]) do |res, schema|
54
- res.push(JSON.pretty_generate(schema).to_s)
55
- end.join("\n\n")
56
- end
57
-
58
- def json_schema
59
- @schemas[index.first]
60
- end
61
-
62
- def ignored?(ignore_list)
63
- @request.ignored?(ignore_list)
64
- end
65
-
66
- private
67
-
68
- def index
69
- return @index_res if @index_res
70
-
71
- @index_res = []
72
- @schemas.size.times do |i|
73
- @index_res.push(i) if fully_validates[i] == []
74
- end
75
- @index_res
76
- end
77
-
78
- def strict_index
79
- return @strict_index_res if @strict_index_res
80
-
81
- @strict_index_res = []
82
- @schemas.size.times do |i|
83
- @strict_index_res.push(i) if strict_fully_validates[i] == []
84
- end
85
- @strict_index_res
86
- end
87
- end
88
- end
@@ -1,25 +0,0 @@
1
- require 'fitting/statistics/lists'
2
- require 'fitting/statistics/requests_stats'
3
- require 'fitting/statistics/responses_stats'
4
- require 'fitting/statistics/great'
5
- require 'fitting/statistics/not_covered_responses'
6
-
7
- module Fitting
8
- class Statistics
9
- class Analysis
10
- def initialize(measurement, depth)
11
- @measurement = measurement
12
- @depth = depth
13
- end
14
-
15
- def to_s
16
- [
17
- Fitting::Statistics::Lists.new(@measurement, @depth).to_s,
18
- Fitting::Statistics::RequestsStats.new(@measurement).to_s,
19
- Fitting::Statistics::ResponsesStats.new(@measurement).to_s,
20
- Fitting::Statistics::Great.new(@measurement).to_s
21
- ].compact.join("\n\n")
22
- end
23
- end
24
- end
25
- end
@@ -1,29 +0,0 @@
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
- next unless response.tested_bodies != []
13
-
14
- response.json_schemas.map do |json_schema|
15
- json_schema.combinations.map do |combination|
16
- next unless combination.valid_bodies == []
17
-
18
- res += "request method: #{request.method}\nrequest path: #{request.path}\n"\
19
- "response status: #{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
- res
26
- end
27
- end
28
- end
29
- end
@@ -1,29 +0,0 @@
1
- module Fitting
2
- class Statistics
3
- class CoverErrorEnum
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
- next unless response.tested_bodies != []
13
-
14
- response.json_schemas.map do |json_schema|
15
- json_schema.combinations_with_enum.map do |combination|
16
- next unless combination.valid_bodies == []
17
-
18
- res += "request method: #{request.method}\nrequest path: #{request.path}\n"\
19
- "response status: #{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
- res
26
- end
27
- end
28
- end
29
- end