cascading_classes 0.3.0 → 0.6.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.
@@ -0,0 +1,56 @@
1
+ begin
2
+ require_relative '../helper_spec'
3
+ rescue NameError
4
+ require File.expand_path('../helper_spec', __FILE__)
5
+ end
6
+
7
+ describe "null syntax" do
8
+ before do
9
+ Parent = Class.new{extend CC}
10
+ Child = Class.new(Parent)
11
+ GrandChild = Class.new(Child)
12
+ end
13
+
14
+ after do
15
+ Object.send :remove_const, :Parent
16
+ Object.send :remove_const, :Child
17
+ Object.send :remove_const, :GrandChild
18
+ end
19
+
20
+ describe "nulls" do
21
+ before do
22
+ @props = Parent.cascade do
23
+ future_string
24
+ future_int
25
+ future_float
26
+ future_sym
27
+ future_bool
28
+ future_hash
29
+ future_array
30
+ future_set
31
+ end
32
+ end
33
+
34
+ it "has ':Object' type" do
35
+ [:string, :int, :float, :sym, :bool, :hash, :array, :set].each do |type|
36
+ name = "future_#{type}".to_sym
37
+ @props[name][:type].must_equal :Object
38
+ end
39
+ end
40
+
41
+ it "is nil for parent class" do
42
+ [:string, :int, :float, :sym, :bool, :hash, :array, :set].each do |type|
43
+ name = "future_#{type}".to_sym
44
+ Parent.send(name).must_equal nil
45
+ end
46
+ end
47
+
48
+ it "is nil for subclasses" do
49
+ [:string, :int, :float, :sym, :bool, :hash, :array, :set].each do |type|
50
+ name = "future_#{type}".to_sym
51
+ Child.send(name).must_equal nil
52
+ GrandChild.send(name).must_equal nil
53
+ end
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,59 @@
1
+ begin
2
+ require_relative '../helper_spec'
3
+ rescue NameError
4
+ require File.expand_path('../helper_spec', __FILE__)
5
+ end
6
+
7
+ describe "options" do
8
+ before do
9
+ A = Class.new{extend CC}
10
+ B = Class.new(A)
11
+ C = Class.new(B)
12
+ end
13
+
14
+ after do
15
+ Object.send :remove_const, :A
16
+ Object.send :remove_const, :B
17
+ Object.send :remove_const, :C
18
+ end
19
+
20
+ describe "blocks are yielded to alone or evaluated with instance exec" do
21
+
22
+ it "has a global default" do
23
+ CC.block_inst_exec = true
24
+ CC.block_inst_exec?.must_equal true
25
+
26
+ CC.block_inst_exec = false
27
+ CC.block_inst_exec?.must_equal false
28
+ end
29
+
30
+ it "defaults to global setting" do
31
+ props = A.cascade do
32
+ color
33
+ end
34
+ props[:color][:block_inst_exec].must_equal(CC.block_inst_exec?)
35
+ end
36
+
37
+ it "can be set in the 'cascade' block, overruling the global default" do
38
+ CC.block_inst_exec = true
39
+ props = A.cascade do
40
+ color :block_inst_exec => false
41
+ end
42
+ props[:color][:block_inst_exec].must_equal false
43
+ end
44
+
45
+ it "can be set in 'opts' hash of property method, overruling others" do
46
+ A.cascade do
47
+ color :block_inst_exec => false
48
+ end
49
+ A.color = "red"
50
+ who_am_i = self
51
+
52
+ who_is_self_1 = A.color(:inherit, 0){|me, parents| self}
53
+ who_is_self_2 = A.color(:inherit, 0, {:block_inst_exec => true}){|me, parents| self}
54
+
55
+ who_is_self_1.must_equal who_am_i
56
+ who_is_self_2.must_equal A
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,60 @@
1
+ begin
2
+ require_relative '../helper_spec'
3
+ rescue NameError
4
+ require File.expand_path('../helper_spec', __FILE__)
5
+ end
6
+
7
+ describe "options" do
8
+ before do
9
+ A = Class.new{extend CC}
10
+ B = Class.new(A)
11
+ C = Class.new(B)
12
+ end
13
+
14
+ after do
15
+ Object.send :remove_const, :A
16
+ Object.send :remove_const, :B
17
+ Object.send :remove_const, :C
18
+ end
19
+
20
+ describe "proc values are called alone or evaluated with instance exec" do
21
+ it "has a global default" do
22
+ CC.proc_inst_exec = true
23
+ CC.proc_inst_exec?.must_equal true
24
+
25
+ CC.proc_inst_exec = false
26
+ CC.proc_inst_exec?.must_equal false
27
+ end
28
+
29
+ it "defaults to global setting" do
30
+ props = A.cascade do
31
+ color
32
+ end
33
+ props[:color][:proc_inst_exec].must_equal(CC.proc_inst_exec?)
34
+ end
35
+
36
+ it "can be set in the 'cascade' block, overruling the global default" do
37
+ CC.proc_inst_exec = true
38
+ props = A.cascade do
39
+ color :proc_inst_exec => false
40
+ end
41
+ props[:color][:proc_inst_exec].must_equal false
42
+ end
43
+
44
+ it "can be set in 'opts' hash of property method, overruling others" do
45
+ A.cascade do
46
+ color :default => :red, :proc_inst_exec => false
47
+ end
48
+ outside_context = self
49
+ who_is_self = nil
50
+
51
+ B.color = Proc.new{|me, parents| who_is_self = self; :orange}
52
+
53
+ B.color.must_equal :orange
54
+ who_is_self.must_equal(outside_context)
55
+
56
+ B.color(:undef, :undef, {:proc_inst_exec => true}).must_equal :orange
57
+ who_is_self.must_equal(B)
58
+ end
59
+ end
60
+ end
data/todo ADDED
@@ -0,0 +1,6 @@
1
+
2
+ in opts hash in property call:
3
+ :new => true
4
+ this returns the value of @props[:my_property][:new].call
5
+
6
+ when setting properties, allow an option so that the property can never be inherited. IE: descendents will pass over it when blank
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cascading_classes
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.6.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,13 +9,9 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2011-08-09 00:00:00.000000000Z
12
+ date: 2011-09-04 00:00:00.000000000Z
13
13
  dependencies: []
