fitting 2.18.1 → 3.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (65) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +2 -11
  3. data/CHANGELOG.md +21 -0
  4. data/README.md +46 -6
  5. data/fitting.gemspec +3 -1
  6. data/lib/fitting/configuration.rb +11 -41
  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/console.rb +32 -12
  17. data/lib/fitting/report/prefix.rb +20 -41
  18. data/lib/fitting/report/prefixes.rb +7 -8
  19. data/lib/fitting/report/response.rb +0 -3
  20. data/lib/fitting/report/tests.rb +23 -10
  21. data/lib/fitting/storage/responses.rb +5 -9
  22. data/lib/fitting/tests.rb +12 -4
  23. data/lib/fitting/version.rb +1 -1
  24. data/lib/fitting.rb +38 -43
  25. data/lib/tasks/fitting.rake +3 -186
  26. data/lib/tasks/fitting_outgoing.rake +91 -0
  27. metadata +28 -45
  28. data/lib/fitting/configuration/legacy.rb +0 -61
  29. data/lib/fitting/configuration/yaml.rb +0 -89
  30. data/lib/fitting/cover/response.rb +0 -37
  31. data/lib/fitting/documentation.rb +0 -56
  32. data/lib/fitting/matchers/response_matcher.rb +0 -96
  33. data/lib/fitting/records/realized_unit.rb +0 -52
  34. data/lib/fitting/records/test_unit/request.rb +0 -98
  35. data/lib/fitting/records/unit/combination.rb +0 -27
  36. data/lib/fitting/records/unit/json_schema.rb +0 -111
  37. data/lib/fitting/records/unit/request.rb +0 -37
  38. data/lib/fitting/records/unit/response.rb +0 -32
  39. data/lib/fitting/request.rb +0 -38
  40. data/lib/fitting/response/fully_validates.rb +0 -34
  41. data/lib/fitting/response.rb +0 -88
  42. data/lib/fitting/statistics/analysis.rb +0 -25
  43. data/lib/fitting/statistics/cover_error.rb +0 -29
  44. data/lib/fitting/statistics/cover_error_enum.rb +0 -29
  45. data/lib/fitting/statistics/cover_error_one_of.rb +0 -29
  46. data/lib/fitting/statistics/great.rb +0 -13
  47. data/lib/fitting/statistics/list.rb +0 -55
  48. data/lib/fitting/statistics/lists.rb +0 -53
  49. data/lib/fitting/statistics/measurement.rb +0 -92
  50. data/lib/fitting/statistics/measurement_cover.rb +0 -92
  51. data/lib/fitting/statistics/measurement_cover_enum.rb +0 -92
  52. data/lib/fitting/statistics/measurement_cover_one_of.rb +0 -92
  53. data/lib/fitting/statistics/not_covered_responses.rb +0 -13
  54. data/lib/fitting/statistics/percent.rb +0 -20
  55. data/lib/fitting/statistics/requests_stats.rb +0 -40
  56. data/lib/fitting/statistics/responses_stats.rb +0 -32
  57. data/lib/fitting/statistics/template.rb +0 -117
  58. data/lib/fitting/statistics/template_cover_error.rb +0 -50
  59. data/lib/fitting/statistics/template_cover_error_enum.rb +0 -50
  60. data/lib/fitting/statistics/template_cover_error_one_of.rb +0 -50
  61. data/lib/fitting/statistics.rb +0 -25
  62. data/lib/fitting/storage/white_list.rb +0 -158
  63. data/lib/fitting/templates/realized_template.rb +0 -49
  64. data/lib/fitting/view/report.html.haml +0 -16
  65. data/lib/fitting/view/style.css +0 -47
@@ -3,13 +3,26 @@ require 'fitting/report/test'
3
3
  module Fitting
4
4
  module Report
5
5
  class Tests
6
+ attr_reader :tests
7
+
6
8
  def initialize(tests)
7
9
  @tests = tests
8
10
  end
9
11
 
