datamapper 0.2.3 → 0.2.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (121) hide show
  1. data/example.rb +5 -5
  2. data/lib/data_mapper/adapters/abstract_adapter.rb +2 -2
  3. data/lib/data_mapper/adapters/data_object_adapter.rb +141 -147
  4. data/lib/data_mapper/adapters/mysql_adapter.rb +14 -1
  5. data/lib/data_mapper/adapters/postgresql_adapter.rb +123 -18
  6. data/lib/data_mapper/adapters/sql/coersion.rb +21 -9
  7. data/lib/data_mapper/adapters/sql/commands/load_command.rb +36 -19
  8. data/lib/data_mapper/adapters/sql/mappings/column.rb +111 -17
  9. data/lib/data_mapper/adapters/sql/mappings/schema.rb +27 -0
  10. data/lib/data_mapper/adapters/sql/mappings/table.rb +256 -29
  11. data/lib/data_mapper/adapters/sqlite3_adapter.rb +93 -8
  12. data/lib/data_mapper/associations/belongs_to_association.rb +53 -54
  13. data/lib/data_mapper/associations/has_and_belongs_to_many_association.rb +157 -25
  14. data/lib/data_mapper/associations/has_many_association.rb +45 -15
  15. data/lib/data_mapper/associations/has_n_association.rb +79 -20
  16. data/lib/data_mapper/associations/has_one_association.rb +2 -2
  17. data/lib/data_mapper/associations/reference.rb +1 -1
  18. data/lib/data_mapper/auto_migrations.rb +40 -0
  19. data/lib/data_mapper/base.rb +201 -98
  20. data/lib/data_mapper/context.rb +16 -10
  21. data/lib/data_mapper/database.rb +22 -11
  22. data/lib/data_mapper/dependency_queue.rb +28 -0
  23. data/lib/data_mapper/embedded_value.rb +61 -17
  24. data/lib/data_mapper/property.rb +4 -0
  25. data/lib/data_mapper/support/active_record_impersonation.rb +13 -5
  26. data/lib/data_mapper/support/errors.rb +5 -0
  27. data/lib/data_mapper/support/serialization.rb +8 -4
  28. data/lib/data_mapper/validatable_extensions/errors.rb +12 -0
  29. data/lib/data_mapper/validatable_extensions/macros.rb +7 -0
  30. data/lib/data_mapper/validatable_extensions/validatable_instance_methods.rb +62 -0
  31. data/lib/data_mapper/validatable_extensions/validation_base.rb +18 -0
  32. data/lib/data_mapper/validatable_extensions/validations/formats/email.rb +43 -0
  33. data/lib/data_mapper/validatable_extensions/validations/validates_acceptance_of.rb +7 -0
  34. data/lib/data_mapper/validatable_extensions/validations/validates_confirmation_of.rb +7 -0
  35. data/lib/data_mapper/validatable_extensions/validations/validates_each.rb +7 -0
  36. data/lib/data_mapper/validatable_extensions/validations/validates_format_of.rb +28 -0
  37. data/lib/data_mapper/validatable_extensions/validations/validates_length_of.rb +15 -0
  38. data/lib/data_mapper/validatable_extensions/validations/validates_numericality_of.rb +7 -0
  39. data/lib/data_mapper/validatable_extensions/validations/validates_presence_of.rb +7 -0
  40. data/lib/data_mapper/validatable_extensions/validations/validates_true_for.rb +7 -0
  41. data/lib/data_mapper/validatable_extensions/validations/validates_uniqueness_of.rb +33 -0
  42. data/lib/data_mapper/validations.rb +20 -0
  43. data/lib/data_mapper.rb +39 -34
  44. data/performance.rb +24 -18
  45. data/plugins/dataobjects/do_rb +0 -0
  46. data/rakefile.rb +12 -2
  47. data/spec/active_record_impersonation_spec.rb +133 -0
  48. data/spec/acts_as_tree_spec.rb +25 -9
  49. data/spec/associations_spec.rb +124 -4
  50. data/spec/attributes_spec.rb +13 -0
  51. data/spec/auto_migrations_spec.rb +44 -0
  52. data/spec/base_spec.rb +189 -1
  53. data/spec/column_spec.rb +85 -7
  54. data/spec/conditions_spec.rb +2 -2
  55. data/spec/dependency_spec.rb +25 -0
  56. data/spec/embedded_value_spec.rb +123 -3
  57. data/spec/fixtures/animals.yaml +1 -0
  58. data/spec/fixtures/careers.yaml +5 -0
  59. data/spec/fixtures/comments.yaml +1 -0
  60. data/spec/fixtures/people.yaml +14 -9
  61. data/spec/fixtures/projects.yaml +4 -0
  62. data/spec/fixtures/sections.yaml +5 -0
  63. data/spec/fixtures/serializers.yaml +6 -0
  64. data/spec/fixtures/users.yaml +1 -0
  65. data/spec/load_command_spec.rb +5 -4
  66. data/spec/mock_adapter.rb +2 -2
  67. data/spec/models/animal.rb +2 -1
  68. data/spec/models/animals_exhibit.rb +2 -2
  69. data/spec/models/career.rb +6 -0
  70. data/spec/models/comment.rb +4 -0
  71. data/spec/models/exhibit.rb +4 -0
  72. data/spec/models/person.rb +3 -13
  73. data/spec/models/project.rb +1 -1
  74. data/spec/models/serializer.rb +3 -0
  75. data/spec/models/user.rb +4 -0
  76. data/spec/models/zoo.rb +8 -1
  77. data/spec/natural_key_spec.rb +36 -0
  78. data/spec/paranoia_spec.rb +36 -0
  79. data/spec/property_spec.rb +70 -0
  80. data/spec/schema_spec.rb +10 -2
  81. data/spec/serialization_spec.rb +6 -3
  82. data/spec/serialize_spec.rb +19 -0
  83. data/spec/single_table_inheritance_spec.rb +7 -1
  84. data/spec/spec_helper.rb +26 -8
  85. data/spec/table_spec.rb +33 -0
  86. data/spec/validates_confirmation_of_spec.rb +20 -4
  87. data/spec/validates_format_of_spec.rb +22 -8
  88. data/spec/validates_length_of_spec.rb +26 -13
  89. data/spec/validates_uniqueness_of_spec.rb +18 -5
  90. data/spec/validations_spec.rb +55 -10
  91. data/tasks/fixtures.rb +13 -7
  92. metadata +189 -153
  93. data/lib/data_mapper/validations/confirmation_validator.rb +0 -53
  94. data/lib/data_mapper/validations/contextual_validations.rb +0 -50
  95. data/lib/data_mapper/validations/format_validator.rb +0 -85
  96. data/lib/data_mapper/validations/formats/email.rb +0 -78
  97. data/lib/data_mapper/validations/generic_validator.rb +0 -22
  98. data/lib/data_mapper/validations/length_validator.rb +0 -76
  99. data/lib/data_mapper/validations/required_field_validator.rb +0 -41
  100. data/lib/data_mapper/validations/unique_validator.rb +0 -56
  101. data/lib/data_mapper/validations/validation_errors.rb +0 -37
  102. data/lib/data_mapper/validations/validation_helper.rb +0 -77
  103. data/plugins/dataobjects/REVISION +0 -1
  104. data/plugins/dataobjects/Rakefile +0 -9
  105. data/plugins/dataobjects/do.rb +0 -348
  106. data/plugins/dataobjects/do_mysql.rb +0 -212
  107. data/plugins/dataobjects/do_postgres.rb +0 -196
  108. data/plugins/dataobjects/do_sqlite3.rb +0 -157
  109. data/plugins/dataobjects/spec/do_spec.rb +0 -150
  110. data/plugins/dataobjects/spec/spec_helper.rb +0 -81
  111. data/plugins/dataobjects/swig_mysql/extconf.rb +0 -45
  112. data/plugins/dataobjects/swig_mysql/mysql_c.c +0 -16602
  113. data/plugins/dataobjects/swig_mysql/mysql_c.i +0 -67
  114. data/plugins/dataobjects/swig_mysql/mysql_supp.i +0 -46
  115. data/plugins/dataobjects/swig_postgres/extconf.rb +0 -29
  116. data/plugins/dataobjects/swig_postgres/postgres_c.c +0 -8185
  117. data/plugins/dataobjects/swig_postgres/postgres_c.i +0 -73
  118. data/plugins/dataobjects/swig_sqlite/extconf.rb +0 -9
  119. data/plugins/dataobjects/swig_sqlite/sqlite3_c.c +0 -4725
  120. data/plugins/dataobjects/swig_sqlite/sqlite_c.i +0 -168
  121. data/tasks/drivers.rb +0 -20
