micro-max-box 0.0.1

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 (55) hide show
  1. checksums.yaml +7 -0
  2. data/aasm-6.0.0/CHANGELOG.md +497 -0
  3. data/aasm-6.0.0/LICENSE +20 -0
  4. data/aasm-6.0.0/README.md +1534 -0
  5. data/aasm-6.0.0/lib/aasm/aasm.rb +208 -0
  6. data/aasm-6.0.0/lib/aasm/base.rb +300 -0
  7. data/aasm-6.0.0/lib/aasm/configuration.rb +48 -0
  8. data/aasm-6.0.0/lib/aasm/core/event.rb +178 -0
  9. data/aasm-6.0.0/lib/aasm/core/invoker.rb +129 -0
  10. data/aasm-6.0.0/lib/aasm/core/invokers/base_invoker.rb +85 -0
  11. data/aasm-6.0.0/lib/aasm/core/invokers/class_invoker.rb +75 -0
  12. data/aasm-6.0.0/lib/aasm/core/invokers/literal_invoker.rb +90 -0
  13. data/aasm-6.0.0/lib/aasm/core/invokers/proc_invoker.rb +94 -0
  14. data/aasm-6.0.0/lib/aasm/core/state.rb +91 -0
  15. data/aasm-6.0.0/lib/aasm/core/transition.rb +83 -0
  16. data/aasm-6.0.0/lib/aasm/dsl_helper.rb +32 -0
  17. data/aasm-6.0.0/lib/aasm/errors.rb +22 -0
  18. data/aasm-6.0.0/lib/aasm/instance_base.rb +153 -0
  19. data/aasm-6.0.0/lib/aasm/localizer.rb +64 -0
  20. data/aasm-6.0.0/lib/aasm/minitest/allow_event.rb +13 -0
  21. data/aasm-6.0.0/lib/aasm/minitest/allow_transition_to.rb +13 -0
  22. data/aasm-6.0.0/lib/aasm/minitest/have_state.rb +13 -0
  23. data/aasm-6.0.0/lib/aasm/minitest/transition_from.rb +21 -0
  24. data/aasm-6.0.0/lib/aasm/minitest.rb +5 -0
  25. data/aasm-6.0.0/lib/aasm/minitest_spec.rb +15 -0
  26. data/aasm-6.0.0/lib/aasm/persistence/active_record_persistence.rb +174 -0
  27. data/aasm-6.0.0/lib/aasm/persistence/base.rb +89 -0
  28. data/aasm-6.0.0/lib/aasm/persistence/core_data_query_persistence.rb +94 -0
  29. data/aasm-6.0.0/lib/aasm/persistence/dynamoid_persistence.rb +92 -0
  30. data/aasm-6.0.0/lib/aasm/persistence/mongoid_persistence.rb +126 -0
  31. data/aasm-6.0.0/lib/aasm/persistence/no_brainer_persistence.rb +105 -0
  32. data/aasm-6.0.0/lib/aasm/persistence/orm.rb +154 -0
  33. data/aasm-6.0.0/lib/aasm/persistence/plain_persistence.rb +26 -0
  34. data/aasm-6.0.0/lib/aasm/persistence/redis_persistence.rb +112 -0
  35. data/aasm-6.0.0/lib/aasm/persistence/sequel_persistence.rb +83 -0
  36. data/aasm-6.0.0/lib/aasm/persistence.rb +54 -0
  37. data/aasm-6.0.0/lib/aasm/rspec/allow_event.rb +26 -0
  38. data/aasm-6.0.0/lib/aasm/rspec/allow_transition_to.rb +26 -0
  39. data/aasm-6.0.0/lib/aasm/rspec/have_state.rb +22 -0
  40. data/aasm-6.0.0/lib/aasm/rspec/transition_from.rb +36 -0
  41. data/aasm-6.0.0/lib/aasm/rspec.rb +5 -0
  42. data/aasm-6.0.0/lib/aasm/state_machine.rb +53 -0
  43. data/aasm-6.0.0/lib/aasm/state_machine_store.rb +77 -0
  44. data/aasm-6.0.0/lib/aasm/version.rb +3 -0
  45. data/aasm-6.0.0/lib/aasm.rb +21 -0
  46. data/aasm-6.0.0/lib/generators/aasm/aasm_generator.rb +16 -0
  47. data/aasm-6.0.0/lib/generators/aasm/orm_helpers.rb +41 -0
  48. data/aasm-6.0.0/lib/generators/active_record/aasm_generator.rb +40 -0
  49. data/aasm-6.0.0/lib/generators/active_record/templates/migration.rb +8 -0
  50. data/aasm-6.0.0/lib/generators/active_record/templates/migration_existing.rb +5 -0
  51. data/aasm-6.0.0/lib/generators/mongoid/aasm_generator.rb +28 -0
  52. data/aasm-6.0.0/lib/generators/nobrainer/aasm_generator.rb +28 -0
  53. data/aasm-6.0.0/lib/motion-aasm.rb +37 -0
  54. data/micro-max-box.gemspec +12 -0
  55. metadata +94 -0
