active_interaction 1.6.1 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (29) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +24 -5
  3. data/README.md +35 -32
  4. data/lib/active_interaction.rb +3 -4
  5. data/lib/active_interaction/backports.rb +47 -0
  6. data/lib/active_interaction/base.rb +8 -25
  7. data/lib/active_interaction/concerns/runnable.rb +4 -14
  8. data/lib/active_interaction/errors.rb +12 -82
  9. data/lib/active_interaction/filters/array_filter.rb +3 -9
  10. data/lib/active_interaction/filters/file_filter.rb +5 -24
  11. data/lib/active_interaction/filters/hash_filter.rb +6 -13
  12. data/lib/active_interaction/filters/interface_filter.rb +2 -2
  13. data/lib/active_interaction/filters/{model_filter.rb → object_filter.rb} +4 -5
  14. data/lib/active_interaction/locale/en.yml +0 -1
  15. data/lib/active_interaction/version.rb +1 -1
  16. data/spec/active_interaction/base_spec.rb +15 -14
  17. data/spec/active_interaction/concerns/runnable_spec.rb +2 -34
  18. data/spec/active_interaction/errors_spec.rb +5 -87
  19. data/spec/active_interaction/filters/array_filter_spec.rb +2 -2
  20. data/spec/active_interaction/filters/file_filter_spec.rb +4 -4
  21. data/spec/active_interaction/filters/hash_filter_spec.rb +1 -17
  22. data/spec/active_interaction/filters/{model_filter_spec.rb → object_filter_spec.rb} +17 -17
  23. data/spec/active_interaction/integration/array_interaction_spec.rb +10 -0
  24. data/spec/active_interaction/integration/hash_interaction_spec.rb +12 -2
  25. data/spec/active_interaction/integration/object_interaction_spec.rb +16 -0
  26. metadata +8 -11
  27. data/lib/active_interaction/concerns/transactable.rb +0 -81
  28. data/spec/active_interaction/concerns/transactable_spec.rb +0 -135
  29. data/spec/active_interaction/integration/model_interaction_spec.rb +0 -16
@@ -84,8 +84,8 @@ describe ActiveInteraction::ArrayFilter, :filter do
84
84
  end
85
85
  end
86
86
 
87
- context 'with a nested model filter' do
88
- let(:block) { proc { model } }
87
+ context 'with a nested object filter' do
88
+ let(:block) { proc { object } }
89
89
  let(:name) { :objects }
90
90
  let(:value) { [Object.new] }
91
91
 
@@ -25,11 +25,11 @@ describe ActiveInteraction::FileFilter, :filter do
25
25
  end
26
26
  end
27
27
 
28
- context 'with an object that responds to #tempfile' do
29
- let(:value) { double(tempfile: Tempfile.new(SecureRandom.hex)) }
28
+ context 'with an object that responds to #eof?' do
29
+ let(:value) { double(eof?: true) }
30
30
 
31
- it 'returns the Tempfile' do
32
- expect(result).to eq value.tempfile
31
+ it 'returns the object' do
32
+ expect(result).to eq value
33
33
  end
34
34
  end
35
35
  end
@@ -37,7 +37,7 @@ describe ActiveInteraction::HashFilter, :filter do
37
37
  let(:block) { proc { hash :a } }
38
38
 
39
39
  context 'with a Hash' do
40
- let(:value) { { a: {} } }
40
+ let(:value) { { 'a' => {} } }
41
41
 
42
42
  it 'returns the Hash' do
43
43
  expect(result).to eql value
@@ -75,22 +75,6 @@ describe ActiveInteraction::HashFilter, :filter do
75
75
  end
76
76
  end
77
77
  end
78
-
79
- context 'keys are symbolized' do
80
- let(:value) { { 'a' => 'a', 1 => 1 } }
81
-
82
- before do
83
- options.merge!(strip: false)
84
- end
85
-
86
- it 'symbolizes String keys' do
87
- expect(result).to have_key :a
88
- end
89
-
90
- it 'leaves other keys alone' do
91
- expect(result).to have_key 1
92
- end
93
- end
94
78
  end
95
79
 
96
80
  describe '#default' do
@@ -2,19 +2,19 @@
2
2
 
3
3
  require 'spec_helper'
4
4
 
