dm-core 0.9.3 → 0.9.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 (45) hide show
  1. data/CONTRIBUTING +51 -0
  2. data/FAQ +26 -8
  3. data/Manifest.txt +2 -0
  4. data/Rakefile +2 -1
  5. data/lib/dm-core.rb +8 -3
  6. data/lib/dm-core/adapters/abstract_adapter.rb +2 -2
  7. data/lib/dm-core/adapters/data_objects_adapter.rb +18 -4
  8. data/lib/dm-core/adapters/mysql_adapter.rb +8 -4
  9. data/lib/dm-core/adapters/postgres_adapter.rb +12 -3
  10. data/lib/dm-core/adapters/sqlite3_adapter.rb +1 -1
  11. data/lib/dm-core/associations.rb +1 -0
  12. data/lib/dm-core/associations/many_to_one.rb +7 -1
  13. data/lib/dm-core/associations/one_to_many.rb +1 -1
  14. data/lib/dm-core/associations/relationship.rb +14 -13
  15. data/lib/dm-core/auto_migrations.rb +57 -5
  16. data/lib/dm-core/collection.rb +2 -1
  17. data/lib/dm-core/logger.rb +5 -6
  18. data/lib/dm-core/model.rb +17 -2
  19. data/lib/dm-core/naming_conventions.rb +57 -25
  20. data/lib/dm-core/property.rb +6 -5
  21. data/lib/dm-core/query.rb +20 -16
  22. data/lib/dm-core/resource.rb +24 -7
  23. data/lib/dm-core/version.rb +1 -1
  24. data/script/performance.rb +2 -1
  25. data/script/profile.rb +1 -0
  26. data/spec/integration/association_spec.rb +131 -81
  27. data/spec/integration/association_through_spec.rb +87 -42
  28. data/spec/integration/associations/many_to_many_spec.rb +76 -16
  29. data/spec/integration/associations/many_to_one_spec.rb +6 -1
  30. data/spec/integration/associations/one_to_many_spec.rb +69 -0
  31. data/spec/integration/collection_spec.rb +7 -0
  32. data/spec/integration/query_spec.rb +24 -7
  33. data/spec/integration/resource_spec.rb +59 -10
  34. data/spec/integration/sti_spec.rb +23 -0
  35. data/spec/models/zoo.rb +2 -3
  36. data/spec/spec_helper.rb +9 -1
  37. data/spec/unit/adapters/postgres_adapter_spec.rb +9 -1
  38. data/spec/unit/associations/many_to_one_spec.rb +6 -0
  39. data/spec/unit/auto_migrations_spec.rb +2 -1
  40. data/spec/unit/naming_conventions_spec.rb +26 -18
  41. data/spec/unit/property_spec.rb +3 -4
  42. data/spec/unit/resource_spec.rb +19 -22
  43. data/tasks/gemspec.rb +23 -0
  44. data/tasks/hoe.rb +9 -1
  45. metadata +6 -14
@@ -509,7 +509,8 @@ module DataMapper
509
509
  assert_kind_of 'query', query, Query
510
510
 
511
511
  unless block_given?
512
- raise ArgumentError, 'a block must be supplied for lazy loading results', caller
512
+ # It can be helpful (relationship.rb: 112-13, used for SEL) to have a non-lazy Collection.
513
+ block = lambda {}
513
514
  end
514
515
 
515
516
  @query = query
@@ -4,10 +4,10 @@ require "time" # httpdate
4
4
  # Logger taken from Merb :)
5
5
  #
6
6
  # To replace an existing logger with a new one:
7
- # DataMapper::Logger.set_log(log{String, IO},level{Symbol, String})
7
+ # DataMapper.logger.set_log(log{String, IO},level{Symbol, String})
8
8
  #
9
- # Available logging levels are
10
- # DataMapper::Logger::{ Fatal, Error, Warn, Info, Debug }
9
+ # Available logging levels are:
10
+ # :off, :fatal, :error, :warn, :info, :debug
11
11
  #
12
12
  # Logging via:
13
13
  # DataMapper.logger.fatal(message<String>)
