activefacts-api 0.8.12 → 0.9.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (36) hide show
  1. data/.rspec +1 -0
  2. data/.travis.yml +9 -0
  3. data/Gemfile +14 -0
  4. data/Rakefile +21 -9
  5. data/VERSION +1 -1
  6. data/activefacts-api.gemspec +31 -12
  7. data/lib/activefacts/api.rb +1 -0
  8. data/lib/activefacts/api/constellation.rb +3 -1
  9. data/lib/activefacts/api/entity.rb +74 -29
  10. data/lib/activefacts/api/exceptions.rb +17 -0
  11. data/lib/activefacts/api/instance.rb +96 -1
  12. data/lib/activefacts/api/instance_index.rb +35 -37
  13. data/lib/activefacts/api/numeric.rb +62 -56
  14. data/lib/activefacts/api/object_type.rb +49 -23
  15. data/lib/activefacts/api/role.rb +8 -2
  16. data/lib/activefacts/api/role_values.rb +8 -26
  17. data/lib/activefacts/api/standard_types.rb +2 -17
  18. data/lib/activefacts/api/vocabulary.rb +1 -1
  19. data/lib/activefacts/tracer.rb +13 -1
  20. data/spec/{constellation_spec.rb → constellation/constellation_spec.rb} +127 -56
  21. data/spec/constellation/instance_index_spec.rb +90 -0
  22. data/spec/{instance_spec.rb → constellation/instance_spec.rb} +48 -42
  23. data/spec/{role_values_spec.rb → fact_type/role_values_spec.rb} +28 -19
  24. data/spec/{roles_spec.rb → fact_type/roles_spec.rb} +55 -21
  25. data/spec/fixtures/tax.rb +45 -0
  26. data/spec/{identification_spec.rb → identification_scheme/identification_spec.rb} +88 -74
  27. data/spec/identification_scheme/identity_change_spec.rb +118 -0
  28. data/spec/identification_scheme/identity_supertype_change_spec.rb +63 -0
  29. data/spec/{entity_type_spec.rb → object_type/entity_type/entity_type_spec.rb} +2 -4
  30. data/spec/object_type/entity_type/multipart_identification_spec.rb +77 -0
  31. data/spec/{autocounter_spec.rb → object_type/value_type/autocounter_spec.rb} +2 -4
  32. data/spec/object_type/value_type/numeric_spec.rb +63 -0
  33. data/spec/{value_type_spec.rb → object_type/value_type/value_type_spec.rb} +10 -14
  34. data/spec/simplecov_helper.rb +8 -0
  35. data/spec/spec_helper.rb +1 -1
  36. metadata +100 -19
@@ -8,6 +8,7 @@
8
8
  # and allow any Class to become an Entity.
9
9
  #
10
10
  require 'date'
11
+ require 'activefacts/api/numeric'
11
12
 
12
13
  module ActiveFacts
13
14
  module API
@@ -20,12 +21,9 @@ module ActiveFacts
20
21
  end
21
22
  end
22
23
  end
23
-
24
- require 'activefacts/api/numeric'
25
-
26
24
  # Add the methods that convert our classes into ObjectType types:
27
25
 
28
- ValueClasses = [String, Date, DateTime, Time, Int, Real, AutoCounter]
26
+ ValueClasses = [String, Date, DateTime, Time, Int, Real, AutoCounter, Decimal]
29
27
  ValueClasses.each{|c|
30
28
  c.send :extend, ActiveFacts::API::ValueClass
31
29
  }
@@ -62,19 +60,6 @@ class Class
62
60
  end
63
61
  end
64
62
 
65
- require 'bigdecimal'
66
- class Decimal < BigDecimal #:nodoc:
67
- extend ActiveFacts::API::ValueClass
68
- # The problem here is you can't pass a BigDecimal to BigDecimal.new. Fix it.
69
- def self.new(v)
70
- if v.is_a?(BigDecimal) || v.is_a?(Bignum)
71
- super(v.to_s)
72
- else
73
- super
74
- end
75
- end
76
- end
77
-
78
63
  # These types are generated on conversion from NORMA's types:
79
64
  class Char < String #:nodoc: # FixedLengthText
80
65
  end
@@ -12,7 +12,7 @@ module ActiveFacts
12
12
  # Vocabulary is a mixin that adds methods to any Module which has any ObjectType classes (ValueType or EntityType).
13
13
  # A Vocabulary knows all the ObjectType classes including forward-referenced ones,
