activefacts-api 1.8.1 → 1.8.3
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.
- checksums.yaml +4 -4
- data/.gitignore +28 -0
- data/.rspec +0 -1
- data/Gemfile +1 -10
- data/Rakefile +3 -27
- data/VERSION +1 -1
- data/activefacts-api.gemspec +35 -95
- data/lib/activefacts/api/version.rb +5 -0
- data/lib/activefacts/tracer.rb +13 -9
- metadata +23 -68
- data/spec/constellation/constellation_spec.rb +0 -577
- data/spec/constellation/instance_index_spec.rb +0 -91
- data/spec/constellation/instance_spec.rb +0 -441
- data/spec/fact_type/role_values_spec.rb +0 -439
- data/spec/fact_type/roles_spec.rb +0 -283
- data/spec/fixtures/tax.rb +0 -45
- data/spec/identification_scheme/identification_spec.rb +0 -420
- data/spec/identification_scheme/identity_change_spec.rb +0 -119
- data/spec/identification_scheme/identity_supertype_change_spec.rb +0 -63
- data/spec/metadata_spec.rb +0 -267
- data/spec/object_type/entity_type/entity_type_spec.rb +0 -102
- data/spec/object_type/entity_type/multipart_identification_spec.rb +0 -82
- data/spec/object_type/value_type/autocounter_spec.rb +0 -87
- data/spec/object_type/value_type/date_time_spec.rb +0 -38
- data/spec/object_type/value_type/guid_spec.rb +0 -71
- data/spec/object_type/value_type/numeric_spec.rb +0 -63
- data/spec/object_type/value_type/value_type_spec.rb +0 -124
- data/spec/simplecov_helper.rb +0 -9
- data/spec/spec_helper.rb +0 -13
- data/spec/support/reduce_exceptions_helper.rb +0 -29
@@ -1,119 +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
|
-
require 'fixtures/tax'
|
7
|
-
include ActiveFacts::API
|
8
|
-
|
9
|
-
describe "identity" do
|
10
|
-
before :each do
|
11
|
-
@c1 = Constellation.new(Tax)
|
12
|
-
@juliar = "Juliar Gillard"
|
13
|
-
|
14
|
-
@p1 = @c1.Australian(@juliar)
|
15
|
-
end
|
16
|
-
|
17
|
-
it "should be indexed" do
|
18
|
-
@c1.Name.keys.should == [@juliar]
|
19
|
-
@c1.Name.values.should == [@juliar]
|
20
|
-
@c1.Person.keys.should == [[@juliar]]
|
21
|
-
@c1.Person.values.should == [@p1]
|
22
|
-
@c1.Australian.keys.should == [[@juliar]]
|
23
|
-
@c1.Australian.values.should == [@p1]
|
24
|
-
end
|
25
|
-
|
26
|
-
describe "change" do
|
27
|
-
before :each do
|
28
|
-
@tony = "Tony Abbot"
|
29
|
-
@p3 = @c1.AustralianTaxPayer(:tfn => 123, :name => @tony)
|
30
|
-
|
31
|
-
@r1 = @c1.AustralianTaxReturn(@p3, 2010)
|
32
|
-
@c1.AustralianTaxReturn.keys.should == [[[123], [2010]]]
|
33
|
-
@c1.AustralianTaxReturn.values.should == [@r1]
|
34
|
-
|
35
|
-
@c1.Name.keys.should =~ [@juliar, @tony]
|
36
|
-
@c1.Name.values.should =~ [@juliar, @tony]
|
37
|
-
@c1.Person.keys.should =~ [[@juliar], [@tony]]
|
38
|
-
@c1.Person.values.should =~ [@p1, @p3]
|
39
|
-
@c1.Australian.keys.should =~ [[@juliar], [@tony]]
|
40
|
-
@c1.Australian.values.should =~ [@p1, @p3]
|
41
|
-
@c1.AustralianTaxPayer.keys.should =~ [[123]]
|
42
|
-
@c1.AustralianTaxPayer.values.should =~ [@p3]
|
43
|
-
end
|
44
|
-
|
45
|
-
describe "that implies change of subtype" do
|
46
|
-
before :each do
|
47
|
-
@p2 = nil
|
48
|
-
@change = proc {
|
49
|
-
@p2 = @c1.AustralianTaxPayer(:tfn => 789, :name => "Juliar Gillard")
|
50
|
-
}
|
51
|
-
end
|
52
|
-
|
53
|
-
it "should be denied" do
|
54
|
-
@change.should raise_error(TypeMigrationException)
|
55
|
-
end
|
56
|
-
|
57
|
-
it "should not change instance subtype" do
|
58
|
-
@p1.class.should == Tax::Australian
|
59
|
-
end
|
60
|
-
|
61
|
-
it "should have no side-effects" do
|
62
|
-
begin
|
63
|
-
@change.call
|
64
|
-
rescue TypeMigrationException => e
|
65
|
-
# Now check that no unexpected change occurred
|
66
|
-
end
|
67
|
-
|
68
|
-
@p2.should be_nil
|
69
|
-
@c1.Name.values.should =~ [@juliar, @tony]
|
70
|
-
@c1.Name.keys.should =~ [@juliar, @tony]
|
71
|
-
@c1.TFN.keys.should =~ [123]
|
72
|
-
@c1.Person.values.should =~ [@p1, @p3]
|
73
|
-
@c1.Person.keys.should =~ [[@juliar],[@tony]]
|
74
|
-
@c1.Australian.values.should =~ [@p1, @p3]
|
75
|
-
end
|
76
|
-
|
77
|
-
it "should have no side-effects (retracting values which shouldn't)" do
|
78
|
-
@p2_tfn = @c1.TFN(789)
|
79
|
-
begin
|
80
|
-
@change.call
|
81
|
-
rescue TypeMigrationException => e
|
82
|
-
end
|
83
|
-
|
84
|
-
@c1.TFN.keys.should =~ [123, 789]
|
85
|
-
end
|
86
|
-
end
|
87
|
-
|
88
|
-
describe "causing conflict" do
|
89
|
-
it "should fail and make no change" do
|
90
|
-
proc {
|
91
|
-
@p3.name = "Juliar Gillard" # Must fail; must leave @p3 untouched.
|
92
|
-
}.should raise_error # (ActiveFacts::API::AmbiguousIdentityChange)
|
93
|
-
|
94
|
-
@p3.name.should == @tony
|
95
|
-
end
|
96
|
-
end
|
97
|
-
|
98
|
-
describe "without conflict" do
|
99
|
-
before :each do
|
100
|
-
@p3.tfn = 456
|
101
|
-
end
|
102
|
-
|
103
|
-
it "should be allowed" do
|
104
|
-
@p3.identifying_role_values.should == [456]
|
105
|
-
end
|
106
|
-
|
107
|
-
it "should be re-indexed" do
|
108
|
-
@c1.AustralianTaxPayer.keys.should == [[456]]
|
109
|
-
end
|
110
|
-
|
111
|
-
it "should be propagated" do
|
112
|
-
key = [[456], [2010]]
|
113
|
-
@r1.identifying_role_values.should == key
|
114
|
-
@c1.AustralianTaxReturn.keys.should == [key]
|
115
|
-
@c1.AustralianTaxReturn.values.should == [@r1]
|
116
|
-
end
|
117
|
-
end
|
118
|
-
end
|
119
|
-
end
|
@@ -1,63 +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 'identity change on subtype' do
|
7
|
-
before :all do
|
8
|
-
module Mod
|
9
|
-
class EntityA
|
10
|
-
identified_by :value_a
|
11
|
-
one_to_one :value_a
|
12
|
-
has_one :value_b
|
13
|
-
end
|
14
|
-
|
15
|
-
class ValueA < Int
|
16
|
-
value_type
|
17
|
-
end
|
18
|
-
|
19
|
-
class ValueB < String
|
20
|
-
value_type
|
21
|
-
end
|
22
|
-
|
23
|
-
class EntityB < EntityA
|
24
|
-
identified_by :value_b
|
25
|
-
end
|
26
|
-
end
|
27
|
-
|
28
|
-
@constellation = ActiveFacts::API::Constellation.new(Mod)
|
29
|
-
@a = @constellation.EntityA(123)
|
30
|
-
end
|
31
|
-
|
32
|
-
it "should fail if the value is the same" do
|
33
|
-
lambda { @b = @constellation.EntityB(123, 'abc') }.should raise_error(ActiveFacts::API::UnexpectedIdentifyingValueException)
|
34
|
-
end
|
35
|
-
|
36
|
-
context "on a deep-subtype" do
|
37
|
-
before :all do
|
38
|
-
module Mod
|
39
|
-
class EntityC < EntityB
|
40
|
-
end
|
41
|
-
end
|
42
|
-
|
43
|
-
@c = @constellation.EntityC(:value_a => 1, :value_b => 'abc')
|
44
|
-
end
|
45
|
-
|
46
|
-
it "should fail if the value already exist" do
|
47
|
-
@a.value_a.should == 123
|
48
|
-
@c.value_a.should == 1
|
49
|
-
lambda { @a.value_a = 1 }.should raise_error(ActiveFacts::API::DuplicateIdentifyingValueException)
|
50
|
-
lambda { @c.value_a = 123 }.should raise_error(ActiveFacts::API::DuplicateIdentifyingValueException)
|
51
|
-
end
|
52
|
-
|
53
|
-
it "should keep the previous value intact" do
|
54
|
-
@a.value_a.should == 123
|
55
|
-
@c.value_a.should == 1
|
56
|
-
end
|
57
|
-
|
58
|
-
it "should allow the change when the value doesn't exist" do
|
59
|
-
@c.value_a = 987
|
60
|
-
@c.value_a.should == 987
|
61
|
-
end
|
62
|
-
end
|
63
|
-
end
|
data/spec/metadata_spec.rb
DELETED
@@ -1,267 +0,0 @@
|
|
1
|
-
#
|
2
|
-
# ActiveFacts tests: Metadata in the Runtime API
|
3
|
-
# Copyright (c) 2012 Clifford Heath. Read the LICENSE file.
|
4
|
-
#
|
5
|
-
require 'activefacts/api'
|
6
|
-
|
7
|
-
describe "In a vocabulary" do
|
8
|
-
before :each do
|
9
|
-
Object.send :remove_const, :Mod if Object.const_defined?("Mod")
|
10
|
-
module Mod
|
11
|
-
end
|
12
|
-
@constellation = ActiveFacts::API::Constellation.new(Mod)
|
13
|
-
end
|
14
|
-
|
15
|
-
ObjectType_methods = [
|
16
|
-
:has_one, :maybe, :one_to_one,
|
17
|
-
:add_role, :all_role, :subtypes, :supertypes, :vocabulary,
|
18
|
-
:all_role_transitive,
|
19
|
-
# To make private:
|
20
|
-
:check_identifying_role_has_valid_cardinality, :realise_role, :supertypes_transitive, :subtypes_transitive,
|
21
|
-
]
|
22
|
-
|
23
|
-
ValueType_methods = [
|
24
|
-
:assert_instance, :identifying_role_values, :index_instance,
|
25
|
-
:inherited, :length, :restrict, :scale, :value_type, :verbalise
|
26
|
-
]
|
27
|
-
|
28
|
-
Instance_methods = [
|
29
|
-
:constellation, :retract, :is_a?,
|
30
|
-
# To remove or move to EntityType
|
31
|
-
:related_entities,
|
32
|
-
:instance_index
|
33
|
-
]
|
34
|
-
Value_methods = Instance_methods + [
|
35
|
-
:verbalise, :identifying_role_values
|
36
|
-
]
|
37
|
-
|
38
|
-
EntityType_methods = [
|
39
|
-
:assert_instance, :identified_by,
|
40
|
-
:identifying_role_names, :identifying_role_values, :identifying_roles,
|
41
|
-
:index_instance, :inherited,
|
42
|
-
:verbalise,
|
43
|
-
# To make private:
|
44
|
-
:check_no_supertype_instance_exists, :check_supertype_identifiers_match,
|
45
|
-
:identification_inherited_from, :identification_inherited_from=,
|
46
|
-
:find_inherited_role,
|
47
|
-
:overrides_identification_of, :overrides_identification_of=,
|
48
|
-
# To remove
|
49
|
-
:created_instances, :created_instances=
|
50
|
-
]
|
51
|
-
|
52
|
-
Entity_methods = Instance_methods + [
|
53
|
-
:verbalise, :identifying_role_values,
|
54
|
-
# To remove hide or rewrite:
|
55
|
-
:identity_by, :identity_as_hash, :check_identification_change_legality,
|
56
|
-
]
|
57
|
-
|
58
|
-
Cases =
|
59
|
-
ValueClasses.map do |klass| # [String, Date, DateTime, Int, Real, AutoCounter, Decimal, Guid]
|
60
|
-
{ :name => "a #{klass}",
|
61
|
-
:definition => %Q{
|
62
|
-
class T < #{klass}
|
63
|
-
value_type
|
64
|
-
end
|
65
|
-
},
|
66
|
-
:pattern => /Method: Class(#[a-z_0-9]*[?=]? )?\((defined in )?ActiveFacts::API::Value::ClassMethods[) ]/,
|
67
|
-
:class_methods => ValueType_methods,
|
68
|
-
:instance_methods => Value_methods,
|
69
|
-
:constructor_args => Array(
|
70
|
-
case klass.name
|
71
|
-
when 'String'; 'foo'
|
72
|
-
when 'DateTime'; [2008, 04, 20, 10, 28, 14]
|
73
|
-
when 'Date'; '2012-12-11'
|
74
|
-
when 'Time'; [2008, 04, 20, 10, 28, 14]
|
75
|
-
when 'Int'; 23
|
76
|
-
when 'Real'; 23.45
|
77
|
-
when 'AutoCounter', 'Guid'; :new
|
78
|
-
when 'Decimal'; '12345.5678'
|
79
|
-
else
|
80
|
-
raise "Please define constructor args for #{klass}"
|
81
|
-
end
|
82
|
-
).compact
|
83
|
-
}
|
84
|
-
end + [
|
85
|
-
{ :name => "a Value Sub Type",
|
86
|
-
:definition => %q{
|
87
|
-
class V < String
|
88
|
-
value_type
|
89
|
-
end
|
90
|
-
class T < V
|
91
|
-
end
|
92
|
-
},
|
93
|
-
:pattern => /Method: Class(#[a-z_0-9]*[?=]? )?\((defined in )?ActiveFacts::API::Value::ClassMethods[) ]/,
|
94
|
-
:class_methods => ValueType_methods,
|
95
|
-
:instance_methods => Value_methods,
|
96
|
-
:constructor_args => [ 'foo' ]
|
97
|
-
},
|
98
|
-
|
99
|
-
{ :name => "an Entity Type",
|
100
|
-
:definition => %q{
|
101
|
-
class V < String
|
102
|
-
value_type
|
103
|
-
end
|
104
|
-
class T
|
105
|
-
identified_by :foo
|
106
|
-
one_to_one :foo, :class => V
|
107
|
-
end
|
108
|
-
},
|
109
|
-
:pattern => /Method: Class(#[a-z_0-9]*[?=]? )?\((defined in )?ActiveFacts::API::Entity::ClassMethods[) ]/,
|
110
|
-
:class_methods => EntityType_methods,
|
111
|
-
:instance_methods => Entity_methods,
|
112
|
-
:constructor_args => [ 'foo' ]
|
113
|
-
},
|
114
|
-
|
115
|
-
{ :name => "an Entity Sub Type",
|
116
|
-
:definition => %q{
|
117
|
-
class V < String
|
118
|
-
value_type
|
119
|
-
end
|
120
|
-
class E
|
121
|
-
identified_by :foo
|
122
|
-
one_to_one :foo, :class => V
|
123
|
-
end
|
124
|
-
class T < E
|
125
|
-
end
|
126
|
-
},
|
127
|
-
:pattern => /Method: Class(#[a-z_0-9]*[?=]? )?\((defined in )?ActiveFacts::API::Entity::ClassMethods[) ]/,
|
128
|
-
:class_methods => EntityType_methods,
|
129
|
-
:instance_methods => Entity_methods,
|
130
|
-
:constructor_args => [ 'foo' ]
|
131
|
-
},
|
132
|
-
|
133
|
-
{ :name => "an Entity Sub Type with independent identification",
|
134
|
-
:definition => %q{
|
135
|
-
class V < String
|
136
|
-
value_type
|
137
|
-
end
|
138
|
-
class E
|
139
|
-
identified_by :foo
|
140
|
-
one_to_one :foo, :class => V
|
141
|
-
end
|
142
|
-
class T < E
|
143
|
-
identified_by :bar
|
144
|
-
one_to_one :bar, :class => V
|
145
|
-
end
|
146
|
-
},
|
147
|
-
:pattern => /Method: Class(#[a-z_0-9]*[?=]? )?\((defined in )?ActiveFacts::API::Entity::ClassMethods[) ]/,
|
148
|
-
:class_methods => EntityType_methods,
|
149
|
-
:instance_methods => Entity_methods,
|
150
|
-
:constructor_args => [ 'bar', {:foo => 'foo'} ]
|
151
|
-
},
|
152
|
-
|
153
|
-
{ :name => "an Entity Sub Type with extra supertypes",
|
154
|
-
:definition => %q{
|
155
|
-
class V < String
|
156
|
-
value_type
|
157
|
-
end
|
158
|
-
class E
|
159
|
-
identified_by :foo
|
160
|
-
one_to_one :foo, :class => V
|
161
|
-
end
|
162
|
-
class E2
|
163
|
-
identified_by :baz
|
164
|
-
one_to_one :baz, :class => V
|
165
|
-
end
|
166
|
-
class T < E
|
167
|
-
supertypes E2
|
168
|
-
one_to_one :bar, :class => V
|
169
|
-
end
|
170
|
-
},
|
171
|
-
:pattern => /Method: Class(#[a-z_0-9]*[?=]? )?\((defined in )?ActiveFacts::API::Entity::ClassMethods[) ]/,
|
172
|
-
:class_methods => EntityType_methods,
|
173
|
-
:instance_methods => Entity_methods,
|
174
|
-
:constructor_args => [ 'bar', {:foo => 'foo', :baz => 'baz'} ]
|
175
|
-
},
|
176
|
-
|
177
|
-
]
|
178
|
-
|
179
|
-
Cases.each do |casehash|
|
180
|
-
case_name = casehash[:name]
|
181
|
-
definition = "module Mod; "+ casehash[:definition] + "; end"
|
182
|
-
pattern = casehash[:pattern]
|
183
|
-
class_methods = casehash[:class_methods]
|
184
|
-
instance_methods = casehash[:instance_methods]
|
185
|
-
constructor_args = casehash[:constructor_args]
|
186
|
-
|
187
|
-
describe "#{case_name}" do
|
188
|
-
before :each do
|
189
|
-
eval definition
|
190
|
-
all_T_methods = Mod::T.methods.select{|m| Mod::T.method(m).inspect =~ /ActiveFacts/}.map(&:to_s).sort
|
191
|
-
@object_type_methods, @value_type_methods =
|
192
|
-
*all_T_methods.partition do |m|
|
193
|
-
Mod::T.method(m).inspect =~ /Method: Class(#[a-z_0-9]*[?=]? )?\((defined in )?ActiveFacts::API::ObjectType[) ]/
|
194
|
-
end
|
195
|
-
end
|
196
|
-
|
197
|
-
describe "as an ObjectType" do
|
198
|
-
it "should have the appropriate class methods" do
|
199
|
-
@object_type_methods.should == ObjectType_methods.map(&:to_s).sort
|
200
|
-
end
|
201
|
-
|
202
|
-
ObjectType_methods.each do |m|
|
203
|
-
it "should respond to ObjectType.#{m}" do
|
204
|
-
Mod::T.should respond_to(m)
|
205
|
-
Mod::T.method(m).inspect.should =~ /Method: Class(#[a-z_0-9]*[?=]? )?\((defined in )?ActiveFacts::API::ObjectType[) ]/
|
206
|
-
end
|
207
|
-
end
|
208
|
-
end
|
209
|
-
|
210
|
-
describe "as #{case_name}" do
|
211
|
-
it "should have the appropriate class methods" do
|
212
|
-
@value_type_methods.should == class_methods.map(&:to_s).sort
|
213
|
-
end
|
214
|
-
|
215
|
-
class_methods.each do |m|
|
216
|
-
it "should respond to #{case_name}.#{m}" do
|
217
|
-
Mod::T.should respond_to(m)
|
218
|
-
Mod::T.method(m).inspect.should =~ pattern
|
219
|
-
end
|
220
|
-
end
|
221
|
-
end
|
222
|
-
|
223
|
-
describe "when instantiated" do
|
224
|
-
before :each do
|
225
|
-
@instance = @constellation.T(*constructor_args)
|
226
|
-
end
|
227
|
-
|
228
|
-
it "should be ok" do
|
229
|
-
@instance.should_not be_nil
|
230
|
-
end
|
231
|
-
|
232
|
-
if @instance
|
233
|
-
end
|
234
|
-
end
|
235
|
-
|
236
|
-
describe "An instance of #{case_name}" do
|
237
|
-
before :each do
|
238
|
-
@v = @constellation.T(*constructor_args)
|
239
|
-
all_T_instance_methods = @v.methods.select do |m|
|
240
|
-
i = @v.method(m).inspect
|
241
|
-
i =~ /ActiveFacts/ || i =~ /identifying_role_values/
|
242
|
-
end.sort.map(&:to_sym)
|
243
|
-
@actual_instance_methods = all_T_instance_methods
|
244
|
-
end
|
245
|
-
|
246
|
-
it "should have the appropriate instance methods" do
|
247
|
-
# @actual_instance_methods.should == instance_methods.map(&:to_s).sort
|
248
|
-
# Weaken our expectation to just that nothing should be missing (extra methods are ok)
|
249
|
-
missing_methods = instance_methods - @actual_instance_methods
|
250
|
-
missing_methods.should == []
|
251
|
-
end
|
252
|
-
|
253
|
-
instance_methods.each do |m|
|
254
|
-
it "should respond to #{case_name}\##{m}" do
|
255
|
-
v = @constellation.T(*constructor_args)
|
256
|
-
v.should respond_to(m)
|
257
|
-
if Instance_methods.include?(m)
|
258
|
-
v.method(m).inspect.should =~ /Mod::T(#[a-z_0-9]*[?=]? )?\((defined in )?ActiveFacts::API::Instance[) ]/
|
259
|
-
else
|
260
|
-
v.method(m).inspect.should =~ /Mod::T(#[a-z_0-9]*[?=]? )?\((defined in )?ActiveFacts::API::(Value|Entity)[) ]/
|
261
|
-
end
|
262
|
-
end
|
263
|
-
end
|
264
|
-
end
|
265
|
-
end
|
266
|
-
end
|
267
|
-
end
|