active_interaction 3.3.0 → 3.4.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: bcb762bfdc148c4eeb1e277f07e13c60fb3944d8
4
- data.tar.gz: 7676378a761abeadec3fecc6e350dd27a7fbdd37
3
+ metadata.gz: e565176aa5fba8541adcb1bff86f9deb7b88de08
4
+ data.tar.gz: 071ae728292232470bf81b5ae049c7e51444ef8f
5
5
  SHA512:
6
- metadata.gz: 4abdb88c3887e65abed055d535a49ebf8ff9ccd42fba9798315c3f0cb7646461c60007381867c32a8a5f8b4c87082bd4a8bedd3905e3fec041cd0457daed94e9
7
- data.tar.gz: b8c6e2b73a547575e9eaa92c3d412044174e3ea1196dd6a868ad17fb657cdbb495a5455f9411ba5bba9f1c76350bf7505ac78f576cae5b8a7080e0e5a751751b
6
+ metadata.gz: 049b8e1805135d5a6f4a800e7fcefd68d6d6f26513d75f48cede2aebf83120ea52815d7bf02f94c39417b4222de08e29e571aaf63717c5857dca7688cb09acfa
7
+ data.tar.gz: 94d18809c216c9fe7df17ff6b57b7b9e994ff0b1f097f432838856f038d48c6a2c16e7580324967754d643118b54d62f0d0549d23c936bff78177089455933bb
data/README.md CHANGED
@@ -66,13 +66,13 @@ Read more on [the project page][] or check out [the full documentation][].
66
66
  Add it to your Gemfile:
67
67
 
68
68
  ``` rb
69
- gem 'active_interaction', '~> 3.2'
69
+ gem 'active_interaction', '~> 3.4'
70
70
  ```
71
71
 
72
72
  Or install it manually:
73
73
 
74
74
  ``` sh
75
- $ gem install active_interaction --version '~> 3.2'
75
+ $ gem install active_interaction --version '~> 3.4'
76
76
  ```
77
77
 
78
78
  This project uses [Semantic Versioning][]. Check out [the change log][] for a
@@ -604,6 +604,27 @@ IntegerInteraction.run!(limit: 10)
604
604
  # => [10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
605
605
  ```
606
606
 
607
+ When a `String` is passed into an `integer` input, the value will be coerced.
608
+ Coercion is based on `Kernel#Integer` which attempts to detect the base being used.
609
+ However, you may want to specify the `base` for the conversion to something more
610
+ sensible (e.g. `base: 10`).
611
+
612
+ ``` rb
613
+ class IntegerInteraction < ActiveInteraction::Base
614
+ integer :limit1, base: 10
615
+ integer :limit2
616
+
617
+ def execute
618
+ [limit1, limit2]
619
+ end
620
+ end
621
+
622
+ IntegerInteraction.run!(limit1: "08", limit2: 8)
623
+ # => [8, 8]
624
+ IntegerInteraction.run!(limit1: "08", limit2: "08")
625
+ # ArgumentError: invalid value for Integer(): "08"
626
+ ```
627
+
607
628
  ## Rails
608
629
 
609
630
  ActiveInteraction plays nicely with Rails. You can use interactions to handle
@@ -59,23 +59,27 @@ module ActiveInteraction
59
59
  # @param (see ClassMethods.run)
60
60
  #
61
61
  # @return (see #result)
62
+ #
63
+ # @raise [Interrupt]
62
64
  def compose(other, *args)
63
65
  outcome = other.run(*args)
64
66
 
65
- if outcome.valid?
66
- outcome.result
67
- else
68
- throw :interrupt, outcome.errors
69
- end
67
+ raise Interrupt, outcome.errors if outcome.invalid?
68
+
69
+ outcome.result
70
70
  end
71
71
 
72
72
  # @return (see #result=)
73
73
  # @return [nil]
