universe_compiler 0.2.11

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 (51) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +183 -0
  3. data/.rspec +2 -0
  4. data/.rubocop.yml +3 -0
  5. data/.travis.yml +4 -0
  6. data/CODE_OF_CONDUCT.md +49 -0
  7. data/Gemfile +4 -0
  8. data/LICENSE.txt +21 -0
  9. data/README.md +318 -0
  10. data/Rakefile +6 -0
  11. data/bin/console +10 -0
  12. data/bin/setup +8 -0
  13. data/lib/universe_compiler/entity/auto_named.rb +31 -0
  14. data/lib/universe_compiler/entity/conversion.rb +66 -0
  15. data/lib/universe_compiler/entity/field_binder.rb +36 -0
  16. data/lib/universe_compiler/entity/field_constraint_management.rb +95 -0
  17. data/lib/universe_compiler/entity/field_management.rb +57 -0
  18. data/lib/universe_compiler/entity/inheritance.rb +87 -0
  19. data/lib/universe_compiler/entity/inheritance_merge_policy.rb +19 -0
  20. data/lib/universe_compiler/entity/marshalling.rb +71 -0
  21. data/lib/universe_compiler/entity/overridden.rb +31 -0
  22. data/lib/universe_compiler/entity/persistence.rb +34 -0
  23. data/lib/universe_compiler/entity/reference.rb +77 -0
  24. data/lib/universe_compiler/entity/relations_management.rb +46 -0
  25. data/lib/universe_compiler/entity/type_management.rb +43 -0
  26. data/lib/universe_compiler/entity/validation.rb +92 -0
  27. data/lib/universe_compiler/entity.rb +64 -0
  28. data/lib/universe_compiler/error.rb +15 -0
  29. data/lib/universe_compiler/override.rb +24 -0
  30. data/lib/universe_compiler/package/bootstrap.rb +46 -0
  31. data/lib/universe_compiler/package.rb +17 -0
  32. data/lib/universe_compiler/persistence/basic_yaml_engine.rb +68 -0
  33. data/lib/universe_compiler/persistence/management.rb +30 -0
  34. data/lib/universe_compiler/universe/compile.rb +45 -0
  35. data/lib/universe_compiler/universe/duplication.rb +62 -0
  36. data/lib/universe_compiler/universe/entities.rb +52 -0
  37. data/lib/universe_compiler/universe/index.rb +40 -0
  38. data/lib/universe_compiler/universe/multiverse.rb +44 -0
  39. data/lib/universe_compiler/universe/persistence.rb +23 -0
  40. data/lib/universe_compiler/universe/query.rb +45 -0
  41. data/lib/universe_compiler/universe/validation.rb +30 -0
  42. data/lib/universe_compiler/universe.rb +38 -0
  43. data/lib/universe_compiler/utils/array_utils.rb +59 -0
  44. data/lib/universe_compiler/utils/basic_logger.rb +24 -0
  45. data/lib/universe_compiler/utils/deep_traverse.rb +61 -0
  46. data/lib/universe_compiler/utils/error_propagation.rb +20 -0
  47. data/lib/universe_compiler/utils/with_unique_name.rb +75 -0
  48. data/lib/universe_compiler/version.rb +3 -0
  49. data/lib/universe_compiler.rb +60 -0
  50. data/universe_compiler.gemspec +32 -0
  51. metadata +218 -0
