granite 0.17.1 → 0.17.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (49) hide show
  1. checksums.yaml +4 -4
  2. data/app/controllers/granite/controller/translations.rb +1 -1
  3. data/app/controllers/granite/controller.rb +1 -1
  4. data/lib/generators/granite/install_controller_generator.rb +1 -1
  5. data/lib/generators/granite_generator.rb +5 -2
  6. data/lib/granite/action/error.rb +1 -1
  7. data/lib/granite/action/exceptions_handling.rb +5 -5
  8. data/lib/granite/action/instrumentation.rb +1 -1
  9. data/lib/granite/action/performing.rb +7 -4
  10. data/lib/granite/action/policies.rb +3 -3
  11. data/lib/granite/action/precondition.rb +2 -2
  12. data/lib/granite/action/preconditions/base_precondition.rb +1 -1
  13. data/lib/granite/action/preconditions/object_precondition.rb +1 -1
  14. data/lib/granite/action/preconditions.rb +3 -3
  15. data/lib/granite/action/projectors.rb +4 -6
  16. data/lib/granite/action/subject.rb +5 -5
  17. data/lib/granite/action/transaction.rb +1 -1
  18. data/lib/granite/action/transaction_manager/transactions_stack.rb +2 -3
  19. data/lib/granite/action/transaction_manager.rb +5 -4
  20. data/lib/granite/action/translations.rb +2 -2
  21. data/lib/granite/action.rb +7 -4
  22. data/lib/granite/assign_data.rb +2 -2
  23. data/lib/granite/config.rb +1 -1
  24. data/lib/granite/context.rb +1 -1
  25. data/lib/granite/context_proxy.rb +1 -1
  26. data/lib/granite/dispatcher.rb +49 -46
  27. data/lib/granite/projector/controller_actions.rb +3 -3
  28. data/lib/granite/projector/error.rb +1 -1
  29. data/lib/granite/projector/helpers.rb +4 -4
  30. data/lib/granite/projector/translations.rb +1 -1
  31. data/lib/granite/projector.rb +1 -1
  32. data/lib/granite/routing/cache.rb +1 -1
  33. data/lib/granite/routing/caching.rb +1 -1
  34. data/lib/granite/routing/declarer.rb +1 -1
  35. data/lib/granite/routing/mapper.rb +1 -1
  36. data/lib/granite/routing/mapping.rb +1 -1
  37. data/lib/granite/routing/route.rb +1 -1
  38. data/lib/granite/rspec/action_helpers.rb +8 -4
  39. data/lib/granite/rspec/perform_action.rb +1 -1
  40. data/lib/granite/rspec/projector_helpers.rb +43 -38
  41. data/lib/granite/rspec/raise_validation_error.rb +2 -6
  42. data/lib/granite/rspec/satisfy_preconditions.rb +6 -6
  43. data/lib/granite/translations.rb +1 -1
  44. data/lib/granite/version.rb +1 -1
  45. data/lib/granite.rb +5 -1
  46. data/lib/rubocop/granite/inject.rb +1 -3
  47. data/lib/rubocop/granite.rb +1 -1
  48. data/lib/rubocop-granite.rb +0 -2
  49. metadata +30 -29
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 9e0ea5a4829a8f42ea8d86fa3ad0c8ae3e0e15bf4b0b92824b2268bc4be9489b
4
- data.tar.gz: a40be02b1b8cef2bfa329c1f33415b78142d497a9d20f10d4ae7b3adc060bdf5
3
+ metadata.gz: a3e1ba1452b79b7af5130326fb9fd4b11399bf8c23d2bdcbb3cf7a3d54a81c6f
4
+ data.tar.gz: dbc6e24fa6d5e22710bed7a24f0ff9bde67d91bc6672bb0af89477601ec1b199
5
5
  SHA512:
6
- metadata.gz: 37d3fe242ac9ea96ec2b4bf4aa8f55e97086a12634600e3d474558319a143cbe0a718bbd1f76a77514a9ca98fac39c0ae39439ede746ead6a8c08f3ec2e85b1e
7
- data.tar.gz: 34a452491cc98a5c650ffb513684e5f8ab1dd12407cddaadcc7a3905ece4eaab5dc40c27ab93ee99ae3f55381ebee9f510abf8a31e2d3d1d9929ab695b743aeb
6
+ metadata.gz: cfff687bb585d2ddff0fc504e08a849e3f148c13cfb9bb6d48a016dca0a83a57008cdce581753ccacb18005a5c9cac46ad49ebcacc3e615f14c9a7af4fc7aa90
7
+ data.tar.gz: 77fa6fd1b0c27b045cca42ec681ae51e3042fa89c45c602bdd509f78126920da694d85582089805cf753ce9792aef21177ee9cfe745e268bd36e6be62b0094b5
@@ -1,6 +1,6 @@
1
1
  module Granite
2
2
  class Controller
3
- module Translations
3
+ module Translations # :nodoc:
4
4
  def i18n_scopes
5
5
  Granite::Translations.combine_paths(projector.i18n_scopes, [*action_name, nil])
6
6
  end
@@ -1,7 +1,7 @@
1
1
  require 'action_controller'
2
2
 
3
3
  module Granite
4
- class Controller < Granite.base_controller_class
4
+ class Controller < Granite.base_controller_class # :nodoc:
5
5
  include Controller::Translations
6
6
  helper Controller::Translations
7
7
 
@@ -2,7 +2,7 @@ require 'rails/generators/base'
2
2
 
3
3
  module Granite
4
4
  module Generators
5
- class InstallControllerGenerator < Rails::Generators::Base
5
+ class InstallControllerGenerator < Rails::Generators::Base # :nodoc:
6
6
  source_root File.expand_path('../../..', __dir__)
7
7
 
8
8
  desc 'Creates a Granite::Controller for further customization'
@@ -1,4 +1,4 @@
1
- class GraniteGenerator < Rails::Generators::NamedBase
1
+ class GraniteGenerator < Rails::Generators::NamedBase # :nodoc:
2
2
  source_root File.expand_path('templates', __dir__)
