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.
- data/README.md +959 -140
- data/Rakefile +9 -2
- data/lib/cascading_classes.rb +254 -46
- data/lib/cascading_classes/cascading_classes.rb +194 -40
- data/lib/cascading_classes/dsl.rb +137 -59
- data/lib/cascading_classes/parse_options.rb +71 -0
- data/lib/cascading_classes/types.rb +229 -0
- data/spec/basics/basic_spec.rb +230 -0
- data/spec/basics/block_spec.rb +52 -0
- data/spec/basics/container_spec.rb +201 -0
- data/spec/basics/inherit_spec.rb +339 -0
- data/spec/basics/proc_spec.rb +343 -0
- data/spec/class_helper_methods/parents_for_spec.rb +36 -0
- data/spec/custom_classes/hash_like_spec.rb +144 -0
- data/spec/helper_spec.rb +34 -2
- data/spec/instances/basics.rb +239 -0
- data/spec/preset_classes/array_spec.rb +214 -0
- data/spec/preset_classes/hash_spec.rb +210 -0
- data/spec/preset_classes/strings.rb +190 -0
- data/spec/preset_classes/undefined.rb +56 -0
- data/spec/usage/block_spec.rb +59 -0
- data/spec/usage/proc_spec.rb +60 -0
- data/todo +6 -0
- metadata +35 -14
- data/spec/alternative_syntax_spec.rb +0 -173
- data/spec/extended_spec.rb +0 -315
- data/spec/included_spec.rb +0 -103
@@ -0,0 +1,214 @@
|
|
1
|
+
begin
|
2
|
+
require_relative '../helper_spec'
|
3
|
+
rescue NameError
|
4
|
+
require File.expand_path('../helper_spec', __FILE__)
|
5
|
+
end
|
6
|
+
|
7
|
+
describe "array 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 "equivalent syntax" do
|
21
|
+
before do
|
22
|
+
Parent.cascade do
|
23
|
+
colors_a :default => [:red, :blue, :yellow]
|
24
|
+
colors_b :array => true
|
25
|
+
colors_c
|
26
|
+
end
|
27
|
+
|
28
|
+
props = Parent.singleton_class.properties
|
29
|
+
|
30
|
+
props[:colors_a][:type].must_equal :Array
|
31
|
+
props[:colors_b][:type].must_equal :Array
|
32
|
+
props[:colors_c][:type].must_equal :undefined_type
|
33
|
+
Parent.colors_a.must_equal [:red, :blue, :yellow]
|
34
|
+
Parent.colors_b.must_equal []
|
35
|
+
Parent.colors_c.must_equal nil
|
36
|
+
|
37
|
+
Parent.colors_b << :red << :blue << :yellow
|
38
|
+
Parent.colors_c = [:red, :blue, :yellow]
|
39
|
+
|
40
|
+
props[:colors_c][:type].must_equal :Array
|
41
|
+
Parent.colors_b.must_equal [:red, :blue, :yellow]
|
42
|
+
Parent.colors_c.must_equal [:red, :blue, :yellow]
|
43
|
+
|
44
|
+
Parent.cascade [:colors_d, [:red, :blue, :yellow]], :colors_e
|
45
|
+
Parent.cascade [:colors_f, [:red, :blue, :yellow]]
|
46
|
+
Parent.cascade :colors_g
|
47
|
+
|
48
|
+
props[:colors_d][:type].must_equal :Array
|
49
|
+
props[:colors_e][:type].must_equal :undefined_type
|
50
|
+
props[:colors_f][:type].must_equal :Array
|
51
|
+
props[:colors_g][:type].must_equal :undefined_type
|
52
|
+
Parent.colors_d.must_equal [:red, :blue, :yellow]
|
53
|
+
Parent.colors_e.must_equal nil
|
54
|
+
Parent.colors_f.must_equal [:red, :blue, :yellow]
|
55
|
+
Parent.colors_g.must_equal nil
|
56
|
+
|
57
|
+
Parent.colors_e = [:red, :blue, :yellow]
|
58
|
+
Parent.colors_g = [:red, :blue, :yellow]
|
59
|
+
|
60
|
+
props[:colors_e][:type].must_equal :Array
|
61
|
+
props[:colors_g][:type].must_equal :Array
|
62
|
+
Parent.colors_e.must_equal [:red, :blue, :yellow]
|
63
|
+
Parent.colors_g.must_equal [:red, :blue, :yellow]
|
64
|
+
end
|
65
|
+
|
66
|
+
it "is all the same" do
|
67
|
+
Parent.colors_a.must_equal [:red, :blue, :yellow]
|
68
|
+
Parent.colors_b.must_equal [:red, :blue, :yellow]
|
69
|
+
Parent.colors_c.must_equal [:red, :blue, :yellow]
|
70
|
+
Parent.colors_d.must_equal [:red, :blue, :yellow]
|
71
|
+
Parent.colors_e.must_equal [:red, :blue, :yellow]
|
72
|
+
Parent.colors_f.must_equal [:red, :blue, :yellow]
|
73
|
+
Parent.colors_g.must_equal [:red, :blue, :yellow]
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
describe "array syntax" do
|
79
|
+
before do
|
80
|
+
Parent = Class.new{include CC}
|
81
|
+
Child = Class.new(Parent)
|
82
|
+
GrandChild = Class.new(Child)
|
83
|
+
|
84
|
+
@props = Parent.cascade do
|
85
|
+
fruit :default => [:orange, :apple, :pear]
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
after do
|
90
|
+
Object.send :remove_const, :Parent
|
91
|
+
Object.send :remove_const, :Child
|
92
|
+
Object.send :remove_const, :GrandChild
|
93
|
+
end
|
94
|
+
|
95
|
+
describe "by default" do
|
96
|
+
it "is set to not 'inherit' by default" do
|
97
|
+
@props[:fruit][:inherit].must_equal(false)
|
98
|
+
Child.fruit.must_equal []
|
99
|
+
end
|
100
|
+
|
101
|
+
it "descendents (including instances) do not inherit" do
|
102
|
+
Parent.new.fruit.must_equal []
|
103
|
+
Child.fruit.must_equal []
|
104
|
+
Child.new.fruit.must_equal []
|
105
|
+
GrandChild.fruit.must_equal []
|
106
|
+
GrandChild.new.fruit.must_equal []
|
107
|
+
end
|
108
|
+
|
109
|
+
it "'Parent' has default value" do
|
110
|
+
Parent.fruit.must_equal [:orange, :apple, :pear]
|
111
|
+
end
|
112
|
+
|
113
|
+
it "has type ':Array'" do
|
114
|
+
@props[:fruit][:type].must_equal :Array
|
115
|
+
end
|
116
|
+
|
117
|
+
it "has blank value of empty array" do
|
118
|
+
@props[:fruit][:blank].call([]).must_equal true
|
119
|
+
end
|
120
|
+
|
121
|
+
it "has new value of empty array" do
|
122
|
+
@props[:fruit][:new].call.must_equal []
|
123
|
+
end
|
124
|
+
|
125
|
+
it "nonblank values never inherit" do
|
126
|
+
nonblank_helper(Parent, :fruit, [:orange, :apple, :pear])
|
127
|
+
|
128
|
+
parent = Parent.new
|
129
|
+
parent.fruit = [:mango, :pineapple]
|
130
|
+
nonblank_helper(parent, :fruit, [:mango, :pineapple])
|
131
|
+
|
132
|
+
Child.fruit = ["summer", "rain"]
|
133
|
+
nonblank_helper(Child, :fruit, ["summer", "rain"])
|
134
|
+
|
135
|
+
child = Child.new
|
136
|
+
child.fruit = [:lemons, :limes]
|
137
|
+
nonblank_helper(child, :fruit, [:lemons, :limes])
|
138
|
+
|
139
|
+
GrandChild.fruit = [:watermelon, :orange]
|
140
|
+
nonblank_helper(GrandChild, :fruit, [:watermelon, :orange])
|
141
|
+
|
142
|
+
grandchild = GrandChild.new
|
143
|
+
grandchild.fruit = [{:time => false, :color => "blue"}]
|
144
|
+
nonblank_helper(grandchild, :fruit, [{:time => false, :color => "blue"}])
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
describe "property on instance of 'Parent' is blank" do
|
149
|
+
before do
|
150
|
+
@parent = Parent.new
|
151
|
+
end
|
152
|
+
|
153
|
+
it "can inherit one level up to 'Parent'" do
|
154
|
+
blank_inherit_helper(@parent, :fruit, 1, [:orange, :apple, :pear], [])
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
describe "'Child'" do
|
159
|
+
describe "property on 'Child' is blank" do
|
160
|
+
it "can inherit one level up to 'Parent'" do
|
161
|
+
blank_inherit_helper(Child, :fruit, 1, [:orange, :apple, :pear], [])
|
162
|
+
end
|
163
|
+
|
164
|
+
describe "property on instance of 'Child' is blank" do
|
165
|
+
before do
|
166
|
+
@child = Child.new
|
167
|
+
end
|
168
|
+
|
169
|
+
it "can inherit two levels up to 'Parent'" do
|
170
|
+
blank_inherit_helper(@child, :fruit, 2, [:orange, :apple, :pear], [])
|
171
|
+
end
|
172
|
+
end
|
173
|
+
|
174
|
+
describe "property on 'GrandChild' is blank" do
|
175
|
+
it "can inherit two levels up to 'Parent'" do
|
176
|
+
blank_inherit_helper(GrandChild, :fruit, 2, [:orange, :apple, :pear], [])
|
177
|
+
end
|
178
|
+
end
|
179
|
+
end
|
180
|
+
|
181
|
+
describe "property on 'Child' is nonblank" do
|
182
|
+
before do
|
183
|
+
Child.fruit = [:mango, :pineapple]
|
184
|
+
end
|
185
|
+
|
186
|
+
describe "property on instance of 'Child' is blank" do
|
187
|
+
before do
|
188
|
+
@child = Child.new
|
189
|
+
end
|
190
|
+
|
191
|
+
it "can inherit one level up to 'Child'" do
|
192
|
+
blank_inherit_helper(@child, :fruit, 1, [:mango, :pineapple], [])
|
193
|
+
end
|
194
|
+
end
|
195
|
+
|
196
|
+
describe "property on 'GrandChild' is blank" do
|
197
|
+
it "can inherit one level up to 'Child'" do
|
198
|
+
blank_inherit_helper(GrandChild, :fruit, 1, [:mango, :pineapple], [])
|
199
|
+
end
|
200
|
+
|
201
|
+
describe "property on instance of 'GrandChild' is blank" do
|
202
|
+
before do
|
203
|
+
@grandchild = GrandChild.new
|
204
|
+
end
|
205
|
+
|
206
|
+
it "can inherit two levels up to 'Child'" do
|
207
|
+
blank_inherit_helper(@grandchild, :fruit, 2, [:mango, :pineapple], [])
|
208
|
+
end
|
209
|
+
end
|
210
|
+
end
|
211
|
+
end
|
212
|
+
end
|
213
|
+
end
|
214
|
+
|
@@ -0,0 +1,210 @@
|
|
1
|
+
begin
|
2
|
+
require_relative '../helper_spec'
|
3
|
+
rescue NameError
|
4
|
+
require File.expand_path('../helper_spec', __FILE__)
|
5
|
+
end
|
6
|
+
|
7
|
+
# todo: subclasses that inherit :Object (undefined types)
|
8
|
+
|
9
|
+
describe "hash syntax" do
|
10
|
+
before do
|
11
|
+
Parent = Class.new{extend CC}
|
12
|
+
Child = Class.new(Parent)
|
13
|
+
GrandChild = Class.new(Child)
|
14
|
+
end
|
15
|
+
|
16
|
+
after do
|
17
|
+
Object.send :remove_const, :Parent
|
18
|
+
Object.send :remove_const, :Child
|
19
|
+
Object.send :remove_const, :GrandChild
|
20
|
+
end
|
21
|
+
|
22
|
+
describe "equivalent syntax" do
|
23
|
+
before do
|
24
|
+
Parent.cascade do
|
25
|
+
person_a :default => {:name => ['williamson', 'charles']}
|
26
|
+
person_b :hash => true
|
27
|
+
person_c
|
28
|
+
end
|
29
|
+
|
30
|
+
props = Parent.singleton_class.properties
|
31
|
+
|
32
|
+
props[:person_a][:type].must_equal :Hash
|
33
|
+
props[:person_b][:type].must_equal :Hash
|
34
|
+
props[:person_c][:type].must_equal :undefined_type
|
35
|
+
Parent.person_a.must_equal({:name => ['williamson', 'charles']})
|
36
|
+
Parent.person_b.must_equal({})
|
37
|
+
Parent.person_c.must_equal nil
|
38
|
+
|
39
|
+
Parent.person_b[:name] = ['williamson', 'charles']
|
40
|
+
Parent.person_c = {:name => ['williamson', 'charles']}
|
41
|
+
props[:person_c][:type].must_equal :Hash
|
42
|
+
Parent.person_b.must_equal({:name => ['williamson', 'charles']})
|
43
|
+
Parent.person_c.must_equal({:name => ['williamson', 'charles']})
|
44
|
+
|
45
|
+
Parent.cascade [:person_d, {:name => ['williamson', 'charles']}], :person_e
|
46
|
+
Parent.cascade [:person_f, {:name => ['williamson', 'charles']}]
|
47
|
+
Parent.cascade :person_g
|
48
|
+
props[:person_d][:type].must_equal :Hash
|
49
|
+
props[:person_e][:type].must_equal :undefined_type
|
50
|
+
props[:person_f][:type].must_equal :Hash
|
51
|
+
props[:person_g][:type].must_equal :undefined_type
|
52
|
+
Parent.person_d.must_equal({:name => ['williamson', 'charles']})
|
53
|
+
Parent.person_e.must_equal nil
|
54
|
+
Parent.person_f.must_equal({:name => ['williamson', 'charles']})
|
55
|
+
Parent.person_g.must_equal nil
|
56
|
+
|
57
|
+
Parent.person_e = Parent.person_g = {:name => ['williamson', 'charles']}
|
58
|
+
props[:person_e][:type].must_equal :Hash
|
59
|
+
props[:person_g][:type].must_equal :Hash
|
60
|
+
Parent.person_e.must_equal({:name => ['williamson', 'charles']})
|
61
|
+
Parent.person_g.must_equal({:name => ['williamson', 'charles']})
|
62
|
+
end
|
63
|
+
|
64
|
+
it 'is all the same' do
|
65
|
+
Parent.person_a.must_equal({:name => ['williamson', 'charles']})
|
66
|
+
Parent.person_b.must_equal({:name => ['williamson', 'charles']})
|
67
|
+
Parent.person_c.must_equal({:name => ['williamson', 'charles']})
|
68
|
+
Parent.person_d.must_equal({:name => ['williamson', 'charles']})
|
69
|
+
Parent.person_e.must_equal({:name => ['williamson', 'charles']})
|
70
|
+
Parent.person_f.must_equal({:name => ['williamson', 'charles']})
|
71
|
+
Parent.person_g.must_equal({:name => ['williamson', 'charles']})
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
describe "hash usage" do
|
77
|
+
before do
|
78
|
+
Parent = Class.new{include CC}
|
79
|
+
Child = Class.new(Parent)
|
80
|
+
GrandChild = Class.new(Child)
|
81
|
+
|
82
|
+
@props = Parent.cascade do
|
83
|
+
eyes :default => {:color => "red"}
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
after do
|
88
|
+
Object.send :remove_const, :Parent
|
89
|
+
Object.send :remove_const, :Child
|
90
|
+
Object.send :remove_const, :GrandChild
|
91
|
+
end
|
92
|
+
|
93
|
+
describe "by default" do
|
94
|
+
it "is set to not 'inherit' by default" do
|
95
|
+
@props[:eyes][:inherit].must_equal false
|
96
|
+
end
|
97
|
+
|
98
|
+
it "descendents (including instances) do not inherit" do
|
99
|
+
Parent.new.eyes.must_equal({})
|
100
|
+
Child.eyes.must_equal({})
|
101
|
+
Child.new.eyes.must_equal({})
|
102
|
+
GrandChild.eyes.must_equal({})
|
103
|
+
GrandChild.new.eyes.must_equal({})
|
104
|
+
end
|
105
|
+
|
106
|
+
it "'Parent' has 'default' value" do
|
107
|
+
Parent.eyes.must_equal({:color => "red"})
|
108
|
+
end
|
109
|
+
|
110
|
+
it "has type ':Hash'" do
|
111
|
+
@props[:eyes][:type].must_equal :Hash
|
112
|
+
end
|
113
|
+
|
114
|
+
it "has blank value of empty hash" do
|
115
|
+
@props[:eyes][:blank].call({}).must_equal true
|
116
|
+
end
|
117
|
+
|
118
|
+
it "has new value of empty hash" do
|
119
|
+
@props[:eyes][:new].call.must_equal({})
|
120
|
+
end
|
121
|
+
|
122
|
+
it "nonblank values never inherit" do
|
123
|
+
nonblank_helper(Parent, :eyes, {:color => "red"})
|
124
|
+
|
125
|
+
parent = Parent.new
|
126
|
+
parent.eyes[:style] = "western"
|
127
|
+
nonblank_helper(parent, :eyes, {:style => "western"})
|
128
|
+
|
129
|
+
Child.eyes[:orig] = true
|
130
|
+
nonblank_helper(Child, :eyes, {:orig => true})
|
131
|
+
|
132
|
+
child = Child.new
|
133
|
+
child.eyes[:temp] = 95
|
134
|
+
nonblank_helper(child, :eyes, {:temp => 95})
|
135
|
+
|
136
|
+
GrandChild.eyes[:layout] = :normal
|
137
|
+
nonblank_helper(GrandChild, :eyes, {:layout => :normal})
|
138
|
+
|
139
|
+
grandchild = GrandChild.new
|
140
|
+
grandchild.eyes[:locale] = "en"
|
141
|
+
nonblank_helper(grandchild, :eyes, {:locale => "en"})
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
describe "property on instance of 'Parent' is blank" do
|
146
|
+
before do
|
147
|
+
@parent = Parent.new
|
148
|
+
end
|
149
|
+
|
150
|
+
it "can inherit one level up to 'Parent'" do
|
151
|
+
blank_inherit_helper(@parent, :eyes, 1, {:color => "red"}, {})
|
152
|
+
end
|
153
|
+
end
|
154
|
+
|
155
|
+
describe "'Child'" do
|
156
|
+
describe "property on 'Child' is blank" do
|
157
|
+
it "can inherit one level up to 'Parent'" do
|
158
|
+
blank_inherit_helper(Child, :eyes, 1, {:color => "red"}, {})
|
159
|
+
end
|
160
|
+
|
161
|
+
describe "property on instance of 'Child' is blank" do
|
162
|
+
before do
|
163
|
+
@child = Child.new
|
164
|
+
end
|
165
|
+
|
166
|
+
it "can inherit two levels up to 'Parent'" do
|
167
|
+
blank_inherit_helper(@child, :eyes, 2, {:color => "red"}, {})
|
168
|
+
end
|
169
|
+
end
|
170
|
+
|
171
|
+
describe "property on 'GrandChild' is blank" do
|
172
|
+
it "can inherit two levels up to 'Parent'" do
|
173
|
+
blank_inherit_helper(GrandChild, :eyes, 2, {:color => "red"}, {})
|
174
|
+
end
|
175
|
+
end
|
176
|
+
end
|
177
|
+
|
178
|
+
describe "property on 'Child' is nonblank" do
|
179
|
+
before do
|
180
|
+
Child.eyes[:degrees] = [:bachelors]
|
181
|
+
end
|
182
|
+
|
183
|
+
describe "property on instance of 'Child' is blank" do
|
184
|
+
before do
|
185
|
+
@child = Child.new
|
186
|
+
end
|
187
|
+
|
188
|
+
it "can inherit one level up to 'Child'" do
|
189
|
+
blank_inherit_helper(@child, :eyes, 1, {:degrees => [:bachelors]}, {})
|
190
|
+
end
|
191
|
+
end
|
192
|
+
|
193
|
+
describe "property on 'GrandChild' is blank" do
|
194
|
+
it "can inherit one level up to 'Child'" do
|
195
|
+
blank_inherit_helper(GrandChild, :eyes, 1, {:degrees => [:bachelors]}, {})
|
196
|
+
end
|
197
|
+
|
198
|
+
describe "property on instance of 'GrandChild' is blank" do
|
199
|
+
before do
|
200
|
+
@grandchild = GrandChild.new
|
201
|
+
end
|
202
|
+
|
203
|
+
it "can inherit two levels up to 'Child'" do
|
204
|
+
blank_inherit_helper(@grandchild, :eyes, 2, {:degrees => [:bachelors]}, {})
|
205
|
+
end
|
206
|
+
end
|
207
|
+
end
|
208
|
+
end
|
209
|
+
end
|
210
|
+
end
|
@@ -0,0 +1,190 @@
|
|
1
|
+
begin
|
2
|
+
require_relative '../helper_spec'
|
3
|
+
rescue NameError
|
4
|
+
require File.expand_path('../helper_spec', __FILE__)
|
5
|
+
end
|
6
|
+
|
7
|
+
describe "string - base" 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 "equivalent syntax" do
|
21
|
+
before do
|
22
|
+
Parent.cascade do
|
23
|
+
color_a :default => "white"
|
24
|
+
color_b :string => true
|
25
|
+
color_c
|
26
|
+
end
|
27
|
+
|
28
|
+
props = Parent.singleton_class.properties
|
29
|
+
|
30
|
+
props[:color_a][:type].must_equal :String
|
31
|
+
props[:color_b][:type].must_equal :String
|
32
|
+
props[:color_c][:type].must_equal :Object
|
33
|
+
Parent.color_a.must_equal "white"
|
34
|
+
Parent.color_b.must_equal ''
|
35
|
+
Parent.color_c.must_equal nil
|
36
|
+
|
37
|
+
Parent.color_b = "white"
|
38
|
+
Parent.color_c = "white"
|
39
|
+
props[:color_c][:type].must_equal :String
|
40
|
+
Parent.color_b.must_equal "white"
|
41
|
+
Parent.color_c.must_equal "white"
|
42
|
+
|
43
|
+
Parent.cascade [:color_d, "white"], :color_e
|
44
|
+
Parent.cascade [:color_f, "white"]
|
45
|
+
Parent.cascade :color_g
|
46
|
+
props[:color_d][:type].must_equal :String
|
47
|
+
props[:color_e][:type].must_equal :Object
|
48
|
+
props[:color_f][:type].must_equal :String
|
49
|
+
props[:color_g][:type].must_equal :Object
|
50
|
+
Parent.color_d.must_equal "white"
|
51
|
+
Parent.color_e.must_equal nil
|
52
|
+
Parent.color_f.must_equal "white"
|
53
|
+
Parent.color_g.must_equal nil
|
54
|
+
|
55
|
+
Parent.color_e = Parent.color_g = "white"
|
56
|
+
props[:color_e][:type].must_equal :String
|
57
|
+
props[:color_g][:type].must_equal :String
|
58
|
+
Parent.color_e.must_equal "white"
|
59
|
+
Parent.color_g.must_equal "white"
|
60
|
+
end
|
61
|
+
|
62
|
+
it "is all the same" do
|
63
|
+
Parent.color_a.must_equal "white"
|
64
|
+
Parent.color_b.must_equal "white"
|
65
|
+
Parent.color_c.must_equal "white"
|
66
|
+
Parent.color_d.must_equal "white"
|
67
|
+
Parent.color_e.must_equal "white"
|
68
|
+
Parent.color_f.must_equal "white"
|
69
|
+
Parent.color_g.must_equal "white"
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
describe "string" do
|
75
|
+
before do
|
76
|
+
Parent = Class.new{extend CC}
|
77
|
+
Child = Class.new(Parent)
|
78
|
+
GrandChild = Class.new(Child)
|
79
|
+
|
80
|
+
@props = Parent.cascade do
|
81
|
+
color :default => "red"
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
after do
|
86
|
+
Object.send :remove_const, :Parent
|
87
|
+
Object.send :remove_const, :Child
|
88
|
+
Object.send :remove_const, :GrandChild
|
89
|
+
end
|
90
|
+
|
91
|
+
describe "by default" do
|
92
|
+
it "has type :String" do
|
93
|
+
@props[:color][:type].must_equal :String
|
94
|
+
end
|
95
|
+
|
96
|
+
it "inherits by default" do
|
97
|
+
@props[:color][:inherit].must_equal true
|
98
|
+
end
|
99
|
+
|
100
|
+
it "has blank value of empty string" do
|
101
|
+
@props[:color][:blank].call('').must_equal true
|
102
|
+
end
|
103
|
+
|
104
|
+
it "has new value of empty string" do
|
105
|
+
@props[:color][:new].call.must_equal ''
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
describe "'Child' is blank" do
|
110
|
+
it "can inherit from 'Parent'" do
|
111
|
+
blank_inherit_helper(Child, :color, 1, "red", '')
|
112
|
+
end
|
113
|
+
|
114
|
+
describe "descendents of 'Child'" do
|
115
|
+
it "can inherit from 'Parent'" do
|
116
|
+
blank_inherit_helper(GrandChild, :color, 2, "red", '')
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
describe "'Child' is not blank" do
|
122
|
+
before do
|
123
|
+
Child.color = "blue"
|
124
|
+
end
|
125
|
+
|
126
|
+
it "does not inherit" do
|
127
|
+
nonblank_helper(Child, :color, "blue")
|
128
|
+
end
|
129
|
+
|
130
|
+
describe "descendents of 'Child'" do
|
131
|
+
it "inherits from 'Child'" do
|
132
|
+
blank_inherit_helper(GrandChild, :color, 1, "blue", '')
|
133
|
+
end
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
describe "change 'blank' proc, leave 'new' proc" do
|
138
|
+
before do
|
139
|
+
@props = Parent.cascade do
|
140
|
+
city :default => "new york", :blank => Proc.new{|v| v.nil?}
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
144
|
+
it "has blank value of nil and new value of empty string" do
|
145
|
+
@props[:city][:blank].call('').must_equal false
|
146
|
+
@props[:city][:blank].call(nil).must_equal true
|
147
|
+
|
148
|
+
new_val = @props[:city][:new].call
|
149
|
+
|
150
|
+
Parent.city.must_equal "new york"
|
151
|
+
Parent.city_is_blank?.must_equal false
|
152
|
+
Child.city.must_equal new_val
|
153
|
+
Child.city_is_blank?.must_equal false
|
154
|
+
GrandChild.city.must_equal new_val
|
155
|
+
GrandChild.city_is_blank?.must_equal false
|
156
|
+
|
157
|
+
GrandChild.city = nil
|
158
|
+
GrandChild.city_is_blank?.must_equal true
|
159
|
+
GrandChild.city.must_equal Child.city
|
160
|
+
|
161
|
+
Child.city = nil
|
162
|
+
Child.city_is_blank?.must_equal true
|
163
|
+
Child.city.must_equal Parent.city
|
164
|
+
|
165
|
+
Parent.city = nil
|
166
|
+
Parent.city.must_equal nil
|
167
|
+
Parent.city_is_blank?.must_equal true
|
168
|
+
end
|
169
|
+
end
|
170
|
+
|
171
|
+
describe "change 'blank' proc and 'new' proc" do
|
172
|
+
before do
|
173
|
+
@props = Parent.cascade do
|
174
|
+
state :default => "NY", :blank => proc{|v| v.nil?}, :new => proc{ nil }
|
175
|
+
end
|
176
|
+
end
|
177
|
+
|
178
|
+
it "has blank value of nil and new value of nil" do
|
179
|
+
@props[:state][:blank].call('').must_equal false
|
180
|
+
@props[:state][:blank].call(nil).must_equal true
|
181
|
+
@props[:state][:new].call.must_equal nil
|
182
|
+
|
183
|
+
Child.state_is_blank?.must_equal true
|
184
|
+
GrandChild.state_is_blank?.must_equal true
|
185
|
+
|
186
|
+
Child.state(false).must_equal nil
|
187
|
+
GrandChild.state(false).must_equal nil
|
188
|
+
end
|
189
|
+
end
|
190
|
+
end
|