5
- class Model; end
5
+ class Thing; end
6
6
  class Things; end
7
7
 
8
- describe ActiveInteraction::ModelFilter, :filter do
8
+ describe ActiveInteraction::ObjectFilter, :filter do
9
9
  include_context 'filters'
10
10
  it_behaves_like 'a filter'
11
11
 
12
12
  before do
13
- options.merge!(class: Model)
13
+ options.merge!(class: Thing)
14
14
  end
15
15
 
16
16
  describe '#cast' do
17
- let(:value) { Model.new }
17
+ let(:value) { Thing.new }
18
18
  let(:result) { filter.cast(value) }
19
19
 
20
20
  context 'with class as a Class' do
@@ -25,9 +25,9 @@ describe ActiveInteraction::ModelFilter, :filter do
25
25
  it 'handles reconstantizing' do
26
26
  expect(result).to eql value
27
27
 
28
- Object.send(:remove_const, :Model)
29
- class Model; end
30
- value = Model.new
28
+ Object.send(:remove_const, :Thing)
29
+ class Thing; end
30
+ value = Thing.new
31
31
 
32
32
  expect(filter.cast(value)).to eql value
33
33
  end
@@ -35,10 +35,10 @@ describe ActiveInteraction::ModelFilter, :filter do
35
35
  it 'handles reconstantizing subclasses' do
36
36
  filter
37
37
 
38
- Object.send(:remove_const, :Model)
39
- class Model; end
40
- class Submodel < Model; end
41
- value = Submodel.new
38
+ Object.send(:remove_const, :Thing)
39
+ class Thing; end
40
+ class SubThing < Thing; end
41
+ value = SubThing.new
42
42
 
43
43
  expect(filter.cast(value)).to eql value
44
44
  end
@@ -46,7 +46,7 @@ describe ActiveInteraction::ModelFilter, :filter do
46
46
  it 'does not overflow the stack' do
47
47
  klass = Class.new do
48
48
  def self.name
49
- Model.name
49
+ Thing.name
50
50
  end
51
51
  end
52
52
 
@@ -56,8 +56,8 @@ describe ActiveInteraction::ModelFilter, :filter do
56
56
  end
57
57
 
58
58
  context 'without the class available' do
59
- before { Object.send(:remove_const, :Model) }
60
- after { class Model; end }
59
+ before { Object.send(:remove_const, :Thing) }
60
+ after { class Thing; end }
61
61
 
62
62
  it 'does not raise an error on initialization' do
63
63
  expect { filter }.to_not raise_error
@@ -69,7 +69,7 @@ describe ActiveInteraction::ModelFilter, :filter do
69
69
  let(:class_equality) { false }
70
70
 
71
71
  before do
72
- allow(Model).to receive(:===).and_return(case_equality)
72
+ allow(Thing).to receive(:===).and_return(case_equality)
73
73
  allow(value).to receive(:is_a?).and_return(class_equality)
74
74
  end
75
75
 
@@ -101,7 +101,7 @@ describe ActiveInteraction::ModelFilter, :filter do
101
101
 
102
102
  context 'with class as a superclass' do
103
103
  before do
104
- options.merge!(class: Model.superclass)
104
+ options.merge!(class: Thing.superclass)
105
105
  end
106
106
 
107
107
  it 'returns the instance' do
@@ -111,7 +111,7 @@ describe ActiveInteraction::ModelFilter, :filter do
111
111
 
112
112
  context 'with class as a String' do
113
113
  before do
114
- options.merge!(class: Model.name)
114
+ options.merge!(class: Thing.name)
115
115
  end
116
116
 
117
117
  it 'returns the instance' do
@@ -39,6 +39,16 @@ describe ArrayInteraction do
39
39
  end
40
40
  end
41
41
 
42
+ context 'with an invalid default as a proc' do
43
+ it 'does not raise an error' do
44
+ expect do
45
+ Class.new(ActiveInteraction::Base) do
46
+ array :a, default: -> { Object.new }
47
+ end
48
+ end.to_not raise_error
49
+ end
50
+ end
51
+
42
52
  context 'with an invalid nested default' do
43
53
  it 'raises an error' do
44
54
  expect do
@@ -21,11 +21,11 @@ describe HashInteraction do
21
21
  before { inputs.merge!(a: a) }
