activefacts 0.8.16 → 0.8.18

Sign up to get free protection for your applications and to get access to all the features.
Files changed (100) hide show
  1. checksums.yaml +15 -0
  2. data/Manifest.txt +10 -4
  3. data/bin/afgen +26 -20
  4. data/bin/cql +1 -1
  5. data/css/orm2.css +89 -9
  6. data/examples/CQL/CompanyDirectorEmployee.cql +4 -4
  7. data/examples/CQL/Genealogy.cql +5 -5
  8. data/examples/CQL/Metamodel.cql +121 -91
  9. data/examples/CQL/MonthInSeason.cql +2 -6
  10. data/examples/CQL/SeparateSubtype.cql +11 -9
  11. data/examples/CQL/ServiceDirector.cql +21 -33
  12. data/examples/CQL/Supervision.cql +0 -3
  13. data/examples/CQL/WindowInRoomInBldg.cql +10 -4
  14. data/examples/CQL/unit.cql +1 -1
  15. data/lib/activefacts.rb +1 -0
  16. data/lib/activefacts/cql/CQLParser.treetop +5 -1
  17. data/lib/activefacts/cql/Context.treetop +2 -7
  18. data/lib/activefacts/cql/Expressions.treetop +2 -2
  19. data/lib/activefacts/cql/FactTypes.treetop +37 -31
  20. data/lib/activefacts/cql/Language/English.treetop +21 -4
  21. data/lib/activefacts/cql/LexicalRules.treetop +59 -1
  22. data/lib/activefacts/cql/ObjectTypes.treetop +22 -12
  23. data/lib/activefacts/cql/Terms.treetop +13 -9
  24. data/lib/activefacts/cql/ValueTypes.treetop +30 -11
  25. data/lib/activefacts/cql/compiler.rb +34 -5
  26. data/lib/activefacts/cql/compiler/clause.rb +207 -116
  27. data/lib/activefacts/cql/compiler/constraint.rb +129 -105
  28. data/lib/activefacts/cql/compiler/entity_type.rb +49 -27
  29. data/lib/activefacts/cql/compiler/expression.rb +71 -42
  30. data/lib/activefacts/cql/compiler/fact.rb +70 -64
  31. data/lib/activefacts/cql/compiler/fact_type.rb +108 -57
  32. data/lib/activefacts/cql/compiler/query.rb +178 -0
  33. data/lib/activefacts/cql/compiler/shared.rb +13 -12
  34. data/lib/activefacts/cql/compiler/value_type.rb +10 -4
  35. data/lib/activefacts/cql/nodes.rb +1 -1
  36. data/lib/activefacts/cql/parser.rb +6 -2
  37. data/lib/activefacts/generate/absorption.rb +6 -3
  38. data/lib/activefacts/generate/cql.rb +140 -84
  39. data/lib/activefacts/generate/dm.rb +12 -6
  40. data/lib/activefacts/generate/help.rb +25 -6
  41. data/lib/activefacts/generate/helpers/oo.rb +195 -0
  42. data/lib/activefacts/generate/helpers/ordered.rb +589 -0
  43. data/lib/activefacts/generate/helpers/rails.rb +57 -0
  44. data/lib/activefacts/generate/html/glossary.rb +274 -54
  45. data/lib/activefacts/generate/json.rb +25 -22
  46. data/lib/activefacts/generate/null.rb +1 -0
  47. data/lib/activefacts/generate/rails/models.rb +244 -0
  48. data/lib/activefacts/generate/rails/schema.rb +185 -0
  49. data/lib/activefacts/generate/records.rb +1 -0
  50. data/lib/activefacts/generate/ruby.rb +51 -30
  51. data/lib/activefacts/generate/sql/mysql.rb +5 -3
  52. data/lib/activefacts/generate/sql/server.rb +8 -4
  53. data/lib/activefacts/generate/text.rb +1 -0
  54. data/lib/activefacts/generate/transform/surrogate.rb +209 -0
  55. data/lib/activefacts/generate/version.rb +1 -0
  56. data/lib/activefacts/input/orm.rb +234 -181
  57. data/lib/activefacts/mapping/rails.rb +122 -0
  58. data/lib/activefacts/persistence/columns.rb +34 -18
  59. data/lib/activefacts/persistence/foreignkey.rb +129 -71
  60. data/lib/activefacts/persistence/index.rb +42 -12
  61. data/lib/activefacts/persistence/reference.rb +37 -23
  62. data/lib/activefacts/persistence/tables.rb +53 -19
  63. data/lib/activefacts/registry.rb +11 -0
  64. data/lib/activefacts/support.rb +28 -10
  65. data/lib/activefacts/version.rb +1 -1
  66. data/lib/activefacts/vocabulary/extensions.rb +246 -117
  67. data/lib/activefacts/vocabulary/metamodel.rb +105 -65
  68. data/lib/activefacts/vocabulary/verbaliser.rb +226 -194
  69. data/spec/absorption_spec.rb +1 -0
  70. data/spec/cql/comparison_spec.rb +8 -8
  71. data/spec/cql/contractions_spec.rb +16 -43
  72. data/spec/cql/entity_type_spec.rb +2 -1
  73. data/spec/cql/expressions_spec.rb +2 -2
  74. data/spec/cql/fact_type_matching_spec.rb +4 -1
  75. data/spec/cql/parser/bad_literals_spec.rb +30 -30
  76. data/spec/cql/parser/entity_types_spec.rb +6 -6
  77. data/spec/cql/parser/expressions_spec.rb +25 -19
  78. data/spec/cql/samples_spec.rb +5 -4
  79. data/spec/cql_cql_spec.rb +2 -1
  80. data/spec/cql_dm_spec.rb +4 -0
  81. data/spec/cql_mysql_spec.rb +4 -0
  82. data/spec/cql_parse_spec.rb +2 -0
  83. data/spec/cql_ruby_spec.rb +4 -0
  84. data/spec/cql_sql_spec.rb +4 -0
  85. data/spec/cqldump_spec.rb +7 -4
  86. data/spec/helpers/parse_to_ast_matcher.rb +7 -3
  87. data/spec/helpers/test_parser.rb +2 -0
  88. data/spec/norma_cql_spec.rb +5 -2
  89. data/spec/norma_ruby_spec.rb +4 -1
  90. data/spec/norma_ruby_sql_spec.rb +4 -1
  91. data/spec/norma_sql_spec.rb +4 -1
  92. data/spec/norma_tables_spec.rb +2 -2
  93. data/spec/ruby_api_spec.rb +1 -1
  94. data/spec/spec_helper.rb +2 -0
  95. data/spec/transform_surrogate_spec.rb +59 -0
  96. metadata +70 -60
  97. data/TODO +0 -308
  98. data/lib/activefacts/cql/compiler/join.rb +0 -162
  99. data/lib/activefacts/generate/oo.rb +0 -176
  100. data/lib/activefacts/generate/ordered.rb +0 -602
