cells 4.0.0.beta6 → 4.0.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
data/cells.gemspec CHANGED
@@ -21,12 +21,10 @@ Gem::Specification.new do |spec|
21
21
 
22
22
  spec.add_dependency "uber", "~> 0.0.9"
23
23
  spec.add_dependency 'tilt', '>= 1.4', '< 3'
24
- spec.add_dependency 'disposable', '~> 0.0.8'
25
-
26
24
 
27
25
  spec.add_development_dependency "rake"
28
26
  spec.add_development_dependency "minitest-reporters"
29
27
  spec.add_development_dependency "capybara"
30
28
 
31
- spec.add_development_dependency "cells-erb", ">= 0.0.2"
29
+ spec.add_development_dependency "cells-erb", ">= 0.0.4"
32
30
  end
data/lib/cell/caching.rb CHANGED
@@ -43,6 +43,7 @@ module Cell
43
43
 
44
44
 
45
45
  def render_state(state, *args)
46
+ state = state.to_sym
46
47
  return super(state, *args) unless cache?(state, *args)
47
48
 
48
49
  key = self.class.state_cache_key(state, self.class.version_procs[state].evaluate(self, *args))
data/lib/cell/rails.rb CHANGED
@@ -34,6 +34,13 @@ module Cell
34
34
  module ViewModel
35
35
  extend ActiveSupport::Concern
36
36
 
37
+ # DISCUSS: who actually uses forgery protection with cells? it is not working since 4, anyway?
38
+ # include ActionController::RequestForgeryProtection
39
+ included do
40
+ extend Uber::Delegates
41
+ delegates :parent_controller, :session, :params, :request, :config, :env, :url_options
42
+ end
43
+
37
44
  def call(*)
38
45
  super.html_safe
39
46
  end
data/lib/cell/railtie.rb CHANGED
@@ -11,10 +11,6 @@ module Cell
11
11
  end
12
12
  end
13
13
 
14
- # initializer 'cells.template_engine' do |app|
15
- # ViewModel.template_engine = app.config.app_generators.rails.fetch(:template_engine, 'erb').to_s
16
- # end
17
-
18
14
  # ruthlessly stolen from the zurb-foundation gem.
19
15
  initializer 'cells.update_asset_paths' do |app|
20
16
  Array(app.config.cells.with_assets).each do |cell_class|
@@ -38,7 +34,7 @@ module Cell
38
34
  end
39
35
 
40
36
  initializer "cells.include_default_helpers" do
41
- #include assert helpers (image_path, font_path, ect)
37
+ # include asset helpers (image_path, font_path, ect)
42
38
  ViewModel.class_eval do
43
39
  include ActionView::Helpers::UrlHelper
44
40
  include ::Cell::RailsExtensions::HelpersAreShit
@@ -58,6 +54,7 @@ module Cell
58
54
  ViewModel.send(:include, Cell::Haml) if Cell.const_defined?(:Haml)
59
55
  ViewModel.send(:include, Cell::Slim) if Cell.const_defined?(:Slim)
60
56
  end
57
+ # ViewModel.template_engine = app.config.app_generators.rails.fetch(:template_engine, 'erb').to_s
61
58
 
62
59
  initializer('cells.development') do |app|
63
60
  if Rails.env == "development"
data/lib/cell/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Cell
2
- VERSION = "4.0.0.beta6"
2
+ VERSION = "4.0.0.rc1"
3
3
  end
@@ -1,9 +1,3 @@
1
- # no helper_method calls
2
- # no instance variables
3
- # no locals
4
- # options are automatically made instance methods via constructor.
5
- # call "helpers" in class
6
-
7
1
  # TODO: warn when using ::property but not passing in model in constructor.
8
2
  module Cell
9
3
  class ViewModel
@@ -36,29 +30,21 @@ module Cell
36
30
  @controller_path ||= util.underscore(name.sub(/Cell$/, ''))
37
31
  end
38
32
 
39
- # FIXME: this is all rails-only.
40
- # DISCUSS: who actually uses forgery protection with cells? it is not working since 4, anyway?
41
- # include ActionController::RequestForgeryProtection
42
- delegates :parent_controller, :session, :params, :request, :config, :env, :url_options
43
-
44
33
  attr_reader :model
