cells 3.4.3 → 3.4.4
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 +8 -0
- data/Gemfile +3 -2
- data/README.rdoc +23 -0
- data/lib/cell.rb +45 -2
- data/lib/cell/rails.rb +1 -5
- data/lib/cell/test_case.rb +22 -0
- data/lib/cells.rb +4 -24
- data/lib/cells/version.rb +1 -1
- data/test/cell_module_test.rb +90 -0
- data/test/cells_module_test.rb +21 -0
- data/test/rails/view_test.rb +8 -10
- data/test/test_case_test.rb +19 -1
- metadata +5 -3
data/CHANGES.textile
CHANGED
|
@@ -1,3 +1,11 @@
|
|
|
1
|
+
h2. 3.4.4
|
|
2
|
+
|
|
3
|
+
h3. Changes
|
|
4
|
+
* Cells.setup now yields Cell::Base, so you can really call append_view_path and friends here.
|
|
5
|
+
* added Cell::Base.build for streamlining the process of deciders around #render_cell, "see here":http://nicksda.apotomo.de/2010/12/pragmatic-rails-thoughts-on-views-inheritance-view-inheritance-and-rails-304
|
|
6
|
+
* added TestCase#in_view to test helpers in a real cell view.
|
|
7
|
+
|
|
8
|
+
|
|
1
9
|
h2. 3.4.3
|
|
2
10
|
|
|
3
11
|
h3. Changes
|
data/Gemfile
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
source :gemcutter
|
|
2
2
|
gem 'sqlite3-ruby', '1.2.5', :require => 'sqlite3' # needed in router_test, whatever.
|
|
3
3
|
|
|
4
|
-
#gem "rails" , :path => "/home/nick/projects/
|
|
5
|
-
gem "rails", '3.0
|
|
4
|
+
#gem "rails" , :path => "/home/nick/projects/rayls"
|
|
5
|
+
gem "rails", '~> 3.0'
|
|
6
6
|
gem "haml"
|
|
7
7
|
|
|
8
8
|
group :test do
|
|
9
9
|
gem "shoulda"
|
|
10
10
|
end
|
|
11
|
+
gem "rack", :git => "git://github.com/rack/rack.git"
|
data/README.rdoc
CHANGED
|
@@ -94,6 +94,29 @@ The distinction between partials and views is making things more complex, so why
|
|
|
94
94
|
= render :view => 'items'
|
|
95
95
|
|
|
96
96
|
|
|
97
|
+
== View Inheritance
|
|
98
|
+
|
|
99
|
+
This is where OOP comes back to your view.
|
|
100
|
+
|
|
101
|
+
* <b>Inherit code</b> into your cells by deriving more abstract cells.
|
|
102
|
+
* <b>Inherit views</b> from ancesting cells.
|
|
103
|
+
|
|
104
|
+
=== Builders
|
|
105
|
+
|
|
106
|
+
Let +render_cell+ take care of creating the right cell. Just configure your super-cell properly.
|
|
107
|
+
|
|
108
|
+
class LoginCell < Cell::Rails
|
|
109
|
+
build do
|
|
110
|
+
UnauthorizedUserCell unless logged_in?
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
A call to
|
|
114
|
+
|
|
115
|
+
render_cell(:login, :box)
|
|
116
|
+
|
|
117
|
+
will render the configured +UnauthorizedUserCell+ instead of the original +LoginCell+ if the login test fails.
|
|
118
|
+
|
|
119
|
+
|
|
97
120
|
== Caching
|
|
98
121
|
|
|
99
122
|
Cells do strict view caching. No cluttered fragment caching. Add
|
data/lib/cell.rb
CHANGED
|
@@ -10,9 +10,52 @@ module Cell
|
|
|
10
10
|
cell.render_state(state)
|
|
11
11
|
end
|
|
12
12
|
|
|
13
|
-
# Creates a cell instance.
|
|
13
|
+
# Creates a cell instance. Note that this method calls builders which were attached to the
|
|
14
|
+
# class with Cell::Base.build - this might lead to a different cell being returned.
|
|
14
15
|
def create_cell_for(controller, name, opts={})
|
|
15
|
-
class_from_cell_name(name)
|
|
16
|
+
build_class_for(controller, class_from_cell_name(name), opts).
|
|
17
|
+
new(controller, opts)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
# Adds a builder to the cell class. Builders are used in #render_cell to find out the concrete
|
|
21
|
+
# class for rendering. This is helpful if you frequently want to render subclasses according
|
|
22
|
+
# to different circumstances (e.g. login situations) and you don't want to place these deciders in
|
|
23
|
+
# your view code.
|
|
24
|
+
#
|
|
25
|
+
# Passes the opts hash from #render_cell into the block. The block is executed in controller context.
|
|
26
|
+
# Multiple build blocks are ORed, if no builder matches the building cell is used.
|
|
27
|
+
#
|
|
28
|
+
# Example:
|
|
29
|
+
#
|
|
30
|
+
# Consider two different user box cells in your app.
|
|
31
|
+
#
|
|
32
|
+
# class AuthorizedUserBox < UserInfoBox
|
|
33
|
+
# end
|
|
34
|
+
#
|
|
35
|
+
# class AdminUserBox < UserInfoBox
|
|
36
|
+
# end
|
|
37
|
+
#
|
|
38
|
+
# Now you don't want to have deciders all over your views - use a declarative builder.
|
|
39
|
+
#
|
|
40
|
+
# UserInfoBox.build do |opts|
|
|
41
|
+
# AuthorizedUserBox if user_signed_in?
|
|
42
|
+
# AdminUserBox if admin_signed_in?
|
|
43
|
+
# end
|
|
44
|
+
#
|
|
45
|
+
# In your view #render_cell will instantiate the right cell for you now.
|
|
46
|
+
def build(&block)
|
|
47
|
+
builders << block
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def build_class_for(controller, target_class, opts)
|
|
51
|
+
target_class.builders.each do |blk|
|
|
52
|
+
res = controller.instance_exec(opts, &blk) and return res
|
|
53
|
+
end
|
|
54
|
+
target_class
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def builders
|
|
58
|
+
@builders ||= []
|
|
16
59
|
end
|
|
17
60
|
|
|
18
61
|
# Return the default view path for +state+. Override this if you cell has a differing naming style.
|
data/lib/cell/rails.rb
CHANGED
|
@@ -48,8 +48,6 @@ module Cell
|
|
|
48
48
|
include Rendering
|
|
49
49
|
include Caching
|
|
50
50
|
|
|
51
|
-
|
|
52
|
-
cattr_accessor :url_helpers ### TODO: discuss if we really need that or can handle that in cells.rb already.
|
|
53
51
|
attr_reader :parent_controller
|
|
54
52
|
|
|
55
53
|
abstract!
|
|
@@ -67,12 +65,10 @@ module Cell
|
|
|
67
65
|
|
|
68
66
|
View.class_eval do
|
|
69
67
|
include controller._helpers
|
|
70
|
-
include
|
|
68
|
+
include controller._routes.url_helpers
|
|
71
69
|
end
|
|
72
70
|
|
|
73
|
-
|
|
74
71
|
@view_context_class ||= View
|
|
75
|
-
### DISCUSS: copy behaviour from abstract_controller/rendering-line 49? (helpers)
|
|
76
72
|
end
|
|
77
73
|
|
|
78
74
|
def self.controller_path
|
data/lib/cell/test_case.rb
CHANGED
|
@@ -89,6 +89,27 @@ module Cell
|
|
|
89
89
|
cell.instance_eval &block if block_given?
|
|
90
90
|
cell
|
|
91
91
|
end
|
|
92
|
+
|
|
93
|
+
# Execute the passed +block+ in a real view context of +cell_class+.
|
|
94
|
+
# Usually you'd test helpers here.
|
|
95
|
+
#
|
|
96
|
+
# Example:
|
|
97
|
+
#
|
|
98
|
+
# assert_equal("<h1>Modularity rocks.</h1>", in_view do content_tag(:h1, "Modularity rocks."))
|
|
99
|
+
def in_view(cell_class, &block)
|
|
100
|
+
subject = cell(cell_class, :block => block)
|
|
101
|
+
setup_test_states_in(subject) # add #in_view to subject cell.
|
|
102
|
+
subject.render_state(:in_view)
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
protected
|
|
106
|
+
def setup_test_states_in(cell)
|
|
107
|
+
cell.instance_eval do
|
|
108
|
+
def in_view
|
|
109
|
+
render :inline => "<%= instance_exec(&block) %>", :locals => {:block => @opts[:block]}
|
|
110
|
+
end
|
|
111
|
+
end
|
|
112
|
+
end
|
|
92
113
|
end
|
|
93
114
|
|
|
94
115
|
include TestMethods
|
|
@@ -97,6 +118,7 @@ module Cell
|
|
|
97
118
|
include AssertSelect
|
|
98
119
|
|
|
99
120
|
extend ActionController::TestCase::Behavior::ClassMethods
|
|
121
|
+
class_attribute :_controller_class
|
|
100
122
|
|
|
101
123
|
|
|
102
124
|
attr_reader :last_invoke
|
data/lib/cells.rb
CHANGED
|
@@ -66,40 +66,22 @@ require 'cell/rails'
|
|
|
66
66
|
require 'cell/test_case' if Object.const_defined?("Rails") and Rails.env == "test"
|
|
67
67
|
|
|
68
68
|
module Cells
|
|
69
|
-
# Any config should be placed here using +mattr_accessor+.
|
|
70
|
-
|
|
71
69
|
# Default view paths for Cells.
|
|
72
70
|
DEFAULT_VIEW_PATHS = [
|
|
73
71
|
File.join('app', 'cells'),
|
|
74
72
|
File.join('app', 'cells', 'layouts')
|
|
75
73
|
]
|
|
76
74
|
|
|
77
|
-
|
|
78
|
-
# Holds paths in which Cells should look for cell views (i.e. view template files).
|
|
79
|
-
#
|
|
80
|
-
# == Default:
|
|
81
|
-
#
|
|
82
|
-
# * +app/cells+
|
|
83
|
-
# * +app/cells/layouts+
|
|
84
|
-
#
|
|
85
|
-
def self.view_paths
|
|
86
|
-
::Cell::Base.view_paths
|
|
87
|
-
end
|
|
88
|
-
def self.view_paths=(paths)
|
|
89
|
-
::Cell::Base.view_paths = paths
|
|
90
|
-
end
|
|
91
|
-
end
|
|
92
|
-
|
|
93
|
-
# Cells setup/configuration helper for initializer.
|
|
75
|
+
# Setup your special needs for Cells here. Use this to add new view paths.
|
|
94
76
|
#
|
|
95
|
-
#
|
|
77
|
+
# Example:
|
|
96
78
|
#
|
|
97
79
|
# Cells.setup do |config|
|
|
98
|
-
# config.
|
|
80
|
+
# config.append_view_path << "app/view_models"
|
|
99
81
|
# end
|
|
100
82
|
#
|
|
101
83
|
def self.setup
|
|
102
|
-
yield(
|
|
84
|
+
yield(Cell::Base)
|
|
103
85
|
end
|
|
104
86
|
end
|
|
105
87
|
|
|
@@ -115,8 +97,6 @@ class Cells::Railtie < Rails::Railtie
|
|
|
115
97
|
Cell::Rails.class_eval do
|
|
116
98
|
include app.routes.url_helpers
|
|
117
99
|
end
|
|
118
|
-
|
|
119
|
-
Cell::Base.url_helpers = app.routes.url_helpers
|
|
120
100
|
end
|
|
121
101
|
|
|
122
102
|
rake_tasks do
|
data/lib/cells/version.rb
CHANGED
data/test/cell_module_test.rb
CHANGED
|
@@ -1,5 +1,16 @@
|
|
|
1
1
|
require 'test_helper'
|
|
2
2
|
|
|
3
|
+
class MusicianCell < Cell::Base
|
|
4
|
+
|
|
5
|
+
end
|
|
6
|
+
|
|
7
|
+
class PianistCell < MusicianCell
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
class SingerCell < MusicianCell
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
|
|
3
14
|
class CellModuleTest < ActiveSupport::TestCase
|
|
4
15
|
include Cell::TestCase::TestMethods
|
|
5
16
|
|
|
@@ -20,9 +31,88 @@ class CellModuleTest < ActiveSupport::TestCase
|
|
|
20
31
|
assert_equal "Doo", html
|
|
21
32
|
assert flag
|
|
22
33
|
end
|
|
34
|
+
|
|
35
|
+
|
|
23
36
|
end
|
|
24
37
|
|
|
38
|
+
context "create_cell_for" do
|
|
39
|
+
should "call the cell's builders, eventually returning a different class" do
|
|
40
|
+
class DrummerCell < BassistCell
|
|
41
|
+
build do
|
|
42
|
+
BassistCell
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
assert_instance_of BassistCell, Cell::Base.create_cell_for(@controller, "cell_module_test/drummer", :play)
|
|
47
|
+
end
|
|
48
|
+
end
|
|
25
49
|
|
|
50
|
+
context "calling build" do
|
|
51
|
+
setup do
|
|
52
|
+
@controller.class_eval do
|
|
53
|
+
attr_accessor :bassist
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
MusicianCell.build do
|
|
57
|
+
BassistCell if bassist
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
teardown do
|
|
62
|
+
MusicianCell.class_eval do
|
|
63
|
+
@builders = false
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
should "execute the block in controller context" do
|
|
68
|
+
@controller.bassist = true
|
|
69
|
+
assert_equal BassistCell, Cell::Base.build_class_for(@controller, MusicianCell, {})
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
should "limit the builder to the receiving class" do
|
|
73
|
+
assert_equal PianistCell, Cell::Base.build_class_for(@controller, PianistCell, {}) # don't inherit anything.
|
|
74
|
+
@controller.bassist = true
|
|
75
|
+
assert_equal BassistCell, Cell::Base.build_class_for(@controller, MusicianCell, {})
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
should "chain build blocks and execute them by ORing them in the same order" do
|
|
79
|
+
MusicianCell.build do
|
|
80
|
+
PianistCell unless bassist
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
MusicianCell.build do
|
|
84
|
+
UnknownCell # should never be executed.
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
assert_equal PianistCell, Cell::Base.build_class_for(@controller, MusicianCell, {}) # bassist is false.
|
|
88
|
+
@controller.bassist = true
|
|
89
|
+
assert_equal BassistCell, Cell::Base.build_class_for(@controller, MusicianCell, {})
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
should "use the original cell if no builder matches" do
|
|
93
|
+
assert_equal MusicianCell, Cell::Base.build_class_for(@controller, MusicianCell, {}) # bassist is false.
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
should "stop at the first builder returning a valid cell" do
|
|
97
|
+
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
should "pass options to the block" do
|
|
101
|
+
BassistCell.build do |opts|
|
|
102
|
+
SingerCell if opts[:sing_the_song]
|
|
103
|
+
end
|
|
104
|
+
assert_equal BassistCell, Cell::Base.build_class_for(@controller, BassistCell, {})
|
|
105
|
+
assert_equal SingerCell, Cell::Base.build_class_for(@controller, BassistCell, {:sing_the_song => true})
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
should "create the original target class if no block matches" do
|
|
109
|
+
assert_equal PianistCell, Cell::Base.build_class_for(@controller, PianistCell, {})
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
should "builders should return an empty array per default" do
|
|
113
|
+
assert_equal [], PianistCell.builders
|
|
114
|
+
end
|
|
115
|
+
end
|
|
26
116
|
|
|
27
117
|
should "provide possible_paths_for_state" do
|
|
28
118
|
assert_equal ["bad_guitarist/play", "bassist/play", "cell/rails/play"], cell(:bad_guitarist).possible_paths_for_state(:play)
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
require 'test_helper'
|
|
2
|
+
|
|
3
|
+
class CellsModuleTest < ActiveSupport::TestCase
|
|
4
|
+
context "Cells" do
|
|
5
|
+
setup do
|
|
6
|
+
@old_view_paths = Cell::Base.view_paths.clone
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
should "provide .setup" do
|
|
10
|
+
Cells.setup do |c|
|
|
11
|
+
c.append_view_path "/road/to/nowhere"
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
assert_equal "/road/to/nowhere", Cell::Base.view_paths.last.to_s
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
teardown do
|
|
18
|
+
Cell::Base.view_paths = @old_view_paths
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
data/test/rails/view_test.rb
CHANGED
|
@@ -5,18 +5,16 @@ class RailsViewTest < ActiveSupport::TestCase
|
|
|
5
5
|
|
|
6
6
|
context "A cell view" do
|
|
7
7
|
context "calling render :partial" do
|
|
8
|
-
should "render the cell partial in bassist/dii" do
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
end
|
|
12
|
-
assert_equal "Dumm Dii", render_cell(:bassist, :compose)
|
|
8
|
+
should "render the local cell partial in bassist/dii" do
|
|
9
|
+
assert_equal("Dii", in_view(:bassist) do
|
|
10
|
+
render :partial => 'dii'
|
|
11
|
+
end)
|
|
13
12
|
end
|
|
14
13
|
|
|
15
|
-
should "render the cell partial in bad_guitarist/dii" do
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
end
|
|
19
|
-
assert_equal "Dumm Dooom", render_cell(:bassist, :compose)
|
|
14
|
+
should "render the foreign cell partial in bad_guitarist/dii" do
|
|
15
|
+
assert_equal("Dooom", in_view(:bassist) do
|
|
16
|
+
render :partial => "bad_guitarist/dii"
|
|
17
|
+
end)
|
|
20
18
|
end
|
|
21
19
|
end
|
|
22
20
|
|
data/test/test_case_test.rb
CHANGED
|
@@ -49,7 +49,7 @@ class TestCaseTest < Cell::TestCase
|
|
|
49
49
|
assert_equal SingerCell, SingerCellTest.new(:cell_test).class.controller_class
|
|
50
50
|
end
|
|
51
51
|
|
|
52
|
-
context "with invoke" do
|
|
52
|
+
context "with #invoke" do
|
|
53
53
|
setup do
|
|
54
54
|
self.class.tests BassistCell
|
|
55
55
|
end
|
|
@@ -73,6 +73,24 @@ class TestCaseTest < Cell::TestCase
|
|
|
73
73
|
assert_select "a", "vd.com"
|
|
74
74
|
end
|
|
75
75
|
end
|
|
76
|
+
|
|
77
|
+
context "#setup_test_states_in" do
|
|
78
|
+
should "add the :in_view state" do
|
|
79
|
+
c = cell(:bassist, :block => lambda{"Cells rock."})
|
|
80
|
+
assert_not c.respond_to?(:in_view)
|
|
81
|
+
|
|
82
|
+
setup_test_states_in(c)
|
|
83
|
+
assert_equal "Cells rock.", c.render_state(:in_view)
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
context "#in_view" do
|
|
88
|
+
should "execute the block in a real view" do
|
|
89
|
+
content = "Cells rule."
|
|
90
|
+
@test.setup
|
|
91
|
+
assert_equal("<h1>Cells rule.</h1>", @test.in_view(:bassist) do content_tag("h1", content) end)
|
|
92
|
+
end
|
|
93
|
+
end
|
|
76
94
|
end
|
|
77
95
|
end
|
|
78
96
|
end
|
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
|
+
- 4
|
|
9
|
+
version: 3.4.4
|
|
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:
|
|
17
|
+
date: 2011-01-02 00:00:00 +01:00
|
|
18
18
|
default_executable:
|
|
19
19
|
dependencies: []
|
|
20
20
|
|
|
@@ -88,6 +88,7 @@ files:
|
|
|
88
88
|
- test/dummy/app/views/musician/hamlet.html.haml
|
|
89
89
|
- test/dummy/app/views/musician/featured.html.erb
|
|
90
90
|
- test/dummy/app/helpers/application_helper.rb
|
|
91
|
+
- test/cells_module_test.rb
|
|
91
92
|
- test/test_case_test.rb
|
|
92
93
|
- test/helper_test.rb
|
|
93
94
|
- test/cell_module_test.rb
|
|
@@ -184,6 +185,7 @@ test_files:
|
|
|
184
185
|
- test/dummy/app/views/musician/hamlet.html.haml
|
|
185
186
|
- test/dummy/app/views/musician/featured.html.erb
|
|
186
187
|
- test/dummy/app/helpers/application_helper.rb
|
|
188
|
+
- test/cells_module_test.rb
|
|
187
189
|
- test/test_case_test.rb
|
|
188
190
|
- test/helper_test.rb
|
|
189
191
|
- test/cell_module_test.rb
|