@@ -25,7 +25,7 @@ require "time" # httpdate
25
25
  # ==== Private DataMapper Logger API
26
26
  #
27
27
  # To initialize the logger you create a new object, proxies to set_log.
28
- # DataMapper::Logger.new(log{String, IO},level{Symbol, String})
28
+ # DataMapper::Logger.new(log{String, IO}, level{Symbol, String})
29
29
  #
30
30
  # Logger will not create the file until something is actually logged
31
31
  # This avoids file creation on DataMapper init when it creates the
@@ -147,8 +147,7 @@ module DataMapper
147
147
  end
148
148
 
149
149
  # To replace an existing logger with a new one:
150
- # DataMapper::Logger.set_log(log{String, IO},level{Symbol, String})
151
- #
150
+ # DataMapper.logger.set_log(log{String, IO},level{Symbol, String})
152
151
  #
153
152
  # @param log<IO,String> either an IO object or a name of a logfile.
154
153
  # @param log_level<Symbol> a symbol representing the log level from
data/lib/dm-core/model.rb CHANGED
@@ -31,6 +31,7 @@ module DataMapper
31
31
  def self.extended(model)
32
32
  model.instance_variable_set(:@storage_names, Hash.new { |h,k| h[k] = repository(k).adapter.resource_naming_convention.call(model.send(:default_storage_name)) })
33
33
  model.instance_variable_set(:@properties, Hash.new { |h,k| h[k] = k == Repository.default_name ? PropertySet.new : h[Repository.default_name].dup })
34
+ model.instance_variable_set(:@field_naming_conventions, Hash.new { |h,k| h[k] = repository(k).adapter.field_naming_convention })
34
35
  extra_extensions.each { |extension| model.extend(extension) }
35
36
  end
36
37
 
@@ -39,7 +40,13 @@ module DataMapper
39
40
  target.instance_variable_set(:@properties, Hash.new { |h,k| h[k] = k == Repository.default_name ? PropertySet.new : h[Repository.default_name].dup })
40
41
  target.instance_variable_set(:@base_model, self.base_model)
41
42
  target.instance_variable_set(:@paranoid_properties, @paranoid_properties)
42
- target.instance_variable_set(:@validations, @validations.dup) if self.respond_to?(:validators)
43
+ target.instance_variable_set(:@field_naming_conventions, @field_naming_conventions.dup)
44
+
45
+ if self.respond_to?(:validators)
46
+ @validations.contexts.each do |context, validators|
47
+ validators.each { |validator| target.validators.context(context) << validator }
48
+ end
49
+ end
43
50
 
44
51
  @properties.each do |repository_name,properties|
45
52
  repository(repository_name) do
@@ -120,6 +127,14 @@ module DataMapper
120
127
  @storage_names
121
128
  end
122
129
 
130
+ ##
131
+ # The field naming conventions for this resource across all repositories.
132
+ #
133
+ # @return <Hash(Symbol => String)> All available field naming conventions
134
+ def field_naming_conventions
135
+ @field_naming_conventions
136
+ end
137
+
123
138
  ##
124
139
  # defines a property on the resource
125
140
  #
@@ -262,7 +277,7 @@ module DataMapper
262
277
 
263
278
  ##
264
279
  # This method is deprecated, and will be removed from dm-core.
265
- #
280
+ #
266
281
  def create!(attributes = {})
267
282
  warn("Model#create! is deprecated. It is moving to dm-validations, and will be used to create a record without validations")
268
283
  resource = create(attributes)
@@ -4,7 +4,7 @@ module DataMapper
4
4
  # The default is UnderscoredAndPluralized.
5
5
  # You assign a naming convention like so:
6
6
  #
7
- # repository(:default).adapter.resource_naming_convention = NamingConventions::Underscored
7
+ # repository(:default).adapter.resource_naming_convention = NamingConventions::Resource::Underscored
8
8
  #
9
9
  # You can also easily assign a custom convention with a Proc:
10
10
  #
@@ -21,32 +21,64 @@ module DataMapper
21
21
  # use code like this:
22
22
  #
23
23
  # adapter = DataMapper.setup(:default, "mock://localhost/mock")