10
- def self.new_from_config(tests_path)
12
+ def self.new_from_config
13
+ tests = []
14
+ Dir["#{Fitting.configuration.rspec_json_path}/*.json"].each do |file|
15
+ JSON.parse(File.read(file)).map do |test|
16
+ tests.push(Fitting::Report::Test.new(test))
17
+ end
18
+ end
19
+ tests.sort { |a, b| b.path <=> a.path }
20
+ new(tests)
21
+ end
22
+
23
+ def self.new_from_outgoing_config
11
24
  tests = []
12
- Dir[tests_path].each do |file|
25
+ Dir["#{Fitting.configuration.webmock_json_path}/*.json"].each do |file|
13
26
  JSON.parse(File.read(file)).map do |test|
14
27
  tests.push(Fitting::Report::Test.new(test))
15
28
  end
@@ -19,45 +32,45 @@ module Fitting
19
32
  end
20
33
 
21
34
  def without_prefixes
22
- @tests.each_with_object([]) do |test, result|
35
+ tests.each_with_object([]) do |test, result|
23
36
  result.push(test.path) unless test.there_a_prefix?
24
37
  end
25
38
  end
26
39
 
27
40
  def without_actions
28
- @tests.each_with_object([]) do |test, result|
41
+ tests.each_with_object([]) do |test, result|
29
42
  result.push("#{test.method} #{test.path}") unless test.there_an_actions?
30
43
  end
31
44
  end
32
45
 
33
46
  def without_responses
34
- @tests.each_with_object([]) do |test, result|
47
+ tests.each_with_object([]) do |test, result|
35
48
  result.push(test.id) unless test.there_an_responses?
36
49
  end
37
50
  end
38
51
 
39
52
  def without_combinations
40
- @tests.each_with_object([]) do |test, result|
53
+ tests.each_with_object([]) do |test, result|
41
54
  result.push(test.path) unless test.there_an_combinations?
42
55
  end
43
56
  end
44
57
 
45
58
  def push(test)
46
- @tests.push(test)
59
+ tests.push(test)
47
60
  end
48
61
 
49
62
  def size
50
- @tests.size
63
+ tests.size
51
64
  end
52
65
 
53
66
  def to_a
54
- @tests
67
+ tests
55
68
  end
56
69
 
57
70
  def to_h
58
71
  return @hash if @hash
59
72
 
60
- @hash = @tests.inject({}) do |res, test|
73
+ @hash = tests.inject({}) do |res, test|
61
74
  res.merge!(test.id => test.to_h)
62
75
  end
63
76
  end
@@ -1,24 +1,20 @@
1
- require 'fitting/statistics'
2
- require 'fitting/tests'
3
1
  require 'fitting/records/tested/request'
4
2
 
5
3
  module Fitting
6
4
  module Storage
7
5
  class Responses
6
+ attr_reader :tested_requests
7
+
8
8
  def initialize
9
9
  @tested_requests = []
10
10
  end
11
11
 
12
- def add(env_response, metadata = {})
13
- @tested_requests.push(Fitting::Records::Tested::Request.new(env_response, metadata))
14
- end
15
-
16
- def statistics
17
- Fitting::Statistics.new(@tested_requests)
12
+ def add(response, example)
13
+ tested_requests.push(Fitting::Records::Tested::Request.new(response, example))
18
14
  end
19
15
 
20
16
  def tests
21
- Fitting::Tests.new(@tested_requests)
17
+ Fitting::Tests.new(tested_requests)
22
18
  end
23
19
  end
24
20
  end
data/lib/fitting/tests.rb CHANGED
@@ -1,5 +1,3 @@
1
- require 'fitting/statistics/template'
2
-
3
1
  module Fitting
4
2
  class Tests
5
3
  def initialize(tested_requests)
@@ -7,13 +5,23 @@ module Fitting
7
5
  end
8
6
 
9
7
  def save
10
- make_dir('fitting_tests')
8
+ make_dir(Fitting.configuration.rspec_json_path)
9
+ array = @tested_requests.inject([]) do |res, request|
10
+ res.push(request.to_spherical.to_hash)
11
+ end
12
+ json = JSON.dump(array)
13
+
14
+ File.open("#{Fitting.configuration.rspec_json_path}/test#{ENV['TEST_ENV_NUMBER']}.json", 'w') { |file| file.write(json) }
15
+ end
16
+
17
+ def outgoing_save
18
+ make_dir('./outgoing_request_tests')
11
19
  array = @tested_requests.inject([]) do |res, request|
