cells 3.4.0.beta1 → 3.4.0.beta2

Sign up to get free protection for your applications and to get access to all the features.
data/Gemfile CHANGED
@@ -1,6 +1,10 @@
1
1
  source :gemcutter
2
- #gem "rails" , :git => "http://github.com/rails/rails.git"
3
2
  gem 'sqlite3-ruby', '1.2.5', :require => 'sqlite3' # needed in router_test, whatever.
4
3
 
5
- gem "rails" , :path => "/home/nick/projects/rails"
6
- #gem "railties"
4
+ #gem "rails" , :path => "/home/nick/projects/rails"
5
+ gem "rails" #, :git => "http://github.com/rails/rails.git"
6
+ gem "haml"
7
+
8
+ group :test do
9
+ gem "shoulda"
10
+ end
@@ -0,0 +1,77 @@
1
+ GEM
2
+ remote: http://rubygems.org/
3
+ specs:
4
+ abstract (1.0.0)
5
+ actionmailer (3.0.0)
6
+ actionpack (= 3.0.0)
7
+ mail (~> 2.2.5)
8
+ actionpack (3.0.0)
9
+ activemodel (= 3.0.0)
10
+ activesupport (= 3.0.0)
11
+ builder (~> 2.1.2)
12
+ erubis (~> 2.6.6)
13
+ i18n (~> 0.4.1)
14
+ rack (~> 1.2.1)
15
+ rack-mount (~> 0.6.12)
16
+ rack-test (~> 0.5.4)
17
+ tzinfo (~> 0.3.23)
18
+ activemodel (3.0.0)
19
+ activesupport (= 3.0.0)
20
+ builder (~> 2.1.2)
21
+ i18n (~> 0.4.1)
22
+ activerecord (3.0.0)
23
+ activemodel (= 3.0.0)
24
+ activesupport (= 3.0.0)
25
+ arel (~> 1.0.0)
26
+ tzinfo (~> 0.3.23)
27
+ activeresource (3.0.0)
28
+ activemodel (= 3.0.0)
29
+ activesupport (= 3.0.0)
30
+ activesupport (3.0.0)
31
+ arel (1.0.1)
32
+ activesupport (~> 3.0.0)
33
+ builder (2.1.2)
34
+ erubis (2.6.6)
35
+ abstract (>= 1.0.0)
36
+ haml (3.0.15)
37
+ i18n (0.4.1)
38
+ mail (2.2.5)
39
+ activesupport (>= 2.3.6)
40
+ mime-types
41
+ treetop (>= 1.4.5)
42
+ mime-types (1.16)
43
+ polyglot (0.3.1)
44
+ rack (1.2.1)
45
+ rack-mount (0.6.13)
46
+ rack (>= 1.0.0)
47
+ rack-test (0.5.4)
48
+ rack (>= 1.0)
49
+ rails (3.0.0)
50
+ actionmailer (= 3.0.0)
51
+ actionpack (= 3.0.0)
52
+ activerecord (= 3.0.0)
53
+ activeresource (= 3.0.0)
54
+ activesupport (= 3.0.0)
55
+ bundler (~> 1.0.0)
56
+ railties (= 3.0.0)
57
+ railties (3.0.0)
58
+ actionpack (= 3.0.0)
59
+ activesupport (= 3.0.0)
60
+ rake (>= 0.8.4)
61
+ thor (~> 0.14.0)
62
+ rake (0.8.7)
63
+ shoulda (2.11.3)
64
+ sqlite3-ruby (1.2.5)
65
+ thor (0.14.0)
66
+ treetop (1.4.8)
67
+ polyglot (>= 0.3.1)
68
+ tzinfo (0.3.23)
69
+
70
+ PLATFORMS
71
+ ruby
72
+
73
+ DEPENDENCIES
74
+ haml
75
+ rails
76
+ shoulda
77
+ sqlite3-ruby (= 1.2.5)
@@ -8,7 +8,9 @@ Say you're writing a Rails online shop - the shopping cart is reappearing again
8
8
 
9
9
  No. That sucks. Take Cells.
10
10
 
11
- Cells are View Components for Rails. They look and feel like controllers. They don't have no +DoubleRenderError+. They are callable everywhere in your controllers or views. They are cacheable, testable, fast and wonderful. They bring back OOP to your view and improve your software design.
11
+ Cells are View Components for Rails. They look and feel like controllers. They don't have no +DoubleRenderError+. They can be rendered everywhere in your controllers or views. They are cacheable, testable, fast and wonderful. They bring back OOP to your view and improve your software design.
12
+
13
+ And the best: You can have as many cells in your page as you need!
12
14
 
13
15
  == Installation
14
16
 
@@ -16,11 +18,11 @@ It's a gem!
16
18
 
17
19
  Rails 3:
18
20
 
19
- gem install cells
21
+ gem install cells --pre
20
22
 
21
23
  Rails 2.3:
22
24
 
23
- gem install cells --version 3.3.4
25
+ gem install cells
24
26
 
25
27
 
26
28
  == Generate
@@ -51,7 +53,8 @@ Time to improve our cell code. Let's start with <tt>app/cells/shopping_cart_cell
51
53
 
52
54
  class ShoppingCartCell < Cell::Rails
53
55
  def display
54
- @items = @opts[:user].items_in_cart
56
+ user = @opts[:user] # @opts exposes options passed to #render_cell.
57
+ @items = user.items_in_cart
55
58
 
