active_interaction 0.9.1 → 0.10.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 0449466d5aadcc60fb21146f2f69cad47097698a
4
- data.tar.gz: d88a740e6c885e713a2829b7a26902e9712a57c8
3
+ metadata.gz: 3b1db83e71226e6160a36354484c59cd312fcdc2
4
+ data.tar.gz: 13ab7a0625523b7cc531197d697a03ee5c52b14e
5
5
  SHA512:
6
- metadata.gz: 3563d4d5944e8316c3a75c9450c52a411a626436b9acc87380b92890cd393f1cd743f1b6cd2b3a7159a5e963aac06c2bc21dcdb494616337c4d2fb654cfa0ac5
7
- data.tar.gz: 58cb5f5101acce859c491c3eb3a5d8c0117d46f31c966007f3d86a34244c87ac8810493204161dcdee1d840d5954730d88b06c6173e10cdf9366f41542feec66
6
+ metadata.gz: d7daa784b53f26ae7fd99ee906874e551c98dfb1db49cf0a248fd7aca7878f44adaa070a1014862d9c1f1038504912581069e887a0167ae4c2ac61b552991a12
7
+ data.tar.gz: 367a7f33d4386b31020fa29a204219a89231c2dc1b0670cb91b06b5eb00394529121cb181734b9b478a6c19b55d55f007acc51952c184518a22f870b969c0f4e
data/CHANGELOG.md CHANGED
@@ -1,5 +1,10 @@
1
1
  # [Master][]
2
2
 
3
+ # [0.10.0][] (2013-12-19)
4
+
5
+ - Support casting "true" and "false" as booleans.
6
+ - Fix bug that allowed subclasses to mutate the filters on their superclasses.
7
+
3
8
  # [0.9.1][] (2013-12-17)
4
9
 
5
10
  - Fix I18n deprecation warning.
@@ -92,7 +97,8 @@
92
97
 
93
98
  - Initial release.
94
99
 
95
- [master]: https://github.com/orgsync/active_interaction/compare/v0.9.1...master
100
+ [master]: https://github.com/orgsync/active_interaction/compare/v0.10.0...master
101
+ [0.10.0]: https://github.com/orgsync/active_interaction/compare/v0.9.1...0.10.0
96
102
  [0.9.1]: https://github.com/orgsync/active_interaction/compare/v0.9.0...0.9.1
97
103
  [0.9.0]: https://github.com/orgsync/active_interaction/compare/v0.9.0...0.9.0
98
104
  [0.8.0]: https://github.com/orgsync/active_interaction/compare/v0.7.0...v0.8.0
data/README.md CHANGED
@@ -25,7 +25,7 @@ This project uses [semantic versioning][].
25
25
  Add it to your Gemfile:
26
26
 
27
27
  ```ruby
28
- gem 'active_interaction', '~> 0.9.1'
28
+ gem 'active_interaction', '~> 0.10.0'
29
29
  ```
30
30
 
31
31
  And then execute:
@@ -278,7 +278,9 @@ p Interaction.run.errors.messages
278
278
 
279
279
  ## Credits
280
280
 
281
- This project was inspired by the fantastic work done in [Mutations][].
281
+ ActiveInteraction is brought to you by [@AaronLasseigne][] and
282
+ [@tfausak][] from [@orgsync][]. We were inspired by the fantastic
283
+ work done in [Mutations][].
282
284
 
