apotomo 0.1.2 → 0.1.3

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.
Files changed (47) hide show
  1. data/Gemfile +2 -1
  2. data/Gemfile.lock +3 -0
  3. data/Rakefile +6 -43
  4. data/lib/apotomo/event_methods.rb +1 -1
  5. data/lib/apotomo/rails/controller_methods.rb +4 -4
  6. data/lib/apotomo/request_processor.rb +2 -2
  7. data/lib/apotomo/test_methods.rb +8 -0
  8. data/lib/apotomo/tree_node.rb +5 -7
  9. data/lib/apotomo/version.rb +1 -1
  10. data/lib/apotomo/widget.rb +45 -48
  11. data/lib/apotomo.rb +1 -9
  12. data/test/rails/controller_methods_test.rb +8 -8
  13. data/test/rails/rails_integration_test.rb +2 -2
  14. data/test/rails/view_helper_test.rb +2 -3
  15. data/test/rails/view_methods_test.rb +2 -2
  16. data/test/rails/widget_generator_test.rb +2 -2
  17. data/test/unit/apotomo_test.rb +2 -2
  18. data/test/unit/container_test.rb +2 -2
  19. data/test/unit/event_handler_test.rb +1 -2
  20. data/test/unit/event_methods_test.rb +2 -2
  21. data/test/unit/event_test.rb +2 -2
  22. data/test/unit/invoke_test.rb +2 -2
  23. data/test/unit/javascript_generator_test.rb +2 -3
  24. data/test/unit/onfire_integration_test.rb +2 -2
  25. data/test/unit/persistence_test.rb +2 -2
  26. data/test/unit/render_test.rb +20 -2
  27. data/test/unit/request_processor_test.rb +2 -2
  28. data/test/unit/stateful_widget_test.rb +2 -2
  29. data/test/unit/test_addressing.rb +1 -2
  30. data/test/unit/test_caching.rb +1 -2
  31. data/test/unit/test_jump_to_state.rb +1 -1
  32. data/test/unit/test_methods_test.rb +11 -0
  33. data/test/unit/test_tab_panel.rb +1 -2
  34. data/test/unit/test_widget_shortcuts.rb +1 -2
  35. data/test/unit/transition_test.rb +2 -2
  36. data/test/unit/widget_shortcuts_test.rb +2 -2
  37. data/test/unit/widget_test.rb +35 -36
  38. metadata +22 -13
  39. data/app/cells/apotomo/child_switch_widget/switch.html.erb +0 -1
  40. data/app/cells/apotomo/child_switch_widget/switch.rhtml +0 -1
  41. data/app/cells/apotomo/deep_link_widget/setup.html.erb +0 -20
  42. data/app/cells/apotomo/deep_link_widget.rb +0 -27
  43. data/app/cells/apotomo/java_script_widget.rb +0 -12
  44. data/app/cells/apotomo/tab_panel_widget/display.html.erb +0 -57
  45. data/app/cells/apotomo/tab_panel_widget.rb +0 -87
  46. data/app/cells/apotomo/tab_widget/display.html.erb +0 -1
  47. data/app/cells/apotomo/tab_widget.rb +0 -18
data/Gemfile CHANGED
@@ -3,8 +3,9 @@ source "http://rubygems.org"
3
3
  gem "rails", "~> 2.3.8"
4
4
  gem "cells", "3.3.4"
5
5
  gem "onfire"
6
+ gem "hooks", "~> 0.1"
6
7
  gem "jeweler"
7
8
 
8
9
  # for test env:
9
10
  gem "shoulda"
10
- gem "mocha"
11
+ gem "mocha"
data/Gemfile.lock CHANGED
@@ -14,6 +14,8 @@ GEM
14
14
  cells (3.3.4)
15
15
  gemcutter (0.6.1)
16
16
  git (1.2.5)
17
+ hooks (0.1)
18
+ activesupport (>= 2.3.0)
17
19
  jeweler (1.4.0)
18
20
  gemcutter (>= 0.1.0)
19
21
  git (>= 1.2.5)
@@ -40,6 +42,7 @@ PLATFORMS
40
42
 
41
43
  DEPENDENCIES
42
44
  cells (= 3.3.4)
45
+ hooks (~> 0.1)
43
46
  jeweler
44
47
  mocha
45
48
  onfire
data/Rakefile CHANGED
@@ -5,59 +5,21 @@ require 'rake'
5
5
  require 'rake/testtask'
6
6
  require 'rake/rdoctask'
7
7
 
8
+ $:.unshift File.dirname(__FILE__)+"/lib" # add current dir to LOAD_PATHS
9
+
8
10
  desc 'Default: run unit tests.'
9
11
  task :default => :test
10
12
 
11
13
  desc 'Test the Apotomo plugin.'
12
14
  Rake::TestTask.new(:test) do |t|
13
- t.libs << 'lib'
15
+ t.libs << 'test'
14
16
  t.pattern = 'test/**/*_test.rb'
15
17
  t.verbose = true
16
18
  end
17
19
 
18
- namespace 'rdoc' do
19
- desc 'Generate documentation for Apotomo.'
20
- Rake::RDocTask.new(:build) do |rdoc|
21
- rdoc.rdoc_dir = 'rdoc'
22
- rdoc.title = 'Apotomo API'
23
- rdoc.options << '--line-numbers' << '--inline-source' << '-m README'
24
-
25
- rdoc.rdoc_files.include('lib/**/*.rb')
26
- rdoc.rdoc_files.include('app/**/*.rb')
27
- rdoc.rdoc_files.include('test/*.rb')
28
- rdoc.rdoc_files.include('README')
29
- end
30
-
31
- desc 'Upload the rdocs to apotomo.rubyforge.org.'
32
- task :upload do
33
- sh %{ scp -r rdoc nix@rubyforge.org:/var/www/gforge-projects/apotomo/ }
34
- end
35
- end
36
20
 
