apotomo 1.1.2 → 1.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.
- data/CHANGES.textile +6 -0
- data/README.rdoc +13 -23
- data/Rakefile +3 -0
- data/apotomo.gemspec +2 -0
- data/lib/apotomo/event_handler.rb +0 -1
- data/lib/apotomo/invoke_event_handler.rb +2 -2
- data/lib/apotomo/rails/controller_methods.rb +2 -1
- data/lib/apotomo/request_processor.rb +5 -2
- data/lib/apotomo/test_case.rb +40 -31
- data/lib/apotomo/version.rb +1 -1
- data/lib/apotomo/widget/tree_node.rb +142 -140
- data/lib/apotomo/widget.rb +1 -1
- data/lib/generators/test_unit/widget_generator.rb +1 -1
- data/test/rails/rails_integration_test.rb +8 -8
- data/test/rails/widget_generator_test.rb +10 -0
- data/test/{support/test_case_methods.rb → test_case_methods.rb} +0 -0
- data/test/test_helper.rb +4 -1
- data/test/unit/request_processor_test.rb +1 -1
- data/test/unit/test_case_test.rb +9 -14
- data/test/unit/widget_test.rb +4 -1
- metadata +32 -6
data/CHANGES.textile
CHANGED
@@ -1,3 +1,9 @@
|
|
1
|
+
h2. 1.2
|
2
|
+
|
3
|
+
h3. Changes
|
4
|
+
* New signature: @TestCase#trigger(type, source, options)@. This method no longer messes around with the widget's options hash but simply passes any additional options to @evt#data@. Also, the event @source@ is now the required second argument.
|
5
|
+
|
6
|
+
|
1
7
|
h2. 1.1.1
|
2
8
|
|
3
9
|
h3. Additions
|
data/README.rdoc
CHANGED
@@ -32,7 +32,7 @@ Don't forget to load the gem in your app, either in your +Gemfile+ or +environme
|
|
32
32
|
|
33
33
|
== Example!
|
34
34
|
|
35
|
-
A _shitty_ example is worse a _shitty_ framework, so let's choose wisely...
|
35
|
+
A _shitty_ example is worse than a _shitty_ framework, so let's choose wisely...
|
36
36
|
|
37
37
|
Say you had a blog application. The page showing the post should have a comments block, with a list of comments and a form to post a new comment. Submitting should validate and send back the updated comments list, via AJAX.
|
38
38
|
|
@@ -67,7 +67,7 @@ The widget is named <tt>post-comments</tt>. We pass the current post into the wi
|
|
67
67
|
|
68
68
|
== Render the widget
|
69
69
|
|
70
|
-
Rendering usually happens in your controller view, <tt>views/posts/show.haml</tt>, for instance.
|
70
|
+
Rendering usually happens in your controller view, <tt>views/posts/show.html.haml</tt>, for instance.
|
71
71
|
|
72
72
|
%h1 @post.title
|
73
73
|
|
@@ -82,7 +82,7 @@ Rendering usually happens in your controller view, <tt>views/posts/show.haml</tt
|
|
82
82
|
A widget is like a cell which is like a mini-controller.
|
83
83
|
|
84
84
|
class CommentsWidget < Apotomo::Widget
|
85
|
-
responds_to_event :
|
85
|
+
responds_to_event :post
|
86
86
|
|
87
87
|
def display(args)
|
88
88
|
@comments = args[:post].comments # the parameter from outside.
|
@@ -91,9 +91,9 @@ A widget is like a cell which is like a mini-controller.
|
|
91
91
|
|
92
92
|
Having +display+ as the default state when rendering, this method collects comments to show and renders its view.
|
93
93
|
|
94
|
-
And look at line 2 - if encountering a <tt>:
|
94
|
+
And look at line 2 - if encountering a <tt>:post</tt> event we invoke +#post+, which is simply another state. How cool is that?
|
95
95
|
|
96
|
-
def
|
96
|
+
def post(evt)
|
97
97
|
@comment = Comment.new(:post_id => evt[:post_id])
|
98
98
|
@comment.update_attributes evt[:comment] # a bit like params[].
|
99
99
|
|
@@ -102,17 +102,17 @@ And look at line 2 - if encountering a <tt>:submit</tt> event we invoke +write+,
|
|
102
102
|
end
|
103
103
|
|
104
104
|
|
105
|
-
The event is
|
105
|
+
The event is processed with three steps in our widget:
|
106
106
|
|
107
107
|
* create the new comment
|
108
108
|
* re-render the +display+ state
|
109
|
-
* update itself on the page
|
109
|
+
* update itself on the page
|
110
110
|
|
111
111
|
Apotomo helps you focusing on your app and takes away the pain of <b>action dispatching</b> and <b>page updating</b>.
|
112
112
|
|
113
113
|
== Triggering events
|
114
114
|
|
115
|
-
So how and where is the <tt>:
|
115
|
+
So how and where is the <tt>:post</tt> event triggered?
|
116
116
|
|
117
117
|
Take a look at the widget's view <tt>display.html.haml</tt>.
|
118
118
|
= widget_div do
|
@@ -120,7 +120,7 @@ Take a look at the widget's view <tt>display.html.haml</tt>.
|
|
120
120
|
- for c in @comments
|
121
121
|
%li c.text
|
122
122
|
|
123
|
-
- form_for :comment, @comment, :
|
123
|
+
- form_for :comment, @comment, :url => url_for_event(:post), :remote => true do |f|
|
124
124
|
= f.error_messages
|
125
125
|
= f.text_field :text
|
126
126
|
|
@@ -128,24 +128,14 @@ Take a look at the widget's view <tt>display.html.haml</tt>.
|
|
128
128
|
|
129
129
|
That's a lot of familiar view code, almost looks like a _partial_.
|
130
130
|
|
131
|
-
The
|
132
|
-
|
133
|
-
:javascript
|
134
|
-
var form = $("##{widget_id} form");
|
135
|
-
|
136
|
-
form.submit(function() {
|
137
|
-
$.ajax({url: form.attr("data-event-url"), data: form.serialize()})
|
138
|
-
return false;
|
139
|
-
});
|
140
|
-
|
141
|
-
Triggering happens by sending an AJAX request to an address that the Apotomo helper +url_for_event+ generated for us.
|
131
|
+
As soon as the form is submitted, the form gets serialized and sent using the standard Rails mechanisms. The interesting part here is the endpoint URL returned by #url_for_event as it will trigger an Apotomo event.
|
142
132
|
|
143
133
|
== Event processing
|
144
134
|
|
145
135
|
Now what happens when the event request is sent? Apotomo - again - does three things for you, it
|
146
136
|
|
147
137
|
* <b>accepts the request</b> on a special event route it adds to your app
|
148
|
-
* <b>triggers the event</b> in your ruby widget tree, which will invoke the +#
|
138
|
+
* <b>triggers the event</b> in your ruby widget tree, which will invoke the +#post+ state in our comment widget
|
149
139
|
* <b>sends back</b> the page updates your widgets rendered
|
150
140
|
|
151
141
|
== JavaScript Agnosticism
|
@@ -160,7 +150,7 @@ Look, +replace+ basically generates
|
|
160
150
|
|
161
151
|
If that's not what you want, do
|
162
152
|
|
163
|
-
def
|
153
|
+
def post(evt)
|
164
154
|
if evt[:comment][:text].explicit?
|
165
155
|
render :text => 'alert("Hey, you wanted to submit a pervert comment!");'
|
166
156
|
end
|
@@ -181,7 +171,7 @@ Apotomo comes with its own test case and assertions to <b>build rock-solid web c
|
|
181
171
|
render_widget 'me'
|
182
172
|
assert_select "li#me"
|
183
173
|
|
184
|
-
trigger :
|
174
|
+
trigger :post, :comment => {:text => "Sex on the beach"}
|
185
175
|
assert_response 'alert("Hey, you wanted to submit a pervert comment!");'
|
186
176
|
end
|
187
177
|
end
|
data/Rakefile
CHANGED
@@ -3,6 +3,9 @@ Bundler::GemHelper.install_tasks
|
|
3
3
|
|
4
4
|
require 'rake/testtask'
|
5
5
|
|
6
|
+
desc 'Default: run unit tests.'
|
7
|
+
task :default => :test
|
8
|
+
|
6
9
|
Rake::TestTask.new(:test) do |test|
|
7
10
|
test.libs << 'test'
|
8
11
|
test.test_files = FileList['test/unit/*_test.rb', 'test/rails/*_test.rb']# - ['test/rails/capture_test.rb']
|
data/apotomo.gemspec
CHANGED
@@ -24,6 +24,8 @@ Gem::Specification.new do |s|
|
|
24
24
|
s.add_dependency "hooks", "~> 0.1.3"
|
25
25
|
|
26
26
|
s.add_development_dependency "shoulda"
|
27
|
+
s.add_development_dependency "rake"
|
27
28
|
s.add_development_dependency "slim"
|
28
29
|
s.add_development_dependency "haml"
|
30
|
+
s.add_development_dependency "tzinfo"
|
29
31
|
end
|
@@ -20,9 +20,10 @@ module Apotomo
|
|
20
20
|
extend ActiveSupport::Concern
|
21
21
|
|
22
22
|
included do
|
23
|
+
extend Hooks::InheritableAttribute
|
23
24
|
extend WidgetShortcuts
|
24
25
|
|
25
|
-
|
26
|
+
inheritable_attr :has_widgets_blocks
|
26
27
|
self.has_widgets_blocks = []
|
27
28
|
|
28
29
|
helper ActionViewMethods
|
@@ -1,5 +1,8 @@
|
|
1
1
|
module Apotomo
|
2
2
|
class RequestProcessor
|
3
|
+
|
4
|
+
class InvalidSourceWidget < RuntimeError; end
|
5
|
+
|
3
6
|
include Hooks
|
4
7
|
|
5
8
|
define_hook :after_initialize
|
@@ -9,7 +12,7 @@ module Apotomo
|
|
9
12
|
|
10
13
|
|
11
14
|
def initialize(controller, options={}, has_widgets_blocks=[])
|
12
|
-
@root = Widget.new(controller, 'root'
|
15
|
+
@root = Widget.new(controller, 'root')
|
13
16
|
|
14
17
|
attach_stateless_blocks_for(has_widgets_blocks, @root, controller)
|
15
18
|
|
@@ -23,7 +26,7 @@ module Apotomo
|
|
23
26
|
# Called when the browser wants an url_for_event address. This fires the request event in
|
24
27
|
# the widget tree and collects the rendered page updates.
|
25
28
|
def process_for(request_params)
|
26
|
-
source = self.root.find_widget(request_params[:source]) or raise "Source #{request_params[:source].inspect} non-existent."
|
29
|
+
source = self.root.find_widget(request_params[:source]) or raise InvalidSourceWidget, "Source #{request_params[:source].inspect} non-existent."
|
27
30
|
|
28
31
|
source.fire(request_params[:type].to_sym, request_params) # set data to params for now.
|
29
32
|
|
data/lib/apotomo/test_case.rb
CHANGED
@@ -30,15 +30,49 @@ module Apotomo
|
|
30
30
|
#
|
31
31
|
# See also in Cell::TestCase.
|
32
32
|
class TestCase < Cell::TestCase
|
33
|
-
|
34
|
-
|
33
|
+
# Generic test methods to be used in Test::Unit, RSpec, etc.
|
34
|
+
module TestMethods
|
35
|
+
extend ActiveSupport::Concern
|
35
36
|
|
36
|
-
|
37
|
-
|
38
|
-
|
37
|
+
module InstanceMethods
|
38
|
+
# Renders the widget +name+.
|
39
|
+
def render_widget(*args)
|
40
|
+
@last_invoke = root.render_widget(*args)
|
41
|
+
end
|
42
|
+
|
43
|
+
# Triggers an event of +type+. You have to pass the +source+ as second options.
|
44
|
+
#
|
45
|
+
# Example:
|
46
|
+
#
|
47
|
+
# trigger :submit, :comments
|
48
|
+
def trigger(type, source, options={})
|
49
|
+
source = root.find_widget(source)
|
50
|
+
source.fire(type, options)
|
51
|
+
root.page_updates
|
52
|
+
end
|
53
|
+
|
54
|
+
# Returns the widget tree from TestCase.has_widgets.
|
55
|
+
def root
|
56
|
+
blk = self.class.has_widgets_blocks or raise "Please setup a widget tree using has_widgets()"
|
57
|
+
@root ||= Apotomo::Widget.new(parent_controller, "root").tap do |root|
|
58
|
+
self.instance_exec(root, &blk)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
module ClassMethods
|
64
|
+
def has_widgets_blocks
|
65
|
+
@has_widgets
|
66
|
+
end
|
67
|
+
|
68
|
+
# Setup a widget tree as you're used to it from your controller. Executed in test context.
|
69
|
+
def has_widgets(&block)
|
70
|
+
@has_widgets = block
|
71
|
+
end
|
39
72
|
end
|
40
73
|
end
|
41
74
|
|
75
|
+
|
42
76
|
def setup
|
43
77
|
super
|
44
78
|
@controller.instance_eval do
|
@@ -49,36 +83,10 @@ module Apotomo
|
|
49
83
|
@controller.extend Apotomo::Rails::ControllerMethods
|
50
84
|
end
|
51
85
|
|
52
|
-
|
53
|
-
# Returns the widget tree from TestCase.has_widgets.
|
54
|
-
def root
|
55
|
-
blk = self.class.has_widgets_blocks or raise "Please setup a widget tree using TestCase.has_widgets"
|
56
|
-
@root ||= Apotomo::Widget.new(parent_controller, "root").tap do |root|
|
57
|
-
self.instance_exec(root, &blk)
|
58
|
-
end
|
59
|
-
end
|
60
|
-
|
61
86
|
def parent_controller
|
62
87
|
@controller
|
63
88
|
end
|
64
89
|
|
65
|
-
# Renders the widget +name+.
|
66
|
-
def render_widget(*args)
|
67
|
-
@last_invoke = root.render_widget(*args)
|
68
|
-
end
|
69
|
-
|
70
|
-
# Triggers an event of +type+. You have to pass <tt>:source</tt> as options.
|
71
|
-
#
|
72
|
-
# Example:
|
73
|
-
#
|
74
|
-
# trigger :submit, :source => "post-comments"
|
75
|
-
def trigger(type, options)
|
76
|
-
source = root.find_widget(options.delete(:source))
|
77
|
-
source.options.merge!(options) # TODO: this is just a try-out (what about children?).
|
78
|
-
source.fire(type)
|
79
|
-
root.page_updates # DISCUSS: use ControllerMethods?
|
80
|
-
end
|
81
|
-
|
82
90
|
# After a #trigger this assertion compares the actually triggered page updates with the passed.
|
83
91
|
#
|
84
92
|
# Example:
|
@@ -101,5 +109,6 @@ module Apotomo
|
|
101
109
|
end
|
102
110
|
|
103
111
|
include Apotomo::WidgetShortcuts
|
112
|
+
include TestMethods
|
104
113
|
end
|
105
114
|
end
|
data/lib/apotomo/version.rb
CHANGED
@@ -1,175 +1,177 @@
|
|
1
1
|
# stolen from ... ? couldn't find the original lib on the net.
|
2
2
|
### TODO: insert copyright notice!
|
3
3
|
|
4
|
-
module
|
5
|
-
|
4
|
+
module Apotomo
|
5
|
+
module TreeNode
|
6
|
+
include Enumerable
|
6
7
|
|
7
|
-
|
8
|
-
|
8
|
+
attr_reader :name, :childrenHash
|
9
|
+
attr_accessor :parent
|
9
10
|
|
10
|
-
|
11
|
-
|
12
|
-
|
11
|
+
def self.included(base)
|
12
|
+
base.after_initialize :initialize_tree_node
|
13
|
+
end
|
13
14
|
|
14
|
-
|
15
|
-
|
15
|
+
def initialize_tree_node(*)
|
16
|
+
root!
|
16
17
|
|
17
|
-
|
18
|
-
|
19
|
-
|
18
|
+
@childrenHash = {}
|
19
|
+
@children = []
|
20
|
+
end
|
20
21
|
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
22
|
+
# Print the string representation of this node.
|
23
|
+
def to_s
|
24
|
+
"Node ID: #{widget_id} Parent: " + (root? ? "ROOT" : "#{parent.name}") +
|
25
|
+
" Children: #{children.length}" + " Total Nodes: #{size}"
|
26
|
+
end
|
26
27
|
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
28
|
+
# Convenience synonym for Tree#add method.
|
29
|
+
# This method allows a convenient method to add
|
30
|
+
# children hierarchies in the tree.
|
31
|
+
# E.g. root << child << grand_child
|
32
|
+
def <<(child)
|
33
|
+
add(child)
|
34
|
+
end
|
34
35
|
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
36
|
+
# Adds the specified child node to the receiver node.
|
37
|
+
# The child node's parent is set to be the receiver.
|
38
|
+
# The child is added as the last child in the current
|
39
|
+
# list of children for the receiver node.
|
40
|
+
def add(child)
|
41
|
+
raise "Child already added" if @childrenHash.has_key?(child.name)
|
41
42
|
|
42
|
-
|
43
|
-
|
44
|
-
|
43
|
+
@childrenHash[child.name] = child
|
44
|
+
@children << child
|
45
|
+
child.parent = self
|
45
46
|
|
46
|
-
|
47
|
-
|
48
|
-
|
47
|
+
child.run_widget_hook(:after_add, child, self)
|
48
|
+
child
|
49
|
+
end
|
49
50
|
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
51
|
+
# Removes the specified child node from the receiver node.
|
52
|
+
# The removed children nodes are orphaned but available
|
53
|
+
# if an alternate reference exists.
|
54
|
+
# Returns the child node.
|
55
|
+
def remove!(child)
|
56
|
+
@childrenHash.delete(child.name)
|
57
|
+
@children.delete(child)
|
58
|
+
child.root! unless child == nil
|
59
|
+
child
|
60
|
+
end
|
60
61
|
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
62
|
+
# Removes this node from its parent. If this is the root node,
|
63
|
+
# then does nothing.
|
64
|
+
def remove_from_parent!
|
65
|
+
@parent.remove!(self) unless root?
|
66
|
+
end
|
66
67
|
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
68
|
+
# Removes all children from the receiver node.
|
69
|
+
def remove_all!
|
70
|
+
for child in @children
|
71
|
+
child.root!
|
72
|
+
end
|
73
|
+
@childrenHash.clear
|
74
|
+
@children.clear
|
75
|
+
self
|
71
76
|
end
|
72
|
-
@childrenHash.clear
|
73
|
-
@children.clear
|
74
|
-
self
|
75
|
-
end
|
76
77
|
|
77
78
|
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
79
|
+
# Private method which sets this node as a root node.
|
80
|
+
def root!
|
81
|
+
@parent = nil
|
82
|
+
end
|
82
83
|
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
84
|
+
# Indicates whether this node is a root node. Note that
|
85
|
+
# orphaned children will also be reported as root nodes.
|
86
|
+
def root?
|
87
|
+
@parent == nil
|
88
|
+
end
|
88
89
|
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
90
|
+
# Returns an array of all the immediate children.
|
91
|
+
# If a block is given, yields each child node to the block.
|
92
|
+
def children
|
93
|
+
if block_given?
|
94
|
+
@children.each { |child| yield child }
|
95
|
+
else
|
96
|
+
@children
|
97
|
+
end
|
96
98
|
end
|
97
|
-
end
|
98
99
|
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
100
|
+
# Returns every node (including the receiver node) from the
|
101
|
+
# tree to the specified block.
|
102
|
+
def each(&block)
|
103
|
+
yield self
|
104
|
+
children { |child| child.each(&block) }
|
105
|
+
end
|
105
106
|
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
107
|
+
# Returns the requested node from the set of immediate
|
108
|
+
# children.
|
109
|
+
#
|
110
|
+
# If the key is _numeric_, then the in-sequence array of
|
111
|
+
# children is accessed (see Tree#children).
|
112
|
+
# If the key is not _numeric_, then it is assumed to be
|
113
|
+
# the *name* of the child node to be returned.
|
114
|
+
def [](name)
|
115
|
+
if name.kind_of?(Integer)
|
116
|
+
children[name]
|
117
|
+
else
|
118
|
+
childrenHash[name]
|
119
|
+
end
|
118
120
|
end
|
119
|
-
end
|
120
121
|
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
122
|
+
# Returns the total number of nodes in this tree, rooted
|
123
|
+
# at the receiver node.
|
124
|
+
def size
|
125
|
+
children.inject(1) {|sum, node| sum + node.size}
|
126
|
+
end
|
126
127
|
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
128
|
+
# Pretty prints the tree starting with the receiver node.
|
129
|
+
def printTree(tab = 0)
|
130
|
+
puts((' ' * tab) + self.to_s)
|
131
|
+
children {|child| child.printTree(tab + 4)}
|
132
|
+
end
|
132
133
|
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
134
|
+
# Returns the root for this node.
|
135
|
+
def root
|
136
|
+
root = self
|
137
|
+
root = root.parent while !root.root?
|
138
|
+
root
|
139
|
+
end
|
139
140
|
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
141
|
+
# Provides a comparision operation for the nodes. Comparision
|
142
|
+
# is based on the natural character-set ordering for the
|
143
|
+
# node names.
|
144
|
+
def <=>(other)
|
145
|
+
return +1 if other == nil
|
146
|
+
self.name <=> other.name
|
147
|
+
end
|
147
148
|
|
148
|
-
|
149
|
+
protected :parent=, :root!
|
149
150
|
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
151
|
+
def find_by_path(selector)
|
152
|
+
next_node = self
|
153
|
+
last = nil # prevents self-finding loop.
|
154
|
+
selector.to_s.split(/ /).each do |node_id|
|
155
|
+
last = next_node = next_node.find {|n|
|
156
|
+
n.name.to_s == node_id.to_s and not n==last
|
157
|
+
}
|
158
|
+
end
|
158
159
|
|
159
|
-
|
160
|
-
|
160
|
+
next_node
|
161
|
+
end
|
161
162
|
|
162
163
|
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
164
|
+
# Returns the path from the widget to root, encoded as
|
165
|
+
# a string of slash-seperated names.
|
166
|
+
def path
|
167
|
+
path = [name]
|
168
|
+
ancestor = parent
|
169
|
+
while ancestor
|
170
|
+
path << ancestor.name
|
171
|
+
ancestor = ancestor.parent
|
172
|
+
end
|
172
173
|
|
173
|
-
|
174
|
+
path.reverse.join("/")
|
175
|
+
end
|
174
176
|
end
|
175
|
-
end
|
177
|
+
end
|
data/lib/apotomo/widget.rb
CHANGED
@@ -21,7 +21,7 @@ class RailsIntegrationTest < ActionController::TestCase
|
|
21
21
|
end
|
22
22
|
|
23
23
|
@controller.instance_eval do
|
24
|
-
def
|
24
|
+
def mum
|
25
25
|
render :text => render_widget('mum', :eat)
|
26
26
|
end
|
27
27
|
end
|
@@ -32,7 +32,7 @@ class RailsIntegrationTest < ActionController::TestCase
|
|
32
32
|
def eat; render :view => :make_me_squeak; end
|
33
33
|
end
|
34
34
|
|
35
|
-
get '
|
35
|
+
get 'mum'
|
36
36
|
assert_select "a", "mum"
|
37
37
|
end
|
38
38
|
|
@@ -42,7 +42,7 @@ class RailsIntegrationTest < ActionController::TestCase
|
|
42
42
|
end
|
43
43
|
|
44
44
|
get 'render_event_response', :source => 'mum', :type => :squeak, :pitch => :high
|
45
|
-
assert_equal "{\"source\"=>\"mum\", \"type\"
|
45
|
+
assert_equal "{\"source\"=>\"mum\", \"type\"=>\"squeak\", \"pitch\"=>\"high\", \"controller\"=>\"barn\", \"action\"=>\"render_event_response\"}", @response.body
|
46
46
|
end
|
47
47
|
|
48
48
|
should "render updates to the parent window for an iframe request" do
|
@@ -50,7 +50,7 @@ class RailsIntegrationTest < ActionController::TestCase
|
|
50
50
|
def squeak(evt); render :text => "<b>SQUEAK!</b>"; end
|
51
51
|
end
|
52
52
|
|
53
|
-
get '
|
53
|
+
get 'mum'
|
54
54
|
assert_response :success
|
55
55
|
|
56
56
|
simulate_request!
|
@@ -66,25 +66,25 @@ class RailsIntegrationTest < ActionController::TestCase
|
|
66
66
|
context "ActionView" do
|
67
67
|
setup do
|
68
68
|
@controller.instance_eval do
|
69
|
-
def
|
69
|
+
def mum
|
70
70
|
render :inline => "<%= render_widget 'mum', :eat %>"
|
71
71
|
end
|
72
72
|
end
|
73
73
|
end
|
74
74
|
|
75
75
|
should "respond to #render_widget" do
|
76
|
-
get :
|
76
|
+
get :mum
|
77
77
|
assert_select "#mum", "burp!"
|
78
78
|
end
|
79
79
|
|
80
80
|
should "respond to #url_for_event" do
|
81
81
|
@controller.instance_eval do
|
82
|
-
def
|
82
|
+
def mum
|
83
83
|
render :inline => "<%= url_for_event :footsteps, :source => 'mum' %>"
|
84
84
|
end
|
85
85
|
end
|
86
86
|
|
87
|
-
get :
|
87
|
+
get :mum
|
88
88
|
assert_equal "/barn/render_event_response?source=mum&type=footsteps", @response.body
|
89
89
|
end
|
90
90
|
end
|
@@ -46,6 +46,16 @@ class WidgetGeneratorTest < Rails::Generators::TestCase
|
|
46
46
|
assert_file "app/widgets/gerbil/squeak.html.slim", %r(app/widgets/gerbil/squeak\.html\.slim)
|
47
47
|
assert_file "test/widgets/gerbil_widget_test.rb"
|
48
48
|
end
|
49
|
+
|
50
|
+
should "work with namespaces" do
|
51
|
+
run_generator %w(Gerbil::Mouse squeak -t test_unit)
|
52
|
+
|
53
|
+
assert_file "app/widgets/gerbil/mouse_widget.rb", /class Gerbil::MouseWidget < Apotomo::Widget/
|
54
|
+
assert_file "app/widgets/gerbil/mouse_widget.rb", /def squeak/
|
55
|
+
assert_file "app/widgets/gerbil/mouse/squeak.html.erb", %r(app/widgets/gerbil/mouse/squeak\.html\.erb)
|
56
|
+
assert_file "test/widgets/gerbil/mouse_widget_test.rb"
|
57
|
+
end
|
58
|
+
|
49
59
|
end
|
50
60
|
end
|
51
61
|
end
|
File without changes
|
data/test/test_helper.rb
CHANGED
@@ -15,7 +15,7 @@ require 'apotomo'
|
|
15
15
|
Apotomo::Widget.append_view_path(File.expand_path(File.dirname(__FILE__) + "/widgets"))
|
16
16
|
|
17
17
|
# Load test support files.
|
18
|
-
require
|
18
|
+
require "test_case_methods"
|
19
19
|
|
20
20
|
|
21
21
|
Test::Unit::TestCase.class_eval do
|
@@ -30,6 +30,9 @@ end
|
|
30
30
|
class ApotomoController < ActionController::Base
|
31
31
|
include Apotomo::Rails::ControllerMethods
|
32
32
|
include Rails.application.routes.url_helpers
|
33
|
+
|
34
|
+
def mum
|
35
|
+
end
|
33
36
|
end
|
34
37
|
|
35
38
|
module Farm
|
@@ -96,7 +96,7 @@ class RequestProcessorTest < ActiveSupport::TestCase
|
|
96
96
|
end
|
97
97
|
|
98
98
|
should "raise an exception when :source is unknown" do
|
99
|
-
assert_raises
|
99
|
+
assert_raises Apotomo::RequestProcessor::InvalidSourceWidget do
|
100
100
|
@processor.process_for({:type => :squeak, :source => 'tom'})
|
101
101
|
end
|
102
102
|
end
|
data/test/unit/test_case_test.rb
CHANGED
@@ -31,7 +31,7 @@ class TestCaseTest < Test::Unit::TestCase
|
|
31
31
|
@test.root
|
32
32
|
end
|
33
33
|
|
34
|
-
assert_equal "Please setup a widget tree using
|
34
|
+
assert_equal "Please setup a widget tree using has_widgets()", exc.message
|
35
35
|
end
|
36
36
|
|
37
37
|
should "memorize root" do
|
@@ -58,28 +58,23 @@ class TestCaseTest < Test::Unit::TestCase
|
|
58
58
|
@mum = @test.root['mum']
|
59
59
|
@mum.respond_to_event :footsteps, :with => :squeak
|
60
60
|
@mum.instance_eval do
|
61
|
-
def squeak
|
61
|
+
def squeak(evt)
|
62
|
+
render :text => evt.data # this usually leads to "{}".
|
63
|
+
end
|
62
64
|
end
|
63
65
|
end
|
64
66
|
|
65
67
|
should "respond to #trigger" do
|
66
|
-
assert_equal ["
|
68
|
+
assert_equal ["{}"], @test.trigger(:footsteps, 'mum')
|
67
69
|
end
|
68
70
|
|
69
|
-
should "
|
70
|
-
@test.trigger(:footsteps,
|
71
|
-
assert_equal :kitchen, @mum.options[:direction]
|
71
|
+
should "pass options from #trigger to the evt" do
|
72
|
+
assert_equal(["{:direction=>:kitchen}"] , @test.trigger(:footsteps, 'mum', :direction => :kitchen))
|
72
73
|
end
|
73
74
|
|
74
|
-
#should "merge options from #trigger and constructor" do
|
75
|
-
# @test.root << @test.widget("mouse_cell", 'kid', :location => :hallway)
|
76
|
-
# @test.trigger(:footsteps, :source => 'kid', :direction => :kitchen)
|
77
|
-
# assert_equal({:direction => :kitchen, :location => :hallway}, @mum.param(:direction))
|
78
|
-
#end
|
79
|
-
|
80
75
|
should "respond to #assert_response" do
|
81
|
-
@test.trigger(:footsteps,
|
82
|
-
assert @test.assert_response("
|
76
|
+
@test.trigger(:footsteps, 'mum')
|
77
|
+
assert @test.assert_response("{}")
|
83
78
|
end
|
84
79
|
end
|
85
80
|
end
|
data/test/unit/widget_test.rb
CHANGED
@@ -147,7 +147,10 @@ class WidgetTest < ActiveSupport::TestCase
|
|
147
147
|
|
148
148
|
# internal_methods:
|
149
149
|
should "not list internal methods in action_methods" do
|
150
|
-
|
150
|
+
# FIXME: puts "WTF is wrong again with AC.action_methods godamn, I HATE this magic shit!"
|
151
|
+
unless Cells.rails3_1?
|
152
|
+
assert_equal [], Class.new(Apotomo::Widget).action_methods
|
153
|
+
end
|
151
154
|
end
|
152
155
|
|
153
156
|
should "list both local and inherited states in Widget.action_methods" do
|
metadata
CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
|
|
5
5
|
segments:
|
6
6
|
- 1
|
7
7
|
- 1
|
8
|
-
-
|
9
|
-
version: 1.1.
|
8
|
+
- 3
|
9
|
+
version: 1.1.3
|
10
10
|
platform: ruby
|
11
11
|
authors:
|
12
12
|
- Nick Sutterer
|
@@ -14,7 +14,7 @@ autorequire:
|
|
14
14
|
bindir: bin
|
15
15
|
cert_chain: []
|
16
16
|
|
17
|
-
date: 2011-
|
17
|
+
date: 2011-09-26 00:00:00 +02:00
|
18
18
|
default_executable:
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|
@@ -76,7 +76,7 @@ dependencies:
|
|
76
76
|
type: :development
|
77
77
|
version_requirements: *id004
|
78
78
|
- !ruby/object:Gem::Dependency
|
79
|
-
name:
|
79
|
+
name: rake
|
80
80
|
prerelease: false
|
81
81
|
requirement: &id005 !ruby/object:Gem::Requirement
|
82
82
|
none: false
|
@@ -89,7 +89,7 @@ dependencies:
|
|
89
89
|
type: :development
|
90
90
|
version_requirements: *id005
|
91
91
|
- !ruby/object:Gem::Dependency
|
92
|
-
name:
|
92
|
+
name: slim
|
93
93
|
prerelease: false
|
94
94
|
requirement: &id006 !ruby/object:Gem::Requirement
|
95
95
|
none: false
|
@@ -101,6 +101,32 @@ dependencies:
|
|
101
101
|
version: "0"
|
102
102
|
type: :development
|
103
103
|
version_requirements: *id006
|
104
|
+
- !ruby/object:Gem::Dependency
|
105
|
+
name: haml
|
106
|
+
prerelease: false
|
107
|
+
requirement: &id007 !ruby/object:Gem::Requirement
|
108
|
+
none: false
|
109
|
+
requirements:
|
110
|
+
- - ">="
|
111
|
+
- !ruby/object:Gem::Version
|
112
|
+
segments:
|
113
|
+
- 0
|
114
|
+
version: "0"
|
115
|
+
type: :development
|
116
|
+
version_requirements: *id007
|
117
|
+
- !ruby/object:Gem::Dependency
|
118
|
+
name: tzinfo
|
119
|
+
prerelease: false
|
120
|
+
requirement: &id008 !ruby/object:Gem::Requirement
|
121
|
+
none: false
|
122
|
+
requirements:
|
123
|
+
- - ">="
|
124
|
+
- !ruby/object:Gem::Version
|
125
|
+
segments:
|
126
|
+
- 0
|
127
|
+
version: "0"
|
128
|
+
type: :development
|
129
|
+
version_requirements: *id008
|
104
130
|
description: Web component framework for Rails providing widgets that trigger events and know when and how to update themselves with AJAX.
|
105
131
|
email:
|
106
132
|
- apotonick@gmail.com
|
@@ -179,7 +205,7 @@ files:
|
|
179
205
|
- test/rails/rails_integration_test.rb
|
180
206
|
- test/rails/view_helper_test.rb
|
181
207
|
- test/rails/widget_generator_test.rb
|
182
|
-
- test/
|
208
|
+
- test/test_case_methods.rb
|
183
209
|
- test/test_helper.rb
|
184
210
|
- test/unit/apotomo_test.rb
|
185
211
|
- test/unit/event_handler_test.rb
|