data/performance.rb CHANGED
@@ -1,38 +1,44 @@
1
1
  require 'benchmark'
2
2
  require 'active_record'
3
3
 
4
- ActiveRecord::Base.establish_connection :adapter => 'mysql',
4
+ socket_file = [
5
+ "/opt/local/var/run/mysql5/mysqld.sock",
6
+ "tmp/mysqld.sock",
7
+ "tmp/mysql.sock"
8
+ ].find { |path| File.exists?(path) }
9
+
10
+ configuration_options = {
11
+ :adapter => 'mysql',
5
12
  :username => 'root',
6
13
  :password => '',
7
- :database => 'data_mapper_1',
8
- :socker => "/tmp/mysql.sock"
14
+ :database => 'data_mapper_1'
15
+ }
16
+
17
+ configuration_options[:socket] = socket_file unless socket_file.nil?
18
+
19
+ ActiveRecord::Base.establish_connection(configuration_options)
9
20
 
10
21
  ActiveRecord::Base.find_by_sql('SELECT 1')
11
22
 
12
- class ARAnimal < ActiveRecord::Base
23
+ class ARAnimal < ActiveRecord::Base #:nodoc:
13
24
  set_table_name 'animals'
14
25
  end
15
26
 
16
- class ARPerson < ActiveRecord::Base
27
+ class ARPerson < ActiveRecord::Base #:nodoc:
17
28
  set_table_name 'people'