14
14
  # and can resolve the forward references when the class is finally defined.
15
- # Construction of a Constellation requires a Vocabuary as argument.
15
+ # Construction of a Constellation requires a Vocabulary as argument.
16
16
  module Vocabulary
17
17
  # With a parameter, look up an object type by name.
18
18
  # Without, return the hash (keyed by the class' basename) of all object_types in this vocabulary
@@ -25,7 +25,17 @@ module ActiveFacts
25
25
  @stderr.puts "---\nDebugging keys available: #{@available.keys.map{|s| s.to_s}.sort*", "}"
26
26
  }
27
27
  end
28
- require 'ruby-debug' if @keys[:debug]
28
+ if @keys[:debug]
29
+ ['pry', 'debugger', 'ruby-debug'].each do |debugger|
30
+ begin
31
+ require debugger
32
+ puts "Loaded "+debugger
33
+ break
34
+ rescue LoadError
35
+ end
36
+ end
37
+ ::Debugger.start rescue nil
38
+ end
29
39
  end
30
40
  end
31
41
 
@@ -107,3 +117,5 @@ class Object
107
117
  (ActiveFacts.tracer ||= ActiveFacts::Tracer.new).trace(*args, &block)
108
118
  end
109
119
  end
120
+
121
+ trace ''
@@ -3,9 +3,6 @@
3
3
  # Copyright (c) 2008 Clifford Heath. Read the LICENSE file.
4
4
  #
5
5
 
6
- require 'rspec'
7
- require 'activefacts/api'
8
-
9
6
  describe "A Constellation instance" do
10
7
  before :each do
11
8
  Object.send :remove_const, :Mod if Object.const_defined?("Mod")
@@ -16,30 +13,30 @@ describe "A Constellation instance" do
16
13
 
17
14
  # Create a value type and a subtype of that value type for each base type:
18
15
  @base_types.each do |base_type|
19
- eval <<-END
20
- class #{base_type.basename}Value < #{base_type.name}
16
+ Mod.module_eval <<-END
17
+ class #{base_type.basename}Val < #{base_type.name}
21
18
  value_type
22
19
  end
23
20
 
24
- class #{base_type.basename}SubValue < #{base_type.name}Value
21
+ class #{base_type.basename}SubVal < #{base_type.name}Val
25
22
  # Note no new "value_type" is required here, it comes through inheritance
26
23
  end
27
24
  END
28
25
  end
29
26
 
30
- class Name < StringValue
27
+ class Name < StringVal
31
28
  value_type
32
29
  #has_one :attr, Name
33
30
  end
34
31
 
35
32
  class LegalEntity
36
33
  identified_by :name
37
- has_one :name, :mandatory => true
34
+ one_to_one :name, :mandatory => true
38
35
  end
39
36
 
40
37
  class SurrogateId
41
- identified_by :auto_counter_value
42
- has_one :auto_counter_value
38
+ identified_by :auto_counter_val
39
+ one_to_one :auto_counter_val
43
40
  end
44
41
 
45
42
  class Company < LegalEntity
@@ -60,18 +57,18 @@ describe "A Constellation instance" do
60
57
 
61
58
  describe "Vocabulary" do
62
59
  it "should create the constellation" do
63
- Mod.constellation.should be_is_a ActiveFacts::API::Constellation
60
+ Mod.constellation.should be_an_instance_of ActiveFacts::API::Constellation
64
61
  end
65
62
 
66
63
  it "should create the constellation by direct populate" do
67
64
  Mod.populate do
68
65
  Name "foo"
69
- end.should be_is_a ActiveFacts::API::Constellation
66
+ end.should be_an_instance_of ActiveFacts::API::Constellation
70
67
  end
71
68
 
72
69
  it "should verbalise" do
73
70
  s = Mod.verbalise
74
- s.should be_is_a String
71
+ s.should be_an_instance_of String
75
72
  end
76
73
  end
77
74
 
@@ -107,8 +104,8 @@ describe "A Constellation instance" do
107
104
  lambda {
108
105
  name = @constellation.Name("foo")
109
106
  foo = @constellation.LegalEntity("foo")
110
- acme = @constellation.Company("Acme, Inc", :auto_counter_value => :new)
111
- fred_fly = @constellation.Person("fred", "fly", :auto_counter_value => :new)
107
+ acme = @constellation.Company("Acme, Inc", :auto_counter_val => :new)
108
+ fred_fly = @constellation.Person("fred", "fly", :auto_counter_val => :new)
112
109
  }.should_not raise_error
