cascading-configuration-array 1.1.4 → 1.1.5

Sign up to get free protection for your applications and to get access to all the features.
@@ -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