activefacts-api 1.8.1 → 1.8.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,91 +0,0 @@
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_c
25
- one_to_one :value_c, :class => ValueB
26
- end
27
-
28
- class EntityD < EntityA
29
- has_one :value_d, :class => ValueB
30
- end
31
-
32
- class EntityC < EntityB
33
- supertypes EntityD
34
- end
35
- end
36
-
37
- @constellation = ActiveFacts::API::Constellation.new(Mod)
38
- @a = @constellation.EntityA(:value_a => 1, :value_b => 'a')
39
- @b = @constellation.EntityB(:value_a => 12, :value_b => 'ab', :value_c => 'abc')
40
- @c = @constellation.EntityC(:value_a => 123, :value_b => 'abc1', :value_c => 'abc2', :value_d => 'abcd')
41
- end
42
-
43
- it "should index an instance under its own class" do
44
- @constellation.instances[Mod::EntityC].size.should == 1
45
- end
46
-
47
- it "should index instances of subtypes" do
48
- @constellation.instances[Mod::EntityA].size.should == 3
49
- @constellation.instances[Mod::EntityB].size.should == 2
50
- @constellation.instances[Mod::EntityD].size.should == 1
51
- end
52
-
53
- describe "#flatten_key" do
54
- it "should use identifying role values when using an entity type" do
55
- @constellation.EntityA[@a.identifying_role_values].should == @a
56
- end
57
-
58
- it "should recursively try to use identifying role values within an array" do
59
- value_b = @constellation.ValueB('abc2')
60
- @constellation.EntityC[[value_b]].should == @c
61
- end
62
-
63
- it "should use the value as-is if it doesn't have identifying role values" do
64
- @constellation.EntityC[%w{abc2}].should == @c
65
- end
66
- end
67
-
68
- describe "should iterate over instances" do
69
- [:each, :map, :detect].each do |api|
70
- it "Should pass the key and object to #{api}" do
71
- a_index = @constellation.EntityA
72
- a_index.size.should == 3
73
- a_index.send(api) do |k, v, *a|
74
- [[1], [12], [123]].should include(k)
75
- [@a, @b, @c].should include(v)
76
- a.size.should == 0
77
- false
78
- end
79
-
80
- b_index = @constellation.EntityB
81
- b_index.size.should == 2
82
- b_index.send(api) do |k, v, *a|
83
- [['ab'], ['abc'], ['abc2']].should include(k)
84
- [@b, @c].should include v
85
- a.size.should == 0
86
- false
87
- end
88
- end
89
- end
90
- end
91
- end
@@ -1,441 +0,0 @@
1
- #
2
- # ActiveFacts tests: Value instances in the Runtime API
3
- # Copyright (c) 2008 Clifford Heath. Read the LICENSE file.
4
- #
5
-
6
- describe "An instance of every type of ObjectType" do
7
- before :all do
8
- Object.send :remove_const, :Mod if Object.const_defined?("Mod")
9
- module Mod
10
- # These are the base value types we're going to test:
11
- @base_types = [
12
- Int, Real, AutoCounter, String, Date, DateTime, Decimal, Guid
13
- ]
14
-
15
- # Construct the names of the roles they play:
16
- @base_type_roles = @base_types.map do |t|
17
- t.name.snakecase
18
- end
19
- @role_names = @base_type_roles.inject([]) {|a, t|
20
- a << :"#{t}_val"
21
- } +
22
- @base_type_roles.inject([]) {|a, t|
23
- a << :"#{t}_sub_val"
24
- }
25
-
26
- # Create a value type and a subtype of that value type for each base type:
27
- @base_types.each do |base_type|
28
- Mod.module_eval <<-END
29
- class #{base_type.name}Val < #{base_type.name}
30
- value_type
31
- end
32
-
33
- class #{base_type.name}SubVal < #{base_type.name}Val
34
- # Note no new "value_type" is required here, it comes through inheritance
35
- end
36
- END
37
- end
38
-
39
- # Create a TestByX, TestByXSub, and TestSubByX class for all base types X
40
- # Each class has a has_one and a one_to_one for all roles.
41
- # and is identified by the has_one :x role
42
- @base_types.each do |base_type|
43
- code = <<-END
44
- class TestBy#{base_type.name}
45
- identified_by :#{base_type.name.snakecase}_val#{
46
- @role_names.map do |role_name|
47
- %Q{
48
- #{
49
- (role_name == (base_type.name.snakecase+'_val').to_sym ? "one_to_one :#{role_name}, :mandatory => true" : "has_one :#{role_name}")
50
- }
51
- one_to_one :one_#{role_name}, :class => #{role_name.to_s.camelcase}}
52
- end*""
53
- }
54
- end
55
-
56
- class TestBy#{base_type.name}Sub
57
- identified_by :#{base_type.name.snakecase}_sub_val#{
58
- @role_names.map do |role_name|
59
- %Q{
60
- #{
61
- (role_name == (base_type.name.snakecase+'_sub_val').to_sym ? "one_to_one :#{role_name}" : "has_one :#{role_name}")
62
- }
63
- one_to_one :one_#{role_name}, :class => #{role_name.to_s.camelcase}}
64
- end*""
65
- }
66
- end
67
-
68
- class TestSubBy#{base_type.name} < TestBy#{base_type.name}
69
- # Entity subtypes, inherit identification and all roles
70
- end
71
-
72
- class TestBy#{base_type.name}Entity
73
- identified_by :test_by_#{base_type.name.snakecase}
74
- one_to_one :test_by_#{base_type.name.snakecase}
75
- end
76
- END
77
-
78
- begin
79
- Mod.module_eval code
80
- rescue Exception => e
81
- puts "Failure: #{e}"
82
- puts "Failed on: <<END\n#{code}\nEND"
83
- end
84
- end
85
- end
86
-
87
- @constellation = ActiveFacts::API::Constellation.new(Mod)
88
-
89
- # Simple Values
90
- @int = 0
91
- @real = 0.0
92
- @auto_counter = 0
93
- @new_auto_counter = :new
94
- @string = "zero"
95
- @date = [2008, 04, 19]
96
- @date_time = [2008, 04, 19, 10, 28, 14]
97
- @decimal = BigDecimal.new('98765432109876543210')
98
- @guid = '01234567-89ab-cdef-0123-456789abcdef'
99
-
100
- # Value Type instances
101
- @int_value = @constellation.IntVal(1)
102
- @real_value = @constellation.RealVal(1.0)
103
- @auto_counter_value = @constellation.AutoCounterVal(1)
104
- @new_auto_counter_value = @constellation.AutoCounterVal(:new)
105
- @string_value = @constellation.StringVal("one")
106
- @date_value = @constellation.DateVal(2008, 04, 20)
107
- # Parse the date:
108
- @date_value = @constellation.DateVal('2nd Nov 2001')
109
- d = ::Date.civil(2008, 04, 20)
110
- @date_time_value = Mod::DateTimeVal.civil(2008, 04, 20, 10, 28, 14)
111
- # This next isn't in the same pattern; it makes a Decimal from a BigDecimal rather than a String (coverage reasons)
112
- @decimal_value = @constellation.DecimalVal(BigDecimal.new('98765432109876543210'))
113
- @guid_value = @constellation.GuidVal(:new)
114
- @guid_as_value = @constellation.GuidVal(@guid)
115
-
116
- # Value SubType instances
117
- @int_sub_value = @constellation.IntSubVal(4)
118
- @real_sub_value = @constellation.RealSubVal(4.0)
119
- @auto_counter_sub_value = @constellation.AutoCounterSubVal(4)
120
- @auto_counter_sub_value_new = @constellation.AutoCounterSubVal(:new)
121
- @string_sub_value = @constellation.StringSubVal("five")
122
- @date_sub_value = @constellation.DateSubVal(2008, 04, 25)
123
- @date_time_sub_value = @constellation.DateTimeSubVal(::DateTime.civil(2008, 04, 26, 10, 28, 14))
124
- # This next isn't in the same pattern; it makes a Decimal from a BigNum rather than a String (coverage reasons)
125
- @decimal_sub_value = @constellation.DecimalSubVal(98765432109876543210)
126
- @guid_sub_value = @constellation.GuidSubVal(:new)
127
-
128
- # Entities identified by Value Type, SubType and Entity-by-value-type instances
129
- @test_by_int = @constellation.TestByInt(2)
130
- @test_by_real = @constellation.TestByReal(2.0)
131
- @test_by_auto_counter = @constellation.TestByAutoCounter(2)
132
- @test_by_auto_counter_new = @constellation.TestByAutoCounter(:new)
133
- @test_by_string = @constellation.TestByString("two")
134
- @test_by_date = @constellation.TestByDate(Date.civil(2008,04,28))
135
- #@test_by_date = @constellation.TestByDate(2008,04,28)
136
- # Array packing/unpacking obfuscates the following case
137
- # @test_by_date_time = @constellation.TestByDateTime([2008,04,28,10,28,15])
138
- # Pass an array of values directly to DateTime.civil:
139
- @test_by_date_time = @constellation.TestByDateTime(@date_time_value)
140
- #@test_by_date_time = @constellation.TestByDateTime(DateTime.civil(2008,04,28,10,28,15))
141
- @test_by_decimal = @constellation.TestByDecimal('98765432109876543210')
142
-
143
- @test_by_guid = @constellation.TestByGuid(@guid)
144
- @constellation.TestByGuid[[@guid_as_value]].should_not be_nil
145
-
146
- @test_by_int_sub = @constellation.TestByIntSub(2)
147
- @test_by_real_sub = @constellation.TestByRealSub(5.0)
148
- @test_by_auto_counter_sub = @constellation.TestByAutoCounterSub(6)
149
- @test_by_auto_counter_new_sub = @constellation.TestByAutoCounterSub(:new)
150
- @test_by_string_sub = @constellation.TestByStringSub("six")
151
- @test_by_date_sub = @constellation.TestByDateSub(Date.civil(2008,04,27))
152
- # Array packing/unpacking obfuscates the following case
153
- # @test_by_date_time_sub = @constellation.TestByDateTimeSub([2008,04,29,10,28,15])
154
- # Pass an array of values directly to DateTime.civil:
155
- @test_by_date_time_sub = @constellation.TestByDateTimeSub(@date_time_value)
156
- @test_by_decimal_sub = @constellation.TestByDecimalSub('98765432109876543210')
157
- @test_by_guid_sub = @constellation.TestByGuidSub('01234567-89ab-cdef-0123-456789abcdef')
158
-
159
- @test_by_int_entity = @constellation.TestByIntEntity(@test_by_int)
160
- @test_by_real_entity = @constellation.TestByRealEntity(@test_by_real)
161
- @test_by_auto_counter_entity = @constellation.TestByAutoCounterEntity(@test_by_auto_counter)
162
- @test_by_auto_counter_new_entity = @constellation.TestByAutoCounterEntity(@test_by_auto_counter_new)
163
- @test_by_string_entity = @constellation.TestByStringEntity(@test_by_string)
164
- @test_by_date_entity = @constellation.TestByDateEntity(@test_by_date)
165
- @test_by_date_time_entity = @constellation.TestByDateTimeEntity(@test_by_date_time)
166
- @test_by_decimal_entity = @constellation.TestByDecimalEntity(@test_by_decimal)
167
- @test_by_guid_entity = @constellation.TestByGuidEntity(@test_by_guid)
168
- @constellation.TestByGuidEntity[[@test_by_guid.identifying_role_values]].should_not be_nil
169
-
170
- # Entity subtypes
171
- @test_sub_by_int = @constellation.TestSubByInt(2*2)
172
- @test_sub_by_real = @constellation.TestSubByReal(2.0*2)
173
- @test_sub_by_auto_counter = @constellation.TestSubByAutoCounter(2*2)
174
- @test_sub_by_auto_counter_new = @constellation.TestSubByAutoCounter(:new)
175
- @test_sub_by_string = @constellation.TestSubByString("twotwo")
176
- @test_sub_by_date = @constellation.TestSubByDate(Date.civil(2008,04*2,28))
177
- # Array packing/unpacking obfuscates the following case
178
- # @test_sub_by_date_time = @constellation.TestSubByDateTime([2008,04*2,28,10,28,15])
179
- @test_sub_by_decimal = @constellation.TestSubByDecimal('987654321098765432109')
180
- @test_sub_by_guid = @constellation.TestSubByGuid('01234567-89ab-cdef-0123-456789abcde0')
181
-
182
- # These arrays get zipped together in various ways. Keep them aligned.
183
- @values = [
184
- @int, @real, @auto_counter, @new_auto_counter,
185
- @string, @date, @date_time, @decimal, @guid
186
- ]
187
- @classes = [
188
- Int, Real, AutoCounter, AutoCounter,
189
- String, Date, DateTime, Decimal, Guid
190
- ]
191
- @value_types = [
192
- Mod::IntVal, Mod::RealVal, Mod::AutoCounterVal, Mod::AutoCounterVal,
193
- Mod::StringVal, Mod::DateVal, Mod::DateTimeVal, Mod::DecimalVal,
194
- Mod::GuidVal,
195
- Mod::IntSubVal, Mod::RealSubVal, Mod::AutoCounterSubVal, Mod::AutoCounterSubVal,
196
- Mod::StringSubVal, Mod::DateSubVal, Mod::DateTimeSubVal, Mod::DecimalSubVal,
197
- Mod::GuidSubVal,
198
- ]
199
- @value_instances = [
200
- @int_value, @real_value, @auto_counter_value, @new_auto_counter_value,
201
- @string_value, @date_value, @date_time_value, @decimal_value, @guid_value,
202
- @int_sub_value, @real_sub_value, @auto_counter_sub_value, @auto_counter_sub_value_new,
203
- @string_sub_value, @date_sub_value, @date_time_sub_value, @decimal_sub_value, @guid_sub_value,
204
- @int_value, @real_value, @auto_counter_value, @new_auto_counter_value,
205
- @string_value, @date_value, @date_time_value, @decimal_value, @guid_value,
206
- ]
207
- @entity_types = [
208
- Mod::TestByInt, Mod::TestByReal, Mod::TestByAutoCounter, Mod::TestByAutoCounter,
209
- Mod::TestByString, Mod::TestByDate, Mod::TestByDateTime, Mod::TestByDecimal,
210
- Mod::TestByGuid,
211
- Mod::TestByIntSub, Mod::TestByRealSub, Mod::TestByAutoCounterSub, Mod::TestByAutoCounterSub,
212
- Mod::TestByStringSub, Mod::TestByDateSub, Mod::TestByDateTimeSub, Mod::TestByDecimalSub,
213
- Mod::TestByGuidSub,
214
- Mod::TestSubByInt, Mod::TestSubByReal, Mod::TestSubByAutoCounter, Mod::TestSubByAutoCounter,
215
- Mod::TestSubByString, Mod::TestSubByDate, Mod::TestSubByDateTime, Mod::TestByDecimalEntity,
216
- Mod::TestByGuidEntity,
217
- ]
218
- @entities = [
219
- @test_by_int, @test_by_real, @test_by_auto_counter, @test_by_auto_counter_new,
220
- @test_by_string, @test_by_date, @test_by_date_time, @test_by_decimal,
221
- @test_by_guid,
222
- @test_by_int_sub, @test_by_real_sub, @test_by_auto_counter_sub, @test_by_auto_counter_new_sub,
223
- @test_by_string_sub, @test_by_date_sub, @test_by_date_time_sub, @test_by_decimal_sub,
224
- @test_by_guid_sub,
225
- @test_sub_by_int, @test_sub_by_real, @test_sub_by_auto_counter, @test_sub_by_auto_counter_new,
226
- @test_sub_by_string, @test_sub_by_date, @test_sub_by_date_time, @test_sub_by_decimal,
227
- @test_sub_by_guid,
228
- ].compact
229
- @entities_by_entity = [
230
- @test_by_int_entity,
231
- @test_by_real_entity,
232
- @test_by_auto_counter_entity,
233
- @test_by_auto_counter_new_entity,
234
- @test_by_string_entity,
235
- @test_by_date_entity,
236
- @test_by_date_time_entity,
237
- @test_by_decimal_entity,
238
- @test_by_guid_entity,
239
- ].compact
240
- @entities_by_entity_types = [
241
- Mod::TestByIntEntity, Mod::TestByRealEntity, Mod::TestByAutoCounterEntity, Mod::TestByAutoCounterEntity,
242
- Mod::TestByStringEntity, Mod::TestByDateEntity, Mod::TestByDateTimeEntity, Mod::TestByDecimalEntity,
243
- Mod::TestByGuidEntity,
244
- ]
245
- @test_role_names = [
246
- :int_value, :real_value, :auto_counter_value, :auto_counter_value,
247
- :string_value, :date_value, :date_time_value, :decimal_value,
248
- :guid_value,
249
- :int_sub_value, :real_sub_value, :auto_counter_sub_value, :auto_counter_sub_value,
250
- :string_sub_value, :date_sub_value, :date_time_sub_value, :decimal_sub_value,
251
- :guid_sub_value,
252
- :int_value, :real_value, :auto_counter_value, :auto_counter_value,
253
- :string_value, :date_value, :date_time_value, :decimal_value,
254
- :guid_value,
255
- ]
256
- @role_values = [
257
- 3, 4.0, 5, 6,
258
- "three", Date.civil(2008,4,21), DateTime.civil(2008,4,22,10,28,16),
259
- '98765432109876543210',
260
- '01234567-89ab-cdef-0123-456789abcdef'
261
- ]
262
- @role_alternate_values = [
263
- 4, 5.0, 6, 7,
264
- "four", Date.civil(2009,4,21), DateTime.civil(2009,4,22,10,28,16),
265
- '98765432109876543211',
266
- '01234567-89ab-cdef-0123-456789abcdef'
267
- ]
268
- @subtype_role_instances = [
269
- @constellation.IntSubVal(6), Mod::RealSubVal.new(6.0),
270
- @constellation.AutoCounterSubVal(:new), Mod::AutoCounterSubVal.new(8),
271
- @constellation.StringSubVal("seven"),
272
- @constellation.DateSubVal(2008,4,29), @constellation.DateTimeSubVal(2008,4,30,10,28,16),
273
- @constellation.DecimalSubVal('98765432109876543210'),
274
- @constellation.DecimalSubVal('01234567-89ab-cdef-0123-456789abcdef'),
275
- ]
276
- end
277
-
278
- describe "verbalisation" do
279
- it "if a value type, should verbalise" do
280
- @value_types.each do |value_type|
281
- #puts "#{value_type} verbalises as #{value_type.verbalise}"
282
- value_type.respond_to?(:verbalise).should be true
283
- verbalisation = value_type.verbalise
284
- verbalisation.should =~ %r{\b#{value_type.basename}\b}
285
- verbalisation.should =~ %r{\b#{value_type.superclass.basename}\b}
286
- end
287
- end
288
-
289
- it "if an entity type, should verbalise" do
290
- @entity_types.each do |entity_type|
291
- #puts entity_type.verbalise
292
- entity_type.respond_to?(:verbalise).should be true
293
- verbalisation = entity_type.verbalise
294
- verbalisation.should =~ %r{\b#{entity_type.basename}\b}
295
-
296
- # All identifying roles should be in the verbalisation.
297
- # Strictly this should be the role name, but we don't set names here.
298
- entity_type.identifying_role_names.each do |ir|
299
- role = entity_type.all_role(ir)
300
- role.should_not be_nil
301
- counterpart_object_type = role.counterpart.object_type
302
- verbalisation.should =~ %r{\b#{counterpart_object_type.basename}\b}
303
- end
304
- end
305
- end
306
-
307
- it "should inspect" do
308
- (@value_instances+@entities+@entities_by_entity).each_with_index do |object, i|
309
- begin
310
- object.inspect
311
- rescue Exception => e
312
- puts "FAILED on #{object.class} at #{i}"
313
- raise
314
- end
315
- end
316
- end
317
-
318
- it "if a value, should verbalise" do
319
- @value_instances.each do |value|
320
- #puts value.verbalise
321
- value.respond_to?(:verbalise).should be true
322
- verbalisation = value.verbalise
323
- verbalisation.should =~ %r{\b#{value.class.basename}\b}
324
- end
325
- end
326
-
327
- it "if an entity, should respond to verbalise" do
328
- (@entities+@entities_by_entity).each do |entity|
329
- entity.respond_to?(:verbalise).should be true
330
- verbalisation = entity.verbalise
331
- verbalisation.should =~ %r{\b#{entity.class.basename}\b}
332
- entity.class.identifying_role_names.each do |ir|
333
- role = entity.class.all_role(ir)
334
- role.should_not be_nil
335
- counterpart_object_type = role.counterpart.object_type
336
- verbalisation.should =~ %r{\b#{counterpart_object_type.basename}\b}
337
- end
338
- end
339
- end
340
- end
341
-
342
- it "should respond to constellation" do
343
- (@value_instances+@entities+@entities_by_entity).each do |instance|
344
- next if instance == nil
345
- instance.respond_to?(:constellation).should be true
346
- end
347
- end
348
-
349
- it "should return the module in response to .vocabulary()" do
350
- (@value_types+@entity_types).zip((@value_instances+@entities+@entities_by_entity)).each do |object_type, instance|
351
- next if instance == nil
352
- instance.class.vocabulary.should == Mod
353
- end
354
- end
355
-
356
- it "should disallow treating an unresolved AutoCounter as an integer" do
357
- c = ActiveFacts::API::Constellation.new(Mod)
358
- a = c.AutoCounterVal(:new)
359
- lambda {
360
- b = 2 + a
361
- }.should raise_error(TypeError)
362
- a.assign(3)
363
- lambda {
364
- b = 2 + a
365
- a.to_i
366
- }.should_not raise_error
367
- end
368
-
369
- it "should complain when not enough identifying values are provided for an entity" do
370
- c = ActiveFacts::API::Constellation.new(Mod)
371
- lambda {
372
- c.TestByInt(:int_val => nil)
373
- }.should raise_error(ActiveFacts::API::MissingMandatoryRoleValueException)
374
- end
375
-
376
- it "should complain when too many identifying values are provided for an entity" do
377
- c = ActiveFacts::API::Constellation.new(Mod)
378
- lambda {
379
- c.TestByInt(2, 3)
380
- }.should raise_error(ActiveFacts::API::UnexpectedIdentifyingValueException)
381
- end
382
-
383
- it "should complain when wrong type is used for an entity" do
384
- c = ActiveFacts::API::Constellation.new(Mod)
385
- lambda {
386
- c.TestByInt("Not an Int")
387
- }.should raise_error(ArgumentError)
388
- end
389
-
390
- it "should handle a non-mandatory missing identifying role" do
391
- module Mod2
392
- class Word
393
- identified_by :singular, :plural
394
- has_one :singular, :class => "Spelling", :mandatory => true
395
- has_one :plural, :class => "Spelling"
396
- end
397
- class Spelling < String
398
- value_type
399
- end
400
- end
401
- c = ActiveFacts::API::Constellation.new(Mod2)
402
- s = c.Word('sheep')
403
- f = c.Word('fish', :plural => nil)
404
- a = c.Word('aircraft', nil)
405
- s.plural.should be_nil
406
- f.plural.should be_nil
407
- a.plural.should be_nil
408
- end
409
-
410
- it "should handle a unary as an identifying role" do
411
- module Mod2
412
- class Status
413
- identified_by :is_ok
414
- maybe :is_ok
415
- end
416
- end
417
- c = ActiveFacts::API::Constellation.new(Mod2)
418
-
419
- n = c.Status(:is_ok => nil)
420
- t = c.Status(:is_ok => true)
421
- f = c.Status(:is_ok => false)
422
- s = c.Status(:is_ok => 'foo')
423
- n.is_ok.should == nil
424
- t.is_ok.should == true
425
- f.is_ok.should == false
426
- s.is_ok.should == true
427
-
428
- n.is_ok = nil
429
- t.is_ok = true
430
- f.is_ok = false
431
- s.is_ok = true
432
- n.is_ok.should == nil
433
- t.is_ok.should == true
434
- f.is_ok.should == false
435
- s.is_ok.should == true
436
-
437
- proc { n.is_ok = false }.should raise_error(ActiveFacts::API::DuplicateIdentifyingValueException)
438
- proc { t.is_ok = nil }.should raise_error(ActiveFacts::API::DuplicateIdentifyingValueException)
439
- proc { f.is_ok = true }.should raise_error(ActiveFacts::API::DuplicateIdentifyingValueException)
440
- end
441
- end