cascading_configuration 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (43) hide show
  1. data/CHANGELOG.md +40 -0
  2. data/README.md +211 -0
  3. data/lib/cascading_configuration/array/sorted/unique.rb +110 -0
  4. data/lib/cascading_configuration/array/sorted.rb +106 -0
  5. data/lib/cascading_configuration/array/unique.rb +106 -0
  6. data/lib/cascading_configuration/array.rb +103 -0
  7. data/lib/cascading_configuration/core/enable_instance_support.rb +22 -0
  8. data/lib/cascading_configuration/core/enable_module_support.rb +24 -0
  9. data/lib/cascading_configuration/core/encapsulation.rb +343 -0
  10. data/lib/cascading_configuration/core/instance_controller/extension_module.rb +38 -0
  11. data/lib/cascading_configuration/core/instance_controller/support_module/instance_support_module.rb +21 -0
  12. data/lib/cascading_configuration/core/instance_controller/support_module/singleton_support_module.rb +21 -0
  13. data/lib/cascading_configuration/core/instance_controller/support_module.rb +253 -0
  14. data/lib/cascading_configuration/core/instance_controller.rb +840 -0
  15. data/lib/cascading_configuration/core/module/block_configurations/cascading_variables.rb +129 -0
  16. data/lib/cascading_configuration/core/module/block_configurations.rb +15 -0
  17. data/lib/cascading_configuration/core/module/extended_configurations/compositing_objects.rb +173 -0
  18. data/lib/cascading_configuration/core/module/extended_configurations.rb +65 -0
  19. data/lib/cascading_configuration/core/module/inheriting_values.rb +64 -0
  20. data/lib/cascading_configuration/core/module.rb +284 -0
  21. data/lib/cascading_configuration/core.rb +23 -0
  22. data/lib/cascading_configuration/hash.rb +103 -0
  23. data/lib/cascading_configuration/setting.rb +87 -0
  24. data/lib/cascading_configuration.rb +47 -0
  25. data/lib/namespaces.rb +9 -0
  26. data/lib/requires.rb +46 -0
  27. data/spec/cascading_configuration/array/sorted/unique_spec.rb +742 -0
  28. data/spec/cascading_configuration/array/sorted_spec.rb +741 -0
  29. data/spec/cascading_configuration/array/unique_spec.rb +746 -0
  30. data/spec/cascading_configuration/array_spec.rb +768 -0
  31. data/spec/cascading_configuration/core/encapsulation_spec.rb +208 -0
  32. data/spec/cascading_configuration/core/instance_controller/extension_module_spec.rb +26 -0
  33. data/spec/cascading_configuration/core/instance_controller/support_module_spec.rb +269 -0
  34. data/spec/cascading_configuration/core/instance_controller_spec.rb +273 -0
  35. data/spec/cascading_configuration/core/module/block_configurations/cascading_variables_spec.rb +17 -0
  36. data/spec/cascading_configuration/core/module/extended_configurations/compositing_objects_spec.rb +127 -0
  37. data/spec/cascading_configuration/core/module/extended_configurations_spec.rb +37 -0
  38. data/spec/cascading_configuration/core/module/inheriting_values_spec.rb +87 -0
  39. data/spec/cascading_configuration/core/module_spec.rb +491 -0
  40. data/spec/cascading_configuration/hash_spec.rb +826 -0
  41. data/spec/cascading_configuration/setting_spec.rb +687 -0
  42. data/spec/cascading_configuration_spec.rb +58 -0
  43. metadata +185 -0
