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