@@ -3,6 +3,7 @@
3
3
  # Copyright (c) 2008 Clifford Heath. Read the LICENSE file.
4
4
  #
5
5
 
6
+ require 'spec_helper'
6
7
  require 'activefacts/support'
7
8
  require 'activefacts/api/support'
8
9
  require 'activefacts/input/cql'
@@ -43,7 +43,7 @@ describe "When matching a reading with an existing fact type" do
43
43
  def value_should_match value, lit, unit = nil
44
44
  value.should_not be_nil
45
45
  value.literal.should == lit.to_s
46
- (!!value.is_a_string).should == lit.is_a?(String)
46
+ (!!value.is_literal_string).should == lit.is_a?(String)
47
47
  if unit
48
48
  value.unit.should_not be_nil
49
49
  value.unit.name.should == unit
@@ -52,14 +52,14 @@ describe "When matching a reading with an existing fact type" do
52
52
  end
53
53
  end
54
54
 
55
- def one_join_with_value v, unit = nil
56
- joins.size.should == 1
57
- (jss = join_steps).size.should == 2
58
- (jns = join_nodes).size.should == 3
55
+ def one_query_with_value v, unit = nil
56
+ queries.size.should == 1
57
+ (jss = steps).size.should == 2
58
+ (jns = variables).size.should == 3
59
59
  integer_node = jns.detect{|jn| jn.object_type.name == 'Integer'}
