activefacts 0.8.9 → 0.8.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gemtest +0 -0
- data/Manifest.txt +28 -33
- data/Rakefile +11 -12
- data/bin/cql +90 -46
- data/examples/CQL/Blog.cql +2 -1
- data/examples/CQL/CompanyDirectorEmployee.cql +2 -2
- data/examples/CQL/Death.cql +1 -1
- data/examples/CQL/Diplomacy.cql +9 -9
- data/examples/CQL/Genealogy.cql +3 -2
- data/examples/CQL/Insurance.cql +10 -7
- data/examples/CQL/JoinEquality.cql +2 -2
- data/examples/CQL/Marriage.cql +1 -1
- data/examples/CQL/Metamodel.cql +73 -53
- data/examples/CQL/MetamodelNext.cql +89 -67
- data/examples/CQL/OneToOnes.cql +2 -2
- data/examples/CQL/ServiceDirector.cql +10 -5
- data/examples/CQL/Supervision.cql +3 -3
- data/examples/CQL/Tests.Test5.Load.cql +1 -1
- data/examples/CQL/Warehousing.cql +4 -2
- data/lib/activefacts/cql/CQLParser.treetop +26 -60
- data/lib/activefacts/cql/Context.treetop +12 -2
- data/lib/activefacts/cql/Expressions.treetop +14 -30
- data/lib/activefacts/cql/FactTypes.treetop +165 -110
- data/lib/activefacts/cql/Language/English.treetop +167 -54
- data/lib/activefacts/cql/LexicalRules.treetop +16 -2
- data/lib/activefacts/cql/{Concepts.treetop → ObjectTypes.treetop} +36 -37
- data/lib/activefacts/cql/Terms.treetop +57 -27
- data/lib/activefacts/cql/ValueTypes.treetop +39 -13
- data/lib/activefacts/cql/compiler.rb +5 -3
- data/lib/activefacts/cql/compiler/{reading.rb → clause.rb} +407 -285
- data/lib/activefacts/cql/compiler/constraint.rb +178 -275
- data/lib/activefacts/cql/compiler/entity_type.rb +73 -64
- data/lib/activefacts/cql/compiler/expression.rb +418 -0
- data/lib/activefacts/cql/compiler/fact.rb +146 -145
- data/lib/activefacts/cql/compiler/fact_type.rb +197 -80
- data/lib/activefacts/cql/compiler/join.rb +159 -0
- data/lib/activefacts/cql/compiler/shared.rb +51 -23
- data/lib/activefacts/cql/compiler/value_type.rb +56 -2
- data/lib/activefacts/cql/parser.rb +15 -4
- data/lib/activefacts/generate/absorption.rb +7 -7
- data/lib/activefacts/generate/cql.rb +100 -37
- data/lib/activefacts/generate/oo.rb +28 -51
- data/lib/activefacts/generate/ordered.rb +60 -36
- data/lib/activefacts/generate/ruby.rb +6 -6
- data/lib/activefacts/generate/sql/server.rb +4 -4
- data/lib/activefacts/input/orm.rb +71 -53
- data/lib/activefacts/persistence.rb +1 -1
- data/lib/activefacts/persistence/columns.rb +27 -23
- data/lib/activefacts/persistence/foreignkey.rb +6 -6
- data/lib/activefacts/persistence/index.rb +17 -17
- data/lib/activefacts/persistence/{concept.rb → object_type.rb} +9 -9
- data/lib/activefacts/persistence/reference.rb +61 -36
- data/lib/activefacts/persistence/tables.rb +61 -59
- data/lib/activefacts/support.rb +54 -29
- data/lib/activefacts/version.rb +1 -1
- data/lib/activefacts/vocabulary/extensions.rb +99 -54
- data/lib/activefacts/vocabulary/metamodel.rb +43 -37
- data/lib/activefacts/vocabulary/verbaliser.rb +134 -109
- data/spec/absorption_spec.rb +8 -8
- data/spec/cql/comparison_spec.rb +91 -0
- data/spec/cql/contractions_spec.rb +251 -0
- data/spec/cql/entity_type_spec.rb +319 -0
- data/spec/cql/expressions_spec.rb +63 -0
- data/spec/cql/fact_type_matching_spec.rb +283 -0
- data/spec/cql/french_spec.rb +21 -0
- data/spec/cql/parser/bad_literals_spec.rb +86 -0
- data/spec/cql/parser/constraints_spec.rb +19 -0
- data/spec/cql/parser/entity_types_spec.rb +106 -0
- data/spec/cql/parser/expressions_spec.rb +179 -0
- data/spec/cql/parser/fact_types_spec.rb +41 -0
- data/spec/cql/parser/literals_spec.rb +312 -0
- data/spec/cql/parser/pragmas_spec.rb +89 -0
- data/spec/cql/parser/value_types_spec.rb +42 -0
- data/spec/cql/role_matching_spec.rb +147 -0
- data/spec/cql/samples_spec.rb +9 -9
- data/spec/cql_cql_spec.rb +1 -1
- data/spec/cql_dm_spec.rb +116 -0
- data/spec/cql_mysql_spec.rb +1 -1
- data/spec/cql_ruby_spec.rb +1 -1
- data/spec/cql_sql_spec.rb +3 -3
- data/spec/cql_symbol_tables_spec.rb +30 -30
- data/spec/cqldump_spec.rb +4 -4
- data/spec/helpers/array_matcher.rb +32 -27
- data/spec/helpers/diff_matcher.rb +6 -26
- data/spec/helpers/file_matcher.rb +41 -32
- data/spec/helpers/parse_to_ast_matcher.rb +76 -0
- data/spec/helpers/string_matcher.rb +32 -31
- data/spec/norma_cql_spec.rb +1 -1
- data/spec/norma_ruby_spec.rb +1 -1
- data/spec/norma_ruby_sql_spec.rb +1 -1
- data/spec/norma_sql_spec.rb +3 -1
- data/spec/norma_tables_spec.rb +1 -1
- data/spec/ruby_api_spec.rb +23 -0
- data/spec/spec_helper.rb +5 -4
- metadata +66 -66
- data/examples/CQL/OrienteeringER.cql +0 -58
- data/lib/activefacts/api.rb +0 -44
- data/lib/activefacts/api/concept.rb +0 -410
- data/lib/activefacts/api/constellation.rb +0 -128
- data/lib/activefacts/api/entity.rb +0 -256
- data/lib/activefacts/api/instance.rb +0 -60
- data/lib/activefacts/api/instance_index.rb +0 -80
- data/lib/activefacts/api/numeric.rb +0 -167
- data/lib/activefacts/api/role.rb +0 -80
- data/lib/activefacts/api/role_proxy.rb +0 -70
- data/lib/activefacts/api/role_values.rb +0 -117
- data/lib/activefacts/api/standard_types.rb +0 -87
- data/lib/activefacts/api/support.rb +0 -65
- data/lib/activefacts/api/value.rb +0 -135
- data/lib/activefacts/api/vocabulary.rb +0 -82
- data/spec/api/autocounter.rb +0 -82
- data/spec/api/constellation.rb +0 -130
- data/spec/api/entity_type.rb +0 -103
- data/spec/api/instance.rb +0 -461
- data/spec/api/roles.rb +0 -124
- data/spec/api/value_type.rb +0 -112
- data/spec/api_spec.rb +0 -13
- data/spec/cql/matching_spec.rb +0 -517
- data/spec/cql/unit_spec.rb +0 -394
- data/spec/spec.opts +0 -1
|
@@ -1,65 +0,0 @@
|
|
|
1
|
-
#
|
|
2
|
-
# ActiveFacts Runtime API.
|
|
3
|
-
# Various additions or patches to Ruby built-in classes, and some global support methods
|
|
4
|
-
#
|
|
5
|
-
# Copyright (c) 2009 Clifford Heath. Read the LICENSE file.
|
|
6
|
-
#
|
|
7
|
-
|
|
8
|
-
class Symbol #:nodoc:
|
|
9
|
-
def to_proc
|
|
10
|
-
Proc.new{|*args| args.shift.__send__(self, *args)}
|
|
11
|
-
end
|
|
12
|
-
end
|
|
13
|
-
|
|
14
|
-
class String #:nodoc:
|
|
15
|
-
def camelcase(first=false, on='_\s')
|
|
16
|
-
if first
|
|
17
|
-
gsub(/(^|[#{on}]+)([A-Za-z])/){ $2.upcase }
|
|
18
|
-
else
|
|
19
|
-
gsub(/([#{on}]+)([A-Za-z])/){ $2.upcase }
|
|
20
|
-
end
|
|
21
|
-
end
|
|
22
|
-
|
|
23
|
-
def snakecase
|
|
24
|
-
gsub(/([a-z])([A-Z])/,'\1_\2').downcase
|
|
25
|
-
end
|
|
26
|
-
|
|
27
|
-
def camelwords
|
|
28
|
-
gsub(/-([a-zA-Z])/){ $1.upcase }. # Break and upcase on hyphenated words
|
|
29
|
-
gsub(/([a-z])([A-Z])/,'\1_\2').
|
|
30
|
-
split(/[_\s]+/)
|
|
31
|
-
end
|
|
32
|
-
end
|
|
33
|
-
|
|
34
|
-
class Module #:nodoc:
|
|
35
|
-
def modspace
|
|
36
|
-
space = name[ 0...(name.rindex( '::' ) || 0)]
|
|
37
|
-
space == '' ? Object : eval(space)
|
|
38
|
-
end
|
|
39
|
-
|
|
40
|
-
def basename
|
|
41
|
-
name.gsub(/.*::/, '')
|
|
42
|
-
end
|
|
43
|
-
end
|
|
44
|
-
|
|
45
|
-
module ActiveFacts #:nodoc:
|
|
46
|
-
# If the args array ends with a hash, remove it.
|
|
47
|
-
# If the remaining args are fewer than the arg_names,
|
|
48
|
-
# extract values from the hash and append them to args.
|
|
49
|
-
# Return the new args array and the hash.
|
|
50
|
-
# In any case leave the original args unmodified.
|
|
51
|
-
def self.extract_hash_args(arg_names, args)
|
|
52
|
-
if Hash === args[-1]
|
|
53
|
-
arg_hash = args[-1] # Don't pop args, leave it unmodified
|
|
54
|
-
args = args[0..-2]
|
|
55
|
-
arg_hash = arg_hash.clone if (args.size < arg_names.size)
|
|
56
|
-
while args.size < arg_names.size
|
|
57
|
-
args << arg_hash[n = arg_names[args.size]]
|
|
58
|
-
arg_hash.delete(n)
|
|
59
|
-
end
|
|
60
|
-
else
|
|
61
|
-
arg_hash = {}
|
|
62
|
-
end
|
|
63
|
-
return args, arg_hash
|
|
64
|
-
end
|
|
65
|
-
end
|
|
@@ -1,135 +0,0 @@
|
|
|
1
|
-
#
|
|
2
|
-
# ActiveFacts Runtime API
|
|
3
|
-
# Value module (mixins for ValueType classes and instances)
|
|
4
|
-
#
|
|
5
|
-
# Copyright (c) 2009 Clifford Heath. Read the LICENSE file.
|
|
6
|
-
#
|
|
7
|
-
# The methods of this module are added to Value type classes.
|
|
8
|
-
#
|
|
9
|
-
module ActiveFacts
|
|
10
|
-
module API
|
|
11
|
-
|
|
12
|
-
# All Value instances include the methods defined here
|
|
13
|
-
module Value
|
|
14
|
-
include Instance
|
|
15
|
-
|
|
16
|
-
# Value instance methods:
|
|
17
|
-
def initialize(*args) #:nodoc:
|
|
18
|
-
args[0] = args[0].__getobj__ if RoleProxy === args[0]
|
|
19
|
-
super(args)
|
|
20
|
-
end
|
|
21
|
-
|
|
22
|
-
# verbalise this Value
|
|
23
|
-
def verbalise(role_name = nil)
|
|
24
|
-
"#{role_name || self.class.basename} '#{to_s}'"
|
|
25
|
-
end
|
|
26
|
-
|
|
27
|
-
# A value is its own key
|
|
28
|
-
def identifying_role_values #:nodoc:
|
|
29
|
-
self
|
|
30
|
-
end
|
|
31
|
-
|
|
32
|
-
# All ValueType classes include the methods defined here
|
|
33
|
-
module ClassMethods
|
|
34
|
-
include Instance::ClassMethods
|
|
35
|
-
|
|
36
|
-
def initialise_value_type *args, &block #:nodoc:
|
|
37
|
-
# REVISIT: args could be a hash, with keys :length, :scale, :unit, :allow
|
|
38
|
-
#raise "value_type args unexpected" if args.size > 0
|
|
39
|
-
end
|
|
40
|
-
|
|
41
|
-
class_eval do
|
|
42
|
-
define_method :length do |*args|
|
|
43
|
-
@length = args[0] if args.length > 0
|
|
44
|
-
@length
|
|
45
|
-
end
|
|
46
|
-
end
|
|
47
|
-
|
|
48
|
-
class_eval do
|
|
49
|
-
define_method :scale do |*args|
|
|
50
|
-
@scale = args[0] if args.length > 0
|
|
51
|
-
@scale
|
|
52
|
-
end
|
|
53
|
-
end
|
|
54
|
-
|
|
55
|
-
class_eval do
|
|
56
|
-
define_method :restrict do |*value_ranges|
|
|
57
|
-
@value_ranges = *value_ranges
|
|
58
|
-
end
|
|
59
|
-
end
|
|
60
|
-
|
|
61
|
-
# verbalise this ValueType
|
|
62
|
-
def verbalise
|
|
63
|
-
# REVISIT: Add length and scale here, if set
|
|
64
|
-
# REVISIT: Set vocabulary name of superclass if not same as this
|
|
65
|
-
"#{basename} = #{superclass.basename}();"
|
|
66
|
-
end
|
|
67
|
-
|
|
68
|
-
def identifying_role_values(*args) #:nodoc:
|
|
69
|
-
# If the single arg is the correct class or a subclass, use it directly
|
|
70
|
-
#puts "#{basename}.identifying_role_values#{args.inspect}"
|
|
71
|
-
if (args.size == 1 and (arg = args[0]).is_a?(self.class)) # No secondary supertypes allowed for value types
|
|
72
|
-
arg = arg.__getobj__ if RoleProxy === arg
|
|
73
|
-
return arg
|
|
74
|
-
end
|
|
75
|
-
new(*args)
|
|
76
|
-
end
|
|
77
|
-
|
|
78
|
-
def assert_instance(constellation, args) #:nodoc:
|
|
79
|
-
# Build the key for this instance from the args
|
|
80
|
-
# The key of an instance is the value or array of keys of the identifying values.
|
|
81
|
-
# The key values aren't necessarily present in the constellation, even after this.
|
|
82
|
-
key = identifying_role_values(*args)
|
|
83
|
-
#puts "#{klass} key is #{key.inspect}"
|
|
84
|
-
|
|
85
|
-
# Find and return an existing instance matching this key
|
|
86
|
-
instances = constellation.instances[self] # All instances of this class in this constellation
|
|
87
|
-
instance = instances[key]
|
|
88
|
-
# DEBUG: puts "assert #{self.basename} #{key.inspect} #{instance ? "exists" : "new"}"
|
|
89
|
-
return instance, key if instance # A matching instance of this class
|
|
90
|
-
|
|
91
|
-
instance = new(*args)
|
|
92
|
-
|
|
93
|
-
instance.constellation = constellation
|
|
94
|
-
return *index_instance(instance)
|
|
95
|
-
end
|
|
96
|
-
|
|
97
|
-
def index_instance(instance, key = nil) #:nodoc:
|
|
98
|
-
instances = instance.constellation.instances[self]
|
|
99
|
-
key = instance.identifying_role_values
|
|
100
|
-
instances[key] = instance
|
|
101
|
-
# DEBUG: puts "indexing value #{basename} using #{key.inspect} in #{constellation.object_id}"
|
|
102
|
-
|
|
103
|
-
# Index the instance for each supertype:
|
|
104
|
-
supertypes.each do |supertype|
|
|
105
|
-
supertype.index_instance(instance, key)
|
|
106
|
-
end
|
|
107
|
-
|
|
108
|
-
return instance, key
|
|
109
|
-
end
|
|
110
|
-
|
|
111
|
-
def inherited(other) #:nodoc:
|
|
112
|
-
#puts "REVISIT: ValueType #{self} < #{self.superclass} was inherited by #{other}; not implemented" #+"from #{caller*"\n\t"}"
|
|
113
|
-
# Copy the type parameters here, etc?
|
|
114
|
-
other.send :realise_supertypes, self
|
|
115
|
-
vocabulary.__add_concept(other)
|
|
116
|
-
super
|
|
117
|
-
end
|
|
118
|
-
end
|
|
119
|
-
|
|
120
|
-
def self.included other #:nodoc:
|
|
121
|
-
other.send :extend, ClassMethods
|
|
122
|
-
|
|
123
|
-
#puts "ValueType included in #{other.basename} from #{caller*"\n\t"}"
|
|
124
|
-
|
|
125
|
-
# Register ourselves with the parent module, which has become a Vocabulary:
|
|
126
|
-
vocabulary = other.modspace
|
|
127
|
-
# puts "ValueType.included(#{other.inspect})"
|
|
128
|
-
unless vocabulary.respond_to? :concept # Extend module with Vocabulary if necessary
|
|
129
|
-
vocabulary.send :extend, Vocabulary
|
|
130
|
-
end
|
|
131
|
-
vocabulary.__add_concept(other)
|
|
132
|
-
end
|
|
133
|
-
end
|
|
134
|
-
end
|
|
135
|
-
end
|
|
@@ -1,82 +0,0 @@
|
|
|
1
|
-
#
|
|
2
|
-
# ActiveFacts Runtime API
|
|
3
|
-
# Vocabulary module (mixin for any Module that contains classes having Concept mixed in)
|
|
4
|
-
#
|
|
5
|
-
# Copyright (c) 2009 Clifford Heath. Read the LICENSE file.
|
|
6
|
-
#
|
|
7
|
-
# The methods of this module are extended into any module that contains
|
|
8
|
-
# a Concept class (Entity type or Value type).
|
|
9
|
-
#
|
|
10
|
-
module ActiveFacts
|
|
11
|
-
module API
|
|
12
|
-
# Vocabulary is a mixin that adds methods to any Module which has any Concept classes (ValueType or EntityType).
|
|
13
|
-
# A Vocabulary knows all the Concept classes including forward-referenced ones,
|
|
14
|
-
# and can resolve the forward references when the class is finally defined.
|
|
15
|
-
# Construction of a Constellation requires a Vocabuary as argument.
|
|
16
|
-
module Vocabulary
|
|
17
|
-
# With a parameter, look up a concept class by name.
|
|
18
|
-
# Without, return the hash (keyed by the class' basename) of all concepts in this vocabulary
|
|
19
|
-
def concept(name = nil)
|
|
20
|
-
@concept ||= {}
|
|
21
|
-
return @concept unless name
|
|
22
|
-
|
|
23
|
-
return name if name.is_a? Class
|
|
24
|
-
|
|
25
|
-
# puts "Looking up concept #{name} in #{self.name}"
|
|
26
|
-
camel = name.to_s.camelcase(true)
|
|
27
|
-
if (c = @concept[camel])
|
|
28
|
-
__bind(camel)
|
|
29
|
-
return c
|
|
30
|
-
end
|
|
31
|
-
return (const_get("#{name}::#{camel}") rescue nil)
|
|
32
|
-
end
|
|
33
|
-
|
|
34
|
-
# Create a new constellation over this vocabulary
|
|
35
|
-
def constellation
|
|
36
|
-
Constellation.new(self)
|
|
37
|
-
end
|
|
38
|
-
|
|
39
|
-
def populate &b
|
|
40
|
-
constellation.populate &b
|
|
41
|
-
end
|
|
42
|
-
|
|
43
|
-
def verbalise
|
|
44
|
-
"Vocabulary #{name}:\n\t" +
|
|
45
|
-
@concept.keys.sort.map{|concept|
|
|
46
|
-
c = @concept[concept]
|
|
47
|
-
__bind(c.basename)
|
|
48
|
-
c.verbalise + "\n\t\t// Roles played: " + c.roles.verbalise
|
|
49
|
-
}*"\n\t"
|
|
50
|
-
end
|
|
51
|
-
|
|
52
|
-
def __add_concept(klass) #:nodoc:
|
|
53
|
-
name = klass.basename
|
|
54
|
-
__bind(name)
|
|
55
|
-
# puts "Adding concept #{name} to #{self.name}"
|
|
56
|
-
@concept ||= {}
|
|
57
|
-
@concept[klass.basename] = klass
|
|
58
|
-
end
|
|
59
|
-
|
|
60
|
-
def __delay(concept_name, args, &block) #:nodoc:
|
|
61
|
-
# puts "Arranging for delayed binding on #{concept_name.inspect}"
|
|
62
|
-
@delayed ||= Hash.new { |h,k| h[k] = [] }
|
|
63
|
-
@delayed[concept_name] << [args, block]
|
|
64
|
-
end
|
|
65
|
-
|
|
66
|
-
# __bind raises an error if the named class doesn't exist yet.
|
|
67
|
-
def __bind(concept_name) #:nodoc:
|
|
68
|
-
concept = const_get(concept_name)
|
|
69
|
-
# puts "#{name}.__bind #{concept_name} -> #{concept.name}" if concept
|
|
70
|
-
if (@delayed && @delayed.include?(concept_name))
|
|
71
|
-
# $stderr.puts "#{concept_name} was delayed, binding now"
|
|
72
|
-
d = @delayed[concept_name]
|
|
73
|
-
d.each{|(a,b)|
|
|
74
|
-
b.call(concept, *a)
|
|
75
|
-
}
|
|
76
|
-
@delayed.delete(concept_name)
|
|
77
|
-
end
|
|
78
|
-
end
|
|
79
|
-
|
|
80
|
-
end
|
|
81
|
-
end
|
|
82
|
-
end
|
data/spec/api/autocounter.rb
DELETED
|
@@ -1,82 +0,0 @@
|
|
|
1
|
-
#
|
|
2
|
-
# ActiveFacts tests: Value instances in the Runtime API
|
|
3
|
-
# Copyright (c) 2008 Clifford Heath. Read the LICENSE file.
|
|
4
|
-
#
|
|
5
|
-
describe "AutoCounter Value Type instances" do
|
|
6
|
-
before :each do
|
|
7
|
-
Object.send :remove_const, :Mod if Object.const_defined?("Mod")
|
|
8
|
-
module Mod
|
|
9
|
-
class ThingId < AutoCounter
|
|
10
|
-
value_type
|
|
11
|
-
end
|
|
12
|
-
class Thing
|
|
13
|
-
identified_by :thing_id
|
|
14
|
-
has_one :thing_id
|
|
15
|
-
end
|
|
16
|
-
class Ordinal < Int
|
|
17
|
-
value_type
|
|
18
|
-
end
|
|
19
|
-
class ThingFacet
|
|
20
|
-
identified_by :thing, :ordinal
|
|
21
|
-
has_one :thing
|
|
22
|
-
has_one :ordinal
|
|
23
|
-
end
|
|
24
|
-
end
|
|
25
|
-
@constellation = ActiveFacts::API::Constellation.new(Mod)
|
|
26
|
-
@thing = Mod::Thing.new(:new)
|
|
27
|
-
@thing_id = Mod::ThingId.new
|
|
28
|
-
end
|
|
29
|
-
|
|
30
|
-
it "should respond to verbalise" do
|
|
31
|
-
@thing_id.respond_to?(:verbalise).should be_true
|
|
32
|
-
end
|
|
33
|
-
|
|
34
|
-
it "should verbalise correctly" do
|
|
35
|
-
@thing_id.verbalise.should =~ /ThingId 'new_[0-9]+'/
|
|
36
|
-
end
|
|
37
|
-
|
|
38
|
-
it "should respond to constellation" do
|
|
39
|
-
@thing_id.respond_to?(:constellation).should be_true
|
|
40
|
-
end
|
|
41
|
-
|
|
42
|
-
it "should respond to its roles" do
|
|
43
|
-
@thing_id.respond_to?(:all_thing).should be_true
|
|
44
|
-
end
|
|
45
|
-
|
|
46
|
-
it "should allow prevent invalid role assignment" do
|
|
47
|
-
lambda {
|
|
48
|
-
@thing.thing_id = "foo"
|
|
49
|
-
}.should raise_error
|
|
50
|
-
end
|
|
51
|
-
|
|
52
|
-
it "should not allow its identifying roles to be assigned" do
|
|
53
|
-
lambda {
|
|
54
|
-
@thing.thing_id = @thing_id
|
|
55
|
-
}.should raise_error
|
|
56
|
-
end
|
|
57
|
-
|
|
58
|
-
it "should allow an existing counter to be re-used" do
|
|
59
|
-
@new_thing = Mod::Thing.new(@thing_id)
|
|
60
|
-
@new_thing.thing_id.should == @thing_id
|
|
61
|
-
end
|
|
62
|
-
|
|
63
|
-
it "should return the ValueType in response to .class()" do
|
|
64
|
-
@thing_id.class.vocabulary.should == Mod
|
|
65
|
-
end
|
|
66
|
-
|
|
67
|
-
it "should not allow a counter to be cloned" do
|
|
68
|
-
lambda {
|
|
69
|
-
@thing_id.clone
|
|
70
|
-
}.should raise_error
|
|
71
|
-
end
|
|
72
|
-
|
|
73
|
-
it "should allow an existing counter-identified object to be re-used" do
|
|
74
|
-
thing = @constellation.Thing(:new)
|
|
75
|
-
facets = []
|
|
76
|
-
facets << @constellation.ThingFacet(thing, 0)
|
|
77
|
-
facets << @constellation.ThingFacet(thing, 1)
|
|
78
|
-
facets[0].thing.object_id.should == facets[1].thing.object_id
|
|
79
|
-
facets[0].thing.thing_id.object_id.should == facets[1].thing.thing_id.object_id
|
|
80
|
-
end
|
|
81
|
-
|
|
82
|
-
end
|
data/spec/api/constellation.rb
DELETED
|
@@ -1,130 +0,0 @@
|
|
|
1
|
-
#
|
|
2
|
-
# ActiveFacts tests: Constellation instances in the Runtime API
|
|
3
|
-
# Copyright (c) 2008 Clifford Heath. Read the LICENSE file.
|
|
4
|
-
#
|
|
5
|
-
require "ruby-debug"
|
|
6
|
-
|
|
7
|
-
require 'activefacts/api'
|
|
8
|
-
|
|
9
|
-
describe "A Constellation instance" do
|
|
10
|
-
before :each do
|
|
11
|
-
Object.send :remove_const, :Mod if Object.const_defined?("Mod")
|
|
12
|
-
module Mod
|
|
13
|
-
@base_types = [
|
|
14
|
-
Int, Real, AutoCounter, String, Date, DateTime
|
|
15
|
-
]
|
|
16
|
-
|
|
17
|
-
# Create a value type and a subtype of that value type for each base type:
|
|
18
|
-
@base_types.each do |base_type|
|
|
19
|
-
eval %Q{
|
|
20
|
-
class #{base_type.name}Value < #{base_type.name}
|
|
21
|
-
value_type
|
|
22
|
-
end
|
|
23
|
-
|
|
24
|
-
class #{base_type.name}SubValue < #{base_type.name}Value
|
|
25
|
-
# Note no new "value_type" is required here, it comes through inheritance
|
|
26
|
-
end
|
|
27
|
-
}
|
|
28
|
-
end
|
|
29
|
-
|
|
30
|
-
class Name < StringValue
|
|
31
|
-
value_type
|
|
32
|
-
#has_one :attr, Name
|
|
33
|
-
end
|
|
34
|
-
|
|
35
|
-
class LegalEntity
|
|
36
|
-
identified_by :name
|
|
37
|
-
has_one :name
|
|
38
|
-
end
|
|
39
|
-
|
|
40
|
-
class SurrogateId
|
|
41
|
-
identified_by :auto_counter_value
|
|
42
|
-
has_one :auto_counter_value
|
|
43
|
-
end
|
|
44
|
-
|
|
45
|
-
class Company < LegalEntity
|
|
46
|
-
supertypes SurrogateId
|
|
47
|
-
end
|
|
48
|
-
|
|
49
|
-
class Person < LegalEntity
|
|
50
|
-
identified_by :name, :family_name # REVISIT: want a way to role_alias :name, :given_name
|
|
51
|
-
supertypes SurrogateId
|
|
52
|
-
|
|
53
|
-
has_one :family_name, :class => Name
|
|
54
|
-
end
|
|
55
|
-
end
|
|
56
|
-
@constellation = ActiveFacts::API::Constellation.new(Mod)
|
|
57
|
-
end
|
|
58
|
-
|
|
59
|
-
it "should support fetching its vocabulary" do
|
|
60
|
-
@constellation.vocabulary.should == Mod
|
|
61
|
-
end
|
|
62
|
-
|
|
63
|
-
# it "should support fetching its query" do
|
|
64
|
-
# pending
|
|
65
|
-
# @constellation.query.should == Mod
|
|
66
|
-
# end
|
|
67
|
-
|
|
68
|
-
it "should support methods to construct instances of any concept" do
|
|
69
|
-
name = foo = acme = fred_fly = nil
|
|
70
|
-
lambda {
|
|
71
|
-
name = @constellation.Name("foo")
|
|
72
|
-
foo = @constellation.LegalEntity("foo")
|
|
73
|
-
acme = @constellation.Company("Acme, Inc")
|
|
74
|
-
fred_fly = @constellation.Person("fred", "fly")
|
|
75
|
-
}.should_not raise_error
|
|
76
|
-
name.class.should == Mod::Name
|
|
77
|
-
name.constellation.should == @constellation
|
|
78
|
-
foo.class.should == Mod::LegalEntity
|
|
79
|
-
foo.constellation.should == @constellation
|
|
80
|
-
acme.class.should == Mod::Company
|
|
81
|
-
acme.constellation.should == @constellation
|
|
82
|
-
fred_fly.class.should == Mod::Person
|
|
83
|
-
fred_fly.constellation.should == @constellation
|
|
84
|
-
end
|
|
85
|
-
|
|
86
|
-
it "should re-use instances constructed the same way" do
|
|
87
|
-
name1 = @constellation.Name("foo")
|
|
88
|
-
foo1 = @constellation.LegalEntity("foo")
|
|
89
|
-
acme1 = @constellation.Company("Acme, Inc")
|
|
90
|
-
fred_fly1 = @constellation.Person("fred", "fly")
|
|
91
|
-
|
|
92
|
-
name2 = @constellation.Name("foo")
|
|
93
|
-
foo2 = @constellation.LegalEntity("foo")
|
|
94
|
-
acme2 = @constellation.Company("Acme, Inc")
|
|
95
|
-
fred_fly2 = @constellation.Person("fred", "fly")
|
|
96
|
-
|
|
97
|
-
name1.object_id.should == name2.object_id
|
|
98
|
-
foo1.object_id.should == foo2.object_id
|
|
99
|
-
acme1.object_id.should == acme2.object_id
|
|
100
|
-
fred_fly1.object_id.should == fred_fly2.object_id
|
|
101
|
-
end
|
|
102
|
-
|
|
103
|
-
it "should index value instances, including by its superclasses" do
|
|
104
|
-
baz = @constellation.Name("baz")
|
|
105
|
-
@constellation.Name.keys.sort.should == ["baz"]
|
|
106
|
-
|
|
107
|
-
@constellation.StringValue.keys.sort.should == ["baz"]
|
|
108
|
-
end
|
|
109
|
-
|
|
110
|
-
it "should index entity instances, including by its superclass and secondary supertypes" do
|
|
111
|
-
name = "Acme, Inc"
|
|
112
|
-
fred = "Fred"
|
|
113
|
-
fly = "Fly"
|
|
114
|
-
acme = @constellation.Company name, :auto_counter_value => :new
|
|
115
|
-
fred_fly = @constellation.Person fred, fly, :auto_counter_value => :new
|
|
116
|
-
|
|
117
|
-
# REVISIT: This should be illegal:
|
|
118
|
-
#fred_fly.auto_counter_value = :new
|
|
119
|
-
|
|
120
|
-
@constellation.Person.keys.sort.should == [[fred, fly]]
|
|
121
|
-
@constellation.Company.keys.sort.should == [[name]]
|
|
122
|
-
|
|
123
|
-
@constellation.LegalEntity.keys.sort.should be_include([name])
|
|
124
|
-
@constellation.LegalEntity.keys.sort.should be_include([fred])
|
|
125
|
-
|
|
126
|
-
@constellation.SurrogateId.values.should be_include(acme)
|
|
127
|
-
@constellation.SurrogateId.values.should be_include(fred_fly)
|
|
128
|
-
end
|
|
129
|
-
|
|
130
|
-
end
|