datamapper-dm-core 0.9.11 → 0.10.0

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 (192) hide show
  1. data/.autotest +17 -14
  2. data/.gitignore +3 -1
  3. data/FAQ +6 -5
  4. data/History.txt +5 -39
  5. data/Manifest.txt +67 -76
  6. data/QUICKLINKS +1 -1
  7. data/README.txt +21 -15
  8. data/Rakefile +16 -15
  9. data/SPECS +2 -29
  10. data/TODO +1 -1
  11. data/dm-core.gemspec +11 -15
  12. data/lib/dm-core/adapters/abstract_adapter.rb +182 -185
  13. data/lib/dm-core/adapters/data_objects_adapter.rb +482 -534
  14. data/lib/dm-core/adapters/in_memory_adapter.rb +90 -69
  15. data/lib/dm-core/adapters/mysql_adapter.rb +22 -115
  16. data/lib/dm-core/adapters/oracle_adapter.rb +249 -0
  17. data/lib/dm-core/adapters/postgres_adapter.rb +7 -173
  18. data/lib/dm-core/adapters/sqlite3_adapter.rb +4 -97
  19. data/lib/dm-core/adapters/yaml_adapter.rb +116 -0
  20. data/lib/dm-core/adapters.rb +135 -16
  21. data/lib/dm-core/associations/many_to_many.rb +372 -90
  22. data/lib/dm-core/associations/many_to_one.rb +220 -73
  23. data/lib/dm-core/associations/one_to_many.rb +319 -255
  24. data/lib/dm-core/associations/one_to_one.rb +66 -53
  25. data/lib/dm-core/associations/relationship.rb +560 -158
  26. data/lib/dm-core/collection.rb +1104 -381
  27. data/lib/dm-core/core_ext/kernel.rb +12 -0
  28. data/lib/dm-core/core_ext/symbol.rb +10 -0
  29. data/lib/dm-core/identity_map.rb +4 -34
  30. data/lib/dm-core/migrations.rb +1283 -0
  31. data/lib/dm-core/model/descendant_set.rb +81 -0
  32. data/lib/dm-core/model/hook.rb +45 -0
  33. data/lib/dm-core/model/is.rb +32 -0
  34. data/lib/dm-core/model/property.rb +248 -0
  35. data/lib/dm-core/model/relationship.rb +335 -0
  36. data/lib/dm-core/model/scope.rb +90 -0
  37. data/lib/dm-core/model.rb +570 -369
  38. data/lib/dm-core/property.rb +753 -280
  39. data/lib/dm-core/property_set.rb +141 -98
  40. data/lib/dm-core/query/conditions/comparison.rb +814 -0
  41. data/lib/dm-core/query/conditions/operation.rb +247 -0
  42. data/lib/dm-core/query/direction.rb +43 -0
  43. data/lib/dm-core/query/operator.rb +42 -0
  44. data/lib/dm-core/query/path.rb +102 -0
  45. data/lib/dm-core/query/sort.rb +45 -0
  46. data/lib/dm-core/query.rb +974 -492
  47. data/lib/dm-core/repository.rb +147 -107
  48. data/lib/dm-core/resource.rb +644 -429
  49. data/lib/dm-core/spec/adapter_shared_spec.rb +294 -0
  50. data/lib/dm-core/spec/data_objects_adapter_shared_spec.rb +106 -0
  51. data/lib/dm-core/support/chainable.rb +20 -0
  52. data/lib/dm-core/support/deprecate.rb +12 -0
  53. data/lib/dm-core/support/equalizer.rb +23 -0
  54. data/lib/dm-core/support/logger.rb +13 -0
  55. data/lib/dm-core/{naming_conventions.rb → support/naming_conventions.rb} +6 -6
  56. data/lib/dm-core/transaction.rb +333 -92
  57. data/lib/dm-core/type.rb +98 -60
  58. data/lib/dm-core/types/boolean.rb +1 -1
  59. data/lib/dm-core/types/discriminator.rb +34 -20
  60. data/lib/dm-core/types/object.rb +7 -4
  61. data/lib/dm-core/types/paranoid_boolean.rb +11 -9
  62. data/lib/dm-core/types/paranoid_datetime.rb +11 -9
  63. data/lib/dm-core/types/serial.rb +3 -3
  64. data/lib/dm-core/types/text.rb +3 -4
  65. data/lib/dm-core/version.rb +1 -1
  66. data/lib/dm-core.rb +106 -110
  67. data/script/performance.rb +102 -109
  68. data/script/profile.rb +169 -38
  69. data/spec/lib/adapter_helpers.rb +105 -0
  70. data/spec/lib/collection_helpers.rb +18 -0
  71. data/spec/lib/counter_adapter.rb +34 -0
  72. data/spec/lib/pending_helpers.rb +27 -0
  73. data/spec/lib/rspec_immediate_feedback_formatter.rb +53 -0
  74. data/spec/public/associations/many_to_many_spec.rb +193 -0
  75. data/spec/public/associations/many_to_one_spec.rb +73 -0
  76. data/spec/public/associations/one_to_many_spec.rb +77 -0
  77. data/spec/public/associations/one_to_one_spec.rb +156 -0
  78. data/spec/public/collection_spec.rb +65 -0
  79. data/spec/public/model/relationship_spec.rb +924 -0
  80. data/spec/public/model_spec.rb +159 -0
  81. data/spec/public/property_spec.rb +829 -0
  82. data/spec/public/resource_spec.rb +71 -0
  83. data/spec/public/sel_spec.rb +44 -0
  84. data/spec/public/setup_spec.rb +145 -0
  85. data/spec/public/shared/association_collection_shared_spec.rb +317 -0
  86. data/spec/public/shared/collection_shared_spec.rb +1723 -0
  87. data/spec/public/shared/finder_shared_spec.rb +1619 -0
  88. data/spec/public/shared/resource_shared_spec.rb +924 -0
  89. data/spec/public/shared/sel_shared_spec.rb +112 -0
  90. data/spec/public/transaction_spec.rb +129 -0
  91. data/spec/public/types/discriminator_spec.rb +130 -0
  92. data/spec/semipublic/adapters/abstract_adapter_spec.rb +30 -0
  93. data/spec/semipublic/adapters/in_memory_adapter_spec.rb +12 -0
  94. data/spec/semipublic/adapters/mysql_adapter_spec.rb +17 -0
  95. data/spec/semipublic/adapters/oracle_adapter_spec.rb +194 -0
  96. data/spec/semipublic/adapters/postgres_adapter_spec.rb +17 -0
  97. data/spec/semipublic/adapters/sqlite3_adapter_spec.rb +17 -0
  98. data/spec/semipublic/adapters/yaml_adapter_spec.rb +12 -0
  99. data/spec/semipublic/associations/many_to_one_spec.rb +53 -0
  100. data/spec/semipublic/associations/relationship_spec.rb +194 -0
  101. data/spec/semipublic/associations_spec.rb +177 -0
  102. data/spec/semipublic/collection_spec.rb +142 -0
  103. data/spec/semipublic/property_spec.rb +61 -0
  104. data/spec/semipublic/query/conditions_spec.rb +528 -0
  105. data/spec/semipublic/query/path_spec.rb +443 -0
  106. data/spec/semipublic/query_spec.rb +2626 -0
  107. data/spec/semipublic/resource_spec.rb +47 -0
  108. data/spec/semipublic/shared/resource_shared_spec.rb +126 -0
  109. data/spec/spec.opts +3 -1
  110. data/spec/spec_helper.rb +80 -57
  111. data/tasks/ci.rb +19 -31
  112. data/tasks/dm.rb +43 -48
  113. data/tasks/doc.rb +8 -11
  114. data/tasks/gemspec.rb +5 -5
  115. data/tasks/hoe.rb +15 -16
  116. data/tasks/install.rb +8 -10
  117. metadata +72 -93
  118. data/lib/dm-core/associations/relationship_chain.rb +0 -81
  119. data/lib/dm-core/associations.rb +0 -207
  120. data/lib/dm-core/auto_migrations.rb +0 -105
  121. data/lib/dm-core/dependency_queue.rb +0 -32
  122. data/lib/dm-core/hook.rb +0 -11
  123. data/lib/dm-core/is.rb +0 -16
  124. data/lib/dm-core/logger.rb +0 -232
  125. data/lib/dm-core/migrations/destructive_migrations.rb +0 -17
  126. data/lib/dm-core/migrator.rb +0 -29
  127. data/lib/dm-core/scope.rb +0 -58
  128. data/lib/dm-core/support/array.rb +0 -13
  129. data/lib/dm-core/support/assertions.rb +0 -8
  130. data/lib/dm-core/support/errors.rb +0 -23
  131. data/lib/dm-core/support/kernel.rb +0 -11
  132. data/lib/dm-core/support/symbol.rb +0 -41
  133. data/lib/dm-core/support.rb +0 -7
  134. data/lib/dm-core/type_map.rb +0 -80
  135. data/lib/dm-core/types.rb +0 -19
  136. data/script/all +0 -4
  137. data/spec/integration/association_spec.rb +0 -1382
  138. data/spec/integration/association_through_spec.rb +0 -203
  139. data/spec/integration/associations/many_to_many_spec.rb +0 -449
  140. data/spec/integration/associations/many_to_one_spec.rb +0 -163
  141. data/spec/integration/associations/one_to_many_spec.rb +0 -188
  142. data/spec/integration/auto_migrations_spec.rb +0 -413
  143. data/spec/integration/collection_spec.rb +0 -1073
  144. data/spec/integration/data_objects_adapter_spec.rb +0 -32
  145. data/spec/integration/dependency_queue_spec.rb +0 -46
  146. data/spec/integration/model_spec.rb +0 -197
  147. data/spec/integration/mysql_adapter_spec.rb +0 -85
  148. data/spec/integration/postgres_adapter_spec.rb +0 -731
  149. data/spec/integration/property_spec.rb +0 -253
  150. data/spec/integration/query_spec.rb +0 -514
  151. data/spec/integration/repository_spec.rb +0 -61
  152. data/spec/integration/resource_spec.rb +0 -513
  153. data/spec/integration/sqlite3_adapter_spec.rb +0 -352
  154. data/spec/integration/sti_spec.rb +0 -273
  155. data/spec/integration/strategic_eager_loading_spec.rb +0 -156
  156. data/spec/integration/transaction_spec.rb +0 -75
  157. data/spec/integration/type_spec.rb +0 -275
  158. data/spec/lib/logging_helper.rb +0 -18
  159. data/spec/lib/mock_adapter.rb +0 -27
  160. data/spec/lib/model_loader.rb +0 -100
  161. data/spec/lib/publicize_methods.rb +0 -28
  162. data/spec/models/content.rb +0 -16
  163. data/spec/models/vehicles.rb +0 -34
  164. data/spec/models/zoo.rb +0 -48
  165. data/spec/unit/adapters/abstract_adapter_spec.rb +0 -133
  166. data/spec/unit/adapters/adapter_shared_spec.rb +0 -15
  167. data/spec/unit/adapters/data_objects_adapter_spec.rb +0 -632
  168. data/spec/unit/adapters/in_memory_adapter_spec.rb +0 -98
  169. data/spec/unit/adapters/postgres_adapter_spec.rb +0 -133
  170. data/spec/unit/associations/many_to_many_spec.rb +0 -32
  171. data/spec/unit/associations/many_to_one_spec.rb +0 -159
  172. data/spec/unit/associations/one_to_many_spec.rb +0 -393
  173. data/spec/unit/associations/one_to_one_spec.rb +0 -7
  174. data/spec/unit/associations/relationship_spec.rb +0 -71
  175. data/spec/unit/associations_spec.rb +0 -242
  176. data/spec/unit/auto_migrations_spec.rb +0 -111
  177. data/spec/unit/collection_spec.rb +0 -182
  178. data/spec/unit/data_mapper_spec.rb +0 -35
  179. data/spec/unit/identity_map_spec.rb +0 -126
  180. data/spec/unit/is_spec.rb +0 -80
  181. data/spec/unit/migrator_spec.rb +0 -33
  182. data/spec/unit/model_spec.rb +0 -321
  183. data/spec/unit/naming_conventions_spec.rb +0 -36
  184. data/spec/unit/property_set_spec.rb +0 -90
  185. data/spec/unit/property_spec.rb +0 -753
  186. data/spec/unit/query_spec.rb +0 -571
  187. data/spec/unit/repository_spec.rb +0 -93
  188. data/spec/unit/resource_spec.rb +0 -649
  189. data/spec/unit/scope_spec.rb +0 -142
  190. data/spec/unit/transaction_spec.rb +0 -493
  191. data/spec/unit/type_map_spec.rb +0 -114
  192. data/spec/unit/type_spec.rb +0 -119
