granite 0.12.0 → 0.14.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: 8f01fbcec194a3031c22582899a7ff0210d2b621aa149a5ccf7814a3a70540ea
4
- data.tar.gz: c763544b18d4feb43a5502df2e661dce313c304f47543978be095e4e72afc863
3
+ metadata.gz: d0524a0055b0ea48aeab0691a1063cf332455b87094e2a78dbb6b66cc24b168e
4
+ data.tar.gz: e07a9c6a636eed28916860e213beea548aa92943da442b7d39019b346079e3fc
5
5
  SHA512:
6
- metadata.gz: '099c76956322fe11a1118dc25a1fffbc0553018d1abf660d7c6270256f40505a3d93be01e57df0d7502c767c09d961fcf3361a7281315296e6abb9c512a38a9f'
7
- data.tar.gz: 9b1b66eca75f4ff623319d1828cbec2b987c36050fb70598a8a14ea7edd760da38eb61c89f0a4de3b706875b68a16dccefe22333c3ac8edbe5b80864e04f4aca
6
+ metadata.gz: 217ac1d410c18e838f648af770c610b24ad4a28fc70e37514060509b5ac0a9303907912da5a2e7151162df2d842c78cdf3dd4c03e64ae464427bea9707923410
7
+ data.tar.gz: 2824f499e042ce4df4565d450367ccf3c33b711586c496c752fde675c4a1bd4d2a5810b92c84916603436981ef61c100583d89865e7f5c758c5033fbc3d97e20
@@ -14,11 +14,12 @@ module Granite
14
14
  before_action :authorize_action!
15
15
 
16
16
  def projector
17
- @projector ||= begin
18
- action_projector_class = action_class.public_send(projector_name)
19
- action_projector_class = action_projector_class.as(projector_performer) if respond_to?(:projector_performer, true)
20
- action_projector_class.new(projector_params)
21
- end
17
+ @projector ||=
18
+ begin
19
+ projector_class = action_class.public_send(projector_name)
20
+ projector_class = projector_class.with(projector_context) if respond_to?(:projector_context, true)
21
+ projector_class.new(projector_params)
22
+ end
22
23
  end
23
24
  helper_method :projector
24
25
 
@@ -7,7 +7,7 @@ module Granite
7
7
  class_attribute :_exception_handlers, instance_writer: false
8
8
  self._exception_handlers = {}
9
9
 
10
- protected :_exception_handlers # rubocop:disable Style/AccessModifierDeclarations
10
+ protected :_exception_handlers
11
11
  end
12
12
 
13
13
  module ClassMethods
@@ -0,0 +1,23 @@
1
+ module Granite
2
+ class Action
3
+ module Instrumentation
4
+ def perform!(*, **)
5
+ instrument_perform(:perform!) { super }
6
+ end
7
+
8
+ def perform(*, **)
9
+ instrument_perform(:perform) { super }
10
+ end
11
+
12
+ def try_perform!(*, **)
13
+ instrument_perform(:try_perform!) { super }
14
+ end
15
+
16
+ private
17
+
18
+ def instrument_perform(using, &block)
19
+ ActiveSupport::Notifications.instrument('granite.perform_action', action: self, using: using, &block)
20
+ end
21
+ end
22
+ end
23
+ end
@@ -1,4 +1,4 @@
1
- require 'granite/performer_proxy'
1
+ require 'granite/context_proxy'
2
2
 
3
3
  module Granite
4
4
  class Action
@@ -8,15 +8,16 @@ module Granite
8
8
  extend ActiveSupport::Concern
9
9
 
10
10
  included do
11
- include PerformerProxy
12
- attr_reader :performer
11
+ include ContextProxy
12
+ attr_reader :ctx
13
13
  end
14
14
 
15
15
  def initialize(*args)
16
- @performer = self.class.proxy_performer
16
+ @ctx = self.class.proxy_context
17
17
  super
18
18
  end
19
19
 
20
+ delegate :performer, to: :ctx, allow_nil: true
20
21
  delegate :id, to: :performer, prefix: true, allow_nil: true
