cascading-configuration-array 1.1.4 → 1.1.5

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.
@@ -0,0 +1,216 @@
1
+
2
+ class CascadingConfiguration::CompositingArray < Array
3
+
4
+ attr_accessor :working_instance, :local_cascading_array
5
+
6
+ ################
7
+ # initialize #
8
+ ################
9
+
10
+ def initialize( cascading_name, working_instance )
11
+ @cascading_name = cascading_name
12
+ working_class = ( working_instance.is_a?( Module ) ? working_instance : working_instance.class )
13
+ @cascading_variable = working_class::AccessorSupportModule.cascading_variable_name( @cascading_name )
14
+ @working_instance = working_instance
15
+ # if first ancestor can have a composite array, register self with it in case it gets updated in the future
16
+ if ( first_ancestor = @working_instance.first_ancestor ).respond_to?( :composite_array_for_cascading_configuration )
17
+ @parent_composite_array = first_ancestor.composite_array_for_cascading_configuration( @cascading_name )
18
+ @parent_composite_array.register_child_composite_array( self )
19
+ end
20
+ # get local cascading array (not included in parent composite)
21
+ @local_cascading_array = ::CascadingConfiguration::LocalConfigurationArray.new
22
+ # we may later have our own child composites
23
+ @child_composite_arrays = ::Array.new
24
+ # initialize self status for parent and local
25
+ update_self_as_cascading_composite
26
+ end
27
+
28
+ ####################################
29
+ # register_child_composite_array #
30
+ ####################################
31
+
32
+ def register_child_composite_array( child_composite_array )
33
+ @child_composite_arrays.push( child_composite_array )
34
+ return self
35
+ end
36
+
37
+ ######################################
38
+ # unregister_child_composite_array #
39
+ ######################################
40
+
41
+ def unregister_child_composite_array( child_composite_array )
42
+ @child_composite_arrays.delete( child_composite_array )
43
+ return self
44
+ end
45
+
46
+ #########
47
+ # []= #
48
+ #########
49
+
50
+ def []=( index, element )
51
+ # we sort internally, so index is irrelevant
52
+ # no reason to differentiate from push
53
+ push( element )
54
+ end
55
+
56
+ ########
57
+ # << #
58
+ ########
59
+
60
+ def <<( *elements )
61
+ # no reason to differentiate from push
62
+ push( *elements )
63
+ end
64
+
65
+ #######
66
+ # + #
67
+ #######
68
+
69
+ def +( *arrays )
70
+ # no reason to differentiate from push
71
+ arrays.each do |this_array|
72
+ push( *this_array )
73
+ end
74
+ return self
75
+ end
76
+
77
+ ############
78
+ # concat #
79
+ ############
80
+
81
+ def concat( *arrays )
82
+ arrays.each do |this_array|
83
+ push( *this_array )
84
+ end
85
+ end
86
+
87
+ ##########
88
+ # push #
89
+ ##########
90
+
91
+ alias_method :super_push, :push
92
+ def push( *elements )
93
+
94
+ # we are a composite array
95
+ # that means we have to set the value for our class
96
+ @local_cascading_array.push( *elements )
97
+
98
+ update_adding_composite_elements( *elements )
99
+
100
+ return self
101
+
102
+ end
103
+
104
+ #######
105
+ # - #
106
+ #######
107
+
108
+ def -( *arrays )
109
+
110
+ arrays.each do |this_array|
111
+ delete( *this_array )
112
+ end
113
+
114
+ return self
115
+
116
+ end
117
+
118
+ ############
119
+ # delete #
120
+ ############
121
+
122
+ alias_method :super_delete, :delete
123
+ def delete( *elements )
124
+
125
+ @local_cascading_array.delete( *elements )
126
+
127
+ update_removing_composite_elements( *elements )
128
+
129
+ return self
130
+
131
+ end
132
+
133
+ #########
134
+ # pop #
135
+ #########
136
+
137
+ def pop
138
+
139
+ element = super
140
+
141
+ @local_cascading_array.delete( element )
142
+
143
+ update_removing_composite_elements( element )
144
+
145
+ return element
146
+
147
+ end
148
+
149
+ ###########
150
+ # shift #
151
+ ###########
152
+
153
+ def shift
154
+
155
+ element = super
156
+
157
+ @local_cascading_array.delete( element )
158
+
159
+ update_removing_composite_elements( element )
160
+
161
+ return element
162
+
163
+ end
164
+
165
+ ############
166
+ # slice! #
167
+ ############
168
+
169
+ def slice!( *args )
170
+
171
+ elements = super
172
+
173
+ @local_cascading_array.delete( *elements )
174
+
175
+ update_removing_composite_elements( *elements )
176
+
177
+ return elements
178
+
179
+ end
180
+
181
+ ###########
182
+ # clear #
183
+ ###########
184
+
185
+ alias_method :super_clear, :clear
186
+ def clear
187
+
188
+ # add all existing values to exclude array
189
+ @local_cascading_array.delete( *self )
190
+
191
+ update_removing_composite_elements( *self )
192
+
193
+ return self
194
+
195
+ end
196
+
197
+ #############
198
+ # freeze! #
199
+ #############
200
+
201
+ # freezes configuration and prevents ancestors from changing this configuration in the future
202
+ def freeze!
203
+
204
+ # move current configuration into local configuration
205
+ @local_cascading_array.clear
206
+ @local_cascading_array.exclude_array.clear
207
+ @local_cascading_array.push( *self )
208
+
209
+ # unregister with parent composite so we don't get future updates from it
210
+ @parent_composite_array.unregister_child_composite_array( self ) if @parent_composite_array
211
+
212
+ return self
213
+
214
+ end
215
+
216
+ end
@@ -0,0 +1,166 @@
1
+
2
+ class CascadingConfiguration::LocalConfigurationArray < Array
3
+
4
+ attr_accessor :exclude_array
5
+
6
+ ################
7
+ # initialize #
8
+ ################
9
+
10
+ def initialize()
11
+ @exclude_array = ::Array.new
12
+ end
13
+
14
+ #########
15
+ # []= #
16
+ #########
17
+
18
+ def []=( index, element )
19
+ # we sort internally, so index is irrelevant
20
+ # no reason to differentiate from push
21
+ push( element )
22
+ end
23
+
24
+ ########
25
+ # << #
26
+ ########
27
+
28
+ def <<( *elements )
29
+ # no reason to differentiate from push
30
+ push( *elements )
31
+ end
32
+
33
+ #######
34
+ # + #
35
+ #######
36
+
37
+ def +( *element_arrays )
38
+ element_arrays.each do |this_element_array|
39
+ push( *this_element_array )
40
+ end
41
+ return self
42
+ end
43
+
44
+ ##########
45
+ # push #
46
+ ##########
47
+
48
+ def push( *elements )
49
+
50
+ # add elements to configuration array
51
+ super
52
+
53
+ # sort and uniq self
54
+ sort!.uniq!
55
+
56
+ # make sure we don't still have any elements noted as excluded at this level
57
+ remove_from_exclude_array( *elements )
58
+
59
+ return self
60
+
61
+ end
62
+
63
+ ############
64
+ # concat #
65
+ ############
66
+
67
+ def concat( *arrays )
68
+
69
+ arrays.each do |this_array|
70
+ push( *this_array )
71
+ end
72
+
73
+ return self
74
+
75
+ end
76
+
77
+ #######
78
+ # - #
79
+ #######
80
+
81
+ def -( *arrays )
82
+
83
+ arrays.each do |this_array|
84
+ delete( *this_array )
85
+ end
86
+
87
+ return self
88
+
89
+ end
90
+
91
+ ############
92
+ # delete #
93
+ ############
94
+
95
+ def delete( *elements )
96
+
97
+ elements.each do |this_element|
98
+ super( this_element )
99
+ end
100
+ # add subtracted elements to exclude array
101
+ add_to_exclude_array( *elements )
102
+
103
+ return self
104
+
105
+ end
106
+
107
+ #########
108
+ # pop #
109
+ #########
110
+
111
+ def pop
112
+
113
+ element = super
114
+
115
+ # add popped element to exclude array
116
+ add_to_exclude_array( element )
117
+
118
+ return element
119
+
120
+ end
121
+
122
+ ###########
123
+ # shift #
124
+ ###########
125
+
126
+ def shift
127
+
128
+ element = super
129
+
130
+ # add shifted element to exclude array
131
+ add_to_exclude_array( element )
132
+
133
+ return element
134
+
135
+ end
136
+
137
+ ############
138
+ # slice! #
139
+ ############
140
+
141
+ def slice!( *args )
142
+
143
+ elements = super
144
+
145
+ # add sliced elements to exclude array
146
+ delete( *elements )
147
+
148
+ return elements
149
+
150
+ end
151
+
152
+ ###########
153
+ # clear #
154
+ ###########
155
+
156
+ def clear
157
+
158
+ # add all existing values to exclude array
159
+ delete( *self )
160
+
161
+ # clear existing values
162
+ super
163
+
164
+ end
165
+
166
+ end
@@ -0,0 +1,57 @@
1
+
2
+ class CascadingConfiguration::CompositingArray < Array
3
+
4
+ ###########################################################################################################
5
+ private ###############################################################################################
6
+ ###########################################################################################################
7
+
8
+ ########################################
9
+ # update_self_as_cascading_composite #
10
+ ########################################
11
+
12
+ def update_self_as_cascading_composite
13
+ # start fresh
14
+ super_clear
15
+ # add parent config
16
+ super_push( *@parent_composite_array ) if @parent_composite_array
17
+ # add additional local config
18
+ super_push( *@local_cascading_array )
19
+ # remove local exclude
20
+ super_delete( *@local_cascading_array.exclude_array ) unless @local_cascading_array.exclude_array.empty?
21
+ # notify children to update their composite status
22
+ update_child_composite_arrays
23
+ return self
24
+ end
25
+
26
+ ######################################
27
+ # update_adding_composite_elements #
28
+ ######################################
29
+
30
+ def update_adding_composite_elements( *elements_to_cascade )
31
+ super_push( *elements_to_cascade )
32
+ sort!.uniq!
33
+ update_child_composite_arrays
34
+ end
35
+
36
+ ########################################
37
+ # update_removing_composite_elements #
38
+ ########################################
39
+
40
+ def update_removing_composite_elements( *elements_to_exclude )
41
+ elements_to_exclude.each do |this_excluded_element|
42
+ super_delete( this_excluded_element )
43
+ end
44
+ update_child_composite_arrays
45
+ end
46
+
47
+ ###################################
48
+ # update_child_composite_arrays #
49
+ ###################################
50
+
51
+ def update_child_composite_arrays
52
+ @child_composite_arrays.each do |this_composite_array|
53
+ this_composite_array.instance_eval { update_self_as_cascading_composite }
54
+ end
55
+ end
56
+
57
+ end
@@ -0,0 +1,26 @@
1
+
2
+ class CascadingConfiguration::LocalConfigurationArray < Array
3
+
4
+ ###########################################################################################################
5
+ private ###############################################################################################
6
+ ###########################################################################################################
7
+
8
+ ##########################
9
+ # add_to_exclude_array #
10
+ ##########################
11
+
12
+ def add_to_exclude_array( *elements )
13
+ @exclude_array += elements
14
+ @exclude_array.sort!.uniq!
15
+ end
16
+
17
+ ###############################
18
+ # remove_from_exclude_array #
19
+ ###############################
20
+
21
+ def remove_from_exclude_array( *elements )
22
+ @exclude_array -= elements
23
+ @exclude_array.sort!.uniq!
24
+ end
25
+
26
+ end
@@ -0,0 +1,35 @@
1
+
2
+ if $cascading_configuration_development
3
+ require_relative '../../variable/lib/cascading-configuration-variable.rb'
4
+ else
5
+ require 'cascading-configuration-variable'
6
+ end
7
+
8
+ module CascadingConfiguration
9
+ class CompositingArray < Array
10
+ module Instance
11
+ end
12
+ end
13
+ class LocalConfigurationArray < Array
14
+ end
15
+ module Array
16
+ module Accessors
17
+ end
18
+ module ClassInstance
19
+ end
20
+ module ObjectInstance
21
+ end
22
+ module ModuleInstance
23
+ end
24
+ end
25
+ end
26
+
27
+ require_relative 'cascading-configuration-array/CascadingConfiguration/CompositingArray.rb'
28
+ require_relative 'cascading-configuration-array/CascadingConfiguration/_private_/CompositingArray.rb'
29
+ require_relative 'cascading-configuration-array/CascadingConfiguration/CompositingArray/Instance.rb'
30
+ require_relative 'cascading-configuration-array/CascadingConfiguration/LocalConfigurationArray.rb'
31
+ require_relative 'cascading-configuration-array/CascadingConfiguration/_private_/LocalConfigurationArray.rb'
32
+ require_relative 'cascading-configuration-array/CascadingConfiguration/Array.rb'
33
+ require_relative 'cascading-configuration-array/CascadingConfiguration/Array/Accessors.rb'
34
+ require_relative 'cascading-configuration-array/CascadingConfiguration/Array/ClassInstance.rb'
35
+ require_relative 'cascading-configuration-array/CascadingConfiguration/Array/ModuleInstance.rb'
@@ -0,0 +1,28 @@
1
+
2
+ require_relative '../../../lib/cascading-configuration-array.rb'
3
+
4
+ describe CascadingConfiguration::Array::Accessors do
5
+
6
+ ###################################
7
+ # define_cascading_array_setter #
8
+ # define_cascading_array_getter #
9
+ ###################################
10
+
11
+ it 'can define a method to get and modify the configuration array' do
12
+ class CascadingConfiguration::Array::Mock
13
+ include CascadingConfiguration::Variable
14
+ extend CascadingConfiguration::Array::Accessors
15
+ include CascadingConfiguration::Array::ObjectInstance
16
+ extend CascadingConfiguration::Array::ClassInstance
17
+ end
18
+ # setter
19
+ CascadingConfiguration::Array::Mock.define_cascading_array_setter( :some_configuration )
20
+ CascadingConfiguration::Array::Mock.methods.include?( :some_configuration= ).should == true
21
+ CascadingConfiguration::Array::Mock.instance_methods.include?( :some_configuration= ).should == true
22
+ # getter
23
+ CascadingConfiguration::Array::Mock.define_cascading_array_getter( :some_configuration )
24
+ CascadingConfiguration::Array::Mock.methods.include?( :some_configuration ).should == true
25
+ CascadingConfiguration::Array::Mock.instance_methods.include?( :some_configuration ).should == true
26
+ end
27
+
28
+ end
@@ -0,0 +1,90 @@
1
+
2
+ require_relative '../../lib/cascading-configuration-array.rb'
3
+
4
+ describe CascadingConfiguration::Array do
5
+
6
+ ##############################
7
+ # attr_configuration_array #
8
+ ##############################
9
+
10
+ it 'can define a configuration array, which is the primary interface' do
11
+
12
+ module CascadingConfiguration::Array::MockModule
13
+ include CascadingConfiguration::Array
14
+ attr_configuration_array :configuration_setting
15
+ configuration_setting.should == []
16
+ configuration_setting.push( :a_configuration )
17
+ configuration_setting.should == [ :a_configuration ]
18
+ end
19
+
20
+ module CascadingConfiguration::Array::MockModule2
21
+ include CascadingConfiguration::Array::MockModule
22
+ configuration_setting.should == [ :a_configuration ]
23
+ configuration_setting.push( :another_configuration )
24
+ configuration_setting.should == [ :a_configuration, :another_configuration ]
25
+ end
26
+
27
+ module CascadingConfiguration::Array::MockModule3
28
+ include CascadingConfiguration::Array::MockModule2
29
+ configuration_setting.should == [ :a_configuration, :another_configuration ]
30
+ end
31
+
32
+ class CascadingConfiguration::Array::MockClass
33
+ include CascadingConfiguration::Array::MockModule3
34
+ configuration_setting.should == [ :a_configuration, :another_configuration ]
35
+ configuration_setting.delete( :another_configuration )
36
+ configuration_setting.should == [ :a_configuration ]
37
+ end
38
+
39
+ object_instance_one = CascadingConfiguration::Array::MockClass.new
40
+ object_instance_one.configuration_setting.should == [ :a_configuration ]
41
+ object_instance_one.configuration_setting.push( :some_other_configuration )
42
+ object_instance_one.configuration_setting.should == [ :a_configuration, :some_other_configuration ]
43
+
44
+ class CascadingConfiguration::Array::MockClassSub1 < CascadingConfiguration::Array::MockClass
45
+ configuration_setting.should == [ :a_configuration ]
46
+ configuration_setting.push( :another_configuration)
47
+ configuration_setting.should == [ :a_configuration, :another_configuration ]
48
+ end
49
+
50
+ object_instance_two = CascadingConfiguration::Array::MockClassSub1.new
51
+ object_instance_two.configuration_setting.should == [ :a_configuration, :another_configuration ]
52
+ object_instance_two.configuration_setting.push( :some_other_configuration )
53
+ object_instance_two.configuration_setting.should == [ :a_configuration, :another_configuration, :some_other_configuration ]
54
+
55
+ # change ancestor setting
56
+ CascadingConfiguration::Array::MockClass.configuration_setting.push( :a_yet_unused_configuration )
57
+ CascadingConfiguration::Array::MockClass.configuration_setting.should == [ :a_configuration, :a_yet_unused_configuration ]
58
+ object_instance_one.configuration_setting.should == [ :a_configuration, :a_yet_unused_configuration, :some_other_configuration ]
59
+ CascadingConfiguration::Array::MockClassSub1.configuration_setting.should == [ :a_configuration, :a_yet_unused_configuration, :another_configuration ]
60
+ object_instance_two.configuration_setting.should == [ :a_configuration, :a_yet_unused_configuration, :another_configuration, :some_other_configuration ]
61
+
62
+ # freeze ancestor setting
63
+ object_instance_one.configuration_setting.freeze!
64
+ object_instance_one.configuration_setting.should == [ :a_configuration, :a_yet_unused_configuration, :some_other_configuration ]
65
+ CascadingConfiguration::Array::MockClassSub1.configuration_setting.freeze!
66
+ CascadingConfiguration::Array::MockClassSub1.configuration_setting.should == [ :a_configuration, :a_yet_unused_configuration, :another_configuration ]
67
+ CascadingConfiguration::Array::MockClass.configuration_setting.push( :non_cascading_configuration )
68
+ CascadingConfiguration::Array::MockClass.configuration_setting.should == [ :a_configuration, :a_yet_unused_configuration, :non_cascading_configuration ]
69
+ object_instance_one.configuration_setting.should == [ :a_configuration, :a_yet_unused_configuration, :some_other_configuration ]
70
+ CascadingConfiguration::Array::MockClassSub1.configuration_setting.should == [ :a_configuration, :a_yet_unused_configuration, :another_configuration ]
71
+ object_instance_two.configuration_setting.should == [ :a_configuration, :a_yet_unused_configuration, :another_configuration, :some_other_configuration ]
72
+
73
+ # test two
74
+
75
+ module CascadingConfiguration::Array::MockModuleExtended
76
+ include CascadingConfiguration::Array
77
+ attr_configuration_array :configuration_setting
78
+ configuration_setting.should == []
79
+ configuration_setting.push( :a_configuration )
80
+ configuration_setting.should == [ :a_configuration ]
81
+ end
82
+
83
+ class CascadingConfiguration::Array::MockClassExtended
84
+ extend CascadingConfiguration::Array::MockModuleExtended
85
+ configuration_setting.should == [ :a_configuration ]
86
+ end
87
+
88
+ end
89
+
90
+ end