24
- # adapter.resource_naming_convention = DataMapper::NamingConventions::Underscored
24
+ # adapter.resource_naming_convention = DataMapper::NamingConventions::Resource::Underscored
25
25
  module NamingConventions
26
26
 
27
- module UnderscoredAndPluralized
28
- def self.call(value)
29
- Extlib::Inflection.pluralize(Extlib::Inflection.underscore(value)).gsub('/','_')
30
- end
31
- end # module UnderscoredAndPluralized
32
-
33
- module UnderscoredAndPluralizedWithoutModule
34
- def self.call(value)
35
- Extlib::Inflection.pluralize(Extlib::Inflection.underscore(Extlib::Inflection.demodulize(value)))
36
- end
37
- end # module UnderscoredAndPluralizedWithoutModule
38
-
39
- module Underscored
40
- def self.call(value)
41
- Extlib::Inflection.underscore(value)
42
- end
43
- end # module Underscored
44
-
45
- module Yaml
46
- def self.call(value)
47
- Extlib::Inflection.pluralize(Extlib::Inflection.underscore(value)) + ".yaml"
48
- end
49
- end # module Yaml
27
+ module Resource
28
+
29
+ module UnderscoredAndPluralized
30
+ def self.call(name)
31
+ Extlib::Inflection.pluralize(Extlib::Inflection.underscore(name)).gsub('/','_')
32
+ end
33
+ end # module UnderscoredAndPluralized
34
+
35
+ module UnderscoredAndPluralizedWithoutModule
36
+ def self.call(name)
37
+ Extlib::Inflection.pluralize(Extlib::Inflection.underscore(Extlib::Inflection.demodulize(name)))
38
+ end
39
+ end # module UnderscoredAndPluralizedWithoutModule
40
+
41
+ module Underscored
42
+ def self.call(name)
43
+ Extlib::Inflection.underscore(name)
44
+ end
45
+ end # module Underscored
46
+
47
+ module Yaml
48
+ def self.call(name)
49
+ Extlib::Inflection.pluralize(Extlib::Inflection.underscore(name)) + ".yaml"
50
+ end
51
+ end # module Yaml
52
+
53
+ end # module Resource
54
+
55
+ module Field
56
+
57
+ module UnderscoredAndPluralized
58
+ def self.call(property)
59
+ Extlib::Inflection.pluralize(Extlib::Inflection.underscore(property.name.to_s)).gsub('/','_')
60
+ end
61
+ end # module UnderscoredAndPluralized
62
+
63
+ module UnderscoredAndPluralizedWithoutModule
64
+ def self.call(property)
65
+ Extlib::Inflection.pluralize(Extlib::Inflection.underscore(Extlib::Inflection.demodulize(property.name.to_s)))
66
+ end
67
+ end # module UnderscoredAndPluralizedWithoutModule
68
+
69
+ module Underscored
70
+ def self.call(property)
71
+ Extlib::Inflection.underscore(property.name.to_s)
72
+ end
73
+ end # module Underscored
74
+
75
+ module Yaml
76
+ def self.call(property)
77
+ Extlib::Inflection.pluralize(Extlib::Inflection.underscore(property.name.to_s)) + ".yaml"
78
+ end
79
+ end # module Yaml
80
+
81
+ end # module Field
50
82
 
51
83
  end # module NamingConventions
52
84
  end # module DataMapper
@@ -279,7 +279,7 @@ module DataMapper
279
279
 
280
280
  attr_reader :primitive, :model, :name, :instance_variable_name,
281
281
  :type, :reader_visibility, :writer_visibility, :getter, :options,
282
- :default, :precision, :scale, :track
282
+ :default, :precision, :scale, :track, :extra_options
283
283
 
284
284
  # Supplies the field in the data-store which the property corresponds to
285
285
  #
@@ -510,8 +510,9 @@ module DataMapper
510
510
  raise ArgumentError, "+type+ was #{type.inspect}, which is not a supported type: #{TYPES * ', '}", caller
511
511
  end
512
512
 
