cells 3.8.8 → 3.9.0
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.
- checksums.yaml +7 -0
- data/.gitignore +2 -1
- data/.travis.yml +5 -2
- data/CHANGES.textile +23 -15
- data/Gemfile +1 -1
- data/README.md +412 -0
- data/Rakefile +2 -2
- data/cells.gemspec +5 -6
- data/gemfiles/Gemfile.rails3-0 +2 -2
- data/gemfiles/Gemfile.rails3-1 +1 -1
- data/gemfiles/Gemfile.rails3-2 +1 -2
- data/gemfiles/Gemfile.rails4-0 +7 -0
- data/lib/cell.rb +27 -0
- data/lib/cell/base.rb +31 -18
- data/lib/cell/builder.rb +11 -10
- data/lib/cell/dsl.rb +7 -0
- data/lib/cell/rack.rb +5 -9
- data/lib/cell/rails.rb +19 -11
- data/lib/cell/rails/view_model.rb +115 -0
- data/lib/cell/rails3_0_strategy.rb +1 -1
- data/lib/cell/rails3_1_strategy.rb +1 -1
- data/lib/cell/rails4_0_strategy.rb +1 -2
- data/lib/cell/test_case.rb +11 -11
- data/lib/cells.rb +4 -3
- data/lib/cells/rails.rb +16 -3
- data/lib/cells/version.rb +1 -1
- data/test/app/cells/bassist_cell.rb +9 -1
- data/test/app/cells/rails_helper_api_test/bassist/edit.html.erb +3 -3
- data/test/app/cells/song/dashboard.haml +7 -0
- data/test/app/cells/song/details.html.haml +1 -0
- data/test/app/cells/song/info.html.haml +1 -0
- data/test/app/cells/song/lyrics.html.haml +6 -0
- data/test/app/cells/song/plays.haml +1 -0
- data/test/app/cells/song/show.html.haml +3 -0
- data/test/app/cells/song/title.html.haml +1 -0
- data/test/app/cells/view_model_test/comments/show.haml +7 -0
- data/test/cell_module_test.rb +39 -41
- data/test/cell_test.rb +28 -0
- data/test/dummy/app/views/musician/featured_with_block.html.erb +1 -1
- data/test/dummy/app/views/musician/title.erb +1 -0
- data/test/dummy/config/routes.rb +1 -0
- data/test/helper_test.rb +13 -10
- data/test/rails/caching_test.rb +75 -73
- data/test/rails/cells_test.rb +25 -23
- data/test/rails/integration_test.rb +80 -61
- data/test/rails/view_model_test.rb +119 -0
- data/test/rails_helper_api_test.rb +11 -13
- metadata +41 -61
- data/README.rdoc +0 -279
- data/about.yml +0 -7
- data/test/app/cells/producer/capture.html.erb +0 -1
- data/test/app/cells/producer/content_for.html.erb +0 -2
- data/test/rails/capture_test.rb +0 -70
data/lib/cell/test_case.rb
CHANGED
|
@@ -58,36 +58,36 @@ module Cell
|
|
|
58
58
|
super(HTML::Document.new(last_invoke).root, *args, &block)
|
|
59
59
|
end
|
|
60
60
|
end
|
|
61
|
-
|
|
61
|
+
|
|
62
62
|
module CommonTestMethods
|
|
63
63
|
def setup
|
|
64
|
-
@controller
|
|
65
|
-
@request
|
|
64
|
+
@controller ||= Class.new(ActionController::Base).new
|
|
65
|
+
@request ||= ::ActionController::TestRequest.new
|
|
66
66
|
@response = ::ActionController::TestResponse.new
|
|
67
67
|
@controller.request = @request
|
|
68
68
|
@controller.response = @response
|
|
69
69
|
@controller.params = {}
|
|
70
70
|
end
|
|
71
|
-
|
|
72
|
-
# Runs the block while computing the instance variables diff from before and after.
|
|
71
|
+
|
|
72
|
+
# Runs the block while computing the instance variables diff from before and after.
|
|
73
73
|
def extract_state_ivars_for(cell)
|
|
74
74
|
before = cell.instance_variables
|
|
75
|
-
yield
|
|
75
|
+
yield
|
|
76
76
|
after = cell.instance_variables
|
|
77
|
-
|
|
77
|
+
|
|
78
78
|
Hash[(after - before).collect do |var|
|
|
79
79
|
next if var =~ /^@_/
|
|
80
80
|
[var[1, var.length].to_sym, cell.instance_variable_get(var)]
|
|
81
81
|
end.compact]
|
|
82
82
|
end
|
|
83
83
|
end
|
|
84
|
-
|
|
84
|
+
|
|
85
85
|
|
|
86
86
|
module TestMethods
|
|
87
87
|
include CommonTestMethods
|
|
88
|
-
|
|
88
|
+
|
|
89
89
|
attr_reader :last_invoke, :subject_cell, :view_assigns
|
|
90
|
-
|
|
90
|
+
|
|
91
91
|
# Use this for functional tests of your application cells.
|
|
92
92
|
#
|
|
93
93
|
# Example:
|
|
@@ -100,7 +100,7 @@ module Cell
|
|
|
100
100
|
@view_assigns = extract_state_ivars_for(@subject_cell) do
|
|
101
101
|
@last_invoke = @subject_cell.render_state(state, *args)
|
|
102
102
|
end
|
|
103
|
-
|
|
103
|
+
|
|
104
104
|
@last_invoke
|
|
105
105
|
end
|
|
106
106
|
|
data/lib/cells.rb
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
#
|
|
3
3
|
# Cells are view components for Rails. Being lightweight controllers with actions and views, cells are the
|
|
4
4
|
# answer to <tt>DoubleRenderError</tt>s and the long awaited ability to render actions within actions.
|
|
5
|
-
#
|
|
5
|
+
#
|
|
6
6
|
# == Directory structure
|
|
7
7
|
#
|
|
8
8
|
# Cells live in +app/cells/+ and have a similar file layout as controllers.
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
# box.html.erb
|
|
18
18
|
#
|
|
19
19
|
# == Cell nesting
|
|
20
|
-
#
|
|
20
|
+
#
|
|
21
21
|
# Is is good practice to split up complex cell views into multiple states or views. Remember, you can always use
|
|
22
22
|
# <tt>render :view => ...</tt> and <tt>render :state => ...</tt> in your views.
|
|
23
23
|
#
|
|
@@ -42,7 +42,7 @@
|
|
|
42
42
|
# = @item.title
|
|
43
43
|
#
|
|
44
44
|
# render :state => :order_button
|
|
45
|
-
#
|
|
45
|
+
#
|
|
46
46
|
# which is more than just a partial, as you may execute additional code in the state method.
|
|
47
47
|
#
|
|
48
48
|
# == View inheritance
|
|
@@ -72,6 +72,7 @@ module Cells
|
|
|
72
72
|
end
|
|
73
73
|
end
|
|
74
74
|
|
|
75
|
+
require 'cell'
|
|
75
76
|
require 'cell/rails'
|
|
76
77
|
require 'cells/rails'
|
|
77
78
|
require 'cell/deprecations'
|
data/lib/cells/rails.rb
CHANGED
|
@@ -3,9 +3,14 @@
|
|
|
3
3
|
module Cells
|
|
4
4
|
module Rails
|
|
5
5
|
module ActionController
|
|
6
|
+
def cell_for(name, *args, &block)
|
|
7
|
+
::Cell::Base.cell_for(name, self, *args, &block)
|
|
8
|
+
end
|
|
9
|
+
alias_method :cell, :cell_for # DISCUSS: make this configurable?
|
|
10
|
+
|
|
6
11
|
# Renders the cell state and returns the content. You may pass options here, too. They will be
|
|
7
12
|
# around in @opts.
|
|
8
|
-
#
|
|
13
|
+
#
|
|
9
14
|
# Example:
|
|
10
15
|
#
|
|
11
16
|
# @box = render_cell(:posts, :latest, :user => current_user)
|
|
@@ -41,19 +46,27 @@ module Cells
|
|
|
41
46
|
ActiveSupport::Deprecation.warn "Please pass the cell class into #expire_cell_state, as in expire_cell_state(DirectorCell, :count, :user_id => 1)"
|
|
42
47
|
cell_class = Cell::Rails.class_from_cell_name(cell_class)
|
|
43
48
|
end
|
|
44
|
-
|
|
49
|
+
|
|
45
50
|
key = cell_class.state_cache_key(state, args)
|
|
46
51
|
cell_class.expire_cache_key(key, opts)
|
|
47
52
|
end
|
|
48
53
|
end
|
|
49
54
|
|
|
50
55
|
module ActionView
|
|
56
|
+
# Returns the cell instance for +name+. You may pass arbitrary options to your
|
|
57
|
+
# cell.
|
|
58
|
+
#
|
|
59
|
+
# = cell(:song, :title => "Creeping Out Sara").render(:show)
|
|
60
|
+
def cell_for(name, *args, &block)
|
|
61
|
+
controller.cell_for(name, *args, &block)
|
|
62
|
+
end
|
|
63
|
+
alias_method :cell, :cell_for # DISCUSS: make this configurable?
|
|
64
|
+
|
|
51
65
|
# See Cells::Rails::ActionController#render_cell.
|
|
52
66
|
def render_cell(name, state, *args, &block)
|
|
53
67
|
::Cell::Rails.render_cell_for(name, state, controller, *args, &block)
|
|
54
68
|
end
|
|
55
69
|
end
|
|
56
|
-
|
|
57
70
|
end
|
|
58
71
|
end
|
|
59
72
|
|
data/lib/cells/version.rb
CHANGED
|
@@ -1,8 +1,16 @@
|
|
|
1
1
|
class BassistCell < Cell::Rails
|
|
2
|
-
def play
|
|
2
|
+
def play
|
|
3
|
+
render
|
|
4
|
+
end
|
|
3
5
|
|
|
4
6
|
def shout(args)
|
|
5
7
|
@words = args[:words]
|
|
6
8
|
render
|
|
7
9
|
end
|
|
10
|
+
|
|
11
|
+
def provoke
|
|
12
|
+
controller.config.relative_url_root = "" if Cell.rails3_0?
|
|
13
|
+
|
|
14
|
+
render
|
|
15
|
+
end
|
|
8
16
|
end
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
%h3 #{title}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
%li #{render :title}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
Plays: 99
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
= title
|
data/test/cell_module_test.rb
CHANGED
|
@@ -18,25 +18,23 @@ end
|
|
|
18
18
|
|
|
19
19
|
|
|
20
20
|
class CellBaseTest < MiniTest::Spec
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
{:host => "cells-project.org"}
|
|
28
|
-
end
|
|
29
|
-
|
|
21
|
+
it "still have a working #url_for" do
|
|
22
|
+
cell = Cell::Base.new
|
|
23
|
+
cell.instance_eval do
|
|
24
|
+
# You can use #default_url_options.
|
|
25
|
+
def default_url_options
|
|
26
|
+
{:host => "cells-project.org"}
|
|
30
27
|
end
|
|
31
|
-
|
|
32
|
-
assert_equal "http://cells-project.org/dashboard/show", cell.url_for(:action => :show, :controller => :dashboard)
|
|
28
|
+
|
|
33
29
|
end
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
30
|
+
# You could also use a *_url or *_path helper method here.
|
|
31
|
+
assert_equal "http://cells-project.org/dashboard/show", cell.url_for(:action => :show, :controller => :dashboard)
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
describe ".render_cell_for" do
|
|
35
|
+
it "invokes controller-less cell" do
|
|
36
|
+
Cell::Base.view_paths= ["test/app/cells"]
|
|
37
|
+
assert_equal "YAAAaaargh!\n", Cell::Base.render_cell_for(:shouter, :sing, "Y")
|
|
40
38
|
end
|
|
41
39
|
end
|
|
42
40
|
end
|
|
@@ -50,19 +48,19 @@ class CellModuleTest < MiniTest::Spec
|
|
|
50
48
|
it "render the actual cell" do
|
|
51
49
|
assert_equal "Doo", Cell::Rails.render_cell_for(:bassist, :play, @controller)
|
|
52
50
|
end
|
|
53
|
-
|
|
51
|
+
|
|
54
52
|
it "accept a block, passing the cell instance" do
|
|
55
53
|
flag = false
|
|
56
54
|
html = Cell::Rails.render_cell_for(:bassist, :play, @controller) do |cell|
|
|
57
55
|
assert_equal BassistCell, cell.class
|
|
58
56
|
flag = true
|
|
59
57
|
end
|
|
60
|
-
|
|
58
|
+
|
|
61
59
|
assert_equal "Doo", html
|
|
62
60
|
assert flag
|
|
63
61
|
end
|
|
64
62
|
end
|
|
65
|
-
|
|
63
|
+
|
|
66
64
|
describe "create_cell_for" do
|
|
67
65
|
it "call the cell's builders, eventually returning a different class" do
|
|
68
66
|
class DrummerCell < BassistCell
|
|
@@ -70,22 +68,22 @@ class CellModuleTest < MiniTest::Spec
|
|
|
70
68
|
BassistCell
|
|
71
69
|
end
|
|
72
70
|
end
|
|
73
|
-
|
|
71
|
+
|
|
74
72
|
assert_instance_of BassistCell, Cell::Rails.create_cell_for("cell_module_test/drummer", :play, @controller)
|
|
75
73
|
end
|
|
76
74
|
end
|
|
77
|
-
|
|
75
|
+
|
|
78
76
|
describe "#create_cell_for with #build" do
|
|
79
77
|
before do
|
|
80
78
|
@controller.class_eval do
|
|
81
79
|
attr_accessor :bassist
|
|
82
80
|
end
|
|
83
|
-
|
|
81
|
+
|
|
84
82
|
MusicianCell.build do
|
|
85
83
|
BassistCell if bassist
|
|
86
84
|
end
|
|
87
85
|
end
|
|
88
|
-
|
|
86
|
+
|
|
89
87
|
after do
|
|
90
88
|
MusicianCell.class_eval do
|
|
91
89
|
@builders = false
|
|
@@ -94,40 +92,40 @@ class CellModuleTest < MiniTest::Spec
|
|
|
94
92
|
@builders = false
|
|
95
93
|
end
|
|
96
94
|
end
|
|
97
|
-
|
|
95
|
+
|
|
98
96
|
it "execute the block in controller describe" do
|
|
99
97
|
@controller.bassist = true
|
|
100
98
|
assert_is_a BassistCell, Cell::Rails.create_cell_for(:musician, @controller)
|
|
101
99
|
end
|
|
102
|
-
|
|
100
|
+
|
|
103
101
|
it "limit the builder to the receiving class" do
|
|
104
102
|
assert_is_a PianistCell, Cell::Rails.create_cell_for(:pianist, @controller) # don't inherit anything.
|
|
105
103
|
@controller.bassist = true
|
|
106
104
|
assert_is_a BassistCell, Cell::Rails.create_cell_for(:musician, @controller)
|
|
107
105
|
end
|
|
108
|
-
|
|
106
|
+
|
|
109
107
|
it "chain build blocks and execute them by ORing them in the same order" do
|
|
110
108
|
MusicianCell.build do
|
|
111
109
|
PianistCell unless bassist
|
|
112
110
|
end
|
|
113
|
-
|
|
111
|
+
|
|
114
112
|
MusicianCell.build do
|
|
115
113
|
UnknownCell # it never be executed.
|
|
116
114
|
end
|
|
117
|
-
|
|
115
|
+
|
|
118
116
|
assert_is_a PianistCell, Cell::Rails.create_cell_for(:musician, @controller) # bassist is false.
|
|
119
117
|
@controller.bassist = true
|
|
120
118
|
assert_is_a BassistCell, Cell::Rails.create_cell_for(:musician, @controller)
|
|
121
119
|
end
|
|
122
|
-
|
|
120
|
+
|
|
123
121
|
it "use the original cell if no builder matches" do
|
|
124
122
|
assert_is_a MusicianCell, Cell::Rails.create_cell_for(:musician, @controller) # bassist is false.
|
|
125
123
|
end
|
|
126
|
-
|
|
124
|
+
|
|
127
125
|
it "stop at the first builder returning a valid cell" do
|
|
128
|
-
|
|
126
|
+
|
|
129
127
|
end
|
|
130
|
-
|
|
128
|
+
|
|
131
129
|
it "pass options to the block" do
|
|
132
130
|
BassistCell.build do |opts|
|
|
133
131
|
SingerCell if opts[:sing_the_song]
|
|
@@ -135,38 +133,38 @@ class CellModuleTest < MiniTest::Spec
|
|
|
135
133
|
assert_kind_of BassistCell, Cell::Rails.create_cell_for(:bassist, @controller, {})
|
|
136
134
|
assert_kind_of SingerCell, Cell::Rails.create_cell_for(:bassist, @controller, {:sing_the_song => true})
|
|
137
135
|
end
|
|
138
|
-
|
|
136
|
+
|
|
139
137
|
it "create the original target class if no block matches" do
|
|
140
138
|
assert_kind_of PianistCell, Cell::Rails.create_cell_for(:pianist, @controller)
|
|
141
139
|
end
|
|
142
|
-
|
|
140
|
+
|
|
143
141
|
it "builders it return an empty array per default" do
|
|
144
142
|
assert_equal [], PianistCell.send(:builders)
|
|
145
143
|
end
|
|
146
144
|
end
|
|
147
|
-
|
|
145
|
+
|
|
148
146
|
it "provide class_from_cell_name" do
|
|
149
147
|
assert_equal BassistCell, ::Cell::Rails.class_from_cell_name('bassist')
|
|
150
148
|
end
|
|
151
|
-
|
|
149
|
+
|
|
152
150
|
if Cell.rails3_0?
|
|
153
151
|
it "provide possible_paths_for_state" do
|
|
154
152
|
assert_equal ["bad_guitarist/play", "bassist/play"], cell(:bad_guitarist).send(:possible_paths_for_state, :play)
|
|
155
153
|
end
|
|
156
|
-
|
|
154
|
+
|
|
157
155
|
it "provide Cell.cell_name" do
|
|
158
156
|
assert_equal 'bassist', cell(:bassist).class.cell_name
|
|
159
157
|
end
|
|
160
|
-
|
|
158
|
+
|
|
161
159
|
it "provide cell_name for modules, too" do
|
|
162
160
|
class SingerCell < Cell::Rails
|
|
163
161
|
end
|
|
164
|
-
|
|
162
|
+
|
|
165
163
|
assert_equal "cell_module_test/singer", CellModuleTest::SingerCell.cell_name
|
|
166
164
|
end
|
|
167
165
|
end
|
|
168
166
|
end
|
|
169
|
-
|
|
167
|
+
|
|
170
168
|
it "respond to #rails3_1_or_more?" do
|
|
171
169
|
if Rails::VERSION::MAJOR == 3
|
|
172
170
|
if Rails::VERSION::MINOR == 0
|
data/test/cell_test.rb
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
require "test_helper"
|
|
2
|
+
|
|
3
|
+
class CellTest < MiniTest::Spec
|
|
4
|
+
class ArtistCell < Cell::Rails
|
|
5
|
+
end
|
|
6
|
+
class SongCell < Cell::Base
|
|
7
|
+
include Cell::OptionsConstructor
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
describe "#initialize" do
|
|
11
|
+
it { Class.new(Cell::Base) { include Cell::OptionsConstructor }.new(:song => song=Object.new).song.must_equal song }
|
|
12
|
+
it { Class.new(Cell::Rack) { include Cell::OptionsConstructor }.new(Object, :song => song=Object.new).song.must_equal song }
|
|
13
|
+
it { Class.new(Cell::Rails) { include Cell::OptionsConstructor }.new(Object, :song => song=Object.new).song.must_equal song }
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
describe "::create_cell_for" do
|
|
17
|
+
it { Cell::Base.create_cell_for("cell_test/song", :song => song=Object.new).song.must_equal song }
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
describe "#cell" do
|
|
21
|
+
it { Cell::Rails.new(Object).cell("cell_test/artist").must_be_instance_of ArtistCell }
|
|
22
|
+
it { Cell::Base.new.cell("cell_test/song").must_be_instance_of SongCell }
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
class OptionsConstructorTest < MiniTest::Spec
|
|
27
|
+
it { Class.new(Cell::Base) { include Cell::OptionsConstructor }.new(:song => song=Object.new).song.must_equal song }
|
|
28
|
+
end
|