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.
Files changed (84) hide show
  1. data/History.txt +4 -0
  2. data/Manifest.txt +83 -0
  3. data/README.rdoc +81 -0
  4. data/Rakefile +41 -0
  5. data/bin/afgen +46 -0
  6. data/bin/cql +52 -0
  7. data/examples/CQL/Address.cql +46 -0
  8. data/examples/CQL/Blog.cql +54 -0
  9. data/examples/CQL/CompanyDirectorEmployee.cql +51 -0
  10. data/examples/CQL/Death.cql +16 -0
  11. data/examples/CQL/Genealogy.cql +95 -0
  12. data/examples/CQL/Marriage.cql +18 -0
  13. data/examples/CQL/Metamodel.cql +238 -0
  14. data/examples/CQL/MultiInheritance.cql +19 -0
  15. data/examples/CQL/OilSupply.cql +47 -0
  16. data/examples/CQL/Orienteering.cql +108 -0
  17. data/examples/CQL/PersonPlaysGame.cql +17 -0
  18. data/examples/CQL/SchoolActivities.cql +31 -0
  19. data/examples/CQL/SimplestUnary.cql +12 -0
  20. data/examples/CQL/SubtypePI.cql +32 -0
  21. data/examples/CQL/Warehousing.cql +99 -0
  22. data/examples/CQL/WindowInRoomInBldg.cql +22 -0
  23. data/lib/activefacts.rb +10 -0
  24. data/lib/activefacts/api.rb +25 -0
  25. data/lib/activefacts/api/concept.rb +384 -0
  26. data/lib/activefacts/api/constellation.rb +106 -0
  27. data/lib/activefacts/api/entity.rb +239 -0
  28. data/lib/activefacts/api/instance.rb +54 -0
  29. data/lib/activefacts/api/numeric.rb +158 -0
  30. data/lib/activefacts/api/role.rb +94 -0
  31. data/lib/activefacts/api/standard_types.rb +67 -0
  32. data/lib/activefacts/api/support.rb +59 -0
  33. data/lib/activefacts/api/value.rb +122 -0
  34. data/lib/activefacts/api/vocabulary.rb +120 -0
  35. data/lib/activefacts/cql.rb +31 -0
  36. data/lib/activefacts/cql/CQLParser.treetop +104 -0
  37. data/lib/activefacts/cql/Concepts.treetop +112 -0
  38. data/lib/activefacts/cql/DataTypes.treetop +66 -0
  39. data/lib/activefacts/cql/Expressions.treetop +113 -0
  40. data/lib/activefacts/cql/FactTypes.treetop +185 -0
  41. data/lib/activefacts/cql/Language/English.treetop +92 -0
  42. data/lib/activefacts/cql/LexicalRules.treetop +169 -0
  43. data/lib/activefacts/cql/Rakefile +6 -0
  44. data/lib/activefacts/cql/parser.rb +88 -0
  45. data/lib/activefacts/generate/absorption.rb +87 -0
  46. data/lib/activefacts/generate/cql.rb +441 -0
  47. data/lib/activefacts/generate/cql/html.rb +397 -0
  48. data/lib/activefacts/generate/null.rb +19 -0
  49. data/lib/activefacts/generate/ordered.rb +557 -0
  50. data/lib/activefacts/generate/ruby.rb +326 -0
  51. data/lib/activefacts/generate/sql/server.rb +164 -0
  52. data/lib/activefacts/generate/text.rb +21 -0
  53. data/lib/activefacts/input/cql.rb +1268 -0
  54. data/lib/activefacts/input/orm.rb +926 -0
  55. data/lib/activefacts/persistence.rb +1 -0
  56. data/lib/activefacts/persistence/composition.rb +653 -0
  57. data/lib/activefacts/support.rb +51 -0
  58. data/lib/activefacts/version.rb +3 -0
  59. data/lib/activefacts/vocabulary.rb +6 -0
  60. data/lib/activefacts/vocabulary/extensions.rb +343 -0
  61. data/lib/activefacts/vocabulary/metamodel.rb +303 -0
  62. data/script/txt2html +71 -0
  63. data/spec/absorption_spec.rb +95 -0
  64. data/spec/api/autocounter.rb +82 -0
  65. data/spec/api/constellation.rb +130 -0
  66. data/spec/api/entity_type.rb +101 -0
  67. data/spec/api/instance.rb +428 -0
  68. data/spec/api/roles.rb +122 -0
  69. data/spec/api/value_type.rb +112 -0
  70. data/spec/api_spec.rb +14 -0
  71. data/spec/cql_cql_spec.rb +58 -0
  72. data/spec/cql_parse_spec.rb +31 -0
  73. data/spec/cql_ruby_spec.rb +60 -0
  74. data/spec/cql_sql_spec.rb +54 -0
  75. data/spec/cql_symbol_tables_spec.rb +259 -0
  76. data/spec/cql_unit_spec.rb +336 -0
  77. data/spec/cqldump_spec.rb +169 -0
  78. data/spec/norma_cql_spec.rb +48 -0
  79. data/spec/norma_ruby_spec.rb +50 -0
  80. data/spec/norma_sql_spec.rb +45 -0
  81. data/spec/norma_tables_spec.rb +94 -0
  82. data/spec/spec.opts +1 -0
  83. data/spec/spec_helper.rb +10 -0
  84. 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