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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 72c47c82596d5cef0a75c5a359e9f3a2b138f875
4
- data.tar.gz: 484f42b9d2cad246fb71748ebfff3ad73977e43e
3
+ metadata.gz: 36ecd3914a3443c58fd61371532b3e04003f5dea
4
+ data.tar.gz: 63aa4153512b0f40d245c977a1ecf67ef74af9b0
5
5
  SHA512:
6
- metadata.gz: e33037b19ace299416fc07695e994aae498672f70864113ad9e8fdb84f22855f285568690aa1831c9ec6d3de14ef037ec9ad43f78eace98de8fe507f1cf99b59
7
- data.tar.gz: a6dd677fbdd5778b99b64d01ecb29b8699f6e676c17f38f9a653ae709ab4c3c9465149081b2a37a28370f83d60f10c4ec1c861d4fe8c7817709d77d1548c9813
6
+ metadata.gz: 8d540b4fbf5a1e2fa7f8b94c55df9f02ffec8c31bc49875daac55be07b112b448b4296631277328bdf044352d4d43e4c3132814d06c429ccce33378604d1cb8f
7
+ data.tar.gz: 2e6f4830c5af8fcedd2097736d799543eac77c35f72c5895920b22c5364e68be4f9021fd193e7e7fbcbd47e034d1a2e952a3a827afc1c2cc2f0eff29b4ef754b
data/.gitignore CHANGED
@@ -1,3 +1,7 @@
1
+ .DS_STORE
2
+ .rspec
3
+ .ruby-gemset
4
+ .ruby-version
1
5
  test/*/log/*.log
2
6
  doc
3
7
  coverage
@@ -8,6 +12,7 @@ pkg
8
12
  tags
9
13
  tmp
10
14
  .bundle
15
+ .git
11
16
  *.rbc
12
17
  *.gem
13
18
  gemfiles/*
@@ -1,7 +1,7 @@
1
1
  rvm:
2
2
  - 1.9.3
3
3
  - 2.0.0
4
- - 2.1.0
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.0.gemfile
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
@@ -1,3 +1,9 @@
1
+ appraise '4.1' do
2
+ gem 'rails', '~>4.1'
3
+ gem 'jquery-rails'
4
+ gem 'sass-rails'
5
+ end
6
+
1
7
  appraise '4.0' do
2
8
  gem 'rails', '~>4.0'
3
9
  gem 'jquery-rails'
@@ -1,4 +1,4 @@
1
- Copyright (c) 2012 Beat Richartz
1
+ Copyright (c) 2014 Beat Richartz
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person
4
4
  obtaining a copy of this software and associated documentation
data/README.md CHANGED
@@ -1,6 +1,12 @@
1
- Matchers to test before, after and around hooks(currently supports gsymbol and object callbacks):
2
-
3
- Symbol Callbacks:
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
- def after_create{}
23
- def before_validation{}
24
- def after_find{}
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
- Be aware that this tests for the method call and not the method itself. It makes testing via triggering the callback events (validation, save) unnecessary, but you should still test the called procedure seperately.
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.4"
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-2012 thoughtbot, inc.
71
- Callback Matchers is Copyright © 2012 Beat Richartz
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.
@@ -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(:domain => :local).find_gems_with_sources(dep).empty? ||
5
- !Gem::DependencyInstaller.new(:domain => :local,:prerelease => true).find_gems_with_sources(dep).empty?
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(:prerelease => true)
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
- require 'shoulda/callback/matchers'
1
+ require_relative 'shoulda/callback/matchers'
@@ -1,7 +1,8 @@
1
- require 'shoulda/callback/matchers/version'
1
+ require_relative 'matchers/version'
2
+ require_relative 'matchers/rails_version_helper'
2
3
 
3
4
  if defined?(RSpec)
4
- require 'shoulda/callback/matchers/integrations/rspec'
5
+ require_relative 'matchers/integrations/rspec'
5
6
  end
6
7
 
7
- require 'shoulda/callback/matchers/integrations/test_unit'
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(method)
21
- CallbackMatcher.new(method)
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(method)
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(optional_lifecycle)
52
+ def on optional_lifecycle
49
53
  unless @lifecycle == :validation
50
- @failure_message = "The .on option is only valid for the validation lifecycle and cannot be used with #{@lifecycle}, use with .before(:validation) or .after(:validation)"
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?(subject)
59
- unless @lifecycle
60
- @failure_message = "callback #{@method} can not be tested against an undefined lifecycle, use .before, .after or .around"
61
- false
62
- else
63
- callbacks = subject.send(:"_#{@lifecycle}_callbacks").dup
64
- callbacks = callbacks.select do |callback|
65
- subject.respond_to?(callback.filter) &&
66
- is_callback?(subject, callback) &&
67
- callback.kind == @hook &&
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 is_callback_symbol?(subject, callback)
80
- callback.filter == @method
81
- end
82
-
83
- def is_callback_object?(subject, callback)
84
- @method.kind_of?(Class) &&
85
- callback.filter.match(/^_callback/) &&
86
- subject.respond_to?("#{callback.filter}_object") &&
87
- subject.send("#{callback.filter}_object").class == @method
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
- def matches_conditions?(callback)
105
- !@condition || callback.options[@condition_type].include?(@condition)
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
- def matches_optional_lifecycle?(callback)
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
- def condition_phrase
113
- " #{@condition_type} #{@condition} evaluates to #{@condition_type == :if ? 'true' : 'false'}" if @condition
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
- def optional_lifecycle_phrase
117
- " on #{@optional_lifecycle}" if @optional_lifecycle
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
- def lifecycle_context_string
121
- if ActiveRecord::VERSION::MAJOR == 4
122
- "[:#{@optional_lifecycle}].include? self.validation_context"
123
- else
124
- "self.validation_context == :#{@optional_lifecycle}"
125
- end
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
@@ -1,7 +1,7 @@
1
1
  module Shoulda
2
2
  module Callback
3
3
  module Matchers
4
- VERSION = '0.4.0'.freeze
4
+ VERSION = '1.0.0'.freeze
5
5
  end
6
6
  end
7
7
  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(:callback) do
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 failure message when used without a defined lifecycle" do
23
- matcher = callback(:dance!)
24
- matcher.matches?(@model).should be_false
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 failure message when used with an optional lifecycle without the original lifecycle being validation" do
29
- matcher = callback(:dance!).after(:create).on(:save)
30
- matcher.matches?(@model).should be_false
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 failure message when used without a defined lifecycle" do
35
- matcher = callback(@callback_object_class)
36
- matcher.matches?(@model).should be_false
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 failure message when used with an optional lifecycle without the original lifecycle being validation" do
41
- matcher = callback(@callback_object_class).after(:create).on(:save)
42
- matcher.matches?(@model).should be_false
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
- @callback_object_not_found_class = define_model(:callback_not_fount) do
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(:callback_not_fount) do
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(:callback_not_fount) do
372
+ @callback_object_not_found_class = define_model(:callback_not_found) do
357
373
  define_method("after_#{lifecycle}"){}
358
374
  end
359
375
 
@@ -1,26 +1,34 @@
1
- # Create Rails environment based on the version given from Appraisal
2
- TESTAPP_ROOT = File.join(File.dirname(__FILE__), '..', 'tmp', 'aruba', 'testapp')
3
- FileUtils.rm_rf(TESTAPP_ROOT) if File.exists?(TESTAPP_ROOT)
4
- `rails new #{TESTAPP_ROOT}`
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 + '/Gemfile'
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 "#{TESTAPP_ROOT}/config/environment"
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(File.join(File.dirname(__FILE__), '..')).freeze
18
+ PROJECT_ROOT = Pathname.new File.expand_path('../..', __FILE__)
19
+ $LOAD_PATH << PROJECT_ROOT.join('lib')
15
20
 
16
- $LOAD_PATH << File.join(PROJECT_ROOT, 'lib')
17
-
18
- Dir[File.join(PROJECT_ROOT, 'spec', 'support', '**', '*.rb')].each { |file| require(file) }
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.mock_with :mocha
26
- end
32
+ config.include ClassBuilder
33
+ config.include ModelBuilder
34
+ end
@@ -1,5 +1,5 @@
1
1
  module ClassBuilder
2
- def self.included(example_group)
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(class_name, base = Object, &block)
11
- class_name = class_name.to_s.camelize
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 = ActiveRecord::Base.connection
16
-
17
- begin
18
- connection.execute("DROP TABLE IF EXISTS #{table_name}")
19
- connection.create_table(table_name, options, &block)
20
- @created_tables << table_name
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
- connection.execute("DROP TABLE IF EXISTS #{table_name}")
59
+ drop_table(table_name)
67
60
  end
68
61
  end
69
- end
70
-
71
- RSpec.configure do |config|
72
- config.include ModelBuilder
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.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-03-22 00:00:00.000000000 Z
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
@@ -1 +0,0 @@
1
- should-callback-matchers
@@ -1 +0,0 @@
1
- 1.9.3
@@ -1,6 +0,0 @@
1
- first:
2
- id: 1
3
- name: Some dude
4
- age: 2
5
- email: none@none.com
6
- ssn: 123456789
@@ -1,9 +0,0 @@
1
- RSpec.configure do |c|
2
- def active_model_3_1?
3
- ::ActiveModel::VERSION::MAJOR == 3 && ::ActiveModel::VERSION::MINOR >= 1
4
- end
5
-
6
- def active_model_3_2?
7
- ::ActiveModel::VERSION::MAJOR == 3 && ::ActiveModel::VERSION::MINOR >= 2
8
- end
9
- end