activefacts 0.8.9 → 0.8.10

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.
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