12
20
  res.push(request.to_spherical.to_hash)
13
21
  end
14
22
  json = JSON.dump(array)
15
23
 
16
- File.open("fitting_tests/test#{ENV['TEST_ENV_NUMBER']}.json", 'w') { |file| file.write(json) }
24
+ File.open("./outgoing_request_tests/test#{ENV['TEST_ENV_NUMBER']}.json", 'w') { |file| file.write(json) }
17
25
  end
18
26
 
19
27
  def make_dir(dir_name)
@@ -1,3 +1,3 @@
1
1
  module Fitting
2
- VERSION = '2.18.1'.freeze
2
+ VERSION = '3.0.1'.freeze
3
3
  end
data/lib/fitting.rb CHANGED
@@ -1,73 +1,68 @@
1
1
  require 'fitting/version'
2
2
  require 'fitting/configuration'
3
- require 'fitting/matchers/response_matcher'
4
- require 'fitting/documentation'
3
+
5
4
  require 'fitting/storage/responses'
5
+ require 'fitting/tests'
6
+ require 'fitting/cover/json_schema_enum'
7
+ require 'fitting/cover/json_schema_one_of'
8
+ require 'fitting/records/documented/request'
6
9
  require 'fitting/railtie' if defined?(Rails)
7
10
 
8
11
  module Fitting
9
12
  class << self
10
- def configure
11
- yield configuration
12
- end
13
-
14
13
  def configuration
15
- @configuration ||= Configuration.craft
14
+ yaml = YAML.safe_load(File.read('.fitting.yml'))
15
+ @configuration ||= Configuration.new(yaml)
16
16
  end
17
17
 
18
- def statistics
19
- responses = Fitting::Storage::Responses.new
20
-
21
- RSpec.configure do |config|
22
- config.after(:each, type: :controller) do
23
- responses.add(response, inspect)
24
- end
25
-
26
- config.after(:suite) do
27
- responses.statistics.save
28
- end
29
- end
18
+ def configure
19
+ yield(configuration)
30
20
  end
31
21
 
32
- extend Gem::Deprecate
33
- deprecate :statistics, :save_test_data, 2022, 1
22
+ def clear_tests_directory
23
+ FileUtils.rm_r Dir.glob(configuration.rspec_json_path), force: true
24
+ FileUtils.rm_r Dir.glob(configuration.webmock_json_path), force: true
25
+ end
34
26
 
35
27
  def save_test_data
36
- responses = Fitting::Storage::Responses.new
28
+ clear_tests_directory
37
29
 
38
- FileUtils.rm_r Dir.glob('fitting_tests/*'), force: true
30
+ outgoing_responses = Fitting::Storage::Responses.new
31
+ responses = Fitting::Storage::Responses.new
39
32
 
40
33
  RSpec.configure do |config|
34
+ if defined?(WebMock)
35
+ config.before(:each) do |example|
36
+ WebMock.after_request do |request_signature, response|
37
+ env = Rack::MockRequest.env_for(request_signature.uri, { method: request_signature.method })
38
+ # Парсим в тот формат с которым работает fitting
39
+ mock_request = ActionDispatch::Request.new(env)
40
+ mock_response = ActionDispatch::Response.create(response.status.first || 200, response.headers || {},
41
+ response.body || {})
42
+ mock_response.instance_variable_set(:@request, mock_request)
43
+
44
+ outgoing_responses.add(mock_response, example)
45
+ end
46
+ end
47
+ end
48
+
41
49
  config.after(:each, type: :request) do |example|
42
- responses.add(response, example.metadata)
50
+ responses.add(response, example)
43
51
  end
44
52
 
45
53
  config.after(:each, type: :controller) do |example|
46
- responses.add(response, example.metadata)
54
+ responses.add(response, example)
55
+ end
56
+
57
+ config.after(:each) do
58
+ WebMock::CallbackRegistry.reset
47
59
  end