60
60
  integer_node.should_not be_nil
61
61
  value_should_match integer_node.value, v, unit
62
- # pending should test content of the join steps
62
+ # pending should test content of the steps
63
63
  end
64
64
 
65
65
  it "should create a comparison fact type" do
@@ -72,7 +72,7 @@ describe "When matching a reading with an existing fact type" do
72
72
  comparison_ft = (new_fact_types - [is_old_ft])[0]
73
73
  (comparison_ft.all_reading.map{ |r| r.expand }*', ').should == "Boolean = Age >= Integer"
74
74
 
75
- one_join_with_value 60, 'year'
75
+ one_query_with_value 60, 'year'
76
76
  end
77
77
 
78
78
  it "should create a comparison fact type twice without duplication"
@@ -83,7 +83,7 @@ describe "When matching a reading with an existing fact type" do
83
83
  (readings = new_fact_types[0].all_reading).size.should == 1
84
84
  readings.single.text.should == '{0} = {1} >= {2}'
85
85
 
86
- one_join_with_value 60, 'year'
86
+ one_query_with_value 60, 'year'
87
87
  end
88
88
  end
89
89
  end
@@ -121,7 +121,7 @@ require 'activefacts/api/support'
121
121
  require 'activefacts/cql/compiler'
122
122
  require File.dirname(__FILE__) + '/../helpers/compile_helpers' # Can't see how to include/extend these methods correctly
123
123
 
124
- describe "When compiling a join, " do
124
+ describe "When compiling a query, " do
125
125
  before :each do
126
126
  extend CompileHelpers
127
127
 
@@ -139,33 +139,6 @@ describe "When compiling a join, " do
139
139
 
140
140
  baseline
141
141
 
142
- =begin
143
- def self.baseline
144
- @base_facts = @constellation.FactType.values-@constellation.ImplicitFactType.values
145
- @base_objects = @constellation.ObjectType.values
146
- end
147
-
148
- def self.fact_types
149
- @constellation.FactType.values-@base_facts-@constellation.ImplicitFactType.values
150
- end
151
-
152
- def self.object_types
153
- @constellation.ObjectType.values-@base_objects
154
- end
155
-
156
- def self.fact_pcs fact_type
157
- fact_type.all_role.map{|r| r.all_role_ref.map{|rr| rr.role_sequence.all_presence_constraint.to_a}}.flatten.uniq
158
- end
159
-
160
- def self.derivation fact_type
161
- join = (joins = @constellation.Join.values.to_a)[0]
162
- # PENDING: When the fact type's roles are projected, use this instead:
163
- # joins = fact_type.all_role.map{|r| r.all_join_role.map{|jr| jr.join}}.flatten.uniq
164
- joins.size.should == 1
165
- joins[0]
166
- end
167
- =end
168
-
169
142
  def self.compile string
