active_interaction 0.1.2 → 0.1.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,15 @@
1
+ ---
2
+ !binary "U0hBMQ==":
3
+ metadata.gz: !binary |-
4
+ NWZlM2U4M2ZiMTYwNjRkOTRkNjQwYWM4OWU5OGM2ZWFhY2FjNDBhMA==
5
+ data.tar.gz: !binary |-
6
+ YjRjODdkZTczNWM0MWY1ZTQxMWY5NDUxMTcwNDRhYTI2YWNhYTY1MA==
7
+ !binary "U0hBNTEy":
8
+ metadata.gz: !binary |-
9
+ YWIxYmE0YzhjYzQwNGY1ZjMxY2M5ZTYyODEwYzA5N2UyYWM1ZjY5ZDIyN2Vk
10
+ MTM3YzY5YzZkOGQyZjZmZGQzY2VlNDJkNjBhMjQ1YzQyNGRiMmY3NzRhMDc1
11
+ MTQ0ZWM5Y2VhMGMxZTY1MjU4Nzg3YjQ5MzU2ZmNmMDhmZTdjNzY=
12
+ data.tar.gz: !binary |-
13
+ ZDQ3MDUwNDVmMDA3MmIwZDJiZmE4NDYxYTQ5ODIyMjY4ZmYwYTgwMDllYjhi
14
+ YjZjNWNhODA2NWFhNjA0ZjY0ODliMTBhOWU3YTUzZDc5YTkyNWVmYjI2MDBl
15
+ ZGI2Y2UxYjhhYjVjYTVmM2RhYjBlOTBiMWZlZDdmMjQwZmRjYWE=
data/CHANGELOG.md CHANGED
@@ -1,6 +1,15 @@
1
+ # Master
2
+
3
+ # 0.1.3
4
+
5
+ - Fix bug that prevented `attr_accessor`s from working.
6
+ - Handle unconfigured timezones.
7
+ - Use RDoc as YARD's Markdown provider instead of kramdown.
8
+
1
9
  # 0.1.2
2
10
 
3
- - `execute` will now have the filtered version of the values passed to `run` or `run!` as was intended.
11
+ - `execute` will now have the filtered version of the values passed
12
+ to `run` or `run!` as was intended.
4
13
 
5
14
  # 0.1.1
6
15
 
data/README.md CHANGED
@@ -1,18 +1,19 @@
1
1
  # ActiveInteraction
2
2
 