48
60
 
49
61
  config.after(:suite) do
50
62
  responses.tests.save
63
+ outgoing_responses.tests.outgoing_save
51
64
  end
52
65
  end
53
66
  end
54
67
  end
55
-
56
- def self.loaded_tasks=(val)
57
- @loaded_tasks = val
58
- end
59
-
60
- def self.loaded_tasks
61
- @loaded_tasks
62
- end
63
-
64
- def self.load_tasks
65
- return if loaded_tasks
66
-
67
- self.loaded_tasks = true
68
-
69
- Dir[File.join(File.dirname(__FILE__), 'tasks', '**/*.rake')].each do |rake|
70
- load rake
71
- end
72
- end
73
68
  end
@@ -1,10 +1,4 @@
1
1
  require 'fitting/records/spherical/requests'
2
- require 'fitting/configuration'
3
- require 'fitting/records/realized_unit'
4
- require 'fitting/templates/realized_template'
5
- require 'fitting/statistics/template_cover_error'
6
- require 'fitting/statistics/template_cover_error_enum'
7
- require 'fitting/statistics/template_cover_error_one_of'
8
2
  require 'fitting/cover/json_schema'
9
3
  require 'fitting/report/prefixes'
10
4
  require 'fitting/report/tests'
@@ -12,8 +6,8 @@ require 'fitting/report/console'
12
6
 
13
7
  namespace :fitting do
14
8
  task :report do
15
- tests = Fitting::Report::Tests.new_from_config('fitting_tests/*.json')
16
- prefixes = Fitting::Report::Prefixes.new('.fitting.yml')
9
+ tests = Fitting::Report::Tests.new_from_config
10
+ prefixes = Fitting::Report::Prefixes.new(Fitting.configuration.prefixes)
17
11
 
18
12
  prefixes.join(tests)
19
13
 
@@ -88,187 +82,10 @@ namespace :fitting do
88
82
  )
89
83
 
90
84
  puts console.output
85
+ puts console.output_sum
91
86
 
92
87
  exit 1 unless console.good?
93
88
 
94
89
  exit 0
