mirror of
https://github.com/rails/rails.git
synced 2022-11-09 12:12:34 -05:00
Do not use instantiated fixtures (in general) in tests. Also, support the use of transactional fixtures by setting the AR_TX_FIXTURES environment variable to "yes".
git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@1399 5ecf4fe2-1ee6-0310-87b1-e25e094e27de
This commit is contained in:
parent
7f9ffb2ebf
commit
2c0fa32088
23 changed files with 253 additions and 222 deletions
|
@ -33,3 +33,14 @@ You can also run all the suites on a specific adapter with:
|
|||
|
||||
cd test; all.sh "connections/native_mysql"
|
||||
|
||||
== Faster tests
|
||||
|
||||
If you are using a database that supports transactions, you can set the
|
||||
"AR_TX_FIXTURES" environment variable to "yes" to use transactional fixtures.
|
||||
This gives a very large speed boost. With rake:
|
||||
|
||||
rake AR_TX_FIXTURES=yes
|
||||
|
||||
Or, by hand:
|
||||
|
||||
AR_TX_FIXTURES=yes ruby -I connections/native_sqlite3 base_test.rb
|
||||
|
|
|
@ -441,6 +441,20 @@ module Test #:nodoc:
|
|||
end
|
||||
end
|
||||
|
||||
def self.uses_transaction(*methods)
|
||||
@uses_transaction ||= []
|
||||
@uses_transaction.concat methods.map { |m| m.to_s }
|
||||
end
|
||||
|
||||
def self.uses_transaction?(method)
|
||||
@uses_transaction && @uses_transaction.include?(method.to_s)
|
||||
end
|
||||
|
||||
def use_transactional_fixtures?
|
||||
use_transactional_fixtures &&
|
||||
!self.class.uses_transaction?(method_name)
|
||||
end
|
||||
|
||||
def setup_with_fixtures
|
||||
if pre_loaded_fixtures && !use_transactional_fixtures
|
||||
raise RuntimeError, 'pre_loaded_fixtures requires use_transactional_fixtures'
|
||||
|
@ -449,7 +463,7 @@ module Test #:nodoc:
|
|||
@fixture_cache = Hash.new
|
||||
|
||||
# Load fixtures once and begin transaction.
|
||||
if use_transactional_fixtures
|
||||
if use_transactional_fixtures?
|
||||
if @@already_loaded_fixtures[self.class]
|
||||
@loaded_fixtures = @@already_loaded_fixtures[self.class]
|
||||
else
|
||||
|
@ -461,6 +475,7 @@ module Test #:nodoc:
|
|||
|
||||
# Load fixtures for every test.
|
||||
else
|
||||
@@already_loaded_fixtures[self.class] = nil
|
||||
load_fixtures
|
||||
end
|
||||
|
||||
|
@ -472,7 +487,7 @@ module Test #:nodoc:
|
|||
|
||||
def teardown_with_fixtures
|
||||
# Rollback changes.
|
||||
if use_transactional_fixtures
|
||||
if use_transactional_fixtures?
|
||||
ActiveRecord::Base.connection.rollback_db_transaction
|
||||
ActiveRecord::Base.unlock_mutex
|
||||
end
|
||||
|
|
|
@ -19,6 +19,6 @@ class Test::Unit::TestCase #:nodoc:
|
|||
end
|
||||
|
||||
Test::Unit::TestCase.fixture_path = File.dirname(__FILE__) + "/fixtures/"
|
||||
#Test::Unit::TestCase.use_instantiated_fixtures = false
|
||||
#Test::Unit::TestCase.use_transactional_fixtures = (ENV['AR_TX_FIXTURES'] == "yes")
|
||||
Test::Unit::TestCase.use_instantiated_fixtures = false
|
||||
Test::Unit::TestCase.use_transactional_fixtures = (ENV['AR_TX_FIXTURES'] == "yes")
|
||||
|
||||
|
|
|
@ -5,43 +5,43 @@ class AggregationsTest < Test::Unit::TestCase
|
|||
fixtures :customers
|
||||
|
||||
def test_find_single_value_object
|
||||
assert_equal 50, @david.balance.amount
|
||||
assert_kind_of Money, @david.balance
|
||||
assert_equal 300, @david.balance.exchange_to("DKK").amount
|
||||
assert_equal 50, customers(:david).balance.amount
|
||||
assert_kind_of Money, customers(:david).balance
|
||||
assert_equal 300, customers(:david).balance.exchange_to("DKK").amount
|
||||
end
|
||||
|
||||
def test_find_multiple_value_object
|
||||
assert_equal @customers["david"]["address_street"], @david.address.street
|
||||
assert_equal customers(:david).address_street, customers(:david).address.street
|
||||
assert(
|
||||
@david.address.close_to?(Address.new("Different Street", @customers["david"]["address_city"], @customers["david"]["address_country"]))
|
||||
customers(:david).address.close_to?(Address.new("Different Street", customers(:david).address_city, customers(:david).address_country))
|
||||
)
|
||||
end
|
||||
|
||||
def test_change_single_value_object
|
||||
@david.balance = Money.new(100)
|
||||
@david.save
|
||||
customers(:david).balance = Money.new(100)
|
||||
customers(:david).save
|
||||
assert_equal 100, Customer.find(1).balance.amount
|
||||
end
|
||||
|
||||
def test_immutable_value_objects
|
||||
@david.balance = Money.new(100)
|
||||
assert_raises(TypeError) { @david.balance.instance_eval { @amount = 20 } }
|
||||
customers(:david).balance = Money.new(100)
|
||||
assert_raises(TypeError) { customers(:david).balance.instance_eval { @amount = 20 } }
|
||||
end
|
||||
|
||||
def test_inferred_mapping
|
||||
assert_equal "35.544623640962634", @david.gps_location.latitude
|
||||
assert_equal "-105.9309951055148", @david.gps_location.longitude
|
||||
assert_equal "35.544623640962634", customers(:david).gps_location.latitude
|
||||
assert_equal "-105.9309951055148", customers(:david).gps_location.longitude
|
||||
|
||||
@david.gps_location = GpsLocation.new("39x-110")
|
||||
customers(:david).gps_location = GpsLocation.new("39x-110")
|
||||
|
||||
assert_equal "39", @david.gps_location.latitude
|
||||
assert_equal "-110", @david.gps_location.longitude
|
||||
assert_equal "39", customers(:david).gps_location.latitude
|
||||
assert_equal "-110", customers(:david).gps_location.longitude
|
||||
|
||||
@david.save
|
||||
customers(:david).save
|
||||
|
||||
@david.reload
|
||||
customers(:david).reload
|
||||
|
||||
assert_equal "39", @david.gps_location.latitude
|
||||
assert_equal "-110", @david.gps_location.longitude
|
||||
assert_equal "39", customers(:david).gps_location.latitude
|
||||
assert_equal "-110", customers(:david).gps_location.longitude
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -556,6 +556,7 @@ class HasManyAssociationsTest < Test::Unit::TestCase
|
|||
assert_nothing_raised { topic.destroy }
|
||||
end
|
||||
|
||||
uses_transaction :test_dependence_with_transaction_support_on_failure
|
||||
def test_dependence_with_transaction_support_on_failure
|
||||
assert_equal 2, Client.find_all.length
|
||||
firm = Firm.find_first
|
||||
|
@ -851,7 +852,7 @@ class HasAndBelongsToManyAssociationsTest < Test::Unit::TestCase
|
|||
def test_uniq_before_the_fact
|
||||
projects(:active_record).developers << developers(:jamis)
|
||||
projects(:active_record).developers << developers(:david)
|
||||
assert_equal 2, projects(:active_record).developers.size
|
||||
assert_equal 2, projects(:active_record, :reload).developers.size
|
||||
end
|
||||
|
||||
def test_deleting
|
||||
|
@ -933,7 +934,7 @@ class HasAndBelongsToManyAssociationsTest < Test::Unit::TestCase
|
|||
assert_equal 1, projects(:active_record).developers_named_david.size
|
||||
|
||||
projects(:active_record).developers_named_david.clear
|
||||
assert_equal 1, projects(:active_record).developers.size
|
||||
assert_equal 1, projects(:active_record, :reload).developers.size
|
||||
end
|
||||
|
||||
def test_find_in_association
|
||||
|
|
|
@ -42,7 +42,7 @@ class BasicsTest < Test::Unit::TestCase
|
|||
topic.save
|
||||
assert_equal("Budget", topic.title)
|
||||
assert_equal("Jason", topic.author_name)
|
||||
assert_equal(@topics["first"]["author_email_address"], Topic.find(1).author_email_address)
|
||||
assert_equal(topics(:first).author_email_address, Topic.find(1).author_email_address)
|
||||
end
|
||||
|
||||
def test_integers_as_nil
|
||||
|
@ -110,7 +110,7 @@ class BasicsTest < Test::Unit::TestCase
|
|||
end
|
||||
|
||||
def test_attributes_hash
|
||||
assert_equal @projects['active_record'].to_hash, Project.find_first.attributes
|
||||
assert_equal @loaded_fixtures['projects']['active_record'].to_hash, Project.find_first.attributes
|
||||
end
|
||||
|
||||
def test_create
|
||||
|
@ -229,14 +229,14 @@ class BasicsTest < Test::Unit::TestCase
|
|||
def test_load
|
||||
topics = Topic.find_all nil, "id"
|
||||
assert_equal(2, topics.size)
|
||||
assert_equal(@topics["first"]["title"], topics.first.title)
|
||||
assert_equal(topics(:first).title, topics.first.title)
|
||||
end
|
||||
|
||||
def test_load_with_condition
|
||||
topics = Topic.find_all "author_name = 'Mary'"
|
||||
|
||||
assert_equal(1, topics.size)
|
||||
assert_equal(@topics["second"]["title"], topics.first.title)
|
||||
assert_equal(topics(:second).title, topics.first.title)
|
||||
end
|
||||
|
||||
def test_table_name_guesses
|
||||
|
@ -721,35 +721,35 @@ class BasicsTest < Test::Unit::TestCase
|
|||
end
|
||||
|
||||
def test_increment_attribute
|
||||
assert_equal 0, @topics["first"].find.replies_count
|
||||
@topics["first"].find.increment! :replies_count
|
||||
assert_equal 1, @topics["first"].find.replies_count
|
||||
assert_equal 0, topics(:first).replies_count
|
||||
topics(:first).increment! :replies_count
|
||||
assert_equal 1, topics(:first, :reload).replies_count
|
||||
|
||||
@topics["first"].find.increment(:replies_count).increment!(:replies_count)
|
||||
assert_equal 3, @topics["first"].find.replies_count
|
||||
topics(:first).increment(:replies_count).increment!(:replies_count)
|
||||
assert_equal 3, topics(:first, :reload).replies_count
|
||||
end
|
||||
|
||||
def test_increment_nil_attribute
|
||||
assert_nil @topics["first"].find.parent_id
|
||||
@topics["first"].find.increment! :parent_id
|
||||
assert_equal 1, @topics["first"].find.parent_id
|
||||
assert_nil topics(:first).parent_id
|
||||
topics(:first).increment! :parent_id
|
||||
assert_equal 1, topics(:first).parent_id
|
||||
end
|
||||
|
||||
def test_decrement_attribute
|
||||
@topics["first"].find.increment(:replies_count).increment!(:replies_count)
|
||||
assert_equal 2, @topics["first"].find.replies_count
|
||||
topics(:first).increment(:replies_count).increment!(:replies_count)
|
||||
assert_equal 2, topics(:first).replies_count
|
||||
|
||||
@topics["first"].find.decrement!(:replies_count)
|
||||
assert_equal 1, @topics["first"].find.replies_count
|
||||
topics(:first).decrement!(:replies_count)
|
||||
assert_equal 1, topics(:first, :reload).replies_count
|
||||
|
||||
@topics["first"].find.decrement(:replies_count).decrement!(:replies_count)
|
||||
assert_equal -1, @topics["first"].find.replies_count
|
||||
topics(:first).decrement(:replies_count).decrement!(:replies_count)
|
||||
assert_equal -1, topics(:first, :reload).replies_count
|
||||
end
|
||||
|
||||
def test_toggle_attribute
|
||||
assert !@topics["first"].find.approved?
|
||||
@topics["first"].find.toggle!(:approved)
|
||||
assert @topics["first"].find.approved?
|
||||
assert !topics(:first).approved?
|
||||
topics(:first).toggle!(:approved)
|
||||
assert topics(:first).approved?
|
||||
end
|
||||
|
||||
def test_reload
|
||||
|
|
|
@ -51,9 +51,7 @@ end
|
|||
|
||||
|
||||
class CallbacksTest < Test::Unit::TestCase
|
||||
def setup
|
||||
@developers = create_fixtures('developers')
|
||||
end
|
||||
fixtures :developers
|
||||
|
||||
def test_initialize
|
||||
david = CallbackDeveloper.new
|
||||
|
|
|
@ -16,10 +16,8 @@ raise "ActiveRecord should have barked on bad collection keys" unless bad_collec
|
|||
|
||||
|
||||
class DeprecatedAssociationsTest < Test::Unit::TestCase
|
||||
def setup
|
||||
create_fixtures "accounts", "companies", "developers", "projects", "developers_projects", "topics"
|
||||
@signals37 = Firm.find(1)
|
||||
end
|
||||
fixtures :accounts, :companies, :developers, :projects, :topics,
|
||||
:developers_projects
|
||||
|
||||
def test_has_many_find
|
||||
assert_equal 2, Firm.find_first.clients.length
|
||||
|
@ -67,6 +65,7 @@ class DeprecatedAssociationsTest < Test::Unit::TestCase
|
|||
assert_equal 0, Client.find_all.length
|
||||
end
|
||||
|
||||
uses_transaction :test_has_many_dependence_with_transaction_support_on_failure
|
||||
def test_has_many_dependence_with_transaction_support_on_failure
|
||||
assert_equal 2, Client.find_all.length
|
||||
|
||||
|
@ -94,7 +93,7 @@ class DeprecatedAssociationsTest < Test::Unit::TestCase
|
|||
end
|
||||
|
||||
def test_belongs_to
|
||||
assert_equal @signals37.name, Client.find(3).firm.name
|
||||
assert_equal companies(:first_firm).name, Client.find(3).firm.name
|
||||
assert Client.find(3).has_firm?, "Microsoft should have a firm"
|
||||
# assert !Company.find(1).has_firm?, "37signals shouldn't have a firm"
|
||||
end
|
||||
|
@ -115,25 +114,25 @@ class DeprecatedAssociationsTest < Test::Unit::TestCase
|
|||
end
|
||||
|
||||
def test_has_one
|
||||
assert @signals37.account?(Account.find(1))
|
||||
assert_equal Account.find(1).credit_limit, @signals37.account.credit_limit
|
||||
assert @signals37.has_account?, "37signals should have an account"
|
||||
assert Account.find(1).firm?(@signals37), "37signals account should be able to backtrack"
|
||||
assert companies(:first_firm).account?(Account.find(1))
|
||||
assert_equal Account.find(1).credit_limit, companies(:first_firm).account.credit_limit
|
||||
assert companies(:first_firm).has_account?, "37signals should have an account"
|
||||
assert Account.find(1).firm?(companies(:first_firm)), "37signals account should be able to backtrack"
|
||||
assert Account.find(1).has_firm?, "37signals account should be able to backtrack"
|
||||
|
||||
assert !Account.find(2).has_firm?, "Unknown isn't linked"
|
||||
assert !Account.find(2).firm?(@signals37), "Unknown isn't linked"
|
||||
assert !Account.find(2).firm?(companies(:first_firm)), "Unknown isn't linked"
|
||||
end
|
||||
|
||||
def test_has_many_dependence_on_account
|
||||
assert_equal 2, Account.find_all.length
|
||||
@signals37.destroy
|
||||
companies(:first_firm).destroy
|
||||
assert_equal 1, Account.find_all.length
|
||||
end
|
||||
|
||||
def test_find_in
|
||||
assert_equal Client.find(2).name, @signals37.find_in_clients(2).name
|
||||
assert_raises(ActiveRecord::RecordNotFound) { @signals37.find_in_clients(6) }
|
||||
assert_equal Client.find(2).name, companies(:first_firm).find_in_clients(2).name
|
||||
assert_raises(ActiveRecord::RecordNotFound) { companies(:first_firm).find_in_clients(6) }
|
||||
end
|
||||
|
||||
def test_force_reload
|
||||
|
@ -157,21 +156,21 @@ class DeprecatedAssociationsTest < Test::Unit::TestCase
|
|||
end
|
||||
|
||||
def test_included_in_collection
|
||||
assert @signals37.clients.include?(Client.find(2))
|
||||
assert companies(:first_firm).clients.include?(Client.find(2))
|
||||
end
|
||||
|
||||
def test_build_to_collection
|
||||
assert_equal 1, @signals37.clients_of_firm_count
|
||||
new_client = @signals37.build_to_clients_of_firm("name" => "Another Client")
|
||||
assert_equal 1, companies(:first_firm).clients_of_firm_count
|
||||
new_client = companies(:first_firm).build_to_clients_of_firm("name" => "Another Client")
|
||||
assert_equal "Another Client", new_client.name
|
||||
assert new_client.save
|
||||
|
||||
assert new_client.firm?(@signals37)
|
||||
assert_equal 2, @signals37.clients_of_firm_count(true)
|
||||
assert new_client.firm?(companies(:first_firm))
|
||||
assert_equal 2, companies(:first_firm).clients_of_firm_count(true)
|
||||
end
|
||||
|
||||
def test_create_in_collection
|
||||
assert_equal @signals37.create_in_clients_of_firm("name" => "Another Client"), @signals37.clients_of_firm(true).last
|
||||
assert_equal companies(:first_firm).create_in_clients_of_firm("name" => "Another Client"), companies(:first_firm).clients_of_firm(true).last
|
||||
end
|
||||
|
||||
def test_has_and_belongs_to_many
|
||||
|
@ -317,13 +316,13 @@ class DeprecatedAssociationsTest < Test::Unit::TestCase
|
|||
end
|
||||
|
||||
def test_has_one
|
||||
assert @signals37.account?(Account.find(1))
|
||||
assert @signals37.has_account?, "37signals should have an account"
|
||||
assert Account.find(1).firm?(@signals37), "37signals account should be able to backtrack"
|
||||
assert companies(:first_firm).account?(Account.find(1))
|
||||
assert companies(:first_firm).has_account?, "37signals should have an account"
|
||||
assert Account.find(1).firm?(companies(:first_firm)), "37signals account should be able to backtrack"
|
||||
assert Account.find(1).has_firm?, "37signals account should be able to backtrack"
|
||||
|
||||
assert !Account.find(2).has_firm?, "Unknown isn't linked"
|
||||
assert !Account.find(2).firm?(@signals37), "Unknown isn't linked"
|
||||
assert !Account.find(2).firm?(companies(:first_firm)), "Unknown isn't linked"
|
||||
end
|
||||
|
||||
def test_has_one_build
|
||||
|
|
|
@ -11,7 +11,7 @@ class FinderTest < Test::Unit::TestCase
|
|||
entrants = Entrant.find_all nil, "id ASC", 2
|
||||
|
||||
assert_equal(2, entrants.size)
|
||||
assert_equal(@entrants["first"]["name"], entrants.first.name)
|
||||
assert_equal(entrants(:first).name, entrants.first.name)
|
||||
end
|
||||
|
||||
def test_find_all_with_prepared_limit_and_offset
|
||||
|
@ -23,13 +23,13 @@ class FinderTest < Test::Unit::TestCase
|
|||
entrants = Entrant.find_all nil, "id ASC", [2, 1]
|
||||
|
||||
assert_equal(2, entrants.size)
|
||||
assert_equal(@entrants["second"]["name"], entrants.first.name)
|
||||
assert_equal(entrants(:second).name, entrants.first.name)
|
||||
end
|
||||
end
|
||||
|
||||
def test_find_first
|
||||
first = Topic.find_first "title = 'The First Topic'"
|
||||
assert_equal(@topics["first"]["title"], first.title)
|
||||
assert_equal(topics(:first).title, first.title)
|
||||
end
|
||||
|
||||
def test_find_first_failing
|
||||
|
@ -129,10 +129,10 @@ class FinderTest < Test::Unit::TestCase
|
|||
|
||||
def test_find_all_by_one_attribute_with_options
|
||||
topics = Topic.find_all_by_content("Have a nice day", nil, "id DESC")
|
||||
assert @topics["first"].find, topics.last
|
||||
assert topics(:first), topics.last
|
||||
|
||||
topics = Topic.find_all_by_content("Have a nice day", nil, "id DESC")
|
||||
assert @topics["first"].find, topics.first
|
||||
assert topics(:first), topics.first
|
||||
end
|
||||
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@ class FinderTest < Test::Unit::TestCase
|
|||
fixtures :companies, :topics, :entrants, :developers
|
||||
|
||||
def test_find
|
||||
assert_equal(@topics["first"]["title"], Topic.find(1).title)
|
||||
assert_equal(topics(:first).title, Topic.find(1).title)
|
||||
end
|
||||
|
||||
def test_exists
|
||||
|
@ -25,7 +25,7 @@ class FinderTest < Test::Unit::TestCase
|
|||
|
||||
def test_find_by_ids
|
||||
assert_equal(2, Topic.find(1, 2).length)
|
||||
assert_equal(@topics["second"]["title"], Topic.find([ 2 ]).first.title)
|
||||
assert_equal(topics(:second).title, Topic.find([ 2 ]).first.title)
|
||||
end
|
||||
|
||||
def test_find_by_ids_missing_one
|
||||
|
@ -38,7 +38,7 @@ class FinderTest < Test::Unit::TestCase
|
|||
entrants = Entrant.find(:all, :order => "id ASC", :limit => 2)
|
||||
|
||||
assert_equal(2, entrants.size)
|
||||
assert_equal(@entrants["first"]["name"], entrants.first.name)
|
||||
assert_equal(entrants(:first).name, entrants.first.name)
|
||||
end
|
||||
|
||||
def test_find_all_with_prepared_limit_and_offset
|
||||
|
@ -50,7 +50,7 @@ class FinderTest < Test::Unit::TestCase
|
|||
entrants = Entrant.find(:all, :order => "id ASC", :limit => 2, :offset => 1)
|
||||
|
||||
assert_equal(2, entrants.size)
|
||||
assert_equal(@entrants["second"]["name"], entrants.first.name)
|
||||
assert_equal(entrants(:second).name, entrants.first.name)
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -58,19 +58,19 @@ class FinderTest < Test::Unit::TestCase
|
|||
topics = Topic.find_by_sql "SELECT * FROM topics WHERE author_name = 'Mary'"
|
||||
|
||||
assert_equal(1, topics.size)
|
||||
assert_equal(@topics["second"]["title"], topics.first.title)
|
||||
assert_equal(topics(:second).title, topics.first.title)
|
||||
end
|
||||
|
||||
def test_find_with_prepared_select_statement
|
||||
topics = Topic.find_by_sql ["SELECT * FROM topics WHERE author_name = ?", "Mary"]
|
||||
|
||||
assert_equal(1, topics.size)
|
||||
assert_equal(@topics["second"]["title"], topics.first.title)
|
||||
assert_equal(topics(:second).title, topics.first.title)
|
||||
end
|
||||
|
||||
def test_find_first
|
||||
first = Topic.find(:first, :conditions => "title = 'The First Topic'")
|
||||
assert_equal(@topics["first"]["title"], first.title)
|
||||
assert_equal(topics(:first).title, first.title)
|
||||
end
|
||||
|
||||
def test_find_first_failing
|
||||
|
@ -182,7 +182,7 @@ class FinderTest < Test::Unit::TestCase
|
|||
end
|
||||
|
||||
def test_find_by_one_attribute
|
||||
assert_equal @topics["first"].find, Topic.find_by_title("The First Topic")
|
||||
assert_equal topics(:first), Topic.find_by_title("The First Topic")
|
||||
assert_nil Topic.find_by_title("The First Topic!")
|
||||
end
|
||||
|
||||
|
@ -191,24 +191,24 @@ class FinderTest < Test::Unit::TestCase
|
|||
end
|
||||
|
||||
def test_find_by_two_attributes
|
||||
assert_equal @topics["first"].find, Topic.find_by_title_and_author_name("The First Topic", "David")
|
||||
assert_equal topics(:first), Topic.find_by_title_and_author_name("The First Topic", "David")
|
||||
assert_nil Topic.find_by_title_and_author_name("The First Topic", "Mary")
|
||||
end
|
||||
|
||||
def test_find_all_by_one_attribute
|
||||
topics = Topic.find_all_by_content("Have a nice day")
|
||||
assert_equal 2, topics.size
|
||||
assert topics.include?(@topics["first"].find)
|
||||
assert topics.include?(topics(:first))
|
||||
|
||||
assert_equal [], Topic.find_all_by_title("The First Topic!!")
|
||||
end
|
||||
|
||||
def test_find_all_by_one_attribute_with_options
|
||||
topics = Topic.find_all_by_content("Have a nice day", :order => "id DESC")
|
||||
assert @topics["first"].find, topics.last
|
||||
assert topics(:first), topics.last
|
||||
|
||||
topics = Topic.find_all_by_content("Have a nice day", :order => "id")
|
||||
assert @topics["first"].find, topics.first
|
||||
assert topics(:first), topics.first
|
||||
end
|
||||
|
||||
def test_find_all_by_array_attribute
|
||||
|
@ -218,11 +218,11 @@ class FinderTest < Test::Unit::TestCase
|
|||
def test_find_all_by_boolean_attribute
|
||||
topics = Topic.find_all_by_approved(false)
|
||||
assert_equal 1, topics.size
|
||||
assert topics.include?(@topics["first"].find)
|
||||
assert topics.include?(topics(:first))
|
||||
|
||||
topics = Topic.find_all_by_approved(true)
|
||||
assert_equal 1, topics.size
|
||||
assert topics.include?(@topics["second"].find)
|
||||
assert topics.include?(topics(:second))
|
||||
end
|
||||
|
||||
def test_find_by_nil_attribute
|
||||
|
|
|
@ -155,26 +155,26 @@ CREATE TABLE `tasks` (
|
|||
`starting` datetime NOT NULL default '0000-00-00 00:00:00',
|
||||
`ending` datetime NOT NULL default '0000-00-00 00:00:00',
|
||||
PRIMARY KEY (`id`)
|
||||
);
|
||||
) TYPE=InnoDB;
|
||||
|
||||
CREATE TABLE `categories` (
|
||||
`id` int(11) NOT NULL auto_increment,
|
||||
`name` VARCHAR(255) NOT NULL,
|
||||
PRIMARY KEY (`id`)
|
||||
);
|
||||
) TYPE=InnoDB;
|
||||
|
||||
CREATE TABLE `categories_posts` (
|
||||
`category_id` int(11) NOT NULL,
|
||||
`post_id` int(11) NOT NULL
|
||||
);
|
||||
) TYPE=InnoDB;
|
||||
|
||||
CREATE TABLE `fk_test_has_pk` (
|
||||
`id` INTEGER NOT NULL PRIMARY KEY
|
||||
);
|
||||
) TYPE=InnoDB;
|
||||
|
||||
CREATE TABLE `fk_test_has_fk` (
|
||||
`id` INTEGER NOT NULL PRIMARY KEY,
|
||||
`fk_id` INTEGER NOT NULL,
|
||||
|
||||
FOREIGN KEY (`fk_id`) REFERENCES `fk_test_has_pk`(`id`)
|
||||
);
|
||||
) TYPE=InnoDB;
|
||||
|
|
|
@ -6,6 +6,9 @@ require 'fixtures/task'
|
|||
require 'fixtures/reply'
|
||||
|
||||
class FixturesTest < Test::Unit::TestCase
|
||||
self.use_instantiated_fixtures = true
|
||||
self.use_transactional_fixtures = false
|
||||
|
||||
fixtures :topics, :developers, :accounts, :tasks
|
||||
|
||||
FIXTURES = %w( accounts companies customers
|
||||
|
@ -141,7 +144,9 @@ end
|
|||
|
||||
|
||||
class FixturesWithoutInstanceInstantiationTest < Test::Unit::TestCase
|
||||
self.use_instantiated_fixtures = true
|
||||
self.use_instantiated_fixtures = :no_instances
|
||||
|
||||
fixtures :topics, :developers, :accounts
|
||||
|
||||
def test_without_instance_instantiation
|
||||
|
@ -154,7 +159,9 @@ end
|
|||
|
||||
|
||||
class TransactionalFixturesTest < Test::Unit::TestCase
|
||||
self.use_instantiated_fixtures = true
|
||||
self.use_transactional_fixtures = true
|
||||
|
||||
fixtures :topics
|
||||
|
||||
def test_destroy
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
require 'abstract_unit'
|
||||
require 'fixtures/topic'
|
||||
require 'fixtures/developer'
|
||||
require 'fixtures/reply'
|
||||
|
||||
class Topic; def after_find() end end
|
||||
class Developer; def after_find() end end
|
||||
|
@ -54,9 +55,7 @@ class MultiObserver < ActiveRecord::Observer
|
|||
end
|
||||
|
||||
class LifecycleTest < Test::Unit::TestCase
|
||||
def setup
|
||||
@topics, @developers = create_fixtures("topics", "developers")
|
||||
end
|
||||
fixtures :topics, :developers
|
||||
|
||||
def test_before_destroy
|
||||
assert_equal 2, Topic.count
|
||||
|
@ -106,4 +105,4 @@ class LifecycleTest < Test::Unit::TestCase
|
|||
developer = Developer.find(1)
|
||||
assert_equal multi_observer.record.name, developer.name
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -2,9 +2,7 @@ require 'abstract_unit'
|
|||
require 'fixtures/person'
|
||||
|
||||
class LockingTest < Test::Unit::TestCase
|
||||
def setup
|
||||
@people = create_fixtures('people')
|
||||
end
|
||||
fixtures :people
|
||||
|
||||
def test_lock_existing
|
||||
p1 = Person.find(1)
|
||||
|
@ -31,4 +29,4 @@ class LockingTest < Test::Unit::TestCase
|
|||
p2.save
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -147,37 +147,37 @@ class MixinNestedSetTest < Test::Unit::TestCase
|
|||
end
|
||||
|
||||
def test_common_usage
|
||||
@set_1.add_child( @set_2 )
|
||||
assert_equal( 1, @set_1.direct_children.length )
|
||||
mixins(:set_1).add_child( mixins(:set_2) )
|
||||
assert_equal( 1, mixins(:set_1).direct_children.length )
|
||||
|
||||
@set_2.add_child( @set_3 )
|
||||
assert_equal( 1, @set_1.direct_children.length )
|
||||
mixins(:set_2).add_child( mixins(:set_3) )
|
||||
assert_equal( 1, mixins(:set_1).direct_children.length )
|
||||
|
||||
# Local cache is now out of date!
|
||||
# Problem: the update_alls update all objects up the tree
|
||||
@set_1.reload
|
||||
assert_equal( 2, @set_1.all_children.length )
|
||||
mixins(:set_1).reload
|
||||
assert_equal( 2, mixins(:set_1).all_children.length )
|
||||
|
||||
assert_equal( 1, @set_1.lft )
|
||||
assert_equal( 2, @set_2.lft )
|
||||
assert_equal( 3, @set_3.lft )
|
||||
assert_equal( 4, @set_3.rgt )
|
||||
assert_equal( 5, @set_2.rgt )
|
||||
assert_equal( 6, @set_1.rgt )
|
||||
assert_equal( 1, mixins(:set_1).lft )
|
||||
assert_equal( 2, mixins(:set_2).lft )
|
||||
assert_equal( 3, mixins(:set_3).lft )
|
||||
assert_equal( 4, mixins(:set_3).rgt )
|
||||
assert_equal( 5, mixins(:set_2).rgt )
|
||||
assert_equal( 6, mixins(:set_1).rgt )
|
||||
|
||||
assert( @set_1.root? )
|
||||
assert( mixins(:set_1).root? )
|
||||
|
||||
begin
|
||||
@set_4.add_child( @set_1 )
|
||||
mixins(:set_4).add_child( mixins(:set_1) )
|
||||
fail
|
||||
rescue
|
||||
end
|
||||
|
||||
assert_equal( 2, @set_1.all_children.length )
|
||||
assert_equal( 2, mixins(:set_1).all_children.length )
|
||||
|
||||
@set_1.add_child @set_4
|
||||
mixins(:set_1).add_child mixins(:set_4)
|
||||
|
||||
assert_equal( 3, @set_1.all_children.length )
|
||||
assert_equal( 3, mixins(:set_1).all_children.length )
|
||||
|
||||
|
||||
end
|
||||
|
|
|
@ -9,68 +9,68 @@ class ListTest < Test::Unit::TestCase
|
|||
|
||||
def test_reordering
|
||||
|
||||
assert_equal [@mixins['list_1'].find,
|
||||
@mixins['list_2'].find,
|
||||
@mixins['list_3'].find,
|
||||
@mixins['list_4'].find],
|
||||
assert_equal [mixins(:list_1),
|
||||
mixins(:list_2),
|
||||
mixins(:list_3),
|
||||
mixins(:list_4)],
|
||||
ListMixin.find_all("parent_id=5", "pos")
|
||||
|
||||
@mixins['list_2'].find.move_lower
|
||||
mixins(:list_2).move_lower
|
||||
|
||||
assert_equal [@mixins['list_1'].find,
|
||||
@mixins['list_3'].find,
|
||||
@mixins['list_2'].find,
|
||||
@mixins['list_4'].find],
|
||||
assert_equal [mixins(:list_1),
|
||||
mixins(:list_3),
|
||||
mixins(:list_2),
|
||||
mixins(:list_4)],
|
||||
ListMixin.find_all("parent_id=5", "pos")
|
||||
|
||||
@mixins['list_2'].find.move_higher
|
||||
mixins(:list_2).move_higher
|
||||
|
||||
assert_equal [@mixins['list_1'].find,
|
||||
@mixins['list_2'].find,
|
||||
@mixins['list_3'].find,
|
||||
@mixins['list_4'].find],
|
||||
assert_equal [mixins(:list_1),
|
||||
mixins(:list_2),
|
||||
mixins(:list_3),
|
||||
mixins(:list_4)],
|
||||
ListMixin.find_all("parent_id=5", "pos")
|
||||
|
||||
@mixins['list_1'].find.move_to_bottom
|
||||
mixins(:list_1).move_to_bottom
|
||||
|
||||
assert_equal [@mixins['list_2'].find,
|
||||
@mixins['list_3'].find,
|
||||
@mixins['list_4'].find,
|
||||
@mixins['list_1'].find],
|
||||
assert_equal [mixins(:list_2),
|
||||
mixins(:list_3),
|
||||
mixins(:list_4),
|
||||
mixins(:list_1)],
|
||||
ListMixin.find_all("parent_id=5", "pos")
|
||||
|
||||
@mixins['list_1'].find.move_to_top
|
||||
mixins(:list_1).move_to_top
|
||||
|
||||
assert_equal [@mixins['list_1'].find,
|
||||
@mixins['list_2'].find,
|
||||
@mixins['list_3'].find,
|
||||
@mixins['list_4'].find],
|
||||
assert_equal [mixins(:list_1),
|
||||
mixins(:list_2),
|
||||
mixins(:list_3),
|
||||
mixins(:list_4)],
|
||||
ListMixin.find_all("parent_id=5", "pos")
|
||||
|
||||
|
||||
@mixins['list_2'].find.move_to_bottom
|
||||
mixins(:list_2).move_to_bottom
|
||||
|
||||
assert_equal [@mixins['list_1'].find,
|
||||
@mixins['list_3'].find,
|
||||
@mixins['list_4'].find,
|
||||
@mixins['list_2'].find],
|
||||
assert_equal [mixins(:list_1),
|
||||
mixins(:list_3),
|
||||
mixins(:list_4),
|
||||
mixins(:list_2)],
|
||||
ListMixin.find_all("parent_id=5", "pos")
|
||||
|
||||
@mixins['list_4'].find.move_to_top
|
||||
mixins(:list_4).move_to_top
|
||||
|
||||
assert_equal [@mixins['list_4'].find,
|
||||
@mixins['list_1'].find,
|
||||
@mixins['list_3'].find,
|
||||
@mixins['list_2'].find],
|
||||
assert_equal [mixins(:list_4),
|
||||
mixins(:list_1),
|
||||
mixins(:list_3),
|
||||
mixins(:list_2)],
|
||||
ListMixin.find_all("parent_id=5", "pos")
|
||||
|
||||
end
|
||||
|
||||
def test_next_prev
|
||||
assert_equal @list_2, @list_1.lower_item
|
||||
assert_nil @list_1.higher_item
|
||||
assert_equal @list_3, @list_4.higher_item
|
||||
assert_nil @list_4.lower_item
|
||||
assert_equal mixins(:list_2), mixins(:list_1).lower_item
|
||||
assert_nil mixins(:list_1).higher_item
|
||||
assert_equal mixins(:list_3), mixins(:list_4).higher_item
|
||||
assert_nil mixins(:list_4).lower_item
|
||||
end
|
||||
|
||||
|
||||
|
@ -130,31 +130,31 @@ class ListTest < Test::Unit::TestCase
|
|||
|
||||
def test_delete_middle
|
||||
|
||||
assert_equal [@mixins['list_1'].find,
|
||||
@mixins['list_2'].find,
|
||||
@mixins['list_3'].find,
|
||||
@mixins['list_4'].find],
|
||||
assert_equal [mixins(:list_1),
|
||||
mixins(:list_2),
|
||||
mixins(:list_3),
|
||||
mixins(:list_4)],
|
||||
ListMixin.find_all("parent_id=5", "pos")
|
||||
|
||||
@mixins['list_2'].find.destroy
|
||||
mixins(:list_2).destroy
|
||||
|
||||
assert_equal [@mixins['list_1'].find,
|
||||
@mixins['list_3'].find,
|
||||
@mixins['list_4'].find],
|
||||
assert_equal [mixins(:list_1, :reload),
|
||||
mixins(:list_3, :reload),
|
||||
mixins(:list_4, :reload)],
|
||||
ListMixin.find_all("parent_id=5", "pos")
|
||||
|
||||
assert_equal 1, @mixins['list_1'].find.pos
|
||||
assert_equal 2, @mixins['list_3'].find.pos
|
||||
assert_equal 3, @mixins['list_4'].find.pos
|
||||
assert_equal 1, mixins(:list_1).pos
|
||||
assert_equal 2, mixins(:list_3).pos
|
||||
assert_equal 3, mixins(:list_4).pos
|
||||
|
||||
@mixins['list_1'].find.destroy
|
||||
mixins(:list_1).destroy
|
||||
|
||||
assert_equal [@mixins['list_3'].find,
|
||||
@mixins['list_4'].find],
|
||||
assert_equal [mixins(:list_3, :reload),
|
||||
mixins(:list_4, :reload)],
|
||||
ListMixin.find_all("parent_id=5", "pos")
|
||||
|
||||
assert_equal 1, @mixins['list_3'].find.pos
|
||||
assert_equal 2, @mixins['list_4'].find.pos
|
||||
assert_equal 1, mixins(:list_3).pos
|
||||
assert_equal 2, mixins(:list_4).pos
|
||||
|
||||
end
|
||||
|
||||
|
@ -176,42 +176,42 @@ class TreeTest < Test::Unit::TestCase
|
|||
fixtures :mixins
|
||||
|
||||
def test_has_child
|
||||
assert_equal true, @tree_1.has_children?
|
||||
assert_equal true, @tree_2.has_children?
|
||||
assert_equal false, @tree_3.has_children?
|
||||
assert_equal false, @tree_4.has_children?
|
||||
assert_equal true, mixins(:tree_1).has_children?
|
||||
assert_equal true, mixins(:tree_2).has_children?
|
||||
assert_equal false, mixins(:tree_3).has_children?
|
||||
assert_equal false, mixins(:tree_4).has_children?
|
||||
end
|
||||
|
||||
def test_children
|
||||
assert_equal @tree_1.children, [@tree_2, @tree_4]
|
||||
assert_equal @tree_2.children, [@tree_3]
|
||||
assert_equal @tree_3.children, []
|
||||
assert_equal @tree_4.children, []
|
||||
assert_equal mixins(:tree_1).children, [mixins(:tree_2), mixins(:tree_4)]
|
||||
assert_equal mixins(:tree_2).children, [mixins(:tree_3)]
|
||||
assert_equal mixins(:tree_3).children, []
|
||||
assert_equal mixins(:tree_4).children, []
|
||||
end
|
||||
|
||||
def test_parent
|
||||
assert_equal @tree_2.parent, @tree_1
|
||||
assert_equal @tree_2.parent, @tree_4.parent
|
||||
assert_nil @tree_1.parent
|
||||
assert_equal mixins(:tree_2).parent, mixins(:tree_1)
|
||||
assert_equal mixins(:tree_2).parent, mixins(:tree_4).parent
|
||||
assert_nil mixins(:tree_1).parent
|
||||
end
|
||||
|
||||
def test_delete
|
||||
assert_equal 4, TreeMixin.count
|
||||
@tree_1.destroy
|
||||
mixins(:tree_1).destroy
|
||||
assert_equal 0, TreeMixin.count
|
||||
end
|
||||
|
||||
def test_insert
|
||||
@extra = @tree_1.children.create
|
||||
@extra = mixins(:tree_1).children.create
|
||||
|
||||
assert @extra
|
||||
|
||||
assert_equal @extra.parent, @tree_1
|
||||
assert_equal @extra.parent, mixins(:tree_1)
|
||||
|
||||
assert_equal 3, @tree_1.children.size
|
||||
assert @tree_1.children.include?(@extra)
|
||||
assert @tree_1.children.include?(@tree_2)
|
||||
assert @tree_1.children.include?(@tree_4)
|
||||
assert_equal 3, mixins(:tree_1).children.size
|
||||
assert mixins(:tree_1).children.include?(@extra)
|
||||
assert mixins(:tree_1).children.include?(mixins(:tree_2))
|
||||
assert mixins(:tree_1).children.include?(mixins(:tree_4))
|
||||
end
|
||||
|
||||
end
|
||||
|
@ -258,9 +258,9 @@ class TouchTest < Test::Unit::TestCase
|
|||
def test_create_turned_off
|
||||
Mixin.record_timestamps = false
|
||||
|
||||
assert_nil @tree_1.updated_at
|
||||
@tree_1.save
|
||||
assert_nil @tree_1.updated_at
|
||||
assert_nil mixins(:tree_1).updated_at
|
||||
mixins(:tree_1).save
|
||||
assert_nil mixins(:tree_1).updated_at
|
||||
|
||||
Mixin.record_timestamps = true
|
||||
end
|
||||
|
|
|
@ -2,12 +2,7 @@ require 'abstract_unit'
|
|||
require 'fixtures/company_in_module'
|
||||
|
||||
class ModulesTest < Test::Unit::TestCase
|
||||
def setup
|
||||
create_fixtures "accounts"
|
||||
create_fixtures "companies"
|
||||
create_fixtures "projects"
|
||||
create_fixtures "developers"
|
||||
end
|
||||
fixtures :accounts, :companies, :projects, :developers
|
||||
|
||||
def test_module_spanning_associations
|
||||
assert MyApplication::Business::Firm.find_first.has_clients?, "Firm should have clients"
|
||||
|
@ -25,4 +20,4 @@ class ModulesTest < Test::Unit::TestCase
|
|||
def test_associations_spanning_cross_modules
|
||||
assert MyApplication::Billing::Account.find(1).has_firm?, "37signals account should be able to backtrack"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -3,6 +3,8 @@ require 'fixtures/course'
|
|||
require 'fixtures/entrant'
|
||||
|
||||
class MultipleDbTest < Test::Unit::TestCase
|
||||
self.use_transactional_fixtures = false
|
||||
|
||||
def setup
|
||||
@courses = create_fixtures("courses") { Course.retrieve_connection }
|
||||
@entrants = create_fixtures("entrants")
|
||||
|
|
|
@ -4,17 +4,13 @@ require 'fixtures/subscriber'
|
|||
require 'fixtures/movie'
|
||||
|
||||
class PrimaryKeysTest < Test::Unit::TestCase
|
||||
def setup
|
||||
@topics = create_fixtures "topics"
|
||||
@subscribers = create_fixtures "subscribers"
|
||||
@movies = create_fixtures "movies"
|
||||
end
|
||||
fixtures :topics, :subscribers, :movies
|
||||
|
||||
def test_integer_key
|
||||
topic = Topic.find(1)
|
||||
assert_equal(@topics["first"]["author_name"], topic.author_name)
|
||||
assert_equal(topics(:first).author_name, topic.author_name)
|
||||
topic = Topic.find(2)
|
||||
assert_equal(@topics["second"]["author_name"], topic.author_name)
|
||||
assert_equal(topics(:second).author_name, topic.author_name)
|
||||
|
||||
topic = Topic.new
|
||||
topic.title = "New Topic"
|
||||
|
@ -27,10 +23,10 @@ class PrimaryKeysTest < Test::Unit::TestCase
|
|||
end
|
||||
|
||||
def test_string_key
|
||||
subscriber = Subscriber.find(@subscribers["first"]["nick"])
|
||||
assert_equal(@subscribers["first"]["name"], subscriber.name)
|
||||
subscriber = Subscriber.find(@subscribers["second"]["nick"])
|
||||
assert_equal(@subscribers["second"]["name"], subscriber.name)
|
||||
subscriber = Subscriber.find(subscribers(:first).nick)
|
||||
assert_equal(subscribers(:first).name, subscriber.name)
|
||||
subscriber = Subscriber.find(subscribers(:second).nick)
|
||||
assert_equal(subscribers(:second).name, subscriber.name)
|
||||
|
||||
subscriber = Subscriber.new
|
||||
subscriber.id = "jdoe"
|
||||
|
@ -43,7 +39,7 @@ class PrimaryKeysTest < Test::Unit::TestCase
|
|||
end
|
||||
|
||||
def test_find_with_more_than_one_string_key
|
||||
assert_equal 2, Subscriber.find(@subscribers["first"]["nick"], @subscribers["second"]["nick"]).length
|
||||
assert_equal 2, Subscriber.find(subscribers(:first).nick, subscribers(:second).nick).length
|
||||
end
|
||||
|
||||
def test_primary_key_prefix
|
||||
|
|
|
@ -5,10 +5,9 @@ require 'fixtures/company'
|
|||
require 'fixtures/company_in_module'
|
||||
|
||||
class ReflectionTest < Test::Unit::TestCase
|
||||
fixtures :topics, :customers, :companies
|
||||
|
||||
def setup
|
||||
@topics = create_fixtures "topics"
|
||||
@customers = create_fixtures "customers"
|
||||
@companies = create_fixtures "companies"
|
||||
@first = Topic.find(1)
|
||||
end
|
||||
|
||||
|
@ -78,4 +77,4 @@ class ReflectionTest < Test::Unit::TestCase
|
|||
assert_equal MyApplication::Business::Client, MyApplication::Business::Firm.reflect_on_association(:clients_of_firm).klass
|
||||
assert_equal MyApplication::Business::Firm, MyApplication::Billing::Account.reflect_on_association(:firm).klass
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -2,8 +2,11 @@ require 'abstract_unit'
|
|||
require 'fixtures/topic'
|
||||
|
||||
class ThreadSafetyTest < Test::Unit::TestCase
|
||||
self.use_transactional_fixtures = false
|
||||
|
||||
fixtures :topics
|
||||
|
||||
def setup
|
||||
@topics = create_fixtures "topics"
|
||||
@threads = []
|
||||
end
|
||||
|
||||
|
|
|
@ -3,9 +3,14 @@ require 'fixtures/topic'
|
|||
|
||||
|
||||
class TransactionTest < Test::Unit::TestCase
|
||||
self.use_transactional_fixtures = false
|
||||
|
||||
fixtures :topics
|
||||
|
||||
def setup
|
||||
@topics = create_fixtures "topics"
|
||||
@first, @second = Topic.find(1, 2)
|
||||
# sqlite does not seem to return these in the right order, so we sort them
|
||||
# explicitly for sqlite's sake. sqlite3 does fine.
|
||||
@first, @second = Topic.find(1, 2).sort_by { |t| t.id }
|
||||
end
|
||||
|
||||
def test_successful
|
||||
|
@ -53,6 +58,8 @@ class TransactionTest < Test::Unit::TestCase
|
|||
end
|
||||
|
||||
def test_failing_with_object_rollback
|
||||
assert !@first.approved?, "First should be unapproved initially"
|
||||
|
||||
begin
|
||||
Topic.transaction(@first, @second) do
|
||||
@first.approved = true
|
||||
|
|
|
@ -4,6 +4,7 @@ class TestRecord < ActiveRecord::Base
|
|||
end
|
||||
|
||||
class TestUnconnectedAdaptor < Test::Unit::TestCase
|
||||
self.use_transactional_fixtures = false
|
||||
|
||||
def setup
|
||||
@connection = ActiveRecord::Base.remove_connection
|
||||
|
|
Loading…
Reference in a new issue