active_interaction 0.1.2 → 0.1.3

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 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