95
-
96
- actions.map do |action|
97
- action.to_hash['responses'].map do |response|
98
- response['combination'] ||= []
99
- combinations = Fitting::Cover::JSONSchema.new(response['body']).combi +
100
- Fitting::Cover::JSONSchemaEnum.new(response['body']).combi +
101
- Fitting::Cover::JSONSchemaOneOf.new(response['body']).combi
102
- next unless combinations != []
103
-
104
- combinations.map do |combination|
105
- response['combination'].push(
106
- {
107
- 'json_schema' => combination[0],
108
- 'type' => combination[1][0],
109
- 'combination' => combination[1][1],
110
- 'tests' => [],
111
- 'error' => []
112
- }
113
- )
114
- end
115
- end
116
- end
117
-
118
- actions.map do |action|
119
- action.to_hash['responses'].map do |response|
120
- response['tests'] ||= []
121
- response['tests'].map do |test|
122
- next unless response['combination'][0]
123
-
124
- response['combination'].map do |combination|
125
- res = JSON::Validator.fully_validate(combination['json_schema'], test['response']['body'])
126
- if res == []
127
- combination['tests'].push(test)
128
- response['tests'] = response['tests'] - [test]
129
- next
130
- else
131
- combination['error'].push({ test: test, error: res })
132
- end
133
- rescue JSON::Schema::SchemaError => e
134
- combination['error'].push({ test: test, error: e })
135
- end
136
- end
137
- end
138
- end
139
-
140
- actions_test = { actions: actions, tests: tests }
141
-
142
- makedirs('fitting')
143
- File.open('fitting/old_report.json', 'w') { |file| file.write(JSON.dump(actions_test)) }
144
- end
145
-
146
- # deprecated
147
- desc 'Fitting documentation'
148
- task :documentation do
149
- documented_unit = Fitting::Statistics::Template.new(
150
- Fitting::Records::Spherical::Requests.new,
151
- Fitting.configuration
152
- )
153
- puts documented_unit.stats
154
-
155
- unless documented_unit.not_covered == "\n"
156
- puts 'Not all responses from the whitelist are covered!'
157
- exit 1
158
- end
159
- end
160
-
161
- desc 'Fitting documentation responses cover'
162
- task :documentation_responses, [:size] => :environment do |_, args|
163
- case args.size
164
- when 'xs'
165
- documented_unit = Fitting::Statistics::Template.new(
166
- Fitting::Records::Spherical::Requests.new,
167
- Fitting.configuration
168
- )
169
- puts documented_unit.stats
170
-
171
- unless documented_unit.not_covered == "\n"
172
- puts 'Not all responses from the whitelist are covered!'
173
- exit 1
174
- end
175
- when 's'
176
- documented_unit = Fitting::Statistics::Template.new(
177
- Fitting::Records::Spherical::Requests.new,
178
- Fitting.configuration,
179
- 'cover'
180
- )
181
- puts documented_unit.stats
182
-
183
- unless documented_unit.not_covered == "\n"
184
- puts 'Not all responses from the whitelist are covered!'
185
- exit 1
186
- end
187
- when 'm'
188
- documented_unit = Fitting::Statistics::Template.new(
189
- Fitting::Records::Spherical::Requests.new,
190
- Fitting.configuration,
191
- 'cover_enum'
192
- )
193
- puts documented_unit.stats
194
-
195
- unless documented_unit.not_covered == "\n"
196
- puts 'Not all responses from the whitelist are covered!'
197
- exit 1
198
- end
199
- when 'l'
200
- documented_unit = Fitting::Statistics::Template.new(
201
- Fitting::Records::Spherical::Requests.new,
202
- Fitting.configuration,
203
- 'cover_one_of'
204
- )
205
- puts documented_unit.stats
206
-
207
- unless documented_unit.not_covered == "\n"
208
- puts 'Not all responses from the whitelist are covered!'
209
- exit 1
210
- end
211
- else
212
- puts 'need key xs, s, m or l'
213
- end
214
- end
215
-
216
- desc 'Fitting documentation responses cover error'
217
- task :documentation_responses_error, [:size] => :environment do |_, args|
218
- case args.size
219
- when 's'
220
- documented_unit = Fitting::Statistics::TemplateCoverError.new(
221
- Fitting::Records::Spherical::Requests.new,
222
- Fitting.configuration
223
- )
224
- puts documented_unit.stats
225
- when 'm'
226
- documented_unit = Fitting::Statistics::TemplateCoverErrorEnum.new(
227
- Fitting::Records::Spherical::Requests.new,
228
- Fitting.configuration
229
- )
230
- puts documented_unit.stats
231
- when 'l'
232
- documented_unit = Fitting::Statistics::TemplateCoverErrorOneOf.new(
233
- Fitting::Records::Spherical::Requests.new,
234
- Fitting.configuration
235
- )
236
- puts documented_unit.stats
237
- else
238
- puts 'need key s, m or l'
239
- end
240
- end
241
-
242
- # deprecated
243
- desc 'Fitting tests'
244
- task :tests do
245
- realized_unit = Fitting::Records::RealizedUnit.new(
246
- Fitting::Records::Spherical::Requests.new,
247
- Fitting.configuration.tomogram
248
- )
249
- puts Fitting::Templates::RealizedTemplate.new(realized_unit).to_s
250
-
251
- unless realized_unit.fully_covered?
252
- puts 'Not all responses from the whitelist are covered!'
253
- exit 1
254
- end
255
- end
256
-
257
- desc 'Fitting tests'
258
- task :tests_responses, [:size] => :environment do |_, args|
259
- if args.size == 'xs'
260
- realized_unit = Fitting::Records::RealizedUnit.new(
261
- Fitting::Records::Spherical::Requests.new,
262
- Fitting.configuration.tomogram
263
- )
264
- puts Fitting::Templates::RealizedTemplate.new(realized_unit).to_s
265
-
266
- unless realized_unit.fully_covered?
267
- puts 'Not all responses from the whitelist are covered!'
268
- exit 1
269
- end
270
- else
271
- puts 'need key xs'
272
- end
273
90
  end
