granite 0.11.1 → 0.13.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 +4 -4
- data/lib/granite/action/exceptions_handling.rb +1 -1
- data/lib/granite/action/preconditions.rb +2 -2
- data/lib/granite/action/projectors.rb +7 -7
- data/lib/granite/action/transaction_manager.rb +4 -6
- data/lib/granite/action/translations.rb +1 -1
- data/lib/granite/action.rb +16 -8
- data/lib/granite/assign_data.rb +2 -2
- data/lib/granite/performer_proxy/proxy.rb +3 -1
- data/lib/granite/projector/controller_actions.rb +7 -7
- data/lib/granite/projector/helpers.rb +1 -2
- data/lib/granite/represents/attribute.rb +5 -5
- data/lib/granite/rspec/projector_helpers.rb +4 -10
- data/lib/granite/rspec/raise_validation_error.rb +6 -8
- data/lib/granite/ruby3_compatibility.rb +15 -0
- data/lib/granite/version.rb +1 -1
- data/lib/granite.rb +1 -0
- metadata +32 -23
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 17fb5bd6029503d159cdb3e5dd88d0f58961a30e81e1752327bc261733c62df9
|
4
|
+
data.tar.gz: cf15fd7b77203667a28c57ede076ee17a1df1014eca1cf97f15cc6efc2a3755a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3540905bc5f0198b002bfd0be1c7a2dca41b594c6a21538c4cfa0763d85fe770fafb45227fb6f28b73e206b63dfe302a3cbe04af97cfe1e1f055f9adaa48f4dc
|
7
|
+
data.tar.gz: f8837fc5c591f9c4169bcf60f6c6c9de8a3158e66c52d961b871f8bfe753f63ee353d7e560fa7fd3cb8667656fb30da01acf2065377ea50d6162f74ce8757202
|
@@ -98,8 +98,8 @@ module Granite
|
|
98
98
|
end
|
99
99
|
|
100
100
|
# Adds passed error message and options to `errors` object
|
101
|
-
def decline_with(*args)
|
102
|
-
errors.add(:base, *args)
|
101
|
+
def decline_with(*args, **kwargs)
|
102
|
+
errors.add(:base, *args, **kwargs)
|
103
103
|
failed_preconditions << args.first
|
104
104
|
end
|
105
105
|
|
@@ -85,13 +85,13 @@ module Granite
|
|
85
85
|
_projectors.store(name, options, &block)
|
86
86
|
|
87
87
|
class_eval <<-METHOD, __FILE__, __LINE__ + 1
|
88
|
-
def self.#{name}
|
89
|
-
_projectors.fetch(:#{name})
|
90
|
-
end
|
91
|
-
|
92
|
-
def #{name}
|
93
|
-
@#{name} ||= self.class._projectors.fetch(:#{name}).new(self)
|
94
|
-
end
|
88
|
+
def self.#{name} # def self.foo
|
89
|
+
_projectors.fetch(:#{name}) # _projectors.fetch(:foo)
|
90
|
+
end # end
|
91
|
+
#
|
92
|
+
def #{name} # def foo
|
93
|
+
@#{name} ||= self.class._projectors.fetch(:#{name}).new(self) # @foo ||= self.class._projectors.fetch(:foo).new(self)
|
94
|
+
end # end
|
95
95
|
METHOD
|
96
96
|
end
|
97
97
|
end
|
@@ -62,16 +62,14 @@ module Granite
|
|
62
62
|
collected_errors = []
|
63
63
|
|
64
64
|
callbacks.reverse_each do |callback|
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
collected_errors << e
|
69
|
-
end
|
65
|
+
callback.respond_to?(:run_callbacks) ? callback.run_callbacks(:commit) : callback.call
|
66
|
+
rescue StandardError => e
|
67
|
+
collected_errors << e
|
70
68
|
end
|
71
69
|
|
72
70
|
return unless collected_errors.any?
|
73
71
|
|
74
|
-
log_errors(collected_errors[1
|
72
|
+
log_errors(collected_errors[1..])
|
75
73
|
fail collected_errors.first
|
76
74
|
end
|
77
75
|
|
data/lib/granite/action.rb
CHANGED
@@ -50,20 +50,28 @@ module Granite
|
|
50
50
|
prepend AssignAttributes
|
51
51
|
|
52
52
|
handle_exception ActiveRecord::RecordInvalid do |e|
|
53
|
-
|
54
|
-
(this + other).uniq
|
55
|
-
end
|
53
|
+
merge_errors(e.record.errors)
|
56
54
|
end
|
57
55
|
|
58
56
|
handle_exception ActiveData::ValidationError do |e|
|
59
|
-
|
60
|
-
(this + other).uniq
|
61
|
-
end
|
57
|
+
merge_errors(e.model.errors)
|
62
58
|
end
|
63
59
|
|
64
60
|
handle_exception Granite::Action::ValidationError do |e|
|
65
|
-
|
66
|
-
|
61
|
+
merge_errors(e.action.errors)
|
62
|
+
end
|
63
|
+
|
64
|
+
if ActiveModel.version < Gem::Version.new('6.1.0')
|
65
|
+
def merge_errors(other_errors)
|
66
|
+
errors.messages.deep_merge!(other_errors.messages) do |_, this, other|
|
67
|
+
(this + other).uniq
|
68
|
+
end
|
69
|
+
end
|
70
|
+
else
|
71
|
+
def merge_errors(other_errors)
|
72
|
+
other_errors.each do |error|
|
73
|
+
errors.import(error) unless errors.added?(error.attribute, error)
|
74
|
+
end
|
67
75
|
end
|
68
76
|
end
|
69
77
|
|
data/lib/granite/assign_data.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
module Granite
|
2
2
|
module AssignData
|
3
|
-
DataAssignment = Struct.new(:method, :options)
|
3
|
+
DataAssignment = Struct.new(:method, :options) # rubocop:disable Lint/StructNewOverride
|
4
4
|
|
5
5
|
extend ActiveSupport::Concern
|
6
6
|
|
@@ -9,7 +9,7 @@ module Granite
|
|
9
9
|
self.data_assignments = []
|
10
10
|
|
11
11
|
alias_method :only_run_validations!, :run_validations!
|
12
|
-
protected :only_run_validations!
|
12
|
+
protected :only_run_validations!
|
13
13
|
end
|
14
14
|
|
15
15
|
module ClassMethods
|
@@ -4,6 +4,8 @@ module Granite
|
|
4
4
|
# performer-enabled context.
|
5
5
|
#
|
6
6
|
class Proxy
|
7
|
+
extend Granite::Ruby3Compatibility
|
8
|
+
|
7
9
|
def initialize(klass, performer)
|
8
10
|
@klass = klass
|
9
11
|
@performer = performer
|
@@ -13,7 +15,7 @@ module Granite
|
|
13
15
|
"<#{@klass}PerformerProxy #{@performer}>"
|
14
16
|
end
|
15
17
|
|
16
|
-
def method_missing(method, *args, &block)
|
18
|
+
ruby2_keywords def method_missing(method, *args, &block)
|
17
19
|
if @klass.respond_to?(method)
|
18
20
|
@klass.with_proxy_performer(@performer) do
|
19
21
|
@klass.public_send(method, *args, &block)
|
@@ -22,13 +22,13 @@ module Granite
|
|
22
22
|
self.controller_actions = controller_actions.merge(name.to_sym => options)
|
23
23
|
controller_class.__send__(:define_method, name, &block)
|
24
24
|
class_eval <<-METHOD, __FILE__, __LINE__ + 1
|
25
|
-
def #{name}_url(options = {})
|
26
|
-
action_url(:#{name}, **options.symbolize_keys)
|
27
|
-
end
|
28
|
-
|
29
|
-
def #{name}_path(options = {})
|
30
|
-
action_path(:#{name}, **options.symbolize_keys)
|
31
|
-
end
|
25
|
+
def #{name}_url(options = {}) # def foo_url(options = {}
|
26
|
+
action_url(:#{name}, **options.symbolize_keys) # action_url(:foo, **options.symbolize_keys)
|
27
|
+
end # end
|
28
|
+
#
|
29
|
+
def #{name}_path(options = {}) # def foo_path(options = {})
|
30
|
+
action_path(:#{name}, **options.symbolize_keys) # action_path(:foo, **options.symbolize_keys)
|
31
|
+
end # end
|
32
32
|
METHOD
|
33
33
|
else
|
34
34
|
controller_actions[name.to_sym]
|
@@ -35,8 +35,7 @@ Do you have #{projector.action_class.name.underscore}##{projector.projector_name
|
|
35
35
|
|
36
36
|
def required_params
|
37
37
|
corresponding_route.required_parts
|
38
|
-
.
|
39
|
-
.to_h
|
38
|
+
.to_h { |name| [name, action.public_send(name)] }
|
40
39
|
end
|
41
40
|
|
42
41
|
def corresponding_route
|
@@ -15,7 +15,7 @@ module Granite
|
|
15
15
|
end
|
16
16
|
|
17
17
|
def typecast(value)
|
18
|
-
return value if value.class == type
|
18
|
+
return value if value.class == type # rubocop:disable Style/ClassEqualityComparison
|
19
19
|
|
20
20
|
typecaster.call(value, self) unless value.nil?
|
21
21
|
end
|
@@ -28,13 +28,13 @@ module Granite
|
|
28
28
|
|
29
29
|
def typecaster
|
30
30
|
@typecaster ||= begin
|
31
|
-
|
32
|
-
|
33
|
-
|
31
|
+
type_class = type.instance_of?(Class) ? type : type.class
|
32
|
+
@typecaster = ActiveData.typecaster(type_class.ancestors.grep(Class))
|
33
|
+
end
|
34
34
|
end
|
35
35
|
|
36
36
|
def changed?
|
37
|
-
if reflection.options
|
37
|
+
if reflection.options.key?(:default)
|
38
38
|
reference.public_send(reader) != read
|
39
39
|
else
|
40
40
|
owner.public_send("#{name}_changed?")
|
@@ -30,16 +30,10 @@ module Granite::ProjectorHelpers
|
|
30
30
|
|
31
31
|
private
|
32
32
|
|
33
|
-
def setup_controller
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
end
|
38
|
-
|
39
|
-
before do
|
40
|
-
@controller = yield.controller_class.new
|
41
|
-
@controller.class.instance_variable_set(:@controller_path, yield.projector_path)
|
42
|
-
@controller.request = @request
|
33
|
+
def setup_controller(&block)
|
34
|
+
define_method :setup_controller_request_and_response do
|
35
|
+
@controller ||= instance_eval(&block).controller_class.new
|
36
|
+
super()
|
43
37
|
end
|
44
38
|
end
|
45
39
|
|
@@ -23,14 +23,12 @@ RSpec::Matchers.define :raise_validation_error do
|
|
23
23
|
end
|
24
24
|
|
25
25
|
match do |block|
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
@result = @details_being_checked&.any? { |x| x[:error] == @error_type }
|
33
|
-
end
|
26
|
+
block.call
|
27
|
+
false
|
28
|
+
rescue Granite::Action::ValidationError => e
|
29
|
+
@details = e.errors.details
|
30
|
+
@details_being_checked = @details[@attribute || :base]
|
31
|
+
@result = @details_being_checked&.any? { |x| x[:error] == @error_type }
|
34
32
|
end
|
35
33
|
|
36
34
|
description do
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module Granite
|
2
|
+
module Ruby3Compatibility
|
3
|
+
# Method definition aimed to provide compatibility between Ruby 2.6 and 3.0
|
4
|
+
# It's being recommended in this article
|
5
|
+
# https://www.ruby-lang.org/en/news/2019/12/12/separation-of-positional-and-keyword-arguments-in-ruby-3-0/
|
6
|
+
#
|
7
|
+
# Example:
|
8
|
+
#
|
9
|
+
# ruby2_keywords def a_method(argument, *args, &block)
|
10
|
+
# delegating_to_method(argument, *args, &block)
|
11
|
+
# end
|
12
|
+
def ruby2_keywords(*)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
data/lib/granite/version.rb
CHANGED
data/lib/granite.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: granite
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.13.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Toptal Engineering
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2022-07-14 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: actionpack
|
@@ -19,7 +19,7 @@ dependencies:
|
|
19
19
|
version: '5.1'
|
20
20
|
- - "<"
|
21
21
|
- !ruby/object:Gem::Version
|
22
|
-
version: '
|
22
|
+
version: '7.1'
|
23
23
|
type: :runtime
|
24
24
|
prerelease: false
|
25
25
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -29,21 +29,21 @@ dependencies:
|
|
29
29
|
version: '5.1'
|
30
30
|
- - "<"
|
31
31
|
- !ruby/object:Gem::Version
|
32
|
-
version: '
|
32
|
+
version: '7.1'
|
33
33
|
- !ruby/object:Gem::Dependency
|
34
34
|
name: active_data
|
35
35
|
requirement: !ruby/object:Gem::Requirement
|
36
36
|
requirements:
|
37
37
|
- - "~>"
|
38
38
|
- !ruby/object:Gem::Version
|
39
|
-
version: 1.
|
39
|
+
version: 1.2.0
|
40
40
|
type: :runtime
|
41
41
|
prerelease: false
|
42
42
|
version_requirements: !ruby/object:Gem::Requirement
|
43
43
|
requirements:
|
44
44
|
- - "~>"
|
45
45
|
- !ruby/object:Gem::Version
|
46
|
-
version: 1.
|
46
|
+
version: 1.2.0
|
47
47
|
- !ruby/object:Gem::Dependency
|
48
48
|
name: activesupport
|
49
49
|
requirement: !ruby/object:Gem::Requirement
|
@@ -53,7 +53,7 @@ dependencies:
|
|
53
53
|
version: '5.1'
|
54
54
|
- - "<"
|
55
55
|
- !ruby/object:Gem::Version
|
56
|
-
version: '
|
56
|
+
version: '7.1'
|
57
57
|
type: :runtime
|
58
58
|
prerelease: false
|
59
59
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -63,7 +63,7 @@ dependencies:
|
|
63
63
|
version: '5.1'
|
64
64
|
- - "<"
|
65
65
|
- !ruby/object:Gem::Version
|
66
|
-
version: '
|
66
|
+
version: '7.1'
|
67
67
|
- !ruby/object:Gem::Dependency
|
68
68
|
name: memoist
|
69
69
|
requirement: !ruby/object:Gem::Requirement
|
@@ -84,20 +84,28 @@ dependencies:
|
|
84
84
|
requirements:
|
85
85
|
- - ">="
|
86
86
|
- !ruby/object:Gem::Version
|
87
|
-
version: '
|
88
|
-
- - "<"
|
89
|
-
- !ruby/object:Gem::Version
|
90
|
-
version: '6.1'
|
87
|
+
version: '0'
|
91
88
|
type: :development
|
92
89
|
prerelease: false
|
93
90
|
version_requirements: !ruby/object:Gem::Requirement
|
94
91
|
requirements:
|
95
92
|
- - ">="
|
96
93
|
- !ruby/object:Gem::Version
|
97
|
-
version: '
|
98
|
-
|
94
|
+
version: '0'
|
95
|
+
- !ruby/object:Gem::Dependency
|
96
|
+
name: appraisal
|
97
|
+
requirement: !ruby/object:Gem::Requirement
|
98
|
+
requirements:
|
99
|
+
- - ">="
|
100
|
+
- !ruby/object:Gem::Version
|
101
|
+
version: '0'
|
102
|
+
type: :development
|
103
|
+
prerelease: false
|
104
|
+
version_requirements: !ruby/object:Gem::Requirement
|
105
|
+
requirements:
|
106
|
+
- - ">="
|
99
107
|
- !ruby/object:Gem::Version
|
100
|
-
version: '
|
108
|
+
version: '0'
|
101
109
|
- !ruby/object:Gem::Dependency
|
102
110
|
name: capybara
|
103
111
|
requirement: !ruby/object:Gem::Requirement
|
@@ -244,42 +252,42 @@ dependencies:
|
|
244
252
|
requirements:
|
245
253
|
- - "~>"
|
246
254
|
- !ruby/object:Gem::Version
|
247
|
-
version:
|
255
|
+
version: '1.0'
|
248
256
|
type: :development
|
249
257
|
prerelease: false
|
250
258
|
version_requirements: !ruby/object:Gem::Requirement
|
251
259
|
requirements:
|
252
260
|
- - "~>"
|
253
261
|
- !ruby/object:Gem::Version
|
254
|
-
version:
|
262
|
+
version: '1.0'
|
255
263
|
- !ruby/object:Gem::Dependency
|
256
264
|
name: rubocop-rails
|
257
265
|
requirement: !ruby/object:Gem::Requirement
|
258
266
|
requirements:
|
259
267
|
- - "~>"
|
260
268
|
- !ruby/object:Gem::Version
|
261
|
-
version: 2.
|
269
|
+
version: '2.13'
|
262
270
|
type: :development
|
263
271
|
prerelease: false
|
264
272
|
version_requirements: !ruby/object:Gem::Requirement
|
265
273
|
requirements:
|
266
274
|
- - "~>"
|
267
275
|
- !ruby/object:Gem::Version
|
268
|
-
version: 2.
|
276
|
+
version: '2.13'
|
269
277
|
- !ruby/object:Gem::Dependency
|
270
278
|
name: rubocop-rspec
|
271
279
|
requirement: !ruby/object:Gem::Requirement
|
272
280
|
requirements:
|
273
281
|
- - "~>"
|
274
282
|
- !ruby/object:Gem::Version
|
275
|
-
version:
|
283
|
+
version: '2.8'
|
276
284
|
type: :development
|
277
285
|
prerelease: false
|
278
286
|
version_requirements: !ruby/object:Gem::Requirement
|
279
287
|
requirements:
|
280
288
|
- - "~>"
|
281
289
|
- !ruby/object:Gem::Version
|
282
|
-
version:
|
290
|
+
version: '2.8'
|
283
291
|
- !ruby/object:Gem::Dependency
|
284
292
|
name: simplecov
|
285
293
|
requirement: !ruby/object:Gem::Requirement
|
@@ -364,6 +372,7 @@ files:
|
|
364
372
|
- lib/granite/rspec/projector_helpers.rb
|
365
373
|
- lib/granite/rspec/raise_validation_error.rb
|
366
374
|
- lib/granite/rspec/satisfy_preconditions.rb
|
375
|
+
- lib/granite/ruby3_compatibility.rb
|
367
376
|
- lib/granite/translations.rb
|
368
377
|
- lib/granite/typecasters.rb
|
369
378
|
- lib/granite/util.rb
|
@@ -383,14 +392,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
383
392
|
requirements:
|
384
393
|
- - ">="
|
385
394
|
- !ruby/object:Gem::Version
|
386
|
-
version: '
|
395
|
+
version: '2.5'
|
387
396
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
388
397
|
requirements:
|
389
398
|
- - ">="
|
390
399
|
- !ruby/object:Gem::Version
|
391
400
|
version: '0'
|
392
401
|
requirements: []
|
393
|
-
rubygems_version: 3.
|
402
|
+
rubygems_version: 3.3.17
|
394
403
|
signing_key:
|
395
404
|
specification_version: 4
|
396
405
|
summary: Another business actions architecture for Rails apps
|