much-rails 0.3.0 → 0.4.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.
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