fitting 3.0.2 → 4.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 (85) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/.ruby-version +1 -1
  4. data/CHANGELOG.md +9 -0
  5. data/README.md +272 -109
  6. data/fitting.gemspec +2 -2
  7. data/images/b1.png +0 -0
  8. data/images/b2.png +0 -0
  9. data/images/w1.png +0 -0
  10. data/images/w2.png +0 -0
  11. data/lib/fitting/action.rb +105 -0
  12. data/lib/fitting/cover/json_schema.rb +2 -2
  13. data/lib/fitting/cover/json_schema_one_of.rb +4 -2
  14. data/lib/fitting/debug.rb +47 -0
  15. data/lib/fitting/doc/action.rb +141 -0
  16. data/lib/fitting/doc/code.rb +53 -0
  17. data/lib/fitting/doc/combination_enum.rb +110 -0
  18. data/lib/fitting/doc/combination_one_of.rb +61 -0
  19. data/lib/fitting/doc/combination_optional.rb +54 -0
  20. data/lib/fitting/doc/combination_step.rb +48 -0
  21. data/lib/fitting/doc/content_type.rb +152 -0
  22. data/lib/fitting/doc/json_schema.rb +116 -0
  23. data/lib/fitting/doc/step.rb +102 -0
  24. data/lib/fitting/doc.rb +107 -0
  25. data/lib/fitting/host.rb +37 -0
  26. data/lib/fitting/log.rb +102 -0
  27. data/lib/fitting/nocov.rb +64 -0
  28. data/lib/fitting/prefix.rb +62 -0
  29. data/lib/fitting/railtie.rb +0 -1
  30. data/lib/fitting/records/spherical/request.rb +7 -4
  31. data/lib/fitting/records/spherical/response.rb +22 -16
  32. data/lib/fitting/records/tested/request.rb +6 -1
  33. data/lib/fitting/records/tested/response.rb +6 -1
  34. data/lib/fitting/rep/html.rb +32 -0
  35. data/lib/fitting/rep.rb +24 -0
  36. data/lib/fitting/report/action.rb +9 -15
  37. data/lib/fitting/report/actions.rb +22 -33
  38. data/lib/fitting/report/combination.rb +10 -6
  39. data/lib/fitting/report/combinations.rb +9 -29
  40. data/lib/fitting/report/prefix.rb +7 -24
  41. data/lib/fitting/report/prefixes.rb +11 -25
  42. data/lib/fitting/report/response.rb +12 -22
  43. data/lib/fitting/report/responses.rb +23 -27
  44. data/lib/fitting/report/tests.rb +4 -8
  45. data/lib/fitting/skip/action.rb +44 -0
  46. data/lib/fitting/skip/api.rb +29 -0
  47. data/lib/fitting/skip.rb +21 -0
  48. data/lib/fitting/version.rb +1 -1
  49. data/lib/fitting.rb +12 -28
  50. data/lib/tasks/fitting.rake +23 -84
  51. data/lib/templates/htmlcss/bootstrap-nightshade.min.css +12 -0
  52. data/lib/templates/htmlcss/bootstrap.min.js +7 -0
  53. data/lib/templates/htmlcss/darkmode.min.js +6 -0
  54. data/lib/templates/htmlcss/fitting.html +196 -0
  55. data/lib/templates/htmlcss/jquery-3.6.0.min.js +2 -0
  56. metadata +40 -39
  57. data/lib/fitting/configuration.rb +0 -17
  58. data/lib/fitting/records/spherical/requests.rb +0 -25
  59. data/lib/fitting/storage/responses.rb +0 -21
  60. data/lib/fitting/tests.rb +0 -31
  61. data/lib/tasks/fitting_outgoing.rake +0 -91
  62. data/lib/templates/bomboniere/.gitignore +0 -21
  63. data/lib/templates/bomboniere/.tool-versions +0 -1
  64. data/lib/templates/bomboniere/README.md +0 -19
  65. data/lib/templates/bomboniere/dist/css/app.aa2bcd8a.css +0 -1
  66. data/lib/templates/bomboniere/dist/css/chunk-vendors.ec5f6c3f.css +0 -1
  67. data/lib/templates/bomboniere/dist/favicon.ico +0 -0
  68. data/lib/templates/bomboniere/dist/index.html +0 -1
  69. data/lib/templates/bomboniere/dist/js/app.e5f1a5ec.js +0 -2
  70. data/lib/templates/bomboniere/dist/js/app.e5f1a5ec.js.map +0 -1
  71. data/lib/templates/bomboniere/dist/js/chunk-vendors.0f99b670.js +0 -13
  72. data/lib/templates/bomboniere/dist/js/chunk-vendors.0f99b670.js.map +0 -1
  73. data/lib/templates/bomboniere/package-lock.json +0 -9292
  74. data/lib/templates/bomboniere/package.json +0 -27
  75. data/lib/templates/bomboniere/public/favicon.ico +0 -0
  76. data/lib/templates/bomboniere/public/index.html +0 -17
  77. data/lib/templates/bomboniere/src/App.vue +0 -102
  78. data/lib/templates/bomboniere/src/assets/logo.png +0 -0
  79. data/lib/templates/bomboniere/src/components/HelloWorld.vue +0 -204
  80. data/lib/templates/bomboniere/src/main.js +0 -10
  81. data/lib/templates/bomboniere/src/router/index.js +0 -31
  82. data/lib/templates/bomboniere/src/views/About.vue +0 -5
  83. data/lib/templates/bomboniere/src/views/Action.vue +0 -173
  84. data/lib/templates/bomboniere/src/views/Home.vue +0 -17
  85. data/lib/templates/bomboniere/vue.config.js +0 -3
