apotomo 0.1.1
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/Gemfile +10 -0
- data/Gemfile.lock +47 -0
- data/README +141 -0
- data/README.rdoc +141 -0
- data/Rakefile +78 -0
- data/TODO +36 -0
- data/app/cells/apotomo/child_switch_widget/switch.html.erb +1 -0
- data/app/cells/apotomo/child_switch_widget/switch.rhtml +1 -0
- data/app/cells/apotomo/deep_link_widget.rb +27 -0
- data/app/cells/apotomo/deep_link_widget/setup.html.erb +20 -0
- data/app/cells/apotomo/java_script_widget.rb +12 -0
- data/app/cells/apotomo/tab_panel_widget.rb +87 -0
- data/app/cells/apotomo/tab_panel_widget/display.html.erb +57 -0
- data/app/cells/apotomo/tab_widget.rb +18 -0
- data/app/cells/apotomo/tab_widget/display.html.erb +1 -0
- data/config/routes.rb +3 -0
- data/generators/widget/USAGE +15 -0
- data/generators/widget/templates/functional_test.rb +8 -0
- data/generators/widget/templates/view.html.erb +2 -0
- data/generators/widget/templates/view.html.haml +3 -0
- data/generators/widget/templates/widget.rb +8 -0
- data/generators/widget/widget_generator.rb +34 -0
- data/lib/apotomo.rb +59 -0
- data/lib/apotomo/caching.rb +37 -0
- data/lib/apotomo/container_widget.rb +10 -0
- data/lib/apotomo/deep_link_methods.rb +90 -0
- data/lib/apotomo/event.rb +9 -0
- data/lib/apotomo/event_handler.rb +23 -0
- data/lib/apotomo/event_methods.rb +102 -0
- data/lib/apotomo/invoke_event_handler.rb +24 -0
- data/lib/apotomo/javascript_generator.rb +57 -0
- data/lib/apotomo/persistence.rb +139 -0
- data/lib/apotomo/proc_event_handler.rb +18 -0
- data/lib/apotomo/rails/controller_methods.rb +161 -0
- data/lib/apotomo/rails/view_helper.rb +95 -0
- data/lib/apotomo/rails/view_methods.rb +7 -0
- data/lib/apotomo/request_processor.rb +92 -0
- data/lib/apotomo/stateful_widget.rb +8 -0
- data/lib/apotomo/transition.rb +46 -0
- data/lib/apotomo/tree_node.rb +186 -0
- data/lib/apotomo/version.rb +5 -0
- data/lib/apotomo/widget.rb +289 -0
- data/lib/apotomo/widget_shortcuts.rb +36 -0
- data/rails/init.rb +0 -0
- data/test/fixtures/application_widget_tree.rb +2 -0
- data/test/rails/controller_methods_test.rb +206 -0
- data/test/rails/rails_integration_test.rb +99 -0
- data/test/rails/view_helper_test.rb +77 -0
- data/test/rails/view_methods_test.rb +40 -0
- data/test/rails/widget_generator_test.rb +47 -0
- data/test/support/assertions_helper.rb +13 -0
- data/test/support/test_case_methods.rb +68 -0
- data/test/test_helper.rb +77 -0
- data/test/unit/apotomo_test.rb +20 -0
- data/test/unit/container_test.rb +20 -0
- data/test/unit/event_handler_test.rb +67 -0
- data/test/unit/event_methods_test.rb +83 -0
- data/test/unit/event_test.rb +30 -0
- data/test/unit/invoke_test.rb +123 -0
- data/test/unit/javascript_generator_test.rb +90 -0
- data/test/unit/onfire_integration_test.rb +19 -0
- data/test/unit/persistence_test.rb +240 -0
- data/test/unit/render_test.rb +203 -0
- data/test/unit/request_processor_test.rb +178 -0
- data/test/unit/stateful_widget_test.rb +135 -0
- data/test/unit/test_addressing.rb +111 -0
- data/test/unit/test_caching.rb +54 -0
- data/test/unit/test_jump_to_state.rb +89 -0
- data/test/unit/test_tab_panel.rb +72 -0
- data/test/unit/test_widget_shortcuts.rb +45 -0
- data/test/unit/transition_test.rb +33 -0
- data/test/unit/widget_shortcuts_test.rb +68 -0
- data/test/unit/widget_test.rb +24 -0
- metadata +215 -0
@@ -0,0 +1,203 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), *%w[.. test_helper])
|
2
|
+
|
3
|
+
class RenderTest < ActionView::TestCase
|
4
|
+
context "Rendering a single widget" do
|
5
|
+
setup do
|
6
|
+
@mum = mouse_mock
|
7
|
+
end
|
8
|
+
|
9
|
+
should "per default display the state content framed in a div" do
|
10
|
+
assert_equal '<div id="mouse">burp!</div>', @mum.invoke(:eating)
|
11
|
+
end
|
12
|
+
|
13
|
+
context "with :text" do
|
14
|
+
setup do
|
15
|
+
@mum.instance_eval { def eating; render :text => "burp!!!"; end }
|
16
|
+
end
|
17
|
+
|
18
|
+
should "render the :text" do
|
19
|
+
assert_equal "burp!!!", @mum.invoke
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
|
24
|
+
context "with :suppress_js" do
|
25
|
+
setup do
|
26
|
+
@mum.instance_eval do
|
27
|
+
def snuggle; render; end
|
28
|
+
self.class.send :attr_reader, :suppress_js
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
should "per default be false" do
|
33
|
+
@mum.invoke :snuggle
|
34
|
+
assert !@mum.suppress_js
|
35
|
+
end
|
36
|
+
|
37
|
+
should "be true when set" do
|
38
|
+
@mum.instance_eval do
|
39
|
+
def snuggle; render :suppress_js => true; end
|
40
|
+
end
|
41
|
+
@mum.invoke :snuggle
|
42
|
+
assert @mum.suppress_js
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
should "expose its instance variables in the rendered view" do
|
47
|
+
@mum = mouse_mock('mum', :educate) do
|
48
|
+
def educate
|
49
|
+
@who = "the cat"
|
50
|
+
@what = "run away"
|
51
|
+
render
|
52
|
+
end
|
53
|
+
end
|
54
|
+
assert_equal 'If you see the cat do run away!', @mum.invoke(:educate)
|
55
|
+
end
|
56
|
+
|
57
|
+
context "with #emit" do
|
58
|
+
setup do
|
59
|
+
@kid = mouse_mock('kid', :squeak)
|
60
|
+
@kid.instance_eval do
|
61
|
+
def squeak
|
62
|
+
render :text => "squeeeeaaak"
|
63
|
+
end
|
64
|
+
|
65
|
+
def render(*)
|
66
|
+
@rendered = true
|
67
|
+
super
|
68
|
+
end
|
69
|
+
def rendered?; @rendered; end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
context "and :text" do
|
74
|
+
setup do
|
75
|
+
@mum.instance_eval do
|
76
|
+
def squeak
|
77
|
+
emit :text => "squeak();"
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
should "just return the plain :text" do
|
83
|
+
assert_equal 'squeak();', @mum.invoke(:squeak)
|
84
|
+
end
|
85
|
+
|
86
|
+
should "not render children" do
|
87
|
+
@mum << @kid
|
88
|
+
@mum.invoke(:squeak)
|
89
|
+
|
90
|
+
assert_not @kid.rendered?
|
91
|
+
end
|
92
|
+
|
93
|
+
should "allow rendering children" do
|
94
|
+
@mum.instance_eval do
|
95
|
+
def squeak
|
96
|
+
emit :text => "squeak();", :render_children => true
|
97
|
+
end
|
98
|
+
end
|
99
|
+
@mum << @kid
|
100
|
+
@mum.invoke(:squeak)
|
101
|
+
|
102
|
+
assert @kid.rendered?
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
context "and no options" do
|
107
|
+
setup do
|
108
|
+
@mum.instance_eval do
|
109
|
+
def squeak
|
110
|
+
emit
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
should "render the view" do
|
116
|
+
assert_equal "<div id=\"mouse\">burp!</div>", @mum.invoke(:eating)
|
117
|
+
end
|
118
|
+
|
119
|
+
should "render the children, too" do
|
120
|
+
@mum << @kid
|
121
|
+
@mum.invoke(:eating)
|
122
|
+
assert @kid.rendered?
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
context "and :view" do
|
127
|
+
setup do
|
128
|
+
@mum.instance_eval do
|
129
|
+
def squeak
|
130
|
+
emit :view => :snuggle
|
131
|
+
end
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
should "render the :view" do
|
136
|
+
assert_equal "<div id=\"mouse\"><snuggle></snuggle></div>", @mum.invoke(:squeak)
|
137
|
+
end
|
138
|
+
|
139
|
+
should "render the children" do
|
140
|
+
@mum << @kid
|
141
|
+
|
142
|
+
assert_equal "<div id=\"mouse\"><snuggle>squeeeeaaak</snuggle></div>", @mum.invoke(:squeak)
|
143
|
+
assert @kid.rendered?
|
144
|
+
end
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
context "with #update" do
|
149
|
+
setup do
|
150
|
+
Apotomo.js_framework = :prototype
|
151
|
+
end
|
152
|
+
|
153
|
+
should "wrap the :text in an update statement" do
|
154
|
+
@mum.instance_eval do
|
155
|
+
def squeak
|
156
|
+
update :text => "squeak!"
|
157
|
+
end
|
158
|
+
end
|
159
|
+
assert_equal "$(\"mouse\").update(\"squeak!\")", @mum.invoke(:squeak)
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
163
|
+
context "with #replace" do
|
164
|
+
setup do
|
165
|
+
Apotomo.js_framework = :prototype
|
166
|
+
end
|
167
|
+
|
168
|
+
should "wrap the :text in a replace statement" do
|
169
|
+
@mum.instance_eval do
|
170
|
+
def squeak
|
171
|
+
replace :text => '<div id="mum">squeak!</div>'
|
172
|
+
end
|
173
|
+
end
|
174
|
+
assert_equal "$(\"mouse\").replace(\"<div id=\\\"mum\\\">squeak!<\\/div>\")", @mum.invoke(:squeak)
|
175
|
+
end
|
176
|
+
end
|
177
|
+
end
|
178
|
+
|
179
|
+
context "rendering a widget family" do
|
180
|
+
setup do
|
181
|
+
@mum = mouse_mock('mum', :snuggle) do
|
182
|
+
def snuggle; render; end
|
183
|
+
end
|
184
|
+
|
185
|
+
@mum << @kid = mouse_mock('kid')
|
186
|
+
end
|
187
|
+
|
188
|
+
should "per default render kid's content inside mums div with rendered_children" do
|
189
|
+
assert_equal '<div id="mum"><snuggle><div id="kid">burp!</div></snuggle></div>', @mum.invoke(:snuggle)
|
190
|
+
end
|
191
|
+
|
192
|
+
should "skip kids if :render_children=>false but still provide a rendered_children hash" do
|
193
|
+
@mum.instance_eval do
|
194
|
+
def snuggle; render :render_children => false; end
|
195
|
+
end
|
196
|
+
|
197
|
+
assert_equal '<div id="mum"><snuggle></snuggle></div>', @mum.invoke(:snuggle)
|
198
|
+
end
|
199
|
+
|
200
|
+
should_eventually "provide an ordered rendered_children hash"
|
201
|
+
end
|
202
|
+
|
203
|
+
end
|
@@ -0,0 +1,178 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), *%w[.. test_helper])
|
2
|
+
|
3
|
+
class RequestProcessorTest < Test::Unit::TestCase
|
4
|
+
context "#root" do
|
5
|
+
should "allow external modification of the tree" do
|
6
|
+
@processor = Apotomo::RequestProcessor.new({})
|
7
|
+
root = @processor.root
|
8
|
+
root << mouse_mock
|
9
|
+
assert_equal 2, @processor.root.size
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
context "option processing at construction time" do
|
14
|
+
context "with empty session and options" do
|
15
|
+
setup do
|
16
|
+
@processor = Apotomo::RequestProcessor.new({})
|
17
|
+
end
|
18
|
+
|
19
|
+
should "mark the tree as flushed" do
|
20
|
+
assert @processor.widgets_flushed?
|
21
|
+
end
|
22
|
+
|
23
|
+
should "provide a single root-node for #root" do
|
24
|
+
assert_equal 1, @processor.root.size
|
25
|
+
end
|
26
|
+
|
27
|
+
should "initialize version to 0" do
|
28
|
+
assert_equal 0, @processor.root.version
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
context "with session" do
|
33
|
+
setup do
|
34
|
+
mum_and_kid!
|
35
|
+
@mum.version = 1
|
36
|
+
@session = {:apotomo_stateful_branches => [[@mum, 'root']]}
|
37
|
+
@processor = Apotomo::RequestProcessor.new(@session)
|
38
|
+
end
|
39
|
+
|
40
|
+
should "provide a widget family for #root" do
|
41
|
+
assert_equal 3, @processor.root.size
|
42
|
+
assert_equal 1, @processor.root['mum'].version
|
43
|
+
assert_not @processor.widgets_flushed?
|
44
|
+
end
|
45
|
+
|
46
|
+
context "having a flush flag set" do
|
47
|
+
setup do
|
48
|
+
@processor = Apotomo::RequestProcessor.new(@session, :flush_widgets => true)
|
49
|
+
end
|
50
|
+
|
51
|
+
should "provide a single root for #root when :flush_widgets is set" do
|
52
|
+
assert_equal 1, @processor.root.size
|
53
|
+
assert @processor.widgets_flushed?
|
54
|
+
end
|
55
|
+
|
56
|
+
should "wipe-out our session variables" do
|
57
|
+
assert_nil @session[:apotomo_stateful_branches]
|
58
|
+
assert_nil @session[:apotomo_widget_ivars]
|
59
|
+
end
|
60
|
+
|
61
|
+
should ""
|
62
|
+
end
|
63
|
+
|
64
|
+
context "and with stateless widgets" do
|
65
|
+
setup do
|
66
|
+
@session = {:apotomo_stateful_branches => [[@mum, 'grandma']]}
|
67
|
+
@processor = Apotomo::RequestProcessor.new(@session, {}, [Proc.new { |root| root << Apotomo::Widget.new('grandma', :eating) }])
|
68
|
+
end
|
69
|
+
|
70
|
+
should "first attach passed stateless, then stateful widgets to root" do
|
71
|
+
assert_equal 4, @processor.root.size
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
end
|
77
|
+
|
78
|
+
context "#process_for" do
|
79
|
+
setup do
|
80
|
+
### FIXME: what about that automatic @controller everywhere?
|
81
|
+
mum_and_kid!
|
82
|
+
@mum.controller = nil # check if controller gets connected.
|
83
|
+
@processor = Apotomo::RequestProcessor.new({:apotomo_stateful_branches => [[@mum, 'root']]}, :js_framework => :prototype)
|
84
|
+
|
85
|
+
|
86
|
+
|
87
|
+
|
88
|
+
|
89
|
+
@kid.respond_to_event :doorSlam, :with => :eating, :on => 'mum'
|
90
|
+
@kid.respond_to_event :doorSlam, :with => :squeak
|
91
|
+
@mum.respond_to_event :doorSlam, :with => :squeak
|
92
|
+
|
93
|
+
@mum.instance_eval do
|
94
|
+
def squeak; render :js => 'squeak();'; end
|
95
|
+
end
|
96
|
+
@kid.instance_eval do
|
97
|
+
def squeak; render :text => 'squeak!', :update => :true; end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
should "return 2 page_updates when @kid squeaks" do
|
102
|
+
res = @processor.process_for({:type => :squeak, :source => 'kid'}, @controller)
|
103
|
+
|
104
|
+
assert_equal ["alert!", "squeak"], res
|
105
|
+
end
|
106
|
+
|
107
|
+
should "raise an exception when :source is unknown" do
|
108
|
+
assert_raises RuntimeError do
|
109
|
+
@processor.process_for({:type => :squeak, :source => 'tom'}, @controller)
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
|
115
|
+
|
116
|
+
context "#freeze!" do
|
117
|
+
should "serialize stateful branches to @session" do
|
118
|
+
@processor = Apotomo::RequestProcessor.new({})
|
119
|
+
@processor.root << mum_and_kid!
|
120
|
+
assert_equal 3, @processor.root.size
|
121
|
+
@processor.freeze!
|
122
|
+
|
123
|
+
@processor = Apotomo::RequestProcessor.new(@processor.session)
|
124
|
+
assert_equal 3, @processor.root.size
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
context "#render_widget_for" do
|
129
|
+
setup do
|
130
|
+
@mum = mouse_mock('mum', :snuggle) do
|
131
|
+
def snuggle; render; end
|
132
|
+
end
|
133
|
+
@mum.controller = nil
|
134
|
+
|
135
|
+
@processor = Apotomo::RequestProcessor.new({:apotomo_stateful_branches => [[@mum, 'root']]})
|
136
|
+
end
|
137
|
+
|
138
|
+
should "render the widget when passing an existing widget id" do
|
139
|
+
assert_equal '<div id="mum"><snuggle></snuggle></div>', @processor.render_widget_for('mum', {}, @controller)
|
140
|
+
end
|
141
|
+
|
142
|
+
should "render the widget when passing an existing widget instance" do
|
143
|
+
assert_equal '<div id="mum"><snuggle></snuggle></div>', @processor.render_widget_for(@mum, {}, @controller)
|
144
|
+
end
|
145
|
+
|
146
|
+
should "raise an exception when a non-existent widget id id passed" do
|
147
|
+
assert_raises RuntimeError do
|
148
|
+
@processor.render_widget_for('mummy', {}, @controller)
|
149
|
+
end
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
context "invoking #address_for" do
|
154
|
+
setup do
|
155
|
+
@processor = Apotomo::RequestProcessor.new({})
|
156
|
+
end
|
157
|
+
|
158
|
+
should "accept an event :type" do
|
159
|
+
assert_equal({:type => :squeak, :source => 'mum'}, @processor.address_for(:type => :squeak, :source => 'mum'))
|
160
|
+
end
|
161
|
+
|
162
|
+
should "accept arbitrary options" do
|
163
|
+
assert_equal({:type => :squeak, :volume => 'loud', :source => 'mum'}, @processor.address_for(:type => :squeak, :volume => 'loud', :source => 'mum'))
|
164
|
+
end
|
165
|
+
|
166
|
+
should "complain if no type given" do
|
167
|
+
assert_raises RuntimeError do
|
168
|
+
@processor.address_for(:source => 'mum')
|
169
|
+
end
|
170
|
+
end
|
171
|
+
|
172
|
+
should "complain if no source given" do
|
173
|
+
assert_raises RuntimeError do
|
174
|
+
@processor.address_for(:type => :footsteps)
|
175
|
+
end
|
176
|
+
end
|
177
|
+
end
|
178
|
+
end
|
@@ -0,0 +1,135 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), '..', 'test_helper')
|
2
|
+
|
3
|
+
class StatefulWidgetTest < Test::Unit::TestCase
|
4
|
+
context "The StatefulWidget" do
|
5
|
+
setup do
|
6
|
+
@mum = Apotomo::StatefulWidget.new('mum', :squeak)
|
7
|
+
end
|
8
|
+
|
9
|
+
should "accept an id as first option" do
|
10
|
+
assert_equal 'mum', @mum.name
|
11
|
+
end
|
12
|
+
|
13
|
+
should "accept a start state as second option" do
|
14
|
+
assert_equal :squeak, @mum.instance_variable_get('@start_state')
|
15
|
+
end
|
16
|
+
|
17
|
+
should "respond to #version" do
|
18
|
+
assert_equal 0, mouse_mock.version
|
19
|
+
end
|
20
|
+
|
21
|
+
should "have a version setter" do
|
22
|
+
@mum = mouse_mock
|
23
|
+
@mum.version = 1
|
24
|
+
assert_equal 1, @mum.version
|
25
|
+
end
|
26
|
+
|
27
|
+
context "responding to #address_for_event" do
|
28
|
+
should "accept an event :type" do
|
29
|
+
assert_equal({:type => :squeak, :source => 'mum'}, @mum.address_for_event(:type => :squeak))
|
30
|
+
end
|
31
|
+
|
32
|
+
should "accept a :source" do
|
33
|
+
assert_equal({:type => :squeak, :source => 'kid'}, @mum.address_for_event(:type => :squeak, :source => 'kid'))
|
34
|
+
end
|
35
|
+
|
36
|
+
should "accept arbitrary options" do
|
37
|
+
assert_equal({:type => :squeak, :volume => 'loud', :source => 'mum'}, @mum.address_for_event(:type => :squeak, :volume => 'loud'))
|
38
|
+
end
|
39
|
+
|
40
|
+
should "complain if no type given" do
|
41
|
+
assert_raises RuntimeError do
|
42
|
+
@mum.address_for_event(:source => 'mum')
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
context "implementing visibility" do
|
48
|
+
should "per default respond to #visible?" do
|
49
|
+
assert @mum.visible?
|
50
|
+
end
|
51
|
+
|
52
|
+
should "expose a setter therefore" do
|
53
|
+
@mum.visible = false
|
54
|
+
assert_not @mum.visible?
|
55
|
+
end
|
56
|
+
|
57
|
+
context "in a widget family" do
|
58
|
+
setup do
|
59
|
+
@mum << @jerry = mouse_mock('jerry')
|
60
|
+
@mum << @berry = mouse_mock('berry')
|
61
|
+
end
|
62
|
+
|
63
|
+
should "per default return all #visible_children" do
|
64
|
+
assert_equal [@jerry, @berry], @mum.visible_children
|
65
|
+
assert_equal [], @jerry.visible_children
|
66
|
+
end
|
67
|
+
|
68
|
+
should "hide berry in #visible_children if he's invisible" do
|
69
|
+
@berry.visible = false
|
70
|
+
assert_equal [@jerry], @mum.visible_children
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
should "respond to #find_widget" do
|
76
|
+
mum_and_kid!
|
77
|
+
assert_not @mum.find_widget('pet')
|
78
|
+
assert @kid, @mum.find_widget('kid')
|
79
|
+
end
|
80
|
+
|
81
|
+
should "respond to the WidgetShortcuts methods, like #widget" do
|
82
|
+
assert_respond_to @mum, :widget
|
83
|
+
end
|
84
|
+
|
85
|
+
context "with initialize_hooks" do
|
86
|
+
should "expose its class_inheritable_array with #initialize_hooks" do
|
87
|
+
@mum = mouse_class_mock.new('mum', :eating)
|
88
|
+
@mum.class.instance_eval { self.initialize_hooks << :initialize_mouse }
|
89
|
+
assert ::Apotomo::StatefulWidget.initialize_hooks.size + 1 == @mum.class.initialize_hooks.size
|
90
|
+
end
|
91
|
+
|
92
|
+
should "execute the initialize_hooks in the correct order in #process_initialize_hooks" do
|
93
|
+
@mum = mouse_class_mock.new('mum', :eating)
|
94
|
+
@mum.class.instance_eval do
|
95
|
+
define_method(:executed) { |*args| @executed ||= [] }
|
96
|
+
define_method(:setup) { |*args| executed << :setup }
|
97
|
+
define_method(:configure) { |*args| executed << :configure }
|
98
|
+
initialize_hooks << :setup
|
99
|
+
initialize_hooks << :configure
|
100
|
+
end
|
101
|
+
|
102
|
+
assert_equal [:setup, :configure], @mum.class.new('zombie', nil).executed
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
context "mum having a family" do
|
108
|
+
setup do
|
109
|
+
mum_and_kid!
|
110
|
+
@mum << @berry = mouse_mock('berry')
|
111
|
+
@berry << @pet = mouse_mock('pet')
|
112
|
+
end
|
113
|
+
|
114
|
+
context "responding to #render_children" do
|
115
|
+
should "return an OrderedHash for the rendered kids" do
|
116
|
+
kids = @mum.render_children
|
117
|
+
assert_kind_of ::ActiveSupport::OrderedHash, kids
|
118
|
+
assert_equal 2, kids.size
|
119
|
+
end
|
120
|
+
|
121
|
+
should "return an OrderedHash even if there are no kids" do
|
122
|
+
kids = @kid.render_children
|
123
|
+
assert_kind_of ::ActiveSupport::OrderedHash, kids
|
124
|
+
assert_equal 0, kids.size
|
125
|
+
end
|
126
|
+
|
127
|
+
should "return an empty OrderedHash when all kids are invisible" do
|
128
|
+
@pet.visible = false
|
129
|
+
kids = @berry.render_children
|
130
|
+
assert_kind_of ::ActiveSupport::OrderedHash, kids
|
131
|
+
assert_equal 0, kids.size
|
132
|
+
end
|
133
|
+
end
|
134
|
+
end
|
135
|
+
end
|