Skip to content

Commit

Permalink
Completely remove potential global state leaks in ActiveModel tests.
Browse files Browse the repository at this point in the history
ActiveModel tests can now be run in random order.
  • Loading branch information
zuhao committed Mar 10, 2014
1 parent 5ade4b0 commit cc6bc1c
Show file tree
Hide file tree
Showing 7 changed files with 136 additions and 110 deletions.
76 changes: 52 additions & 24 deletions activemodel/test/cases/attribute_methods_test.rb
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -104,10 +104,14 @@ class AttributeMethodsTest < ActiveModel::TestCase
end end


test '#define_attribute_method generates attribute method' do test '#define_attribute_method generates attribute method' do
ModelWithAttributes.define_attribute_method(:foo) begin
ModelWithAttributes.define_attribute_method(:foo)


assert_respond_to ModelWithAttributes.new, :foo assert_respond_to ModelWithAttributes.new, :foo
assert_equal "value of foo", ModelWithAttributes.new.foo assert_equal "value of foo", ModelWithAttributes.new.foo
ensure
ModelWithAttributes.undefine_attribute_methods
end
end end


test '#define_attribute_method does not generate attribute method if already defined in attribute module' do test '#define_attribute_method does not generate attribute method if already defined in attribute module' do
Expand All @@ -134,24 +138,36 @@ def foo
end end


test '#define_attribute_method generates attribute method with invalid identifier characters' do test '#define_attribute_method generates attribute method with invalid identifier characters' do
ModelWithWeirdNamesAttributes.define_attribute_method(:'a?b') begin
ModelWithWeirdNamesAttributes.define_attribute_method(:'a?b')


assert_respond_to ModelWithWeirdNamesAttributes.new, :'a?b' assert_respond_to ModelWithWeirdNamesAttributes.new, :'a?b'
assert_equal "value of a?b", ModelWithWeirdNamesAttributes.new.send('a?b') assert_equal "value of a?b", ModelWithWeirdNamesAttributes.new.send('a?b')
ensure
ModelWithWeirdNamesAttributes.undefine_attribute_methods
end
end end


test '#define_attribute_methods works passing multiple arguments' do test '#define_attribute_methods works passing multiple arguments' do
ModelWithAttributes.define_attribute_methods(:foo, :baz) begin
ModelWithAttributes.define_attribute_methods(:foo, :baz)


assert_equal "value of foo", ModelWithAttributes.new.foo assert_equal "value of foo", ModelWithAttributes.new.foo
assert_equal "value of baz", ModelWithAttributes.new.baz assert_equal "value of baz", ModelWithAttributes.new.baz
ensure
ModelWithAttributes.undefine_attribute_methods
end
end end


test '#define_attribute_methods generates attribute methods' do test '#define_attribute_methods generates attribute methods' do
ModelWithAttributes.define_attribute_methods(:foo) begin
ModelWithAttributes.define_attribute_methods(:foo)


assert_respond_to ModelWithAttributes.new, :foo assert_respond_to ModelWithAttributes.new, :foo
assert_equal "value of foo", ModelWithAttributes.new.foo assert_equal "value of foo", ModelWithAttributes.new.foo
ensure
ModelWithAttributes.undefine_attribute_methods
end
end end


test '#alias_attribute generates attribute_aliases lookup hash' do test '#alias_attribute generates attribute_aliases lookup hash' do
Expand All @@ -164,26 +180,38 @@ def foo
end end


test '#define_attribute_methods generates attribute methods with spaces in their names' do test '#define_attribute_methods generates attribute methods with spaces in their names' do
ModelWithAttributesWithSpaces.define_attribute_methods(:'foo bar') begin
ModelWithAttributesWithSpaces.define_attribute_methods(:'foo bar')


assert_respond_to ModelWithAttributesWithSpaces.new, :'foo bar' assert_respond_to ModelWithAttributesWithSpaces.new, :'foo bar'
assert_equal "value of foo bar", ModelWithAttributesWithSpaces.new.send(:'foo bar') assert_equal "value of foo bar", ModelWithAttributesWithSpaces.new.send(:'foo bar')
ensure
ModelWithAttributesWithSpaces.undefine_attribute_methods
end
end end


test '#alias_attribute works with attributes with spaces in their names' do test '#alias_attribute works with attributes with spaces in their names' do
ModelWithAttributesWithSpaces.define_attribute_methods(:'foo bar') begin
ModelWithAttributesWithSpaces.alias_attribute(:'foo_bar', :'foo bar') ModelWithAttributesWithSpaces.define_attribute_methods(:'foo bar')
ModelWithAttributesWithSpaces.alias_attribute(:'foo_bar', :'foo bar')