45
34
 
46
35
 
47
36
  module Helpers
37
+ # Constantizes name, call builders and returns instance.
38
+ def cell(name, *args, &block) # classic Rails fuzzy API.
39
+ class_from_cell_name(name).(*args, &block)
40
+ end
41
+
42
+ private
48
43
  # Renders collection of cells.
49
- def _collection(name, array, options) # private.
44
+ def render_collection(array, options) # private.
50
45
  method = options.delete(:method) || :show
51
46
  join = options.delete(:collection_join)
52
- array.collect { |model| cell_for(name, *[model, options]).call(method) }.join(join).html_safe
53
- end
54
-
55
- # Returns cell instance.
56
- def cell(name, model=nil, options={}, &block) # classic Rails fuzzy API.
57
- if model.is_a?(Hash) and array = model.delete(:collection)
58
- return _collection(name, array, model.merge(options))
59
- end
60
-
61
- cell_for(name, model, options, &block)
47
+ array.collect { |model| build(*[model, options]).call(method) }.join(join).html_safe
62
48
  end
63
49
  end
64
50
  extend Helpers
@@ -71,18 +57,25 @@ module Cell
71
57
 
72
58
  include Helpers
73
59
 
74
- # DISCUSS: introduce ::for which takes constant? rename ::build_cell to ::build?
60
+ # Public entry point. Use this to instantiate cells with builders.
61
+ #
62
+ # SongCell.(@song)
63
+ # SongCell.(collection: Song.all)
64
+ def call(model=nil, options={}, &block)
65
+ if model.is_a?(Hash) and array = model.delete(:collection)
66
+ return render_collection(array, model.merge(options))
67
+ end
75
68
 
76
- def cell_for(name, *args)
77
- class_from_cell_name(name).build_cell(*args)
69
+ build(model, options)
78
70
  end
79
71
 
80
- def class_from_cell_name(name)
81
- "#{name}_cell".classify.constantize
72
+ def build(*args) # semi-public.
73
+ class_builder.call(*args).new(*args) # Uber::Builder::class_builder.
82
74
  end
83
75
 
84
- def build_cell(*args)
85
- class_builder.call(*args).new(*args) # Uber::Builder::class_builder.
76
+ private
77
+ def class_from_cell_name(name)
78
+ "#{name}_cell".classify.constantize
86
79
  end
87
80
  end
88
81
 
@@ -185,10 +178,11 @@ module Cell
185
178
  module TemplateFor
186
179
  def find_template(options)
187
180
  template_options = template_options_for(options) # imported by Erb, Haml, etc.
181
+ # required options: :template_class, :suffix. everything else is passed to the template implementation.
188
182
 
189
183
  view = options[:view]
190
184
  prefixes = options[:prefixes]
191
- suffix = template_options[:suffix]
185
+ suffix = template_options.delete(:suffix)
192
186
  view = "#{view}.#{suffix}"
193
187
 
194
188
  template_for(prefixes, view, template_options) or raise TemplateMissingError.new(prefixes, view)
data/test/builder_test.rb CHANGED
@@ -34,25 +34,28 @@ class BuilderTest < MiniTest::Spec
34
34
  end
35
35
 
36
36
  # the original class is used when no builder matches.
37
- it { Cell::ViewModel.cell("builder_test/song", Song.new("Nation States"), {}).must_be_instance_of BuilderTest::SongCell }
37
+ it { SongCell.(Song.new("Nation States"), {}).must_be_instance_of SongCell }
38
38
 
39
39
  it do
40
- cell = Cell::ViewModel.cell("builder_test/song", Hit.new("New York"), {})
41
- cell.must_be_instance_of BuilderTest::HitCell
40
+ cell = SongCell.(Hit.new("New York"), {})
41
+ cell.must_be_instance_of HitCell
42
42
  cell.options.must_equal({})
43
43
  end
44
44
 
45
45
  it do