37
- # Gem managment tasks.
38
- #
39
- # == Bump gem version (any):
40
- #
41
- # rake version:bump:major
42
- # rake version:bump:minor
43
- # rake version:bump:patch
44
- #
45
- # == Generate gemspec, build & install locally:
46
- #
47
- # rake gemspec
48
- # rake build
49
- # sudo rake install
50
- #
51
- # == Git tag & push to origin/master
52
- #
53
- # rake release
54
- #
55
- # == Release to Gemcutter.org:
56
- #
57
- # rake gemcutter:release
58
- #
59
21
  require 'jeweler'
60
- require 'lib/apotomo/version'
22
+ require 'apotomo/version'
61
23
 
62
24
  Jeweler::Tasks.new do |spec|
63
25
  spec.name = "apotomo"
@@ -73,6 +35,7 @@ Jeweler::Tasks.new do |spec|
73
35
  spec.add_dependency 'cells', '~> 3.3'
74
36
  spec.add_dependency 'activesupport', '>= 2.3.0'
75
37
  spec.add_dependency 'onfire', '>= 0.1.0'
38
+ spec.add_dependency 'hooks', '~> 0.1'
76
39
  end
77
40
 
78
- Jeweler::GemcutterTasks.new
41
+ Jeweler::GemcutterTasks.new
@@ -12,7 +12,7 @@ module Apotomo
12
12
 
13
13
  def self.included(base)
14
14
  base.extend(ClassMethods)
15
- base.initialize_hooks << :add_class_event_handlers
15
+ base.after_initialize :add_class_event_handlers
16
16
  end
17
17
 
18
18
  def add_class_event_handlers(*)
@@ -11,8 +11,8 @@ require 'apotomo/rails/view_methods'
11
11
  extend WidgetShortcuts
12
12
  extend ClassMethods
13
13
 
14
- class_inheritable_array :uses_widgets_blocks
15
- self.uses_widgets_blocks = []
14
+ class_inheritable_array :has_widgets_blocks
15
+ self.has_widgets_blocks = []
16
16
 
17
17
  helper ::Apotomo::Rails::ViewMethods
18
18
 
@@ -22,7 +22,7 @@ require 'apotomo/rails/view_methods'
22
22
 
23
23
  module ClassMethods
24
24
  def has_widgets(&block)
25
- uses_widgets_blocks << block
25
+ has_widgets_blocks << block
26
26
  end
27
27
 
28
28
  alias_method :uses_widgets, :has_widgets
@@ -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(self, session, options, self.class.uses_widgets_blocks)
48
+ @apotomo_request_processor = Apotomo::RequestProcessor.new(self, session, options, self.class.has_widgets_blocks)
49
49
 
50
50
  flush_bound_use_widgets_blocks if @apotomo_request_processor.widgets_flushed?
51
51
 
@@ -4,14 +4,14 @@ module Apotomo
4
4
 
5
5
  attr_reader :session, :root
6
6
 