21
22
  end
22
23
  end
@@ -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
- begin
66
- callback.respond_to?(:run_callbacks) ? callback.run_callbacks(:commit) : callback.call
67
- rescue StandardError => e
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..-1])
72
+ log_errors(collected_errors[1..])
75
73
  fail collected_errors.first
76
74
  end
77
75
 
@@ -17,7 +17,7 @@ module Granite
17
17
 
18
18
  def translate(*args, **options)
19
19
  key, options = Granite::Translations.scope_translation_args(self.class.i18n_scopes, *args, **options)
20
- I18n.translate(key, **options)
20
+ I18n.t(key, **options)
21
21
  end
22
22
  alias t translate
23
23
  end
@@ -5,6 +5,7 @@ require 'active_support/callbacks'
5
5
 
6
6
  require 'granite/action/types'
7
7
  require 'granite/action/error'
8
+ require 'granite/action/instrumentation'
8
9
  require 'granite/action/performing'
9
10
  require 'granite/action/performer'
10
11
  require 'granite/action/precondition'
@@ -48,6 +49,7 @@ module Granite
48
49
  include Policies
49
50
  include Projectors
50
51
  prepend AssignAttributes
52
+ prepend Instrumentation
51
53
 
52
54
  handle_exception ActiveRecord::RecordInvalid do |e|
53
55
  merge_errors(e.record.errors)
@@ -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! # rubocop:disable Style/AccessModifierDeclarations
12
+ protected :only_run_validations!
13
13
  end
14
14
 
15
15
  module ClassMethods
@@ -0,0 +1,20 @@
1
+ module Granite
2
+ module ContextProxy
3
+ # Contains all the arbitrary data that is passed to BA with `with`
4
+ class Data
5
+ attr_reader :performer
6
+
7
+ def self.wrap(data)
8
+ if data.is_a?(self)
9
+ data
10
+ else
11
+ new(**data || {})
12
+ end
13
+ end
14
+
15
+ def initialize(performer: nil)
16
+ @performer = performer
17
+ end
18
+ end
19
+ end
20
+ end
@@ -1,21 +1,22 @@
1
1
  module Granite
2
- module PerformerProxy
3
- # Proxy helps to wrap the following method call with
4
- # performer-enabled context.
2
+ module ContextProxy
3
+ # Proxy which wraps the following method calls with BA context.
5
4
  #
6
5
  class Proxy
7
- def initialize(klass, performer)
6
+ extend Granite::Ruby3Compatibility
7
+
8
+ def initialize(klass, context)
8
9
  @klass = klass
9
- @performer = performer
10
+ @context = context
10
11
  end
11
12
 
12
13
  def inspect
13
- "<#{@klass}PerformerProxy #{@performer}>"
14
+ "<#{@klass}ContextProxy #{@context}>"
14
15
  end
15
16
 
16
- def method_missing(method, *args, &block)
17
+ ruby2_keywords def method_missing(method, *args, &block)
17
18
  if @klass.respond_to?(method)
18
- @klass.with_proxy_performer(@performer) do
19
+ @klass.with_context(@context) do
19
20
  @klass.public_send(method, *args, &block)
20
21
  end
21
22
  else
@@ -0,0 +1,34 @@
1
+ require 'granite/context_proxy/data'
2
+ require 'granite/context_proxy/proxy'
3
+
4
+ module Granite
5
+ # This concern contains class methods used for actions and projectors
6
+ #
7
+ module ContextProxy
8
+ extend ActiveSupport::Concern
9
+
10
+ module ClassMethods
11
+ PROXY_CONTEXT_KEY = :granite_proxy_context
12
+
13
+ def with(data)
14
+ Proxy.new(self, Data.wrap(data))
15
+ end
16
+
17
+ def as(performer)
18
+ with(performer: performer)
19
+ end
20
+
21
+ def with_context(context)
22
+ old_context = proxy_context
23
+ Thread.current[PROXY_CONTEXT_KEY] = context
24
+ yield
25
+ ensure
26
+ Thread.current[PROXY_CONTEXT_KEY] = old_context
27
+ end
28
+
29
+ def proxy_context
30
+ Thread.current[PROXY_CONTEXT_KEY]
31
+ end
32
+ end
33
+ end
34
+ end
@@ -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
- .map { |name| [name, action.public_send(name)] }
39
- .to_h
38
+ .to_h { |name| [name, action.public_send(name)] }
40
39
  end
