aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord/test
diff options
context:
space:
mode:
Diffstat (limited to 'activerecord/test')
-rwxr-xr-xactiverecord/test/base_test.rb34
-rw-r--r--activerecord/test/calculations_test.rb2
-rw-r--r--activerecord/test/defaults_test.rb18
-rw-r--r--activerecord/test/fixtures/db_definitions/db2.drop.sql1
-rw-r--r--activerecord/test/fixtures/db_definitions/db2.sql9
-rw-r--r--activerecord/test/fixtures/db_definitions/firebird.drop.sql2
-rw-r--r--activerecord/test/fixtures/db_definitions/firebird.sql12
-rw-r--r--activerecord/test/fixtures/db_definitions/frontbase.drop.sql1
-rw-r--r--activerecord/test/fixtures/db_definitions/frontbase.sql11
-rw-r--r--activerecord/test/fixtures/db_definitions/mysql.drop.sql1
-rwxr-xr-xactiverecord/test/fixtures/db_definitions/mysql.sql9
-rw-r--r--activerecord/test/fixtures/db_definitions/openbase.sql14
-rw-r--r--activerecord/test/fixtures/db_definitions/oracle.drop.sql2
-rw-r--r--activerecord/test/fixtures/db_definitions/oracle.sql10
-rw-r--r--activerecord/test/fixtures/db_definitions/postgresql.drop.sql4
-rw-r--r--activerecord/test/fixtures/db_definitions/postgresql.sql12
-rw-r--r--activerecord/test/fixtures/db_definitions/sqlite.drop.sql1
-rw-r--r--activerecord/test/fixtures/db_definitions/sqlite.sql11
-rw-r--r--activerecord/test/fixtures/db_definitions/sqlserver.drop.sql2
-rw-r--r--activerecord/test/fixtures/db_definitions/sqlserver.sql27
-rw-r--r--activerecord/test/fixtures/db_definitions/sybase.drop.sql1
-rw-r--r--activerecord/test/fixtures/db_definitions/sybase.sql11
-rw-r--r--activerecord/test/fixtures/migrations_with_decimal/1_give_me_big_numbers.rb15
-rw-r--r--activerecord/test/locking_test.rb8
-rw-r--r--activerecord/test/migration_test.rb153
-rw-r--r--activerecord/test/schema_dumper_test.rb11
-rwxr-xr-xactiverecord/test/validations_test.rb12
27 files changed, 350 insertions, 44 deletions
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