7
- def initialize(controller, session, options={}, uses_widgets_blocks=[])
7
+ def initialize(controller, session, options={}, has_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
13
 
14
- attach_stateless_blocks_for(uses_widgets_blocks, @root, controller)
14
+ attach_stateless_blocks_for(has_widgets_blocks, @root, controller)
15
15
 
16
16
  if options[:flush_widgets].blank? and ::Apotomo::StatefulWidget.frozen_widget_in?(session)
17
17
  @root = ::Apotomo::StatefulWidget.thaw_for(session, @root)
@@ -0,0 +1,8 @@
1
+ module Apotomo
2
+ module TestMethods
3
+ def render_widget(*args)
4
+ @controller.render_widget(*args)
5
+ end
6
+
7
+ end
8
+ end
@@ -8,14 +8,10 @@ module TreeNode
8
8
  attr_writer :content, :parent
9
9
 
10
10
  def self.included(base)
11
- base.after_initialize :initialize_tree_node_for
11
+ base.after_initialize :initialize_tree_node
12
12
  end
13
13
 
14
- # Constructor which expects the name of the node
15
- #
16
- # name of the node is expected to be unique across the
17
- # tree.
18
- def initialize_tree_node_for(name, *args)
14
+ def initialize_tree_node(*)
19
15
  self.setAsRoot!
20
16
 
21
17
  @childrenHash = Hash.new
@@ -49,7 +45,9 @@ module TreeNode
49
45
  @childrenHash[child.name] = child
50
46
  @children << child
51
47
  child.parent = self
52
- return child
48
+
49
+ child.run_hook :after_add, child, self
50
+ child
53
51
  end
54
52
 
55
53
  # Removes the specified child node from the receiver node.
@@ -1,5 +1,5 @@
1
1
  # encoding: utf-8
2
2
 
3
3
  module Apotomo
4
- VERSION = '0.1.2'
4
+ VERSION = '0.1.3'
5
5
  end
@@ -1,25 +1,33 @@
1
+ require 'cells'
1
2
  require 'onfire'
2
- require 'apotomo/tree_node'
3
-
3
+ require 'hooks'
4
4
 
5
+ require 'apotomo/tree_node'
5
6
  require 'apotomo/event'
6
7
  require 'apotomo/event_methods'
7
8
  require 'apotomo/transition'
8
9
  require 'apotomo/caching'
9
- require 'apotomo/deep_link_methods'
10
10
  require 'apotomo/widget_shortcuts'
11
11
  require 'apotomo/rails/view_helper'
12
12
 
13
- ### TODO: use load_hooks when switching to rails 3.
14
- # wycats@gmail.com: ActiveSupport.run_load_hooks(:name)
15
- # (21:01:17) wycats@gmail.com: ActiveSupport.on_load(:name) { … }
16
- #require 'active_support/lazy_load_hooks'
17
-
18
13
  module Apotomo
19
14
  class Widget < Cell::Base
15
+ include Hooks
20
16
 
21
- class_inheritable_array :initialize_hooks, :instance_writer => false
22
- self.initialize_hooks = []
17
+ # Use this for setup code you're calling in every state. Almost like a +before_filter+ except that it's
18
+ # invoked after the initialization in #has_widgets.
19
+ #
20
+ # Example:
21
+ #
22
+ # class MouseWidget < Apotomo::Widget
23
+ # after_initialize :setup_cheese
24
+ #
25
+ # # we need @cheese in every state:
26
+ # def setup_cheese(*)
27
+ # @cheese = Cheese.find @opts[:cheese_id]
28
+ define_hook :after_initialize
29
+ define_hook :has_widgets
30
+ define_hook :after_add
23
31
 
24
32
  attr_accessor :opts
25
33
  attr_writer :visible
@@ -27,34 +35,8 @@ module Apotomo
27
35
  attr_writer :controller
28
36
  attr_accessor :version
29
37
 
30
- ### DISCUSS: extract to has_widgets_methods for both Widget and Controller?
31
- #class_inheritable_array :has_widgets_blocks
32
-
33
38
  class << self
34
39
  include WidgetShortcuts
35
-
36
- def has_widgets_blocks
37
- @has_widgets_blocks ||= []
38
- end
39
-
40
- def has_widgets(&block)
41
- has_widgets_blocks << block
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
40
  end
59
41
 
60
42
  include TreeNode
@@ -64,15 +46,15 @@ module Apotomo
64
46
 
65
47
  include Transition
66
48
  include Caching
67
-
68
- include DeepLinkMethods
69
49
  include WidgetShortcuts
70
50
 
71
51
  helper Apotomo::Rails::ViewHelper
72
52
 
73
53
 
54
+
55
+
74
56
  def add_has_widgets_blocks(*)
75
- self.class.has_widgets_blocks.each { |block| block.call(self) }
57
+ run_hook :has_widgets, self
76
58
  end
77
59
  after_initialize :add_has_widgets_blocks
78
60
 
@@ -89,11 +71,7 @@ module Apotomo
89
71
 
90
72
  @cell = self
91
73
 
92
- process_initialize_hooks(id, start_state, opts)
93
- end
94
-
95
- def process_initialize_hooks(*args)
96
- self.class.initialize_hooks.each { |method| send(method, *args) }
74
+ run_hook(:after_initialize, id, start_state, opts)
97
75
  end
98
76
 
99
77
  def last_state
@@ -211,15 +189,32 @@ module Apotomo
211
189
 
212
190
  alias_method :emit, :render
213
191
 
214
-
192
+ # Wraps the rendered content in a replace statement targeted at your +Apotomo.js_framework+ setting.
193
+ # Use +:selector+ to change the selector.
194
+ #
195
+ # Example:
196
+ #
197
+ # Assuming you set
198
+ # Apotomo.js_framework = :jquery
199
+ #
200
+ # and call replace in a state
201
+ #
202
+ # replace :view => :squeak, :selector => "div#mouse"
203
+ # #=> "$(\"div#mouse\").replaceWith(\"<div id=\\\"mum\\\">squeak!<\\/div>\")"
215
204
  def replace(options={})
216
205
  content = render(options)
217
- Apotomo.js_generator.replace(self.name, content)
206
+ Apotomo.js_generator.replace(options[:selector] || self.name, content)
218
207
  end
219
208
 
209
+ # Same as replace except that the content is wrapped in an update statement.
210
+ #
211
+ # Example for +:jquery+:
212
+ #
213
+ # update :view => :squeak
214
+ # #=> "$(\"mum\").html(\"<div id=\\\"mum\\\">squeak!<\\/div>\")"
220
215
  def update(options={})
221
216
  content = render(options)
222
- Apotomo.js_generator.update(self.name, content)
217
+ Apotomo.js_generator.update(options[:selector] || self.name, content)
223
218
  end
224
219
 
225
220
  # Force the FSM to go into <tt>state</tt>, regardless whether it's a valid
@@ -299,5 +294,7 @@ module Apotomo
299
294
  def controller
300
295
  root? ? @controller : root.controller
301
296
  end
297
+
298
+ alias_method :widget_id, :name
302
299
  end
303
- end
300
+ end
data/lib/apotomo.rb CHANGED
@@ -19,11 +19,6 @@
19
19
  # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
20
  # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
21
  # THE SOFTWARE.
22
- #
23
-
24
-
25
- require 'cells'
26
- require 'onfire'
27
22
 
28
23
  module Apotomo
29
24
  class << self
@@ -47,13 +42,10 @@ module Apotomo
47
42
  end
48
43
  end
49
44
 
50
- ### FIXME: move to rails.rb
51
-
52
45
  require 'apotomo/javascript_generator'
53
46
  Apotomo.js_framework = :prototype ### DISCUSS: move to rails.rb
54
47
 
55
- ### DISCUSS: move to 'apotomo/widgets'?
56
48
  require 'apotomo/widget'
57
49
  require 'apotomo/stateful_widget'
58
50
  require 'apotomo/container_widget'
59
- require 'apotomo/widget_shortcuts'
51
+ require 'apotomo/widget_shortcuts'
@@ -1,4 +1,4 @@
1
- require File.join(File.dirname(__FILE__), *%w[.. test_helper])
1
+ require 'test_helper'
2
2
 
3
3
  class ControllerMethodsTest < ActionController::TestCase
4
4
  context "A Rails controller" do
@@ -24,9 +24,9 @@ class ControllerMethodsTest < ActionController::TestCase
24
24
  end
25
25
  end
26
26
 
27
- context "invoking #uses_widgets" do
27
+ context "invoking #has_widgets" do
28
28
  setup do
29
- @controller.class.uses_widgets do |root|
29
+ @controller.class.has_widgets do |root|
30
30
  root << mouse_mock('mum')
31
31
  end
32
32
  end
@@ -40,8 +40,8 @@ class ControllerMethodsTest < ActionController::TestCase
40
40
  assert @controller.apotomo_root['mum']
41
41
  end
42
42
 
43
- should "allow multiple calls to uses_widgets" do
44
- @controller.class.uses_widgets do |root|
43
+ should "allow multiple calls to has_widgets" do
44
+ @controller.class.has_widgets do |root|
45
45
  root << mouse_mock('kid')
46
46
  end
47
47
 
@@ -49,10 +49,10 @@ class ControllerMethodsTest < ActionController::TestCase
49
49
  assert @controller.apotomo_root['kid']
50
50
  end
51
51
 
52
- should "inherit uses_widgets blocks to sub-controllers" do
52
+ should "inherit has_widgets blocks to sub-controllers" do
53
53
  berry = mouse_mock('berry')
54
54
  @sub_controller = Class.new(@controller.class) do
55
- uses_widgets { |root| root << berry }
55
+ has_widgets { |root| root << berry }
56
56
  end.new
57
57
  @sub_controller.params = {}
58
58
  @sub_controller.session = {}
@@ -203,4 +203,4 @@ class ControllerMethodsTest < ActionController::TestCase
203
203
  end
204
204
  end
205
205
 
206
- end
206
+ end
@@ -1,4 +1,4 @@
1
- require File.join(File.dirname(__FILE__), %w(.. test_helper))
1
+ require 'test_helper'
2
2
 
3
3
  class RailsIntegrationTest < ActionController::TestCase
4
4
  def simulate_request!
@@ -96,4 +96,4 @@ class RailsIntegrationTest < ActionController::TestCase
96
96
  assert_equal "<html><body><script type='text/javascript' charset='utf-8'>\nvar loc = document.location;\nwith(window.parent) { setTimeout(function() { window.eval('<div id=\\\"mum\\\"><snuggle><\\/snuggle><\\/div>'); window.loc && loc.replace('about:blank'); }, 1) }\n</script></body></html>", @response.body
97
97
  end
98
98
  end
99
- end
99
+ end
@@ -1,5 +1,4 @@
1
- require File.join(File.dirname(__FILE__), *%w[.. test_helper])
2
-
1
+ require 'test_helper'
3
2
  require 'action_view/test_case'
4
3
 
5
4
  class ViewHelperTest < ActionView::TestCase
@@ -96,4 +95,4 @@ class ViewHelperTest < ActionView::TestCase
96
95
  @mum.url_for_event(:bla)
97
96
  end
98
97
  end
99
- end
98
+ end
@@ -1,4 +1,4 @@
1
- require File.join(File.dirname(__FILE__), *%w[.. test_helper])
1
+ require 'test_helper'
2
2
 
3
3
  class ViewMethodsTest < ActionController::TestCase
4
4
  context "A Rails controller view" do
@@ -37,4 +37,4 @@ class ViewMethodsTest < ActionController::TestCase
37
37
  assert_equal "/apotomo/render_event_response?source=mum&type=footsteps", @response.body
38
38
  end
39
39
  end
40
- end
40
+ end
@@ -1,4 +1,4 @@
1
- require File.join(File.dirname(__FILE__), %w(.. test_helper))
1
+ require 'test_helper'
2
2
  require 'rails_generator'
3
3
  require 'rails_generator/scripts/generate'
4
4
 
@@ -44,4 +44,4 @@ class WidgetGeneratorTest < Test::Unit::TestCase
44
44
  def file_list
45
45
  Dir.glob(File.join(fake_rails_root, "**/*"))
46
46
  end
47
- end
47
+ end
@@ -1,4 +1,4 @@
1
- require File.dirname(__FILE__) + '/../test_helper'
1
+ require 'test_helper'
2
2
 
3
3
  class ApotomoTest < Test::Unit::TestCase
4
4
  context "The main module" do
@@ -17,4 +17,4 @@ class ApotomoTest < Test::Unit::TestCase
17
17
  assert_respond_to Apotomo.js_generator, :prototype
18
18
  end
19
19
  end
20
- end
20
+ end
@@ -1,4 +1,4 @@
1
- require File.join(File.dirname(__FILE__), *%w[.. test_helper])
1
+ require 'test_helper'
2
2
 
3
3
  class ContainerTest < Test::Unit::TestCase
4
4
  context "Rendering a container" do
@@ -17,4 +17,4 @@ class ContainerTest < Test::Unit::TestCase
17
17
  assert_equal "<div id=\"family\"><div id=\"mum\">burp!</div>\n<div id=\"kid\">burp!</div></div>", @family.invoke
18
18
  end
19
19
  end
20
- end
20
+ end
@@ -1,5 +1,4 @@
1
- require File.join(File.dirname(__FILE__), *%w[.. test_helper])
2
-
1
+ require 'test_helper'
3
2
 
4
3
  class EventHandlerTest < Test::Unit::TestCase
5
4
  context "an abstract EventHandler" do
@@ -1,4 +1,4 @@
1
- require File.join(File.dirname(__FILE__), %w(.. test_helper))
1
+ require 'test_helper'
2
2
 
3
3
  class EventMethodsTest < Test::Unit::TestCase
4
4
 
@@ -80,4 +80,4 @@ class EventMethodsTest < Test::Unit::TestCase
80
80
  end
81
81
 
82
82
  end
83
- end
83
+ end
@@ -1,4 +1,4 @@
1
- require File.join(File.dirname(__FILE__), *%w[.. test_helper])
1
+ require 'test_helper'
2
2
 
3
3
  class EventTest < Test::Unit::TestCase
4
4
  context "An Event" do
@@ -27,4 +27,4 @@ class EventTest < Test::Unit::TestCase
27
27
  assert_not Apotomo::Event.new(:footsteps, 'mum').stopped?
28
28
  end
29
29
  end
30
- end
30
+ end
@@ -1,4 +1,4 @@
1
- require File.join(File.dirname(__FILE__), *%w[.. test_helper])
1
+ require 'test_helper'
2
2
 
3
3
  class InvokeTest < Test::Unit::TestCase
4
4
  class LocalMouse < MouseCell
@@ -120,4 +120,4 @@ class InvokeTest < Test::Unit::TestCase
120
120
  end
121
121
  end
122
122
  end
123
- end
123
+ end
@@ -1,5 +1,4 @@
1
- require File.dirname(__FILE__) + '/../test_helper'
2
-
1
+ require 'test_helper'
3
2
 
4
3
  class JavascriptGeneratorTest < Test::Unit::TestCase
5
4
  context "The JavascriptGenerator" do
@@ -87,4 +86,4 @@ class JavascriptGeneratorTest < Test::Unit::TestCase
87
86
  end
88
87
  end
89
88
  end
90
- end
89
+ end
@@ -1,4 +1,4 @@
1
- require File.join(File.dirname(__FILE__), *%w[.. test_helper])
1
+ require 'test_helper'
2
2
 
3
3
  class OnfireIntegrationTest < Test::Unit::TestCase
4
4
  context "including Onfire into the StatefulWidget it" do
@@ -16,4 +16,4 @@ class OnfireIntegrationTest < Test::Unit::TestCase
16
16
  assert_equal @mum, @kid.parent
17
17
  end
18
18
  end
19
- end
19
+ end
@@ -1,4 +1,4 @@
1
- require File.join(File.dirname(__FILE__), *%w[.. test_helper])
1
+ require 'test_helper'
2
2
 
3
3
  class PersistenceTest < Test::Unit::TestCase
4
4
 
@@ -237,4 +237,4 @@ class PersistenceTest < Test::Unit::TestCase
237
237
  assert_not @mum.symbolized_instance_variables.find { |ivar| ivar.kind_of? String }
238
238
  end
239
239
  end
240
- end
240
+ end
@@ -1,4 +1,4 @@
1
- require File.join(File.dirname(__FILE__), *%w[.. test_helper])
1
+ require 'test_helper'
2
2
 
3
3
  class RenderTest < ActionView::TestCase
4
4
  context "Rendering a single widget" do
@@ -158,6 +158,15 @@ class RenderTest < ActionView::TestCase
158
158
  end
159
159
  assert_equal "$(\"mouse\").update(\"squeak!\")", @mum.invoke(:squeak)
160
160
  end
161
+
162
+ should "accept :selector" do
163
+ @mum.instance_eval do
164
+ def squeak
165
+ update :text => '<div id="mum">squeak!</div>', :selector => "div#mouse"
166
+ end
167
+ end
168
+ assert_equal "$(\"div#mouse\").update(\"<div id=\\\"mum\\\">squeak!<\\/div>\")", @mum.invoke(:squeak)
169
+ end
161
170
  end
162
171
 
163
172
  context "with #replace" do
@@ -173,6 +182,15 @@ class RenderTest < ActionView::TestCase
173
182
  end
174
183
  assert_equal "$(\"mouse\").replace(\"<div id=\\\"mum\\\">squeak!<\\/div>\")", @mum.invoke(:squeak)
175
184
  end
185
+
186
+ should "accept :selector" do
187
+ @mum.instance_eval do
188
+ def squeak
189
+ replace :text => '<div id="mum">squeak!</div>', :selector => "div#mouse"
190
+ end
191
+ end
192
+ assert_equal "$(\"div#mouse\").replace(\"<div id=\\\"mum\\\">squeak!<\\/div>\")", @mum.invoke(:squeak)
193
+ end
176
194
  end
177
195
  end
178
196
 
@@ -200,4 +218,4 @@ class RenderTest < ActionView::TestCase
200
218
  should_eventually "provide an ordered rendered_children hash"
201
219
  end
202
220
 
203
- end
221
+ end
@@ -1,4 +1,4 @@
1
- require File.join(File.dirname(__FILE__), *%w[.. test_helper])
1
+ require 'test_helper'
2
2
 
3
3
  class RequestProcessorTest < Test::Unit::TestCase
4
4
  context "#root" do
@@ -198,4 +198,4 @@ class RequestProcessorTest < Test::Unit::TestCase
198
198
  end
199
199
  end
200
200
  end
201
- end
201
+ end
@@ -1,4 +1,4 @@
1
- require File.join(File.dirname(__FILE__), '..', 'test_helper')
1
+ require 'test_helper'
2
2
 
3
3
  class StatefulWidgetTest < Test::Unit::TestCase
4
4
  context "The StatefulWidget" do
@@ -53,4 +53,4 @@ class StatefulWidgetTest < Test::Unit::TestCase
53
53
  end
54
54
  end
55
55
  end
56
- end
56
+ end
@@ -1,5 +1,4 @@
1
- require File.expand_path(File.dirname(__FILE__) + "/../test_helper")
2
-
1
+ require 'test_helper'
3
2
 
4
3
  class AddressingTest < Test::Unit::TestCase
5
4
  include Apotomo::UnitTestCase
@@ -1,5 +1,4 @@
1
- require File.expand_path(File.dirname(__FILE__) + "/../test_helper")
2
-
1
+ require 'test_helper'
3
2
 
4
3
  class ApotomoCachingTest < Test::Unit::TestCase
5
4
  include Apotomo::UnitTestCase
@@ -1,4 +1,4 @@
1
- require File.expand_path(File.dirname(__FILE__) + "/../test_helper")
1
+ require 'test_helper'
2
2
 
3
3
  ### DISCUSS: move some tests from PersistenceTest to this test file.
4
4
 
@@ -0,0 +1,11 @@
1
+ require 'test_helper'
2
+ require 'apotomo/test_methods'
3
+
4
+ class TestMethodsTest < Test::Unit::TestCase
5
+ include Apotomo::TestMethods
6
+ context "A Unit test with included module" do
7
+ should "provide #render_widget" do
8
+ assert_respond_to self, :render_widget
9
+ end
10
+ end
11
+ end
@@ -1,5 +1,4 @@
1
- require File.expand_path(File.dirname(__FILE__) + "/../test_helper")
2
-
1
+ require 'test_helper'
3
2
 
4
3
  class TabPanelTest < Test::Unit::TestCase
5
4
  include Apotomo::UnitTestCase
@@ -1,5 +1,4 @@
1
- require File.expand_path(File.dirname(__FILE__) + "/../test_helper")
2
-
1
+ require 'test_helper'
3
2
 
4
3
  # fixture:
5
4
  module My
@@ -1,4 +1,4 @@
1
- require File.join(File.dirname(__FILE__), *%w[.. test_helper])
1
+ require 'test_helper'
2
2
 
3
3
  class TransitionTest < Test::Unit::TestCase
4
4
  context "Calling #next_state_for" do
@@ -30,4 +30,4 @@ class TransitionTest < Test::Unit::TestCase
30
30
  assert_equal :snore, @mum.send(:next_state_for, :snuggle)
31
31
  end
32
32
  end
33
- end
33
+ end
@@ -1,4 +1,4 @@
1
- require File.join(File.dirname(__FILE__), *%w[.. test_helper])
1
+ require 'test_helper'
2
2
 
3
3
  class MumWidget < MouseCell; end
4
4
  class MouseTabs;end
@@ -77,4 +77,4 @@ class WidgetShortcutsTest < Test::Unit::TestCase
77
77
  assert_kind_of ::Apotomo::ContainerWidget, section('family')
78
78
  end
79
79
  end
80
- end
80
+ end
@@ -1,7 +1,7 @@
1
- require File.join(File.dirname(__FILE__), '..', 'test_helper')
1
+ require 'test_helper'
2
2
 
3
3
  class WidgetTest < ActiveSupport::TestCase
4
- context "#has_widgets in class context" do
4
+ context "Widget.has_widgets" do
5
5
  setup do
6
6
  @mum = Class.new(MouseCell) do
7
7
  has_widgets do |me|
@@ -17,8 +17,35 @@ class WidgetTest < ActiveSupport::TestCase
17
17
  assert_kind_of Apotomo::StatefulWidget, @mum['baby']
18
18
  end
19
19
 
20
- should "not inherit trees for now" do
21
- assert_equal [], @kid.children
20
+ should "inherit trees for now" do
21
+ assert_equal 1, @mum.children.size
22
+ assert_kind_of Apotomo::StatefulWidget, @mum['baby']
23
+ end
24
+ end
25
+
26
+ context "Widget.after_add" do
27
+ setup do
28
+ @mum = Class.new(MouseCell) do
29
+ after_add do |me, parent|
30
+ parent << widget('mouse_cell', 'kid', :squeak)
31
+ end
32
+ end.new('mum', :squeak)
33
+
34
+ @root = mouse_mock('root')
35
+ end
36
+
37
+ should "be invoked after mum is added" do
38
+ assert_equal [], @root.children
39
+ @root << @mum
40
+
41
+ assert_equal ['mum', 'kid'], @root.children.collect { |w| w.name }
42
+ end
43
+
44
+ should "inherit callbacks for now" do
45
+ @berry = Class.new(@mum.class).new('berry', :squeak)
46
+ @root << @berry
47
+
48
+ assert_equal ['berry', 'kid'], @root.children.collect { |w| w.name }
22
49
  end
23
50
  end
24
51
 
@@ -78,43 +105,15 @@ class WidgetTest < ActiveSupport::TestCase
78
105
  should "respond to #find_widget" do
79
106
  mum_and_kid!
80
107
  assert_not @mum.find_widget('pet')
81
- assert @kid, @mum.find_widget('kid')
108
+ assert_equal @kid, @mum.find_widget('kid')
82
109
  end
83
110
 
84
111
  should "respond to the WidgetShortcuts methods, like #widget" do
85
112
  assert_respond_to @mum, :widget
86
113
  end
87
114
 
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
115
+ should "alias #widget_id to #name" do
116
+ assert_equal @mum.name, @mum.widget_id
118
117
  end
119
118
  end
120
- end
119
+ 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: 31
4
+ hash: 29
5
5
  prerelease: false
6
6
  segments:
7
7
  - 0
8
8
  - 1
9
- - 2
10
- version: 0.1.2
9
+ - 3
10
+ version: 0.1.3
11
11
  platform: ruby
12
12
  authors:
13
13
  - Nick Sutterer
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2010-09-16 00:00:00 +02:00
18
+ date: 2010-10-12 00:00:00 +02:00
19
19
  default_executable:
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency
@@ -65,6 +65,21 @@ dependencies:
65
65
  version: 0.1.0
66
66
  type: :runtime
67
67
  version_requirements: *id003
68
+ - !ruby/object:Gem::Dependency
69
+ name: hooks
70
+ prerelease: false
71
+ requirement: &id004 !ruby/object:Gem::Requirement
72
+ none: false
73
+ requirements:
74
+ - - ~>
75
+ - !ruby/object:Gem::Version
76
+ hash: 9
77
+ segments:
78
+ - 0
79
+ - 1
80
+ version: "0.1"
81
+ type: :runtime
82
+ version_requirements: *id004
68
83
  description: A generic widget framework for Rails. Event-driven. Clean. Fast. Free optional statefulness included.
69
84
  email: apotonick@gmail.com
70
85
  executables: []
@@ -82,15 +97,6 @@ files:
82
97
  - README.rdoc
83
98
  - Rakefile
84
99
  - TODO
85
- - app/cells/apotomo/child_switch_widget/switch.html.erb
86
- - app/cells/apotomo/child_switch_widget/switch.rhtml
87
- - app/cells/apotomo/deep_link_widget.rb
88
- - app/cells/apotomo/deep_link_widget/setup.html.erb
89
- - app/cells/apotomo/java_script_widget.rb
90
- - app/cells/apotomo/tab_panel_widget.rb
91
- - app/cells/apotomo/tab_panel_widget/display.html.erb
92
- - app/cells/apotomo/tab_widget.rb
93
- - app/cells/apotomo/tab_widget/display.html.erb
94
100
  - config/routes.rb
95
101
  - generators/widget/USAGE
96
102
  - generators/widget/templates/functional_test.rb
@@ -114,6 +120,7 @@ files:
114
120
  - lib/apotomo/rails/view_methods.rb
115
121
  - lib/apotomo/request_processor.rb
116
122
  - lib/apotomo/stateful_widget.rb
123
+ - lib/apotomo/test_methods.rb
117
124
  - lib/apotomo/transition.rb
118
125
  - lib/apotomo/tree_node.rb
119
126
  - lib/apotomo/version.rb
@@ -133,6 +140,7 @@ files:
133
140
  - test/unit/event_handler_test.rb
134
141
  - test/unit/widget_shortcuts_test.rb
135
142
  - test/unit/stateful_widget_test.rb
143
+ - test/unit/test_methods_test.rb
136
144
  - test/unit/test_addressing.rb
137
145
  - test/unit/invoke_test.rb
138
146
  - test/unit/container_test.rb
@@ -197,6 +205,7 @@ test_files:
197
205
  - test/unit/event_handler_test.rb
198
206
  - test/unit/widget_shortcuts_test.rb
199
207
  - test/unit/stateful_widget_test.rb
208
+ - test/unit/test_methods_test.rb
200
209
  - test/unit/test_addressing.rb
201
210
  - test/unit/invoke_test.rb
202
211
  - test/unit/container_test.rb
@@ -1 +0,0 @@
1
- <%= @content.to_s %>
@@ -1 +0,0 @@
1
- <%= @content.to_s %>
@@ -1,20 +0,0 @@
1
- <%= javascript_tag "
2
- SWFAddress.onInternalChange = function() {
3
- //alert('internalChange');
4
- #{remote_function :url => address_to_event(:type=>:internalChange), :with => '\'deep_link=\'+SWFAddress.getPath()'}
5
- }
6
-
7
- SWFAddress.onExternalChange = function() {
8
- //alert(SWFAddress.getPath()+SWFAddress.getQueryString());
9
- #{remote_function :url => address_to_event(:type=>:internalChange), :with => '\'deep_link=\'+SWFAddress.getPath()'}
10
- }
11
-
12
-
13
- SWFAddress.onChange = function() {
14
- }
15
-
16
- SWFAddress.onInit = function() {
17
- #{remote_function :url => address_to_event(:type=>:internalChange), :with => '\'deep_link=\'+SWFAddress.getPath()'}
18
- //alert('init');
19
- }
20
- " %>
@@ -1,27 +0,0 @@
1
- class Apotomo::DeepLinkWidget < Apotomo::StatefulWidget
2
-
3
- transition :from => :setup, :to => :process
4
- transition :in => :process
5
-
6
- def setup
7
- root.respond_to_event :externalChange, :on => 'deep_link', :with => :process
8
- root.respond_to_event :internalChange, :on => 'deep_link', :with => :process
9
-
10
- render
11
- end
12
-
13
- def process
14
- # find out what changed in the deep link
15
- # find the update root (### DISCUSS: this might be more than one root, as in A--B)
16
- #path = param(:deep_link) # path is #tab=users/icon=3
17
-
18
- update_root = root.find {|w| w.responds_to_url_change? and w.responds_to_url_change_for?(url_fragment)} ### DISCUSS: we just look for one root here.
19
-
20
- if update_root
21
- controller.logger.debug "deep_link#process: `#{update_root.name}` responds to :urlChange"
22
- update_root.trigger(:urlChange)
23
- end
24
-
25
- render :nothing => true
26
- end
27
- end
@@ -1,12 +0,0 @@
1
- module Apotomo
2
-
3
- ### TODO: if a state doesn't return anything, the view-finding is invoked, which
4
- ### is nonsense in a JS widget. current work-around: return render :js => ""
5
-
6
- class JavaScriptWidget < StatefulWidget
7
- def frame_content(content)
8
- content
9
- end
10
- end
11
-
12
- end
@@ -1,57 +0,0 @@
1
- <style type="text/css">
2
- .TabPanel ul {
3
- display: block;
4
- list-style: none;
5
- padding: 0;
6
- margin: 0 0 -1px 0;
7
- height: 100%;
8
- font-size: 14px;
9
- border-left: 1px solid #888888;
10
-
11
- }
12
-
13
- .TabPanel ul li {
14
- float: left;
15
- margin: 0;
16
- padding: 5px;
17
- background-color: #dbdbdb;
18
- color: #888888;
19
- border-top: 1px solid #888888;
20
- border-right: 1px solid #888888;
21
- border-bottom: 1px solid #888888;
22
- }
23
-
24
- .TabPanel ul li.active {
25
- border-bottom: 1px solid #ffffff;
26
- background-color: #ffffff;
27
- color: #000000;
28
-
29
- }
30
-
31
- .TabPanel ul li a, .TabPanel ul li a:visited {
32
- color: #888888
33
- }
34
- </style>
35
-
36
-
37
- <div class="TabPanel">
38
- <ul>
39
- <% tabs.each do |tab|
40
- tab_class = ""
41
- tab_class = "active" if tab.name == @current_child_id
42
- %>
43
- <li class="<%= tab_class %>">
44
- <%- if @cell.responds_to_url_change? %>
45
- <%= link_to_function tab.title, update_url(@cell.url_fragment_for_tab(tab)) %>
46
- <%- else %>
47
- <%= link_to_event tab.title, {:type => :switchChild, @cell.param_name => tab.name} %>
48
- <% end %>
49
- </li>
50
- <% end -%>
51
-
52
- <div style="clear: both;" />
53
- </ul>
54
- </div>
55
- <div style="clear: both;"></div>
56
-
57
- <%= rendered_children.first %>
@@ -1,87 +0,0 @@
1
- module Apotomo
2
- class TabPanelWidget < StatefulWidget
3
- transition :from => :display, :to => :switch
4
- transition :in => :switch
5
-
6
- attr_accessor :current_child_id
7
-
8
-
9
- # Called in StatefulWidget's constructor.
10
- def initialize_deep_link_for(id, start_states, opts)
11
- return unless opts[:is_url_listener]
12
-
13
- respond_to_event :urlChange, :from => self.name, :with => :switch
14
- end
15
-
16
-
17
-
18
- def display
19
- respond_to_event(:switchChild, :with => :switch)
20
-
21
-
22
- @current_child_id = find_current_child.name
23
-
24
- render :locals => {:tabs => children}
25
- end
26
-
27
-
28
- def switch
29
- @current_child_id = find_current_child.name
30
-
31
- render :view => :display, :locals => {:tabs => children}
32
- end
33
-
34
-
35
- def children_to_render
36
- [children.find{ |c| c.name == @current_child_id } ]
37
- end
38
-
39
- ### DISCUSS: use #find_param instead of #param to provide a cleaner parameter retrieval?
40
- def find_current_child
41
- if responds_to_url_change?
42
- child_id = url_fragment[param_name]
43
- else
44
- child_id = param(param_name)
45
- end
46
-
47
- find_child(child_id) || find_child(@current_child_id) || default_child
48
- end
49
-
50
- def default_child; children.first; end
51
-
52
-
53
- def find_child(id)
54
- children.find { |c| c.name.to_s == id }
55
- end
56
-
57
- def param_name; name; end
58
-
59
-
60
- # Called by deep_link_widget#process to query if we're involved in an URL change.
61
- def responds_to_url_change_for?(fragment)
62
- # don't respond to an empty/invalid/ fragment as we don't get any information from it:
63
- return if fragment[param_name].blank?
64
-
65
- fragment[param_name] != @current_child_id
66
- end
67
-
68
- def local_fragment
69
- "#{param_name}=#{current_child_id}"
70
- end
71
-
72
-
73
- # Used in view to create the tab link in deep-linking mode.
74
- def url_fragment_for_tab(tab)
75
- url_fragment_for("#{param_name}=#{tab.name}")
76
- end
77
-
78
-
79
- def address(way={}, target=self, state=nil)
80
- way.merge!( local_address(target, way, state) )
81
-
82
- return way if isRoot?
83
-
84
- return parent.address(way, target)
85
- end
86
- end
87
- end
@@ -1 +0,0 @@
1
- <%= rendered_children.collect{|e| e.last}.join("") %>
@@ -1,18 +0,0 @@
1
- module Apotomo
2
- class TabWidget < StatefulWidget
3
-
4
- attr_accessor :title
5
-
6
- def initialize(*args)
7
- super(*args)
8
-
9
- @title = @opts[:title] || self.name.to_s
10
- end
11
-
12
-
13
- def display
14
- render
15
- end
16
-
17
- end
18
- end