activefacts 0.8.9 → 0.8.10

Sign up to get free protection for your applications and to get access to all the features.
Files changed (120) hide show
  1. data/.gemtest +0 -0
  2. data/Manifest.txt +28 -33
  3. data/Rakefile +11 -12
  4. data/bin/cql +90 -46
  5. data/examples/CQL/Blog.cql +2 -1
  6. data/examples/CQL/CompanyDirectorEmployee.cql +2 -2
  7. data/examples/CQL/Death.cql +1 -1
  8. data/examples/CQL/Diplomacy.cql +9 -9
  9. data/examples/CQL/Genealogy.cql +3 -2
  10. data/examples/CQL/Insurance.cql +10 -7
  11. data/examples/CQL/JoinEquality.cql +2 -2
  12. data/examples/CQL/Marriage.cql +1 -1
  13. data/examples/CQL/Metamodel.cql +73 -53
  14. data/examples/CQL/MetamodelNext.cql +89 -67
  15. data/examples/CQL/OneToOnes.cql +2 -2
  16. data/examples/CQL/ServiceDirector.cql +10 -5
  17. data/examples/CQL/Supervision.cql +3 -3
  18. data/examples/CQL/Tests.Test5.Load.cql +1 -1
  19. data/examples/CQL/Warehousing.cql +4 -2
  20. data/lib/activefacts/cql/CQLParser.treetop +26 -60
  21. data/lib/activefacts/cql/Context.treetop +12 -2
  22. data/lib/activefacts/cql/Expressions.treetop +14 -30
  23. data/lib/activefacts/cql/FactTypes.treetop +165 -110
  24. data/lib/activefacts/cql/Language/English.treetop +167 -54
  25. data/lib/activefacts/cql/LexicalRules.treetop +16 -2
  26. data/lib/activefacts/cql/{Concepts.treetop → ObjectTypes.treetop} +36 -37
  27. data/lib/activefacts/cql/Terms.treetop +57 -27
  28. data/lib/activefacts/cql/ValueTypes.treetop +39 -13
  29. data/lib/activefacts/cql/compiler.rb +5 -3
  30. data/lib/activefacts/cql/compiler/{reading.rb → clause.rb} +407 -285
  31. data/lib/activefacts/cql/compiler/constraint.rb +178 -275
  32. data/lib/activefacts/cql/compiler/entity_type.rb +73 -64
  33. data/lib/activefacts/cql/compiler/expression.rb +418 -0
  34. data/lib/activefacts/cql/compiler/fact.rb +146 -145
  35. data/lib/activefacts/cql/compiler/fact_type.rb +197 -80
  36. data/lib/activefacts/cql/compiler/join.rb +159 -0
  37. data/lib/activefacts/cql/compiler/shared.rb +51 -23
  38. data/lib/activefacts/cql/compiler/value_type.rb +56 -2
  39. data/lib/activefacts/cql/parser.rb +15 -4
  40. data/lib/activefacts/generate/absorption.rb +7 -7
  41. data/lib/activefacts/generate/cql.rb +100 -37
  42. data/lib/activefacts/generate/oo.rb +28 -51
  43. data/lib/activefacts/generate/ordered.rb +60 -36
  44. data/lib/activefacts/generate/ruby.rb +6 -6
  45. data/lib/activefacts/generate/sql/server.rb +4 -4
  46. data/lib/activefacts/input/orm.rb +71 -53
  47. data/lib/activefacts/persistence.rb +1 -1
  48. data/lib/activefacts/persistence/columns.rb +27 -23
  49. data/lib/activefacts/persistence/foreignkey.rb +6 -6
  50. data/lib/activefacts/persistence/index.rb +17 -17
  51. data/lib/activefacts/persistence/{concept.rb → object_type.rb} +9 -9
  52. data/lib/activefacts/persistence/reference.rb +61 -36
  53. data/lib/activefacts/persistence/tables.rb +61 -59
  54. data/lib/activefacts/support.rb +54 -29
  55. data/lib/activefacts/version.rb +1 -1
  56. data/lib/activefacts/vocabulary/extensions.rb +99 -54
  57. data/lib/activefacts/vocabulary/metamodel.rb +43 -37
  58. data/lib/activefacts/vocabulary/verbaliser.rb +134 -109
  59. data/spec/absorption_spec.rb +8 -8
  60. data/spec/cql/comparison_spec.rb +91 -0
  61. data/spec/cql/contractions_spec.rb +251 -0
  62. data/spec/cql/entity_type_spec.rb +319 -0
  63. data/spec/cql/expressions_spec.rb +63 -0
  64. data/spec/cql/fact_type_matching_spec.rb +283 -0
  65. data/spec/cql/french_spec.rb +21 -0
  66. data/spec/cql/parser/bad_literals_spec.rb +86 -0
  67. data/spec/cql/parser/constraints_spec.rb +19 -0
  68. data/spec/cql/parser/entity_types_spec.rb +106 -0
  69. data/spec/cql/parser/expressions_spec.rb +179 -0
  70. data/spec/cql/parser/fact_types_spec.rb +41 -0
  71. data/spec/cql/parser/literals_spec.rb +312 -0
  72. data/spec/cql/parser/pragmas_spec.rb +89 -0
  73. data/spec/cql/parser/value_types_spec.rb +42 -0
  74. data/spec/cql/role_matching_spec.rb +147 -0
  75. data/spec/cql/samples_spec.rb +9 -9
  76. data/spec/cql_cql_spec.rb +1 -1
  77. data/spec/cql_dm_spec.rb +116 -0
  78. data/spec/cql_mysql_spec.rb +1 -1
  79. data/spec/cql_ruby_spec.rb +1 -1
  80. data/spec/cql_sql_spec.rb +3 -3
  81. data/spec/cql_symbol_tables_spec.rb +30 -30
  82. data/spec/cqldump_spec.rb +4 -4
  83. data/spec/helpers/array_matcher.rb +32 -27
  84. data/spec/helpers/diff_matcher.rb +6 -26
  85. data/spec/helpers/file_matcher.rb +41 -32
  86. data/spec/helpers/parse_to_ast_matcher.rb +76 -0
  87. data/spec/helpers/string_matcher.rb +32 -31
  88. data/spec/norma_cql_spec.rb +1 -1
  89. data/spec/norma_ruby_spec.rb +1 -1
  90. data/spec/norma_ruby_sql_spec.rb +1 -1
  91. data/spec/norma_sql_spec.rb +3 -1
  92. data/spec/norma_tables_spec.rb +1 -1
  93. data/spec/ruby_api_spec.rb +23 -0
  94. data/spec/spec_helper.rb +5 -4
  95. metadata +66 -66
  96. data/examples/CQL/OrienteeringER.cql +0 -58
  97. data/lib/activefacts/api.rb +0 -44
  98. data/lib/activefacts/api/concept.rb +0 -410
  99. data/lib/activefacts/api/constellation.rb +0 -128
  100. data/lib/activefacts/api/entity.rb +0 -256
  101. data/lib/activefacts/api/instance.rb +0 -60
  102. data/lib/activefacts/api/instance_index.rb +0 -80
  103. data/lib/activefacts/api/numeric.rb +0 -167
  104. data/lib/activefacts/api/role.rb +0 -80
  105. data/lib/activefacts/api/role_proxy.rb +0 -70
  106. data/lib/activefacts/api/role_values.rb +0 -117
  107. data/lib/activefacts/api/standard_types.rb +0 -87
  108. data/lib/activefacts/api/support.rb +0 -65
  109. data/lib/activefacts/api/value.rb +0 -135
  110. data/lib/activefacts/api/vocabulary.rb +0 -82
  111. data/spec/api/autocounter.rb +0 -82
  112. data/spec/api/constellation.rb +0 -130
  113. data/spec/api/entity_type.rb +0 -103
  114. data/spec/api/instance.rb +0 -461
  115. data/spec/api/roles.rb +0 -124
  116. data/spec/api/value_type.rb +0 -112
  117. data/spec/api_spec.rb +0 -13
  118. data/spec/cql/matching_spec.rb +0 -517
  119. data/spec/cql/unit_spec.rb +0 -394
  120. data/spec/spec.opts +0 -1
