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.
@@ -21,11 +21,11 @@ require 'apotomo/rails/view_methods'
21
21
  end
22
22
 
23
23
  module ClassMethods
24
- def uses_widgets(&block)
24
+ def has_widgets(&block)
25
25
  uses_widgets_blocks << block
26
26
  end
27
27
 
28
- alias_method :has_widgets, :uses_widgets
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, self, &block)
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]}, self)
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 => @cell.name
69
- @controller.url_for_event(type, options)
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
- def widget_div(*args, &block)
91
- content_tag(:div, :id => @cell.name, :class => :widget, &block)
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
- uses_widgets_blocks.each { |blk| blk.call(@root) } # add stateless widgets.
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, controller)
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, controller, &block)
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
 
@@ -8,7 +8,7 @@ module TreeNode
8
8
  attr_writer :content, :parent
9
9
 
10
10
  def self.included(base)
11
- base.initialize_hooks << :initialize_tree_node_for
11
+ base.after_initialize :initialize_tree_node_for
12
12
  end
13
13
 
14
14
  # Constructor which expects the name of the node
@@ -1,5 +1,5 @@
1
1
  # encoding: utf-8
2
2
 
3
3
  module Apotomo
4
- VERSION = '0.1.1'
5
- end
4
+ VERSION = '0.1.2'
5
+ end
@@ -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
- self.initialize_hooks << :add_has_widgets_blocks
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.to_s.classify.constantize.new(id, state, *args)
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 class="widget" id="mum">squeak!</div>', widget_div { "squeak!" }
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
@@ -1,4 +1,5 @@
1
1
  # wycats says...
2
+ require 'rubygems'
2
3
  require 'bundler'
3
4
  Bundler.setup
4
5
 
@@ -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'}, @controller)
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'}, @controller)
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', {}, @controller)
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, {}, @controller)
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', {}, @controller)
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')
@@ -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: 25
4
+ hash: 31
5
5
  prerelease: false
6
6
  segments:
7
7
  - 0
8
8
  - 1
9
- - 1
10
- version: 0.1.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-08-24 00:00:00 +02:00
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/unit/onfire_integration_test.rb
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/request_processor_test.rb
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/stateful_widget_test.rb
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/unit/onfire_integration_test.rb
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/request_processor_test.rb
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/stateful_widget_test.rb
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