activefacts 0.6.0
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.
- data/History.txt +4 -0
- data/Manifest.txt +83 -0
- data/README.rdoc +81 -0
- data/Rakefile +41 -0
- data/bin/afgen +46 -0
- data/bin/cql +52 -0
- data/examples/CQL/Address.cql +46 -0
- data/examples/CQL/Blog.cql +54 -0
- data/examples/CQL/CompanyDirectorEmployee.cql +51 -0
- data/examples/CQL/Death.cql +16 -0
- data/examples/CQL/Genealogy.cql +95 -0
- data/examples/CQL/Marriage.cql +18 -0
- data/examples/CQL/Metamodel.cql +238 -0
- data/examples/CQL/MultiInheritance.cql +19 -0
- data/examples/CQL/OilSupply.cql +47 -0
- data/examples/CQL/Orienteering.cql +108 -0
- data/examples/CQL/PersonPlaysGame.cql +17 -0
- data/examples/CQL/SchoolActivities.cql +31 -0
- data/examples/CQL/SimplestUnary.cql +12 -0
- data/examples/CQL/SubtypePI.cql +32 -0
- data/examples/CQL/Warehousing.cql +99 -0
- data/examples/CQL/WindowInRoomInBldg.cql +22 -0
- data/lib/activefacts.rb +10 -0
- data/lib/activefacts/api.rb +25 -0
- data/lib/activefacts/api/concept.rb +384 -0
- data/lib/activefacts/api/constellation.rb +106 -0
- data/lib/activefacts/api/entity.rb +239 -0
- data/lib/activefacts/api/instance.rb +54 -0
- data/lib/activefacts/api/numeric.rb +158 -0
- data/lib/activefacts/api/role.rb +94 -0
- data/lib/activefacts/api/standard_types.rb +67 -0
- data/lib/activefacts/api/support.rb +59 -0
- data/lib/activefacts/api/value.rb +122 -0
- data/lib/activefacts/api/vocabulary.rb +120 -0
- data/lib/activefacts/cql.rb +31 -0
- data/lib/activefacts/cql/CQLParser.treetop +104 -0
- data/lib/activefacts/cql/Concepts.treetop +112 -0
- data/lib/activefacts/cql/DataTypes.treetop +66 -0
- data/lib/activefacts/cql/Expressions.treetop +113 -0
- data/lib/activefacts/cql/FactTypes.treetop +185 -0
- data/lib/activefacts/cql/Language/English.treetop +92 -0
- data/lib/activefacts/cql/LexicalRules.treetop +169 -0
- data/lib/activefacts/cql/Rakefile +6 -0
- data/lib/activefacts/cql/parser.rb +88 -0
- data/lib/activefacts/generate/absorption.rb +87 -0
- data/lib/activefacts/generate/cql.rb +441 -0
- data/lib/activefacts/generate/cql/html.rb +397 -0
- data/lib/activefacts/generate/null.rb +19 -0
- data/lib/activefacts/generate/ordered.rb +557 -0
- data/lib/activefacts/generate/ruby.rb +326 -0
- data/lib/activefacts/generate/sql/server.rb +164 -0
- data/lib/activefacts/generate/text.rb +21 -0
- data/lib/activefacts/input/cql.rb +1268 -0
- data/lib/activefacts/input/orm.rb +926 -0
- data/lib/activefacts/persistence.rb +1 -0
- data/lib/activefacts/persistence/composition.rb +653 -0
- data/lib/activefacts/support.rb +51 -0
- data/lib/activefacts/version.rb +3 -0
- data/lib/activefacts/vocabulary.rb +6 -0
- data/lib/activefacts/vocabulary/extensions.rb +343 -0
- data/lib/activefacts/vocabulary/metamodel.rb +303 -0
- data/script/txt2html +71 -0
- data/spec/absorption_spec.rb +95 -0
- data/spec/api/autocounter.rb +82 -0
- data/spec/api/constellation.rb +130 -0
- data/spec/api/entity_type.rb +101 -0
- data/spec/api/instance.rb +428 -0
- data/spec/api/roles.rb +122 -0
- data/spec/api/value_type.rb +112 -0
- data/spec/api_spec.rb +14 -0
- data/spec/cql_cql_spec.rb +58 -0
- data/spec/cql_parse_spec.rb +31 -0
- data/spec/cql_ruby_spec.rb +60 -0
- data/spec/cql_sql_spec.rb +54 -0
- data/spec/cql_symbol_tables_spec.rb +259 -0
- data/spec/cql_unit_spec.rb +336 -0
- data/spec/cqldump_spec.rb +169 -0
- data/spec/norma_cql_spec.rb +48 -0
- data/spec/norma_ruby_spec.rb +50 -0
- data/spec/norma_sql_spec.rb +45 -0
- data/spec/norma_tables_spec.rb +94 -0
- data/spec/spec.opts +1 -0
- data/spec/spec_helper.rb +10 -0
- metadata +173 -0
@@ -0,0 +1,112 @@
|
|
1
|
+
#
|
2
|
+
# ActiveFacts tests: Value types in the Runtime API
|
3
|
+
# Copyright (c) 2008 Clifford Heath. Read the LICENSE file.
|
4
|
+
#
|
5
|
+
describe "Value Type class definitions" do
|
6
|
+
setup do
|
7
|
+
Object.send :remove_const, :Mod if Object.const_defined?("Mod")
|
8
|
+
module Mod
|
9
|
+
class Name < String
|
10
|
+
value_type
|
11
|
+
has_one :name
|
12
|
+
end
|
13
|
+
class Year < Int
|
14
|
+
value_type
|
15
|
+
has_one :name
|
16
|
+
end
|
17
|
+
class Weight < Real
|
18
|
+
value_type
|
19
|
+
has_one :name
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
@classes = [Mod::Name, Mod::Year,Mod::Weight]
|
24
|
+
@attrs = [:name, :name, :name]
|
25
|
+
|
26
|
+
end
|
27
|
+
|
28
|
+
it "should respond_to verbalise" do
|
29
|
+
@classes.each { |klass|
|
30
|
+
klass.respond_to?(:verbalise).should be_true
|
31
|
+
}
|
32
|
+
end
|
33
|
+
|
34
|
+
it "should not pollute the value class" do
|
35
|
+
@classes.each { |klass|
|
36
|
+
klass.superclass.respond_to?(:verbalise).should_not be_true
|
37
|
+
}
|
38
|
+
end
|
39
|
+
|
40
|
+
it "should return a string from verbalise" do
|
41
|
+
@classes.each { |klass|
|
42
|
+
v = klass.verbalise
|
43
|
+
v.should_not be_nil
|
44
|
+
v.should_not =~ /REVISIT/
|
45
|
+
}
|
46
|
+
end
|
47
|
+
|
48
|
+
it "should respond_to vocabulary" do
|
49
|
+
@classes.each { |klass|
|
50
|
+
klass.respond_to?(:vocabulary).should be_true
|
51
|
+
}
|
52
|
+
end
|
53
|
+
|
54
|
+
it "should return the parent module as the vocabulary" do
|
55
|
+
@classes.each { |klass|
|
56
|
+
vocabulary = klass.vocabulary
|
57
|
+
vocabulary.should == Mod
|
58
|
+
}
|
59
|
+
end
|
60
|
+
|
61
|
+
it "should return a vocabulary that knows about this concept" do
|
62
|
+
@classes.each { |klass|
|
63
|
+
vocabulary = klass.vocabulary
|
64
|
+
vocabulary.respond_to?(:concept).should be_true
|
65
|
+
vocabulary.concept.has_key?(klass.basename).should be_true
|
66
|
+
}
|
67
|
+
end
|
68
|
+
|
69
|
+
it "should respond to roles()" do
|
70
|
+
@classes.each { |klass|
|
71
|
+
klass.respond_to?(:roles).should be_true
|
72
|
+
}
|
73
|
+
end
|
74
|
+
|
75
|
+
it "should contain only the added role definitions" do
|
76
|
+
Mod::Name.roles.size.should == 4
|
77
|
+
(@classes-[Mod::Name]).each { |klass|
|
78
|
+
klass.roles.size.should == 1
|
79
|
+
}
|
80
|
+
end
|
81
|
+
|
82
|
+
it "should return the role definition" do
|
83
|
+
# Check the role definition may not be accessed by passing an index:
|
84
|
+
Mod::Name.roles(0).should be_nil
|
85
|
+
|
86
|
+
@classes.zip(@attrs).each { |pair|
|
87
|
+
klass, attr = *pair
|
88
|
+
role = klass.roles(attr)
|
89
|
+
role.should_not be_nil
|
90
|
+
|
91
|
+
role = klass.roles(attr.to_s)
|
92
|
+
role.should_not be_nil
|
93
|
+
|
94
|
+
# Check the role definition may be accessed by indexing the returned array:
|
95
|
+
role = klass.roles[attr]
|
96
|
+
role.should_not be_nil
|
97
|
+
|
98
|
+
# Check the role definition array by .include?
|
99
|
+
klass.roles.include?(attr).should be_true
|
100
|
+
}
|
101
|
+
end
|
102
|
+
|
103
|
+
# REVISIT: role value restrictions
|
104
|
+
|
105
|
+
it "should fail on a non-ValueClass" do
|
106
|
+
lambda{
|
107
|
+
class NameNotString
|
108
|
+
value_type
|
109
|
+
end
|
110
|
+
}.should raise_error
|
111
|
+
end
|
112
|
+
end
|
data/spec/api_spec.rb
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
#
|
2
|
+
# ActiveFacts tests: Run the API tests
|
3
|
+
# Copyright (c) 2008 Clifford Heath. Read the LICENSE file.
|
4
|
+
#
|
5
|
+
base = File.dirname(__FILE__)+"/"
|
6
|
+
require 'rubygems'
|
7
|
+
require 'activefacts/api'
|
8
|
+
|
9
|
+
require base+'api/constellation'
|
10
|
+
require base+'api/entity_type'
|
11
|
+
require base+'api/instance'
|
12
|
+
require base+'api/autocounter'
|
13
|
+
require base+'api/value_type'
|
14
|
+
require base+'api/roles'
|
@@ -0,0 +1,58 @@
|
|
1
|
+
#
|
2
|
+
# ActiveFacts tests: Parse all CQL files and check the generated CQL.
|
3
|
+
# Copyright (c) 2008 Clifford Heath. Read the LICENSE file.
|
4
|
+
#
|
5
|
+
require 'rubygems'
|
6
|
+
require 'stringio'
|
7
|
+
require 'activefacts/vocabulary'
|
8
|
+
require 'activefacts/support'
|
9
|
+
require 'activefacts/input/cql'
|
10
|
+
require 'activefacts/generate/cql'
|
11
|
+
|
12
|
+
include ActiveFacts
|
13
|
+
|
14
|
+
class String
|
15
|
+
def strip_comments()
|
16
|
+
c_comment = %r{/\*((?!\*/).)*\*/}m
|
17
|
+
gsub(c_comment, '').gsub(%r{\n\n+},"\n")
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
describe "CQL Loader" do
|
22
|
+
CQL_CQL_FAILURES = %w{
|
23
|
+
Airline
|
24
|
+
CompanyQuery
|
25
|
+
Insurance
|
26
|
+
OrienteeringER
|
27
|
+
ServiceDirector
|
28
|
+
}
|
29
|
+
|
30
|
+
# Generate and return the CQL for the given vocabulary
|
31
|
+
def cql(vocabulary)
|
32
|
+
output = StringIO.new
|
33
|
+
@dumper = ActiveFacts::Generate::CQL.new(vocabulary.constellation)
|
34
|
+
@dumper.generate(output)
|
35
|
+
output.rewind
|
36
|
+
output.read
|
37
|
+
end
|
38
|
+
|
39
|
+
#Dir["examples/CQL/Bl*.cql"].each do |cql_file|
|
40
|
+
#Dir["examples/CQL/Meta*.cql"].each do |cql_file|
|
41
|
+
#Dir["examples/CQL/[ACG]*.cql"].each do |cql_file|
|
42
|
+
Dir["examples/CQL/*.cql"].each do |cql_file|
|
43
|
+
actual_file = cql_file.sub(%r{examples/CQL/}, 'spec/actual/')
|
44
|
+
|
45
|
+
it "should load CQL and dump valid CQL for #{cql_file}" do
|
46
|
+
pending if CQL_CQL_FAILURES.include? File.basename(cql_file, ".cql")
|
47
|
+
vocabulary = ActiveFacts::Input::CQL.readfile(cql_file)
|
48
|
+
|
49
|
+
# Build and save the actual file:
|
50
|
+
cql_text = cql(vocabulary)
|
51
|
+
File.open(actual_file, "w") { |f| f.write cql_text }
|
52
|
+
|
53
|
+
expected_text = File.open(cql_file) {|f| f.read.strip_comments }.scan(/.*?\n/)
|
54
|
+
cql_text.strip_comments.scan(/.*?\n/).should == expected_text
|
55
|
+
File.delete(actual_file) # It succeeded, we don't need the file.
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
#
|
2
|
+
# ActiveFacts tests: Parse all NORMA files and check the generated CQL.
|
3
|
+
# Copyright (c) 2008 Clifford Heath. Read the LICENSE file.
|
4
|
+
#
|
5
|
+
require 'rubygems'
|
6
|
+
require 'stringio'
|
7
|
+
require 'activefacts/vocabulary'
|
8
|
+
require 'activefacts/support'
|
9
|
+
require 'activefacts/input/cql'
|
10
|
+
require 'activefacts/generate/cql'
|
11
|
+
|
12
|
+
include ActiveFacts
|
13
|
+
|
14
|
+
describe "CQL Parser" do
|
15
|
+
CQLPARSE_FAILURES = %w{
|
16
|
+
Airline
|
17
|
+
CompanyQuery
|
18
|
+
Insurance
|
19
|
+
OrienteeringER
|
20
|
+
}
|
21
|
+
|
22
|
+
#Dir["examples/CQL/Bl*.cql"].each do |cql_file|
|
23
|
+
#Dir["examples/CQL/Meta*.cql"].each do |cql_file|
|
24
|
+
#Dir["examples/CQL/[ACG]*.cql"].each do |cql_file|
|
25
|
+
Dir["examples/CQL/*.cql"].each do |cql_file|
|
26
|
+
it "should load CQL #{cql_file} without parse errors" do
|
27
|
+
pending if CQLPARSE_FAILURES.include? File.basename(cql_file, ".cql")
|
28
|
+
lambda { vocabulary = ActiveFacts::Input::CQL.readfile(cql_file) }.should_not raise_error
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
#
|
2
|
+
# ActiveFacts tests: Parse all CQL files and check the generated Ruby.
|
3
|
+
# Copyright (c) 2008 Clifford Heath. Read the LICENSE file.
|
4
|
+
#
|
5
|
+
require 'rubygems'
|
6
|
+
require 'stringio'
|
7
|
+
require 'activefacts/vocabulary'
|
8
|
+
require 'activefacts/support'
|
9
|
+
require 'activefacts/input/cql'
|
10
|
+
require 'activefacts/generate/ruby'
|
11
|
+
|
12
|
+
include ActiveFacts
|
13
|
+
|
14
|
+
class String
|
15
|
+
def strip_comments()
|
16
|
+
c_comment = %r{/\*((?!\*/).)*\*/}m
|
17
|
+
gsub(c_comment, '').gsub(%r{\n\n+},"\n")
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
describe "CQL Loader with Ruby output" do
|
22
|
+
CQL_RUBY_FAILURES = %w{
|
23
|
+
Airline
|
24
|
+
CompanyQuery
|
25
|
+
Insurance
|
26
|
+
OrienteeringER
|
27
|
+
Orienteering
|
28
|
+
ServiceDirector
|
29
|
+
}
|
30
|
+
|
31
|
+
# Generate and return the Ruby for the given vocabulary
|
32
|
+
def ruby(vocabulary)
|
33
|
+
output = StringIO.new
|
34
|
+
@dumper = ActiveFacts::Generate::RUBY.new(vocabulary.constellation)
|
35
|
+
@dumper.generate(output)
|
36
|
+
output.rewind
|
37
|
+
output.read
|
38
|
+
end
|
39
|
+
|
40
|
+
#Dir["examples/CQL/Bl*.cql"].each do |cql_file|
|
41
|
+
#Dir["examples/CQL/Meta*.cql"].each do |cql_file|
|
42
|
+
#Dir["examples/CQL/[ACG]*.cql"].each do |cql_file|
|
43
|
+
Dir["examples/CQL/*.cql"].each do |cql_file|
|
44
|
+
expected_file = cql_file.sub(%r{/CQL/(.*).cql\Z}, '/ruby/\1.rb')
|
45
|
+
actual_file = cql_file.sub(%r{examples/CQL/(.*).cql\Z}, 'spec/actual/\1.rb')
|
46
|
+
|
47
|
+
it "should load #{cql_file} and dump Ruby matching #{expected_file}" do
|
48
|
+
pending if CQL_RUBY_FAILURES.include? File.basename(cql_file, ".cql")
|
49
|
+
vocabulary = ActiveFacts::Input::CQL.readfile(cql_file)
|
50
|
+
|
51
|
+
# Build and save the actual file:
|
52
|
+
ruby_text = ruby(vocabulary)
|
53
|
+
File.open(actual_file, "w") { |f| f.write ruby_text }
|
54
|
+
|
55
|
+
pending unless File.exists? expected_file
|
56
|
+
ruby_text.should == File.open(expected_file) {|f| f.read }
|
57
|
+
File.delete(actual_file) # It succeeded, we don't need the file.
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
#
|
2
|
+
# ActiveFacts tests: Parse all CQL files and check the generated SQL.
|
3
|
+
# Copyright (c) 2008 Clifford Heath. Read the LICENSE file.
|
4
|
+
#
|
5
|
+
require 'rubygems'
|
6
|
+
require 'stringio'
|
7
|
+
require 'activefacts/vocabulary'
|
8
|
+
require 'activefacts/support'
|
9
|
+
require 'activefacts/input/cql'
|
10
|
+
require 'activefacts/generate/sql/server'
|
11
|
+
|
12
|
+
include ActiveFacts
|
13
|
+
include ActiveFacts::Metamodel
|
14
|
+
|
15
|
+
describe "CQL Loader with SQL output" do
|
16
|
+
CQL_SQL_FAILURES = %w{
|
17
|
+
Airline
|
18
|
+
CompanyQuery
|
19
|
+
Insurance
|
20
|
+
OrienteeringER
|
21
|
+
ServiceDirector
|
22
|
+
SimplestUnary
|
23
|
+
}
|
24
|
+
|
25
|
+
# Generate and return the SQL for the given vocabulary
|
26
|
+
def sql(vocabulary)
|
27
|
+
output = StringIO.new
|
28
|
+
@dumper = ActiveFacts::Generate::SQL::SERVER.new(vocabulary.constellation)
|
29
|
+
@dumper.generate(output)
|
30
|
+
output.rewind
|
31
|
+
output.read
|
32
|
+
end
|
33
|
+
|
34
|
+
#Dir["examples/CQL/Bl*.cql"].each do |cql_file|
|
35
|
+
#Dir["examples/CQL/Meta*.cql"].each do |cql_file|
|
36
|
+
#Dir["examples/CQL/[ACG]*.cql"].each do |cql_file|
|
37
|
+
Dir["examples/CQL/*.cql"].each do |cql_file|
|
38
|
+
actual_file = cql_file.sub(%r{examples/CQL/(.*).cql}, 'spec/actual/\1.sql')
|
39
|
+
expected_file = cql_file.sub(%r{examples/CQL/(.*).cql\Z}, 'examples/SQL/\1.sql')
|
40
|
+
|
41
|
+
it "should load #{cql_file} and dump SQL matching #{expected_file}" do
|
42
|
+
pending if CQL_SQL_FAILURES.include? File.basename(cql_file, ".cql")
|
43
|
+
vocabulary = ActiveFacts::Input::CQL.readfile(cql_file)
|
44
|
+
|
45
|
+
# Build and save the actual file:
|
46
|
+
sql_text = sql(vocabulary)
|
47
|
+
File.open(actual_file, "w") { |f| f.write sql_text }
|
48
|
+
|
49
|
+
pending unless File.exists? expected_file
|
50
|
+
sql_text.should == File.open(expected_file) {|f| f.read }
|
51
|
+
File.delete(actual_file) # It succeeded, we don't need the file.
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,259 @@
|
|
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
|
+
require 'rubygems'
|
6
|
+
require 'treetop'
|
7
|
+
require 'activefacts/support'
|
8
|
+
require 'activefacts/api/support'
|
9
|
+
require 'activefacts/input/cql'
|
10
|
+
|
11
|
+
describe "CQL Symbol table" do
|
12
|
+
|
13
|
+
# A Form here is a form of reference to a concept, being a name and optional adjectives, possibly designated by a role name:
|
14
|
+
# Struct.new("Form", :concept, :name, :leading_adjective, :trailing_adjective, :role_name)
|
15
|
+
# def initialize(constellation, vocabulary)
|
16
|
+
# def bind(words, leading_adjective = nil, trailing_adjective = nil, role_name = nil, allowed_forward = false, leading_speculative = false, trailing_speculative = false)
|
17
|
+
|
18
|
+
setup do
|
19
|
+
include ActiveFacts::Input::CQL
|
20
|
+
@constellation = ActiveFacts::API::Constellation.new(ActiveFacts::Metamodel)
|
21
|
+
@vocabulary = @constellation.Vocabulary("Test")
|
22
|
+
@symbols = ActiveFacts::Input::CQL::SymbolTable.new(@constellation, @vocabulary)
|
23
|
+
end
|
24
|
+
|
25
|
+
Definitions = [
|
26
|
+
[ "predefined value type",
|
27
|
+
["Date"],
|
28
|
+
["Date", nil, nil, nil]],
|
29
|
+
[ "predefined value type as word array",
|
30
|
+
[["Date"]],
|
31
|
+
["Date", nil, nil, nil]],
|
32
|
+
[ "predefined value type with inline leading adjective",
|
33
|
+
[["Birth", "Date"]],
|
34
|
+
["Date", "Birth", nil, nil]],
|
35
|
+
[ "predefined value types with inline trailing adjective",
|
36
|
+
[["Date", "OfBirth"]],
|
37
|
+
["Date", nil, "OfBirth", nil]],
|
38
|
+
[ "predefined value type with two inline adjectives",
|
39
|
+
[["Second", "Birth", "Date"]],
|
40
|
+
nil], # Illegal
|
41
|
+
[ "predefined value type with defined leading adjective",
|
42
|
+
["Date", "Birth"],
|
43
|
+
["Date", "Birth", nil, nil]],
|
44
|
+
[ "predefined value types with defined trailing adjective",
|
45
|
+
["Date", nil, "OfBirth"],
|
46
|
+
["Date", nil, "OfBirth", nil]],
|
47
|
+
[ "predefined value type with inline and defined leading adjective",
|
48
|
+
[["Second", "Date"], "Birth"],
|
49
|
+
nil], # Illegal
|
50
|
+
[ "predefined value types with inline and defined trailing adjective",
|
51
|
+
[["Second", "Date"], nil, "OfBirth"],
|
52
|
+
nil], # Illegal
|
53
|
+
|
54
|
+
[ "predefined type with role name",
|
55
|
+
["Date", nil, nil, "BirthDate"],
|
56
|
+
["Date", nil, nil, "BirthDate"]],
|
57
|
+
|
58
|
+
[ "forward-referenced type",
|
59
|
+
["Unknown", nil, nil, nil, true],
|
60
|
+
["Unknown", nil, nil, nil]],
|
61
|
+
[ "forward-referenced type with inline adjective",
|
62
|
+
[["Haha", "Unknown"], nil, nil, nil, true],
|
63
|
+
nil], # Illegal
|
64
|
+
|
65
|
+
[ "entity type",
|
66
|
+
["Person"],
|
67
|
+
["Person", nil, nil, nil]],
|
68
|
+
[ "entity type as word array",
|
69
|
+
[["Person"]],
|
70
|
+
["Person", nil, nil, nil]],
|
71
|
+
[ "entity type with inline leading adjective",
|
72
|
+
[["Birth", "Person"]],
|
73
|
+
["Person", "Birth", nil, nil]],
|
74
|
+
[ "entity types with inline trailing adjective",
|
75
|
+
[["Person", "OfBirth"]],
|
76
|
+
["Person", nil, "OfBirth", nil]],
|
77
|
+
[ "entity type with two inline adjectives",
|
78
|
+
[["Second", "Birth", "Person"]],
|
79
|
+
nil], # Illegal
|
80
|
+
[ "entity type with defined leading adjective",
|
81
|
+
["Person", "Birth"],
|
82
|
+
["Person", "Birth", nil, nil]],
|
83
|
+
[ "entity types with defined trailing adjective",
|
84
|
+
["Person", nil, "OfBirth"],
|
85
|
+
["Person", nil, "OfBirth", nil]],
|
86
|
+
[ "entity type with inline and defined leading adjective",
|
87
|
+
[["Second", "Person"], "Birth"],
|
88
|
+
nil], # Illegal
|
89
|
+
[ "entity types with inline and defined trailing adjective",
|
90
|
+
[["Second", "Person"], nil, "OfBirth"],
|
91
|
+
nil], # Illegal
|
92
|
+
|
93
|
+
[ "entity type with role name",
|
94
|
+
["Person", nil, nil, "Father"],
|
95
|
+
["Person", nil, nil, "Father"]],
|
96
|
+
]
|
97
|
+
|
98
|
+
Definitions.each do |c|
|
99
|
+
description, args, result = *c
|
100
|
+
|
101
|
+
it "should define #{description}" do
|
102
|
+
if result
|
103
|
+
# Predefine an entity type, some cases use it:
|
104
|
+
@constellation.EntityType("Person", @vocabulary.identifying_role_values)
|
105
|
+
|
106
|
+
player, bound = @symbols.bind(*args)
|
107
|
+
player.should_not be_nil
|
108
|
+
player.should == bound.concept
|
109
|
+
[bound.name, bound.leading_adjective, bound.trailing_adjective, bound.role_name].should == result
|
110
|
+
else
|
111
|
+
lambda {player, bound = @symbols.bind(*args)}.should raise_error
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
it "should disallow binding to a role name where a leading adjective is provided" do
|
117
|
+
concept, = @symbols.bind("Name", nil, nil, "GivenName", true)
|
118
|
+
lambda{player, bound = @symbols.bind("GivenName", "SomeAdj")}.should raise_error
|
119
|
+
end
|
120
|
+
|
121
|
+
it "should disallow binding to a role name where a trailing adjective is provided" do
|
122
|
+
concept, = @symbols.bind("Name", nil, nil, "GivenName", true)
|
123
|
+
lambda{player, bound = @symbols.bind("GivenName", nil, "SomeAdj")}.should raise_error
|
124
|
+
end
|
125
|
+
|
126
|
+
it "should disallow binding to a role name and defining a new role name" do
|
127
|
+
concept, = @symbols.bind("Name", nil, nil, "GivenName", true)
|
128
|
+
lambda{player, bound = @symbols.bind("GivenName", nil, nil, "SomeName")}.should raise_error
|
129
|
+
end
|
130
|
+
|
131
|
+
Predefined = [
|
132
|
+
[ "Name", "Given", nil, nil, true ],
|
133
|
+
[ "Nom", nil, "Donné", nil, true ],
|
134
|
+
[ "Name", nil, nil, "GivenName", true ],
|
135
|
+
[ "Simple", nil, nil, ],
|
136
|
+
]
|
137
|
+
|
138
|
+
it "should allow adding a role name to an adjectival form without one" do
|
139
|
+
concept, = @symbols.bind("Name", "Given", nil, nil, true)
|
140
|
+
player, bound = @symbols.bind("Name", nil, nil, "GivenName")
|
141
|
+
player.should == concept
|
142
|
+
end
|
143
|
+
|
144
|
+
it "should create new binding with a role name rather than binding to existing simple player without adjectives" do
|
145
|
+
concept, bare = @symbols.bind("Name", nil, nil, nil, true)
|
146
|
+
player, bound = @symbols.bind("Name", nil, nil, "SomeAdj")
|
147
|
+
bare.should_not == bound
|
148
|
+
end
|
149
|
+
|
150
|
+
it "should disallow adding a role name which is the name of an existing concept" do
|
151
|
+
concept, = @symbols.bind("Name", "Given", nil, nil, true)
|
152
|
+
lambda{player, bound = @symbols.bind("Name", "Given", nil, "Date")}.should raise_error
|
153
|
+
end
|
154
|
+
|
155
|
+
it "should disallow adding a role name to a role player that already has one" do
|
156
|
+
concept, first = @symbols.bind("Name", "Given", nil, "GivenName", true)
|
157
|
+
player, bound = @symbols.bind("Name", "Given", nil, "FirstName")
|
158
|
+
first.should_not == bound
|
159
|
+
end
|
160
|
+
|
161
|
+
it "should bind to an existing player without adjectives" do
|
162
|
+
concept, = @symbols.bind("Name", nil, nil, nil, true)
|
163
|
+
player, bound = @symbols.bind("Name")
|
164
|
+
player.should == concept
|
165
|
+
end
|
166
|
+
|
167
|
+
it "should bind to an existing player using a leading adjective" do
|
168
|
+
concept, = @symbols.bind("Name", nil, nil, nil, true)
|
169
|
+
player, bound = @symbols.bind("Name", "Given")
|
170
|
+
player.should == concept
|
171
|
+
end
|
172
|
+
|
173
|
+
it "should bind to an existing player using a trailing adjective" do
|
174
|
+
concept, = @symbols.bind("Name", nil, nil, nil, true)
|
175
|
+
player, bound = @symbols.bind("Name", nil, "Donné")
|
176
|
+
player.should == concept
|
177
|
+
end
|
178
|
+
|
179
|
+
it "should bind to an existing player only using the defined leading adjective" do
|
180
|
+
concept, = @symbols.bind("Name", "Given", nil, nil, true)
|
181
|
+
player, bound = @symbols.bind("Name", "Given")
|
182
|
+
player.should == concept
|
183
|
+
forms = [bound]
|
184
|
+
|
185
|
+
player, alt = @symbols.bind("Name")
|
186
|
+
forms.should_not be_include(alt)
|
187
|
+
forms << alt
|
188
|
+
|
189
|
+
player, alt = @symbols.bind("Name", nil, "Donné")
|
190
|
+
forms.should_not be_include(alt)
|
191
|
+
forms << alt
|
192
|
+
|
193
|
+
player, alt = @symbols.bind("Name", "Given", "Donné")
|
194
|
+
forms.should_not be_include(alt)
|
195
|
+
end
|
196
|
+
|
197
|
+
it "should bind to an existing player only using a defined trailing adjective" do
|
198
|
+
concept, = @symbols.bind("Name", nil, "Donné", nil, true)
|
199
|
+
player, bound = @symbols.bind("Name", nil, "Donné")
|
200
|
+
player.should == concept
|
201
|
+
forms = [bound]
|
202
|
+
|
203
|
+
player, alt = @symbols.bind("Name")
|
204
|
+
forms.should_not be_include(alt)
|
205
|
+
forms << alt
|
206
|
+
|
207
|
+
player, alt = @symbols.bind("Name", "Given")
|
208
|
+
forms.should_not be_include(alt)
|
209
|
+
forms << alt
|
210
|
+
|
211
|
+
player, alt = @symbols.bind("Name", "Given", "Donné")
|
212
|
+
forms.should_not be_include(alt)
|
213
|
+
end
|
214
|
+
|
215
|
+
it "should bind to an existing player only using defined leading and trailing adjective" do
|
216
|
+
concept, = @symbols.bind("Name", "Given", "Donné", nil, true)
|
217
|
+
player, bound = @symbols.bind("Name", "Given", "Donné")
|
218
|
+
player.should == concept
|
219
|
+
forms = [bound]
|
220
|
+
|
221
|
+
player, alt = @symbols.bind("Name")
|
222
|
+
forms.should_not be_include(alt)
|
223
|
+
forms << alt
|
224
|
+
|
225
|
+
player, alt = @symbols.bind("Name", "Given")
|
226
|
+
forms.should_not be_include(alt)
|
227
|
+
forms << alt
|
228
|
+
|
229
|
+
player, alt = @symbols.bind("Name", nil, "Donné")
|
230
|
+
forms.should_not be_include(alt)
|
231
|
+
end
|
232
|
+
|
233
|
+
it "should bind to an existing player using a speculative leading adjective" do
|
234
|
+
concept, = @symbols.bind("Name", "Given", nil, nil, true)
|
235
|
+
player, bound = @symbols.bind("Name", l = "Given", t = "Donné", nil, nil, true, true)
|
236
|
+
player.should == concept
|
237
|
+
bound.leading_adjective.should == "Given"
|
238
|
+
bound.trailing_adjective.should be_nil
|
239
|
+
l.should be_empty
|
240
|
+
t.should == "Donné"
|
241
|
+
end
|
242
|
+
|
243
|
+
it "should bind to an existing player using a speculative trailing adjective" do
|
244
|
+
concept, = @symbols.bind("Name", nil, "Donné", nil, true)
|
245
|
+
player, bound = @symbols.bind("Name", l = "Given", t = "Donné", nil, nil, true, true)
|
246
|
+
player.should == concept
|
247
|
+
l.should == "Given"
|
248
|
+
t.should be_empty
|
249
|
+
end
|
250
|
+
|
251
|
+
it "should bind to an existing player using a speculative leading and trailing adjective" do
|
252
|
+
concept, = @symbols.bind("Name", "Given", "Donné", nil, true)
|
253
|
+
player, bound = @symbols.bind("Name", l = "Given", t = "Donné", nil, nil, true, true)
|
254
|
+
player.should == concept
|
255
|
+
l.should be_empty
|
256
|
+
t.should be_empty
|
257
|
+
end
|
258
|
+
|
259
|
+
end
|