datamapper 0.2.3 → 0.2.4

Sign up to get free protection for your applications and to get access to all the features.
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