activefacts 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
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