activefacts-api 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.
@@ -50,25 +50,3 @@ class Module #:nodoc:
50
50
  name.gsub(/.*::/, '')
51
51
  end
52
52
  end
53
-
54
- module ActiveFacts #:nodoc:
55
- # If the args array ends with a hash, remove it.
56
- # If the remaining args are fewer than the arg_names,
57
- # extract values from the hash and append them to args.
58
- # Return the new args array and the hash.
59
- # In any case leave the original args unmodified.
60
- def self.extract_hash_args(arg_names, args)
61
- if Hash === args[-1]
62
- arg_hash = args[-1] # Don't pop args, leave it unmodified
63
- args = args[0..-2]
64
- arg_hash = arg_hash.clone if (args.size < arg_names.size)
65
- while args.size < arg_names.size
66
- args << arg_hash[n = arg_names[args.size]]
67
- arg_hash.delete(n)
68
- end
69
- else
70
- arg_hash = {}
71
- end
72
- return args, arg_hash
73
- end
74
- end
@@ -6,6 +6,7 @@
6
6
  #
7
7
  # The methods of this module are added to Value type classes.
8
8
  #
9
+
9
10
  module ActiveFacts
10
11
  module API
11
12
 
@@ -15,14 +16,9 @@ module ActiveFacts
15
16
 
16
17
  # Value instance methods:
17
18
  def initialize(*args) #:nodoc:
18
- hash = args[-1].is_a?(Hash) ? args.pop.clone : nil
19
+ arg_hash = args[-1].is_a?(Hash) ? args.pop.clone : nil
19
20
 
20
21
  super(args)
21
-
22
- (hash ? hash.entries : []).each do |role_name, value|
23
- role = self.class.roles(role_name)
24
- send(role.setter, value)
25
- end
26
22
  end
27
23
 
28
24
  # verbalise this Value
@@ -31,7 +27,9 @@ module ActiveFacts
31
27
  end
32
28
 
33
29
  # A value is its own key, unless it's a delegate for a raw value
34
- def identifying_role_values #:nodoc:
30
+ def identifying_role_values(klass = nil) #:nodoc:
31
+ # The identifying role value for the supertype of a value type is always the same as for the subtype:
32
+ # raise "Value Types cannot return identifying_role_values for supertypes" if klass and klass != self.class
35
33
  __getobj__ rescue self
36
34
  end
37
35
 
@@ -75,44 +73,58 @@ module ActiveFacts
75
73
  "#{basename} = #{superclass.basename}();"
76
74
  end
77
75
 
78
- def identifying_role_values(*args) #:nodoc:
79
- # If the single arg is the correct class or a subclass, use it directly
80
- if (args.size == 1 and (arg = args[0]).is_a?(self)) # No secondary supertypes allowed for value types
81
- return arg.identifying_role_values
82
- end
83
- new(*args).identifying_role_values
84
- end
85
-
86
- def assert_instance(constellation, args) #:nodoc:
87
- # Build the key for this instance from the args
88
- # The key of an instance is the value or array of keys of the identifying values.
89
- # The key values aren't necessarily present in the constellation, even after this.
90
- key = identifying_role_values(*args)
76
+ def identifying_role_values(constellation, args) #:nodoc:
77
+ # Normalise positional arguments into an arguments hash (this changes the passed parameter)
78
+ arg_hash = args[-1].is_a?(Hash) ? args.pop : {}
91
79
 
92
- # Find and return an existing instance matching this key
93
- instances = constellation.instances[self] # All instances of this class in this constellation
94
- instance = instances[key]
95
- return instance, key if instance # A matching instance of this class
96
-
97
- #trace :assert, "Constructing new #{self} with #{args.inspect}" do
98
- instance = new(*args)
99
- #end
100
-
101
- instance.constellation = constellation
102
- return *index_instance(instance)
80
+ # If a single arg is already the correct class or a subclass,
81
+ # use it directly, otherwise create one.
82
+ # This appears to be the only way to handle e.g. Date correctly
83
+ unless args.size == 1 and instance = args[0] and instance.is_a?(self)
84
+ instance = new_instance(constellation, *args)
85
+ end
86
+ args.replace([arg_hash])
87
+ instance.identifying_role_values
103
88
  end
104
89
 
