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.
Files changed (120) hide show
  1. data/.gemtest +0 -0
  2. data/Manifest.txt +28 -33
  3. data/Rakefile +11 -12
  4. data/bin/cql +90 -46
  5. data/examples/CQL/Blog.cql +2 -1
  6. data/examples/CQL/CompanyDirectorEmployee.cql +2 -2
  7. data/examples/CQL/Death.cql +1 -1
  8. data/examples/CQL/Diplomacy.cql +9 -9
  9. data/examples/CQL/Genealogy.cql +3 -2
  10. data/examples/CQL/Insurance.cql +10 -7
  11. data/examples/CQL/JoinEquality.cql +2 -2
  12. data/examples/CQL/Marriage.cql +1 -1
  13. data/examples/CQL/Metamodel.cql +73 -53
  14. data/examples/CQL/MetamodelNext.cql +89 -67
  15. data/examples/CQL/OneToOnes.cql +2 -2
  16. data/examples/CQL/ServiceDirector.cql +10 -5
  17. data/examples/CQL/Supervision.cql +3 -3
  18. data/examples/CQL/Tests.Test5.Load.cql +1 -1
  19. data/examples/CQL/Warehousing.cql +4 -2
  20. data/lib/activefacts/cql/CQLParser.treetop +26 -60
  21. data/lib/activefacts/cql/Context.treetop +12 -2
  22. data/lib/activefacts/cql/Expressions.treetop +14 -30
  23. data/lib/activefacts/cql/FactTypes.treetop +165 -110
  24. data/lib/activefacts/cql/Language/English.treetop +167 -54
  25. data/lib/activefacts/cql/LexicalRules.treetop +16 -2
  26. data/lib/activefacts/cql/{Concepts.treetop → ObjectTypes.treetop} +36 -37
  27. data/lib/activefacts/cql/Terms.treetop +57 -27
  28. data/lib/activefacts/cql/ValueTypes.treetop +39 -13
  29. data/lib/activefacts/cql/compiler.rb +5 -3
  30. data/lib/activefacts/cql/compiler/{reading.rb → clause.rb} +407 -285
  31. data/lib/activefacts/cql/compiler/constraint.rb +178 -275
  32. data/lib/activefacts/cql/compiler/entity_type.rb +73 -64
  33. data/lib/activefacts/cql/compiler/expression.rb +418 -0
  34. data/lib/activefacts/cql/compiler/fact.rb +146 -145
  35. data/lib/activefacts/cql/compiler/fact_type.rb +197 -80
  36. data/lib/activefacts/cql/compiler/join.rb +159 -0
  37. data/lib/activefacts/cql/compiler/shared.rb +51 -23
  38. data/lib/activefacts/cql/compiler/value_type.rb +56 -2
  39. data/lib/activefacts/cql/parser.rb +15 -4
  40. data/lib/activefacts/generate/absorption.rb +7 -7
  41. data/lib/activefacts/generate/cql.rb +100 -37
  42. data/lib/activefacts/generate/oo.rb +28 -51
  43. data/lib/activefacts/generate/ordered.rb +60 -36
  44. data/lib/activefacts/generate/ruby.rb +6 -6
  45. data/lib/activefacts/generate/sql/server.rb +4 -4
  46. data/lib/activefacts/input/orm.rb +71 -53
  47. data/lib/activefacts/persistence.rb +1 -1
  48. data/lib/activefacts/persistence/columns.rb +27 -23
  49. data/lib/activefacts/persistence/foreignkey.rb +6 -6
  50. data/lib/activefacts/persistence/index.rb +17 -17
  51. data/lib/activefacts/persistence/{concept.rb → object_type.rb} +9 -9
  52. data/lib/activefacts/persistence/reference.rb +61 -36
  53. data/lib/activefacts/persistence/tables.rb +61 -59
  54. data/lib/activefacts/support.rb +54 -29
  55. data/lib/activefacts/version.rb +1 -1
  56. data/lib/activefacts/vocabulary/extensions.rb +99 -54
  57. data/lib/activefacts/vocabulary/metamodel.rb +43 -37
  58. data/lib/activefacts/vocabulary/verbaliser.rb +134 -109
  59. data/spec/absorption_spec.rb +8 -8
  60. data/spec/cql/comparison_spec.rb +91 -0
  61. data/spec/cql/contractions_spec.rb +251 -0
  62. data/spec/cql/entity_type_spec.rb +319 -0
  63. data/spec/cql/expressions_spec.rb +63 -0
  64. data/spec/cql/fact_type_matching_spec.rb +283 -0
  65. data/spec/cql/french_spec.rb +21 -0
  66. data/spec/cql/parser/bad_literals_spec.rb +86 -0
  67. data/spec/cql/parser/constraints_spec.rb +19 -0
  68. data/spec/cql/parser/entity_types_spec.rb +106 -0
  69. data/spec/cql/parser/expressions_spec.rb +179 -0
  70. data/spec/cql/parser/fact_types_spec.rb +41 -0
  71. data/spec/cql/parser/literals_spec.rb +312 -0
  72. data/spec/cql/parser/pragmas_spec.rb +89 -0
  73. data/spec/cql/parser/value_types_spec.rb +42 -0
  74. data/spec/cql/role_matching_spec.rb +147 -0
  75. data/spec/cql/samples_spec.rb +9 -9
  76. data/spec/cql_cql_spec.rb +1 -1
  77. data/spec/cql_dm_spec.rb +116 -0
  78. data/spec/cql_mysql_spec.rb +1 -1
  79. data/spec/cql_ruby_spec.rb +1 -1
  80. data/spec/cql_sql_spec.rb +3 -3
  81. data/spec/cql_symbol_tables_spec.rb +30 -30
  82. data/spec/cqldump_spec.rb +4 -4
  83. data/spec/helpers/array_matcher.rb +32 -27
  84. data/spec/helpers/diff_matcher.rb +6 -26
  85. data/spec/helpers/file_matcher.rb +41 -32
  86. data/spec/helpers/parse_to_ast_matcher.rb +76 -0
  87. data/spec/helpers/string_matcher.rb +32 -31
  88. data/spec/norma_cql_spec.rb +1 -1
  89. data/spec/norma_ruby_spec.rb +1 -1
  90. data/spec/norma_ruby_sql_spec.rb +1 -1
  91. data/spec/norma_sql_spec.rb +3 -1
  92. data/spec/norma_tables_spec.rb +1 -1
  93. data/spec/ruby_api_spec.rb +23 -0
  94. data/spec/spec_helper.rb +5 -4
  95. metadata +66 -66
  96. data/examples/CQL/OrienteeringER.cql +0 -58
  97. data/lib/activefacts/api.rb +0 -44
  98. data/lib/activefacts/api/concept.rb +0 -410
  99. data/lib/activefacts/api/constellation.rb +0 -128
  100. data/lib/activefacts/api/entity.rb +0 -256
  101. data/lib/activefacts/api/instance.rb +0 -60
  102. data/lib/activefacts/api/instance_index.rb +0 -80
  103. data/lib/activefacts/api/numeric.rb +0 -167
  104. data/lib/activefacts/api/role.rb +0 -80
  105. data/lib/activefacts/api/role_proxy.rb +0 -70
  106. data/lib/activefacts/api/role_values.rb +0 -117
  107. data/lib/activefacts/api/standard_types.rb +0 -87
  108. data/lib/activefacts/api/support.rb +0 -65
  109. data/lib/activefacts/api/value.rb +0 -135
  110. data/lib/activefacts/api/vocabulary.rb +0 -82
  111. data/spec/api/autocounter.rb +0 -82
  112. data/spec/api/constellation.rb +0 -130
  113. data/spec/api/entity_type.rb +0 -103
  114. data/spec/api/instance.rb +0 -461
  115. data/spec/api/roles.rb +0 -124
  116. data/spec/api/value_type.rb +0 -112
  117. data/spec/api_spec.rb +0 -13
  118. data/spec/cql/matching_spec.rb +0 -517
  119. data/spec/cql/unit_spec.rb +0 -394
  120. 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
@@ -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
@@ -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