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,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
@@ -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