18
29
  end
19
30
 
20
31
  require 'lib/data_mapper'
21
32
 
22
- DataMapper::Database.setup({
23
- :adapter => 'mysql',
24
- :database => 'data_mapper_1',
25
- :username => 'root',
26
- :socket => "/tmp/mysql.sock"
27
- })
33
+ DataMapper::Database.setup(configuration_options)
28
34
 
29
- class DMAnimal < DataMapper::Base
35
+ class DMAnimal < DataMapper::Base #:nodoc:
30
36
  set_table_name 'animals'
31
37
  property :name, :string
32
38
  property :notes, :string
33
39
  end
34
40
 
35
- class DMPerson < DataMapper::Base
41
+ class DMPerson < DataMapper::Base #:nodoc:
36
42
  set_table_name 'people'
37
43
  property :name, :string
38
44
  property :age, :integer
@@ -44,22 +50,22 @@ class DMPerson < DataMapper::Base
44
50
  property :zip_code, :string, :size => 10
45
51
  end
46
52
 
47
- class Exhibit < DataMapper::Base
53
+ class Exhibit < DataMapper::Base #:nodoc:
48
54
  property :name, :string
49
55
  belongs_to :zoo
50
56
  end
51
57
 
52
- class Zoo < DataMapper::Base
58
+ class Zoo < DataMapper::Base #:nodoc:
53
59
  property :name, :string
54
60
  has_many :exhibits
55
61
  end
56
62
 
57
- class ARZoo < ActiveRecord::Base
63
+ class ARZoo < ActiveRecord::Base #:nodoc:
58
64
  set_table_name 'zoos'
59
65
  has_many :exhibits, :class_name => 'ARExhibit', :foreign_key => 'zoo_id'
60
66
  end
61
67
 
62
- class ARExhibit < ActiveRecord::Base
68
+ class ARExhibit < ActiveRecord::Base #:nodoc:
63
69
  set_table_name 'exhibits'
64
70
  belongs_to :zoo, :class_name => 'ARZoo', :foreign_key => 'zoo_id'
65
71
  end
@@ -260,4 +266,4 @@ Benchmark::send(ENV['BM'] || :bmbm, 40) do |x|
260
266
  end
261
267
 
262
268
 
263
- end
269
+ end
Binary file
data/rakefile.rb CHANGED
@@ -1,5 +1,6 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
+ require 'rubygems'
3
4
  require 'rake'
4
5
  require 'spec/rake/spectask'
5
6
  require 'rake/rdoctask'
