shoulda-callback-matchers 0.4.0 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +5 -0
- data/.travis.yml +2 -5
- data/Appraisals +6 -0
- data/MIT-LICENSE +1 -1
- data/README.md +33 -12
- data/ext/mkrf_conf.rb +3 -3
- data/lib/shoulda-callback-matchers.rb +1 -1
- data/lib/shoulda/callback/matchers.rb +4 -3
- data/lib/shoulda/callback/matchers/active_model.rb +117 -48
- data/lib/shoulda/callback/matchers/integrations/test_unit.rb +5 -3
- data/lib/shoulda/callback/matchers/rails_version_helper.rb +46 -0
- data/lib/shoulda/callback/matchers/version.rb +1 -1
- data/shoulda-callback-matchers.gemspec +0 -1
- data/spec/shoulda/active_model/callback_matcher_spec.rb +43 -27
- data/spec/spec_helper.rb +21 -13
- data/spec/support/class_builder.rb +5 -18
- data/spec/support/model_builder.rb +15 -18
- metadata +3 -23
- data/.DS_Store +0 -0
- data/.ruby-gemset +0 -1
- data/.ruby-version +0 -1
- data/spec/fixtures/users.yml +0 -6
- data/spec/support/active_model_versions.rb +0 -9
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 36ecd3914a3443c58fd61371532b3e04003f5dea
|
4
|
+
data.tar.gz: 63aa4153512b0f40d245c977a1ecf67ef74af9b0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8d540b4fbf5a1e2fa7f8b94c55df9f02ffec8c31bc49875daac55be07b112b448b4296631277328bdf044352d4d43e4c3132814d06c429ccce33378604d1cb8f
|
7
|
+
data.tar.gz: 2e6f4830c5af8fcedd2097736d799543eac77c35f72c5895920b22c5364e68be4f9021fd193e7e7fbcbd47e034d1a2e952a3a827afc1c2cc2f0eff29b4ef754b
|
data/.gitignore
CHANGED
data/.travis.yml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
rvm:
|
2
2
|
- 1.9.3
|
3
3
|
- 2.0.0
|
4
|
-
- 2.1.
|
4
|
+
- 2.1.1
|
5
5
|
- rbx
|
6
6
|
- jruby-19mode
|
7
7
|
- jruby-20mode
|
@@ -9,11 +9,8 @@ rvm:
|
|
9
9
|
script: "bundle install && bundle exec rake"
|
10
10
|
|
11
11
|
gemfile:
|
12
|
-
- gemfiles/4.
|
12
|
+
- gemfiles/4.1.gemfile
|
13
13
|
|
14
14
|
matrix:
|
15
15
|
allow_failures:
|
16
|
-
- rvm: 2.1.0
|
17
16
|
- rvm: rbx
|
18
|
-
- rvm: jruby-19mode
|
19
|
-
- rvm: jruby-20mode
|
data/Appraisals
CHANGED
data/MIT-LICENSE
CHANGED
data/README.md
CHANGED
@@ -1,6 +1,12 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
1
|
+
#Shoulda Callback Matchers
|
2
|
+
[![Gem Version](https://badge.fury.io/rb/shoulda-callback-matchers.svg)](http://badge.fury.io/rb/shoulda-callback-matchers) [![Build Status](https://travis-ci.org/beatrichartz/shoulda-callback-matchers.svg?branch=master)](https://travis-ci.org/beatrichartz/shoulda-callback-matchers) [![Code Climate](https://codeclimate.com/github/beatrichartz/shoulda-callback-matchers.png)](https://codeclimate.com/github/beatrichartz/shoulda-callback-matchers) [![Dependency Status](https://gemnasium.com/beatrichartz/shoulda-callback-matchers.svg)](https://gemnasium.com/beatrichartz/shoulda-callback-matchers)
|
3
|
+
|
4
|
+
|
5
|
+
Matchers to test before, after and around hooks(currently supports method and object callbacks):
|
6
|
+
|
7
|
+
## Usage
|
8
|
+
|
9
|
+
Method Callbacks:
|
4
10
|
|
5
11
|
describe Post do
|
6
12
|
it { should callback(:count_comments).before(:save) }
|
@@ -18,10 +24,21 @@ Symbol Callbacks:
|
|
18
24
|
Object Callbacks:
|
19
25
|
|
20
26
|
class CallbackClass
|
21
|
-
def before_save
|
22
|
-
|
23
|
-
|
24
|
-
|
27
|
+
def before_save
|
28
|
+
...
|
29
|
+
end
|
30
|
+
|
31
|
+
def after_create
|
32
|
+
...
|
33
|
+
end
|
34
|
+
|
35
|
+
def before_validation
|
36
|
+
...
|
37
|
+
end
|
38
|
+
|
39
|
+
def after_find
|
40
|
+
...
|
41
|
+
end
|
25
42
|
end
|
26
43
|
|
27
44
|
describe Post do
|
@@ -37,12 +54,16 @@ Object Callbacks:
|
|
37
54
|
it { should callback(CallbackClass).before(:destroy) }
|
38
55
|
end
|
39
56
|
|
40
|
-
|
57
|
+
This will test:
|
58
|
+
- the method call
|
59
|
+
- method existence
|
60
|
+
|
61
|
+
Either on the model itself or on the callback object. Be aware that obviously this does not test the callback method or object itself. It makes testing via triggering the callback events (validation, save) unnecessary, but you still have to test the called procedure seperately.
|
41
62
|
|
42
63
|
In Rails 3 or 4 and Bundler, add the following to your Gemfile:
|
43
64
|
|
44
65
|
group :test do
|
45
|
-
gem "shoulda-callback-matchers", "~> 0
|
66
|
+
gem "shoulda-callback-matchers", "~> 1.0"
|
46
67
|
end
|
47
68
|
|
48
69
|
This gem uses semantic versioning, so you won't have incompability issues with patches.
|
@@ -61,12 +82,12 @@ This gem is maintained by me and its contributors,
|
|
61
82
|
Shoulda is maintained and funded by [thoughtbot](http://thoughtbot.com/community)
|
62
83
|
|
63
84
|
## Contributors & Contributions
|
64
|
-
- @pvertenten
|
85
|
+
- @pvertenten (callback objects)
|
65
86
|
|
66
87
|
Let's make this gem useful, send me a PR if you've discovered an issue you'd like to fix!
|
67
88
|
|
68
89
|
## License
|
69
90
|
|
70
|
-
Shoulda is Copyright © 2006-
|
71
|
-
Callback Matchers is Copyright ©
|
91
|
+
Shoulda is Copyright © 2006-2014 thoughtbot, inc.
|
92
|
+
Callback Matchers is Copyright © 2014 Beat Richartz
|
72
93
|
It is free software, and may be redistributed under the terms specified in the MIT-LICENSE file.
|
data/ext/mkrf_conf.rb
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
rbx = defined?(RUBY_ENGINE) && 'rbx' == RUBY_ENGINE
|
2
2
|
|
3
3
|
def already_installed(dep)
|
4
|
-
!Gem::DependencyInstaller.new(:
|
5
|
-
!Gem::DependencyInstaller.new(:
|
4
|
+
!Gem::DependencyInstaller.new(domain: :local).find_gems_with_sources(dep).empty? ||
|
5
|
+
!Gem::DependencyInstaller.new(domain: :local, prerelease: true).find_gems_with_sources(dep).empty?
|
6
6
|
end
|
7
7
|
|
8
8
|
if rbx
|
@@ -27,7 +27,7 @@ if rbx
|
|
27
27
|
inst = Gem::DependencyInstaller.new
|
28
28
|
dep.each {|d| inst.install d }
|
29
29
|
rescue
|
30
|
-
inst = Gem::DependencyInstaller.new(:
|
30
|
+
inst = Gem::DependencyInstaller.new(prerelease: true)
|
31
31
|
begin
|
32
32
|
dep.each {|d| inst.install d }
|
33
33
|
rescue Exception => e
|
@@ -1 +1 @@
|
|
1
|
-
|
1
|
+
require_relative 'shoulda/callback/matchers'
|
@@ -1,7 +1,8 @@
|
|
1
|
-
|
1
|
+
require_relative 'matchers/version'
|
2
|
+
require_relative 'matchers/rails_version_helper'
|
2
3
|
|
3
4
|
if defined?(RSpec)
|
4
|
-
|
5
|
+
require_relative 'matchers/integrations/rspec'
|
5
6
|
end
|
6
7
|
|
7
|
-
|
8
|
+
require_relative 'matchers/integrations/test_unit'
|
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'ostruct'
|
2
|
+
|
1
3
|
module Shoulda # :nodoc:
|
2
4
|
module Callback # :nodoc:
|
3
5
|
module Matchers # :nodoc:
|
@@ -17,16 +19,18 @@ module Shoulda # :nodoc:
|
|
17
19
|
# it { should callback(:method).before(:validation).unless(:should_it_not?) }
|
18
20
|
# it { should callback(CallbackClass).before(:validation).unless(:should_it_not?) }
|
19
21
|
#
|
20
|
-
def callback
|
21
|
-
CallbackMatcher.new
|
22
|
+
def callback method
|
23
|
+
CallbackMatcher.new method
|
22
24
|
end
|
23
25
|
|
24
26
|
class CallbackMatcher # :nodoc:
|
27
|
+
include RailsVersionHelper
|
25
28
|
|
26
|
-
def initialize
|
29
|
+
def initialize method
|
27
30
|
@method = method
|
28
31
|
end
|
29
32
|
|
33
|
+
# @todo replace with %i() as soon as 1.9 is deprecated
|
30
34
|
[:before, :after, :around].each do |hook|
|
31
35
|
define_method hook do |lifecycle|
|
32
36
|
@hook = hook
|
@@ -45,46 +49,39 @@ module Shoulda # :nodoc:
|
|
45
49
|
end
|
46
50
|
end
|
47
51
|
|
48
|
-
def on
|
52
|
+
def on optional_lifecycle
|
49
53
|
unless @lifecycle == :validation
|
50
|
-
|
51
|
-
else
|
52
|
-
@optional_lifecycle = optional_lifecycle
|
54
|
+
raise UsageError.new("The .on option is only valid for the validation lifecycle and cannot be used with #{@lifecycle}, use with .before(:validation) or .after(:validation)")
|
53
55
|
end
|
56
|
+
|
57
|
+
@optional_lifecycle = optional_lifecycle
|
54
58
|
|
55
59
|
self
|
56
60
|
end
|
57
61
|
|
58
|
-
def matches?
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
matches_conditions?(callback) &&
|
69
|
-
matches_optional_lifecycle?(callback)
|
70
|
-
end
|
71
|
-
callbacks.size > 0
|
62
|
+
def matches? subject
|
63
|
+
check_preconditions!
|
64
|
+
|
65
|
+
callbacks = subject.send :"_#{@lifecycle}_callbacks"
|
66
|
+
callbacks.any? do |callback|
|
67
|
+
has_callback?(subject, callback) &&
|
68
|
+
matches_hook?(callback) &&
|
69
|
+
matches_conditions?(callback) &&
|
70
|
+
matches_optional_lifecycle?(callback) &&
|
71
|
+
callback_method_exists?(subject, callback)
|
72
72
|
end
|
73
73
|
end
|
74
|
-
|
75
|
-
def is_callback?(subject, callback)
|
76
|
-
is_callback_object?(subject, callback) || is_callback_symbol?(subject, callback)
|
77
|
-
end
|
78
74
|
|
79
|
-
def
|
80
|
-
callback
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
75
|
+
def callback_method_exists? object, callback
|
76
|
+
if is_class_callback?(object, callback) && !callback_object(object, callback).respond_to?(:"#{@hook}_#{@lifecycle}", true)
|
77
|
+
@failure_message = "callback #{@method} is listed as a callback #{@hook} #{@lifecycle}#{optional_lifecycle_phrase}#{condition_phrase}, but the given object does not respond to #{@hook}_#{@lifecycle} (using respond_to?(:#{@hook}_#{@lifecycle}, true)"
|
78
|
+
false
|
79
|
+
elsif !is_class_callback?(object, callback) && !object.respond_to?(callback.filter, true)
|
80
|
+
@failure_message = "callback #{@method} is listed as a callback #{@hook} #{@lifecycle}#{optional_lifecycle_phrase}#{condition_phrase}, but the model does not respond to #{@method} (using respond_to?(:#{@method}, true)"
|
81
|
+
false
|
82
|
+
else
|
83
|
+
true
|
84
|
+
end
|
88
85
|
end
|
89
86
|
|
90
87
|
def failure_message
|
@@ -98,34 +95,106 @@ module Shoulda # :nodoc:
|
|
98
95
|
def description
|
99
96
|
"callback #{@method} #{@hook} #{@lifecycle}#{optional_lifecycle_phrase}#{condition_phrase}"
|
100
97
|
end
|
98
|
+
|
99
|
+
|
101
100
|
|
102
101
|
private
|
103
102
|
|
104
|
-
|
105
|
-
|
103
|
+
def check_preconditions!
|
104
|
+
check_lifecycle_present!
|
105
|
+
end
|
106
|
+
|
107
|
+
def check_lifecycle_present!
|
108
|
+
unless @lifecycle
|
109
|
+
raise UsageError.new("callback #{@method} can not be tested against an undefined lifecycle, use .before, .after or .around")
|
106
110
|
end
|
111
|
+
end
|
107
112
|
|
108
|
-
|
113
|
+
def precondition_failed?
|
114
|
+
@failure_message.present?
|
115
|
+
end
|
116
|
+
|
117
|
+
def matches_hook? callback
|
118
|
+
callback.kind == @hook
|
119
|
+
end
|
120
|
+
|
121
|
+
def has_callback? subject, callback
|
122
|
+
has_callback_object?(subject, callback) || has_callback_method?(callback) || has_callback_class?(callback)
|
123
|
+
end
|
124
|
+
|
125
|
+
def has_callback_method? callback
|
126
|
+
callback.filter == @method
|
127
|
+
end
|
128
|
+
|
129
|
+
def has_callback_class? callback
|
130
|
+
class_callback_required? && callback.filter.is_a?(@method)
|
131
|
+
end
|
132
|
+
|
133
|
+
def has_callback_object? subject, callback
|
134
|
+
callback.filter.respond_to?(:match) &&
|
135
|
+
callback.filter.match(/\A_callback/) &&
|
136
|
+
subject.respond_to?(:"#{callback.filter}_object") &&
|
137
|
+
callback_object(subject, callback).class == @method
|
138
|
+
end
|
139
|
+
|
140
|
+
def matches_conditions? callback
|
141
|
+
if rails_4_1?
|
142
|
+
!@condition || callback.instance_variable_get(:"@#{@condition_type}").include?(@condition)
|
143
|
+
else
|
144
|
+
!@condition || callback.options[@condition_type].include?(@condition)
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
def matches_optional_lifecycle? callback
|
149
|
+
if rails_4_1?
|
150
|
+
if_conditions = callback.instance_variable_get(:@if)
|
151
|
+
!@optional_lifecycle || if_conditions.include?(lifecycle_context_string) || active_model_proc_matches_optional_lifecycle?(if_conditions)
|
152
|
+
else
|
109
153
|
!@optional_lifecycle || callback.options[:if].include?(lifecycle_context_string)
|
110
154
|
end
|
155
|
+
end
|
156
|
+
|
157
|
+
def condition_phrase
|
158
|
+
" #{@condition_type} #{@condition} evaluates to #{@condition_type == :if ? 'true' : 'false'}" if @condition
|
159
|
+
end
|
160
|
+
|
161
|
+
def optional_lifecycle_phrase
|
162
|
+
" on #{@optional_lifecycle}" if @optional_lifecycle
|
163
|
+
end
|
111
164
|
|
112
|
-
|
113
|
-
|
165
|
+
def lifecycle_context_string
|
166
|
+
if rails_4?
|
167
|
+
"[:#{@optional_lifecycle}].include? self.validation_context"
|
168
|
+
else
|
169
|
+
"self.validation_context == :#{@optional_lifecycle}"
|
114
170
|
end
|
171
|
+
end
|
115
172
|
|
116
|
-
|
117
|
-
|
173
|
+
def active_model_proc_matches_optional_lifecycle? if_conditions
|
174
|
+
if_conditions.select{|i| i.is_a? Proc }.any? do |condition|
|
175
|
+
condition.call OpenStruct.new validation_context: @optional_lifecycle
|
118
176
|
end
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
177
|
+
end
|
178
|
+
|
179
|
+
def class_callback_required?
|
180
|
+
!@method.is_a?(Symbol) && !@method.is_a?(String)
|
181
|
+
end
|
182
|
+
|
183
|
+
def is_class_callback? subject, callback
|
184
|
+
!callback_object(subject, callback).is_a?(Symbol) && !callback_object(subject, callback).is_a?(String)
|
185
|
+
end
|
186
|
+
|
187
|
+
def callback_object subject, callback
|
188
|
+
if rails_3? && !callback.filter.is_a?(Symbol)
|
189
|
+
subject.send("#{callback.filter}_object")
|
190
|
+
else
|
191
|
+
callback.filter
|
126
192
|
end
|
193
|
+
end
|
127
194
|
|
128
195
|
end
|
196
|
+
|
197
|
+
UsageError = Class.new NameError
|
129
198
|
end
|
130
199
|
end
|
131
200
|
end
|
@@ -1,15 +1,17 @@
|
|
1
1
|
# :enddoc:
|
2
2
|
|
3
|
+
include Shoulda::Callback::Matchers::RailsVersionHelper
|
4
|
+
|
3
5
|
# in environments where test/unit is not required, this is necessary
|
4
6
|
unless defined?(Test::Unit::TestCase)
|
5
7
|
begin
|
6
|
-
require 'test/unit/testcase'
|
8
|
+
require rails_4_1? ? 'minitest' : 'test/unit/testcase'
|
7
9
|
rescue LoadError
|
8
10
|
# silent
|
9
11
|
end
|
10
12
|
end
|
11
13
|
|
12
|
-
if defined?(ActiveRecord)
|
14
|
+
if defined?(::ActiveRecord)
|
13
15
|
require 'shoulda/callback/matchers/active_model'
|
14
16
|
|
15
17
|
module Test
|
@@ -20,7 +22,7 @@ if defined?(ActiveRecord)
|
|
20
22
|
end
|
21
23
|
end
|
22
24
|
end
|
23
|
-
elsif defined?(ActiveModel)
|
25
|
+
elsif defined?(::ActiveModel)
|
24
26
|
require 'shoulda/callback/matchers/active_model'
|
25
27
|
|
26
28
|
module Test
|
@@ -0,0 +1,46 @@
|
|
1
|
+
# :enddoc:
|
2
|
+
module Shoulda
|
3
|
+
module Callback
|
4
|
+
module Matchers
|
5
|
+
module RailsVersionHelper
|
6
|
+
def rails_4_1?
|
7
|
+
rails_4? && minor_version_equals?(1)
|
8
|
+
end
|
9
|
+
|
10
|
+
def rails_4_0?
|
11
|
+
rails_4? && vminor_version_equals?(0)
|
12
|
+
end
|
13
|
+
|
14
|
+
def rails_4?
|
15
|
+
major_version_equals? 4
|
16
|
+
end
|
17
|
+
|
18
|
+
def rails_3?
|
19
|
+
major_version_equals? 3
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
def major_version_equals? number
|
25
|
+
if active_record?
|
26
|
+
ActiveRecord::VERSION::MAJOR == number
|
27
|
+
else
|
28
|
+
ActiveModel::VERSION::MAJOR == number
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def minor_version_equals? number
|
33
|
+
if active_record?
|
34
|
+
ActiveRecord::VERSION::MINOR == number
|
35
|
+
else
|
36
|
+
ActiveModel::VERSION::MINOR == number
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def active_record?
|
41
|
+
defined?(::ActiveRecord)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -22,7 +22,6 @@ Gem::Specification.new do |s|
|
|
22
22
|
|
23
23
|
s.add_development_dependency('appraisal', '~> 0.5')
|
24
24
|
s.add_development_dependency('aruba')
|
25
|
-
s.add_development_dependency('bourne', '~> 1.3')
|
26
25
|
s.add_development_dependency('bundler', '>= 1.1')
|
27
26
|
s.add_development_dependency('rails', '>= 3')
|
28
27
|
s.add_development_dependency('rake', '~> 10')
|
@@ -1,10 +1,10 @@
|
|
1
|
-
require 'spec_helper'
|
1
|
+
require 'spec_helper'
|
2
2
|
|
3
3
|
describe Shoulda::Callback::Matchers::ActiveModel do
|
4
4
|
|
5
5
|
context "invalid use" do
|
6
6
|
before do
|
7
|
-
@callback_object_class = define_model
|
7
|
+
@callback_object_class = define_model :callback do
|
8
8
|
define_method("before_create"){}
|
9
9
|
define_method("after_save"){}
|
10
10
|
end
|
@@ -13,35 +13,30 @@ describe Shoulda::Callback::Matchers::ActiveModel do
|
|
13
13
|
:other => :integer) do
|
14
14
|
before_create :dance!, :if => :evaluates_to_false!
|
15
15
|
after_save :shake!, :unless => :evaluates_to_true!
|
16
|
+
after_create :wiggle!
|
16
17
|
before_create callback_object, :if => :evaluates_to_false!
|
17
18
|
after_save callback_object, :unless => :evaluates_to_true!
|
19
|
+
after_create callback_object
|
18
20
|
define_method(:shake!){}
|
19
21
|
define_method(:dance!){}
|
20
22
|
end.new
|
23
|
+
|
21
24
|
end
|
22
|
-
it "should return a meaningful
|
23
|
-
|
24
|
-
|
25
|
-
matcher.failure_message.should == "callback dance! can not be tested against an undefined lifecycle, use .before, .after or .around"
|
26
|
-
matcher.negative_failure_message.should == "callback dance! can not be tested against an undefined lifecycle, use .before, .after or .around"
|
25
|
+
it "should return a meaningful error when used without a defined lifecycle" do
|
26
|
+
lambda { callback(:dance!).matches? :foo }.should raise_error Shoulda::Callback::Matchers::ActiveModel::UsageError,
|
27
|
+
"callback dance! can not be tested against an undefined lifecycle, use .before, .after or .around"
|
27
28
|
end
|
28
|
-
it "should return a meaningful
|
29
|
-
|
30
|
-
|
31
|
-
matcher.failure_message.should == "The .on option is only valid for the validation lifecycle and cannot be used with create, use with .before(:validation) or .after(:validation)"
|
32
|
-
matcher.negative_failure_message.should == "The .on option is only valid for the validation lifecycle and cannot be used with create, use with .before(:validation) or .after(:validation)"
|
29
|
+
it "should return a meaningful error when used with an optional lifecycle without the original lifecycle being validation" do
|
30
|
+
lambda { callback(:dance!).after(:create).on(:save) }.should raise_error Shoulda::Callback::Matchers::ActiveModel::UsageError,
|
31
|
+
"The .on option is only valid for the validation lifecycle and cannot be used with create, use with .before(:validation) or .after(:validation)"
|
33
32
|
end
|
34
|
-
it "should return a meaningful
|
35
|
-
|
36
|
-
|
37
|
-
matcher.failure_message.should == "callback Callback can not be tested against an undefined lifecycle, use .before, .after or .around"
|
38
|
-
matcher.negative_failure_message.should == "callback Callback can not be tested against an undefined lifecycle, use .before, .after or .around"
|
33
|
+
it "should return a meaningful error when used without a defined lifecycle" do
|
34
|
+
lambda { callback(@callback_object_class).matches? :foo }.should raise_error Shoulda::Callback::Matchers::ActiveModel::UsageError,
|
35
|
+
"callback Callback can not be tested against an undefined lifecycle, use .before, .after or .around"
|
39
36
|
end
|
40
|
-
it "should return a meaningful
|
41
|
-
|
42
|
-
|
43
|
-
matcher.failure_message.should == "The .on option is only valid for the validation lifecycle and cannot be used with create, use with .before(:validation) or .after(:validation)"
|
44
|
-
matcher.negative_failure_message.should == "The .on option is only valid for the validation lifecycle and cannot be used with create, use with .before(:validation) or .after(:validation)"
|
37
|
+
it "should return a meaningful error when used with an optional lifecycle without the original lifecycle being validation" do
|
38
|
+
lambda { callback(@callback_object_class).after(:create).on(:save) }.should raise_error Shoulda::Callback::Matchers::ActiveModel::UsageError,
|
39
|
+
"The .on option is only valid for the validation lifecycle and cannot be used with create, use with .before(:validation) or .after(:validation)"
|
45
40
|
end
|
46
41
|
end
|
47
42
|
|
@@ -54,10 +49,17 @@ describe Shoulda::Callback::Matchers::ActiveModel do
|
|
54
49
|
define_method("after_#{lifecycle}"){}
|
55
50
|
define_method("around_#{lifecycle}"){}
|
56
51
|
end
|
57
|
-
|
52
|
+
|
58
53
|
callback_object = @callback_object_class.new
|
54
|
+
|
55
|
+
@other_callback_object_class = define_model(:other_callback) do
|
56
|
+
define_method("after_#{lifecycle}"){}
|
57
|
+
define_method("around_#{lifecycle}"){}
|
58
|
+
end
|
59
59
|
|
60
|
-
|
60
|
+
other_callback_object = @other_callback_object_class.new
|
61
|
+
|
62
|
+
@callback_object_not_found_class = define_model(:callback_not_found) do
|
61
63
|
define_method("before_#{lifecycle}"){}
|
62
64
|
define_method("after_#{lifecycle}"){}
|
63
65
|
define_method("around_#{lifecycle}"){}
|
@@ -68,9 +70,13 @@ describe Shoulda::Callback::Matchers::ActiveModel do
|
|
68
70
|
send(:"before_#{lifecycle}", :dance!, :if => :evaluates_to_false!)
|
69
71
|
send(:"after_#{lifecycle}", :shake!, :unless => :evaluates_to_true!)
|
70
72
|
send(:"around_#{lifecycle}", :giggle!)
|
73
|
+
send(:"before_#{lifecycle}", :wiggle!)
|
74
|
+
|
71
75
|
send(:"before_#{lifecycle}", callback_object, :if => :evaluates_to_false!)
|
72
76
|
send(:"after_#{lifecycle}", callback_object, :unless => :evaluates_to_true!)
|
73
77
|
send(:"around_#{lifecycle}", callback_object)
|
78
|
+
send(:"before_#{lifecycle}", other_callback_object)
|
79
|
+
|
74
80
|
define_method(:shake!){}
|
75
81
|
define_method(:dance!){}
|
76
82
|
define_method(:giggle!){}
|
@@ -115,6 +121,16 @@ describe Shoulda::Callback::Matchers::ActiveModel do
|
|
115
121
|
matcher = callback(@callback_object_class).before(lifecycle)
|
116
122
|
matcher.description.should == "callback Callback before #{lifecycle}"
|
117
123
|
end
|
124
|
+
it "should have a meaningful error if it fails with an inexistent method on a model" do
|
125
|
+
matcher = callback(:wiggle!).before(lifecycle)
|
126
|
+
matcher.matches?(@model).should be_false
|
127
|
+
matcher.failure_message.should == "callback wiggle! is listed as a callback before #{lifecycle}, but the model does not respond to wiggle! (using respond_to?(:wiggle!, true)"
|
128
|
+
end
|
129
|
+
it "should have a meaningful error if it fails with an inexistent method on a callback class" do
|
130
|
+
matcher = callback(@other_callback_object_class).before(lifecycle)
|
131
|
+
matcher.matches?(@model).should be_false
|
132
|
+
matcher.failure_message.should == "callback OtherCallback is listed as a callback before #{lifecycle}, but the given object does not respond to before_#{lifecycle} (using respond_to?(:before_#{lifecycle}, true)"
|
133
|
+
end
|
118
134
|
end
|
119
135
|
context "with conditions" do
|
120
136
|
it "should match the if condition" do
|
@@ -169,7 +185,7 @@ describe Shoulda::Callback::Matchers::ActiveModel do
|
|
169
185
|
callback_object = @callback_object_class.new
|
170
186
|
callback_object2 = @callback_object_class2.new
|
171
187
|
|
172
|
-
@callback_object_not_found_class = define_model(:
|
188
|
+
@callback_object_not_found_class = define_model(:callback_not_found) do
|
173
189
|
define_method("before_validation"){}
|
174
190
|
define_method("after_validation"){}
|
175
191
|
end
|
@@ -338,7 +354,7 @@ describe Shoulda::Callback::Matchers::ActiveModel do
|
|
338
354
|
end
|
339
355
|
end
|
340
356
|
|
341
|
-
[:initialize, :find, :touch].each do |lifecycle|
|
357
|
+
[:initialize, :find, :touch, :rollback, :commit].each do |lifecycle|
|
342
358
|
|
343
359
|
context "on #{lifecycle}" do
|
344
360
|
before do
|
@@ -353,7 +369,7 @@ describe Shoulda::Callback::Matchers::ActiveModel do
|
|
353
369
|
callback_object = @callback_object_class.new
|
354
370
|
callback_object2 = @callback_object_class2.new
|
355
371
|
|
356
|
-
@callback_object_not_found_class = define_model(:
|
372
|
+
@callback_object_not_found_class = define_model(:callback_not_found) do
|
357
373
|
define_method("after_#{lifecycle}"){}
|
358
374
|
end
|
359
375
|
|
data/spec/spec_helper.rb
CHANGED
@@ -1,26 +1,34 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
1
|
+
require 'logger'
|
2
|
+
|
3
|
+
LOGGER = Logger.new STDOUT
|
4
|
+
TESTAPP_ROOT = Pathname.new File.expand_path('../tmp/aruba/testapp', __FILE__)
|
5
|
+
FileUtils.rm_rf TESTAPP_ROOT if File.exists? TESTAPP_ROOT
|
5
6
|
|
6
7
|
ENV['RAILS_ENV'] = 'test'
|
7
|
-
ENV['BUNDLE_GEMFILE'] ||= TESTAPP_ROOT
|
8
|
+
ENV['BUNDLE_GEMFILE'] ||= TESTAPP_ROOT.join('Gemfile')
|
9
|
+
|
10
|
+
LOGGER.info "Generating Rails app in #{TESTAPP_ROOT}..."
|
11
|
+
`rails new #{TESTAPP_ROOT}`
|
12
|
+
LOGGER.info "Done"
|
8
13
|
|
9
|
-
require
|
10
|
-
require 'bourne'
|
14
|
+
require TESTAPP_ROOT.join('config', 'environment')
|
11
15
|
require 'shoulda-callback-matchers'
|
12
16
|
require 'rspec/rails'
|
13
17
|
|
14
|
-
PROJECT_ROOT = File.expand_path(
|
18
|
+
PROJECT_ROOT = Pathname.new File.expand_path('../..', __FILE__)
|
19
|
+
$LOAD_PATH << PROJECT_ROOT.join('lib')
|
15
20
|
|
16
|
-
|
17
|
-
|
18
|
-
|
21
|
+
Dir[PROJECT_ROOT.join('spec', 'support', '**', '*.rb')].each do |file|
|
22
|
+
require file
|
23
|
+
end
|
19
24
|
|
20
25
|
# Run the migrations
|
26
|
+
LOGGER.info "Running the migrations for the testapp..."
|
21
27
|
ActiveRecord::Migration.verbose = false
|
22
28
|
ActiveRecord::Migrator.migrate("#{Rails.root}/db/migrate")
|
29
|
+
LOGGER.info "Done"
|
23
30
|
|
24
31
|
RSpec.configure do |config|
|
25
|
-
config.
|
26
|
-
|
32
|
+
config.include ClassBuilder
|
33
|
+
config.include ModelBuilder
|
34
|
+
end
|
@@ -1,5 +1,5 @@
|
|
1
1
|
module ClassBuilder
|
2
|
-
def self.included
|
2
|
+
def self.included example_group
|
3
3
|
example_group.class_eval do
|
4
4
|
after do
|
5
5
|
teardown_defined_constants
|
@@ -7,18 +7,9 @@ module ClassBuilder
|
|
7
7
|
end
|
8
8
|
end
|
9
9
|
|
10
|
-
def define_class
|
11
|
-
class_name
|
12
|
-
|
13
|
-
# FIXME: ActionMailer 3.2 calls `name.underscore` immediately upon
|
14
|
-
# subclassing. Class.new.name == nil. So, Class.new(ActionMailer::Base)
|
15
|
-
# errors out since it's trying to do `nil.underscore`. This is very ugly but
|
16
|
-
# allows us to test against ActionMailer 3.2.x.
|
17
|
-
eval <<-A_REAL_CLASS_FOR_ACTION_MAILER_3_2
|
18
|
-
class ::#{class_name} < #{base}
|
19
|
-
end
|
20
|
-
A_REAL_CLASS_FOR_ACTION_MAILER_3_2
|
21
|
-
|
10
|
+
def define_class class_name, base = Object, &block
|
11
|
+
Object.const_set class_name, Class.new(base)
|
12
|
+
|
22
13
|
Object.const_get(class_name).tap do |constant_class|
|
23
14
|
constant_class.unloadable
|
24
15
|
|
@@ -35,8 +26,4 @@ module ClassBuilder
|
|
35
26
|
def teardown_defined_constants
|
36
27
|
ActiveSupport::Dependencies.clear
|
37
28
|
end
|
38
|
-
end
|
39
|
-
|
40
|
-
RSpec.configure do |config|
|
41
|
-
config.include ClassBuilder
|
42
|
-
end
|
29
|
+
end
|
@@ -12,17 +12,12 @@ module ModelBuilder
|
|
12
12
|
end
|
13
13
|
|
14
14
|
def create_table(table_name, options = {}, &block)
|
15
|
-
connection
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
connection
|
22
|
-
rescue Exception => e
|
23
|
-
connection.execute("DROP TABLE IF EXISTS #{table_name}")
|
24
|
-
raise e
|
25
|
-
end
|
15
|
+
connection.create_table(table_name, options, &block)
|
16
|
+
@created_tables << table_name
|
17
|
+
connection
|
18
|
+
rescue Exception => e
|
19
|
+
drop_table(table_name)
|
20
|
+
raise e
|
26
21
|
end
|
27
22
|
|
28
23
|
def define_model_class(class_name, &block)
|
@@ -60,14 +55,16 @@ module ModelBuilder
|
|
60
55
|
end
|
61
56
|
|
62
57
|
def drop_created_tables
|
63
|
-
connection = ActiveRecord::Base.connection
|
64
|
-
|
65
58
|
@created_tables.each do |table_name|
|
66
|
-
|
59
|
+
drop_table(table_name)
|
67
60
|
end
|
68
61
|
end
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
62
|
+
|
63
|
+
def drop_table table_name
|
64
|
+
connection.execute("DROP TABLE IF EXISTS #{table_name}")
|
65
|
+
end
|
66
|
+
|
67
|
+
def connection
|
68
|
+
@connection ||= ActiveRecord::Base.connection
|
69
|
+
end
|
73
70
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: shoulda-callback-matchers
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 1.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Beat Richartz
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-
|
11
|
+
date: 2014-04-17 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -52,20 +52,6 @@ dependencies:
|
|
52
52
|
- - '>='
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: '0'
|
55
|
-
- !ruby/object:Gem::Dependency
|
56
|
-
name: bourne
|
57
|
-
requirement: !ruby/object:Gem::Requirement
|
58
|
-
requirements:
|
59
|
-
- - ~>
|
60
|
-
- !ruby/object:Gem::Version
|
61
|
-
version: '1.3'
|
62
|
-
type: :development
|
63
|
-
prerelease: false
|
64
|
-
version_requirements: !ruby/object:Gem::Requirement
|
65
|
-
requirements:
|
66
|
-
- - ~>
|
67
|
-
- !ruby/object:Gem::Version
|
68
|
-
version: '1.3'
|
69
55
|
- !ruby/object:Gem::Dependency
|
70
56
|
name: bundler
|
71
57
|
requirement: !ruby/object:Gem::Requirement
|
@@ -129,10 +115,7 @@ extensions:
|
|
129
115
|
- ext/mkrf_conf.rb
|
130
116
|
extra_rdoc_files: []
|
131
117
|
files:
|
132
|
-
- .DS_Store
|
133
118
|
- .gitignore
|
134
|
-
- .ruby-gemset
|
135
|
-
- .ruby-version
|
136
119
|
- .travis.yml
|
137
120
|
- Appraisals
|
138
121
|
- CONTRIBUTING.md
|
@@ -147,12 +130,11 @@ files:
|
|
147
130
|
- lib/shoulda/callback/matchers/active_model.rb
|
148
131
|
- lib/shoulda/callback/matchers/integrations/rspec.rb
|
149
132
|
- lib/shoulda/callback/matchers/integrations/test_unit.rb
|
133
|
+
- lib/shoulda/callback/matchers/rails_version_helper.rb
|
150
134
|
- lib/shoulda/callback/matchers/version.rb
|
151
135
|
- shoulda-callback-matchers.gemspec
|
152
|
-
- spec/fixtures/users.yml
|
153
136
|
- spec/shoulda/active_model/callback_matcher_spec.rb
|
154
137
|
- spec/spec_helper.rb
|
155
|
-
- spec/support/active_model_versions.rb
|
156
138
|
- spec/support/class_builder.rb
|
157
139
|
- spec/support/model_builder.rb
|
158
140
|
homepage: http://github.com/beatrichartz/shoulda-callback-matchers
|
@@ -180,9 +162,7 @@ signing_key:
|
|
180
162
|
specification_version: 4
|
181
163
|
summary: Making callback tests easy on the fingers and eyes
|
182
164
|
test_files:
|
183
|
-
- spec/fixtures/users.yml
|
184
165
|
- spec/shoulda/active_model/callback_matcher_spec.rb
|
185
166
|
- spec/spec_helper.rb
|
186
|
-
- spec/support/active_model_versions.rb
|
187
167
|
- spec/support/class_builder.rb
|
188
168
|
- spec/support/model_builder.rb
|
data/.DS_Store
DELETED
Binary file
|
data/.ruby-gemset
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
should-callback-matchers
|
data/.ruby-version
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
1.9.3
|
data/spec/fixtures/users.yml
DELETED