41
40
 
42
41
  def corresponding_route
@@ -2,11 +2,11 @@ require 'granite/projector/controller_actions'
2
2
  require 'granite/projector/error'
3
3
  require 'granite/projector/helpers'
4
4
  require 'granite/projector/translations'
5
- require 'granite/performer_proxy'
5
+ require 'granite/context_proxy'
6
6
 
7
7
  module Granite
8
8
  class Projector
9
- include PerformerProxy
9
+ include ContextProxy
10
10
  include ControllerActions
11
11
  include Helpers
12
12
  include Translations
@@ -42,7 +42,7 @@ module Granite
42
42
  private
43
43
 
44
44
  def build_action(*args)
45
- action_class.as(self.class.proxy_performer).new(*args)
45
+ action_class.with(self.class.proxy_context).new(*args)
46
46
  end
47
47
  end
48
48
  end
@@ -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,9 +28,9 @@ module Granite
28
28
 
29
29
  def typecaster
30
30
  @typecaster ||= begin
31
- type_class = type.instance_of?(Class) ? type : type.class
32
- @typecaster = ActiveData.typecaster(type_class.ancestors.grep(Class))
33
- end
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?
@@ -0,0 +1,89 @@
1
+ RSpec::Matchers.define :perform_action do |klass|
2
+ chain :using do |using|
3
+ @using = using
4
+ end
5
+
6
+ chain :as do |performer|
7
+ @performer = performer
8
+ end
9
+
10
+ chain :with do |attributes|
11
+ @attributes = attributes
12
+ end
13
+
14
+ match do |block|
15
+ @klass = klass
16
+ @using ||= :perform!
17
+
18
+ @payloads = []
19
+ subscriber = ActiveSupport::Notifications.subscribe('granite.perform_action') do |_, _, _, _, payload|
20
+ @payloads << payload
21
+ end
22
+
23
+ block.call
24
+
25
+ ActiveSupport::Notifications.unsubscribe(subscriber)
26
+
27
+ @payloads.detect { |payload| action_matches?(payload[:action]) && payload[:using] == @using }
28
+ end
29
+
30
+ failure_message do
31
+ output = "expected to call #{performed_entity}"
32
+ add_performer_message(output, @performer) if defined?(@performer)
33
+ add_attributes_message(output, @attributes) if defined?(@attributes)
34
+
35
+ similar_payloads = @payloads.select { |payload| class_matches?(payload[:action]) && payload[:using] == @using }
36
+ if similar_payloads.present?
37
+ output << "\nreceived calls to #{performed_entity}:"
38
+ similar_payloads.each { |payload| add_message_from_payload(output, payload) }
39
+ end
40
+
41
+ output
42
+ end
43
+
44
+ failure_message_when_negated do
45
+ "expected not to call #{performed_entity}"
46
+ end
47
+
48
+ supports_block_expectations
49
+
50
+ private
51
+
52
+ def add_message_from_payload(output, payload)
53
+ action = payload[:action]
54
+ add_performer_message(output, action.performer) if defined?(@performer)
55
+ add_attributes_message(output, actual_attributes(action)) if defined?(@attributes)
56
+ end
57
+
58
+ def add_performer_message(output, performer)
59
+ output << "\n AS #{performer.inspect}"
60
+ end
61
+
62
+ def add_attributes_message(output, attributes)
63
+ output << "\n WITH #{attributes.inspect}"
64
+ end
65
+
66
+ def performed_entity
67
+ "#{@klass}##{@using}"
68
+ end
69
+
70
+ def actual_attributes(action)
71
+ @attributes.keys.to_h { |attr| [attr, action.public_send(attr)] }
72
+ end
73
+
74
+ def action_matches?(action)
75
+ class_matches?(action) && performer_matches?(action) && attributes_match?(action)
76
+ end
77
+
78
+ def class_matches?(action)
79
+ action.is_a?(@klass)
80
+ end
81
+
82
+ def performer_matches?(action)
83
+ !defined?(@performer) || action.performer == @performer
84
+ end
85
+
86
+ def attributes_match?(action)
87
+ !defined?(@attributes) || match(@attributes).matches?(actual_attributes(action))
88
+ end
89
+ end
@@ -30,16 +30,10 @@ module Granite::ProjectorHelpers
30
30
 