56
59
  render # renders display.html.erb
57
60
  end
@@ -118,7 +121,8 @@ That's easy, clean and strongly improves your component-driven software quality.
118
121
  == More features
119
122
 
120
123
  Cells can do more.
121
-
124
+
125
+ <b>No Limits</b>:: Have as many cells in your page as you need - no limitation to your +render_cell+ calls.
122
126
  <b>View Inheritance</b>:: Inherit view files dynamically from parent cells.
123
127
  <b>Cell Nesting</b>:: Have complex cell hierarchies as you can call +render_cell+ within cells, too.
124
128
 
@@ -1,25 +1,10 @@
1
- # encoding: utf-8
2
-
3
- # To improve performance rendered state views can be cached using Rails' caching
4
- # mechanism.
5
- # If this it configured (e.g. using our fast friend memcached) all you have to do is to
6
- # tell Cells which state to cache. You can further attach a proc to expire the
7
- # cached view.
8
- #
9
- # As always I stole a lot of code, this time from Lance Ivy <cainlevy@gmail.com> and
10
- # his fine components plugin at http://github.com/cainlevy/components.
1
+ require 'active_support/concern'
2
+ require 'active_support/cache'
11
3
 
12
4
  module Cell
13
5
  module Caching
14
-
15
- def self.included(base) #:nodoc:
16
- base.class_eval do
17
- extend ClassMethods
18
-
19
- alias_method_chain :render_state, :caching
20
- end
21
- end
22
-
6
+ extend ActiveSupport::Concern
7
+
23
8
  module ClassMethods
24
9
  # Activate caching for the state <tt>state</tt>. If no other options are passed
25
10
  # the view will be cached forever.
@@ -106,32 +91,17 @@ module Cell
106
91
  end
107
92
  end
108
93
 
109
- def render_state_with_caching(state, request=ActionDispatch::Request.new({}))
110
- return render_state_without_caching(state, request) unless state_cached?(state)
111
-
112
- key = cache_key(state, call_version_proc_for_state(state))
113
- ### DISCUSS: see sweep discussion at #cache.
94
+ def render_state(state)
95
+ return super(state) unless state_cached?(state)
114
96
 
115
- # cache hit:
116
- if content = read_fragment(key)
117
- return content
118
- end
119
- # re-render:
120
- return write_fragment(key, render_state_without_caching(state, request), self.class.cache_options[state])
121
- end
122
-
123
- def read_fragment(key, cache_options = nil) #:nodoc:
124
- returning self.class.cache_store.read(key, cache_options) do |content|
125
- log "Cell Cache hit: #{key}" unless content.blank?
97
+ key = cache_key(state, call_version_proc_for_state(state))
98
+ options = self.class.cache_options[state]
99
+
100
+ self.class.cache_store.fetch(key, options) do
101
+ super(state)
126
102
  end
127
103
  end
128
104
 
129
- def write_fragment(key, content, cache_opts = nil) #:nodoc:
130
- log "Cell Cache miss: #{key}"
131
- self.class.cache_store.write(key, content, cache_opts)
132
- content
133
- end
134
-
135
105
  # Call the versioning Proc for the respective state.
136
106
  def call_version_proc_for_state(state)
137
107
  version_proc = self.class.version_procs[state]
@@ -7,6 +7,30 @@ module Cell
7
7
  include AbstractController
8
8
  include Rendering, Layouts, Helpers, Callbacks, Translation
9
9
  include ActionController::RequestForgeryProtection
10
+
11
+ module Rendering
12
+ def render_state(state)
13
+ rack_response = dispatch(state, parent_controller.request)
14
+
15
+ str = '' # copied from Response#body.
16
+ rack_response[2].each { |part| str << part.to_s }
17
+ str.html_safe # in fact, i'd love to return a real OutputBuffer here.
18
+ end
19
+ end
20
+
21
+ class View < ActionView::Base
22
+ def render(options = {}, locals = {}, &block)
23
+ if options[:state] or options[:view]
24
+ return @_controller.render(options, &block)
25
+ end
26
+
27
+ super
28
+ end
29
+ end
30
+
31
+ include Rendering
32
+ include Caching
33
+
10
34
  #include AbstractController::Logger
11
35
 
12
36
 
@@ -25,34 +49,13 @@ module Cell
25
49
 
26
50
  def log(*args); end
27
51
 
28
- class View < ActionView::Base
29
- def render(options = {}, locals = {}, &block)
30
- if options[:state] or options[:view]
31
- return @_controller.render(options, &block)
32
- end
33
-
34
- super
35
- end
36
- end
37
52
 
38
53
  def self.view_context_class
39
54
  controller = self
40
- # Unfortunately, there is currently an abstraction leak between AC::Base
41
- # and AV::Base which requires having the URL helpers in both AC and AV.
42
- # To do this safely at runtime for tests, we need to bump up the helper serial
43
- # to that the old AV subclass isn't cached.
44
- #
45
- # TODO: Make this unnecessary
46
- #if @controller
47
- # @controller.singleton_class.send(:include, _routes.url_helpers)
48
- # @controller.view_context_class = Class.new(@controller.view_context_class) do
49
- # include _routes.url_helpers
50
55
 
51
56
  View.class_eval do
52
-
53
57
  include controller._helpers
