much-rails 0.3.0 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ba7d46f07c2592e152fe836a0cff5a7bf8061e9f531aac1c6a748f1365cc383b
4
- data.tar.gz: 19e41c6e470a0021b6b78ea9c7eff7e6e530758d0522a591b4f8623b610f9fa2
3
+ metadata.gz: 06a9727075cd562255a4af1a8d1a37f542cda97dae2180389d6c16446ad545a9
4
+ data.tar.gz: 750e9cb46067e57fbbc4bdf46181e3cf274c1a9e6eacfb04ee702cfd8268d4ff
5
5
  SHA512:
6
- metadata.gz: 37bdf6aa9a624f270cd53e5ba22f3e400f331b9b91c29aed2c6169627350f9c49e2f929ff6b9bc83665c789953559f67f546c11fd4cc9660814b46f61bfb2bb9
7
- data.tar.gz: eb78925cf707aef2f6484665963da6dee38f495cad04de680f7ea349292eae41b77bdd36f014b05a2e5fcda48e8c8d03b23485f60786020100794f4d1cb3c15f
6
+ metadata.gz: 8a3e8f4bd80630a89fbca5bd1a88ccf83f7e99c957f81ce7c16255164cb08af8dc404e6cc2f319aba35dfe9acb9f63c91650fbbde814cb7576ecbfcce07f3295
7
+ data.tar.gz: 41884fcc5e7671a4fd3faa79cef4297ececfbcc6d5ad5c3fd79e8979950dbd413ebc9b984bda7350f199585b5619878b1e7158361f96283b77fd21f8b4b1d749
data/lib/much-rails.rb CHANGED
@@ -18,6 +18,7 @@ require "much-rails/destroy_action"
18
18
  require "much-rails/destroy_service"
19
19
  require "much-rails/has_slug"
20
20
  require "much-rails/input_value"
21
+ require "much-rails/invalid_error"
21
22
  require "much-rails/json"
22
23
  require "much-rails/layout"
23
24
  require "much-rails/not_given"
@@ -115,7 +115,7 @@ module MuchRails::Action
115
115
  def initialize(params: nil, request: nil)
116
116
  @params = params.to_h.with_indifferent_access
117
117
  @request = request
118
- @errors = Hash.new{ |hash, key| hash[key] = [] }
118
+ @errors = HashWithIndifferentAccess.new{ |hash, key| hash[key] = [] }
119
119
  end
120
120
 
121
121
  def on_call
@@ -40,7 +40,7 @@ class MuchRails::ChangeActionResult
40
40
  end
41
41
 
42
42
  def extract_validation_error(field_name)
43
- validation_errors.delete(field_name)
43
+ Array.wrap(validation_errors.delete(field_name)).compact
44
44
  end
45
45
 
46
46
  def any_unextracted_validation_errors?
@@ -1,10 +1,12 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "much-rails/invalid_error"
3
4
  require "much-rails/mixin"
4
5
  require "much-rails/records"
5
6
  require "much-rails/records/validate_destroy"
6
7
  require "much-rails/result"
7
8
  require "much-rails/service"
9
+ require "much-rails/service_validation_errors"
8
10
 
9
11
  module MuchRails; end
10
12
 
@@ -51,6 +53,13 @@ module MuchRails::DestroyService
51
53
  validation_error_messages: ex.error_full_messages.to_a,
52
54
  )
53
55
  end
56
+ e.add(MuchRails::InvalidError) do |ex|
57
+ MuchRails::SaveService::FailureResult.new(
58
+ exception: ex,
59
+ validation_errors: ex.errors,
60
+ validation_error_messages: ex.error_messages,
61
+ )
62
+ end
54
63
  end
55
64
  end
56
65
  end
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ module MuchRails; end
4
+
5
+ # MuchRails::InvalidError allows for raising and auto-rescueing general
6
+ # validation errors outside the scope of e.g. an ActiveRecord save.
7
+ class MuchRails::InvalidError < StandardError
8
+ attr_reader :errors
9
+
10
+ def initialize(backtrace: nil, **errors)
11
+ @errors = errors
12
+
13
+ super(@errors.inspect)
14
+ set_backtrace(backtrace) if backtrace
15
+ end
16
+
17
+ def error_messages
18
+ @errors.to_a.map do |(field_name, message)|
19
+ "#{field_name}: #{Array.wrap(message).to_sentence}"
20
+ end
21
+ end
22
+ end
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "active_record"
4
+ require "much-rails/invalid_error"
4
5
  require "much-rails/mixin"
5
6
  require "much-rails/result"
6
7
  require "much-rails/service"