46
- cell = Cell::ViewModel.cell("builder_test/song", Song.new("San Francisco"), evergreen: true)
47
- cell.must_be_instance_of BuilderTest::EvergreenCell
46
+ cell = SongCell.(Song.new("San Francisco"), evergreen: true)
47
+ cell.must_be_instance_of EvergreenCell
48
48
  cell.options.must_equal({:evergreen=>true})
49
49
  end
50
50
 
51
+ # without arguments.
52
+ it { SongCell.(Hit.new("Frenzy")).must_be_instance_of HitCell }
53
+
51
54
  # with collection.
52
- it { Cell::ViewModel.cell("builder_test/song", collection: [Song.new("Nation States"), Hit.new("New York")]).must_equal "* Nation States* **New York**" }
55
+ it { SongCell.(collection: [Song.new("Nation States"), Hit.new("New York")]).must_equal "* Nation States* **New York**" }
53
56
 
54
57
  # with Concept
55
58
  class Track < Cell::Concept
56
59
  end
57
- it { Cell::Concept.cell("builder_test/track").must_be_instance_of Track }
60
+ it { Track.().must_be_instance_of Track }
58
61
  end
data/test/caching_test.rb CHANGED
@@ -140,91 +140,98 @@ class CachingTest < MiniTest::Spec
140
140
  end
141
141
 
142
142
  # let (:cell) { DirectorCell.new(nil) }
143
- def cellule(*args)
143
+ def director_cell(*args)
144
144
  DirectorCell.new(*args)
145
145
  end
146
146
 
147
147
  # no caching when turned off.
148
148
  it do
149
- cellule.class.cache :show
149
+ director_cell.class.cache :show
150
150
  ActionController::Base.perform_caching = false
151
151
 
152
- cellule(1).call.must_equal "1"
153
- cellule(2).call.must_equal "2"
152
+ director_cell(1).call.must_equal "1"
153
+ director_cell(2).call.must_equal "2"
154
154
  end
155
155
 
156
156
  # cache forever when no options.
157
157
  it do
158
- cellule.class.cache :show
159
- cellule(1).call.must_equal "1"
160
- cellule(2).call.must_equal "1"
158
+ director_cell.class.cache :show
159
+ director_cell(1).call.must_equal "1"
160
+ director_cell(2).call.must_equal "1"
161
+ end
162
+
163
+ # caches with string state name.
164
+ it do
165
+ director_cell.class.cache :show
166
+ director_cell(1).("show").must_equal "1"
167
+ director_cell(2).("show").must_equal "1"
161
168
  end
162
169
 
163
170
 
164
171
  # no caching when state not configured.
165
172
  it do
166
- cellule.class.class_eval do
173
+ director_cell.class.class_eval do
167
174
  def dictate
168
175
  @counter
169
176
  end
170
177
  end
171
178
 
172
- cellule(1).call(:dictate).must_equal "1"
173
- cellule(2).call(:dictate).must_equal "2"
179
+ director_cell(1).call(:dictate).must_equal "1"
180
+ director_cell(2).call(:dictate).must_equal "2"
174
181
  end
175
182
 
176
183
  # compute key with cell properties from #initialize.
177
184
  it do
178
- cellule.class.cache :show do
185
+ director_cell.class.cache :show do
179
186
  @counter < 3 ? {:count => "<"} : {:count => ">"}
180
187
  end
181
188
 
182
- cellule(1).call.must_equal "1"
183
- cellule(2).call.must_equal "1"
184
- cellule(3).call.must_equal "3"
185
- cellule(4).call.must_equal "3"
189
+ director_cell(1).call.must_equal "1"
190
+ director_cell(2).call.must_equal "1"
191
+ director_cell(3).call.must_equal "3"
192
+ director_cell(4).call.must_equal "3"
186
193
  end
187
194
 
188
195
  # compute key with instance method
189
196
  it do
190
- cellule.class.cache :show, :version
191
- cellule.class.class_eval do
197
+ director_cell.class.cache :show, :version
198
+ director_cell.class.class_eval do
192
199
  def version
193
200
  @counter < 3 ? {:count => "<"} : {:count => ">"}
194
201
  end
195
202
  end
196
203
 