@@ -0,0 +1,129 @@
1
+
2
+ class ::CascadingConfiguration::Core::Module::BlockConfigurations::CascadingVariables <
3
+ ::CascadingConfiguration::Core::Module::BlockConfigurations
4
+
5
+ ##########################
6
+ # create_configuration #
7
+ ##########################
8
+
9
+ # Pending.
10
+ def create_configuration( encapsulation, instance, name )
11
+
12
+ unless compositing_object = encapsulation.get_configuration( instance, name )
13
+
14
+ super
15
+
16
+ # initialize without initializing for parents
17
+ # we will initialize for parents after initializing all instances for inheritance
18
+ compositing_object = @compositing_object_class.new( nil, instance )
19
+
20
+ instance_controller = ::CascadingConfiguration::Core::InstanceController.nearest_instance_controller( encapsulation,
21
+ instance,
22
+ name )
23
+
24
+ extension_modules = instance_controller.extension_modules_upward( name, encapsulation )
25
+
26
+ unless extension_modules.empty?
27
+ # Modules are gathered from lowest ancestor upward. This means that they are already
28
+ # in the proper order for include/extend (which usually we would have to reverse).
29
+ compositing_object.extend( *extension_modules )
30
+ end
31
+
32
+ encapsulation.set_configuration( instance, name, compositing_object )
33
+
34
+ initialize_compositing_configuration_for_parent( encapsulation, instance, name )
35
+
36
+ end
37
+
38
+ return compositing_object
39
+
40
+ end
41
+
42
+ ############
43
+ # setter #
44
+ ############
45
+
46
+ # Pending.
47
+ def setter( encapsulation, instance, name, value )
48
+
49
+ return encapsulation.set_configuration( instance, name, value )
50
+
51
+ end
52
+
53
+ ############
54
+ # getter #
55
+ ############
56
+
57
+ # Pending.
58
+ def getter( encapsulation, instance, name )
59
+
60
+ return encapsulation.get_configuration( instance, name )
61
+
62
+ end
63
+
64
+ #####################
65
+ # instance_setter #
66
+ #####################
67
+
68
+ # Pending.
69
+ def instance_setter( encapsulation, instance, name, value )
70
+
71
+ # ensure our compositing object already exists
72
+ instance_getter( encapsulation, instance, name, value )
73
+
74
+ # now we can set normally
75
+ return setter( encapsulation, instance, name, value )
76
+
77
+ end
78
+
79
+ #####################
80
+ # instance_getter #
81
+ #####################
82
+
83
+ # Pending.
84
+ def instance_getter( encapsulation, instance, name )
85
+
86
+ cascading_value = nil
87
+
88
+ if encapsulation.has_configuration_value?( instance, name )
89
+ cascading_value = encapsulation.get_configuration( instance, name )
90
+ else
91
+ cascading_value = initialize_configuration_for_parent( encapsulation, instance, configuration_name )
92
+ end
93
+
94
+ return cascading_value
95
+
96
+ end
97
+
98
+ #####################################################
99
+ # initialize_compositing_configuration_for_parent #
100
+ #####################################################
101
+
102
+ # Pending.
103
+ def initialize_compositing_configuration_for_parent( encapsulation, instance, configuration_name )
104
+
105
+ unless compositing_object = encapsulation.get_configuration( instance, configuration_name )
106
+ compositing_object = create_configuration( encapsulation, instance, configuration_name )
107
+ end
108
+
109
+ # if instance has a parent
110
+ if parent = encapsulation.parent_for_configuration( instance, configuration_name )
111
+
112
+ # if first parent for configuration isn't initialized yet, initialize it
113
+ unless parent_composite_object = encapsulation.get_configuration( parent, configuration_name )
114
+ parent_composite_object = initialize_compositing_configuration_for_parent( encapsulation,
115
+ parent,
116
+ configuration_name )
117
+ end
118
+
119
+ unless compositing_object.parent_composite_object == parent_composite_object
120
+ compositing_object.initialize_for_parent( parent_composite_object )
121
+ end
122
+
123
+ end
124
+
125
+ return compositing_object
126
+
127
+ end
128
+
129
+ end
@@ -0,0 +1,15 @@
1
+
2
+ class ::CascadingConfiguration::Core::Module::BlockConfigurations < ::CascadingConfiguration::Core::Module
3
+
4
+ ###########################
5
+ # define_configurations #
6
+ ###########################
7
+
8
+ # Pending.
9
+ def define_configurations( instance_controller, encapsulation, method_types, *names, & definer_block )
10
+
11
+ super
12
+
13
+ end
14
+
15
+ end
@@ -0,0 +1,173 @@
1
+
2
+ class ::CascadingConfiguration::Core::Module::ExtendedConfigurations::CompositingObjects <
3
+ ::CascadingConfiguration::Core::Module::ExtendedConfigurations
4
+
5
+ ################
6
+ # initialize #
7
+ ################
8
+
9
+ def initialize( ccm_name,
10
+ compositing_object_class = nil,
11
+ default_encapsulation_or_encapsulation_name = ::CascadingConfiguration::Core::
12
+ Module::DefaultEncapsulation,
13
+ *ccm_aliases )
14
+
15
+ super( ccm_name, default_encapsulation_or_encapsulation_name, *ccm_aliases )
16
+
17
+ @compositing_object_class = compositing_object_class
18
+
19
+ end
20
+
21
+ ##########################
22
+ # create_configuration #
23
+ ##########################
24
+
25
+ def create_configuration( encapsulation, instance, name )
26
+
27
+ unless compositing_object = encapsulation.get_configuration( instance, name )
28
+
29
+ super
30
+
31
+ # initialize without initializing for parents
32
+ # we will initialize for parents after initializing all instances for inheritance
33
+ compositing_object = @compositing_object_class.new( nil, instance )
34
+
35
+ instance_controller = ::CascadingConfiguration::Core::
36
+ InstanceController.nearest_instance_controller( encapsulation, instance, name )
37
+
38
+ if instance_controller
39
+
40
+ extension_modules = instance_controller.extension_modules_upward( name, encapsulation )
41
+
42
+ unless extension_modules.empty?
43
+ # Modules are gathered from lowest ancestor upward. This means that they are already
44
+ # in the proper order for include/extend (which usually we would have to reverse).
45
+ compositing_object.extend( *extension_modules )
46
+ end
47
+
48
+ end
49
+
50
+ encapsulation.set_configuration( instance, name, compositing_object )
51
+
52
+ end
53
+
54
+ return compositing_object
55
+
56
+ end
57
+
58
+ ##############################
59
+ # initialize_configuration #
60
+ ##############################
61
+
62
+ def initialize_configuration( encapsulation, instance, name )
63
+
64
+ initialize_compositing_configuration_for_parent( encapsulation, instance, name )
65
+
66
+ end
67
+
68
+ ##############################
69
+ # compositing_object_class #
70
+ ##############################
71
+
72
+ attr_reader :compositing_object_class
73
+
74
+ ############
75
+ # setter #
76
+ ############
77
+
78
+ def setter( encapsulation, instance, name, value )
79
+
80
+ compositing_object = encapsulation.get_configuration( instance, name )
81
+
82
+ compositing_object.replace( value )
83
+
84
+ return compositing_object
85
+
86
+ end
87
+
88
+ #####################
89
+ # instance_setter #
90
+ #####################
91
+
92
+ def instance_setter( encapsulation, instance, name, value )
93
+
94
+ # ensure our compositing object already exists
95
+ instance_getter( encapsulation, instance, name )
96
+
97
+ # now we can set normally
98
+ return setter( encapsulation, instance, name, value )
99
+
100
+ end
101
+
102
+ ############
103
+ # getter #
104
+ ############
105
+
106
+ def getter( encapsulation, instance, name )
107
+
108
+ return encapsulation.get_configuration( instance, name )
109
+
110
+ end
111
+
112
+ #####################
113
+ # instance_getter #
114
+ #####################
115
+
116
+ def instance_getter( encapsulation, instance, name )
117
+
118
+ compositing_object = nil
119
+
120
+ unless compositing_object = encapsulation.get_configuration( instance, name )
121
+ compositing_object = initialize_compositing_configuration_for_parent( encapsulation, instance, name )
122
+ end
123
+
124
+ return compositing_object
125
+
126
+ end
127
+
128
+ #####################################################
129
+ # initialize_compositing_configuration_for_parent #
130
+ #####################################################
131
+
132
+ def initialize_compositing_configuration_for_parent( encapsulation, instance, configuration_name )
133
+
134
+ unless compositing_object = encapsulation.get_configuration( instance, configuration_name )
135
+ compositing_object = create_configuration( encapsulation, instance, configuration_name )
136
+ end
137
+
138
+ # if instance has a parent
139
+ if parent = encapsulation.parent_for_configuration( instance, configuration_name )
140
+
141
+ # We are initializing for existing ancestors, but they may not have initialized yet -
142
+ # so we need to make sure they did before we initialize for instance.
143
+
144
+ # As long as our ancestor has an ancestor make sure that it has initialized for its parent.
145
+ # We can break at the first ancestor that we hit that has initialized for parent
146
+ # or if we run out of ancestors.
147
+
148
+ parent_composite_object = encapsulation.get_configuration( parent, configuration_name )
149
+ parent_composite_object2 = nil
150
+ if parent2 = encapsulation.parent_for_configuration( parent, configuration_name )
151
+ parent_composite_object2 = encapsulation.get_configuration( parent2, configuration_name )
152
+ end
153
+
154
+ # if first parent for configuration isn't initialized yet, initialize it
155
+ unless parent_composite_object and
156
+ parent_composite_object.parent_composite_object.equal?( parent_composite_object2 )
157
+
158
+ parent_composite_object = initialize_compositing_configuration_for_parent( encapsulation,
159
+ parent,
160
+ configuration_name )
161
+ end
162
+
163
+ unless compositing_object.parent_composite_object.equal?( parent_composite_object )
164
+ compositing_object.initialize_for_parent( parent_composite_object )
165
+ end
166
+
167
+ end
168
+
169
+ return compositing_object
170
+
171
+ end
172
+
173
+ end
@@ -0,0 +1,65 @@
1
+
2
+ class ::CascadingConfiguration::Core::Module::ExtendedConfigurations < ::CascadingConfiguration::Core::Module
3
+
4
+ ##################################
5
+ # self.parse_extension_modules #
6
+ ##################################
7
+
8
+ def self.parse_extension_modules( instance_controller, encapsulation, *names_modules )
9
+
10
+ # We can have configuration names or modules - we need to separate them.
11
+ names = [ ]
12
+ modules = [ ]
13
+
14
+ names_modules.each do |this_name_or_module|
15
+
16
+ case this_name_or_module
17
+
18
+ when ::Class
19
+
20
+ raise ArgumentError, 'Module expected (received Class).'
21
+
22
+ when ::Module
23
+
24
+ modules.push( this_name_or_module )
25
+
26
+ else
27
+
28
+ names.push( this_name_or_module )
29
+
30
+ end
31
+
32
+ end
33
+
34
+ names_modules_hash = { }
35
+
36
+ # if we have a block to define extensions to the compositing object:
37
+
38
+ names.each do |this_name|
39
+ names_modules_hash[ this_name ] = modules
40
+ end
41
+
42
+ return names_modules_hash
43
+
44
+ end
45
+
46
+ ###########################
47
+ # define_configurations #
48
+ ###########################
49
+
50
+ def define_configurations( instance_controller, encapsulation, method_types, *names_modules, & definer_block )
51
+
52
+ # Ask MethodModule to parse extension modules for these declarations on instance.
53
+ names_modules_hash = self.class.parse_extension_modules( instance_controller, encapsulation, *names_modules )
54
+
55
+ names_modules_hash.each do |this_name, these_modules|
56
+ instance_controller.add_extension_modules( this_name, encapsulation, *these_modules, & definer_block )
57
+ end
58
+
59
+ names = names_modules_hash.keys
60
+
61
+ super( instance_controller, encapsulation, method_types, *names, & definer_block )
62
+
63
+ end
64
+
65
+ end
@@ -0,0 +1,64 @@
1
+
2
+ class ::CascadingConfiguration::Core::Module::InheritingValues < ::CascadingConfiguration::Core::Module
3
+
4
+ ############
5
+ # setter #
6
+ ############
7
+
8
+ def setter( encapsulation, instance, name, value )
9
+
10
+ return encapsulation.set_configuration( instance, name, value )
11
+
12
+ end
13
+
14
+ ############
15
+ # getter #
16
+ ############
17
+
18
+ def getter( encapsulation, instance, name )
19
+
20
+ return get_configuration_searching_upward( encapsulation, instance, name )
21
+
22
+ end
23
+
24
+ #####################
25
+ # instance_getter #
26
+ #####################
27
+
28
+ alias_method( :instance_getter, :getter )
29
+
30
+ #####################
31
+ # instance_setter #
32
+ #####################
33
+
34
+ alias_method( :instance_setter, :setter )
35
+
36
+ ########################################
37
+ # get_configuration_searching_upward #
38
+ ########################################
39
+
40
+ def get_configuration_searching_upward( encapsulation, instance, configuration_name )
41
+
42
+ configuration_value = nil
43
+
44
+ matching_ancestor = nil
45
+
46
+ did_match_ancestor = false
47
+
48
+ matching_ancestor = encapsulation.match_parent( instance, configuration_name ) do |this_ancestor|
49
+ if encapsulation.has_configuration_value?( this_ancestor, configuration_name )
50
+ did_match_ancestor = true
51
+ else
52
+ false
53
+ end
54
+ end
55
+
56
+ if did_match_ancestor
57
+ configuration_value = encapsulation.get_configuration( matching_ancestor, configuration_name )
58
+ end
59
+
60
+ return configuration_value
61
+
62
+ end
63
+
64
+ end