113
110
  name.class.should == Mod::Name
114
111
  name.constellation.should == @constellation
@@ -132,13 +129,13 @@ describe "A Constellation instance" do
132
129
  it "should re-use instances constructed the same way" do
133
130
  name1 = @constellation.Name("foo")
134
131
  foo1 = @constellation.LegalEntity("foo")
135
- acme1 = @constellation.Company("Acme, Inc", :auto_counter_value => :new)
136
- fred_fly1 = @constellation.Person("fred", "fly", :auto_counter_value => :new)
132
+ acme1 = @constellation.Company("Acme, Inc", :auto_counter_val => :new)
133
+ fred_fly1 = @constellation.Person("fred", "fly", :auto_counter_val => :new)
137
134
 
138
135
  name2 = @constellation.Name("foo")
139
136
  foo2 = @constellation.LegalEntity("foo")
140
- acme2 = @constellation.Company("Acme, Inc", :auto_counter_value => :new)
141
- fred_fly2 = @constellation.Person("fred", "fly", :auto_counter_value => :new)
137
+ acme2 = @constellation.Company("Acme, Inc") # , :auto_counter_val => :new)
138
+ fred_fly2 = @constellation.Person("fred", "fly") # , :auto_counter_val => :new)
142
139
 
143
140
  name1.object_id.should == name2.object_id
144
141
  foo1.object_id.should == foo2.object_id
@@ -146,13 +143,23 @@ describe "A Constellation instance" do
146
143
  fred_fly1.object_id.should == fred_fly2.object_id
147
144
  end
148
145
 
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
+
151
+ name2 = @constellation.Name("foo")
152
+ foo2 = @constellation.LegalEntity("foo")
153
+ lambda { @constellation.Company("Acme, Inc", :auto_counter_val => :new) }.should raise_error
154
+ end
155
+
149
156
  it "should support methods to assert instances via the class for that type" do
150
157
  name = foo = acme = fred_fly = nil
151
158
  lambda {
152
159
  name = @constellation.Name.assert("foo")
153
160
  foo = @constellation.LegalEntity.assert("foo")
154
- acme = @constellation.Company.assert("Acme, Inc", :auto_counter_value => :new)
155
- fred_fly = @constellation.Person.assert("fred", "fly", :auto_counter_value => :new)
161
+ acme = @constellation.Company.assert("Acme, Inc", :auto_counter_val => :new)
162
+ fred_fly = @constellation.Person.assert("fred", "fly", :auto_counter_val => :new)
156
163
  }.should_not raise_error
157
164
  name.class.should == Mod::Name
158
165
  name.constellation.should == @constellation
@@ -177,8 +184,8 @@ describe "A Constellation instance" do
177
184
  @constellation.populate do
178
185
  Name("bar")
179
186
  LegalEntity("foo")
180
- Person("Fred", "Nerk", :auto_counter_value => :new)
181
- Company("Acme, Inc", :auto_counter_value => :new)
187
+ Person("Fred", "Nerk", :auto_counter_val => :new)
188
+ Company("Acme, Inc", :auto_counter_val => :new)
182
189
  end
183
190
  @constellation.Name.size.should == 5
184
191
  @constellation.SurrogateId.size.should == 2
@@ -188,29 +195,29 @@ describe "A Constellation instance" do
188
195
  @constellation.populate do
189
196
  Name("bar")
190
197
  LegalEntity("foo")
191
- c = Company("Acme, Inc", :auto_counter_value => :new)
192
- p = Person("Fred", "Nerk", :auto_counter_value => :new, :employer => c)
198
+ c = Company("Acme, Inc", :auto_counter_val => :new)
199
+ p = Person("Fred", "Nerk", :auto_counter_val => :new, :employer => c)
193
200
  p.birth_name = "Nerk"
194
201
  end
195
202
  s = @constellation.verbalise
196
203
  names = s.split(/\n/).grep(/\tEvery /).map{|l| l.sub(/.*Every (.*):$/, '\1')}
197
- expected = ["AutoCounterValue", "Company", "LegalEntity", "Name", "Person", "StringValue", "SurrogateId"]
204
+ expected = ["AutoCounterVal", "Company", "LegalEntity", "Name", "Person", "StringVal", "SurrogateId"]
198
205
  names.sort.should == expected
199
206
  end
200
207
 
201
208
  it "should support string capitalisation functions" do