197
- cellule(1).call.must_equal "1"
198
- cellule(2).call.must_equal "1"
199
- cellule(3).call.must_equal "3"
200
- cellule(4).call.must_equal "3"
204
+ director_cell(1).call.must_equal "1"
205
+ director_cell(2).call.must_equal "1"
206
+ director_cell(3).call.must_equal "3"
207
+ director_cell(4).call.must_equal "3"
201
208
  end
202
209
 
203
210
  # allow returning strings for key
204
211
  it do
205
- cellule.class.cache :show do
212
+ director_cell.class.cache :show do
206
213
  @counter < 3 ? "<" : ">"
207
214
  end
208
215
 
209
- cellule(1).call.must_equal "1"
210
- cellule(2).call.must_equal "1"
211
- cellule(3).call.must_equal "3"
212
- cellule(4).call.must_equal "3"
216
+ director_cell(1).call.must_equal "1"
217
+ director_cell(2).call.must_equal "1"
218
+ director_cell(3).call.must_equal "3"
219
+ director_cell(4).call.must_equal "3"
213
220
  end
214
221
 
215
222
  # allows conditional ifs.
216
223
  it do
217
- cellule.class.cache :show, if: lambda { @counter < 3 }
224
+ director_cell.class.cache :show, if: lambda { @counter < 3 }
218
225
 
219
- cellule(1).call.must_equal "1"
220
- cellule(2).call.must_equal "1"
221
- cellule(3).call.must_equal "3"
222
- cellule(4).call.must_equal "4"
226
+ director_cell(1).call.must_equal "1"
227
+ director_cell(2).call.must_equal "1"
228
+ director_cell(3).call.must_equal "3"
229
+ director_cell(4).call.must_equal "4"
223
230
  end
224
231
 
225
232
  # allows conditional ifs with instance method.
226
233
  it do
227
- cellule.class.class_eval do
234
+ director_cell.class.class_eval do
228
235
  cache :show, if: :smaller?
229
236
 
230
237
  def smaller?
@@ -232,22 +239,22 @@ class CachingTest < MiniTest::Spec
232
239
  end
233
240
  end
234
241
 
235
- cellule(1).call.must_equal "1"
236
- cellule(2).call.must_equal "1"
237
- cellule(3).call.must_equal "3"
238
- cellule(4).call.must_equal "4"
242
+ director_cell(1).call.must_equal "1"
243
+ director_cell(2).call.must_equal "1"
244
+ director_cell(3).call.must_equal "3"
245
+ director_cell(4).call.must_equal "4"
239
246
  end
240
247
 
241
248
 
242
249
  unless ::ActionPack::VERSION::MAJOR == 3 and ::ActionPack::VERSION::MINOR >= 2 # bug in 3.2.
243
250
  describe "utf-8" do
244
251
  before do
245
- @key = cellule.class.state_cache_key(:utf8)
252
+ @key = director_cell.class.state_cache_key(:utf8)
246
253
  end
247
254
 
248
255
  it "has the correct encoding when reading from cache" do
249
- assert_equal "UTF-8", cellule.call(:utf8).encoding.to_s
250
- assert_equal "UTF-8", cellule.cache_store.read(@key).encoding.to_s
256
+ assert_equal "UTF-8", director_cell.call(:utf8).encoding.to_s
257
+ assert_equal "UTF-8", director_cell.cache_store.read(@key).encoding.to_s
251
258
  end
252
259
  end
253
260
  end
@@ -264,7 +271,7 @@ class CachingTest < MiniTest::Spec
264
271
  end
265
272
 
266
273
  it do
267
- cellule = self.cellule
274
+ cellule = self.director_cell
268
275
 
269
276
  cellule.instance_eval do
270
277
  def cache_store;
@@ -2,4 +2,11 @@ class SongCell < Cell::ViewModel
2
2
  def show
3
3
  "happy"
4
4
  end
5
+
6
+ # include ActionView::Helpers::AssetUrlHelper
7
+ # include Sprockets::Rails::Helper
8
+
9
+ # self.assets_prefix = Rails.application.config.assets.prefix
10
+ # self.assets_environment = Rails.application.assets
11
+ # self.digest_assets = Rails.application.config.assets[:digest]
5
12
  end
