active_interaction 0.10.2 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +14 -1
  3. data/README.md +32 -35
  4. data/lib/active_interaction.rb +14 -6
  5. data/lib/active_interaction/base.rb +155 -135
  6. data/lib/active_interaction/concerns/active_modelable.rb +46 -0
  7. data/lib/active_interaction/{modules/overload_hash.rb → concerns/hashable.rb} +5 -1
  8. data/lib/active_interaction/concerns/missable.rb +47 -0
  9. data/lib/active_interaction/concerns/runnable.rb +156 -0
  10. data/lib/active_interaction/errors.rb +50 -14
  11. data/lib/active_interaction/filter.rb +33 -45
  12. data/lib/active_interaction/filters/abstract_date_time_filter.rb +24 -15
  13. data/lib/active_interaction/filters/abstract_filter.rb +18 -0
  14. data/lib/active_interaction/filters/abstract_numeric_filter.rb +13 -8
  15. data/lib/active_interaction/filters/array_filter.rb +42 -35
  16. data/lib/active_interaction/filters/boolean_filter.rb +8 -11
  17. data/lib/active_interaction/filters/date_filter.rb +11 -15
  18. data/lib/active_interaction/filters/date_time_filter.rb +11 -15
  19. data/lib/active_interaction/filters/file_filter.rb +11 -11
  20. data/lib/active_interaction/filters/float_filter.rb +7 -15
  21. data/lib/active_interaction/filters/hash_filter.rb +18 -24
  22. data/lib/active_interaction/filters/integer_filter.rb +7 -14
  23. data/lib/active_interaction/filters/model_filter.rb +13 -14
  24. data/lib/active_interaction/filters/string_filter.rb +11 -14
  25. data/lib/active_interaction/filters/symbol_filter.rb +6 -9
  26. data/lib/active_interaction/filters/time_filter.rb +13 -16
  27. data/lib/active_interaction/modules/validation.rb +9 -4
  28. data/lib/active_interaction/version.rb +5 -2
  29. data/spec/active_interaction/base_spec.rb +109 -4
  30. data/spec/active_interaction/{modules/active_model_spec.rb → concerns/active_modelable_spec.rb} +15 -3
  31. data/spec/active_interaction/{modules/overload_hash_spec.rb → concerns/hashable_spec.rb} +2 -3
  32. data/spec/active_interaction/{modules/method_missing_spec.rb → concerns/missable_spec.rb} +38 -3
  33. data/spec/active_interaction/concerns/runnable_spec.rb +192 -0
  34. data/spec/active_interaction/filters/abstract_filter_spec.rb +8 -0
  35. data/spec/active_interaction/filters/abstract_numeric_filter_spec.rb +1 -1
  36. data/spec/active_interaction/modules/validation_spec.rb +2 -2
  37. data/spec/support/concerns.rb +15 -0
  38. data/spec/support/filters.rb +5 -5
  39. data/spec/support/interactions.rb +6 -5
  40. metadata +47 -73
  41. data/lib/active_interaction/filters.rb +0 -28
  42. data/lib/active_interaction/modules/active_model.rb +0 -32
  43. data/lib/active_interaction/modules/core.rb +0 -70
  44. data/lib/active_interaction/modules/method_missing.rb +0 -20
  45. data/spec/active_interaction/filters_spec.rb +0 -23
  46. data/spec/active_interaction/modules/core_spec.rb +0 -114