54
-
55
- include Cell::Base.url_helpers if Cell::Rails.respond_to?(:url_helpers) and Cell::Rails.url_helpers
58
+ include Cell::Base.url_helpers if Cell::Rails.url_helpers
56
59
  end
57
60
 
58
61
 
@@ -65,26 +68,13 @@ module Cell
65
68
  end
66
69
 
67
70
  def process(*) # defined in AC::Metal.
68
- self.response_body = super ### TODO: discuss with yehuda.
71
+ self.response_body = super
69
72
  end
70
-
71
- #attr_internal :request
73
+
72
74
  delegate :request, :to => :parent_controller
73
75
  delegate :config, :to => :parent_controller # DISCUSS: what if a cell has its own config (eg for assets, cells/bassist/images)?
74
76
  # DISCUSS: let @controller point to @parent_controller in views, and @cell is the actual real controller?
75
77
 
76
-
77
- def render_state(state, request=ActionDispatch::Request.new({})) ### FIXME: where to set Request if none given? leave blank?
78
- rack_response = dispatch(state, parent_controller.request)
79
-
80
- return rack_response[2].last if rack_response[2].kind_of?(Array) ### FIXME: HACK for testing, wtf is going on here?
81
- rack_response[2] ### TODO: discuss with yehuda.
82
- # rack_response in test mode: [nil, nil, ["Doo"]]
83
- # rack_response in dev mode: [nil, nil, "<div>..."]
84
- end
85
- include Cell::Caching
86
-
87
-
88
78
 
89
79
 
90
80
  class << self
@@ -138,6 +128,7 @@ module Cell
138
128
  #
139
129
  #
140
130
  # ==== Where have all the partials gone?
131
+ #
141
132
  # In Cells we abandoned the term 'partial' in favor of plain 'views' - we don't need to distinguish
142
133
  # between both terms. A cell view is both, a view and a kind of partial as it represents only a small
143
134
  # part of the page.
@@ -148,16 +139,11 @@ module Cell
148
139
 
149
140
 
150
141
 
151
- # Climbs up the inheritance hierarchy of the Cell, looking for a view
152
- # for the current <tt>state</tt> in each level.
153
- # As soon as a view file is found it is returned as an ActionView::Template
154
- # instance.
155
- ### DISCUSS: moved to Cell::View#find_template in rainhead's fork:
142
+ # Climbs up the inheritance hierarchy of the Cell, looking for a view for the current +state+ in each level.
156
143
  def find_family_view_for_state(state)
157
144
  missing_template_exception = nil
158
145
 
159
146
  possible_paths_for_state(state).each do |template_path|
160
- # we need to catch MissingTemplate, since we want to try for all possible family views.
161
147
  begin
162
148
  template = find_template(template_path)
163
149
  return template if template
@@ -167,22 +153,6 @@ module Cell
167
153
 
168
154
  raise missing_template_exception
169
155
  end
170
-
171
- # In production mode, the view for a state/template_format is cached.
172
- ### DISCUSS: ActionView::Base already caches results for #pick_template, so maybe
173
- ### we should just cache the family path for a state/format?
174
- def find_family_view_for_state_with_caching(state)
175
- return find_family_view_for_state(state) unless self.class.cache_configured?
176
-
177
- # in production mode:
178
- key = "#{state}/#{action_view.template_format}"
179
- state2view = self.class.state2view_cache
180
- state2view[key] || state2view[key] = find_family_view_for_state(state, action_view)
181
- end
182
-
183
-
184
-
185
-
186
156
 
187
157
  # Render the view belonging to the given state. Will raise ActionView::MissingTemplate
188
158
  # if it can not find one of the requested view template. Note that this behaviour was
@@ -200,9 +170,6 @@ module Cell
200
170
  # handle :layout, :template_format, :view
201
171
  opts = defaultize_render_options_for(opts, state)
202
172
 
203
- # set instance vars, include helpers:
204
- #prepare_action_view_for(action_view, opts)
205
-
206
173
  #template = find_family_view_for_state_with_caching(opts[:view], action_view)
207
174
  template = find_family_view_for_state(opts[:view])
208
175
  opts[:template] = template
@@ -219,19 +186,7 @@ module Cell
219
186
  opts[:view] ||= state
220
187
  opts
221
188
  end
222
-
223
- def prepare_action_view_for(action_view, opts)
224
- # make helpers available:
225
- include_helpers_in_class(action_view.class)
226
-
227
- import_active_helpers_into(action_view) # in Cells::Cell::ActiveHelper.
228
-
229
- action_view.assigns = assigns_for_view # make instance vars available.
230
- action_view.template_format = opts[:template_format]
231
- end
232
-
233
- # Prepares <tt>opts</tt> to be passed to ActionView::Base#render by removing
234
- # unknown parameters.
189
+
235
190
  def sanitize_render_options(opts)
236
191
  opts.except!(:view, :state)
237
192
  end
@@ -1,25 +1,8 @@
1
1
  # encoding: utf-8
2
2
 
3
- begin
4
- require 'active_support'
5
- rescue
6
- gem 'activesupport'
7
- require 'active_support'
8
- end
3
+ require 'active_support'
4
+ require 'action_controller'
9
5
 
10
- begin
11
- require 'action_controller'
12
- rescue
13
- gem 'actionpack'
14
- require 'action_controller'
15
- end
16
-
17
- begin
18
- require 'action_view'
19
- rescue
20
- gem 'actionpack'
21
- require 'action_view'
22
- end
23
6
 
