cascading_configuration 1.0.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/CHANGELOG.md +40 -0
- data/README.md +211 -0
- data/lib/cascading_configuration/array/sorted/unique.rb +110 -0
- data/lib/cascading_configuration/array/sorted.rb +106 -0
- data/lib/cascading_configuration/array/unique.rb +106 -0
- data/lib/cascading_configuration/array.rb +103 -0
- data/lib/cascading_configuration/core/enable_instance_support.rb +22 -0
- data/lib/cascading_configuration/core/enable_module_support.rb +24 -0
- data/lib/cascading_configuration/core/encapsulation.rb +343 -0
- data/lib/cascading_configuration/core/instance_controller/extension_module.rb +38 -0
- data/lib/cascading_configuration/core/instance_controller/support_module/instance_support_module.rb +21 -0
- data/lib/cascading_configuration/core/instance_controller/support_module/singleton_support_module.rb +21 -0
- data/lib/cascading_configuration/core/instance_controller/support_module.rb +253 -0
- data/lib/cascading_configuration/core/instance_controller.rb +840 -0
- data/lib/cascading_configuration/core/module/block_configurations/cascading_variables.rb +129 -0
- data/lib/cascading_configuration/core/module/block_configurations.rb +15 -0
- data/lib/cascading_configuration/core/module/extended_configurations/compositing_objects.rb +173 -0
- data/lib/cascading_configuration/core/module/extended_configurations.rb +65 -0
- data/lib/cascading_configuration/core/module/inheriting_values.rb +64 -0
- data/lib/cascading_configuration/core/module.rb +284 -0
- data/lib/cascading_configuration/core.rb +23 -0
- data/lib/cascading_configuration/hash.rb +103 -0
- data/lib/cascading_configuration/setting.rb +87 -0
- data/lib/cascading_configuration.rb +47 -0
- data/lib/namespaces.rb +9 -0
- data/lib/requires.rb +46 -0
- data/spec/cascading_configuration/array/sorted/unique_spec.rb +742 -0
- data/spec/cascading_configuration/array/sorted_spec.rb +741 -0
- data/spec/cascading_configuration/array/unique_spec.rb +746 -0
- data/spec/cascading_configuration/array_spec.rb +768 -0
- data/spec/cascading_configuration/core/encapsulation_spec.rb +208 -0
- data/spec/cascading_configuration/core/instance_controller/extension_module_spec.rb +26 -0
- data/spec/cascading_configuration/core/instance_controller/support_module_spec.rb +269 -0
- data/spec/cascading_configuration/core/instance_controller_spec.rb +273 -0
- data/spec/cascading_configuration/core/module/block_configurations/cascading_variables_spec.rb +17 -0
- data/spec/cascading_configuration/core/module/extended_configurations/compositing_objects_spec.rb +127 -0
- data/spec/cascading_configuration/core/module/extended_configurations_spec.rb +37 -0
- data/spec/cascading_configuration/core/module/inheriting_values_spec.rb +87 -0
- data/spec/cascading_configuration/core/module_spec.rb +491 -0
- data/spec/cascading_configuration/hash_spec.rb +826 -0
- data/spec/cascading_configuration/setting_spec.rb +687 -0
- data/spec/cascading_configuration_spec.rb +58 -0
- metadata +185 -0
@@ -0,0 +1,22 @@
|
|
1
|
+
|
2
|
+
module ::CascadingConfiguration::Core::EnableInstanceSupport
|
3
|
+
|
4
|
+
##############
|
5
|
+
# included #
|
6
|
+
##############
|
7
|
+
|
8
|
+
def included( instance )
|
9
|
+
|
10
|
+
super if defined?( super )
|
11
|
+
|
12
|
+
# Ensure our instance has an instance controller
|
13
|
+
unless instance_controller = ::CascadingConfiguration::Core::InstanceController.instance_controller( instance )
|
14
|
+
default_encapsulation = self::ClassInstance.default_encapsulation
|
15
|
+
instance_controller = ::CascadingConfiguration::Core::InstanceController.new( instance, default_encapsulation )
|
16
|
+
end
|
17
|
+
|
18
|
+
instance_controller.create_instance_support
|
19
|
+
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
|
2
|
+
module ::CascadingConfiguration::Core::EnableModuleSupport
|
3
|
+
|
4
|
+
##############
|
5
|
+
# extended #
|
6
|
+
##############
|
7
|
+
|
8
|
+
def extended( instance )
|
9
|
+
|
10
|
+
super if defined?( super )
|
11
|
+
|
12
|
+
# Ensure our instance has an instance controller
|
13
|
+
unless instance_controller = ::CascadingConfiguration::Core::InstanceController.instance_controller( instance )
|
14
|
+
instance_controller = ::CascadingConfiguration::Core::InstanceController.new( instance,
|
15
|
+
@default_encapsulation,
|
16
|
+
:Controller,
|
17
|
+
true )
|
18
|
+
end
|
19
|
+
|
20
|
+
instance_controller.create_singleton_support
|
21
|
+
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
@@ -0,0 +1,343 @@
|
|
1
|
+
|
2
|
+
class ::CascadingConfiguration::Core::Encapsulation < ::Module
|
3
|
+
|
4
|
+
include ::ParallelAncestry
|
5
|
+
|
6
|
+
InstanceStruct = ::Struct.new( :configuration_variables_hash,
|
7
|
+
:configurations_hash,
|
8
|
+
:parent_for_configuration_hash )
|
9
|
+
|
10
|
+
@encapsulations = { }
|
11
|
+
|
12
|
+
########################
|
13
|
+
# self.encapsulation #
|
14
|
+
########################
|
15
|
+
|
16
|
+
def self.encapsulation( encapsulation_or_name, ensure_exists = false )
|
17
|
+
|
18
|
+
encapsulation_instance = nil
|
19
|
+
|
20
|
+
case encapsulation_or_name
|
21
|
+
|
22
|
+
when nil
|
23
|
+
|
24
|
+
encapsulation_instance = ::CascadingConfiguration::Core::Module::DefaultEncapsulation
|
25
|
+
|
26
|
+
when self
|
27
|
+
|
28
|
+
encapsulation_instance = encapsulation_or_name
|
29
|
+
|
30
|
+
when ::Symbol, ::String
|
31
|
+
|
32
|
+
unless encapsulation_instance = @encapsulations[ encapsulation_or_name ]
|
33
|
+
if ensure_exists
|
34
|
+
exception_string = 'No encapsulation defined for :' << encapsulation_or_name.to_s
|
35
|
+
exception_string << '.'
|
36
|
+
raise ::ArgumentError, exception_string
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
41
|
+
|
42
|
+
return encapsulation_instance
|
43
|
+
|
44
|
+
end
|
45
|
+
|
46
|
+
################
|
47
|
+
# initialize #
|
48
|
+
################
|
49
|
+
|
50
|
+
def initialize( encapsulation_name )
|
51
|
+
|
52
|
+
super()
|
53
|
+
|
54
|
+
@encapsulation_name = encapsulation_name
|
55
|
+
|
56
|
+
encapsulation_instance = self
|
57
|
+
|
58
|
+
# We manage reference to self in singleton from here to avoid duplicative efforts.
|
59
|
+
self.class.class_eval do
|
60
|
+
@encapsulations[ encapsulation_name ] = encapsulation_instance
|
61
|
+
const_set( encapsulation_name.to_s.to_camel_case, encapsulation_instance )
|
62
|
+
end
|
63
|
+
|
64
|
+
@instances_hash = { }
|
65
|
+
|
66
|
+
end
|
67
|
+
|
68
|
+
########################
|
69
|
+
# encapsulation_name #
|
70
|
+
########################
|
71
|
+
|
72
|
+
attr_reader :encapsulation_name
|
73
|
+
|
74
|
+
#########################
|
75
|
+
# has_configurations? #
|
76
|
+
#########################
|
77
|
+
|
78
|
+
def has_configurations?( instance )
|
79
|
+
|
80
|
+
return ! configurations( instance ).empty?
|
81
|
+
|
82
|
+
end
|
83
|
+
|
84
|
+
#########################
|
85
|
+
# configuration_names #
|
86
|
+
#########################
|
87
|
+
|
88
|
+
def configuration_names( instance )
|
89
|
+
|
90
|
+
return configurations( instance ).keys
|
91
|
+
|
92
|
+
end
|
93
|
+
|
94
|
+
############################
|
95
|
+
# register_configuration #
|
96
|
+
############################
|
97
|
+
|
98
|
+
def register_configuration( instance, configuration_name, configuration_module )
|
99
|
+
|
100
|
+
# Record that a configuration is defined for this instance.
|
101
|
+
#
|
102
|
+
# This doesn't suggest that a configuration exists for this instance and name, only that it has
|
103
|
+
# been registered to acknowledge it could exist.
|
104
|
+
return configurations( instance )[ configuration_name ] = configuration_module
|
105
|
+
|
106
|
+
end
|
107
|
+
|
108
|
+
####################
|
109
|
+
# configurations #
|
110
|
+
####################
|
111
|
+
|
112
|
+
def configurations( instance )
|
113
|
+
|
114
|
+
return configuration_struct( instance ).configurations_hash ||= { }
|
115
|
+
|
116
|
+
end
|
117
|
+
|
118
|
+
########################
|
119
|
+
# has_configuration? #
|
120
|
+
########################
|
121
|
+
|
122
|
+
def has_configuration?( instance, configuration_name )
|
123
|
+
|
124
|
+
has_configuration = nil
|
125
|
+
|
126
|
+
unless has_configuration = configurations( instance ).has_key?( configuration_name ) or
|
127
|
+
instance == instance.class
|
128
|
+
has_configuration = configurations( instance.class ).has_key?( configuration_name )
|
129
|
+
end
|
130
|
+
|
131
|
+
return has_configuration
|
132
|
+
|
133
|
+
end
|
134
|
+
|
135
|
+
##########################
|
136
|
+
# remove_configuration #
|
137
|
+
##########################
|
138
|
+
|
139
|
+
def remove_configuration( instance, configuration_name )
|
140
|
+
|
141
|
+
return configurations( instance ).delete( configuration_name )
|
142
|
+
|
143
|
+
end
|
144
|
+
|
145
|
+
###############################
|
146
|
+
# register_child_for_parent #
|
147
|
+
###############################
|
148
|
+
|
149
|
+
def register_child_for_parent( child, parent )
|
150
|
+
|
151
|
+
super
|
152
|
+
|
153
|
+
# Modules already have configurations and if parent already has configurations
|
154
|
+
unless parent.is_a?( ::Module ) or has_parents?( parent )
|
155
|
+
register_child_for_parent( parent, parent.class )
|
156
|
+
end
|
157
|
+
|
158
|
+
parent_configurations = configurations( parent )
|
159
|
+
|
160
|
+
parent_configurations.each do |this_name, this_configuration_module|
|
161
|
+
register_configuration( child, this_name, this_configuration_module )
|
162
|
+
register_parent_for_configuration( child, parent, this_name )
|
163
|
+
this_configuration_module.create_configuration( self, child, this_name )
|
164
|
+
end
|
165
|
+
|
166
|
+
parent_configurations.each do |this_name, this_configuration_module|
|
167
|
+
this_configuration_module.initialize_configuration( self, child, this_name )
|
168
|
+
end
|
169
|
+
|
170
|
+
end
|
171
|
+
|
172
|
+
##################################
|
173
|
+
# is_parent_for_configuration? #
|
174
|
+
##################################
|
175
|
+
|
176
|
+
def is_parent_for_configuration?( existing_parent, configuration_name, parent )
|
177
|
+
|
178
|
+
is_parent_for_configuration = false
|
179
|
+
|
180
|
+
this_parent = existing_parent
|
181
|
+
|
182
|
+
begin
|
183
|
+
|
184
|
+
if this_parent.equal?( parent )
|
185
|
+
is_parent_for_configuration = true
|
186
|
+
end
|
187
|
+
|
188
|
+
end while this_parent = parent_for_configuration( this_parent, configuration_name )
|
189
|
+
|
190
|
+
return is_parent_for_configuration
|
191
|
+
|
192
|
+
end
|
193
|
+
|
194
|
+
#######################################
|
195
|
+
# register_parent_for_configuration #
|
196
|
+
#######################################
|
197
|
+
|
198
|
+
def register_parent_for_configuration( child, parent, configuration_name )
|
199
|
+
|
200
|
+
parents_hash = parent_for_configuration_hash( child )
|
201
|
+
|
202
|
+
# if we already have a parent, check to see if new parent is an ancestor of it
|
203
|
+
# if so, keep existing parent
|
204
|
+
unless existing_parent = parents_hash[ configuration_name ] and
|
205
|
+
is_parent_for_configuration?( existing_parent, configuration_name, parent )
|
206
|
+
|
207
|
+
parents_hash[ configuration_name ] = parent
|
208
|
+
|
209
|
+
parents( child ).unshift( parent )
|
210
|
+
|
211
|
+
end
|
212
|
+
|
213
|
+
return self
|
214
|
+
|
215
|
+
end
|
216
|
+
|
217
|
+
##############################
|
218
|
+
# parent_for_configuration #
|
219
|
+
##############################
|
220
|
+
|
221
|
+
def parent_for_configuration( instance, configuration_name )
|
222
|
+
|
223
|
+
unless instance.equal?( ::Class ) or
|
224
|
+
parent = parent_for_configuration_hash( instance )[ configuration_name ]
|
225
|
+
|
226
|
+
instance_class = instance.class
|
227
|
+
if has_configuration?( instance_class, configuration_name )
|
228
|
+
parent = instance_class
|
229
|
+
end
|
230
|
+
end
|
231
|
+
|
232
|
+
return parent
|
233
|
+
|
234
|
+
end
|
235
|
+
|
236
|
+
#############################
|
237
|
+
# configuration_variables #
|
238
|
+
#############################
|
239
|
+
|
240
|
+
def configuration_variables( instance )
|
241
|
+
|
242
|
+
return configuration_struct( instance ).configuration_variables_hash ||= { }
|
243
|
+
|
244
|
+
end
|
245
|
+
|
246
|
+
#######################
|
247
|
+
# set_configuration #
|
248
|
+
#######################
|
249
|
+
|
250
|
+
def set_configuration( instance, configuration_name, value )
|
251
|
+
|
252
|
+
return configuration_variables( instance )[ configuration_name ] = value
|
253
|
+
|
254
|
+
end
|
255
|
+
|
256
|
+
##############################
|
257
|
+
# has_configuration_value? #
|
258
|
+
##############################
|
259
|
+
|
260
|
+
def has_configuration_value?( instance, configuration_name )
|
261
|
+
|
262
|
+
return configuration_variables( instance ).has_key?( configuration_name )
|
263
|
+
|
264
|
+
end
|
265
|
+
|
266
|
+
#######################
|
267
|
+
# get_configuration #
|
268
|
+
#######################
|
269
|
+
|
270
|
+
def get_configuration( instance, configuration_name )
|
271
|
+
|
272
|
+
return configuration_variables( instance )[ configuration_name ]
|
273
|
+
|
274
|
+
end
|
275
|
+
|
276
|
+
###################################
|
277
|
+
# remove_configuration_variable #
|
278
|
+
###################################
|
279
|
+
|
280
|
+
def remove_configuration_variable( instance, configuration_name )
|
281
|
+
|
282
|
+
return configuration_variables( instance ).delete( configuration_name )
|
283
|
+
|
284
|
+
end
|
285
|
+
|
286
|
+
##################
|
287
|
+
# match_parent #
|
288
|
+
##################
|
289
|
+
|
290
|
+
def match_parent( instance, configuration_name, & match_block )
|
291
|
+
|
292
|
+
matched_parent = nil
|
293
|
+
|
294
|
+
this_parent = instance
|
295
|
+
|
296
|
+
begin
|
297
|
+
|
298
|
+
if match_block.call( this_parent )
|
299
|
+
matched_parent = this_parent
|
300
|
+
break
|
301
|
+
end
|
302
|
+
|
303
|
+
end while this_parent = parent_for_configuration( this_parent, configuration_name )
|
304
|
+
|
305
|
+
return matched_parent
|
306
|
+
|
307
|
+
end
|
308
|
+
|
309
|
+
##################################################################################################
|
310
|
+
private ######################################################################################
|
311
|
+
##################################################################################################
|
312
|
+
|
313
|
+
##########################
|
314
|
+
# configuration_struct #
|
315
|
+
##########################
|
316
|
+
|
317
|
+
def configuration_struct( instance )
|
318
|
+
|
319
|
+
configuration_struct = nil
|
320
|
+
|
321
|
+
instance_id = instance.__id__
|
322
|
+
|
323
|
+
unless configuration_struct = @instances_hash[ instance_id ]
|
324
|
+
# fill in slots lazily
|
325
|
+
configuration_struct = self.class::InstanceStruct.new
|
326
|
+
@instances_hash[ instance_id ] = configuration_struct
|
327
|
+
end
|
328
|
+
|
329
|
+
return configuration_struct
|
330
|
+
|
331
|
+
end
|
332
|
+
|
333
|
+
###################################
|
334
|
+
# parent_for_configuration_hash #
|
335
|
+
###################################
|
336
|
+
|
337
|
+
def parent_for_configuration_hash( instance )
|
338
|
+
|
339
|
+
return configuration_struct( instance ).parent_for_configuration_hash ||= { }
|
340
|
+
|
341
|
+
end
|
342
|
+
|
343
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
|
2
|
+
class ::CascadingConfiguration::Core::InstanceController::ExtensionModule < ::Module
|
3
|
+
|
4
|
+
################
|
5
|
+
# initialize #
|
6
|
+
################
|
7
|
+
|
8
|
+
def initialize( instance_controller, encapsulation, configuration_name, & definer_block )
|
9
|
+
|
10
|
+
@instance_controller = instance_controller
|
11
|
+
@encapsulation = encapsulation
|
12
|
+
@configuration_name = configuration_name
|
13
|
+
|
14
|
+
if block_given?
|
15
|
+
module_eval( & definer_block )
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
19
|
+
|
20
|
+
#########################
|
21
|
+
# instance_controller #
|
22
|
+
#########################
|
23
|
+
|
24
|
+
attr_reader :instance_controller
|
25
|
+
|
26
|
+
###################
|
27
|
+
# encapsulation #
|
28
|
+
###################
|
29
|
+
|
30
|
+
attr_reader :encapsulation
|
31
|
+
|
32
|
+
########################
|
33
|
+
# configuration_name #
|
34
|
+
########################
|
35
|
+
|
36
|
+
attr_reader :configuration_name
|
37
|
+
|
38
|
+
end
|
data/lib/cascading_configuration/core/instance_controller/support_module/instance_support_module.rb
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
|
2
|
+
class ::CascadingConfiguration::Core::InstanceController::SupportModule::InstanceSupportModule <
|
3
|
+
::CascadingConfiguration::Core::InstanceController::SupportModule
|
4
|
+
|
5
|
+
######################
|
6
|
+
# is_super_module? #
|
7
|
+
######################
|
8
|
+
|
9
|
+
def is_super_module?( module_instance )
|
10
|
+
|
11
|
+
is_super_module = false
|
12
|
+
|
13
|
+
if is_super_module = super
|
14
|
+
is_super_module = module_instance.included?( @instance_controller.instance )
|
15
|
+
end
|
16
|
+
|
17
|
+
return is_super_module
|
18
|
+
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
data/lib/cascading_configuration/core/instance_controller/support_module/singleton_support_module.rb
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
|
2
|
+
class ::CascadingConfiguration::Core::InstanceController::SupportModule::SingletonSupportModule <
|
3
|
+
::CascadingConfiguration::Core::InstanceController::SupportModule
|
4
|
+
|
5
|
+
######################
|
6
|
+
# is_super_module? #
|
7
|
+
######################
|
8
|
+
|
9
|
+
def is_super_module?( module_instance )
|
10
|
+
|
11
|
+
is_super_module = false
|
12
|
+
|
13
|
+
if is_super_module = super
|
14
|
+
is_super_module = module_instance.extended?( @instance_controller.instance )
|
15
|
+
end
|
16
|
+
|
17
|
+
return is_super_module
|
18
|
+
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|