granite 0.17.1 → 0.17.2

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.
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