3
3
 
4
4
  argument :projector, type: :string, required: false
@@ -6,7 +6,10 @@ class GraniteGenerator < Rails::Generators::NamedBase
6
6
 
7
7
  def create_action
8
8
  template 'granite_action.rb.erb', "apq/actions/#{file_path}.rb"
9
- template 'granite_business_action.rb.erb', "apq/actions/#{class_path.join('/')}/business_action.rb" unless options.collection?
9
+ unless options.collection?
10
+ template 'granite_business_action.rb.erb',
11
+ "apq/actions/#{class_path.join('/')}/business_action.rb"
12
+ end
10
13
  template 'granite_base_action.rb.erb', 'apq/actions/base_action.rb', skip: true
11
14
  template 'granite_action_spec.rb.erb', "spec/apq/actions/#{file_path}_spec.rb"
12
15
  empty_directory "apq/actions/#{file_path}/#{projector}" if projector
@@ -2,7 +2,7 @@ require 'granite/error'
2
2
 
3
3
  module Granite
4
4
  class Action
5
- class Error < Granite::Error
5
+ class Error < Granite::Error # :nodoc:
6
6
  attr_reader :action
7
7
 
8
8
  def initialize(message, action = nil)
@@ -1,6 +1,6 @@
1
1
  module Granite
2
2
  class Action
3
- module ExceptionsHandling
3
+ module ExceptionsHandling # :nodoc:
4
4
  extend ActiveSupport::Concern
5
5
 
6
6
  included do
@@ -10,7 +10,7 @@ module Granite
10
10
  protected :_exception_handlers
11
11
  end
12
12
 
13
- module ClassMethods
13
+ module ClassMethods # :nodoc:
14
14
  # Register default handler for exceptions thrown inside execute_perform! and after_commit methods.
15
15
  # @param klass Exception class, could be parent class too [Class]
16
16
  # @param block [Block<Exception>] with default behavior for handling specified
@@ -28,11 +28,11 @@ module Granite
28
28
  _exception_handlers.keys
29
29
  end
30
30
 
31
- def handle_exception(e)
32
- klass = e.class.ancestors.detect do |ancestor|
31
+ def handle_exception(exception)
32
+ klass = exception.class.ancestors.detect do |ancestor|
33
33
  ancestor <= Exception && _exception_handlers[ancestor]
34
34
  end
35
- instance_exec(e, &_exception_handlers[klass]) if klass
35
+ instance_exec(exception, &_exception_handlers[klass]) if klass
36
36
  end
37
37
  end
38
38
  end
@@ -1,6 +1,6 @@
1
1
  module Granite
2
2
  class Action
3
- module Instrumentation
3
+ module Instrumentation # :nodoc:
4
4
  def perform!(*, **)
5
5
  instrument_perform(:perform!) { super }
6
6
  end
@@ -25,9 +25,9 @@ module Granite
25
25
  define_callbacks :execute_perform
26
26
  end
27
27
 
28
- module ClassMethods
28
+ module ClassMethods # :nodoc:
29
29
  def perform(*)
30
- fail 'Perform block declaration was removed! Please declare `private def execute_perform!(*)` method'
30
+ raise 'Perform block declaration was removed! Please declare `private def execute_perform!(*)` method'
31
31
  end
32
32
  end
33
33
 
@@ -36,13 +36,16 @@ module Granite
36
36
  # database transaction. Returns the result of execute_perform! method execution
37
37
  # or true if method execution returned false or nil
38
38
  #
39
+ # @deprecated Use {#perform!} or {#try_perform!} instead
39
40
  # @param context [Symbol] can be optionally provided to define which
40
41
  # validations to test against (the context is defined on validations
41
42
  # using `:on`)
42
43
  # @return [Object] result of execute_perform! method execution or false in case of errors
43
44
  def perform(context: nil, **options)
45
+ Granite.deprecator.warn('Granite::Action#perform is deprecated, use #perform! or #try_perform! instead')
46
+
44
47
  transaction do
45
- fail Rollback unless valid?(context)
48
+ raise Rollback unless valid?(context)
46
49
 
47
50
  perform_action(**options)
48
51
  end
@@ -110,7 +113,7 @@ module Granite
110
113
  end
111
114
 
112
115
  def execute_perform!(**_options)
113
- fail NotImplementedError, "BA perform body MUST be defined for #{self}"
116
+ raise NotImplementedError, "BA perform body MUST be defined for #{self}"
114
117
  end
115
118
  end
116
119
  end
@@ -5,7 +5,7 @@ require 'granite/action/policies/required_performer_strategy'
5
5
 
6
6
  module Granite
7
7
  class Action
8
- class NotAllowedError < Error
8
+ class NotAllowedError < Error # :nodoc:
9
9
  def initialize(action)
10
10
  performer_id = "##{action.performer.id}" if action.performer.respond_to?(:id) && action.performer.id.present?
11
11
 
@@ -30,7 +30,7 @@ module Granite
30
30
  self._policies_strategy = AnyStrategy
31
31
  end
32
32
 
33
- module ClassMethods
33
+ module ClassMethods # :nodoc:
34
34
  # The simplies policy. Takes block and executes it returning
35
35
  # boolean result. Multiple policies are reduced with ||
36
36
  #
@@ -80,7 +80,7 @@ module Granite
80
80
  # Raises Granite::Action::NotAllowedError if action is not allowed
81
81
  #
82
82
  def authorize!
83
- fail Granite::Action::NotAllowedError, self unless allowed?
83
+ raise Granite::Action::NotAllowedError, self unless allowed?
84
84
 
85
85
  self
86
86
  end
@@ -1,6 +1,6 @@
1
1
  module Granite
2
2
  class Action
3
- class Precondition < BasicObject
3
+ class Precondition < BasicObject # :nodoc:
4
4
  UNDEFINED = ::Object.new.freeze
5
5
 