14
- description: ! 'Easily create properties whose values cascade down class trees.
15
-
16
-
17
- Similar to active_support/core_ext/class/attribute.rb but better. Also, doesn''t
18
- monkey-patch Class'
14
+ description:
19
15
  email: jeremy.gables@gmail.com
20
16
  executables: []
21
17
  extensions: []
@@ -23,13 +19,27 @@ extra_rdoc_files: []
23
19
  files:
24
20
  - README.md
25
21
  - Rakefile
22
+ - todo
26
23
  - lib/cascading_classes.rb
27
24
  - lib/cascading_classes/cascading_classes.rb
28
25
  - lib/cascading_classes/dsl.rb
26
+ - lib/cascading_classes/types.rb
27
+ - lib/cascading_classes/parse_options.rb
29
28
  - spec/helper_spec.rb
30
- - spec/extended_spec.rb
31
- - spec/included_spec.rb
32
- - spec/alternative_syntax_spec.rb
29
+ - spec/basics/basic_spec.rb
30
+ - spec/basics/block_spec.rb
31
+ - spec/basics/container_spec.rb
32
+ - spec/basics/inherit_spec.rb
33
+ - spec/basics/proc_spec.rb
34
+ - spec/class_helper_methods/parents_for_spec.rb
35
+ - spec/custom_classes/hash_like_spec.rb
36
+ - spec/instances/basics.rb
37
+ - spec/preset_classes/array_spec.rb
38
+ - spec/preset_classes/hash_spec.rb
39
+ - spec/preset_classes/strings.rb
40
+ - spec/preset_classes/undefined.rb
41
+ - spec/usage/block_spec.rb
42
+ - spec/usage/proc_spec.rb
33
43
  homepage: http://github.com/gables/cascading_classes