170
143
  lambda {
171
144
  @compiler.compile string
@@ -185,29 +158,29 @@ describe "When compiling a join, " do
185
158
  fact_type = fact_types[0]
186
159
  (pcs = fact_pcs(fact_type)).size.should == 0
187
160
  end
188
- it "should produce one join" do
161
+ it "should produce one query" do
189
162
  fact_type = fact_types[0]
190
- join = derivation(fact_type)
163
+ query = derivation(fact_type)
191
164
  end
192
- it "the join should have 3 nodes" do
165
+ it "the query should have 3 variables" do
193
166
  fact_type = fact_types[0]
194
- join = derivation(fact_type)
195
- nodes = join.all_join_node.to_a
196
- nodes.size.should == 3
167
+ query = derivation(fact_type)
168
+ variables = query.all_variable.to_a
169
+ variables.size.should == 3
197
170
  end
198
- it "the join should have 2 steps" do
171
+ it "the query should have 2 steps" do
199
172
  fact_type = fact_types[0]
200
- join = derivation(fact_type)
201
- steps = join.all_join_step.to_a
173
+ query = derivation(fact_type)
174
+ steps = query.all_step.to_a
202
175
  steps.size.should == 2
203
176
  end
204
177
 
205
- it "and should project the fact type roles from the join" do
206
- pending "Join roles are not yet projected" do
207
- join = derivation(fact_type)
208
- joins = fact_type.all_role.map{|r| r.all_join_role.map{|jr| jr.join}}.flatten.uniq
209
- joins.size == 1
210
- joins.should == [join]
178
+ it "and should project the fact type roles from the query" do
179
+ pending "Plays are not yet projected" do
180
+ query = derivation(fact_type)
181
+ queries = fact_type.all_role.map{|r| r.all_play.map{|play| play.query}}.flatten.uniq
182
+ queries.size == 1
183
+ queries.should == [query]
211
184
  end
212
185
  end
213
186
  end
@@ -20,7 +20,7 @@ describe "When compiling an entity type, " do
20
20
 
21
21
  def self.SingleFact &b
22
22
  lambda {|c|
23
- real_fact_types = c.FactType.values-c.ImplicitFactType.values
23
+ real_fact_types = c.FactType.values-c.LinkFactType.values
24
24
  real_fact_types.size.should == 1
25
25
  @fact_type = real_fact_types[0]
26
26
  b.call(@fact_type) if b
@@ -301,6 +301,7 @@ describe "When compiling an entity type, " do
301
301
  result = @compiler.compile(MatchingPrefix+test)
302
302
  puts @compiler.failure_reason unless result
303
303
  result.should_not be_nil
304
+ @compiler.vocabulary.finalise
304
305
  when Proc
305
306
  begin
306
307
  test.call(@compiler.vocabulary.constellation)
@@ -1,5 +1,5 @@
1
1
  #
2
- # ActiveFacts CQL Join Expressions
2
+ # ActiveFacts CQL Expressions
3
3
  # Copyright (c) 2009 Clifford Heath. Read the LICENSE file.
4
4
  #
5
5
 
@@ -55,7 +55,7 @@ describe "When compiling expressions" do
55
55
  comparison_ft = (new_fact_types - [is_old_ft])[0]
56
56
  (comparison_ft.all_reading.map{ |r| r.expand }*', ').should == "Boolean = Age >= product(Integer, sum(Integer, Integer))"
57
57
 
58
- # one_join_with_value 60, 'year'
58
+ # one_query_with_value 60, 'year'
59
59
  end
60
60
  end
61
61
  end
@@ -22,6 +22,7 @@ describe "When matching a reading" do
22
22
  }
23
23
  @compiler = ActiveFacts::CQL::Compiler.new('Test')
24
24
  @compiler.compile(prefix)
25
+ @compiler.vocabulary.finalise
25
26
  @constellation = @compiler.vocabulary.constellation
26
27
 
27
28
  baseline
@@ -219,8 +220,10 @@ describe "When matching a reading" do
219
220
  Girl is going out with ugly-Boy monster,
220
221
  Boy is going out with Girl;
221
222
  }
223
+ @compiler.vocabulary.finalise
222
224
  (new_fact_types = fact_types).size.should == 1