6
6
  def self.description(text = UNDEFINED)
@@ -17,7 +17,7 @@ module Granite
17
17
  end
18
18
 
19
19
  def call(*)
20
- fail NotImplementedError, "#call method must be implemented for #{self.class}"
20
+ raise NotImplementedError, "#call method must be implemented for #{self.class}"
21
21
  end
22
22
 
23
23
  def method_missing(method_name, *args, &blk)
@@ -1,7 +1,7 @@
1
1
  module Granite
2
2
  class Action
3
3
  module Preconditions
4
- class BasePrecondition
4
+ class BasePrecondition # :nodoc:
5
5
  def initialize(*args, &block)
6
6
  @options = args.extract_options!
7
7
  @args = args
@@ -3,7 +3,7 @@ require 'granite/action/preconditions/base_precondition'
3
3
  module Granite
4
4
  class Action
5
5
  module Preconditions
6
- class ObjectPrecondition < BasePrecondition
6
+ class ObjectPrecondition < BasePrecondition # :nodoc:
7
7
  private
8
8
 
9
9
  def _execute(context)
@@ -13,7 +13,7 @@ module Granite
13
13
  module Preconditions
14
14
  extend ActiveSupport::Concern
15
15
 
16
- class PreconditionsCollection
16
+ class PreconditionsCollection # :nodoc:
17
17
  include Enumerable
18
18
 
19
19
  delegate :each, to: :@preconditions
@@ -36,7 +36,7 @@ module Granite
36
36
  self._preconditions = PreconditionsCollection.new
37
37
  end
38
38
 
39
- module ClassMethods
39
+ module ClassMethods # :nodoc:
40
40
  # Define preconditions for current action.
41
41
  #
42
42
  # @param options [Hash] hash with
@@ -61,7 +61,7 @@ module Granite
61
61
  key = key.to_s.camelize
62
62
  Granite.precondition_namespaces.reduce(nil) do |memo, ns|
63
63
  memo || "#{ns.to_s.camelize}::#{key}Precondition".safe_constantize
64
- end || fail(NameError, "No precondition class for #{key}Precondition")
64
+ end || raise(NameError, "No precondition class for #{key}Precondition")
65
65
  end
66
66
 
67
67
  def add_preconditions_hash(*args, **options)
@@ -1,9 +1,9 @@
1
1
  module Granite
2
2
  class Action
3
- module Projectors
3
+ module Projectors # :nodoc:
4
4
  extend ActiveSupport::Concern
5
5
 
6
- class ProjectorsCollection
6
+ class ProjectorsCollection # :nodoc:
7
7
  def initialize(action_class)
8
8
  @action_class = action_class
9
9
  @storage = {}
@@ -40,9 +40,7 @@ module Granite
40
40
  redefine_const(projector_name, projector)
41
41
  redefine_const(controller_name, projector.controller_class)
42
42
 
43
- blocks.each do |block|
44
- projector.class_eval(&block)
45
- end
43
+ blocks.each { |block| projector.class_eval(&block) }
46
44
 
47
45
  projector
48
46
  end
@@ -72,7 +70,7 @@ module Granite
72
70
  end
73
71
  end
74
72
 
75
- module ClassMethods
73
+ module ClassMethods # :nodoc:
76
74
  def _projectors
77
75
  @_projectors ||= ProjectorsCollection.new(self)
78
76
  end
@@ -1,25 +1,25 @@
1
1
  module Granite
2
2
  class Action
3
- class SubjectNotFoundError < ArgumentError
3
+ class SubjectNotFoundError < ArgumentError # :nodoc:
4
4
  def initialize(action_class)
5
5
  super("Unable to initialize #{action_class} without subject provided")
6
6
  end
7
7
  end
8
8
 
9
- class SubjectTypeMismatchError < ArgumentError
9
+ class SubjectTypeMismatchError < ArgumentError # :nodoc:
10
10
  def initialize(action_class, candidate, expected)
11
11
  super("Unable to initialize #{action_class} with #{candidate} as subject, expecting instance of #{expected}")
12
12
  end
13
13
  end
14
14
 
15
- module Subject
15
+ module Subject # :nodoc:
16
16
  extend ActiveSupport::Concern
17
17
 
18
18
  included do
19
19
  class_attribute :_subject
20
20
  end
21
21
 
22
- module ClassMethods
22
+ module ClassMethods # :nodoc:
23
23
  def subject(name, *args, &block)
24
24
  reflection = reflect_on_association(name)
25
25
  reflection ||= references_one name, *args, &block
@@ -65,7 +65,7 @@ module Granite
65
65
  assign_attributes(attributes)
66
66
 
67
67
  self.subject = args.first unless args.empty?
68
- fail SubjectNotFoundError, self.class unless subject
68
+ raise SubjectNotFoundError, self.class unless subject
69
69
  rescue Granite::Form::AssociationTypeMismatch
70
70
  raise SubjectTypeMismatchError.new(self.class, args.first.class.name, reflection.klass)
71
71
  end
@@ -2,7 +2,7 @@ require 'granite/action/transaction_manager'
2
2
 
3
3
  module Granite
4
4
  class Action
5
- module Transaction
5
+ module Transaction # :nodoc:
6
6
  extend ActiveSupport::Concern
7
7
 
8
8
  included do
@@ -21,7 +21,7 @@ module Granite
21
21
  end
22
22
 
23
23
  def add_callback(callback)
24
- fail 'Start a transaction before you add callbacks on it' if depth.zero?
24
+ raise 'Start a transaction before you add callbacks on it' if depth.zero?
25
25
 
26
26
  @callbacks.last << callback
27
27
  end
@@ -46,7 +46,7 @@ module Granite
46
46
  end
47
47
 
48
48
  def finish_current(result)
49
- fail ArgumentError, 'No current transaction' if @depth.zero?
49
+ raise ArgumentError, 'No current transaction' if @depth.zero?
50
50
 
51
51
  @depth -= 1
52
52
 