513
- if (unknown_options = options.keys - PROPERTY_OPTIONS).any?
514
- raise ArgumentError, "+options+ contained unknown keys: #{unknown_options * ', '}", caller
513
+ @extra_options = {}
514
+ (options.keys - PROPERTY_OPTIONS).each do |key|
515
+ @extra_options[key] = options.delete(key)
515
516
  end
516
517
 
517
518
  @model = model
@@ -548,7 +549,7 @@ module DataMapper
548
549
  @length = @options.fetch(:length, @options.fetch(:size, DEFAULT_LENGTH))
549
550
  elsif BigDecimal == @primitive || Float == @primitive
550
551
  @precision = @options.fetch(:precision, DEFAULT_PRECISION)
551
-
552
+
552
553
  default_scale = (Float == @primitive) ? DEFAULT_SCALE_FLOAT : DEFAULT_SCALE_BIGDECIMAL
553
554
  @scale = @options.fetch(:scale, default_scale)
554
555
  # @scale = @options.fetch(:scale, DEFAULT_SCALE_BIGDECIMAL)
@@ -575,7 +576,7 @@ module DataMapper
575
576
  end
576
577
 
577
578
  def fields
578
- @fields ||= Hash.new { |h,k| h[k] = repository(k).adapter.field_naming_convention.call(self.name) }
579
+ @fields ||= Hash.new { |h,k| h[k] = self.model.field_naming_conventions[k].call(self) }
579
580
  end
580
581
 
581
582
  def determine_visibility # :nodoc:
data/lib/dm-core/query.rb CHANGED
@@ -47,7 +47,7 @@ module DataMapper
47
47
  # only overwrite the attributes with non-default values
48
48
  @reload = other.reload? unless other.reload? == false
49
49
  @unique = other.unique? unless other.unique? == false
50
- @offset = other.offset unless other.offset == 0
50
+ @offset = other.offset if other.reload? || other.offset != 0
51
51
  @limit = other.limit unless other.limit == nil
52
52
  @order = other.order unless other.order == model.default_order
53
53
  @add_reversed = other.add_reversed? unless other.add_reversed? == false
@@ -189,8 +189,6 @@ module DataMapper
189
189
  @links = normalize_links(@links)
190
190
  @includes = normalize_includes(@includes)
191
191
 
192
- translate_custom_types(@properties, options)
193
-
194
192
  # treat all non-options as conditions
195
193
  (options.keys - OPTIONS - OPTIONS.map { |option| option.to_s }).each do |k|
196
194
  append_condition(k, options[k])
@@ -218,17 +216,6 @@ module DataMapper
218
216
  @conditions = original.conditions.map { |tuple| tuple.dup }
219
217
  end
220
218
 
221
- def translate_custom_types(properties, options)
222
- options.each do |key, value|
223
- case key
224
- when DataMapper::Query::Operator
225
- options[key] = properties[key.target].type.dump(value, properties[key.target]) if properties.has_property?(key.target) && properties[key.target].custom?
226
- when Symbol, String
227
- options[key] = properties[key].type.dump(value, properties[key]) if properties.has_property?(key) && properties[key].custom?
228
- end
229
- end
230
- end
231
-
232
219
  # validate the options
233
220
  def assert_valid_options(options)
234
221
  # validate the reload option and unique option
@@ -440,9 +427,26 @@ module DataMapper
440
427
  raise ArgumentError, "Clause #{clause.inspect} does not map to a DataMapper::Property", caller(2)
441
428
  end
442
429
 
430
+ bind_value = dump_custom_value(property, bind_value)
431
+
443
432
  @conditions << [ operator, property, bind_value ]
444
433
  end
445
434
 
435
+ def dump_custom_value(property_or_path, bind_value)
436
+ case property_or_path
437
+ when DataMapper::Query::Path
438
+ dump_custom_value(property_or_path.property, bind_value)
439
+ when Property
440
+ if property_or_path.custom?
441
+ property_or_path.type.dump(bind_value, property_or_path)
442
+ else
443
+ bind_value
444
+ end
445
+ else
446
+ bind_value
447
+ end
448
+ end
449
+
446
450
  # TODO: check for other mutually exclusive operator + property
447
451
  # combinations. For example if self's conditions were