22
22
 
23
23
  it 'returns the correct value for :a' do
24
- expect(result[:a]).to eql a.symbolize_keys
24
+ expect(result[:a]).to eql a.with_indifferent_access
25
25
  end
26
26
 
27
27
  it 'returns the correct value for :b' do
28
- expect(result[:b]).to eql(x: {})
28
+ expect(result[:b]).to eql('x' => {})
29
29
  end
30
30
  end
31
31
 
@@ -39,6 +39,16 @@ describe HashInteraction do
39
39
  end
40
40
  end
41
41
 
42
+ context 'with an invalid default as a proc' do
43
+ it 'does not raise an error' do
44
+ expect do
45
+ Class.new(ActiveInteraction::Base) do
46
+ array :a, default: -> { Object.new }
47
+ end
48
+ end.to_not raise_error
49
+ end
50
+ end
51
+
42
52
  context 'with an invalid nested default' do
43
53
  it 'raises an error' do
44
54
  expect do
@@ -0,0 +1,16 @@
1
+ # coding: utf-8
2
+
3
+ require 'spec_helper'
4
+
5
+ ObjectInteraction = Class.new(TestInteraction) do
6
+ object :object
7
+ end
8
+
9
+ describe ObjectInteraction do
10
+ include_context 'interactions'
11
+ it_behaves_like 'an interaction', :object, -> { // }, class: Regexp
12
+
13
+ it 'succeeds when given nil' do
14
+ expect { result }.to_not raise_error
15
+ end
16
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: active_interaction
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.6.1
4
+ version: 2.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Aaron Lasseigne
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2015-10-02 00:00:00.000000000 Z
12
+ date: 2015-05-06 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: activemodel
@@ -179,7 +179,6 @@ files:
179
179
  - lib/active_interaction/concerns/hashable.rb
180
180
  - lib/active_interaction/concerns/missable.rb
181
181
  - lib/active_interaction/concerns/runnable.rb
182
- - lib/active_interaction/concerns/transactable.rb
183
182
  - lib/active_interaction/errors.rb
184
183
  - lib/active_interaction/filter.rb
185
184
  - lib/active_interaction/filter_column.rb
@@ -196,7 +195,7 @@ files:
196
195
  - lib/active_interaction/filters/hash_filter.rb
197
196
  - lib/active_interaction/filters/integer_filter.rb
198
197
  - lib/active_interaction/filters/interface_filter.rb
199
- - lib/active_interaction/filters/model_filter.rb
198
+ - lib/active_interaction/filters/object_filter.rb
200
199
  - lib/active_interaction/filters/string_filter.rb
201
200
  - lib/active_interaction/filters/symbol_filter.rb
202
201
  - lib/active_interaction/filters/time_filter.rb
@@ -211,7 +210,6 @@ files:
211
210
  - spec/active_interaction/concerns/hashable_spec.rb
212
211
  - spec/active_interaction/concerns/missable_spec.rb
213
212
  - spec/active_interaction/concerns/runnable_spec.rb
214
- - spec/active_interaction/concerns/transactable_spec.rb
215
213
  - spec/active_interaction/errors_spec.rb
216
214
  - spec/active_interaction/filter_column_spec.rb
217
215
  - spec/active_interaction/filter_spec.rb
@@ -228,7 +226,7 @@ files:
228
226
  - spec/active_interaction/filters/hash_filter_spec.rb
229
227
  - spec/active_interaction/filters/integer_filter_spec.rb
230
228
  - spec/active_interaction/filters/interface_filter_spec.rb
231
- - spec/active_interaction/filters/model_filter_spec.rb
229
+ - spec/active_interaction/filters/object_filter_spec.rb
232
230
  - spec/active_interaction/filters/string_filter_spec.rb
233
231
  - spec/active_interaction/filters/symbol_filter_spec.rb
234
232
  - spec/active_interaction/filters/time_filter_spec.rb
@@ -243,7 +241,7 @@ files:
243
241
  - spec/active_interaction/integration/hash_interaction_spec.rb
244
242
  - spec/active_interaction/integration/integer_interaction_spec.rb
245
243
  - spec/active_interaction/integration/interface_interaction_spec.rb
246
- - spec/active_interaction/integration/model_interaction_spec.rb
244
+ - spec/active_interaction/integration/object_interaction_spec.rb
247
245
  - spec/active_interaction/integration/string_interaction_spec.rb
248
246
  - spec/active_interaction/integration/symbol_interaction_spec.rb
249
247
  - spec/active_interaction/integration/time_interaction_spec.rb
@@ -273,7 +271,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
273
271
  version: '0'
274
272
  requirements: []
275
273
  rubyforge_project:
276
- rubygems_version: 2.4.5
274
+ rubygems_version: 2.4.6
277
275
  signing_key:
278
276
  specification_version: 4
279
277
  summary: Manage application specific business logic.
@@ -284,7 +282,6 @@ test_files:
284
282
  - spec/active_interaction/concerns/hashable_spec.rb
285
283
  - spec/active_interaction/concerns/missable_spec.rb
286
284
  - spec/active_interaction/concerns/runnable_spec.rb
287
- - spec/active_interaction/concerns/transactable_spec.rb
288
285
  - spec/active_interaction/errors_spec.rb
289
286
  - spec/active_interaction/filter_column_spec.rb
290
287
  - spec/active_interaction/filter_spec.rb
@@ -301,7 +298,7 @@ test_files:
301
298
  - spec/active_interaction/filters/hash_filter_spec.rb
302
299
  - spec/active_interaction/filters/integer_filter_spec.rb
303
300
  - spec/active_interaction/filters/interface_filter_spec.rb
304
- - spec/active_interaction/filters/model_filter_spec.rb
301
+ - spec/active_interaction/filters/object_filter_spec.rb
305
302
  - spec/active_interaction/filters/string_filter_spec.rb
306
303
  - spec/active_interaction/filters/symbol_filter_spec.rb
307
304
  - spec/active_interaction/filters/time_filter_spec.rb
@@ -316,7 +313,7 @@ test_files:
316
313
  - spec/active_interaction/integration/hash_interaction_spec.rb
317
314
  - spec/active_interaction/integration/integer_interaction_spec.rb
318
315
  - spec/active_interaction/integration/interface_interaction_spec.rb
319
- - spec/active_interaction/integration/model_interaction_spec.rb
316
+ - spec/active_interaction/integration/object_interaction_spec.rb
320
317
  - spec/active_interaction/integration/string_interaction_spec.rb
321
318
  - spec/active_interaction/integration/symbol_interaction_spec.rb
322
319
  - spec/active_interaction/integration/time_interaction_spec.rb
@@ -1,81 +0,0 @@
1
- # coding: utf-8
2
-
3
- begin
4
- require 'active_record'
5
- rescue LoadError
6
- module ActiveRecord # rubocop:disable Style/Documentation
7
- Rollback = Class.new(ActiveInteraction::Error)
8
-
9
- class Base # rubocop:disable Style/Documentation
10
- def self.transaction(*)
11
- yield
12
- rescue Rollback
13
- end
14
- end
15
- end
16
- end
17
-
18
- module ActiveInteraction
19
- # @private
20
- #
21
- # Execute code in a transaction. If ActiveRecord isn't available, don't do
22
- # anything special.
23
- #
24
- # @since 1.2.0
25
- module Transactable
26
- extend ActiveSupport::Concern
27
-
28
- # @yield []
29
- def transaction
30
- return unless block_given?
31
-
32
- if self.class.transaction?
33
- ActiveRecord::Base.transaction(self.class.transaction_options) do
34
- yield
35
- end
36
- else
37
- yield
38
- end
39
- end
40
-
41
- module ClassMethods # rubocop:disable Style/Documentation
42
- # @param klass [Class]
43
- def inherited(klass)
44
- klass.transaction_without_deprecation(
45
- transaction?, transaction_options.dup)
46
-
47
- super
48
- end
49
-
50
- # @param enable [Boolean]
51
- # @param options [Hash]
52
- #
53
- # @return [nil]
54
- def transaction(enable, options = {})
55
- @_interaction_transaction_enabled = enable
56
- @_interaction_transaction_options = options
57
-
58
- nil
59
- end
60
- ActiveInteraction.deprecate self, :transaction
61
-
62
- # @return [Boolean]
63
- def transaction?
64
- unless defined?(@_interaction_transaction_enabled)
65
- @_interaction_transaction_enabled = true
66
- end
67
-
68
- @_interaction_transaction_enabled
69
- end
70
-
71
- # @return [Hash]
72
- def transaction_options
73
- unless defined?(@_interaction_transaction_options)
74
- @_interaction_transaction_options = {}
75
- end
76
-
77
- @_interaction_transaction_options
78
- end
79
- end
80
- end
81
- end
@@ -1,135 +0,0 @@
1
- # coding: utf-8
2
-
3
- require 'spec_helper'
4
-
5
- describe ActiveRecord::Base do
6
- describe '.transaction' do
7
- it 'raises an error' do
8
- expect { described_class.transaction }.to raise_error LocalJumpError
9
- end
10
-
11
- it 'silently rescues ActiveRecord::Rollback' do
12
- expect do
13
- described_class.transaction do
14
- fail ActiveRecord::Rollback
15
- end
16
- end.to_not raise_error
17
- end
18
-
19
- context 'with a block' do
20
- it 'yields to the block' do
21
- expect { |b| described_class.transaction(&b) }.to yield_with_no_args
22
- end
23
-
24
- it 'accepts an argument' do
25
- expect { described_class.transaction(nil) {} }.to_not raise_error
26
- end
27
- end
28
- end
29
- end
30
-
31
- describe ActiveInteraction::Transactable do
32
- include_context 'concerns', ActiveInteraction::Transactable
33
-
34
- describe '.transaction' do
35
- it 'returns nil' do
36
- expect(klass.transaction(true)).to be_nil
37
- end
38
-
39
- it 'accepts a flag parameter' do
40
- expect { klass.transaction(true) }.to_not raise_error
41
- end
42
-
43
- it 'also accepts an options parameter' do
44
- expect { klass.transaction(true, {}) }.to_not raise_error
45
- end
46
- end
47
-
48
- describe '.transaction?' do
49
- it 'defaults to true' do
50
- expect(klass.transaction?).to be_truthy
51
- end
52
-
53
- it 'returns the stored value' do
54
- klass.transaction(false)
55
- expect(klass.transaction?).to be_falsey
56
- end
57
-
58
- context 'with a subclass' do
59
- before { klass.transaction(false) }
60
-
61
- let(:subclass) { Class.new(klass) }
62
-
63
- it 'inherits from the superclass' do
64
- expect(subclass.transaction?).to be_falsey
65
- end
66
- end
67
- end
68
-
69
- describe '.transaction_options' do
70
- let(:h) { { rand => rand } }
71
-
72
- it 'defaults to an empty hash' do
73
- expect(klass.transaction_options).to eql({})
74
- end
75
-
76
- it 'returns the stored value' do
77
- klass.transaction(klass.transaction?, h)
78
- expect(klass.transaction_options).to eql h
79
- end
80
-
81
- context 'with a subclass' do
82
- before { klass.transaction(klass.transaction?, h) }
83
-
84
- let(:subclass) { Class.new(klass) }
85
-
86
- it 'inherits from the superclass' do
87
- expect(subclass.transaction_options).to eql h
88
- end
89
- end
90
- end
91
-
92
- describe '#transaction' do
93
- let(:block) { -> { value } }
94
- let(:result) { instance.transaction(&block) }
95
- let(:value) { double }
96
-
97
- before do
98
- allow(ActiveRecord::Base).to receive(:transaction).and_call_original
99
- end
100
-
101
- it 'returns nil' do
102
- expect(instance.transaction).to be_nil
103
- end
104
-
105
- context 'with transactions disabled' do
106
- before do
107
- klass.transaction(false)
108
- end
109
-
110
- it 'returns the value of the block' do
111
- expect(result).to eql value
112
- end
113
-
114
- it 'does not call ActiveRecord::Base.transaction' do
115
- expect(ActiveRecord::Base).to_not have_received(:transaction)
116
- end
117
- end
118
-
119
- context 'with transactions enabled' do
120
- before do
121
- klass.transaction(true)
122
- end
123
-
124
- it 'returns the value of the block' do
125
- expect(result).to eql value
126
- end
127
-
128
- it 'calls ActiveRecord::Base.transaction' do
129
- result
130
- expect(ActiveRecord::Base).to have_received(:transaction)
131
- .once.with(klass.transaction_options, &block)
132
- end
133
- end
134
- end
135
- end