@@ -37,7 +38,7 @@ namespace :dm do
37
38
 
38
39
  end
39
40
 
40
- PACKAGE_VERSION = '0.2.3'
41
+ PACKAGE_VERSION = '0.2.4'
41
42
 
42
43
  PACKAGE_FILES = FileList[
43
44
  'README',
@@ -86,7 +87,9 @@ gem_spec = Gem::Specification.new do |s|
86
87
  s.requirements << 'none'
87
88
  s.autorequire = 'data_mapper'
88
89
  s.add_dependency('fastthread')
90
+ s.add_dependency('json')
89
91
  s.add_dependency('rspec')
92
+ s.add_dependency('validatable')
90
93
 
91
94
  s.has_rdoc = true
92
95
  s.rdoc_options << '--line-numbers' << '--inline-source' << '--main' << 'README'
@@ -106,4 +109,11 @@ end
106
109
 
107
110
  task :install => :package do
108
111
  sh %{sudo gem install pkg/#{PROJECT}-#{PACKAGE_VERSION}}
109
- end
112
+ end
113
+
114
+ namespace :dev do
115
+ desc "Install for development (for windows)"
116
+ task :winstall => :gem do
117
+ system %{gem install --no-rdoc --no-ri -l pkg/#{PROJECT}-#{PACKAGE_VERSION}.gem}
118
+ end
119
+ end
@@ -0,0 +1,133 @@
1
+ require File.dirname(__FILE__) + "/spec_helper"
2
+
3
+ describe DataMapper::Support::ActiveRecordImpersonation do
4
+
5
+ before(:all) do
6
+ fixtures(:animals)
7
+ fixtures(:exhibits)
8
+ end
9
+
10
+ describe 'A record' do
11
+ it 'should save and return true if validations pass' do
12
+ count = Exhibit.count
13
+ bugs_and_more_bugs = Exhibit.new(:name => 'Bugs And More Bugs')
14
+ bugs_and_more_bugs.save.should be_true
15
+ Exhibit.count.should == count + 1
16
+ end
17
+
18
+ it 'should return false on save if validations fail' do
19
+ count = Exhibit.count
20
+ bugs_and_more_bugs = Exhibit.new
21
+ bugs_and_more_bugs.save.should be_false
22
+ Exhibit.count.should == count
23
+ end
24
+
25
+ it 'should reload its attributes' do
26
+ frog = Animal[:name => 'Frog']
27
+ frog.name = 'MegaFrog'
28
+ frog.name.should == 'MegaFrog'
29
+ frog.reload!
30
+ frog.name.should == 'Frog'
31
+ end
32
+
33
+ it "should prepare it's associations for reload" do
34
+ chippy = Animal.first(:name => 'Cup')
35
+ amazonia = Exhibit.first(:name => 'Amazonia')
36
+ amazonia.animals << chippy
37
+ amazonia.animals.should include(chippy)
38
+ amazonia.reload!
39
+ amazonia.animals.should_not include(chippy)
40
+ end
41
+
42
+ it 'should be destroyed!' do
43
+ capybara = Animal.create(:name => 'Capybara')
44
+ count = Animal.count
45
+ capybara.destroy!
46
+ Animal[:name => 'Capybara'].should be_nil
47
+ Animal.count.should == count - 1
48
+ end
49
+ end
50
+
51
+ it 'should return the first match using find_or_create' do
52
+ count = Animal.count
53
+ frog = Animal.find_or_create(:name => 'Frog')
54
+ frog.name.should == 'Frog'
55
+ Animal.count.should == count
56
+ end
57
+
58
+ it 'should create a record if a match is not found with find_or_create' do
59
+ count = Animal.count
60
+ capybara = Animal.find_or_create(:name => 'Capybara')
61
+ capybara.name.should == 'Capybara'
62
+ Animal.count.should == count + 1
63
+ end
64
+
65
+ it 'should return all records' do
66
+ all_animals = Animal.all
67
+ all_animals.length.should == Animal.count
68
+ all_animals.each do |animal|
69
+ animal.class.should == Animal
70
+ end
71
+ end
72
+
73
+ it 'should return the first record' do
74
+ Animal.first.should == Animal.find(:first)
75
+ end
76
+
77
+ it 'should return a count of the records' do
78
+ Animal.count.should == Animal.find_by_sql("SELECT COUNT(*) FROM animals")[0]
79
+ end
80
+
81
+ it 'should delete all records' do
82
+ Animal.delete_all
83
+ Animal.count.should == 0
84
+
85
+ fixtures(:animals)
86
+ end
87
+
88
+ #it 'should be truncated' do
89
+ # Animal.truncate!
90
+ # Animal.count.should == 0
91
+ #
92
+ # fixtures(:animals)
93
+ #end
94
+
95
+ it 'should find a matching record given an id' do
96
+ Animal.find(1).name.should == 'Frog'
97
+ end
98
+
99
+ it 'should find all records' do
100
+ Animal.find(:all).length.should == Animal.count
101
+ end
102
+
103
+ it 'should find all matching records given some condition' do
104
+ Animal.find(:all, :conditions => ["name = ?", "Frog"])[0].name.should == 'Frog'
105
+ end
106
+
107
+ it 'should find the first matching record' do
108
+ Animal.find(:first).name.should == 'Frog'
109
+ end
110
+
111
+ it 'should find the first matching record given some condition' do
112
+ Animal.find(:first, :conditions => ["name = ?", "Frog"]).name.should == 'Frog'
113
+ end
114
+
115
+ it 'should select records using the supplied sql fragment' do
116
+ Animal.find_by_sql("SELECT name FROM animals WHERE name='Frog'")[0].should == 'Frog'
117
+ end
118
+
119
+ it 'should retrieve the indexed element' do
120
+ Animal[1].id.should == 1
121
+ end
122
+
123
+ it 'should retrieve the indexed element using a hash condition' do
124
+ Animal[:name => 'Frog'].name.should == 'Frog'
125
+ end
126
+
127
+ it 'should create a new record' do
128
+ count = Animal.count
129
+ capybara = Animal.create(:name => 'Capybara')
130
+ capybara.name.should == 'Capybara'
131
+ Animal.count.should == count + 1
132
+ end
133
+ end
@@ -10,9 +10,12 @@ describe('A tree') do
10
10
  has_many :children, :class => 'Node', :foreign_key => 'parent_id'
11
11
  end
12
12
 
13
- database.schema[Node].drop!
14
- database.save(Node)
15
- end
13
+ Node.auto_migrate!
14
+ end
15
+
16
+ after(:all) do
17
+ database.table(Node).drop!
18
+ end
16
19
 
17
20
  it 'should work' do
18
21
  root = Node.new(:name => 'root')
@@ -21,7 +24,9 @@ describe('A tree') do
21
24
  two = Node.new(:name => 'two')
22
25
 
23
26
  root.children << one << two
24
-
27
+
28
+ root.parent_id.should be_nil
29
+
25
30
  one_one = Node.new(:name => 'one_one')
26
31
  one_two = Node.new(:name => 'one_two')
27
32
  one.children << one_one << one_two
@@ -30,12 +35,23 @@ describe('A tree') do
30
35
  two_two = Node.new(:name => 'two_two')
31
36
  two.children << two_one << two_two
32
37
 
33
- root.save
34
-
35
- grand = Node[:name => 'root']
36
- root.should_not == grand # false since +root+ and +grand+ are in different sessions.
38
+ root.save.should == true
39
+ root.parent_id.should be_nil
40
+
41
+ root.should have(2).children
42
+ one.should have(2).children
43
+ two.should have(2).children
37
44
 
45
+ Node.all(:name => 'root').should have(1).entries
46
+
47
+ grand = Node.first(:name => 'root')
48
+
49
+ grand.should have(2).children
50
+
51
+ root.should == grand # true since +root+ and +grand+ are objects with identical types and attributes.
52
+ root.should_not eql(grand) # false since +root+ and +grand+ are in different sessions.
53
+
38
54
  grand.children[0].children[0].name.should == 'one_one'
39
55
  end
40
56
 
41
- end
57
+ end
@@ -1,6 +1,10 @@
1
1
  require File.dirname(__FILE__) + "/spec_helper"
2
2
 
3
3
  describe DataMapper::Associations::BelongsToAssociation do
4
+ before(:all) do
5
+ fixtures(:zoos)
6
+ end
7
+
4
8
  before(:each) do
5
9
  @aviary = Exhibit[:name => 'Monkey Mayhem']
6
10
  end
@@ -11,14 +15,31 @@ describe DataMapper::Associations::BelongsToAssociation do
11
15
  end
12
16
 
13
17
  it 'belongs to a zoo' do
14
- @aviary.zoo.should == @aviary.session.first(Zoo, :name => 'San Diego')
18
+ @aviary.zoo.should == @aviary.database_context.first(Zoo, :name => 'San Diego')
15
19
  end
16
20
 
17
21
  it "is assigned a zoo_id" do
18
22
  zoo = Zoo.first
19
23
  exhibit = Exhibit.new(:name => 'bob')
20
24
  exhibit.zoo = zoo
21
- exhibit.instance_variable_get("@zoo_id").should == zoo.id
25
+ exhibit.instance_variable_get("@zoo_id").should == zoo.id
26
+
27
+ exhibit.save.should eql(true)
28
+
29
+ zoo2 = Zoo.first
30
+ zoo2.exhibits.should include(exhibit)
31
+
32
+ exhibit.destroy!
33
+
34
+ zoo = Zoo.new(:name => 'bob')
35
+ bob = Exhibit.new(:name => 'bob')
36
+ zoo.exhibits << bob
37
+ zoo.save.should eql(true)
38
+
39
+ zoo.exhibits.first.should_not be_a_new_record
40
+
41
+ bob.destroy!
42
+ zoo.destroy!
22
43
  end
23
44
 
24
45
  it 'can build its zoo' do
@@ -118,14 +139,35 @@ describe DataMapper::Associations::HasManyAssociation do
118
139
  JOIN `exhibits` ON `exhibits`.`zoo_id` = `zoos`.`id`
119
140
  EOS
120
141
  end
121
-
142
+
122
143
  it "should add an item to an association" do
123
144
  bear = Exhibit.new( :name => "Bear")
124
145
  @zoo.exhibits << bear
125
146
  @zoo.exhibits.should include(bear)
126
147
  end
148
+
149
+ it "should build a new item" do
150
+ bear = @zoo.exhibits.build( :name => "Bear" )
151
+ bear.should be_kind_of(Exhibit)
152
+ @zoo.exhibits.should include(bear)
153
+ end
127
154
 
155
+ it "should not save the item when building" do
156
+ bear = @zoo.exhibits.build( :name => "Bear" )
157
+ bear.should be_new_record
158
+ end
128
159
 
160
+ it "should create a new item" do
161
+ bear = @zoo.exhibits.create( :name => "Bear" )
162
+ bear.should be_kind_of(Exhibit)
163
+ @zoo.exhibits.should include(bear)
164
+ end
165
+
166
+ it "should save the item when creating" do
167
+ bear = @zoo.exhibits.create( :name => "Bear" )
168
+ bear.should_not be_new_record
169
+ end
170
+
129
171
  it "should set the association to a saved target when added with <<" do
130
172
  pirahna = Exhibit.new(:name => "Pirahna")
131
173
  pirahna.zoo_id.should be_nil
@@ -228,5 +270,83 @@ describe DataMapper::Associations::HasAndBelongsToManyAssociation do
228
270
  end
229
271
  end
230
272
  end
273
+
274
+ it 'should allow association of additional objects' do
275
+ @amazonia.animals << Animal.new(:name => "Buffalo")
276
+ @amazonia.animals.size.should == 2
277
+ @amazonia.reload
278
+ end
279
+
280
+ it 'should allow you to fill and clear an association' do
281
+ marcy = Exhibit.create(:name => 'marcy')
282
+
283
+ Animal.all.each do |animal|
284
+ marcy.animals << animal
285
+ end
286
+
287
+ marcy.save.should eql(true)
288
+ marcy.should have(Animal.count).animals
289
+
290
+ marcy.animals.clear
291
+ marcy.should have(0).animals
292
+
293
+ marcy.save.should eql(true)
294
+
295
+ marcys_stand_in = Exhibit[marcy.id]
296
+ marcys_stand_in.should have(0).animals
297
+
298
+ marcy.destroy!
299
+ end
300
+
301
+ it 'should allow you to delete a specific association member' do
302
+ walter = Exhibit.create(:name => 'walter')
303
+
304
+ Animal.all.each do |animal|
305
+ walter.animals << animal
306
+ end
307
+
308
+ walter.save.should eql(true)
309
+ walter.should have(Animal.count).animals
310
+
311
+ delete_me = walter.animals.entries.first
312
+ walter.animals.delete(delete_me).should eql(delete_me)
313
+ walter.animals.delete(delete_me).should eql(nil)
314
+
315
+ walter.should have(Animal.count - 1).animals
316
+ walter.save.should eql(true)
317
+
318
+ walters_stand_in = Exhibit[walter.id]
319
+ walters_stand_in.animals.size.should eql(walter.animals.size)
320
+
321
+ walter.destroy!
322
+ end
323
+
324
+ it "should allow updates to associations using association_ids[]" do
325
+ pending "Awaiting implementation of association_ids[]"
326
+ meerkat = Animal.new(:name => "Meerkat")
327
+ @amazonia.animals.size.should == 1
328
+
329
+ @amazonia.animal_ids << meerkat.id
330
+ @amazonia.save
331
+
332
+ @amazonia.animals.size.should == 2
333
+ @amazonia.animals.should include?(meerkat)
334
+ end
335
+
336
+ it "Should handle setting complementary associations" do
337
+ u1 = User.create(:name => "u1")
338
+ u1.comments.should be_empty
339
+
340
+ c1 = Comment.create(:comment => "c", :author => u1)
341
+ p u1
342
+ p c1
343
+
344
+ u1.comments.should_not be_empty
345
+ u1.comments.should include(c1)
346
+
347
+ u1.reload!
348
+ u1.comments.should_not be_empty
349
+ u1.comments.should include(c1)
350
+ end
231
351
 
232
- end
352
+ end
@@ -14,4 +14,17 @@ describe DataMapper::Base do
14
14
  zoo.notes.should eql('This is another test.')
15
15
  end
16
16
 
17
+ it "should allow custom setters" do
18
+ zoo = Zoo.new
19
+
20
+ zoo.name = 'Colorado Springs'
21
+ zoo.name.should eql("Cheyenne Mountain")
22
+ end
23
+
24
+ it "should call custom setters on mass-assignment" do
25
+ zoo = Zoo.new(:name => 'Colorado Springs')
26
+
27
+ zoo.name.should eql("Cheyenne Mountain")
28
+ end
29
+
17
30
  end
@@ -0,0 +1,44 @@
1
+ require File.dirname(__FILE__) + "/spec_helper"
2
+
3
+ describe Zoo, "with auto-migrations" do
4
+ it "should allow auto migration" do
5
+ Zoo.should respond_to("auto_migrate!")
6
+ end
7
+ end
8
+
9
+ describe DataMapper::AutoMigrations do
10
+ it "should find all new models" do
11
+ database.schema[Zoo].drop!
12
+ Zoo.auto_migrate!
13
+ database.table_exists?(Zoo).should be_true
14
+ database.column_exists_for_table?(Zoo, :id).should be_true
15
+ database.column_exists_for_table?(Zoo, :name).should be_true
16
+ database.column_exists_for_table?(Zoo, :notes).should be_true
17
+ database.column_exists_for_table?(Zoo, :updated_at).should be_true
18
+ end
19
+
20
+ it "should find all changed models"
21
+ it "should find all unmapped tables"
22
+ end
23
+
24
+ describe DataMapper::AutoMigrations, "when migrating a new model" do
25
+ it "should allow creation of new tables for new models"
26
+ it "should allow renaming of unmapped tables for new models"
27
+ it "should create columns for the model's properties"
28
+ end
29
+
30
+ describe DataMapper::AutoMigrations, "when migrating a changed model" do
31
+ it "should find all new properties"
32
+ it "should allow creation of new columns for new properties"
33
+ it "should allow an unmapped column to be renamed for a new property"
34
+ it "should find all unmapped columns"
35
+ it "should allow removal of any or all unmapped columns"
36
+ end
37
+
38
+ describe DataMapper::AutoMigrations, "when migrating an unmapped table" do
39
+ it "should allow the table to be dropped"
40
+ end
41
+
42
+ describe DataMapper::AutoMigrations, "after migrating" do
43
+ it "should store migration decisions to allow the migration to be replicated"
44
+ end