@@ -52,6 +53,13 @@ module MuchRails::SaveService
52
53
  ex.record&.errors&.full_messages.to_a,
53
54
  )
54
55
  end
56
+ e.add(MuchRails::InvalidError) do |ex|
57
+ MuchRails::SaveService::FailureResult.new(
58
+ exception: ex,
59
+ validation_errors: ex.errors,
60
+ validation_error_messages: ex.error_messages,
61
+ )
62
+ end
55
63
  end
56
64
  end
57
65
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module MuchRails
4
- VERSION = "0.3.0"
4
+ VERSION = "0.4.0"
5
5
  end
@@ -199,7 +199,7 @@ module MuchRails::Action
199
199
  end
200
200
 
201
201
  if params[:fail_custom_validation]
202
- errors[:custom_validation] << "ERROR1"
202
+ errors["custom_validation"] << "ERROR1"
203
203
  end
204
204
  end
205
205
 
@@ -64,10 +64,14 @@ class MuchRails::ChangeActionResult
64
64
  class ValidationMethodsTests < UnitTests
65
65
  desc "validation methods"
66
66
  subject do
67
- unit_class.failure(validation_errors: {
68
- name: ["NAME ERROR"],
69
- other: ["OTHER ERROR"],
70
- })
67
+ unit_class.failure(
68
+ validation_errors: {
69
+ name: ["NAME ERROR"],
70
+ other: ["OTHER ERROR"],
71
+ empty: [],
72
+ none: nil,
73
+ },
74
+ )
71
75
  end
72
76
 
73
77
  should "know its attributes" do
@@ -76,6 +80,8 @@ class MuchRails::ChangeActionResult
76
80
  .equals({
77
81
  name: ["NAME ERROR"],
78
82
  other: ["OTHER ERROR"],
83
+ empty: [],
84
+ none: [nil],
79
85
  })
80
86
 
81
87
  # validation_error_messages
@@ -90,6 +96,12 @@ class MuchRails::ChangeActionResult
90
96
  .equals(["NAME ERROR"])
91
97
  assert_that(subject.extract_validation_error(:other))
92
98
  .equals(["OTHER ERROR"])
99
+ assert_that(subject.extract_validation_error(:empty))
100
+ .equals([])
101
+ assert_that(subject.extract_validation_error(:none))
102
+ .equals([])
103
+ assert_that(subject.extract_validation_error(:unknown))
104
+ .equals([])
93
105
  assert_that(subject.validation_errors).is_empty
94
106
 
95
107
  # any_unextracted_validation_errors?
@@ -73,6 +73,7 @@ module MuchRails::DestroyService
73
73
  RuntimeError.new(Factory.string),
74
74
  ArgumentError.new(Factory.string),
75
75
  MuchRails::Records::DestructionInvalid.new(FakeRecord.new),
76
+ MuchRails::InvalidError.new,
76
77
  ]
77
78
  end
78
79
  let(:exception_classes){ exceptions.map(&:class) }
@@ -102,6 +103,8 @@ module MuchRails::DestroyService
102
103
  .is_an_instance_of(MuchRails::ServiceValidationErrors)
103
104
  assert_that(subject.service_validation_errors.exception_classes)
104
105
  .includes(MuchRails::Records::DestructionInvalid)
106
+ assert_that(subject.service_validation_errors.exception_classes)
107
+ .includes(MuchRails::InvalidError)
105
108
  end
106
109
  end
107
110
 
@@ -185,6 +188,22 @@ module MuchRails::DestroyService
185
188
  end
186
189
  end
187
190
 
191
+ class ValidationErrorsResultForInvalidErrorTests < ValidationErrorsTests
192
+ desc "when .result_for is passed an MuchRails::InvalidError"
193
+
194
+ let(:exception){ MuchRails::InvalidError.new }
195
+
196
+ should "return a failure result with the record and validation errors" do
197
+ result = subject.result_for(exception)
198
+
199
+ assert_that(result.failure?).is_true
200
+ assert_that(result.exception).equals(exception)
201
+ assert_that(result.validation_errors).equals(exception.errors)
202
+ assert_that(result.validation_error_messages)
203
+ .equals(exception.error_messages)
204
+ end
205
+ end
206
+
188
207
  class FailureResultTests < UnitTests
189
208
  desc "FailureResult"
190
209
  subject{ unit_class::FailureResult }