24
7
  require 'cell/base_methods'
25
8
 
@@ -72,8 +55,6 @@ Cell::Base = Cell::Rails
72
55
 
73
56
  Cell::Base.view_paths = Cells::DEFAULT_VIEW_PATHS if Cell::Base.view_paths.blank?
74
57
 
75
- require 'cells/rails'
76
-
77
58
 
78
59
  require "rails/railtie"
79
60
  class Cells::Railtie < Rails::Railtie
@@ -87,5 +68,6 @@ class Cells::Railtie < Rails::Railtie
87
68
 
88
69
  initializer "cells.add_load_path" do |app|
89
70
  #ActiveSupport::Dependencies.load_paths << Rails.root.join(*%w[app cells])
71
+ ### DISCUSS: how are cell classes found by Rails?
90
72
  end
91
73
  end
@@ -1,5 +1,5 @@
1
1
  # encoding: utf-8
2
2
 
3
3
  module Cells
4
- VERSION = '3.4.0.beta1'
4
+ VERSION = '3.4.0.beta2'
5
5
  end
@@ -0,0 +1,248 @@
1
+ ### TODO: extract that file to railties/lib/test/isolation/abstract_unit
2
+
3
+ # Note:
4
+ # It is important to keep this file as light as possible
5
+ # the goal for tests that require this is to test booting up
6
+ # rails from an empty state, so anything added here could
7
+ # hide potential failures
8
+ #
9
+ # It is also good to know what is the bare minimum to get
10
+ # Rails booted up.
11
+ require 'fileutils'
12
+
13
+ # TODO: Remove rubygems when possible
14
+ require 'rubygems'
15
+ require 'test/unit'
16
+
17
+ # TODO: Remove setting this magic constant
18
+ #RAILS_FRAMEWORK_ROOT = File.expand_path("#{File.dirname(__FILE__)}/../../..")
19
+ RAILS_FRAMEWORK_ROOT = "/home/nick/projects/rails"
20
+
21
+ # These files do not require any others and are needed
22
+ # to run the tests
23
+ require "active_support/testing/isolation"
24
+ require "active_support/testing/declarative"
25
+
26
+ module TestHelpers
27
+ module Paths
28
+ module_function
29
+
30
+ TMP_PATH = File.expand_path(File.join(File.dirname(__FILE__), *%w[.. .. tmp]))
31
+
32
+ def tmp_path(*args)
33
+ File.join(TMP_PATH, *args)
34
+ end
35
+
36
+ def app_path(*args)
37
+ tmp_path(*%w[app] + args)
38
+ end
39
+
40
+ def framework_path
41
+ RAILS_FRAMEWORK_ROOT
42
+ end
43
+
44
+ def rails_root
45
+ app_path
46
+ end
47
+ end
48
+
49
+ module Rack
50
+ def extract_body(response)
51
+ "".tap do |body|
52
+ response[2].each {|chunk| body << chunk }
53
+ end
54
+ end
55
+
56
+ def get(path)
57
+ @app.call(::Rack::MockRequest.env_for(path))
58
+ end
59
+
60
+ def assert_welcome(resp)
61
+ assert_equal 200, resp[0]
62
+ assert resp[1]["Content-Type"] = "text/html"
63
+ assert extract_body(resp).match(/Welcome aboard/)
64
+ end
65
+
66
+ def assert_success(resp)
67
+ assert_equal 202, resp[0]
68
+ end
69
+
70
+ def assert_missing(resp)
71
+ assert_equal 404, resp[0]
72
+ end
73
+
74
+ def assert_header(key, value, resp)
75
+ assert_equal value, resp[1][key.to_s]
76
+ end
77
+
78
+ def assert_body(expected, resp)
79
+ assert_equal expected, extract_body(resp)
80
+ end
81
+ end
82
+
83
+ module Generation
84
+ def build_app(options = {})
85
+ FileUtils.rm_rf(app_path)
86
+ FileUtils.cp_r(tmp_path('app_template'), app_path)
87
+
88
+ # Delete the initializers unless requested
89
+ unless options[:initializers]
90
+ Dir["#{app_path}/config/initializers/*.rb"].each do |initializer|
91
+ File.delete(initializer)
92
+ end
93
+ end
94
+
95
+ unless options[:gemfile]
96
+ File.delete"#{app_path}/Gemfile"
97
+ end
98
+
99
+ routes = File.read("#{app_path}/config/routes.rb")
100
+ if routes =~ /(\n\s*end\s*)\Z/
101
+ File.open("#{app_path}/config/routes.rb", 'w') do |f|
102
+ f.puts $` + "\nmatch ':controller(/:action(/:id))(.:format)'\n" + $1
103
+ end
104
+ end
105
+
106
+ add_to_config 'config.secret_token = "3b7cd727ee24e8444053437c36cc66c4"; config.session_store :cookie_store, :key => "_myapp_session"; config.active_support.deprecation = :log'
107
+ end
108
+
109
+ def make_basic_app
110
+ require "rails"
111
+ require "action_controller/railtie"
112
+
113
+ app = Class.new(Rails::Application)
114
+ app.config.secret_token = "3b7cd727ee24e8444053437c36cc66c4"
115
+ app.config.session_store :cookie_store, :key => "_myapp_session"
116
+ app.config.active_support.deprecation = :log
117
+
118
+ yield app if block_given?
119
+ app.initialize!
120
+
121
+ app.routes.draw do
122
+ match "/" => "omg#index"
123
+ end
124
+
125
+ require 'rack/test'
126
+ extend ::Rack::Test::Methods
127
+ end
128
+
129
+ class Bukkit
130
+ attr_reader :path
131
+
132
+ def initialize(path)
133
+ @path = path
134
+ end
135
+
136
+ def write(file, string)
137
+ path = "#{@path}/#{file}"
138
+ FileUtils.mkdir_p(File.dirname(path))
139
+ File.open(path, "w") {|f| f.puts string }
140
+ end
141
+
142
+ def delete(file)
143
+ File.delete("#{@path}/#{file}")
144
+ end
145
+ end
146
+
147
+ def plugin(name, string = "")
148
+ dir = "#{app_path}/vendor/plugins/#{name}"
149
+ FileUtils.mkdir_p(dir)
150
+
151
+ File.open("#{dir}/init.rb", 'w') do |f|
152
+ f.puts "::#{name.upcase} = 'loaded'"
153
+ f.puts string
154
+ end
155
+
156
+ Bukkit.new(dir).tap do |bukkit|
157
+ yield bukkit if block_given?
158
+ end
159
+ end
160
+
161
+ def engine(name)
162
+ dir = "#{app_path}/random/#{name}"
163
+ FileUtils.mkdir_p(dir)
164
+
165
+ app = File.readlines("#{app_path}/config/application.rb")
166
+ app.insert(2, "$:.unshift(\"#{dir}/lib\")")
167
+ app.insert(3, "require #{name.inspect}")
168
+
169
+ File.open("#{app_path}/config/application.rb", 'r+') do |f|
170
+ f.puts app
171
+ end
172
+
173
+ Bukkit.new(dir).tap do |bukkit|
174
+ yield bukkit if block_given?
175
+ end
176
+ end
177
+
178
+ def script(script)
179
+ Dir.chdir(app_path) do
180
+ `#{Gem.ruby} #{app_path}/script/rails #{script}`
181
+ end
182
+ end
183
+
184
+ def add_to_config(str)
185
+ environment = File.read("#{app_path}/config/application.rb")
186
+ if environment =~ /(\n\s*end\s*end\s*)\Z/
187
+ File.open("#{app_path}/config/application.rb", 'w') do |f|
188
+ f.puts $` + "\n#{str}\n" + $1
189
+ end
190
+ end
191
+ end
192
+
193
+ def app_file(path, contents)
194
+ FileUtils.mkdir_p File.dirname("#{app_path}/#{path}")
195
+ File.open("#{app_path}/#{path}", 'w') do |f|
196
+ f.puts contents
197
+ end
198
+ end
199
+
200
+ def controller(name, contents)
201
+ app_file("app/controllers/#{name}_controller.rb", contents)
202
+ end
203
+
204
+ def use_frameworks(arr)
205
+ to_remove = [:actionmailer,
206
+ :activemodel,
207
+ :activerecord,
208
+ :activeresource] - arr
209
+ $:.reject! {|path| path =~ %r'/(#{to_remove.join('|')})/' }
210
+ end
211
+
212
+ def boot_rails
213
+ require File.expand_path('/home/nick/projects/rails/load_paths', __FILE__)
214
+ end
215
+ end
216
+ end
217
+
218
+ class Test::Unit::TestCase
219
+ include TestHelpers::Paths
220
+ include TestHelpers::Rack
221
+ include TestHelpers::Generation
222
+ extend ActiveSupport::Testing::Declarative
223
+ end
224
+
225
+ # Create a scope and build a fixture rails app
226
+ Module.new do
227
+ extend TestHelpers::Paths
228
+ # Build a rails app
229
+ if File.exist?(tmp_path)
230
+ FileUtils.rm_rf(tmp_path)
231
+ end
232
+ FileUtils.mkdir(tmp_path)
233
+
234
+ environment = File.expand_path('../../../../load_paths', __FILE__)
235
+ if File.exist?("#{environment}.rb")
236
+ require_environment = "-r #{environment}"
237
+ end
238
+
239
+ `#{Gem.ruby} #{require_environment} #{RAILS_FRAMEWORK_ROOT}/bin/rails new #{tmp_path('app_template')}`
240
+ File.open("#{tmp_path}/app_template/config/boot.rb", 'w') do |f|
241
+ if require_environment
242
+ f.puts "Dir.chdir('#{File.dirname(environment)}') do"
243
+ f.puts " require '#{environment}'"
244
+ f.puts "end"
245
+ end
246
+ f.puts "require 'rails/all'"
247
+ end
248
+ end
@@ -5,8 +5,6 @@ require File.join(File.dirname(__FILE__), 'test_helper')
5
5
  class ActiveHelperTest < ActiveSupport::TestCase