274
91
  end
@@ -0,0 +1,91 @@
1
+ require 'fitting/records/spherical/requests'
2
+ require 'fitting/cover/json_schema'
3
+ require 'fitting/report/prefixes'
4
+ require 'fitting/report/tests'
5
+ require 'fitting/report/console'
6
+
7
+ namespace :fitting_out do
8
+ task :report do
9
+ tests = Fitting::Report::Tests.new_from_outgoing_config
10
+ prefixes = Fitting::Report::Prefixes.new(Fitting.configuration.outgoing_prefixes)
11
+
12
+ prefixes.join(tests)
13
+
14
+ prefixes.to_a.map do |prefix|
15
+ prefix.actions.join(prefix.tests) unless prefix.skip?
16
+ end
17
+
18
+ prefixes.to_a.map do |prefix|
19
+ next if prefix.skip?
20
+
21
+ prefix.actions.to_a.map do |action|
22
+ action.responses.join(action.tests)
23
+ end
24
+ end
25
+
26
+ prefixes.to_a.map do |prefix|
27
+ next if prefix.skip?
28
+
29
+ prefix.actions.to_a.map do |action|
30
+ action.responses.to_a.map do |response|
31
+ response.combinations.join(response.tests)
32
+ end
33
+ end
34
+ end
35
+
36
+ report = JSON.pretty_generate(
37
+ {
38
+ tests_without_prefixes: tests.without_prefixes,
39
+ prefixes_details: prefixes.to_a.map(&:details)
40
+ }
41
+ )
42
+
43
+ destination = 'fitting'
44
+ FileUtils.mkdir_p(destination)
45
+ FileUtils.rm_r Dir.glob("#{destination}/*"), force: true
46
+ File.open('fitting/report.json', 'w') { |file| file.write(report) }
47
+
48
+ gem_path = $LOAD_PATH.find { |i| i.include?('fitting') }
49
+ source_path = "#{gem_path}/templates/bomboniere/dist"
50
+ FileUtils.copy_entry source_path, destination
51
+
52
+ json_schemas = {}
53
+ combinations = {}
54
+ prefixes.to_a.map do |prefix|
55
+ next if prefix.skip?
56
+
57
+ prefix.actions.to_a.map do |action|
58
+ action.responses.to_a.map do |response|
59
+ json_schemas[response.id] = response.body
60
+ response.combinations.to_a.map do |combination|
61
+ combinations.merge!(combination.id => combination.json_schema)
62
+ end
63
+ end
64
+ end
65
+ end
66
+ File.open('fitting/json_schemas.json', 'w') { |file| file.write(JSON.pretty_generate(json_schemas)) }
67
+ File.open('fitting/combinations.json', 'w') { |file| file.write(JSON.pretty_generate(combinations)) }
68
+ File.open('fitting/tests.json', 'w') { |file| file.write(JSON.pretty_generate(tests.to_h)) }
69
+
70
+ js_path = Dir["#{destination}/js/*"].find { |f| f[0..14] == 'fitting/js/app.' and f[-3..] == '.js' }
71
+ js_file = File.read(js_path)
72
+ new_js_file = js_file.gsub('{stub:"prefixes report"}', report)
73
+ new_js_file = new_js_file.gsub('{stub:"for action page"}', report)
74
+ new_js_file = new_js_file.gsub('{stub:"json-schemas"}', JSON.pretty_generate(json_schemas))
75
+ new_js_file = new_js_file.gsub('{stub:"combinations"}', JSON.pretty_generate(combinations))
76
+ new_js_file = new_js_file.gsub('{stub:"tests"}', JSON.pretty_generate(tests.to_h))
77
+ File.open(js_path, 'w') { |file| file.write(new_js_file) }
78
+
79
+ console = Fitting::Report::Console.new(
80
+ tests.without_prefixes,
81
+ prefixes.to_a.map(&:details)
82
+ )
83
+
84
+ puts console.output
85
+ puts console.output_sum
86
+
87
+ exit 1 unless console.good?
88
+
89
+ exit 0
90
+ end
91
+ end