74
- def run
74
+ def run # rubocop:disable MethodLength
75
75
  return unless valid?
76
76
 
77
77
  result_or_errors = run_callbacks(:execute) do
78
- catch(:interrupt) { execute }
78
+ begin
79
+ execute
80
+ rescue Interrupt => interrupt
81
+ interrupt.errors
82
+ end
79
83
  end
80
84
 
81
85
  self.result =
@@ -92,11 +96,11 @@ module ActiveInteraction
92
96
  def run!
93
97
  run
94
98
 
95
- if valid?
96
- result
97
- else
99
+ unless valid?
98
100
  raise InvalidInteractionError, errors.full_messages.join(', ')
99
101
  end
102
+
103
+ result
100
104
  end
101
105
 
102
106
  #
@@ -75,6 +75,21 @@ module ActiveInteraction
75
75
  end
76
76
  end
77
77
 
78
+ # Used by {Runnable} to signal a failure when composing.
79
+ #
80
+ # @private
81
+ class Interrupt < Error
82
+ attr_reader :errors
83
+
84
+ # @param errors [Runnable]
85
+ def initialize(errors)
86
+ super()
87
+
88
+ @errors = errors
89
+ end
90
+ end
91
+ private_constant :Interrupt
92
+
78
93
  # An extension that provides the ability to merge other errors into itself.
79
94
  class Errors < ActiveModel::Errors
80
95
  # Merge other errors into this one.
@@ -17,5 +17,18 @@ module ActiveInteraction
17
17
  # @private
18
18
  class IntegerFilter < AbstractNumericFilter
19
19
  register :integer
20
+
21
+ private
22
+
23
+ # @return [Integer]
24
+ def base
25
+ options.fetch(:base, 0)
26
+ end
27
+
28
+ def convert(value, context)
29
+ Integer(value, base)
30
+ rescue ArgumentError
31
+ _cast(value, context)
32
+ end
20
33
  end
21
34
  end
@@ -6,5 +6,5 @@ module ActiveInteraction
6
6
  # The version number.
7
7
  #
8
8
  # @return [Gem::Version]
9
- VERSION = Gem::Version.new('3.3.0')
9
+ VERSION = Gem::Version.new('3.4.0')
10
10
  end
@@ -9,8 +9,8 @@ describe ActiveInteraction::Hashable do
9
9
  context 'with no arguments' do
10
10
  let(:hash) { subject.hash }
11
11
 
12
- it 'returns a Fixnum' do
13
- expect(hash).to be_a Fixnum
12
+ it 'returns an Integer' do
13
+ expect(hash).to be_an Integer
14
14
  end
15
15
  end
16
16
 
@@ -5,6 +5,14 @@ require 'spec_helper'
5
5
  describe ActiveInteraction::Runnable do
6
6
  include_context 'concerns', ActiveInteraction::Runnable
7
7
 
8
+ class WrappableFailingInteraction
9
+ include ActiveInteraction::Runnable
10
+
11
+ def execute
12
+ errors.add(:base)
13
+ end
14
+ end
15
+
8
16
  shared_context 'with an error' do
9
17
  before { instance.errors.add(:base) }
10
18
  end
@@ -64,30 +72,22 @@ describe ActiveInteraction::Runnable do
64
72
  include_examples 'set_callback examples', :execute
65
73
 
66
74
  context 'execute with composed interaction' do
67
- class InnerInteraction
68
- include ActiveInteraction::Runnable
69
-
70
- def execute
71
- errors.add(:base)
72
- end
73
- end
74
-
75
- class OuterInteraction
75
+ class WithFailingCompose
76
76
  include ActiveInteraction::Runnable
77
77
 
78
78
  def execute
79
- compose(InnerInteraction)
79
+ compose(WrappableFailingInteraction)
80
80
  end
81
81
  end
82
82
 
83
83
  context 'around' do
84
84
  it 'is yielded errors from composed interactions' do