6
6
  context "The Cell::Base class" do
7
7
  setup do
8
- require 'active_helper'
9
- require 'active_helper/rails'
10
8
  class FingeringHelper < ActiveHelper::Base
11
9
  provides :finger
12
10
  end
@@ -16,17 +14,17 @@ class ActiveHelperTest < ActiveSupport::TestCase
16
14
  end
17
15
  end
18
16
 
19
- should "respond to active_helper" do
17
+ should_eventually "respond to active_helper" do
20
18
  assert_respond_to Cell::Base, :active_helper
21
19
  end
22
20
 
23
- should "store helper constants from active_helper" do
21
+ should_eventually "store helper constants from active_helper" do
24
22
  @cell = Class.new(BassistCell)
25
23
  @cell.active_helper SlappingHelper
26
24
  assert_equal [SlappingHelper], @cell.active_helpers
27
25
  end
28
26
 
29
- should "inherit helper constants from active_helper" do
27
+ should_eventually "inherit helper constants from active_helper" do
30
28
  @base_cell = Class.new(BassistCell)
31
29
  @base_cell.active_helper SlappingHelper
32
30
  @cell = Class.new(@base_cell)
@@ -45,7 +43,7 @@ class ActiveHelperTest < ActiveSupport::TestCase
45
43
  end
