fitting 3.0.2 → 4.0.0

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