apotomo 0.1.2 → 0.1.3

Sign up to get free protection for your applications and to get access to all the features.
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