assert_equal "value of foo bar", ModelWithAttributesWithSpaces.new.foo_bar assert_equal "value of foo bar", ModelWithAttributesWithSpaces.new.foo_bar
ensure
ModelWithAttributesWithSpaces.undefine_attribute_methods
end
end end


test '#alias_attribute works with attributes named as a ruby keyword' do test '#alias_attribute works with attributes named as a ruby keyword' do
ModelWithRubyKeywordNamedAttributes.define_attribute_methods([:begin, :end]) begin
ModelWithRubyKeywordNamedAttributes.alias_attribute(:from, :begin) ModelWithRubyKeywordNamedAttributes.define_attribute_methods([:begin, :end])
ModelWithRubyKeywordNamedAttributes.alias_attribute(:to, :end) ModelWithRubyKeywordNamedAttributes.alias_attribute(:from, :begin)

ModelWithRubyKeywordNamedAttributes.alias_attribute(:to, :end)
assert_equal "value of begin", ModelWithRubyKeywordNamedAttributes.new.from
assert_equal "value of end", ModelWithRubyKeywordNamedAttributes.new.to assert_equal "value of begin", ModelWithRubyKeywordNamedAttributes.new.from
assert_equal "value of end", ModelWithRubyKeywordNamedAttributes.new.to
ensure
ModelWithRubyKeywordNamedAttributes.undefine_attribute_methods
end
end end


test '#undefine_attribute_methods removes attribute methods' do test '#undefine_attribute_methods removes attribute methods' do
Expand Down
34 changes: 11 additions & 23 deletions activemodel/test/cases/secure_password_test.rb
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@


class SecurePasswordTest < ActiveModel::TestCase class SecurePasswordTest < ActiveModel::TestCase
setup do setup do
@original_min_cost = ActiveModel::SecurePassword.min_cost
ActiveModel::SecurePassword.min_cost = true ActiveModel::SecurePassword.min_cost = true


@user = User.new @user = User.new
Expand All @@ -15,7 +16,7 @@ class SecurePasswordTest < ActiveModel::TestCase
end end


teardown do teardown do
ActiveModel::SecurePassword.min_cost = false ActiveModel::SecurePassword.min_cost = @original_min_cost
end end


test "create and updating without validations" do test "create and updating without validations" do
Expand Down Expand Up @@ -157,42 +158,29 @@ class SecurePasswordTest < ActiveModel::TestCase
end end


test "Password digest cost defaults to bcrypt default cost when min_cost is false" do test "Password digest cost defaults to bcrypt default cost when min_cost is false" do
original_min_cost = ActiveModel::SecurePassword.min_cost
ActiveModel::SecurePassword.min_cost = false ActiveModel::SecurePassword.min_cost = false


begin @user.password = "secret"
@user.password = "secret" assert_equal BCrypt::Engine::DEFAULT_COST, @user.password_digest.cost
assert_equal BCrypt::Engine::DEFAULT_COST, @user.password_digest.cost
ensure
ActiveModel::SecurePassword.min_cost = original_min_cost
end
end end


test "Password digest cost honors bcrypt cost attribute when min_cost is false" do test "Password digest cost honors bcrypt cost attribute when min_cost is false" do
original_min_cost = ActiveModel::SecurePassword.min_cost
original_cost = BCrypt::Engine.cost

ActiveModel::SecurePassword.min_cost = false
BCrypt::Engine.cost = 5

begin begin
original_bcrypt_cost = BCrypt::Engine.cost
ActiveModel::SecurePassword.min_cost = false
BCrypt::Engine.cost = 5

@user.password = "secret" @user.password = "secret"
assert_equal BCrypt::Engine.cost, @user.password_digest.cost assert_equal BCrypt::Engine.cost, @user.password_digest.cost
ensure ensure
ActiveModel::SecurePassword.min_cost = original_min_cost BCrypt::Engine.cost = original_bcrypt_cost
BCrypt::Engine.cost = original_cost
end end
end end


test "Password digest cost can be set to bcrypt min cost to speed up tests" do test "Password digest cost can be set to bcrypt min cost to speed up tests" do
original_min_cost = ActiveModel::SecurePassword.min_cost
ActiveModel::SecurePassword.min_cost = true ActiveModel::SecurePassword.min_cost = true


begin @user.password = "secret"
@user.password = "secret" assert_equal BCrypt::Engine::MIN_COST, @user.password_digest.cost
assert_equal BCrypt::Engine::MIN_COST, @user.password_digest.cost
ensure
ActiveModel::SecurePassword.min_cost = original_min_cost
end
end end
end end
48 changes: 27 additions & 21 deletions activemodel/test/cases/serializers/json_serialization_test.rb
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -30,11 +30,6 @@ def setup
@contact.preferences = { 'shows' => 'anime' } @contact.preferences = { 'shows' => 'anime' }
end end