@@ -1,98 +0,0 @@
1
- require File.expand_path(File.join(File.dirname(__FILE__), '..', "..", 'spec_helper'))
2
-
3
- describe DataMapper::Adapters::InMemoryAdapter do
4
- before do
5
- DataMapper.setup(:inmem, :adapter => 'in_memory')
6
-
7
- class ::Heffalump
8
- include DataMapper::Resource
9
-
10
- def self.default_repository_name
11
- :inmem
12
- end
13
-
14
- property :color, String, :key => true # TODO: Drop the 'must have a key' limitation
15
- property :num_spots, Integer
16
- property :striped, Boolean
17
- end
18
-
19
- @heff1 = Heffalump.create(:color => 'Black', :num_spots => 0, :striped => true)
20
- @heff2 = Heffalump.create(:color => 'Brown', :num_spots => 25, :striped => false)
21
- @heff3 = Heffalump.create(:color => 'Blue', :num_spots => nil, :striped => false)
22
- end
23
-
24
- it 'should successfully save an object' do
25
- @heff1.new_record?.should be_false
26
- end
27
-
28
- it 'should be able to get the object' do
29
- Heffalump.get('Black').should == @heff1
30
- end
31
-
32
- it 'should be able to get all the objects' do
33
- Heffalump.all.should == [@heff1, @heff2, @heff3]
34
- end
35
-
36
- it 'should be able to search for objects with equal value' do
37
- Heffalump.all(:striped => true).should == [@heff1]
38
- end
39
-
40
- it 'should be able to search for objects included in an array of values' do
41
- Heffalump.all(:num_spots => [ 25, 50, 75, 100 ]).should == [@heff2]
42
- end
43
-
44
- it 'should be able to search for objects included in a range of values' do
45
- Heffalump.all(:num_spots => 25..100).should == [@heff2]
46
- end
47
-
48
- it 'should be able to search for objects with nil value' do
49
- Heffalump.all(:num_spots => nil).should == [@heff3]
50
- end
51
-
52
- it 'should be able to search for objects with not equal value' do
53
- Heffalump.all(:striped.not => true).should == [@heff2, @heff3]
54
- end
55
-
56
- it 'should be able to search for objects not included in an array of values' do
57
- Heffalump.all(:num_spots.not => [ 25, 50, 75, 100 ]).should == [@heff1, @heff3]
58
- end
59
-
60
- it 'should be able to search for objects not included in a range of values' do
61
- Heffalump.all(:num_spots.not => 25..100).should == [@heff1, @heff3]
62
- end
63
-
64
- it 'should be able to search for objects with not nil value' do
65
- Heffalump.all(:num_spots.not => nil).should == [@heff1, @heff2]
66
- end
67
-
68
- it 'should be able to search for objects that match value' do
69
- Heffalump.all(:color.like => 'Bl').should == [@heff1, @heff3]
70
- end
71
-
72
- it 'should be able to search for objects with value greater than' do
73
- Heffalump.all(:num_spots.gt => 0).should == [@heff2]
74
- end
75
-
76
- it 'should be able to search for objects with value greater than or equal to' do
77
- Heffalump.all(:num_spots.gte => 0).should == [@heff1, @heff2]
78
- end
79
-
80
- it 'should be able to search for objects with value less than' do
81
- Heffalump.all(:num_spots.lt => 1).should == [@heff1]
82
- end
83
-
84
- it 'should be able to search for objects with value less than or equal to' do
85
- Heffalump.all(:num_spots.lte => 0).should == [@heff1]
86
- end
87
-
88
- it 'should be able to update an object' do
89
- @heff1.num_spots = 10
90
- @heff1.save
91
- Heffalump.get('Black').num_spots.should == 10
92
- end
93
-
94
- it 'should be able to destroy an object' do
95
- @heff1.destroy
96
- Heffalump.all.size.should == 2
97
- end
98
- end
@@ -1,133 +0,0 @@
1
- require File.expand_path(File.join(File.dirname(__FILE__), '..', "..", 'spec_helper'))
2
-
3
- if HAS_POSTGRES
4
- describe DataMapper::Adapters::PostgresAdapter do
5
- before :all do
6
- @adapter = repository(:postgres).adapter
7
- end
8
-
9
- describe '#upgrade_model_storage' do
10
- before do
11
- @repository = mock('repository', :kind_of? => true, :name => :postgres)
12
- @model = mock('model', :kind_of? => true, :storage_name => 'models')
13
- @property = mock('property', :kind_of? => true, :model => @model, :serial? => true, :field => 'property')
14
-
15
- @model.should_receive(:properties).with(:postgres).any_number_of_times.and_return([@property])
16
-
17
- @command = mock('command')
18
- @connection = mock('connection', :create_command => @command, :close => true)
19
- @result = mock('result', :to_i => 0)
20
-
21
- DataObjects::Connection.stub!(:new).and_return(@connection)
22
-
23
- @adapter.stub!(:execute).and_return(@result)
24
- @adapter.stub!(:storage_exists?).and_return(true)
25
- @adapter.stub!(:query).and_return([ 0 ])
26
-
27
- @original_method = @adapter.class.superclass.instance_method(:upgrade_model_storage)
28
- @adapter.class.superclass.send(:define_method, :upgrade_model_storage) { |repository, model| }
29
- end
30
-
31
- after do
32
- method = @original_method
33
- @adapter.class.superclass.send(:define_method, :upgrade_model_storage) do |*args|
34
- method.bind(self).call(*args)
35
- end
36
- end
37
-
38
- it 'should check to make sure the sequences exist' do
39
- statement = %q[SELECT COUNT(*) FROM "information_schema"."sequences" WHERE "sequence_name" = ? AND "sequence_schema" = current_schema()]
40
- @adapter.should_receive(:query).with(statement, 'models_property_seq').and_return([ 0 ])
41
- @adapter.upgrade_model_storage(@repository, @model)
42
- end
43
-
44
- it 'should add sequences' do
45
- statement = %q[CREATE SEQUENCE "models_property_seq"]
46
- @adapter.should_receive(:execute).with(statement)
47
- @adapter.upgrade_model_storage(@repository, @model)
48
- end
49
-
50
- it 'should execute the superclass upgrade_model_storage' do
51
- rv = mock('inside super')
52
- @adapter.class.superclass.send(:define_method, :upgrade_model_storage) { |repository, model| rv }
53
- @adapter.upgrade_model_storage(@repository, @model).should == rv
54
- end
55
- end
56
-
57
- describe '#create_model_storage' do
58
- before do
59
- @repository = mock('repository', :kind_of? => true, :name => :postgres)
60
- @model = mock('model', :kind_of? => true, :storage_name => 'models')
61
- @property = mock('property', :kind_of? => true, :model => @model, :serial? => true, :field => 'property')
62
-
63
- @model.should_receive(:properties).with(:postgres).any_number_of_times.and_return([@property])
64
-
65
- @adapter.stub!(:execute).and_return(@result)
66
- @adapter.stub!(:storage_exists?).and_return(true)
67
- @adapter.stub!(:query).and_return([ 0 ])
68
-
69
- @original_method = @adapter.class.superclass.instance_method(:create_table_statement)
70
- @adapter.class.superclass.send(:define_method, :create_table_statement) {}
71
- end
72
-
73
- after do
74
- method = @original_method
75
- @adapter.class.superclass.send(:define_method, :create_table_statement) do |*args|
76
- method.bind(self).call(*args)
77
- end
78
- end
79
-
80
- it 'should check to make sure the sequences exist' do
81
- statement = %q[SELECT COUNT(*) FROM "information_schema"."sequences" WHERE "sequence_name" = ? AND "sequence_schema" = current_schema()]
82
- @adapter.should_receive(:query).with(statement, 'models_property_seq').and_return([ 0 ])
83
- @adapter.create_model_storage(@repository, @model)
84
- end
85
-
86
- it 'should add sequences' do
87
- statement = %q[CREATE SEQUENCE "models_property_seq"]
88
- @adapter.should_receive(:execute).with(statement)
89
- @adapter.create_model_storage(@repository, @model)
90
- end
91
-
92
- it 'should execute the superclass upgrade_model_storage' do
93
- rv = mock('inside super')
94
- @adapter.class.superclass.send(:define_method, :create_table_statement) { |repository, model| rv }
95
- @adapter.create_table_statement(@repository, @model).should == rv
96
- end
97
- end
98
-
99
- describe '#destroy_model_storage' do
100
- before do
101
- @repository = mock('repository', :kind_of? => true, :name => :postgres)
102
- @model = mock('model', :kind_of? => true, :storage_name => 'models')
103
- @property = mock('property', :kind_of? => true, :model => @model, :serial? => true, :field => 'property')
104
-
105
- @model.should_receive(:properties).with(:postgres).any_number_of_times.and_return([@property])
106
-
107
- @original_method = @adapter.class.superclass.instance_method(:destroy_model_storage)
108
- @adapter.class.superclass.send(:define_method, :destroy_model_storage) {}
109
- end
110
-
111
- after do
112
- method = @original_method
113
- @adapter.class.superclass.send(:define_method, :destroy_model_storage) do |*args|
114
- method.bind(self).call(*args)
115
- end
116
- end
117
-
118
- it 'should not execute the superclass destroy_model_storage if the storage does not exist' do
119
- rv = mock('inside super')
120
- @adapter.class.superclass.send(:define_method, :destroy_model_storage) { |repository, model| rv }
121
- @adapter.destroy_model_storage(@repository, @model).should_not == rv
122
- end
123
-
124
- it 'should execute the superclass destroy_model_storage if the storage exists' do
125
- rv = mock('inside super')
126
- @adapter.class.superclass.send(:define_method, :destroy_model_storage) { |repository, model| rv }
127
- @adapter.stub!(:storage_exists?).and_return(true)
128
-
129
- @adapter.destroy_model_storage(@repository, @model).should == rv
130
- end
131
- end
132
- end
133
- end
@@ -1,32 +0,0 @@
1
- require File.expand_path(File.join(File.dirname(__FILE__), '..', '..', 'spec_helper'))
2
-
3
- describe DataMapper::Associations::ManyToMany do
4
-
5
- load_models_for_metaphor :vehicles, :content
6
-
7
- it 'should allow a declaration' do
8
- lambda do
9
- class ::Supplier
10
- has n, :manufacturers, :through => Resource
11
- end
12
- end.should_not raise_error
13
- end
14
-
15
- it 'should handle models inside modules' do
16
- lambda do
17
- module ::Content
18
- class Dialect
19
- has n, :locales, :through => Resource, :class_name => "Language::Locale"
20
- end
21
-
22
- class Locale
23
- has n, :dialects, :through => Resource, :class_name => "Language::Dialect"
24
- end
25
- end
26
- end.should_not raise_error
27
- end
28
-
29
- end
30
-
31
- describe DataMapper::Associations::ManyToMany::Proxy do
32
- end
@@ -1,159 +0,0 @@
1
- require File.expand_path(File.join(File.dirname(__FILE__), '..', '..', 'spec_helper'))
2
-
3
- describe DataMapper::Associations::ManyToOne do
4
-
5
- load_models_for_metaphor :vehicles
6
-
7
- it 'should allow a declaration' do
8
- lambda do
9
- class ::Vehicle
10
- belongs_to :manufacturer
11
- end
12
- end.should_not raise_error
13
- end
14
- end
15
-
16
- describe DataMapper::Associations::ManyToOne::Proxy do
17
-
18
- load_models_for_metaphor :vehicles
19
-
20
- before do
21
- @child = mock('child', :kind_of? => true)
22
- @parent = mock('parent', :nil? => false, :new_record? => false)
23
- @relationship = mock('relationship', :kind_of? => true, :get_parent => @parent, :attach_parent => nil)
24
- @association = DataMapper::Associations::ManyToOne::Proxy.new(@relationship, @child)
25
-
26
- @association.replace(@parent)
27
- end
28
-
29
- it 'should provide #replace' do
30
- @association.should respond_to(:replace)
31
- end
32
-
33
- describe '#class' do
34
- it 'should be forwarded to parent' do
35
- @parent.should_receive(:class).and_return(Manufacturer)
36
- @association.class.should == Manufacturer
37
- end
38
- end
39
-
40
- describe '#replace' do
41
- before do
42
- @other = mock('other parent')
43
- end
44
-
45
- before do
46
- @relationship.should_receive(:attach_parent).with(@child, @other)
47
- end
48
-
49
- it 'should remove the resource from the collection' do
50
- @association.should == @parent
51
- @association.replace(@other)
52
- @association.should == @other
53
- end
54
-
55
- it 'should not automatically save that the resource was removed from the association' do
56
- @other.should_not_receive(:save)
57
- @association.replace(@other)
58
- end
59
-
60
- it 'should return the association' do
61
- @association.replace(@other).object_id.should == @association.object_id
62
- end
63
- end
64
-
65
- it 'should provide #save' do
66
- @association.should respond_to(:replace)
67
- end
68
-
69
- describe '#save' do
70
- describe 'when the parent is nil' do
71
- before do
72
- @parent.stub!(:nil?).and_return(true)
73
- end
74
-
75
- it 'should not save the parent' do
76
- @association.save
77
- end
78
-
79
- it 'should return false' do
80
- @association.save.should == false
81
- end
82
- end
83
-
84
- describe 'when the parent is not a new record' do
85
- before do
86
- @parent.should_receive(:new_record?).with(no_args).and_return(false)
87
- end
88
-
89
- it 'should not save the parent' do
90
- @parent.should_not_receive(:save)
91
- @association.save
92
- end
93
-
94
- it 'should return true' do
95
- @association.save.should == true
96
- end
97
- end
98
-
99
- describe 'when the parent is a new record' do
100
- before do
101
- @parent.should_receive(:new_record?).with(no_args).and_return(true)
102
- end
103
-
104
- it 'should save the parent' do
105
- @relationship.should_receive(:with_repository).and_yield
106
- @parent.should_receive(:save).with(no_args)
107
- @association.save
108
- end
109
-
110
- it 'should return the result of the save' do
111
- child_key = mock("child_key")
112
- child_key.should_receive(:set).and_return(true)
113
- parent_key = mock("parent_key")
114
- parent_key.should_receive(:get).and_return(1)
115
- @relationship.should_receive(:with_repository).and_yield
116
- @relationship.should_receive(:child_key).and_return(child_key)
117
- @relationship.should_receive(:parent_key).and_return(parent_key)
118
- save_results = mock('save results')
119
- @parent.should_receive(:save).with(no_args).and_return(save_results)
120
- @association.save.object_id.should == save_results.object_id
121
- end
122
- end
123
- end
124
-
125
- it 'should provide #reload' do
126
- @association.should respond_to(:reload)
127
- end
128
-
129
- describe '#reload' do
130
- before(:each) do
131
- @mock_parent = mock('#reload test parent')
132
- @association.replace(@mock_parent)
133
- end
134
-
135
- it 'should set the @parent ivar to nil' do
136
- @association.__send__(:parent).should == @mock_parent # Sanity check.
137
-
138
- # We can't test the value of the instance variable since
139
- # #instance_variable_get will be run on the @parent (thanks to
140
- # Proxy#method_missing). Instead, test that Relationship#get_parent is
141
- # run -- if @parent wasn't set to nil, this expectation should fail.
142
- @relationship.should_receive(:get_parent).once.and_return(@mock_parent)
143
- @association.reload
144
-
145
- # Trigger #get_parent on the relationship.
146
- @association.__send__(:parent)
147
- end
148
-
149
- it 'should not change the foreign key in the child' do
150
- @relationship.should_not_receive(:attach_parent)
151
- @association.reload
152
- end
153
-
154
- it 'should return self' do
155
- @association.reload.should be_kind_of(DataMapper::Associations::ManyToOne::Proxy)
156
- @association.reload.object_id.should == @association.object_id
157
- end
158
- end
159
- end