fitting 2.18.3 → 3.0.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.
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