202
- names = ["Company", "LegalEntity", "Name", "Person", "StringValue", "SurrogateId"]
209
+ names = ["Company", "LegalEntity", "Name", "Person", "StringVal", "SurrogateId"]
203
210
  camelwords = names.map{|n| n.camelwords }
204
- camelwords.should == [["Company"], ["Legal", "Entity"], ["Name"], ["Person"], ["String", "Value"], ["Surrogate", "Id"]]
211
+ camelwords.should == [["Company"], ["Legal", "Entity"], ["Name"], ["Person"], ["String", "Val"], ["Surrogate", "Id"]]
205
212
 
206
213
  snakes = names.map{|n| n.snakecase }
207
- snakes.should == ["company", "legal_entity", "name", "person", "string_value", "surrogate_id"]
214
+ snakes.should == ["company", "legal_entity", "name", "person", "string_val", "surrogate_id"]
208
215
 
209
216
  camelupper = snakes.map{|n| n.camelcase }
210
- camelupper.should == ["Company", "LegalEntity", "Name", "Person", "StringValue", "SurrogateId"]
217
+ camelupper.should == ["Company", "LegalEntity", "Name", "Person", "StringVal", "SurrogateId"]
211
218
 
212
219
  camellower = snakes.map{|n| n.camelcase(:lower) }
213
- camellower.should == ["company", "legalEntity", "name", "person", "stringValue", "surrogateId"]
220
+ camellower.should == ["company", "legalEntity", "name", "person", "stringVal", "surrogateId"]
214
221
  end
215
222
 
216
223
  it "should allow inspection of instance indices" do
@@ -222,9 +229,9 @@ describe "A Constellation instance" do
222
229
  baz = @constellation.Name("baz")
223
230
  @constellation.Name.keys.sort.should == ["baz"]
224
231
 
225
- @constellation.StringValue.keys.sort.should == ["baz"]
226
- @constellation.StringValue.include?(baz).should == baz
227
- @constellation.StringValue.include?("baz").should == baz
232
+ @constellation.StringVal.keys.sort.should == ["baz"]
233
+ @constellation.StringVal.include?(baz).should == baz
234
+ @constellation.StringVal.include?("baz").should == baz
228
235
  end
229
236
 
230
237
  describe "instance indices" do
@@ -245,24 +252,24 @@ describe "A Constellation instance" do
245
252
  name = "Acme, Inc"
246
253
  fred = "Fred"
247
254
  fly = "Fly"
248
- acme = @constellation.Company name, :auto_counter_value => :new
249
- fred_fly = @constellation.Person fred, fly, :auto_counter_value => :new
255
+ acme = @constellation.Company name, :auto_counter_val => :new
256
+ fred_fly = @constellation.Person fred, fly, :auto_counter_val => :new
250
257
 
251
258
  # REVISIT: This should be illegal:
252
- #fred_fly.auto_counter_value = :new
259
+ #fred_fly.auto_counter_val = :new
253
260
 
254
261
  @constellation.Person.keys.sort.should == [[fred, fly]]
255
262
  @constellation.Company.keys.sort.should == [[name]]
256
263
 
257
- @constellation.LegalEntity.keys.sort.should be_include([name])
258
- @constellation.LegalEntity.keys.sort.should be_include([fred])
264
+ @constellation.LegalEntity.keys.sort.should include [name]
265
+ @constellation.LegalEntity.keys.sort.should include [fred]
259
266
 
260
- @constellation.SurrogateId.values.should be_include(acme)
261
- @constellation.SurrogateId.values.should be_include(fred_fly)
267
+ @constellation.SurrogateId.values.should include acme
268
+ @constellation.SurrogateId.values.should include fred_fly
262
269
  end
263
270
 
264
271
  it "should handle one-to-ones correctly" do
265
- person = @constellation.Person "Fred", "Smith", :auto_counter_value => :new, :birth_name => "Nerk"
272
+ person = @constellation.Person "Fred", "Smith", :auto_counter_val => :new, :birth_name => "Nerk"
266
273
 
267
274
  nerk = @constellation.Name["Nerk"]
268
275
  nerk.should_not be_nil
@@ -273,7 +280,7 @@ describe "A Constellation instance" do
273
280
  end
274
281
 
275
282
  it "should allow retraction of instances" do
276
- person = @constellation.Person "Fred", "Smith", :auto_counter_value => :new, :birth_name => "Nerk"
283
+ person = @constellation.Person "Fred", "Smith", :auto_counter_val => :new, :birth_name => "Nerk"
277
284
 
