cells 3.4.0.beta1 → 3.4.0.beta2

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/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