Use current thoughtbot style in specs
This commit is contained in:
parent
cc03053e50
commit
af8f9a7bff
|
@ -25,8 +25,8 @@ When 'I generate a new rails application' do
|
|||
And I set the "BUNDLE_GEMFILE" environment variable to "Gemfile"
|
||||
And I successfully run `bundle install --local`
|
||||
}
|
||||
if RUBY_VERSION >= "1.9.3"
|
||||
append_to_gemfile %(gem "rake", "~> 0.9.3.beta.1")
|
||||
if RUBY_VERSION >= '1.9.3'
|
||||
append_to_gemfile %(gem 'rake', '~> 0.9.3.beta.1')
|
||||
step %(I successfully run `bundle update rake`)
|
||||
end
|
||||
end
|
||||
|
@ -52,7 +52,7 @@ When 'I run the rspec generator' do
|
|||
end
|
||||
|
||||
When 'I configure the application to use rspec-rails' do
|
||||
append_to_gemfile "gem 'rspec-rails', '~> 2.8.1'"
|
||||
append_to_gemfile %q(gem 'rspec-rails', '~> 2.8.1')
|
||||
steps %{And I run `bundle install --local`}
|
||||
end
|
||||
|
||||
|
@ -66,7 +66,7 @@ When 'I configure the application to use rspec-rails in test and development' do
|
|||
end
|
||||
|
||||
When 'I configure the application to use shoulda-context' do
|
||||
append_to_gemfile "gem 'shoulda-context', '~> 1.0.0'"
|
||||
append_to_gemfile %q(gem 'shoulda-context', '~> 1.0.0')
|
||||
steps %{And I run `bundle install --local`}
|
||||
end
|
||||
|
||||
|
@ -106,7 +106,7 @@ end
|
|||
module FileHelpers
|
||||
def append_to(path, contents)
|
||||
in_current_dir do
|
||||
File.open(path, "a") do |file|
|
||||
File.open(path, 'a') do |file|
|
||||
file.puts
|
||||
file.puts contents
|
||||
end
|
||||
|
@ -119,9 +119,9 @@ module FileHelpers
|
|||
|
||||
def comment_out_gem_in_gemfile(gemname)
|
||||
in_current_dir do
|
||||
gemfile = File.read("Gemfile")
|
||||
gemfile = File.read('Gemfile')
|
||||
gemfile.sub!(/^(\s*)(gem\s*['"]#{gemname})/, "\\1# \\2")
|
||||
File.open("Gemfile", 'w'){ |file| file.write(gemfile) }
|
||||
File.open('Gemfile', 'w'){ |file| file.write(gemfile) }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
require 'aruba/cucumber'
|
||||
|
||||
Before do
|
||||
@aruba_timeout_seconds = 120
|
||||
@aruba_timeout_seconds = 60 * 2
|
||||
end
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
PATH
|
||||
remote: /Users/draper/Dropbox/Development/shoulda-matchers
|
||||
remote: /Users/gabe/thoughtbot/open-source/shoulda-matchers
|
||||
specs:
|
||||
shoulda-matchers (1.4.2)
|
||||
activesupport (>= 3.0.0)
|
||||
|
@ -90,7 +90,7 @@ GEM
|
|||
rake (>= 0.8.7)
|
||||
rdoc (~> 3.4)
|
||||
thor (~> 0.14.4)
|
||||
rake (10.0.2)
|
||||
rake (10.0.3)
|
||||
rdoc (3.12)
|
||||
json (~> 1.4)
|
||||
rspec (2.8.0)
|
||||
|
@ -106,7 +106,7 @@ GEM
|
|||
activesupport (>= 3.0)
|
||||
railties (>= 3.0)
|
||||
rspec (~> 2.8.0)
|
||||
shoulda-context (1.0.1)
|
||||
shoulda-context (1.0.2)
|
||||
sqlite3 (1.3.6)
|
||||
thor (0.14.6)
|
||||
treetop (1.4.12)
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
PATH
|
||||
remote: /Users/draper/Dropbox/Development/shoulda-matchers
|
||||
remote: /Users/gabe/thoughtbot/open-source/shoulda-matchers
|
||||
specs:
|
||||
shoulda-matchers (1.4.2)
|
||||
activesupport (>= 3.0.0)
|
||||
|
@ -99,7 +99,7 @@ GEM
|
|||
rake (>= 0.8.7)
|
||||
rdoc (~> 3.4)
|
||||
thor (~> 0.14.6)
|
||||
rake (10.0.2)
|
||||
rake (10.0.3)
|
||||
rdoc (3.12)
|
||||
json (~> 1.4)
|
||||
rspec (2.8.0)
|
||||
|
@ -121,7 +121,7 @@ GEM
|
|||
railties (~> 3.1.0)
|
||||
sass (>= 3.1.10)
|
||||
tilt (~> 1.3.2)
|
||||
shoulda-context (1.0.1)
|
||||
shoulda-context (1.0.2)
|
||||
sprockets (2.0.4)
|
||||
hike (~> 1.2)
|
||||
rack (~> 1.0)
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
PATH
|
||||
remote: /Users/draper/Dropbox/Development/shoulda-matchers
|
||||
remote: /Users/gabe/thoughtbot/open-source/shoulda-matchers
|
||||
specs:
|
||||
shoulda-matchers (1.4.2)
|
||||
activesupport (>= 3.0.0)
|
||||
|
@ -73,7 +73,7 @@ GEM
|
|||
mime-types (1.19)
|
||||
mocha (0.12.7)
|
||||
metaclass (~> 0.0.1)
|
||||
multi_json (1.4.0)
|
||||
multi_json (1.5.0)
|
||||
polyglot (0.3.3)
|
||||
rack (1.4.1)
|
||||
rack-cache (1.2)
|
||||
|
@ -97,7 +97,7 @@ GEM
|
|||
rake (>= 0.8.7)
|
||||
rdoc (~> 3.4)
|
||||
thor (>= 0.14.6, < 2.0)
|
||||
rake (10.0.2)
|
||||
rake (10.0.3)
|
||||
rdoc (3.12)
|
||||
json (~> 1.4)
|
||||
rspec (2.8.0)
|
||||
|
@ -118,7 +118,7 @@ GEM
|
|||
railties (~> 3.2.0)
|
||||
sass (>= 3.1.10)
|
||||
tilt (~> 1.3)
|
||||
shoulda-context (1.0.1)
|
||||
shoulda-context (1.0.2)
|
||||
sprockets (2.2.2)
|
||||
hike (~> 1.2)
|
||||
multi_json (~> 1.0)
|
||||
|
|
|
@ -16,7 +16,7 @@ module Shoulda
|
|||
#
|
||||
# This code segment:
|
||||
#
|
||||
# describe UsersController, "on GET to show with a valid id" do
|
||||
# describe UsersController, 'on GET to show with a valid id' do
|
||||
# before(:each) do
|
||||
# get :show, :id => User.first.to_param
|
||||
# end
|
||||
|
@ -26,7 +26,7 @@ module Shoulda
|
|||
# it { should render_template(:show) }
|
||||
# it { should not_set_the_flash) }
|
||||
#
|
||||
# it "should do something else really cool" do
|
||||
# it 'does something else really cool' do
|
||||
# assigns[:user].id.should == 1
|
||||
# end
|
||||
# end
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
module Shoulda # :nodoc:
|
||||
module Matchers
|
||||
module ActionController # :nodoc:
|
||||
|
||||
# Ensures that the controller assigned to the named instance variable.
|
||||
#
|
||||
# Options:
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
module Shoulda # :nodoc:
|
||||
module Matchers
|
||||
module ActionController # :nodoc:
|
||||
|
||||
# Ensures a controller redirected to the given url.
|
||||
#
|
||||
# Example:
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
module Shoulda # :nodoc:
|
||||
module Matchers
|
||||
module ActionController # :nodoc:
|
||||
|
||||
# Ensures a controller rendered the given template.
|
||||
#
|
||||
# Example:
|
||||
|
|
|
@ -42,9 +42,9 @@ module Shoulda # :nodoc:
|
|||
end
|
||||
|
||||
def description
|
||||
description = "render with "
|
||||
description = 'render with '
|
||||
if @expected_layout.nil?
|
||||
description << "a layout"
|
||||
description << 'a layout'
|
||||
else
|
||||
description << "the #{@expected_layout.inspect} layout"
|
||||
end
|
||||
|
@ -83,9 +83,9 @@ module Shoulda # :nodoc:
|
|||
|
||||
def result
|
||||
if rendered_with_layout?
|
||||
"rendered with " + rendered_layouts.map(&:inspect).join(", ")
|
||||
'rendered with ' + rendered_layouts.map(&:inspect).join(', ')
|
||||
else
|
||||
"rendered without a layout"
|
||||
'rendered without a layout'
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -11,16 +11,16 @@ module Shoulda # :nodoc:
|
|||
#
|
||||
# Examples:
|
||||
#
|
||||
# it { should route(:get, "/posts").
|
||||
# it { should route(:get, '/posts').
|
||||
# to(:controller => :posts, :action => :index) }
|
||||
# it { should route(:get, "/posts/new").to(:action => :new) }
|
||||
# it { should route(:post, "/posts").to(:action => :create) }
|
||||
# it { should route(:get, "/posts/1").to(:action => :show, :id => 1) }
|
||||
# it { should route(:get, "/posts/1/edit").to(:action => :edit, :id => 1) }
|
||||
# it { should route(:put, "/posts/1").to(:action => :update, :id => 1) }
|
||||
# it { should route(:delete, "/posts/1").
|
||||
# it { should route(:get, '/posts/new').to(:action => :new) }
|
||||
# it { should route(:post, '/posts').to(:action => :create) }
|
||||
# it { should route(:get, '/posts/1').to(:action => :show, :id => 1) }
|
||||
# it { should route(:get, '/posts/1/edit').to(:action => :edit, :id => 1) }
|
||||
# it { should route(:put, '/posts/1').to(:action => :update, :id => 1) }
|
||||
# it { should route(:delete, '/posts/1').
|
||||
# to(:action => :destroy, :id => 1) }
|
||||
# it { should route(:get, "/users/1/posts/1").
|
||||
# it { should route(:get, '/users/1/posts/1').
|
||||
# to(:action => :show, :id => 1, :user_id => 1) }
|
||||
def route(method, path)
|
||||
RouteMatcher.new(method, path, self)
|
||||
|
|
|
@ -82,12 +82,11 @@ module Shoulda # :nodoc:
|
|||
if @value
|
||||
expectation << " to #{@value.inspect}"
|
||||
end
|
||||
expectation
|
||||
end
|
||||
|
||||
def result
|
||||
if session.empty?
|
||||
"no session variables were set"
|
||||
'no session variables were set'
|
||||
else
|
||||
"the session was #{session.inspect}"
|
||||
end
|
||||
|
|
|
@ -8,9 +8,9 @@ module Shoulda # :nodoc:
|
|||
# Example:
|
||||
#
|
||||
# it { should set_the_flash }
|
||||
# it { should set_the_flash.to("Thank you for placing this order.") }
|
||||
# it { should set_the_flash.to('Thank you for placing this order.') }
|
||||
# it { should set_the_flash.to(/created/i) }
|
||||
# it { should set_the_flash[:alert].to("Password doesn't match") }
|
||||
# it { should set_the_flash[:alert].to('Password does not match') }
|
||||
# it { should set_the_flash.to(/logged in/i).now }
|
||||
# it { should_not set_the_flash }
|
||||
def set_the_flash
|
||||
|
@ -96,7 +96,8 @@ module Shoulda # :nodoc:
|
|||
@flash
|
||||
else
|
||||
@flash = @controller.flash.dup
|
||||
@flash.instance_variable_set(:@used, @controller.flash.instance_variable_get(:@used).dup)
|
||||
used = @controller.flash.instance_variable_get(:@used).dup
|
||||
@flash.instance_variable_set(:@used, used)
|
||||
sweep_flash_if_necessary
|
||||
@flash
|
||||
end
|
||||
|
@ -117,7 +118,7 @@ module Shoulda # :nodoc:
|
|||
|
||||
def flash_description
|
||||
if flash.blank?
|
||||
"no flash was set"
|
||||
'no flash was set'
|
||||
else
|
||||
"was #{flash.inspect}"
|
||||
end
|
||||
|
@ -129,9 +130,9 @@ module Shoulda # :nodoc:
|
|||
|
||||
def pretty_now
|
||||
if @options[:now]
|
||||
".now"
|
||||
'.now'
|
||||
else
|
||||
""
|
||||
''
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -139,7 +140,7 @@ module Shoulda # :nodoc:
|
|||
if @options[:key]
|
||||
"[:#{@options[:key]}]"
|
||||
else
|
||||
""
|
||||
''
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -115,7 +115,7 @@ module Shoulda # :nodoc:
|
|||
end
|
||||
|
||||
def description
|
||||
description = "send an email"
|
||||
description = 'send an email'
|
||||
description << " with a subject of #{@email_subject.inspect}" if @email_subject
|
||||
description << " containing #{@body.inspect}" if @body
|
||||
if @parts
|
||||
|
@ -136,7 +136,7 @@ module Shoulda # :nodoc:
|
|||
private
|
||||
|
||||
def expectation
|
||||
expectation = "sent email"
|
||||
expectation = 'sent email'
|
||||
expectation << " with subject #{@email_subject.inspect}" if @subject_failed
|
||||
expectation << " with body #{@body.inspect}" if @body_failed
|
||||
@parts.each do |_, body, content_type|
|
||||
|
|
|
@ -30,7 +30,7 @@ module Shoulda
|
|||
# %w(abcd 1234).each do |value|
|
||||
# it { should_not allow_value(value).for(:phone_number) }
|
||||
# end
|
||||
# it { should allow_value("(123) 456-7890").for(:phone_number) }
|
||||
# it { should allow_value('(123) 456-7890').for(:phone_number) }
|
||||
# it { should_not allow_mass_assignment_of(:password) }
|
||||
# it { should allow_value('Activated', 'Pending').for(:status).strict }
|
||||
# it { should_not allow_value('Amazing').for(:status).strict }
|
||||
|
|
|
@ -25,7 +25,7 @@ module Shoulda # :nodoc:
|
|||
|
||||
def as(role)
|
||||
if active_model_less_than_3_1?
|
||||
raise "You can specify role only in Rails 3.1 or greater"
|
||||
raise 'You can specify role only in Rails 3.1 or greater'
|
||||
end
|
||||
@options[:role] = role
|
||||
self
|
||||
|
@ -38,7 +38,7 @@ module Shoulda # :nodoc:
|
|||
@negative_failure_message = "#{@attribute} was made accessible"
|
||||
else
|
||||
if protected_attributes.empty?
|
||||
@negative_failure_message = "no attributes were protected"
|
||||
@negative_failure_message = 'no attributes were protected'
|
||||
else
|
||||
@negative_failure_message = "#{class_name} is protecting " <<
|
||||
"#{protected_attributes.to_a.to_sentence}, " <<
|
||||
|
@ -57,7 +57,7 @@ module Shoulda # :nodoc:
|
|||
end
|
||||
|
||||
def description
|
||||
[base_description, role_description].compact.join(" ")
|
||||
[base_description, role_description].compact.join(' ')
|
||||
end
|
||||
|
||||
private
|
||||
|
|
|
@ -17,11 +17,11 @@ module Shoulda # :nodoc:
|
|||
#
|
||||
# Example:
|
||||
# it { should_not allow_value('bad').for(:isbn) }
|
||||
# it { should allow_value("isbn 1 2345 6789 0").for(:isbn) }
|
||||
# it { should allow_value('isbn 1 2345 6789 0').for(:isbn) }
|
||||
#
|
||||
def allow_value(*values)
|
||||
if values.empty?
|
||||
raise ArgumentError, "need at least one argument"
|
||||
raise ArgumentError, 'need at least one argument'
|
||||
else
|
||||
AllowValueMatcher.new(*values)
|
||||
end
|
||||
|
|
|
@ -25,7 +25,7 @@ module Shoulda # :nodoc:
|
|||
end
|
||||
|
||||
def allowed_types
|
||||
""
|
||||
''
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -22,7 +22,7 @@ module Shoulda # :nodoc:
|
|||
end
|
||||
|
||||
class EnsureInclusionOfMatcher < ValidationMatcher # :nodoc:
|
||||
ARBITRARY_OUTSIDE_STRING = "shouldamatchersteststring"
|
||||
ARBITRARY_OUTSIDE_STRING = 'shouldamatchersteststring'
|
||||
|
||||
def initialize(attribute)
|
||||
super(attribute)
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
module Shoulda
|
||||
module Matchers
|
||||
module ActiveModel
|
||||
|
||||
# Finds message information from exceptions thrown by #valid?
|
||||
class ExceptionMessageFinder
|
||||
def initialize(instance, attribute)
|
||||
|
|
|
@ -21,7 +21,7 @@ module Shoulda # :nodoc:
|
|||
end
|
||||
|
||||
def allowed_types
|
||||
"integer"
|
||||
'integer'
|
||||
end
|
||||
|
||||
def failure_message
|
||||
|
|
|
@ -39,23 +39,25 @@ module Shoulda # :nodoc:
|
|||
private
|
||||
|
||||
def disallows_different_value
|
||||
set_confirmation("some value")
|
||||
matches = disallows_value_of("different value", @message)
|
||||
set_confirmation('some value')
|
||||
disallows_value_of('different value', @message)
|
||||
end
|
||||
|
||||
def allows_same_value
|
||||
set_confirmation("same value")
|
||||
allows_value_of("same value", @message)
|
||||
set_confirmation('same value')
|
||||
allows_value_of('same value', @message)
|
||||
end
|
||||
|
||||
def allows_missing_confirmation
|
||||
set_confirmation(nil)
|
||||
allows_value_of("any value", @message)
|
||||
allows_value_of('any value', @message)
|
||||
end
|
||||
|
||||
def set_confirmation(val)
|
||||
setter = :"#{@confirmation}="
|
||||
@subject.send(setter, val) if @subject.respond_to?(setter)
|
||||
if @subject.respond_to?(setter)
|
||||
@subject.send(setter, val)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
module Shoulda # :nodoc:
|
||||
module Matchers
|
||||
module ActiveModel # :nodoc:
|
||||
|
||||
# Ensures that the model is not valid if the given attribute is not
|
||||
# formatted correctly.
|
||||
#
|
||||
|
@ -27,7 +26,6 @@ module Shoulda # :nodoc:
|
|||
end
|
||||
|
||||
class ValidateFormatOfMatcher < ValidationMatcher # :nodoc:
|
||||
|
||||
def initialize(attribute)
|
||||
super
|
||||
@options = {}
|
||||
|
@ -44,20 +42,28 @@ module Shoulda # :nodoc:
|
|||
end
|
||||
|
||||
def with_message(message)
|
||||
@expected_message = message if message
|
||||
if message
|
||||
@expected_message = message
|
||||
end
|
||||
self
|
||||
end
|
||||
|
||||
def with(value)
|
||||
raise "You may not call both with and not_with" if @value_to_fail
|
||||
@value_to_pass = value
|
||||
self
|
||||
if @value_to_fail
|
||||
raise 'You may not call both with and not_with'
|
||||
else
|
||||
@value_to_pass = value
|
||||
self
|
||||
end
|
||||
end
|
||||
|
||||
def not_with(value)
|
||||
raise "You may not call both with and not_with" if @value_to_pass
|
||||
@value_to_fail = value
|
||||
self
|
||||
if @value_to_pass
|
||||
raise 'You may not call both with and not_with'
|
||||
else
|
||||
@value_to_fail = value
|
||||
self
|
||||
end
|
||||
end
|
||||
|
||||
def matches?(subject)
|
||||
|
|
|
@ -79,8 +79,8 @@ module Shoulda # :nodoc:
|
|||
end
|
||||
|
||||
def allowed_types
|
||||
allowed = ["numeric"] + submatcher_allowed_types
|
||||
allowed.join(", ")
|
||||
allowed = ['numeric'] + submatcher_allowed_types
|
||||
allowed.join(', ')
|
||||
end
|
||||
|
||||
def submatcher_allowed_types
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
module Shoulda # :nodoc:
|
||||
module Matchers
|
||||
module ActiveModel # :nodoc:
|
||||
|
||||
# Ensures that the model is invalid if the given attribute is not unique.
|
||||
#
|
||||
# Internally, this uses values from existing records to test validations,
|
||||
|
@ -57,14 +56,6 @@ module Shoulda # :nodoc:
|
|||
self
|
||||
end
|
||||
|
||||
def description
|
||||
result = "require "
|
||||
result << "case sensitive " unless @options[:case_insensitive]
|
||||
result << "unique value for #{@attribute}"
|
||||
result << " scoped to #{@options[:scopes].join(', ')}" if @options[:scopes].present?
|
||||
result
|
||||
end
|
||||
|
||||
def matches?(subject)
|
||||
@subject = subject.class.new
|
||||
@expected_message ||= :taken
|
||||
|
@ -73,6 +64,14 @@ module Shoulda # :nodoc:
|
|||
validate_after_scope_change?
|
||||
end
|
||||
|
||||
def description
|
||||
result = 'require '
|
||||
result << 'case sensitive ' unless @options[:case_insensitive]
|
||||
result << "unique value for #{@attribute}"
|
||||
result << " scoped to #{@options[:scopes].join(', ')}" if @options[:scopes].present?
|
||||
result
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def existing
|
||||
|
@ -85,7 +84,7 @@ module Shoulda # :nodoc:
|
|||
|
||||
def create_instance_in_database
|
||||
@subject.class.new.tap do |instance|
|
||||
instance.send("#{@attribute}=", "arbitrary_string")
|
||||
instance.send("#{@attribute}=", 'arbitrary_string')
|
||||
instance.save(:validate => false)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -29,7 +29,7 @@ module Shoulda
|
|||
|
||||
def messages_description
|
||||
if errors.empty?
|
||||
"no errors"
|
||||
'no errors'
|
||||
else
|
||||
"errors: #{pretty_error_messages(validated_instance)}"
|
||||
end
|
||||
|
|
|
@ -78,7 +78,7 @@ module Shoulda
|
|||
if config
|
||||
true
|
||||
else
|
||||
@problem = "is not declared"
|
||||
@problem = 'is not declared'
|
||||
false
|
||||
end
|
||||
end
|
||||
|
@ -129,9 +129,9 @@ module Shoulda
|
|||
|
||||
def should_or_should_not(value)
|
||||
if value
|
||||
"should"
|
||||
'should'
|
||||
else
|
||||
"should not"
|
||||
'should not'
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -260,7 +260,7 @@ module Shoulda # :nodoc:
|
|||
if !@validate && !reflection.options[:validate] || @validate == reflection.options[:validate]
|
||||
true
|
||||
else
|
||||
@missing = "#{@name} should have #{@validate} as validate"
|
||||
@missing = "#{@name} should have :validate => #{@validate}"
|
||||
false
|
||||
end
|
||||
end
|
||||
|
|
|
@ -149,11 +149,11 @@ module Shoulda # :nodoc:
|
|||
def correct_scale?
|
||||
return true unless @options.key?(:scale)
|
||||
|
||||
if matched_column.scale.to_s == @options[:scale].to_s
|
||||
if actual_scale.to_s == @options[:scale].to_s
|
||||
true
|
||||
else
|
||||
@missing = "#{model_class} has a db column named #{@column} " <<
|
||||
"of scale #{matched_column.scale}, not #{@options[:scale]}."
|
||||
@missing = "#{model_class} has a db column named #{@column} "
|
||||
@missing << "of scale #{actual_scale}, not #{@options[:scale]}."
|
||||
false
|
||||
end
|
||||
end
|
||||
|
@ -166,9 +166,9 @@ module Shoulda # :nodoc:
|
|||
else
|
||||
@missing = "#{model_class} has a db column named #{@column} "
|
||||
if @options[:primary]
|
||||
@missing << "that is not primary, but should be"
|
||||
@missing << 'that is not primary, but should be'
|
||||
else
|
||||
@missing << "that is primary, but should not be"
|
||||
@missing << 'that is primary, but should not be'
|
||||
end
|
||||
false
|
||||
end
|
||||
|
@ -182,6 +182,10 @@ module Shoulda # :nodoc:
|
|||
@subject.class
|
||||
end
|
||||
|
||||
def actual_scale
|
||||
matched_column.scale
|
||||
end
|
||||
|
||||
def expectation
|
||||
expected = "#{model_class.name} to #{description}"
|
||||
end
|
||||
|
|
|
@ -26,7 +26,7 @@ module Shoulda # :nodoc:
|
|||
else
|
||||
if readonly_attributes.empty?
|
||||
@failure_message = "#{class_name} attribute #{@attribute} " <<
|
||||
"is not read-only"
|
||||
'is not read-only'
|
||||
else
|
||||
@failure_message = "#{class_name} is making " <<
|
||||
"#{readonly_attributes.to_a.to_sentence} " <<
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
module Shoulda # :nodoc:
|
||||
module Matchers
|
||||
module ActiveRecord # :nodoc:
|
||||
|
||||
# Ensure that the field becomes serialized.
|
||||
#
|
||||
# Options:
|
||||
|
@ -10,6 +9,7 @@ module Shoulda # :nodoc:
|
|||
# Example:
|
||||
# it { should serialize(:details) }
|
||||
# it { should serialize(:details).as(Hash) }
|
||||
# it { should serialize(:details).as_instance_of(ExampleSerializer) }
|
||||
#
|
||||
def serialize(name)
|
||||
SerializeMatcher.new(name)
|
||||
|
|
|
@ -3,11 +3,11 @@ module Shoulda
|
|||
if Gem.ruby_version >= Gem::Version.new('1.8') && Gem.ruby_version < Gem::Version.new('1.9')
|
||||
require 'test/unit'
|
||||
AssertionError = Test::Unit::AssertionFailedError
|
||||
elsif Gem.ruby_version >= Gem::Version.new("1.9")
|
||||
elsif Gem.ruby_version >= Gem::Version.new('1.9')
|
||||
require 'minitest/unit'
|
||||
AssertionError = MiniTest::Assertion
|
||||
else
|
||||
raise "No unit test library available"
|
||||
raise 'No unit test library available'
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
require 'spec_helper'
|
||||
|
||||
describe Shoulda::Matchers::ActionController::AssignToMatcher do
|
||||
it "should include the actual class in the failure message" do
|
||||
it 'includes the actual class in the failure message' do
|
||||
define_class(:WrongClass) do
|
||||
def to_s
|
||||
'wrong class'
|
||||
|
@ -15,48 +15,51 @@ describe Shoulda::Matchers::ActionController::AssignToMatcher do
|
|||
matcher.failure_message.should =~ /but got wrong class \(WrongClass\)$/
|
||||
end
|
||||
|
||||
context "a controller that assigns to an instance variable" do
|
||||
let(:controller) { build_response { @var = 'value' } }
|
||||
|
||||
it "should accept assigning to that variable" do
|
||||
context 'a controller that assigns to an instance variable' do
|
||||
it 'accepts assigning to that variable' do
|
||||
controller.should assign_to(:var)
|
||||
end
|
||||
|
||||
it "should accept assigning to that variable with the correct class" do
|
||||
it 'accepts assigning to that variable with the correct class' do
|
||||
controller.should assign_to(:var).with_kind_of(String)
|
||||
end
|
||||
|
||||
it "should reject assigning to that variable with another class" do
|
||||
it 'rejects assigning to that variable with another class' do
|
||||
controller.should_not assign_to(:var).with_kind_of(Fixnum)
|
||||
end
|
||||
|
||||
it "should accept assigning the correct value to that variable" do
|
||||
it 'accepts assigning the correct value to that variable' do
|
||||
controller.should assign_to(:var).with('value')
|
||||
end
|
||||
|
||||
it "should reject assigning another value to that variable" do
|
||||
it 'rejects assigning another value to that variable' do
|
||||
controller.should_not assign_to(:var).with('other')
|
||||
end
|
||||
|
||||
it "should reject assigning to another variable" do
|
||||
it 'rejects assigning to another variable' do
|
||||
controller.should_not assign_to(:other)
|
||||
end
|
||||
|
||||
it "should accept assigning to the same value in the test context" do
|
||||
it 'accepts assigning to the same value in the test context' do
|
||||
expected = 'value'
|
||||
controller.should assign_to(:var).in_context(self).with { expected }
|
||||
end
|
||||
|
||||
it "should reject assigning to the another value in the test context" do
|
||||
it 'rejects assigning to the another value in the test context' do
|
||||
expected = 'other'
|
||||
controller.should_not assign_to(:var).in_context(self).with { expected }
|
||||
end
|
||||
|
||||
def controller
|
||||
build_response { @var = 'value' }
|
||||
end
|
||||
end
|
||||
|
||||
context "a controller that assigns a nil value to an instance variable" do
|
||||
let(:controller) { build_response { @var = nil } }
|
||||
|
||||
it "should accept assigning to that variable" do
|
||||
context 'a controller that assigns a nil value to an instance variable' do
|
||||
it 'accepts assigning to that variable' do
|
||||
controller = build_response do
|
||||
@var = nil
|
||||
end
|
||||
controller.should assign_to(:var)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,20 +1,22 @@
|
|||
require 'spec_helper'
|
||||
|
||||
describe Shoulda::Matchers::ActionController::FilterParamMatcher do
|
||||
context "given parameter filters" do
|
||||
before do
|
||||
Rails.application.config.filter_parameters = [:secret]
|
||||
end
|
||||
it 'accepts filtering a filtered parameter' do
|
||||
filter(:secret)
|
||||
|
||||
it "should accept filtering that parameter" do
|
||||
nil.should filter_param(:secret)
|
||||
end
|
||||
nil.should filter_param(:secret)
|
||||
end
|
||||
|
||||
it "should reject filtering another parameter" do
|
||||
matcher = filter_param(:other)
|
||||
matcher.matches?(nil).should be_false
|
||||
matcher.failure_message.should include("Expected other to be filtered")
|
||||
matcher.failure_message.should =~ /secret/
|
||||
end
|
||||
it 'rejects filtering an unfiltered parameter' do
|
||||
filter(:secret)
|
||||
matcher = filter_param(:other)
|
||||
|
||||
matcher.matches?(nil).should be_false
|
||||
|
||||
matcher.failure_message.should =~ /Expected other to be filtered.*secret/
|
||||
end
|
||||
|
||||
def filter(param)
|
||||
Rails.application.config.filter_parameters = [param]
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,40 +1,42 @@
|
|||
require 'spec_helper'
|
||||
|
||||
describe Shoulda::Matchers::ActionController::RedirectToMatcher do
|
||||
context "a controller that redirects" do
|
||||
let(:controller) do
|
||||
build_response { redirect_to '/some/url' }
|
||||
context 'a controller that redirects' do
|
||||
it 'accepts redirecting to that url' do
|
||||
controller_redirecting_to('/some/url').should redirect_to('/some/url')
|
||||
end
|
||||
|
||||
it "accepts redirecting to that url" do
|
||||
controller.should redirect_to('/some/url')
|
||||
it 'rejects redirecting to a different url' do
|
||||
controller_redirecting_to('/some/url').should_not
|
||||
redirect_to('/some/other/url')
|
||||
end
|
||||
|
||||
it "rejects redirecting to a different url" do
|
||||
controller.should_not redirect_to('/some/other/url')
|
||||
it 'accepts redirecting to that url in a block' do
|
||||
controller_redirecting_to('/some/url').should
|
||||
redirect_to('somewhere') { '/some/url' }
|
||||
end
|
||||
|
||||
it "accepts redirecting to that url in a block" do
|
||||
controller.should redirect_to('somewhere') { '/some/url' }
|
||||
it 'rejects redirecting to a different url in a block' do
|
||||
controller_redirecting_to('/some/url').should_not
|
||||
redirect_to('somewhere else') { '/some/other/url' }
|
||||
end
|
||||
|
||||
it "rejects redirecting to a different url in a block" do
|
||||
controller.should_not redirect_to('somewhere else') { '/some/other/url' }
|
||||
def controller_redirecting_to(url)
|
||||
build_response { redirect_to url }
|
||||
end
|
||||
end
|
||||
|
||||
context "a controller that doesn't redirect" do
|
||||
let(:controller) do
|
||||
build_response { render :text => 'hello' }
|
||||
end
|
||||
context 'a controller that does not redirect' do
|
||||
it 'rejects redirecting to a url' do
|
||||
controller = build_response { render :text => 'hello' }
|
||||
|
||||
it "rejects redirecting to a url" do
|
||||
controller.should_not redirect_to('/some/url')
|
||||
end
|
||||
end
|
||||
|
||||
it "provides the correct description when provided a block" do
|
||||
it 'provides the correct description when provided a block' do
|
||||
matcher = redirect_to('somewhere else') { '/some/other/url' }
|
||||
|
||||
matcher.description.should == 'redirect to somewhere else'
|
||||
end
|
||||
end
|
||||
|
|
|
@ -3,67 +3,76 @@ require 'spec_helper'
|
|||
describe Shoulda::Matchers::ActionController::RenderTemplateMatcher do
|
||||
include ActionController::TemplateAssertions
|
||||
|
||||
context "a controller that renders a template" do
|
||||
let(:controller) { build_response(:action => 'show') { render } }
|
||||
|
||||
it "accepts rendering that template" do
|
||||
controller.should render_template(:show)
|
||||
context 'a controller that renders a template' do
|
||||
it 'accepts rendering that template' do
|
||||
controller_with_show.should render_template(:show)
|
||||
end
|
||||
|
||||
it "rejects rendering a different template" do
|
||||
controller.should_not render_template(:index)
|
||||
it 'rejects rendering a different template' do
|
||||
controller_with_show.should_not render_template(:index)
|
||||
end
|
||||
|
||||
it "accepts rendering that template in the given context" do
|
||||
controller.should render_template(:show).in_context(self)
|
||||
it 'accepts rendering that template in the given context' do
|
||||
controller_with_show.should render_template(:show).in_context(self)
|
||||
end
|
||||
|
||||
it "rejects rendering a different template in the given context" do
|
||||
controller.should_not render_template(:index).in_context(self)
|
||||
it 'rejects rendering a different template in the given context' do
|
||||
controller_with_show.should_not render_template(:index).in_context(self)
|
||||
end
|
||||
|
||||
def controller_with_show
|
||||
build_response(:action => 'show') { render }
|
||||
end
|
||||
end
|
||||
|
||||
context "a controller that renders a partial" do
|
||||
let(:controller) { build_response(:partial => '_customer') { render :partial => 'customer' } }
|
||||
|
||||
it "accepts rendering that partial" do
|
||||
controller.should render_template(:partial => '_customer')
|
||||
context 'a controller that renders a partial' do
|
||||
it 'accepts rendering that partial' do
|
||||
controller_with_customer_partial.should
|
||||
render_template(:partial => '_customer')
|
||||
end
|
||||
|
||||
it "rejects rendering a different template" do
|
||||
controller.should_not render_template(:partial => '_client')
|
||||
it 'rejects rendering a different template' do
|
||||
controller_with_customer_partial.should_not
|
||||
render_template(:partial => '_client')
|
||||
end
|
||||
|
||||
it "accepts rendering that template in the given context" do
|
||||
controller.should render_template(:partial => '_customer').in_context(self)
|
||||
it 'accepts rendering that template in the given context' do
|
||||
controller_with_customer_partial.should
|
||||
render_template(:partial => '_customer').in_context(self)
|
||||
end
|
||||
|
||||
it "rejects rendering a different template in the given context" do
|
||||
controller.should_not render_template(:partial => '_client').in_context(self)
|
||||
it 'rejects rendering a different template in the given context' do
|
||||
controller_with_customer_partial.should_not
|
||||
render_template(:partial => '_client').in_context(self)
|
||||
end
|
||||
|
||||
def controller_with_customer_partial
|
||||
build_response(:partial => '_customer') { render :partial => 'customer' }
|
||||
end
|
||||
end
|
||||
|
||||
context "a controller that doesn't render partials" do
|
||||
let(:controller) { build_response(:action => 'show') { render } }
|
||||
context 'a controller that does not render partials' do
|
||||
it 'accepts not rendering a partial' do
|
||||
controller = build_response(:action => 'show') { render }
|
||||
|
||||
it "should not render a partial" do
|
||||
controller.should render_template(:partial => false)
|
||||
end
|
||||
end
|
||||
|
||||
context "a controller that renders a partial several times" do
|
||||
let(:controller) { build_response(:partial => '_customer') { render :partial => 'customer', :collection => [1,2] } }
|
||||
context 'a controller that renders a partial several times' do
|
||||
it 'accepts rendering that partial twice' do
|
||||
controller = build_response(:partial => '_customer') do
|
||||
render :partial => 'customer', :collection => [1,2]
|
||||
end
|
||||
|
||||
it "accepts rendering that partial twice" do
|
||||
controller.should render_template(:partial => '_customer', :count => 2)
|
||||
end
|
||||
end
|
||||
|
||||
context "a controller that doesn't render a template" do
|
||||
let(:controller) { build_response { render :nothing => true } }
|
||||
|
||||
it "rejects rendering a template" do
|
||||
controller.should_not render_template(:show)
|
||||
context 'a controller that does not render a template' do
|
||||
it 'rejects rendering a template' do
|
||||
build_response { render :nothing => true }.should_not
|
||||
render_template(:show)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -3,53 +3,56 @@ require 'spec_helper'
|
|||
describe Shoulda::Matchers::ActionController::RenderWithLayoutMatcher do
|
||||
include ActionController::TemplateAssertions
|
||||
|
||||
context "a controller that renders with a layout" do
|
||||
let(:controller) { build_response { render :layout => 'wide' } }
|
||||
context 'a controller that renders with a layout' do
|
||||
it 'accepts rendering with any layout' do
|
||||
controller_with_wide_layout.should render_with_layout
|
||||
end
|
||||
|
||||
before do
|
||||
it 'accepts rendering with that layout' do
|
||||
controller_with_wide_layout.should render_with_layout(:wide)
|
||||
end
|
||||
|
||||
it 'rejects rendering with another layout' do
|
||||
controller_with_wide_layout.should_not render_with_layout(:other)
|
||||
end
|
||||
|
||||
def controller_with_wide_layout
|
||||
create_view('layouts/wide.html.erb', 'some content, <%= yield %>')
|
||||
end
|
||||
|
||||
it "should accept rendering with any layout" do
|
||||
controller.should render_with_layout
|
||||
end
|
||||
|
||||
it "should accept rendering with that layout" do
|
||||
controller.should render_with_layout(:wide)
|
||||
end
|
||||
|
||||
it "should reject rendering with another layout" do
|
||||
controller.should_not render_with_layout(:other)
|
||||
build_response { render :layout => 'wide' }
|
||||
end
|
||||
end
|
||||
|
||||
context "a controller that renders without a layout" do
|
||||
let(:controller) { build_response { render :layout => false } }
|
||||
context 'a controller that renders without a layout' do
|
||||
|
||||
it "should reject rendering with a layout" do
|
||||
controller.should_not render_with_layout
|
||||
it 'rejects rendering with a layout' do
|
||||
controller_without_layout = build_response { render :layout => false }
|
||||
|
||||
controller_without_layout.should_not render_with_layout
|
||||
end
|
||||
end
|
||||
|
||||
context "a controller that renders a partial" do
|
||||
let(:controller) { build_response { render :partial => 'partial' } }
|
||||
context 'a controller that renders a partial' do
|
||||
it 'rejects rendering with a layout' do
|
||||
controller_with_partial = build_response { render :partial => 'partial' }
|
||||
|
||||
it "should reject rendering with a layout" do
|
||||
controller.should_not render_with_layout
|
||||
controller_with_partial.should_not render_with_layout
|
||||
end
|
||||
end
|
||||
|
||||
context "given a context with layouts" do
|
||||
let(:layout) { 'happy' }
|
||||
let(:controller) { build_response { render :layout => false } }
|
||||
context 'given a context with layouts' do
|
||||
it 'accepts that layout in that context' do
|
||||
set_in_context_layout('happy')
|
||||
|
||||
before do
|
||||
controller_without_layout.should render_with_layout('happy').in_context(self)
|
||||
end
|
||||
|
||||
def set_in_context_layout(layout)
|
||||
@layouts = Hash.new(0)
|
||||
@layouts[layout] = 1
|
||||
end
|
||||
|
||||
it "should accept that layout in that context" do
|
||||
controller.should render_with_layout(layout).in_context(self)
|
||||
def controller_without_layout
|
||||
build_response { render :layout => false }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,28 +1,31 @@
|
|||
require 'spec_helper'
|
||||
|
||||
describe Shoulda::Matchers::ActionController::RespondWithContentTypeMatcher do
|
||||
context "a controller responding with content type :xml" do
|
||||
let(:controller) { build_response { render :xml => { :user => "thoughtbot" }.to_xml } }
|
||||
it 'generates the correct description' do
|
||||
expected = 'respond with content type of application/xml'
|
||||
|
||||
it "should accept responding with content type :xml" do
|
||||
controller.should respond_with_content_type(:xml)
|
||||
end
|
||||
|
||||
it "should accept responding with content type 'application/xml'" do
|
||||
controller.should respond_with_content_type('application/xml')
|
||||
end
|
||||
|
||||
it "should accept responding with content type /xml/" do
|
||||
controller.should respond_with_content_type(/xml/)
|
||||
end
|
||||
|
||||
it "should reject responding with another content type" do
|
||||
controller.should_not respond_with_content_type(:json)
|
||||
end
|
||||
respond_with_content_type(:xml).description.should == expected
|
||||
end
|
||||
|
||||
it "should generate the correct test name" do
|
||||
respond_with_content_type(:xml).description.
|
||||
should == "respond with content type of application/xml"
|
||||
it 'accepts responding with content type as symbol' do
|
||||
xml_controller.should respond_with_content_type(:xml)
|
||||
end
|
||||
|
||||
it 'accepts responding with qualified MIME-style content type' do
|
||||
xml_controller.should respond_with_content_type('application/xml')
|
||||
end
|
||||
|
||||
it 'accepts responding with a regex matching the content type' do
|
||||
xml_controller.should respond_with_content_type(/xml/)
|
||||
end
|
||||
|
||||
it 'rejects responding with another content type' do
|
||||
xml_controller.should_not respond_with_content_type(:json)
|
||||
end
|
||||
|
||||
def xml_controller
|
||||
build_response do
|
||||
render :xml => { :user => 'thoughtbot' }.to_xml
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,83 +1,31 @@
|
|||
require 'spec_helper'
|
||||
|
||||
describe Shoulda::Matchers::ActionController::RespondWithMatcher do
|
||||
context "a controller responding with success" do
|
||||
let(:controller) { build_response { render :text => "text", :status => 200 } }
|
||||
statuses = { :success => 200, :redirect => 301, :missing => 404, :error => 500,
|
||||
:not_implemented => 501 }
|
||||
|
||||
it "should accept responding with 200" do
|
||||
controller.should respond_with(200)
|
||||
end
|
||||
statuses.each do |human_name, numeric_code|
|
||||
context "a controller responding with #{human_name}" do
|
||||
it 'accepts responding with a numeric response code' do
|
||||
controller_with_status(numeric_code).should respond_with(numeric_code)
|
||||
end
|
||||
|
||||
it "should accept responding with :success" do
|
||||
controller.should respond_with(:success)
|
||||
end
|
||||
it 'accepts responding with a symbol response code' do
|
||||
controller_with_status(numeric_code).should respond_with(human_name)
|
||||
end
|
||||
|
||||
it "should reject responding with another status" do
|
||||
controller.should_not respond_with(:error)
|
||||
it 'rejects responding with another status' do
|
||||
another_status = statuses.except(human_name).keys.first
|
||||
|
||||
controller_with_status(numeric_code).should_not
|
||||
respond_with(another_status)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context "a controller responding with redirect" do
|
||||
let(:controller) { build_response { render :text => "text", :status => 301 } }
|
||||
|
||||
it "should accept responding with 301" do
|
||||
controller.should respond_with(301)
|
||||
end
|
||||
|
||||
it "should accept responding with :redirect" do
|
||||
controller.should respond_with(:redirect)
|
||||
end
|
||||
|
||||
it "should reject responding with another status" do
|
||||
controller.should_not respond_with(:error)
|
||||
end
|
||||
end
|
||||
|
||||
context "a controller responding with missing" do
|
||||
let(:controller) { build_response { render :text => "text", :status => 404 } }
|
||||
|
||||
it "should accept responding with 404" do
|
||||
controller.should respond_with(404)
|
||||
end
|
||||
|
||||
it "should accept responding with :missing" do
|
||||
controller.should respond_with(:missing)
|
||||
end
|
||||
|
||||
it "should reject responding with another status" do
|
||||
controller.should_not respond_with(:success)
|
||||
end
|
||||
end
|
||||
|
||||
context "a controller responding with error" do
|
||||
let(:controller) { build_response { render :text => "text", :status => 500 } }
|
||||
|
||||
it "should accept responding with 500" do
|
||||
controller.should respond_with(500)
|
||||
end
|
||||
|
||||
it "should accept responding with :error" do
|
||||
controller.should respond_with(:error)
|
||||
end
|
||||
|
||||
it "should reject responding with another status" do
|
||||
controller.should_not respond_with(:success)
|
||||
end
|
||||
end
|
||||
|
||||
context "a controller responding with not implemented" do
|
||||
let(:controller) { build_response { render :text => "text", :status => 501 } }
|
||||
|
||||
it "should accept responding with 501" do
|
||||
controller.should respond_with(501)
|
||||
end
|
||||
|
||||
it "should accept responding with :not_implemented" do
|
||||
controller.should respond_with(:not_implemented)
|
||||
end
|
||||
|
||||
it "should reject responding with another status" do
|
||||
controller.should_not respond_with(:success)
|
||||
def controller_with_status(status)
|
||||
build_response do
|
||||
render :text => 'text', :status => status
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,65 +1,65 @@
|
|||
require 'spec_helper'
|
||||
|
||||
describe Shoulda::Matchers::ActionController::RouteMatcher do
|
||||
context "given a controller with a defined glob url" do
|
||||
let(:controller) { define_controller('Examples').new }
|
||||
context 'given a controller with a defined glob url' do
|
||||
it 'accepts glob route' do
|
||||
controller = define_controller('Examples').new
|
||||
|
||||
before do
|
||||
define_routes do
|
||||
match 'examples/*id', :to => 'examples#example'
|
||||
end
|
||||
end
|
||||
|
||||
it "should accept glob route" do
|
||||
controller.should route(:get, '/examples/foo/bar').
|
||||
to(:action => 'example', :id => 'foo/bar')
|
||||
end
|
||||
end
|
||||
|
||||
context "given a controller with a defined route" do
|
||||
let!(:controller) { define_controller('Examples').new }
|
||||
context 'given a controller with a defined route' do
|
||||
|
||||
before do
|
||||
define_routes do
|
||||
match 'examples/:id', :to => 'examples#example'
|
||||
end
|
||||
end
|
||||
|
||||
it "should accept routing the correct path to the correct parameters" do
|
||||
controller.should route(:get, '/examples/1').
|
||||
it 'accepts routing the correct path to the correct parameters' do
|
||||
route_examples_to_examples.should route(:get, '/examples/1').
|
||||
to(:action => 'example', :id => '1')
|
||||
end
|
||||
|
||||
it "should accept a symbol controller" do
|
||||
it 'accepts a symbol controller' do
|
||||
route_examples_to_examples
|
||||
Object.new.should route(:get, '/examples/1').
|
||||
to(:controller => :examples,
|
||||
:action => 'example',
|
||||
:id => '1')
|
||||
to(:controller => :examples, :action => 'example', :id => '1')
|
||||
end
|
||||
|
||||
it "should accept a symbol action" do
|
||||
controller.should route(:get, '/examples/1').
|
||||
it 'accepts a symbol action' do
|
||||
route_examples_to_examples.should route(:get, '/examples/1').
|
||||
to(:action => :example, :id => '1')
|
||||
end
|
||||
|
||||
it "should accept a non-string parameter" do
|
||||
controller.should route(:get, '/examples/1').
|
||||
it 'accepts a non-string parameter' do
|
||||
route_examples_to_examples.should route(:get, '/examples/1').
|
||||
to(:action => 'example', :id => 1)
|
||||
end
|
||||
|
||||
it "should reject an undefined route" do
|
||||
controller.should_not route(:get, '/bad_route').to(:var => 'value')
|
||||
it 'rejects an undefined route' do
|
||||
route_examples_to_examples.should_not
|
||||
route(:get, '/bad_route').to(:var => 'value')
|
||||
end
|
||||
|
||||
it "should reject a route for another controller" do
|
||||
it 'rejects a route for another controller' do
|
||||
route_examples_to_examples
|
||||
other = define_controller('Other').new
|
||||
other.should_not route(:get, '/examples/1').
|
||||
to(:action => 'example', :id => '1')
|
||||
end
|
||||
|
||||
it "should reject a route for different parameters" do
|
||||
controller.should_not route(:get, '/examples/1').
|
||||
it 'rejects a route for different parameters' do
|
||||
route_examples_to_examples.should_not route(:get, '/examples/1').
|
||||
to(:action => 'other', :id => '1')
|
||||
end
|
||||
|
||||
def route_examples_to_examples
|
||||
define_routes do
|
||||
get 'examples/:id', :to => 'examples#example'
|
||||
end
|
||||
|
||||
define_controller('Examples').new
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,46 +1,51 @@
|
|||
require 'spec_helper'
|
||||
|
||||
describe Shoulda::Matchers::ActionController::SetSessionMatcher do
|
||||
context "a controller that sets a session variable" do
|
||||
let(:controller) do
|
||||
build_response do
|
||||
session[:var] = 'value'
|
||||
session[:false_var] = false
|
||||
end
|
||||
context 'a controller that sets a session variable' do
|
||||
it 'accepts assigning to that variable' do
|
||||
controller_with_session(:var => 'hi').should set_session(:var)
|
||||
end
|
||||
|
||||
it "should accept assigning to that variable" do
|
||||
controller.should set_session(:var)
|
||||
it 'accepts assigning the correct value to that variable' do
|
||||
controller_with_session(:var => 'hi').should set_session(:var).to('hi')
|
||||
end
|
||||
|
||||
it "should accept assigning the correct value to that variable" do
|
||||
controller.should set_session(:var).to('value')
|
||||
it 'rejects assigning another value to that variable' do
|
||||
controller_with_session(:var => 'hi').should_not set_session(:var).to('other')
|
||||
end
|
||||
|
||||
it "should reject assigning another value to that variable" do
|
||||
controller.should_not set_session(:var).to('other')
|
||||
it 'rejects assigning to another variable' do
|
||||
controller_with_session(:var => 'hi').should_not set_session(:other)
|
||||
end
|
||||
|
||||
it "should reject assigning to another variable" do
|
||||
controller.should_not set_session(:other)
|
||||
it 'accepts assigning nil to another variable' do
|
||||
controller_with_session(:var => 'hi').should set_session(:other).to(nil)
|
||||
end
|
||||
|
||||
it "should accept assigning nil to another variable" do
|
||||
controller.should set_session(:other).to(nil)
|
||||
it 'accepts assigning false to that variable' do
|
||||
controller_with_session(:var => false).should set_session(:var).to(false)
|
||||
end
|
||||
|
||||
it "should accept assigning false to that variable" do
|
||||
controller.should set_session(:false_var).to(false)
|
||||
end
|
||||
|
||||
it "should accept assigning to the same value in the test context" do
|
||||
it 'accepts assigning to the same value in the test context' do
|
||||
expected = 'value'
|
||||
controller.should set_session(:var).in_context(self).to { expected }
|
||||
|
||||
controller_with_session(:var => expected).should
|
||||
set_session(:var).in_context(self).to { expected }
|
||||
end
|
||||
|
||||
it "should reject assigning to the another value in the test context" do
|
||||
it 'rejects assigning to the another value in the test context' do
|
||||
expected = 'other'
|
||||
controller.should_not set_session(:var).in_context(self).to { expected }
|
||||
|
||||
controller_with_session(:var => 'unexpected').should_not
|
||||
set_session(:var).in_context(self).to { expected }
|
||||
end
|
||||
|
||||
def controller_with_session(session_hash)
|
||||
build_response do
|
||||
session_hash.each do |key, value|
|
||||
session[key] = value
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,130 +1,155 @@
|
|||
require 'spec_helper'
|
||||
|
||||
describe Shoulda::Matchers::ActionController::SetTheFlashMatcher do
|
||||
it "should fail with unmatchable to" do
|
||||
expect{
|
||||
it 'fails with unmatchable #to' do
|
||||
expect {
|
||||
set_the_flash.to(1).should
|
||||
}.to raise_error("cannot match against 1")
|
||||
}.to raise_error('cannot match against 1')
|
||||
end
|
||||
|
||||
context "a controller that sets a flash message" do
|
||||
let(:controller) { build_response { flash[:notice] = 'value' } }
|
||||
|
||||
it "should accept setting any flash message" do
|
||||
controller.should set_the_flash
|
||||
context 'a controller that sets a flash message' do
|
||||
it 'accepts setting any flash message' do
|
||||
controller_with_flash(:notice => 'hi').should set_the_flash
|
||||
end
|
||||
|
||||
it "should accept setting the exact flash message" do
|
||||
controller.should set_the_flash.to('value')
|
||||
it 'accepts setting the exact flash message' do
|
||||
controller_with_flash(:notice => 'hi').should set_the_flash.to('hi')
|
||||
end
|
||||
|
||||
it "should accept setting a matched flash message" do
|
||||
controller.should set_the_flash.to(/value/)
|
||||
it 'accepts setting a matched flash message' do
|
||||
controller_with_flash(:notice => 'hello').should set_the_flash.to(/he/)
|
||||
end
|
||||
|
||||
it "should reject setting a different flash message" do
|
||||
controller.should_not set_the_flash.to('other')
|
||||
it 'rejects setting a different flash message' do
|
||||
controller_with_flash(:notice => 'hi').should_not
|
||||
set_the_flash.to('other')
|
||||
end
|
||||
|
||||
it "should reject setting a different pattern" do
|
||||
controller.should_not set_the_flash.to(/other/)
|
||||
it 'rejects setting a different pattern' do
|
||||
controller_with_flash(:notice => 'hi').should_not
|
||||
set_the_flash.to(/other/)
|
||||
end
|
||||
end
|
||||
|
||||
context "a controller that sets a flash.now message" do
|
||||
let(:controller) { build_response { flash.now[:notice] = 'value' } }
|
||||
|
||||
it "should reject setting any flash message" do
|
||||
controller.should_not set_the_flash
|
||||
context 'a controller that sets a flash.now message' do
|
||||
it 'rejects setting any flash message' do
|
||||
controller_with_flash_now.should_not set_the_flash
|
||||
end
|
||||
|
||||
it "should accept setting any flash.now message" do
|
||||
controller.should set_the_flash.now
|
||||
it 'accepts setting any flash.now message' do
|
||||
controller_with_flash_now.should set_the_flash.now
|
||||
end
|
||||
|
||||
it "should accept setting the exact flash.now message" do
|
||||
controller.should set_the_flash.to('value').now
|
||||
it 'accepts setting the exact flash.now message' do
|
||||
controller_with_flash_now(:notice => 'hi').should
|
||||
set_the_flash.now.to('hi')
|
||||
end
|
||||
|
||||
it "should accept setting a matched flash.now message" do
|
||||
controller.should set_the_flash.to(/value/).now
|
||||
it 'accepts setting a matched flash.now message' do
|
||||
controller_with_flash_now(:notice => 'flasher').should
|
||||
set_the_flash.now.to(/lash/)
|
||||
end
|
||||
|
||||
it "should reject setting a different flash.now message" do
|
||||
controller.should_not set_the_flash.to('other').now
|
||||
it 'rejects setting a different flash.now message' do
|
||||
controller_with_flash_now(:notice => 'hi').should_not
|
||||
set_the_flash.now.to('other')
|
||||
end
|
||||
|
||||
it "should reject setting a different flash.now pattern" do
|
||||
controller.should_not set_the_flash.to(/other/).now
|
||||
it 'rejects setting a different flash.now pattern' do
|
||||
controller_with_flash_now(:notice => 'hi').should_not
|
||||
set_the_flash.now.to(/other/)
|
||||
end
|
||||
end
|
||||
|
||||
context "a controller that sets a flash message of notice and alert" do
|
||||
let(:controller) do
|
||||
build_response do
|
||||
flash[:notice] = 'value'
|
||||
flash[:alert] = 'other'
|
||||
end
|
||||
end
|
||||
context 'a controller that sets flash messages for multiple keys' do
|
||||
it 'accepts flash message for either key' do
|
||||
controller = controller_with_flash(:notice => 'one', :alert => 'two')
|
||||
|
||||
it "should accept flash message of notice" do
|
||||
controller.should set_the_flash[:notice]
|
||||
controller.should set_the_flash[:alert]
|
||||
end
|
||||
|
||||
it "should accept flash message of alert" do
|
||||
controller.should set_the_flash[:notice]
|
||||
it 'rejects a flash message that is not one of the set keys' do
|
||||
controller_with_flash(:notice => 'one', :alert => 'two').should_not
|
||||
set_the_flash[:warning]
|
||||
end
|
||||
|
||||
it "should reject flash message of warning" do
|
||||
controller.should_not set_the_flash[:warning]
|
||||
it 'accepts exact flash message of notice' do
|
||||
controller_with_flash(:notice => 'one', :alert => 'two').should
|
||||
set_the_flash[:notice].to('one')
|
||||
end
|
||||
|
||||
it "should accept exact flash message of notice" do
|
||||
controller.should set_the_flash[:notice].to('value')
|
||||
it 'accepts setting a matched flash message of notice' do
|
||||
controller_with_flash(:notice => 'one', :alert => 'two').should
|
||||
set_the_flash[:notice].to(/on/)
|
||||
end
|
||||
|
||||
it "should accept setting a matched flash message of notice" do
|
||||
controller.should set_the_flash[:notice].to(/value/)
|
||||
it 'rejects setting a different flash message of notice' do
|
||||
controller_with_flash(:notice => 'one', :alert => 'two').should_not
|
||||
set_the_flash[:notice].to('other')
|
||||
end
|
||||
|
||||
it "should reject setting a different flash message of notice" do
|
||||
controller.should_not set_the_flash[:notice].to('other')
|
||||
end
|
||||
|
||||
it "should reject setting a different pattern" do
|
||||
controller.should_not set_the_flash[:notice].to(/other/)
|
||||
it 'rejects setting a different pattern' do
|
||||
controller_with_flash(:notice => 'one', :alert => 'two').should_not
|
||||
set_the_flash[:notice].to(/other/)
|
||||
end
|
||||
end
|
||||
|
||||
context "a controller that sets multiple flash messages" do
|
||||
let(:controller) do
|
||||
build_response do
|
||||
context 'a controller that sets flash and flash.now' do
|
||||
it 'accepts setting any flash.now message' do
|
||||
controller = build_response do
|
||||
flash.now[:notice] = 'value'
|
||||
flash[:success] = 'great job'
|
||||
end
|
||||
end
|
||||
|
||||
it "should accept setting any flash.now message" do
|
||||
controller.should set_the_flash.now
|
||||
controller.should set_the_flash
|
||||
end
|
||||
|
||||
it "should accept setting a matched flash.now message" do
|
||||
controller.should set_the_flash.to(/value/).now
|
||||
it 'accepts setting a matched flash.now message' do
|
||||
controller = build_response do
|
||||
flash.now[:notice] = 'value'
|
||||
flash[:success] = 'great job'
|
||||
end
|
||||
|
||||
controller.should set_the_flash.now.to(/value/)
|
||||
controller.should set_the_flash.to(/great/)
|
||||
end
|
||||
|
||||
it "should reject setting a different flash.now message" do
|
||||
controller.should_not set_the_flash.to('other').now
|
||||
it 'rejects setting a different flash.now message' do
|
||||
controller = build_response do
|
||||
flash.now[:notice] = 'value'
|
||||
flash[:success] = 'great job'
|
||||
end
|
||||
|
||||
controller.should_not set_the_flash.now.to('other')
|
||||
controller.should_not set_the_flash.to('other')
|
||||
end
|
||||
end
|
||||
|
||||
context "a controller that doesn't set a flash message" do
|
||||
let(:controller) { build_response }
|
||||
context 'a controller that does not set a flash message' do
|
||||
it 'rejects setting any flash message' do
|
||||
controller_with_no_flashes.should_not set_the_flash
|
||||
end
|
||||
end
|
||||
|
||||
it "should reject setting any flash message" do
|
||||
controller.should_not set_the_flash
|
||||
def controller_with_no_flashes
|
||||
build_response
|
||||
end
|
||||
|
||||
def controller_with_flash(flash_hash)
|
||||
build_response do
|
||||
flash_hash.each do |key, value|
|
||||
flash[key] = value
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def controller_with_flash_now(flash_hash = { :notice => 'hi' })
|
||||
build_response do
|
||||
flash_hash.each do |key, value|
|
||||
flash.now[key] = value
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,22 +1,23 @@
|
|||
require 'spec_helper'
|
||||
|
||||
describe Shoulda::Matchers::ActionMailer::HaveSentEmailMatcher do
|
||||
subject { Shoulda::Matchers::ActionMailer::HaveSentEmailMatcher.new(self) }
|
||||
subject { described_class.new(self) }
|
||||
after { ::ActionMailer::Base.deliveries.clear }
|
||||
|
||||
def add_mail_to_deliveries(params = nil)
|
||||
::ActionMailer::Base.deliveries << Mailer.the_email(params)
|
||||
end
|
||||
|
||||
context "testing with instance variables with no multipart" do
|
||||
context 'testing with instance variables with no multipart' do
|
||||
let(:info) do
|
||||
{
|
||||
:from => "do-not-reply@example.com",
|
||||
:reply_to => "reply-to-me@example.com",
|
||||
:to => "myself@me.com",
|
||||
:cc => ["you@you.com", "joe@bob.com", "hello@goodbye.com"],
|
||||
:bcc => ["test@example.com", "sam@bob.com", "goodbye@hello.com"],
|
||||
:subject => "This is spam",
|
||||
:body => "Every email is spam."
|
||||
:from => 'do-not-reply@example.com',
|
||||
:reply_to => 'reply-to-me@example.com',
|
||||
:to => 'myself@me.com',
|
||||
:cc => ['you@you.com', 'joe@bob.com', 'hello@goodbye.com'],
|
||||
:bcc => ['test@example.com', 'sam@bob.com', 'goodbye@hello.com'],
|
||||
:subject => 'This is spam',
|
||||
:body => 'Every email is spam.'
|
||||
}
|
||||
end
|
||||
|
||||
|
@ -29,55 +30,53 @@ describe Shoulda::Matchers::ActionMailer::HaveSentEmailMatcher do
|
|||
add_mail_to_deliveries(info)
|
||||
end
|
||||
|
||||
after { ::ActionMailer::Base.deliveries.clear }
|
||||
|
||||
it "should send an e-mail based on subject" do
|
||||
it 'sends an e-mail based on subject' do
|
||||
should have_sent_email.with_subject{ info[:subject] }
|
||||
end
|
||||
|
||||
it "should send an e-mail based on recipient" do
|
||||
it 'sends an e-mail based on recipient' do
|
||||
should have_sent_email.to(nil) { info[:to] }
|
||||
end
|
||||
|
||||
it "should send an e-mail based on sender" do
|
||||
it 'sends an e-mail based on sender' do
|
||||
should have_sent_email.from{ info[:from] }
|
||||
end
|
||||
|
||||
it "should send an e-email based on reply_to" do
|
||||
it 'sends an e-email based on reply_to' do
|
||||
should have_sent_email.reply_to { info[:reply_to] }
|
||||
end
|
||||
|
||||
it "should send an e-mail based on cc" do
|
||||
it 'sends an e-mail based on cc' do
|
||||
should have_sent_email.cc{ info[:cc][0] }
|
||||
end
|
||||
|
||||
it "should send an e-mail based on cc list" do
|
||||
it 'sends an e-mail based on cc list' do
|
||||
should have_sent_email.with_cc{ info[:cc] }
|
||||
end
|
||||
|
||||
it "should send an e-mail based on bcc" do
|
||||
it 'sends an e-mail based on bcc' do
|
||||
should have_sent_email.bcc{ info[:bcc][0] }
|
||||
end
|
||||
|
||||
it "should send an e-mail based on bcc list" do
|
||||
it 'sends an e-mail based on bcc list' do
|
||||
should have_sent_email.with_bcc{ info[:bcc] }
|
||||
end
|
||||
|
||||
it "should send an e-mail based on body" do
|
||||
it 'sends an e-mail based on body' do
|
||||
should have_sent_email.with_body{ info[:body] }
|
||||
end
|
||||
end
|
||||
|
||||
context "testing with instance variables with multiple parts" do
|
||||
context 'testing with instance variables with multiple parts' do
|
||||
let(:info) do
|
||||
{
|
||||
:from => "do-not-reply@example.com",
|
||||
:to => "myself@me.com",
|
||||
:cc => ["you@you.com", "joe@bob.com", "hello@goodbye.com"],
|
||||
:bcc => ["test@example.com", "sam@bob.com", "goodbye@hello.com"],
|
||||
:subject => "This is spam",
|
||||
:text => "Every email is spam.",
|
||||
:html => "<h1>HTML is spam.</h1><p>Notably.</p>"
|
||||
:from => 'do-not-reply@example.com',
|
||||
:to => 'myself@me.com',
|
||||
:cc => ['you@you.com', 'joe@bob.com', 'hello@goodbye.com'],
|
||||
:bcc => ['test@example.com', 'sam@bob.com', 'goodbye@hello.com'],
|
||||
:subject => 'This is spam',
|
||||
:text => 'Every email is spam.',
|
||||
:html => '<h1>HTML is spam.</h1><p>Notably.</p>'
|
||||
}
|
||||
end
|
||||
|
||||
|
@ -93,170 +92,164 @@ describe Shoulda::Matchers::ActionMailer::HaveSentEmailMatcher do
|
|||
add_mail_to_deliveries(info)
|
||||
end
|
||||
|
||||
after { ::ActionMailer::Base.deliveries.clear }
|
||||
|
||||
it "should send emails with text and html parts" do
|
||||
it 'sends emails with text and html parts' do
|
||||
should have_sent_email.with_part('text/plain') { info[:text] }.with_part('text/html') { info[:html] }
|
||||
end
|
||||
|
||||
it "should have the block override the method argument" do
|
||||
it 'should have the block override the method argument' do
|
||||
should have_sent_email.with_part('text/plain', 'foo') { info[:text] }.with_part('text/html', /bar/) { info[:html] }
|
||||
end
|
||||
end
|
||||
|
||||
context "an email without multiple parts" do
|
||||
context 'an email without multiple parts' do
|
||||
before do
|
||||
define_mailer :mailer, [:the_email] do
|
||||
def the_email(params)
|
||||
mail :from => "do-not-reply@example.com",
|
||||
:to => "myself@me.com",
|
||||
:subject => "This is spam",
|
||||
:cc => ["you@you.com", "joe@bob.com", "hello@goodbye.com"],
|
||||
:bcc => ["test@example.com", "sam@bob.com", "goodbye@hello.com"],
|
||||
:body => "Every email is spam."
|
||||
mail :from => 'do-not-reply@example.com',
|
||||
:to => 'myself@me.com',
|
||||
:subject => 'This is spam',
|
||||
:cc => ['you@you.com', 'joe@bob.com', 'hello@goodbye.com'],
|
||||
:bcc => ['test@example.com', 'sam@bob.com', 'goodbye@hello.com'],
|
||||
:body => 'Every email is spam.'
|
||||
end
|
||||
end
|
||||
add_mail_to_deliveries
|
||||
end
|
||||
|
||||
after { ::ActionMailer::Base.deliveries.clear }
|
||||
|
||||
it "accepts sent-email when it is not multipart" do
|
||||
it 'accepts sent-email when it is not multipart' do
|
||||
should_not have_sent_email.multipart
|
||||
matcher = have_sent_email.multipart(true)
|
||||
matcher.matches?(Mailer.the_email(nil))
|
||||
matcher.failure_message.should =~ /Expected sent email being multipart/
|
||||
end
|
||||
|
||||
it "matches the body with a regexp" do
|
||||
it 'matches the body with a regexp' do
|
||||
should have_sent_email.with_body(/email is spam/)
|
||||
end
|
||||
|
||||
it "matches the body with a string" do
|
||||
should have_sent_email.with_body("Every email is spam.")
|
||||
should_not have_sent_email.with_body("emails is")
|
||||
it 'matches the body with a string' do
|
||||
should have_sent_email.with_body('Every email is spam.')
|
||||
should_not have_sent_email.with_body('emails is')
|
||||
end
|
||||
end
|
||||
|
||||
context "an email with both a text/plain and text/html part" do
|
||||
context 'an email with both a text/plain and text/html part' do
|
||||
before do
|
||||
define_mailer :mailer, [:the_email] do
|
||||
def the_email(params)
|
||||
mail :from => "do-not-reply@example.com",
|
||||
:to => "myself@me.com",
|
||||
:cc => ["you@you.com", "joe@bob.com", "hello@goodbye.com"],
|
||||
:bcc => ["test@example.com", "sam@bob.com", "goodbye@hello.com"],
|
||||
:subject => "This is spam" do |format|
|
||||
mail :from => 'do-not-reply@example.com',
|
||||
:to => 'myself@me.com',
|
||||
:cc => ['you@you.com', 'joe@bob.com', 'hello@goodbye.com'],
|
||||
:bcc => ['test@example.com', 'sam@bob.com', 'goodbye@hello.com'],
|
||||
:subject => 'This is spam' do |format|
|
||||
|
||||
format.text { render :text => "Every email is spam." }
|
||||
format.html { render :text => "<h1>HTML is spam.</h1><p>Notably.</p>" }
|
||||
format.text { render :text => 'Every email is spam.' }
|
||||
format.html { render :text => '<h1>HTML is spam.</h1><p>Notably.</p>' }
|
||||
end
|
||||
end
|
||||
end
|
||||
add_mail_to_deliveries
|
||||
end
|
||||
|
||||
after { ::ActionMailer::Base.deliveries.clear }
|
||||
|
||||
it "accepts sent e-mail based on the subject" do
|
||||
it 'accepts sent e-mail based on the subject' do
|
||||
should have_sent_email.with_subject(/is spam$/)
|
||||
matcher = have_sent_email.with_subject(/totally safe/)
|
||||
matcher.matches?(nil)
|
||||
matcher.failure_message.should =~ /Expected sent email with subject/
|
||||
end
|
||||
|
||||
it "accepts sent e-mail based on a string sender" do
|
||||
it 'accepts sent e-mail based on a string sender' do
|
||||
should have_sent_email.from('do-not-reply@example.com')
|
||||
matcher = have_sent_email.from('you@example.com')
|
||||
matcher.matches?(nil)
|
||||
matcher.failure_message.should =~ /Expected sent email from/
|
||||
end
|
||||
|
||||
it "accepts sent e-mail based on a regexp sender" do
|
||||
it 'accepts sent e-mail based on a regexp sender' do
|
||||
should have_sent_email.from(/@example\.com/)
|
||||
matcher = have_sent_email.from(/you@/)
|
||||
matcher.matches?(nil)
|
||||
matcher.failure_message.should =~ /Expected sent email from/
|
||||
end
|
||||
|
||||
it "accepts sent e-mail based on the body" do
|
||||
it 'accepts sent e-mail based on the body' do
|
||||
should have_sent_email.with_body(/is spam\./)
|
||||
matcher = have_sent_email.with_body(/totally safe/)
|
||||
matcher.matches?(nil)
|
||||
matcher.failure_message.should =~ /Expected sent email with body/
|
||||
end
|
||||
|
||||
it "accepts sent e-mail based on a text/plain part" do
|
||||
it 'accepts sent e-mail based on a text/plain part' do
|
||||
should have_sent_email.with_part('text/plain', /is spam\./)
|
||||
matcher = have_sent_email.with_part('text/plain', /HTML is spam/)
|
||||
matcher.matches?(nil)
|
||||
matcher.failure_message.should =~ /Expected sent email with a text\/plain part containing/
|
||||
end
|
||||
|
||||
it "accepts sent e-mail based on a text/html part" do
|
||||
it 'accepts sent e-mail based on a text/html part' do
|
||||
should have_sent_email.with_part('text/html', /HTML is spam/)
|
||||
matcher = have_sent_email.with_part('text/html', /HTML is not spam\./)
|
||||
matcher.matches?(nil)
|
||||
matcher.failure_message.should =~ /Expected sent email with a text\/html part containing/
|
||||
end
|
||||
|
||||
it "accept sent e-mail based on the recipient" do
|
||||
it 'accept sent e-mail based on the recipient' do
|
||||
should have_sent_email.to('myself@me.com')
|
||||
matcher = have_sent_email.to('you@example.com')
|
||||
matcher.matches?(nil)
|
||||
matcher.failure_message.should =~ /Expected sent email to/
|
||||
end
|
||||
|
||||
it "accepts sent e-mail based on cc string" do
|
||||
it 'accepts sent e-mail based on cc string' do
|
||||
should have_sent_email.cc('joe@bob.com')
|
||||
matcher = have_sent_email.cc('you@example.com')
|
||||
matcher.matches?(nil)
|
||||
matcher.failure_message.should =~ /Expected sent email cc/
|
||||
end
|
||||
|
||||
it "accepts sent-email based on cc regex" do
|
||||
it 'accepts sent-email based on cc regex' do
|
||||
should have_sent_email.cc(/@bob\.com/)
|
||||
matcher = have_sent_email.cc(/us@/)
|
||||
matcher.matches?(nil)
|
||||
matcher.failure_message.should =~ /Expected sent email cc/
|
||||
end
|
||||
|
||||
it "accepts sent e-mail based on cc list" do
|
||||
it 'accepts sent e-mail based on cc list' do
|
||||
should have_sent_email.with_cc(['you@you.com', 'joe@bob.com'])
|
||||
matcher = have_sent_email.with_cc(['you@example.com'])
|
||||
matcher.matches?(nil)
|
||||
matcher.failure_message.should =~ /Expected sent email with cc/
|
||||
end
|
||||
|
||||
it "accepts sent e-mail based on bcc string" do
|
||||
should have_sent_email.bcc("goodbye@hello.com")
|
||||
matcher = have_sent_email.bcc("test@hello.com")
|
||||
it 'accepts sent e-mail based on bcc string' do
|
||||
should have_sent_email.bcc('goodbye@hello.com')
|
||||
matcher = have_sent_email.bcc('test@hello.com')
|
||||
matcher.matches?(nil)
|
||||
matcher.failure_message.should =~ /Expected sent email bcc/
|
||||
end
|
||||
|
||||
it "accepts sent e-mail based on bcc regex" do
|
||||
it 'accepts sent e-mail based on bcc regex' do
|
||||
should have_sent_email.bcc(/@example\.com/)
|
||||
matcher = have_sent_email.bcc(/you@/)
|
||||
matcher.matches?(nil)
|
||||
matcher.failure_message.should =~ /Expected sent email bcc/
|
||||
end
|
||||
|
||||
it "accepts sent e-mail based on bcc list" do
|
||||
it 'accepts sent e-mail based on bcc list' do
|
||||
should have_sent_email.with_bcc(['sam@bob.com', 'test@example.com'])
|
||||
matcher = have_sent_email.with_bcc(['you@you.com', 'joe@bob.com'])
|
||||
matcher.matches?(nil)
|
||||
matcher.failure_message.should =~ /Expected sent email with bcc/
|
||||
end
|
||||
|
||||
it "accepts sent-email when it is multipart" do
|
||||
it 'accepts sent-email when it is multipart' do
|
||||
should have_sent_email.multipart
|
||||
matcher = have_sent_email.multipart(false)
|
||||
matcher.matches?(nil)
|
||||
matcher.failure_message.should =~ /Expected sent email not being multipart/
|
||||
end
|
||||
|
||||
it "lists all the deliveries within failure message" do
|
||||
it 'lists all the deliveries within failure message' do
|
||||
add_mail_to_deliveries
|
||||
|
||||
matcher = have_sent_email.to('you@example.com')
|
||||
|
@ -264,7 +257,7 @@ describe Shoulda::Matchers::ActionMailer::HaveSentEmailMatcher do
|
|||
matcher.failure_message.should =~ /Deliveries:\n"This is spam" to \["myself@me\.com"\]\n"This is spam" to \["myself@me\.com"\]/
|
||||
end
|
||||
|
||||
it "allows chaining" do
|
||||
it 'allows chaining' do
|
||||
should have_sent_email.with_subject(/spam/).from('do-not-reply@example.com').with_body(/spam/).
|
||||
with_part('text/plain', /is spam\./).with_part('text/html', /HTML is spam/).to('myself@me.com')
|
||||
should_not have_sent_email.with_subject(/ham/).from('you@example.com').with_body(/ham/).
|
||||
|
@ -272,22 +265,22 @@ describe Shoulda::Matchers::ActionMailer::HaveSentEmailMatcher do
|
|||
end
|
||||
end
|
||||
|
||||
context "testing multiple email deliveries at once" do
|
||||
context 'testing multiple email deliveries at once' do
|
||||
let(:info1) do
|
||||
{
|
||||
:from => "do-not-reply@example.com",
|
||||
:to => "one@me.com",
|
||||
:subject => "subject",
|
||||
:body => "body"
|
||||
:from => 'do-not-reply@example.com',
|
||||
:to => 'one@me.com',
|
||||
:subject => 'subject',
|
||||
:body => 'body'
|
||||
}
|
||||
end
|
||||
|
||||
let(:info2) do
|
||||
{
|
||||
:from => "do-not-reply@example.com",
|
||||
:to => "two@me.com",
|
||||
:subject => "subject",
|
||||
:body => "body"
|
||||
:from => 'do-not-reply@example.com',
|
||||
:to => 'two@me.com',
|
||||
:subject => 'subject',
|
||||
:body => 'body'
|
||||
}
|
||||
end
|
||||
|
||||
|
@ -301,33 +294,31 @@ describe Shoulda::Matchers::ActionMailer::HaveSentEmailMatcher do
|
|||
add_mail_to_deliveries(info2)
|
||||
end
|
||||
|
||||
after { ::ActionMailer::Base.deliveries.clear }
|
||||
|
||||
it "should send an e-mail based on recipient 1" do
|
||||
should have_sent_email.to("one@me.com")
|
||||
it 'sends an e-mail based on recipient 1' do
|
||||
should have_sent_email.to('one@me.com')
|
||||
end
|
||||
|
||||
it "should send an e-mail based on recipient 2" do
|
||||
should have_sent_email.to("two@me.com")
|
||||
it 'sends an e-mail based on recipient 2' do
|
||||
should have_sent_email.to('two@me.com')
|
||||
end
|
||||
end
|
||||
|
||||
it "provides a detailed description of the e-mail expected to be sent" do
|
||||
it 'provides a detailed description of the e-mail expected to be sent' do
|
||||
matcher = have_sent_email
|
||||
matcher.description.should == 'send an email'
|
||||
matcher = matcher.with_subject("Welcome!")
|
||||
matcher.description.should == 'send an email with a subject of "Welcome!"'
|
||||
matcher = matcher.with_body("Welcome, human!")
|
||||
matcher.description.should == 'send an email with a subject of "Welcome!" containing "Welcome, human!"'
|
||||
matcher = matcher.with_part('text/plain', 'plain')
|
||||
matcher.description.should == 'send an email with a subject of "Welcome!" containing "Welcome, human!" having a text/plain part containing "plain"'
|
||||
matcher = matcher.with_subject('Welcome!')
|
||||
matcher.description.should == %q(send an email with a subject of "Welcome!")
|
||||
matcher = matcher.with_body('Welcome, human!')
|
||||
matcher.description.should == %q(send an email with a subject of "Welcome!" containing "Welcome, human!")
|
||||
matcher = matcher.with_part("text/plain", "plain")
|
||||
matcher.description.should == %q(send an email with a subject of "Welcome!" containing "Welcome, human!" having a text/plain part containing "plain")
|
||||
matcher = matcher.with_part('text/html', 'html')
|
||||
matcher.description.should == 'send an email with a subject of "Welcome!" containing "Welcome, human!" having a text/plain part containing "plain" having a text/html part containing "html"'
|
||||
matcher = matcher.from("alien@example.com")
|
||||
matcher.description.should == 'send an email with a subject of "Welcome!" containing "Welcome, human!" having a text/plain part containing "plain" having a text/html part containing "html" from "alien@example.com"'
|
||||
matcher = matcher.to("human@example.com")
|
||||
matcher.description.should == 'send an email with a subject of "Welcome!" containing "Welcome, human!" having a text/plain part containing "plain" having a text/html part containing "html" from "alien@example.com" to "human@example.com"'
|
||||
matcher = matcher.reply_to("reply-to-me@example.com")
|
||||
matcher.description.should == 'send an email with a subject of "Welcome!" containing "Welcome, human!" having a text/plain part containing "plain" having a text/html part containing "html" from "alien@example.com" reply to "reply-to-me@example.com" to "human@example.com"'
|
||||
matcher.description.should == %q(send an email with a subject of "Welcome!" containing "Welcome, human!" having a text/plain part containing "plain" having a text/html part containing "html")
|
||||
matcher = matcher.from('alien@example.com')
|
||||
matcher.description.should == %q(send an email with a subject of "Welcome!" containing "Welcome, human!" having a text/plain part containing "plain" having a text/html part containing "html" from "alien@example.com")
|
||||
matcher = matcher.to('human@example.com')
|
||||
matcher.description.should == %q(send an email with a subject of "Welcome!" containing "Welcome, human!" having a text/plain part containing "plain" having a text/html part containing "html" from "alien@example.com" to "human@example.com")
|
||||
matcher = matcher.reply_to('reply-to-me@example.com')
|
||||
matcher.description.should == %q(send an email with a subject of "Welcome!" containing "Welcome, human!" having a text/plain part containing "plain" having a text/html part containing "html" from "alien@example.com" reply to "reply-to-me@example.com" to "human@example.com")
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,115 +1,111 @@
|
|||
require 'spec_helper'
|
||||
|
||||
describe Shoulda::Matchers::ActiveModel::AllowMassAssignmentOfMatcher do
|
||||
describe "#description" do
|
||||
context '#description' do
|
||||
context 'without a role' do
|
||||
it 'includes the attribute name' do
|
||||
matcher = Shoulda::Matchers::ActiveModel::AllowMassAssignmentOfMatcher.new(:attr)
|
||||
matcher.description.should eq("allow mass assignment of attr")
|
||||
described_class.new(:attr).description.should ==
|
||||
'allow mass assignment of attr'
|
||||
end
|
||||
end
|
||||
|
||||
if active_model_3_1?
|
||||
context 'with a role' do
|
||||
it 'includes the attribute name and the role' do
|
||||
matcher = Shoulda::Matchers::ActiveModel::AllowMassAssignmentOfMatcher.new(:attr).as(:admin)
|
||||
matcher.description.should eq("allow mass assignment of attr as admin")
|
||||
described_class.new(:attr).as(:admin).description.should ==
|
||||
'allow mass assignment of attr as admin'
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context "an attribute that is blacklisted from mass-assignment" do
|
||||
let(:model) do
|
||||
define_model(:example, :attr => :string) do
|
||||
attr_protected :attr
|
||||
context 'an attribute that is blacklisted from mass-assignment' do
|
||||
it 'rejects being mass-assignable' do
|
||||
model = define_model(:example, :blacklisted => :string) do
|
||||
attr_protected :blacklisted
|
||||
end.new
|
||||
end
|
||||
|
||||
it "should reject being mass-assignable" do
|
||||
model.should_not allow_mass_assignment_of(:attr)
|
||||
model.should_not allow_mass_assignment_of(:blacklisted)
|
||||
end
|
||||
end
|
||||
|
||||
context "an attribute that is not whitelisted for mass-assignment" do
|
||||
let(:model) do
|
||||
define_model(:example, :attr => :string, :other => :string) do
|
||||
attr_accessible :other
|
||||
context 'an attribute that is not whitelisted for mass-assignment' do
|
||||
it 'rejects being mass-assignable' do
|
||||
model = define_model(:example, :not_whitelisted => :string,
|
||||
:whitelisted => :string) do
|
||||
attr_accessible :whitelisted
|
||||
end.new
|
||||
end
|
||||
|
||||
it "should reject being mass-assignable" do
|
||||
model.should_not allow_mass_assignment_of(:attr)
|
||||
model.should_not allow_mass_assignment_of(:not_whitelisted)
|
||||
end
|
||||
end
|
||||
|
||||
context "an attribute that is whitelisted for mass-assignment" do
|
||||
let(:model) do
|
||||
define_model(:example, :attr => :string) do
|
||||
attr_accessible :attr
|
||||
end.new
|
||||
end
|
||||
|
||||
it "should accept being mass-assignable" do
|
||||
model.should allow_mass_assignment_of(:attr)
|
||||
context 'an attribute that is whitelisted for mass-assignment' do
|
||||
it 'accepts being mass-assignable' do
|
||||
define_model(:example, :whitelisted => :string) do
|
||||
attr_accessible :whitelisted
|
||||
end.new.should allow_mass_assignment_of(:whitelisted)
|
||||
end
|
||||
end
|
||||
|
||||
context "an attribute not included in the mass-assignment blacklist" do
|
||||
let(:model) do
|
||||
define_model(:example, :attr => :string, :other => :string) do
|
||||
attr_protected :other
|
||||
context 'an attribute not included in the mass-assignment blacklist' do
|
||||
it 'accepts being mass-assignable' do
|
||||
model = define_model(:example, :not_blacklisted => :string,
|
||||
:blacklisted => :string) do
|
||||
attr_protected :blacklisted
|
||||
end.new
|
||||
end
|
||||
|
||||
it "should accept being mass-assignable" do
|
||||
model.should allow_mass_assignment_of(:attr)
|
||||
model.should allow_mass_assignment_of(:not_blacklisted)
|
||||
end
|
||||
end
|
||||
|
||||
unless active_model_3_2?
|
||||
context "an attribute on a class with no protected attributes" do
|
||||
let(:model) { define_model(:example, :attr => :string).new }
|
||||
|
||||
it "should accept being mass-assignable" do
|
||||
model.should allow_mass_assignment_of(:attr)
|
||||
context 'an attribute on a class with no protected attributes' do
|
||||
it 'accepts being mass-assignable' do
|
||||
no_protected_attributes.should allow_mass_assignment_of(:attr)
|
||||
end
|
||||
|
||||
it "should assign a negative failure message" do
|
||||
it 'assigns a negative failure message' do
|
||||
matcher = allow_mass_assignment_of(:attr)
|
||||
matcher.matches?(model).should == true
|
||||
|
||||
matcher.matches?(no_protected_attributes).should be_true
|
||||
|
||||
matcher.negative_failure_message.should_not be_nil
|
||||
end
|
||||
end
|
||||
|
||||
def no_protected_attributes
|
||||
define_model(:example, :attr => :string).new
|
||||
end
|
||||
end
|
||||
|
||||
context "an attribute on a class with all protected attributes" do
|
||||
let(:model) do
|
||||
define_model(:example, :attr => :string) do
|
||||
attr_accessible
|
||||
end.new
|
||||
context 'an attribute on a class with all protected attributes' do
|
||||
it 'rejects being mass-assignable' do
|
||||
all_protected_attributes.should_not allow_mass_assignment_of(:attr)
|
||||
end
|
||||
|
||||
it "should reject being mass-assignable" do
|
||||
model.should_not allow_mass_assignment_of(:attr)
|
||||
def all_protected_attributes
|
||||
define_model(:example, :attr => :string) do
|
||||
attr_accessible nil
|
||||
end.new
|
||||
end
|
||||
end
|
||||
|
||||
if active_model_3_1?
|
||||
context "an attribute included in the mass-assignment whitelist for admin role only" do
|
||||
let(:model) do
|
||||
context 'an attribute included in the mass-assignment whitelist for admin role only' do
|
||||
it 'rejects being mass-assignable' do
|
||||
mass_assignable_as_admin.should_not allow_mass_assignment_of(:attr)
|
||||
end
|
||||
|
||||
it 'accepts being mass-assignable for admin' do
|
||||
mass_assignable_as_admin.should allow_mass_assignment_of(:attr).as(:admin)
|
||||
end
|
||||
|
||||
def mass_assignable_as_admin
|
||||
define_model(:example, :attr => :string) do
|
||||
attr_accessible :attr, :as => :admin
|
||||
end.new
|
||||
end
|
||||
|
||||
it "should reject being mass-assignable" do
|
||||
model.should_not allow_mass_assignment_of(:attr)
|
||||
end
|
||||
|
||||
it "should accept being mass-assignable for admin" do
|
||||
model.should allow_mass_assignment_of(:attr).as(:admin)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,47 +1,62 @@
|
|||
require 'spec_helper'
|
||||
|
||||
describe Shoulda::Matchers::ActiveModel::AllowValueMatcher do
|
||||
context "an attribute with a format validation" do
|
||||
let(:model) do
|
||||
define_model :example, :attr => :string do
|
||||
validates_format_of :attr, :with => /abc/
|
||||
end.new
|
||||
context "#description" do
|
||||
it 'describes itself with multiple values' do
|
||||
matcher = allow_value('foo', 'bar').for(:baz)
|
||||
|
||||
matcher.description.should == 'allow baz to be set to any of ["foo", "bar"]'
|
||||
end
|
||||
|
||||
it "allows a good value" do
|
||||
model.should allow_value("abcde").for(:attr)
|
||||
it 'describes itself with a single value' do
|
||||
matcher = allow_value('foo').for(:baz)
|
||||
|
||||
matcher.description.should == 'allow baz to be set to "foo"'
|
||||
end
|
||||
|
||||
it "rejects a bad value" do
|
||||
model.should_not allow_value("xyz").for(:attr)
|
||||
end
|
||||
if active_model_3_2?
|
||||
it 'describes itself with a strict validation' do
|
||||
strict_matcher = allow_value('xyz').for(:attr).strict
|
||||
|
||||
it "allows several good values" do
|
||||
model.should allow_value("abcde", "deabc").for(:attr)
|
||||
end
|
||||
|
||||
it "rejects several bad values" do
|
||||
model.should_not allow_value("xyz", "zyx", nil, []).for(:attr)
|
||||
strict_matcher.description.should ==
|
||||
%q(doesn't raise when attr is set to "xyz")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context "an attribute with a format validation and a custom message" do
|
||||
let(:model) do
|
||||
define_model :example, :attr => :string do
|
||||
validates_format_of :attr, :with => /abc/, :message => 'bad value'
|
||||
end.new
|
||||
context 'an attribute with a validation' do
|
||||
it 'allows a good value' do
|
||||
validating_format(:with => /abc/).should allow_value('abcde').for(:attr)
|
||||
end
|
||||
|
||||
it "allows a good value" do
|
||||
model.should allow_value('abcde').for(:attr).with_message(/bad/)
|
||||
it 'rejects a bad value' do
|
||||
validating_format(:with => /abc/).should_not allow_value('xyz').for(:attr)
|
||||
end
|
||||
|
||||
it "rejects a bad value" do
|
||||
model.should_not allow_value('xyz').for(:attr).with_message(/bad/)
|
||||
it 'allows several good values' do
|
||||
validating_format(:with => /abc/).should
|
||||
allow_value('abcde', 'deabc').for(:attr)
|
||||
end
|
||||
|
||||
it 'rejects several bad values' do
|
||||
validating_format(:with => /abc/).should_not
|
||||
allow_value('xyz', 'zyx', nil, []).for(:attr)
|
||||
end
|
||||
end
|
||||
|
||||
context "an attribute with several validations" do
|
||||
context 'an attribute with a validation and a custom message' do
|
||||
it 'allows a good value' do
|
||||
validating_format(:with => /abc/, :message => 'bad value').should
|
||||
allow_value('abcde').for(:attr).with_message(/bad/)
|
||||
end
|
||||
|
||||
it 'rejects a bad value' do
|
||||
validating_format(:with => /abc/, :message => 'bad value').should_not
|
||||
allow_value('xyz').for(:attr).with_message(/bad/)
|
||||
end
|
||||
end
|
||||
|
||||
context 'an attribute with several validations' do
|
||||
let(:model) do
|
||||
define_model :example, :attr => :string do
|
||||
validates_presence_of :attr
|
||||
|
@ -50,10 +65,10 @@ describe Shoulda::Matchers::ActiveModel::AllowValueMatcher do
|
|||
:less_than_or_equal_to => 50000
|
||||
end.new
|
||||
end
|
||||
bad_values = [nil, "", "abc", "0", "50001", "123456", []]
|
||||
bad_values = [nil, '', 'abc', '0', '50001', '123456', []]
|
||||
|
||||
it "allows a good value" do
|
||||
model.should allow_value("12345").for(:attr)
|
||||
it 'allows a good value' do
|
||||
model.should allow_value('12345').for(:attr)
|
||||
end
|
||||
|
||||
bad_values.each do |bad_value|
|
||||
|
@ -62,70 +77,48 @@ describe Shoulda::Matchers::ActiveModel::AllowValueMatcher do
|
|||
end
|
||||
end
|
||||
|
||||
it "rejects bad values (#{bad_values.map(&:inspect).join(', ')})" do
|
||||
it "rejects several bad values (#{bad_values.map(&:inspect).join(', ')})" do
|
||||
model.should_not allow_value(*bad_values).for(:attr)
|
||||
end
|
||||
end
|
||||
|
||||
context "an AllowValueMatcher with multiple values" do
|
||||
it "should describe itself" do
|
||||
matcher = allow_value("foo", "bar").for(:baz)
|
||||
matcher.description.should == 'allow baz to be set to any of ["foo", "bar"]'
|
||||
end
|
||||
end
|
||||
|
||||
context "an AllowValueMatcher with a single value" do
|
||||
it "should describe itself" do
|
||||
matcher = allow_value("foo").for(:baz)
|
||||
matcher.description.should eq('allow baz to be set to "foo"')
|
||||
end
|
||||
|
||||
it "allows you to call description before calling matches?" do
|
||||
context 'with a single value' do
|
||||
it 'allows you to call description before calling matches?' do
|
||||
model = define_model(:example, :attr => :string).new
|
||||
matcher = Shoulda::Matchers::ActiveModel::AllowValueMatcher.new("foo").for(:attr)
|
||||
matcher = described_class.new('foo').for(:attr)
|
||||
matcher.description
|
||||
|
||||
expect { matcher.matches?(model) }.not_to raise_error
|
||||
expect { matcher.matches?(model) }.not_to raise_error(NoMethodError)
|
||||
end
|
||||
end
|
||||
|
||||
context "an AllowValueMatcher with no values" do
|
||||
it "raises an error" do
|
||||
lambda do
|
||||
allow_value.for(:baz)
|
||||
end.should raise_error(ArgumentError, /at least one argument/)
|
||||
context 'with no values' do
|
||||
it 'raises an error' do
|
||||
expect { allow_value.for(:baz) }.to
|
||||
raise_error(ArgumentError, /at least one argument/)
|
||||
end
|
||||
end
|
||||
|
||||
if Rails::VERSION::STRING.to_f >= 3.2
|
||||
context "an attribute with a strict format validation" do
|
||||
let(:model) do
|
||||
define_model :example, :attr => :string do
|
||||
validates_format_of :attr, :with => /abc/, :strict => true
|
||||
end.new
|
||||
if active_model_3_2?
|
||||
context 'an attribute with a strict format validation' do
|
||||
it 'strictly rejects a bad value' do
|
||||
validating_format(:with => /abc/, :strict => true).should_not
|
||||
allow_value('xyz').for(:attr).strict
|
||||
end
|
||||
|
||||
it "strictly rejects a bad value" do
|
||||
model.should_not allow_value("xyz").for(:attr).strict
|
||||
it 'strictly allows a bad value with a different message' do
|
||||
validating_format(:with => /abc/, :strict => true).should
|
||||
allow_value('xyz').for(:attr).with_message(/abc/).strict
|
||||
end
|
||||
|
||||
it "strictly allows a bad value with a different message" do
|
||||
model.should allow_value("xyz").for(:attr).with_message(/abc/).strict
|
||||
end
|
||||
it 'provides a useful negative failure message' do
|
||||
matcher = allow_value('xyz').for(:attr).strict.with_message(/abc/)
|
||||
|
||||
it "describes itself" do
|
||||
allow_value("xyz").for(:attr).strict.description.
|
||||
should == %{doesn't raise when attr is set to "xyz"}
|
||||
end
|
||||
matcher.matches?(validating_format(:with => /abc/, :strict => true))
|
||||
|
||||
it "provides a useful negative failure message" do
|
||||
matcher = allow_value("xyz").for(:attr).strict.with_message(/abc/)
|
||||
matcher.matches?(model)
|
||||
matcher.negative_failure_message.
|
||||
should == 'Expected exception to include /abc/ ' +
|
||||
'when attr is set to "xyz", got Attr is invalid'
|
||||
matcher.negative_failure_message.should == 'Expected exception to include /abc/ ' +
|
||||
'when attr is set to "xyz", got Attr is invalid'
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
@ -1,65 +1,43 @@
|
|||
require 'spec_helper'
|
||||
|
||||
describe Shoulda::Matchers::ActiveModel::DisallowValueMatcher do
|
||||
it "does not allow any types" do
|
||||
matcher = Shoulda::Matchers::ActiveModel::DisallowValueMatcher.new("abcde")
|
||||
matcher.allowed_types.should == ""
|
||||
it 'does not allow any types' do
|
||||
matcher('abcde').allowed_types.should == ''
|
||||
end
|
||||
|
||||
context "an attribute with a format validation" do
|
||||
before do
|
||||
define_model :example, :attr => :string do
|
||||
validates_format_of :attr, :with => /abc/
|
||||
end
|
||||
@model = Example.new
|
||||
context 'an attribute with a format validation' do
|
||||
it 'does not match if the value is allowed' do
|
||||
validating_format(:with => /abc/).should_not matcher('abcde').for(:attr)
|
||||
end
|
||||
|
||||
it "does not match if the value is allowed" do
|
||||
matcher = new_matcher("abcde")
|
||||
matcher.for(:attr)
|
||||
matcher.matches?(@model).should be_false
|
||||
end
|
||||
|
||||
it "matches if the value is not allowed" do
|
||||
matcher = new_matcher("xyz")
|
||||
matcher.for(:attr)
|
||||
matcher.matches?(@model).should be_true
|
||||
it 'matches if the value is not allowed' do
|
||||
validating_format(:with => /abc/).should matcher('xyz').for(:attr)
|
||||
end
|
||||
end
|
||||
|
||||
context "an attribute with a format validation and a custom message" do
|
||||
before do
|
||||
define_model :example, :attr => :string do
|
||||
validates_format_of :attr, :with => /abc/, :message => 'good message'
|
||||
end
|
||||
@model = Example.new
|
||||
end
|
||||
|
||||
it "does not match if the value and message are both correct" do
|
||||
matcher = new_matcher("abcde")
|
||||
matcher.for(:attr).with_message('good message')
|
||||
matcher.matches?(@model).should be_false
|
||||
context 'an attribute with a format validation and a custom message' do
|
||||
it 'does not match if the value and message are both correct' do
|
||||
validating_format(:with => /abc/, :message => 'good message').should_not
|
||||
matcher('abcde').for(:attr).with_message('good message')
|
||||
end
|
||||
|
||||
it "delegates its failure message to its allow matcher's negative failure message" do
|
||||
allow_matcher = stub_everything(:negative_failure_message => "allow matcher failure")
|
||||
allow_matcher = stub_everything(:negative_failure_message => 'allow matcher failure')
|
||||
Shoulda::Matchers::ActiveModel::AllowValueMatcher.stubs(:new).returns(allow_matcher)
|
||||
|
||||
matcher = new_matcher("abcde")
|
||||
matcher.for(:attr).with_message('good message')
|
||||
matcher.matches?(@model)
|
||||
matcher = matcher('abcde').for(:attr).with_message('good message')
|
||||
matcher.matches?(validating_format(:with => /abc/, :message => 'good message'))
|
||||
|
||||
matcher.failure_message.should == "allow matcher failure"
|
||||
matcher.failure_message.should == 'allow matcher failure'
|
||||
end
|
||||
|
||||
it "matches if the message is correct but the value is not" do
|
||||
matcher = new_matcher("xyz")
|
||||
matcher.for(:attr).with_message('good message')
|
||||
matcher.matches?(@model).should be_true
|
||||
it 'matches if the message is correct but the value is not' do
|
||||
validating_format(:with => /abc/, :message => 'good message').should
|
||||
matcher('xyz').for(:attr).with_message('good message')
|
||||
end
|
||||
end
|
||||
|
||||
def new_matcher(value)
|
||||
matcher = Shoulda::Matchers::ActiveModel::DisallowValueMatcher.new(value)
|
||||
def matcher(value)
|
||||
described_class.new(value)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,79 +1,68 @@
|
|||
require 'spec_helper'
|
||||
|
||||
describe Shoulda::Matchers::ActiveModel::EnsureExclusionOfMatcher do
|
||||
|
||||
context "an attribute which must be excluded of a range" do
|
||||
before do
|
||||
@model = define_model(:example, :attr => :integer) do
|
||||
validates_exclusion_of :attr, :in => 2..5
|
||||
end.new
|
||||
context 'an attribute which must be excluded from a range' do
|
||||
it 'accepts ensuring the correct range' do
|
||||
validating_exclusion(:in => 2..5).should
|
||||
ensure_exclusion_of(:attr).in_range(2..5)
|
||||
end
|
||||
|
||||
it "should accept ensuring the correct range" do
|
||||
@model.should ensure_exclusion_of(:attr).in_range(2..5)
|
||||
it 'rejects ensuring excluded value' do
|
||||
validating_exclusion(:in => 2..5).should_not
|
||||
ensure_exclusion_of(:attr).in_range(2..6)
|
||||
end
|
||||
|
||||
it "should reject ensuring excluded value" do
|
||||
@model.should_not ensure_exclusion_of(:attr).in_range(2..6)
|
||||
end
|
||||
|
||||
it "should not override the default message with a blank" do
|
||||
@model.should ensure_exclusion_of(:attr).in_range(2..5).with_message(nil)
|
||||
it 'does not override the default message with a blank' do
|
||||
validating_exclusion(:in => 2..5).should
|
||||
ensure_exclusion_of(:attr).in_range(2..5).with_message(nil)
|
||||
end
|
||||
end
|
||||
|
||||
context "an attribute with a custom ranged value validation" do
|
||||
before do
|
||||
@model = define_model(:example, :attr => :string) do
|
||||
validates_exclusion_of :attr, :in => 2..4, :message => 'not good'
|
||||
|
||||
end.new
|
||||
end
|
||||
|
||||
it "should accept ensuring the correct range" do
|
||||
@model.should ensure_exclusion_of(:attr).in_range(2..4).with_message(/not good/)
|
||||
context 'an attribute with a custom validation message' do
|
||||
it 'accepts ensuring the correct range' do
|
||||
validating_exclusion(:in => 2..4, :message => 'not good').should
|
||||
ensure_exclusion_of(:attr).in_range(2..4).with_message(/not good/)
|
||||
end
|
||||
end
|
||||
|
||||
context "an attribute with custom range validations" do
|
||||
before do
|
||||
define_model :example, :attr => :integer do
|
||||
validate :custom_validation
|
||||
def custom_validation
|
||||
if attr >= 2 && attr <= 5
|
||||
errors.add(:attr, 'shoud be out of this range')
|
||||
end
|
||||
context 'an attribute with custom range validations' do
|
||||
it 'accepts ensuring the correct range and messages' do
|
||||
model = custom_validation do
|
||||
if attr >= 2 && attr <= 5
|
||||
errors.add(:attr, 'should be out of this range')
|
||||
end
|
||||
end
|
||||
@model = Example.new
|
||||
end
|
||||
|
||||
it "should accept ensuring the correct range and messages" do
|
||||
@model.should ensure_exclusion_of(:attr).in_range(2..5).with_message(/shoud be out of this range/)
|
||||
model.should ensure_exclusion_of(:attr).in_range(2..5).
|
||||
with_message(/should be out of this range/)
|
||||
end
|
||||
end
|
||||
|
||||
context "an attribute which must be excluded in an array" do
|
||||
before do
|
||||
@model = define_model(:example, :attr => :string) do
|
||||
validates_exclusion_of :attr, :in => %w(one two)
|
||||
end.new
|
||||
context 'an attribute which must be excluded from an array' do
|
||||
it 'accepts with correct array' do
|
||||
validating_exclusion(:in => %w(one two)).should
|
||||
ensure_exclusion_of(:attr).in_array(%w(one two))
|
||||
end
|
||||
|
||||
it "accepts with correct array" do
|
||||
@model.should ensure_exclusion_of(:attr).in_array(%w(one two))
|
||||
it 'rejects when only part of array matches' do
|
||||
validating_exclusion(:in => %w(one two)).should_not
|
||||
ensure_exclusion_of(:attr).in_array(%w(one wrong_value))
|
||||
end
|
||||
|
||||
it "rejects when only part of array matches" do
|
||||
@model.should_not ensure_exclusion_of(:attr).in_array(%w(one wrong_value))
|
||||
it 'rejects when array does not match at all' do
|
||||
validating_exclusion(:in => %w(one two)).should_not
|
||||
ensure_exclusion_of(:attr).in_array(%w(cat dog))
|
||||
end
|
||||
|
||||
it "rejects when array doesn't match at all" do
|
||||
@model.should_not ensure_exclusion_of(:attr).in_array(%w(cat dog))
|
||||
it 'has correct description' do
|
||||
ensure_exclusion_of(:attr).in_array([true, 'dog']).description.should ==
|
||||
'ensure exclusion of attr in [true, "dog"]'
|
||||
end
|
||||
end
|
||||
|
||||
it "has correct description" do
|
||||
ensure_exclusion_of(:attr).in_array([true, 'dog']).description.should == 'ensure exclusion of attr in [true, "dog"]'
|
||||
end
|
||||
def validating_exclusion(options)
|
||||
define_model(:example, :attr => :integer) do
|
||||
validates_exclusion_of :attr, options
|
||||
end.new
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,181 +1,171 @@
|
|||
require 'spec_helper'
|
||||
|
||||
describe Shoulda::Matchers::ActiveModel::EnsureInclusionOfMatcher do
|
||||
context "with no validations" do
|
||||
before do
|
||||
@model = define_model(:example, :attr => :string) do
|
||||
end.new
|
||||
end
|
||||
|
||||
it "should reject an array which does not have a validator defined" do
|
||||
@model.should_not ensure_inclusion_of(:attr).in_array(%w(Yes No))
|
||||
context 'with no validations' do
|
||||
it 'rejects an array which does not have a validator defined' do
|
||||
define_model(:example, :attr => :string).new.should_not
|
||||
ensure_inclusion_of(:attr).in_array(%w(Yes No))
|
||||
end
|
||||
end
|
||||
|
||||
context "with true/false values" do
|
||||
it "can verify outside values to ensure the negative case" do
|
||||
model = define_model(:example, :attr => :string).new
|
||||
|
||||
model.should_not ensure_inclusion_of(:attr).in_array([true, false])
|
||||
context 'with true/false values' do
|
||||
it 'can verify outside values to ensure the negative case' do
|
||||
define_model(:example, :attr => :string).new.should_not
|
||||
ensure_inclusion_of(:attr).in_array([true, false])
|
||||
end
|
||||
end
|
||||
|
||||
context "where we cannot determine a value outside the array" do
|
||||
it "should raise a custom exception" do
|
||||
context 'where we cannot determine a value outside the array' do
|
||||
it 'raises a custom exception' do
|
||||
model = define_model(:example, :attr => :string).new
|
||||
|
||||
arbitrary_string = Shoulda::Matchers::ActiveModel::EnsureInclusionOfMatcher::ARBITRARY_OUTSIDE_STRING
|
||||
arbitrary_string = described_class::ARBITRARY_OUTSIDE_STRING
|
||||
expect { model.should ensure_inclusion_of(:attr).in_array([arbitrary_string]) }.to raise_error Shoulda::Matchers::ActiveModel::CouldNotDetermineValueOutsideOfArray
|
||||
end
|
||||
end
|
||||
|
||||
context "an attribute which must be included in a range" do
|
||||
before do
|
||||
@model = define_model(:example, :attr => :integer) do
|
||||
validates_inclusion_of :attr, :in => 2..5
|
||||
end.new
|
||||
context 'an attribute which must be included in a range' do
|
||||
it 'accepts ensuring the correct range' do
|
||||
validating_inclusion(:in => 2..5).should
|
||||
ensure_inclusion_of(:attr).in_range(2..5)
|
||||
end
|
||||
|
||||
it "should accept ensuring the correct range" do
|
||||
@model.should ensure_inclusion_of(:attr).in_range(2..5)
|
||||
it 'rejects ensuring a lower minimum value' do
|
||||
validating_inclusion(:in => 2..5).should_not
|
||||
ensure_inclusion_of(:attr).in_range(1..5)
|
||||
end
|
||||
|
||||
it "should reject ensuring a lower minimum value" do
|
||||
@model.should_not ensure_inclusion_of(:attr).in_range(1..5)
|
||||
it 'rejects ensuring a higher minimum value' do
|
||||
validating_inclusion(:in => 2..5).should_not
|
||||
ensure_inclusion_of(:attr).in_range(3..5)
|
||||
end
|
||||
|
||||
it "should reject ensuring a higher minimum value" do
|
||||
@model.should_not ensure_inclusion_of(:attr).in_range(3..5)
|
||||
it 'rejects ensuring a lower maximum value' do
|
||||
validating_inclusion(:in => 2..5).should_not
|
||||
ensure_inclusion_of(:attr).in_range(2..4)
|
||||
end
|
||||
|
||||
it "should reject ensuring a lower maximum value" do
|
||||
@model.should_not ensure_inclusion_of(:attr).in_range(2..4)
|
||||
it 'rejects ensuring a higher maximum value' do
|
||||
validating_inclusion(:in => 2..5).should_not
|
||||
ensure_inclusion_of(:attr).in_range(2..6)
|
||||
end
|
||||
|
||||
it "should reject ensuring a higher maximum value" do
|
||||
@model.should_not ensure_inclusion_of(:attr).in_range(2..6)
|
||||
end
|
||||
|
||||
it "should not override the default message with a blank" do
|
||||
@model.should ensure_inclusion_of(:attr).in_range(2..5).with_message(nil)
|
||||
it 'does not override the default message with a blank' do
|
||||
validating_inclusion(:in => 2..5).should
|
||||
ensure_inclusion_of(:attr).in_range(2..5).with_message(nil)
|
||||
end
|
||||
end
|
||||
|
||||
context "an attribute with a custom ranged value validation" do
|
||||
before do
|
||||
@model = define_model(:example, :attr => :string) do
|
||||
validates_inclusion_of :attr, :in => 2..4, :message => 'not good'
|
||||
|
||||
end.new
|
||||
end
|
||||
|
||||
it "should accept ensuring the correct range" do
|
||||
@model.should ensure_inclusion_of(:attr).in_range(2..4).with_message(/not good/)
|
||||
context 'an attribute with a custom ranged value validation' do
|
||||
it 'accepts ensuring the correct range' do
|
||||
validating_inclusion(:in => 2..4, :message => 'not good').should
|
||||
ensure_inclusion_of(:attr).in_range(2..4).with_message(/not good/)
|
||||
end
|
||||
end
|
||||
|
||||
context "an attribute with custom range validations" do
|
||||
before do
|
||||
define_model :example, :attr => :integer do
|
||||
validate :custom_validation
|
||||
def custom_validation
|
||||
if attr < 2
|
||||
errors.add(:attr, 'too low')
|
||||
elsif attr > 5
|
||||
errors.add(:attr, 'too high')
|
||||
end
|
||||
context 'an attribute with custom range validations' do
|
||||
it 'accepts ensuring the correct range and messages' do
|
||||
model = custom_validation do
|
||||
if attr < 2
|
||||
errors.add(:attr, 'too low')
|
||||
elsif attr > 5
|
||||
errors.add(:attr, 'too high')
|
||||
end
|
||||
end
|
||||
@model = Example.new
|
||||
end
|
||||
|
||||
it "should accept ensuring the correct range and messages" do
|
||||
@model.should ensure_inclusion_of(:attr).in_range(2..5).with_low_message(/low/).with_high_message(/high/)
|
||||
model.should ensure_inclusion_of(:attr).in_range(2..5).
|
||||
with_low_message(/low/).with_high_message(/high/)
|
||||
end
|
||||
end
|
||||
|
||||
context "an attribute which must be included in an array" do
|
||||
before do
|
||||
@model = define_model(:example, :attr => :string) do
|
||||
validates_inclusion_of :attr, :in => %w(one two)
|
||||
end.new
|
||||
context 'an attribute which must be included in an array' do
|
||||
it 'accepts with correct array' do
|
||||
validating_inclusion(:in => %w(one two)).should
|
||||
ensure_inclusion_of(:attr).in_array(%w(one two))
|
||||
end
|
||||
|
||||
it "accepts with correct array" do
|
||||
@model.should ensure_inclusion_of(:attr).in_array(%w(one two))
|
||||
it 'rejects when only part of array matches' do
|
||||
validating_inclusion(:in => %w(one two)).should_not
|
||||
ensure_inclusion_of(:attr).in_array(%w(one wrong_value))
|
||||
end
|
||||
|
||||
it "rejects when only part of array matches" do
|
||||
@model.should_not ensure_inclusion_of(:attr).in_array(%w(one wrong_value))
|
||||
it 'rejects when array does not match at all' do
|
||||
validating_inclusion(:in => %w(one two)).should_not
|
||||
ensure_inclusion_of(:attr).in_array(%w(cat dog))
|
||||
end
|
||||
|
||||
it "rejects when array doesn't match at all" do
|
||||
@model.should_not ensure_inclusion_of(:attr).in_array(%w(cat dog))
|
||||
it 'has correct description' do
|
||||
ensure_inclusion_of(:attr).in_array([true, "dog"]).description.should ==
|
||||
'ensure inclusion of attr in [true, "dog"]'
|
||||
end
|
||||
|
||||
it "has correct description" do
|
||||
ensure_inclusion_of(:attr).in_array([true, 'dog']).description.should == 'ensure inclusion of attr in [true, "dog"]'
|
||||
it 'rejects allow_blank' do
|
||||
validating_inclusion(:in => %w(one two)).should_not
|
||||
ensure_inclusion_of(:attr).in_array(%w(one two)).allow_blank(true)
|
||||
end
|
||||
|
||||
it "rejects allow_blank" do
|
||||
@model.should_not ensure_inclusion_of(:attr).in_array(['one', 'two']).allow_blank(true)
|
||||
@model.should ensure_inclusion_of(:attr).in_array(['one', 'two']).allow_blank(false)
|
||||
it 'accepts allow_blank(false)' do
|
||||
validating_inclusion(:in => %w(one two)).should
|
||||
ensure_inclusion_of(:attr).in_array(%w(one two)).allow_blank(false)
|
||||
end
|
||||
|
||||
it "rejects allow_nil" do
|
||||
@model.should_not ensure_inclusion_of(:attr).in_array(['one', 'two']).allow_nil(true)
|
||||
@model.should ensure_inclusion_of(:attr).in_array(['one', 'two']).allow_nil(false)
|
||||
it 'rejects allow_nil' do
|
||||
validating_inclusion(:in => %w(one two)).should_not
|
||||
ensure_inclusion_of(:attr).in_array(%w(one two)).allow_nil(true)
|
||||
end
|
||||
|
||||
it 'accepts allow_nil(false)' do
|
||||
validating_inclusion(:in => %w(one two)).should
|
||||
ensure_inclusion_of(:attr).in_array(%w(one two)).allow_nil(false)
|
||||
end
|
||||
end
|
||||
|
||||
context "allowed blank and allowed nil" do
|
||||
before do
|
||||
@model = define_model(:example, :attr => :string) do
|
||||
validates_inclusion_of :attr, :in => %w(one two), :allow_blank => true, :allow_nil => true
|
||||
end.new
|
||||
context 'with allowed blank and allowed nil' do
|
||||
it 'accepts allow_blank' do
|
||||
validating_inclusion(:in => %w(one two), :allow_blank => true).should
|
||||
ensure_inclusion_of(:attr).in_array(%w(one two)).allow_blank
|
||||
end
|
||||
|
||||
it "allows allow_blank" do
|
||||
@model.should ensure_inclusion_of(:attr).in_array(['one', 'two']).allow_blank(true)
|
||||
@model.should ensure_inclusion_of(:attr).in_array(['one', 'two']).allow_blank()
|
||||
@model.should_not ensure_inclusion_of(:attr).in_array(['one', 'two']).allow_blank(false)
|
||||
it 'rejects allow_blank(false)' do
|
||||
validating_inclusion(:in => %w(one two), :allow_blank => true).should_not
|
||||
ensure_inclusion_of(:attr).in_array(%w(one two)).allow_blank(false)
|
||||
end
|
||||
|
||||
it "allows allow_nil" do
|
||||
@model.should ensure_inclusion_of(:attr).in_array(['one', 'two']).allow_nil(true)
|
||||
@model.should ensure_inclusion_of(:attr).in_array(['one', 'two']).allow_nil()
|
||||
@model.should_not ensure_inclusion_of(:attr).in_array(['one', 'two']).allow_nil(false)
|
||||
it 'accepts allow_nil' do
|
||||
validating_inclusion(:in => %w(one two), :allow_nil => true).should
|
||||
ensure_inclusion_of(:attr).in_array(%w(one two)).allow_nil
|
||||
end
|
||||
|
||||
it 'rejects allow_nil' do
|
||||
validating_inclusion(:in => %w(one two), :allow_nil => true).should_not
|
||||
ensure_inclusion_of(:attr).in_array(%w(one two)).allow_nil(false)
|
||||
end
|
||||
end
|
||||
|
||||
context "an attribute allowing some blank values but not others" do
|
||||
before do
|
||||
@model = define_model(:example, :attr => :string) do
|
||||
validates_inclusion_of :attr, :in => ['one', 'two', '']
|
||||
end.new
|
||||
end
|
||||
|
||||
it "rejects allow_blank" do
|
||||
@model.should_not ensure_inclusion_of(:attr).in_array(['one', 'two', '']).allow_blank(true)
|
||||
@model.should ensure_inclusion_of(:attr).in_array(['one', 'two', '']).allow_blank(false)
|
||||
context 'an attribute allowing some blank values but not others' do
|
||||
it 'rejects allow_blank' do
|
||||
validating_inclusion(:in => ['one', 'two', '']).should_not
|
||||
ensure_inclusion_of(:attr).in_array(['one', 'two', '']).allow_blank(true)
|
||||
end
|
||||
end
|
||||
|
||||
if Rails::VERSION::STRING.to_f >= 3.2
|
||||
context "a strict attribute which must be included in a range" do
|
||||
before do
|
||||
@model = define_model(:example, :attr => :integer) do
|
||||
validates_inclusion_of :attr, :in => 2..5, :strict => true
|
||||
end.new
|
||||
if active_model_3_2?
|
||||
context 'a strict attribute which must be included in a range' do
|
||||
it 'accepts ensuring the correct range' do
|
||||
validating_inclusion(:in => 2..5, :strict => true).should
|
||||
ensure_inclusion_of(:attr).in_range(2..5).strict
|
||||
end
|
||||
|
||||
it "should accept ensuring the correct range" do
|
||||
@model.should ensure_inclusion_of(:attr).in_range(2..5).strict
|
||||
end
|
||||
|
||||
it "should not accept ensuring another range" do
|
||||
@model.should_not ensure_inclusion_of(:attr).in_range(2..6).strict
|
||||
it 'rejects ensuring another range' do
|
||||
validating_inclusion(:in => 2..5, :strict => true).should_not
|
||||
ensure_inclusion_of(:attr).in_range(2..6).strict
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def validating_inclusion(options)
|
||||
define_model(:example, :attr => :integer) do
|
||||
validates_inclusion_of :attr, options
|
||||
end.new
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,138 +1,112 @@
|
|||
require 'spec_helper'
|
||||
|
||||
describe Shoulda::Matchers::ActiveModel::EnsureLengthOfMatcher do
|
||||
|
||||
context "an attribute with a non-zero minimum length validation" do
|
||||
before do
|
||||
@model = define_model(:example, :attr => :string) do
|
||||
validates_length_of :attr, :minimum => 4
|
||||
end.new
|
||||
context 'an attribute with a non-zero minimum length validation' do
|
||||
it 'accepts ensuring the correct minimum length' do
|
||||
validating_length(:minimum => 4).should
|
||||
ensure_length_of(:attr).is_at_least(4)
|
||||
end
|
||||
|
||||
it "should accept ensuring the correct minimum length" do
|
||||
@model.should ensure_length_of(:attr).is_at_least(4)
|
||||
it 'rejects ensuring a lower minimum length with any message' do
|
||||
validating_length(:minimum => 4).should_not
|
||||
ensure_length_of(:attr).is_at_least(3).with_short_message(/.*/)
|
||||
end
|
||||
|
||||
it "should reject ensuring a lower minimum length with any message" do
|
||||
@model.should_not ensure_length_of(:attr).is_at_least(3).with_short_message(/.*/)
|
||||
it 'rejects ensuring a higher minimum length with any message' do
|
||||
validating_length(:minimum => 4).should_not
|
||||
ensure_length_of(:attr).is_at_least(5).with_short_message(/.*/)
|
||||
end
|
||||
|
||||
it "should reject ensuring a higher minimum length with any message" do
|
||||
@model.should_not ensure_length_of(:attr).is_at_least(5).with_short_message(/.*/)
|
||||
end
|
||||
|
||||
it "should not override the default message with a blank" do
|
||||
@model.should ensure_length_of(:attr).is_at_least(4).with_short_message(nil)
|
||||
it 'does not override the default message with a blank' do
|
||||
validating_length(:minimum => 4).should
|
||||
ensure_length_of(:attr).is_at_least(4).with_short_message(nil)
|
||||
end
|
||||
end
|
||||
|
||||
context "an attribute with a minimum length validation of 0" do
|
||||
before do
|
||||
@model = define_model(:example, :attr => :string) do
|
||||
validates_length_of :attr, :minimum => 0
|
||||
end.new
|
||||
context 'an attribute with a minimum length validation of 0' do
|
||||
it 'accepts ensuring the correct minimum length' do
|
||||
validating_length(:minimum => 0).should
|
||||
ensure_length_of(:attr).is_at_least(0) end
|
||||
end
|
||||
|
||||
context 'an attribute with a maximum length' do
|
||||
it 'accepts ensuring the correct maximum length' do
|
||||
validating_length(:maximum => 4).should
|
||||
ensure_length_of(:attr).is_at_most(4)
|
||||
end
|
||||
|
||||
it "should accept ensuring the correct minimum length" do
|
||||
@model.should ensure_length_of(:attr).is_at_least(0)
|
||||
it 'rejects ensuring a lower maximum length with any message' do
|
||||
validating_length(:maximum => 4).should_not
|
||||
ensure_length_of(:attr).is_at_most(3).with_long_message(/.*/)
|
||||
end
|
||||
|
||||
it 'rejects ensuring a higher maximum length with any message' do
|
||||
validating_length(:maximum => 4).should_not
|
||||
ensure_length_of(:attr).is_at_most(5).with_long_message(/.*/)
|
||||
end
|
||||
|
||||
it 'does not override the default message with a blank' do
|
||||
validating_length(:maximum => 4).should
|
||||
ensure_length_of(:attr).is_at_most(4).with_long_message(nil)
|
||||
end
|
||||
end
|
||||
|
||||
context "an attribute with a maximum length" do
|
||||
before do
|
||||
@model = define_model(:example, :attr => :string) do
|
||||
validates_length_of :attr, :maximum => 4
|
||||
end.new
|
||||
context 'an attribute with a required exact length' do
|
||||
it 'accepts ensuring the correct length' do
|
||||
validating_length(:is => 4).should ensure_length_of(:attr).is_equal_to(4)
|
||||
end
|
||||
|
||||
it "should accept ensuring the correct maximum length" do
|
||||
@model.should ensure_length_of(:attr).is_at_most(4)
|
||||
it 'rejects ensuring a lower maximum length with any message' do
|
||||
validating_length(:is => 4).should_not
|
||||
ensure_length_of(:attr).is_equal_to(3).with_message(/.*/)
|
||||
end
|
||||
|
||||
it "should reject ensuring a lower maximum length with any message" do
|
||||
@model.should_not ensure_length_of(:attr).is_at_most(3).with_long_message(/.*/)
|
||||
it 'rejects ensuring a higher maximum length with any message' do
|
||||
validating_length(:is => 4).should_not
|
||||
ensure_length_of(:attr).is_equal_to(5).with_message(/.*/)
|
||||
end
|
||||
|
||||
it "should reject ensuring a higher maximum length with any message" do
|
||||
@model.should_not ensure_length_of(:attr).is_at_most(5).with_long_message(/.*/)
|
||||
end
|
||||
|
||||
it "should not override the default message with a blank" do
|
||||
@model.should ensure_length_of(:attr).is_at_most(4).with_long_message(nil)
|
||||
it 'does not override the default message with a blank' do
|
||||
validating_length(:is => 4).should
|
||||
ensure_length_of(:attr).is_equal_to(4).with_message(nil)
|
||||
end
|
||||
end
|
||||
|
||||
context "an attribute with a required exact length" do
|
||||
before do
|
||||
@model = define_model(:example, :attr => :string) do
|
||||
validates_length_of :attr, :is => 4
|
||||
end.new
|
||||
end
|
||||
|
||||
it "should accept ensuring the correct length" do
|
||||
@model.should ensure_length_of(:attr).is_equal_to(4)
|
||||
end
|
||||
|
||||
it "should reject ensuring a lower maximum length with any message" do
|
||||
@model.should_not ensure_length_of(:attr).is_equal_to(3).with_message(/.*/)
|
||||
end
|
||||
|
||||
it "should reject ensuring a higher maximum length with any message" do
|
||||
@model.should_not ensure_length_of(:attr).is_equal_to(5).with_message(/.*/)
|
||||
end
|
||||
|
||||
it "should not override the default message with a blank" do
|
||||
@model.should ensure_length_of(:attr).is_equal_to(4).with_message(nil)
|
||||
end
|
||||
end
|
||||
|
||||
context "an attribute with a required exact length and another validation" do
|
||||
before do
|
||||
@model = define_model(:example, :attr => :string) do
|
||||
context 'an attribute with a required exact length and another validation' do
|
||||
it 'accepts ensuring the correct length' do
|
||||
model = define_model(:example, :attr => :string) do
|
||||
validates_length_of :attr, :is => 4
|
||||
validates_numericality_of :attr
|
||||
end.new
|
||||
end
|
||||
|
||||
it "should accept ensuring the correct length" do
|
||||
@model.should ensure_length_of(:attr).is_equal_to(4)
|
||||
model.should ensure_length_of(:attr).is_equal_to(4)
|
||||
end
|
||||
end
|
||||
|
||||
context "an attribute with a custom minimum length validation" do
|
||||
before do
|
||||
@model = define_model(:example, :attr => :string) do
|
||||
validates_length_of :attr, :minimum => 4, :too_short => 'short'
|
||||
end.new
|
||||
end
|
||||
|
||||
it "should accept ensuring the correct minimum length" do
|
||||
@model.should ensure_length_of(:attr).is_at_least(4).with_short_message(/short/)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
context "an attribute with a custom maximum length validation" do
|
||||
before do
|
||||
@model = define_model(:example, :attr => :string) do
|
||||
validates_length_of :attr, :maximum => 4, :too_long => 'long'
|
||||
end.new
|
||||
end
|
||||
|
||||
it "should accept ensuring the correct minimum length" do
|
||||
@model.should ensure_length_of(:attr).is_at_most(4).with_long_message(/long/)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
context "an attribute without a length validation" do
|
||||
before do
|
||||
@model = define_model(:example, :attr => :string).new
|
||||
end
|
||||
|
||||
it "should reject ensuring a minimum length" do
|
||||
@model.should_not ensure_length_of(:attr).is_at_least(1)
|
||||
context 'an attribute with a custom minimum length validation' do
|
||||
it 'accepts ensuring the correct minimum length' do
|
||||
validating_length(:minimum => 4, :too_short => 'foobar').should
|
||||
ensure_length_of(:attr).is_at_least(4).with_short_message(/foo/)
|
||||
end
|
||||
end
|
||||
|
||||
context 'an attribute with a custom maximum length validation' do
|
||||
it 'accepts ensuring the correct minimum length' do
|
||||
validating_length(:maximum => 4, :too_long => 'foobar').should
|
||||
ensure_length_of(:attr).is_at_most(4).with_long_message(/foo/)
|
||||
end
|
||||
end
|
||||
|
||||
context 'an attribute without a length validation' do
|
||||
it 'rejects ensuring a minimum length' do
|
||||
define_model(:example, :attr => :string).new.should_not
|
||||
ensure_length_of(:attr).is_at_least(1)
|
||||
end
|
||||
end
|
||||
|
||||
def validating_length(options = {})
|
||||
define_model(:example, :attr => :string) do
|
||||
validates_length_of :attr, options
|
||||
end.new
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
require 'spec_helper'
|
||||
|
||||
describe Shoulda::Matchers::ActiveModel::ExceptionMessageFinder do
|
||||
if Rails::VERSION::STRING.to_f >= 3.2
|
||||
if active_model_3_2?
|
||||
context '#allow_description' do
|
||||
it 'describes its attribute' do
|
||||
finder = build_finder(:attribute => :attr)
|
||||
|
||||
description = finder.allow_description('allowed values')
|
||||
|
||||
description.should == "doesn't raise when attr is set to allowed values"
|
||||
description.should == %q(doesn't raise when attr is set to allowed values)
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -1,129 +1,140 @@
|
|||
# encoding: UTF-8
|
||||
require "spec_helper"
|
||||
|
||||
def store_translations(options = {:without => []})
|
||||
options[:without] = Array.wrap(options[:without] || [])
|
||||
|
||||
translations = {
|
||||
:activerecord => {
|
||||
:errors => {
|
||||
:models => {
|
||||
:example => {
|
||||
:attributes => {
|
||||
:attr => {}
|
||||
}
|
||||
}
|
||||
},
|
||||
:messages => {}
|
||||
}
|
||||
},
|
||||
:errors => {
|
||||
:attributes => {
|
||||
:attr => {}
|
||||
},
|
||||
:messages => {}
|
||||
}
|
||||
}
|
||||
|
||||
unless options[:without].include?(:model_attribute)
|
||||
translations[:activerecord][:errors][:models][:example][:attributes][:attr][:blank] = "Don't you do that to me!"
|
||||
translations[:activerecord][:errors][:models][:example][:attributes][:attr][:wrong_length] = "Don't you do that to me!"
|
||||
end
|
||||
|
||||
unless options[:without].include?(:model)
|
||||
translations[:activerecord][:errors][:models][:example][:blank] = 'Give it one more try!'
|
||||
translations[:activerecord][:errors][:models][:example][:wrong_length] = 'Give it one more try!'
|
||||
end
|
||||
|
||||
unless options[:without].include?(:message)
|
||||
translations[:activerecord][:errors][:messages][:blank] = 'Oh no!'
|
||||
translations[:activerecord][:errors][:messages][:wrong_length] = 'Oh no!'
|
||||
end
|
||||
|
||||
unless options[:without].include?(:attribute)
|
||||
translations[:errors][:attributes][:attr][:blank] = 'Seriously?'
|
||||
translations[:errors][:attributes][:attr][:wrong_length] = 'Seriously?'
|
||||
end
|
||||
|
||||
I18n.backend.store_translations(:en, translations)
|
||||
end
|
||||
require 'spec_helper'
|
||||
|
||||
describe Shoulda::Matchers::ActiveModel::Helpers do
|
||||
include Shoulda::Matchers::ActiveModel
|
||||
after { I18n.backend.reload! }
|
||||
|
||||
describe "default_error_message" do
|
||||
before do
|
||||
define_model :example, :attr => :string do
|
||||
validates_presence_of :attr
|
||||
validates_length_of :attr, :is => 40, :allow_blank => true
|
||||
end
|
||||
@model = Example.new
|
||||
end
|
||||
|
||||
after { I18n.backend.reload! }
|
||||
|
||||
context "if the translation for the model attribute’s error exists" do
|
||||
it "provides the right error message for validate_presence_of" do
|
||||
describe 'default_error_message' do
|
||||
context 'if the translation for the model attribute’s error exists' do
|
||||
it 'provides the right error message for validate_presence_of' do
|
||||
store_translations
|
||||
@model.should validate_presence_of(:attr)
|
||||
|
||||
assert_presence_validation_has_correct_message
|
||||
end
|
||||
|
||||
it "provides the right error message for validates_length_of" do
|
||||
it 'provides the right error message for validates_length_of' do
|
||||
store_translations
|
||||
@model.should ensure_length_of(:attr).is_equal_to(40)
|
||||
|
||||
assert_length_validation_has_correct_message
|
||||
end
|
||||
end
|
||||
|
||||
context "if no translation for the model attribute’s error exists" do
|
||||
context "and the translation for the model’s error exists" do
|
||||
it "provides the right error message for validate_presence_of" do
|
||||
context 'if no translation for the model attribute’s error exists' do
|
||||
context 'and the translation for the model’s error exists' do
|
||||
it 'provides the right error message for validate_presence_of' do
|
||||
store_translations(:without => :model_attribute)
|
||||
@model.should validate_presence_of(:attr)
|
||||
|
||||
assert_presence_validation_has_correct_message
|
||||
end
|
||||
|
||||
it "provides the right error message for validates_length_of" do
|
||||
it 'provides the right error message for validates_length_of' do
|
||||
store_translations(:without => :model_attribute)
|
||||
@model.should ensure_length_of(:attr).is_equal_to(40)
|
||||
|
||||
assert_length_validation_has_correct_message
|
||||
end
|
||||
end
|
||||
|
||||
context "and no translation for the model’s error exists" do
|
||||
context "and the translation for the message exists" do
|
||||
it "provides the right error message for validate_presence_of" do
|
||||
context 'and no translation for the model’s error exists' do
|
||||
context 'and the translation for the message exists' do
|
||||
it 'provides the right error message for validate_presence_of' do
|
||||
store_translations(:without => [:model_attribute, :model])
|
||||
@model.should validate_presence_of(:attr)
|
||||
|
||||
assert_presence_validation_has_correct_message
|
||||
end
|
||||
|
||||
it "provides the right error message for validates_length_of" do
|
||||
it 'provides the right error message for validates_length_of' do
|
||||
store_translations(:without => [:model_attribute, :model])
|
||||
@model.should ensure_length_of(:attr).is_equal_to(40)
|
||||
|
||||
assert_length_validation_has_correct_message
|
||||
end
|
||||
end
|
||||
|
||||
context "and no translation for the message exists" do
|
||||
context "and the translation for the attribute exists" do
|
||||
it "provides the right error message for validate_presence_of" do
|
||||
context 'and no translation for the message exists' do
|
||||
context 'and the translation for the attribute exists' do
|
||||
it 'provides the right error message for validate_presence_of' do
|
||||
store_translations(:without => [:model_attribute, :model, :message])
|
||||
@model.should validate_presence_of(:attr)
|
||||
|
||||
assert_presence_validation_has_correct_message
|
||||
end
|
||||
|
||||
it "provides the right error message for validates_length_of" do
|
||||
it 'provides the right error message for validates_length_of' do
|
||||
store_translations(:without => [:model_attribute, :model, :message])
|
||||
@model.should ensure_length_of(:attr).is_equal_to(40)
|
||||
|
||||
assert_length_validation_has_correct_message
|
||||
end
|
||||
end
|
||||
|
||||
context "and no translation for the attribute exists" do
|
||||
it "provides the general error message for validate_presence_of" do
|
||||
@model.should validate_presence_of(:attr)
|
||||
context 'and no translation for the attribute exists' do
|
||||
it 'provides the general error message for validate_presence_of' do
|
||||
assert_presence_validation_has_correct_message
|
||||
end
|
||||
|
||||
it "provides the general error message for validates_length_of" do
|
||||
@model.should ensure_length_of(:attr).is_equal_to(40)
|
||||
it 'provides the general error message for validates_length_of' do
|
||||
assert_length_validation_has_correct_message
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def assert_presence_validation_has_correct_message
|
||||
define_model :example, :attr => :string do
|
||||
validates_presence_of :attr
|
||||
end.new.should validate_presence_of(:attr)
|
||||
end
|
||||
|
||||
def assert_length_validation_has_correct_message
|
||||
define_model :example, :attr => :string do
|
||||
validates_length_of :attr, :is => 40, :allow_blank => true
|
||||
end.new.should ensure_length_of(:attr).is_equal_to(40)
|
||||
end
|
||||
|
||||
def store_translations(options = {:without => []})
|
||||
options[:without] = Array.wrap(options[:without] || [])
|
||||
|
||||
translations = {
|
||||
:activerecord => {
|
||||
:errors => {
|
||||
:models => {
|
||||
:example => {
|
||||
:attributes => {
|
||||
:attr => {}
|
||||
}
|
||||
}
|
||||
},
|
||||
:messages => {}
|
||||
}
|
||||
},
|
||||
:errors => {
|
||||
:attributes => {
|
||||
:attr => {}
|
||||
},
|
||||
:messages => {}
|
||||
}
|
||||
}
|
||||
|
||||
unless options[:without].include?(:model_attribute)
|
||||
translations[:activerecord][:errors][:models][:example][:attributes][:attr][:blank] = "Don't you do that to me!"
|
||||
translations[:activerecord][:errors][:models][:example][:attributes][:attr][:wrong_length] = "Don't you do that to me!"
|
||||
end
|
||||
|
||||
unless options[:without].include?(:model)
|
||||
translations[:activerecord][:errors][:models][:example][:blank] = 'Give it one more try!'
|
||||
translations[:activerecord][:errors][:models][:example][:wrong_length] = 'Give it one more try!'
|
||||
end
|
||||
|
||||
unless options[:without].include?(:message)
|
||||
translations[:activerecord][:errors][:messages][:blank] = 'Oh no!'
|
||||
translations[:activerecord][:errors][:messages][:wrong_length] = 'Oh no!'
|
||||
end
|
||||
|
||||
unless options[:without].include?(:attribute)
|
||||
translations[:errors][:attributes][:attr][:blank] = 'Seriously?'
|
||||
translations[:errors][:attributes][:attr][:wrong_length] = 'Seriously?'
|
||||
end
|
||||
|
||||
I18n.backend.store_translations(:en, translations)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,69 +1,54 @@
|
|||
require 'spec_helper'
|
||||
|
||||
describe Shoulda::Matchers::ActiveModel::OnlyIntegerMatcher do
|
||||
context "given an attribute that only allows integer values" do
|
||||
before do
|
||||
define_model :example, :attr => :string do
|
||||
validates_numericality_of :attr, { :only_integer => true }
|
||||
end
|
||||
@model = Example.new
|
||||
context 'given an attribute that only allows integer values' do
|
||||
it 'matches' do
|
||||
only_integer.should new_matcher
|
||||
end
|
||||
|
||||
it "matches" do
|
||||
matcher = new_matcher(:attr)
|
||||
matcher.matches?(@model).should be_true
|
||||
it 'allows integer types' do
|
||||
new_matcher.allowed_types.should == 'integer'
|
||||
end
|
||||
|
||||
it "allows integer types" do
|
||||
matcher = new_matcher(:attr)
|
||||
matcher.allowed_types.should == "integer"
|
||||
end
|
||||
|
||||
it "returns itself when given a message" do
|
||||
matcher = new_matcher(:attr)
|
||||
matcher.with_message("some message").should == matcher
|
||||
it 'returns itself when given a message' do
|
||||
matcher = new_matcher
|
||||
matcher.with_message('some message').should == matcher
|
||||
end
|
||||
end
|
||||
|
||||
context "given an attribute that only allows integer values with a custom validation message" do
|
||||
before do
|
||||
define_model :example, :attr => :string do
|
||||
validates_numericality_of :attr, { :only_integer => true, :message => 'custom' }
|
||||
end
|
||||
@model = Example.new
|
||||
context 'given an attribute that only allows integer values with a custom validation message' do
|
||||
it 'only accepts integer values for that attribute with that message' do
|
||||
only_integer(:message => 'custom').should
|
||||
new_matcher.with_message(/custom/)
|
||||
end
|
||||
|
||||
it "should only allow integer values for that attribute with that message" do
|
||||
matcher = new_matcher(:attr)
|
||||
matcher.with_message(/custom/)
|
||||
matcher.matches?(@model).should be_true
|
||||
end
|
||||
|
||||
it "should not allow integer values for that attribute with another message" do
|
||||
matcher = new_matcher(:attr)
|
||||
matcher.with_message(/wrong/)
|
||||
matcher.matches?(@model).should be_false
|
||||
it 'rejects integer values for that attribute with another message' do
|
||||
only_integer(:message => 'custom').should_not
|
||||
new_matcher.with_message(/wrong/)
|
||||
end
|
||||
end
|
||||
|
||||
context "given an attribute that allows values other than integers" do
|
||||
before do
|
||||
@model = define_model(:example, :attr => :string).new
|
||||
context 'when the model does not have an only_integer validation' do
|
||||
it 'does not match' do
|
||||
define_model(:example, :attr => :string).new.should_not new_matcher
|
||||
end
|
||||
|
||||
it "does not match" do
|
||||
matcher = new_matcher(:attr)
|
||||
matcher.matches?(@model).should be_false
|
||||
end
|
||||
it 'fails with the ActiveRecord :not_an_integer message' do
|
||||
matcher = new_matcher
|
||||
|
||||
matcher.matches?(define_model(:example, :attr => :string).new)
|
||||
|
||||
it "should fail with the ActiveRecord :not_an_integer message" do
|
||||
matcher = new_matcher(:attr)
|
||||
matcher.matches?(@model)
|
||||
matcher.failure_message.should include 'Expected errors to include "must be an integer"'
|
||||
end
|
||||
end
|
||||
|
||||
def new_matcher(attribute)
|
||||
matcher = Shoulda::Matchers::ActiveModel::OnlyIntegerMatcher.new(attribute)
|
||||
def new_matcher
|
||||
described_class.new(:attr)
|
||||
end
|
||||
|
||||
def only_integer(options = {})
|
||||
define_model :example, :attr => :string do
|
||||
validates_numericality_of :attr, { :only_integer => true }.merge(options)
|
||||
end.new
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,43 +1,41 @@
|
|||
require 'spec_helper'
|
||||
|
||||
describe Shoulda::Matchers::ActiveModel::ValidateAcceptanceOfMatcher do
|
||||
|
||||
context "an attribute which must be accepted" do
|
||||
before do
|
||||
@model = define_model(:example, :attr => :string) do
|
||||
validates_acceptance_of :attr
|
||||
end.new
|
||||
context 'a model with an acceptance validation' do
|
||||
it 'accepts when the attributes match' do
|
||||
validating_acceptance.should matcher
|
||||
end
|
||||
|
||||
it "should require that attribute to be accepted" do
|
||||
@model.should validate_acceptance_of(:attr)
|
||||
end
|
||||
|
||||
it "should not overwrite the default message with nil" do
|
||||
@model.should validate_acceptance_of(:attr).with_message(nil)
|
||||
it 'does not overwrite the default message with nil' do
|
||||
validating_acceptance.should matcher.with_message(nil)
|
||||
end
|
||||
end
|
||||
|
||||
context "an attribute that does not need to be accepted" do
|
||||
before do
|
||||
@model = define_model(:example, :attr => :string).new
|
||||
end
|
||||
|
||||
it "should not require that attribute to be accepted" do
|
||||
@model.should_not validate_acceptance_of(:attr)
|
||||
context 'a model without an acceptance validation' do
|
||||
it 'rejects' do
|
||||
define_model(:example, :attr => :string).new.should_not matcher
|
||||
end
|
||||
end
|
||||
|
||||
context "an attribute which must be accepted with a custom message" do
|
||||
before do
|
||||
@model = define_model(:example, :attr => :string) do
|
||||
validates_acceptance_of :attr, :message => 'custom'
|
||||
end.new
|
||||
context 'an attribute which must be accepted with a custom message' do
|
||||
it 'accepts when the message matches' do
|
||||
validating_acceptance(:message => 'custom').should
|
||||
matcher.with_message(/custom/)
|
||||
end
|
||||
|
||||
it "should require that attribute to be accepted with that message" do
|
||||
@model.should validate_acceptance_of(:attr).with_message(/custom/)
|
||||
it 'rejects when the message does not match' do
|
||||
validating_acceptance(:message => 'custom').should_not
|
||||
matcher.with_message(/wrong/)
|
||||
end
|
||||
end
|
||||
|
||||
def matcher
|
||||
validate_acceptance_of(:attr)
|
||||
end
|
||||
|
||||
def validating_acceptance(options = {})
|
||||
define_model(:example, :attr => :string) do
|
||||
validates_acceptance_of :attr, options
|
||||
end.new
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,48 +1,41 @@
|
|||
require 'spec_helper'
|
||||
|
||||
describe Shoulda::Matchers::ActiveModel::ValidateConfirmationOfMatcher do
|
||||
|
||||
context "an attribute which needs confirmation" do
|
||||
before do
|
||||
define_model(:example, :attr => :string) do
|
||||
validates_confirmation_of :attr
|
||||
end
|
||||
@model = Example.new
|
||||
context 'a model with a confirmation validation' do
|
||||
it 'accepts' do
|
||||
validating_confirmation.should matcher
|
||||
end
|
||||
|
||||
it "should require confirmation of that attribute" do
|
||||
@model.should validate_confirmation_of(:attr)
|
||||
end
|
||||
|
||||
it "should not override the default message with a blank" do
|
||||
@model.should validate_confirmation_of(:attr).with_message(nil)
|
||||
it 'does not override the default message with a blank' do
|
||||
validating_confirmation.should matcher.with_message(nil)
|
||||
end
|
||||
end
|
||||
|
||||
context "an attribute which must be confirmed with a custom message" do
|
||||
before do
|
||||
define_model :example, :attr => :string do
|
||||
validates_confirmation_of :attr, :message => 'custom'
|
||||
end
|
||||
@model = Example.new
|
||||
end
|
||||
|
||||
it "should require confirmation of that attribute with that message" do
|
||||
@model.should validate_confirmation_of(:attr).with_message(/custom/)
|
||||
end
|
||||
|
||||
it "should not require confirmation of that attribute with another message" do
|
||||
@model.should_not validate_confirmation_of(:attr)
|
||||
context 'a model without a confirmation validation' do
|
||||
it 'rejects' do
|
||||
define_model(:example, :attr => :string).new.should_not matcher
|
||||
end
|
||||
end
|
||||
|
||||
context "an attribute which doesn't need confirmation" do
|
||||
before do
|
||||
@model = define_model(:example, :attr => :string).new
|
||||
context 'a confirmation validation with a custom message' do
|
||||
it 'accepts when the message matches' do
|
||||
validating_confirmation(:message => 'custom').should
|
||||
matcher.with_message(/custom/)
|
||||
end
|
||||
|
||||
it "should not require confirmation of that attribute" do
|
||||
@model.should_not validate_confirmation_of(:attr)
|
||||
it 'rejects when the messages do not match' do
|
||||
validating_confirmation(:message => 'custom').should_not
|
||||
matcher.with_message(/wrong/)
|
||||
end
|
||||
end
|
||||
|
||||
def matcher
|
||||
validate_confirmation_of(:attr)
|
||||
end
|
||||
|
||||
def validating_confirmation(options = {})
|
||||
define_model(:example, :attr => :string) do
|
||||
validates_confirmation_of :attr, options
|
||||
end.new
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,79 +1,82 @@
|
|||
require 'spec_helper'
|
||||
|
||||
describe Shoulda::Matchers::ActiveModel::ValidateFormatOfMatcher do
|
||||
context "a postal code" do
|
||||
before do
|
||||
define_model :example, :attr => :string do
|
||||
validates_format_of :attr, :with => /^\d{5}$/
|
||||
end
|
||||
@model = Example.new
|
||||
context 'a model with a format validation' do
|
||||
it 'accepts when format matches ' do
|
||||
validating_format(:with => /^\d{5}$/).should matcher.with('12345')
|
||||
end
|
||||
|
||||
it "is valid" do
|
||||
@model.should validate_format_of(:attr).with('12345')
|
||||
it 'rejects blank with should_not' do
|
||||
validating_format(:with => /^\d{5}$/).should_not matcher.with(' ')
|
||||
end
|
||||
|
||||
it "is not valid with blank" do
|
||||
@model.should_not validate_format_of(:attr).with(' ')
|
||||
@model.should validate_format_of(:attr).not_with(' ')
|
||||
it 'rejects blank with not_with' do
|
||||
validating_format(:with => /^\d{5}$/).should matcher.not_with(' ')
|
||||
end
|
||||
|
||||
it "is not valid with nil" do
|
||||
@model.should_not validate_format_of(:attr).with(nil)
|
||||
it 'rejects nil' do
|
||||
validating_format(:with => /^\d{5}$/).should_not matcher.with(nil)
|
||||
end
|
||||
|
||||
it "is not valid with alpha in zip" do
|
||||
@model.should_not validate_format_of(:attr).with('1234a')
|
||||
@model.should validate_format_of(:attr).not_with('1234a')
|
||||
it 'rejects a non-matching format with should_not' do
|
||||
validating_format(:with => /^\d{5}$/).should_not matcher.with('1234a')
|
||||
end
|
||||
|
||||
it "is not valid with too few digits" do
|
||||
@model.should_not validate_format_of(:attr).with('1234')
|
||||
@model.should validate_format_of(:attr).not_with('1234')
|
||||
it 'rejects a non-matching format with not_with' do
|
||||
validating_format(:with => /^\d{5}$/).should matcher.not_with('1234a')
|
||||
end
|
||||
|
||||
it "is not valid with too many digits" do
|
||||
@model.should_not validate_format_of(:attr).with('123456')
|
||||
@model.should validate_format_of(:attr).not_with('123456')
|
||||
end
|
||||
|
||||
it "raises error if you try to call both with and not_with" do
|
||||
expect { validate_format_of(:attr).not_with('123456').with('12345') }.
|
||||
to raise_error(RuntimeError)
|
||||
it 'raises an error if you try to call both with and not_with' do
|
||||
expect {
|
||||
validate_format_of(:attr).not_with('123456').with('12345')
|
||||
}.to raise_error(RuntimeError)
|
||||
end
|
||||
end
|
||||
|
||||
context "when allow_blank and allow_nil are set" do
|
||||
before do
|
||||
define_model :example, :attr => :string do
|
||||
validates_format_of :attr, :with => /^\d{5}$/, :allow_blank => true, :allow_nil => true
|
||||
end
|
||||
@model = Example.new
|
||||
end
|
||||
|
||||
it "is valid when attr is nil" do
|
||||
@model.should validate_format_of(:attr).with(nil)
|
||||
end
|
||||
|
||||
it "is valid when attr is blank" do
|
||||
@model.should validate_format_of(:attr).with(' ')
|
||||
end
|
||||
|
||||
describe "#allow_blank" do
|
||||
it "allows allow_blank" do
|
||||
@model.should validate_format_of(:attr).allow_blank
|
||||
@model.should validate_format_of(:attr).allow_blank(true)
|
||||
@model.should_not validate_format_of(:attr).allow_blank(false)
|
||||
end
|
||||
end
|
||||
|
||||
describe "#allow_nil" do
|
||||
it "allows allow_nil" do
|
||||
@model.should validate_format_of(:attr).allow_nil
|
||||
@model.should validate_format_of(:attr).allow_nil(true)
|
||||
@model.should_not validate_format_of(:attr).allow_nil(false)
|
||||
end
|
||||
context 'a model without a format validation' do
|
||||
it 'rejects' do
|
||||
define_model(:example, :attr => :string).new.should_not
|
||||
matcher.with('hello')
|
||||
end
|
||||
end
|
||||
|
||||
context 'when allow_blank or allow_nil are set' do
|
||||
it 'is valid when attr is nil' do
|
||||
validating_format(:with => /abc/, :allow_nil => true).should
|
||||
matcher.with(nil)
|
||||
end
|
||||
|
||||
it 'is valid when attr is blank' do
|
||||
validating_format(:with => /abc/, :allow_blank => true).should
|
||||
matcher.with(' ')
|
||||
end
|
||||
end
|
||||
|
||||
context '#allow_blank' do
|
||||
it 'accepts when allow_blank matches' do
|
||||
validating_format(:with => /abc/, :allow_blank => true).should
|
||||
matcher.allow_blank
|
||||
end
|
||||
|
||||
it 'rejects when allow_blank does not match' do
|
||||
validating_format(:with => /abc/, :allow_blank => false).should_not
|
||||
matcher.allow_blank
|
||||
end
|
||||
end
|
||||
|
||||
context '#allow_nil' do
|
||||
it 'accepts when allow_nil matches' do
|
||||
validating_format(:with => /abc/, :allow_nil => true).should
|
||||
matcher.allow_nil
|
||||
end
|
||||
|
||||
it 'rejects when allow_nil does not match' do
|
||||
validating_format(:with => /abc/, :allow_nil => false).should_not
|
||||
matcher.allow_nil
|
||||
end
|
||||
end
|
||||
|
||||
def matcher
|
||||
validate_format_of(:attr)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,112 +1,73 @@
|
|||
require 'spec_helper'
|
||||
|
||||
describe Shoulda::Matchers::ActiveModel::ValidateNumericalityOfMatcher do
|
||||
it "should state in its description that it allows only numeric values" do
|
||||
matcher = Shoulda::Matchers::ActiveModel::ValidateNumericalityOfMatcher.new(:attr)
|
||||
matcher.description.should == "only allow numeric values for attr"
|
||||
end
|
||||
|
||||
context "given a numeric attribute" do
|
||||
before do
|
||||
define_model :example, :attr => :string do
|
||||
validates_numericality_of :attr
|
||||
end
|
||||
@model = Example.new
|
||||
end
|
||||
|
||||
it "should only allow numeric values for that attribute" do
|
||||
matcher = new_matcher(:attr)
|
||||
matcher.matches?(@model).should be_true
|
||||
end
|
||||
|
||||
it "should not override the default message with a blank" do
|
||||
matcher = new_matcher(:attr)
|
||||
matcher.with_message(nil)
|
||||
matcher.matches?(@model).should be_true
|
||||
end
|
||||
|
||||
context "when asked to enforce integer values for that attribute" do
|
||||
it "should not match" do
|
||||
matcher = new_matcher(:attr)
|
||||
matcher.only_integer
|
||||
matcher.matches?(@model).should be_false
|
||||
end
|
||||
|
||||
it "should fail with the ActiveRecord :not_an_integer message" do
|
||||
matcher = new_matcher(:attr)
|
||||
matcher.only_integer
|
||||
matcher.matches?(@model)
|
||||
matcher.failure_message.should include 'Expected errors to include "must be an integer"'
|
||||
end
|
||||
context '#description' do
|
||||
it 'states that it allows only numeric values' do
|
||||
matcher.description.should == 'only allow numeric values for attr'
|
||||
end
|
||||
end
|
||||
|
||||
context "given a numeric attribute which must be integer" do
|
||||
before do
|
||||
define_model :example, :attr => :string do
|
||||
validates_numericality_of :attr, { :only_integer => true }
|
||||
end
|
||||
@model = Example.new
|
||||
context 'with a model with a numericality validation' do
|
||||
it 'accepts' do
|
||||
validating_numericality.should matcher
|
||||
end
|
||||
|
||||
it "allows integer values for that attribute" do
|
||||
matcher = new_matcher(:attr)
|
||||
matcher.only_integer
|
||||
matcher.matches?(@model).should be_true
|
||||
end
|
||||
|
||||
it "does not allow non-integer values for that attribute" do
|
||||
matcher = new_matcher(:attr)
|
||||
matcher.only_integer
|
||||
matcher.matches?(@model).should be_true
|
||||
end
|
||||
|
||||
it "should state in its description that it allows only integer values" do
|
||||
matcher = new_matcher(:attr)
|
||||
matcher.only_integer
|
||||
matcher.description.should == "only allow numeric, integer values for attr"
|
||||
it 'does not override the default message with a blank' do
|
||||
validating_numericality.should matcher.with_message(nil)
|
||||
end
|
||||
end
|
||||
|
||||
context "given a numeric attribute with a custom validation message" do
|
||||
before do
|
||||
define_model :example, :attr => :string do
|
||||
validates_numericality_of :attr, :message => 'custom'
|
||||
end
|
||||
@model = Example.new
|
||||
context 'with a model without a numericality validation' do
|
||||
it 'rejects' do
|
||||
define_model(:example, :attr => :string).new.should_not matcher
|
||||
end
|
||||
|
||||
it "should only allow numeric values for that attribute with that message" do
|
||||
matcher = new_matcher(:attr)
|
||||
matcher.with_message(/custom/)
|
||||
matcher.matches?(@model).should be_true
|
||||
end
|
||||
it 'rejects with the ActiveRecord :not_an_integer message' do
|
||||
the_matcher = matcher.only_integer
|
||||
|
||||
it "should not allow numeric values for that attribute with another message" do
|
||||
matcher = new_matcher(:attr)
|
||||
matcher.with_message(/wrong/)
|
||||
matcher.matches?(@model).should be_false
|
||||
the_matcher.matches?(define_model(:example, :attr => :string).new)
|
||||
|
||||
the_matcher.failure_message.should include 'Expected errors to include "must be an integer"'
|
||||
end
|
||||
end
|
||||
|
||||
context "given a non-numeric attribute" do
|
||||
before do
|
||||
@model = define_model(:example, :attr => :string).new
|
||||
context 'with the only_integer option' do
|
||||
it 'allows integer values for that attribute' do
|
||||
validating_numericality(:only_integer => true).should matcher.only_integer
|
||||
end
|
||||
|
||||
it "should not only allow numeric values for that attribute" do
|
||||
matcher = new_matcher(:attr)
|
||||
matcher.matches?(@model).should be_false
|
||||
it 'rejects when the model does not enforce integer values' do
|
||||
validating_numericality.should_not matcher.only_integer
|
||||
end
|
||||
|
||||
it "should fail with the ActiveRecord :not_a_number message" do
|
||||
matcher = new_matcher(:attr)
|
||||
matcher.matches?(@model)
|
||||
matcher.failure_message.should include 'Expected errors to include "is not a number"'
|
||||
it 'rejects with the ActiveRecord :not_an_integer message' do
|
||||
the_matcher = matcher.only_integer
|
||||
|
||||
the_matcher.matches?(validating_numericality)
|
||||
|
||||
the_matcher.failure_message.should include 'Expected errors to include "must be an integer"'
|
||||
end
|
||||
end
|
||||
|
||||
def new_matcher(attr)
|
||||
Shoulda::Matchers::ActiveModel::ValidateNumericalityOfMatcher.new(attr)
|
||||
context 'with a custom validation message' do
|
||||
it 'accepts when the messages match' do
|
||||
validating_numericality(:message => 'custom').should
|
||||
matcher.with_message(/custom/)
|
||||
end
|
||||
|
||||
it 'rejects when the messages do not match' do
|
||||
validating_numericality(:message => 'custom').should_not
|
||||
matcher.with_message(/wrong/)
|
||||
end
|
||||
end
|
||||
|
||||
def validating_numericality(options = {})
|
||||
define_model :example, :attr => :string do
|
||||
validates_numericality_of :attr, options
|
||||
end.new
|
||||
end
|
||||
|
||||
def matcher
|
||||
validate_numericality_of(:attr)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,135 +1,127 @@
|
|||
require 'spec_helper'
|
||||
|
||||
describe Shoulda::Matchers::ActiveModel::ValidatePresenceOfMatcher do
|
||||
context "a required attribute" do
|
||||
before do
|
||||
define_model :example, :attr => :string do
|
||||
validates_presence_of :attr
|
||||
end
|
||||
@model = Example.new
|
||||
context 'a model with a presence validation' do
|
||||
it 'accepts' do
|
||||
validating_presence.should matcher
|
||||
end
|
||||
|
||||
it "should require a value" do
|
||||
@model.should validate_presence_of(:attr)
|
||||
end
|
||||
|
||||
it "should not override the default message with a blank" do
|
||||
@model.should validate_presence_of(:attr).with_message(nil)
|
||||
it 'does not override the default message with a blank' do
|
||||
validating_presence.should matcher.with_message(nil)
|
||||
end
|
||||
end
|
||||
|
||||
context "a required attribute on a class using ActiveModel::Validations" do
|
||||
before do
|
||||
define_active_model_class("Example", :accessors => [:attr]) do
|
||||
validates_presence_of :attr
|
||||
end
|
||||
@model = Example.new
|
||||
end
|
||||
|
||||
it "should require a value" do
|
||||
@model.should validate_presence_of(:attr)
|
||||
end
|
||||
|
||||
it "should not override the default message with a blank" do
|
||||
@model.should validate_presence_of(:attr).with_message(nil)
|
||||
context 'a model without a presence validation' do
|
||||
it 'rejects' do
|
||||
define_model(:example, :attr => :string).new.should_not matcher
|
||||
end
|
||||
end
|
||||
|
||||
context "an optional attribute" do
|
||||
before do
|
||||
@model = define_model(:example, :attr => :string).new
|
||||
context 'an ActiveModel class with a presence validation' do
|
||||
it 'accepts' do
|
||||
active_model_validating_presence.should matcher
|
||||
end
|
||||
|
||||
it "should not require a value" do
|
||||
@model.should_not validate_presence_of(:attr)
|
||||
it 'does not override the default message with a blank' do
|
||||
active_model_validating_presence.should matcher.with_message(nil)
|
||||
end
|
||||
end
|
||||
|
||||
context "an optional attribute on a class using ActiveModel::Validations" do
|
||||
before do
|
||||
@model = define_active_model_class("Example", :accessors => [:attr]).new
|
||||
end
|
||||
|
||||
it "should not require a value" do
|
||||
@model.should_not validate_presence_of(:attr)
|
||||
context 'an ActiveModel class without a presence validation' do
|
||||
it 'rejects' do
|
||||
define_active_model_class('Example', :accessors => [:attr]).new.should_not
|
||||
matcher
|
||||
end
|
||||
end
|
||||
|
||||
context "a required has_many association" do
|
||||
before do
|
||||
define_model :child
|
||||
@model = define_model :parent do
|
||||
has_many :children
|
||||
validates_presence_of :children
|
||||
end.new
|
||||
end
|
||||
|
||||
it "should require the attribute to be set" do
|
||||
@model.should validate_presence_of(:children)
|
||||
context 'a has_many association with a presence validation' do
|
||||
it 'requires the attribute to be set' do
|
||||
has_many_children(:presence => true).should validate_presence_of(:children)
|
||||
end
|
||||
end
|
||||
|
||||
context "an optional has_many association" do
|
||||
before do
|
||||
define_model :child
|
||||
@model = define_model :parent do
|
||||
has_many :children
|
||||
end.new
|
||||
end
|
||||
|
||||
it "should not require the attribute to be set" do
|
||||
@model.should_not validate_presence_of(:children)
|
||||
context 'a has_many association without a presence validation' do
|
||||
it 'does not require the attribute to be set' do
|
||||
has_many_children(:presence => false).should_not
|
||||
validate_presence_of(:children)
|
||||
end
|
||||
end
|
||||
|
||||
context "a required has_and_belongs_to_many association" do
|
||||
context 'a required has_and_belongs_to_many association' do
|
||||
before do
|
||||
define_model :child
|
||||
@model = define_model :parent do
|
||||
has_and_belongs_to_many :children
|
||||
validates_presence_of :children
|
||||
end.new
|
||||
create_table "children_parents", :id => false do |t|
|
||||
create_table 'children_parents', :id => false do |t|
|
||||
t.integer :child_id
|
||||
t.integer :parent_id
|
||||
end
|
||||
end
|
||||
|
||||
it "should require the attribute to be set" do
|
||||
it 'accepts' do
|
||||
@model.should validate_presence_of(:children)
|
||||
end
|
||||
end
|
||||
|
||||
context "an optional has_and_belongs_to_many association" do
|
||||
context 'an optional has_and_belongs_to_many association' do
|
||||
before do
|
||||
define_model :child
|
||||
@model = define_model :parent do
|
||||
has_and_belongs_to_many :children
|
||||
end.new
|
||||
create_table "children_parents", :id => false do |t|
|
||||
create_table 'children_parents', :id => false do |t|
|
||||
t.integer :child_id
|
||||
t.integer :parent_id
|
||||
end
|
||||
end
|
||||
|
||||
it "should not require the attribute to be set" do
|
||||
it 'rejects' do
|
||||
@model.should_not validate_presence_of(:children)
|
||||
end
|
||||
end
|
||||
|
||||
if Rails::VERSION::STRING.to_f >= 3.2
|
||||
context "a strictly required attribute" do
|
||||
before do
|
||||
define_model :example, :attr => :string do
|
||||
validates_presence_of :attr, :strict => true
|
||||
end
|
||||
@model = Example.new
|
||||
if active_model_3_2?
|
||||
context 'a strictly required attribute' do
|
||||
it 'accepts when the :strict options match' do
|
||||
validating_presence(:strict => true).should matcher.strict
|
||||
end
|
||||
|
||||
it "should require a value" do
|
||||
@model.should validate_presence_of(:attr).strict
|
||||
it 'rejects when the :strict options do not match' do
|
||||
validating_presence(:strict => false).should_not matcher.strict
|
||||
end
|
||||
end
|
||||
|
||||
it 'does not override the default message with a blank' do
|
||||
validating_presence(:strict => true).should
|
||||
matcher.strict.with_message(nil)
|
||||
end
|
||||
end
|
||||
|
||||
def matcher
|
||||
validate_presence_of(:attr)
|
||||
end
|
||||
|
||||
def validating_presence(options = {})
|
||||
define_model :example, :attr => :string do
|
||||
validates_presence_of :attr, options
|
||||
end.new
|
||||
end
|
||||
|
||||
def active_model_validating_presence
|
||||
define_active_model_class('Example', :accessors => [:attr]) do
|
||||
validates_presence_of :attr
|
||||
end.new
|
||||
end
|
||||
|
||||
def has_many_children(options = {})
|
||||
define_model :child
|
||||
define_model :parent do
|
||||
has_many :children
|
||||
if options[:presence]
|
||||
validates_presence_of :children
|
||||
end
|
||||
end.new
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,154 +1,175 @@
|
|||
require 'spec_helper'
|
||||
|
||||
describe Shoulda::Matchers::ActiveModel::ValidateUniquenessOfMatcher do
|
||||
context "a unique attribute" do
|
||||
before do
|
||||
@model = define_model(:example, :attr => :string,
|
||||
:other => :integer) do
|
||||
context 'a model without a a uniqueness validation' do
|
||||
it 'rejects' do
|
||||
model = define_model(:example, :attr => :string) { attr_accessible :attr } .new
|
||||
Example.create!(:attr => 'value')
|
||||
model.should_not matcher
|
||||
end
|
||||
end
|
||||
|
||||
context 'a model with a uniqueness validation' do
|
||||
context 'with an existing record' do
|
||||
it 'requires a unique value for that attribute' do
|
||||
create_existing
|
||||
validating_uniqueness_with_other.should matcher
|
||||
end
|
||||
|
||||
it 'accepts when the subject is an existing record' do
|
||||
create_existing.should matcher
|
||||
end
|
||||
|
||||
it 'rejects when a scope is specified' do
|
||||
create_existing
|
||||
validating_uniqueness_with_other.should_not matcher.scoped_to(:other)
|
||||
end
|
||||
|
||||
def create_existing
|
||||
define_model_with_other
|
||||
Example.create!(:attr => 'value', :other => 1)
|
||||
end
|
||||
end
|
||||
|
||||
context 'without an existing record' do
|
||||
it 'does not require a created instance' do
|
||||
define_model_with_other
|
||||
Example.count.should == 0
|
||||
validating_uniqueness_with_other.should matcher
|
||||
end
|
||||
end
|
||||
|
||||
def define_model_with_other(options = {})
|
||||
@model ||= define_model(:example, :attr => :string, :other => :integer) do
|
||||
attr_accessible :attr, :other
|
||||
validates_uniqueness_of :attr
|
||||
end.new
|
||||
end
|
||||
|
||||
context "with an existing value" do
|
||||
before do
|
||||
@existing = Example.create!(:attr => 'value', :other => 1)
|
||||
end
|
||||
|
||||
it "should require a unique value for that attribute" do
|
||||
@model.should validate_uniqueness_of(:attr)
|
||||
end
|
||||
|
||||
it "should pass when the subject is an existing record" do
|
||||
@existing.should validate_uniqueness_of(:attr)
|
||||
end
|
||||
|
||||
it "should fail when a scope is specified" do
|
||||
@model.should_not validate_uniqueness_of(:attr).scoped_to(:other)
|
||||
validates_uniqueness_of :attr, options
|
||||
end
|
||||
end
|
||||
|
||||
context "without an existing value" do
|
||||
before do
|
||||
Example.find(:first).should be_nil
|
||||
@matcher = validate_uniqueness_of(:attr)
|
||||
end
|
||||
|
||||
it "does not not require a created instance" do
|
||||
@model.should @matcher
|
||||
end
|
||||
def validating_uniqueness_with_other(options = {})
|
||||
define_model_with_other.new
|
||||
end
|
||||
end
|
||||
|
||||
context "a unique attribute with a custom error and an existing value" do
|
||||
before do
|
||||
@model = define_model(:example, :attr => :string) do
|
||||
context 'a model with a uniqueness validation, a custom error, and an existing record' do
|
||||
it 'rejects when the actual message does not match the default message' do
|
||||
validating_uniqueness_with_existing_record(:message => 'Bad value').
|
||||
should_not matcher
|
||||
end
|
||||
|
||||
it 'rejects when the messages do not match' do
|
||||
validating_uniqueness_with_existing_record(:message => 'Bad value').
|
||||
should_not matcher.with_message(/abc/)
|
||||
end
|
||||
|
||||
it 'accepts when the messages match' do
|
||||
validating_uniqueness_with_existing_record(:message => 'Bad value').
|
||||
should matcher.with_message(/Bad/)
|
||||
end
|
||||
|
||||
def validating_uniqueness_with_existing_record(options = {})
|
||||
model = define_model(:example, :attr => :string) do
|
||||
attr_accessible :attr
|
||||
validates_uniqueness_of :attr, :message => 'Bad value'
|
||||
validates_uniqueness_of :attr, options
|
||||
end.new
|
||||
Example.create!(:attr => 'value')
|
||||
end
|
||||
|
||||
it "should fail when checking the default message" do
|
||||
@model.should_not validate_uniqueness_of(:attr)
|
||||
end
|
||||
|
||||
it "should fail when checking a message that doesn't match" do
|
||||
@model.should_not validate_uniqueness_of(:attr).with_message(/abc/i)
|
||||
end
|
||||
|
||||
it "should pass when checking a message that matches" do
|
||||
@model.should validate_uniqueness_of(:attr).with_message(/bad/i)
|
||||
model
|
||||
end
|
||||
end
|
||||
|
||||
context "a scoped unique attribute with an existing value" do
|
||||
before do
|
||||
@model = define_model(:example, :attr => :string,
|
||||
:scope1 => :integer,
|
||||
:scope2 => :integer,
|
||||
:other => :integer) do
|
||||
context 'a model with a scoped uniqueness validation with an existing value' do
|
||||
it 'accepts when the correct scope is specified' do
|
||||
validating_scoped_uniqueness([:scope1, :scope2]).should
|
||||
matcher.scoped_to(:scope1, :scope2)
|
||||
end
|
||||
|
||||
it 'accepts when the subject is an existing record' do
|
||||
define_scoped_model([:scope1, :scope2])
|
||||
create_existing_record.should matcher.scoped_to(:scope1, :scope2)
|
||||
end
|
||||
|
||||
it 'rejects when too narrow of a scope is specified' do
|
||||
validating_scoped_uniqueness([:scope1, :scope2]).should_not
|
||||
matcher.scoped_to(:scope1, :scope2, :other)
|
||||
end
|
||||
|
||||
it 'rejects when too broad of a scope is specified' do
|
||||
validating_scoped_uniqueness([:scope1, :scope2]).should_not
|
||||
matcher.scoped_to(:scope1)
|
||||
end
|
||||
|
||||
it 'rejects when a different scope is specified' do
|
||||
validating_scoped_uniqueness([:scope1]).should_not
|
||||
matcher.scoped_to(:other)
|
||||
end
|
||||
|
||||
it 'rejects when no scope is specified' do
|
||||
validating_scoped_uniqueness([:scope1]).should_not matcher
|
||||
end
|
||||
|
||||
it 'rejects when a non-existent attribute is specified as a scope' do
|
||||
validating_scoped_uniqueness([:scope1]).should_not
|
||||
matcher.scoped_to(:fake)
|
||||
end
|
||||
|
||||
def create_existing_record
|
||||
@existing ||= Example.create!(:attr => 'value', :scope1 => 1, :scope2 => 2, :other => 3)
|
||||
end
|
||||
|
||||
def define_scoped_model(scope)
|
||||
define_model(:example, :attr => :string, :scope1 => :integer,
|
||||
:scope2 => :integer, :other => :integer) do
|
||||
attr_accessible :attr, :scope1, :scope2, :other
|
||||
validates_uniqueness_of :attr, :scope => [:scope1, :scope2]
|
||||
end.new
|
||||
@existing = Example.create!(:attr => 'value', :scope1 => 1, :scope2 => 2, :other => 3)
|
||||
validates_uniqueness_of :attr, :scope => scope
|
||||
end
|
||||
end
|
||||
|
||||
it "should pass when the correct scope is specified" do
|
||||
@model.should validate_uniqueness_of(:attr).scoped_to(:scope1, :scope2)
|
||||
end
|
||||
|
||||
it "should pass when the subject is an existing record" do
|
||||
@existing.should validate_uniqueness_of(:attr).scoped_to(:scope1, :scope2)
|
||||
end
|
||||
|
||||
it "should fail when too narrow of a scope is specified" do
|
||||
@model.should_not validate_uniqueness_of(:attr).scoped_to(:scope1, :scope2, :other)
|
||||
end
|
||||
|
||||
it "should fail when too broad of a scope is specified" do
|
||||
@model.should_not validate_uniqueness_of(:attr).scoped_to(:scope1)
|
||||
end
|
||||
|
||||
it "should fail when a different scope is specified" do
|
||||
@model.should_not validate_uniqueness_of(:attr).scoped_to(:other)
|
||||
end
|
||||
|
||||
it "should fail when no scope is specified" do
|
||||
@model.should_not validate_uniqueness_of(:attr)
|
||||
end
|
||||
|
||||
it "should fail when a non-existent attribute is specified as a scope" do
|
||||
@model.should_not validate_uniqueness_of(:attr).scoped_to(:fake)
|
||||
def validating_scoped_uniqueness(scope)
|
||||
model = define_scoped_model(scope).new
|
||||
create_existing_record
|
||||
model
|
||||
end
|
||||
end
|
||||
|
||||
context "a non-unique attribute with an existing value" do
|
||||
before do
|
||||
@model = define_model(:example, :attr => :string) do
|
||||
attr_accessible :attr
|
||||
end.new
|
||||
Example.create!(:attr => 'value')
|
||||
context 'a model with a case-sensitive uniqueness validation on a string attribute and an existing record' do
|
||||
it 'accepts a case-sensitive value for that attribute' do
|
||||
case_sensitive_validation_with_existing_value(:string).should
|
||||
matcher
|
||||
end
|
||||
|
||||
it "should not require a unique value for that attribute" do
|
||||
@model.should_not validate_uniqueness_of(:attr)
|
||||
it 'rejects a case-insensitive value for that attribute' do
|
||||
case_sensitive_validation_with_existing_value(:string).should_not
|
||||
matcher.case_insensitive
|
||||
end
|
||||
end
|
||||
|
||||
context "a case sensitive unique attribute with an existing value" do
|
||||
before do
|
||||
@model = define_model(:example, :attr => :string) do
|
||||
attr_accessible :attr
|
||||
validates_uniqueness_of :attr, :case_sensitive => true
|
||||
end.new
|
||||
Example.create!(:attr => 'value')
|
||||
context 'a model with a case-sensitive uniqueness validation on an integer attribute with an existing value' do
|
||||
it 'accepts a case-insensitive value for that attribute' do
|
||||
case_sensitive_validation_with_existing_value(:integer).should
|
||||
matcher.case_insensitive
|
||||
end
|
||||
|
||||
it "should not require a unique, case-insensitive value for that attribute" do
|
||||
@model.should_not validate_uniqueness_of(:attr).case_insensitive
|
||||
end
|
||||
|
||||
it "should require a unique, case-sensitive value for that attribute" do
|
||||
@model.should validate_uniqueness_of(:attr)
|
||||
it 'accepts a case-sensitive value for that attribute' do
|
||||
case_sensitive_validation_with_existing_value(:integer).should matcher
|
||||
end
|
||||
end
|
||||
|
||||
context "a case sensitive unique integer attribute with an existing value" do
|
||||
before do
|
||||
@model = define_model(:example, :attr => :integer) do
|
||||
attr_accessible :attr
|
||||
validates_uniqueness_of :attr, :case_sensitive => true
|
||||
end.new
|
||||
def case_sensitive_validation_with_existing_value(attr_type)
|
||||
model = define_model(:example, :attr => attr_type) do
|
||||
attr_accessible :attr
|
||||
validates_uniqueness_of :attr, :case_sensitive => true
|
||||
end.new
|
||||
if attr_type == :string
|
||||
Example.create!(:attr => 'value')
|
||||
elsif attr_type == :integer
|
||||
Example.create!(:attr => 1)
|
||||
else
|
||||
raise 'Must be :string or :integer'
|
||||
end
|
||||
model
|
||||
end
|
||||
|
||||
it "should require a unique, case-insensitive value for that attribute" do
|
||||
@model.should validate_uniqueness_of(:attr).case_insensitive
|
||||
end
|
||||
|
||||
it "should require a unique, case-sensitive value for that attribute" do
|
||||
@model.should validate_uniqueness_of(:attr)
|
||||
end
|
||||
def matcher
|
||||
validate_uniqueness_of(:attr)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -51,7 +51,6 @@ describe Shoulda::Matchers::ActiveModel::ValidationMessageFinder do
|
|||
|
||||
context '#messages_description' do
|
||||
it 'describes errors for the given attribute' do
|
||||
value = 'xyz'
|
||||
finder = build_finder(
|
||||
:attribute => :attr,
|
||||
:format => /abc/,
|
||||
|
|
|
@ -1,84 +1,106 @@
|
|||
require 'spec_helper'
|
||||
|
||||
describe Shoulda::Matchers::ActiveRecord::AcceptNestedAttributesForMatcher do
|
||||
before do
|
||||
define_model :child, :parent_id => :integer
|
||||
define_model :parent do
|
||||
has_many :children
|
||||
end
|
||||
it 'accepts an existing declaration' do
|
||||
accepting_children.should accept_nested_attributes_for(:children)
|
||||
end
|
||||
|
||||
let(:parent) { Parent.new }
|
||||
let(:matcher) { accept_nested_attributes_for(:children) }
|
||||
it 'rejects a missing declaration' do
|
||||
matcher = children_matcher
|
||||
|
||||
it "should accept an existing declaration" do
|
||||
Parent.accepts_nested_attributes_for :children
|
||||
matcher.matches?(parent).should be_true
|
||||
matcher.matches?(rejecting_children).should be_false
|
||||
|
||||
matcher.failure_message.should == 'Expected Parent to accept nested attributes for children (is not declared)'
|
||||
end
|
||||
|
||||
it "should reject a missing declaration" do
|
||||
matcher.matches?(parent).should be_false
|
||||
matcher.failure_message.should == "Expected Parent to accept nested attributes for children (is not declared)"
|
||||
end
|
||||
context 'allow_destroy' do
|
||||
it 'accepts a valid truthy value' do
|
||||
matching = accepting_children(:allow_destroy => true)
|
||||
|
||||
context "allow_destroy" do
|
||||
it "should accept a valid truthy value" do
|
||||
Parent.accepts_nested_attributes_for :children, :allow_destroy => true
|
||||
matcher.allow_destroy(true).matches?(parent).should be_true
|
||||
matching.should children_matcher.allow_destroy(true)
|
||||
end
|
||||
|
||||
it "should accept a valid falsey value" do
|
||||
Parent.accepts_nested_attributes_for :children, :allow_destroy => false
|
||||
matcher.allow_destroy(false).matches?(parent).should be_true
|
||||
it 'accepts a valid falsey value' do
|
||||
matching = accepting_children(:allow_destroy => false)
|
||||
|
||||
matching.should children_matcher.allow_destroy(false)
|
||||
end
|
||||
|
||||
it "should reject an invalid truthy value" do
|
||||
Parent.accepts_nested_attributes_for :children, :allow_destroy => true
|
||||
matcher.allow_destroy(false).matches?(parent).should be_false
|
||||
it 'rejects an invalid truthy value' do
|
||||
matcher = children_matcher
|
||||
matching = accepting_children(:allow_destroy => true)
|
||||
|
||||
matcher.allow_destroy(false).matches?(matching).should be_false
|
||||
matcher.failure_message.should =~ /should not allow destroy/
|
||||
end
|
||||
|
||||
it "should reject an invalid falsey value" do
|
||||
Parent.accepts_nested_attributes_for :children, :allow_destroy => false
|
||||
matcher.allow_destroy(true).matches?(parent).should be_false
|
||||
it 'rejects an invalid falsey value' do
|
||||
matcher = children_matcher
|
||||
matching = accepting_children(:allow_destroy => false)
|
||||
|
||||
matcher.allow_destroy(true).matches?(matching).should be_false
|
||||
matcher.failure_message.should =~ /should allow destroy/
|
||||
end
|
||||
end
|
||||
|
||||
context "limit" do
|
||||
it "should accept a correct value" do
|
||||
Parent.accepts_nested_attributes_for :children, :limit => 3
|
||||
matcher.limit(3).matches?(parent).should be_true
|
||||
context 'limit' do
|
||||
it 'accepts a correct value' do
|
||||
accepting_children(:limit => 3).should children_matcher.limit(3)
|
||||
end
|
||||
|
||||
it "should reject a false value" do
|
||||
Parent.accepts_nested_attributes_for :children, :limit => 3
|
||||
matcher.limit(2).matches?(parent).should be_false
|
||||
it 'rejects a false value' do
|
||||
matcher = children_matcher
|
||||
rejecting = accepting_children(:limit => 3)
|
||||
|
||||
matcher.limit(2).matches?(rejecting).should be_false
|
||||
matcher.failure_message.should =~ /limit should be 2, got 3/
|
||||
end
|
||||
end
|
||||
|
||||
context "update_only" do
|
||||
it "should accept a valid truthy value" do
|
||||
Parent.accepts_nested_attributes_for :children, :update_only => true
|
||||
matcher.update_only(true).matches?(parent).should be_true
|
||||
context 'update_only' do
|
||||
it 'accepts a valid truthy value' do
|
||||
accepting_children(:update_only => true).should
|
||||
children_matcher.update_only(true)
|
||||
end
|
||||
|
||||
it "should accept a valid falsey value" do
|
||||
Parent.accepts_nested_attributes_for :children, :update_only => false
|
||||
matcher.update_only(false).matches?(parent).should be_true
|
||||
it 'accepts a valid falsey value' do
|
||||
accepting_children(:update_only => false).should
|
||||
children_matcher.update_only(false)
|
||||
end
|
||||
|
||||
it "should reject an invalid truthy value" do
|
||||
Parent.accepts_nested_attributes_for :children, :update_only => true
|
||||
matcher.update_only(false).matches?(parent).should be_false
|
||||
it 'rejects an invalid truthy value' do
|
||||
matcher = children_matcher.update_only(false)
|
||||
rejecting = accepting_children(:update_only => true)
|
||||
|
||||
matcher.matches?(rejecting).should be_false
|
||||
matcher.failure_message.should =~ /should not be update only/
|
||||
end
|
||||
|
||||
it "should reject an invalid falsey value" do
|
||||
Parent.accepts_nested_attributes_for :children, :update_only => false
|
||||
matcher.update_only(true).matches?(parent).should be_false
|
||||
it 'rejects an invalid falsey value' do
|
||||
matcher = children_matcher.update_only(true)
|
||||
rejecting = accepting_children(:update_only => false)
|
||||
|
||||
matcher.matches?(rejecting).should be_false
|
||||
matcher.failure_message.should =~ /should be update only/
|
||||
end
|
||||
end
|
||||
|
||||
def accepting_children(options = {})
|
||||
define_model :child, :parent_id => :integer
|
||||
define_model :parent do
|
||||
has_many :children
|
||||
accepts_nested_attributes_for :children, options
|
||||
end.new
|
||||
end
|
||||
|
||||
def children_matcher
|
||||
accept_nested_attributes_for(:children)
|
||||
end
|
||||
|
||||
def rejecting_children
|
||||
define_model :child, :parent_id => :integer
|
||||
define_model :parent do
|
||||
has_many :children
|
||||
end.new
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,210 +1,185 @@
|
|||
require 'spec_helper'
|
||||
|
||||
describe Shoulda::Matchers::ActiveRecord::AssociationMatcher do
|
||||
context "belong_to" do
|
||||
before do
|
||||
@matcher = belong_to(:parent)
|
||||
context 'belong_to' do
|
||||
it 'accepts a good association with the default foreign key' do
|
||||
belonging_to_parent.should belong_to(:parent)
|
||||
end
|
||||
|
||||
it "should accept a good association with the default foreign key" do
|
||||
define_model :parent
|
||||
define_model :child, :parent_id => :integer do
|
||||
belongs_to :parent
|
||||
end
|
||||
Child.new.should @matcher
|
||||
it 'rejects a nonexistent association' do
|
||||
define_model(:child).new.should_not belong_to(:parent)
|
||||
end
|
||||
|
||||
it "should reject a nonexistent association" do
|
||||
define_model :child
|
||||
Child.new.should_not @matcher
|
||||
end
|
||||
|
||||
it "should reject an association of the wrong type" do
|
||||
it 'rejects an association of the wrong type' do
|
||||
define_model :parent, :child_id => :integer
|
||||
child_class = define_model :child do
|
||||
has_one :parent
|
||||
end
|
||||
Child.new.should_not @matcher
|
||||
define_model(:child) { has_one :parent }.new.should_not belong_to(:parent)
|
||||
end
|
||||
|
||||
it "should reject an association that has a nonexistent foreign key" do
|
||||
it 'rejects an association that has a nonexistent foreign key' do
|
||||
define_model :parent
|
||||
define_model :child do
|
||||
belongs_to :parent
|
||||
end
|
||||
Child.new.should_not @matcher
|
||||
define_model(:child) { belongs_to :parent }.new.should_not belong_to(:parent)
|
||||
end
|
||||
|
||||
it "should accept an association with an existing custom foreign key" do
|
||||
it 'accepts an association with an existing custom foreign key' do
|
||||
define_model :parent
|
||||
define_model :child, :guardian_id => :integer do
|
||||
belongs_to :parent, :foreign_key => 'guardian_id'
|
||||
end
|
||||
Child.new.should @matcher
|
||||
|
||||
Child.new.should belong_to(:parent)
|
||||
end
|
||||
|
||||
it "should accept a polymorphic association" do
|
||||
define_model :child, :parent_type => :string,
|
||||
:parent_id => :integer do
|
||||
it 'accepts a polymorphic association' do
|
||||
define_model :child, :parent_type => :string, :parent_id => :integer do
|
||||
belongs_to :parent, :polymorphic => true
|
||||
end
|
||||
Child.new.should @matcher
|
||||
|
||||
Child.new.should belong_to(:parent)
|
||||
end
|
||||
|
||||
it "should accept an association with a valid :dependent option" do
|
||||
define_model :parent
|
||||
define_model :child, :parent_id => :integer do
|
||||
belongs_to :parent, :dependent => :destroy
|
||||
end
|
||||
Child.new.should @matcher.dependent(:destroy)
|
||||
it 'accepts an association with a valid :dependent option' do
|
||||
belonging_to_parent(:dependent => :destroy).should
|
||||
belong_to(:parent).dependent(:destroy)
|
||||
end
|
||||
|
||||
it "should reject an association with a bad :dependent option" do
|
||||
define_model :parent
|
||||
define_model :child, :parent_id => :integer do
|
||||
belongs_to :parent
|
||||
end
|
||||
Child.new.should_not @matcher.dependent(:destroy)
|
||||
it 'rejects an association with a bad :dependent option' do
|
||||
belonging_to_parent.should_not belong_to(:parent).dependent(:destroy)
|
||||
end
|
||||
|
||||
it "should accept an association with a valid :conditions option" do
|
||||
it 'accepts an association with a valid :conditions option' do
|
||||
define_model :parent, :adopter => :boolean
|
||||
define_model :child, :parent_id => :integer do
|
||||
belongs_to :parent, :conditions => { :adopter => true }
|
||||
end
|
||||
Child.new.should @matcher.conditions(:adopter => true)
|
||||
|
||||
Child.new.should belong_to(:parent).conditions(:adopter => true)
|
||||
end
|
||||
|
||||
it "should reject an association with a bad :conditions option" do
|
||||
it 'rejects an association with a bad :conditions option' do
|
||||
define_model :parent, :adopter => :boolean
|
||||
define_model :child, :parent_id => :integer do
|
||||
belongs_to :parent
|
||||
end
|
||||
Child.new.should_not @matcher.conditions(:adopter => true)
|
||||
|
||||
Child.new.should_not belong_to(:parent).conditions(:adopter => true)
|
||||
end
|
||||
|
||||
it "should accept an association with a valid :class_name option" do
|
||||
define_model :tree_parent, :adopter => :boolean
|
||||
it 'accepts an association with a valid :class_name option' do
|
||||
belonging_to_parent(:class_name => 'TreeParent').should
|
||||
belong_to(:parent).class_name('TreeParent')
|
||||
end
|
||||
|
||||
it 'rejects an association with a bad :class_name option' do
|
||||
belonging_to_parent(:class_name => 'TreeParent').should_not
|
||||
belong_to(:parent).class_name('TreeChild')
|
||||
end
|
||||
|
||||
context 'validate' do
|
||||
[false, true].each do |validate_value|
|
||||
context 'when the model has :validate => #{validate_value}' do
|
||||
it 'accepts a matching validate option' do
|
||||
belonging_to_parent(:validate => validate_value).should
|
||||
belong_to(:parent).validate(validate_value)
|
||||
end
|
||||
|
||||
it 'rejects a non-matching validate option' do
|
||||
belonging_to_parent(:validate => validate_value).should_not
|
||||
belong_to(:parent).validate(!validate_value)
|
||||
end
|
||||
|
||||
it 'defaults to validate(true)' do
|
||||
if validate_value
|
||||
belonging_to_parent(:validate => validate_value).should
|
||||
belong_to(:parent).validate
|
||||
else
|
||||
belonging_to_parent(:validate => validate_value).should_not
|
||||
belong_to(:parent).validate
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'an association without a :validate option' do
|
||||
it 'accepts validate(false)' do
|
||||
belonging_to_parent.should belong_to(:parent).validate(false)
|
||||
end
|
||||
|
||||
it 'rejects validate(true)' do
|
||||
belonging_to_parent.should_not belong_to(:parent).validate(true)
|
||||
end
|
||||
|
||||
it 'rejects validate()' do
|
||||
belonging_to_parent.should_not belong_to(:parent).validate
|
||||
end
|
||||
end
|
||||
|
||||
def belonging_to_parent(options = {})
|
||||
define_model :parent
|
||||
define_model :child, :parent_id => :integer do
|
||||
belongs_to :parent, :class_name => 'TreeParent'
|
||||
end
|
||||
Child.new.should @matcher.class_name('TreeParent')
|
||||
belongs_to :parent, options
|
||||
end.new
|
||||
end
|
||||
|
||||
it "should reject an association with a bad :class_name option" do
|
||||
define_model :parent, :adopter => :boolean
|
||||
define_model :child, :parent_id => :integer do
|
||||
belongs_to :parent
|
||||
end
|
||||
Child.new.should_not @matcher.class_name('TreeChild')
|
||||
end
|
||||
|
||||
context 'should accept an association with a false :validate option' do
|
||||
before do
|
||||
define_model :parent, :adopter => :boolean
|
||||
define_model :child, :parent_id => :integer do
|
||||
belongs_to :parent, :validate => false
|
||||
end
|
||||
end
|
||||
subject { Child.new }
|
||||
specify { subject.should @matcher.validate(false) }
|
||||
specify { subject.should_not @matcher.validate(true) }
|
||||
specify { subject.should_not @matcher.validate }
|
||||
end
|
||||
|
||||
context 'should accept an association with a true :validate option' do
|
||||
before do
|
||||
define_model :parent, :adopter => :boolean
|
||||
define_model :child, :parent_id => :integer do
|
||||
belongs_to :parent, :validate => true
|
||||
end
|
||||
end
|
||||
subject { Child.new }
|
||||
specify { subject.should_not @matcher.validate(false) }
|
||||
specify { subject.should @matcher.validate(true) }
|
||||
specify { subject.should @matcher.validate }
|
||||
end
|
||||
|
||||
context 'should accept an association without a :validate option' do
|
||||
before do
|
||||
define_model :parent, :adopter => :boolean
|
||||
define_model :child, :parent_id => :integer do
|
||||
belongs_to :parent
|
||||
end
|
||||
end
|
||||
subject { Child.new }
|
||||
specify { subject.should @matcher.validate(false) }
|
||||
specify { subject.should_not @matcher.validate(true) }
|
||||
specify { subject.should_not @matcher.validate }
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
context "have_many" do
|
||||
before do
|
||||
@matcher = have_many(:children)
|
||||
context 'have_many' do
|
||||
it 'accepts a valid association without any options' do
|
||||
having_many_children.should have_many(:children)
|
||||
end
|
||||
|
||||
it "should accept a valid association without any options" do
|
||||
define_model :child, :parent_id => :integer
|
||||
define_model :parent do
|
||||
has_many :children
|
||||
end
|
||||
Parent.new.should @matcher
|
||||
end
|
||||
|
||||
it "should accept a valid association with a :through option" do
|
||||
it 'accepts a valid association with a :through option' do
|
||||
define_model :child
|
||||
define_model :conception, :child_id => :integer,
|
||||
:parent_id => :integer do
|
||||
define_model :conception, :child_id => :integer,
|
||||
:parent_id => :integer do
|
||||
belongs_to :child
|
||||
end
|
||||
define_model :parent do
|
||||
has_many :conceptions
|
||||
has_many :children, :through => :conceptions
|
||||
end
|
||||
Parent.new.should @matcher
|
||||
Parent.new.should have_many(:children)
|
||||
end
|
||||
|
||||
it "should accept a valid association with an :as option" do
|
||||
define_model :child, :guardian_type => :string,
|
||||
:guardian_id => :integer
|
||||
it 'accepts a valid association with an :as option' do
|
||||
define_model :child, :guardian_type => :string, :guardian_id => :integer
|
||||
define_model :parent do
|
||||
has_many :children, :as => :guardian
|
||||
end
|
||||
Parent.new.should @matcher
|
||||
|
||||
Parent.new.should have_many(:children)
|
||||
end
|
||||
|
||||
it "should reject an association that has a nonexistent foreign key" do
|
||||
it 'rejects an association that has a nonexistent foreign key' do
|
||||
define_model :child
|
||||
define_model :parent do
|
||||
has_many :children
|
||||
end
|
||||
Parent.new.should_not @matcher
|
||||
|
||||
Parent.new.should_not have_many(:children)
|
||||
end
|
||||
|
||||
it "should reject an association with a bad :as option" do
|
||||
it 'rejects an association with a bad :as option' do
|
||||
define_model :child, :caretaker_type => :string,
|
||||
:caretaker_id => :integer
|
||||
:caretaker_id => :integer
|
||||
define_model :parent do
|
||||
has_many :children, :as => :guardian
|
||||
end
|
||||
Parent.new.should_not @matcher
|
||||
|
||||
Parent.new.should_not have_many(:children)
|
||||
end
|
||||
|
||||
it "should reject an association that has a bad :through option" do
|
||||
define_model :child, :parent_id => :integer
|
||||
define_model :parent do
|
||||
has_many :children
|
||||
end
|
||||
@matcher.through(:conceptions).matches?(Parent.new).should be_false
|
||||
@matcher.failure_message.should =~ /does not have any relationship to conceptions/
|
||||
it 'rejects an association that has a bad :through option' do
|
||||
matcher = have_many(:children).through(:conceptions)
|
||||
|
||||
matcher.matches?(having_many_children).should be_false
|
||||
|
||||
matcher.failure_message.should =~ /does not have any relationship to conceptions/
|
||||
end
|
||||
|
||||
it "should reject an association that has the wrong :through option" do
|
||||
it 'rejects an association that has the wrong :through option' do
|
||||
define_model :child
|
||||
define_model :conception, :child_id => :integer,
|
||||
:parent_id => :integer do
|
||||
define_model :conception, :child_id => :integer,
|
||||
:parent_id => :integer do
|
||||
belongs_to :child
|
||||
end
|
||||
define_model :parent do
|
||||
|
@ -212,246 +187,197 @@ describe Shoulda::Matchers::ActiveRecord::AssociationMatcher do
|
|||
has_many :relationships
|
||||
has_many :children, :through => :conceptions
|
||||
end
|
||||
@matcher.through(:relationships).matches?(Parent.new).should be_false
|
||||
@matcher.failure_message.should =~ /through relationships, but got it through conceptions/
|
||||
|
||||
matcher = have_many(:children).through(:relationships)
|
||||
matcher.matches?(Parent.new).should be_false
|
||||
matcher.failure_message.should =~ /through relationships, but got it through conceptions/
|
||||
end
|
||||
|
||||
it "should accept an association with a valid :dependent option" do
|
||||
define_model :child, :parent_id => :integer
|
||||
define_model :parent do
|
||||
has_many :children, :dependent => :destroy
|
||||
end
|
||||
Parent.new.should @matcher.dependent(:destroy)
|
||||
it 'accepts an association with a valid :dependent option' do
|
||||
having_many_children(:dependent => :destroy).should
|
||||
have_many(:children).dependent(:destroy)
|
||||
end
|
||||
|
||||
it "should reject an association with a bad :dependent option" do
|
||||
define_model :child, :parent_id => :integer
|
||||
define_model :parent do
|
||||
has_many :children
|
||||
end
|
||||
Parent.new.should_not @matcher.dependent(:destroy)
|
||||
it 'rejects an association with a bad :dependent option' do
|
||||
having_many_children.should_not have_many(:children).dependent(:destroy)
|
||||
end
|
||||
|
||||
it "should accept an association with a valid :order option" do
|
||||
define_model :child, :parent_id => :integer
|
||||
define_model :parent do
|
||||
has_many :children, :order => :id
|
||||
end
|
||||
Parent.new.should @matcher.order(:id)
|
||||
it 'accepts an association with a valid :order option' do
|
||||
having_many_children(:order => :id).should
|
||||
have_many(:children).order(:id)
|
||||
end
|
||||
|
||||
it "should reject an association with a bad :order option" do
|
||||
define_model :child, :parent_id => :integer
|
||||
define_model :parent do
|
||||
has_many :children
|
||||
end
|
||||
Parent.new.should_not @matcher.order(:id)
|
||||
it 'rejects an association with a bad :order option' do
|
||||
having_many_children.should_not have_many(:children).order(:id)
|
||||
end
|
||||
|
||||
it "should accept an association with a valid :conditions option" do
|
||||
it 'accepts an association with a valid :conditions option' do
|
||||
define_model :child, :parent_id => :integer, :adopted => :boolean
|
||||
define_model :parent do
|
||||
has_many :children, :conditions => { :adopted => true }
|
||||
end
|
||||
Parent.new.should @matcher.conditions({ :adopted => true })
|
||||
|
||||
Parent.new.should have_many(:children).conditions(:adopted => true)
|
||||
end
|
||||
|
||||
it "should reject an association with a bad :conditions option" do
|
||||
it 'rejects an association with a bad :conditions option' do
|
||||
define_model :child, :parent_id => :integer, :adopted => :boolean
|
||||
define_model :parent do
|
||||
has_many :children
|
||||
end
|
||||
Parent.new.should_not @matcher.conditions({ :adopted => true })
|
||||
|
||||
Parent.new.should_not have_many(:children).conditions(:adopted => true)
|
||||
end
|
||||
|
||||
it "should accept an association with a valid :class_name option" do
|
||||
define_model :node, :parent_id => :integer, :adopted => :boolean
|
||||
it 'accepts an association with a valid :class_name option' do
|
||||
define_model :node, :parent_id => :integer
|
||||
define_model :parent do
|
||||
has_many :children, :class_name => 'Node'
|
||||
end
|
||||
Parent.new.should @matcher.class_name('Node')
|
||||
|
||||
Parent.new.should have_many(:children).class_name('Node')
|
||||
end
|
||||
|
||||
it "should reject an association with a bad :class_name option" do
|
||||
define_model :child, :parent_id => :integer, :adopted => :boolean
|
||||
define_model :parent do
|
||||
has_many :children
|
||||
it 'rejects an association with a bad :class_name option' do
|
||||
having_many_children.should_not have_many(:children).class_name('Node')
|
||||
end
|
||||
|
||||
context 'validate' do
|
||||
it 'accepts when the :validate option matches' do
|
||||
having_many_children(:validate => false).should have_many(:children).validate(false)
|
||||
end
|
||||
Parent.new.should_not @matcher.class_name('Node')
|
||||
end
|
||||
|
||||
context 'should accept an association with a false :validate option' do
|
||||
before do
|
||||
define_model :child, :parent_id => :integer, :adopted => :boolean
|
||||
define_model :parent do
|
||||
has_many :children, :validate => false
|
||||
end
|
||||
it 'rejects when the :validate option does not match' do
|
||||
having_many_children(:validate => true).should_not have_many(:children).validate(false)
|
||||
end
|
||||
subject { Parent.new }
|
||||
specify { subject.should @matcher.validate(false) }
|
||||
specify { subject.should_not @matcher.validate(true) }
|
||||
specify { subject.should_not @matcher.validate }
|
||||
end
|
||||
|
||||
context 'should accept an association with a true :validate option' do
|
||||
before do
|
||||
define_model :child, :parent_id => :integer, :adopted => :boolean
|
||||
define_model :parent do
|
||||
has_many :children, :validate => true
|
||||
end
|
||||
it 'assumes validate() means validate(true)' do
|
||||
having_many_children(:validate => false).should_not
|
||||
have_many(:children).validate
|
||||
end
|
||||
subject { Parent.new }
|
||||
specify { subject.should_not @matcher.validate(false) }
|
||||
specify { subject.should @matcher.validate(true) }
|
||||
specify { subject.should @matcher.validate }
|
||||
end
|
||||
|
||||
context 'should accept an association without a :validate option' do
|
||||
before do
|
||||
define_model :child, :parent_id => :integer, :adopted => :boolean
|
||||
define_model :parent do
|
||||
has_many :children
|
||||
end
|
||||
it 'matches validate(false) to having no validate option specified' do
|
||||
having_many_children.should have_many(:children).validate(false)
|
||||
end
|
||||
subject { Parent.new }
|
||||
specify { subject.should @matcher.validate(false) }
|
||||
specify { subject.should_not @matcher.validate(true) }
|
||||
specify { subject.should_not @matcher.validate }
|
||||
end
|
||||
|
||||
it "should accept an association with a nonstandard reverse foreign key, using :inverse_of" do
|
||||
it 'accepts an association with a nonstandard reverse foreign key, using :inverse_of' do
|
||||
define_model :child, :ancestor_id => :integer do
|
||||
belongs_to :ancestor, :inverse_of => :children, :class_name => :Parent
|
||||
end
|
||||
define_model :parent do
|
||||
has_many :children, :inverse_of => :ancestor
|
||||
end
|
||||
Parent.new.should @matcher
|
||||
|
||||
Parent.new.should have_many(:children)
|
||||
end
|
||||
|
||||
it "should reject an association with a nonstandard reverse foreign key, if :inverse_of is not correct" do
|
||||
it 'rejects an association with a nonstandard reverse foreign key, if :inverse_of is not correct' do
|
||||
define_model :child, :mother_id => :integer do
|
||||
belongs_to :mother, :inverse_of => :children, :class_name => :Parent
|
||||
end
|
||||
define_model :parent do
|
||||
has_many :children, :inverse_of => :ancestor
|
||||
end
|
||||
Parent.new.should_not @matcher
|
||||
|
||||
Parent.new.should_not have_many(:children)
|
||||
end
|
||||
|
||||
def having_many_children(options = {})
|
||||
define_model :child, :parent_id => :integer
|
||||
define_model :parent do
|
||||
has_many :children, options
|
||||
end.new
|
||||
end
|
||||
end
|
||||
|
||||
context "have_one" do
|
||||
before do
|
||||
@matcher = have_one(:detail)
|
||||
context 'have_one' do
|
||||
it 'accepts a valid association without any options' do
|
||||
having_one_detail.should have_one(:detail)
|
||||
end
|
||||
|
||||
it "should accept a valid association without any options" do
|
||||
define_model :detail, :person_id => :integer
|
||||
define_model :person do
|
||||
has_one :detail
|
||||
end
|
||||
Person.new.should @matcher
|
||||
end
|
||||
|
||||
it "should accept a valid association with an :as option" do
|
||||
define_model :detail, :detailable_id => :integer,
|
||||
:detailable_type => :string
|
||||
it 'accepts a valid association with an :as option' do
|
||||
define_model :detail, :detailable_id => :integer,
|
||||
:detailable_type => :string
|
||||
define_model :person do
|
||||
has_one :detail, :as => :detailable
|
||||
end
|
||||
Person.new.should @matcher
|
||||
|
||||
Person.new.should have_one(:detail)
|
||||
end
|
||||
|
||||
it "should reject an association that has a nonexistent foreign key" do
|
||||
it 'rejects an association that has a nonexistent foreign key' do
|
||||
define_model :detail
|
||||
define_model :person do
|
||||
has_one :detail
|
||||
end
|
||||
Person.new.should_not @matcher
|
||||
|
||||
Person.new.should_not have_one(:detail)
|
||||
end
|
||||
|
||||
it "should accept an association with an existing custom foreign key" do
|
||||
it 'accepts an association with an existing custom foreign key' do
|
||||
define_model :detail, :detailed_person_id => :integer
|
||||
define_model :person do
|
||||
has_one :detail, :foreign_key => :detailed_person_id
|
||||
end
|
||||
Person.new.should @matcher.with_foreign_key(:detailed_person_id)
|
||||
Person.new.should have_one(:detail).with_foreign_key(:detailed_person_id)
|
||||
end
|
||||
|
||||
it "should reject an association with a bad :as option" do
|
||||
define_model :detail, :detailable_id => :integer,
|
||||
:detailable_type => :string
|
||||
it 'rejects an association with a bad :as option' do
|
||||
define_model :detail, :detailable_id => :integer,
|
||||
:detailable_type => :string
|
||||
define_model :person do
|
||||
has_one :detail, :as => :describable
|
||||
end
|
||||
Person.new.should_not @matcher
|
||||
|
||||
Person.new.should_not have_one(:detail)
|
||||
end
|
||||
|
||||
it "should accept an association with a valid :dependent option" do
|
||||
define_model :detail, :person_id => :integer
|
||||
define_model :person do
|
||||
has_one :detail, :dependent => :destroy
|
||||
end
|
||||
Person.new.should @matcher.dependent(:destroy)
|
||||
it 'accepts an association with a valid :dependent option' do
|
||||
having_one_detail(:dependent => :destroy).should
|
||||
have_one(:detail).dependent(:destroy)
|
||||
end
|
||||
|
||||
it "should reject an association with a bad :dependent option" do
|
||||
define_model :detail, :person_id => :integer
|
||||
define_model :person do
|
||||
has_one :detail
|
||||
end
|
||||
Person.new.should_not @matcher.dependent(:destroy)
|
||||
it 'rejects an association with a bad :dependent option' do
|
||||
having_one_detail.should_not have_one(:detail).dependent(:destroy)
|
||||
end
|
||||
|
||||
it "should accept an association with a valid :order option" do
|
||||
define_model :detail, :person_id => :integer
|
||||
define_model :person do
|
||||
has_one :detail, :order => :id
|
||||
end
|
||||
Person.new.should @matcher.order(:id)
|
||||
it 'accepts an association with a valid :order option' do
|
||||
having_one_detail(:order => :id).should have_one(:detail).order(:id)
|
||||
end
|
||||
|
||||
it "should reject an association with a bad :order option" do
|
||||
define_model :detail, :person_id => :integer
|
||||
define_model :person do
|
||||
has_one :detail
|
||||
end
|
||||
Person.new.should_not @matcher.order(:id)
|
||||
it 'rejects an association with a bad :order option' do
|
||||
having_one_detail.should_not have_one(:detail).order(:id)
|
||||
end
|
||||
|
||||
it "should accept an association with a valid :conditions option" do
|
||||
it 'accepts an association with a valid :conditions option' do
|
||||
define_model :detail, :person_id => :integer, :disabled => :boolean
|
||||
define_model :person do
|
||||
has_one :detail, :conditions => { :disabled => true}
|
||||
end
|
||||
Person.new.should @matcher.conditions(:disabled => true)
|
||||
|
||||
Person.new.should have_one(:detail).conditions(:disabled => true)
|
||||
end
|
||||
|
||||
it "should reject an association with a bad :conditions option" do
|
||||
it 'rejects an association with a bad :conditions option' do
|
||||
define_model :detail, :person_id => :integer, :disabled => :boolean
|
||||
define_model :person do
|
||||
has_one :detail
|
||||
end
|
||||
Person.new.should_not @matcher.conditions(:disabled => true)
|
||||
|
||||
Person.new.should_not have_one(:detail).conditions(:disabled => true)
|
||||
end
|
||||
|
||||
it "should accept an association with a valid :class_name option" do
|
||||
define_model :person_detail, :person_id => :integer, :disabled => :boolean
|
||||
define_model :person do
|
||||
has_one :detail, :class_name => 'PersonDetail'
|
||||
end
|
||||
Person.new.should @matcher.class_name('PersonDetail')
|
||||
it 'accepts an association with a valid :class_name option' do
|
||||
having_one_detail(:class_name => 'PersonDetail').should
|
||||
have_one(:detail).class_name('PersonDetail')
|
||||
end
|
||||
|
||||
it "should reject an association with a bad :class_name option" do
|
||||
define_model :detail, :person_id => :integer, :disabled => :boolean
|
||||
define_model :person do
|
||||
has_one :detail
|
||||
end
|
||||
Person.new.should_not @matcher.class_name('PersonDetail')
|
||||
it 'rejects an association with a bad :class_name option' do
|
||||
having_one_detail.should_not have_one(:detail).class_name('NotSet')
|
||||
end
|
||||
|
||||
it "should accept an association with a through" do
|
||||
it 'accepts an association with a through' do
|
||||
define_model :detail
|
||||
|
||||
define_model :account do
|
||||
|
@ -463,180 +389,145 @@ describe Shoulda::Matchers::ActiveRecord::AssociationMatcher do
|
|||
has_one :detail, :through => :account
|
||||
end
|
||||
|
||||
Person.new.should @matcher.through(:account)
|
||||
Person.new.should have_one(:detail).through(:account)
|
||||
end
|
||||
|
||||
it "should reject an association with a through" do
|
||||
define_model :detail
|
||||
it 'rejects an association with a bad through' do
|
||||
having_one_detail.should_not have_one(:detail).through(:account)
|
||||
end
|
||||
|
||||
context 'validate' do
|
||||
it 'accepts when the :validate option matches' do
|
||||
having_one_detail(:validate => false).should
|
||||
have_one(:detail).validate(false)
|
||||
end
|
||||
|
||||
it 'rejects when the :validate option does not match' do
|
||||
having_one_detail(:validate => true).should_not
|
||||
have_one(:detail).validate(false) end
|
||||
|
||||
it 'assumes validate() means validate(true)' do
|
||||
having_one_detail(:validate => false).should_not
|
||||
have_one(:detail).validate
|
||||
end
|
||||
|
||||
it 'matches validate(false) to having no validate option specified' do
|
||||
having_one_detail.should have_one(:detail).validate(false)
|
||||
end
|
||||
end
|
||||
|
||||
def having_one_detail(options = {})
|
||||
define_model :detail, :person_id => :integer
|
||||
define_model :person do
|
||||
has_one :detail
|
||||
end
|
||||
|
||||
Person.new.should_not @matcher.through(:account)
|
||||
has_one :detail, options
|
||||
end.new
|
||||
end
|
||||
|
||||
context 'should accept an association with a false :validate option' do
|
||||
before do
|
||||
define_model :detail, :person_id => :integer, :disabled => :boolean
|
||||
define_model :person do
|
||||
has_one :detail, :validate => false
|
||||
end
|
||||
end
|
||||
subject { Person.new }
|
||||
specify { subject.should @matcher.validate(false) }
|
||||
specify { subject.should_not @matcher.validate(true) }
|
||||
specify { subject.should_not @matcher.validate }
|
||||
end
|
||||
|
||||
context 'should accept an association with a true :validate option' do
|
||||
before do
|
||||
define_model :detail, :person_id => :integer, :disabled => :boolean
|
||||
define_model :person do
|
||||
has_one :detail, :validate => true
|
||||
end
|
||||
end
|
||||
subject { Person.new }
|
||||
specify { subject.should_not @matcher.validate(false) }
|
||||
specify { subject.should @matcher.validate(true) }
|
||||
specify { subject.should @matcher.validate }
|
||||
end
|
||||
|
||||
context 'should accept an association without a :validate option' do
|
||||
before do
|
||||
define_model :detail, :person_id => :integer, :disabled => :boolean
|
||||
define_model :person do
|
||||
has_one :detail
|
||||
end
|
||||
end
|
||||
subject { Person.new }
|
||||
specify { subject.should @matcher.validate(false) }
|
||||
specify { subject.should_not @matcher.validate(true) }
|
||||
specify { subject.should_not @matcher.validate }
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
context "have_and_belong_to_many" do
|
||||
before do
|
||||
@matcher = have_and_belong_to_many(:relatives)
|
||||
end
|
||||
context 'have_and_belong_to_many' do
|
||||
it 'accepts a valid association' do
|
||||
having_and_belonging_to_many_relatives.should
|
||||
have_and_belong_to_many(:relatives)
|
||||
end
|
||||
|
||||
it "should accept a valid association" do
|
||||
define_model :relatives
|
||||
define_model :person do
|
||||
has_and_belongs_to_many :relatives
|
||||
end
|
||||
define_model :people_relative, :person_id => :integer,
|
||||
:relative_id => :integer
|
||||
Person.new.should @matcher
|
||||
end
|
||||
|
||||
it "should reject a nonexistent association" do
|
||||
it 'rejects a nonexistent association' do
|
||||
define_model :relatives
|
||||
define_model :person
|
||||
define_model :people_relative, :person_id => :integer,
|
||||
:relative_id => :integer
|
||||
Person.new.should_not @matcher
|
||||
define_model :people_relative, :id => false, :person_id => :integer,
|
||||
:relative_id => :integer
|
||||
|
||||
Person.new.should_not have_and_belong_to_many(:relatives)
|
||||
end
|
||||
|
||||
it "should reject an association with a nonexistent join table" do
|
||||
it 'rejects an association with a nonexistent join table' do
|
||||
define_model :relatives
|
||||
define_model :person do
|
||||
has_and_belongs_to_many :relatives
|
||||
end
|
||||
Person.new.should_not @matcher
|
||||
|
||||
Person.new.should_not have_and_belong_to_many(:relatives)
|
||||
end
|
||||
|
||||
it "should reject an association of the wrong type" do
|
||||
it 'rejects an association of the wrong type' do
|
||||
define_model :relatives, :person_id => :integer
|
||||
define_model :person do
|
||||
has_many :relatives
|
||||
end
|
||||
Person.new.should_not @matcher
|
||||
|
||||
Person.new.should_not have_and_belong_to_many(:relatives)
|
||||
end
|
||||
|
||||
it "should accept an association with a valid :conditions option" do
|
||||
it 'accepts an association with a valid :conditions option' do
|
||||
define_model :relatives, :adopted => :boolean
|
||||
define_model :person do
|
||||
has_and_belongs_to_many :relatives, :conditions => { :adopted => true }
|
||||
end
|
||||
define_model :people_relative, :person_id => :integer,
|
||||
:relative_id => :integer
|
||||
Person.new.should @matcher.conditions(:adopted => true)
|
||||
define_model :people_relative, :id => false, :person_id => :integer,
|
||||
:relative_id => :integer
|
||||
|
||||
Person.new.should
|
||||
have_and_belong_to_many(:relatives).conditions(:adopted => true)
|
||||
end
|
||||
|
||||
it "should reject an association with a bad :conditions option" do
|
||||
it 'rejects an association with a bad :conditions option' do
|
||||
define_model :relatives, :adopted => :boolean
|
||||
define_model :person do
|
||||
has_and_belongs_to_many :relatives
|
||||
end
|
||||
define_model :people_relative, :person_id => :integer,
|
||||
:relative_id => :integer
|
||||
Person.new.should_not @matcher.conditions(:adopted => true)
|
||||
define_model :people_relative, :id => false, :person_id => :integer,
|
||||
:relative_id => :integer
|
||||
|
||||
Person.new.should_not
|
||||
have_and_belong_to_many(:relatives).conditions(:adopted => true)
|
||||
end
|
||||
|
||||
it "should accept an association with a valid :class_name option" do
|
||||
it 'accepts an association with a valid :class_name option' do
|
||||
define_model :person_relatives, :adopted => :boolean
|
||||
define_model :person do
|
||||
has_and_belongs_to_many :relatives, :class_name => 'PersonRelatives'
|
||||
end
|
||||
define_model :people_person_relative, :person_id => :integer,
|
||||
:person_relative_id => :integer
|
||||
Person.new.should @matcher.class_name('PersonRelatives')
|
||||
|
||||
define_model :people_person_relative, :person_id => :integer,
|
||||
:person_relative_id => :integer
|
||||
|
||||
Person.new.should
|
||||
have_and_belong_to_many(:relatives).class_name('PersonRelatives')
|
||||
end
|
||||
|
||||
it "should reject an association with a bad :class_name option" do
|
||||
define_model :relatives, :adopted => :boolean
|
||||
it 'rejects an association with a bad :class_name option' do
|
||||
having_and_belonging_to_many_relatives.should_not
|
||||
have_and_belong_to_many(:relatives).class_name('PersonRelatives')
|
||||
end
|
||||
|
||||
context 'validate' do
|
||||
it 'accepts when the :validate option matches' do
|
||||
having_and_belonging_to_many_relatives(:validate => false).should
|
||||
have_and_belong_to_many(:relatives).validate(false)
|
||||
end
|
||||
|
||||
it 'rejects when the :validate option does not match' do
|
||||
having_and_belonging_to_many_relatives(:validate => true).should
|
||||
have_and_belong_to_many(:relatives).validate(false)
|
||||
end
|
||||
|
||||
it 'assumes validate() means validate(true)' do
|
||||
having_and_belonging_to_many_relatives(:validate => false).should_not
|
||||
have_and_belong_to_many(:relatives).validate
|
||||
end
|
||||
|
||||
it 'matches validate(false) to having no validate option specified' do
|
||||
having_and_belonging_to_many_relatives.should
|
||||
have_and_belong_to_many(:relatives).validate(false)
|
||||
end
|
||||
end
|
||||
|
||||
def having_and_belonging_to_many_relatives(options = {})
|
||||
define_model :relatives
|
||||
define_model :people_relative, :id => false, :person_id => :integer,
|
||||
:relative_id => :integer
|
||||
define_model :person do
|
||||
has_and_belongs_to_many :relatives
|
||||
end
|
||||
define_model :people_relative, :person_id => :integer,
|
||||
:relative_id => :integer
|
||||
Person.new.should_not @matcher.class_name('PersonRelatives')
|
||||
end.new
|
||||
end
|
||||
|
||||
context 'should accept an association with a false :validate option' do
|
||||
before do
|
||||
define_model :relatives, :adopted => :boolean
|
||||
define_model :person do
|
||||
has_and_belongs_to_many :relatives, :validate => false
|
||||
end
|
||||
define_model :people_relative, :person_id => :integer, :relative_id => :integer
|
||||
end
|
||||
subject { Person.new }
|
||||
specify { subject.should @matcher.validate(false) }
|
||||
specify { subject.should_not @matcher.validate(true) }
|
||||
specify { subject.should_not @matcher.validate }
|
||||
end
|
||||
|
||||
context 'should accept an association with a true :validate option' do
|
||||
before do
|
||||
define_model :relatives, :adopted => :boolean
|
||||
define_model :person do
|
||||
has_and_belongs_to_many :relatives, :validate => true
|
||||
end
|
||||
define_model :people_relative, :person_id => :integer, :relative_id => :integer
|
||||
end
|
||||
subject { Person.new }
|
||||
specify { subject.should_not @matcher.validate(false) }
|
||||
specify { subject.should @matcher.validate(true) }
|
||||
specify { subject.should @matcher.validate }
|
||||
end
|
||||
|
||||
context 'should accept an association without a :validate option' do
|
||||
before do
|
||||
define_model :relatives, :adopted => :boolean
|
||||
define_model :person do
|
||||
has_and_belongs_to_many :relatives
|
||||
end
|
||||
define_model :people_relative, :person_id => :integer, :relative_id => :integer
|
||||
end
|
||||
subject { Person.new }
|
||||
specify { subject.should @matcher.validate(false) }
|
||||
specify { subject.should_not @matcher.validate(true) }
|
||||
specify { subject.should_not @matcher.validate }
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,185 +1,111 @@
|
|||
require 'spec_helper'
|
||||
|
||||
describe Shoulda::Matchers::ActiveRecord::HaveDbColumnMatcher do
|
||||
context "have_db_column" do
|
||||
before do
|
||||
@matcher = have_db_column(:nickname)
|
||||
it 'accepts an existing database column' do
|
||||
model(:nickname => :string).should have_db_column(:nickname)
|
||||
end
|
||||
|
||||
it 'rejects a nonexistent database column' do
|
||||
define_model(:employee).new.should_not have_db_column(:nickname)
|
||||
end
|
||||
|
||||
context '#of_type' do
|
||||
it 'accepts a column of correct type' do
|
||||
model(:nickname => :string).should
|
||||
have_db_column(:nickname).of_type(:string)
|
||||
end
|
||||
|
||||
it "should accept an existing database column" do
|
||||
create_table 'superheros' do |table|
|
||||
table.string :nickname
|
||||
end
|
||||
define_model_class 'Superhero'
|
||||
Superhero.new.should @matcher
|
||||
it 'rejects a nonexistent database column' do
|
||||
define_model(:superhero).should_not
|
||||
have_db_column(:nickname).of_type(:string)
|
||||
end
|
||||
|
||||
it "should reject a nonexistent database column" do
|
||||
define_model :superhero
|
||||
Superhero.new.should_not @matcher
|
||||
it 'rejects a column of wrong type' do
|
||||
model(:nickname => :integer).should_not
|
||||
have_db_column(:nickname).of_type(:string)
|
||||
end
|
||||
end
|
||||
|
||||
context "have_db_column of type string" do
|
||||
before do
|
||||
@matcher = have_db_column(:nickname).of_type(:string)
|
||||
context 'with precision option' do
|
||||
it 'accepts a column of correct precision' do
|
||||
with_table(:salary, :decimal, :precision => 5).should
|
||||
have_db_column(:salary).with_options(:precision => 5)
|
||||
end
|
||||
|
||||
it "should accept a column of correct type" do
|
||||
create_table 'superheros' do |table|
|
||||
table.string :nickname
|
||||
end
|
||||
define_model_class 'Superhero'
|
||||
Superhero.new.should @matcher
|
||||
end
|
||||
|
||||
it "should reject a nonexistent database column" do
|
||||
define_model :superhero
|
||||
Superhero.new.should_not @matcher
|
||||
end
|
||||
|
||||
it "should reject a column of wrong type" do
|
||||
create_table 'superheros' do |table|
|
||||
table.integer :nickname
|
||||
end
|
||||
define_model_class 'Superhero'
|
||||
Superhero.new.should_not @matcher
|
||||
it 'rejects a column of wrong precision' do
|
||||
with_table(:salary, :decimal, :precision => 6).should_not
|
||||
have_db_column(:salary).with_options(:precision => 5)
|
||||
end
|
||||
end
|
||||
|
||||
context "have_db_column with precision option" do
|
||||
before do
|
||||
@matcher = have_db_column(:salary).with_options(:precision => 5)
|
||||
context 'with limit option' do
|
||||
it 'accepts a column of correct limit' do
|
||||
with_table(:email, :string, :limit => 255).should
|
||||
have_db_column(:email).with_options(:limit => 255)
|
||||
end
|
||||
|
||||
it "should accept a column of correct precision" do
|
||||
create_table 'superheros' do |table|
|
||||
table.decimal :salary, :precision => 5
|
||||
end
|
||||
define_model_class 'Superhero'
|
||||
Superhero.new.should @matcher
|
||||
end
|
||||
|
||||
it "should reject a column of wrong precision" do
|
||||
create_table 'superheros' do |table|
|
||||
table.decimal :salary, :precision => 15
|
||||
end
|
||||
define_model_class 'Superhero'
|
||||
Superhero.new.should_not @matcher
|
||||
it 'rejects a column of wrong limit' do
|
||||
with_table(:email, :string, :limit => 100).should_not
|
||||
have_db_column(:email).with_options(:limit => 255)
|
||||
end
|
||||
end
|
||||
|
||||
context "have_db_column with limit option" do
|
||||
before do
|
||||
@matcher = have_db_column(:email).
|
||||
of_type(:string).
|
||||
with_options(:limit => 255)
|
||||
context 'with default option' do
|
||||
it 'accepts a column with correct default' do
|
||||
with_table(:admin, :boolean, :default => false).should
|
||||
have_db_column(:admin).with_options(:default => false)
|
||||
end
|
||||
|
||||
it "should accept a column of correct limit" do
|
||||
create_table 'superheros' do |table|
|
||||
table.string :email, :limit => 255
|
||||
end
|
||||
define_model_class 'Superhero'
|
||||
Superhero.new.should @matcher
|
||||
end
|
||||
|
||||
it "should reject a column of wrong limit" do
|
||||
create_table 'superheros' do |table|
|
||||
table.string :email, :limit => 500
|
||||
end
|
||||
define_model_class 'Superhero'
|
||||
Superhero.new.should_not @matcher
|
||||
it 'rejects a column with wrong default' do
|
||||
with_table(:admin, :boolean, :default => true).should_not
|
||||
have_db_column(:admin).with_options(:default => false)
|
||||
end
|
||||
end
|
||||
|
||||
context "have_db_column with default option" do
|
||||
before do
|
||||
@matcher = have_db_column(:admin).
|
||||
of_type(:boolean).
|
||||
with_options(:default => false)
|
||||
context 'with null option' do
|
||||
it 'accepts a column of correct null' do
|
||||
with_table(:admin, :boolean, :null => false).should
|
||||
have_db_column(:admin).with_options(:null => false)
|
||||
end
|
||||
|
||||
it "should accept a column of correct default" do
|
||||
create_table 'superheros' do |table|
|
||||
table.boolean :admin, :default => false
|
||||
end
|
||||
define_model_class 'Superhero'
|
||||
Superhero.new.should @matcher
|
||||
end
|
||||
|
||||
it "should reject a column of wrong default" do
|
||||
create_table 'superheros' do |table|
|
||||
table.boolean :admin, :default => true
|
||||
end
|
||||
define_model_class 'Superhero'
|
||||
Superhero.new.should_not @matcher
|
||||
it 'rejects a column of wrong null' do
|
||||
with_table(:admin, :boolean, :null => true).should_not
|
||||
have_db_column(:admin).with_options(:null => false)
|
||||
end
|
||||
end
|
||||
|
||||
context "have_db_column with null option" do
|
||||
before do
|
||||
@matcher = have_db_column(:admin).
|
||||
of_type(:boolean).
|
||||
with_options(:null => false)
|
||||
context 'with scale option' do
|
||||
it 'accepts a column of correct scale' do
|
||||
with_table(:salary, :decimal, :scale => 2).should
|
||||
have_db_column(:salary).with_options(:scale => 2)
|
||||
end
|
||||
|
||||
it "should accept a column of correct null" do
|
||||
create_table 'superheros' do |table|
|
||||
table.boolean :admin, :null => false
|
||||
end
|
||||
define_model_class 'Superhero'
|
||||
Superhero.new.should @matcher
|
||||
end
|
||||
|
||||
it "should reject a column of wrong null" do
|
||||
create_table 'superheros' do |table|
|
||||
table.boolean :admin, :null => true
|
||||
end
|
||||
define_model_class 'Superhero'
|
||||
Superhero.new.should_not @matcher
|
||||
it 'rejects a column of wrong scale' do
|
||||
with_table(:salary, :decimal, :scale => 4).should_not
|
||||
have_db_column(:salary).with_options(:scale => 2)
|
||||
end
|
||||
end
|
||||
|
||||
context "have_db_column with scale option" do
|
||||
before do
|
||||
@matcher = have_db_column(:salary).
|
||||
of_type(:decimal).
|
||||
with_options(:scale => 2)
|
||||
context 'with primary option' do
|
||||
it 'accepts a column that is primary' do
|
||||
with_table(:id, :integer, :primary => true).should
|
||||
have_db_column(:id).with_options(:primary => true)
|
||||
end
|
||||
|
||||
it "should accept a column of correct scale" do
|
||||
create_table 'superheros' do |table|
|
||||
table.decimal :salary, :precision => 10, :scale => 2
|
||||
end
|
||||
define_model_class 'Superhero'
|
||||
Superhero.new.should @matcher
|
||||
end
|
||||
|
||||
it "should reject a column of wrong scale" do
|
||||
create_table 'superheros' do |table|
|
||||
table.decimal :salary, :precision => 10, :scale => 4
|
||||
end
|
||||
define_model_class 'Superhero'
|
||||
Superhero.new.should_not @matcher
|
||||
it 'rejects a column that is not primary' do
|
||||
with_table(:whatever, :integer, :primary => false).should_not
|
||||
have_db_column(:whatever).with_options(:primary => true)
|
||||
end
|
||||
end
|
||||
|
||||
context "have_db_column with primary option" do
|
||||
it "should accept a column that is primary" do
|
||||
create_table 'superheros' do |table|
|
||||
table.integer :id, :primary => true
|
||||
end
|
||||
define_model_class 'Superhero'
|
||||
Superhero.new.should have_db_column(:id).with_options(:primary => true)
|
||||
end
|
||||
def model(options = {})
|
||||
define_model(:employee, options).new
|
||||
end
|
||||
|
||||
it "should reject a column that is not primary" do
|
||||
create_table 'superheros' do |table|
|
||||
table.integer :primary
|
||||
end
|
||||
define_model_class 'Superhero'
|
||||
Superhero.new.should_not have_db_column(:primary).with_options(:primary => true)
|
||||
def with_table(column_name, column_type, options)
|
||||
create_table 'employees' do |table|
|
||||
table.send(column_type, column_name, options)
|
||||
end
|
||||
define_model_class('Employee').new
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,105 +1,78 @@
|
|||
require 'spec_helper'
|
||||
|
||||
describe Shoulda::Matchers::ActiveRecord::HaveDbIndexMatcher do
|
||||
context "have_db_index" do
|
||||
before do
|
||||
@matcher = have_db_index(:age)
|
||||
context 'have_db_index' do
|
||||
it 'accepts an existing index' do
|
||||
with_index_on(:age).should have_db_index(:age)
|
||||
end
|
||||
|
||||
it "should accept an existing index" do
|
||||
db_connection = create_table 'superheros' do |table|
|
||||
table.integer :age
|
||||
end
|
||||
db_connection.add_index :superheros, :age
|
||||
define_model_class 'Superhero'
|
||||
Superhero.new.should @matcher
|
||||
end
|
||||
|
||||
it "should reject a nonexistent index" do
|
||||
define_model :superhero
|
||||
Superhero.new.should_not @matcher
|
||||
it 'rejects a nonexistent index' do
|
||||
define_model(:employee).new.should_not have_db_index(:age)
|
||||
end
|
||||
end
|
||||
|
||||
context "have_db_index with unique option" do
|
||||
before do
|
||||
@matcher = have_db_index(:ssn).unique(true)
|
||||
context 'have_db_index with unique option' do
|
||||
it 'accepts an index of correct unique' do
|
||||
with_index_on(:ssn, :unique => true).should
|
||||
have_db_index(:ssn).unique(true)
|
||||
end
|
||||
|
||||
it "should accept an index of correct unique" do
|
||||
db_connection = create_table 'superheros' do |table|
|
||||
table.integer :ssn
|
||||
end
|
||||
db_connection.add_index :superheros, :ssn, :unique => true
|
||||
define_model_class 'Superhero'
|
||||
Superhero.new.should @matcher
|
||||
end
|
||||
|
||||
it "should reject an index of wrong unique" do
|
||||
db_connection = create_table 'superheros' do |table|
|
||||
table.integer :ssn
|
||||
end
|
||||
db_connection.add_index :superheros, :ssn, :unique => false
|
||||
define_model_class 'Superhero'
|
||||
Superhero.new.should_not @matcher
|
||||
it 'rejects an index of wrong unique' do
|
||||
with_index_on(:ssn, :unique => false).should_not
|
||||
have_db_index(:ssn).unique(true)
|
||||
end
|
||||
end
|
||||
|
||||
context "have_db_index on multiple columns" do
|
||||
before do
|
||||
@matcher = have_db_index([:geocodable_type, :geocodable_id])
|
||||
end
|
||||
|
||||
it "should accept an existing index" do
|
||||
context 'have_db_index on multiple columns' do
|
||||
it 'accepts an existing index' do
|
||||
db_connection = create_table 'geocodings' do |table|
|
||||
table.integer :geocodable_id
|
||||
table.string :geocodable_type
|
||||
end
|
||||
db_connection.add_index :geocodings, [:geocodable_type, :geocodable_id]
|
||||
define_model_class 'Geocoding'
|
||||
Geocoding.new.should @matcher
|
||||
define_model_class('Geocoding').new.should
|
||||
have_db_index([:geocodable_type, :geocodable_id])
|
||||
end
|
||||
|
||||
it "should reject a nonexistant index" do
|
||||
db_connection = create_table 'geocodings' do |table|
|
||||
it 'rejects a nonexistent index' do
|
||||
create_table 'geocodings' do |table|
|
||||
table.integer :geocodable_id
|
||||
table.string :geocodable_type
|
||||
end
|
||||
define_model_class 'Geocoding'
|
||||
Geocoding.new.should_not @matcher
|
||||
define_model_class('Geocoding').new.should_not
|
||||
have_db_index([:geocodable_type, :geocodable_id])
|
||||
end
|
||||
end
|
||||
|
||||
it "should join columns with and describing multiple columns" do
|
||||
it 'join columns with and when describing multiple columns' do
|
||||
have_db_index([:user_id, :post_id]).description.should =~ /on columns user_id and post_id/
|
||||
end
|
||||
|
||||
it "should context a unique index as unique" do
|
||||
it 'describes a unique index as unique' do
|
||||
have_db_index(:user_id).unique(true).description.should =~ /a unique index/
|
||||
end
|
||||
|
||||
it "should context a non-unique index as non-unique" do
|
||||
it 'describes a non-unique index as non-unique' do
|
||||
have_db_index(:user_id).unique(false).description.should =~ /a non-unique index/
|
||||
end
|
||||
|
||||
it "should not context an index's uniqueness when it isn't important" do
|
||||
it "does not display an index's uniqueness when it's not important" do
|
||||
have_db_index(:user_id).description.should_not =~ /unique/
|
||||
end
|
||||
|
||||
it "allows an IndexDefinition to have a truthy value for unique" do
|
||||
db_connection = create_table 'superheros' do |table|
|
||||
table.integer :age
|
||||
end
|
||||
db_connection.add_index :superheros, :age
|
||||
define_model_class 'Superhero'
|
||||
it 'allows an IndexDefinition to have a truthy value for unique' do
|
||||
index_definition = stub('ActiveRecord::ConnectionAdapters::IndexDefinition',
|
||||
:unique => 7, :name => :age)
|
||||
matcher = have_db_index(:age).unique(true)
|
||||
matcher.stubs(:matched_index => index_definition)
|
||||
|
||||
@matcher = have_db_index(:age).unique(true)
|
||||
with_index_on(:age).should matcher
|
||||
end
|
||||
|
||||
index_definition = stub("ActiveRecord::ConnectionAdapters::IndexDefinition",
|
||||
:unique => 7,
|
||||
:name => :age)
|
||||
@matcher.stubs(:matched_index => index_definition)
|
||||
|
||||
Superhero.new.should @matcher
|
||||
def with_index_on(column_name, index_options = {})
|
||||
create_table 'employees' do |table|
|
||||
table.integer column_name
|
||||
end.add_index(:employees, column_name, index_options)
|
||||
define_model_class('Employee').new
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,46 +1,41 @@
|
|||
require 'spec_helper'
|
||||
|
||||
describe Shoulda::Matchers::ActiveRecord::HaveReadonlyAttributeMatcher do
|
||||
context "an attribute that cannot be set after being saved" do
|
||||
before do
|
||||
define_model :example, :attr => :string do
|
||||
context 'a read-only attribute' do
|
||||
it 'accepts' do
|
||||
with_readonly_attr.should have_readonly_attribute(:attr)
|
||||
end
|
||||
end
|
||||
|
||||
context 'an attribute that is not part of the read-only set' do
|
||||
it 'rejects being read-only' do
|
||||
model = define_model :example, :attr => :string, :other => :string do
|
||||
attr_readonly :attr
|
||||
end
|
||||
@model = Example.new
|
||||
end
|
||||
end.new
|
||||
|
||||
it "should accept being read-only" do
|
||||
@model.should have_readonly_attribute(:attr)
|
||||
model.should_not have_readonly_attribute(:other)
|
||||
end
|
||||
end
|
||||
|
||||
context "an attribute not included in the readonly set" do
|
||||
before do
|
||||
define_model :example, :attr => :string, :other => :string do
|
||||
attr_readonly :other
|
||||
end
|
||||
@model = Example.new
|
||||
context 'an attribute on a class with no readonly attributes' do
|
||||
it 'rejects being read-only' do
|
||||
define_model(:example, :attr => :string).new.should_not
|
||||
have_readonly_attribute(:attr)
|
||||
end
|
||||
|
||||
it "should not accept being read-only" do
|
||||
@model.should_not have_readonly_attribute(:attr)
|
||||
end
|
||||
end
|
||||
|
||||
context "an attribute on a class with no readonly attributes" do
|
||||
before do
|
||||
define_model :example, :attr => :string
|
||||
@model = Example.new
|
||||
end
|
||||
|
||||
it "should not accept being read-only" do
|
||||
@model.should_not have_readonly_attribute(:attr)
|
||||
end
|
||||
|
||||
it "should assign a failure message" do
|
||||
it 'assigns a failure message' do
|
||||
model = define_model(:example, :attr => :string).new
|
||||
matcher = have_readonly_attribute(:attr)
|
||||
matcher.matches?(@model).should == false
|
||||
|
||||
matcher.matches?(model)
|
||||
|
||||
matcher.failure_message.should_not be_nil
|
||||
end
|
||||
end
|
||||
|
||||
def with_readonly_attr
|
||||
define_model :example, :attr => :string do
|
||||
attr_readonly :attr
|
||||
end.new
|
||||
end
|
||||
end
|
||||
|
|
|
@ -10,36 +10,36 @@ describe Shoulda::Matchers::ActiveRecord::QueryTheDatabaseMatcher do
|
|||
end
|
||||
end
|
||||
|
||||
it "accepts the correct number of queries when there is a single query" do
|
||||
it 'accepts the correct number of queries when there is a single query' do
|
||||
@parent.should query_the_database(1.times).when_calling(:count)
|
||||
end
|
||||
|
||||
it "accepts any number of queries when no number is specified" do
|
||||
it 'accepts any number of queries when no number is specified' do
|
||||
@parent.should query_the_database.when_calling(:count)
|
||||
end
|
||||
|
||||
it "rejects any number of queries when no number is specified" do
|
||||
it 'rejects any number of queries when no number is specified' do
|
||||
@parent.should_not query_the_database.when_calling(:to_s)
|
||||
end
|
||||
|
||||
it "accepts the correct number of queries when there are two queries" do
|
||||
it 'accepts the correct number of queries when there are two queries' do
|
||||
nonsense = lambda do
|
||||
@parent.create.kittens.create
|
||||
end
|
||||
nonsense.should query_the_database(2.times).when_calling(:call)
|
||||
end
|
||||
|
||||
it "rejects the wrong number of queries" do
|
||||
it 'rejects the wrong number of queries' do
|
||||
@parent.should_not query_the_database(10.times).when_calling(:count)
|
||||
end
|
||||
|
||||
it "accepts fewer than the specified maximum" do
|
||||
it 'accepts fewer than the specified maximum' do
|
||||
@parent.should query_the_database(5.times).or_less.when_calling(:count)
|
||||
end
|
||||
|
||||
it "passes arguments to the method to examine" do
|
||||
model = stub("Model", :count => nil)
|
||||
model.should_not query_the_database.when_calling(:count).with("arguments")
|
||||
model.should have_received(:count).with("arguments")
|
||||
it 'passes arguments to the method to examine' do
|
||||
model = stub('Model', :count => nil)
|
||||
model.should_not query_the_database.when_calling(:count).with('arguments')
|
||||
model.should have_received(:count).with('arguments')
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,81 +1,87 @@
|
|||
require 'spec_helper'
|
||||
|
||||
describe Shoulda::Matchers::ActiveRecord::SerializeMatcher do
|
||||
context "an attribute that should be serialized" do
|
||||
let(:model) do
|
||||
define_model(:example, :attr => :string) do
|
||||
serialize :attr
|
||||
end.new
|
||||
end
|
||||
|
||||
it "should be serialized" do
|
||||
model.should serialize(:attr)
|
||||
end
|
||||
it 'accepts when the attribute is serialized' do
|
||||
with_serialized_attr.should serialize(:attr)
|
||||
end
|
||||
|
||||
context "an attribute that should be serialized with a type of Hash" do
|
||||
let(:model) do
|
||||
define_model(:example, :attr => :string) do
|
||||
serialize :attr, Hash
|
||||
end.new
|
||||
context 'when attribute is not serialized' do
|
||||
it 'rejects' do
|
||||
unserialized_model.should_not serialize(:attr)
|
||||
end
|
||||
|
||||
it "should be serialized" do
|
||||
model.should serialize(:attr).as(Hash)
|
||||
end
|
||||
|
||||
it "should not match when using as_instance_of" do
|
||||
model.should_not serialize(:attr).as_instance_of(Hash)
|
||||
end
|
||||
end
|
||||
|
||||
context "an attribute that should be serialized with a type of Array" do
|
||||
let(:model) do
|
||||
define_model(:example, :attr => :string, :attr2 => :string) do
|
||||
serialize :attr, Array
|
||||
serialize :attr2, Array
|
||||
end.new
|
||||
end
|
||||
|
||||
it "should be serialized" do
|
||||
model.should serialize(:attr).as(Array)
|
||||
end
|
||||
end
|
||||
|
||||
context "an attribute that should be serialized but isn't" do
|
||||
let(:model) { define_model(:example, :attr => :string).new }
|
||||
|
||||
it "should assign a failure message" do
|
||||
it 'assigns a helpful failure message' do
|
||||
matcher = serialize(:attr)
|
||||
matcher.matches?(model).should == false
|
||||
matcher.failure_message.should_not be_nil
|
||||
|
||||
matcher.matches?(unserialized_model)
|
||||
|
||||
matcher.failure_message.should =~ /to serialize the attribute called :attr/
|
||||
end
|
||||
|
||||
it "should assign a failure message with 'as'" do
|
||||
it 'assigns a helpful failure message when using #as' do
|
||||
matcher = serialize(:attr).as(Hash)
|
||||
matcher.matches?(model).should == false
|
||||
matcher.failure_message.should_not be_nil
|
||||
|
||||
matcher.matches?(unserialized_model)
|
||||
|
||||
matcher.failure_message.should =~ /with a type of Hash/
|
||||
end
|
||||
|
||||
context "a serializer that is an instance of a class" do
|
||||
before do
|
||||
define_class(:ExampleSerializer) do
|
||||
def load(*); end
|
||||
def dump(*); end
|
||||
end
|
||||
define_model :example, :attr => :string do
|
||||
serialize :attr, ExampleSerializer.new
|
||||
end
|
||||
@model = Example.new
|
||||
end
|
||||
it 'assigns a helpful failure message when using #as_instance_of' do
|
||||
matcher = serialize(:attr).as_instance_of(Hash)
|
||||
|
||||
it "should match when using as_instance_of" do
|
||||
@model.should serialize(:attr).as_instance_of(ExampleSerializer)
|
||||
end
|
||||
matcher.matches?(unserialized_model)
|
||||
|
||||
it "should not match when using as" do
|
||||
@model.should_not serialize(:attr).as(ExampleSerializer)
|
||||
matcher.failure_message.should =~ /with an instance of Hash/
|
||||
end
|
||||
|
||||
def unserialized_model
|
||||
@model ||= define_model(:example, :attr => :string).new
|
||||
end
|
||||
end
|
||||
|
||||
context 'an attribute that is serialized as a specific type' do
|
||||
it 'accepts when the types match' do
|
||||
with_serialized_attr(Hash).should serialize(:attr).as(Hash)
|
||||
end
|
||||
|
||||
it 'rejects when the types do not match' do
|
||||
with_serialized_attr(Hash).should_not serialize(:attr).as(String)
|
||||
end
|
||||
|
||||
it 'rejects when using as_instance_of' do
|
||||
with_serialized_attr(Hash).should_not
|
||||
serialize(:attr).as_instance_of(Hash)
|
||||
end
|
||||
end
|
||||
|
||||
context 'a serializer that is an instance of a class' do
|
||||
it 'accepts when using #as_instance_of' do
|
||||
define_serializer(:ExampleSerializer)
|
||||
with_serialized_attr(ExampleSerializer.new).should
|
||||
serialize(:attr).as_instance_of(ExampleSerializer)
|
||||
end
|
||||
|
||||
it 'rejects when using #as' do
|
||||
define_serializer(:ExampleSerializer)
|
||||
with_serialized_attr(ExampleSerializer.new).should_not
|
||||
serialize(:attr).as(ExampleSerializer)
|
||||
end
|
||||
end
|
||||
|
||||
def with_serialized_attr(type = nil)
|
||||
define_model(:example, :attr => :string) do
|
||||
if type
|
||||
serialize :attr, type
|
||||
else
|
||||
serialize :attr
|
||||
end
|
||||
end.new
|
||||
end
|
||||
|
||||
def define_serializer(name)
|
||||
define_class(name) do
|
||||
def load(*); end
|
||||
def dump(*); end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -3,31 +3,30 @@ require 'spec_helper'
|
|||
describe Shoulda::Matchers::Independent::DelegateMatcher do
|
||||
it 'supports chaining on #to' do
|
||||
matcher = delegate_method(:method)
|
||||
|
||||
matcher.to(:another_method).should == matcher
|
||||
end
|
||||
|
||||
it 'supports chaining on #with_arguments' do
|
||||
matcher = delegate_method(:method)
|
||||
|
||||
matcher.with_arguments(1, 2, 3).should == matcher
|
||||
end
|
||||
|
||||
it 'supports chaining on #as' do
|
||||
matcher = delegate_method(:method)
|
||||
|
||||
matcher.as(:some_other_method).should == matcher
|
||||
end
|
||||
|
||||
it 'should raise an error if no delegation target is defined' do
|
||||
object = Object.new
|
||||
expect {
|
||||
object.should delegate_method(:name)
|
||||
}.to raise_exception Shoulda::Matchers::Independent::DelegateMatcher::TargetNotDefinedError
|
||||
it 'raises an error if no delegation target is defined' do
|
||||
expect { Object.new.should delegate_method(:name) }.to raise_exception
|
||||
described_class::TargetNotDefinedError
|
||||
end
|
||||
|
||||
it 'should raise an error if called with #should_not' do
|
||||
object = Object.new
|
||||
expect {
|
||||
object.should_not delegate_method(:name).to(:anyone)
|
||||
}.to raise_exception Shoulda::Matchers::Independent::DelegateMatcher::InvalidDelegateMatcher
|
||||
it 'raises an error if called with #should_not' do
|
||||
expect { Object.new.should_not delegate_method(:name).to(:anyone) }.to
|
||||
raise_exception described_class::InvalidDelegateMatcher
|
||||
end
|
||||
|
||||
context 'given a method that does not delegate' do
|
||||
|
@ -39,9 +38,10 @@ describe Shoulda::Matchers::Independent::DelegateMatcher do
|
|||
end
|
||||
end
|
||||
|
||||
it 'does not match' do
|
||||
it 'rejects' do
|
||||
post_office = PostOffice.new
|
||||
matcher = delegate_method(:deliver_mail).to(:mailman)
|
||||
|
||||
matcher.matches?(post_office).should be_false
|
||||
end
|
||||
|
||||
|
@ -66,7 +66,7 @@ describe Shoulda::Matchers::Independent::DelegateMatcher do
|
|||
end
|
||||
|
||||
context 'given a method that delegates properly' do
|
||||
before do
|
||||
it 'accepts' do
|
||||
define_class(:mailman)
|
||||
define_class(:post_office) do
|
||||
def deliver_mail
|
||||
|
@ -76,12 +76,7 @@ describe Shoulda::Matchers::Independent::DelegateMatcher do
|
|||
def mailman
|
||||
Mailman.new
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
it 'matches' do
|
||||
post_office = PostOffice.new
|
||||
post_office.should delegate_method(:deliver_mail).to(:mailman)
|
||||
end.new.should delegate_method(:deliver_mail).to(:mailman)
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -100,17 +95,17 @@ describe Shoulda::Matchers::Independent::DelegateMatcher do
|
|||
end
|
||||
|
||||
context 'when given the correct arguments' do
|
||||
it 'matches' do
|
||||
post_office = PostOffice.new
|
||||
matcher = delegate_method(:deliver_mail).to(:mailman).with_arguments('221B Baker St.', :hastily => true)
|
||||
post_office.should matcher
|
||||
it 'accepts' do
|
||||
PostOffice.new.should delegate_method(:deliver_mail).
|
||||
to(:mailman).with_arguments('221B Baker St.', :hastily => true)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when not given the correct arguments' do
|
||||
it 'does not match' do
|
||||
it 'rejects' do
|
||||
post_office = PostOffice.new
|
||||
matcher = delegate_method(:deliver_mail).to(:mailman).with_arguments('123 Nowhere Ln.')
|
||||
matcher = delegate_method(:deliver_mail).to(:mailman).
|
||||
with_arguments('123 Nowhere Ln.')
|
||||
matcher.matches?(post_office).should be_false
|
||||
end
|
||||
|
||||
|
@ -141,15 +136,14 @@ describe Shoulda::Matchers::Independent::DelegateMatcher do
|
|||
end
|
||||
|
||||
context 'when given the correct method name' do
|
||||
it 'matches' do
|
||||
post_office = PostOffice.new
|
||||
matcher = delegate_method(:deliver_mail).to(:mailman).as(:deliver_mail_and_avoid_dogs)
|
||||
post_office.should matcher
|
||||
it 'accepts' do
|
||||
PostOffice.new.should
|
||||
delegate_method(:deliver_mail).to(:mailman).as(:deliver_mail_and_avoid_dogs)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when given an incorrect method name' do
|
||||
it 'does not match' do
|
||||
it 'rejects' do
|
||||
post_office = PostOffice.new
|
||||
matcher = delegate_method(:deliver_mail).to(:mailman).as(:watch_tv)
|
||||
matcher.matches?(post_office).should be_false
|
||||
|
|
|
@ -20,7 +20,7 @@ Dir[File.join(PROJECT_ROOT, 'spec', 'support', '**', '*.rb')].each { |file| requ
|
|||
|
||||
# Run the migrations
|
||||
ActiveRecord::Migration.verbose = false
|
||||
ActiveRecord::Migrator.migrate("#{Rails.root}/db/migrate")
|
||||
ActiveRecord::Migrator.migrate(Rails.root.join('db/migrate'))
|
||||
|
||||
RSpec.configure do |config|
|
||||
config.mock_with :mocha
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
module ActiveModelHelpers
|
||||
def custom_validation(&block)
|
||||
define_model(:example, :attr => :integer) do
|
||||
validate :custom_validation
|
||||
|
||||
define_method(:custom_validation, &block)
|
||||
end.new
|
||||
end
|
||||
|
||||
def validating_format(options)
|
||||
define_model :example, :attr => :string do
|
||||
validates_format_of :attr, options
|
||||
end.new
|
||||
end
|
||||
end
|
||||
|
||||
RSpec.configure do |c|
|
||||
c.include ActiveModelHelpers
|
||||
end
|
|
@ -36,11 +36,11 @@ module ControllerBuilder
|
|||
controller_class.view_paths = [TMP_VIEW_PATH]
|
||||
|
||||
define_routes do
|
||||
get "examples", :to => "examples##{action}"
|
||||
get 'examples', :to => "examples##{action}"
|
||||
end
|
||||
|
||||
create_view("examples/#{action}.html.erb", "action")
|
||||
create_view("examples/#{partial}.html.erb", "partial")
|
||||
create_view("examples/#{action}.html.erb", 'action')
|
||||
create_view("examples/#{partial}.html.erb", 'partial')
|
||||
|
||||
@controller = controller_class.new
|
||||
@request = ActionController::TestRequest.new
|
||||
|
|
|
@ -46,13 +46,19 @@ module ModelBuilder
|
|||
def define_model(name, columns = {}, &block)
|
||||
class_name = name.to_s.pluralize.classify
|
||||
table_name = class_name.tableize
|
||||
|
||||
create_table(table_name) do |table|
|
||||
table_block = lambda do |table|
|
||||
columns.each do |name, type|
|
||||
table.column name, type
|
||||
end
|
||||
end
|
||||
|
||||
if columns.key?(:id) && columns[:id] == false
|
||||
columns.delete(:id)
|
||||
create_table(table_name, :id => false, &table_block)
|
||||
else
|
||||
create_table(table_name, &table_block)
|
||||
end
|
||||
|
||||
define_model_class(class_name, &block)
|
||||
end
|
||||
|
||||
|
|
Loading…
Reference in New Issue