@@ -1,28 +0,0 @@
1
- # coding: utf-8
2
-
3
- module ActiveInteraction
4
- # A collection of {Filter}s.
5
- #
6
- # @since 0.6.0
7
- class Filters
8
- include Enumerable
9
-
10
- def initialize
11
- @filters = []
12
- end
13
-
14
- # @return [Enumerator]
15
- def each(&block)
16
- @filters.each(&block)
17
- end
18
-
19
- # @param filter [Filter]
20
- #
21
- # @return [Filters]
22
- def add(filter)
23
- @filters << filter
24
-
25
- self
26
- end
27
- end
28
- end
@@ -1,32 +0,0 @@
1
- # coding: utf-8
2
-
3
- module ActiveInteraction
4
- # @private
5
- module ActiveModel
6
- extend ::ActiveSupport::Concern
7
-
8
- include ::ActiveModel::Conversion
9
- include ::ActiveModel::Validations
10
-
11
- extend ::ActiveModel::Naming
12
-
13
- def i18n_scope
14
- self.class.i18n_scope
15
- end
16
-
17
- def new_record?
18
- true
19
- end
20
-
21
- def persisted?
22
- false
23
- end
24
-
25
- # @private
26
- module ClassMethods
27
- def i18n_scope
28
- :active_interaction
29
- end
30
- end
31
- end
32
- end
@@ -1,70 +0,0 @@
1
- # coding: utf-8
2
-
3
- begin
4
- require 'active_record'
5
- rescue LoadError
6
- # ActiveRecord is an optional dependency.
7
- end
8
-
9
- module ActiveInteraction
10
- # Functionality common between {Base}.
11
- #
12
- # @see Base
13
- module Core
14
- # Get or set the description.
15
- #
16
- # @example
17
- # core.desc
18
- # # => nil
19
- # core.desc('descriptive!')
20
- # core.desc
21
- # # => "descriptive!"
22
- #
23
- # @param desc [String, nil] what to set the description to
24
- #
25
- # @return [String, nil] the description
26
- #
27
- # @since 0.8.0
28
- def desc(desc = nil)
29
- if desc.nil?
30
- unless instance_variable_defined?(:@_interaction_desc)
31
- @_interaction_desc = nil
32
- end
33
- else
34
- @_interaction_desc = desc
35
- end
36
-
37
- @_interaction_desc
38
- end
39
-
40
- # Like {Base.run} except that it returns the value of {Base#execute} or
41
- # raises an exception if there were any validation errors.
42
- #
43
- # @param (see Base.run)
44
- #
45
- # @return [Object] the return value of {Base#execute}
46
- #
47
- # @raise [InvalidInteractionError] if the outcome is invalid
48
- def run!(*args)
49
- outcome = run(*args)
50
-
51
- if outcome.valid?
52
- outcome.result
53
- else
54
- fail InvalidInteractionError, outcome.errors.full_messages.join(', ')
55
- end
56
- end
57
-
58
- private
59
-
60
- def transaction(*args)
61
- return unless block_given?
62
-
63
- if defined?(ActiveRecord)
64
- ::ActiveRecord::Base.transaction(*args) { yield }
65
- else
66
- yield
67
- end
68
- end
69
- end
70
- end
@@ -1,20 +0,0 @@
1
- # coding: utf-8
2
-
3
- module ActiveInteraction
4
- # @private
5
- module MethodMissing
6
- def method_missing(slug, *args, &block)
7
- begin
8
- klass = Filter.factory(slug)
9
- rescue MissingFilterError
10
- super
11
- end
12
-
13
- options = args.last.is_a?(Hash) ? args.pop : {}
14
-
15
- yield(klass, args, options) if block_given?
16
-
17
- self
18
- end
19
- end
20
- end
@@ -1,23 +0,0 @@
1
- # coding: utf-8
2
-
3
- require 'spec_helper'
4
-
5
- describe ActiveInteraction::Filters do
6
- describe '#each' do
7
- it 'returns an Enumerator' do
8
- expect(subject.each).to be_an Enumerator
9
- end
10
- end
11
-
12
- describe '#add(filter)' do
13
- it 'returns self' do
14
- expect(subject.add(double)).to equal subject
15
- end
16
-
17
- it 'adds the filter' do
18
- filter = double
19
-
20
- expect(subject.add(filter).to_a).to eql [filter]
21
- end
22
- end
23
- end
@@ -1,114 +0,0 @@
1
- # coding: utf-8
2
-
3
- require 'spec_helper'
4
-
5
- describe ActiveInteraction::Core do
6
- let(:klass) { Class.new { include ActiveInteraction::Core } }
7
- subject(:instance) { klass.new }
8
-
9
- describe '#desc' do
10
- let(:desc) { SecureRandom.hex }
11
-
12
- it 'returns nil' do
13
- expect(instance.desc).to be_nil
14
- end
15
-
16
- it 'returns the description' do
17
- expect(instance.desc(desc)).to eq desc
18
- end
19
-
20
- it 'saves the description' do
21
- instance.desc(desc)
22
- expect(instance.desc).to eq desc
23
- end
24
- end
25
-
26
- describe '#run!' do
27
- let(:errors) { double(full_messages: []) }
28
- let(:outcome) { double(errors: errors, result: result) }
29
- let(:result) { double }
30
-
31
- before do
32
- allow(instance).to receive(:run).and_return(outcome)
33
- end
34
-
35
- shared_examples '#run!' do
36
- let(:inputs) { double }
37
-
38
- it 'calls #run' do
39
- begin
40
- instance.run!(inputs)
41
- rescue ActiveInteraction::InvalidInteractionError
42
- expect(instance).to have_received(:run).once.with(inputs)
43
- end
44
- end
45
- end
46
-
47
- context 'with invalid outcome' do
48
- include_examples '#run!'
49
-
50
- before do
51
- allow(outcome).to receive(:valid?).and_return(false)
52
- end
53
-
54
- it 'raises an error' do
55
- expect do
56
- instance.run!
57
- end.to raise_error ActiveInteraction::InvalidInteractionError
58
- end
59
- end
60
-
61
- context 'with valid outcome' do
62
- include_examples '#run!'
63
-
64
- before do
65
- allow(outcome).to receive(:valid?).and_return(true)
66
- end
67
-
68
- it 'returns the result' do
69
- expect(instance.run!).to eq result
70
- end
71
- end
72
- end
73
-
74
- describe '#transaction' do
75
- context 'without ActiveRecord' do
76
- it 'returns nil' do
77
- expect(instance.send(:transaction)).to be_nil
78
- end
79
-
80
- it 'yields' do
81
- expect { |b| instance.send(:transaction, &b) }.to yield_control
82
- end
83
- end
84
-
85
- context 'with ActiveRecord' do
86
- before do
87
- ActiveRecord = Class.new
88
- ActiveRecord::Base = double
89
- allow(ActiveRecord::Base).to receive(:transaction)
90
- end
91
-
92
- after do
93
- Object.send(:remove_const, :ActiveRecord)
94
- end
95
-
96
- it 'returns nil' do
97
- expect(instance.send(:transaction)).to be_nil
98
- end
99
-
100
- it 'calls ActiveRecord::Base#transaction' do
101
- block = proc {}
102
- expect(ActiveRecord::Base).to receive(:transaction).once.with(no_args)
103
- instance.send(:transaction, &block)
104
- end
105
-
106
- it 'calls ActiveRecord::Base#transaction' do
107
- args = [:a, :b, :c]
108
- block = proc {}
109
- expect(ActiveRecord::Base).to receive(:transaction).once.with(*args)
110
- instance.send(:transaction, *args, &block)
111
- end
112
- end
113
- end
114
- end