105
- def index_instance(instance, key = nil, key_roles = nil) #:nodoc:
106
- instances = instance.constellation.instances[self]
90
+ def assert_instance(constellation, args)
91
+ new_identifier = args == [:new]
92
+ key = identifying_role_values(constellation, args)
93
+ # args are now normalized to an array containing a single Hash element
94
+ arg_hash = args[0]
95
+
96
+ if new_identifier
97
+ instance = key # AutoCounter is its own key
98
+ else
99
+ instance_index = constellation.instances[self]
100
+ unless instance = constellation.has_candidate(self, key) || instance_index[key]
101
+ instance = new_instance(constellation, key)
102
+ constellation.candidate(instance)
103
+ end
104
+ end
105
+
106
+ # Assign any extra roles that may have been passed.
107
+ # An exception here leaves the object as a candidate,
108
+ # but without the offending role (re-)assigned.
109
+ arg_hash.each do |k, v|
110
+ instance.send(:"#{k}=", v)
111
+ end
112
+
113
+ instance
114
+ end
115
+
116
+ def index_instance(constellation, instance) #:nodoc:
117
+ # Index the instance in the constellation's InstanceIndex for this class:
118
+ instances = constellation.instances[self]
107
119
  key = instance.identifying_role_values
108
120
  instances[key] = instance
109
121
 
110
122
  # Index the instance for each supertype:
111
123
  supertypes.each do |supertype|
112
- supertype.index_instance(instance, key)
124
+ supertype.index_instance(constellation, instance)
113
125
  end
114
126
 
115
- return instance, key
127
+ instance
116
128
  end
117
129
 
118
130
  def inherited(other) #:nodoc:
@@ -123,15 +135,26 @@ module ActiveFacts
123
135
  end
124
136
  end
125
137
 
126
- def self.included other #:nodoc:
127
- other.send :extend, ClassMethods
138
+ def self.included klass #:nodoc:
139
+ klass.send :extend, ClassMethods
140
+
141
+ if !klass.respond_to?(:new_instance)
142
+ class << klass
143
+ def new_instance constellation, *args
144
+ instance = allocate
145
+ instance.instance_variable_set("@constellation", constellation)
146
+ instance.send(:initialize, *args)
147
+ instance
148
+ end
149
+ end
150
+ end
128
151
 
129
152
  # Register ourselves with the parent module, which has become a Vocabulary:
130
- vocabulary = other.modspace
153
+ vocabulary = klass.modspace
131
154
  unless vocabulary.respond_to? :object_type # Extend module with Vocabulary if necessary
132
155
  vocabulary.send :extend, Vocabulary
133
156
  end
134
- vocabulary.__add_object_type(other)
157
+ vocabulary.__add_object_type(klass)
135
158
  end
136
159
  end
137
160
  end
@@ -28,12 +28,14 @@ module ActiveFacts
28
28
  if @keys[:debug]
29
29
  errors = []
30
30
  success = false
31
- [ENV["DEBUG_PREFERENCE"]].compact+
32
- [
33
- 'pry',
34
- 'debugger',
35
- 'ruby-debug'
36
- ].each do |debugger|
31
+ (
32
+ [ENV["DEBUG_PREFERENCE"]].compact +
33
+ [
34
+ 'pry',
35
+ 'debugger',
36
+ 'ruby-debug'
37
+ ]
38
+ ).each do |debugger|
37
39
  begin
38
40
  require debugger
39
41
  puts "Loaded "+debugger
@@ -27,6 +27,7 @@ describe "A Constellation instance" do
27
27
  class Name < StringVal
28
28
  value_type
29
29
  #has_one :attr, Name
30
+ has_one :undefined_role # This will be unsatisfied with the non-existence of the UndefinedRole class
30
31
  end
31
32
 
32
33
  class LegalEntity
@@ -34,18 +35,18 @@ describe "A Constellation instance" do
34
35
  one_to_one :name, :mandatory => true
35
36
  end
36
37
 
37
- class SurrogateId
38
+ class Surrogate
38
39
  identified_by :auto_counter_val
39
40
  one_to_one :auto_counter_val
40
41
  end
41
42
 
42
43
  class Company < LegalEntity
43
- supertypes SurrogateId
44
+ supertypes Surrogate
44
45
  end
45
46
 
46
47
  class Person < LegalEntity
47
- identified_by :name, :family_name # REVISIT: want a way to role_alias :name, :given_name
48
- supertypes :surrogate_id # Use a Symbol binding this time
48
+ identified_by :name, :family_name # REVISIT: want a way to role_alias :name, :given_name
49
+ supertypes :surrogate # Use a Symbol binding this time
49
50
 