46
44
 
47
45
  context "The view rendered by the cell" do
48
- should "respond to used helper methods" do
46
+ should_eventually "respond to used helper methods" do
49
47
  @cell = bassist_mock
50
48
  @cell.class.active_helper SlappingHelper
51
49
 
@@ -56,5 +54,4 @@ class ActiveHelperTest < ActiveSupport::TestCase
56
54
  end
57
55
  end
58
56
  end
59
-
60
57
  end
@@ -1,16 +1,17 @@
1
1
  class MusicianController < ActionController::Base
2
2
  def promotion
3
- render :text => render_cell(:bassist, :play)
3
+ render :text => render_cell(:bassist, :provoke)
4
4
  end
5
5
 
6
6
  def featured
7
- self.view_paths << File.expand_path(File.join(File.dirname(__FILE__), '../views'))
8
7
  end
9
8
 
10
9
  def skills
11
10
  render :text => render_cell(:bassist, :listen)
12
11
  end
13
12
 
13
+ def hamlet
14
+ end
14
15
 
15
16
  def action_method?(name); true; end ### FIXME: fixes NameError: undefined local variable or method `_router' for MusicianController:Class
16
17
  end
@@ -3,7 +3,9 @@ require File.join(File.dirname(__FILE__), *%w[test_helper])
3
3
  #require 'rails/generators/test_unit'
4
4
 
5
5
 
6
- require '/home/nick/projects/rails/railties/lib/rails/test/isolation/abstract_unit'
6
+ #require '/home/nick/projects/rails/railties/lib/rails/test/isolation/abstract_unit'
7
+ require 'abstract_unit'
8
+
7
9
  #require '/home/nick/projects/rails/railties/test/generators/generators_test_helper'
8
10
  require 'rails/generators'
9
11
  require 'rails_generators/cell/cell_generator'
@@ -3,19 +3,45 @@ require File.join(File.dirname(__FILE__), '..', 'test_helper')
3
3
 
4
4
  class DirectorCell < Cell::Rails
5
5
  cache :count
6
+
6
7
  @@counter = 0
8
+ cattr_accessor :counter
7
9
 
8
- def count
10
+ def self.increment!
9
11
  @@counter += 1
10
- render :text => @@counter
12
+ end
13
+
14
+ def self.reset!
15
+ @@counter = 0
16
+ end
17
+
18
+ def increment!
19
+ self.class.increment!
20
+ end
21
+
22
+ def count
23
+ render :text => increment!
11
24
  end
12
25
  end
13
26
 
14
27
  class CachingTest < ActiveSupport::TestCase
28
+ context "The DirectorCell" do
29
+ setup do
30
+ DirectorCell.reset!
31
+ end
32
+
33
+ should "respond to #increment" do
34
+ assert_equal 0, DirectorCell.counter
35
+ assert_equal 1, DirectorCell.increment!
36
+ assert_equal 1, DirectorCell.counter
37
+ end
38
+ end
39
+
15
40
  context "A cell" do
16
41
  setup do
17
42
  ::ActionController::Base.cache_store = :memory_store
18
43
  ::ActionController::Base.perform_caching = true
44
+ DirectorCell.reset!
19
45
  end
20
46
 
21
47
  should "respond to state_cached?" do
@@ -54,12 +80,7 @@ class CachingTest < ActiveSupport::TestCase
54
80
 
55
81
  context "caching without options" do
56
82
  setup do
57
- DirectorCell.class_eval do
58
- @@counter = 0
59
- cattr_accessor :count
60
- end
61
-
62
- key = cell(:director).cache_key(:count, :count => 0)
83
+ key = cell(:director).cache_key(:count, :count => 0)
63
84
  Cell::Base.expire_cache_key(key) ### TODO: separate test
64
85
  end
65
86
 
@@ -78,8 +99,7 @@ class CachingTest < ActiveSupport::TestCase
78
99
  should "not cache at all" do
79
100
  DirectorCell.class_eval do
80
101
  def dictate
81
- @@counter += 1
82
- render :text => @@counter
102
+ render :text => increment!
83
103
  end
84
104
  end
85
105
 
@@ -90,20 +110,19 @@ class CachingTest < ActiveSupport::TestCase
90
110
  should "expire the cache with a version proc" do
91
111
  DirectorCell.class_eval do
92
112
  cache :count, Proc.new { |cell|
93
- cell.class.count >= 2 ? {:count => 2} : {:count => 0}
113
+ cell.class.counter >= 2 ? {:count => 2} : {:count => 0}
94
114
  }