@@ -6,4 +6,12 @@ class SongsController < ApplicationController
6
6
  def index
7
7
  render text: cell(:song).()
8
8
  end
9
+
10
+ def new
11
+ render text: cell(:song).url_for(Song.new)
12
+ end
13
+
14
+ def edit
15
+ render text: cell(:song).video_path(1)
16
+ end
9
17
  end
@@ -2,6 +2,7 @@ require "test_helper"
2
2
 
3
3
  class FormForTestTest < MiniTest::Spec
4
4
  include Cell::Testing
5
+ controller SongsController # provides #url_options.
5
6
 
6
7
  it do
7
8
  cell("formtastic").().gsub(/\s\s/, "").must_equal %{<form novalidate=\"novalidate\" class=\"formtastic song\" id=\"edit_song_1\" action=\"/songs/1\" accept-charset=\"UTF-8\" method=\"post\"><input name=\"utf8\" type=\"hidden\" value=\"&#x2713;\" /><input type=\"hidden\" name=\"_method\" value=\"patch\" /> First <li class=\"string input required stringish\" id=\"song_id_input\"><label for=\"song_id\" class=\"label\">Id<abbr title=\"required\">*</abbr></label><input id=\"song_id\" type=\"text\" value=\"1\" name=\"song[id]\" /></li><li class=\"string input required stringish\" id=\"song_artist_id_input\"><label for=\"song_artist_id\" class=\"label\">Id<abbr title=\"required\">*</abbr></label><input id=\"song_artist_id\" type=\"text\" name=\"song[artist][id]\" /></li><fieldset class=\"actions\"><ol> <input type=\"submit\" name=\"commit\" value=\"Go!\" as=\"button\" class=\"btn btn-primary\" />
@@ -2,6 +2,7 @@ require "test_helper"
2
2
 
3
3
  class SimpleFormTest < MiniTest::Spec
4
4
  include Cell::Testing
5
+ controller SongsController # provides #url_options.
5
6
 
6
7
  it do
7
8
  cell("simple_form").().gsub(/\s\s/, "").must_equal %{<form class=\"simple_form edit_song\" id=\"edit_song_1\" action=\"/songs/1\" accept-charset=\"UTF-8\" method=\"post\"><input name=\"utf8\" type=\"hidden\" value=\"&#x2713;\" /><input type=\"hidden\" name=\"_method\" value=\"patch\" /> First <div class=\"input string required song_id\"><label class=\"string required\" for=\"song_id\"><abbr title=\"required\">*</abbr> Id</label><input class=\"string required\" required=\"required\" aria-required=\"true\" type=\"text\" value=\"1\" name=\"song[id]\" id=\"song_id\" /></div><div class=\"input string required song_artist_id\"><label class=\"string required\" for=\"song_artist_id\"><abbr title=\"required\">*</abbr> Id</label><input class=\"string required\" required=\"required\" aria-required=\"true\" type=\"text\" name=\"song[artist][id]\" id=\"song_artist_id\" /></div>
@@ -11,15 +11,26 @@ class UrlHelperTest < MiniTest::Spec
11
11
  def show
12
12
  url_for(model)
13
13
  end
14
-
15
- def default_url_options
16
- {host: "rails.sucks"}
17
- end
18
14
  end
19
15
 
20
16
  let (:song_cell) { Cell.new(Song.new, controller: controller) }
21
17
 
22
18
  # path helpers work in cell instance.
23
19
  it { song_cell.songs_path.must_equal "/songs" }
24
- it { song_cell.().must_equal "http://rails.sucks/songs/1" }
20
+ it { song_cell.().must_equal "http://test.host/songs/1" }
25
21
  end
22
+
23
+
24
+ class UrlTest < ActionDispatch::IntegrationTest
25
+ include ::Capybara::DSL
26
+
27
+ it do
28
+ visit "/songs/new" # cell.url_for(Song.new)
29
+ page.text.must_equal "http://www.example.com/songs/1"
30
+ end
31
+
32
+ # it do
33
+ # visit "/songs/1/edit"
34
+ # page.text.must_equal "http://www.example.com/songs/1"
35
+ # end
36
+ end