@@ -58,7 +58,6 @@ module Granite
58
58
  @callbacks.pop
59
59
  end
60
60
  end
61
-
62
61
  end
63
62
  end
64
63
  end
@@ -5,7 +5,7 @@ module Granite
5
5
  class Rollback < defined?(ActiveRecord) ? ActiveRecord::Rollback : StandardError
6
6
  end
7
7
 
8
- module TransactionManager
8
+ module TransactionManager # :nodoc:
9
9
  class << self
10
10
  # Runs a block in a transaction
11
11
  # It will open a new transaction or append a block to the current one if it exists
@@ -23,7 +23,7 @@ module Granite
23
23
  def after_commit(listener = nil, &block)
24
24
  callback = listener || block
25
25
 
26
- fail 'Block or object is required to register after_commit hook!' unless callback
26
+ raise 'Block or object is required to register after_commit hook!' unless callback
27
27
 
28
28
  transactions_stack.add_callback callback
29
29
  end
@@ -70,12 +70,13 @@ module Granite
70
70
  return unless collected_errors.any?
71
71
 
72
72
  log_errors(collected_errors[1..])
73
- fail collected_errors.first
73
+ raise collected_errors.first
74
74
  end
75
75
 
76
76
  def log_errors(errors)
77
77
  errors.each do |error|
78
- Granite::Form.config.logger.error "Unhandled error in callback: #{error.inspect}\n#{error.backtrace.join("\n")}"
78
+ message = "Unhandled error in after_commit callback: #{error.inspect}\n#{error.backtrace.join("\n")}"
79
+ Granite::Form.config.logger.error message
79
80
  end
80
81
  end
81
82
  end
@@ -1,9 +1,9 @@
1
1
  module Granite
2
2
  class Action
3
- module Translations
3
+ module Translations # :nodoc:
4
4
  extend ActiveSupport::Concern
5
5
 
6
- module ClassMethods
6
+ module ClassMethods # :nodoc:
7
7
  def i18n_scope
8
8
  :granite_action
9
9
  end
@@ -15,13 +15,16 @@ require 'granite/action/subject'
15
15
  require 'granite/action/translations'
16
16
 
17
17
  module Granite
18
- class Action
19
- class ValidationError < Error
18
+ class Action # :nodoc:
19
+ class ValidationError < Error # :nodoc:
20
20
  delegate :errors, to: :action
21
21
 
22
22
  def initialize(action)
23
23
  errors = action.errors.full_messages.join(', ')
24
- super(I18n.t(:"#{action.class.i18n_scope}.errors.messages.action_invalid", action: action.class, errors: errors, default: :'errors.messages.action_invalid'), action)
24
+ super(I18n.t(:"#{action.class.i18n_scope}.errors.messages.action_invalid",
25
+ action: action.class,
26
+ errors: errors,
27
+ default: :'errors.messages.action_invalid'), action)
25
28
  end
26
29
  end
27
30
 
@@ -102,7 +105,7 @@ module Granite
102
105
  protected
103
106
 
104
107
  def raise_validation_error(original_error = nil)
105
- fail ValidationError, self, original_error&.backtrace
108
+ raise ValidationError, self, original_error&.backtrace
106
109
  end
107
110
  end
108
111
  end
@@ -1,5 +1,5 @@
1
1
  module Granite
2
- module AssignData
2
+ module AssignData # :nodoc:
3
3
  DataAssignment = Struct.new(:method, :options) # rubocop:disable Lint/StructNewOverride
4
4
 
5
5
  extend ActiveSupport::Concern
@@ -14,7 +14,7 @@ module Granite
14
14
  assign_data :sync_attributes
15
15
  end
16
16
 
17
- module ClassMethods
17
+ module ClassMethods # :nodoc:
18
18
  # Defines a callback to call when assigning data from business action to model.
19
19
  # @param methods [Array<Symbol>] list of methods to call
20
20
  # @param block [Proc] a block to call
@@ -2,7 +2,7 @@ require 'singleton'
2
2
  require 'active_support/core_ext/object/try'
3
3
 
4
4
  module Granite
5
- class Config
5
+ class Config # :nodoc:
6
6
  include Singleton
7
7
 
8
8
  attr_accessor :base_controller
@@ -1,7 +1,7 @@
1
1
  require 'singleton'
2
2
 
3
3
  module Granite
4
- class Context
4
+ class Context # :nodoc:
5
5
  include Singleton
6
6
 
7
7
  def view_context
@@ -7,7 +7,7 @@ module Granite
7
7
  module ContextProxy
8
8
  extend ActiveSupport::Concern
9
9
 
10
- module ClassMethods
10
+ module ClassMethods # :nodoc:
11
11
  PROXY_CONTEXT_KEY = :granite_proxy_context
12
12
 
13
13
  def with(data)
@@ -1,64 +1,67 @@
1
1
  require 'memoist'
2
2
  require 'action_controller/metal/exceptions'
3
3
 
4
- class Granite::Dispatcher
5
- extend Memoist
4
+ module Granite
5
+ class Dispatcher # :nodoc:
6
+ extend Memoist
6
7
 
7
- # Make dispatcher object pristine, clean memoist cache.
8
- def reset!
9
- unmemoize_all
10
- end
8
+ # Make dispatcher object pristine, clean memoist cache.
9
+ def reset!
10
+ unmemoize_all
11
+ end
11
12
 
12
- def call(*)
13
- # Pretend to be a Rack app, however we are still dispatcher, so this method should never be called
14
- # see lib/granite/routing/mapping.rb for more info.
15
- fail 'Dispatcher can\'t be used as a Rack app.'
16
- end
13
+ def call(*)
14
+ # Pretend to be a Rack app, however we are still dispatcher, so this method should never be called
15
+ # see lib/granite/routing/mapping.rb for more info.
16
+ raise 'Dispatcher can\'t be used as a Rack app.'
17
+ end
17
18
 
