active_interaction 0.10.2 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
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