31
31
  private
32
32
 
33
- def setup_controller
34
- singleton_class.class_eval do
35
- def controller_class
36
- end
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
- begin
27
- block.call
28
- false
29
- rescue Granite::Action::ValidationError => e
30
- @details = e.errors.details
31
- @details_being_checked = @details[@attribute || :base]
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
data/lib/granite/rspec.rb CHANGED
@@ -1,5 +1,6 @@
1
1
  require 'granite/rspec/action_helpers'
2
2
  require 'granite/rspec/have_projector'
3
+ require 'granite/rspec/perform_action'
3
4
  require 'granite/rspec/projector_helpers'
4
5
  require 'granite/rspec/raise_validation_error'
5
6
  require 'granite/rspec/satisfy_preconditions'
@@ -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
@@ -1,3 +1,3 @@
1
1
  module Granite
2
- VERSION = '0.12.0'.freeze
2
+ VERSION = '0.14.0'.freeze
3
3
  end
data/lib/granite.rb CHANGED
@@ -5,6 +5,7 @@ require 'granite/version'
5
5
  require 'granite/config'
6
6
  require 'granite/context'
7
7
  require 'granite/util'
8
+ require 'granite/ruby3_compatibility'
8
9
 
9
10
  module Granite
10
11
  def self.config
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.12.0
4
+ version: 0.14.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Toptal Engineering
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-12-23 00:00:00.000000000 Z
11
+ date: 2022-08-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: actionpack
@@ -252,42 +252,42 @@ dependencies:
252
252
  requirements:
253
253
  - - "~>"
254
254
  - !ruby/object:Gem::Version
255
- version: 0.78.0
255
+ version: '1.0'
256
256
  type: :development
257
257
  prerelease: false
258
258
  version_requirements: !ruby/object:Gem::Requirement
259
259
  requirements:
260
260
  - - "~>"
261
261
  - !ruby/object:Gem::Version
262
- version: 0.78.0
262
+ version: '1.0'
263
263
  - !ruby/object:Gem::Dependency
264
264
  name: rubocop-rails
265
265
  requirement: !ruby/object:Gem::Requirement
266
266
  requirements:
267
267
  - - "~>"
268
268
  - !ruby/object:Gem::Version
269
- version: 2.4.1
269
+ version: '2.13'
270
270
  type: :development
271
271
  prerelease: false
272
272
  version_requirements: !ruby/object:Gem::Requirement
273
273
  requirements:
274
274
  - - "~>"
275
275
  - !ruby/object:Gem::Version
276
- version: 2.4.1
276
+ version: '2.13'
277
277
  - !ruby/object:Gem::Dependency
278
278
  name: rubocop-rspec
279
279
  requirement: !ruby/object:Gem::Requirement
280
280
  requirements:
281
281
  - - "~>"
282
282
  - !ruby/object:Gem::Version
283
- version: 1.37.0
283
+ version: '2.8'
284
284
  type: :development
285
285
  prerelease: false
286
286
  version_requirements: !ruby/object:Gem::Requirement
287
287
  requirements:
288
288
  - - "~>"
289
289
  - !ruby/object:Gem::Version
290
- version: 1.37.0
290
+ version: '2.8'
291
291
  - !ruby/object:Gem::Dependency
292
292
  name: simplecov
293
293
  requirement: !ruby/object:Gem::Requirement