95
115
 
96
116
  def count
97
- render :text => @@count += 1
98
- #@@count
117
+ render :text => increment!
99
118
  end
100
119
  end
101
- DirectorCell.count = 0
120
+ DirectorCell.reset!
102
121
 
103
122
  assert_equal "1", render_cell(:director, :count)
104
123
  assert_equal "1", render_cell(:director, :count) # cached.
105
124
 
106
- DirectorCell.count = 2 # invalidates the view cache.
125
+ DirectorCell.counter = 2 # invalidates the view cache.
107
126
  assert_equal "3", render_cell(:director, :count)
108
127
  assert_equal "3", render_cell(:director, :count) # cached.
109
128
  end
@@ -113,20 +132,19 @@ class CachingTest < ActiveSupport::TestCase
113
132
  cache :count, :expire_count
114
133
 
115
134
  def expire_count
116
- self.class.count >= 2 ? {:count => 2} : {:count => 0}
135
+ self.class.counter >= 2 ? {:count => 2} : {:count => 0}
117
136
  end
118
137
 
119
138
  def count
120
- @@count += 1
121
- render :text => @@count
139
+ render :text => increment!
122
140
  end
123
141
  end
124
- DirectorCell.count = 0
142
+ DirectorCell.reset!
125
143
 
126
144
  assert_equal "1", render_cell(:director, :count)
127
145
  assert_equal "1", render_cell(:director, :count) # cached.
128
146
 
129
- DirectorCell.count = 2 # invalidates the view cache.
147
+ DirectorCell.counter = 2 # invalidates the view cache.
130
148
  assert_equal "3", render_cell(:director, :count)
131
149
  assert_equal "3", render_cell(:director, :count) # cached.
132
150
  end
@@ -153,10 +171,10 @@ class CachingTest < ActiveSupport::TestCase
153
171
  DirectorCell.class_eval do
154
172
  cache :count
155
173
  def count
156
- render :text => @@count += 1
174
+ render :text => increment!
157
175
  end
158
176
  end
159
- DirectorCell.count = 0
177
+ DirectorCell.reset!
160
178
 
161
179
  @key = cell(:director).cache_key(:count)
162
180
  render_cell(:director, :count)
@@ -176,40 +194,9 @@ class CachingTest < ActiveSupport::TestCase
176
194
  should "accept cache options" do
177
195
  key = cell(:director).cache_key(:count, :volume => 9)
178
196
  assert ::Cell::Base.cache_store.write(key, 'ONE!')
179
-
197
+
180
198
  MusicianController.new.expire_cell_state(:director, :count, :volume => 9)
181
199
  assert_not ::Cell::Base.cache_store.read(key)
182
200
  end
183
201
  end
184
-
185
- def test_find_family_view_for_state_with_caching
186
- # test environment: --------------------------------------
187
- BassistCell.instance_variable_set :@state2view_cache, {}
188
- assert_equal({}, BassistCell.state2view_cache)
189
-
190
- BassistCell.instance_eval do
191
- self.default_template_format = :html
192
-
193
- def play; render; end
194
- end
195
-
196
-
197
- cell = cell(:bassist)
198
- cell.class.instance_eval do
199
- def cache_configured?; false; end
200
- end
201
- cell.render_state :play
202
- # in development/test environment, no view name caching should happen,
203
- # if perform_caching is false.
204
- assert_equal({}, BassistCell.state2view_cache)
205
-
206
- # production environment: --------------------------------
207
- cell = BassistCell.new(@controller)
208
- cell.class.instance_eval do
209
- def cache_configured?; true; end
210
- end
211
-
212
- cell.render_state :play
213
- assert BassistCell.state2view_cache["play/html"]
214
- end
215
202
  end
@@ -30,14 +30,14 @@ class RailsCellsTest < ActiveSupport::TestCase
30
30
  end
31
31
 
32
32
  context "invoking find_family_view_for_state" do
33
- should "### use find_template" do
34
- assert cell(:bassist).find_template("bassist/play")
33
+ should "raise an error when a template is missing" do
35
34
  assert_raises ActionView::MissingTemplate do
36
35
  cell(:bassist).find_template("bassist/playyy")
37
36
  end
37
+
38
+ puts "format: #{cell(:bassist).find_template("bassist/play.js").formats.inspect}"
38
39
  end
39
40
 
40
-
41
41
  should "return play.html.erb" do
42
42
  assert_equal "bassist/play", cell(:bassist).find_family_view_for_state(:play).virtual_path
43
43
  end
@@ -1,26 +1,38 @@
1
1
  require File.join(File.dirname(__FILE__), '/../test_helper')
2
2
 
3
- require 'active_support/core_ext/object/to_query'
4
-
5
3
  class RailsIntegrationTest < ActionController::TestCase
6
4
 
7
5
  context "A Rails controller" do
6
+
8
7
  setup do
9
8
  @routes = ActionDispatch::Routing::RouteSet.new
10
9
  @routes.draw do
11
10
  |map| match ':action', :to => MusicianController
12
11
  end
12
+
13
13
  @controller = MusicianController.new
14
+ @controller.view_paths << File.expand_path(File.join(File.dirname(__FILE__), '../app/views'))
14
15
  end
15
16
 
16
17
  should "respond to render_cell" do
17
18
  get 'promotion'