278
285
  @constellation.retract(@constellation.Name("Smith"))
279
286
  @constellation.Name["Smith"].should be_nil
@@ -282,9 +289,14 @@ describe "A Constellation instance" do
282
289
  person.family_name.should be_nil
283
290
  @constellation.retract(@constellation.Name("Fred"))
284
291
  @constellation.Name["Fred"].should be_nil
285
- pending "Retraction of identifiers doesn't de/re-index" do
286
- @constellation.Person.size.should == 0
287
- end
292
+ end
293
+
294
+ it "should retract linked instances (cascading)" do
295
+ @constellation.Person "Fred", "Smith", :auto_counter_val => :new, :birth_name => "Nerk"
296
+ @constellation.Person "George", "Smith", :auto_counter_val => :new, :birth_name => "Patrick"
297
+ @constellation.Person.size.should == 2
298
+ @constellation.retract(@constellation.Name("Smith"))
299
+ @constellation.Person.size.should == 0
288
300
  end
289
301
 
290
302
  it "should fail to recognise references to unresolved forward referenced classes" do
@@ -338,7 +350,7 @@ describe "A Constellation instance" do
338
350
 
339
351
  lambda {
340
352
  module Mod
341
- class IntValue
353
+ class IntVal
342
354
  has_one :thingummy, :class => Outside::Other
343
355
  end
344
356
  end
@@ -377,10 +389,70 @@ describe "A Constellation instance" do
377
389
  class ListedCompany < Company
378
390
  end
379
391
  end
380
- c = @constellation.ListedCompany("foo", :auto_counter_value => 23)
392
+ c = @constellation.ListedCompany("foo", :auto_counter_val => 23)
381
393
  }.should_not raise_error(NameError)
382
394
  end
383
395
 
396
+ it "should be able to attach a new supertype on an entity type to make it a (sub-)subtype" do
397
+ module Mod
398
+ class Dad
399
+ identified_by :name
400
+ end
401
+ class Son < Dad
402
+ identified_by :name
403
+ end
404
+ # the grand son will be linked on the fly
405
+ class GrandSon
406
+ identified_by :name
407
+ end
408
+ end
409
+ Mod::GrandSon.supertypes(Mod::Son)
410
+ Mod::GrandSon.supertypes.should include Mod::Son
411
+ Mod::Son.supertypes.should include Mod::Dad
412
+ end
413
+
414
+ it "should keep information on where the identification came from" do
415
+ module Mod
416
+ class Dad
417
+ identified_by :name
418
+ end
419
+ class Son < Dad
420
+ identified_by :name
421
+ end
422
+ # Note the inheritance.
423
+ class GrandSon < Son
424
+ identified_by :name
425
+ end
426
+ end
427
+
428
+ Mod::Son.identification_inherited_from.should == Mod::Dad
429
+ Mod::Son.identification_inherited_from.should == Mod::Dad
430
+ Mod::GrandSon.identification_inherited_from.should == Mod::Son
431
+ Mod::GrandSon.overrides_identification_of.should == Mod::Dad
432
+ end
433
+
434
+ it "should disallow using a value type as a supertypes for an entity type" do
435
+ lambda {
436
+ module Mod
437
+ class CompanyName
438
+ identified_by :name
439
+ supertypes :name
440
+ end
441
+ end
442
+ }.should raise_error
443
+ end
444
+
445
+ it "should complain when role name and counter part mismatch" do
446
+ lambda {
447
+ module Mod
448
+ class CompanyName
449
+ identified_by :name
450
+ has_one :company, :class => :person
451
+ end
452
+ end
453
+ }.should raise_error(Exception, /indicates a different counterpart object_type/)
454
+ end
455
+
384
456
  it "should error on invalid :class values" do