223
- (fact_type = new_fact_types[0]).all_reading.size.should == 2
225
+ fact_type = new_fact_types[0]
226
+ fact_type.all_reading.size.should == 2
224
227
  (pcs = fact_pcs(fact_type)).size.should == 1
225
228
  end
226
229
  end
@@ -11,76 +11,76 @@ require 'helpers/test_parser'
11
11
 
12
12
  describe "Parsing Invalid Numbers and Strings" do
13
13
  it "should fail to parse an octal number containing non-octal digits" do
14
- "a is written as b(08);".
15
- should fail_to_parse /Expected (.|\n)* after a is written as b\(0$/
14
+ "aa is written as b(08);".
15
+ should fail_to_parse /Expected (.|\n)* at .* after aa is written as b\(0$/
16
16
  end
17
17
 
18
18
  it "should fail to parse a hexadecimal number containing non-hexadecimal digits" do
19
- "a is written as b(0xDice);".
20
- should fail_to_parse /Expected (.|\n)* after a is written as b\(0$/
19
+ "aa is written as b(0xDice);".
20
+ should fail_to_parse /Expected (.|\n)* at .* after aa is written as b\(0$/
21
21
  end
22
22
 
23
23
  it "should fail to parse a negative number with an intervening space" do
24
- "a is written as b(- 1);".
25
- should fail_to_parse /Expected .* after a is written as b\(/
24
+ "aa is written as b(- 1);".
25
+ should fail_to_parse /Expected .* after aa is written as b\(/
26
26
  end
27
27
 
28
28
  it "should fail to parse an explicit positive number with an intervening space" do
29
- "a is written as b(+ 1);".
30
- should fail_to_parse /Expected .* after a is written as b\(/
29
+ "aa is written as b(+ 1);".
30
+ should fail_to_parse /Expected .* after aa is written as b\(/
31
31
  end
32
32
 
33
33
  it "should fail to parse a negative octal number" do
34
- "a is written as b(-077);".
35
- should fail_to_parse /Expected .* after a is written as b\(/
34
+ "aa is written as b(-077);".
35
+ should fail_to_parse /Expected .* after aa is written as b\(/
36
36
  end
37
37
 
38
38
  it "should fail to parse a negative hexadecimal number" do
39
- "a is written as b(-0xFace);".
40
- should fail_to_parse /Expected .* after a is written as b\(/
39
+ "aa is written as b(-0xFace);".
40
+ should fail_to_parse /Expected .* after aa is written as b\(/
41
41
  end
42
42
 
43
43
  it "should fail to parse invalid real numbers (no digits before or nonzero after the point)" do
44
- "a is written as b(.0);".
45
- should fail_to_parse /Expected .* after a is written as b\(/
44
+ "aa is written as b(.0);".
45
+ should fail_to_parse /Expected .* after aa is written as b\(/
46
46
  end
47
47
 
48
48
  it "should fail to parse invalid real numbers (no digits after or nonzero before the point)" do
49
- "a is written as b(0.);".
50
- should fail_to_parse /Expected .* after a is written as b\(/
49
+ "aa is written as b(0.);".
50
+ should fail_to_parse /Expected .* after aa is written as b\(/
51
51
  end
52
52
 
53
53
  it "should fail to parse a number with illegal whitespace before the exponent" do
54
- "inch converts to 1 inch; a is written as b() inch ^2 ; ".
55
- should fail_to_parse /Expected .* after a is written as b\(\) inch/
54
+ "inch converts to 1 inch; aa is written as b() inch ^2 ; ".
55
+ should fail_to_parse /Expected .* after aa is written as b\(\) inch/
56
56
  end
57
57
 
58
58
  it "should fail to parse a number with illegal whitespace around the exponent" do
59
- "inch converts to 1 inch; a is written as b() inch^ 2 ; ".
60
- should fail_to_parse /Expected .* after a is written as b\(\) inch/
59
+ "inch converts to 1 inch; aa is written as b() inch^ 2 ; ".
60
+ should fail_to_parse /Expected .* after aa is written as b\(\) inch/
61
61
  end
62
62
 
63
63
  it "should fail to parse a string with an illegal octal escape" do
64
- "a is written as b() restricted to { '\\7a' };".
65
- should fail_to_parse /Expected .* a is written as b\(\) restricted to \{ '/
64
+ "aa is written as b() restricted to { '\\7a' };".
65
+ should fail_to_parse /Expected .* aa is written as b\(\) restricted to \{ '/
66
66
  end
67
67
 
68
68
  it "should fail to parse a string with a control character" do
69
- "a is written as b() restricted to { '\001' };".
70
- should fail_to_parse /Expected .* a is written as b\(\) restricted to \{ '/
69
+ "aa is written as b() restricted to { '\001' };".
70
+ should fail_to_parse /Expected .* aa is written as b\(\) restricted to \{ '/
71
71
  end
72
72
 
73
73
  it "should fail to parse a string with a control character" do
74
- "a is written as b() restricted to { '\n' };".
75
- should fail_to_parse /Expected .* a is written as b\(\) restricted to \{ '/
74
+ "aa is written as b() restricted to { '\n' };".
75
+ should fail_to_parse /Expected .* aa is written as b\(\) restricted to \{ '/
76
76
  end
77
77
 
78
78
  it "should fail to parse a cross-typed range" do
79
- "a is written as b() restricted to { 0..'A' };".
80
- should fail_to_parse /Expected .* after a is written as b\(\) restricted to \{ 0\.\./
79
+ "aa is written as b() restricted to { 0..'A' };".
80
+ should fail_to_parse /Expected .* after aa is written as b\(\) restricted to \{ 0\.\./
81
81
 
82
- "a is written as b() restricted to { 'a'..27 };".
83
- should fail_to_parse /Expected .* after a is written as b\(\) restricted to \{ 'a'\.\./
82
+ "aa is written as b() restricted to { 'a'..27 };".
83
+ should fail_to_parse /Expected .* after aa is written as b\(\) restricted to \{ 'a'\.\./
84
84
  end
85
85
 
86
86
  end
@@ -37,14 +37,14 @@ describe "Entity Types" do
37
37
  [ "a is identified by b, c where d;", # Entity type declaration with two-part identifier
38
38
  ["EntityType: a [{b}, {c}] where [\"d\"];"]
39
39
  ],
40
- [ "a is written as b(); e is identified by a where d;",
41
- ["ValueType: a is written as b;", "EntityType: e [{a}] where [\"d\"];"]
40
+ [ "aa is written as b(); e is identified by aa where d;",
41
+ ["ValueType: aa is written as b;", "EntityType: e [{aa}] where [\"d\"];"]
42
42
  ],
43
- [ " a is written as b ( ) ; e is identified by a where d ; ",
44
- ["ValueType: a is written as b;", "EntityType: e [{a}] where [\"d\"];"]
43
+ [ " aa is written as b ( ) ; e is identified by aa where d ; ",
44
+ ["ValueType: aa is written as b;", "EntityType: e [{aa}] where [\"d\"];"]
45
45
  ],
46
- [ "e is written as b; a is identified by e where maybe d;",
47
- ["ValueType: e is written as b;", "EntityType: a [{e}] where [[\"maybe\"] \"d\"];"]
46
+ [ "e is written as b; aa is identified by e where maybe d;",
47
+ ["ValueType: e is written as b;", "EntityType: aa [{e}] where [maybe \"d\"];"]
48
48
  ],
49
49
  ]
50
50
 
@@ -64,16 +64,16 @@ describe "ASTs from Derived Fact Types with expressions" do
64
64
  Person(1) is ancestor of Person(2): maybe Person(1) is parent of Person(2) [transitive];
65
65
  }.should parse_to_ast \
66
66
  %q{FactType: [{Person(1)} "is ancestor of" {Person(2)}] where
67
- ["maybe", "transitive"] {Person(1)} "is parent of" {Person(2)}}
67
+ ["transitive"] maybe {Person(1)} "is parent of" {Person(2)}}
68
68
  end
69
69
 
70
70
  it "should parse a contracted reading with qualifiers" do
71
71
  %q{
72
72
  Person(1) provides lineage of Person(2): maybe Person(2) is child of Person(1) [transitive] who is male;
73
73
  }.should parse_to_ast \
74
- %q{FactType: [{Person(1)} "provides lineage of" {Person(2)}] where
75
- ["maybe", "transitive"] {Person(2)} "is child of" {Person(1)}
76
- who {Person(1)} "is male"}
74
+ %q{FactType: [{Person(1)} "provides lineage of" {Person(2)}] where
75
+ ["transitive"] maybe {Person(2)} "is child of" {Person(1)}
76
+ who {Person(1)} "is male"}
77
77
  end
78
78
 
79
79
  it "should parse a contracted readings and comparisons with qualifiers" do
@@ -83,10 +83,10 @@ describe "ASTs from Derived Fact Types with expressions" do
83
83
  who maybe is of Age [static]
84
84
  definitely >= 21;
85
85
  }.should parse_to_ast \
86
- %q{FactType: [{Person(1)} "is ancestor of adult" {Person(2)}] where
87
- ["maybe", "transitive"] {Person(1)} "is parent of" {Person(2)}
88
- who ["maybe", "static"] {Person(2)} "is of" {Age}
89
- >= compare>=({Age} 21, [definitely])}
86
+ %q{FactType: [{Person(1)} "is ancestor of adult" {Person(2)}] where
87
+ ["transitive"] maybe {Person(1)} "is parent of" {Person(2)}
88
+ who ["static"] maybe {Person(2)} "is of" {Age}
89
+ >= compare>=({Age} 21)}
90
90
  end
91
91
 
92
92
  it "should parse a comparison expression with a contracted reading" do
@@ -102,10 +102,10 @@ describe "ASTs from Derived Fact Types with expressions" do
102
102
  %q{
103
103
  Director is old: Person directs company, Person is of Age, maybe 20 <= Age definitely < 60;
104
104
  }.should parse_to_ast \
105
- %q{FactType: [{Director} "is old"] where {Person} "directs company" ,
106
- {Person} "is of" {Age} ,
107
- compare<=(20 {Age}, [maybe])
108
- < compare<({Age} 60, [definitely])}
105
+ %q{FactType: [{Director} "is old"] where {Person} "directs company" ,
106
+ {Person} "is of" {Age} ,
107
+ compare<=(maybe 20 {Age})
108
+ < compare<({Age} 60)}
109
109
  end
110
110
 
111
111
  it "should parse a comparison expression with right-contracted then left-contracted comparisons"
@@ -122,18 +122,18 @@ describe "ASTs from Derived Fact Types with expressions" do
122
122
  %q{
123
123
  A is a farce: maybe A has completely- B [transitive, acyclic] < 5, B -c = 2;
124
124
  }.should parse_to_ast \
125
- %q{FactType: [{A} "is a farce"] where ["acyclic", "maybe", "transitive"] {A} "has" {completely- B}
126
- < compare<({completely- B} 5)
127
- , compare=({B -c} 2)}
125
+ %q{FactType: [{A} "is a farce"] where ["acyclic", "transitive"] maybe {A} "has" {completely- B}
126
+ < compare<({completely- B} 5)
127
+ , compare=({B -c} 2)}
128
128
  end
129
129
 
130
130
  it "should parse multiple leading and trailing adjectives with contracted comparisons" do
131
131
  %q{
132
132
  A is a farce: maybe A has completely- green B [transitive, acyclic] < 9, B c -d = 2;
133
133
  }.should parse_to_ast \
134
- %q{FactType: [{A} "is a farce"] where ["acyclic", "maybe", "transitive"] {A} "has" {completely- green B}
135
- < compare<({completely- green B} 9)
136
- , compare=({B c -d} 2)}
134
+ %q{FactType: [{A} "is a farce"] where ["acyclic", "transitive"] maybe {A} "has" {completely- green B}
135
+ < compare<({completely- green B} 9)
136
+ , compare=({B c -d} 2)}
137
137
  end
138
138
 
139
139
  it "should parse a comparison clause containing units" do
@@ -163,11 +163,17 @@ describe "ASTs from Derived Fact Types with expressions" do
163
163
 
164
164
  it "should parse a fact type containing an expression with subscripts"
165
165
 
166
- it "should parse a fact type containing objectification joins and contractions" do
166
+ it "should parse a fact type containing objectification steps and contractions" do
167
167
  %q{
168
168
  Driving was negligent where
169
169
  Driving (where maybe Driver drove in Incident [acyclic] that definitely is of Claim [intransitive]) followed Intoxication [static];
170
170
  }.should parse_to_ast \
171
+ %q{
172
+ FactType: [{Driving} "was negligent"] where ["static"] {Driving}
173
+ (where ["acyclic"] maybe {Driver} "drove in" {Incident}
174
+ that ["intransitive"] {Incident} "is of" {Claim})
175
+ "followed" {Intoxication}
176
+ }
171
177
  %q{
172
178
  FactType: [{Driving} "was negligent"] where ["static"] {Driving}
173
179
  (where ["acyclic", "maybe"] {Driver} "drove in" {Incident}
@@ -51,11 +51,11 @@ describe "Sample data" do
51
51
  "Company has Company Name 'Microsoft';",
52
52
  [{:facts=>Set["Company has Company Name 'Microsoft'"], :instances=>Set["Company is identified by Company Name where Company has Company Name 'Microsoft'", "Company Name 'Microsoft'"]}]
53
53
  ],
54
- [ # The Company instance asserted with an joined identifying instance
54
+ [ # The Company instance asserted with a related identifying instance
55
55
  "Company has Company Name, Company Name 'Microsoft';",
56
56
  [{:facts=>Set["Company has Company Name 'Microsoft'"], :instances=>Set["Company is identified by Company Name where Company has Company Name 'Microsoft'", "Company Name 'Microsoft'"]}]
57
57
  ],
58
- [ # The same, with an explicit identifying instance join
58
+ [ # The same, with an explicit identifying value step
59
59
  "Company Name 'Microsoft', Company has Company Name;",
60
60
  [{:facts=>Set["Company has Company Name 'Microsoft'"], :instances=>Set["Company is identified by Company Name where Company has Company Name 'Microsoft'", "Company Name 'Microsoft'"]}]
61
61
  ],
@@ -107,7 +107,7 @@ describe "Sample data" do
107
107
  if v.to_s !~ /[^-+0-9.]/ and (n = eval(v.to_s) rescue nil)
108
108
  n
109
109
  else
110
- "'"+v.to_s.gsub(/'/,'\\\'')+"'"
110
+ v.to_s
111
111
  end
112
112
  end
113
113
 
@@ -179,6 +179,7 @@ describe "Sample data" do
179
179
  lambda do
180
180
  begin
181
181
  @vocabulary = ActiveFacts::Input::CQL.readstring(@text)
182
+ @vocabulary.finalise
182
183
  rescue => exception
183
184
  if debug :exception
184
185
  puts "#{exception.message}"
@@ -220,7 +221,7 @@ describe "Sample data" do
220
221
 
221
222
  BadSamples.each do |c|
222
223
  source, missing = *Array(c)
223
- it "should detect missing joins in #{source.inspect}" do
224
+ it "should detect missing queries in #{source.inspect}" do
224
225
  @text = SamplePrefix+source
225
226
  lambda do
226
227
  begin