cells 3.5.0 → 3.5.1
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/cells.gemspec +2 -2
- data/lib/cell/caching.rb +58 -75
- data/lib/cell/rails.rb +4 -5
- data/lib/cells/rails.rb +8 -3
- data/lib/cells/version.rb +1 -1
- data/test/rails/caching_test.rb +220 -151
- data/test/rails/view_test.rb +16 -0
- metadata +6 -5
data/CHANGES.textile
CHANGED
@@ -1,3 +1,11 @@
|
|
1
|
+
h2. 3.5.1
|
2
|
+
* No longer pass an explicit Proc but a versioner block to @Cell.Base.cache@. Example: @cache :show do "v1" end@
|
3
|
+
* Caching.cache_key_for now uses @ActiveSupport::Cache.expand_cache_key@. Consequently, a key which used to be like @"cells/director/count/a=1/b=2"@ now is @cells/director/count/a=1&b=2@ and so on. Be warned that this might break your home-made cache expiry.
|
4
|
+
* Controller#expire_cell_state now expects the cell class as first arg. Example: @expire_cell_state(DirectorCell, :count)@
|
5
|
+
|
6
|
+
h3. Bugfixes
|
7
|
+
* Passing options to @render :state@ in views finally works: @render({:state => :list_item}, item, i)@
|
8
|
+
|
1
9
|
h2. 3.5.0
|
2
10
|
|
3
11
|
h3. Changes
|
data/cells.gemspec
CHANGED
@@ -12,14 +12,14 @@ Gem::Specification.new do |s|
|
|
12
12
|
s.email = ["apotonick@gmail.com"]
|
13
13
|
s.homepage = "http://cells.rubyforge.org"
|
14
14
|
s.summary = %q{View Components for Rails.}
|
15
|
-
s.description = %q{Cells are
|
15
|
+
s.description = %q{Cells are view components for Rails. They are lightweight controllers, can be rendered in views and thus provide an elegant and fast way for encapsulation and component-orientation.}
|
16
16
|
|
17
17
|
s.files = `git ls-files`.split("\n")
|
18
18
|
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
19
19
|
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
20
20
|
s.require_paths = ["lib"]
|
21
21
|
|
22
|
-
s.add_dependency "rails", "~> 3.0"
|
22
|
+
s.add_dependency "rails", "~> 3.0.0"
|
23
23
|
|
24
24
|
s.add_development_dependency "shoulda"
|
25
25
|
s.add_development_dependency "haml"
|
data/lib/cell/caching.rb
CHANGED
@@ -6,59 +6,42 @@ module Cell
|
|
6
6
|
extend ActiveSupport::Concern
|
7
7
|
|
8
8
|
module ClassMethods
|
9
|
-
#
|
10
|
-
# the view will be cached forever.
|
9
|
+
# Caches the rendered view of +state+.
|
11
10
|
#
|
12
|
-
#
|
13
|
-
# This method is called every time the state is rendered, and is expected to return a
|
14
|
-
# Hash containing the cache key ingredients.
|
11
|
+
# Examples:
|
15
12
|
#
|
16
|
-
#
|
17
|
-
# Useful for simply setting a TTL for a cached state.
|
18
|
-
# Note that you may omit the <tt>version_proc</tt>.
|
13
|
+
# This will cache forever.
|
19
14
|
#
|
15
|
+
# class CartCell < Cell::Base
|
16
|
+
# cache :show
|
20
17
|
#
|
21
|
-
#
|
22
|
-
# class CachingCell < ::Cell::Base
|
23
|
-
# cache :versioned_cached_state, Proc.new{ {:version => 0} }
|
24
|
-
# would result in the complete cache key
|
25
|
-
# cells/CachingCell/versioned_cached_state/version=0
|
18
|
+
# You can also pass options to the caching engine as known from Rails caching.
|
26
19
|
#
|
27
|
-
#
|
28
|
-
# method:
|
20
|
+
# cache :show, :expires_in => 10.minutes
|
29
21
|
#
|
30
|
-
#
|
31
|
-
# cache :cached_state, :my_cache_version
|
22
|
+
# If you need your own granular cache keys, pass a versioner block.
|
32
23
|
#
|
33
|
-
#
|
34
|
-
#
|
35
|
-
#
|
36
|
-
# }
|
37
|
-
# end
|
38
|
-
# results in a very specific cache key, for customized caching:
|
39
|
-
# cells/CachingCell/cached_state/user=18/item_id=1
|
24
|
+
# cache :show do |cell|
|
25
|
+
# "user/#{cell.options[:id]}"
|
26
|
+
# end
|
40
27
|
#
|
41
|
-
#
|
28
|
+
# This will result in a cache key like <tt>cells/cart/show/user/1</tt>.
|
42
29
|
#
|
43
|
-
#
|
30
|
+
# Alternatively, use an instance method.
|
44
31
|
#
|
45
|
-
#
|
46
|
-
#
|
32
|
+
# cache :show, :versioner
|
33
|
+
# def versioner
|
34
|
+
# "user/#{options[:id]}"
|
35
|
+
# end
|
47
36
|
#
|
48
|
-
#
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
cache_opts = version_proc
|
57
|
-
version_proc = nil
|
58
|
-
end
|
59
|
-
|
60
|
-
version_procs[state] = version_proc
|
61
|
-
cache_options[state] = cache_opts
|
37
|
+
# Two things to mention here.
|
38
|
+
# * The return value of the method/block is <em>appended</em> to the state cache key.
|
39
|
+
# * You may return a string, a hash, an array, ActiveSupport::Caching will compile it.
|
40
|
+
def cache(state, *args, &block)
|
41
|
+
options = args.extract_options!
|
42
|
+
|
43
|
+
version_procs[state] = args.first || block
|
44
|
+
cache_options[state] = options
|
62
45
|
end
|
63
46
|
|
64
47
|
def version_procs
|
@@ -69,55 +52,55 @@ module Cell
|
|
69
52
|
@cache_options ||= {}
|
70
53
|
end
|
71
54
|
|
72
|
-
def cache_store
|
55
|
+
def cache_store
|
56
|
+
# DISCUSS: move to instance level and delegate to #config/#parent_controller.
|
57
|
+
# This would allow convenient cache settings per cell (if needed).
|
73
58
|
::ActionController::Base.cache_store
|
74
59
|
end
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
args.collect{|a,b| [a.to_s, b]}.sort.each{ |k,v| key_pieces << "#{k}=#{v}" }
|
80
|
-
key = key_pieces.join('/')
|
81
|
-
|
82
|
-
::ActiveSupport::Cache.expand_cache_key(key, :cells)
|
60
|
+
|
61
|
+
# Computes the complete, namespaced cache key for +state+.
|
62
|
+
def state_cache_key(state, key_parts={})
|
63
|
+
expand_cache_key([cell_name, state, key_parts])
|
83
64
|
end
|
84
65
|
|
85
|
-
def expire_cache_key(key,
|
86
|
-
cache_store.delete(key,
|
66
|
+
def expire_cache_key(key, *args)
|
67
|
+
cache_store.delete(key, *args)
|
87
68
|
end
|
88
|
-
|
89
|
-
def
|
90
|
-
|
69
|
+
|
70
|
+
def cache?(state)
|
71
|
+
# DISCUSS: why is it private?
|
72
|
+
ActionController::Base.send(:cache_configured?) and state_cached?(state)
|
73
|
+
end
|
74
|
+
|
75
|
+
protected
|
76
|
+
# Compiles cache key and adds :cells namespace to +key+, according to the
|
77
|
+
# ActiveSupport::Cache.expand_cache_key API.
|
78
|
+
def expand_cache_key(key)
|
79
|
+
::ActiveSupport::Cache.expand_cache_key(key, :cells)
|
80
|
+
end
|
81
|
+
|
82
|
+
def state_cached?(state)
|
83
|
+
version_procs.has_key?(state)
|
91
84
|
end
|
92
85
|
end
|
93
86
|
|
94
87
|
def render_state(state, *args)
|
95
|
-
return super(state, *args) unless
|
96
|
-
|
97
|
-
key =
|
88
|
+
return super(state, *args) unless self.class.cache?(state)
|
89
|
+
|
90
|
+
key = self.class.state_cache_key(state, call_state_versioner(state))
|
98
91
|
options = self.class.cache_options[state]
|
99
|
-
|
92
|
+
|
100
93
|
self.class.cache_store.fetch(key, options) do
|
101
94
|
super(state, *args)
|
102
95
|
end
|
103
96
|
end
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
return {} unless version_proc # call to #cache was without any args.
|
110
|
-
|
97
|
+
|
98
|
+
def call_state_versioner(state)
|
99
|
+
version_proc = self.class.version_procs[state] or return
|
100
|
+
|
111
101
|
return version_proc.call(self) if version_proc.kind_of?(Proc)
|
112
102
|
send(version_proc)
|
113
103
|
end
|
114
|
-
|
115
|
-
def cache_key(state, args = {}) #:nodoc:
|
116
|
-
self.class.cache_key_for(self.class.cell_name, state, args)
|
117
|
-
end
|
118
|
-
|
119
|
-
def state_cached?(state)
|
120
|
-
self.class.version_procs.has_key?(state)
|
121
|
-
end
|
104
|
+
|
122
105
|
end
|
123
106
|
end
|
data/lib/cell/rails.rb
CHANGED
@@ -10,11 +10,10 @@ module Cell
|
|
10
10
|
|
11
11
|
|
12
12
|
class View < ActionView::Base
|
13
|
-
def render(
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
13
|
+
def render(*args, &block)
|
14
|
+
options = args.first.is_a?(::Hash) ? args.first : {} # this is copied from #render by intention.
|
15
|
+
|
16
|
+
return controller.render(*args, &block) if options[:state] or options[:view]
|
18
17
|
super
|
19
18
|
end
|
20
19
|
end
|
data/lib/cells/rails.rb
CHANGED
@@ -36,9 +36,14 @@ module Cells
|
|
36
36
|
# end
|
37
37
|
#
|
38
38
|
# will expire the view for state <tt>:display_list</tt> in the cell <tt>MyListingCell</tt>.
|
39
|
-
def expire_cell_state(
|
40
|
-
|
41
|
-
|
39
|
+
def expire_cell_state(cell_class, state, args={}, opts=nil)
|
40
|
+
if cell_class.is_a?(Symbol)
|
41
|
+
ActiveSupport::Deprecation.warn "Please pass the cell class into #expire_cell_state, as in expire_cell_state(DirectorCell, :count, :user_id => 1)"
|
42
|
+
cell_class = Cell::Base.class_from_cell_name(cell_class)
|
43
|
+
end
|
44
|
+
|
45
|
+
key = cell_class.state_cache_key(state, args)
|
46
|
+
cell_class.expire_cache_key(key, opts)
|
42
47
|
end
|
43
48
|
end
|
44
49
|
|
data/lib/cells/version.rb
CHANGED
data/test/rails/caching_test.rb
CHANGED
@@ -1,203 +1,272 @@
|
|
1
1
|
require 'test_helper'
|
2
2
|
|
3
3
|
class DirectorCell < Cell::Rails
|
4
|
-
|
4
|
+
attr_reader :count
|
5
5
|
|
6
|
-
|
7
|
-
|
6
|
+
def initialize(*)
|
7
|
+
super
|
8
|
+
@count = 0
|
9
|
+
end
|
8
10
|
|
9
|
-
|
10
|
-
|
11
|
+
cache :tock
|
12
|
+
def tock
|
13
|
+
@count += 1
|
14
|
+
render :text => @count
|
11
15
|
end
|
16
|
+
end
|
17
|
+
|
18
|
+
class CachingUnitTest < ActiveSupport::TestCase
|
19
|
+
include Cell::TestCase::TestMethods
|
12
20
|
|
13
|
-
|
14
|
-
|
21
|
+
setup do
|
22
|
+
ActionController::Base.cache_store.clear
|
23
|
+
ActionController::Base.perform_caching = true
|
24
|
+
@cell = cell(:director)
|
25
|
+
@class = @cell.class
|
15
26
|
end
|
16
27
|
|
17
|
-
|
18
|
-
|
28
|
+
|
29
|
+
context ".state_cache_key" do
|
30
|
+
should "accept state only" do
|
31
|
+
assert_equal "cells/director/count/", @class.state_cache_key(:count)
|
32
|
+
end
|
33
|
+
|
34
|
+
should "accept hash as key parts" do
|
35
|
+
assert_equal "cells/director/count/a=1&b=2", @class.state_cache_key(:count, :b=>2, :a=>1)
|
36
|
+
end
|
37
|
+
|
38
|
+
should "accept array as key parts" do
|
39
|
+
assert_equal "cells/director/count/1/2/3", @class.state_cache_key(:count, [1,2,3])
|
40
|
+
end
|
41
|
+
|
42
|
+
should "accept string as key parts" do
|
43
|
+
assert_equal "cells/director/count/1/2", @class.state_cache_key(:count, "1/2")
|
44
|
+
end
|
45
|
+
|
46
|
+
should "accept nil as key parts" do
|
47
|
+
assert_equal "cells/director/count/", @class.state_cache_key(:count, nil)
|
48
|
+
end
|
19
49
|
end
|
20
50
|
|
21
|
-
def count
|
22
|
-
render :text => increment!
|
23
|
-
end
|
24
|
-
end
|
25
|
-
|
26
|
-
class CachingTest < ActiveSupport::TestCase
|
27
|
-
include Cell::TestCase::TestMethods
|
28
51
|
|
29
|
-
context "
|
30
|
-
|
31
|
-
|
52
|
+
context ".expand_cache_key" do
|
53
|
+
should "add :cells namespace" do
|
54
|
+
assert_equal "cells/director/count", @class.send(:expand_cache_key, [:director, :count])
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
|
59
|
+
context ".state_cached?" do
|
60
|
+
should "return true for cached" do
|
61
|
+
assert @class.send :state_cached?, :count
|
32
62
|
end
|
33
63
|
|
34
|
-
should "
|
35
|
-
|
36
|
-
assert_equal 1, DirectorCell.increment!
|
37
|
-
assert_equal 1, DirectorCell.counter
|
64
|
+
should "return false otherwise" do
|
65
|
+
assert_not @class.send :state_cached?, :sing
|
38
66
|
end
|
39
67
|
end
|
40
68
|
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
DirectorCell.reset!
|
69
|
+
|
70
|
+
context ".cache?" do
|
71
|
+
should "return true for cached" do
|
72
|
+
assert @cell.class.cache?(:count)
|
46
73
|
end
|
47
74
|
|
48
|
-
should "
|
49
|
-
|
50
|
-
assert_not cell(:director).state_cached?(:sing)
|
75
|
+
should "return false otherwise" do
|
76
|
+
assert_not @cell.class.cache?(:sing)
|
51
77
|
end
|
52
78
|
|
53
|
-
context "
|
54
|
-
|
55
|
-
|
79
|
+
context "perform_caching turned off" do
|
80
|
+
teardown do
|
81
|
+
::ActionController::Base.perform_caching = true
|
56
82
|
end
|
57
83
|
|
58
|
-
should "
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
assert_equal({}, cell(:director).class.cache_options[:count])
|
84
|
+
should "always return false if caching turned-off" do
|
85
|
+
::ActionController::Base.perform_caching = false
|
86
|
+
assert_not @cell.class.cache?(:count)
|
87
|
+
assert_not @cell.class.cache?(:sing)
|
63
88
|
end
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
|
93
|
+
context ".expire_cache_key" do
|
94
|
+
setup do
|
95
|
+
@key = @class.state_cache_key(:tock)
|
96
|
+
assert_equal "1", render_cell(:director, :tock)
|
97
|
+
assert_equal "1", @class.cache_store.read(@key)
|
98
|
+
end
|
99
|
+
|
100
|
+
should "delete the state from cache" do
|
101
|
+
@class.expire_cache_key(@key)
|
102
|
+
assert_not @class.cache_store.read(@key)
|
103
|
+
end
|
104
|
+
|
105
|
+
should "be available in controllers for sweepers" do
|
106
|
+
MusicianController.new.expire_cell_state(DirectorCell, :tock)
|
107
|
+
assert_not @class.cache_store.read(@key)
|
108
|
+
end
|
109
|
+
|
110
|
+
should "accept cache options" do
|
111
|
+
key = @class.state_cache_key(:tock, :volume => 9)
|
112
|
+
assert Cell::Base.cache_store.write(key, 'ONE!')
|
113
|
+
|
114
|
+
MusicianController.new.expire_cell_state(DirectorCell, :tock, :volume => 9)
|
115
|
+
assert_equal "1", @class.cache_store.read(@key)
|
116
|
+
assert_not ::Cell::Base.cache_store.read(key)
|
117
|
+
end
|
118
|
+
|
119
|
+
should "raise a deprecation notice when passing in a :symbol" do
|
120
|
+
assert_deprecated do
|
121
|
+
MusicianController.new.expire_cell_state(:director, :tock)
|
70
122
|
end
|
123
|
+
assert_not @class.cache_store.read(@key)
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
|
128
|
+
context ".cache" do
|
129
|
+
setup do
|
130
|
+
@proc = Proc.new{}
|
131
|
+
end
|
132
|
+
|
133
|
+
should "accept a state name, only" do
|
134
|
+
@class.cache :count
|
71
135
|
|
72
|
-
|
73
|
-
|
74
|
-
class SecondDirectorCell < DirectorCell; end
|
75
|
-
SecondDirectorCell.cache :count, @proc
|
76
|
-
|
77
|
-
assert_equal nil, cell(:director).class.version_procs[:count]
|
78
|
-
assert_equal @proc, cell(:"caching_test/second_director").class.version_procs[:count]
|
79
|
-
end
|
136
|
+
assert_not @class.version_procs[:count]
|
137
|
+
assert_equal({}, @class.cache_options[:count])
|
80
138
|
end
|
81
139
|
|
82
|
-
|
83
|
-
|
84
|
-
key = cell(:director).cache_key(:count, :count => 0)
|
85
|
-
Cell::Base.expire_cache_key(key) ### TODO: separate test
|
86
|
-
end
|
140
|
+
should "accept state and cache options" do
|
141
|
+
@class.cache :count, :expires_in => 10.minutes
|
87
142
|
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
143
|
+
assert_not @class.version_procs[:count]
|
144
|
+
assert_equal({:expires_in => 10.minutes}, @class.cache_options[:count])
|
145
|
+
end
|
146
|
+
|
147
|
+
should "accept args and versioner block" do
|
148
|
+
@class.cache :count, :expires_in => 10.minutes do "v1" end
|
149
|
+
|
150
|
+
assert_kind_of Proc, @class.version_procs[:count]
|
151
|
+
assert_equal({:expires_in => 10.minutes}, @class.cache_options[:count])
|
152
|
+
end
|
153
|
+
|
154
|
+
should "stil accept a versioner proc, only" do
|
155
|
+
@class.cache :count, @proc
|
99
156
|
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
assert_equal "1", render_cell(:director, :dictate)
|
108
|
-
assert_equal "2", render_cell(:director, :dictate)
|
109
|
-
end
|
157
|
+
assert_equal @proc, @class.version_procs[:count]
|
158
|
+
assert_equal({}, @class.cache_options[:count])
|
159
|
+
end
|
160
|
+
|
161
|
+
should "stil accept a versioner block" do
|
162
|
+
@class.cache :count do "v1" end
|
110
163
|
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
end
|
120
|
-
end
|
121
|
-
DirectorCell.reset!
|
122
|
-
|
123
|
-
assert_equal "1", render_cell(:director, :count)
|
124
|
-
assert_equal "1", render_cell(:director, :count) # cached.
|
125
|
-
|
126
|
-
DirectorCell.counter = 2 # invalidates the view cache.
|
127
|
-
assert_equal "3", render_cell(:director, :count)
|
128
|
-
assert_equal "3", render_cell(:director, :count) # cached.
|
129
|
-
end
|
164
|
+
assert_kind_of Proc, @class.version_procs[:count]
|
165
|
+
assert_equal({}, @class.cache_options[:count])
|
166
|
+
end
|
167
|
+
|
168
|
+
should "not inherit caching configuration" do
|
169
|
+
@class.cache :count
|
170
|
+
klass = Class.new(@class)
|
171
|
+
klass.cache :count, @proc
|
130
172
|
|
131
|
-
|
132
|
-
|
133
|
-
cache :count, :expire_count
|
134
|
-
|
135
|
-
def expire_count
|
136
|
-
self.class.counter >= 2 ? {:count => 2} : {:count => 0}
|
137
|
-
end
|
138
|
-
|
139
|
-
def count
|
140
|
-
render :text => increment!
|
141
|
-
end
|
142
|
-
end
|
143
|
-
DirectorCell.reset!
|
144
|
-
|
145
|
-
assert_equal "1", render_cell(:director, :count)
|
146
|
-
assert_equal "1", render_cell(:director, :count) # cached.
|
147
|
-
|
148
|
-
DirectorCell.counter = 2 # invalidates the view cache.
|
149
|
-
assert_equal "3", render_cell(:director, :count)
|
150
|
-
assert_equal "3", render_cell(:director, :count) # cached.
|
151
|
-
end
|
173
|
+
assert_not cell(:director).class.version_procs[:count]
|
174
|
+
assert_equal @proc, klass.version_procs[:count]
|
152
175
|
end
|
153
176
|
end
|
177
|
+
end
|
154
178
|
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
179
|
+
class CachingFunctionalTest < ActiveSupport::TestCase
|
180
|
+
include Cell::TestCase::TestMethods
|
181
|
+
|
182
|
+
setup do
|
183
|
+
ActionController::Base.cache_store.clear
|
184
|
+
ActionController::Base.perform_caching = true
|
185
|
+
setup # from Cell::TestCase::TestMethods
|
159
186
|
|
160
|
-
|
161
|
-
|
162
|
-
|
187
|
+
@cell = cell(:director)
|
188
|
+
@class = @cell.class
|
189
|
+
end
|
190
|
+
|
191
|
+
context "turned off" do
|
192
|
+
should "not invoke caching" do
|
193
|
+
::ActionController::Base.perform_caching = false
|
194
|
+
|
195
|
+
assert_equal "1", @cell.render_state(:tock)
|
196
|
+
assert_equal "2", @cell.render_state(:tock)
|
163
197
|
end
|
164
|
-
|
165
|
-
|
166
|
-
|
198
|
+
end
|
199
|
+
|
200
|
+
|
201
|
+
context "without options" do
|
202
|
+
should "cache forever" do
|
203
|
+
@class.cache :tock
|
204
|
+
assert_equal "1", render_cell(:director, :tock)
|
205
|
+
assert_equal "1", render_cell(:director, :tock)
|
167
206
|
end
|
168
207
|
end
|
169
208
|
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
def
|
175
|
-
|
209
|
+
|
210
|
+
context "uncached states" do
|
211
|
+
should "not cache at all" do
|
212
|
+
@class.class_eval do
|
213
|
+
def dictate
|
214
|
+
@count ||= 0
|
215
|
+
render :text => (@count += 1)
|
176
216
|
end
|
177
217
|
end
|
178
|
-
DirectorCell.reset!
|
179
218
|
|
180
|
-
|
181
|
-
|
182
|
-
|
219
|
+
assert_equal "1", @cell.render_state(:dictate)
|
220
|
+
assert_equal "2", @cell.render_state(:dictate)
|
221
|
+
end
|
222
|
+
end
|
223
|
+
|
224
|
+
context "with versioner" do
|
225
|
+
setup do
|
226
|
+
@class.class_eval do
|
227
|
+
def count(i)
|
228
|
+
render :text => i
|
229
|
+
end
|
230
|
+
end
|
183
231
|
end
|
184
232
|
|
185
|
-
should "
|
186
|
-
|
187
|
-
|
233
|
+
should "compute the key with the proc" do
|
234
|
+
@class.cache :count do |cell|
|
235
|
+
(cell.options % 2)==0 ? {:count => "even"} : {:count => "odd"}
|
236
|
+
end
|
237
|
+
# example cache key: cells/director/count/count=odd
|
238
|
+
|
239
|
+
assert_equal "1", render_cell(:director, :count, 1)
|
240
|
+
assert_equal "2", render_cell(:director, :count, 2)
|
241
|
+
assert_equal "1", render_cell(:director, :count, 3)
|
242
|
+
assert_equal "2", render_cell(:director, :count, 4)
|
188
243
|
end
|
189
244
|
|
190
|
-
should "
|
191
|
-
|
192
|
-
|
245
|
+
should "compute the key with an instance method" do
|
246
|
+
@class.cache :count, :version
|
247
|
+
@class.class_eval do
|
248
|
+
def version
|
249
|
+
(options % 3)==0 ? {:count => "even"} : {:count => "odd"}
|
250
|
+
end
|
251
|
+
end
|
252
|
+
|
253
|
+
assert_equal "1", render_cell(:director, :count, 1)
|
254
|
+
assert_equal "1", render_cell(:director, :count, 2)
|
255
|
+
assert_equal "3", render_cell(:director, :count, 3)
|
256
|
+
assert_equal "1", render_cell(:director, :count, 4)
|
257
|
+
assert_equal "1", render_cell(:director, :count, 5)
|
258
|
+
assert_equal "3", render_cell(:director, :count, 6)
|
193
259
|
end
|
194
260
|
|
195
|
-
should "
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
261
|
+
should "allow returning strings, too" do
|
262
|
+
@class.cache :count do |cell|
|
263
|
+
(cell.options % 2)==0 ? "even" : "odd"
|
264
|
+
end
|
265
|
+
|
266
|
+
assert_equal "1", render_cell(:director, :count, 1)
|
267
|
+
assert_equal "2", render_cell(:director, :count, 2)
|
268
|
+
assert_equal "1", render_cell(:director, :count, 3)
|
269
|
+
assert_equal "2", render_cell(:director, :count, 4)
|
201
270
|
end
|
202
271
|
end
|
203
272
|
end
|
data/test/rails/view_test.rb
CHANGED
@@ -18,5 +18,21 @@ class RailsViewTest < ActiveSupport::TestCase
|
|
18
18
|
end
|
19
19
|
end
|
20
20
|
|
21
|
+
should "respond to render :state" do
|
22
|
+
assert_equal("Doo", in_view(:bassist) do
|
23
|
+
render :state => :play
|
24
|
+
end)
|
25
|
+
end
|
26
|
+
|
27
|
+
should "respond to render :state with options" do
|
28
|
+
BassistCell.class_eval do
|
29
|
+
def listen(*args)
|
30
|
+
render :text => "Listening to #{args.join(' ')}"
|
31
|
+
end
|
32
|
+
end
|
33
|
+
assert_equal("Listening to Much the Same", in_view(:bassist) do
|
34
|
+
render({:state => :listen}, "Much", "the", "Same")
|
35
|
+
end)
|
36
|
+
end
|
21
37
|
end
|
22
38
|
end
|
metadata
CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
|
|
5
5
|
segments:
|
6
6
|
- 3
|
7
7
|
- 5
|
8
|
-
-
|
9
|
-
version: 3.5.
|
8
|
+
- 1
|
9
|
+
version: 3.5.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: 2011-02-
|
17
|
+
date: 2011-02-10 00:00:00 +01:00
|
18
18
|
default_executable:
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|
@@ -28,7 +28,8 @@ dependencies:
|
|
28
28
|
segments:
|
29
29
|
- 3
|
30
30
|
- 0
|
31
|
-
|
31
|
+
- 0
|
32
|
+
version: 3.0.0
|
32
33
|
type: :runtime
|
33
34
|
version_requirements: *id001
|
34
35
|
- !ruby/object:Gem::Dependency
|
@@ -57,7 +58,7 @@ dependencies:
|
|
57
58
|
version: "0"
|
58
59
|
type: :development
|
59
60
|
version_requirements: *id003
|
60
|
-
description: Cells are
|
61
|
+
description: Cells are view components for Rails. They are lightweight controllers, can be rendered in views and thus provide an elegant and fast way for encapsulation and component-orientation.
|
61
62
|
email:
|
62
63
|
- apotonick@gmail.com
|
63
64
|
executables: []
|