apotomo 0.1.1 → 0.1.2
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/lib/apotomo/rails/controller_methods.rb +5 -5
- data/lib/apotomo/rails/view_helper.rb +22 -8
- data/lib/apotomo/request_processor.rb +16 -10
- data/lib/apotomo/tree_node.rb +1 -1
- data/lib/apotomo/version.rb +2 -2
- data/lib/apotomo/widget.rb +30 -16
- data/lib/apotomo/widget_shortcuts.rb +10 -1
- data/test/rails/view_helper_test.rb +23 -1
- data/test/test_helper.rb +1 -0
- data/test/unit/request_processor_test.rb +39 -16
- data/test/unit/stateful_widget_test.rb +0 -79
- data/test/unit/widget_shortcuts_test.rb +12 -0
- data/test/unit/widget_test.rb +96 -0
- metadata +39 -39
@@ -21,11 +21,11 @@ require 'apotomo/rails/view_methods'
|
|
21
21
|
end
|
22
22
|
|
23
23
|
module ClassMethods
|
24
|
-
def
|
24
|
+
def has_widgets(&block)
|
25
25
|
uses_widgets_blocks << block
|
26
26
|
end
|
27
27
|
|
28
|
-
alias_method :
|
28
|
+
alias_method :uses_widgets, :has_widgets
|
29
29
|
end
|
30
30
|
|
31
31
|
def bound_use_widgets_blocks
|
@@ -45,7 +45,7 @@ require 'apotomo/rails/view_methods'
|
|
45
45
|
:js_framework => Apotomo.js_framework || :prototype,
|
46
46
|
} ### TODO: process rails options (flush_tree, version)
|
47
47
|
|
48
|
-
@apotomo_request_processor = Apotomo::RequestProcessor.new(session, options, self.class.uses_widgets_blocks)
|
48
|
+
@apotomo_request_processor = Apotomo::RequestProcessor.new(self, session, options, self.class.uses_widgets_blocks)
|
49
49
|
|
50
50
|
flush_bound_use_widgets_blocks if @apotomo_request_processor.widgets_flushed?
|
51
51
|
|
@@ -80,7 +80,7 @@ require 'apotomo/rails/view_methods'
|
|
80
80
|
|
81
81
|
|
82
82
|
def render_widget(widget, options={}, &block)
|
83
|
-
apotomo_request_processor.render_widget_for(widget, options,
|
83
|
+
apotomo_request_processor.render_widget_for(widget, options, &block)
|
84
84
|
end
|
85
85
|
|
86
86
|
def apotomo_freeze
|
@@ -88,7 +88,7 @@ require 'apotomo/rails/view_methods'
|
|
88
88
|
end
|
89
89
|
|
90
90
|
def render_event_response
|
91
|
-
page_updates = apotomo_request_processor.process_for({:type => params[:type], :source => params[:source]}
|
91
|
+
page_updates = apotomo_request_processor.process_for({:type => params[:type], :source => params[:source]})
|
92
92
|
|
93
93
|
return render_iframe_updates(page_updates) if params[:apotomo_iframe]
|
94
94
|
|
@@ -38,10 +38,6 @@ module Apotomo
|
|
38
38
|
return multipart_form_to_event(type, options, html_options, &block) if options.delete(:multipart)
|
39
39
|
|
40
40
|
form_remote_tag({:url => url_for_event(type, options), :html => html_options}, &block)
|
41
|
-
### FIXME: couldn't get obstrusive js working, i don't understand rails helpers.
|
42
|
-
#html_options[:onSubmit] = js_generator.escape(js_generator.xhr(url_for_event(type, options)))
|
43
|
-
#puts html_options.inspect
|
44
|
-
#form_tag(url_for_event(type, options), html_options, &block)
|
45
41
|
end
|
46
42
|
|
47
43
|
# Creates a form that submits itself via an iFrame and executes the response
|
@@ -65,8 +61,8 @@ module Apotomo
|
|
65
61
|
# url_for_event(:paginate, :page => 2)
|
66
62
|
# #=> http://apotomo.de/mouse/process_event_request?type=paginate&source=mouse&page=2
|
67
63
|
def url_for_event(type, options={})
|
68
|
-
options.reverse_merge! :source =>
|
69
|
-
|
64
|
+
options.reverse_merge! :source => widget_id
|
65
|
+
controller.url_for_event(type, options)
|
70
66
|
end
|
71
67
|
|
72
68
|
### TODO: test me.
|
@@ -87,8 +83,26 @@ module Apotomo
|
|
87
83
|
javascript_tag(*args, &block)
|
88
84
|
end
|
89
85
|
|
90
|
-
|
91
|
-
|
86
|
+
# Wraps your content in a +div+ and sets the id. Feel free to pass additional html options.
|
87
|
+
#
|
88
|
+
# Example:
|
89
|
+
#
|
90
|
+
# - widget_div do
|
91
|
+
# %p I'm wrapped
|
92
|
+
#
|
93
|
+
# will render
|
94
|
+
#
|
95
|
+
# <div id="mouse">
|
96
|
+
# <p>I'm wrapped</p>
|
97
|
+
# </div>
|
98
|
+
def widget_div(options={}, &block)
|
99
|
+
options.reverse_merge!(:id => widget_id)
|
100
|
+
content_tag(:div, options, &block)
|
101
|
+
end
|
102
|
+
|
103
|
+
# Returns the widget id you passed in a has_widgets block.
|
104
|
+
def widget_id
|
105
|
+
@cell.name
|
92
106
|
end
|
93
107
|
end
|
94
108
|
end
|
@@ -4,12 +4,14 @@ module Apotomo
|
|
4
4
|
|
5
5
|
attr_reader :session, :root
|
6
6
|
|
7
|
-
def initialize(session, options={}, uses_widgets_blocks=[])
|
7
|
+
def initialize(controller, session, options={}, uses_widgets_blocks=[])
|
8
8
|
@session = session
|
9
9
|
@widgets_flushed = false
|
10
10
|
|
11
11
|
@root = widget('apotomo/widget', 'root')
|
12
|
-
|
12
|
+
@root.controller = controller
|
13
|
+
|
14
|
+
attach_stateless_blocks_for(uses_widgets_blocks, @root, controller)
|
13
15
|
|
14
16
|
if options[:flush_widgets].blank? and ::Apotomo::StatefulWidget.frozen_widget_in?(session)
|
15
17
|
@root = ::Apotomo::StatefulWidget.thaw_for(session, @root)
|
@@ -22,6 +24,16 @@ module Apotomo
|
|
22
24
|
#handle_version!(options[:version])
|
23
25
|
end
|
24
26
|
|
27
|
+
def attach_stateless_blocks_for(blocks, root, controller)
|
28
|
+
blocks.each do |blk|
|
29
|
+
if blk.arity == 1
|
30
|
+
blk.call(root) and next # fixes misbehaviour in ruby 1.8.
|
31
|
+
end
|
32
|
+
|
33
|
+
blk.call(root, controller)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
25
37
|
|
26
38
|
def flushed_root
|
27
39
|
StatefulWidget.flush_storage(session)
|
@@ -41,10 +53,7 @@ module Apotomo
|
|
41
53
|
def widgets_flushed?; @widgets_flushed; end
|
42
54
|
|
43
55
|
# Fires the request event in the widget tree and collects the rendered page updates.
|
44
|
-
def process_for(request_params
|
45
|
-
### TODO: move controller dependency to rails/merb/sinatra layer only!
|
46
|
-
self.root.controller = controller
|
47
|
-
|
56
|
+
def process_for(request_params)
|
48
57
|
source = self.root.find_widget(request_params[:source]) or raise "Source #{request_params[:source].inspect} non-existent."
|
49
58
|
|
50
59
|
source.fire(request_params[:type].to_sym)
|
@@ -64,7 +73,7 @@ module Apotomo
|
|
64
73
|
|
65
74
|
# Renders the widget named <tt>widget_id</tt>, passing optional <tt>opts</tt> and a block to it.
|
66
75
|
# Use this in your #render_widget wrapper.
|
67
|
-
def render_widget_for(widget_id, opts,
|
76
|
+
def render_widget_for(widget_id, opts, &block)
|
68
77
|
if widget_id.kind_of?(::Apotomo::Widget)
|
69
78
|
widget = widget_id
|
70
79
|
else
|
@@ -76,9 +85,6 @@ module Apotomo
|
|
76
85
|
### TODO: pass options in invoke.
|
77
86
|
widget.opts = opts unless opts.empty?
|
78
87
|
|
79
|
-
### TODO: move controller dependency to rails/merb/sinatra layer only!
|
80
|
-
widget.root.controller = controller
|
81
|
-
|
82
88
|
widget.invoke(&block)
|
83
89
|
end
|
84
90
|
|
data/lib/apotomo/tree_node.rb
CHANGED
data/lib/apotomo/version.rb
CHANGED
data/lib/apotomo/widget.rb
CHANGED
@@ -24,21 +24,6 @@ module Apotomo
|
|
24
24
|
attr_accessor :opts
|
25
25
|
attr_writer :visible
|
26
26
|
|
27
|
-
include TreeNode
|
28
|
-
|
29
|
-
|
30
|
-
include Onfire
|
31
|
-
include EventMethods
|
32
|
-
|
33
|
-
include Transition
|
34
|
-
include Caching
|
35
|
-
|
36
|
-
include DeepLinkMethods
|
37
|
-
include WidgetShortcuts
|
38
|
-
|
39
|
-
helper Apotomo::Rails::ViewHelper
|
40
|
-
|
41
|
-
|
42
27
|
attr_writer :controller
|
43
28
|
attr_accessor :version
|
44
29
|
|
@@ -55,12 +40,41 @@ module Apotomo
|
|
55
40
|
def has_widgets(&block)
|
56
41
|
has_widgets_blocks << block
|
57
42
|
end
|
43
|
+
|
44
|
+
# Use this for setup code you're calling in every state. Almost like a +before_filter+ except that it's
|
45
|
+
# invoked after the initialization in #has_widgets.
|
46
|
+
#
|
47
|
+
# Example:
|
48
|
+
#
|
49
|
+
# class MouseWidget < Apotomo::Widget
|
50
|
+
# after_initialize :setup_cheese
|
51
|
+
#
|
52
|
+
# # we need @cheese in every state:
|
53
|
+
# def setup_cheese(*)
|
54
|
+
# @cheese = Cheese.find @opts[:cheese_id]
|
55
|
+
def after_initialize(method)
|
56
|
+
self.initialize_hooks << method
|
57
|
+
end
|
58
58
|
end
|
59
|
-
|
59
|
+
|
60
|
+
include TreeNode
|
61
|
+
|
62
|
+
include Onfire
|
63
|
+
include EventMethods
|
64
|
+
|
65
|
+
include Transition
|
66
|
+
include Caching
|
67
|
+
|
68
|
+
include DeepLinkMethods
|
69
|
+
include WidgetShortcuts
|
70
|
+
|
71
|
+
helper Apotomo::Rails::ViewHelper
|
72
|
+
|
60
73
|
|
61
74
|
def add_has_widgets_blocks(*)
|
62
75
|
self.class.has_widgets_blocks.each { |block| block.call(self) }
|
63
76
|
end
|
77
|
+
after_initialize :add_has_widgets_blocks
|
64
78
|
|
65
79
|
|
66
80
|
# Constructor which needs a unique id for the widget and one or multiple start states.
|
@@ -7,8 +7,12 @@ module Apotomo
|
|
7
7
|
# Example:
|
8
8
|
# widget(:form, 'uploads', :build_form) do |form|
|
9
9
|
# form << widget(:upload_field)
|
10
|
+
#
|
11
|
+
# You can also use namespaces.
|
12
|
+
#
|
13
|
+
# widget('jquery/tabs', 'panel')
|
10
14
|
def widget(class_name, id, state=:display, *args)
|
11
|
-
object = class_name.
|
15
|
+
object = constant_for(class_name).new(id, state, *args)
|
12
16
|
yield object if block_given?
|
13
17
|
object
|
14
18
|
end
|
@@ -32,5 +36,10 @@ module Apotomo
|
|
32
36
|
def tab(id, *args)
|
33
37
|
widget('apotomo/tab_widget', :display, id, *args)
|
34
38
|
end
|
39
|
+
|
40
|
+
private
|
41
|
+
def constant_for(class_name)
|
42
|
+
class_name.to_s.camelize.constantize
|
43
|
+
end
|
35
44
|
end
|
36
45
|
end
|
@@ -52,7 +52,15 @@ class ViewHelperTest < ActionView::TestCase
|
|
52
52
|
end
|
53
53
|
|
54
54
|
should "respond to #widget_div" do
|
55
|
-
assert_equal '<div
|
55
|
+
assert_equal '<div id="mum">squeak!</div>', widget_div { "squeak!" }
|
56
|
+
end
|
57
|
+
|
58
|
+
should "respond to #widget_div with options" do
|
59
|
+
assert_equal '<div class="mouse" id="kid">squeak!</div>', widget_div(:id => 'kid', :class => "mouse") { "squeak!" }
|
60
|
+
end
|
61
|
+
|
62
|
+
should "respond to #widget_id" do
|
63
|
+
assert_equal 'mum', widget_id
|
56
64
|
end
|
57
65
|
|
58
66
|
context "#widget_javascript" do
|
@@ -74,4 +82,18 @@ class ViewHelperTest < ActionView::TestCase
|
|
74
82
|
end
|
75
83
|
end
|
76
84
|
end
|
85
|
+
|
86
|
+
context "A widget including ViewHelper" do
|
87
|
+
setup do
|
88
|
+
barn_controller!
|
89
|
+
@mum = mouse_mock
|
90
|
+
@mum.class_eval do
|
91
|
+
include Apotomo::Rails::ViewHelper
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
should "respond to url_for_event" do
|
96
|
+
@mum.url_for_event(:bla)
|
97
|
+
end
|
98
|
+
end
|
77
99
|
end
|
data/test/test_helper.rb
CHANGED
@@ -3,17 +3,35 @@ require File.join(File.dirname(__FILE__), *%w[.. test_helper])
|
|
3
3
|
class RequestProcessorTest < Test::Unit::TestCase
|
4
4
|
context "#root" do
|
5
5
|
should "allow external modification of the tree" do
|
6
|
-
@processor = Apotomo::RequestProcessor.new({})
|
6
|
+
@processor = Apotomo::RequestProcessor.new(nil, {})
|
7
7
|
root = @processor.root
|
8
8
|
root << mouse_mock
|
9
9
|
assert_equal 2, @processor.root.size
|
10
10
|
end
|
11
11
|
end
|
12
|
+
|
13
|
+
context "#attach_stateless_blocks_for" do
|
14
|
+
setup do
|
15
|
+
@processor = Apotomo::RequestProcessor.new("controller", {})
|
16
|
+
@root = @processor.root
|
17
|
+
@controller = "yo"
|
18
|
+
end
|
19
|
+
|
20
|
+
should "allow has_widgets blocks with root parameter, only" do
|
21
|
+
@processor.send(:attach_stateless_blocks_for, [Proc.new{ |root| root.add mouse_mock }], @root, @controller)
|
22
|
+
assert_equal 'mouse', @processor.root['mouse'].name
|
23
|
+
end
|
24
|
+
|
25
|
+
should "allow has_widgets blocks with both root and controller parameter" do
|
26
|
+
@processor.send(:attach_stateless_blocks_for, [Proc.new{ |root,controller| root.add mouse_mock }], @root, @controller)
|
27
|
+
assert_equal 'mouse', @processor.root['mouse'].name
|
28
|
+
end
|
29
|
+
end
|
12
30
|
|
13
31
|
context "option processing at construction time" do
|
14
32
|
context "with empty session and options" do
|
15
33
|
setup do
|
16
|
-
@processor = Apotomo::RequestProcessor.new({})
|
34
|
+
@processor = Apotomo::RequestProcessor.new(nil, {})
|
17
35
|
end
|
18
36
|
|
19
37
|
should "mark the tree as flushed" do
|
@@ -29,12 +47,18 @@ class RequestProcessorTest < Test::Unit::TestCase
|
|
29
47
|
end
|
30
48
|
end
|
31
49
|
|
50
|
+
context "with controller" do
|
51
|
+
should "attach the passed controller to root" do
|
52
|
+
assert_equal "controller", Apotomo::RequestProcessor.new("controller", {}, {}, []).root.controller
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
32
56
|
context "with session" do
|
33
57
|
setup do
|
34
58
|
mum_and_kid!
|
35
59
|
@mum.version = 1
|
36
60
|
@session = {:apotomo_stateful_branches => [[@mum, 'root']]}
|
37
|
-
@processor = Apotomo::RequestProcessor.new(@session)
|
61
|
+
@processor = Apotomo::RequestProcessor.new(nil, @session)
|
38
62
|
end
|
39
63
|
|
40
64
|
should "provide a widget family for #root" do
|
@@ -45,7 +69,7 @@ class RequestProcessorTest < Test::Unit::TestCase
|
|
45
69
|
|
46
70
|
context "having a flush flag set" do
|
47
71
|
setup do
|
48
|
-
@processor = Apotomo::RequestProcessor.new(@session, :flush_widgets => true)
|
72
|
+
@processor = Apotomo::RequestProcessor.new(nil, @session, :flush_widgets => true)
|
49
73
|
end
|
50
74
|
|
51
75
|
should "provide a single root for #root when :flush_widgets is set" do
|
@@ -58,13 +82,12 @@ class RequestProcessorTest < Test::Unit::TestCase
|
|
58
82
|
assert_nil @session[:apotomo_widget_ivars]
|
59
83
|
end
|
60
84
|
|
61
|
-
should ""
|
62
85
|
end
|
63
86
|
|
64
87
|
context "and with stateless widgets" do
|
65
88
|
setup do
|
66
89
|
@session = {:apotomo_stateful_branches => [[@mum, 'grandma']]}
|
67
|
-
@processor = Apotomo::RequestProcessor.new(@session, {}, [Proc.new { |root| root << Apotomo::Widget.new('grandma', :eating) }])
|
90
|
+
@processor = Apotomo::RequestProcessor.new(nil, @session, {}, [Proc.new { |root| root << Apotomo::Widget.new('grandma', :eating) }])
|
68
91
|
end
|
69
92
|
|
70
93
|
should "first attach passed stateless, then stateful widgets to root" do
|
@@ -80,7 +103,7 @@ class RequestProcessorTest < Test::Unit::TestCase
|
|
80
103
|
### FIXME: what about that automatic @controller everywhere?
|
81
104
|
mum_and_kid!
|
82
105
|
@mum.controller = nil # check if controller gets connected.
|
83
|
-
@processor = Apotomo::RequestProcessor.new({:apotomo_stateful_branches => [[@mum, 'root']]}, :js_framework => :prototype)
|
106
|
+
@processor = Apotomo::RequestProcessor.new(nil, {:apotomo_stateful_branches => [[@mum, 'root']]}, :js_framework => :prototype)
|
84
107
|
|
85
108
|
|
86
109
|
|
@@ -99,14 +122,14 @@ class RequestProcessorTest < Test::Unit::TestCase
|
|
99
122
|
end
|
100
123
|
|
101
124
|
should "return 2 page_updates when @kid squeaks" do
|
102
|
-
res = @processor.process_for({:type => :squeak, :source => 'kid'}
|
125
|
+
res = @processor.process_for({:type => :squeak, :source => 'kid'})
|
103
126
|
|
104
127
|
assert_equal ["alert!", "squeak"], res
|
105
128
|
end
|
106
129
|
|
107
130
|
should "raise an exception when :source is unknown" do
|
108
131
|
assert_raises RuntimeError do
|
109
|
-
@processor.process_for({:type => :squeak, :source => 'tom'}
|
132
|
+
@processor.process_for({:type => :squeak, :source => 'tom'})
|
110
133
|
end
|
111
134
|
end
|
112
135
|
end
|
@@ -115,12 +138,12 @@ class RequestProcessorTest < Test::Unit::TestCase
|
|
115
138
|
|
116
139
|
context "#freeze!" do
|
117
140
|
should "serialize stateful branches to @session" do
|
118
|
-
@processor = Apotomo::RequestProcessor.new({})
|
141
|
+
@processor = Apotomo::RequestProcessor.new(nil, {})
|
119
142
|
@processor.root << mum_and_kid!
|
120
143
|
assert_equal 3, @processor.root.size
|
121
144
|
@processor.freeze!
|
122
145
|
|
123
|
-
@processor = Apotomo::RequestProcessor.new(@processor.session)
|
146
|
+
@processor = Apotomo::RequestProcessor.new(nil, @processor.session)
|
124
147
|
assert_equal 3, @processor.root.size
|
125
148
|
end
|
126
149
|
end
|
@@ -132,27 +155,27 @@ class RequestProcessorTest < Test::Unit::TestCase
|
|
132
155
|
end
|
133
156
|
@mum.controller = nil
|
134
157
|
|
135
|
-
@processor = Apotomo::RequestProcessor.new({:apotomo_stateful_branches => [[@mum, 'root']]})
|
158
|
+
@processor = Apotomo::RequestProcessor.new(nil, {:apotomo_stateful_branches => [[@mum, 'root']]})
|
136
159
|
end
|
137
160
|
|
138
161
|
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', {}
|
162
|
+
assert_equal '<div id="mum"><snuggle></snuggle></div>', @processor.render_widget_for('mum', {})
|
140
163
|
end
|
141
164
|
|
142
165
|
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, {}
|
166
|
+
assert_equal '<div id="mum"><snuggle></snuggle></div>', @processor.render_widget_for(@mum, {})
|
144
167
|
end
|
145
168
|
|
146
169
|
should "raise an exception when a non-existent widget id id passed" do
|
147
170
|
assert_raises RuntimeError do
|
148
|
-
@processor.render_widget_for('mummy', {}
|
171
|
+
@processor.render_widget_for('mummy', {})
|
149
172
|
end
|
150
173
|
end
|
151
174
|
end
|
152
175
|
|
153
176
|
context "invoking #address_for" do
|
154
177
|
setup do
|
155
|
-
@processor = Apotomo::RequestProcessor.new({})
|
178
|
+
@processor = Apotomo::RequestProcessor.new(nil, {})
|
156
179
|
end
|
157
180
|
|
158
181
|
should "accept an event :type" do
|
@@ -23,85 +23,6 @@ class StatefulWidgetTest < Test::Unit::TestCase
|
|
23
23
|
@mum.version = 1
|
24
24
|
assert_equal 1, @mum.version
|
25
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
26
|
end
|
106
27
|
|
107
28
|
context "mum having a family" do
|
@@ -1,8 +1,20 @@
|
|
1
1
|
require File.join(File.dirname(__FILE__), *%w[.. test_helper])
|
2
2
|
|
3
3
|
class MumWidget < MouseCell; end
|
4
|
+
class MouseTabs;end
|
4
5
|
|
5
6
|
class WidgetShortcutsTest < Test::Unit::TestCase
|
7
|
+
context "#constant_for" do
|
8
|
+
|
9
|
+
should "constantize symbols" do
|
10
|
+
assert_equal MumWidget, constant_for(:mum_widget)
|
11
|
+
end
|
12
|
+
|
13
|
+
should "not try to singularize the widget class" do
|
14
|
+
assert_equal MouseTabs, constant_for(:mouse_tabs)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
6
18
|
context "#cell" do
|
7
19
|
should "create a MouseCell instance for backward-compatibility" do
|
8
20
|
assert_kind_of MouseCell, cell(:mouse, :eating, 'mum')
|
data/test/unit/widget_test.rb
CHANGED
@@ -21,4 +21,100 @@ class WidgetTest < ActiveSupport::TestCase
|
|
21
21
|
assert_equal [], @kid.children
|
22
22
|
end
|
23
23
|
end
|
24
|
+
|
25
|
+
context "A stateless widget" do
|
26
|
+
setup do
|
27
|
+
@mum = Apotomo::Widget.new('mum', :squeak)
|
28
|
+
end
|
29
|
+
|
30
|
+
context "responding to #address_for_event" do
|
31
|
+
should "accept an event :type" do
|
32
|
+
assert_equal({:type => :squeak, :source => 'mum'}, @mum.address_for_event(:type => :squeak))
|
33
|
+
end
|
34
|
+
|
35
|
+
should "accept a :source" do
|
36
|
+
assert_equal({:type => :squeak, :source => 'kid'}, @mum.address_for_event(:type => :squeak, :source => 'kid'))
|
37
|
+
end
|
38
|
+
|
39
|
+
should "accept arbitrary options" do
|
40
|
+
assert_equal({:type => :squeak, :volume => 'loud', :source => 'mum'}, @mum.address_for_event(:type => :squeak, :volume => 'loud'))
|
41
|
+
end
|
42
|
+
|
43
|
+
should "complain if no type given" do
|
44
|
+
assert_raises RuntimeError do
|
45
|
+
@mum.address_for_event(:source => 'mum')
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
context "implementing visibility" do
|
51
|
+
should "per default respond to #visible?" do
|
52
|
+
assert @mum.visible?
|
53
|
+
end
|
54
|
+
|
55
|
+
should "expose a setter therefore" do
|
56
|
+
@mum.visible = false
|
57
|
+
assert_not @mum.visible?
|
58
|
+
end
|
59
|
+
|
60
|
+
context "in a widget family" do
|
61
|
+
setup do
|
62
|
+
@mum << @jerry = mouse_mock('jerry')
|
63
|
+
@mum << @berry = mouse_mock('berry')
|
64
|
+
end
|
65
|
+
|
66
|
+
should "per default return all #visible_children" do
|
67
|
+
assert_equal [@jerry, @berry], @mum.visible_children
|
68
|
+
assert_equal [], @jerry.visible_children
|
69
|
+
end
|
70
|
+
|
71
|
+
should "hide berry in #visible_children if he's invisible" do
|
72
|
+
@berry.visible = false
|
73
|
+
assert_equal [@jerry], @mum.visible_children
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
should "respond to #find_widget" do
|
79
|
+
mum_and_kid!
|
80
|
+
assert_not @mum.find_widget('pet')
|
81
|
+
assert @kid, @mum.find_widget('kid')
|
82
|
+
end
|
83
|
+
|
84
|
+
should "respond to the WidgetShortcuts methods, like #widget" do
|
85
|
+
assert_respond_to @mum, :widget
|
86
|
+
end
|
87
|
+
|
88
|
+
context "with initialize_hooks" do
|
89
|
+
should "expose its class_inheritable_array with #initialize_hooks" do
|
90
|
+
@mum = mouse_class_mock.new('mum', :eating)
|
91
|
+
@mum.class.instance_eval { self.initialize_hooks << :initialize_mouse }
|
92
|
+
assert ::Apotomo::StatefulWidget.initialize_hooks.size + 1 == @mum.class.initialize_hooks.size
|
93
|
+
end
|
94
|
+
|
95
|
+
should "execute the initialize_hooks in the correct order in #process_initialize_hooks" do
|
96
|
+
@mum = mouse_class_mock.new('mum', :eating)
|
97
|
+
@mum.class.instance_eval do
|
98
|
+
define_method(:executed) { |*args| @executed ||= [] }
|
99
|
+
define_method(:setup) { |*args| executed << :setup }
|
100
|
+
define_method(:configure) { |*args| executed << :configure }
|
101
|
+
initialize_hooks << :setup
|
102
|
+
initialize_hooks << :configure
|
103
|
+
end
|
104
|
+
|
105
|
+
assert_equal [:setup, :configure], @mum.class.new('zombie', nil).executed
|
106
|
+
end
|
107
|
+
|
108
|
+
should "provide after_initialize" do
|
109
|
+
@mum = mouse_class_mock.new('mum', :eat)
|
110
|
+
@mum.class.instance_eval do
|
111
|
+
after_initialize :first
|
112
|
+
after_initialize :second
|
113
|
+
end
|
114
|
+
|
115
|
+
assert_equal @mum.class.initialize_hooks[-1], :second
|
116
|
+
assert_equal @mum.class.initialize_hooks[-2], :first
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
24
120
|
end
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: apotomo
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 31
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 1
|
9
|
-
-
|
10
|
-
version: 0.1.
|
9
|
+
- 2
|
10
|
+
version: 0.1.2
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Nick Sutterer
|
@@ -15,11 +15,12 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2010-
|
18
|
+
date: 2010-09-16 00:00:00 +02:00
|
19
19
|
default_executable:
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|
22
22
|
name: cells
|
23
|
+
prerelease: false
|
23
24
|
requirement: &id001 !ruby/object:Gem::Requirement
|
24
25
|
none: false
|
25
26
|
requirements:
|
@@ -31,10 +32,10 @@ dependencies:
|
|
31
32
|
- 3
|
32
33
|
version: "3.3"
|
33
34
|
type: :runtime
|
34
|
-
prerelease: false
|
35
35
|
version_requirements: *id001
|
36
36
|
- !ruby/object:Gem::Dependency
|
37
37
|
name: activesupport
|
38
|
+
prerelease: false
|
38
39
|
requirement: &id002 !ruby/object:Gem::Requirement
|
39
40
|
none: false
|
40
41
|
requirements:
|
@@ -47,10 +48,10 @@ dependencies:
|
|
47
48
|
- 0
|
48
49
|
version: 2.3.0
|
49
50
|
type: :runtime
|
50
|
-
prerelease: false
|
51
51
|
version_requirements: *id002
|
52
52
|
- !ruby/object:Gem::Dependency
|
53
53
|
name: onfire
|
54
|
+
prerelease: false
|
54
55
|
requirement: &id003 !ruby/object:Gem::Requirement
|
55
56
|
none: false
|
56
57
|
requirements:
|
@@ -63,7 +64,6 @@ dependencies:
|
|
63
64
|
- 0
|
64
65
|
version: 0.1.0
|
65
66
|
type: :runtime
|
66
|
-
prerelease: false
|
67
67
|
version_requirements: *id003
|
68
68
|
description: A generic widget framework for Rails. Event-driven. Clean. Fast. Free optional statefulness included.
|
69
69
|
email: apotonick@gmail.com
|
@@ -121,34 +121,34 @@ files:
|
|
121
121
|
- lib/apotomo/widget_shortcuts.rb
|
122
122
|
- rails/init.rb
|
123
123
|
- test/fixtures/application_widget_tree.rb
|
124
|
-
- test/test_helper.rb
|
125
|
-
- test/support/test_case_methods.rb
|
126
|
-
- test/support/assertions_helper.rb
|
127
|
-
- test/rails/rails_integration_test.rb
|
128
124
|
- test/rails/view_methods_test.rb
|
129
125
|
- test/rails/controller_methods_test.rb
|
130
126
|
- test/rails/view_helper_test.rb
|
131
127
|
- test/rails/widget_generator_test.rb
|
132
|
-
- test/
|
128
|
+
- test/rails/rails_integration_test.rb
|
129
|
+
- test/test_helper.rb
|
130
|
+
- test/support/assertions_helper.rb
|
131
|
+
- test/support/test_case_methods.rb
|
132
|
+
- test/unit/test_widget_shortcuts.rb
|
133
|
+
- test/unit/event_handler_test.rb
|
134
|
+
- test/unit/widget_shortcuts_test.rb
|
135
|
+
- test/unit/stateful_widget_test.rb
|
136
|
+
- test/unit/test_addressing.rb
|
133
137
|
- test/unit/invoke_test.rb
|
134
|
-
- test/unit/
|
138
|
+
- test/unit/container_test.rb
|
139
|
+
- test/unit/test_tab_panel.rb
|
140
|
+
- test/unit/test_jump_to_state.rb
|
135
141
|
- test/unit/render_test.rb
|
136
142
|
- test/unit/apotomo_test.rb
|
143
|
+
- test/unit/request_processor_test.rb
|
144
|
+
- test/unit/test_caching.rb
|
137
145
|
- test/unit/javascript_generator_test.rb
|
138
|
-
- test/unit/
|
139
|
-
- test/unit/event_methods_test.rb
|
146
|
+
- test/unit/onfire_integration_test.rb
|
140
147
|
- test/unit/persistence_test.rb
|
141
|
-
- test/unit/event_handler_test.rb
|
142
148
|
- test/unit/transition_test.rb
|
143
149
|
- test/unit/event_test.rb
|
150
|
+
- test/unit/event_methods_test.rb
|
144
151
|
- test/unit/widget_test.rb
|
145
|
-
- test/unit/widget_shortcuts_test.rb
|
146
|
-
- test/unit/test_caching.rb
|
147
|
-
- test/unit/test_widget_shortcuts.rb
|
148
|
-
- test/unit/test_tab_panel.rb
|
149
|
-
- test/unit/test_addressing.rb
|
150
|
-
- test/unit/container_test.rb
|
151
|
-
- test/unit/test_jump_to_state.rb
|
152
152
|
has_rdoc: true
|
153
153
|
homepage: http://apotomo.de
|
154
154
|
licenses: []
|
@@ -185,31 +185,31 @@ specification_version: 3
|
|
185
185
|
summary: Event-driven Widgets for Rails with optional Statefulness.
|
186
186
|
test_files:
|
187
187
|
- test/fixtures/application_widget_tree.rb
|
188
|
-
- test/test_helper.rb
|
189
|
-
- test/support/test_case_methods.rb
|
190
|
-
- test/support/assertions_helper.rb
|
191
|
-
- test/rails/rails_integration_test.rb
|
192
188
|
- test/rails/view_methods_test.rb
|
193
189
|
- test/rails/controller_methods_test.rb
|
194
190
|
- test/rails/view_helper_test.rb
|
195
191
|
- test/rails/widget_generator_test.rb
|
196
|
-
- test/
|
192
|
+
- test/rails/rails_integration_test.rb
|
193
|
+
- test/test_helper.rb
|
194
|
+
- test/support/assertions_helper.rb
|
195
|
+
- test/support/test_case_methods.rb
|
196
|
+
- test/unit/test_widget_shortcuts.rb
|
197
|
+
- test/unit/event_handler_test.rb
|
198
|
+
- test/unit/widget_shortcuts_test.rb
|
199
|
+
- test/unit/stateful_widget_test.rb
|
200
|
+
- test/unit/test_addressing.rb
|
197
201
|
- test/unit/invoke_test.rb
|
198
|
-
- test/unit/
|
202
|
+
- test/unit/container_test.rb
|
203
|
+
- test/unit/test_tab_panel.rb
|
204
|
+
- test/unit/test_jump_to_state.rb
|
199
205
|
- test/unit/render_test.rb
|
200
206
|
- test/unit/apotomo_test.rb
|
207
|
+
- test/unit/request_processor_test.rb
|
208
|
+
- test/unit/test_caching.rb
|
201
209
|
- test/unit/javascript_generator_test.rb
|
202
|
-
- test/unit/
|
203
|
-
- test/unit/event_methods_test.rb
|
210
|
+
- test/unit/onfire_integration_test.rb
|
204
211
|
- test/unit/persistence_test.rb
|
205
|
-
- test/unit/event_handler_test.rb
|
206
212
|
- test/unit/transition_test.rb
|
207
213
|
- test/unit/event_test.rb
|
214
|
+
- test/unit/event_methods_test.rb
|
208
215
|
- test/unit/widget_test.rb
|
209
|
-
- test/unit/widget_shortcuts_test.rb
|
210
|
-
- test/unit/test_caching.rb
|
211
|
-
- test/unit/test_widget_shortcuts.rb
|
212
|
-
- test/unit/test_tab_panel.rb
|
213
|
-
- test/unit/test_addressing.rb
|
214
|
-
- test/unit/container_test.rb
|
215
|
-
- test/unit/test_jump_to_state.rb
|