18
- assert_equal "Doo", @response.body
19
+ assert_equal "That's me, naked <img alt=\"Me\" src=\"/images/me.png\" />", @response.body
19
20
  end
20
21
 
21
- should "respond to render_cell in the view" do
22
+ should "respond to render_cell in the view without escaping twice" do
23
+ BassistCell.class_eval do
24
+ def provoke; render; end
25
+ end
22
26
  get 'featured'
23
- assert_equal "Doo", @response.body
27
+ assert_equal "That's me, naked <img alt=\"Me\" src=\"/images/me.png\" />", @response.body
28
+ end
29
+
30
+ should "respond to render_cell in a haml view" do
31
+ BassistCell.class_eval do
32
+ def provoke; render; end
33
+ end
34
+ get 'hamlet'
35
+ assert_equal "That's me, naked <img alt=\"Me\" src=\"/images/me.png\" />\n", @response.body
24
36
  end
25
37
 
26
38
  should "make params (and friends) available in a cell" do
@@ -1,5 +1,5 @@
1
- require '/home/nick/projects/rails/railties/lib/rails/test/isolation/abstract_unit'
2
- #require 'rails/test/isolation/abstract_unit'
1
+ #require '/home/nick/projects/rails/railties/lib/rails/test/isolation/abstract_unit'
2
+ require 'abstract_unit'
3
3
 
4
4
  module ApplicationTests
5
5
  class RouterTest < ActionController::TestCase#Test::Unit::TestCase
@@ -44,7 +44,7 @@ module ApplicationTests
44
44
  def promote; render; end
45
45
  end
46
46
 
47
- assert ::Cell::Rails.view_context_class._routes, "Cells::Railtie initializer wasn't invoked."
47
+ #assert ::Cell::Rails.view_context_class._routes, "Cells::Railtie initializer wasn't invoked."
48
48
  #assert ! ::OmgController.new.respond_to?( :render_cell)
49
49
 
50
50
  get "/cell"
@@ -22,17 +22,11 @@ Cell::Rails.append_view_path(File.join(test_app_dir, 'cells'))
22
22
  Cell::Rails.append_view_path(File.join(test_app_dir, 'cells', 'layouts'))
23
23
 
24
24
 
25
- # Now, load the rest.
25
+ # Now, load the controllers.
26
26
  require File.join(test_app_dir, 'controllers', 'cells_test_controller')
27
27
  require File.join(test_app_dir, 'controllers', 'musician_controller')
28
28
 
29
- # We need to setup a fake route for the controller tests.
30
- #ActionController::Routing::Routes.draw do |map|
31
- # map.connect 'cells_test/:action', :controller => 'cells_test'
32
- #end
33
- #ActionController::Routing::Routes.draw do |map|
34
- # map.connect 'musician/:action', :controller => 'musician'
35
- #end
29
+
36
30
 
37
31
  Dir[File.join(gem_dir, 'test', 'support', '**', '*.rb')].each { |f| require f }
38
32
  require File.join(gem_dir, 'lib', 'cells', 'assertions_helper')
@@ -49,4 +43,7 @@ class Cell::Rails
49
43
  end
50
44
 
51
45
  require File.join(test_app_dir, 'cells', 'bassist_cell')
52
- require File.join(test_app_dir, 'cells', 'bad_guitarist_cell')
46
+ require File.join(test_app_dir, 'cells', 'bad_guitarist_cell')
47
+
48
+ require "haml"
49
+ require "haml/template" # Thanks, Nathan!
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cells
3
3
  version: !ruby/object:Gem::Version
4
- hash: 350106850
4
+ hash: -415343653
5
5
  prerelease: true
6
6
  segments:
7
7
  - 3
8
8
  - 4
9
9
  - 0
10
- - beta1
11
- version: 3.4.0.beta1
10
+ - beta2
11
+ version: 3.4.0.beta2
12
12
  platform: ruby
13
13
  authors:
14
14
  - Nick Sutterer
@@ -16,7 +16,7 @@ autorequire:
16
16
  bindir: bin
17
17
  cert_chain: []
18
18
 
19
- date: 2010-07-23 00:00:00 +02:00
19
+ date: 2010-09-09 00:00:00 +02:00
20
20
  default_executable:
21
21
  dependencies: []
22
22
 
@@ -31,6 +31,7 @@ extra_rdoc_files:
31
31
  files:
32
32
  - CHANGES
33
33
  - Gemfile
34
+ - Gemfile.lock
34
35
  - MIT-LICENSE
35
36
  - README.rdoc
36
37
  - Rakefile
@@ -57,6 +58,7 @@ files:
57
58
  - rails_generators/erb/cell_generator.rb
58
59
  - rails_generators/erb/templates/view.html.erb
59
60
  - test/active_helper_test.rb
61
+ - test/abstract_unit.rb
60
62
  - test/base_methods_test.rb
61
63
  - test/assertions_helper_test.rb
62
64
  - test/rails/router_test.rb
@@ -115,6 +117,7 @@ specification_version: 3
115
117
  summary: Cells are lightweight controllers for Rails and can be rendered in controllers and views, providing an elegant and fast way for encapsulation and component-orientation.
116
118
  test_files:
117
119
  - test/active_helper_test.rb
120
+ - test/abstract_unit.rb
118
121
  - test/base_methods_test.rb
119
122
  - test/assertions_helper_test.rb
120
123
  - test/rails/router_test.rb