3
- [![Gem Version][]](https://badge.fury.io/rb/active_interaction)
4
- [![Build Status][]](https://travis-ci.org/orgsync/active_interaction)
5
- [![Coverage Status][]](https://coveralls.io/r/orgsync/active_interaction)
6
- [![Code Climate][]](https://codeclimate.com/github/orgsync/active_interaction)
7
- [![Dependency Status][]](https://gemnasium.com/orgsync/active_interaction)
3
+ [![Gem Version][]][1]
4
+ [![Build Status][]][2]
5
+ [![Coverage Status][]][3]
6
+ [![Code Climate][]][4]
7
+ [![Dependency Status][]][5]
8
8
 
9
- At first it seemed alright. A little business logic in a controller or model
10
- wasn't going to hurt anything. Then one day you wake up and you're surrounded
11
- by fat models and unweildy controllers. Curled up and crying in the
12
- corner, you can't help but wonder how it came to this.
9
+ At first it seemed alright. A little business logic in a controller
10
+ or model wasn't going to hurt anything. Then one day you wake up
11
+ and you're surrounded by fat models and unwieldy controllers. Curled
12
+ up and crying in the corner, you can't help but wonder how it came
13
+ to this.
13
14
 
14
- Take back control. Slim down models and wrangle monstrous controller methods
15
- with ActiveInteraction.
15
+ Take back control. Slim down models and wrangle monstrous controller
16
+ methods with ActiveInteraction.
16
17
 
17
18
  ## Installation
18
19
 
@@ -20,31 +21,32 @@ This project uses [semantic versioning][].
20
21
 
21
22
  Add it to your Gemfile:
22
23
 
23
- ~~~ rb
24
- gem 'active_interaction', '~> 0.1.2'
25
- ~~~
24
+ ```ruby
25
+ gem 'active_interaction', '~> 0.1.3'
26
+ ```
26
27
 
27
28
  And then execute:
28
29
 
29
- ~~~ sh
30
+ ```sh
30
31
  $ bundle
31
- ~~~
32
+ ```
32
33
 
33
- Or install it yourself as:
34
+ Or install it yourself with:
34
35
 
35
- ~~~ rb
36
+ ```sh
36
37
  $ gem install active_interaction
37
- ~~~
38
+ ```
38
39
 
39
40
  ## What do I get?
40
41
 
41
- ActiveInteraction::Base lets you create interaction models. These models ensure
42
- that certain options are provided and that those options are in the format you
43
- want them in. If the options are valid it will call `execute`, store the return
44
- value of that method in `result`, and return an instance of your ActiveInteraction::Base
42
+ ActiveInteraction::Base lets you create interaction models. These
43
+ models ensure that certain options are provided and that those
44
+ options are in the format you want them in. If the options are valid
45
+ it will call `execute`, store the return value of that method in
46
+ `result`, and return an instance of your ActiveInteraction::Base
45
47
  subclass. Let's looks at a simple example:
46
48
 
47
- ~~~ rb
49
+ ```ruby
48
50
  # Define an interaction that signs up a user.
49
51
  class UserSignup < ActiveInteraction::Base
50
52
  # required
@@ -56,11 +58,14 @@ class UserSignup < ActiveInteraction::Base
56
58
  # ActiveRecord validations
57
59
  validates :email, format: EMAIL_REGEX
58
60
 
59
- # The execute method is called only if the options validate. It does your
60
- # business action. The return value will be stored in `result`.
61
+ # The execute method is called only if the options validate. It
62
+ # does your business action. The return value will be stored in
63
+ # `result`.
61
64
  def execute
62
65
  user = User.create!(email: email, name: name)
63
- NewsletterSubscriptions.create(email: email, user_id: user.id) if newsletter_subscribe
66
+ if newsletter_subscribe
67
+ NewsletterSubscriptions.create(email: email, user_id: user.id)
68
+ end
64
69
  UserMailer.async(:deliver_welcome, user.id)
65
70
  user
66
71
  end
@@ -81,45 +86,46 @@ def create
81
86
  render action: :new
82
87
  end
83
88
  end
84
- ~~~
89
+ ```
85
90
 
86
- You may have noticed that ActiveInteraction::Base quacks like ActiveRecord::Base.
87
- It can use validations from your Rails application and check option validity with
88
- `valid?`. Any errors are added to `errors` which works exactly like an ActiveRecord
89
- model.
91
+ You may have noticed that ActiveInteraction::Base quacks like
92
+ ActiveRecord::Base. It can use validations from your Rails application
93
+ and check option validity with `valid?`. Any errors are added to
94
+ `errors` which works exactly like an ActiveRecord model.
90
95
 
91
96
  ## How do I call an interaction?
92
97
 
93
- There are two way to call an interaction. Given UserSignup, you can do this:
98
+ There are two way to call an interaction. Given UserSignup, you can
99
+ do this:
94
100
 
95
- ~~~ rb
101
+ ```ruby
96
102
  outcome = UserSignup.run(params)
97
103
  if outcome.valid?
98
104
  # Do something with outcome.result...
99
105
  else
100
106
  # Do something with outcome.errors...
101
107
  end
102
- ~~~
108
+ ```
103
109
 
104
110
  Or, you can do this:
105
111
 
106
- ~~~ rb
112
+ ```ruby
107
113
  result = UserSignup.run!(params)
108
114
  # Either returns the result of execute,
109
115
  # or raises ActiveInteraction::InteractionInvalid
110
- ~~~
116
+ ```
111
117
 
112
118
  ## What can I pass to an interaction?
113
119
 
114
120
  Interactions only accept a Hash for `run` and `run!`.
115
121
 
116
- ~~~ rb
122
+ ```ruby
117
123
  # A user comments on an article
118
124
  class CreateComment < ActiveInteraction::Base
119
125
  model :article, :user
120
126
  string :comment
121
127
 
122
- validates :comment, length: {maximum: 500}
128
+ validates :comment, length: { maximum: 500 }
123
129
 
124
130
  def execute; ...; end
125
131
  end
@@ -131,21 +137,21 @@ def somewhere
131
137
  user: current_user
132
138
  )
133
139
  end
134
- ~~~
140
+ ```
135
141
 
136
142
  ## How do I define an interaction?
137
143
 
138
144
  1. Subclass ActiveInteraction::Base
139
145
 
140
- ~~~ rb
146
+ ```ruby
141
147
  class YourInteraction < ActiveInteraction::Base
142
148
  # ...
143
149
  end
144
- ~~~
150
+ ```
145
151
 
146
152
  2. Define your attributes:
147
153
 
148
- ~~~ rb
154
+ ```ruby
149
155
  string :name, :state
150
156
  integer :age
151
157
  boolean :is_special
@@ -159,13 +165,13 @@ end
159
165
  end
160
166
  date :arrives_on, default: Date.today
161
167
  date :departs_on, default: Date.tomorrow
162
- ~~~
168
+ ```
163
169
 
164
170
  3. Use any additional validations you need:
165
171
 
166
- ~~~ rb
167
- validates :name, length: {maximum: 10}
168
- validates :state, inclusion: {in: %w(AL AK AR ... WY)}
172
+ ```ruby
173
+ validates :name, length: { maximum: 10 }
174
+ validates :state, inclusion: { in: %w(AL AK AR ... WY) }
169
175
  validate arrives_before_departs
170
176
 
171
177
  private
@@ -175,28 +181,34 @@ end
175
181
  errors.add(:departs_on, 'must come after the arrival time')
176
182
  end
177
183
  end
178
- ~~~
184
+ ```
179
185
 
180
186
  4. Define your execute method. It can return whatever you like:
181
187
 
182
- ~~~ rb
188
+ ```ruby
183
189
  def execute
184
190
  record = do_thing(...)
185
191
  # ...
186
192
  record
187
193
  end
188
- ~~~
194
+ ```
189
195
 
190
- A full list of methods can be found [here](http://www.rubydoc.info/github/orgsync/active_interaction/master/ActiveInteraction/Base).
196
+ Check out the [documentation][] for a full list of methods.
191
197
 
192
198
  ## Credits
193
199
 
194
200
  This project was inspired by the fantastic work done in [Mutations][].
195
201
 
196
- [build status]: https://travis-ci.org/orgsync/active_interaction.png
197
- [code climate]: https://codeclimate.com/github/orgsync/active_interaction.png
198
- [coverage status]: https://coveralls.io/repos/orgsync/active_interaction/badge.png
199
- [dependency status]: https://gemnasium.com/orgsync/active_interaction.png
200
- [gem version]: https://badge.fury.io/rb/active_interaction.png
201
- [mutations]: https://github.com/cypriss/mutations
202
- [semantic versioning]: http://semver.org
202
+ [1]: https://badge.fury.io/rb/active_interaction "Gem Version"
203
+ [2]: https://travis-ci.org/orgsync/active_interaction "Build Status"
204
+ [3]: https://coveralls.io/r/orgsync/active_interaction "Coverage Status"
205
+ [4]: https://codeclimate.com/github/orgsync/active_interaction "Code Climate"
206
+ [5]: https://gemnasium.com/orgsync/active_interaction "Dependency Status"
207
+ [build status]: https://travis-ci.org/orgsync/active_interaction.png
208
+ [code climate]: https://codeclimate.com/github/orgsync/active_interaction.png
209
+ [coverage status]: https://coveralls.io/repos/orgsync/active_interaction/badge.png
210
+ [dependency status]: https://gemnasium.com/orgsync/active_interaction.png
211
+ [documentation]: http://rubydoc.info/github/orgsync/active_interaction
212
+ [gem version]: https://badge.fury.io/rb/active_interaction.png
213
+ [mutations]: https://github.com/cypriss/mutations
214
+ [semantic versioning]: http://semver.org
@@ -20,4 +20,4 @@ require 'active_interaction/filters/time_filter'
20
20
  require 'active_interaction/base'
21
21
 
22
22
  # @since 0.1.0
23
- module ActiveInteraction; end
23
+ module ActiveInteraction end
@@ -1,8 +1,8 @@
1
1
  require 'active_support/core_ext/hash/indifferent_access'
2
2
 
3
3
  module ActiveInteraction
4
- # @abstract Subclass and override {#execute} to implement
5
- # a custom ActiveInteraction class.
4
+ # @abstract Subclass and override {#execute} to implement a custom
5
+ # ActiveInteraction class.
6
6
  #
7
7
  # @example
8
8
  # class ExampleInteraction < ActiveInteraction::Base
@@ -25,7 +25,7 @@ module ActiveInteraction
25
25
  # p outcome.errors
26
26
  # end
27
27
  class Base
28
- extend ::ActiveModel::Naming
28
+ extend ::ActiveModel::Naming
29
29
  include ::ActiveModel::Conversion
30
30
  include ::ActiveModel::Validations
31
31
 
@@ -57,17 +57,18 @@ module ActiveInteraction
57
57
  end
58
58
 
59
59
  options.each do |attribute, value|
60
- if respond_to?("#{attribute}=")
61
- send("_filter__#{attribute}=", value)
60
+ method = "_filter__#{attribute}="
61
+ if respond_to?(method, true)
62
+ send(method, value)
62
63
  else
63
64
  instance_variable_set("@#{attribute}", value)
64
65
  end
65
66
  end
66
67
  end
67
68
 
68
- # Runs the business logic associated with the interactor. The method is only
69
- # run when there are no validation errors. The return value is placed into
70
- # {#result}. This method must be overridden in the subclass.
69
+ # Runs the business logic associated with the interaction. The method is
70
+ # only run when there are no validation errors. The return value is
71
+ # placed into {#result}. This method must be overridden in the subclass.
71
72
  #
72
73
  # @raise [NotImplementedError] if the method is not defined.
73
74
  def execute
@@ -81,7 +82,8 @@ module ActiveInteraction
81
82
  #
82
83
  # @macro run_attributes
83
84
  #
84
- # @return [ActiveInteraction::Base] An instance of the class `run` is called on.
85
+ # @return [ActiveInteraction::Base] An instance of the class `run` is
86
+ # called on.
85
87
  def self.run(options = {})
86
88
  me = new(options)
87
89
 
@@ -105,55 +107,61 @@ module ActiveInteraction
105
107
  end
106
108
 
107
109
  # @private
108
- def self.method_missing(filter_type, *args, &block)
109
- klass = Filter.factory(filter_type)
110
+ def self.method_missing(type, *args, &block)
111
+ filter = Filter.factory(type)
110
112
  options = args.last.is_a?(Hash) ? args.pop : {}
111
113
  args.each do |attribute|
112
- filter_attr_accessor(klass, attribute, options, &block)
113
-
114
- filter_validator(attribute, filter_type, klass, options, &block)
114
+ set_up_reader(attribute, filter, options, &block)
115
+ set_up_writer(attribute, filter, options, &block)
116
+ set_up_validator(attribute, type, filter, options, &block)
115
117
  end
116
118
  end
117
119
  private_class_method :method_missing
118
120
 
119
121
  # @private
120
- def self.filter_attr_accessor(filter, attribute, options, &block)
121
- filter_attr_writer = "_filter__#{attribute}="
122
- define_method(filter_attr_writer) do |value|
123
- filtered_value =
124
- begin
125
- filter.prepare(attribute, value, options, &block)
126
- rescue InvalidValue, MissingValue
127
- value
128
- end
129
-
130
- instance_variable_set("@#{attribute}", filtered_value)
131
- end
132
- private filter_attr_writer
133
-
134
- attr_writer attribute
135
-
122
+ def self.set_up_reader(attribute, filter, options, &block)
123
+ default = nil
136
124
  if options.has_key?(:default)
137
125
  begin
138
- default_value = filter.prepare(attribute, options.delete(:default), options, &block)
126
+ default = filter.
127
+ prepare(attribute, options.delete(:default), options, &block)
139
128
  rescue InvalidValue
140
129
  raise InvalidDefaultValue
141
130
  end
142
131
  end
143
132
 
144
133
  define_method(attribute) do
145
- instance_variable_name = "@#{attribute}"
146
- if instance_variable_defined?(instance_variable_name)
147
- instance_variable_get(instance_variable_name)
134
+ symbol = "@#{attribute}"
135
+ if instance_variable_defined?(symbol)
136
+ instance_variable_get(symbol)
148
137
  else
149
- default_value
138
+ default
150
139
  end
151
140
  end
152
141
  end
153
- private_class_method :filter_attr_accessor
142
+ private_class_method :set_up_reader
143
+
144
+ # @private
145
+ def self.set_up_writer(attribute, filter, options, &block)
146
+ attr_writer attribute
147
+
148
+ writer = "_filter__#{attribute}="
149
+
150
+ define_method(writer) do |value|
151
+ value =
152
+ begin
153
+ filter.prepare(attribute, value, options, &block)
154
+ rescue InvalidValue, MissingValue
155
+ value
156
+ end
157
+ instance_variable_set("@#{attribute}", value)
158
+ end
159
+ private writer
160
+ end
161
+ private_class_method :set_up_writer
154
162
 
155
163
  # @private
156
- def self.filter_validator(attribute, type, filter, options, &block)
164
+ def self.set_up_validator(attribute, type, filter, options, &block)
157
165
  validator = "_validate__#{attribute}__#{type}"
158
166
 
159
167
  validate validator
@@ -165,11 +173,11 @@ module ActiveInteraction
165
173
  errors.add(attribute, 'is required')
166
174
  rescue InvalidValue
167
175
  errors.add(attribute,
168
- "is not a valid #{type.to_s.humanize.downcase}")
176
+ "is not a valid #{type.to_s.humanize.downcase}")
169
177
  end
170
178
  end
171
179
  private validator
172
180
  end
173
- private_class_method :filter_validator
181
+ private_class_method :set_up_validator
174
182
  end
175
183
  end
@@ -7,7 +7,7 @@ module ActiveInteraction
7
7
  @method_name, @block = method_name, block
8
8
 
9
9
  @attribute = args.shift if args.first.is_a?(Symbol)
10
- @options = (args.first || {}).dup
10
+ @options = (args.first || {}).dup
11
11
 
12
12
  if @options.include?(:default)
13
13
  raise ArgumentError, ':default is not supported inside filter blocks'
@@ -36,10 +36,10 @@ module ActiveInteraction
36
36
  def self.convert_values(values, &block)
37
37
  return values.dup unless block_given?
38
38
 
39
- filter_method = get_filter_method(FilterMethods.evaluate(&block))
40
-
39
+ method = get_filter_method(FilterMethods.evaluate(&block))
41
40
  values.map do |value|
42
- Filter.factory(filter_method.method_name).prepare(filter_method.attribute, value, filter_method.options, &filter_method.block)
41
+ Filter.factory(method.method_name).
42
+ prepare(method.attribute, value, method.options, &method.block)
43
43
  end
44
44
  end
45
45
  private_class_method :convert_values
@@ -1,7 +1,8 @@
1
1
  module ActiveInteraction
2
2
  class Base
3
3
  # Creates accessors for the attributes and ensures that values passed to
4
- # the attributes are DateTimes. String values are processed using `parse`.
4
+ # the attributes are DateTimes. String values are processed using
5
+ # `parse`.
5
6
  #
6
7
  # @macro attribute_method_params
7
8
  #
@@ -2,8 +2,8 @@ module ActiveInteraction
2
2
  class Base
3
3
  # Creates accessors for the attributes and ensures that values passed to
4
4
  # the attributes are Files or TempFiles. It will also extract a file from
5
- # any object with a `tempfile` method. This is useful when passing in Rails
6
- # params that include a file upload.
5
+ # any object with a `tempfile` method. This is useful when passing in
6
+ # Rails params that include a file upload.
7
7
  #
8
8
  # @macro attribute_method_params
9
9
  #
@@ -34,10 +34,10 @@ module ActiveInteraction
34
34
  def self.convert_values(hash, &block)
35
35
  return hash unless block_given?
36
36
 
37
- FilterMethods.evaluate(&block).each do |filter_method|
38
- key = filter_method.attribute
39
-
40
- hash[key] = Filter.factory(filter_method.method_name).prepare(key, hash[key], filter_method.options, &filter_method.block)
37
+ FilterMethods.evaluate(&block).each do |method|
38
+ key = method.attribute
39
+ hash[key] = Filter.factory(method.method_name).
40
+ prepare(key, hash[key], method.options, &method.block)
41
41
  end
42
42
 
43
43
  hash
@@ -4,7 +4,8 @@ module ActiveInteraction
4
4
  # the attributes are the correct class.
5
5
  #
6
6
  # @macro attribute_method_params
7
- # @option options [Class, String, Symbol] :class (use the attribute name) Class name used to ensure the value.
7
+ # @option options [Class, String, Symbol] :class (use the attribute name)
8
+ # Class name used to ensure the value.
8
9
  #
9
10
  # @example Ensures that the class is `Account`
10
11
  # model :account
@@ -2,8 +2,8 @@ module ActiveInteraction
2
2
  class Base
3
3
  # Creates accessors for the attributes and ensures that values passed to
4
4
  # the attributes are Times. Numeric values are processed using `at`.
5
- # Strings are processed using `parse`. If `Time.zone` is available it will
6
- # be used so that the values are time zone aware.
5
+ # Strings are processed using `parse`. If `Time.zone` is available it
6
+ # will be used so that the values are time zone aware.
7
7
  #
8
8
  # @macro attribute_method_params
9
9
  #
@@ -33,7 +33,7 @@ module ActiveInteraction
33
33
  end
34
34
 
35
35
  def self.time
36
- if Time.respond_to?(:zone)
36
+ if Time.respond_to?(:zone) && !Time.zone.nil?
37
37
  Time.zone
38
38
  else
39
39
  Time
@@ -1,3 +1,3 @@
1
1
  module ActiveInteraction
2
- VERSION = Gem::Version.new('0.1.2')
2
+ VERSION = Gem::Version.new('0.1.3')
3
3
  end
@@ -30,8 +30,8 @@ describe ActiveInteraction::Base do
30
30
 
31
31
  validates :thing, presence: true
32
32
 
33
- def self.model_name
34
- ActiveModel::Name.new(self, nil, SecureRandom.hex)
33
+ def self.name
34
+ SecureRandom.hex
35
35
  end
36
36
 
37
37
  def execute
@@ -62,13 +62,13 @@ describe ActiveInteraction::Base do
62
62
  end
63
63
  end
64
64
 
65
- describe InteractionWithFilter do
65
+ describe 'with a filter' do
66
66
  let(:described_class) { InteractionWithFilter }
67
67
 
68
68
  context 'failing validations' do
69
69
  before { options.merge!(thing: thing) }
70
70
 
71
- context 'InvalidValue' do
71
+ context 'with an invalid value' do
72
72
  let(:thing) { 'a' }
73
73
 
74
74
  it 'sets the attribute to the filtered value' do
@@ -76,7 +76,7 @@ describe ActiveInteraction::Base do
76
76
  end
77
77
  end
78
78
 
79
- context 'MissingValue' do
79
+ context 'without a value' do
80
80
  let(:thing) { nil }
81
81
 
82
82
  it 'sets the attribute to the filtered value' do
@@ -176,7 +176,9 @@ describe ActiveInteraction::Base do
176
176
 
177
177
  context 'failing validations' do
178
178
  it 'raises an error' do
179
- expect { result }.to raise_error ActiveInteraction::InteractionInvalid
179
+ expect {
180
+ result
181
+ }.to raise_error ActiveInteraction::InteractionInvalid
180
182
  end
181
183
  end
182
184
 
@@ -13,7 +13,7 @@ describe ActiveInteraction::ArrayFilter do
13
13
  end
14
14
  end
15
15
 
16
- context 'with block as a valid block' do
16
+ context 'with a block' do
17
17
  let(:block) { Proc.new { array } }
18
18
 
19
19
  context 'with an Array of Arrays' do
@@ -33,7 +33,7 @@ describe ActiveInteraction::ArrayFilter do
33
33
  end
34
34
  end
35
35
 
36
- context 'with block as a nested block' do
36
+ context 'with a nested block' do
37
37
  let(:block) { Proc.new { array { array } } }
38
38
  let(:value) { [[[]]] }
39
39
 
@@ -42,7 +42,7 @@ describe ActiveInteraction::ArrayFilter do
42
42
  end
43
43
  end
44
44
 
45
- context 'with block as an invalid block' do
45
+ context 'with an invalid block' do
46
46
  let(:block) { Proc.new { array; array } }
47
47
  let(:value) { [] }
48
48
 
@@ -13,7 +13,7 @@ describe ActiveInteraction::HashFilter do
13
13
  end
14
14
  end
15
15
 
16
- context 'with block as a block' do
16
+ context 'with a block' do
17
17
  let(:block) { Proc.new { hash :a } }
18
18
 
19
19
  context 'with a Hash containing a Hash' do
@@ -33,7 +33,7 @@ describe ActiveInteraction::HashFilter do
33
33
  end
34
34
  end
35
35
 
36
- context 'with block as a block with multiple filters' do
36
+ context 'with a block with multiple filters' do
37
37
  let(:block) { Proc.new { hash :a; hash :b } }
38
38
 
39
39
  context 'with a Hash containing Hashes' do
@@ -45,7 +45,7 @@ describe ActiveInteraction::HashFilter do
45
45
  end
46
46
  end
47
47
 
48
- context 'with block as a nested block' do
48
+ context 'with a nested block' do
49
49
  let(:block) { Proc.new { hash :a do; hash :b end } }
50
50
  let(:value) { { a: { b: {} } } }
51
51
 
@@ -9,7 +9,7 @@ describe ActiveInteraction::ModelFilter do
9
9
  before { options.merge!(class: TestModel) }
10
10
 
11
11
  describe '.prepare(key, value, options = {}, &block)' do
12
- shared_examples 'typechecking' do
12
+ shared_examples 'type checking' do
13
13
  context 'with the right class' do
14
14
  let(:value) { TestModel.new }
15
15
 
@@ -20,11 +20,11 @@ describe ActiveInteraction::ModelFilter do
20
20
  end
21
21
 
22
22
  context 'with options[:class] as a Class' do
23
- include_examples 'typechecking'
23
+ include_examples 'type checking'
24
24
  end
25
25
 
26
26
  context 'with options[:class] as a valid String' do
27
- include_examples 'typechecking'
27
+ include_examples 'type checking'
28
28
 
29
29
  before { options.merge!(class: options[:class].to_s) }
30
30
  end
@@ -14,7 +14,7 @@ describe ActiveInteraction::TimeFilter do
14
14
  end
15
15
 
16
16
  shared_examples 'conversion' do
17
- context 'with a float' do
17
+ context 'with a Float' do
18
18
  let(:value) { rand }
19
19
 
20
20
  it 'converts the Float' do
@@ -52,14 +52,28 @@ describe ActiveInteraction::TimeFilter do
52
52
  end
53
53
 
54
54
  context 'with Time.zone' do
55
- include_examples 'conversion'
55
+ context 'as nil' do
56
+ include_examples 'conversion'
57
+
58
+ before do
59
+ allow(Time).to receive(:zone).and_return(nil)
60
+ end
56
61
 
57
- before do
58
- allow(Time).to receive(:zone).and_return(Time)
62
+ after do
63
+ expect(Time).to have_received(:zone).once.with(no_args)
64
+ end
59
65
  end
60
66
 
61
- after do
62
- expect(Time).to have_received(:zone).with(no_args)
67
+ context 'as Time' do
68
+ include_examples 'conversion'
69
+
70
+ before do
71
+ allow(Time).to receive(:zone).and_return(Time)
72
+ end
73
+
74
+ after do
75
+ expect(Time).to have_received(:zone).twice.with(no_args)
76
+ end
63
77
  end
64
78
  end
65
79
  end
@@ -61,7 +61,7 @@ describe ArrayInteraction do
61
61
  array default: []
62
62
  end
63
63
  end
64
- # TODO: We should fail when defining the class, not when trying to run it.
64
+ # TODO: Fail when defining class, not running it.
65
65
  klass.run(a: [])
66
66
  }.to raise_error ArgumentError
67
67
  end
@@ -61,7 +61,7 @@ describe HashInteraction do
61
61
  hash :x, default: {}
62
62
  end
63
63
  end
64
- # TODO: We should fail when defining the class, not when trying to run it.
64
+ # TODO: Fail when defining class, not running it.
65
65
  klass.run(a: {})
66
66
  }.to raise_error ArgumentError
67
67
  end
@@ -1,5 +1,5 @@
1
1
  require 'spec_helper'
2
2
 
3
- describe 'ModelInteraciton' do
3
+ describe 'ModelInteraction' do
4
4
  it_behaves_like 'an interaction', :model, -> { Proc.new {} }, class: Proc
5
5
  end
@@ -34,7 +34,12 @@ describe ActiveInteraction::OverloadHash do
34
34
  with(:hash, *arguments)
35
35
  end
36
36
 
37
- it 'passes the block to method_missing'
37
+ it 'passes the block to method_missing' do
38
+ allow(subject).to receive(:method_missing) do |*, &other_block|
39
+ expect(other_block).to equal block
40
+ end
41
+ hash(&block)
42
+ end
38
43
  end
39
44
  end
40
45
  end
data/spec/spec_helper.rb CHANGED
@@ -3,4 +3,4 @@ Coveralls.wear!
3
3
 
4
4
  require 'active_interaction'
5
5
 
6
- Dir['./spec/support/**/*.rb'].sort.each {|f| require f}
6
+ Dir['./spec/support/**/*.rb'].sort.each { |f| require f }
@@ -4,15 +4,16 @@ shared_context 'interactions' do
4
4
  let(:result) { outcome.result }
5
5
  end
6
6
 
7
- shared_examples_for 'an interaction' do |type, value_lambda, filter_options = {}|
7
+ shared_examples_for 'an interaction' do |type, generator, filter_options = {}|
8
8
  include_context 'interactions'
9
9
 
10
10
  let(:described_class) do
11
11
  Class.new(ActiveInteraction::Base) do
12
12
  send(type, :required, filter_options)
13
13
  send(type, :optional, filter_options.merge(allow_nil: true))
14
- send(type, :default, filter_options.merge(default: value_lambda.call))
15
- send(type, :nil_default, filter_options.merge(allow_nil: true, default: nil))
14
+ send(type, :default, filter_options.merge(default: generator.call))
15
+ send(type, :nil_default,
16
+ filter_options.merge(allow_nil: true, default: nil))
16
17
 
17
18
  def execute
18
19
  {
@@ -32,7 +33,7 @@ shared_examples_for 'an interaction' do |type, value_lambda, filter_options = {}
32
33
  end
33
34
 
34
35
  context 'with options[:required]' do
35
- let(:required) { value_lambda.call }
36
+ let(:required) { generator.call }
36
37
 
37
38
  before { options.merge!(required: required) }
38
39
 
@@ -57,7 +58,7 @@ shared_examples_for 'an interaction' do |type, value_lambda, filter_options = {}
57
58
  end
58
59
 
59
60
  context 'with options[:optional]' do
60
- let(:optional) { value_lambda.call }
61
+ let(:optional) { generator.call }
61
62
 
62
63
  before { options.merge!(optional: optional) }
63
64
 
@@ -67,7 +68,7 @@ shared_examples_for 'an interaction' do |type, value_lambda, filter_options = {}
67
68
  end
68
69
 
69
70
  context 'with options[:default]' do
70
- let(:default) { value_lambda.call }
71
+ let(:default) { generator.call }
71
72
 
72
73
  before { options.merge!(default: default) }
73
74
 
metadata CHANGED
@@ -1,8 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: active_interaction
3
3
  version: !ruby/object:Gem::Version
4
- prerelease:
5
- version: 0.1.2
4
+ version: 0.1.3
6
5
  platform: ruby
7
6
  authors:
8
7
  - Aaron Lasseigne
@@ -10,152 +9,134 @@ authors:
10
9
  autorequire:
11
10
  bindir: bin
12
11
  cert_chain: []
13
- date: 2013-07-15 00:00:00.000000000 Z
12
+ date: 2013-07-16 00:00:00.000000000 Z
14
13
  dependencies:
15
14
  - !ruby/object:Gem::Dependency
16
15
  name: activemodel
17
- type: :runtime
18
16
  requirement: !ruby/object:Gem::Requirement
19
17
  requirements:
20
18
  - - ! '>='
21
19
  - !ruby/object:Gem::Version
22
20
  version: 3.0.0
23
- none: false
21
+ type: :runtime
22
+ prerelease: false
24
23
  version_requirements: !ruby/object:Gem::Requirement
25
24
  requirements:
26
25
  - - ! '>='
27
26
  - !ruby/object:Gem::Version
28
27
  version: 3.0.0
29
- none: false
30
- prerelease: false
31
28
  - !ruby/object:Gem::Dependency
32
29
  name: bundler
33
- type: :development
34
30
  requirement: !ruby/object:Gem::Requirement
35
31
  requirements:
36
32
  - - ~>
37
33
  - !ruby/object:Gem::Version
38
34
  version: '1.3'
39
- none: false
35
+ type: :development
36
+ prerelease: false
40
37
  version_requirements: !ruby/object:Gem::Requirement
41
38
  requirements:
42
39
  - - ~>
43
40
  - !ruby/object:Gem::Version
44
41
  version: '1.3'
45
- none: false
46
- prerelease: false
47
42
  - !ruby/object:Gem::Dependency
48
43
  name: coveralls
49
- type: :development
50
44
  requirement: !ruby/object:Gem::Requirement
51
45
  requirements:
52
46
  - - ~>
53
47
  - !ruby/object:Gem::Version
54
48
  version: '0.6'
55
- none: false
49
+ type: :development
50
+ prerelease: false
56
51
  version_requirements: !ruby/object:Gem::Requirement
57
52
  requirements:
58
53
  - - ~>
59
54
  - !ruby/object:Gem::Version
60
55
  version: '0.6'
61
- none: false
62
- prerelease: false
63
56
  - !ruby/object:Gem::Dependency
64
57
  name: guard-rspec
65
- type: :development
66
58
  requirement: !ruby/object:Gem::Requirement
67
59
  requirements:
68
60
  - - ~>
69
61
  - !ruby/object:Gem::Version
70
62
  version: '3.0'
71
- none: false
63
+ type: :development
64
+ prerelease: false
72
65
  version_requirements: !ruby/object:Gem::Requirement
73
66
  requirements:
74
67
  - - ~>
75
68
  - !ruby/object:Gem::Version
76
69
  version: '3.0'
77
- none: false
78
- prerelease: false
79
70
  - !ruby/object:Gem::Dependency
80
- name: kramdown
81
- type: :development
71
+ name: rake
82
72
  requirement: !ruby/object:Gem::Requirement
83
73
  requirements:
84
74
  - - ~>
85
75
  - !ruby/object:Gem::Version
86
- version: '1.1'
87
- none: false
76
+ version: '10.1'
77
+ type: :development
78
+ prerelease: false
88
79
  version_requirements: !ruby/object:Gem::Requirement
89
80
  requirements:
90
81
  - - ~>
91
82
  - !ruby/object:Gem::Version
92
- version: '1.1'
93
- none: false
94
- prerelease: false
83
+ version: '10.1'
95
84
  - !ruby/object:Gem::Dependency
96
- name: rake
97
- type: :development
85
+ name: rb-fsevent
98
86
  requirement: !ruby/object:Gem::Requirement
99
87
  requirements:
100
88
  - - ~>
101
89
  - !ruby/object:Gem::Version
102
- version: '10.1'
103
- none: false
90
+ version: '0.9'
91
+ type: :development
92
+ prerelease: false
104
93
  version_requirements: !ruby/object:Gem::Requirement
105
94
  requirements:
106
95
  - - ~>
107
96
  - !ruby/object:Gem::Version
108
- version: '10.1'
109
- none: false
110
- prerelease: false
97
+ version: '0.9'
111
98
  - !ruby/object:Gem::Dependency
112
- name: rb-fsevent
113
- type: :development
99
+ name: rdoc
114
100
  requirement: !ruby/object:Gem::Requirement
115
101
  requirements:
116
102
  - - ~>
117
103
  - !ruby/object:Gem::Version
118
- version: '0.9'
119
- none: false
104
+ version: '4.0'
105
+ type: :development
106
+ prerelease: false
120
107
  version_requirements: !ruby/object:Gem::Requirement
121
108
  requirements:
122
109
  - - ~>
123
110
  - !ruby/object:Gem::Version
124
- version: '0.9'
125
- none: false
126
- prerelease: false
111
+ version: '4.0'
127
112
  - !ruby/object:Gem::Dependency
128
113
  name: rspec
129
- type: :development
130
114
  requirement: !ruby/object:Gem::Requirement
131
115
  requirements:
132
116
  - - ~>
133
117
  - !ruby/object:Gem::Version
134
118
  version: '2.14'
135
- none: false
119
+ type: :development
120
+ prerelease: false
136
121
  version_requirements: !ruby/object:Gem::Requirement
137
122
  requirements:
138
123
  - - ~>
139
124
  - !ruby/object:Gem::Version
140
125
  version: '2.14'
141
- none: false
142
- prerelease: false
143
126
  - !ruby/object:Gem::Dependency
144
127
  name: yard
145
- type: :development
146
128
  requirement: !ruby/object:Gem::Requirement
147
129
  requirements:
148
130
  - - ~>
149
131
  - !ruby/object:Gem::Version
150
132
  version: '0.8'
151
- none: false
133
+ type: :development
134
+ prerelease: false
152
135
  version_requirements: !ruby/object:Gem::Requirement
153
136
  requirements:
154
137
  - - ~>
155
138
  - !ruby/object:Gem::Version
156
139
  version: '0.8'
157
- none: false
158
- prerelease: false
159
140
  description: Manage application specific business logic.
160
141
  email:
161
142
  - aaron.lasseigne@gmail.com
@@ -164,6 +145,25 @@ executables: []
164
145
  extensions: []
165
146
  extra_rdoc_files: []
166
147
  files:
148
+ - lib/active_interaction/base.rb
149
+ - lib/active_interaction/errors.rb
150
+ - lib/active_interaction/filter.rb
151
+ - lib/active_interaction/filter_method.rb
152
+ - lib/active_interaction/filter_methods.rb
153
+ - lib/active_interaction/filters/array_filter.rb
154
+ - lib/active_interaction/filters/boolean_filter.rb
155
+ - lib/active_interaction/filters/date_filter.rb
156
+ - lib/active_interaction/filters/date_time_filter.rb
157
+ - lib/active_interaction/filters/file_filter.rb
158
+ - lib/active_interaction/filters/float_filter.rb
159
+ - lib/active_interaction/filters/hash_filter.rb
160
+ - lib/active_interaction/filters/integer_filter.rb
161
+ - lib/active_interaction/filters/model_filter.rb
162
+ - lib/active_interaction/filters/string_filter.rb
163
+ - lib/active_interaction/filters/time_filter.rb
164
+ - lib/active_interaction/overload_hash.rb
165
+ - lib/active_interaction/version.rb
166
+ - lib/active_interaction.rb
167
167
  - spec/active_interaction/base_spec.rb
168
168
  - spec/active_interaction/filter_method_spec.rb
169
169
  - spec/active_interaction/filter_methods_spec.rb
@@ -194,31 +194,13 @@ files:
194
194
  - spec/spec_helper.rb
195
195
  - spec/support/filters.rb
196
196
  - spec/support/interactions.rb
197
- - lib/active_interaction/base.rb
198
- - lib/active_interaction/errors.rb
199
- - lib/active_interaction/filter.rb
200
- - lib/active_interaction/filter_method.rb
201
- - lib/active_interaction/filter_methods.rb
202
- - lib/active_interaction/filters/array_filter.rb
203
- - lib/active_interaction/filters/boolean_filter.rb
204
- - lib/active_interaction/filters/date_filter.rb
205
- - lib/active_interaction/filters/date_time_filter.rb
206
- - lib/active_interaction/filters/file_filter.rb
207
- - lib/active_interaction/filters/float_filter.rb
208
- - lib/active_interaction/filters/hash_filter.rb
209
- - lib/active_interaction/filters/integer_filter.rb
210
- - lib/active_interaction/filters/model_filter.rb
211
- - lib/active_interaction/filters/string_filter.rb
212
- - lib/active_interaction/filters/time_filter.rb
213
- - lib/active_interaction/overload_hash.rb
214
- - lib/active_interaction/version.rb
215
- - lib/active_interaction.rb
216
197
  - CHANGELOG.md
217
198
  - LICENSE.txt
218
199
  - README.md
219
200
  homepage: https://github.com/orgsync/active_interaction
220
201
  licenses:
221
202
  - MIT
203
+ metadata: {}
222
204
  post_install_message:
223
205
  rdoc_options: []
224
206
  require_paths:
@@ -228,21 +210,16 @@ required_ruby_version: !ruby/object:Gem::Requirement
228
210
  - - ! '>='
229
211
  - !ruby/object:Gem::Version
230
212
  version: 1.9.3
231
- none: false
232
213
  required_rubygems_version: !ruby/object:Gem::Requirement
233
214
  requirements:
234
215
  - - ! '>='
235
216
  - !ruby/object:Gem::Version
236
- segments:
237
- - 0
238
- hash: 669983182544330814
239
217
  version: '0'
240
- none: false
241
218
  requirements: []
242
219
  rubyforge_project:
243
- rubygems_version: 1.8.23
220
+ rubygems_version: 2.0.5
244
221
  signing_key:
245
- specification_version: 3
222
+ specification_version: 4
246
223
  summary: Manage application specific business logic.
247
224
  test_files:
248
225
  - spec/active_interaction/base_spec.rb