448
452
  # [ :gt, :amount, 5 ] and the other's condition is [ :lt, :amount, 2 ]
@@ -565,8 +569,8 @@ module DataMapper
565
569
 
566
570
  class Path
567
571
  include Assertions
568
-
569
- %w[ id type ].each { |m| undef_method m }
572
+
573
+ %w[ id type ].each { |m| undef_method m }
570
574
 
571
575
  attr_reader :relationships, :model, :property, :operator
572
576
 
@@ -167,6 +167,17 @@ module DataMapper
167
167
 
168
168
  alias == eql?
169
169
 
170
+ # Computes a hash for the resource
171
+ #
172
+ # ==== Returns
173
+ # <Integer>:: the hash value of the resource
174
+ #
175
+ # -
176
+ # @api public
177
+ def hash
178
+ model.hash + key.hash
179
+ end
180
+
170
181
  # Inspection of the class name and the attributes
171
182
  #
172
183
  # ==== Returns
@@ -233,7 +244,7 @@ module DataMapper
233
244
 
234
245
  def key
235
246
  key_properties.map do |property|
236
- property.get!(self)
247
+ original_values[property.name] || property.get!(self)
237
248
  end
238
249
  end
239
250
 
@@ -259,19 +270,22 @@ module DataMapper
259
270
  # same API through out all of dm-more. dm-validations requires a
260
271
  # context to be passed
261
272
 
262
- child_associations.each { |a| a.save }
273
+ associations_saved = false
274
+ child_associations.each { |a| associations_saved |= a.save }
263
275
 
264
- success = if dirty? || (new_record? && key_properties.any? { |p| p.serial? })
276
+ saved = if dirty? || (new_record? && key_properties.any? { |p| p.serial? })
265
277
  new_record? ? create : update
266
278
  end
267
279
 
268
- if success
280
+ if saved
269
281
  original_values.clear
270
282
  end
271
283
 
272
- parent_associations.each { |a| a.save }
284
+ parent_associations.each { |a| associations_saved |= a.save }
273
285
 
274
- success == true
286
+ # We should return true if the model (or any of its associations)
287
+ # were saved.
288
+ (saved | associations_saved) == true
275
289
  end
276
290
 
277
291
  # destroy the instance, remove it from the repository
@@ -503,7 +517,10 @@ module DataMapper
503
517
  #-
504
518
  # @api public
505
519
  def update_attributes(hash, *update_only)
506
- raise 'Update takes a hash as first parameter' unless hash.is_a?(Hash)
520
+ unless hash.is_a?(Hash)
521
+ raise ArgumentError, "Expecting the first parameter of " +
522
+ "update_attributes to be a hash; got #{hash.inspect}"
523
+ end
507
524
  loop_thru = update_only.empty? ? hash.keys : update_only
508
525
  loop_thru.each { |attr| send("#{attr}=", hash[attr]) }
509
526
  save
@@ -1,3 +1,3 @@
1
1
  module DataMapper
2
- VERSION = '0.9.3' unless defined?(DataMapper::VERSION)
2
+ VERSION = '0.9.4' unless defined?(DataMapper::VERSION)
3
3
  end
@@ -23,6 +23,7 @@ socket_file = Pathname.glob(%w[
23
23
  tmp/mysql.sock
24
24
  /tmp/mysql.sock
25
25
  /var/mysql/mysql.sock
26
+ /var/run/mysqld/mysqld.sock
26
27
  ]).find { |path| path.socket? }
27
28
 
