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
         
     |