activefacts-api 0.8.12 → 0.9.1
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.
- data/.rspec +1 -0
- data/.travis.yml +9 -0
- data/Gemfile +14 -0
- data/Rakefile +21 -9
- data/VERSION +1 -1
- data/activefacts-api.gemspec +31 -12
- data/lib/activefacts/api.rb +1 -0
- data/lib/activefacts/api/constellation.rb +3 -1
- data/lib/activefacts/api/entity.rb +74 -29
- data/lib/activefacts/api/exceptions.rb +17 -0
- data/lib/activefacts/api/instance.rb +96 -1
- data/lib/activefacts/api/instance_index.rb +35 -37
- data/lib/activefacts/api/numeric.rb +62 -56
- data/lib/activefacts/api/object_type.rb +49 -23
- data/lib/activefacts/api/role.rb +8 -2
- data/lib/activefacts/api/role_values.rb +8 -26
- data/lib/activefacts/api/standard_types.rb +2 -17
- data/lib/activefacts/api/vocabulary.rb +1 -1
- data/lib/activefacts/tracer.rb +13 -1
- data/spec/{constellation_spec.rb → constellation/constellation_spec.rb} +127 -56
- data/spec/constellation/instance_index_spec.rb +90 -0
- data/spec/{instance_spec.rb → constellation/instance_spec.rb} +48 -42
- data/spec/{role_values_spec.rb → fact_type/role_values_spec.rb} +28 -19
- data/spec/{roles_spec.rb → fact_type/roles_spec.rb} +55 -21
- data/spec/fixtures/tax.rb +45 -0
- data/spec/{identification_spec.rb → identification_scheme/identification_spec.rb} +88 -74
- data/spec/identification_scheme/identity_change_spec.rb +118 -0
- data/spec/identification_scheme/identity_supertype_change_spec.rb +63 -0
- data/spec/{entity_type_spec.rb → object_type/entity_type/entity_type_spec.rb} +2 -4
- data/spec/object_type/entity_type/multipart_identification_spec.rb +77 -0
- data/spec/{autocounter_spec.rb → object_type/value_type/autocounter_spec.rb} +2 -4
- data/spec/object_type/value_type/numeric_spec.rb +63 -0
- data/spec/{value_type_spec.rb → object_type/value_type/value_type_spec.rb} +10 -14
- data/spec/simplecov_helper.rb +8 -0
- data/spec/spec_helper.rb +1 -1
- metadata +100 -19
@@ -2,8 +2,6 @@
|
|
2
2
|
# ActiveFacts tests: Value instances in the Runtime API
|
3
3
|
# Copyright (c) 2008 Clifford Heath. Read the LICENSE file.
|
4
4
|
#
|
5
|
-
require 'rspec'
|
6
|
-
require 'activefacts/api'
|
7
5
|
|
8
6
|
describe "An instance of every type of ObjectType" do
|
9
7
|
before :each do
|
@@ -19,20 +17,20 @@ describe "An instance of every type of ObjectType" do
|
|
19
17
|
t.name.snakecase
|
20
18
|
end
|
21
19
|
@role_names = @base_type_roles.inject([]) {|a, t|
|
22
|
-
a << :"#{t}
|
20
|
+
a << :"#{t}_val"
|
23
21
|
} +
|
24
22
|
@base_type_roles.inject([]) {|a, t|
|
25
|
-
a << :"#{t}
|
23
|
+
a << :"#{t}_sub_val"
|
26
24
|
}
|
27
25
|
|
28
26
|
# Create a value type and a subtype of that value type for each base type:
|
29
27
|
@base_types.each do |base_type|
|
30
|
-
|
31
|
-
class #{base_type.name}
|
28
|
+
Mod.module_eval <<-END
|
29
|
+
class #{base_type.name}Val < #{base_type.name}
|
32
30
|
value_type
|
33
31
|
end
|
34
32
|
|
35
|
-
class #{base_type.name}
|
33
|
+
class #{base_type.name}SubVal < #{base_type.name}Val
|
36
34
|
# Note no new "value_type" is required here, it comes through inheritance
|
37
35
|
end
|
38
36
|
END
|
@@ -44,11 +42,11 @@ describe "An instance of every type of ObjectType" do
|
|
44
42
|
@base_types.each do |base_type|
|
45
43
|
code = <<-END
|
46
44
|
class TestBy#{base_type.name}
|
47
|
-
identified_by :#{base_type.name.snakecase}
|
45
|
+
identified_by :#{base_type.name.snakecase}_val#{
|
48
46
|
@role_names.map do |role_name|
|
49
47
|
%Q{
|
50
|
-
|
51
|
-
|
48
|
+
#{
|
49
|
+
(role_name == (base_type.name.snakecase+'_val').to_sym ? "one_to_one :#{role_name}, :mandatory => true" : "has_one :#{role_name}")
|
52
50
|
}
|
53
51
|
one_to_one :one_#{role_name}, :class => #{role_name.to_s.camelcase}}
|
54
52
|
end*""
|
@@ -56,10 +54,12 @@ describe "An instance of every type of ObjectType" do
|
|
56
54
|
end
|
57
55
|
|
58
56
|
class TestBy#{base_type.name}Sub
|
59
|
-
identified_by :#{base_type.name.snakecase}
|
57
|
+
identified_by :#{base_type.name.snakecase}_sub_val#{
|
60
58
|
@role_names.map do |role_name|
|
61
59
|
%Q{
|
62
|
-
|
60
|
+
#{
|
61
|
+
(role_name == (base_type.name.snakecase+'_sub_val').to_sym ? "one_to_one :#{role_name}" : "has_one :#{role_name}")
|
62
|
+
}
|
63
63
|
one_to_one :one_#{role_name}, :class => #{role_name.to_s.camelcase}}
|
64
64
|
end*""
|
65
65
|
}
|
@@ -74,7 +74,7 @@ describe "An instance of every type of ObjectType" do
|
|
74
74
|
one_to_one :test_by_#{base_type.name.snakecase}
|
75
75
|
end
|
76
76
|
END
|
77
|
-
|
77
|
+
Mod.module_eval code
|
78
78
|
end
|
79
79
|
end
|
80
80
|
|
@@ -89,29 +89,29 @@ describe "An instance of every type of ObjectType" do
|
|
89
89
|
@decimal = BigDecimal.new('98765432109876543210')
|
90
90
|
|
91
91
|
# Value Type instances
|
92
|
-
@int_value = Mod::
|
93
|
-
@real_value = Mod::
|
94
|
-
@auto_counter_value = Mod::
|
95
|
-
@new_auto_counter_value = Mod::
|
96
|
-
@string_value = Mod::
|
97
|
-
@date_value = Mod::
|
92
|
+
@int_value = Mod::IntVal.new(1)
|
93
|
+
@real_value = Mod::RealVal.new(1.0)
|
94
|
+
@auto_counter_value = Mod::AutoCounterVal.new(1)
|
95
|
+
@new_auto_counter_value = Mod::AutoCounterVal.new(:new)
|
96
|
+
@string_value = Mod::StringVal.new("one")
|
97
|
+
@date_value = Mod::DateVal.new(2008, 04, 20)
|
98
98
|
# Parse the date:
|
99
|
-
@date_value = Mod::
|
99
|
+
@date_value = Mod::DateVal.new '2nd Nov 2001'
|
100
100
|
d = ::Date.civil(2008, 04, 20)
|
101
|
-
@date_time_value = Mod::
|
101
|
+
@date_time_value = Mod::DateTimeVal.new d # 2008, 04, 20, 10, 28, 14
|
102
102
|
# This next isn't in the same pattern; it makes a Decimal from a BigDecimal rather than a String (coverage reasons)
|
103
|
-
@decimal_value = Mod::
|
103
|
+
@decimal_value = Mod::DecimalVal.new(BigDecimal.new('98765432109876543210'))
|
104
104
|
|
105
105
|
# Value SubType instances
|
106
|
-
@int_sub_value = Mod::
|
107
|
-
@real_sub_value = Mod::
|
108
|
-
@auto_counter_sub_value = Mod::
|
109
|
-
@auto_counter_sub_value_new = Mod::
|
110
|
-
@string_sub_value = Mod::
|
111
|
-
@date_sub_value = Mod::
|
112
|
-
@date_time_sub_value = Mod::
|
106
|
+
@int_sub_value = Mod::IntSubVal.new(4)
|
107
|
+
@real_sub_value = Mod::RealSubVal.new(4.0)
|
108
|
+
@auto_counter_sub_value = Mod::AutoCounterSubVal.new(4)
|
109
|
+
@auto_counter_sub_value_new = Mod::AutoCounterSubVal.new(:new)
|
110
|
+
@string_sub_value = Mod::StringSubVal.new("five")
|
111
|
+
@date_sub_value = Mod::DateSubVal.new(2008, 04, 25)
|
112
|
+
@date_time_sub_value = Mod::DateTimeSubVal.new(::DateTime.civil(2008, 04, 26, 10, 28, 14))
|
113
113
|
# This next isn't in the same pattern; it makes a Decimal from a BigNum rather than a String (coverage reasons)
|
114
|
-
@decimal_sub_value = Mod::
|
114
|
+
@decimal_sub_value = Mod::DecimalSubVal.new(98765432109876543210)
|
115
115
|
|
116
116
|
# Entities identified by Value Type, SubType and Entity-by-value-type instances
|
117
117
|
@test_by_int = Mod::TestByInt.new(2)
|
@@ -164,10 +164,10 @@ describe "An instance of every type of ObjectType" do
|
|
164
164
|
String, Date, DateTime, Decimal
|
165
165
|
]
|
166
166
|
@value_types = [
|
167
|
-
Mod::
|
168
|
-
Mod::
|
169
|
-
Mod::
|
170
|
-
Mod::
|
167
|
+
Mod::IntVal, Mod::RealVal, Mod::AutoCounterVal, Mod::AutoCounterVal,
|
168
|
+
Mod::StringVal, Mod::DateVal, Mod::DateTimeVal, Mod::DecimalVal,
|
169
|
+
Mod::IntSubVal, Mod::RealSubVal, Mod::AutoCounterSubVal, Mod::AutoCounterSubVal,
|
170
|
+
Mod::StringSubVal, Mod::DateSubVal, Mod::DateTimeSubVal, Mod::DecimalSubVal,
|
171
171
|
]
|
172
172
|
@value_instances = [
|
173
173
|
@int_value, @real_value, @auto_counter_value, @new_auto_counter_value,
|
@@ -226,11 +226,11 @@ describe "An instance of every type of ObjectType" do
|
|
226
226
|
'98765432109876543211'
|
227
227
|
]
|
228
228
|
@subtype_role_instances = [
|
229
|
-
Mod::
|
230
|
-
Mod::
|
231
|
-
Mod::
|
232
|
-
Mod::
|
233
|
-
Mod::
|
229
|
+
Mod::IntSubVal.new(6), Mod::RealSubVal.new(6.0),
|
230
|
+
Mod::AutoCounterSubVal.new(:new), Mod::AutoCounterSubVal.new(8),
|
231
|
+
Mod::StringSubVal.new("seven"),
|
232
|
+
Mod::DateSubVal.new(2008,4,29), Mod::DateTimeSubVal.new(2008,4,30,10,28,16),
|
233
|
+
Mod::DecimalSubVal.new('98765432109876543210'),
|
234
234
|
]
|
235
235
|
end
|
236
236
|
|
@@ -308,7 +308,7 @@ describe "An instance of every type of ObjectType" do
|
|
308
308
|
|
309
309
|
it "should disallow treating an unresolved AutoCounter as an integer" do
|
310
310
|
c = ActiveFacts::API::Constellation.new(Mod)
|
311
|
-
a = c.
|
311
|
+
a = c.AutoCounterVal(:new)
|
312
312
|
lambda {
|
313
313
|
b = 2 + a
|
314
314
|
}.should raise_error
|
@@ -322,7 +322,7 @@ describe "An instance of every type of ObjectType" do
|
|
322
322
|
it "should complain when not enough identifying values are provided for an entity" do
|
323
323
|
c = ActiveFacts::API::Constellation.new(Mod)
|
324
324
|
lambda {
|
325
|
-
c.TestByInt(:
|
325
|
+
c.TestByInt(:int_val => nil)
|
326
326
|
}.should raise_error
|
327
327
|
end
|
328
328
|
|
@@ -333,6 +333,13 @@ describe "An instance of every type of ObjectType" do
|
|
333
333
|
}.should raise_error
|
334
334
|
end
|
335
335
|
|
336
|
+
it "should complain when wrong type is used for an entity" do
|
337
|
+
c = ActiveFacts::API::Constellation.new(Mod)
|
338
|
+
lambda {
|
339
|
+
c.TestByInt("Not an Int")
|
340
|
+
}.should raise_error
|
341
|
+
end
|
342
|
+
|
336
343
|
it "should handle a non-mandatory missing identifying role" do
|
337
344
|
module Mod2
|
338
345
|
class Word
|
@@ -380,5 +387,4 @@ describe "An instance of every type of ObjectType" do
|
|
380
387
|
f.is_ok.should == false
|
381
388
|
s.is_ok.should == true
|
382
389
|
end
|
383
|
-
|
384
390
|
end
|
@@ -2,8 +2,6 @@
|
|
2
2
|
# ActiveFacts tests: Value instances in the Runtime API
|
3
3
|
# Copyright (c) 2008 Clifford Heath. Read the LICENSE file.
|
4
4
|
#
|
5
|
-
require 'rspec'
|
6
|
-
require 'activefacts/api'
|
7
5
|
|
8
6
|
VALUE_TYPES = Int, Real, AutoCounter, String, Date, DateTime, Decimal
|
9
7
|
RAW_VALUES = [2, 3.0, 4, "5", Date.new(2008, 04, 20), DateTime.new(2008, 04, 20, 10, 28, 14)]
|
@@ -22,20 +20,20 @@ module TestValueTypesModule
|
|
22
20
|
value_type
|
23
21
|
end
|
24
22
|
BASE_VALUE_TYPE_ROLE_NAMES = VALUE_TYPES.map { |base_type| base_type.name.snakecase }
|
25
|
-
VALUE_TYPE_ROLE_NAMES = BASE_VALUE_TYPE_ROLE_NAMES.map { |n| [ :"#{n}
|
23
|
+
VALUE_TYPE_ROLE_NAMES = BASE_VALUE_TYPE_ROLE_NAMES.map { |n| [ :"#{n}_val", :"#{n}_sub_val" ] }.flatten
|
26
24
|
VALUE_TYPES.map do |value_type|
|
27
25
|
code = <<-END
|
28
|
-
class #{value_type.name}
|
26
|
+
class #{value_type.name}Val < #{value_type.name}
|
29
27
|
value_type
|
30
28
|
end
|
31
29
|
|
32
|
-
class #{value_type.name}
|
30
|
+
class #{value_type.name}ValSub < #{value_type.name}Val
|
33
31
|
# Note no new "value_type" is required here, it comes through inheritance
|
34
32
|
end
|
35
33
|
|
36
34
|
class #{value_type.name}Entity
|
37
|
-
identified_by :#{identifying_role_name = "id_#{value_type.name.snakecase}
|
38
|
-
|
35
|
+
identified_by :#{identifying_role_name = "id_#{value_type.name.snakecase}_val"}
|
36
|
+
one_to_one :#{identifying_role_name}, :class => #{value_type.name}Val
|
39
37
|
end
|
40
38
|
|
41
39
|
class #{value_type.name}EntitySub < #{value_type.name}Entity
|
@@ -43,13 +41,13 @@ module TestValueTypesModule
|
|
43
41
|
|
44
42
|
class #{value_type.name}EntitySubCtr < #{value_type.name}Entity
|
45
43
|
identified_by :counter
|
46
|
-
|
44
|
+
one_to_one :counter, :class => "ESCID"
|
47
45
|
end
|
48
46
|
|
49
|
-
VALUE_SUB_FOR_VALUE[#{value_type.name}
|
47
|
+
VALUE_SUB_FOR_VALUE[#{value_type.name}Val] = #{value_type.name}ValSub
|
50
48
|
classes = [
|
51
|
-
#{value_type.name}
|
52
|
-
#{value_type.name}
|
49
|
+
#{value_type.name}Val,
|
50
|
+
#{value_type.name}ValSub,
|
53
51
|
#{value_type.name}Entity,
|
54
52
|
#{value_type.name}EntitySub,
|
55
53
|
#{value_type.name}EntitySubCtr,
|
@@ -57,13 +55,13 @@ module TestValueTypesModule
|
|
57
55
|
OBJECT_TYPES.concat(classes)
|
58
56
|
classes.each { |klass| VALUE_TYPE_FOR_OBJECT_TYPE[klass] = value_type }
|
59
57
|
END
|
60
|
-
|
58
|
+
TestValueTypesModule.module_eval code
|
61
59
|
end
|
62
60
|
OBJECT_TYPE_NAMES = OBJECT_TYPES.map{|object_type| object_type.basename}
|
63
61
|
|
64
62
|
class Octopus
|
65
63
|
identified_by :zero
|
66
|
-
|
64
|
+
one_to_one :zero, :class => IntVal
|
67
65
|
maybe :has_a_unary
|
68
66
|
OBJECT_TYPE_NAMES.each do |object_type_name|
|
69
67
|
has_one object_type_name.snakecase.to_sym
|
@@ -94,7 +92,7 @@ end
|
|
94
92
|
describe "Object type role values" do
|
95
93
|
def object_identifying_parameters object_type_name, value
|
96
94
|
if object_type_name =~ /^(.*)EntitySubCtr$/
|
97
|
-
[{ :"id_#{$1.snakecase}
|
95
|
+
[{ :"id_#{$1.snakecase}_val" => value, :counter => :new}]
|
98
96
|
else
|
99
97
|
[value]
|
100
98
|
end
|
@@ -110,7 +108,7 @@ describe "Object type role values" do
|
|
110
108
|
it "should allow instantiation of a bare #{object_type_name}" do
|
111
109
|
object_identifying_parameters =
|
112
110
|
if object_type_name =~ /^(.*)EntitySubCtr$/
|
113
|
-
[{ :"id_#{$1.snakecase}
|
111
|
+
[{ :"id_#{$1.snakecase}_val" => values[0], :counter => :new}]
|
114
112
|
else
|
115
113
|
[values[0]]
|
116
114
|
end
|
@@ -275,7 +273,7 @@ describe "Object type role values" do
|
|
275
273
|
reflection = assigned.send(role.counterpart.name)
|
276
274
|
reflection.should_not be_empty
|
277
275
|
reflection.size.should == 1
|
278
|
-
reflection.should
|
276
|
+
reflection.should include @object
|
279
277
|
end
|
280
278
|
|
281
279
|
# Update the role to the second value:
|
@@ -299,7 +297,7 @@ describe "Object type role values" do
|
|
299
297
|
# The counterpart should include us in its RoleValues
|
300
298
|
reflection2 = assigned2.send(role.counterpart.name)
|
301
299
|
reflection2.size.should == 1
|
302
|
-
reflection2.should
|
300
|
+
reflection2.should include @object
|
303
301
|
end
|
304
302
|
|
305
303
|
# Nullify the role
|
@@ -388,12 +386,23 @@ describe "Object type role values" do
|
|
388
386
|
|
389
387
|
it "should support each" do
|
390
388
|
count = 0
|
391
|
-
@role_values.each
|
389
|
+
@role_values.each do |v, *a|
|
390
|
+
a.size.should == 0
|
391
|
+
v.should_not be_nil
|
392
|
+
count += 1
|
393
|
+
end
|
392
394
|
count.should == 1
|
393
395
|
end
|
394
396
|
|
395
397
|
it "should support detect" do
|
396
|
-
|
398
|
+
count = 0
|
399
|
+
@role_values.detect do |v, *a|
|
400
|
+
a.size.should == 0
|
401
|
+
v.should_not be_nil
|
402
|
+
count += 1
|
403
|
+
false
|
404
|
+
end
|
405
|
+
count.should == 1
|
397
406
|
end
|
398
407
|
|
399
408
|
it "should verbalise" do
|
@@ -2,19 +2,21 @@
|
|
2
2
|
# ActiveFacts tests: Roles of object_type classes in the Runtime API
|
3
3
|
# Copyright (c) 2008 Clifford Heath. Read the LICENSE file.
|
4
4
|
#
|
5
|
-
require 'rspec'
|
6
|
-
require 'activefacts/api'
|
7
5
|
|
8
6
|
describe "Roles" do
|
9
7
|
before :each do
|
10
8
|
Object.send :remove_const, :Mod if Object.const_defined?("Mod")
|
11
9
|
module Mod
|
12
10
|
class Name < String
|
13
|
-
value_type :length => 40, :scale => 0, :restrict => /^[A-Z][a-
|
11
|
+
value_type :length => 40, :scale => 0, :restrict => /^[A-Z][a-z0-9]*/
|
12
|
+
end
|
13
|
+
class Identifier
|
14
|
+
identified_by :name
|
15
|
+
one_to_one :name
|
14
16
|
end
|
15
17
|
class LegalEntity
|
16
18
|
identified_by :name
|
17
|
-
|
19
|
+
one_to_one :name
|
18
20
|
end
|
19
21
|
class Contract
|
20
22
|
identified_by :first, :second
|
@@ -30,6 +32,11 @@ describe "Roles" do
|
|
30
32
|
alias :given= :name=
|
31
33
|
has_one :related_to, :class => LegalEntity
|
32
34
|
end
|
35
|
+
class Employee
|
36
|
+
identified_by :name
|
37
|
+
one_to_one :identifier
|
38
|
+
one_to_one :name
|
39
|
+
end
|
33
40
|
end
|
34
41
|
# print "object_type: "; p Mod.object_type
|
35
42
|
end
|
@@ -116,10 +123,10 @@ describe "Roles" do
|
|
116
123
|
le = Mod::LegalEntity.new(foo)
|
117
124
|
le.respond_to?(:name).should be_true
|
118
125
|
name = le.name
|
119
|
-
name.respond_to?(:
|
126
|
+
name.respond_to?(:legal_entity).should be_true
|
120
127
|
|
121
128
|
#pending
|
122
|
-
|
129
|
+
[name.legal_entity].should === [le]
|
123
130
|
end
|
124
131
|
|
125
132
|
it "should instantiate subclasses sensibly" do
|
@@ -127,7 +134,7 @@ describe "Roles" do
|
|
127
134
|
bloggs = c.LegalEntity("Bloggs & Co")
|
128
135
|
p = c.Person("Fred", "Bloggs")
|
129
136
|
p.related_to = "Bloggs & Co"
|
130
|
-
p.related_to.should
|
137
|
+
p.related_to.should be_an_instance_of Mod::LegalEntity
|
131
138
|
p.related_to.should == bloggs
|
132
139
|
|
133
140
|
# REVISIT: The raw instance doesn't override == to compare itself to a RoleProxy unfortunately...
|
@@ -136,28 +143,55 @@ describe "Roles" do
|
|
136
143
|
end
|
137
144
|
|
138
145
|
it "should forward missing methods on the role proxies" do
|
146
|
+
c = ActiveFacts::API::Constellation.new(Mod)
|
147
|
+
p = c.Person("Fred", "Bloggs")
|
148
|
+
lambda {p.family.foo}.should raise_error(NoMethodError)
|
149
|
+
end
|
150
|
+
|
151
|
+
it "should forward re-raise exceptions from missing methods on the role proxies" do
|
139
152
|
c = ActiveFacts::API::Constellation.new(Mod)
|
140
153
|
p = c.Person("Fred", "Bloggs")
|
154
|
+
class String
|
155
|
+
def foo
|
156
|
+
raise "Yawning"
|
157
|
+
end
|
158
|
+
end
|
141
159
|
|
142
|
-
|
143
|
-
lambda {
|
144
|
-
p.family.foo
|
145
|
-
}.should raise_error(NoMethodError)
|
160
|
+
lambda {p.family.foo}.should raise_error(RuntimeError)
|
146
161
|
end
|
147
162
|
|
148
|
-
it "should
|
163
|
+
it "should keep a trace of the overwritten class when changing identification" do
|
164
|
+
pending
|
149
165
|
c = ActiveFacts::API::Constellation.new(Mod)
|
150
|
-
|
166
|
+
e = c.Employee(:identifier => "Project2501")
|
167
|
+
e.overrides_identification_of.is_a?(Mod::LegalEntity).should be_true
|
168
|
+
end
|
151
169
|
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
#end
|
156
|
-
lambda {
|
157
|
-
p.family.barf
|
158
|
-
#}.should raise_error(RuntimeError)
|
159
|
-
}.should raise_error(NoMethodError)
|
170
|
+
it "should be able to import an entity from another constellation" do
|
171
|
+
c1 = ActiveFacts::API::Constellation.new(Mod)
|
172
|
+
c2 = ActiveFacts::API::Constellation.new(Mod)
|
160
173
|
|
174
|
+
e = c1.Employee("PuppetMaster")
|
175
|
+
identifier = c2.Identifier("Project2501", :employee => e)
|
176
|
+
identifier.employee.name.should == "PuppetMaster"
|
161
177
|
end
|
162
178
|
|
179
|
+
it "should be able to import an entity from another constellation which subclass another entity" do
|
180
|
+
pending "fails because identify_role_values get only the current class identifying roles" do
|
181
|
+
# in this example, it returns :identifier, but not :name from LegalEntity
|
182
|
+
module Mod
|
183
|
+
class Person2 < LegalEntity
|
184
|
+
identified_by :identifier
|
185
|
+
one_to_one :identifier
|
186
|
+
end
|
187
|
+
end
|
188
|
+
|
189
|
+
c1 = ActiveFacts::API::Constellation.new(Mod)
|
190
|
+
c2 = ActiveFacts::API::Constellation.new(Mod)
|
191
|
+
|
192
|
+
p = c1.Person2("Person2Name", :identifier => "Project2501")
|
193
|
+
identifier = c2.Identifier("Project2501", :person2 => p)
|
194
|
+
identifier.person2.name.should == "Person2Name"
|
195
|
+
end
|
196
|
+
end
|
163
197
|
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
require 'activefacts/api'
|
2
|
+
|
3
|
+
module Tax
|
4
|
+
|
5
|
+
class Name < String
|
6
|
+
value_type
|
7
|
+
end
|
8
|
+
|
9
|
+
class Person
|
10
|
+
identified_by :name
|
11
|
+
one_to_one :name
|
12
|
+
end
|
13
|
+
|
14
|
+
class Australian < Person
|
15
|
+
end
|
16
|
+
|
17
|
+
class TaxPayer < Person
|
18
|
+
end
|
19
|
+
|
20
|
+
class TFN < Int
|
21
|
+
value_type
|
22
|
+
end
|
23
|
+
|
24
|
+
class AustralianTaxPayer < Australian
|
25
|
+
supertypes TaxPayer
|
26
|
+
identified_by :tfn
|
27
|
+
one_to_one :tfn, :class => TFN # Capitalisation rules!
|
28
|
+
end
|
29
|
+
|
30
|
+
class YearNr < Int
|
31
|
+
value_type
|
32
|
+
end
|
33
|
+
|
34
|
+
class Year
|
35
|
+
identified_by :year_nr
|
36
|
+
one_to_one :year_nr
|
37
|
+
end
|
38
|
+
|
39
|
+
class AustralianTaxReturn
|
40
|
+
identified_by :australian_tax_payer, :year
|
41
|
+
has_one :australian_tax_payer
|
42
|
+
has_one :year
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|