18
- def serve(req)
19
- controller, action = detect_controller_class_and_action_name(req)
20
- controller.action(action).call(req.env)
21
- end
19
+ def serve(req)
20
+ controller, action = detect_controller_class_and_action_name(req)
21
+ controller.action(action).call(req.env)
22
+ end
22
23
 
23
- def constraints
24
- [->(req) { detect_controller_class_and_action_name(req).all?(&:present?) }]
25
- end
24
+ def constraints
25
+ [->(req) { detect_controller_class_and_action_name(req).all?(&:present?) }]
26
+ end
26
27
 
27
- def controller(params, *_args)
28
- projector(*params.values_at(:granite_action, :granite_projector))&.controller_class
29
- end
28
+ def controller(params, *_args)
29
+ projector(*params.values_at(:granite_action, :granite_projector))&.controller_class
30
+ end
30
31
 
31
- def prepare_params!(params, *_args)
32
- params
33
- end
32
+ def prepare_params!(params, *_args)
33
+ params
34
+ end
34
35
 
35
- private
36
+ private
36
37
 
37
- def detect_controller_class_and_action_name(req)
38
- [
39
- controller(req.params),
40
- action_name(
41
- req.request_method_symbol,
42
- *req.params.values_at(:granite_action, :granite_projector, :projector_action)
43
- )
44
- ]
45
- end
38
+ def detect_controller_class_and_action_name(req)
39
+ [
40
+ controller(req.params),
41
+ action_name(
42
+ req.request_method_symbol,
43
+ *req.params.values_at(:granite_action, :granite_projector, :projector_action)
44
+ )
45
+ ]
46
+ end
46
47
 
47
- memoize def action_name(request_method_symbol, granite_action, granite_projector, projector_action)
48
- projector = projector(granite_action, granite_projector)
49
- return unless projector
48
+ memoize def action_name(request_method_symbol, granite_action, granite_projector, projector_action)
49
+ projector = projector(granite_action, granite_projector)
50
+ return unless projector
50
51
 
51
- projector.action_for(request_method_symbol, projector_action.to_s)
52
- end
52
+ projector.action_for(request_method_symbol, projector_action.to_s)
53
+ end
53
54
 
54
- memoize def projector(granite_action, granite_projector)
55
- action = business_action(granite_action)
55
+ memoize def projector(granite_action, granite_projector)
56
+ action = business_action(granite_action)
56
57
 
57
- action.public_send(granite_projector) if action.respond_to?(granite_projector)
58
- end
58
+ action.public_send(granite_projector) if action.respond_to?(granite_projector)
59
+ end
59
60
 
60
- memoize def business_action(granite_action)
61
- granite_action.camelize.safe_constantize ||
62
- fail(ActionController::RoutingError, "Granite action '#{granite_action}' is mounted but class '#{granite_action.camelize}' can't be found")
61
+ memoize def business_action(granite_action)
62
+ granite_action.camelize.safe_constantize ||
63
+ raise(ActionController::RoutingError,
64
+ "Granite action '#{granite_action}' is mounted but class '#{granite_action.camelize}' can't be found")
65
+ end
63
66
  end
64
67
  end
@@ -2,7 +2,7 @@ require 'action_dispatch/routing'
2
2
 
3
3
  module Granite
4
4
  class Projector
5
- module ControllerActions
5
+ module ControllerActions # :nodoc:
6
6
  extend ActiveSupport::Concern
7
7
 
8
8
  included do
@@ -16,8 +16,8 @@ module Granite
16
16
  end
17
17
  end
18
18
 
19
- module ClassMethods
20
- def action(name, options = {}, &block)
19
+ module ClassMethods # :nodoc:
20
+ def action(name, options = {}, &block) # rubocop:disable Metrics/MethodLength
21
21
  if block
22
22
  self.controller_actions = controller_actions.merge(name.to_sym => options)
23
23
  controller_class.__send__(:define_method, name, &block)
@@ -2,7 +2,7 @@ require 'granite/error'
2
2
 
3
3
  module Granite
4
4
  class Projector
5
- class Error < Granite::Error
5
+ class Error < Granite::Error # :nodoc:
6
6
  attr_reader :projector
7
7
 
8
8
  def initialize(message, projector = nil)
@@ -2,14 +2,14 @@ require 'granite/projector/error'
2
2
 
3
3
  module Granite
4
4
  class Projector
5
- class ActionNotMountedError < Error
5
+ class ActionNotMountedError < Error # :nodoc:
6
6
  def initialize(projector)