@@ -1,103 +0,0 @@
1
- #
2
- # ActiveFacts tests: Entity classes in the Runtime API
3
- # Copyright (c) 2008 Clifford Heath. Read the LICENSE file.
4
- #
5
- require 'activefacts/api'
6
-
7
- describe "Entity Type class definitions" do
8
- before :each do
9
- Object.send :remove_const, :Mod if Object.const_defined?("Mod")
10
- module Mod
11
- class Name < String
12
- value_type
13
- end
14
- class LegalEntity
15
- end
16
- class Person < LegalEntity
17
- identified_by :name
18
- has_one :name, :class => Name
19
- end
20
- end
21
- end
22
-
23
- it "should respond_to verbalise" do
24
- Mod::Person.respond_to?(:verbalise).should be_true
25
- end
26
-
27
- it "should not pollute the superclass" do
28
- Mod::LegalEntity.respond_to?(:verbalise).should_not be_true
29
- Class.respond_to?(:verbalise).should_not be_true
30
- end
31
-
32
- it "should return a string from verbalise" do
33
- v = Mod::Person.verbalise
34
- v.should_not be_nil
35
- v.should_not =~ /REVISIT/
36
- end
37
-
38
- it "should respond_to vocabulary" do
39
- Mod::Person.respond_to?(:vocabulary).should be_true
40
- end
41
-
42
- it "should return the parent module as the vocabulary" do
43
- vocabulary = Mod::Person.vocabulary
44
- vocabulary.should == Mod
45
- end
46
-
47
- it "should return a vocabulary that knows about this concept" do
48
- vocabulary = Mod::Person.vocabulary
49
- vocabulary.respond_to?(:concept).should be_true
50
- vocabulary.concept.has_key?("Person").should be_true
51
- end
52
-
53
- it "should respond to roles()" do
54
- Mod::Person.respond_to?(:roles).should be_true
55
- end
56
-
57
- it "should contain only the added role definition" do
58
- Mod::Person.roles.size.should == 1
59
- end
60
-
61
- it "should return the role definition" do
62
- # Check the role definition may be accessed by passing an index:
63
- Mod::Person.roles(0).should be_nil
64
-
65
- role = Mod::Person.roles(:name)
66
- role.should_not be_nil
67
-
68
- role = Mod::Person.roles("name")
69
- role.should_not be_nil
70
-
71
- # Check the role definition may be accessed by indexing the returned hash:
72
- role = Mod::Person.roles[:name]
73
- role.should_not be_nil
74
-
75
- # Check the role definition array by .include?
76
- Mod::Person.roles.include?(:name).should be_true
77
- end
78
-
79
- it "should fail on a ValueClass" do
80
- lambda{
81
- class SomeClass < String
82
- identified_by
83
- end
84
- }.should raise_error
85
- end
86
-
87
- it "should return the identifying roles" do
88
- Mod::Person.identifying_role_names.should == [:name]
89
- end
90
-
91
- it "should prevent a role name from matching a concept that exists unless that concept is the counterpart" do
92
- lambda {
93
- module Mod
94
- class LegalEntity
95
- end
96
- class Bad
97
- identified_by :name
98
- has_one :name, LegalEntity
99
- end
100
- end
101
- }.should raise_error
102
- end
103
- end
@@ -1,461 +0,0 @@
1
- #
2
- # ActiveFacts tests: Value instances in the Runtime API
3
- # Copyright (c) 2008 Clifford Heath. Read the LICENSE file.
4
- #
5
- require 'activefacts/api'
6
-
7
- describe "An instance of every type of Concept" do
8
- before :each do
9
- Object.send :remove_const, :Mod if Object.const_defined?("Mod")
10
- module Mod
11
- # These are the base value types we're going to test:
12
- @base_types = [
13
- Int, Real, AutoCounter, String, Date, DateTime
14
- ]
15
-
16
- # Construct the names of the roles they play:
17
- @base_type_roles = @base_types.map do |t|
18
- t.name.snakecase
19
- end
20
- @role_names = @base_type_roles.inject([]) {|a, t|
21
- a << :"#{t}_value"
22
- } +
23
- @base_type_roles.inject([]) {|a, t|
24
- a << :"#{t}_sub_value"
25
- }
26
-
27
- # Create a value type and a subtype of that value type for each base type:
28
- @base_types.each do |base_type|
29
- eval %Q{
30
- class #{base_type.name}Value < #{base_type.name}
31
- value_type
32
- end
33
-
34
- class #{base_type.name}SubValue < #{base_type.name}Value
35
- # Note no new "value_type" is required here, it comes through inheritance
36
- end
37
- }
38
- end
39
-
40
- # Create a TestByX, TestByXSub, and TestSubByX class for all base types X
41
- # Each class has a has_one and a one_to_one for all roles.
42
- # and is identified by the has_one :x role
43
- @base_types.each do |base_type|
44
- eval %Q{
45
- class TestBy#{base_type.name}
46
- identified_by :#{base_type.name.snakecase}_value#{
47
- @role_names.map do |role_name|
48
- %Q{
49
- has_one :#{role_name}
50
- one_to_one :one_#{role_name}, :class => #{role_name.to_s.camelcase(true)}}
51
- end*""
52
- }
53
- end
54
-
55
- class TestBy#{base_type.name}Sub
56
- identified_by :#{base_type.name.snakecase}_sub_value#{
57
- @role_names.map do |role_name|
58
- %Q{
59
- has_one :#{role_name}
60
- one_to_one :one_#{role_name}, :class => #{role_name.to_s.camelcase(true)}}
61
- end*""
62
- }
63
- end
64
-
65
- class TestSubBy#{base_type.name} < TestBy#{base_type.name}
66
- # Entity subtypes, inherit identification and all roles
67
- end
68
-
69
- class TestBy#{base_type.name}Entity
70
- identified_by :test_by_#{base_type.name.snakecase}
71
- one_to_one :test_by_#{base_type.name.snakecase}
72
- end}
73
- end
74
- end
75
-
76
- # Simple Values
77
- @int = 0
78
- @real = 0.0
79
- @auto_counter = 0
80
- @new_auto_counter = :new
81
- @string = "zero"
82
- @date = [2008, 04, 19]
83
- @date_time = [2008, 04, 19, 10, 28, 14]
84
-
85
- # Value Type instances
86
- @int_value = Mod::IntValue.new(1)
87
- @real_value = Mod::RealValue.new(1.0)
88
- @auto_counter_value = Mod::AutoCounterValue.new(1)
89
- @new_auto_counter_value = Mod::AutoCounterValue.new(:new)
90
- @string_value = Mod::StringValue.new("one")
91
- @date_value = Mod::DateValue.new(2008, 04, 20)
92
- @date_time_value = Mod::DateTimeValue.new(2008, 04, 20, 10, 28, 14)
93
-
94
- # Value SubType instances
95
- @int_sub_value = Mod::IntSubValue.new(4)
96
- @real_sub_value = Mod::RealSubValue.new(4.0)
97
- @auto_counter_sub_value = Mod::AutoCounterSubValue.new(4)
98
- @auto_counter_sub_value_new = Mod::AutoCounterSubValue.new(:new)
99
- @string_sub_value = Mod::StringSubValue.new("five")
100
- @date_sub_value = Mod::DateSubValue.new(2008, 04, 25)
101
- @date_time_sub_value = Mod::DateTimeSubValue.new(2008, 04, 26, 10, 28, 14)
102
-
103
- # Entities identified by Value Type, SubType and Entity-by-value-type instances
104
- @test_by_int = Mod::TestByInt.new(2)
105
- @test_by_real = Mod::TestByReal.new(2.0)
106
- @test_by_auto_counter = Mod::TestByAutoCounter.new(2)
107
- @test_by_auto_counter_new = Mod::TestByAutoCounter.new(:new)
108
- @test_by_string = Mod::TestByString.new("two")
109
- @test_by_date = Mod::TestByDate.new(Date.new(2008,04,28))
110
- #@test_by_date = Mod::TestByDate.new(2008,04,28)
111
- @test_by_date_time = Mod::TestByDateTime.new(2008,04,28,10,28,15)
112
- #@test_by_date_time = Mod::TestByDateTime.new(DateTime.new(2008,04,28,10,28,15))
113
-
114
- @test_by_int_sub = Mod::TestByIntSub.new(2)
115
- @test_by_real_sub = Mod::TestByRealSub.new(5.0)
116
- @test_by_auto_counter_sub = Mod::TestByAutoCounterSub.new(6)
117
- @test_by_auto_counter_new_sub = Mod::TestByAutoCounterSub.new(:new)
118
- @test_by_string_sub = Mod::TestByStringSub.new("six")
119
- @test_by_date_sub = Mod::TestByDateSub.new(Date.new(2008,04,27))
120
- @test_by_date_time_sub = Mod::TestByDateTimeSub.new(2008,04,29,10,28,15)
121
-
122
- @test_by_int_entity = Mod::TestByIntEntity.new(@test_by_int)
123
- @test_by_real_entity = Mod::TestByRealEntity.new(@test_by_real)
124
- @test_by_auto_counter_entity = Mod::TestByAutoCounterEntity.new(@test_by_auto_counter)
125
- @test_by_auto_counter_new_entity = Mod::TestByAutoCounterEntity.new(@test_by_auto_counter_new)
126
- @test_by_string_entity = Mod::TestByStringEntity.new(@test_by_string)
127
- @test_by_date_entity = Mod::TestByDateEntity.new(@test_by_date)
128
- @test_by_date_time_entity = Mod::TestByDateTimeEntity.new(@test_by_date_time)
129
-
130
- # Entity subtypes
131
- @test_sub_by_int = Mod::TestSubByInt.new(2)
132
- @test_sub_by_real = Mod::TestSubByReal.new(2.0)
133
- @test_sub_by_auto_counter = Mod::TestSubByAutoCounter.new(2)
134
- @test_sub_by_auto_counter_new = Mod::TestSubByAutoCounter.new(:new)
135
- @test_sub_by_string = Mod::TestSubByString.new("two")
136
- @test_sub_by_date = Mod::TestSubByDate.new(Date.new(2008,04,28))
137
- @test_sub_by_date_time = Mod::TestSubByDateTime.new(2008,04,28,10,28,15)
138
-
139
- # These arrays get zipped together in various ways. Keep them aligned.
140
- @values = [
141
- @int, @real, @auto_counter, @new_auto_counter,
142
- @string, @date, @date_time,
143
- ]
144
- @classes = [
145
- Int, Real, AutoCounter, AutoCounter,
146
- String, Date, DateTime,
147
- ]
148
- @value_types = [
149
- Mod::IntValue, Mod::RealValue, Mod::AutoCounterValue, Mod::AutoCounterValue,
150
- Mod::StringValue, Mod::DateValue, Mod::DateTimeValue,
151
- Mod::IntSubValue, Mod::RealSubValue, Mod::AutoCounterSubValue, Mod::AutoCounterSubValue,
152
- Mod::StringSubValue, Mod::DateSubValue, Mod::DateTimeSubValue,
153
- ]
154
- @value_instances = [
155
- @int_value, @real_value, @auto_counter_value, @new_auto_counter_value,
156
- @string_value, @date_value, @date_time_value,
157
- @int_sub_value, @real_sub_value, @auto_counter_sub_value, @auto_counter_sub_value_new,
158
- @string_sub_value, @date_sub_value, @date_time_sub_value,
159
- @int_value, @real_value, @auto_counter_value, @new_auto_counter_value,
160
- @string_value, @date_value, @date_time_value,
161
- ]
162
- @entity_types = [
163
- Mod::TestByInt, Mod::TestByReal, Mod::TestByAutoCounter, Mod::TestByAutoCounter,
164
- Mod::TestByString, Mod::TestByDate, Mod::TestByDateTime,
165
- Mod::TestByIntSub, Mod::TestByRealSub, Mod::TestByAutoCounterSub, Mod::TestByAutoCounterSub,
166
- Mod::TestByStringSub, Mod::TestByDateSub, Mod::TestByDateTimeSub,
167
- Mod::TestSubByInt, Mod::TestSubByReal, Mod::TestSubByAutoCounter, Mod::TestSubByAutoCounter,
168
- Mod::TestSubByString, Mod::TestSubByDate, Mod::TestSubByDateTime,
169
- ]
170
- @entities = [
171
- @test_by_int, @test_by_real, @test_by_auto_counter, @test_by_auto_counter_new,
172
- @test_by_string, @test_by_date, @test_by_date_time,
173
- @test_by_int_sub, @test_by_real_sub, @test_by_auto_counter_sub, @test_by_auto_counter_new_sub,
174
- @test_by_string_sub, @test_by_date_sub, @test_by_date_time_sub,
175
- @test_sub_by_int, @test_sub_by_real, @test_sub_by_auto_counter, @test_sub_by_auto_counter_new,
176
- @test_sub_by_string, @test_sub_by_date, @test_sub_by_date_time,
177
- ]
178
- @entities_by_entity = [
179
- @test_by_int_entity,
180
- @test_by_real_entity,
181
- @test_by_auto_counter_entity,
182
- @test_by_auto_counter_new_entity,
183
- @test_by_string_entity,
184
- @test_by_date_entity,
185
- @test_by_date_time_entity,
186
- ]
187
- @entities_by_entity_types = [
188
- Mod::TestByIntEntity, Mod::TestByRealEntity, Mod::TestByAutoCounterEntity, Mod::TestByAutoCounterEntity,
189
- Mod::TestByStringEntity, Mod::TestByDateEntity, Mod::TestByDateTimeEntity,
190
- ]
191
- @test_role_names = [
192
- :int_value, :real_value, :auto_counter_value, :auto_counter_value,
193
- :string_value, :date_value, :date_time_value,
194
- :int_sub_value, :real_sub_value, :auto_counter_sub_value, :auto_counter_sub_value,
195
- :string_sub_value, :date_sub_value, :date_time_sub_value,
196
- :int_value, :real_value, :auto_counter_value, :auto_counter_value,
197
- :string_value, :date_value, :date_time_value,
198
- ]
199
- @role_values = [
200
- 3, 3.0, 6, 7,
201
- "three", Date.new(2008,4,21), DateTime.new(2008,4,22,10,28,16),
202
- ]
203
- @subtype_role_instances = [
204
- Mod::IntSubValue.new(6), Mod::RealSubValue.new(6.0),
205
- Mod::AutoCounterSubValue.new(:new), Mod::AutoCounterSubValue.new(8),
206
- Mod::StringSubValue.new("seven"),
207
- Mod::DateSubValue.new(2008,4,29), Mod::DateTimeSubValue.new(2008,4,30,10,28,16)
208
- ]
209
- end
210
-
211
- it "if a value type, should verbalise" do
212
- @value_types.each do |value_type|
213
- #puts "#{value_type} verbalises as #{value_type.verbalise}"
214
- value_type.respond_to?(:verbalise).should be_true
215
- verbalisation = value_type.verbalise
216
- verbalisation.should =~ %r{\b#{value_type.basename}\b}
217
- verbalisation.should =~ %r{\b#{value_type.superclass.basename}\b}
218
- end
219
- end
220
-
221
- it "if an entity type, should verbalise" do
222
- @entity_types.each do |entity_type|
223
- #puts entity_type.verbalise
224
- entity_type.respond_to?(:verbalise).should be_true
225
- verbalisation = entity_type.verbalise
226
- verbalisation.should =~ %r{\b#{entity_type.basename}\b}
227
-
228
- # All identifying roles should be in the verbalisation.
229
- # Strictly this should be the role name, but we don't set names here.
230
- entity_type.identifying_role_names.each do |ir|
231
- role = entity_type.roles(ir)
232
- role.should_not be_nil
233
- counterpart_concept = role.counterpart_concept
234
- verbalisation.should =~ %r{\b#{counterpart_concept.basename}\b}
235
- end
236
- end
237
- end
238
-
239
- it "if a value, should verbalise" do
240
- @value_instances.each do |value|
241
- #puts value.verbalise
242
- value.respond_to?(:verbalise).should be_true
243
- verbalisation = value.verbalise
244
- verbalisation.should =~ %r{\b#{value.class.basename}\b}
245
- end
246
- end
247
-
248
- it "if an entity, should respond to verbalise" do
249
- (@entities+@entities_by_entity).each do |entity|
250
- #puts entity.verbalise
251
- entity.respond_to?(:verbalise).should be_true
252
- verbalisation = entity.verbalise
253
- verbalisation.should =~ %r{\b#{entity.class.basename}\b}
254
- entity.class.identifying_role_names.each do |ir|
255
- role = entity.class.roles(ir)
256
- role.should_not be_nil
257
- counterpart_concept = role.counterpart_concept
258
- verbalisation.should =~ %r{\b#{counterpart_concept.basename}\b}
259
- end
260
- end
261
- end
262
-
263
- it "should respond to constellation" do
264
- (@value_instances+@entities+@entities_by_entity).each do |instance|
265
- instance.respond_to?(:constellation).should be_true
266
- end
267
- end
268
-
269
- it "should respond to all its roles" do
270
- @entities.each do |entity|
271
- @test_role_names.each do |role_name|
272
- entity.respond_to?(role_name).should be_true
273
- entity.respond_to?(:"#{role_name}=").should be_true
274
- entity.respond_to?(:"one_#{role_name}").should be_true
275
- entity.respond_to?(:"one_#{role_name}=").should be_true
276
- end
277
- end
278
- @entities_by_entity.each do |entity|
279
- role = entity.class.roles(entity.class.identifying_role_names[0])
280
- role_name = role.name
281
- entity.respond_to?(role_name).should be_true
282
- entity.respond_to?(:"#{role_name}=").should be_true
283
- end
284
- end
285
-
286
- it "should return the Concept in response to .class()" do
287
- @value_types.zip(@value_instances).each do |concept, instance|
288
- instance.class.should == concept
289
- end
290
- @entity_types.zip(@entities).each do |concept, instance|
291
- instance.class.should == concept
292
- end
293
- @entities_by_entity_types.zip(@entities_by_entity).each do |concept, instance|
294
- instance.class.should == concept
295
- end
296
- end
297
-
298
- it "should return the module in response to .vocabulary()" do
299
- (@value_types+@entity_types).zip((@value_instances+@entities+@entities_by_entity)).each do |concept, instance|
300
- instance.class.vocabulary.should == Mod
301
- end
302
- end
303
-
304
- it "each entity type should be able to be constructed using simple values" do
305
- @entity_types.zip(@values+@values+@values, @classes+@classes+@classes).each do |entity_type, value, klass|
306
- # An identifier parameter can be an array containing a simple value too
307
- [ value,
308
- Array === value ? nil : [value],
309
- # entity_type.new(value) # REVISIT: It's not yet the case that an instance of the correct type can be used as a constructor parameter
310
- ].compact.each do |value|
311
- e = nil
312
- lambda {
313
- #puts "Constructing #{entity_type} using #{value.class} #{value.inspect}:"
314
- e = entity_type.new(value)
315
- }.should_not raise_error
316
- # Verify that the identifying role has a equivalent value (except AutoCounter):
317
- role_name = entity_type.identifying_role_names[0]
318
- role = entity_type.roles(role_name)
319
- counterpart_concept = role.counterpart_concept
320
- player_superclasses = [ counterpart_concept.superclass, counterpart_concept.superclass.superclass ]
321
- e.send(role_name).should == klass.new(*value) unless player_superclasses.include?(AutoCounter)
322
- end
323
- end
324
- end
325
-
326
- it "should allow its non-identifying roles to be assigned values" do
327
- @entities.zip(@test_role_names).each do |entity, identifying_role|
328
- @test_role_names.zip(@role_values).each do |role_name, value|
329
- # No roles of ValueType instances are tested in this file:
330
- raise hell unless entity.class.included_modules.include?(ActiveFacts::API::Entity)
331
- next if entity.class.identifying_role_names.include?(role_name)
332
- lambda {
333
- begin
334
- entity.send(:"#{role_name}=", value)
335
- rescue => e
336
- raise
337
- end
338
- }.should_not raise_error
339
- lambda {
340
- entity.send(:"one_#{role_name}=", value)
341
- }.should_not raise_error
342
- end
343
- end
344
- end
345
-
346
- it "that is an entity type should not allow its identifying roles to be re-assigned" do
347
- @entities.zip(@test_role_names).each do |entity, identifying_role|
348
- @test_role_names.zip(@role_values).each do |role_name, value|
349
- if entity.class.identifying_role_names.include?(role_name) && entity.send(role_name) != nil && value != nil
350
- lambda {
351
- entity.send(:"#{role_name}=", value)
352
- }.should raise_error
353
- end
354
- one_role = :"one_#{role_name}"
355
- if entity.class.identifying_role_names.include?(one_role) && entity.send(one_role) != nil
356
- lambda {
357
- entity.send(:"one_#{role_name}=", value)
358
- }.should raise_error
359
- end
360
- end
361
- end
362
- end
363
-
364
- it "that is an entity type should allow its identifying roles to be assigned to and from nil" do
365
- @entities.zip(@test_role_names).each do |entity, identifying_role|
366
- @test_role_names.zip(@role_values).each do |role_name, value|
367
- if entity.class.identifying_role_names.include?(role_name)
368
- # Nullify the value first:
369
- entity.send(:"#{role_name}=", nil)
370
- lambda {
371
- entity.send(:"#{role_name}=", value)
372
- }.should_not raise_error
373
- end
374
- one_role = :"one_#{role_name}"
375
- if entity.class.identifying_role_names.include?(one_role) && entity.send(one_role) == nil
376
- entity.send(one_role, nil)
377
- lambda {
378
- entity.send(one_role, value)
379
- }.should_not raise_error
380
- end
381
- end
382
- end
383
- end
384
-
385
- it "should allow its non-identifying roles to be assigned instances" do
386
- @entities.zip(@test_role_names).each do |entity, identifying_role|
387
- @test_role_names.zip(@value_types, @role_values).each do |role_name, klass, value|
388
- next unless value
389
- next if role_name == identifying_role
390
- instance = klass.new(value)
391
- lambda {
392
- entity.send(:"#{role_name}=", instance)
393
- }.should_not raise_error
394
- entity.send(role_name).class.should == klass
395
- lambda {
396
- entity.send(:"one_#{role_name}=", instance)
397
- }.should_not raise_error
398
- entity.send(:"one_#{role_name}").class.should == klass
399
- end
400
- end
401
- end
402
-
403
- it "should allow its non-identifying roles to be assigned instances of value subtypes, retaining the subtype" do
404
- @entities.zip(@test_role_names).each do |entity, identifying_role|
405
- @test_role_names.zip(@subtype_role_instances).each do |role_name, instance|
406
- next unless instance
407
- next if role_name == identifying_role
408
- lambda {
409
- entity.send(:"#{role_name}=", instance)
410
- }.should_not raise_error
411
- entity.send(role_name).class.should == instance.class
412
- lambda {
413
- entity.send(:"one_#{role_name}=", instance)
414
- }.should_not raise_error
415
- entity.send(:"one_#{role_name}").class.should == instance.class
416
- end
417
- end
418
- end
419
-
420
- it "should add to has_one's counterpart role when non-identifying roles are assigned values" do
421
- @entities.zip(@test_role_names).each do |entity, identifying_role|
422
- @test_role_names.zip(@role_values).each do |role_name, value|
423
- next if role_name == identifying_role or !value
424
-
425
- # Test the has_one role:
426
- role = entity.class.roles(role_name)
427
- old_counterpart = entity.send(:"#{role_name}")
428
- entity.send(:"#{role_name}=", value)
429
- counterpart = entity.send(:"#{role_name}")
430
- old_counterpart.should_not == counterpart
431
- counterpart.send(role.counterpart.name).should be_include(entity)
432
- old_counterpart.send(role.counterpart.name).should_not be_include(entity) if old_counterpart
433
-
434
- # Test the one_to_one role:
435
- role = entity.class.roles(:"one_#{role_name}")
436
- old_counterpart = entity.send(:"one_#{role_name}")
437
- entity.send(:"one_#{role_name}=", value)
438
- counterpart = entity.send(:"one_#{role_name}")
439
- old_counterpart.should_not == counterpart # Make sure we changed it!
440
- counterpart.send(role.counterpart.name).should == entity
441
- old_counterpart.send(role.counterpart.name).should be_nil if old_counterpart
442
- end
443
- end
444
- end
445
-
446
- it "should allow its non-identifying roles to be assigned nil" do
447
- @entities.zip(@test_role_names).each do |entity, identifying_role|
448
- @test_role_names.zip(@role_values).each do |role_name, value|
449
- next if role_name == identifying_role
450
- entity.send(:"#{role_name}=", value)
451
- lambda {
452
- entity.send(:"#{role_name}=", nil)
453
- }.should_not raise_error
454
- lambda {
455
- entity.send(:"one_#{role_name}=", nil)
456
- }.should_not raise_error
457
- end
458
- end
459
- end
460
-
461
- end