@@ -0,0 +1,30 @@
1
+ module UniverseCompiler
2
+ module Universe
3
+
4
+ module Validation
5
+
6
+ def valid?(raise_error: false)
7
+ entities.each do |entity|
8
+ UniverseCompiler.logger.debug "Checking '#{entity.to_composite_key}'"
9
+ deep_map entity.fields do |leaf|
10
+ case leaf
11
+ when UniverseCompiler::Entity::Reference
12
+ return false_or_raise "Entity '#{entity.to_composite_key}' contains an invalid reference to '#{leaf.to_composite_key}' !", raise_error: raise_error
13
+ when UniverseCompiler::Entity::Base
14
+ unless leaf.universe == self
15
+ return false_or_raise "Entity '#{leaf.to_composite_key}' is not in the correct universe !", raise_error: raise_error
16
+ end
17
+ unless entities.include? leaf
18
+ return false_or_raise "Entity '#{leaf.to_composite_key}' is not present in unniverse !", raise_error: raise_error
19
+ end
20
+ end
21
+ end
22
+ entity.valid?
23
+ end
24
+ true
25
+ end
26
+
27
+ end
28
+
29
+ end
30
+ end
@@ -0,0 +1,38 @@
1
+ require 'active_support/core_ext/string/inflections'
2
+
3
+ require 'universe_compiler/universe/query'
4
+
5
+ module UniverseCompiler
6
+ module Universe
7
+
8
+ class Base
9
+
10
+ include UniverseCompiler::Utils::ErrorPropagation
11
+ extend UniverseCompiler::Universe::Multiverse
12
+ include UniverseCompiler::Universe::Entities
13
+ include UniverseCompiler::Universe::Index
14
+ include UniverseCompiler::Universe::Query
15
+ include UniverseCompiler::Universe::Validation
16
+ include UniverseCompiler::Universe::Duplication
17
+ include UniverseCompiler::Universe::Compile
18
+ include UniverseCompiler::Universe::Persistence
19
+
20
+ attr_reader :name
21
+
22
+ def initialize(name = self.class.get_unique_name)
23
+ @name = self.class.get_unique_name name
24
+ @entities = []
25
+ self.class.register self
26
+ setup_indices
27
+ end
28
+
29
+ def name=(value)
30
+ self.class.universes.delete name
31
+ @name = self.class.get_unique_name value
32
+ self.class.register self
33
+ end
34
+
35
+ end
36
+
37
+ end
38
+ end
@@ -0,0 +1,59 @@
1
+ module UniverseCompiler
2
+ module Utils
3
+
4
+ module ArrayUtils
5
+
6
+
7
+ def contains_only_one_of?(*choices)
8
+ used = used_choices *choices
9
+ return true, used if used.size == 1
10
+ return false, used
11
+ end
12
+
13
+ def contains_at_least_one_of?(*choices)
14
+ used = used_choices *choices
15
+ return true, used unless used.empty?
16
+ return false, used
17
+ end
18
+
19
+ def contains_all_of?(*choices)
20
+ used = used_choices *choices
21
+ return true, used if used.size == choices.size
22
+ return false, used
23
+ end
24
+
25
+ def raises_or_logs(msg, raise_exception=false, logger_level=:error)
26
+ if raise_exception then
27
+ raise UniverseCompiler::Error, msg
28
+ else
29
+ UniverseCompiler.logger.send logger_level, msg
30
+ return false
31
+ end
32
+ end
33
+
34
+ private
35
+
36
+ def used_choices(*choices)
37
+ choices.map do |choice|
38
+ choice_content = self.send choice
39
+ case choice_content
40
+ when NilClass
41
+ nil
42
+ when Fixnum
43
+ choice
44
+ when String
45
+ choice_content.empty? ? nil : choice
46
+ when Array
47
+ choice_content.empty? ? nil : choice
48
+ when Hash
49
+ choice_content.empty? ? nil : choice
50
+ end
51
+ end .compact
52
+ end
53
+
54
+
55
+
56
+ end
57
+
58
+ end
59
+ end
@@ -0,0 +1,24 @@
1
+ module UniverseCompiler
2
+ module Utils
3
+
4
+ module BasicLogger
5
+
6
+ class NullLogger
7
+ def method_missing(*args)
8
+ # Do nothing
9
+ end
10
+ end
11
+
12
+ def logger=(logger)
13
+ @logger = logger
14
+ yield logger if block_given?
15
+ end
16
+
17
+ def logger
18
+ @logger ||= NullLogger.new
19
+ end
20
+
21
+ end
22
+
23
+ end
24
+ end
@@ -0,0 +1,61 @@
1
+ module UniverseCompiler
2
+ module Utils
3
+
4
+ module DeepTraverse
5
+
6
+ def deep_traverse(structure, &block)
7
+ case structure
8
+ when Hash
9
+ deep_traverse_hash structure, &block
10
+ when Array
11
+ deep_traverse_array structure, &block
12
+ else
13
+ yield structure
14
+ end
15
+ end
16
+
17
+ def deep_map(structure, &block)
18
+ case structure
19
+ when Hash
20
+ deep_map_hash structure, &block
21
+ when Array
22
+ deep_map_array structure, &block
23
+ else
24
+ yield structure
25
+ end
26
+ end
27
+
28
+ private
29
+
30
+ def deep_traverse_hash(hash, &block)
31
+ hash.each do |k, v|
32
+ deep_traverse k, &block
33
+ deep_traverse v, &block
34
+ end
35
+ end
36
+
37
+ def deep_traverse_array(array, &block)
38
+ array.each.with_index do |v, idx|
39
+ deep_traverse v, &block
40
+ end
41
+ end
42
+
43
+ def deep_map_hash(hash, res = {}, &block)
44
+ hash.each do |k, v|
45
+ k = deep_map k, &block
46
+ res[k] = deep_map v, &block
47
+ end
48
+ res
49
+ end
50
+
51
+ def deep_map_array(array, res = [], &block)
52
+ array.each.with_index do |v, idx|
53
+ res[idx] = deep_map v, &block
54
+ end
55
+ res
56
+ end
57
+
58
+ end
59
+
60
+ end
61
+ end
@@ -0,0 +1,20 @@
1
+ module UniverseCompiler
2
+ module Utils
3
+
4
+ module ErrorPropagation
5
+
6
+ private
7
+
8
+ def false_or_raise(message = 'Error message not provided!', raise_error: false)
9
+ if raise_error
10
+ raise UniverseCompiler::Error, message
11
+ else
12
+ UniverseCompiler.logger.warn message
13
+ end
14
+ false
15
+ end
16
+
17
+ end
18
+
19
+ end
20
+ end
@@ -0,0 +1,75 @@
1
+ module UniverseCompiler
2
+ module Utils
3
+
4
+ module WithUniqueName
5
+
6
+ module ClassMethods
7
+
8
+ DEFAULT_SEED = 'Unknown'.freeze
9
+
10
+ def set_name_seed(name_seed)
11
+ @name_seed = name_seed.to_s
12
+ end
13
+
14
+ def name_seed
15
+ @name_seed ||DEFAULT_SEED
16
+ end
17
+
18
+ def instances
19
+ @instances ||= {}
20
+ @instances.dup
21
+ end
22
+
23
+ def new_instance(name, *args)
24
+ check_name name
25
+ new_instance = new *args
26
+ @instance[name] = new_instance
27
+ new_instance
28
+ end
29
+
30
+ def set_name(name, object)
31
+ check_name name
32
+ old_name = instances.key object
33
+ @instances[old_name] = nil unless old_name.nil?
34
+ @instances[name] = object
35
+ end
36
+
37
+ def get_unique_name
38
+ '%s_%d' % [name_seed, instance_counter]
39
+ end
40
+
41
+ private
42
+
43
+ def instance_counter
44
+ @instance_counter ||= 0
45
+ @instance_counter += 1
46
+ @instance_counter
47
+ end
48
+
49
+ def check_name(name)
50
+ raise UniverseCompiler::Error, 'There is already an instance of %s named %s' % [self, name] unless instances[name].nil?
51
+ end
52
+
53
+ end
54
+
55
+ def name
56
+ defined_name = self.class.instances.key self
57
+ if defined_name.nil?
58
+ defined_name = self.class.get_unique_name
59
+ self.name = defined_name
60
+ end
61
+ defined_name
62
+ end
63
+
64
+ def name=(name)
65
+ self.class.set_name name, self
66
+ end
67
+
68
+ def self.included(base)
69
+ base.extend UniverseCompiler::Utils::WithUniqueName::ClassMethods
70
+ end
71
+
72
+ end
73
+
74
+ end
75
+ end
@@ -0,0 +1,3 @@
1
+ module UniverseCompiler
2
+ VERSION = '0.2.11'.freeze
3
+ end
@@ -0,0 +1,60 @@
1
+ require 'super_stack'
2
+
3
+ require 'universe_compiler/version'
4
+ require 'universe_compiler/error'
5
+ require 'universe_compiler/utils/basic_logger'
6
+ require 'universe_compiler/utils/error_propagation'
7
+ require 'universe_compiler/utils/array_utils'
8
+ require 'universe_compiler/utils/deep_traverse'
9
+ require 'universe_compiler/utils/with_unique_name'
10
+
11
+ module UniverseCompiler
12
+ extend UniverseCompiler::Utils::BasicLogger
13
+ end
14
+
15
+ # Entity
16
+ require 'universe_compiler/entity/type_management'
17
+ require 'universe_compiler/entity/auto_named'
18
+ require 'universe_compiler/entity/conversion'
19
+ require 'universe_compiler/entity/reference'
20
+ require 'universe_compiler/entity/marshalling'
21
+ require 'universe_compiler/entity/field_binder'
22
+ require 'universe_compiler/entity/field_management'
23
+ require 'universe_compiler/entity/field_constraint_management'
24
+ require 'universe_compiler/entity/relations_management'
25
+ require 'universe_compiler/entity/validation'
26
+ require 'universe_compiler/entity/inheritance_merge_policy'
27
+ require 'universe_compiler/entity/inheritance'
28
+ require 'universe_compiler/entity/overridden'
29
+ require 'universe_compiler/entity/persistence'
30
+ require 'universe_compiler/entity'
31
+ require 'universe_compiler/override'
32
+ # Persistence
33
+ require 'universe_compiler/persistence/basic_yaml_engine'
34
+ require 'universe_compiler/persistence/management'
35
+ # Universe
36
+ require 'universe_compiler/universe/multiverse'
37
+ require 'universe_compiler/universe/entities'
38
+ require 'universe_compiler/universe/index'
39
+ require 'universe_compiler/universe/query'
40
+ require 'universe_compiler/universe/validation'
41
+ require 'universe_compiler/universe/duplication'
42
+ require 'universe_compiler/universe/compile'
43
+ require 'universe_compiler/universe/persistence'
44
+ require 'universe_compiler/universe'
45
+ # Packages
46
+ require 'universe_compiler/package/bootstrap'
47
+ require 'universe_compiler/package'
48
+
49
+
50
+ module UniverseCompiler
51
+
52
+ def self.new_universe(*args)
53
+ UniverseCompiler::Universe::Base.new *args
54
+ end
55
+
56
+ def self.new_override(*args)
57
+ UniverseCompiler::Entity::Override.new *args
58
+ end
59
+
60
+ end
@@ -0,0 +1,32 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'universe_compiler/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = 'universe_compiler'
8
+ spec.version = UniverseCompiler::VERSION
9
+ spec.authors = ['Laurent B.']
10
+ spec.email = ['lbnetid+rb@gmail.com']
11
+
12
+ spec.summary = 'Manage a set of entities with complex interactions.'
13
+ spec.description = 'Provide a way to create objects with complex relationships, inheritance and override mechanisms.'
14
+ spec.homepage = 'https://gitlab.com/tools4devops/universe_compiler'
15
+ spec.license = 'MIT'
16
+
17
+ spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
18
+ spec.bindir = 'exe'
19
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
20
+ spec.require_paths = ['lib']
21
+
22
+ spec.add_development_dependency 'bundler', '~> 2.0'
23
+ spec.add_development_dependency 'rake', '~> 10.0'
24
+ spec.add_development_dependency 'rspec', '~> 3.0'
25
+ spec.add_development_dependency 'factory_girl', '~> 4.0', '>= 4.8'
26
+ spec.add_development_dependency 'rubocop'
27
+ spec.add_development_dependency 'pry'
28
+
29
+ spec.add_runtime_dependency 'super_stack', '~> 1.0', '>= 1.0.6'
30
+ spec.add_runtime_dependency 'activesupport', '~> 5.0'
31
+
32
+ end
metadata ADDED
@@ -0,0 +1,218 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: universe_compiler
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.2.11
5
+ platform: ruby
6
+ authors:
7
+ - Laurent B.
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2019-08-28 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '2.0'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '2.0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '3.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '3.0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: factory_girl
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '4.0'
62
+ - - ">="
63
+ - !ruby/object:Gem::Version
64
+ version: '4.8'
65
+ type: :development
66
+ prerelease: false
67
+ version_requirements: !ruby/object:Gem::Requirement
68
+ requirements:
69
+ - - "~>"
70
+ - !ruby/object:Gem::Version
71
+ version: '4.0'
72
+ - - ">="
73
+ - !ruby/object:Gem::Version
74
+ version: '4.8'
75
+ - !ruby/object:Gem::Dependency
76
+ name: rubocop
77
+ requirement: !ruby/object:Gem::Requirement
78
+ requirements:
79
+ - - ">="
80
+ - !ruby/object:Gem::Version
81
+ version: '0'
82
+ type: :development
83
+ prerelease: false
84
+ version_requirements: !ruby/object:Gem::Requirement
85
+ requirements:
86
+ - - ">="
87
+ - !ruby/object:Gem::Version
88
+ version: '0'
89
+ - !ruby/object:Gem::Dependency
90
+ name: pry
91
+ requirement: !ruby/object:Gem::Requirement
92
+ requirements:
93
+ - - ">="
94
+ - !ruby/object:Gem::Version
95
+ version: '0'
96
+ type: :development
97
+ prerelease: false
98
+ version_requirements: !ruby/object:Gem::Requirement
99
+ requirements:
100
+ - - ">="
101
+ - !ruby/object:Gem::Version
102
+ version: '0'
103
+ - !ruby/object:Gem::Dependency
104
+ name: super_stack
105
+ requirement: !ruby/object:Gem::Requirement
106
+ requirements:
107
+ - - "~>"
108
+ - !ruby/object:Gem::Version
109
+ version: '1.0'
110
+ - - ">="
111
+ - !ruby/object:Gem::Version
112
+ version: 1.0.6
113
+ type: :runtime
114
+ prerelease: false
115
+ version_requirements: !ruby/object:Gem::Requirement
116
+ requirements:
117
+ - - "~>"
118
+ - !ruby/object:Gem::Version
119
+ version: '1.0'
120
+ - - ">="
121
+ - !ruby/object:Gem::Version
122
+ version: 1.0.6
123
+ - !ruby/object:Gem::Dependency
124
+ name: activesupport
125
+ requirement: !ruby/object:Gem::Requirement
126
+ requirements:
127
+ - - "~>"
128
+ - !ruby/object:Gem::Version
129
+ version: '5.0'
130
+ type: :runtime
131
+ prerelease: false
132
+ version_requirements: !ruby/object:Gem::Requirement
133
+ requirements:
134
+ - - "~>"
135
+ - !ruby/object:Gem::Version
136
+ version: '5.0'
137
+ description: Provide a way to create objects with complex relationships, inheritance
138
+ and override mechanisms.
139
+ email:
140
+ - lbnetid+rb@gmail.com
141
+ executables: []
142
+ extensions: []
143
+ extra_rdoc_files: []
144
+ files:
145
+ - ".gitignore"
146
+ - ".rspec"
147
+ - ".rubocop.yml"
148
+ - ".travis.yml"
149
+ - CODE_OF_CONDUCT.md
150
+ - Gemfile
151
+ - LICENSE.txt
152
+ - README.md
153
+ - Rakefile
154
+ - bin/console
155
+ - bin/setup
156
+ - lib/universe_compiler.rb
157
+ - lib/universe_compiler/entity.rb
158
+ - lib/universe_compiler/entity/auto_named.rb
159
+ - lib/universe_compiler/entity/conversion.rb
160
+ - lib/universe_compiler/entity/field_binder.rb
161
+ - lib/universe_compiler/entity/field_constraint_management.rb
162
+ - lib/universe_compiler/entity/field_management.rb
163
+ - lib/universe_compiler/entity/inheritance.rb
164
+ - lib/universe_compiler/entity/inheritance_merge_policy.rb
165
+ - lib/universe_compiler/entity/marshalling.rb
166
+ - lib/universe_compiler/entity/overridden.rb
167
+ - lib/universe_compiler/entity/persistence.rb
168
+ - lib/universe_compiler/entity/reference.rb
169
+ - lib/universe_compiler/entity/relations_management.rb
170
+ - lib/universe_compiler/entity/type_management.rb
171
+ - lib/universe_compiler/entity/validation.rb
172
+ - lib/universe_compiler/error.rb
173
+ - lib/universe_compiler/override.rb
174
+ - lib/universe_compiler/package.rb
175
+ - lib/universe_compiler/package/bootstrap.rb
176
+ - lib/universe_compiler/persistence/basic_yaml_engine.rb
177
+ - lib/universe_compiler/persistence/management.rb
178
+ - lib/universe_compiler/universe.rb
179
+ - lib/universe_compiler/universe/compile.rb
180
+ - lib/universe_compiler/universe/duplication.rb
181
+ - lib/universe_compiler/universe/entities.rb
182
+ - lib/universe_compiler/universe/index.rb
183
+ - lib/universe_compiler/universe/multiverse.rb
184
+ - lib/universe_compiler/universe/persistence.rb
185
+ - lib/universe_compiler/universe/query.rb
186
+ - lib/universe_compiler/universe/validation.rb
187
+ - lib/universe_compiler/utils/array_utils.rb
188
+ - lib/universe_compiler/utils/basic_logger.rb
189
+ - lib/universe_compiler/utils/deep_traverse.rb
190
+ - lib/universe_compiler/utils/error_propagation.rb
191
+ - lib/universe_compiler/utils/with_unique_name.rb
192
+ - lib/universe_compiler/version.rb
193
+ - universe_compiler.gemspec
194
+ homepage: https://gitlab.com/tools4devops/universe_compiler
195
+ licenses:
196
+ - MIT
197
+ metadata: {}
198
+ post_install_message:
199
+ rdoc_options: []
200
+ require_paths:
201
+ - lib
202
+ required_ruby_version: !ruby/object:Gem::Requirement
203
+ requirements:
204
+ - - ">="
205
+ - !ruby/object:Gem::Version
206
+ version: '0'
207
+ required_rubygems_version: !ruby/object:Gem::Requirement
208
+ requirements:
209
+ - - ">="
210
+ - !ruby/object:Gem::Version
211
+ version: '0'
212
+ requirements: []
213
+ rubyforge_project:
214
+ rubygems_version: 2.5.1
215
+ signing_key:
216
+ specification_version: 4
217
+ summary: Manage a set of entities with complex interactions.
218
+ test_files: []