cascading_classes 0.3.0 → 0.6.0

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