@@ -0,0 +1,45 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "assert"
4
+ require "much-rails/invalid_error"
5
+
6
+ class MuchRails::InvalidError
7
+ class UnitTests < Assert::Context
8
+ desc "MuchRails::InvalidError"
9
+ subject{ unit_class }
10
+
11
+ let(:unit_class){ MuchRails::InvalidError }
12
+
13
+ should "be configured as expected" do
14
+ assert_that(subject < StandardError).is_true
15
+ end
16
+ end
17
+
18
+ class InitSetupTests < UnitTests
19
+ desc "when init"
20
+ subject{ unit_class.new }
21
+
22
+ should have_readers :errors
23
+ should have_imeths :error_messages
24
+
25
+ should "know its attributes" do
26
+ assert_that(subject.backtrace).is_nil
27
+ assert_that(subject.errors).equals({})
28
+ assert_that(subject.message).equals(subject.errors.inspect)
29
+ assert_that(subject.error_messages).equals([])
30
+
31
+ backtrace = Array.new(Factory.integer(3)){ Factory.path }
32
+ errors =
33
+ {
34
+ field1: ["ERROR 1A", "ERROR 2B"],
35
+ field2: "ERROR 2A",
36
+ }
37
+ exception = unit_class.new(backtrace: backtrace, **errors)
38
+ assert_that(exception.backtrace).equals(backtrace)
39
+ assert_that(exception.errors).equals(errors)
40
+ assert_that(exception.message).equals(exception.errors.inspect)
41
+ assert_that(exception.error_messages)
42
+ .equals(["field1: ERROR 1A and ERROR 2B", "field2: ERROR 2A"])
43
+ end
44
+ end
45
+ end
@@ -73,6 +73,7 @@ module MuchRails::SaveService
73
73
  RuntimeError.new(Factory.string),
74
74
  ArgumentError.new(Factory.string),
75
75
  ActiveRecord::RecordInvalid.new(FakeRecord.new),
76
+ MuchRails::InvalidError.new,
76
77
  ]
77
78
  end
78
79
  let(:exception_classes){ exceptions.map(&:class) }
@@ -102,6 +103,8 @@ module MuchRails::SaveService
102
103
  .is_an_instance_of(MuchRails::ServiceValidationErrors)
103
104
  assert_that(subject.service_validation_errors.exception_classes)
104
105
  .includes(ActiveRecord::RecordInvalid)
106
+ assert_that(subject.service_validation_errors.exception_classes)
107
+ .includes(MuchRails::InvalidError)
105
108
  end
106
109
  end
107
110
 
@@ -197,6 +200,22 @@ module MuchRails::SaveService
197
200
  end
198
201
  end
199
202
 
203
+ class ValidationErrorsResultForInvalidErrorTests < ValidationErrorsTests
204
+ desc "when .result_for is passed an MuchRails::InvalidError"
205
+
206
+ let(:exception){ MuchRails::InvalidError.new }
207
+
208
+ should "return a failure result with the record and validation errors" do
209
+ result = subject.result_for(exception)
210
+
211
+ assert_that(result.failure?).is_true
212
+ assert_that(result.exception).equals(exception)
213
+ assert_that(result.validation_errors).equals(exception.errors)
214
+ assert_that(result.validation_error_messages)
215
+ .equals(exception.error_messages)
216
+ end
217
+ end
218
+
200
219
  class FailureResultTests < UnitTests
201
220
  desc "FailureResult"
202
221
  subject{ unit_class::FailureResult }
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: much-rails
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kelly Redding
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2021-05-17 00:00:00.000000000 Z
12
+ date: 2021-05-20 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: much-style-guide
@@ -277,6 +277,7 @@ files:
277
277
  - lib/much-rails/destroy_service.rb
278
278
  - lib/much-rails/has_slug.rb
279
279
  - lib/much-rails/input_value.rb
280
+ - lib/much-rails/invalid_error.rb
280
281
  - lib/much-rails/json.rb
281
282
  - lib/much-rails/layout.rb
282
283
  - lib/much-rails/layout/helper.rb
@@ -333,6 +334,7 @@ files:
333
334
  - test/unit/destroy_service_tests.rb
334
335
  - test/unit/has_slug_tests.rb
335
336
  - test/unit/input_value_tests.rb
337
+ - test/unit/invalid_error_tests.rb
336
338
  - test/unit/json_tests.rb
337
339
  - test/unit/layout_tests.rb
338
340
  - test/unit/mixin_tests.rb
@@ -408,6 +410,7 @@ test_files:
408
410
  - test/unit/destroy_service_tests.rb
409
411
  - test/unit/has_slug_tests.rb
410
412
  - test/unit/input_value_tests.rb
413
+ - test/unit/invalid_error_tests.rb
411
414
  - test/unit/json_tests.rb
412
415
  - test/unit/layout_tests.rb
413
416
  - test/unit/mixin_tests.rb