def teardown
# set to the default value
Contact.include_root_in_json = false
end

test "should not include root in json (class method)" do test "should not include root in json (class method)" do
json = @contact.to_json json = @contact.to_json


Expand All @@ -47,19 +42,25 @@ def teardown
end end


test "should include root in json if include_root_in_json is true" do test "should include root in json if include_root_in_json is true" do
Contact.include_root_in_json = true begin
json = @contact.to_json original_include_root_in_json = Contact.include_root_in_json

Contact.include_root_in_json = true
assert_match %r{^\{"contact":\{}, json json = @contact.to_json
assert_match %r{"name":"Konata Izumi"}, json
assert_match %r{"age":16}, json assert_match %r{^\{"contact":\{}, json
assert json.include?(%("created_at":#{ActiveSupport::JSON.encode(Time.utc(2006, 8, 1))})) assert_match %r{"name":"Konata Izumi"}, json
assert_match %r{"awesome":true}, json assert_match %r{"age":16}, json
assert_match %r{"preferences":\{"shows":"anime"\}}, json assert json.include?(%("created_at":#{ActiveSupport::JSON.encode(Time.utc(2006, 8, 1))}))
assert_match %r{"awesome":true}, json
assert_match %r{"preferences":\{"shows":"anime"\}}, json
ensure
Contact.include_root_in_json = original_include_root_in_json
end
end end


test "should include root in json (option) even if the default is set to false" do test "should include root in json (option) even if the default is set to false" do
json = @contact.to_json(root: true) json = @contact.to_json(root: true)

assert_match %r{^\{"contact":\{}, json assert_match %r{^\{"contact":\{}, json
end end


Expand Down Expand Up @@ -145,13 +146,18 @@ def @contact.favorite_quote; "Constraints are liberating"; end
end end


test "as_json should return a hash if include_root_in_json is true" do test "as_json should return a hash if include_root_in_json is true" do
Contact.include_root_in_json = true begin
json = @contact.as_json original_include_root_in_json = Contact.include_root_in_json

Contact.include_root_in_json = true
assert_kind_of Hash, json json = @contact.as_json
assert_kind_of Hash, json['contact']
%w(name age created_at awesome preferences).each do |field| assert_kind_of Hash, json
assert_equal @contact.send(field), json['contact'][field] assert_kind_of Hash, json['contact']
%w(name age created_at awesome preferences).each do |field|
assert_equal @contact.send(field), json['contact'][field]
end
ensure
Contact.include_root_in_json = original_include_root_in_json
end end
end end


Expand Down
66 changes: 33 additions & 33 deletions activemodel/test/cases/serializers/xml_serialization_test.rb
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -57,71 +57,71 @@ def setup
end end


test "should serialize default root" do test "should serialize default root" do
@xml = @contact.to_xml xml = @contact.to_xml
assert_match %r{^<contact>}, @xml assert_match %r{^<contact>}, xml
assert_match %r{</contact>$}, @xml assert_match %r{</contact>$}, xml
end end


test "should serialize namespaced root" do test "should serialize namespaced root" do
@xml = Admin::Contact.new(@contact.attributes).to_xml xml = Admin::Contact.new(@contact.attributes).to_xml
assert_match %r{^<contact>}, @xml assert_match %r{^<contact>}, xml
assert_match %r{</contact>$}, @xml assert_match %r{</contact>$}, xml
end end


test "should serialize default root with namespace" do test "should serialize default root with namespace" do
@xml = @contact.to_xml namespace: "http://xml.rubyonrails.org/contact" xml = @contact.to_xml namespace: "http://xml.rubyonrails.org/contact"
assert_match %r{^<contact xmlns="http://xml.rubyonrails.org/contact">}, @xml assert_match %r{^<contact xmlns="http://xml.rubyonrails.org/contact">}, xml
assert_match %r{</contact>$}, @xml assert_match %r{</contact>$}, xml
end end


test "should serialize custom root" do test "should serialize custom root" do
@xml = @contact.to_xml root: 'xml_contact' xml = @contact.to_xml root: 'xml_contact'
assert_match %r{^<xml-contact>}, @xml assert_match %r{^<xml-contact>}, xml
assert_match %r{</xml-contact>$}, @xml assert_match %r{</xml-contact>$}, xml
end end


test "should allow undasherized tags" do test "should allow undasherized tags" do
@xml = @contact.to_xml root: 'xml_contact', dasherize: false xml = @contact.to_xml root: 'xml_contact', dasherize: false
assert_match %r{^<xml_contact>}, @xml assert_match %r{^<xml_contact>}, xml
assert_match %r{</xml_contact>$}, @xml assert_match %r{</xml_contact>$}, xml
assert_match %r{<created_at}, @xml assert_match %r{<created_at}, xml
end end


test "should allow camelized tags" do test "should allow camelized tags" do
@xml = @contact.to_xml root: 'xml_contact', camelize: true xml = @contact.to_xml root: 'xml_contact', camelize: true
assert_match %r{^<XmlContact>}, @xml assert_match %r{^<XmlContact>}, xml
assert_match %r{</XmlContact>$}, @xml assert_match %r{</XmlContact>$}, xml
assert_match %r{<CreatedAt}, @xml assert_match %r{<CreatedAt}, xml
end end


test "should allow lower-camelized tags" do test "should allow lower-camelized tags" do
@xml = @contact.to_xml root: 'xml_contact', camelize: :lower xml = @contact.to_xml root: 'xml_contact', camelize: :lower
assert_match %r{^<xmlContact>}, @xml assert_match %r{^<xmlContact>}, xml
assert_match %r{</xmlContact>$}, @xml assert_match %r{</xmlContact>$}, xml
assert_match %r{<createdAt}, @xml assert_match %r{<createdAt}, xml
end end


test "should use serializable hash" do test "should use serializable hash" do
@contact = SerializableContact.new @contact = SerializableContact.new
@contact.name = 'aaron stack' @contact.name = 'aaron stack'
@contact.age = 25 @contact.age = 25


@xml = @contact.to_xml xml = @contact.to_xml
assert_match %r{<name>aaron stack</name>}, @xml assert_match %r{<name>aaron stack</name>}, xml
assert_match %r{<age type="integer">25</age>}, @xml assert_match %r{<age type="integer">25</age>}, xml
assert_no_match %r{<awesome>}, @xml assert_no_match %r{<awesome>}, xml
end end


test "should allow skipped types" do test "should allow skipped types" do
@xml = @contact.to_xml skip_types: true xml = @contact.to_xml skip_types: true
assert_match %r{<age>25</age>}, @xml assert_match %r{<age>25</age>}, xml
end end


test "should include yielded additions" do test "should include yielded additions" do
@xml = @contact.to_xml do |xml| xml = @contact.to_xml do |xml|
xml.creator "David" xml.creator "David"
end end
assert_match %r{<creator>David</creator>}, @xml assert_match %r{<creator>David</creator>}, xml
end end


test "should serialize string" do test "should serialize string" do
Expand Down Expand Up @@ -162,7 +162,7 @@ def setup
assert_match %r{<nationality>unknown</nationality>}, xml assert_match %r{<nationality>unknown</nationality>}, xml
end end


test 'should supply serializable to second proc argument' do test "should supply serializable to second proc argument" do
proc = Proc.new { |options, record| options[:builder].tag!('name-reverse', record.name.reverse) } proc = Proc.new { |options, record| options[:builder].tag!('name-reverse', record.name.reverse) }
xml = @contact.to_xml(procs: [ proc ]) xml = @contact.to_xml(procs: [ proc ])
assert_match %r{<name-reverse>kcats noraa</name-reverse>}, xml assert_match %r{<name-reverse>kcats noraa</name-reverse>}, xml
Expand Down
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -53,17 +53,17 @@ def test_validates_confirmation_of_for_ruby_class
end end


def test_title_confirmation_with_i18n_attribute def test_title_confirmation_with_i18n_attribute
@old_load_path, @old_backend = I18n.load_path.dup, I18n.backend begin
I18n.load_path.clear @old_load_path, @old_backend = I18n.load_path.dup, I18n.backend
I18n.backend = I18n::Backend::Simple.new I18n.load_path.clear
I18n.backend.store_translations('en', { I18n.backend = I18n::Backend::Simple.new
errors: { messages: { confirmation: "doesn't match %{attribute}" } }, I18n.backend.store_translations('en', {
activemodel: { attributes: { topic: { title: 'Test Title'} } } errors: { messages: { confirmation: "doesn't match %{attribute}" } },
}) activemodel: { attributes: { topic: { title: 'Test Title'} } }
})


Topic.validates_confirmation_of(:title) Topic.validates_confirmation_of(:title)


begin
t = Topic.new("title" => "We should be confirmed","title_confirmation" => "") t = Topic.new("title" => "We should be confirmed","title_confirmation" => "")
assert t.invalid? assert t.invalid?
assert_equal ["doesn't match Test Title"], t.errors[:title_confirmation] assert_equal ["doesn't match Test Title"], t.errors[:title_confirmation]
Expand Down
Loading

0 comments on commit cc6bc1c

Please sign in to comment.