7
7
  super("Seems like #{projector.class} was not mounted. \
8
8
  Do you have #{projector.action_name}##{projector.projector_name} declared in routes?", projector)
9
9
  end
10
10
  end
11
11
 
12
- module Helpers
12
+ module Helpers # :nodoc:
13
13
  extend ActiveSupport::Concern
14
14
 
15
15
  def view_context
@@ -35,7 +35,7 @@ Do you have #{projector.action_name}##{projector.projector_name} declared in rou
35
35
 
36
36
  def required_params
37
37
  corresponding_route.required_parts
38
- .to_h { |name| [name, action.public_send(name)] }
38
+ .to_h { |name| [name, action.public_send(name)] }
39
39
  end
40
40
 
41
41
  def corresponding_route
@@ -51,7 +51,7 @@ Do you have #{projector.action_name}##{projector.projector_name} declared in rou
51
51
  end
52
52
 
53
53
  def fetch_corresponding_route
54
- Rails.application.routes.routes.granite_cache[*route_id] || fail(ActionNotMountedError, self)
54
+ Rails.application.routes.routes.granite_cache[*route_id] || raise(ActionNotMountedError, self)
55
55
  end
56
56
  end
57
57
  end
@@ -1,6 +1,6 @@
1
1
  module Granite
2
2
  class Projector
3
- module Translations
3
+ module Translations # :nodoc:
4
4
  include ActionView::Helpers::TranslationHelper
5
5
 
6
6
  def i18n_scopes
@@ -5,7 +5,7 @@ require 'granite/projector/translations'
5
5
  require 'granite/context_proxy'
6
6
 
7
7
  module Granite
8
- class Projector
8
+ class Projector # :nodoc:
9
9
  include ContextProxy
10
10
  include ControllerActions
11
11
  include Helpers
@@ -1,6 +1,6 @@
1
1
  module Granite
2
2
  module Routing
3
- class Cache
3
+ class Cache # :nodoc:
4
4
  attr_reader :routes
5
5
 
6
6
  def initialize(routes)
@@ -2,7 +2,7 @@ require 'granite/routing/cache'
2
2
 
3
3
  module Granite
4
4
  module Routing
5
- module Caching
5
+ module Caching # :nodoc:
6
6
  def granite_cache
7
7
  @granite_cache ||= Cache.new(self)
8
8
  end
@@ -1,6 +1,6 @@
1
1
  module Granite
2
2
  module Routing
3
- module Declarer
3
+ module Declarer # :nodoc:
4
4
  class << self
5
5
  def declare(routing, route, **options)
6
6
  routing.match route.path,
@@ -3,7 +3,7 @@ require 'granite/routing/route'
3
3
 
4
4
  module Granite
5
5
  module Routing
6
- module Mapper
6
+ module Mapper # :nodoc:
7
7
  def granite(projector_path, **options)
8
8
  route = Route.new(projector_path, **options.extract!(:path, :as, :projector_prefix))
9
9
  Declarer.declare(self, route, **options)
@@ -1,6 +1,6 @@
1
1
  module Granite
2
2
  module Routing
3
- module Mapping
3
+ module Mapping # :nodoc:
4
4
  # Override the `ActionDispatch::Routing::Mapper::Mapping#app` method to
5
5
  # be able to mount custom Dispatcher objects. Otherwise, the only way to
6
6
  # point a dispatcher to business actions is to mount it as a Rack app
@@ -1,6 +1,6 @@
1
1
  module Granite
2
2
  module Routing
3
- class Route
3
+ class Route # :nodoc:
4
4
  attr_reader :projector_path, :action_path, :projector_name
5
5
 
6
6
  def initialize(projector_path, path: nil, as: nil, projector_prefix: false)
@@ -1,8 +1,12 @@
1
- module Granite::ActionHelpers
2
- extend ActiveSupport::Concern
1
+ module Granite
2
+ module ActionHelpers # :nodoc:
3
+ extend ActiveSupport::Concern
3
4
 
4
- delegate :perform!, to: :subject
5
+ delegate :perform!, to: :subject
6
+ end
5
7
  end
6
8
 
7
- RSpec.configuration.define_derived_metadata(file_path: %r{spec/apq/actions/}) { |metadata| metadata[:type] ||= :granite_action }
9
+ RSpec.configuration.define_derived_metadata(file_path: %r{spec/apq/actions/}) do |metadata|
10
+ metadata[:type] ||= :granite_action
11
+ end
8
12
  RSpec.configuration.include Granite::ActionHelpers, type: :granite_action
@@ -1,4 +1,4 @@
1
- RSpec::Matchers.define :perform_action do |klass|
1
+ RSpec::Matchers.define :perform_action do |klass| # rubocop:disable Metrics/BlockLength
2
2
  chain :using do |using|
3
3
  @using = using
4
4
  end
@@ -1,54 +1,59 @@
1
- module Granite::ProjectorHelpers
2
- extend ActiveSupport::Concern
3
- include RSpec::Rails::ControllerExampleGroup
1
+ module Granite
2
+ module ProjectorHelpers # :nodoc:
3
+ extend ActiveSupport::Concern
4
+ include RSpec::Rails::ControllerExampleGroup
4
5
 
5
- included do
6
- before { Granite::Routing::Declarer.dispatcher.unmemoize_all }
7
- end
6
+ included do
7
+ before { Granite::Routing::Declarer.dispatcher.unmemoize_all }
8
+ end
8
9
 
9
- module ClassMethods
10
- def draw_routes(&block)
11
- before(:all) do
12
- routes = Rails.application.routes
13
- routes.disable_clear_and_finalize = true
14
- routes.draw(&block)
10
+ module ClassMethods # :nodoc:
11
+ def draw_routes(&block)
12
+ before(:all) do
13
+ routes = Rails.application.routes
14
+ routes.disable_clear_and_finalize = true
15
+ routes.draw(&block)
16
+ end
17
+
18
+ after(:all) do
19
+ Rails.application.routes.disable_clear_and_finalize = false
20
+ Rails.application.reload_routes!
21
+ Rails.application.routes.routes.clear_cache!
22
+ end
15
23
  end
16
24
 
17
- after(:all) do
18
- Rails.application.routes.disable_clear_and_finalize = false
19
- Rails.application.reload_routes!
20
- Rails.application.routes.routes.clear_cache!
25
+ def projector(&block)
26
+ setup_controller
27
+ setup_view_context
28
+ let(:projector_class, &block)
29
+ let(:projector) { controller.projector }
21
30
  end
22
- end
23
31
 
24
- def projector(&block)
25
- setup_controller
26
- setup_view_context
27
- let(:projector_class, &block)
28
- let(:projector) { controller.projector }
29
- end
32
+ private
30
33
 
31
- private
34
+ def setup_controller
35
+ define_method :setup_controller_request_and_response do
36
+ @controller ||= projector_class.controller_class.new
37
+ super()
38
+ end
39
+ end
32
40
 
33
- def setup_controller
34
- define_method :setup_controller_request_and_response do
35
- @controller ||= projector_class.controller_class.new
36
- super()
41
+ def setup_view_context
42
+ before { Granite.view_context = controller.view_context }
43
+ after { Granite.view_context = nil }
37
44
  end
38
45
  end
39
46
 
40
- def setup_view_context
41
- before { Granite.view_context = controller.view_context }
42
- after { Granite.view_context = nil }
47
+ # Overrides ActionController::TestCase::Behavior#process to include granite_action and granite_projector
48
+ def process(action, **options)
49
+ projector_params = { granite_action: projector_class.action_name,
50
+ granite_projector: projector_class.projector_name }
51
+ super(action, **options, params: projector_params.reverse_merge(options[:params] || {}))
43
52
  end
44
53
  end
45
-
46
- # Overrides ActionController::TestCase::Behavior#process to include granite_action and granite_projector
47
- def process(action, **options)
48
- projector_params = {granite_action: projector_class.action_name, granite_projector: projector_class.projector_name}
49
- super(action, **options, params: projector_params.reverse_merge(options[:params] || {}))
50
- end
51
54
  end
52
55
 
53
- RSpec.configuration.define_derived_metadata(file_path: %r{spec/apq/projectors/}) { |metadata| metadata[:type] ||= :granite_projector }
56
+ RSpec.configuration.define_derived_metadata(file_path: %r{spec/apq/projectors/}) do |metadata|
57
+ metadata[:type] ||= :granite_projector
58
+ end
54
59
  RSpec.configuration.include Granite::ProjectorHelpers, type: :granite_projector
@@ -38,13 +38,9 @@ RSpec::Matchers.define :raise_validation_error do
38
38
  expected
39
39
  end
40
40
 
41
- failure_message do
42
- "expected to #{description}"
43
- end
41
+ failure_message { "expected to #{description}" }
44
42
 
45
- failure_message_when_negated do
46
- "expected not to #{description}"
47
- end
43
+ failure_message_when_negated { "expected not to #{description}" }
48
44
 
49
45
  supports_block_expectations
50
46
  end
@@ -16,13 +16,13 @@
16
16
  # ```ruby
17
17
  # # assuming subject is business action
18
18
  # it { is_expected.to satisfy_preconditions }
19
- # it { is_expected.not_to satisfy_preconditions.with_message('Tax form has not been signed') }
20
- # it { is_expected.not_to satisfy_preconditions.with_messages(/^Tax form has not been signed by/', 'Signature required') }
21
- # it { is_expected.not_to satisfy_preconditions.with_message_of_kind(:relevant_portfolio_items_needed) }
22
- # it { is_expected.not_to satisfy_preconditions.with_messages_of_kinds(:relevant_portfolio_items_needed, :relevant_education_needed) }
19
+ # it { is_expected.not_to satisfy_preconditions.with_message('Form has not been signed') }
20
+ # it { is_expected.not_to satisfy_preconditions.with_messages(/^Form has not been signed by/', 'Signature required') }
21
+ # it { is_expected.not_to satisfy_preconditions.with_message_of_kind(:portfolio_needed) }
22
+ # it { is_expected.not_to satisfy_preconditions.with_messages_of_kinds(:portfolio_needed, :relevant_education_needed) }
23
23
  # ```
24
24
  #
25
- RSpec::Matchers.define :satisfy_preconditions do
25
+ RSpec::Matchers.define :satisfy_preconditions do # rubocop:disable Metrics/BlockLength
26
26
  chain(:with_message) do |message|
27
27
  @expected_messages = [message]
28
28
  end
@@ -44,7 +44,7 @@ RSpec::Matchers.define :satisfy_preconditions do
44
44
  end
45
45
 
46
46
  match do |object|
47
- fail '"with_messages" method chain is not supported for positive matcher' if @expected_messages
47
+ raise '"with_messages" method chain is not supported for positive matcher' if @expected_messages
48
48
 
49
49
  object.satisfy_preconditions?
50
50
  end
@@ -1,5 +1,5 @@
1
1
  module Granite
2
- class Translations
2
+ class Translations # :nodoc:
3
3
  class << self
4
4
  def combine_paths(paths1, paths2)
5
5
  paths1.flat_map do |path1|
@@ -1,3 +1,3 @@
1
1
  module Granite
2
- VERSION = '0.17.1'.freeze
2
+ VERSION = '0.17.2'.freeze
3
3
  end
data/lib/granite.rb CHANGED
@@ -6,7 +6,7 @@ require 'granite/version'
6
6
  require 'granite/config'
7
7
  require 'granite/context'
8
8
 
9
- module Granite
9
+ module Granite # :nodoc:
10
10
  def self.config
11
11
  Granite::Config.instance
12
12
  end
@@ -15,6 +15,10 @@ module Granite
15
15
  Granite::Context.instance
16
16
  end
17
17
 
18
+ def self.deprecator
19
+ @deprecator ||= ActiveSupport::Deprecation.new('1.0.0', 'Granite')
20
+ end
21
+
18
22
  singleton_class.delegate(*Granite::Config.delegated, to: :config)
19
23
  singleton_class.delegate(*Granite::Context.delegated, to: :context)
20
24
  end
@@ -1,5 +1,3 @@
1
- # frozen_string_literal: true
2
-
3
1
  # The original code is from https://github.com/rubocop-hq/rubocop-rspec/blob/master/lib/rubocop/rspec/inject.rb
4
2
  # See https://github.com/rubocop-hq/rubocop-rspec/blob/master/MIT-LICENSE.md
5
3
  module RuboCop
@@ -11,7 +9,7 @@ module RuboCop
11
9
  path = CONFIG_DEFAULT.to_s
12
10
  hash = ConfigLoader.load_file(path)
13
11
  config = Config.new(hash, path).tap(&:make_excludes_absolute)
14
- puts "configuration from #{path}" if ConfigLoader.debug?
12
+ Rails.logger.debug { "configuration from #{path}" } if ConfigLoader.debug?
15
13
  config = ConfigLoader.merge_with_default(config, path)
16
14
  ConfigLoader.instance_variable_set(:@default_configuration, config)
17
15
  end
@@ -1,5 +1,5 @@
1
1
  module RuboCop
2
- module Granite
2
+ module Granite # :nodoc:
3
3
  PROJECT_ROOT = Pathname.new(__dir__).parent.parent.expand_path.freeze
4
4
  CONFIG_DEFAULT = PROJECT_ROOT.join('config', 'rubocop-default.yml').freeze
5
5
  CONFIG = YAML.safe_load(CONFIG_DEFAULT.read).freeze
@@ -1,5 +1,3 @@
1
- # frozen_string_literal: true
2
-
3
1
  require 'rubocop'
4
2
 
5
3
  require_relative 'rubocop/granite'
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.17.1
4
+ version: 0.17.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Toptal Engineering
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-01-19 00:00:00.000000000 Z
11
+ date: 2024-05-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: actionpack
@@ -31,39 +31,39 @@ dependencies:
31
31
  - !ruby/object:Gem::Version
32
32
  version: '7.2'
33
33
  - !ruby/object:Gem::Dependency
34
- name: granite-form
34
+ name: activesupport
35
35
  requirement: !ruby/object:Gem::Requirement
36
36
  requirements:
37
37
  - - ">="
38
38
  - !ruby/object:Gem::Version
39
- version: 0.3.0
39
+ version: '6.0'
40
+ - - "<"
41
+ - !ruby/object:Gem::Version
42
+ version: '7.2'
40
43
  type: :runtime
41
44
  prerelease: false
42
45
  version_requirements: !ruby/object:Gem::Requirement
43
46
  requirements:
44
47
  - - ">="
45
48
  - !ruby/object:Gem::Version
46
- version: 0.3.0
49
+ version: '6.0'
50
+ - - "<"
51
+ - !ruby/object:Gem::Version
52
+ version: '7.2'
47
53
  - !ruby/object:Gem::Dependency
48
- name: activesupport
54
+ name: granite-form
49
55
  requirement: !ruby/object:Gem::Requirement
50
56
  requirements:
51
57
  - - ">="
52
58
  - !ruby/object:Gem::Version
53
- version: '6.0'
54
- - - "<"
55
- - !ruby/object:Gem::Version
56
- version: '7.2'
59
+ version: 0.3.0
57
60
  type: :runtime
58
61
  prerelease: false
59
62
  version_requirements: !ruby/object:Gem::Requirement
60
63
  requirements:
61
64
  - - ">="
62
65
  - !ruby/object:Gem::Version
63
- version: '6.0'
64
- - - "<"
65
- - !ruby/object:Gem::Version
66
- version: '7.2'
66
+ version: 0.3.0
67
67
  - !ruby/object:Gem::Dependency
68
68
  name: memoist
69
69
  requirement: !ruby/object:Gem::Requirement
@@ -233,75 +233,75 @@ dependencies:
233
233
  - !ruby/object:Gem::Version
234
234
  version: '1.2'
235
235
  - !ruby/object:Gem::Dependency
236
- name: rspec-rails
236
+ name: rspec_junit_formatter
237
237
  requirement: !ruby/object:Gem::Requirement
238
238
  requirements:
239
239
  - - "~>"
240
240
  - !ruby/object:Gem::Version
241
- version: '6.0'
241
+ version: '0.2'
242
242
  type: :development
243
243
  prerelease: false
244
244
  version_requirements: !ruby/object:Gem::Requirement
245
245
  requirements:
246
246
  - - "~>"
247
247
  - !ruby/object:Gem::Version
248
- version: '6.0'
248
+ version: '0.2'
249
249
  - !ruby/object:Gem::Dependency
250
- name: rspec_junit_formatter
250
+ name: rspec-rails
251
251
  requirement: !ruby/object:Gem::Requirement
252
252
  requirements:
253
253
  - - "~>"
254
254
  - !ruby/object:Gem::Version
255
- version: '0.2'
255
+ version: '6.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.2'
262
+ version: '6.0'
263
263
  - !ruby/object:Gem::Dependency
264
264
  name: rubocop
265
265
  requirement: !ruby/object:Gem::Requirement
266
266
  requirements:
267
267
  - - "~>"
268
268
  - !ruby/object:Gem::Version
269
- version: '1.0'
269
+ version: 1.63.5
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: '1.0'
276
+ version: 1.63.5
277
277
  - !ruby/object:Gem::Dependency
278
278
  name: rubocop-rails
279
279
  requirement: !ruby/object:Gem::Requirement
280
280
  requirements:
281
281
  - - "~>"
282
282
  - !ruby/object:Gem::Version
283
- version: '2.13'
283
+ version: 2.25.0
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: '2.13'
290
+ version: 2.25.0
291
291
  - !ruby/object:Gem::Dependency
292
292
  name: rubocop-rspec
293
293
  requirement: !ruby/object:Gem::Requirement
294
294
  requirements:
295
295
  - - "~>"
296
296
  - !ruby/object:Gem::Version
297
- version: '2.8'
297
+ version: 2.29.2
298
298
  type: :development
299
299
  prerelease: false
300
300
  version_requirements: !ruby/object:Gem::Requirement
301
301
  requirements:
302
302
  - - "~>"
303
303
  - !ruby/object:Gem::Version
304
- version: '2.8'
304
+ version: 2.29.2
305
305
  - !ruby/object:Gem::Dependency
306
306
  name: simplecov
307
307
  requirement: !ruby/object:Gem::Requirement
@@ -392,7 +392,8 @@ files:
392
392
  homepage: https://github.com/toptal/granite
393
393
  licenses:
394
394
  - MIT
395
- metadata: {}
395
+ metadata:
396
+ rubygems_mfa_required: 'true'
396
397
  post_install_message:
397
398
  rdoc_options: []
398
399
  require_paths:
@@ -401,14 +402,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
401
402
  requirements:
402
403
  - - ">="
403
404
  - !ruby/object:Gem::Version
404
- version: '2.5'
405
+ version: '2.6'
405
406
  required_rubygems_version: !ruby/object:Gem::Requirement
406
407
  requirements:
407
408
  - - ">="
408
409
  - !ruby/object:Gem::Version
409
410
  version: '0'
410
411
  requirements: []
411
- rubygems_version: 3.1.6
412
+ rubygems_version: 3.5.10
412
413
  signing_key:
413
414
  specification_version: 4
414
415
  summary: Another business actions architecture for Rails apps