50
51
  has_one :family_name, :class => Name
51
52
  has_one :employer, :class => Company
@@ -84,6 +85,13 @@ describe "A Constellation instance" do
84
85
  it "should complain when accessing a class that isn't an object type" do
85
86
  class Mod::Bar; end
86
87
  lambda { @constellation.Bar }.should raise_error
88
+ lambda { @constellation.instances.Bar }.should raise_error
89
+ end
90
+
91
+ it "should deny handling an object type defined outside the current module" do
92
+ class ::Bar; end
93
+ lambda { @constellation.Bar }.should raise_error
94
+ lambda { @constellation.instances[Bar] }.should raise_error
87
95
  end
88
96
 
89
97
  it "should allow inspection" do
@@ -99,7 +107,14 @@ describe "A Constellation instance" do
99
107
  # @constellation.query.should == Mod
100
108
  # end
101
109
 
102
- it "should support methods to assert instances via the instance index for that type" do
110
+ it "should create methods to assert instances" do
111
+ # Check that methods have not yet been created:
112
+ @constellation.should_not respond_to(:Name)
113
+ @constellation.should_not respond_to(:LegalEntity)
114
+ @constellation.should_not respond_to(:Company)
115
+ @constellation.should_not respond_to(:Person)
116
+
117
+ # Assert instances
103
118
  name = foo = acme = fred_fly = nil
104
119
  lambda {
105
120
  name = @constellation.Name("foo")
@@ -107,6 +122,14 @@ describe "A Constellation instance" do
107
122
  acme = @constellation.Company("Acme, Inc", :auto_counter_val => :new)
108
123
  fred_fly = @constellation.Person("fred", "fly", :auto_counter_val => :new)
109
124
  }.should_not raise_error
125
+
126
+ # Check that methods have not yet been created:
127
+ @constellation.should respond_to(:Name)
128
+ @constellation.should respond_to(:LegalEntity)
129
+ @constellation.should respond_to(:Company)
130
+ @constellation.should respond_to(:Person)
131
+
132
+ # Check the instances
110
133
  name.class.should == Mod::Name
111
134
  name.constellation.should == @constellation
112
135
 
@@ -143,47 +166,66 @@ describe "A Constellation instance" do
143
166
  fred_fly1.object_id.should == fred_fly2.object_id
144
167
  end
145
168
 
146
- it "should reject re-assertion with additional assignments" do
147
- name1 = @constellation.Name("foo")
148
- foo1 = @constellation.LegalEntity("foo")
149
- acme1 = @constellation.Company("Acme, Inc", :auto_counter_val => :new)
150
- acme1_id = acme1.auto_counter_val.to_s
169
+ describe "re-assertion with any one of multiple identifiers" do
170
+ before :each do
171
+ # Create some instances:
172
+ @name1 = @constellation.Name("foo") # Value type
173
+ @foo1 = @constellation.LegalEntity("foo") # Entity Type with simple identifier
174
+ @acme1 = @constellation.Company("Acme, Inc", :auto_counter_val => :new)
175
+ @acme1_id = @acme1.auto_counter_val
176
+ end
151
177
 
152
- name2 = @constellation.Name("foo")
153
- foo2 = @constellation.LegalEntity("foo")
154
- acme2 = nil
155
- lambda { acme2 = @constellation.Company("Acme, Inc", :auto_counter_val => :new) }.should_not raise_error
156
- acme2.auto_counter_val = :new
157
- acme2.should == acme1
158
- acme2.auto_counter_val.should_not be_defined
159
- acme2.auto_counter_val.to_s.should == acme1_id
178
+ it "should be allowed with a normal value type id" do
179
+ # Reassert the instances:
180
+ @name2 = @constellation.Name("foo")
181
+ @foo2 = @constellation.LegalEntity("foo")
182
+ @acme2 = nil
183
+ lambda {
184
+ # Without the auto_counter_val
185
+ @acme2 = @constellation.Company("Acme, Inc")
186
+ }.should_not raise_error
187
+
188
+ # This creates a new auto_counter_val, changing the acme instance (and hence, both references to it)
189
+ @acme2.auto_counter_val = :new
190
+ @acme2.should == @acme1
191
+ @acme2.auto_counter_val.should_not be_defined
192
+ @acme2.auto_counter_val.to_s.should_not == @acme1_id.to_s
193
+ end
194
+
195
+ it "should be allowed with an autocounter id" do
196
+ acme3 = @constellation.Surrogate(@acme1_id)
197
+ acme3.should == @acme1
198
+ end
160
199
  end
