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.
@@ -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
@@ -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 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.}
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"
@@ -6,59 +6,42 @@ module Cell
6
6
  extend ActiveSupport::Concern
7
7
 
8
8
  module ClassMethods
9
- # Activate caching for the state <tt>state</tt>. If no other options are passed
10
- # the view will be cached forever.
9
+ # Caches the rendered view of +state+.
11
10
  #
12
- # You may pass a Proc or a Symbol as cache expiration <tt>version_proc</tt>.
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
- # Additional options will be passed directly to the cache store when caching the state.
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
- # Example:
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
- # If you provide a symbol, you can access the cell instance directly in the versioning
28
- # method:
20
+ # cache :show, :expires_in => 10.minutes
29
21
  #
30
- # class CachingCell < ::Cell::Base
31
- # cache :cached_state, :my_cache_version
22
+ # If you need your own granular cache keys, pass a versioner block.
32
23
  #
33
- # def my_cache_version
34
- # { :user => current_user.id,
35
- # :item_id => params[:item] }
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
- # You may also set a TTL only, e.g. when using the memcached store:
28
+ # This will result in a cache key like <tt>cells/cart/show/user/1</tt>.
42
29
  #
43
- # cache :cached_state, :expires_in => 3.minutes
30
+ # Alternatively, use an instance method.
44
31
  #
45
- # Or use both, having a versioning proc <em>and</em> a TTL expiring the state as a fallback
46
- # after a certain amount of time.
32
+ # cache :show, :versioner
33
+ # def versioner
34
+ # "user/#{options[:id]}"
35
+ # end
47
36
  #
48
- # cache :cached_state, Proc.new { {:version => 0} }, :expires_in => 10.minutes
49
- #--
50
- ### TODO: implement for string, nil.
51
- ### DISCUSS: introduce return method #sweep ? so the Proc can explicitly
52
- ### delegate re-rendering to the outside.
53
- #--
54
- def cache(state, version_proc=nil, cache_opts={})
55
- if version_proc.is_a?(Hash)
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 #:nodoc:
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
- def cache_key_for(cell_class, state, args = {}) #:nodoc:
77
- key_pieces = [cell_class, state]
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, opts=nil)
86
- cache_store.delete(key, opts)
66
+ def expire_cache_key(key, *args)
67
+ cache_store.delete(key, *args)
87
68
  end
88
-
89
- def cache_configured?
90
- ::ActionController::Base.cache_configured?
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 state_cached?(state)
96
-
97
- key = cache_key(state, call_version_proc_for_state(state))
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
- # Call the versioning Proc for the respective state.
106
- def call_version_proc_for_state(state)
107
- version_proc = self.class.version_procs[state]
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
@@ -10,11 +10,10 @@ module Cell
10
10
 
11
11
 
12
12
  class View < ActionView::Base
13
- def render(options = {}, locals = {}, &block)
14
- if options[:state] or options[:view]
15
- return @_controller.render(options, &block)
16
- end
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
@@ -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(cell_name, state, args={}, opts=nil)
40
- key = ::Cell::Base.cache_key_for(cell_name, state, args)
41
- ::Cell::Base.expire_cache_key(key, opts)
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
 
@@ -1,3 +1,3 @@
1
1
  module Cells
2
- VERSION = '3.5.0'
2
+ VERSION = '3.5.1'
3
3
  end
@@ -1,203 +1,272 @@
1
1
  require 'test_helper'
2
2
 
3
3
  class DirectorCell < Cell::Rails
4
- cache :count
4
+ attr_reader :count
5
5
 
6
- @@counter = 0
7
- cattr_accessor :counter
6
+ def initialize(*)
7
+ super
8
+ @count = 0
9
+ end
8
10
 
9
- def self.increment!
10
- @@counter += 1
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
- def self.reset!
14
- @@counter = 0
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
- def increment!
18
- self.class.increment!
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 "The DirectorCell" do
30
- setup do
31
- DirectorCell.reset!
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 "respond to #increment" do
35
- assert_equal 0, DirectorCell.counter
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
- context "A cell" do
42
- setup do
43
- ::ActionController::Base.cache_store = :memory_store
44
- ::ActionController::Base.perform_caching = true
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 "respond to state_cached?" do
49
- assert cell(:director).state_cached?(:count)
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 "caching a state" do
54
- setup do
55
- @proc = Proc.new{}
79
+ context "perform_caching turned off" do
80
+ teardown do
81
+ ::ActionController::Base.perform_caching = true
56
82
  end
57
83
 
58
- should "save the version proc" do
59
- DirectorCell.cache :count, @proc
60
-
61
- assert_equal @proc, cell(:director).class.version_procs[:count]
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
- should "save the cache options" do
66
- DirectorCell.cache :count, @proc, :expires_in => 10.minutes
67
-
68
- assert_equal @proc, cell(:director).class.version_procs[:count]
69
- assert_equal({:expires_in => 10.minutes}, cell(:director).class.cache_options[:count])
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
- should "not mix caching configuration with other classes" do
73
- DirectorCell.cache :count
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
- context "caching without options" do
83
- setup do
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
- should "cache forever" do
89
- DirectorCell.class_eval do
90
- cache :count
91
- end
92
-
93
- assert cell(:director).state_cached?(:count)
94
- assert_equal nil, cell(:director).class.version_procs[:count]
95
- assert_equal({}, cell(:director).class.cache_options[:count])
96
-
97
- assert_equal render_cell(:director, :count), render_cell(:director, :count)
98
- end
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
- should "not cache at all" do
101
- DirectorCell.class_eval do
102
- def dictate
103
- render :text => increment!
104
- end
105
- end
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
- should "expire the cache with a version proc" do
112
- DirectorCell.class_eval do
113
- cache :count, Proc.new { |cell|
114
- cell.class.counter >= 2 ? {:count => 2} : {:count => 0}
115
- }
116
-
117
- def count
118
- render :text => increment!
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
- should "expire the cache with an instance method" do
132
- DirectorCell.class_eval do
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
- context "cache_key" do
156
- setup do
157
- @cell = cell(:director)
158
- end
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
- should "respond to cache_key" do
161
- assert_equal "cells/director/count", @cell.cache_key(:count)
162
- assert_equal @cell.cache_key(:count), ::Cell::Base.cache_key_for(:director, :count)
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
- should "order options lexically" do
166
- assert_equal "cells/director/count/a=1/b=2", @cell.cache_key(:count, :b => 2, :a => 1)
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
- context "expire_cache_key" do
171
- setup do
172
- DirectorCell.class_eval do
173
- cache :count
174
- def count
175
- render :text => increment!
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
- @key = cell(:director).cache_key(:count)
181
- render_cell(:director, :count)
182
- assert_equal "1", ::Cell::Base.cache_store.read(@key)
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 "delete the view from cache" do
186
- ::Cell::Base.expire_cache_key(@key)
187
- assert_not ::Cell::Base.cache_store.read(@key)
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 "be available in controllers for sweepers" do
191
- MusicianController.new.expire_cell_state(:director, :count)
192
- assert_not ::Cell::Base.cache_store.read(@key)
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 "accept cache options" do
196
- key = cell(:director).cache_key(:count, :volume => 9)
197
- assert ::Cell::Base.cache_store.write(key, 'ONE!')
198
-
199
- MusicianController.new.expire_cell_state(:director, :count, :volume => 9)
200
- assert_not ::Cell::Base.cache_store.read(key)
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
@@ -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
- - 0
9
- version: 3.5.0
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-05 00:00:00 +01:00
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
- version: "3.0"
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 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
+ 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: []