From 2a12b56841bd6fd3998050e7677a1b2c08257479 Mon Sep 17 00:00:00 2001 From: Jeremy Kemper Date: Sat, 8 Jul 2006 20:35:56 +0000 Subject: r4704@asus: jeremy | 2006-06-27 12:00:19 -0700 decimal r4705@asus: jeremy | 2006-06-27 12:20:47 -0700 current_adapter? checks whether any of its arguments is the name of the current adapter class r4834@asus: jeremy | 2006-07-08 13:08:24 -0700 Room to float. r4835@asus: jeremy | 2006-07-08 13:09:18 -0700 Give lock test a few chances. r4836@asus: jeremy | 2006-07-08 13:12:05 -0700 Numeric and decimal columns map to BigDecimal instead of Float. Those with scale 0 map to Integer. Closes #5454. git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@4596 5ecf4fe2-1ee6-0310-87b1-e25e094e27de --- activerecord/test/base_test.rb | 34 ++++- activerecord/test/calculations_test.rb | 2 +- activerecord/test/defaults_test.rb | 18 ++- .../test/fixtures/db_definitions/db2.drop.sql | 1 + activerecord/test/fixtures/db_definitions/db2.sql | 9 ++ .../test/fixtures/db_definitions/firebird.drop.sql | 2 + .../test/fixtures/db_definitions/firebird.sql | 12 ++ .../fixtures/db_definitions/frontbase.drop.sql | 1 + .../test/fixtures/db_definitions/frontbase.sql | 11 ++ .../test/fixtures/db_definitions/mysql.drop.sql | 1 + .../test/fixtures/db_definitions/mysql.sql | 9 ++ .../test/fixtures/db_definitions/openbase.sql | 14 +- .../test/fixtures/db_definitions/oracle.drop.sql | 2 + .../test/fixtures/db_definitions/oracle.sql | 10 ++ .../fixtures/db_definitions/postgresql.drop.sql | 4 +- .../test/fixtures/db_definitions/postgresql.sql | 12 +- .../test/fixtures/db_definitions/sqlite.drop.sql | 1 + .../test/fixtures/db_definitions/sqlite.sql | 11 +- .../fixtures/db_definitions/sqlserver.drop.sql | 2 + .../test/fixtures/db_definitions/sqlserver.sql | 27 ++++ .../test/fixtures/db_definitions/sybase.drop.sql | 1 + .../test/fixtures/db_definitions/sybase.sql | 11 +- .../1_give_me_big_numbers.rb | 15 ++ activerecord/test/locking_test.rb | 8 +- activerecord/test/migration_test.rb | 153 ++++++++++++++++++--- activerecord/test/schema_dumper_test.rb | 11 +- activerecord/test/validations_test.rb | 12 +- 27 files changed, 350 insertions(+), 44 deletions(-) create mode 100644 activerecord/test/fixtures/migrations_with_decimal/1_give_me_big_numbers.rb (limited to 'activerecord/test') diff --git a/activerecord/test/base_test.rb b/activerecord/test/base_test.rb index 6ccf14af1b..b07ec3eacd 100755 --- a/activerecord/test/base_test.rb +++ b/activerecord/test/base_test.rb @@ -910,12 +910,44 @@ class BasicsTest < Test::Unit::TestCase end end + class NumericData < ActiveRecord::Base + self.table_name = 'numeric_data' + end + + def test_numeric_fields + m = NumericData.new( + :bank_balance => 1586.43, + :big_bank_balance => BigDecimal("1000234000567.95"), + :world_population => 6000000000, + :my_house_population => 3 + ) + assert m.save + + m1 = NumericData.find(m.id) + assert_not_nil m1 + + # As with migration_test.rb, we should make world_population >= 2**62 + # to cover 64-bit platforms and test it is a Bignum, but the main thing + # is that it's an Integer. + assert_kind_of Integer, m1.world_population + assert_equal 6000000000, m1.world_population + + assert_kind_of Fixnum, m1.my_house_population + assert_equal 3, m1.my_house_population + + assert_kind_of BigDecimal, m1.bank_balance + assert_equal BigDecimal("1586.43"), m1.bank_balance + + assert_kind_of BigDecimal, m1.big_bank_balance + assert_equal BigDecimal("1000234000567.95"), m1.big_bank_balance + end + def test_auto_id auto = AutoId.new auto.save assert (auto.id > 0) end - + def quote_column_name(name) "<#{name}>" end diff --git a/activerecord/test/calculations_test.rb b/activerecord/test/calculations_test.rb index 7b89e8c62c..9a0d0434a5 100644 --- a/activerecord/test/calculations_test.rb +++ b/activerecord/test/calculations_test.rb @@ -13,8 +13,8 @@ class CalculationsTest < Test::Unit::TestCase def test_should_average_field value = Account.average(:credit_limit) - assert_equal 53, value assert_kind_of Float, value + assert_in_delta 53.0, value, 0.001 end def test_should_get_maximum_of_field diff --git a/activerecord/test/defaults_test.rb b/activerecord/test/defaults_test.rb index f51f77cd71..aba3c66de4 100644 --- a/activerecord/test/defaults_test.rb +++ b/activerecord/test/defaults_test.rb @@ -1,18 +1,16 @@ require 'abstract_unit' require 'fixtures/default' -class DefaultsTest < Test::Unit::TestCase - if %w(PostgreSQL).include? ActiveRecord::Base.connection.adapter_name +if current_adapter?(:PostgreSQLAdapter, :SQLServerAdapter) + class DefaultsTest < Test::Unit::TestCase def test_default_integers default = Default.new - assert_instance_of(Fixnum, default.positive_integer) - assert_equal(default.positive_integer, 1) - assert_instance_of(Fixnum, default.negative_integer) - assert_equal(default.negative_integer, -1) - end - else - def test_dummy - assert true + assert_instance_of Fixnum, default.positive_integer + assert_equal 1, default.positive_integer + assert_instance_of Fixnum, default.negative_integer + assert_equal -1, default.negative_integer + assert_instance_of BigDecimal, default.decimal_number + assert_equal BigDecimal.new("2.78"), default.decimal_number end end end diff --git a/activerecord/test/fixtures/db_definitions/db2.drop.sql b/activerecord/test/fixtures/db_definitions/db2.drop.sql index c5b32bb9fc..50cffe3b47 100644 --- a/activerecord/test/fixtures/db_definitions/db2.drop.sql +++ b/activerecord/test/fixtures/db_definitions/db2.drop.sql @@ -28,3 +28,4 @@ DROP TABLE fk_test_has_pk; DROP TABLE fk_test_has_fk; DROP TABLE keyboards; DROP TABLE legacy_things; +DROP TABLE numeric_data; diff --git a/activerecord/test/fixtures/db_definitions/db2.sql b/activerecord/test/fixtures/db_definitions/db2.sql index 2f67e9ce53..ee76fc4d05 100644 --- a/activerecord/test/fixtures/db_definitions/db2.sql +++ b/activerecord/test/fixtures/db_definitions/db2.sql @@ -215,3 +215,12 @@ CREATE TABLE legacy_things ( version INT DEFAULT 0, PRIMARY KEY (id) ); + +CREATE TABLE numeric_data ( + id INT NOT NULL PRIMARY KEY, + bank_balance DECIMAL(10,2), + big_bank_balance DECIMAL(15,2), + world_population DECIMAL(10), + my_house_population DECIMAL(2), + decimal_number_with_default DECIMAL(3,2) DEFAULT 2.78 +); diff --git a/activerecord/test/fixtures/db_definitions/firebird.drop.sql b/activerecord/test/fixtures/db_definitions/firebird.drop.sql index 807361ed45..2e43243af7 100644 --- a/activerecord/test/fixtures/db_definitions/firebird.drop.sql +++ b/activerecord/test/fixtures/db_definitions/firebird.drop.sql @@ -29,6 +29,7 @@ DROP TABLE fk_test_has_pk; DROP TABLE keyboards; DROP TABLE defaults; DROP TABLE legacy_things; +DROP TABLE numeric_data; DROP DOMAIN D_BOOLEAN; @@ -57,3 +58,4 @@ DROP GENERATOR categories_seq; DROP GENERATOR keyboards_seq; DROP GENERATOR defaults_seq; DROP GENERATOR legacy_things_seq; +DROP GENERATOR numeric_data_seq; diff --git a/activerecord/test/fixtures/db_definitions/firebird.sql b/activerecord/test/fixtures/db_definitions/firebird.sql index c523bfe7bb..8ca0bf6222 100644 --- a/activerecord/test/fixtures/db_definitions/firebird.sql +++ b/activerecord/test/fixtures/db_definitions/firebird.sql @@ -283,3 +283,15 @@ CREATE TABLE legacy_things ( ); CREATE GENERATOR legacy_things_seq; SET GENERATOR legacy_things_seq TO 10000; + +CREATE TABLE numeric_data ( + id BIGINT NOT NULL, + bank_balance DECIMAL(10,2), + big_bank_balance DECIMAL(15,2), + world_population DECIMAL(10), + my_house_population DECIMAL(2), + decimal_number_with_default DECIMAL(3,2) DEFAULT 2.78, + PRIMARY KEY (id) +); +CREATE GENERATOR numeric_data_seq; +SET GENERATOR numeric_data_seq TO 10000; diff --git a/activerecord/test/fixtures/db_definitions/frontbase.drop.sql b/activerecord/test/fixtures/db_definitions/frontbase.drop.sql index 231af7895c..5fc64f769b 100644 --- a/activerecord/test/fixtures/db_definitions/frontbase.drop.sql +++ b/activerecord/test/fixtures/db_definitions/frontbase.drop.sql @@ -28,3 +28,4 @@ DROP TABLE fk_test_has_fk CASCADE; DROP TABLE fk_test_has_pk CASCADE; DROP TABLE keyboards CASCADE; DROP TABLE legacy_things CASCADE; +DROP TABLE numeric_data CASCADE; diff --git a/activerecord/test/fixtures/db_definitions/frontbase.sql b/activerecord/test/fixtures/db_definitions/frontbase.sql index 13ce65297b..e102f65aa7 100644 --- a/activerecord/test/fixtures/db_definitions/frontbase.sql +++ b/activerecord/test/fixtures/db_definitions/frontbase.sql @@ -249,3 +249,14 @@ create table "legacy_things" primary key ("id") ); SET UNIQUE FOR legacy_things(id); + +CREATE TABLE "numeric_data" ( + "id" integer NOT NULL + "bank_balance" DECIMAL(10,2), + "big_bank_balance" DECIMAL(15,2), + "world_population" DECIMAL(10), + "my_house_population" DECIMAL(2), + "decimal_number_with_default" DECIMAL(3,2) DEFAULT 2.78, + primary key ("id") +); +SET UNIQUE FOR numeric_data(id); diff --git a/activerecord/test/fixtures/db_definitions/mysql.drop.sql b/activerecord/test/fixtures/db_definitions/mysql.drop.sql index 14df93fd2a..cb6a870a7c 100644 --- a/activerecord/test/fixtures/db_definitions/mysql.drop.sql +++ b/activerecord/test/fixtures/db_definitions/mysql.drop.sql @@ -28,3 +28,4 @@ DROP TABLE fk_test_has_fk; DROP TABLE fk_test_has_pk; DROP TABLE keyboards; DROP TABLE legacy_things; +DROP TABLE numeric_data; diff --git a/activerecord/test/fixtures/db_definitions/mysql.sql b/activerecord/test/fixtures/db_definitions/mysql.sql index 4107155450..61ba43e954 100755 --- a/activerecord/test/fixtures/db_definitions/mysql.sql +++ b/activerecord/test/fixtures/db_definitions/mysql.sql @@ -217,3 +217,12 @@ CREATE TABLE `legacy_things` ( `version` int(11) NOT NULL default 0, PRIMARY KEY (`id`) ) TYPE=InnoDB; + +CREATE TABLE `numeric_data` ( + `id` INTEGER NOT NULL PRIMARY KEY, + `bank_balance` decimal(10,2), + `big_bank_balance` decimal(15,2), + `world_population` decimal(10), + `my_house_population` decimal(2), + `decimal_number_with_default` decimal(3,2) DEFAULT 2.78 +) TYPE=InnoDB; diff --git a/activerecord/test/fixtures/db_definitions/openbase.sql b/activerecord/test/fixtures/db_definitions/openbase.sql index 9ca1a7d06e..c3da2efee6 100644 --- a/activerecord/test/fixtures/db_definitions/openbase.sql +++ b/activerecord/test/fixtures/db_definitions/openbase.sql @@ -279,4 +279,16 @@ CREATE TABLE legacy_things ( ) go CREATE PRIMARY KEY legacy_things (id) -go \ No newline at end of file +go + +CREATE TABLE numeric_data ( + id INTEGER NOT NULL DEFAULT _rowid, + bank_balance DECIMAL(10,2), + big_bank_balance DECIMAL(15,2), + world_population DECIMAL(10), + my_house_population DECIMAL(2), + decimal_number_with_default DECIMAL(3,2) DEFAULT 2.78 +); +go +CREATE PRIMARY KEY numeric_data (id) +go diff --git a/activerecord/test/fixtures/db_definitions/oracle.drop.sql b/activerecord/test/fixtures/db_definitions/oracle.drop.sql index 4d4ddb835d..6fa01cdf51 100644 --- a/activerecord/test/fixtures/db_definitions/oracle.drop.sql +++ b/activerecord/test/fixtures/db_definitions/oracle.drop.sql @@ -29,6 +29,7 @@ drop table fk_test_has_pk; drop table fk_test_has_fk; drop table keyboards; drop table legacy_things; +drop table numeric_data; drop sequence accounts_seq; drop sequence funny_jokes_seq; @@ -59,3 +60,4 @@ drop sequence fk_test_has_pk_seq; drop sequence fk_test_has_fk_seq; drop sequence keyboards_seq; drop sequence legacy_things_seq; +drop sequence numeric_data_seq; diff --git a/activerecord/test/fixtures/db_definitions/oracle.sql b/activerecord/test/fixtures/db_definitions/oracle.sql index 48d6bdf073..ccf472c905 100644 --- a/activerecord/test/fixtures/db_definitions/oracle.sql +++ b/activerecord/test/fixtures/db_definitions/oracle.sql @@ -290,3 +290,13 @@ create table legacy_things ( version integer default 0 ); create sequence legacy_things_seq minvalue 10000; + +CREATE TABLE numeric_data ( + id integer NOT NULL PRIMARY KEY, + bank_balance decimal(10,2), + big_bank_balance decimal(15,2), + world_population decimal(10), + my_house_population decimal(2), + decimal_number_with_default decimal(3,2) DEFAULT 2.78 +); +create sequence numeric_data_seq minvalue 10000; diff --git a/activerecord/test/fixtures/db_definitions/postgresql.drop.sql b/activerecord/test/fixtures/db_definitions/postgresql.drop.sql index 2662839214..4910b0ecee 100644 --- a/activerecord/test/fixtures/db_definitions/postgresql.drop.sql +++ b/activerecord/test/fixtures/db_definitions/postgresql.drop.sql @@ -1,5 +1,5 @@ -DROP SEQUENCE accounts_id_seq; DROP TABLE accounts; +DROP SEQUENCE accounts_id_seq; DROP TABLE funny_jokes; DROP TABLE companies; DROP SEQUENCE companies_nonstd_seq; @@ -32,3 +32,5 @@ DROP TABLE fk_test_has_pk; DROP TABLE geometrics; DROP TABLE keyboards; DROP TABLE legacy_things; +DROP TABLE numeric_data; +DROP TABLE column_data; diff --git a/activerecord/test/fixtures/db_definitions/postgresql.sql b/activerecord/test/fixtures/db_definitions/postgresql.sql index 175e8494bb..ce2c775aba 100644 --- a/activerecord/test/fixtures/db_definitions/postgresql.sql +++ b/activerecord/test/fixtures/db_definitions/postgresql.sql @@ -118,7 +118,8 @@ CREATE TABLE defaults ( char2 character varying(50) default 'a varchar field', char3 text default 'a text field', positive_integer integer default 1, - negative_integer integer default -1 + negative_integer integer default -1, + decimal_number decimal(3,2) default 2.78 ); CREATE TABLE auto_id_tests ( @@ -246,3 +247,12 @@ CREATE TABLE legacy_things ( tps_report_number integer, version integer default 0 ); + +CREATE TABLE numeric_data ( + id serial primary key, + bank_balance decimal(10,2), + big_bank_balance decimal(15,2), + world_population decimal(10), + my_house_population decimal(2), + decimal_number_with_default decimal(3,2) default 2.78 +); diff --git a/activerecord/test/fixtures/db_definitions/sqlite.drop.sql b/activerecord/test/fixtures/db_definitions/sqlite.drop.sql index 14df93fd2a..cb6a870a7c 100644 --- a/activerecord/test/fixtures/db_definitions/sqlite.drop.sql +++ b/activerecord/test/fixtures/db_definitions/sqlite.drop.sql @@ -28,3 +28,4 @@ DROP TABLE fk_test_has_fk; DROP TABLE fk_test_has_pk; DROP TABLE keyboards; DROP TABLE legacy_things; +DROP TABLE numeric_data; diff --git a/activerecord/test/fixtures/db_definitions/sqlite.sql b/activerecord/test/fixtures/db_definitions/sqlite.sql index 5a7fec3d7e..8f89c419a1 100644 --- a/activerecord/test/fixtures/db_definitions/sqlite.sql +++ b/activerecord/test/fixtures/db_definitions/sqlite.sql @@ -198,4 +198,13 @@ CREATE TABLE 'legacy_things' ( 'id' INTEGER NOT NULL PRIMARY KEY, 'tps_report_number' INTEGER DEFAULT NULL, 'version' INTEGER NOT NULL DEFAULT 0 -) +); + +CREATE TABLE 'numeric_data' ( + 'id' INTEGER NOT NULL PRIMARY KEY, + 'bank_balance' DECIMAL(10,2), + 'big_bank_balance' DECIMAL(15,2), + 'world_population' DECIMAL(10), + 'my_house_population' DECIMAL(2), + 'decimal_number_with_default' DECIMAL(3,2) DEFAULT 2.78 +); diff --git a/activerecord/test/fixtures/db_definitions/sqlserver.drop.sql b/activerecord/test/fixtures/db_definitions/sqlserver.drop.sql index ea14697bd3..b157d7c0a7 100644 --- a/activerecord/test/fixtures/db_definitions/sqlserver.drop.sql +++ b/activerecord/test/fixtures/db_definitions/sqlserver.drop.sql @@ -10,6 +10,7 @@ DROP TABLE orders; DROP TABLE movies; DROP TABLE subscribers; DROP TABLE booleantests; +DROP TABLE defaults; DROP TABLE auto_id_tests; DROP TABLE entrants; DROP TABLE colnametests; @@ -28,3 +29,4 @@ DROP TABLE fk_test_has_fk; DROP TABLE fk_test_has_pk; DROP TABLE keyboards; DROP TABLE legacy_things; +DROP TABLE numeric_data; diff --git a/activerecord/test/fixtures/db_definitions/sqlserver.sql b/activerecord/test/fixtures/db_definitions/sqlserver.sql index acbcaa1384..7b6f1d7afd 100644 --- a/activerecord/test/fixtures/db_definitions/sqlserver.sql +++ b/activerecord/test/fixtures/db_definitions/sqlserver.sql @@ -88,6 +88,24 @@ CREATE TABLE booleantests ( value bit default NULL ); +CREATE TABLE defaults ( + id int NOT NULL IDENTITY(1, 1) PRIMARY KEY, +-- these brought from the PostgreSQL defaults_test.rb but +-- tests only exist for integers and decimals, currently +-- modified_date date default CURRENT_DATE, +-- modified_date_function date default now(), +-- fixed_date date default '2004-01-01', +-- modified_time timestamp default CURRENT_TIMESTAMP, +-- modified_time_function timestamp default now(), +-- fixed_time timestamp default '2004-01-01 00:00:00.000000-00', +-- char1 char(1) default 'Y', +-- char2 character varying(50) default 'a varchar field', +-- char3 text default 'a text field', + positive_integer integer default 1, + negative_integer integer default -1, + decimal_number decimal(3,2) default 2.78 +); + CREATE TABLE auto_id_tests ( auto_id int NOT NULL IDENTITY(1, 1) PRIMARY KEY, value int default NULL @@ -201,3 +219,12 @@ CREATE TABLE legacy_things ( version int default 0, PRIMARY KEY (id) ); + +CREATE TABLE numeric_data ( + id int NOT NULL IDENTITY(1, 1), + bank_balance decimal(10,2), + big_bank_balance decimal(15,2), + world_population decimal(10), + my_house_population decimal(2), + decimal_number_with_default decimal(3,2) DEFAULT 2.78 +); diff --git a/activerecord/test/fixtures/db_definitions/sybase.drop.sql b/activerecord/test/fixtures/db_definitions/sybase.drop.sql index f843a80f7a..fa51eefeeb 100644 --- a/activerecord/test/fixtures/db_definitions/sybase.drop.sql +++ b/activerecord/test/fixtures/db_definitions/sybase.drop.sql @@ -28,4 +28,5 @@ DROP TABLE fk_test_has_fk DROP TABLE fk_test_has_pk DROP TABLE keyboards DROP TABLE legacy_things +DROP TABLE numeric_data go diff --git a/activerecord/test/fixtures/db_definitions/sybase.sql b/activerecord/test/fixtures/db_definitions/sybase.sql index 98022f8887..79c7b940b5 100644 --- a/activerecord/test/fixtures/db_definitions/sybase.sql +++ b/activerecord/test/fixtures/db_definitions/sybase.sql @@ -200,5 +200,14 @@ CREATE TABLE legacy_things ( version int default 0, ) -go +CREATE TABLE numeric_data ( + id numeric((9,0) IDENTITY PRIMARY KEY, + bank_balance numeric(10,2), + big_bank_balance numeric(15,2), + world_population numeric(10), + my_house_population numeric(2), + decimal_number_with_default numeric(3,2) DEFAULT 2.78 +) + +go diff --git a/activerecord/test/fixtures/migrations_with_decimal/1_give_me_big_numbers.rb b/activerecord/test/fixtures/migrations_with_decimal/1_give_me_big_numbers.rb new file mode 100644 index 0000000000..0aed7cbd84 --- /dev/null +++ b/activerecord/test/fixtures/migrations_with_decimal/1_give_me_big_numbers.rb @@ -0,0 +1,15 @@ +class GiveMeBigNumbers < ActiveRecord::Migration + def self.up + create_table :big_numbers do |table| + table.column :bank_balance, :decimal, :precision => 10, :scale => 2 + table.column :big_bank_balance, :decimal, :precision => 15, :scale => 2 + table.column :world_population, :decimal, :precision => 10 + table.column :my_house_population, :decimal, :precision => 2 + table.column :value_of_e, :decimal + end + end + + def self.down + drop_table :big_numbers + end +end diff --git a/activerecord/test/locking_test.rb b/activerecord/test/locking_test.rb index 8ddfb2289c..58c34a69e3 100644 --- a/activerecord/test/locking_test.rb +++ b/activerecord/test/locking_test.rb @@ -115,12 +115,14 @@ class PessimisticLockingTest < Test::Unit::TestCase end def test_second_lock_waits - first, second = duel { Person.find 1, :lock => true } - assert second.end > first.end + assert [0.2, 1, 5].any? { |zzz| + first, second = duel(zzz) { Person.find 1, :lock => true } + second.end > first.end + } end protected - def duel(zzz = 1.0) + def duel(zzz = 5) t0, t1, t2, t3 = nil, nil, nil, nil a = Thread.new do diff --git a/activerecord/test/migration_test.rb b/activerecord/test/migration_test.rb index 9514eb369d..337d4c8861 100644 --- a/activerecord/test/migration_test.rb +++ b/activerecord/test/migration_test.rb @@ -1,10 +1,15 @@ require 'abstract_unit' +require 'bigdecimal/util' + require 'fixtures/person' require 'fixtures/topic' require File.dirname(__FILE__) + '/fixtures/migrations/1_people_have_last_names' require File.dirname(__FILE__) + '/fixtures/migrations/2_we_need_reminders' +require File.dirname(__FILE__) + '/fixtures/migrations_with_decimal/1_give_me_big_numbers' if ActiveRecord::Base.connection.supports_migrations? + class BigNumber < ActiveRecord::Base; end + class Reminder < ActiveRecord::Base; end class ActiveRecord::Migration @@ -29,20 +34,15 @@ if ActiveRecord::Base.connection.supports_migrations? ActiveRecord::Base.connection.initialize_schema_information ActiveRecord::Base.connection.update "UPDATE #{ActiveRecord::Migrator.schema_info_table_name} SET version = 0" - Reminder.connection.drop_table("reminders") rescue nil - Reminder.connection.drop_table("people_reminders") rescue nil - Reminder.connection.drop_table("prefix_reminders_suffix") rescue nil + %w(reminders people_reminders prefix_reminders_suffix).each do |table| + Reminder.connection.drop_table(table) rescue nil + end Reminder.reset_column_information - Person.connection.remove_column("people", "last_name") rescue nil - Person.connection.remove_column("people", "key") rescue nil - Person.connection.remove_column("people", "bio") rescue nil - Person.connection.remove_column("people", "age") rescue nil - Person.connection.remove_column("people", "height") rescue nil - Person.connection.remove_column("people", "birthday") rescue nil - Person.connection.remove_column("people", "favorite_day") rescue nil - Person.connection.remove_column("people", "male") rescue nil - Person.connection.remove_column("people", "administrator") rescue nil + %w(last_name key bio age height wealth birthday favorite_day + mail administrator).each do |column| + Person.connection.remove_column('people', column) rescue nil + end Person.connection.remove_column("people", "first_name") rescue nil Person.connection.add_column("people", "first_name", :string, :limit => 40) Person.reset_column_information @@ -187,23 +187,74 @@ if ActiveRecord::Base.connection.supports_migrations? Person.connection.drop_table :testings rescue nil end + # We specifically do a manual INSERT here, and then test only the SELECT + # functionality. This allows us to more easily catch INSERT being broken, + # but SELECT actually working fine. + def test_native_decimal_insert_manual_vs_automatic + # SQLite3 always uses float in violation of SQL + # 16 decimal places + correct_value = (current_adapter?(:SQLiteAdapter) ? '0.123456789012346E20' : '0012345678901234567890.0123456789').to_d + + Person.delete_all + Person.connection.add_column "people", "wealth", :decimal, :precision => '30', :scale => '10' + Person.reset_column_information + + # Do a manual insertion + Person.connection.execute "insert into people (wealth) values (12345678901234567890.0123456789)" + + # SELECT + row = Person.find(:first) + assert_kind_of BigDecimal, row.wealth + + # If this assert fails, that means the SELECT is broken! + assert_equal correct_value, row.wealth + + # Reset to old state + Person.delete_all + + # Now use the Rails insertion + assert_nothing_raised { Person.create :wealth => BigDecimal.new("12345678901234567890.0123456789") } + + # SELECT + row = Person.find(:first) + assert_kind_of BigDecimal, row.wealth + + # If these asserts fail, that means the INSERT (create function, or cast to SQL) is broken! + assert_equal correct_value, row.wealth + + # Reset to old state + Person.connection.del_column "people", "wealth" rescue nil + Person.reset_column_information + end + def test_native_types Person.delete_all Person.connection.add_column "people", "last_name", :string Person.connection.add_column "people", "bio", :text Person.connection.add_column "people", "age", :integer Person.connection.add_column "people", "height", :float + Person.connection.add_column "people", "wealth", :decimal, :precision => '30', :scale => '10' Person.connection.add_column "people", "birthday", :datetime Person.connection.add_column "people", "favorite_day", :date Person.connection.add_column "people", "male", :boolean - assert_nothing_raised { Person.create :first_name => 'bob', :last_name => 'bobsen', :bio => "I was born ....", :age => 18, :height => 1.78, :birthday => 18.years.ago, :favorite_day => 10.days.ago, :male => true } + assert_nothing_raised { Person.create :first_name => 'bob', :last_name => 'bobsen', :bio => "I was born ....", :age => 18, :height => 1.78, :wealth => BigDecimal.new("12345678901234567890.0123456789"), :birthday => 18.years.ago, :favorite_day => 10.days.ago, :male => true } bob = Person.find(:first) - assert_equal bob.first_name, 'bob' - assert_equal bob.last_name, 'bobsen' - assert_equal bob.bio, "I was born ...." - assert_equal bob.age, 18 - assert_equal bob.male?, true + assert_equal 'bob', bob.first_name + assert_equal 'bobsen', bob.last_name + assert_equal "I was born ....", bob.bio + assert_equal 18, bob.age + + # Test for 30 significent digits (beyond the 16 of float), 10 of them + # after the decimal place. + if current_adapter?(:SQLiteAdapter) + # SQLite3 uses float in violation of SQL. Test for 16 decimal places. + assert_equal BigDecimal.new('0.123456789012346E20'), bob.wealth + else + assert_equal BigDecimal.new("0012345678901234567890.0123456789"), bob.wealth + end + + assert_equal true, bob.male? assert_equal String, bob.first_name.class assert_equal String, bob.last_name.class @@ -219,6 +270,7 @@ if ActiveRecord::Base.connection.supports_migrations? end assert_equal TrueClass, bob.male?.class + assert_kind_of BigDecimal, bob.wealth end def test_add_remove_single_field_using_string_arguments @@ -351,6 +403,71 @@ if ActiveRecord::Base.connection.supports_migrations? assert_raises(ActiveRecord::StatementInvalid) { Reminder.find(:first) } end + def test_add_table_with_decimals + Person.connection.drop_table :big_numbers rescue nil + + assert !BigNumber.table_exists? + GiveMeBigNumbers.up + + assert BigNumber.create( + :bank_balance => 1586.43, + :big_bank_balance => BigDecimal("1000234000567.95"), + :world_population => 6000000000, + :my_house_population => 3, + :value_of_e => BigDecimal("2.7182818284590452353602875") + ) + + b = BigNumber.find(:first) + assert_not_nil b + + assert_not_nil b.bank_balance + assert_not_nil b.big_bank_balance + assert_not_nil b.world_population + assert_not_nil b.my_house_population + assert_not_nil b.value_of_e + + # TODO: set world_population >= 2**62 to cover 64-bit platforms and test + # is_a?(Bignum) + assert_kind_of Integer, b.world_population + assert_equal 6000000000, b.world_population + assert_kind_of Fixnum, b.my_house_population + assert_equal 3, b.my_house_population + assert_kind_of BigDecimal, b.bank_balance + assert_equal BigDecimal("1586.43"), b.bank_balance + assert_kind_of BigDecimal, b.big_bank_balance + assert_equal BigDecimal("1000234000567.95"), b.big_bank_balance + + # This one is fun. The 'value_of_e' field is defined as 'DECIMAL' with + # precision/scale explictly left out. By the SQL standard, numbers + # assigned to this field should be truncated but that's seldom respected. + if current_adapter?(:PostgreSQLAdapter, :SQLite2Adapter) + # - PostgreSQL changes the SQL spec on columns declared simply as + # "decimal" to something more useful: instead of being given a scale + # of 0, they take on the compile-time limit for precision and scale, + # so the following should succeed unless you have used really wacky + # compilation options + # - SQLite2 has the default behavior of preserving all data sent in, + # so this happens there too + assert_kind_of BigDecimal, b.value_of_e + assert_equal BigDecimal("2.7182818284590452353602875"), b.value_of_e + elsif current_adapter?(:SQLiteAdapter) + # - SQLite3 stores a float, in violation of SQL + assert_kind_of BigDecimal, b.value_of_e + assert_equal BigDecimal("2.71828182845905"), b.value_of_e + elsif current_adapter?(:SQLServer) + # - SQL Server rounds instead of truncating + assert_kind_of Fixnum, b.value_of_e + assert_equal 3, b.value_of_e + else + # - SQL standard is an integer + assert_kind_of Fixnum, b.value_of_e + assert_equal 2, b.value_of_e + end + + GiveMeBigNumbers.down + assert_raises(ActiveRecord::StatementInvalid) { BigNumber.find(:first) } + end + def test_migrator assert !Person.column_methods_hash.include?(:last_name) assert !Reminder.table_exists? diff --git a/activerecord/test/schema_dumper_test.rb b/activerecord/test/schema_dumper_test.rb index 37e8a99048..21e47ce609 100644 --- a/activerecord/test/schema_dumper_test.rb +++ b/activerecord/test/schema_dumper_test.rb @@ -7,6 +7,7 @@ if ActiveRecord::Base.connection.respond_to?(:tables) class SchemaDumperTest < Test::Unit::TestCase def standard_dump stream = StringIO.new + ActiveRecord::SchemaDumper.ignore_tables = [] ActiveRecord::SchemaDumper.dump(ActiveRecord::Base.connection, stream) stream.string end @@ -30,7 +31,7 @@ if ActiveRecord::Base.connection.respond_to?(:tables) def test_arguments_line_up output = standard_dump output.scan(/^( *)create_table.*?\n(.*?)^\1end/m).map{ |m| m.last.split(/\n/) }.each do |column_set| - assert_line_up(column_set, /:(?:integer|float|datetime|timestamp|time|date|text|binary|string|boolean)/, true) + assert_line_up(column_set, /:(?:integer|decimal|float|datetime|timestamp|time|date|text|binary|string|boolean)/, true) assert_line_up(column_set, /:default => /) assert_line_up(column_set, /:limit => /) assert_line_up(column_set, /:null => /) @@ -82,6 +83,14 @@ if ActiveRecord::Base.connection.respond_to?(:tables) ActiveRecord::SchemaDumper.dump(ActiveRecord::Base.connection, stream) end end + + def test_schema_dump_includes_decimal_options + stream = StringIO.new + ActiveRecord::SchemaDumper.ignore_tables = [/^[^n]/] + ActiveRecord::SchemaDumper.dump(ActiveRecord::Base.connection, stream) + output = stream.string + assert_match %r{:precision => 3,[[:space:]]+:scale => 2,[[:space:]]+:default => 0.278E1}, output + end end end diff --git a/activerecord/test/validations_test.rb b/activerecord/test/validations_test.rb index c84408b1b8..ddfdbb7ef0 100755 --- a/activerecord/test/validations_test.rb +++ b/activerecord/test/validations_test.rb @@ -1015,10 +1015,12 @@ end class ValidatesNumericalityTest NIL = [nil, "", " ", " \t \r \n"] - FLOAT_STRINGS = %w(0.0 +0.0 -0.0 10.0 10.5 -10.5 -0.0001 -090.1) + BIGDECIMAL_STRINGS = %w(12345678901234567890.1234567890) # 30 significent digits + FLOAT_STRINGS = %w(0.0 +0.0 -0.0 10.0 10.5 -10.5 -0.0001 -090.1 90.1e1 -90.1e5 -90.1e-5 90e-5) INTEGER_STRINGS = %w(0 +0 -0 10 +10 -10 0090 -090) FLOATS = [0.0, 10.0, 10.5, -10.5, -0.0001] + FLOAT_STRINGS INTEGERS = [0, 10, -10] + INTEGER_STRINGS + BIGDECIMAL = BIGDECIMAL_STRINGS.collect! { |bd| BigDecimal.new(bd) } JUNK = ["not a number", "42 not a number", "0xdeadbeef", "00-1", "--3", "+-3", "+3-1", "-+019.0", "12.12.13.12"] def setup @@ -1031,27 +1033,27 @@ class ValidatesNumericalityTest Topic.validates_numericality_of :approved invalid!(NIL + JUNK) - valid!(FLOATS + INTEGERS) + valid!(FLOATS + INTEGERS + BIGDECIMAL) end def test_validates_numericality_of_with_nil_allowed Topic.validates_numericality_of :approved, :allow_nil => true invalid!(JUNK) - valid!(NIL + FLOATS + INTEGERS) + valid!(NIL + FLOATS + INTEGERS + BIGDECIMAL) end def test_validates_numericality_of_with_integer_only Topic.validates_numericality_of :approved, :only_integer => true - invalid!(NIL + JUNK + FLOATS) + invalid!(NIL + JUNK + FLOATS + BIGDECIMAL) valid!(INTEGERS) end def test_validates_numericality_of_with_integer_only_and_nil_allowed Topic.validates_numericality_of :approved, :only_integer => true, :allow_nil => true - invalid!(JUNK + FLOATS) + invalid!(JUNK + FLOATS + BIGDECIMAL) valid!(NIL + INTEGERS) end -- cgit v1.2.3