@@ -0,0 +1,47 @@
1
+ module Fitting
2
+ class Debug
3
+ attr_accessor :host, :method, :path, :status, :content_type
4
+
5
+ def initialize(host, method, path, code, content_type)
6
+ @host = host
7
+ @method = method
8
+ @path = path
9
+ @status = code.to_s
10
+ @content_type = content_type
11
+ end
12
+
13
+ def self.save!(docs, yaml)
14
+ return unless yaml['Debug']
15
+ yaml['Debug'].map do |action|
16
+ debug = new(action['host'], action['method'], action['path'], action['code'], action['content-type'])
17
+ res = Fitting::Doc.debug(docs, debug)
18
+ index = res.next_steps.first.index_before
19
+ next_steps_first = res.next_steps.first
20
+ res_debug = report(index, next_steps_first, res.logs)
21
+ File.open('coverage/.fitting.debug.yml', 'w') { |file| file.write(YAML.dump(res_debug)) }
22
+ end
23
+ end
24
+
25
+ def self.report(index, next_steps_first, res_logs)
26
+ return {} if index.nil?
27
+ combinations = []
28
+ next_steps_first.next_steps.each do |next_step|
29
+ combinations.push(
30
+ next_step.debug_report(index)
31
+ )
32
+ end
33
+ res_debug = {
34
+ "json_schema" => next_steps_first.to_hash,
35
+ "jsons" => res_logs,
36
+ "valid_jsons" => next_steps_first.logs,
37
+ "index_before" => next_steps_first.index_before - index,
38
+ "index_medium" => next_steps_first.index_medium - index,
39
+ "index_after" => next_steps_first.index_after - index,
40
+ "res_before" => next_steps_first.res_before.map{|r| r ? r : "null"}[index..-1],
41
+ "res_medium" => next_steps_first.res_medium.map{|r| r ? r : "null"}[index..-1],
42
+ "res_after" => next_steps_first.res_after.map{|r| r ? r : "null"}[index..-1],
43
+ "combinations" => combinations
44
+ }
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,141 @@
1
+ require 'fitting/doc/code'
2
+ require 'fitting/debug'
3
+
4
+ module Fitting
5
+ class Doc
6
+ class Action
7
+ attr_accessor :host, :prefix, :path, :method, :responses
8
+
9
+ class NotFound < RuntimeError; end
10
+
11
+ def initialize(host, prefix, method, path, responses)
12
+ @host = host
13
+ @prefix = prefix
14
+ @method = method
15
+ @path = path
16
+ @path.slice!(prefix)
17
+ @responses = []
18
+ responses.group_by { |response| response['status'] }.each do |code, value|
19
+ @responses.push(Code.new(code, value))
20
+ end
21
+ @key = "#{method} #{host}#{prefix}#{path}"
22
+
23
+ @host_cover = 0
24
+ @prefix_cover = 0
25
+ @path_cover = 0
26
+ @method_cover = 0
27
+ end
28
+
29
+ def to_hash_lock
30
+ res = YAML.dump(
31
+ {
32
+ host => {
33
+ prefix => {
34
+ path => {
35
+ method => @responses.inject({}) { |sum, response| sum.merge!(response) }
36
+ }
37
+ }
38
+ }
39
+ }
40
+ ).split("\n")
41
+ { @key => res[1..-1] }
42
+ end
43
+
44
+ def to_hash
45
+ res = [
46
+ @host_cover,
47
+ @prefix_cover,
48
+ @path_cover,
49
+ @method_cover
50
+ ]
51
+ (to_hash_lock[@key].size - 4).times { res.push(nil) }
52
+
53
+ if @method_cover != nil && @method_cover != 0
54
+ code_index = 4
55
+ @responses.each do |code|
56
+ res, code_index = code.report(res, code_index)
57
+ end
58
+ end
59
+
60
+ { @key => res }
61
+ end
62
+
63
+ def cover!(log)
64
+ unless log.host == host
65
+ return
66
+ end
67
+ @host_cover += 1
68
+
69
+ unless prefix.size == 0 || log.path[0..prefix.size - 1] == prefix
70
+ return
71
+ end
72
+ @prefix_cover += 1
73
+
74
+ unless path_match(log.path)
75
+ return
76
+ end
77
+ @path_cover += 1
78
+
79
+ unless log.method == method
80
+ return
81
+ end
82
+ @method_cover += 1
83
+
84
+ @responses.each { |response| response.cover!(log) }
85
+
86
+ true
87
+ rescue Fitting::Doc::Code::NotFound => e
88
+ raise NotFound.new "\n\ntype: #{@type}\n"\
89
+ "host: #{@host}\n" \
90
+ "prefix: #{@prefix}\n" \
91
+ "method: #{@method}\n" \
92
+ "path: #{@path}\n" \
93
+ "#{e.message}"
94
+ end
95
+
96
+ def debug(debug)
97
+ unless debug.host == host
98
+ return nil
99
+ end
100
+
101
+ unless prefix.size == 0 || debug.path[0..prefix.size - 1] == prefix
102
+ return nil
103
+ end
104
+
105
+ unless path_match(debug.path)
106
+ return nil
107
+ end
108
+
109
+ unless debug.method == method
110
+ return nil
111
+ end
112
+
113
+ @responses.each do |response|
114
+ res = response.debug(debug)
115
+ return res if res
116
+ end
117
+ nil
118
+ end
119
+
120
+ def nocover!
121
+ @host_cover = nil
122
+ @prefix_cover = nil
123
+ @path_cover = nil
124
+ @method_cover = nil
125
+ end
126
+
127
+ def path_match(find_path)
128
+ regexp =~ find_path
129
+ end
130
+
131
+ def regexp
132
+ return @regexp if @regexp
133
+
134
+ str = Regexp.escape(@prefix + path)
135
+ str = str.gsub(/\\{\w+\\}/, '[^&=\/]+')
136
+ str = "\\A#{str}\\z"
137
+ @regexp = Regexp.new(str)
138
+ end
139
+ end
140
+ end
141
+ end
@@ -0,0 +1,53 @@
1
+ require 'fitting/doc/step'
2
+ require 'fitting/doc/content_type'
3
+
4
+ module Fitting
5
+ class Doc
6
+ class Code < Step
7
+ class NotFound < RuntimeError; end
8
+
9
+ def initialize(code, value)
10
+ @step_cover_size = 0
11
+ @step_key = code
12
+ @next_steps = []
13
+ value.group_by { |val| val['content-type'] }.each do |content_type, subvalue|
14
+ break if content_type == nil
15
+ @next_steps.push(ContentType.new(content_type, subvalue))
16
+ end
17
+ end
18
+
19
+ def to_hash
20
+ if @next_steps.size == 1 && @next_steps[0].step_key == nil
21
+ {
22
+ @step_key => {}
23
+ }
24
+ else
25
+ {
26
+ @step_key => @next_steps.inject({}) { |sum, value| sum.merge!(value) }
27
+ }
28
+ end
29
+ end
30
+
31
+ def cover!(log)
32
+ if @step_key == log.status
33
+ @step_cover_size += 1
34
+ @next_steps.each { |content_type| content_type.cover!(log) }
35
+ end
36
+ rescue Fitting::Doc::ContentType::NotFound => e
37
+ raise NotFound.new "code: #{@step_key}\n\n"\
38
+ "#{e.message}"
39
+ end
40
+
41
+ def debug(debug)
42
+ if @step_key == debug.status
43
+ @next_steps.each do |content_type|
44
+ res = content_type.debug(debug)
45
+ return res if res
46
+ end
47
+ nil
48
+ end
49
+ nil
50
+ end
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,110 @@
1
+ require 'fitting/doc/combination_step'
2
+ require 'fitting/cover/json_schema_enum'
3
+
4
+ module Fitting
5
+ class Doc
6
+ class CombinationEnum < CombinationStep
7
+ def cover!(log)
8
+ error = JSON::Validator.fully_validate(@json_schema, log.body)
9
+ if error == []
10
+ @step_cover_size += 1
11
+ @logs.push(log.body)
12
+ nil
13
+ else
14
+ bodies = custom_body(log.body)
15
+ errors = []
16
+ bodies.each do |body|
17
+ error = JSON::Validator.fully_validate(@json_schema, body)
18
+ if error == []
19
+ @step_cover_size += 1
20
+ @logs.push(body)
21
+ nil
22
+ else
23
+ errors.push(
24
+ {
25
+ combination: @step_key,
26
+ type: @type,
27
+ json_schema: @json_schema,
28
+ error: error,
29
+ body: body
30
+ })
31
+ end
32
+ end
33
+
34
+ if errors.size == bodies.size
35
+ errors
36
+ else
37
+ nil
38
+ end
39
+ end
40
+ end
41
+
42
+ def find_keys
43
+ new_keys = []
44
+ if YAML.dump(@json_schema).include?("array")
45
+ res = @json_schema
46
+ @step_key.split('.').each do |key|
47
+ if res[key].class == Hash && res[key] != nil
48
+ if res[key].class == Hash && res[key]['type'] == 'array'
49
+ new_keys.push(key)
50
+ return new_keys
51
+ else
52
+ if key != 'properties'
53
+ new_keys.push(key)
54
+ end
55
+ res = res[key]
56
+ end
57
+ end
58
+ end
59
+ end
60
+ []
61
+ end
62
+
63
+ def custom_body(body)
64
+ bodies = []
65
+ keys = find_keys
66
+ if keys != []
67
+ if keys.size == 1
68
+ if body[keys[0]].size == 1
69
+ return body
70
+ else
71
+ body[keys[0]].each do |bb|
72
+ new_body = body.dup
73
+ new_body.delete(keys[0])
74
+ bodies.push(new_body.merge(keys[0] => bb))
75
+ end
76
+ end
77
+ end
78
+ return bodies
79
+ end
80
+ [body]
81
+ end
82
+
83
+ def report(res, index)
84
+ @index_before = index
85
+ @res_before = [] + res
86
+ @index_medium = index
87
+ @res_medium = [] + res
88
+
89
+ combinations = @step_key.split('.')
90
+ elements = YAML.dump(@source_json_schema).split("\n")[1..-1]
91
+
92
+ res_index = 0
93
+ element_index = 0
94
+ elements.each_with_index do |element, i|
95
+ if element.include?(combinations[element_index])
96
+ element_index += 1
97
+ end
98
+ if combinations.size == element_index
99
+ res_index = i
100
+ break
101
+ end
102
+ end
103
+ res[res_index + index] = @step_cover_size
104
+ @index_after = res_index + index
105
+ @res_after = [] + res
106
+ [res, index]
107
+ end
108
+ end
109
+ end
110
+ end
@@ -0,0 +1,61 @@
1
+ require 'fitting/doc/combination_step'
2
+ require 'fitting/cover/json_schema_enum'
3
+ require 'fitting/doc/combination_enum'
4
+ require 'fitting/cover/json_schema'
5
+ require 'fitting/doc/combination_optional'
6
+
7
+ module Fitting
8
+ class Doc
9
+ class CombinationOneOf < CombinationStep
10
+ def initialize_combinations(combination, json_schema)
11
+ combinations = Fitting::Cover::JSONSchemaEnum.new(@json_schema).combi
12
+ if combinations.size > 1
13
+ combinations.each do |comb|
14
+ @next_steps.push(CombinationEnum.new(comb[0], "#{comb[1][0]}", "#{comb[1][1]}", json_schema))
15
+ end
16
+ end
17
+
18
+ combinations = Fitting::Cover::JSONSchema.new(@json_schema).combi
19
+ combinations.each do |comb|
20
+ @next_steps.push(CombinationOptional.new(comb[0], "#{type}.#{comb[1][0]}", "#{combination}.#{comb[1][1]}", json_schema))
21
+ end
22
+ end
23
+
24
+ def cover!(log)
25
+ if JSON::Validator.fully_validate(@json_schema, log.body) == []
26
+ @step_cover_size += 1
27
+ @logs.push(log.body)
28
+ errors = @next_steps.inject([]) do |sum, combination|
29
+ sum.push(combination.cover!(log))
30
+ end.flatten.compact
31
+
32
+ return if @next_steps.size == 0
33
+ return unless @next_steps.size == errors.size
34
+
35
+ error_message = ""
36
+ errors.each do |error|
37
+ error_message += "combination: #{error[:combination]}\n"\
38
+ "combination type: #{error[:type]}\n"\
39
+ "combination json-schema: #{::JSON.pretty_generate(error[:json_schema])}\n"\
40
+ "combination error #{::JSON.pretty_generate(error[:error])}\n"\
41
+ "combination body #{::JSON.pretty_generate(error[:body])}\n"
42
+ end
43
+
44
+ # raise NotFound.new "#{error_message}\n"\
45
+ # "source body: #{::JSON.pretty_generate(log.body)}"
46
+ end
47
+ end
48
+
49
+ def mark_range(index, res)
50
+ res[index + 1] = @step_cover_size
51
+ if @json_schema && @json_schema["required"]
52
+ mark_required(index + 1, res, @json_schema)
53
+ end
54
+ end
55
+
56
+ def index_offset
57
+ YAML.dump(@json_schema['properties']).split("\n").size + YAML.dump(@json_schema['required']).split("\n").size
58
+ end
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,54 @@
1
+ require 'fitting/doc/combination_step'
2
+ require 'fitting/cover/json_schema_enum'
3
+
4
+ module Fitting
5
+ class Doc
6
+ class CombinationOptional < CombinationStep
7
+ def cover!(log)
8
+ error = JSON::Validator.fully_validate(@json_schema, log.body)
9
+ if error == []
10
+ @step_cover_size += 1
11
+ @logs.push(log.body)
12
+ nil
13
+ end
14
+ end
15
+
16
+ def report(res, index)
17
+ @index_before = index
18
+ @res_before = [] + res
19
+ @index_medium = index
20
+ @res_medium = [] + res
21
+
22
+ combinations = @step_key.split('.')
23
+ elements = YAML.dump(@source_json_schema).split("\n")[1..-1]
24
+ res_index = 0
25
+ elements.each_with_index do |element, i|
26
+ if element.include?(combinations[-1])
27
+ res_index = i
28
+ break
29
+ end
30
+ end
31
+
32
+ res[res_index + index] = @step_cover_size
33
+ res[res_index + index + 1] = @step_cover_size
34
+
35
+ if @source_json_schema["properties"][combinations[-1]] && @source_json_schema["properties"][combinations[-1]].class == Hash && @source_json_schema["properties"][combinations[-1]]["type"] == "array"
36
+ res[res_index + index + 2] = @step_cover_size
37
+ res[res_index + index + 3] = @step_cover_size
38
+ res[res_index + index + 4] = @step_cover_size
39
+
40
+ schema = @source_json_schema["properties"][combinations[-1]]['items']
41
+ mark_required(res_index + index + 4, res, schema)
42
+ elsif @source_json_schema["properties"][combinations[-1]] && @source_json_schema["properties"][combinations[-1]].class == Hash && @source_json_schema["properties"][combinations[-1]]["type"] == "object"
43
+ schema = @source_json_schema["properties"][combinations[-1]]
44
+ res[res_index + index + 2] = @step_cover_size
45
+ mark_required(res_index + index + 2, res, schema)
46
+ end
47
+
48
+ @index_after = res_index + index + 4
49
+ @res_after = [] + res
50
+ [res, index]
51
+ end
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,48 @@
1
+ require 'fitting/doc/step'
2
+
3
+ module Fitting
4
+ class Doc
5
+ class CombinationStep < Step
6
+ class NotFound < RuntimeError; end
7
+
8
+ attr_accessor :json_schema, :type, :logs
9
+
10
+ def initialize(json_schema, type, combination, source_json_schema)
11
+ @logs = []
12
+ @step_cover_size = 0
13
+ @json_schema = json_schema
14
+ @next_steps = []
15
+ @type = type
16
+ @step_key = combination
17
+ @source_json_schema = source_json_schema
18
+ initialize_combinations(combination, json_schema)
19
+ end
20
+
21
+ def initialize_combinations(combination, json_schema)
22
+ end
23
+
24
+ def debug_report(index)
25
+ combinations = []
26
+ @next_steps.each do |next_step|
27
+ combinations.push(
28
+ next_step.debug_report(index)
29
+ )
30
+ end
31
+ return {} if index.nil? || index_before.nil?
32
+ {
33
+ "combination type" => @type,
34
+ "combination" => @step_key,
35
+ "json_schema" => @json_schema,
36
+ "valid_jsons" => @logs,
37
+ "index_before" => @index_before - index,
38
+ "index_medium" => @index_medium - index,
39
+ "index_after" => @index_after - index,
40
+ "res_before" => @res_before.map { |r| r ? r : "null" }[index..-1],
41
+ "res_medium" => @res_medium.map { |r| r ? r : "null" }[index..-1],
42
+ "res_after" => @res_after.map { |r| r ? r : "null" }[index..-1],
43
+ "combinations" => combinations
44
+ }
45
+ end
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,152 @@
1
+ require 'fitting/doc/step'
2
+ require 'fitting/doc/json_schema'
3
+
4
+ module Fitting
5
+ class Doc
6
+ class ContentType < Step
7
+ class NotFound < RuntimeError; end
8
+
9
+ def initialize(content_type, subvalue)
10
+ @logs = []
11
+ @step_key = content_type
12
+ @next_steps = []
13
+ @step_cover_size = 0
14
+ return self if content_type != 'application/json'
15
+
16
+ definitions = subvalue.inject({}) do |sum, sv|
17
+ if sv['body']["definitions"] != nil
18
+ sum.merge!(sv['body'].delete('definitions'))
19
+ end
20
+ sum
21
+ end
22
+
23
+ if subvalue.size == 1
24
+ if definitions && definitions != {}
25
+ res = merge_definitions(subvalue[0], definitions)
26
+ if res && res['properties']['type'] == 'object'
27
+ @next_steps.push(JsonSchema.new(
28
+ {
29
+ "$schema" => "http://json-schema.org/draft-04/schema#",
30
+ }.merge(res['properties']), false
31
+ ))
32
+ elsif res
33
+ @next_steps.push(JsonSchema.new(
34
+ {
35
+ "$schema" => "http://json-schema.org/draft-04/schema#",
36
+ "type" => "object"
37
+ }.merge(res), false
38
+ ))
39
+ else
40
+ @next_steps.push(JsonSchema.new({}, false))
41
+ end
42
+ else
43
+ @next_steps.push(JsonSchema.new(subvalue[0]['body'], false))
44
+ end
45
+ else
46
+ if definitions && definitions != {}
47
+ @next_steps.push(JsonSchema.new(
48
+ {
49
+ "$schema" => "http://json-schema.org/draft-04/schema#",
50
+ "type" => "object",
51
+ "oneOf" => subvalue.inject([]) do |sum, sv|
52
+ res = merge_definitions(sv, definitions)
53
+ sum.push(res)
54
+ end
55
+ }, false
56
+ ))
57
+ else
58
+ super_schema = false
59
+ subvalue.each do |sv|
60
+ super_schema = true if sv['body']["properties"] == nil
61
+ end
62
+
63
+ if super_schema
64
+ @next_steps.push(JsonSchema.new(
65
+ {
66
+ "$schema" => "http://json-schema.org/draft-04/schema#",
67
+ "type" => "object",
68
+ "oneOf" => subvalue.inject([]) do |sum, sv|
69
+ if sv['body']["properties"]
70
+ sum.push(check_body(sv['body']["properties"], sv))
71
+ end
72
+ sum
73
+ end
74
+ }, super_schema
75
+ ))
76
+ else
77
+ @next_steps.push(JsonSchema.new(
78
+ {
79
+ "$schema" => "http://json-schema.org/draft-04/schema#",
80
+ "type" => "object",
81
+ "oneOf" => subvalue.inject([]) do |sum, sv|
82
+ sum.push(check_body(sv['body']["properties"], sv))
83
+ end
84
+ }, super_schema
85
+ ))
86
+ super_schema
87
+ end
88
+ end
89
+ end
90
+ end
91
+
92
+ def cover!(log)
93
+ if @step_key == log.content_type && log.content_type == 'application/json'
94
+ @step_cover_size += 1
95
+ @logs.push(log.body)
96
+ @next_steps.each { |json_schema| json_schema.cover!(log) }
97
+ elsif @step_key != 'application/json' && log.content_type != 'application/json'
98
+ @step_cover_size += 1
99
+ end
100
+ rescue Fitting::Doc::JsonSchema::NotFound => e
101
+ raise NotFound.new "content-type: #{@step_key}\n\n"\
102
+ "#{e.message}"
103
+ end
104
+
105
+ def debug(debug)
106
+ return self if @step_key == debug.content_type && debug.content_type == 'application/json'
107
+ nil
108
+ end
109
+
110
+ def logs
111
+ @logs
112
+ end
113
+
114
+ def merge_definitions(sv, definitions)
115
+ if sv['body']["properties"]
116
+ res = sv['body']["properties"]
117
+ elsif sv['body']['type'] != 'array'
118
+ res = sv['body']
119
+ end
120
+ definitions.each_pair do |key, value|
121
+ while JSON.dump(res).include?("\"$ref\":\"#/definitions/#{key}\"") do
122
+ new_res_array = JSON.dump(res).split('{')
123
+ index = new_res_array.index { |js| js.include?("\"$ref\":\"#/definitions/#{key}\"") }
124
+ if index != nil
125
+ def_size = "\"$ref\":\"#/definitions/#{key}\"".size
126
+ new_res_array[index] = JSON.dump(value)[1..-2] + new_res_array[index][def_size..-1]
127
+ res = JSON.load(new_res_array.join("{"))
128
+ end
129
+ end
130
+ end
131
+ if res == nil
132
+ nil
133
+ else
134
+ check_body(res, sv)
135
+ end
136
+ end
137
+
138
+ def check_body(res, sv)
139
+ if sv['body']["required"] == nil
140
+ {
141
+ "properties" => res
142
+ }
143
+ else
144
+ {
145
+ "properties" => res,
146
+ "required" => sv['body']["required"]
147
+ }
148
+ end
149
+ end
150
+ end
151
+ end
152
+ end