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
Expand Up @@ -104,10 +104,14 @@ class AttributeMethodsTest < ActiveModel::TestCase
end

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_equal "value of foo", ModelWithAttributes.new.foo
assert_respond_to ModelWithAttributes.new, :foo
assert_equal "value of foo", ModelWithAttributes.new.foo
ensure
ModelWithAttributes.undefine_attribute_methods
end
end

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

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_equal "value of a?b", ModelWithWeirdNamesAttributes.new.send('a?b')
assert_respond_to ModelWithWeirdNamesAttributes.new, :'a?b'
assert_equal "value of a?b", ModelWithWeirdNamesAttributes.new.send('a?b')
ensure
ModelWithWeirdNamesAttributes.undefine_attribute_methods
end
end

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 baz", ModelWithAttributes.new.baz
assert_equal "value of foo", ModelWithAttributes.new.foo
assert_equal "value of baz", ModelWithAttributes.new.baz
ensure
ModelWithAttributes.undefine_attribute_methods
end
end

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_equal "value of foo", ModelWithAttributes.new.foo
assert_respond_to ModelWithAttributes.new, :foo
assert_equal "value of foo", ModelWithAttributes.new.foo
ensure
ModelWithAttributes.undefine_attribute_methods
end
end

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

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_equal "value of foo bar", ModelWithAttributesWithSpaces.new.send(:'foo bar')
assert_respond_to ModelWithAttributesWithSpaces.new, :'foo bar'
assert_equal "value of foo bar", ModelWithAttributesWithSpaces.new.send(:'foo bar')
ensure
ModelWithAttributesWithSpaces.undefine_attribute_methods
end
end

test '#alias_attribute works with attributes with spaces in their names' do
ModelWithAttributesWithSpaces.define_attribute_methods(:'foo bar')
ModelWithAttributesWithSpaces.alias_attribute(:'foo_bar', :'foo bar')
begin
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

test '#alias_attribute works with attributes named as a ruby keyword' do
ModelWithRubyKeywordNamedAttributes.define_attribute_methods([:begin, :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
begin
ModelWithRubyKeywordNamedAttributes.define_attribute_methods([:begin, :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
ensure
ModelWithRubyKeywordNamedAttributes.undefine_attribute_methods
end
end

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

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

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

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

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

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

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

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
original_bcrypt_cost = BCrypt::Engine.cost
ActiveModel::SecurePassword.min_cost = false
BCrypt::Engine.cost = 5

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

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

begin
@user.password = "secret"
assert_equal BCrypt::Engine::MIN_COST, @user.password_digest.cost
ensure
ActiveModel::SecurePassword.min_cost = original_min_cost
end
@user.password = "secret"
assert_equal BCrypt::Engine::MIN_COST, @user.password_digest.cost
end
end
48 changes: 27 additions & 21 deletions activemodel/test/cases/serializers/json_serialization_test.rb
Expand Up @@ -30,11 +30,6 @@ def setup
@contact.preferences = { 'shows' => 'anime' }
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
json = @contact.to_json

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

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

assert_match %r{^\{"contact":\{}, json
assert_match %r{"name":"Konata Izumi"}, json
assert_match %r{"age":16}, 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
begin
original_include_root_in_json = Contact.include_root_in_json
Contact.include_root_in_json = true
json = @contact.to_json

assert_match %r{^\{"contact":\{}, json
assert_match %r{"name":"Konata Izumi"}, json
assert_match %r{"age":16}, 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

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

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

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

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

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

assert_kind_of Hash, json
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

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

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

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

test "should serialize default root with namespace" do
@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>$}, @xml
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>$}, xml
end

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

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

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

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

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

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

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

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

test "should serialize string" do
Expand Down Expand Up @@ -162,7 +162,7 @@ def setup
assert_match %r{<nationality>unknown</nationality>}, xml
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) }
xml = @contact.to_xml(procs: [ proc ])
assert_match %r{<name-reverse>kcats noraa</name-reverse>}, xml
Expand Down
Expand Up @@ -53,17 +53,17 @@ def test_validates_confirmation_of_for_ruby_class
end

def test_title_confirmation_with_i18n_attribute
@old_load_path, @old_backend = I18n.load_path.dup, I18n.backend
I18n.load_path.clear
I18n.backend = I18n::Backend::Simple.new
I18n.backend.store_translations('en', {
errors: { messages: { confirmation: "doesn't match %{attribute}" } },
activemodel: { attributes: { topic: { title: 'Test Title'} } }
})
begin
@old_load_path, @old_backend = I18n.load_path.dup, I18n.backend
I18n.load_path.clear
I18n.backend = I18n::Backend::Simple.new
I18n.backend.store_translations('en', {
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" => "")
assert t.invalid?
assert_equal ["doesn't match Test Title"], t.errors[:title_confirmation]
Expand Down

0 comments on commit cc6bc1c

Please sign in to comment.