385
457
  lambda {
386
458
  module Mod
@@ -402,29 +474,28 @@ describe "A Constellation instance" do
402
474
  end
403
475
 
404
476
  it "should allow assert using an object of the same type" do
405
- c = @constellation.Company("foo", :auto_counter_value => 23)
477
+ c = @constellation.Company("foo", :auto_counter_val => 23)
406
478
  c2 = ActiveFacts::API::Constellation.new(Mod)
407
479
  lambda {
408
- c2.Company(c, :auto_counter_value => :new)
480
+ c2.Company(c, :auto_counter_val => :new)
409
481
  }.should_not raise_error
410
482
  c2.Company.keys.should == [["foo"]]
411
483
  end
412
484
 
413
485
  it "should allow cross-constellation construction" do
414
- c = @constellation.Company("foo", :auto_counter_value => 23)
486
+ c = @constellation.Company("foo", :auto_counter_val => 23)
415
487
  lambda {
416
488
  c2 = ActiveFacts::API::Constellation.new(Mod)
417
- c2.Company(c.name, :auto_counter_value => :new)
489
+ c2.Company(c.name, :auto_counter_val => :new)
418
490
  }.should_not raise_error
419
491
  end
420
492
 
421
493
  it "should allow cross-constellation assignment" do
422
- c = @constellation.Company("foo", :auto_counter_value => 23)
494
+ c = @constellation.Company("foo", :auto_counter_val => 23)
423
495
  lambda {
424
496
  c2 = ActiveFacts::API::Constellation.new(Mod)
425
- p = c2.Person('Fred', 'Smith', :auto_counter_value => :new)
426
- p.employer = [c, {:auto_counter_value => :new}]
497
+ p = c2.Person('Fred', 'Smith', :auto_counter_val => :new)
498
+ p.employer = [c, {:auto_counter_val => :new}]
427
499
  }.should_not raise_error
428
500
  end
429
-
430
501
  end
@@ -0,0 +1,90 @@
1
+ #
2
+ # ActiveFacts tests: Value instances in the Runtime API
3
+ # Copyright (c) 2008 Clifford Heath. Read the LICENSE file.
4
+ #
5
+
6
+ describe ActiveFacts::API::InstanceIndex do
7
+ before :all do
8
+ module Mod
9
+ class ValueA < Int
10
+ value_type
11
+ end
12
+
13
+ class ValueB < String
14
+ value_type
15
+ end
16
+
17
+ class EntityA
18
+ identified_by :value_a
19
+ one_to_one :value_a
20
+ has_one :value_b
21
+ end
22
+
23
+ class EntityB < EntityA
24
+ identified_by :value_b
25
+ one_to_one :value_b
26
+ end
27
+
28
+ class EntityD < EntityA
29
+ end
30
+
31
+ class EntityC < EntityB
32
+ supertypes EntityD
33
+ end
34
+ end
35
+
36
+ @constellation = ActiveFacts::API::Constellation.new(Mod)
37
+ @a = @constellation.EntityA(:value_a => 1, :value_b => 'a')
38
+ @b = @constellation.EntityB(:value_a => 12, :value_b => 'ab')
39
+ @c = @constellation.EntityC(:value_a => 123, :value_b => 'abc')
40
+ end
41
+
42
+ it "should index an instance under its own class" do
43
+ @constellation.instances[Mod::EntityC].size.should == 1
44
+ end
45
+
46
+ it "should index instances of subtypes" do
47
+ @constellation.instances[Mod::EntityA].size.should == 3
48
+ @constellation.instances[Mod::EntityB].size.should == 2
49
+ @constellation.instances[Mod::EntityD].size.should == 1
50
+ end
51
+
52
+ describe "#flatten_key" do
53
+ it "should use identifying role values when using an entity type" do
54
+ @constellation.EntityA[@a].should == @a
55
+ end
56
+
57
+ it "should recursively try to use identifying role values within an array" do
58
+ value_b = @constellation.ValueB('abc')
59
+ @constellation.EntityC[[value_b]].should == @c
60
+ end
61
+
62
+ it "should use the value as-is if it doesn't have identifying role values" do
63
+ @constellation.EntityC[%w{abc}].should == @c
64
+ end
65
+ end
66
+
67
+ describe "should iterate over instances" do
68
+ [:each, :map, :detect].each do |api|
69
+ it "Should pass the key and object to #{api}" do
70
+ a_index = @constellation.EntityA
71
+ a_index.size.should == 3
72
+ a_index.send(api) do |k, v, *a|
73
+ [[1], [12], [123]].should include(k)
74
+ [@a, @b, @c].should include(v)
75
+ a.size.should == 0
76
+ false
77
+ end
78
+
79
+ b_index = @constellation.EntityB
80
+ b_index.size.should == 2
81
+ b_index.send(api) do |k, v, *a|
82
+ [['ab'], ['abc']].should include(k)
83
+ [@b, @c].should include v
84
+ a.size.should == 0
85
+ false
86
+ end
87
+ end
88
+ end
89
+ end
90
+ end