@@ -302,8 +302,8 @@ dependencies:
302
302
  - - "~>"
303
303
  - !ruby/object:Gem::Version
304
304
  version: '0.15'
305
- description:
306
- email:
305
+ description:
306
+ email:
307
307
  executables: []
308
308
  extensions: []
309
309
  extra_rdoc_files: []
@@ -323,6 +323,7 @@ files:
323
323
  - lib/granite/action.rb
324
324
  - lib/granite/action/error.rb
325
325
  - lib/granite/action/exceptions_handling.rb
326
+ - lib/granite/action/instrumentation.rb
326
327
  - lib/granite/action/performer.rb
327
328
  - lib/granite/action/performing.rb
328
329
  - lib/granite/action/policies.rb
@@ -346,10 +347,11 @@ files:
346
347
  - lib/granite/base.rb
347
348
  - lib/granite/config.rb
348
349
  - lib/granite/context.rb
350
+ - lib/granite/context_proxy.rb
351
+ - lib/granite/context_proxy/data.rb
352
+ - lib/granite/context_proxy/proxy.rb
349
353
  - lib/granite/dispatcher.rb
350
354
  - lib/granite/error.rb
351
- - lib/granite/performer_proxy.rb
352
- - lib/granite/performer_proxy/proxy.rb
353
355
  - lib/granite/projector.rb
354
356
  - lib/granite/projector/controller_actions.rb
355
357
  - lib/granite/projector/error.rb
@@ -369,9 +371,11 @@ files:
369
371
  - lib/granite/rspec.rb
370
372
  - lib/granite/rspec/action_helpers.rb
371
373
  - lib/granite/rspec/have_projector.rb
374
+ - lib/granite/rspec/perform_action.rb
372
375
  - lib/granite/rspec/projector_helpers.rb
373
376
  - lib/granite/rspec/raise_validation_error.rb
374
377
  - lib/granite/rspec/satisfy_preconditions.rb
378
+ - lib/granite/ruby3_compatibility.rb
375
379
  - lib/granite/translations.rb
376
380
  - lib/granite/typecasters.rb
377
381
  - lib/granite/util.rb
@@ -383,7 +387,7 @@ homepage: https://github.com/toptal/granite
383
387
  licenses:
384
388
  - MIT
385
389
  metadata: {}
386
- post_install_message:
390
+ post_install_message:
387
391
  rdoc_options: []
388
392
  require_paths:
389
393
  - lib
@@ -391,15 +395,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
391
395
  requirements:
392
396
  - - ">="
393
397
  - !ruby/object:Gem::Version
394
- version: '0'
398
+ version: '2.5'
395
399
  required_rubygems_version: !ruby/object:Gem::Requirement
396
400
  requirements:
397
401
  - - ">="
398
402
  - !ruby/object:Gem::Version
399
403
  version: '0'
400
404
  requirements: []
401
- rubygems_version: 3.2.29
402
- signing_key:
405
+ rubygems_version: 3.3.9
406
+ signing_key:
403
407
  specification_version: 4
404
408
  summary: Another business actions architecture for Rails apps
405
409
  test_files: []
@@ -1,34 +0,0 @@
1
- require 'granite/performer_proxy/proxy'
2
-
3
- module Granite
4
- # This concern contains class methods used for actions and projectors
5
- #
6
- module PerformerProxy
7
- extend ActiveSupport::Concern
8
-
9
- module ClassMethods
10
- def as(performer)
11
- Proxy.new(self, performer)
12
- end
13
-
14
- def with_proxy_performer(performer)
15
- key = proxy_performer_key
16
- old_performer = Thread.current[key]
17
- Thread.current[key] = performer
18
- yield
19
- ensure
20
- Thread.current[key] = old_performer
21
- end
22
-
23
- def proxy_performer
24
- Thread.current[proxy_performer_key]
25
- end
26
-
27
- private
28
-
29
- def proxy_performer_key
30
- :"granite_proxy_performer_#{hash}"
31
- end
32
- end
33
- end
34
- end