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
@@ -0,0 +1,19 @@
1
+ #
2
+ # ActiveFacts tests: Test the CQL parser by looking at its parse trees.
3
+ # Copyright (c) 2008 Clifford Heath. Read the LICENSE file.
4
+ #
5
+
6
+ require 'activefacts/cql'
7
+ require 'activefacts/support'
8
+ require 'activefacts/api/support'
9
+ require 'spec_helper'
10
+ require 'helpers/test_parser'
11
+
12
+ describe "ASTs from Derived Fact Types with expressions" do
13
+ it "should parse a simple comparison clause" do
14
+ %q{
15
+ each combination FamilyName, GivenName occurs at most one time in Competitor has FamilyName, Competitor has GivenName;
16
+ }.should parse_to_ast \
17
+ "PresenceConstraint over [[{Competitor} \"has\" {FamilyName}], [{Competitor} \"has\" {GivenName}]] -1 over ({FamilyName}, {GivenName})"
18
+ end
19
+ end
@@ -0,0 +1,106 @@
1
+ #
2
+ # ActiveFacts tests: Test the CQL parser by looking at its parse trees.
3
+ # Copyright (c) 2008 Clifford Heath. Read the LICENSE file.
4
+ #
5
+
6
+ require 'activefacts/cql'
7
+ require 'activefacts/support'
8
+ require 'activefacts/api/support'
9
+ require 'helpers/test_parser'
10
+
11
+ describe "Entity Types" do
12
+ EntityTypes_RefMode = [
13
+ [ "a is identified by its id;", # Entity type declaration with reference mode
14
+ ["EntityType: a identified by its id;"]
15
+ ],
16
+ [ "a is identified by its number(12);", # Entity type declaration with reference mode
17
+ ["EntityType: a identified by its number(12);"]
18
+ ],
19
+ [ "a is identified by its id where c;", # Entity type declaration with reference mode and fact type(s)
20
+ ["EntityType: a identified by its id where [{c}];"]
21
+ ],
22
+ [ "a is identified by its id where c;", # Entity type declaration with reference mode and where
23
+ ["EntityType: a identified by its id where [{c}];"]
24
+ ],
25
+ ]
26
+
27
+ EntityTypes_Simple = [
28
+ [ "a is identified by b where c;", # Entity type declaration
29
+ ["EntityType: a [{b}] where [{c}];"]
30
+ ],
31
+ [ "a is identified by b where c;", # Entity type declaration with where
32
+ ["EntityType: a [{b}] where [{c}];"]
33
+ ],
34
+ [ "a is identified by b and c where d;", # Entity type declaration with two-part identifier
35
+ ["EntityType: a [{b}, {c}] where [\"d\"];"]
36
+ ],
37
+ [ "a is identified by b, c where d;", # Entity type declaration with two-part identifier
38
+ ["EntityType: a [{b}, {c}] where [\"d\"];"]
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\"];"]
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\"];"]
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\"];"]
48
+ ],
49
+ ]
50
+
51
+ EntityTypes_Objectified = [
52
+ [ "Director is where b directs c, c is directed by b;",
53
+ ["FactType: Director [{b} \"directs\" {c}, {c} \"is directed by\" {b}]"]
54
+ ],
55
+ ]
56
+
57
+ EntityTypes_Subtypes = [
58
+ [ "Employee is a kind of Person;",
59
+ ["EntityType: Employee < Person nil;"]
60
+ ],
61
+ [ "Employee is a subtype of Person;",
62
+ ["EntityType: Employee < Person nil;"]
63
+ ],
64
+ [ "AustralianEmployee is a subtype of Employee, Australian;",
65
+ ["EntityType: AustralianEmployee < Employee,Australian nil;"]
66
+ ],
67
+ [ "Employee is a kind of Person identified by EmployeeNumber;",
68
+ ["EntityType: Employee < Person [{EmployeeNumber}];"]
69
+ ],
70
+ [ "Employee is a subtype of Person identified by EmployeeNumber;",
71
+ ["EntityType: Employee < Person [{EmployeeNumber}];"]
72
+ ],
73
+ [ "AustralianEmployee is a subtype of Employee, Australian identified by TaxFileNumber;",
74
+ ["EntityType: AustralianEmployee < Employee,Australian [{TaxFileNumber}];"]
75
+ ],
76
+ ]
77
+
78
+ EntityTypes =
79
+ EntityTypes_RefMode +
80
+ EntityTypes_Simple +
81
+ EntityTypes_Objectified +
82
+ EntityTypes_Subtypes
83
+
84
+ before :each do
85
+ @parser = TestParser.new
86
+ @parser.parse_all("c is written as b;", :definition)
87
+ end
88
+
89
+ EntityTypes.each do |c|
90
+ source, ast = *c
91
+ it "should parse #{source.inspect}" do
92
+ result = @parser.parse_all(source, :definition)
93
+
94
+ puts @parser.failure_reason unless result
95
+ result.should_not be_nil
96
+
97
+ canonical_form = result.map{|d| d.ast.to_s}
98
+ if ast
99
+ canonical_form.should == ast
100
+ else
101
+ puts "#{source.inspect} should compile to"
102
+ puts "\t#{canonical_form}"
103
+ end
104
+ end
105
+ end
106
+ end
@@ -0,0 +1,179 @@
1
+ #
2
+ # ActiveFacts tests: Test the CQL parser by looking at its parse trees.
3
+ # Copyright (c) 2008 Clifford Heath. Read the LICENSE file.
4
+ #
5
+
6
+ require 'activefacts/cql'
7
+ require 'activefacts/support'
8
+ require 'activefacts/api/support'
9
+ require 'spec_helper'
10
+ require 'helpers/test_parser'
11
+
12
+ describe "ASTs from Derived Fact Types with expressions" do
13
+ it "should parse a simple comparison clause" do
14
+ # Director is old: Company is directed by Person who is of Age > 60;
15
+ %q{
16
+ Director is old: Person directs Company, Person is of Age, Age > 60;
17
+ }.should parse_to_ast \
18
+ %q{FactType: [{Director} "is old"] where {Person} "directs" {Company} ,
19
+ {Person} "is of" {Age} ,
20
+ compare>({Age} 60)}
21
+ end
22
+
23
+ it "should parse a comparison clause with subscripts" do
24
+ %q{
25
+ Director is old: Person directs Company, Person has Salary(2), Person is of Age(1), Age(1) > Salary(2);
26
+ }.should parse_to_ast \
27
+ %q{
28
+ FactType: [{Director} "is old"]
29
+ where {Person} "directs" {Company} ,
30
+ {Person} "has" {Salary(2)} ,
31
+ {Person} "is of" {Age(1)} ,
32
+ compare>({Age(1)} {Salary(2)})
33
+ }
34
+ end
35
+
36
+ it "should parse simple comparison clause having an unmarked adjective" do
37
+ %q{
38
+ Person is independent: Person has taxable- Income and taxable Income >= 20000 dollars or Person has sugar-Daddy;
39
+ }.should parse_to_ast \
40
+ %q{FactType: [{Person} "is independent"] where {Person} "has" {taxable- Income} and
41
+ compare>=({taxable- Income} (20000 in dollars)) or {Person} "has" {sugar- Daddy}}
42
+ end
43
+
44
+ it "should parse a reading with a contracted comparison expression" do
45
+ %q{
46
+ Director is old: Person directs company, Person is of Age > 20+2*20;
47
+ }.should parse_to_ast \
48
+ %q{FactType: [{Director} "is old"] where {Person} "directs company" ,
49
+ {Person} "is of" {Age}
50
+ > compare>({Age} sum(20 product(2 20)))}
51
+ end
52
+
53
+ it "should parse a right-contracted comparison clause after a right-contracted clause" do
54
+ %q{
55
+ Director is old: Company is directed by Person who is of Age > 60;
56
+ }.should parse_to_ast \
57
+ %q{FactType: [{Director} "is old"] where {Company} "is directed by" {Person} who
58
+ {Person} "is of" {Age} >
59
+ compare>({Age} 60)}
60
+ end
61
+
62
+ it "should parse a simple reading with qualifiers" do
63
+ %q{
64
+ Person(1) is ancestor of Person(2): maybe Person(1) is parent of Person(2) [transitive];
65
+ }.should parse_to_ast \
66
+ %q{FactType: [{Person(1)} "is ancestor of" {Person(2)}] where
67
+ ["maybe", "transitive"] {Person(1)} "is parent of" {Person(2)}}
68
+ end
69
+
70
+ it "should parse a contracted reading with qualifiers" do
71
+ %q{
72
+ Person(1) provides lineage of Person(2): maybe Person(2) is child of Person(1) [transitive] who is male;
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"}
77
+ end
78
+
79
+ it "should parse a contracted readings and comparisons with qualifiers" do
80
+ %q{
81
+ Person(1) is ancestor of adult Person(2):
82
+ maybe Person(1) is parent of Person(2) [transitive]
83
+ who maybe is of Age [static]
84
+ definitely >= 21;
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])}
90
+ end
91
+
92
+ it "should parse a comparison expression with a contracted reading" do
93
+ %q{
94
+ Director is old: Person directs company, 3*30 >= Age that is of Person;
95
+ }.should parse_to_ast \
96
+ %q{FactType: [{Director} "is old"] where {Person} "directs company" ,
97
+ compare>=(product(3 30) {Age})
98
+ that {Age} "is of" {Person}}
99
+ end
100
+
101
+ it "should parse a comparison expression with a contracted comparison" do
102
+ %q{
103
+ Director is old: Person directs company, Person is of Age, maybe 20 <= Age definitely < 60;
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])}
109
+ end
110
+
111
+ it "should parse a comparison expression with right-contracted then left-contracted comparisons"
112
+ # Director is probably adult: Person directs company, Person is of Age maybe >= 21 and definitely < 60;
113
+ # end
114
+
115
+ it "should fail to parse a contracted comparison that doesn't follow a role" do
116
+ %q{
117
+ Director is old: Person directs company, Person is of Age considerable > 3*20;
118
+ }.should fail_to_parse /Expected (.|\n)* after (.|\n)* Age considerable $/
119
+ end
120
+
121
+ it "should parse pre and post-qualifiers and leading and trailing adjectives with contracted comparisons" do
122
+ %q{
123
+ A is a farce: maybe A has completely- B [transitive, acyclic] < 5, B -c = 2;
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)}
128
+ end
129
+
130
+ it "should parse multiple leading and trailing adjectives with contracted comparisons" do
131
+ %q{
132
+ A is a farce: maybe A has completely- green B [transitive, acyclic] < 9, B c -d = 2;
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)}
137
+ end
138
+
139
+ it "should parse a comparison clause containing units" do
140
+ %q{
141
+ 254 mm converts to foot/feet;
142
+ Width is written as Integer mm;
143
+ Window requires toughening where
144
+ Window has Width,
145
+ Window has Height,
146
+ Width * Height >= 10 feet^2;
147
+ }.should parse_to_ast \
148
+ %q{Unit(foot/feet) is 254/1+0 mm^1},
149
+ %q{ValueType: Width is written as Integer in [["mm", 1]];},
150
+ %q{FactType: [{Window} "requires toughening"] where {Window} "has" {Width} ,
151
+ {Window} "has" {Height}
152
+ , compare>=(product({Width} {Height}) (10 in feet^2))}
153
+ end
154
+
155
+ it "should parse nested expressions" do
156
+ %q{
157
+ A is written as B;
158
+ A > B+3*(4+5)?
159
+ }.should parse_to_ast \
160
+ %q{ValueType: A is written as B;},
161
+ %q{FactType: [] where compare>({A} sum({B} product(3 sum(4 5))))}
162
+ end
163
+
164
+ it "should parse a fact type containing an expression with subscripts"
165
+
166
+ it "should parse a fact type containing objectification joins and contractions" do
167
+ %q{
168
+ Driving was negligent where
169
+ Driving (where maybe Driver drove in Incident [acyclic] that definitely is of Claim [intransitive]) followed Intoxication [static];
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 ["definitely", "intransitive"] {Incident} "is of" {Claim})
175
+ "followed" {Intoxication}
176
+ }
177
+ end
178
+
179
+ end
@@ -0,0 +1,41 @@
1
+ #
2
+ # ActiveFacts tests: Test the CQL parser by looking at its parse trees.
3
+ # Copyright (c) 2008 Clifford Heath. Read the LICENSE file.
4
+ #
5
+
6
+ require 'activefacts/cql'
7
+ require 'activefacts/support'
8
+ require 'activefacts/api/support'
9
+ require 'spec_helper'
10
+ require 'helpers/test_parser'
11
+
12
+ describe "Fact Types" do
13
+ FactTypes = [
14
+ [ "Foo has at most one Bar, Bar is of one Foo restricted to {1..10};",
15
+ ["FactType: [{Foo} \"has\" {[..1] Bar}, {Bar} \"is of\" {[1..1] Foo ValueConstraint to ([1..10])}]"]
16
+ ],
17
+ [ "Bar(1) is related to Bar(2), primary-Bar(1) has secondary-Bar(2);",
18
+ ["FactType: [{Bar(1)} \"is related to\" {Bar(2)}, {primary- Bar(1)} \"has\" {secondary- Bar(2)}]"]
19
+ ],
20
+ # REVISIT: Test all quantifiers
21
+ # REVISIT: Test all post-qualifiers
22
+ # [ "AnnualIncome is where Person has total- Income in Year: Person has total- Income.sum(), Income was earned in current- Time.Year() (as Year);",
23
+ # [%q{FactType: AnnualIncome [{Person} "has" {total- Income} "in" {Year}] where {Person} "has" {total- Income}.sum() , {Income} "was earned in" {current- Time (as Year)}.Year()}]
24
+ # ],
25
+ [ "A is interesting : b- C has F -g;",
26
+ ["FactType: [{A} \"is interesting\"] where {b- C} \"has\" {F -g}"]
27
+ ]
28
+ # REVISIT: Test all quantifiers
29
+ ]
30
+
31
+ before :each do
32
+ @parser = TestParser.new
33
+ end
34
+
35
+ FactTypes.each do |c|
36
+ source, ast, definition = *c
37
+ it "should parse #{source.inspect}" do
38
+ source.should parse_to_ast *ast
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,312 @@
1
+ #
2
+ # ActiveFacts tests: Test the CQL parser by looking at its parse trees.
3
+ # Copyright (c) 2008 Clifford Heath. Read the LICENSE file.
4
+ #
5
+
6
+ require 'activefacts/cql'
7
+ require 'activefacts/support'
8
+ require 'activefacts/api/support'
9
+ require 'helpers/test_parser'
10
+
11
+ describe "Valid Numbers, Strings and Ranges" do
12
+ ValidNumbersEtc = [
13
+ [ "a is written as b;", # Value type declaration, no params, minimal whitespace
14
+ ['ValueType: a is written as b;']
15
+ ],
16
+ [ "a is written as B;", # Value type declaration, no params, minimal whitespace
17
+ ['ValueType: a is written as B;']
18
+ ],
19
+ [ "a is written as b();", # Value type declaration, minimal whitespace
20
+ ['ValueType: a is written as b;']
21
+ ],
22
+ [ "a is written as b ;", # Value type declaration, no params, trailing whitespace
23
+ ['ValueType: a is written as b;']
24
+ ],
25
+ [ "a is written as b ( ) ; ", # Value type declaration, maximal whitespace
26
+ ['ValueType: a is written as b;']
27
+ ],
28
+
29
+ # Comments and newlines, etc as whitespace
30
+ [ "\na\nis written as \nb\n(\n)\n;\n", # Basic value type declaration, newlines for whitespace
31
+ ['ValueType: a is written as b;']
32
+ ],
33
+ [ "\ra\ris written as\rb\r(\r)\r;\r", # Basic value type declaration, returns for whitespace
34
+ ['ValueType: a is written as b;']
35
+ ],
36
+ [ "\ta\tis written as\tb\t(\t)\t;\t", # Basic value type declaration, tabs for whitespace
37
+ ['ValueType: a is written as b;']
38
+ ],
39
+ [ " /* Plugh */ a /* Plugh */ is written as\n b /* *Plugh* / */ ( /* *Plugh* / */ ) /* *Plugh* / */ ; /* *Plugh* / */ ",
40
+ ['ValueType: a is written as b;']
41
+ ],
42
+ [ "//Plugh\na // Plugh\n is written as // Plugh\n b // Plugh\n ( // Plugh\n ) // Plugh\n ; // Plugh\n ",
43
+ ['ValueType: a is written as b;']
44
+ ],
45
+
46
+ # Integers
47
+ [ "a is written as b(0);", # Integer zero
48
+ ['ValueType: a is written as b(0);']
49
+ ],
50
+ [ "a is written as b( 0 ) ; ", # Integer zero, maximal whitespace
51
+ ['ValueType: a is written as b(0);']
52
+ ],
53
+ [ "a is written as b(1);", # Integer one
54
+ ['ValueType: a is written as b(1);']
55
+ ],
56
+ [ "a is written as b(-1);", # Integer negative one
57
+ ['ValueType: a is written as b(-1);']
58
+ ],
59
+ [ "a is written as b(+1);", # Positive integer
60
+ ['ValueType: a is written as b(1);']
61
+ ],
62
+ [ "a is written as b(1e4);", # Integer with exponent
63
+ ['ValueType: a is written as b(10000.0);']
64
+ ],
65
+ [ "a is written as b(1e-4);", # Integer with negative exponent
66
+ ['ValueType: a is written as b(0.0001);']
67
+ ],
68
+ [ "a is written as b(-1e-4);", # Negative integer with negative exponent
69
+ ['ValueType: a is written as b(-0.0001);']
70
+ ],
71
+ [ "a is written as b(077);", # Octal integer
72
+ ['ValueType: a is written as b(63);']
73
+ ],
74
+ [ "a is written as b(0xFace8);", # Hexadecimal integer
75
+ ['ValueType: a is written as b(1027304);']
76
+ ],
77
+ [ "a is written as b(0,1);", # Two parameters
78
+ ['ValueType: a is written as b(0, 1);']
79
+ ],
80
+ [ "a is written as b( 0 , 1 );",
81
+ ['ValueType: a is written as b(0, 1);']
82
+ ],
83
+ [ "a is written as b(0,1,2) ;", # Three parameters now allowed
84
+ ['ValueType: a is written as b(0, 1, 2);']
85
+ ],
86
+
87
+ # Reals
88
+ [ "a is written as b(1.0);",
89
+ ['ValueType: a is written as b(1.0);']
90
+ ],
91
+ [ "a is written as b(-1.0);",
92
+ ['ValueType: a is written as b(-1.0);']
93
+ ],
94
+ [ "a is written as b(+1.0);",
95
+ ['ValueType: a is written as b(1.0);']
96
+ ],
97
+ [ "a is written as b(0.1);",
98
+ ['ValueType: a is written as b(0.1);']
99
+ ],
100
+ [ "a is written as b(-0.1);",
101
+ ['ValueType: a is written as b(-0.1);']
102
+ ],
103
+ [ "a is written as b(+0.1);",
104
+ ['ValueType: a is written as b(0.1);']
105
+ ],
106
+ [ "a is written as b(0.0);",
107
+ ['ValueType: a is written as b(0.0);']
108
+ ],
109
+ [ "a is written as b(-0.0);",
110
+ ['ValueType: a is written as b(-0.0);']
111
+ ],
112
+ [ "a is written as b(+0.0);",
113
+ ['ValueType: a is written as b(0.0);']
114
+ ],
115
+
116
+ # Value types with units
117
+ [ "a is written as b inch;", # Value type declaration with unit
118
+ ['ValueType: a is written as b in [["inch", 1]];']
119
+ ],
120
+ [ "a is written as b() inch ; ", # Value type declaration with unit and whitespace
121
+ ['ValueType: a is written as b in [["inch", 1]];']
122
+ ],
123
+ [ "a is written as b() inch;", # Value type declaration with unit
124
+ ['ValueType: a is written as b in [["inch", 1]];']
125
+ ],
126
+ [ "a is written as b inch^2;", # Value type declaration with unit and exponent
127
+ ['ValueType: a is written as b in [["inch", 2]];']
128
+ ],
129
+ [ "a is written as b() inch^2 ; ", # Value type declaration with unit and exponent with maximum whitespace
130
+ ['ValueType: a is written as b in [["inch", 2]];']
131
+ ],
132
+ [ "a is written as b second^-1;", # Value type declaration with unit and negative exponent
133
+ ['ValueType: a is written as b in [["second", -1]];']
134
+ ],
135
+ [ "a is written as b inch inch;", # Value type declaration with repeated unit
136
+ ['ValueType: a is written as b in [["inch", 1], ["inch", 1]];']
137
+ ],
138
+ [ "a is written as b inch^2/minute^-1;", # Value type declaration with unit and divided unit with exponents
139
+ ['ValueType: a is written as b in [["inch", 2], ["minute", 1]];']
140
+ ],
141
+ [ "a is written as b() second^-1/mm^-1 mm^-1;", # Value type declaration with repeated divided unit
142
+ ['ValueType: a is written as b in [["second", -1], ["mm", 1], ["mm", 1]];']
143
+ ],
144
+
145
+ # Integer value constraints
146
+ [ "a is written as b()restricted to{1};", # Integer, minimal whitespace
147
+ ['ValueType: a is written as b ValueConstraint to ([1]);']
148
+ ],
149
+ [ "a is written as b() restricted to { 1 } ;", # Integer, maximal whitespace
150
+ ['ValueType: a is written as b ValueConstraint to ([1]);']
151
+ ],
152
+ [ "a is written as b() restricted to {1..2};", # Integer range, minimal whitespace
153
+ ['ValueType: a is written as b ValueConstraint to ([1..2]);']
154
+ ],
155
+ [ "a is written as b() restricted to { 1 .. 2 };", # Integer range, maximal whitespace
156
+ ['ValueType: a is written as b ValueConstraint to ([1..2]);']
157
+ ],
158
+ [ "a is written as b() restricted to {..2};", # Integer range with open start, minimal whitespace
159
+ ['ValueType: a is written as b ValueConstraint to ([-Infinity..2]);']
160
+ ],
161
+ [ "a is written as b() restricted to { .. 2 };", # Integer range with open start, maximal whitespace
162
+ ['ValueType: a is written as b ValueConstraint to ([-Infinity..2]);']
163
+ ],
164
+ [ "a is written as b() restricted to { ..2,3};", # Range followed by integer, minimal whitespace
165
+ ['ValueType: a is written as b ValueConstraint to ([-Infinity..2, 3]);']
166
+ ],
167
+ [ "a is written as b() restricted to { 1,..2,3};", # Integer, open-start range, integer, minimal whitespace
168
+ ['ValueType: a is written as b ValueConstraint to ([1, -Infinity..2, 3]);']
169
+ ],
170
+ [ "a is written as b() restricted to { .. 2 , 3 };", # Range followed by integer, maximal whitespace
171
+ ['ValueType: a is written as b ValueConstraint to ([-Infinity..2, 3]);']
172
+ ],
173
+ [ "a is written as b() restricted to { ..2 , 3..4 };",# Range followed by range
174
+ ['ValueType: a is written as b ValueConstraint to ([-Infinity..2, 3..4]);']
175
+ ],
176
+ [ "a is written as b() restricted to { ..2, 3..};", # Range followed by range with open end, minimal whitespace
177
+ ['ValueType: a is written as b ValueConstraint to ([-Infinity..2, 3..Infinity]);']
178
+ ],
179
+ [ "a is written as b() restricted to { ..2, 3 .. };", # Range followed by range with open end, maximal whitespace
180
+ ['ValueType: a is written as b ValueConstraint to ([-Infinity..2, 3..Infinity]);']
181
+ ],
182
+ [ "a is written as b() restricted to { 1e4 } ;", # Integer with exponent
183
+ ['ValueType: a is written as b ValueConstraint to ([10000.0]);']
184
+ ],
185
+ [ "a is written as b() restricted to { -1e4 } ;", # Negative integer with exponent
186
+ ['ValueType: a is written as b ValueConstraint to ([-10000.0]);']
187
+ ],
188
+ [ "a is written as b() restricted to { 1e-4 } ;", # Integer with negative exponent
189
+ ['ValueType: a is written as b ValueConstraint to ([0.0001]);']
190
+ ],
191
+ [ "a is written as b() restricted to { -1e-4 } ;", # Negative integer with negative exponent
192
+ ['ValueType: a is written as b ValueConstraint to ([-0.0001]);']
193
+ ],
194
+
195
+ # Real value constraints
196
+ [ "a is written as b() restricted to {1.0};", # Real, minimal whitespace
197
+ ['ValueType: a is written as b ValueConstraint to ([1.0]);']
198
+ ],
199
+ [ "a is written as b() restricted to { 1.0 } ;", # Real, maximal whitespace
200
+ ['ValueType: a is written as b ValueConstraint to ([1.0]);']
201
+ ],
202
+ [ "a is written as b() restricted to { 1.0e4 } ;", # Real with exponent
203
+ ['ValueType: a is written as b ValueConstraint to ([10000.0]);']
204
+ ],
205
+ [ "a is written as b() restricted to { 1.0e-4 } ;", # Real with negative exponent
206
+ ['ValueType: a is written as b ValueConstraint to ([0.0001]);']
207
+ ],
208
+ [ "a is written as b() restricted to { -1.0e-4 } ;", # Negative real with negative exponent
209
+ ['ValueType: a is written as b ValueConstraint to ([-0.0001]);']
210
+ ],
211
+ [ "a is written as b() restricted to { 1.1 .. 2.2 } ;", # Real range, maximal whitespace
212
+ ['ValueType: a is written as b ValueConstraint to ([1.1..2.2]);']
213
+ ],
214
+ [ "a is written as b() restricted to { -1.1 .. 2.2 } ;", # Real range, maximal whitespace
215
+ ['ValueType: a is written as b ValueConstraint to ([-1.1..2.2]);']
216
+ ],
217
+ [ "a is written as b() restricted to { 1.1..2.2};", # Real range, minimal whitespace
218
+ ['ValueType: a is written as b ValueConstraint to ([1.1..2.2]);']
219
+ ],
220
+ [ "a is written as b() restricted to { 1.1..2 } ;", # Real-integer range
221
+ ['ValueType: a is written as b ValueConstraint to ([1.1..2]);']
222
+ ],
223
+ [ "a is written as b() restricted to { 1..2.2 } ;", # Integer-real range
224
+ ['ValueType: a is written as b ValueConstraint to ([1..2.2]);']
225
+ ],
226
+ [ "a is written as b() restricted to { ..2.2};", # Real range with open start
227
+ ['ValueType: a is written as b ValueConstraint to ([-Infinity..2.2]);']
228
+ ],
229
+ [ "a is written as b() restricted to { 1.1.. };", # Real range with open end
230
+ ['ValueType: a is written as b ValueConstraint to ([1.1..Infinity]);']
231
+ ],
232
+ [ "a is written as b() restricted to { 1.1.., 2 };", # Real range with open end and following integer
233
+ ['ValueType: a is written as b ValueConstraint to ([1.1..Infinity, 2]);']
234
+ ],
235
+
236
+ # Strings and string value constraints
237
+ [ "a is written as b() restricted to {''};", # String, empty, minimal whitespace
238
+ ['ValueType: a is written as b ValueConstraint to (["\'\'"]);']
239
+ ],
240
+ [ "a is written as b() restricted to {'A'};", # String, minimal whitespace
241
+ ['ValueType: a is written as b ValueConstraint to (["\'A\'"]);']
242
+ ],
243
+ [ "a is written as b() restricted to { 'A' };", # String, maximal whitespace
244
+ ['ValueType: a is written as b ValueConstraint to (["\'A\'"]);']
245
+ ],
246
+ [ "a is written as b() restricted to { '\\b\\t\\f\\n\\r\\e\\\\' };", # String with special escapes
247
+ ["ValueType: a is written as b ValueConstraint to ([\"'\\\\b\\\\t\\\\f\\\\n\\\\r\\\\e\\\\\\\\'\"]);"]
248
+ ],
249
+ [ "a is written as b() restricted to { ' ' };", # String with space
250
+ ['ValueType: a is written as b ValueConstraint to (["\' \'"]);']
251
+ ],
252
+ [ "a is written as b() restricted to { '\t' };", # String with literal tab
253
+ ['ValueType: a is written as b ValueConstraint to (["\'\t\'"]);']
254
+ ],
255
+ [ "a is written as b() restricted to { '\\0' };", # String with nul character
256
+ ["ValueType: a is written as b ValueConstraint to ([\"'\\\\0'\"]);"]
257
+ ],
258
+ [ "a is written as b() restricted to { '\\077' };", # String with octal escape
259
+ ["ValueType: a is written as b ValueConstraint to ([\"'\\\\077'\"]);"]
260
+ ],
261
+ [ "a is written as b() restricted to { '\\0xA9' };", # String with hexadecimal escape
262
+ ["ValueType: a is written as b ValueConstraint to ([\"'\\\\0xA9'\"]);"]
263
+ ],
264
+ [ "a is written as b() restricted to { '\\0uBabe' };",# String with unicode escape
265
+ ["ValueType: a is written as b ValueConstraint to ([\"'\\\\0uBabe'\"]);"]
266
+ ],
267
+ [ "a is written as b() restricted to {'A'..'F'};", # String range, minimal whitespace
268
+ ['ValueType: a is written as b ValueConstraint to (["\'A\'".."\'F\'"]);']
269
+ ],
270
+ [ "a is written as b() restricted to { 'A' .. 'F' };",# String range, maximal whitespace
271
+ ['ValueType: a is written as b ValueConstraint to (["\'A\'".."\'F\'"]);']
272
+ ],
273
+ [ "a is written as b() restricted to { ..'F' };", # String range, open start
274
+ ['ValueType: a is written as b ValueConstraint to (["MIN".."F"]);']
275
+ ],
276
+ [ "a is written as b() restricted to { 'A'.. };", # String range, open end
277
+ ['ValueType: a is written as b ValueConstraint to (["\'A\'".."MAX"]);']
278
+ ],
279
+
280
+ # Value constraints with units
281
+ [ "a is written as b() restricted to {1} inches^2/second;", # constraint with units and exponent
282
+ ['ValueType: a is written as b ValueConstraint to ([1]) in [["inches", 2], ["second", -1]];']
283
+ ],
284
+ [ "a is written as b() second^-1/mm^-1 mm^-1 restricted to {1} inches^2/second;", # type with unit and constraint with units and exponent
285
+ #['a is written as b ValueConstraint to ([1]) in [["inches", 2], ["second", -1]];']
286
+ ["ValueType: a is written as b in [[\"second\", -1], [\"mm\", 1], [\"mm\", 1]] ValueConstraint to ([1]) in [[\"inches\", 2], [\"second\", -1]];"]
287
+ ],
288
+ ]
289
+
290
+ before :each do
291
+ @parser = TestParser.new
292
+ end
293
+
294
+ ValidNumbersEtc.each do |c|
295
+ source, ast = *c
296
+ it "should parse #{source.inspect}" do
297
+ result = @parser.parse_all(source, :definition)
298
+
299
+ puts @parser.failure_reason unless result
300
+ result.should_not be_nil
301
+
302
+ canonical_form = result.map{|d| d.ast.to_s}
303
+ if ast
304
+ canonical_form.should == ast
305
+ else
306
+ puts "#{source.inspect} should compile to"
307
+ puts "\t#{canonical_form}"
308
+ end
309
+ end
310
+ end
311
+ end
312
+