@@ -0,0 +1,178 @@
1
+ # frozen_string_literal: true
2
+
3
+ module AASM::Core
4
+ class Event
5
+ include AASM::DslHelper
6
+
7
+ attr_reader :name, :state_machine, :options, :default_display_name
8
+
9
+ def initialize(name, state_machine, options = {}, &block)
10
+ @name = name
11
+ @state_machine = state_machine
12
+ @transitions = []
13
+ @valid_transitions = Hash.new { |h, k| h[k] = {} }
14
+ @guards = Array(options[:guard] || options[:guards] || options[:if])
15
+ @unless = Array(options[:unless]) #TODO: This could use a better name
16
+ @default_display_name = name.to_s.gsub(/_/, ' ').capitalize
17
+
18
+ # from aasm4
19
+ @options = options # QUESTION: .dup ?
20
+ add_options_from_dsl(@options, [
21
+ :after,
22
+ :after_commit,
23
+ :after_transaction,
24
+ :before,
25
+ :before_transaction,
26
+ :ensure,
27
+ :error,
28
+ :before_success,
29
+ :success,
30
+ ], &block) if block
31
+ end
32
+
33
+ # called internally by Ruby 1.9 after clone()
34
+ def initialize_copy(orig)
35
+ super
36
+ @transitions = @transitions.collect { |transition| transition.clone }
37
+ @guards = @guards.dup
38
+ @unless = @unless.dup
39
+ @options = {}
40
+ orig.options.each_pair { |name, setting| @options[name] = setting.is_a?(Hash) || setting.is_a?(Array) ? setting.dup : setting }
41
+ end
42
+
43
+ # a neutered version of fire - it doesn't actually fire the event, it just
44
+ # executes the transition guards to determine if a transition is even
45
+ # an option given current conditions.
46
+ def may_fire?(obj, to_state=::AASM::NO_VALUE, *args)
47
+ _fire(obj, {:test_only => true}, to_state, *args) # true indicates test firing
48
+ end
49
+
50
+ def fire(obj, options={}, to_state=::AASM::NO_VALUE, *args)
51
+ _fire(obj, options, to_state, *args) # false indicates this is not a test (fire!)
52
+ end
53
+
54
+ def transitions_from_state?(state)
55
+ transitions_from_state(state).any?
56
+ end
57
+
58
+ def transitions_from_state(state)
59
+ @transitions.select { |t| t.from.nil? or t.from == state }
60
+ end
61
+
62
+ def transitions_to_state?(state)
63
+ transitions_to_state(state).any?
64
+ end
65
+
66
+ def transitions_to_state(state)
67
+ @transitions.select { |t| t.to == state }
68
+ end
69
+
70
+ def fire_global_callbacks(callback_name, record, *args)
71
+ invoke_callbacks(state_machine.global_callbacks[callback_name], record, args)
72
+ end
73
+
74
+ def fire_callbacks(callback_name, record, *args)
75
+ # strip out the first element in args if it's a valid to_state
76
+ # #given where we're coming from, this condition implies args not empty
77
+ invoke_callbacks(@options[callback_name], record, args)
78
+ end
79
+
80
+ def fire_transition_callbacks(obj, *args)
81
+ from_state = obj.aasm(state_machine.name).current_state
82
+ transition = @valid_transitions[obj.object_id][from_state]
83
+ transition.invoke_success_callbacks(obj, *args) if transition
84
+ @valid_transitions.delete(obj.object_id)
85
+ end
86
+
87
+ def ==(event)
88
+ if event.is_a? Symbol
89
+ name == event
90
+ else
91
+ name == event.name
92
+ end
93
+ end
94
+
95
+ ## DSL interface
96
+ def transitions(definitions=nil, &block)
97
+ if definitions # define new transitions
98
+ # Create a separate transition for each from-state to the given state
99
+ Array(definitions[:from]).each do |s|
100
+ @transitions << AASM::Core::Transition.new(self, attach_event_guards(definitions.merge(:from => s.to_sym)), &block)
101
+ end
102
+ # Create a transition if :to is specified without :from (transitions from ANY state)
103
+ if !definitions[:from] && definitions[:to]
104
+ @transitions << AASM::Core::Transition.new(self, attach_event_guards(definitions), &block)
105
+ end
106
+ end
107
+ @transitions
108
+ end
109
+
110
+ def failed_callbacks
111
+ transitions.flat_map(&:failures)
112
+ end
113
+
114
+ def to_s
115
+ name.to_s
116
+ end
117
+
118
+ private
119
+
120
+ def attach_event_guards(definitions)
121
+ unless @guards.empty?
122
+ given_guards = Array(definitions.delete(:guard) || definitions.delete(:guards) || definitions.delete(:if))
123
+ definitions[:guards] = @guards + given_guards # from aasm4
124
+ end
125
+ unless @unless.empty?
126
+ given_unless = Array(definitions.delete(:unless))
127
+ definitions[:unless] = given_unless + @unless
128
+ end
129
+ definitions
130
+ end
131
+
132
+ def _fire(obj, options={}, to_state=::AASM::NO_VALUE, *args)
133
+ result = options[:test_only] ? false : nil
134
+ clear_failed_callbacks
135
+ transitions = @transitions.select { |t| t.from == obj.aasm(state_machine.name).current_state || t.from == nil}
136
+ return result if transitions.size == 0
137
+
138
+ if to_state == ::AASM::NO_VALUE
139
+ to_state = nil
140
+ elsif !(to_state.respond_to?(:to_sym) && transitions.map(&:to).flatten.include?(to_state.to_sym))
141
+ # to_state is an argument
142
+ args.unshift(to_state)
143
+ to_state = nil
144
+ end
145
+
146
+ # nop, to_state is a valid to-state
147
+
148
+ transitions.each do |transition|
149
+ next if to_state and !Array(transition.to).include?(to_state)
150
+ if (options.key?(:may_fire) && transition.eql?(options[:may_fire])) ||
151
+ (!options.key?(:may_fire) && transition.allowed?(obj, *args))
152
+
153
+ if options[:test_only]
154
+ result = transition
155
+ else
156
+ result = to_state || Array(transition.to).first
157
+ Array(transition.to).each {|to| @valid_transitions[obj.object_id][to] = transition }
158
+ transition.execute(obj, *args)
159
+ end
160
+
161
+ break
162
+ end
163
+ end
164
+ result
165
+ end
166
+
167
+ def clear_failed_callbacks
168
+ # https://github.com/aasm/aasm/issues/383, https://github.com/aasm/aasm/issues/599
169
+ transitions.each { |transition| transition.failures.clear }
170
+ end
171
+
172
+ def invoke_callbacks(code, record, args)
173
+ Invoker.new(code, record, args)
174
+ .with_default_return_value(false)
175
+ .invoke
176
+ end
177
+ end
178
+ end # AASM
@@ -0,0 +1,129 @@
1
+ # frozen_string_literal: true
2
+
3
+ module AASM
4
+ module Core
5
+ ##
6
+ # main invoker class which encapsulates the logic
7
+ # for invoking literal-based, proc-based, class-based
8
+ # and array-based callbacks for different entities.
9
+ class Invoker
10
+ DEFAULT_RETURN_VALUE = true
11
+
12
+ ##
13
+ # Initialize a new invoker instance.
14
+ # NOTE that invoker must be used per-subject/record
15
+ # (one instance per subject/record)
16
+ #
17
+ # ==Options:
18
+ #
19
+ # +subject+ - invoking subject, may be Proc,
20
+ # Class, String, Symbol or Array
21
+ # +record+ - invoking record
22
+ # +args+ - arguments which will be passed to the callback
23
+
24
+ def initialize(subject, record, args)
25
+ @subject = subject
26
+ @record = record
27
+ @args = args
28
+ @options = {}
29
+ @failures = []
30
+ @default_return_value = DEFAULT_RETURN_VALUE
31
+ end
32
+
33
+ ##
34
+ # Pass additional options to concrete invoker
35
+ #
36
+ # ==Options:
37
+ #
38
+ # +options+ - hash of options which will be passed to
39
+ # concrete invokers
40
+ #
41
+ # ==Example:
42
+ #
43
+ # with_options(guard: proc {...})
44
+
45
+ def with_options(options)
46
+ @options = options
47
+ self
48
+ end
49
+
50
+ ##
51
+ # Collect failures to a specified buffer
52
+ #
53
+ # ==Options:
54
+ #
55
+ # +failures+ - failures buffer to collect failures
56
+
57
+ def with_failures(failures)
58
+ @failures = failures
59
+ self
60
+ end
61
+
62
+ ##
63
+ # Change default return value of #invoke method
64
+ # if none of invokers processed the request.
65
+ #
66
+ # The default return value is #DEFAULT_RETURN_VALUE
67
+ #
68
+ # ==Options:
69
+ #
70
+ # +value+ - default return value for #invoke method
71
+
72
+ def with_default_return_value(value)
73
+ @default_return_value = value
74
+ self
75
+ end
76
+
77
+ ##
78
+ # Find concrete invoker for specified subject and invoker it,
79
+ # or return default value set by #DEFAULT_RETURN_VALUE or
80
+ # overridden by #with_default_return_value
81
+
82
+ # rubocop:disable Metrics/AbcSize
83
+ def invoke
84
+ return invoke_array if subject.is_a?(Array)
85
+ return literal_invoker.invoke if literal_invoker.may_invoke?
86
+ return proc_invoker.invoke if proc_invoker.may_invoke?
87
+ return class_invoker.invoke if class_invoker.may_invoke?
88
+ default_return_value
89
+ end
90
+ # rubocop:enable Metrics/AbcSize
91
+
92
+ private
93
+
94
+ attr_reader :subject, :record, :args, :options, :failures,
95
+ :default_return_value
96
+
97
+ def invoke_array
98
+ return subject.all? { |item| sub_invoke(item) } if options[:guard]
99
+ return subject.all? { |item| !sub_invoke(item) } if options[:unless]
100
+ subject.map { |item| sub_invoke(item) }
101
+ end
102
+
103
+ def sub_invoke(new_subject)
104
+ self.class.new(new_subject, record, args)
105
+ .with_failures(failures)
106
+ .with_options(options)
107
+ .invoke
108
+ end
109
+
110
+ def proc_invoker
111
+ @proc_invoker ||= Invokers::ProcInvoker
112
+ .new(subject, record, args)
113
+ .with_failures(failures)
114
+ end
115
+
116
+ def class_invoker
117
+ @class_invoker ||= Invokers::ClassInvoker
118
+ .new(subject, record, args)
119
+ .with_failures(failures)
120
+ end
121
+
122
+ def literal_invoker
123
+ @literal_invoker ||= Invokers::LiteralInvoker
124
+ .new(subject, record, args)
125
+ .with_failures(failures)
126
+ end
127
+ end
128
+ end
129
+ end
@@ -0,0 +1,85 @@
1
+ # frozen_string_literal: true
2
+
3
+ module AASM
4
+ module Core
5
+ module Invokers
6
+ ##
7
+ # Base concrete invoker class which contain basic
8
+ # invoking and logging definitions
9
+ class BaseInvoker
10
+ attr_reader :failures, :subject, :record, :args, :result
11
+
12
+ ##
13
+ # Initialize a new concrete invoker instance.
14
+ # NOTE that concrete invoker must be used per-subject/record
15
+ # (one instance per subject/record)
16
+ #
17
+ # ==Options:
18
+ #
19
+ # +subject+ - invoking subject comparable with this invoker
20
+ # +record+ - invoking record
21
+ # +args+ - arguments which will be passed to the callback
22
+
23
+ def initialize(subject, record, args)
24
+ @subject = subject
25
+ @record = record
26
+ @args = args
27
+ @result = false
28
+ @failures = []
29
+ end
30
+
31
+ ##
32
+ # Collect failures to a specified buffer
33
+ #
34
+ # ==Options:
35
+ #
36
+ # +failures+ - failures buffer to collect failures
37
+
38
+ def with_failures(failures_buffer)
39
+ @failures = failures_buffer
40
+ self
41
+ end
42
+
43
+ ##
44
+ # Execute concrete invoker, log the error and return result
45
+
46
+ def invoke
47
+ return unless may_invoke?
48
+ log_failure unless invoke_subject
49
+ result
50
+ end
51
+
52
+ ##
53
+ # Check if concrete invoker may be invoked for a specified subject
54
+
55
+ def may_invoke?
56
+ raise NoMethodError, '"#may_invoke?" is not implemented'
57
+ end
58
+
59
+ ##
60
+ # Log failed invoking
61
+
62
+ def log_failure
63
+ raise NoMethodError, '"#log_failure" is not implemented'
64
+ end
65
+
66
+ ##
67
+ # Execute concrete invoker
68
+
69
+ def invoke_subject
70
+ raise NoMethodError, '"#invoke_subject" is not implemented'
71
+ end
72
+
73
+ ##
74
+ # Parse arguments to separate keyword arguments from positional arguments
75
+ def parse_arguments
76
+ if args.last.is_a?(Hash)
77
+ [args[0..-2], args.last]
78
+ else
79
+ [args, nil]
80
+ end
81
+ end
82
+ end
83
+ end
84
+ end
85
+ end
@@ -0,0 +1,75 @@
1
+ # frozen_string_literal: true
2
+
3
+ module AASM
4
+ module Core
5
+ module Invokers
6
+ ##
7
+ # Class invoker which allows to use classes which respond to #call
8
+ # to be used as state/event/transition callbacks.
9
+ class ClassInvoker < BaseInvoker
10
+ def may_invoke?
11
+ subject.is_a?(Class) && subject.instance_methods.include?(:call)
12
+ end
13
+
14
+ def log_failure
15
+ return log_source_location if Method.method_defined?(:source_location)
16
+ log_method_info
17
+ end
18
+
19
+ def invoke_subject
20
+ @result = instance.call
21
+ end
22
+
23
+ private
24
+
25
+ def log_source_location
26
+ failures << instance.method(:call).source_location.join('#')
27
+ end
28
+
29
+ def log_method_info
30
+ failures << instance.method(:call)
31
+ end
32
+
33
+ def instance
34
+ @instance ||= retrieve_instance
35
+ end
36
+
37
+ def retrieve_instance
38
+ return subject.new if subject_arity.zero?
39
+ return subject.new(record) if subject_arity == 1
40
+
41
+ if keyword_arguments?
42
+ instance_with_keyword_args
43
+ elsif subject_arity < 0
44
+ subject.new(record, *args)
45
+ else
46
+ instance_with_fixed_arity
47
+ end
48
+ end
49
+
50
+ def keyword_arguments?
51
+ params = subject.instance_method(:initialize).parameters
52
+ params.any? { |type, _| [:key, :keyreq].include?(type) }
53
+ end
54
+
55
+ def instance_with_keyword_args
56
+ positional_args, keyword_args = parse_arguments
57
+
58
+ if keyword_args.nil?
59
+ subject.new(record, *positional_args)
60
+ else
61
+ subject.new(record, *positional_args, **keyword_args)
62
+ end
63
+ end
64
+
65
+ def instance_with_fixed_arity
66
+ subject.new(record, *args[0..(subject_arity - 2)])
67
+ end
68
+
69
+ def subject_arity
70
+ @arity ||= subject.instance_method(:initialize).arity
71
+ end
72
+ end
73
+ end
74
+ end
75
+ end
@@ -0,0 +1,90 @@
1
+ # frozen_string_literal: true
2
+
3
+ module AASM
4
+ module Core
5
+ module Invokers
6
+ ##
7
+ # Literal invoker which allows to use strings or symbols to call
8
+ # record methods as state/event/transition callbacks.
9
+ class LiteralInvoker < BaseInvoker
10
+ def may_invoke?
11
+ subject.is_a?(String) || subject.is_a?(Symbol)
12
+ end
13
+
14
+ def log_failure
15
+ failures << subject
16
+ end
17
+
18
+ def invoke_subject
19
+ @result = exec_subject
20
+ end
21
+
22
+ private
23
+
24
+ def subject_arity
25
+ @arity ||= record.__send__(:method, subject.to_sym).arity
26
+ end
27
+
28
+ def exec_subject
29
+ ensure_method_exists
30
+ return simple_invoke if subject_arity.zero?
31
+ invoke_with_arguments
32
+ end
33
+
34
+ def ensure_method_exists
35
+ raise(*record_error) unless record.respond_to?(subject, true)
36
+ end
37
+
38
+ def simple_invoke
39
+ record.__send__(subject)
40
+ end
41
+
42
+ def invoke_with_arguments
43
+ if keyword_arguments?
44
+ instance_with_keyword_args
45
+ elsif subject_arity < 0
46
+ invoke_with_variable_arity
47
+ else
48
+ invoke_with_fixed_arity
49
+ end
50
+ end
51
+
52
+ def keyword_arguments?
53
+ params = record.method(subject).parameters
54
+ params.any? { |type, _| [:key, :keyreq].include?(type) }
55
+ end
56
+
57
+ def instance_with_keyword_args
58
+ positional_args, keyword_args = parse_arguments
59
+
60
+ if keyword_args.nil?
61
+ record.send(subject, *positional_args)
62
+ else
63
+ record.send(subject, *positional_args, **keyword_args)
64
+ end
65
+ end
66
+
67
+ def invoke_with_variable_arity
68
+ record.__send__(subject, *args)
69
+ end
70
+
71
+ def invoke_with_fixed_arity
72
+ req_args = args[0..(subject_arity - 1)]
73
+ if req_args[0].is_a?(Hash)
74
+ record.__send__(subject, **req_args[0])
75
+ else
76
+ record.__send__(subject, *req_args)
77
+ end
78
+ end
79
+
80
+ def record_error
81
+ [
82
+ NoMethodError,
83
+ 'NoMethodError: undefined method ' \
84
+ "`#{subject}' for #{record.inspect}:#{record.class}"
85
+ ]
86
+ end
87
+ end
88
+ end
89
+ end
90
+ end
@@ -0,0 +1,94 @@
1
+ # frozen_string_literal: true
2
+
3
+ module AASM
4
+ module Core
5
+ module Invokers
6
+ ##
7
+ # Proc invoker which allows to use Procs as
8
+ # state/event/transition callbacks.
9
+ class ProcInvoker < BaseInvoker
10
+ def may_invoke?
11
+ subject.is_a?(Proc)
12
+ end
13
+
14
+ def log_failure
15
+ return log_source_location if Method.method_defined?(:source_location)
16
+ log_proc_info
17
+ end
18
+
19
+ def invoke_subject
20
+ @result = if support_parameters?
21
+ exec_proc(parameters_to_arity)
22
+ else
23
+ exec_proc(subject.arity)
24
+ end
25
+ end
26
+
27
+ private
28
+
29
+ def support_parameters?
30
+ subject.respond_to?(:parameters)
31
+ end
32
+
33
+ def keyword_arguments?
34
+ return false unless support_parameters?
35
+ subject.parameters.any? { |type, _| [:key, :keyreq].include?(type) }
36
+ end
37
+
38
+ def exec_proc_with_keyword_args(parameters_size)
39
+ positional_args, keyword_args = parse_arguments
40
+
41
+ if keyword_args.nil?
42
+ if parameters_size < 0
43
+ record.instance_exec(*positional_args, &subject)
44
+ else
45
+ record.instance_exec(*positional_args[0..(parameters_size - 1)], &subject)
46
+ end
47
+ else
48
+ if parameters_size < 0
49
+ record.instance_exec(*positional_args, **keyword_args, &subject)
50
+ else
51
+ record.instance_exec(*positional_args[0..(parameters_size - 1)], **keyword_args, &subject)
52
+ end
53
+ end
54
+ end
55
+
56
+ # rubocop:disable Metrics/AbcSize
57
+ def exec_proc(parameters_size)
58
+ return record.instance_exec(&subject) if parameters_size.zero? && !keyword_arguments?
59
+
60
+ if keyword_arguments?
61
+ exec_proc_with_keyword_args(parameters_size)
62
+ elsif parameters_size < 0
63
+ record.instance_exec(*args, &subject)
64
+ else
65
+ record.instance_exec(*args[0..(parameters_size - 1)], &subject)
66
+ end
67
+ end
68
+ # rubocop:enable Metrics/AbcSize
69
+
70
+ def log_source_location
71
+ failures << subject.source_location.join('#')
72
+ end
73
+
74
+ def log_proc_info
75
+ failures << subject
76
+ end
77
+
78
+ def parameters_to_arity
79
+ subject.parameters.inject(0) do |memo, parameter|
80
+ case parameter[0]
81
+ when :key, :keyreq
82
+ # Keyword arguments don't count towards positional arity
83
+ when :rest
84
+ memo = memo > 0 ? -memo : -1
85
+ else
86
+ memo += 1
87
+ end
88
+ memo
89
+ end
90
+ end
91
+ end
92
+ end
93
+ end
94
+ end