283
285
  [#41]: https://github.com/orgsync/active_interaction/issues/41
284
286
  [#79]: https://github.com/orgsync/active_interaction/issues/79
@@ -287,6 +289,9 @@ This project was inspired by the fantastic work done in [Mutations][].
287
289
  [3]: https://coveralls.io/r/orgsync/active_interaction "Coverage Status"
288
290
  [4]: https://codeclimate.com/github/orgsync/active_interaction "Code Climate"
289
291
  [5]: https://gemnasium.com/orgsync/active_interaction "Dependency Status"
292
+ [@AaronLasseigne]: https://github.com/AaronLasseigne
293
+ [@orgsync]: https://github.com/orgsync
294
+ [@tfausak]: https://github.com/tfausak
290
295
  [build status]: https://travis-ci.org/orgsync/active_interaction.png
291
296
  [code climate]: https://codeclimate.com/github/orgsync/active_interaction.png
292
297
  [coverage status]: https://coveralls.io/repos/orgsync/active_interaction/badge.png
@@ -45,23 +45,7 @@ module ActiveInteraction
45
45
  @_interaction_result = nil
46
46
  @_interaction_runtime_errors = nil
47
47
 
48
- inputs.each do |key, value|
49
- if key.to_s.start_with?('_interaction_')
50
- fail InvalidValueError, key.inspect
51
- end
52
-
53
- instance_variable_set("@#{key}", value)
54
- end
55
-
56
- inputs = inputs.symbolize_keys
57
- self.class.filters.each do |filter|
58
- begin
59
- send("#{filter.name}=", filter.clean(inputs[filter.name]))
60
- # rubocop: disable HandleExceptions
61
- rescue InvalidValueError, MissingValueError
62
- # Validators (#input_errors) will add errors if appropriate.
63
- end
64
- end
48
+ process_inputs(inputs.symbolize_keys)
65
49
  end
66
50
 
67
51
  # Returns the inputs provided to {.run} or {.run!} after being cast based
@@ -127,7 +111,6 @@ module ActiveInteraction
127
111
  result = transaction do
128
112
  begin
129
113
  interaction.execute
130
- # rubocop:disable HandleExceptions
131
114
  rescue Interrupt
132
115
  # Inner interaction failed. #compose handles merging errors.
133
116
  end
@@ -166,6 +149,24 @@ module ActiveInteraction
166
149
 
167
150
  private
168
151
 
152
+ def process_inputs(inputs)
153
+ inputs.each do |key, value|
154
+ if key.to_s.start_with?('_interaction_')
155
+ fail InvalidValueError, key.inspect
156
+ end
157
+
158
+ instance_variable_set("@#{key}", value)
159
+ end
160
+
161
+ self.class.filters.each do |filter|
162
+ begin
163
+ send("#{filter.name}=", filter.clean(inputs[filter.name]))
164
+ rescue InvalidValueError, MissingValueError
165
+ # Validators (#input_errors) will add errors if appropriate.
166
+ end
167
+ end
168
+ end
169
+
169
170
  def input_errors
170
171
  Validation.validate(self.class.filters, inputs).each do |error|
171
172
  errors.add_sym(*error)
@@ -191,11 +192,11 @@ module ActiveInteraction
191
192
  fail Interrupt
192
193
  end
193
194
 
194
- def self.inherited(subclass)
195
- instance_var = :@_interaction_filters
195
+ def self.inherited(klass)
196
+ new_filters = Filters.new
197
+ filters.each { |f| new_filters.add(f) }
196
198
 
197
- subclass.instance_variable_set(
198
- instance_var, instance_variable_get(instance_var))
199
+ klass.instance_variable_set(:@_interaction_filters, new_filters)
199
200
  end
200
201
  end
201
202
  end
@@ -3,8 +3,9 @@
3
3
  module ActiveInteraction
4
4
  class Base
5
5
  # Creates accessors for the attributes and ensures that values passed to
6
- # the attributes are Booleans. The String `"1"` is converted to `true`
7
- # and `"0"` is converted to `false`.
6
+ # the attributes are Booleans. The strings `"1"` and `"true"`
7
+ # (case-insensitive) are converted to `true` while the strings `"0"` and
8
+ # `"false"` are converted to `false`.
8
9
  #
9
10
  # @macro filter_method_params
10
11
  #
@@ -20,9 +21,9 @@ module ActiveInteraction
20
21
  class BooleanFilter < Filter
21
22
  def cast(value)
22
23
  case value
23
- when FalseClass, '0'
24
+ when FalseClass, '0', /\Afalse\z/i
24
25
  false
25
- when TrueClass, '1'
26
+ when TrueClass, '1', /\Atrue\z/i
26
27
  true
27
28
  else
28
29
  super
@@ -2,7 +2,6 @@
2
2
 
3
3
  begin
4
4
  require 'active_record'
5
- # rubocop:disable HandleExceptions
6
5
  rescue LoadError
7
6
  # ActiveRecord is an optional dependency.
8
7
  end
@@ -2,5 +2,5 @@
2
2
 
3
3
  # rubocop:disable Documentation
4
4
  module ActiveInteraction
5
- VERSION = Gem::Version.new('0.9.1')
5
+ VERSION = Gem::Version.new('0.10.0')
6
6
  end
@@ -10,6 +10,24 @@ InteractionWithFilter = Class.new(TestInteraction) do
10
10
  end
11
11
  end
12
12
 
13
+ AddInteraction = Class.new(ActiveInteraction::Base) do
14
+ float :x, :y
15
+
16
+ def execute
17
+ x + y
18
+ end
19
+ end
20
+
21
+ InterruptInteraction = Class.new(ActiveInteraction::Base) do
22
+ model :x, :y,
23
+ class: Object,
24
+ default: nil
25
+
26
+ def execute
27
+ compose(AddInteraction, inputs)
28
+ end
29
+ end
30
+
13
31
  describe ActiveInteraction::Base do
14
32
  include_context 'interactions'
15
33
 
@@ -287,24 +305,6 @@ describe ActiveInteraction::Base do
287
305
  let(:x) { rand }
288
306
  let(:y) { rand }
289
307
 
290
- AddInteraction = Class.new(ActiveInteraction::Base) do
291
- float :x, :y
292
-
293
- def execute
294
- x + y
295
- end
296
- end
297
-
298
- InterruptInteraction = Class.new(ActiveInteraction::Base) do
299
- model :x, :y,
300
- class: Object,
301
- default: nil
302
-
303
- def execute
304
- compose(AddInteraction, inputs)
305
- end
306
- end
307
-
308
308
  context 'with valid composition' do
309
309
  before do
310
310
  inputs.merge!(x: x, y: y)
@@ -338,17 +338,20 @@ describe ActiveInteraction::Base do
338
338
  end
339
339
 
340
340
  context 'inheritance' do
341
- it 'keeps the filters of the parent class' do
342
- ParentInteraction = Class.new(ActiveInteraction::Base) do
343
- boolean :x,
344
- default: nil
341
+ let(:described_class) { InteractionWithFilter }
345
342
 
346
- def execute
347
- inputs
348
- end
349
- end
343
+ def filters(klass)
344
+ klass.filters.map(&:name)
345
+ end
346
+
347
+ it 'includes the filters from the superclass' do
348
+ expect(filters(Class.new(described_class))).to include :thing
349
+ end
350
+
351
+ it 'does not mutate the filters on the superclass' do
352
+ Class.new(described_class) { float :other_thing }
350
353
 
351
- expect(Class.new(ParentInteraction).run!).to eql(x: nil)
354
+ expect(filters(described_class)).to_not include :other_thing
352
355
  end
353
356
  end
354
357
  end
@@ -3,6 +3,7 @@
3
3
  require 'spec_helper'
4
4
 
5
5
  class ActiveInteraction::TestFilter < ActiveInteraction::Filter; end
6
+ class TestFilter < ActiveInteraction::Filter; end
6
7
 
7
8
  describe ActiveInteraction::Filter, :filter do
8
9
  include_context 'filters'
@@ -20,4 +21,23 @@ describe ActiveInteraction::Filter, :filter do
20
21
 
21
22
  let(:described_class) { ActiveInteraction::TestFilter }
22
23
  end
24
+
25
+ context TestFilter do
26
+ let(:described_class) { TestFilter }
27
+
28
+ describe '.factory' do
29
+ it 'returns a Filter' do
30
+ expect(described_class.factory(described_class.name.to_sym))
31
+ .to eq described_class
32
+ end
33
+ end
34
+
35
+ describe '.slug' do
36
+ it 'raises an error' do
37
+ expect do
38
+ described_class.slug
39
+ end.to raise_error ActiveInteraction::InvalidClassError
40
+ end
41
+ end
42
+ end
23
43
  end
@@ -0,0 +1,15 @@
1
+ # coding: utf-8
2
+
3
+ require 'spec_helper'
4
+
5
+ describe ActiveInteraction::AbstractDateTimeFilter, :filter do
6
+ include_context 'filters'
7
+
8
+ describe '#cast' do
9
+ let(:value) { nil }
10
+
11
+ it 'raises an error' do
12
+ expect { filter.cast(value) }.to raise_error NotImplementedError
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,15 @@
1
+ # coding: utf-8
2
+
3
+ require 'spec_helper'
4
+
5
+ describe ActiveInteraction::AbstractNumericFilter, :filter do
6
+ include_context 'filters'
7
+
8
+ describe '#cast' do
9
+ let(:value) { nil }
10
+
11
+ it 'raises an error' do
12
+ expect { filter.cast(value) }.to raise_error NotImplementedError
13
+ end
14
+ end
15
+ end
@@ -7,35 +7,19 @@ describe ActiveInteraction::BooleanFilter, :filter do
7
7
  it_behaves_like 'a filter'
8
8
 
9
9
  describe '#cast' do
10
- context 'with false' do
11
- let(:value) { false }
12
-
13
- it 'returns false' do
14
- expect(filter.cast(value)).to be_false
15
- end
16
- end
17
-
18
- context 'with true' do
19
- let(:value) { true }
20
-
21
- it 'returns true' do
22
- expect(filter.cast(value)).to be_true
10
+ context 'falsey' do
11
+ [false, '0', 'false', 'FALSE'].each do |value|
12
+ it "returns false for #{value.inspect}" do
13
+ expect(filter.cast(value)).to be_false
14
+ end
23
15
  end
24
16
  end
25
17
 
26
- context 'with "0"' do
27
- let(:value) { '0' }
28
-
29
- it 'returns false' do
30
- expect(filter.cast(value)).to be_false
31
- end
32
- end
33
-
34
- context 'with "1"' do
35
- let(:value) { '1' }
36
-
37
- it 'returns true' do
38
- expect(filter.cast(value)).to be_true
18
+ context 'truthy' do
19
+ [true, '1', 'true', 'TRUE'].each do |value|
20
+ it "returns true for #{value.inspect}" do
21
+ expect(filter.cast(value)).to be_true
22
+ end
39
23
  end
40
24
  end
41
25
  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: 0.9.1
4
+ version: 0.10.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: 2013-12-17 00:00:00.000000000 Z
12
+ date: 2013-12-19 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: activemodel
@@ -193,6 +193,8 @@ files:
193
193
  - spec/active_interaction/base_spec.rb
194
194
  - spec/active_interaction/errors_spec.rb
195
195
  - spec/active_interaction/filter_spec.rb
196
+ - spec/active_interaction/filters/abstract_date_time_filter_spec.rb
197
+ - spec/active_interaction/filters/abstract_numeric_filter_spec.rb
196
198
  - spec/active_interaction/filters/array_filter_spec.rb
197
199
  - spec/active_interaction/filters/boolean_filter_spec.rb
198
200
  - spec/active_interaction/filters/date_filter_spec.rb
@@ -258,6 +260,8 @@ test_files:
258
260
  - spec/active_interaction/base_spec.rb
259
261
  - spec/active_interaction/errors_spec.rb
260
262
  - spec/active_interaction/filter_spec.rb
263
+ - spec/active_interaction/filters/abstract_date_time_filter_spec.rb
264
+ - spec/active_interaction/filters/abstract_numeric_filter_spec.rb
261
265
  - spec/active_interaction/filters/array_filter_spec.rb
262
266
  - spec/active_interaction/filters/boolean_filter_spec.rb
263
267
  - spec/active_interaction/filters/date_filter_spec.rb