28
29
  configuration_options = {
@@ -130,7 +131,7 @@ puts "Benchmarks will now run #{TIMES} times"
130
131
  RBench.run(TIMES) do
131
132
 
132
133
  column :times
133
- column :dm, :title => "DM 0.9.3"
134
+ column :dm, :title => "DM 0.9.4"
134
135
  column :ar, :title => "AR 2.1"
135
136
  column :diff, :compare => [:dm,:ar]
136
137
 
data/script/profile.rb CHANGED
@@ -18,6 +18,7 @@ SOCKET_FILE = Pathname.glob(%w[
18
18
  /tmp/mysqld.sock
19
19
  /tmp/mysql.sock
20
20
  /var/mysql/mysql.sock
21
+ /var/run/mysqld/mysqld.sock
21
22
  ]).find { |path| path.socket? }
22
23
 
23
24
  DataMapper::Logger.new(DataMapper.root / 'log' / 'dm.log', :debug)
@@ -165,6 +165,19 @@ if ADAPTER
165
165
  belongs_to :parent, :class_name => 'Node', :child_key => [ :parent_id ]
166
166
  end
167
167
 
168
+ class MadeUpThing
169
+ include DataMapper::Resource
170
+
171
+ def self.default_repository_name
172
+ ADAPTER
173
+ end
174
+
175
+ property :id, Serial
176
+ property :name, String
177
+ belongs_to :area
178
+ belongs_to :machine
179
+ end
180
+
168
181
  module Models
169
182
  class Project
170
183
  include DataMapper::Resource
@@ -227,6 +240,7 @@ if ADAPTER
227
240
 
228
241
  belongs_to :galaxy
229
242
  end
243
+
230
244
  end
231
245
 
232
246
  describe DataMapper::Associations do
@@ -274,6 +288,7 @@ if ADAPTER
274
288
  before do
275
289
  Machine.auto_migrate!(ADAPTER)
276
290
  Area.auto_migrate!(ADAPTER)
291
+ MadeUpThing.auto_migrate!(ADAPTER)
277
292
 
278
293
  machine1 = Machine.create(:name => 'machine1')
279
294
  machine2 = Machine.create(:name => 'machine2')
@@ -299,10 +314,9 @@ if ADAPTER
299
314
  end
300
315
 
301
316
  it 'should save both the object and parent if both are new' do
302
- pending "This is fixed"
303
317
  area1 = Area.new(:name => 'area1')
304
318
  area1.machine = Machine.new(:name => 'machine1')
305
- area1.machine.save
319
+ area1.save
306
320
  area1.machine_id.should == area1.machine.id
307
321
  end
308
322
 
@@ -338,6 +352,16 @@ if ADAPTER
338
352
  Area.new(:machine => machine).machine_id.should == machine.id
339
353
  end
340
354
 
355
+ it "should be able to set an association obtained from another association" do
356
+ machine1 = Machine.first(:name => 'machine1')
357
+ area1 = Area.first(:name => 'area1')
358
+ area1.machine = machine1
359
+
360
+ m = MadeUpThing.create(:machine => area1.machine, :name => "Weird")
361
+
362
+ m.machine_id.should == machine1.id
363
+ end
364
+
341
365
  it 'should save the parent upon saving of child' do
342
366
  e = Machine.new(:name => 'machine10')
343
367
  y = Area.create(:name => 'area10', :machine => e)
@@ -346,6 +370,13 @@ if ADAPTER
346
370
  Machine.first(:name => 'machine10').should_not be_nil
347
371
  end
348
372
 
373
+ it 'should set and retrieve associations on not yet saved objects' do
374
+ e = Machine.create(:name => 'machine10')
375
+ y = e.areas.build(:name => 'area10')
376
+
377
+ y.machine.name.should == 'machine10'
378
+ end
379
+
349
380
  it 'should convert NULL parent ids into nils' do
350
381
  Area.first(:name => 'area2').machine.should be_nil
351
382
  end
@@ -379,6 +410,17 @@ if ADAPTER
379
410
 
380
411
  lambda { y.reload }.should_not raise_error
381
412
  end
413
+
414
+ it "should have machine when created using machine_id" do
415
+ m = Machine.create(:name => 'machineX')
416
+ a = Area.new(:machine_id => m.id)
417
+ a.machine.should == m
418
+ end
419
+
420
+ it "should not have a machine when orphaned" do
421
+ a = Area.new(:machine_id => 42)
422
+ a.machine.should be_nil
423
+ end
382
424
  end
383
425
 
384
426
  describe 'one to one associations' do
@@ -697,7 +739,7 @@ if ADAPTER
697
739
  end
698
740
  property :id, Serial
699
741
  property :name, String
700
- belongs_to :shop, :class_name => 'Sweets::Shop'
742
+ belongs_to :shop
701
743
  has 1, :wife
702
744
  has n, :children
703
745
  has n, :toys, :through => :children
@@ -1178,18 +1220,19 @@ if ADAPTER
1178
1220
  @li = LeftItem.new(:name => "li#{number}")
1179
1221
  end
1180
1222
 
1181
- it "should add to the assocaiton from the left" do
1182
- pending "Waiting on Many To Many to be implemented"
1183
- create_item_pair "0000"
1184
- @ri.save; @li.save
1185
- @ri.should_not be_new_record
1186
- @li.should_not be_new_record
1223
+ it "should add to the association from the left" do
1224
+ pending "Waiting on Many To Many to be implemented" do
1225
+ create_item_pair "0000"
1226
+ @ri.save; @li.save
1227
+ @ri.should_not be_new_record
1228
+ @li.should_not be_new_record
1187
1229
 
1188
- @li.right_items << @ri
1189
- @li.right_items.should include(@ri)
1190
- @li.reload
1191
- @ri.reload
1192
- @li.right_items.should include(@ri)
1230
+ @li.right_items << @ri
1231
+ @li.right_items.should include(@ri)
1232
+ @li.reload
1233
+ @ri.reload
1234
+ @li.right_items.should include(@ri)
1235
+ end
1193
1236
  end
1194
1237
 
1195
1238
  it "should add to the association from the right" do
@@ -1205,93 +1248,100 @@ if ADAPTER
1205
1248
  @ri.left_items.should include(@li)
1206
1249
  end
1207
1250
 
1208
- it "should load the assocaited collection from the either side" do
1209
- pending "Waiting on Many To Many to be implemented"
1210
- create_item_pair "0020"
1211
- @ri.save; @li.save
1212
- @ri.left_items << @li
1213
- @ri.reload; @li.reload
1251
+ it "should load the associated collection from the either side" do
1252
+ pending "Waiting on Many To Many to be implemented" do
1253
+ create_item_pair "0020"
1254
+ @ri.save; @li.save
1255
+ @ri.left_items << @li
1256
+ @ri.reload; @li.reload
1214
1257
 
1215
- @ri.left_items.should include(@li)
1216
- @li.right_items.should include(@ri)
1258
+ @ri.left_items.should include(@li)
1259
+ @li.right_items.should include(@ri)
1260
+ end
1217
1261
  end
1218
1262
 
1219
- it "should load the assocatied collection from the right" do
1220
- pending "Waiting on Many To Many to be implemented"
1221
- create_item_pair "0030"
1222
- @ri.save; @li.save
1223
- @li.right_items << @li
1224
- @ri.reload; @li.reload
1225
-
1226
- @ri.left_items.should include(@li)
1227
- @li.right_items.should include(@ri)
1263
+ it "should load the associated collection from the right" do
1264
+ pending "Waiting on Many To Many to be implemented" do
1265
+ create_item_pair "0030"
1266
+ @ri.save; @li.save
1267
+ @li.right_items << @li
1268
+ @ri.reload; @li.reload
1228
1269
 
1270
+ @ri.left_items.should include(@li)
1271
+ @li.right_items.should include(@ri)
1272
+ end
1229
1273
  end
1230
1274
 
1231
1275
  it "should save the left side of the association if new record" do
1232
- pending "Waiting on Many To Many to be implemented"
1233
- create_item_pair "0040"
1234
- @ri.save
1235
- @li.should be_new_record
1236
- @ri.left_items << @li
1237
- @li.should_not be_new_record
1276
+ pending "Waiting on Many To Many to be implemented" do
1277
+ create_item_pair "0040"
1278
+ @ri.save
1279
+ @li.should be_new_record
1280
+ @ri.left_items << @li
1281
+ @li.should_not be_new_record
1282
+ end
1238
1283
  end
1239
1284
 
1240
- it "should save the right side of the assocaition if new record" do
1241
- pending "Waiting on Many To Many to be implemented"
1242
- create_item_pair "0050"
1243
- @li.save
1244
- @ri.should be_new_record
1245
- @li.right_items << @ri
1246
- @ri.should_not be_new_record
1285
+ it "should save the right side of the association if new record" do
1286
+ pending "Waiting on Many To Many to be implemented" do
1287
+ create_item_pair "0050"
1288
+ @li.save
1289
+ @ri.should be_new_record
1290
+ @li.right_items << @ri
1291
+ @ri.should_not be_new_record
1292
+ end
1247
1293
  end
1248
1294
 
1249
- it "should save both side of the assocaition if new record" do
1250
- pending "Waiting on Many To Many to be implemented"
1251
- create_item_pair "0060"
1252
- @li.should be_new_record
1253
- @ri.should be_new_record
1254
- @ri.left_items << @li
1255
- @ri.should_not be_new_record
1256
- @li.should_not be_new_record
1295
+ it "should save both side of the association if new record" do
1296
+ pending "Waiting on Many To Many to be implemented" do
1297
+ create_item_pair "0060"
1298
+ @li.should be_new_record
1299
+ @ri.should be_new_record
1300
+ @ri.left_items << @li
1301
+ @ri.should_not be_new_record
1302
+ @li.should_not be_new_record
1303
+ end
1257
1304
  end
1258
1305
 
1259
1306
  it "should remove an item from the left collection without destroying the item" do
1260
- pending "Waiting on Many To Many to be implemented"
1261
- create_item_pair "0070"
1262
- @li.save; @ri.save
1263
- @ri.left_items << @li
1264
- @ri.reload; @li.reload
1265
- @ri.left_items.should include(@li)
1266
- @ri.left_items.delete(@li)
1267
- @ri.left_items.should_not include(@li)
1268
- @li.reload
1269
- LeftItem.get(@li.id).should_not be_nil
1307
+ pending "Waiting on Many To Many to be implemented" do
1308
+ create_item_pair "0070"
1309
+ @li.save; @ri.save
1310
+ @ri.left_items << @li
1311
+ @ri.reload; @li.reload
1312
+ @ri.left_items.should include(@li)
1313
+ @ri.left_items.delete(@li)
1314
+ @ri.left_items.should_not include(@li)
1315
+ @li.reload
1316
+ LeftItem.get(@li.id).should_not be_nil
1317
+ end
1270
1318
  end
1271
1319
 
1272
1320
  it "should remove an item from the right collection without destroying the item" do
1273
- pending "Waiting on Many To Many to be implemented"
1274
- create_item_pair "0080"
1275
- @li.save; @ri.save
1276
- @li.right_items << @ri
1277
- @li.reload; @ri.reload
1278
- @li.right_items.should include(@ri)
1279
- @li.right_items.delete(@ri)
1280
- @li.right_items.should_not include(@ri)
1281
- @ri.reload
1282
- RightItem.get(@ri.id).should_not be_nil
1321
+ pending "Waiting on Many To Many to be implemented" do
1322
+ create_item_pair "0080"
1323
+ @li.save; @ri.save
1324
+ @li.right_items << @ri
1325
+ @li.reload; @ri.reload
1326
+ @li.right_items.should include(@ri)
1327
+ @li.right_items.delete(@ri)
1328
+ @li.right_items.should_not include(@ri)
1329
+ @ri.reload
1330
+ RightItem.get(@ri.id).should_not be_nil
1331
+ end
1283
1332
  end
1284
1333
 
1285
1334
  it "should remove the item from the collection when an item is deleted" do
1286
- pending "Waiting on Many To Many to be implemented"
1287
- create_item_pair "0090"
1288
- @li.save; @ri.save
1289
- @ri.left_items << @li
1290
- @ri.reload; @li.reload
1291
- @ri.left_items.should include(@li)
1292
- @li.destroy
1293
- @ri.reload
1294
- @ri.left_items.should_not include(@li)
1335
+ pending "Waiting on Many To Many to be implemented" do
1336
+ create_item_pair "0090"
1337
+ @li.save; @ri.save
1338
+ @ri.left_items << @li
1339
+ @ri.reload; @li.reload
1340
+ @ri.left_items.should include(@li)
1341
+ @li.destroy
1342
+ @ri.reload
1343
+ @ri.left_items.should_not include(@li)
1344
+ end
1295
1345
  end
1296
1346
  end
1297
1347
  end