85
85
  block_result = nil
86
- OuterInteraction.set_callback :execute, :around do |_, block|
86
+ WithFailingCompose.set_callback :execute, :around do |_, block|
87
87
  block_result = block.call
88
88
  end
89
89
 
90
- OuterInteraction.run
90
+ WithFailingCompose.run
91
91
  expect(block_result).to be_an(ActiveInteraction::Errors)
92
92
  expect(block_result).to include(:base)
93
93
  end
@@ -96,11 +96,11 @@ describe ActiveInteraction::Runnable do
96
96
  context 'after' do
97
97
  it 'is yielded errors from composed interactions' do
98
98
  has_run = false
99
- OuterInteraction.set_callback :execute, :after do
99
+ WithFailingCompose.set_callback :execute, :after do
100
100
  has_run = true
101
101
  end
102
102
 
103
- OuterInteraction.run
103
+ WithFailingCompose.run
104
104
  expect(has_run).to be_truthy
105
105
  end
106
106
  end
@@ -242,6 +242,26 @@ describe ActiveInteraction::Runnable do
242
242
  expect(outcome).to be_valid
243
243
  end
244
244
  end
245
+
246
+ context 'with failing composition' do
247
+ class CheckInnerForFailure
248
+ include ActiveInteraction::Runnable
249
+
250
+ attr_reader :caught_error
251
+
252
+ def execute
253
+ compose(WrappableFailingInteraction)
254
+ rescue
255
+ @caught_error = true
256
+ raise
257
+ end
258
+ end
259
+
260
+ it 'throws an error from the inner interaction' do
261
+ outcome = CheckInnerForFailure.run
262
+ expect(outcome.caught_error).to be true
263
+ end
264
+ end
245
265
  end
246
266
 
247
267
  describe '.run!' do
@@ -42,6 +42,14 @@ describe ActiveInteraction::IntegerFilter, :filter do
42
42
  end.to raise_error ActiveInteraction::InvalidValueError
43
43
  end
44
44
  end
45
+
46
+ it 'supports different bases' do
47
+ expect(filter.cast('07', nil)).to eql 7
48
+ expect do
49
+ filter.cast('08', nil)
50
+ end.to raise_error ActiveInteraction::InvalidValueError
51
+ expect(described_class.new(name, base: 10).cast('08', nil)).to eql 8
52
+ end
45
53
  end
46
54
 
47
55
  describe '#database_column_type' do
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: 3.3.0
4
+ version: 3.4.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: 2016-09-13 00:00:00.000000000 Z
12
+ date: 2016-10-20 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: activemodel
@@ -107,14 +107,14 @@ dependencies:
107
107
  requirements:
108
108
  - - "~>"
109
109
  - !ruby/object:Gem::Version
110
- version: '11.2'
110
+ version: '11.3'
111
111
  type: :development
112
112
  prerelease: false
113
113
  version_requirements: !ruby/object:Gem::Requirement
114
114
  requirements:
115
115
  - - "~>"
116
116
  - !ruby/object:Gem::Version
117
- version: '11.2'
117
+ version: '11.3'
118
118
  - !ruby/object:Gem::Dependency
119
119
  name: rspec
120
120
  requirement: !ruby/object:Gem::Requirement
@@ -135,14 +135,14 @@ dependencies:
135
135
  requirements:
136
136
  - - "~>"
137
137
  - !ruby/object:Gem::Version
138
- version: 0.42.0
138
+ version: 0.44.0
139
139
  type: :development
140
140
  prerelease: false
141
141
  version_requirements: !ruby/object:Gem::Requirement
142
142
  requirements:
143
143
  - - "~>"
144
144
  - !ruby/object:Gem::Version
145
- version: 0.42.0
145
+ version: 0.44.0
146
146
  - !ruby/object:Gem::Dependency
147
147
  name: yard
148
148
  requirement: !ruby/object:Gem::Requirement