cells 3.4.0 → 3.4.1
Sign up to get free protection for your applications and to get access to all the features.
- data/README.rdoc +9 -6
- data/lib/cell/test_case.rb +108 -0
- data/lib/cells.rb +5 -1
- data/lib/cells/version.rb +1 -1
- data/lib/generators/cells/USAGE +6 -14
- data/lib/generators/cells/templates/cell_test.rb +6 -8
- data/lib/tasks.rake +6 -0
- data/test/cell_generator_test.rb +1 -1
- data/test/cell_module_test.rb +2 -0
- data/test/dummy/tmp/test/cells/blog_cell_test.rb +9 -11
- data/test/helper_test.rb +2 -0
- data/test/rails/caching_test.rb +2 -0
- data/test/rails/cells_test.rb +15 -0
- data/test/rails/render_test.rb +2 -0
- data/test/rails/view_test.rb +2 -0
- data/test/test_case_test.rb +78 -0
- data/test/test_helper.rb +5 -7
- metadata +7 -9
- data/lib/cell/base.rb +0 -134
- data/lib/cells/assertions_helper.rb +0 -49
- data/test/assertions_helper_test.rb +0 -32
- data/test/support/internal_assertions_helper.rb +0 -69
data/README.rdoc
CHANGED
@@ -115,14 +115,17 @@ There are multiple advanced options for expiring your view caches, including an
|
|
115
115
|
|
116
116
|
Another big advantage compared to monolithic controller/helper/partial piles is the ability to test your cells isolated.
|
117
117
|
|
118
|
-
So what if you wanna test the cart cell? Use the generated <tt>test/cells/
|
118
|
+
So what if you wanna test the cart cell? Use the generated <tt>test/cells/shopping_cart_cell_test.rb</tt> test.
|
119
119
|
|
120
|
-
class
|
121
|
-
include Cells::AssertionsHelper
|
122
|
-
|
120
|
+
class ShoppingCartCellTest < Cell::TestCase
|
123
121
|
test "display" do
|
124
|
-
|
125
|
-
|
122
|
+
invoke :display, :user => @user_fixture
|
123
|
+
assert_select "#cart", "You have 3 items in your shopping cart."
|
124
|
+
end
|
125
|
+
|
126
|
+
Run your tests with
|
127
|
+
|
128
|
+
$ rake test:cells
|
126
129
|
|
127
130
|
That's easy, clean and strongly improves your component-driven software quality. How'd you do that with partials?
|
128
131
|
|
@@ -0,0 +1,108 @@
|
|
1
|
+
module Cell
|
2
|
+
# Test your cells.
|
3
|
+
#
|
4
|
+
# This class is roughly equal to ActionController::TestCase, exposing the same semantics. It will try
|
5
|
+
# to infer the tested cell name from the test name if you use declarative testing. You can also set it
|
6
|
+
# with TestCase.tests.
|
7
|
+
#
|
8
|
+
# A declarative test would look like
|
9
|
+
#
|
10
|
+
# class SellOutTest < Cell::TestCase
|
11
|
+
# tests ShoppingCartCell
|
12
|
+
#
|
13
|
+
# it "should be rendered nicely" do
|
14
|
+
# invoke :order_button, :items => @fixture_items
|
15
|
+
#
|
16
|
+
# assert_select "button", "Order now!"
|
17
|
+
# end
|
18
|
+
#
|
19
|
+
# You can also do stuff yourself, like
|
20
|
+
#
|
21
|
+
# it "should be rendered even nicer" do
|
22
|
+
# html = render_cell(:shopping_cart, :order_button, , :items => @fixture_items)
|
23
|
+
# assert_selector "button", "Order now!", html
|
24
|
+
# end
|
25
|
+
#
|
26
|
+
# Or even unit test your cell:
|
27
|
+
#
|
28
|
+
# it "should provide #default_items" do
|
29
|
+
# assert_equal [@item1, @item2], cell(:shopping_cart).default_items
|
30
|
+
# end
|
31
|
+
#
|
32
|
+
# == Test helpers
|
33
|
+
#
|
34
|
+
# Basically, we got these new methods:
|
35
|
+
#
|
36
|
+
# +invoke+:: Renders the passed +state+ with your tested cell. You may pass options like in #render_cell.
|
37
|
+
# +render_cell+:: As in your views. Will return the rendered view.
|
38
|
+
# +assert_selector+:: Like #assert_select except that the last argument is the html markup you wanna test.
|
39
|
+
# +cell+:: Gives you a cell instance for unit testing and stuff.
|
40
|
+
class TestCase < ActiveSupport::TestCase
|
41
|
+
module AssertSelect
|
42
|
+
# Invokes assert_select for the last argument, the +content+ string.
|
43
|
+
#
|
44
|
+
# Example:
|
45
|
+
# assert_selector "h1", "The latest and greatest!", "<h1>The latest and greatest!</h1>"
|
46
|
+
#
|
47
|
+
# would be true.
|
48
|
+
def assert_selector(*args, &block)
|
49
|
+
rails_assert_select(HTML::Document.new(args.pop).root, *args, &block)
|
50
|
+
end
|
51
|
+
|
52
|
+
# Invokes assert_select on the markup set by the last #invoke.
|
53
|
+
#
|
54
|
+
# Example:
|
55
|
+
# invoke :latest
|
56
|
+
# assert_select "h1", "The latest and greatest!"
|
57
|
+
def assert_select(*args, &block)
|
58
|
+
super(HTML::Document.new(last_invoke).root, *args, &block)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
module TestMethods
|
63
|
+
def setup
|
64
|
+
@controller = Class.new(ActionController::Base).new
|
65
|
+
@request = ::ActionController::TestRequest.new
|
66
|
+
@response = ::ActionController::TestResponse.new
|
67
|
+
@controller.request = @request
|
68
|
+
@controller.response = @response
|
69
|
+
@controller.params = {}
|
70
|
+
end
|
71
|
+
|
72
|
+
# Use this for functional tests of your application cells.
|
73
|
+
#
|
74
|
+
# Example:
|
75
|
+
# should "spit out a h1 title" do
|
76
|
+
# html = render_cell(:news, :latest)
|
77
|
+
# assert_selekt html, "h1", "The latest and greatest!"
|
78
|
+
def render_cell(*args)
|
79
|
+
@controller.render_cell(*args)
|
80
|
+
end
|
81
|
+
|
82
|
+
# Builds an instance of <tt>name</tt>Cell for unit testing.
|
83
|
+
# Passes the optional block to <tt>cell.instance_eval</tt>.
|
84
|
+
#
|
85
|
+
# Example:
|
86
|
+
# assert_equal "Banks kill planet!" cell(:news, :topic => :terror).latest_headline
|
87
|
+
def cell(name, opts={}, &block)
|
88
|
+
cell = ::Cell::Base.create_cell_for(@controller, name, opts)
|
89
|
+
cell.instance_eval &block if block_given?
|
90
|
+
cell
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
include TestMethods
|
95
|
+
include ActionDispatch::Assertions::SelectorAssertions # imports "their" #assert_select.
|
96
|
+
alias_method :rails_assert_select, :assert_select # i hate that.
|
97
|
+
include AssertSelect
|
98
|
+
|
99
|
+
extend ActionController::TestCase::Behavior::ClassMethods
|
100
|
+
|
101
|
+
|
102
|
+
attr_reader :last_invoke
|
103
|
+
|
104
|
+
def invoke(state, *args)
|
105
|
+
@last_invoke = self.class.controller_class.new(@controller, *args).render_state(state)
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
data/lib/cells.rb
CHANGED
@@ -63,7 +63,7 @@ require 'action_controller'
|
|
63
63
|
require 'cell'
|
64
64
|
require 'cells/rails'
|
65
65
|
require 'cell/rails'
|
66
|
-
|
66
|
+
require 'cell/test_case' if Rails.env == "test"
|
67
67
|
|
68
68
|
module Cells
|
69
69
|
# Any config should be placed here using +mattr_accessor+.
|
@@ -122,4 +122,8 @@ class Cells::Railtie < Rails::Railtie
|
|
122
122
|
#ActiveSupport::Dependencies.load_paths << Rails.root.join(*%w[app cells])
|
123
123
|
### DISCUSS: how are cell classes found by Rails?
|
124
124
|
end
|
125
|
+
|
126
|
+
rake_tasks do
|
127
|
+
load "tasks.rake"
|
128
|
+
end
|
125
129
|
end
|
data/lib/cells/version.rb
CHANGED
data/lib/generators/cells/USAGE
CHANGED
@@ -7,20 +7,12 @@ Description:
|
|
7
7
|
|
8
8
|
Examples:
|
9
9
|
|
10
|
-
|
10
|
+
rails g cells:cell ShoppingCart index --haml
|
11
11
|
|
12
|
-
This will create
|
12
|
+
This will create these cell assets:
|
13
13
|
Cell:
|
14
|
-
app/cells/
|
14
|
+
app/cells/shopping_cart_cell.rb
|
15
15
|
Views:
|
16
|
-
app/cells/
|
17
|
-
|
18
|
-
|
19
|
-
./script/generate cell Articles popular recent --haml
|
20
|
-
|
21
|
-
This will create an Articles cell:
|
22
|
-
Cell:
|
23
|
-
app/cells/articles_cell.rb
|
24
|
-
Views:
|
25
|
-
app/cells/articles/popular.html.haml
|
26
|
-
app/cells/articles/recent.html.haml
|
16
|
+
app/cells/shopping_cart/index.html.haml
|
17
|
+
Test:
|
18
|
+
test/cells/shopping_cart_cell_test
|
@@ -1,13 +1,11 @@
|
|
1
1
|
require 'test_helper'
|
2
2
|
|
3
|
-
class <%= class_name %>CellTest <
|
4
|
-
|
5
|
-
|
6
|
-
<% for state in @states -%>
|
3
|
+
class <%= class_name %>CellTest < Cell::TestCase
|
4
|
+
<% for state in @states -%>
|
7
5
|
test "<%= state %>" do
|
8
|
-
|
9
|
-
|
6
|
+
invoke :<%= state %>
|
7
|
+
assert_select "p"
|
10
8
|
end
|
11
9
|
|
12
|
-
|
13
|
-
end
|
10
|
+
<% end %>
|
11
|
+
end
|
data/lib/tasks.rake
ADDED
data/test/cell_generator_test.rb
CHANGED
@@ -20,7 +20,7 @@ class CellGeneratorTest < Rails::Generators::TestCase
|
|
20
20
|
assert_file "app/cells/blog/post.html.erb", %r(<p>)
|
21
21
|
assert_file "app/cells/blog/latest.html.erb", %r(app/cells/blog/latest\.html\.erb)
|
22
22
|
|
23
|
-
assert_file "test/cells/blog_cell_test.rb"
|
23
|
+
assert_file "test/cells/blog_cell_test.rb", %r(class BlogCellTest < Cell::TestCase)
|
24
24
|
end
|
25
25
|
|
26
26
|
should "create haml assets with --haml" do
|
data/test/cell_module_test.rb
CHANGED
@@ -1,17 +1,15 @@
|
|
1
1
|
require 'test_helper'
|
2
2
|
|
3
|
-
class BlogCellTest <
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
html = render_cell(:blog, :post)
|
8
|
-
assert_selekt html, "p"
|
3
|
+
class BlogCellTest < Cell::TestCase
|
4
|
+
test "post" do
|
5
|
+
invoke :post
|
6
|
+
assert_select "p"
|
9
7
|
end
|
10
8
|
|
11
|
-
|
12
|
-
|
13
|
-
|
9
|
+
test "latest" do
|
10
|
+
invoke :latest
|
11
|
+
assert_select "p"
|
14
12
|
end
|
15
13
|
|
16
|
-
|
17
|
-
end
|
14
|
+
|
15
|
+
end
|
data/test/helper_test.rb
CHANGED
data/test/rails/caching_test.rb
CHANGED
data/test/rails/cells_test.rb
CHANGED
@@ -1,6 +1,21 @@
|
|
1
1
|
require 'test_helper'
|
2
2
|
|
3
3
|
class RailsCellsTest < ActiveSupport::TestCase
|
4
|
+
include Cell::TestCase::TestMethods
|
5
|
+
|
6
|
+
def swap(object, new_values)
|
7
|
+
old_values = {}
|
8
|
+
new_values.each do |key, value|
|
9
|
+
old_values[key] = object.send key
|
10
|
+
object.send :"#{key}=", value
|
11
|
+
end
|
12
|
+
yield
|
13
|
+
ensure
|
14
|
+
old_values.each do |key, value|
|
15
|
+
object.send :"#{key}=", value
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
4
19
|
context "A rails cell" do
|
5
20
|
should "respond to view_paths" do
|
6
21
|
assert_kind_of ActionView::PathSet, Cell::Rails.view_paths, "must be a PathSet for proper template caching/reloading (see issue#2)"
|
data/test/rails/render_test.rb
CHANGED
data/test/rails/view_test.rb
CHANGED
@@ -0,0 +1,78 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class TestCaseTest < Cell::TestCase
|
4
|
+
|
5
|
+
context "A TestCase" do
|
6
|
+
setup do
|
7
|
+
@test = Cell::TestCase.new(:cell_test)
|
8
|
+
|
9
|
+
BassistCell.class_eval do
|
10
|
+
def play; render; end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
|
15
|
+
should "respond to #render_cell" do
|
16
|
+
assert_equal "Doo", render_cell(:bassist, :play)
|
17
|
+
end
|
18
|
+
|
19
|
+
should "respond to #assert_selector with 3 args" do
|
20
|
+
assert_selector "p", "Doo", "<p>Doo</p>y"
|
21
|
+
end
|
22
|
+
|
23
|
+
should "respond to #cell" do
|
24
|
+
assert_kind_of BassistCell, cell(:bassist)
|
25
|
+
assert !cell(:bassist).respond_to?(:opts)
|
26
|
+
end
|
27
|
+
|
28
|
+
should "respond to #cell with a block" do
|
29
|
+
assert_respond_to cell(:bassist) { def opts; @opts; end }, :opts
|
30
|
+
end
|
31
|
+
|
32
|
+
should "respond to #cell with options and block" do
|
33
|
+
assert_equal({:topic => :peace}, cell(:bassist, :topic => :peace) { def opts; @opts; end }.opts)
|
34
|
+
end
|
35
|
+
|
36
|
+
context "in declarative tests" do
|
37
|
+
should "respond to TestCase.tests" do
|
38
|
+
self.class.tests BassistCell
|
39
|
+
assert_equal BassistCell, self.class.controller_class
|
40
|
+
end
|
41
|
+
|
42
|
+
should "infer the cell name" do
|
43
|
+
class SingerCell < Cell::Rails
|
44
|
+
end
|
45
|
+
|
46
|
+
class SingerCellTest < Cell::TestCase
|
47
|
+
end
|
48
|
+
|
49
|
+
assert_equal SingerCell, SingerCellTest.new(:cell_test).class.controller_class
|
50
|
+
end
|
51
|
+
|
52
|
+
context "with invoke" do
|
53
|
+
setup do
|
54
|
+
self.class.tests BassistCell
|
55
|
+
end
|
56
|
+
|
57
|
+
should "provide #invoke" do
|
58
|
+
assert_equal "Doo", invoke(:play)
|
59
|
+
end
|
60
|
+
|
61
|
+
should "provide #last_invoke" do
|
62
|
+
assert_equal nil, last_invoke
|
63
|
+
assert_equal "Doo", invoke(:play)
|
64
|
+
assert_equal "Doo", last_invoke
|
65
|
+
end
|
66
|
+
|
67
|
+
should "provide #invoke accepting opts" do
|
68
|
+
#assert_equal "Doo", invoke(:play)
|
69
|
+
end
|
70
|
+
|
71
|
+
should "provide assert_select" do
|
72
|
+
invoke :promote
|
73
|
+
assert_select "a", "vd.com"
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
data/test/test_helper.rb
CHANGED
@@ -26,14 +26,12 @@ require 'cells'
|
|
26
26
|
Cell::Rails.append_view_path(File.join(test_app_dir, 'cells'))
|
27
27
|
Cell::Rails.append_view_path(File.join(test_app_dir, 'cells', 'layouts'))
|
28
28
|
|
29
|
-
|
30
|
-
Dir[File.join(gem_dir, 'test', 'support', '**', '*.rb')].each { |f| require f }
|
31
|
-
require File.join(gem_dir, 'lib', 'cells', 'assertions_helper')
|
32
|
-
|
29
|
+
require "cell/test_case"
|
33
30
|
# Extend TestCase.
|
34
31
|
ActiveSupport::TestCase.class_eval do
|
35
|
-
|
36
|
-
|
32
|
+
def assert_not(assertion)
|
33
|
+
assert !assertion
|
34
|
+
end
|
37
35
|
end
|
38
36
|
|
39
37
|
# Enable dynamic states so we can do Cell.class_eval { def ... } at runtime.
|
@@ -45,4 +43,4 @@ require File.join(test_app_dir, 'cells', 'bassist_cell')
|
|
45
43
|
require File.join(test_app_dir, 'cells', 'bad_guitarist_cell')
|
46
44
|
|
47
45
|
require "haml"
|
48
|
-
require "haml/template" # Thanks, Nathan!
|
46
|
+
require "haml/template" # Thanks, Nathan!
|
metadata
CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
|
|
5
5
|
segments:
|
6
6
|
- 3
|
7
7
|
- 4
|
8
|
-
-
|
9
|
-
version: 3.4.
|
8
|
+
- 1
|
9
|
+
version: 3.4.1
|
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: 2010-
|
17
|
+
date: 2010-10-04 00:00:00 +02:00
|
18
18
|
default_executable:
|
19
19
|
dependencies: []
|
20
20
|
|
@@ -35,11 +35,10 @@ files:
|
|
35
35
|
- Rakefile
|
36
36
|
- lib/cell.rb
|
37
37
|
- lib/cell/active_helper.rb
|
38
|
-
- lib/cell/base.rb
|
39
38
|
- lib/cell/caching.rb
|
40
39
|
- lib/cell/rails.rb
|
40
|
+
- lib/cell/test_case.rb
|
41
41
|
- lib/cells.rb
|
42
|
-
- lib/cells/assertions_helper.rb
|
43
42
|
- lib/cells/helpers.rb
|
44
43
|
- lib/cells/helpers/capture_helper.rb
|
45
44
|
- lib/cells/rails.rb
|
@@ -50,8 +49,8 @@ files:
|
|
50
49
|
- lib/generators/cells/templates/cell_test.rb
|
51
50
|
- lib/generators/cells/templates/view.erb
|
52
51
|
- lib/generators/cells/templates/view.haml
|
52
|
+
- lib/tasks.rake
|
53
53
|
- test/active_helper_test.rb
|
54
|
-
- test/assertions_helper_test.rb
|
55
54
|
- test/rails/router_test.rb
|
56
55
|
- test/rails/view_test.rb
|
57
56
|
- test/rails/capture_test.rb
|
@@ -61,7 +60,6 @@ files:
|
|
61
60
|
- test/rails/caching_test.rb
|
62
61
|
- test/cell_generator_test.rb
|
63
62
|
- test/test_helper.rb
|
64
|
-
- test/support/internal_assertions_helper.rb
|
65
63
|
- test/dummy/config/application.rb
|
66
64
|
- test/dummy/config/initializers/session_store.rb
|
67
65
|
- test/dummy/config/initializers/mime_types.rb
|
@@ -79,6 +77,7 @@ files:
|
|
79
77
|
- test/dummy/app/controllers/musician_controller.rb
|
80
78
|
- test/dummy/app/controllers/application_controller.rb
|
81
79
|
- test/dummy/app/helpers/application_helper.rb
|
80
|
+
- test/test_case_test.rb
|
82
81
|
- test/helper_test.rb
|
83
82
|
- test/cell_module_test.rb
|
84
83
|
- test/app/cells/bassist_cell.rb
|
@@ -120,7 +119,6 @@ specification_version: 3
|
|
120
119
|
summary: View Components for Rails.
|
121
120
|
test_files:
|
122
121
|
- test/active_helper_test.rb
|
123
|
-
- test/assertions_helper_test.rb
|
124
122
|
- test/rails/router_test.rb
|
125
123
|
- test/rails/view_test.rb
|
126
124
|
- test/rails/capture_test.rb
|
@@ -130,7 +128,6 @@ test_files:
|
|
130
128
|
- test/rails/caching_test.rb
|
131
129
|
- test/cell_generator_test.rb
|
132
130
|
- test/test_helper.rb
|
133
|
-
- test/support/internal_assertions_helper.rb
|
134
131
|
- test/dummy/config/application.rb
|
135
132
|
- test/dummy/config/initializers/session_store.rb
|
136
133
|
- test/dummy/config/initializers/mime_types.rb
|
@@ -148,6 +145,7 @@ test_files:
|
|
148
145
|
- test/dummy/app/controllers/musician_controller.rb
|
149
146
|
- test/dummy/app/controllers/application_controller.rb
|
150
147
|
- test/dummy/app/helpers/application_helper.rb
|
148
|
+
- test/test_case_test.rb
|
151
149
|
- test/helper_test.rb
|
152
150
|
- test/cell_module_test.rb
|
153
151
|
- test/app/cells/bassist_cell.rb
|
data/lib/cell/base.rb
DELETED
@@ -1,134 +0,0 @@
|
|
1
|
-
# == Basic overview
|
2
|
-
#
|
3
|
-
# A Cell is the central notion of the cells plugin. A cell acts as a
|
4
|
-
# lightweight controller in the sense that it will assign variables and
|
5
|
-
# render a view. Cells can be rendered from other cells as well as from
|
6
|
-
# regular controllers and views (see ActionView::Base#render_cell and
|
7
|
-
# ControllerMethods#render_cell)
|
8
|
-
#
|
9
|
-
# == A render_cell() cycle
|
10
|
-
#
|
11
|
-
# A typical <tt>render_cell</tt> state rendering cycle looks like this:
|
12
|
-
# render_cell :blog, :newest_article, {...}
|
13
|
-
# - an instance of the class <tt>BlogCell</tt> is created, and a hash containing
|
14
|
-
# arbitrary parameters is passed
|
15
|
-
# - the <em>state method</em> <tt>newest_article</tt> is executed and assigns instance
|
16
|
-
# variables to be used in the view
|
17
|
-
# - Usually the state method will call #render and return
|
18
|
-
# - #render will retrieve the corresponding view
|
19
|
-
# (e.g. <tt>app/cells/blog/newest_article.html. [erb|haml|...]</tt>),
|
20
|
-
# renders this template and returns the markup.
|
21
|
-
#
|
22
|
-
# == Design Principles
|
23
|
-
# A cell is a completely autonomous object and it should not know or have to know
|
24
|
-
# from what controller it is being rendered. For this reason, the controller's
|
25
|
-
# instance variables and params hash are not directly available from the cell or
|
26
|
-
# its views. This is not a bug, this is a feature! It means cells are truly
|
27
|
-
# reusable components which can be plugged in at any point in your application
|
28
|
-
# without having to think about what information is available at that point.
|
29
|
-
# When rendering a cell, you can explicitly pass variables to the cell in the
|
30
|
-
# extra opts argument hash, just like you would pass locals in partials.
|
31
|
-
# This hash is then available inside the cell as the @opts instance variable.
|
32
|
-
#
|
33
|
-
# == Directory hierarchy
|
34
|
-
#
|
35
|
-
# To get started creating your own cells, you can simply create a new directory
|
36
|
-
# structure under your <tt>app</tt> directory called <tt>cells</tt>. Cells are
|
37
|
-
# ruby classes which end in the name Cell. So for example, if you have a
|
38
|
-
# cell which manages all user information, it would be called <tt>UserCell</tt>.
|
39
|
-
# A cell which manages a shopping cart could be called <tt>ShoppingCartCell</tt>.
|
40
|
-
#
|
41
|
-
# The directory structure of this example would look like this:
|
42
|
-
# app/
|
43
|
-
# models/
|
44
|
-
# ..
|
45
|
-
# views/
|
46
|
-
# ..
|
47
|
-
# helpers/
|
48
|
-
# application_helper.rb
|
49
|
-
# product_helper.rb
|
50
|
-
# ..
|
51
|
-
# controllers/
|
52
|
-
# ..
|
53
|
-
# cells/
|
54
|
-
# shopping_cart_cell.rb
|
55
|
-
# shopping_cart/
|
56
|
-
# status.html.erb
|
57
|
-
# product_list.html.erb
|
58
|
-
# empty_prompt.html.erb
|
59
|
-
# user_cell.rb
|
60
|
-
# user/
|
61
|
-
# login.html.erb
|
62
|
-
# layouts/
|
63
|
-
# box.html.erb
|
64
|
-
# ..
|
65
|
-
#
|
66
|
-
# The directory with the same name as the cell contains views for the
|
67
|
-
# cell's <em>states</em>. A state is an executed method along with a
|
68
|
-
# rendered view, resulting in content. This means that states are to
|
69
|
-
# cells as actions are to controllers, so each state has its own view.
|
70
|
-
# The use of partials is deprecated with cells, it is better to just
|
71
|
-
# render a different state on the same cell (which also works recursively).
|
72
|
-
#
|
73
|
-
# Anyway, <tt>render :partial </tt> in a cell view will work, if the
|
74
|
-
# partial is contained in the cell's view directory.
|
75
|
-
#
|
76
|
-
# As can be seen above, Cells also can make use of helpers. All Cells
|
77
|
-
# include ApplicationHelper by default, but you can add additional helpers
|
78
|
-
# as well with the ::Cell::Base.helper class method:
|
79
|
-
# class ShoppingCartCell < ::Cell::Base
|
80
|
-
# helper :product
|
81
|
-
# ...
|
82
|
-
# end
|
83
|
-
#
|
84
|
-
# This will make the <tt>ProductHelper</tt> from <tt>app/helpers/product_helper.rb</tt>
|
85
|
-
# available from all state views from our <tt>ShoppingCartCell</tt>.
|
86
|
-
#
|
87
|
-
# == Cell inheritance
|
88
|
-
#
|
89
|
-
# Unlike controllers, Cells can form a class hierarchy. When a cell class
|
90
|
-
# is inherited by another cell class, its states are inherited as regular
|
91
|
-
# methods are, but also its views are inherited. Whenever a view is looked up,
|
92
|
-
# the view finder first looks for a file in the directory belonging to the
|
93
|
-
# current cell class, but if this is not found in the application or any
|
94
|
-
# engine, the superclass' directory is checked. This continues all the
|
95
|
-
# way up until it stops at ::Cell::Base.
|
96
|
-
#
|
97
|
-
# For instance, when you have two cells:
|
98
|
-
# class MenuCell < ::Cell::Base
|
99
|
-
# def show
|
100
|
-
# end
|
101
|
-
#
|
102
|
-
# def edit
|
103
|
-
# end
|
104
|
-
# end
|
105
|
-
#
|
106
|
-
# class MainMenuCell < MenuCell
|
107
|
-
# .. # no need to redefine show/edit if they do the same!
|
108
|
-
# end
|
109
|
-
# and the following directory structure in <tt>app/cells</tt>:
|
110
|
-
# app/cells/
|
111
|
-
# menu/
|
112
|
-
# show.html.erb
|
113
|
-
# edit.html.erb
|
114
|
-
# main_menu/
|
115
|
-
# show.html.erb
|
116
|
-
# then when you call
|
117
|
-
# render_cell :main_menu, :show
|
118
|
-
# the main menu specific show.html.erb (<tt>app/cells/main_menu/show.html.erb</tt>)
|
119
|
-
# is rendered, but when you call
|
120
|
-
# render_cell :main_menu, :edit
|
121
|
-
# cells notices that the main menu does not have a specific view for the
|
122
|
-
# <tt>edit</tt> state, so it will render the view for the parent class,
|
123
|
-
# <tt>app/cells/menu/edit.html.erb</tt>
|
124
|
-
#
|
125
|
-
#
|
126
|
-
# == Gettext support
|
127
|
-
#
|
128
|
-
# Cells support gettext, just name your views accordingly. It works exactly equivalent
|
129
|
-
# to controller views.
|
130
|
-
#
|
131
|
-
# cells/user/user_form.html.erb
|
132
|
-
# cells/user/user_form_de.html.erb
|
133
|
-
#
|
134
|
-
# If gettext is set to DE_de, the latter view will be chosen.
|
@@ -1,49 +0,0 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
require 'action_controller/test_case'
|
3
|
-
|
4
|
-
module Cells
|
5
|
-
module AssertionsHelper
|
6
|
-
# Sets up a mock controller for usage in render_cell.
|
7
|
-
def setup
|
8
|
-
@controller = Class.new(ActionController::Base).new
|
9
|
-
@request = ::ActionController::TestRequest.new
|
10
|
-
@response = ::ActionController::TestResponse.new
|
11
|
-
@controller.request = @request
|
12
|
-
@controller.response = @response
|
13
|
-
@controller.params = {}
|
14
|
-
end
|
15
|
-
|
16
|
-
# Use this for functional tests of your application cells.
|
17
|
-
#
|
18
|
-
# Example:
|
19
|
-
# should "spit out a h1 title" do
|
20
|
-
# html = render_cell(:news, :latest)
|
21
|
-
# assert_selekt html, "h1", "The latest and greatest!"
|
22
|
-
def render_cell(*args)
|
23
|
-
@controller.render_cell(*args)
|
24
|
-
end
|
25
|
-
|
26
|
-
# Invokes assert_select for the passed <tt>content</tt> string.
|
27
|
-
#
|
28
|
-
# Example:
|
29
|
-
# html = "<h1>The latest and greatest!</h1>"
|
30
|
-
# assert_selekt html, "h1", "The latest and greatest!"
|
31
|
-
#
|
32
|
-
# would be true.
|
33
|
-
def assert_selekt(content, *args)
|
34
|
-
assert_select(HTML::Document.new(content).root, *args)
|
35
|
-
end
|
36
|
-
|
37
|
-
# Builds an instance of <tt>name</tt>Cell for unit testing.
|
38
|
-
# Passes the optional block to <tt>cell.instance_eval</tt>.
|
39
|
-
#
|
40
|
-
# Example:
|
41
|
-
# assert_equal "Banks kill planet!" cell(:news, :topic => :terror).latest_headline
|
42
|
-
def cell(name, opts={}, &block)
|
43
|
-
cell = ::Cell::Base.create_cell_for(@controller, name, opts)
|
44
|
-
cell.instance_eval &block if block_given?
|
45
|
-
cell
|
46
|
-
end
|
47
|
-
end
|
48
|
-
end
|
49
|
-
|
@@ -1,32 +0,0 @@
|
|
1
|
-
require 'test_helper'
|
2
|
-
|
3
|
-
class AssertionsHelperTest < ActionController::TestCase
|
4
|
-
context "A TestCase" do
|
5
|
-
setup do
|
6
|
-
BassistCell.class_eval do
|
7
|
-
def play; render; end
|
8
|
-
end
|
9
|
-
end
|
10
|
-
|
11
|
-
should "respond to #render_cell" do
|
12
|
-
assert_equal "Doo", render_cell(:bassist, :play)
|
13
|
-
end
|
14
|
-
|
15
|
-
should "respond to #assert_selekt" do
|
16
|
-
assert_selekt "<p>Doo</p>", "p", "Doo"
|
17
|
-
end
|
18
|
-
|
19
|
-
should "respond to #cell" do
|
20
|
-
assert_kind_of BassistCell, cell(:bassist)
|
21
|
-
assert_not cell(:bassist).respond_to? :opts
|
22
|
-
end
|
23
|
-
|
24
|
-
should "respond to #cell with a block" do
|
25
|
-
assert_respond_to cell(:bassist) { def opts; @opts; end }, :opts
|
26
|
-
end
|
27
|
-
|
28
|
-
should "respond to #cell with options and block" do
|
29
|
-
assert_equal({:topic => :peace}, cell(:bassist, :topic => :peace) { def opts; @opts; end }.opts)
|
30
|
-
end
|
31
|
-
end
|
32
|
-
end
|
@@ -1,69 +0,0 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
module Cells
|
3
|
-
# Assertion helpers extracted from Devise by José Valim.
|
4
|
-
#
|
5
|
-
module InternalAssertionsHelper
|
6
|
-
def setup
|
7
|
-
@controller = ::MusicianController.new
|
8
|
-
@request = ::ActionController::TestRequest.new
|
9
|
-
@response = ::ActionController::TestResponse.new
|
10
|
-
@controller.request = @request
|
11
|
-
@controller.response = @response
|
12
|
-
@controller.params = {}
|
13
|
-
end
|
14
|
-
|
15
|
-
def assert_not(assertion)
|
16
|
-
assert !assertion
|
17
|
-
end
|
18
|
-
|
19
|
-
def assert_blank(assertion)
|
20
|
-
assert assertion.blank?
|
21
|
-
end
|
22
|
-
|
23
|
-
def assert_not_blank(assertion)
|
24
|
-
assert !assertion.blank?
|
25
|
-
end
|
26
|
-
alias :assert_present :assert_not_blank
|
27
|
-
|
28
|
-
# Execute the block setting the given values and restoring old values after
|
29
|
-
# the block is executed.
|
30
|
-
#
|
31
|
-
# == Usage/Example:
|
32
|
-
#
|
33
|
-
# I18n.locale # => :en
|
34
|
-
#
|
35
|
-
# swap(I18n :locale => :se) do
|
36
|
-
# I18n.locale # => :se
|
37
|
-
# end
|
38
|
-
#
|
39
|
-
# I18n.locale # => :en
|
40
|
-
#
|
41
|
-
def swap(object, new_values)
|
42
|
-
old_values = {}
|
43
|
-
new_values.each do |key, value|
|
44
|
-
old_values[key] = object.send key
|
45
|
-
object.send :"#{key}=", value
|
46
|
-
end
|
47
|
-
yield
|
48
|
-
ensure
|
49
|
-
old_values.each do |key, value|
|
50
|
-
object.send :"#{key}=", value
|
51
|
-
end
|
52
|
-
end
|
53
|
-
|
54
|
-
# Provides a TestCell instance. The <tt>block</tt> is passed to instance_eval and should be used
|
55
|
-
# to extend the mock on the fly.
|
56
|
-
### DISCUSS: make an anonymous subclass of TestCell?
|
57
|
-
def cell_mock(options={}, &block) ### DISCUSS: 2BRM.
|
58
|
-
cell = TestCell.new(@controller, options)
|
59
|
-
cell.instance_eval(&block) if block_given?
|
60
|
-
cell
|
61
|
-
end
|
62
|
-
|
63
|
-
def bassist_mock(options={}, &block)
|
64
|
-
cell = BassistCell.new(@controller, options)
|
65
|
-
cell.instance_eval(&block) if block_given?
|
66
|
-
cell
|
67
|
-
end
|
68
|
-
end
|
69
|
-
end
|