activerecord 1.0.0 → 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of activerecord might be problematic. Click here for more details.
- data/CHANGELOG +4928 -3
- data/README +45 -46
- data/RUNNING_UNIT_TESTS +8 -11
- data/Rakefile +247 -0
- data/install.rb +8 -38
- data/lib/active_record/aggregations.rb +64 -49
- data/lib/active_record/associations/association_collection.rb +217 -47
- data/lib/active_record/associations/association_proxy.rb +159 -0
- data/lib/active_record/associations/belongs_to_association.rb +56 -0
- data/lib/active_record/associations/belongs_to_polymorphic_association.rb +50 -0
- data/lib/active_record/associations/has_and_belongs_to_many_association.rb +155 -37
- data/lib/active_record/associations/has_many_association.rb +145 -75
- data/lib/active_record/associations/has_many_through_association.rb +283 -0
- data/lib/active_record/associations/has_one_association.rb +96 -0
- data/lib/active_record/associations.rb +1537 -304
- data/lib/active_record/attribute_methods.rb +328 -0
- data/lib/active_record/base.rb +2001 -588
- data/lib/active_record/calculations.rb +269 -0
- data/lib/active_record/callbacks.rb +169 -165
- data/lib/active_record/connection_adapters/abstract/connection_specification.rb +308 -0
- data/lib/active_record/connection_adapters/abstract/database_statements.rb +171 -0
- data/lib/active_record/connection_adapters/abstract/query_cache.rb +87 -0
- data/lib/active_record/connection_adapters/abstract/quoting.rb +69 -0
- data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +472 -0
- data/lib/active_record/connection_adapters/abstract/schema_statements.rb +306 -0
- data/lib/active_record/connection_adapters/abstract_adapter.rb +125 -279
- data/lib/active_record/connection_adapters/mysql_adapter.rb +442 -77
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +805 -135
- data/lib/active_record/connection_adapters/sqlite3_adapter.rb +34 -0
- data/lib/active_record/connection_adapters/sqlite_adapter.rb +353 -69
- data/lib/active_record/fixtures.rb +946 -100
- data/lib/active_record/locking/optimistic.rb +144 -0
- data/lib/active_record/locking/pessimistic.rb +77 -0
- data/lib/active_record/migration.rb +417 -0
- data/lib/active_record/observer.rb +142 -32
- data/lib/active_record/query_cache.rb +23 -0
- data/lib/active_record/reflection.rb +163 -70
- data/lib/active_record/schema.rb +58 -0
- data/lib/active_record/schema_dumper.rb +171 -0
- data/lib/active_record/serialization.rb +98 -0
- data/lib/active_record/serializers/json_serializer.rb +71 -0
- data/lib/active_record/serializers/xml_serializer.rb +315 -0
- data/lib/active_record/timestamp.rb +41 -0
- data/lib/active_record/transactions.rb +87 -57
- data/lib/active_record/validations.rb +909 -122
- data/lib/active_record/vendor/db2.rb +362 -0
- data/lib/active_record/vendor/mysql.rb +126 -29
- data/lib/active_record/version.rb +9 -0
- data/lib/active_record.rb +35 -7
- data/lib/activerecord.rb +1 -0
- data/test/aaa_create_tables_test.rb +72 -0
- data/test/abstract_unit.rb +73 -5
- data/test/active_schema_test_mysql.rb +43 -0
- data/test/adapter_test.rb +105 -0
- data/test/adapter_test_sqlserver.rb +95 -0
- data/test/aggregations_test.rb +110 -16
- data/test/all.sh +2 -2
- data/test/ar_schema_test.rb +33 -0
- data/test/association_inheritance_reload.rb +14 -0
- data/test/associations/ar_joins_test.rb +0 -0
- data/test/associations/callbacks_test.rb +147 -0
- data/test/associations/cascaded_eager_loading_test.rb +110 -0
- data/test/associations/eager_singularization_test.rb +145 -0
- data/test/associations/eager_test.rb +442 -0
- data/test/associations/extension_test.rb +47 -0
- data/test/associations/inner_join_association_test.rb +88 -0
- data/test/associations/join_model_test.rb +553 -0
- data/test/associations_test.rb +1930 -267
- data/test/attribute_methods_test.rb +146 -0
- data/test/base_test.rb +1316 -84
- data/test/binary_test.rb +32 -0
- data/test/calculations_test.rb +251 -0
- data/test/callbacks_test.rb +400 -0
- data/test/class_inheritable_attributes_test.rb +3 -4
- data/test/column_alias_test.rb +17 -0
- data/test/connection_test_firebird.rb +8 -0
- data/test/connection_test_mysql.rb +30 -0
- data/test/connections/native_db2/connection.rb +25 -0
- data/test/connections/native_firebird/connection.rb +26 -0
- data/test/connections/native_frontbase/connection.rb +27 -0
- data/test/connections/native_mysql/connection.rb +21 -18
- data/test/connections/native_openbase/connection.rb +21 -0
- data/test/connections/native_oracle/connection.rb +27 -0
- data/test/connections/native_postgresql/connection.rb +17 -18
- data/test/connections/native_sqlite/connection.rb +17 -16
- data/test/connections/native_sqlite3/connection.rb +25 -0
- data/test/connections/native_sqlite3/in_memory_connection.rb +18 -0
- data/test/connections/native_sybase/connection.rb +23 -0
- data/test/copy_table_test_sqlite.rb +69 -0
- data/test/datatype_test_postgresql.rb +203 -0
- data/test/date_time_test.rb +37 -0
- data/test/default_test_firebird.rb +16 -0
- data/test/defaults_test.rb +67 -0
- data/test/deprecated_finder_test.rb +30 -0
- data/test/finder_test.rb +607 -32
- data/test/fixtures/accounts.yml +28 -0
- data/test/fixtures/all/developers.yml +0 -0
- data/test/fixtures/all/people.csv +0 -0
- data/test/fixtures/all/tasks.yml +0 -0
- data/test/fixtures/author.rb +107 -0
- data/test/fixtures/author_favorites.yml +4 -0
- data/test/fixtures/authors.yml +7 -0
- data/test/fixtures/bad_fixtures/attr_with_numeric_first_char +1 -0
- data/test/fixtures/bad_fixtures/attr_with_spaces +1 -0
- data/test/fixtures/bad_fixtures/blank_line +3 -0
- data/test/fixtures/bad_fixtures/duplicate_attributes +3 -0
- data/test/fixtures/bad_fixtures/missing_value +1 -0
- data/test/fixtures/binaries.yml +132 -0
- data/test/fixtures/binary.rb +2 -0
- data/test/fixtures/book.rb +4 -0
- data/test/fixtures/books.yml +7 -0
- data/test/fixtures/categories/special_categories.yml +9 -0
- data/test/fixtures/categories/subsubdir/arbitrary_filename.yml +4 -0
- data/test/fixtures/categories.yml +14 -0
- data/test/fixtures/categories_ordered.yml +7 -0
- data/test/fixtures/categories_posts.yml +23 -0
- data/test/fixtures/categorization.rb +5 -0
- data/test/fixtures/categorizations.yml +17 -0
- data/test/fixtures/category.rb +26 -0
- data/test/fixtures/citation.rb +6 -0
- data/test/fixtures/comment.rb +23 -0
- data/test/fixtures/comments.yml +59 -0
- data/test/fixtures/companies.yml +55 -0
- data/test/fixtures/company.rb +81 -4
- data/test/fixtures/company_in_module.rb +32 -6
- data/test/fixtures/computer.rb +4 -0
- data/test/fixtures/computers.yml +4 -0
- data/test/fixtures/contact.rb +16 -0
- data/test/fixtures/courses.yml +7 -0
- data/test/fixtures/customer.rb +28 -3
- data/test/fixtures/customers.yml +17 -0
- data/test/fixtures/db_definitions/db2.drop.sql +33 -0
- data/test/fixtures/db_definitions/db2.sql +235 -0
- data/test/fixtures/db_definitions/db22.drop.sql +2 -0
- data/test/fixtures/db_definitions/db22.sql +5 -0
- data/test/fixtures/db_definitions/firebird.drop.sql +65 -0
- data/test/fixtures/db_definitions/firebird.sql +310 -0
- data/test/fixtures/db_definitions/firebird2.drop.sql +2 -0
- data/test/fixtures/db_definitions/firebird2.sql +6 -0
- data/test/fixtures/db_definitions/frontbase.drop.sql +33 -0
- data/test/fixtures/db_definitions/frontbase.sql +273 -0
- data/test/fixtures/db_definitions/frontbase2.drop.sql +1 -0
- data/test/fixtures/db_definitions/frontbase2.sql +4 -0
- data/test/fixtures/db_definitions/openbase.drop.sql +2 -0
- data/test/fixtures/db_definitions/openbase.sql +318 -0
- data/test/fixtures/db_definitions/openbase2.drop.sql +2 -0
- data/test/fixtures/db_definitions/openbase2.sql +7 -0
- data/test/fixtures/db_definitions/oracle.drop.sql +67 -0
- data/test/fixtures/db_definitions/oracle.sql +330 -0
- data/test/fixtures/db_definitions/oracle2.drop.sql +2 -0
- data/test/fixtures/db_definitions/oracle2.sql +6 -0
- data/test/fixtures/db_definitions/postgresql.drop.sql +44 -0
- data/test/fixtures/db_definitions/postgresql.sql +217 -38
- data/test/fixtures/db_definitions/postgresql2.drop.sql +2 -0
- data/test/fixtures/db_definitions/postgresql2.sql +2 -2
- data/test/fixtures/db_definitions/schema.rb +354 -0
- data/test/fixtures/db_definitions/schema2.rb +11 -0
- data/test/fixtures/db_definitions/sqlite.drop.sql +33 -0
- data/test/fixtures/db_definitions/sqlite.sql +139 -5
- data/test/fixtures/db_definitions/sqlite2.drop.sql +2 -0
- data/test/fixtures/db_definitions/sqlite2.sql +1 -0
- data/test/fixtures/db_definitions/sybase.drop.sql +35 -0
- data/test/fixtures/db_definitions/sybase.sql +222 -0
- data/test/fixtures/db_definitions/sybase2.drop.sql +4 -0
- data/test/fixtures/db_definitions/sybase2.sql +5 -0
- data/test/fixtures/developer.rb +70 -6
- data/test/fixtures/developers.yml +21 -0
- data/test/fixtures/developers_projects/david_action_controller +2 -1
- data/test/fixtures/developers_projects/david_active_record +2 -1
- data/test/fixtures/developers_projects.yml +17 -0
- data/test/fixtures/edge.rb +5 -0
- data/test/fixtures/edges.yml +6 -0
- data/test/fixtures/entrants.yml +14 -0
- data/test/fixtures/example.log +1 -0
- data/test/fixtures/fk_test_has_fk.yml +3 -0
- data/test/fixtures/fk_test_has_pk.yml +2 -0
- data/test/fixtures/flowers.jpg +0 -0
- data/test/fixtures/funny_jokes.yml +10 -0
- data/test/fixtures/item.rb +7 -0
- data/test/fixtures/items.yml +4 -0
- data/test/fixtures/joke.rb +3 -0
- data/test/fixtures/keyboard.rb +3 -0
- data/test/fixtures/legacy_thing.rb +3 -0
- data/test/fixtures/legacy_things.yml +3 -0
- data/test/fixtures/matey.rb +4 -0
- data/test/fixtures/mateys.yml +4 -0
- data/test/fixtures/migrations/1_people_have_last_names.rb +9 -0
- data/test/fixtures/migrations/2_we_need_reminders.rb +12 -0
- data/test/fixtures/migrations/3_innocent_jointable.rb +12 -0
- data/test/fixtures/migrations_with_decimal/1_give_me_big_numbers.rb +15 -0
- data/test/fixtures/migrations_with_duplicate/1_people_have_last_names.rb +9 -0
- data/test/fixtures/migrations_with_duplicate/2_we_need_reminders.rb +12 -0
- data/test/fixtures/migrations_with_duplicate/3_foo.rb +7 -0
- data/test/fixtures/migrations_with_duplicate/3_innocent_jointable.rb +12 -0
- data/test/fixtures/migrations_with_missing_versions/1000_people_have_middle_names.rb +9 -0
- data/test/fixtures/migrations_with_missing_versions/1_people_have_last_names.rb +9 -0
- data/test/fixtures/migrations_with_missing_versions/3_we_need_reminders.rb +12 -0
- data/test/fixtures/migrations_with_missing_versions/4_innocent_jointable.rb +12 -0
- data/test/fixtures/minimalistic.rb +2 -0
- data/test/fixtures/minimalistics.yml +2 -0
- data/test/fixtures/mixed_case_monkey.rb +3 -0
- data/test/fixtures/mixed_case_monkeys.yml +6 -0
- data/test/fixtures/mixins.yml +29 -0
- data/test/fixtures/movies.yml +7 -0
- data/test/fixtures/naked/csv/accounts.csv +1 -0
- data/test/fixtures/naked/yml/accounts.yml +1 -0
- data/test/fixtures/naked/yml/companies.yml +1 -0
- data/test/fixtures/naked/yml/courses.yml +1 -0
- data/test/fixtures/order.rb +4 -0
- data/test/fixtures/parrot.rb +13 -0
- data/test/fixtures/parrots.yml +27 -0
- data/test/fixtures/parrots_pirates.yml +7 -0
- data/test/fixtures/people.yml +3 -0
- data/test/fixtures/person.rb +4 -0
- data/test/fixtures/pirate.rb +5 -0
- data/test/fixtures/pirates.yml +9 -0
- data/test/fixtures/post.rb +59 -0
- data/test/fixtures/posts.yml +48 -0
- data/test/fixtures/project.rb +27 -2
- data/test/fixtures/projects.yml +7 -0
- data/test/fixtures/reader.rb +4 -0
- data/test/fixtures/readers.yml +4 -0
- data/test/fixtures/reply.rb +18 -2
- data/test/fixtures/reserved_words/distinct.yml +5 -0
- data/test/fixtures/reserved_words/distincts_selects.yml +11 -0
- data/test/fixtures/reserved_words/group.yml +14 -0
- data/test/fixtures/reserved_words/select.yml +8 -0
- data/test/fixtures/reserved_words/values.yml +7 -0
- data/test/fixtures/ship.rb +3 -0
- data/test/fixtures/ships.yml +5 -0
- data/test/fixtures/subject.rb +4 -0
- data/test/fixtures/subscriber.rb +4 -3
- data/test/fixtures/tag.rb +7 -0
- data/test/fixtures/tagging.rb +10 -0
- data/test/fixtures/taggings.yml +25 -0
- data/test/fixtures/tags.yml +7 -0
- data/test/fixtures/task.rb +3 -0
- data/test/fixtures/tasks.yml +7 -0
- data/test/fixtures/topic.rb +20 -3
- data/test/fixtures/topics.yml +22 -0
- data/test/fixtures/treasure.rb +4 -0
- data/test/fixtures/treasures.yml +10 -0
- data/test/fixtures/vertex.rb +9 -0
- data/test/fixtures/vertices.yml +4 -0
- data/test/fixtures_test.rb +574 -8
- data/test/inheritance_test.rb +113 -27
- data/test/json_serialization_test.rb +180 -0
- data/test/lifecycle_test.rb +56 -29
- data/test/locking_test.rb +273 -0
- data/test/method_scoping_test.rb +416 -0
- data/test/migration_test.rb +933 -0
- data/test/migration_test_firebird.rb +124 -0
- data/test/mixin_test.rb +95 -0
- data/test/modules_test.rb +23 -10
- data/test/multiple_db_test.rb +17 -3
- data/test/pk_test.rb +59 -15
- data/test/query_cache_test.rb +104 -0
- data/test/readonly_test.rb +107 -0
- data/test/reflection_test.rb +124 -27
- data/test/reserved_word_test_mysql.rb +177 -0
- data/test/schema_authorization_test_postgresql.rb +75 -0
- data/test/schema_dumper_test.rb +131 -0
- data/test/schema_test_postgresql.rb +64 -0
- data/test/serialization_test.rb +47 -0
- data/test/synonym_test_oracle.rb +17 -0
- data/test/table_name_test_sqlserver.rb +23 -0
- data/test/threaded_connections_test.rb +48 -0
- data/test/transactions_test.rb +227 -29
- data/test/unconnected_test.rb +14 -6
- data/test/validations_test.rb +1293 -32
- data/test/xml_serialization_test.rb +202 -0
- metadata +347 -143
- data/dev-utils/eval_debugger.rb +0 -9
- data/examples/associations.rb +0 -87
- data/examples/shared_setup.rb +0 -15
- data/examples/validation.rb +0 -88
- data/lib/active_record/deprecated_associations.rb +0 -70
- data/lib/active_record/support/class_attribute_accessors.rb +0 -43
- data/lib/active_record/support/class_inheritable_attributes.rb +0 -37
- data/lib/active_record/support/clean_logger.rb +0 -10
- data/lib/active_record/support/inflector.rb +0 -70
- data/lib/active_record/vendor/simple.rb +0 -702
- data/lib/active_record/wrappers/yaml_wrapper.rb +0 -15
- data/lib/active_record/wrappings.rb +0 -59
- data/rakefile +0 -122
- data/test/deprecated_associations_test.rb +0 -336
- data/test/fixtures/accounts/signals37 +0 -3
- data/test/fixtures/accounts/unknown +0 -2
- data/test/fixtures/companies/first_client +0 -6
- data/test/fixtures/companies/first_firm +0 -4
- data/test/fixtures/companies/second_client +0 -6
- data/test/fixtures/courses/java +0 -2
- data/test/fixtures/courses/ruby +0 -2
- data/test/fixtures/customers/david +0 -6
- data/test/fixtures/db_definitions/mysql.sql +0 -96
- data/test/fixtures/db_definitions/mysql2.sql +0 -4
- data/test/fixtures/developers/david +0 -2
- data/test/fixtures/developers/jamis +0 -2
- data/test/fixtures/entrants/first +0 -3
- data/test/fixtures/entrants/second +0 -3
- data/test/fixtures/entrants/third +0 -3
- data/test/fixtures/fixture_database.sqlite +0 -0
- data/test/fixtures/fixture_database_2.sqlite +0 -0
- data/test/fixtures/movies/first +0 -2
- data/test/fixtures/movies/second +0 -2
- data/test/fixtures/projects/action_controller +0 -2
- data/test/fixtures/projects/active_record +0 -2
- data/test/fixtures/topics/first +0 -9
- data/test/fixtures/topics/second +0 -8
- data/test/inflector_test.rb +0 -104
- data/test/thread_safety_test.rb +0 -33
data/test/inheritance_test.rb
CHANGED
@@ -1,20 +1,30 @@
|
|
1
1
|
require 'abstract_unit'
|
2
2
|
require 'fixtures/company'
|
3
|
-
|
3
|
+
require 'fixtures/project'
|
4
|
+
require 'fixtures/subscriber'
|
4
5
|
|
5
6
|
class InheritanceTest < Test::Unit::TestCase
|
6
|
-
|
7
|
-
|
7
|
+
fixtures :companies, :projects, :subscribers, :accounts
|
8
|
+
|
9
|
+
def test_company_descends_from_active_record
|
10
|
+
assert_raise(NoMethodError) { ActiveRecord::Base.descends_from_active_record? }
|
11
|
+
assert AbstractCompany.descends_from_active_record?, 'AbstractCompany should descend from ActiveRecord::Base'
|
12
|
+
assert Company.descends_from_active_record?, 'Company should descend from ActiveRecord::Base'
|
13
|
+
assert !Class.new(Company).descends_from_active_record?, 'Company subclass should not descend from ActiveRecord::Base'
|
8
14
|
end
|
9
15
|
|
10
|
-
def
|
11
|
-
#
|
12
|
-
|
13
|
-
|
14
|
-
c.save
|
16
|
+
def test_a_bad_type_column
|
17
|
+
#SQLServer need to turn Identity Insert On before manually inserting into the Identity column
|
18
|
+
if current_adapter?(:SQLServerAdapter, :SybaseAdapter)
|
19
|
+
Company.connection.execute "SET IDENTITY_INSERT companies ON"
|
15
20
|
end
|
16
|
-
|
17
|
-
|
21
|
+
Company.connection.insert "INSERT INTO companies (id, #{QUOTED_TYPE}, name) VALUES(100, 'bad_class!', 'Not happening')"
|
22
|
+
|
23
|
+
#We then need to turn it back Off before continuing.
|
24
|
+
if current_adapter?(:SQLServerAdapter, :SybaseAdapter)
|
25
|
+
Company.connection.execute "SET IDENTITY_INSERT companies OFF"
|
26
|
+
end
|
27
|
+
assert_raises(ActiveRecord::SubclassNotFound) { Company.find(100) }
|
18
28
|
end
|
19
29
|
|
20
30
|
def test_inheritance_find
|
@@ -27,10 +37,11 @@ class InheritanceTest < Test::Unit::TestCase
|
|
27
37
|
def test_alt_inheritance_find
|
28
38
|
switch_to_alt_inheritance_column
|
29
39
|
test_inheritance_find
|
40
|
+
switch_to_default_inheritance_column
|
30
41
|
end
|
31
42
|
|
32
43
|
def test_inheritance_find_all
|
33
|
-
companies = Company.
|
44
|
+
companies = Company.find(:all, :order => 'id')
|
34
45
|
assert companies[0].kind_of?(Firm), "37signals should be a firm"
|
35
46
|
assert companies[1].kind_of?(Client), "Summit should be a client"
|
36
47
|
end
|
@@ -38,6 +49,7 @@ class InheritanceTest < Test::Unit::TestCase
|
|
38
49
|
def test_alt_inheritance_find_all
|
39
50
|
switch_to_alt_inheritance_column
|
40
51
|
test_inheritance_find_all
|
52
|
+
switch_to_default_inheritance_column
|
41
53
|
end
|
42
54
|
|
43
55
|
def test_inheritance_save
|
@@ -52,17 +64,19 @@ class InheritanceTest < Test::Unit::TestCase
|
|
52
64
|
def test_alt_inheritance_save
|
53
65
|
switch_to_alt_inheritance_column
|
54
66
|
test_inheritance_save
|
67
|
+
switch_to_default_inheritance_column
|
55
68
|
end
|
56
69
|
|
57
70
|
def test_inheritance_condition
|
58
|
-
assert_equal
|
59
|
-
assert_equal
|
60
|
-
assert_equal
|
71
|
+
assert_equal 9, Company.count
|
72
|
+
assert_equal 2, Firm.count
|
73
|
+
assert_equal 3, Client.count
|
61
74
|
end
|
62
75
|
|
63
76
|
def test_alt_inheritance_condition
|
64
77
|
switch_to_alt_inheritance_column
|
65
78
|
test_inheritance_condition
|
79
|
+
switch_to_default_inheritance_column
|
66
80
|
end
|
67
81
|
|
68
82
|
def test_finding_incorrect_type_data
|
@@ -73,53 +87,125 @@ class InheritanceTest < Test::Unit::TestCase
|
|
73
87
|
def test_alt_finding_incorrect_type_data
|
74
88
|
switch_to_alt_inheritance_column
|
75
89
|
test_finding_incorrect_type_data
|
90
|
+
switch_to_default_inheritance_column
|
76
91
|
end
|
77
92
|
|
78
93
|
def test_update_all_within_inheritance
|
79
94
|
Client.update_all "name = 'I am a client'"
|
80
|
-
assert_equal "I am a client", Client.
|
81
|
-
assert_equal "37signals", Firm.
|
95
|
+
assert_equal "I am a client", Client.find(:all).first.name
|
96
|
+
assert_equal "37signals", Firm.find(:all).first.name
|
82
97
|
end
|
83
98
|
|
84
99
|
def test_alt_update_all_within_inheritance
|
85
100
|
switch_to_alt_inheritance_column
|
86
101
|
test_update_all_within_inheritance
|
102
|
+
switch_to_default_inheritance_column
|
87
103
|
end
|
88
104
|
|
89
105
|
def test_destroy_all_within_inheritance
|
90
106
|
Client.destroy_all
|
91
|
-
assert_equal 0, Client.
|
92
|
-
assert_equal
|
107
|
+
assert_equal 0, Client.count
|
108
|
+
assert_equal 2, Firm.count
|
93
109
|
end
|
94
110
|
|
95
111
|
def test_alt_destroy_all_within_inheritance
|
96
112
|
switch_to_alt_inheritance_column
|
97
113
|
test_destroy_all_within_inheritance
|
114
|
+
switch_to_default_inheritance_column
|
98
115
|
end
|
99
116
|
|
100
117
|
def test_find_first_within_inheritance
|
101
|
-
assert_kind_of Firm, Company.
|
102
|
-
assert_kind_of Firm, Firm.
|
103
|
-
assert_nil Client.
|
118
|
+
assert_kind_of Firm, Company.find(:first, :conditions => "name = '37signals'")
|
119
|
+
assert_kind_of Firm, Firm.find(:first, :conditions => "name = '37signals'")
|
120
|
+
assert_nil Client.find(:first, :conditions => "name = '37signals'")
|
104
121
|
end
|
105
122
|
|
106
123
|
def test_alt_find_first_within_inheritance
|
107
124
|
switch_to_alt_inheritance_column
|
108
125
|
test_find_first_within_inheritance
|
126
|
+
switch_to_default_inheritance_column
|
109
127
|
end
|
110
128
|
|
111
129
|
def test_complex_inheritance
|
112
130
|
very_special_client = VerySpecialClient.create("name" => "veryspecial")
|
113
|
-
assert_equal very_special_client, VerySpecialClient.
|
114
|
-
assert_equal very_special_client, SpecialClient.
|
115
|
-
assert_equal very_special_client, Company.
|
116
|
-
assert_equal very_special_client, Client.
|
117
|
-
assert_equal 1, Client.
|
131
|
+
assert_equal very_special_client, VerySpecialClient.find(:first, :conditions => "name = 'veryspecial'")
|
132
|
+
assert_equal very_special_client, SpecialClient.find(:first, :conditions => "name = 'veryspecial'")
|
133
|
+
assert_equal very_special_client, Company.find(:first, :conditions => "name = 'veryspecial'")
|
134
|
+
assert_equal very_special_client, Client.find(:first, :conditions => "name = 'veryspecial'")
|
135
|
+
assert_equal 1, Client.find(:all, :conditions => "name = 'Summit'").size
|
118
136
|
assert_equal very_special_client, Client.find(very_special_client.id)
|
119
137
|
end
|
120
138
|
|
121
139
|
def test_alt_complex_inheritance
|
122
140
|
switch_to_alt_inheritance_column
|
123
141
|
test_complex_inheritance
|
142
|
+
switch_to_default_inheritance_column
|
143
|
+
end
|
144
|
+
|
145
|
+
def test_eager_load_belongs_to_something_inherited
|
146
|
+
account = Account.find(1, :include => :firm)
|
147
|
+
assert_not_nil account.instance_variable_get("@firm"), "nil proves eager load failed"
|
148
|
+
end
|
149
|
+
|
150
|
+
def test_alt_eager_loading
|
151
|
+
switch_to_alt_inheritance_column
|
152
|
+
test_eager_load_belongs_to_something_inherited
|
153
|
+
switch_to_default_inheritance_column
|
154
|
+
end
|
155
|
+
|
156
|
+
def test_inheritance_without_mapping
|
157
|
+
assert_kind_of SpecialSubscriber, SpecialSubscriber.find("webster132")
|
158
|
+
assert_nothing_raised { s = SpecialSubscriber.new("name" => "And breaaaaathe!"); s.id = 'roger'; s.save }
|
159
|
+
end
|
160
|
+
|
161
|
+
private
|
162
|
+
def switch_to_alt_inheritance_column
|
163
|
+
# we don't want misleading test results, so get rid of the values in the type column
|
164
|
+
Company.find(:all, :order => 'id').each do |c|
|
165
|
+
c['type'] = nil
|
166
|
+
c.save
|
167
|
+
end
|
168
|
+
[ Company, Firm, Client].each { |klass| klass.reset_column_information }
|
169
|
+
Company.set_inheritance_column('ruby_type')
|
170
|
+
end
|
171
|
+
def switch_to_default_inheritance_column
|
172
|
+
[ Company, Firm, Client].each { |klass| klass.reset_column_information }
|
173
|
+
Company.set_inheritance_column('type')
|
174
|
+
end
|
175
|
+
end
|
176
|
+
|
177
|
+
|
178
|
+
class InheritanceComputeTypeTest < Test::Unit::TestCase
|
179
|
+
fixtures :companies
|
180
|
+
|
181
|
+
def setup
|
182
|
+
Dependencies.log_activity = true
|
183
|
+
end
|
184
|
+
|
185
|
+
def teardown
|
186
|
+
Dependencies.log_activity = false
|
187
|
+
self.class.const_remove :FirmOnTheFly rescue nil
|
188
|
+
Firm.const_remove :FirmOnTheFly rescue nil
|
189
|
+
end
|
190
|
+
|
191
|
+
def test_instantiation_doesnt_try_to_require_corresponding_file
|
192
|
+
foo = Firm.find(:first).clone
|
193
|
+
foo.ruby_type = foo.type = 'FirmOnTheFly'
|
194
|
+
foo.save!
|
195
|
+
|
196
|
+
# Should fail without FirmOnTheFly in the type condition.
|
197
|
+
assert_raise(ActiveRecord::RecordNotFound) { Firm.find(foo.id) }
|
198
|
+
|
199
|
+
# Nest FirmOnTheFly in the test case where Dependencies won't see it.
|
200
|
+
self.class.const_set :FirmOnTheFly, Class.new(Firm)
|
201
|
+
assert_raise(ActiveRecord::SubclassNotFound) { Firm.find(foo.id) }
|
202
|
+
|
203
|
+
# Nest FirmOnTheFly in Firm where Dependencies will see it.
|
204
|
+
# This is analogous to nesting models in a migration.
|
205
|
+
Firm.const_set :FirmOnTheFly, Class.new(Firm)
|
206
|
+
|
207
|
+
# And instantiate will find the existing constant rather than trying
|
208
|
+
# to require firm_on_the_fly.
|
209
|
+
assert_nothing_raised { assert_kind_of Firm::FirmOnTheFly, Firm.find(foo.id) }
|
124
210
|
end
|
125
|
-
end
|
211
|
+
end
|
@@ -0,0 +1,180 @@
|
|
1
|
+
require 'abstract_unit'
|
2
|
+
require 'fixtures/contact'
|
3
|
+
require 'fixtures/post'
|
4
|
+
require 'fixtures/author'
|
5
|
+
require 'fixtures/tagging'
|
6
|
+
require 'fixtures/tag'
|
7
|
+
require 'fixtures/comment'
|
8
|
+
|
9
|
+
class JsonSerializationTest < Test::Unit::TestCase
|
10
|
+
def setup
|
11
|
+
@contact = Contact.new(
|
12
|
+
:name => 'Konata Izumi',
|
13
|
+
:age => 16,
|
14
|
+
:avatar => 'binarydata',
|
15
|
+
:created_at => Time.utc(2006, 8, 1),
|
16
|
+
:awesome => true,
|
17
|
+
:preferences => { :shows => 'anime' }
|
18
|
+
)
|
19
|
+
end
|
20
|
+
|
21
|
+
def test_should_encode_all_encodable_attributes
|
22
|
+
json = @contact.to_json
|
23
|
+
|
24
|
+
assert_match %r{"name": "Konata Izumi"}, json
|
25
|
+
assert_match %r{"age": 16}, json
|
26
|
+
assert json.include?(%("created_at": #{ActiveSupport::JSON.encode(Time.utc(2006, 8, 1))}))
|
27
|
+
assert_match %r{"awesome": true}, json
|
28
|
+
assert_match %r{"preferences": \{"shows": "anime"\}}, json
|
29
|
+
end
|
30
|
+
|
31
|
+
def test_should_allow_attribute_filtering_with_only
|
32
|
+
json = @contact.to_json(:only => [:name, :age])
|
33
|
+
|
34
|
+
assert_match %r{"name": "Konata Izumi"}, json
|
35
|
+
assert_match %r{"age": 16}, json
|
36
|
+
assert_no_match %r{"awesome": true}, json
|
37
|
+
assert !json.include?(%("created_at": #{ActiveSupport::JSON.encode(Time.utc(2006, 8, 1))}))
|
38
|
+
assert_no_match %r{"preferences": \{"shows": "anime"\}}, json
|
39
|
+
end
|
40
|
+
|
41
|
+
def test_should_allow_attribute_filtering_with_except
|
42
|
+
json = @contact.to_json(:except => [:name, :age])
|
43
|
+
|
44
|
+
assert_no_match %r{"name": "Konata Izumi"}, json
|
45
|
+
assert_no_match %r{"age": 16}, json
|
46
|
+
assert_match %r{"awesome": true}, json
|
47
|
+
assert json.include?(%("created_at": #{ActiveSupport::JSON.encode(Time.utc(2006, 8, 1))}))
|
48
|
+
assert_match %r{"preferences": \{"shows": "anime"\}}, json
|
49
|
+
end
|
50
|
+
|
51
|
+
def test_methods_are_called_on_object
|
52
|
+
# Define methods on fixture.
|
53
|
+
def @contact.label; "Has cheezburger"; end
|
54
|
+
def @contact.favorite_quote; "Constraints are liberating"; end
|
55
|
+
|
56
|
+
# Single method.
|
57
|
+
assert_match %r{"label": "Has cheezburger"}, @contact.to_json(:only => :name, :methods => :label)
|
58
|
+
|
59
|
+
# Both methods.
|
60
|
+
methods_json = @contact.to_json(:only => :name, :methods => [:label, :favorite_quote])
|
61
|
+
assert_match %r{"label": "Has cheezburger"}, methods_json
|
62
|
+
assert_match %r{"favorite_quote": "Constraints are liberating"}, methods_json
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
class DatabaseConnectedJsonEncodingTest < Test::Unit::TestCase
|
67
|
+
fixtures :authors, :posts, :comments, :tags, :taggings
|
68
|
+
|
69
|
+
def setup
|
70
|
+
@david = authors(:david)
|
71
|
+
@mary = authors(:mary)
|
72
|
+
end
|
73
|
+
|
74
|
+
def test_includes_uses_association_name
|
75
|
+
json = @david.to_json(:include => :posts)
|
76
|
+
|
77
|
+
assert_match %r{"posts": \[}, json
|
78
|
+
|
79
|
+
assert_match %r{"id": 1}, json
|
80
|
+
assert_match %r{"name": "David"}, json
|
81
|
+
|
82
|
+
assert_match %r{"author_id": 1}, json
|
83
|
+
assert_match %r{"title": "Welcome to the weblog"}, json
|
84
|
+
assert_match %r{"body": "Such a lovely day"}, json
|
85
|
+
|
86
|
+
assert_match %r{"title": "So I was thinking"}, json
|
87
|
+
assert_match %r{"body": "Like I hopefully always am"}, json
|
88
|
+
end
|
89
|
+
|
90
|
+
def test_includes_uses_association_name_and_applies_attribute_filters
|
91
|
+
json = @david.to_json(:include => { :posts => { :only => :title } })
|
92
|
+
|
93
|
+
assert_match %r{"name": "David"}, json
|
94
|
+
assert_match %r{"posts": \[}, json
|
95
|
+
|
96
|
+
assert_match %r{"title": "Welcome to the weblog"}, json
|
97
|
+
assert_no_match %r{"body": "Such a lovely day"}, json
|
98
|
+
|
99
|
+
assert_match %r{"title": "So I was thinking"}, json
|
100
|
+
assert_no_match %r{"body": "Like I hopefully always am"}, json
|
101
|
+
end
|
102
|
+
|
103
|
+
def test_includes_fetches_second_level_associations
|
104
|
+
json = @david.to_json(:include => { :posts => { :include => { :comments => { :only => :body } } } })
|
105
|
+
|
106
|
+
assert_match %r{"name": "David"}, json
|
107
|
+
assert_match %r{"posts": \[}, json
|
108
|
+
|
109
|
+
assert_match %r{"comments": \[}, json
|
110
|
+
assert_match %r{\{"body": "Thank you again for the welcome"\}}, json
|
111
|
+
assert_match %r{\{"body": "Don't think too hard"\}}, json
|
112
|
+
assert_no_match %r{"post_id": }, json
|
113
|
+
end
|
114
|
+
|
115
|
+
def test_includes_fetches_nth_level_associations
|
116
|
+
json = @david.to_json(
|
117
|
+
:include => {
|
118
|
+
:posts => {
|
119
|
+
:include => {
|
120
|
+
:taggings => {
|
121
|
+
:include => {
|
122
|
+
:tag => { :only => :name }
|
123
|
+
}
|
124
|
+
}
|
125
|
+
}
|
126
|
+
}
|
127
|
+
})
|
128
|
+
|
129
|
+
assert_match %r{"name": "David"}, json
|
130
|
+
assert_match %r{"posts": \[}, json
|
131
|
+
|
132
|
+
assert_match %r{"taggings": \[}, json
|
133
|
+
assert_match %r{"tag": \{"name": "General"\}}, json
|
134
|
+
end
|
135
|
+
|
136
|
+
def test_should_not_call_methods_on_associations_that_dont_respond
|
137
|
+
def @david.favorite_quote; "Constraints are liberating"; end
|
138
|
+
json = @david.to_json(:include => :posts, :methods => :favorite_quote)
|
139
|
+
|
140
|
+
assert !@david.posts.first.respond_to?(:favorite_quote)
|
141
|
+
assert_match %r{"favorite_quote": "Constraints are liberating"}, json
|
142
|
+
assert_equal %r{"favorite_quote": }.match(json).size, 1
|
143
|
+
end
|
144
|
+
|
145
|
+
def test_should_allow_only_option_for_list_of_authors
|
146
|
+
authors = [@david, @mary]
|
147
|
+
|
148
|
+
assert_equal %([{"name": "David"}, {"name": "Mary"}]), authors.to_json(:only => :name)
|
149
|
+
end
|
150
|
+
|
151
|
+
def test_should_allow_except_option_for_list_of_authors
|
152
|
+
authors = [@david, @mary]
|
153
|
+
|
154
|
+
assert_equal %([{"id": 1}, {"id": 2}]), authors.to_json(:except => [:name, :author_address_id])
|
155
|
+
end
|
156
|
+
|
157
|
+
def test_should_allow_includes_for_list_of_authors
|
158
|
+
authors = [@david, @mary]
|
159
|
+
json = authors.to_json(
|
160
|
+
:only => :name,
|
161
|
+
:include => {
|
162
|
+
:posts => { :only => :id }
|
163
|
+
}
|
164
|
+
)
|
165
|
+
|
166
|
+
['"name": "David"', '"posts": [', '{"id": 1}', '{"id": 2}', '{"id": 4}',
|
167
|
+
'{"id": 5}', '{"id": 6}', '"name": "Mary"', '"posts": [{"id": 7}]'].each do |fragment|
|
168
|
+
assert json.include?(fragment), json
|
169
|
+
end
|
170
|
+
end
|
171
|
+
|
172
|
+
def test_should_allow_options_for_hash_of_authors
|
173
|
+
authors_hash = {
|
174
|
+
1 => @david,
|
175
|
+
2 => @mary
|
176
|
+
}
|
177
|
+
|
178
|
+
assert_equal %({1: {"name": "David"}}), authors_hash.to_json(:only => [1, :name])
|
179
|
+
end
|
180
|
+
end
|
data/test/lifecycle_test.rb
CHANGED
@@ -1,10 +1,11 @@
|
|
1
|
-
# require File.dirname(__FILE__) + '/../dev-utils/eval_debugger'
|
2
1
|
require 'abstract_unit'
|
3
2
|
require 'fixtures/topic'
|
4
3
|
require 'fixtures/developer'
|
4
|
+
require 'fixtures/reply'
|
5
5
|
|
6
6
|
class Topic; def after_find() end end
|
7
7
|
class Developer; def after_find() end end
|
8
|
+
class SpecialDeveloper < Developer; end
|
8
9
|
|
9
10
|
class TopicManualObserver
|
10
11
|
include Singleton
|
@@ -26,7 +27,7 @@ class TopicManualObserver
|
|
26
27
|
end
|
27
28
|
|
28
29
|
class TopicaObserver < ActiveRecord::Observer
|
29
|
-
|
30
|
+
observe :topic
|
30
31
|
|
31
32
|
attr_reader :topic
|
32
33
|
|
@@ -45,66 +46,92 @@ end
|
|
45
46
|
|
46
47
|
class MultiObserver < ActiveRecord::Observer
|
47
48
|
attr_reader :record
|
48
|
-
|
49
|
+
|
49
50
|
def self.observed_class() [ Topic, Developer ] end
|
50
51
|
|
52
|
+
cattr_reader :last_inherited
|
53
|
+
@@last_inherited = nil
|
54
|
+
|
55
|
+
def observed_class_inherited_with_testing(subclass)
|
56
|
+
observed_class_inherited_without_testing(subclass)
|
57
|
+
@@last_inherited = subclass
|
58
|
+
end
|
59
|
+
|
60
|
+
alias_method_chain :observed_class_inherited, :testing
|
61
|
+
|
51
62
|
def after_find(record)
|
52
63
|
@record = record
|
53
64
|
end
|
54
|
-
|
55
65
|
end
|
56
66
|
|
57
67
|
class LifecycleTest < Test::Unit::TestCase
|
58
|
-
|
59
|
-
@topics, @developers = create_fixtures("topics", "developers")
|
60
|
-
end
|
68
|
+
fixtures :topics, :developers
|
61
69
|
|
62
70
|
def test_before_destroy
|
63
71
|
assert_equal 2, Topic.count
|
64
72
|
Topic.find(1).destroy
|
65
73
|
assert_equal 0, Topic.count
|
66
74
|
end
|
67
|
-
|
75
|
+
|
68
76
|
def test_after_save
|
69
|
-
|
77
|
+
ActiveRecord::Base.observers = :topic_manual_observer
|
78
|
+
ActiveRecord::Base.instantiate_observers
|
70
79
|
|
71
80
|
topic = Topic.find(1)
|
72
81
|
topic.title = "hello"
|
73
82
|
topic.save
|
74
|
-
|
75
|
-
assert
|
76
|
-
assert_equal :after_save,
|
83
|
+
|
84
|
+
assert TopicManualObserver.instance.has_been_notified?
|
85
|
+
assert_equal :after_save, TopicManualObserver.instance.callbacks.last["callback_method"]
|
77
86
|
end
|
78
|
-
|
87
|
+
|
79
88
|
def test_observer_update_on_save
|
80
|
-
|
89
|
+
ActiveRecord::Base.observers = TopicManualObserver
|
90
|
+
ActiveRecord::Base.instantiate_observers
|
81
91
|
|
82
|
-
topic = Topic.find(1)
|
83
|
-
assert
|
84
|
-
assert_equal :after_find,
|
92
|
+
topic = Topic.find(1)
|
93
|
+
assert TopicManualObserver.instance.has_been_notified?
|
94
|
+
assert_equal :after_find, TopicManualObserver.instance.callbacks.first["callback_method"]
|
85
95
|
end
|
86
|
-
|
96
|
+
|
87
97
|
def test_auto_observer
|
88
98
|
topic_observer = TopicaObserver.instance
|
89
99
|
|
90
|
-
topic = Topic.find(1)
|
91
|
-
assert_equal
|
100
|
+
topic = Topic.find(1)
|
101
|
+
assert_equal topic.title, topic_observer.topic.title
|
92
102
|
end
|
93
|
-
|
94
|
-
def
|
103
|
+
|
104
|
+
def test_inferred_auto_observer
|
95
105
|
topic_observer = TopicObserver.instance
|
96
106
|
|
97
|
-
topic = Topic.find(1)
|
98
|
-
assert_equal
|
107
|
+
topic = Topic.find(1)
|
108
|
+
assert_equal topic.title, topic_observer.topic.title
|
99
109
|
end
|
100
|
-
|
110
|
+
|
101
111
|
def test_observing_two_classes
|
102
112
|
multi_observer = MultiObserver.instance
|
103
113
|
|
104
114
|
topic = Topic.find(1)
|
105
|
-
assert_equal
|
115
|
+
assert_equal topic.title, multi_observer.record.title
|
106
116
|
|
107
|
-
developer = Developer.find(1)
|
108
|
-
assert_equal
|
117
|
+
developer = Developer.find(1)
|
118
|
+
assert_equal developer.name, multi_observer.record.name
|
109
119
|
end
|
110
|
-
|
120
|
+
|
121
|
+
def test_observing_subclasses
|
122
|
+
multi_observer = MultiObserver.instance
|
123
|
+
|
124
|
+
developer = SpecialDeveloper.find(1)
|
125
|
+
assert_equal developer.name, multi_observer.record.name
|
126
|
+
|
127
|
+
klass = Class.new(Developer)
|
128
|
+
assert_equal klass, multi_observer.last_inherited
|
129
|
+
|
130
|
+
developer = klass.find(1)
|
131
|
+
assert_equal developer.name, multi_observer.record.name
|
132
|
+
end
|
133
|
+
|
134
|
+
def test_invalid_observer
|
135
|
+
assert_raise(ArgumentError) { Topic.observers = Object.new; Topic.instantiate_observers }
|
136
|
+
end
|
137
|
+
end
|