34
44
  licenses: []
35
45
  post_install_message:
@@ -53,9 +63,20 @@ rubyforge_project:
53
63
  rubygems_version: 1.8.5
54
64
  signing_key:
55
65
  specification_version: 3
56
- summary: Easily create properties whose values cascade down class trees
66
+ summary: Manage properties on class hierarchies
57
67
  test_files:
58
68
  - spec/helper_spec.rb
59
- - spec/extended_spec.rb
60
- - spec/included_spec.rb
61
- - spec/alternative_syntax_spec.rb
69
+ - spec/basics/basic_spec.rb
70
+ - spec/basics/block_spec.rb
71
+ - spec/basics/container_spec.rb
72
+ - spec/basics/inherit_spec.rb
73
+ - spec/basics/proc_spec.rb
74
+ - spec/class_helper_methods/parents_for_spec.rb
75
+ - spec/custom_classes/hash_like_spec.rb
76
+ - spec/instances/basics.rb
77
+ - spec/preset_classes/array_spec.rb
78
+ - spec/preset_classes/hash_spec.rb
79
+ - spec/preset_classes/strings.rb
80
+ - spec/preset_classes/undefined.rb
81
+ - spec/usage/block_spec.rb
82
+ - spec/usage/proc_spec.rb
@@ -1,173 +0,0 @@
1
- begin
2
- require_relative 'helper_spec'
3
- rescue NameError
4
- require File.expand_path('helper_spec', __FILE__)
5
- end
6
-
7
- describe "when a class extends CascadingClasses and an alternative syntax is used" do
8
-
9
- # this is the same as:
10
- # class Parent
11
- # extend CascadingClasses
12
- # end
13
- #
14
- # class Child < Parent; end
15
- #
16
- # class GrandChild < Child; end
17
- before do
18
- Parent = Class.new{extend CC}
19
- Child = Class.new(Parent)
20
- GrandChild = Class.new(Child)
21
- end
22
-
23
- after do
24
- Object.send :remove_const, :Parent
25
- Object.send :remove_const, :Child
26
- Object.send :remove_const, :GrandChild
27
- end
28
-
29
- def standard
30
- Parent.hair_color.must_equal "black"
31
- Child.hair_color.must_equal "blond"
32
- GrandChild.hair_color.must_equal "blond"
33
-
34
- Parent.eye_color.must_equal nil
35
- Child.eye_color.must_equal "brown"
36
- GrandChild.eye_color.must_equal "brown"
37
-
38
- Parent.piercings.must_equal false
39
- Child.piercings.must_equal false
40
- GrandChild.piercings.must_equal false
41
- end
42
-
43
- describe "when an alternative syntax is given (0)" do
44
- before do
45
- Parent.cascade [:hair_color, "black"], :eye_color, [:piercings, false]
46
-
47
- Child.hair_color = "blond"
48
- Child.eye_color = "brown"
49
- end
50
-
51
- it "should give the same result" do
52
- standard
53
- end
54
- end
55
-
56
- describe "when an alternate syntax is given (1)" do
57
- before do
58
- Parent.all! [:hair_color, "black"], :eye_color, [:piercings, false]
59
-
60
- Child.hair_color = "blond"
61
- Child.eye_color = "brown"
62
- end
63
-
64
- it "should give the same result" do
65
- standard
66
- end
67
- end
68
-
69
- describe "when an alternative syntax is given (2)" do
70
- before do
71
- Parent.cascade :eye_color do
72
- hair_color :begin => "black"
73
- piercings :initial => false
74
- end
75
-
76
- Child.hair_color = "blond"
77
- Child.eye_color = "brown"
78
- end
79
-
80
- it "should give the same result" do
81
- standard
82
- end
83
- end
84
-
85
- describe "when an alternative syntax is given (3)" do
86
- before do
87
- Parent.all! :eye_color do
88
- hair_color :start => "black"
89
- piercings :default => false
90
- end
91
-
92
- Child.hair_color = "blond"
93
- Child.eye_color = "brown"
94
- end
95
-
96
- it "should give the same result" do
97
- standard
98
- end
99
- end
100
-
101
- describe "when an alternative syntax is given (3)" do
102
- before do
103
- Parent.all! :eye_color do
104
- set_property :hair_color, :start => "black"
105
- set_property :piercings, :initial => false
106
- end
107
-
108
- Child.hair_color = "blond"
109
- Child.eye_color = "brown"
110
- end
111
-
112
- it "should give the same result" do
113
- standard
114
- end
115
- end
116
-
117
- # getters/setters
118
- describe "when an alternative getter/setter syntax is given" do
119
- before do
120
- Parent.cascade do
121
- eye_color :getter => :eyes, :setter => :eyes=
122
- hair_color :initial => "black", :getters => :hair, :setters => :hair=
123
- piercings :start => false,
124
- :getter => [:has_piercings?, :piercings?],
125
- :setter => [:has_piercings=, :piercings=]
126
- end
127
-
128
- Child.hair = "blond"
129
- Child.eyes = "brown"
130
- end
131
-
132
- it "should give the same result" do
133
- Parent.hair.must_equal "black"
134
- Child.hair.must_equal "blond"
135
- GrandChild.hair.must_equal "blond"
136
-
137
- Parent.eyes.must_equal nil
138
- Child.eyes.must_equal "brown"
139
- GrandChild.eyes.must_equal "brown"
140
-
141
- Parent.has_piercings?.must_equal false
142
- Child.piercings?.must_equal false
143
- GrandChild.has_piercings?.must_equal false
144
- end
145
- end
146
-
147
- describe "when an alternative syntax is given (2)" do
148
- before do
149
- Parent.cascade [:eye_color, nil, false, :eyes, :eyes=]
150
- Parent.cascade [:hair_color, "black", false, :hair, :hair=]
151
- Parent.cascade [:piercings, false, false,
152
- [:has_piercings?, :piercings?],
153
- [:has_piercings=, :piercings=] ]
154
-
155
- Child.hair = "blond"
156
- Child.eyes = "brown"
157
- end
158
-
159
- it "should give the same result" do
160
- Parent.hair.must_equal "black"
161
- Child.hair.must_equal "blond"
162
- GrandChild.hair.must_equal "blond"
163
-
164
- Parent.eyes.must_equal nil
165
- Child.eyes.must_equal "brown"
166
- GrandChild.eyes.must_equal "brown"
167
-
168
- Parent.has_piercings?.must_equal false
169
- Child.piercings?.must_equal false
170
- GrandChild.has_piercings?.must_equal false
171
- end
172
- end
173
- end
@@ -1,315 +0,0 @@
1
- begin
2
- require_relative 'helper_spec'
3
- rescue NameError
4
- require File.expand_path('helper_spec', __FILE__)
5
- end
6
-
7
- # require 'minitest/autorun'
8
- # require 'cascading_classes'
9
-
10
- # class << MiniTest::Spec
11
- # alias_method :all, :it
12
- # end
13
-
14
- describe "when a class extends CascadingClasses" do
15
-
16
- # this is the same as:
17
- # class Parent
18
- # extend CascadingClasses
19
- # end
20
- #
21
- # class Child < Parent; end
22
- #
23
- # class GrandChild < Child; end
24
- before do
25
- Parent = Class.new{extend CC}
26
- Child = Class.new(Parent)
27
- GrandChild = Class.new(Child)
28
- end
29
-
30
- after do
31
- Object.send :remove_const, :Parent
32
- Object.send :remove_const, :Child
33
- Object.send :remove_const, :GrandChild
34
- end
35
-
36
- describe "when a parent has a default" do
37
- before do
38
- Parent.cascade [:eyes, "brown"]
39
- end
40
-
41
- it "sets the property to the default" do
42
- Parent.eyes.must_equal "brown"
43
- end
44
- end
45
-
46
- describe "when a property is set from above" do
47
- before do
48
- Parent.cascade(:hair_color)
49
-
50
- Parent.hair_color = :blond
51
- end
52
-
53
- it "should cascade down to its descendents" do
54
- Parent.hair_color.must_equal :blond
55
- Child.hair_color.must_equal :blond
56
- GrandChild.hair_color.must_equal :blond
57
- end
58
- end
59
-
60
- describe "when a property is set from below" do
61
- before do
62
- Parent.cascade do
63
- arms :default => 2
64
- legs :default => 2
65
- end
66
-
67
- Child.arms = 3
68
- GrandChild.legs = 1
69
- end
70
-
71
- all "descendents are influenced and no acestors are affected" do
72
- Parent.arms.must_equal 2
73
- Child.arms.must_equal 3
74
- GrandChild.arms.must_equal 3
75
-
76
- Parent.legs.must_equal 2
77
- Child.legs.must_equal 2
78
- GrandChild.legs.must_equal 1
79
- end
80
- end
81
-
82
- describe "when a property has a default and has not been set by any descendent" do
83
- before do
84
- Parent.cascade [:eye_color, "red"]
85
- end
86
-
87
- all "descendents should reflect that default" do
88
- Parent.eye_color.must_equal "red"
89
- Child.eye_color.must_equal "red"
90
- GrandChild.eye_color.must_equal "red"
91
- end
92
- end
93
-
94
- describe "when a property has no default and has not been set by any ancestor" do
95
- before do
96
- Parent.cascade :has_house
97
- end
98
-
99
- all "descendents should reflect nil" do
100
- Parent.has_house.must_equal nil
101
- Child.has_house.must_equal nil
102
- GrandChild.has_house.must_equal nil
103
- end
104
- end
105
-
106
- describe "when a child sets a property when its parent has set it too" do
107
- before do
108
- Parent.all! :trigger
109
-
110
- Parent.trigger = "silent"
111
- Child.trigger = "loud"
112
- end
113
-
114
- all "cascading is scoped off the youngest child with a set property" do
115
- Parent.trigger.must_equal "silent"
116
- Child.trigger.must_equal "loud"
117
- GrandChild.trigger.must_equal "loud"
118
- end
119
- end
120
-
121
- describe "when a parent has a property with a default" do
122
- before do
123
- Parent.cascade [:time, 32]
124
- end
125
-
126
- it "won't matter whether the property is first accessed by the child" do
127
- Child.time
128
-
129
- Child.time.must_equal 32
130
- Parent.time.must_equal 32
131
- end
132
- end
133
-
134
- describe "when a parent has a property with a default" do
135
- before do
136
- Parent.cascade [:time, 32]
137
- end
138
-
139
- it "won't matter if the property is first accessed by the parent" do
140
- Parent.time
141
-
142
- Child.time.must_equal 32
143
- Parent.time.must_equal 32
144
- end
145
- end
146
-
147
- describe "when a property is set to false" do
148
- before do
149
- Parent.cascade [:has_time, false]
150
- end
151
-
152
- it "should return false, not nil" do
153
- Parent.has_time.must_equal false
154
- end
155
- end
156
-
157
- describe "when a property name is not allowed" do
158
- before do
159
- property = CascadingClasses.illegal_names.sample
160
- end
161
-
162
- it "should raise a NameError" do
163
- res = begin
164
- Parent.cascade property
165
- rescue NameError
166
- true
167
- else
168
- false
169
- end
170
- res.must_equal true
171
- end
172
- end
173
-
174
- # getters/setters
175
- describe "when a custom getter is given" do
176
- before do
177
- Parent.cascade do
178
- eye_color :default => "brown", :getter => :color
179
- end
180
- end
181
-
182
- it "is the only reader method" do
183
- Parent.color.must_equal "brown"
184
-
185
- Parent.send(:respond_to?, :eye_color).must_equal false
186
- end
187
- end
188
-
189
- # :getters aliased to :getter
190
- describe "when multiple getters are given" do
191
- before do
192
- Parent.cascade do
193
- eye_color :default => "brown", :getters => [:color, :eyes]
194
- end
195
-
196
- it "those methods are the only readers" do
197
- Parent.color.must_equal "brown"
198
- Parent.eyes.must_equal "brown"
199
-
200
- Parent.send(:respond_to?, :eye_color).must_equal false
201
- end
202
- end
203
- end
204
-
205
- describe "when a getter name is nil" do
206
- before do
207
- Parent.all! do
208
- color :default => "red", :getter => nil
209
- end
210
- end
211
-
212
- it "should not have a getter method" do
213
- Parent.send(:respond_to?, :color).must_equal false
214
- end
215
- end
216
-
217
- describe "when a getter name is false" do
218
- before do
219
- Parent.all!{
220
- color :default => "red", :getter => false
221
- }
222
- end
223
-
224
- it "should not have a getter method" do
225
- Parent.send(:respond_to?, :color).must_equal false
226
- end
227
- end
228
-
229
- describe "when a custom getter is given" do
230
- before do
231
- Parent.cascade do
232
- eye_color :default => "black", :getter => :color
233
- end
234
- end
235
-
236
- it "should also be the getter for child classes" do
237
- Child.color.must_equal "black"
238
-
239
- Child.send(:respond_to?, :eye_color).must_equal false
240
- end
241
- end
242
-
243
- describe "when a custom setter is given" do
244
- before do
245
- Parent.cascade do
246
- eye_color :default => "brown", :setter => :color=
247
- end
248
- end
249
-
250
- it "is the only writer method" do
251
- Parent.color = "blue"
252
- Parent.eye_color.must_equal "blue"
253
-
254
- Parent.send(:respond_to?, :eye_color=).must_equal false
255
- end
256
- end
257
-
258
- # :setters aliased to :setters
259
- describe "when multiple setters are given" do
260
- before do
261
- Parent.cascade do
262
- eye_color :default => "brown", :setters => [:color=, :set_color]
263
- end
264
-
265
- it "those methods are the only readers" do
266
- Parent.color = "blue"
267
- Parent.color.must_equal "blue"
268
-
269
- Parent.set_color "black"
270
- Parent.color.must_equal "black"
271
-
272
- Parent.send(:respond_to?, :eye_color=).must_equal false
273
- end
274
- end
275
- end
276
-
277
- describe "when a setter name is nil" do
278
- before do
279
- Parent.all!{
280
- color :default => "red", :setter => nil
281
- }
282
- end
283
-
284
- it "should not have a setter method" do
285
- Parent.send(:respond_to?, :color=).must_equal false
286
- end
287
- end
288
-
289
- describe "when a setter name is false" do
290
- before do
291
- Parent.all! do
292
- color :default => "red", :setter => false
293
- end
294
- end
295
-
296
- it "should not have a setter method" do
297
- Parent.send(:respond_to?, :color=).must_equal false
298
- end
299
- end
300
-
301
- describe "when a custom setter is given" do
302
- before do
303
- Parent.cascade do
304
- eye_color :default => "black", :setter => :color=
305
- end
306
- end
307
-
308
- it "should also be the getter for child classes" do
309
- Child.color = "blue"
310
- Child.eye_color.must_equal "blue"
311
-
312
- Child.send(:respond_to?, :eye_color=).must_equal false
313
- end
314
- end
315
- end