161
200
 
162
- it "should support methods to assert instances via the class for that type" do
163
- name = foo = acme = fred_fly = nil
164
- lambda {
165
- name = @constellation.Name.assert("foo")
166
- foo = @constellation.LegalEntity.assert("foo")
167
- acme = @constellation.Company.assert("Acme, Inc", :auto_counter_val => :new)
168
- fred_fly = @constellation.Person.assert("fred", "fly", :auto_counter_val => :new)
169
- }.should_not raise_error
170
- name.class.should == Mod::Name
171
- name.constellation.should == @constellation
201
+ it "Should raise an exception with assigning a role whose referent (object type) has not yet been defined" do
202
+ n = @constellation.Name("Fred")
203
+ # This does n;t raise the "settable_roles_exception". I'm no longer sure how I did this, so I can't get coverage on this code :(
204
+ proc { n.undefined_role = 'foo' }.should raise_error
205
+ end
172
206
 
173
- foo.class.should == Mod::LegalEntity
174
- foo.constellation.should == @constellation
175
- foo.inspect.should =~ / in Conste/
176
- foo.verbalise.should =~ /LegalEntity\(/
207
+ # Maybe not complete yet
208
+ describe "assigning additional arguments on asserting a value type" do
209
+ before :each do
210
+ # This should work, but...
211
+ # birth_name = @constellation.Name("Smith", :person_as_birth_name => {:name => "Janet", :family_name => "Jones", :auto_counter_val => :new})
212
+ # for now, use the following form
213
+ @birth_name = @constellation.Name("Smith", :person_as_birth_name => ["Janet", "Jones", {:auto_counter_val => :new}])
214
+ @person = @birth_name.person_as_birth_name
215
+ end
177
216
 
178
- acme.class.should == Mod::Company
179
- acme.constellation.should == @constellation
180
- acme.inspect.should =~ / in Conste/
181
- acme.verbalise.should =~ /Company\(/
217
+ it "should create required instances" do
218
+ @person.should_not be_nil
219
+ @person.family_name.should == "Jones"
220
+ @person.name.should == "Janet"
221
+ @person.birth_name.should == "Smith"
222
+ end
182
223
 
183
- fred_fly.class.should == Mod::Person
184
- fred_fly.constellation.should == @constellation
185
- fred_fly.inspect.should =~ / in Conste/
186
- fred_fly.verbalise.should =~ /Person\(/
224
+ it "should initialise secondary supertypes" do
225
+ @acv = @person.auto_counter_val
226
+ @acv.should_not be_nil
227
+ @acv.surrogate.should == @person
228
+ end
187
229
  end
188
230
 
189
231
  it "should support population blocks" do
@@ -194,7 +236,7 @@ describe "A Constellation instance" do
194
236
  Company("Acme, Inc", :auto_counter_val => :new)
195
237
  end
196
238
  @constellation.Name.size.should == 5
197
- @constellation.SurrogateId.size.should == 2
239
+ @constellation.Surrogate.size.should == 2
198
240
  end
199
241
 
200
242
  it "should verbalise itself" do
@@ -202,28 +244,31 @@ describe "A Constellation instance" do
202
244
  Name("bar")
203
245
  LegalEntity("foo")
204
246
  c = Company("Acme, Inc", :auto_counter_val => :new)
205
- p = Person("Fred", "Nerk", :auto_counter_val => :new, :employer => c)
247
+ c.is_a?(Mod::Surrogate).should == true
248
+ c.auto_counter_val.should_not == nil
249
+ p = Person("Fred", "Nerk", :auto_counter_val => :new)
250
+ p.employer = c
206
251
  p.birth_name = "Nerk"
207
252
  end
208
253
  s = @constellation.verbalise
209
254
  names = s.split(/\n/).grep(/\tEvery /).map{|l| l.sub(/.*Every (.*):$/, '\1')}
210
- expected = ["AutoCounterVal", "Company", "LegalEntity", "Name", "Person", "StringVal", "SurrogateId"]
255
+ expected = ["Company", "LegalEntity", "Name", "Person", "StringVal", "Surrogate"]
211
256
  names.sort.should == expected
212
257
  end
213
258
 
214
259
  it "should support string capitalisation functions" do
215
- names = ["Company", "LegalEntity", "Name", "Person", "StringVal", "SurrogateId"]
260
+ names = ["Company", "LegalEntity", "Name", "Person", "StringVal", "Surrogate"]
216
261
  camelwords = names.map{|n| n.camelwords }
217
- camelwords.should == [["Company"], ["Legal", "Entity"], ["Name"], ["Person"], ["String", "Val"], ["Surrogate", "Id"]]
262
+ camelwords.should == [["Company"], ["Legal", "Entity"], ["Name"], ["Person"], ["String", "Val"], ["Surrogate"]]
218
263
 
219
264
  snakes = names.map{|n| n.snakecase }
220
- snakes.should == ["company", "legal_entity", "name", "person", "string_val", "surrogate_id"]
265
+ snakes.should == ["company", "legal_entity", "name", "person", "string_val", "surrogate"]
221
266
 
222
267
  camelupper = snakes.map{|n| n.camelcase }
223
- camelupper.should == ["Company", "LegalEntity", "Name", "Person", "StringVal", "SurrogateId"]
268
+ camelupper.should == ["Company", "LegalEntity", "Name", "Person", "StringVal", "Surrogate"]
224
269
 
225
270
  camellower = snakes.map{|n| n.camelcase(:lower) }
226
- camellower.should == ["company", "legalEntity", "name", "person", "stringVal", "surrogateId"]
271
+ camellower.should == ["company", "legalEntity", "name", "person", "stringVal", "surrogate"]
227
272
  end
228
273
 
229
274
  it "should allow inspection of instance indices" do
@@ -236,8 +281,8 @@ describe "A Constellation instance" do
236
281
  @constellation.Name.keys.sort.should == ["baz"]
237
282
 
238
283
  @constellation.StringVal.keys.sort.should == ["baz"]
239
- @constellation.StringVal.include?(baz).should == baz
240
- @constellation.StringVal.include?("baz").should == baz
284
+ @constellation.StringVal[baz].should == baz
285
+ @constellation.StringVal["baz"].should == baz
241
286
  end
242
287
 
243
288
  describe "instance indices" do
@@ -270,8 +315,8 @@ describe "A Constellation instance" do
270
315
  @constellation.LegalEntity.keys.sort.should include [name]
271
316
  @constellation.LegalEntity.keys.sort.should include [fred]
272
317
 
273
- @constellation.SurrogateId.values.should include acme
274
- @constellation.SurrogateId.values.should include fred_fly
318
+ @constellation.Surrogate.values.should include acme
319
+ @constellation.Surrogate.values.should include fred_fly
275
320
  end
276
321
 
277
322
  it "should handle one-to-ones correctly" do
@@ -286,23 +331,47 @@ describe "A Constellation instance" do
286
331
  end
287
332
 
288
333
  it "should allow retraction of instances" do
334
+ @constellation.Person
289
335
  person = @constellation.Person "Fred", "Smith", :auto_counter_val => :new, :birth_name => "Nerk"
336
+ smith = @constellation.Name("Smith")
337
+
338
+ # Check things are indexed properly:
339
+ @constellation.Surrogate.size.should == 1
340
+ @constellation.LegalEntity.size.should == 1
341
+ @constellation.Person.size.should == 1
342
+ person.family_name.should == smith
343
+ smith.all_person_as_family_name.size.should == 1
290
344
 
291
- @constellation.retract(@constellation.Name("Smith"))
345
+ @constellation.retract(smith)
346
+
347
+ @constellation.Name["Fred"].should_not be_nil # FamilyName is not mandatory, so Fred still exists
292
348
  @constellation.Name["Smith"].should be_nil
293
- @constellation.Name["Fred"].should_not be_nil
349
+
350
+ @constellation.Surrogate.size.should == 1
351
+ @constellation.LegalEntity.size.should == 1
352
+ @constellation.Person.size.should == 1
294
353
 
295
354
  person.family_name.should be_nil
296
- @constellation.retract(@constellation.Name("Fred"))
297
- @constellation.Name["Fred"].should be_nil
355
+
356
+ smith.all_person_as_family_name.size.should == 0
298
357
  end
299
358
 
300
359
  it "should retract linked instances (cascading)" do
301
- @constellation.Person "Fred", "Smith", :auto_counter_val => :new, :birth_name => "Nerk"
302
- @constellation.Person "George", "Smith", :auto_counter_val => :new, :birth_name => "Patrick"
360
+ fred = @constellation.Person "Fred", "Smith", :auto_counter_val => :new, :birth_name => "Nerk"
361
+ george = @constellation.Person "George", "Smith", :auto_counter_val => :new, :birth_name => "Patrick"
362
+ smith = @constellation.Name("Smith")
363
+
303
364
  @constellation.Person.size.should == 2
304
- @constellation.retract(@constellation.Name("Smith"))
305
- @constellation.Person.size.should == 0
365
+ fred.family_name.should == smith
366
+ george.family_name.should == smith
367
+ smith.all_person_as_family_name.size.should == 2
368
+
369
+ @constellation.retract(fred)
370
+
371
+ @constellation.Person.size.should == 1 # Fred is gone, George still exists
372
+ @constellation.Person.values[0].name.should == 'George'
373
+ fred.family_name.should be_nil
374
+ smith.all_person_as_family_name.size.should == 1
306
375
  end
307
376
 
308
377
  it "should fail to recognise references to unresolved forward referenced classes" do
@@ -310,7 +379,7 @@ describe "A Constellation instance" do
310
379
  class Foo
311
380
  identified_by :name
312
381
  one_to_one :name
313
- has_one :bar
382
+ has_one :not_yet
314
383
  has_one :baz, :class => "BAZ"
315
384
  end
316
385
 
@@ -322,7 +391,7 @@ describe "A Constellation instance" do
322
391
  @c = ActiveFacts::API::Constellation.new(Mod2)
323
392
  le = @c.Foo("Foo")
324
393
  lambda {
325
- le.bar
394
+ le.not_yet
326
395
  }.should raise_error(NoMethodError)
327
396
  lambda {
328
397
  le.baz
@@ -330,7 +399,7 @@ describe "A Constellation instance" do
330
399
 
331
400
  # Now define the classes and try again:
332
401
  module Mod2
333
- class Bar < String
402
+ class NotYet < String
334
403
  value_type
335
404
  end
336
405
  class BAZ < String
@@ -338,8 +407,8 @@ describe "A Constellation instance" do
338
407
  end
339
408
  end
340
409
  lambda {
341
- le.bar
342
- le.bar = 'bar'
410
+ le.not_yet
411
+ le.not_yet = 'not_yet'
343
412
  }.should_not raise_error
344
413
  lambda {
345
414
  le.baz
@@ -448,21 +517,10 @@ describe "A Constellation instance" do
448
517
  }.should raise_error
449
518
  end
450
519
 
451
- it "should complain when role name and counter part mismatch" do
452
- lambda {
453
- module Mod
454
- class CompanyName
455
- identified_by :name
456
- has_one :company, :class => :person
457
- end
458
- end
459
- }.should raise_error(Exception, /indicates a different counterpart object_type/)
460
- end
461
-
462
520
  it "should error on invalid :class values" do
463
521
  lambda {
464
522
  module Mod
465
- class SurrogateId
523
+ class Surrogate
466
524
  has_one :Name, :class => 3
467
525
  end
468
526
  end
@@ -472,7 +530,7 @@ describe "A Constellation instance" do
472
530
  it "should error on misleading :class values" do
473
531
  lambda {
474
532
  module Mod
475
- class SurrogateId
533
+ class Surrogate
476
534
  has_one :Name, :class => Extra
477
535
  end
478
536
  end
@@ -496,12 +554,24 @@ describe "A Constellation instance" do
496
554
  }.should_not raise_error
497
555
  end
498
556
 
499
- it "should allow cross-constellation assignment" do
557
+ it "should copy values during cross-constellation assignment" do
500
558
  c = @constellation.Company("foo", :auto_counter_val => 23)
559
+
560
+ # Now make a new constellation and use the above values to initialise new instances
561
+ p = nil
501
562
  lambda {
502
563
  c2 = ActiveFacts::API::Constellation.new(Mod)
503
564
  p = c2.Person('Fred', 'Smith', :auto_counter_val => :new)
504
- p.employer = [c, {:auto_counter_val => :new}]
565
+ p.employer = [ c.name, {:auto_counter_val => c.auto_counter_val}]
505
566
  }.should_not raise_error
567
+ c.auto_counter_val.should_not === p.employer.auto_counter_val
568
+ c.auto_counter_val.should_not == p.employer.auto_counter_val
569
+ c.auto_counter_val.to_s.should == p.employer.auto_counter_val.to_s
570
+ p.employer.should_not === c
571
+
572
+ lambda {
573
+ # Disallowed because it re-assigns the auto_counter_val identification value
574
+ p.employer = [ "foo", {:auto_counter_val => :new}]
575
+ }.should raise_error
506
576
  end
507
577
  end