cells 3.8.8 → 3.9.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (53) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +2 -1
  3. data/.travis.yml +5 -2
  4. data/CHANGES.textile +23 -15
  5. data/Gemfile +1 -1
  6. data/README.md +412 -0
  7. data/Rakefile +2 -2
  8. data/cells.gemspec +5 -6
  9. data/gemfiles/Gemfile.rails3-0 +2 -2
  10. data/gemfiles/Gemfile.rails3-1 +1 -1
  11. data/gemfiles/Gemfile.rails3-2 +1 -2
  12. data/gemfiles/Gemfile.rails4-0 +7 -0
  13. data/lib/cell.rb +27 -0
  14. data/lib/cell/base.rb +31 -18
  15. data/lib/cell/builder.rb +11 -10
  16. data/lib/cell/dsl.rb +7 -0
  17. data/lib/cell/rack.rb +5 -9
  18. data/lib/cell/rails.rb +19 -11
  19. data/lib/cell/rails/view_model.rb +115 -0
  20. data/lib/cell/rails3_0_strategy.rb +1 -1
  21. data/lib/cell/rails3_1_strategy.rb +1 -1
  22. data/lib/cell/rails4_0_strategy.rb +1 -2
  23. data/lib/cell/test_case.rb +11 -11
  24. data/lib/cells.rb +4 -3
  25. data/lib/cells/rails.rb +16 -3
  26. data/lib/cells/version.rb +1 -1
  27. data/test/app/cells/bassist_cell.rb +9 -1
  28. data/test/app/cells/rails_helper_api_test/bassist/edit.html.erb +3 -3
  29. data/test/app/cells/song/dashboard.haml +7 -0
  30. data/test/app/cells/song/details.html.haml +1 -0
  31. data/test/app/cells/song/info.html.haml +1 -0
  32. data/test/app/cells/song/lyrics.html.haml +6 -0
  33. data/test/app/cells/song/plays.haml +1 -0
  34. data/test/app/cells/song/show.html.haml +3 -0
  35. data/test/app/cells/song/title.html.haml +1 -0
  36. data/test/app/cells/view_model_test/comments/show.haml +7 -0
  37. data/test/cell_module_test.rb +39 -41
  38. data/test/cell_test.rb +28 -0
  39. data/test/dummy/app/views/musician/featured_with_block.html.erb +1 -1
  40. data/test/dummy/app/views/musician/title.erb +1 -0
  41. data/test/dummy/config/routes.rb +1 -0
  42. data/test/helper_test.rb +13 -10
  43. data/test/rails/caching_test.rb +75 -73
  44. data/test/rails/cells_test.rb +25 -23
  45. data/test/rails/integration_test.rb +80 -61
  46. data/test/rails/view_model_test.rb +119 -0
  47. data/test/rails_helper_api_test.rb +11 -13
  48. metadata +41 -61
  49. data/README.rdoc +0 -279
  50. data/about.yml +0 -7
  51. data/test/app/cells/producer/capture.html.erb +0 -1
  52. data/test/app/cells/producer/content_for.html.erb +0 -2
  53. data/test/rails/capture_test.rb +0 -70
@@ -69,7 +69,7 @@ module Cells
69
69
  module Engines
70
70
  module VersionStrategy
71
71
  def registered_engines
72
- ::Rails::Application.railties.engines
72
+ ::Rails.application.railties.engines
73
73
  end
74
74
 
75
75
  def existent_directories_for(path)
@@ -27,7 +27,7 @@ module Cells
27
27
  module Engines
28
28
  module VersionStrategy
29
29
  def registered_engines
30
- ::Rails::Application::Railties.engines
30
+ ::Rails.application.railties.engines
31
31
  end
32
32
 
33
33
  def existent_directories_for(path)
@@ -27,8 +27,7 @@ module Cells
27
27
  module Engines
28
28
  module VersionStrategy
29
29
  def registered_engines
30
- #::Rails::Railties.engines
31
- []
30
+ ::Rails::Engine::Railties.engines
32
31
  end
33
32
 
34
33
  def existent_directories_for(path)
@@ -58,36 +58,36 @@ module Cell
58
58
  super(HTML::Document.new(last_invoke).root, *args, &block)
59
59
  end
60
60
  end
61
-
61
+
62
62
  module CommonTestMethods
63
63
  def setup
64
- @controller = Class.new(ActionController::Base).new
65
- @request = ::ActionController::TestRequest.new
64
+ @controller ||= Class.new(ActionController::Base).new
65
+ @request ||= ::ActionController::TestRequest.new
66
66
  @response = ::ActionController::TestResponse.new
67
67
  @controller.request = @request
68
68
  @controller.response = @response
69
69
  @controller.params = {}
70
70
  end
71
-
72
- # Runs the block while computing the instance variables diff from before and after.
71
+
72
+ # Runs the block while computing the instance variables diff from before and after.
73
73
  def extract_state_ivars_for(cell)
74
74
  before = cell.instance_variables
75
- yield
75
+ yield
76
76
  after = cell.instance_variables
77
-
77
+
78
78
  Hash[(after - before).collect do |var|
79
79
  next if var =~ /^@_/
80
80
  [var[1, var.length].to_sym, cell.instance_variable_get(var)]
81
81
  end.compact]
82
82
  end
83
83
  end
84
-
84
+
85
85
 
86
86
  module TestMethods
87
87
  include CommonTestMethods
88
-
88
+
89
89
  attr_reader :last_invoke, :subject_cell, :view_assigns
90
-
90
+
91
91
  # Use this for functional tests of your application cells.
92
92
  #
93
93
  # Example:
@@ -100,7 +100,7 @@ module Cell
100
100
  @view_assigns = extract_state_ivars_for(@subject_cell) do
101
101
  @last_invoke = @subject_cell.render_state(state, *args)
102
102
  end
103
-
103
+
104
104
  @last_invoke
105
105
  end
106
106
 
data/lib/cells.rb CHANGED
@@ -2,7 +2,7 @@
2
2
  #
3
3
  # Cells are view components for Rails. Being lightweight controllers with actions and views, cells are the
4
4
  # answer to <tt>DoubleRenderError</tt>s and the long awaited ability to render actions within actions.
5
- #
5
+ #
6
6
  # == Directory structure
7
7
  #
8
8
  # Cells live in +app/cells/+ and have a similar file layout as controllers.
@@ -17,7 +17,7 @@
17
17
  # box.html.erb
18
18
  #
19
19
  # == Cell nesting
20
- #
20
+ #
21
21
  # Is is good practice to split up complex cell views into multiple states or views. Remember, you can always use
22
22
  # <tt>render :view => ...</tt> and <tt>render :state => ...</tt> in your views.
23
23
  #
@@ -42,7 +42,7 @@
42
42
  # = @item.title
43
43
  #
44
44
  # render :state => :order_button
45
- #
45
+ #
46
46
  # which is more than just a partial, as you may execute additional code in the state method.
47
47
  #
48
48
  # == View inheritance
@@ -72,6 +72,7 @@ module Cells
72
72
  end
73
73
  end
74
74
 
75
+ require 'cell'
75
76
  require 'cell/rails'
76
77
  require 'cells/rails'
77
78
  require 'cell/deprecations'
data/lib/cells/rails.rb CHANGED
@@ -3,9 +3,14 @@
3
3
  module Cells
4
4
  module Rails
5
5
  module ActionController
6
+ def cell_for(name, *args, &block)
7
+ ::Cell::Base.cell_for(name, self, *args, &block)
8
+ end
9
+ alias_method :cell, :cell_for # DISCUSS: make this configurable?
10
+
6
11
  # Renders the cell state and returns the content. You may pass options here, too. They will be
7
12
  # around in @opts.
8
- #
13
+ #
9
14
  # Example:
10
15
  #
11
16
  # @box = render_cell(:posts, :latest, :user => current_user)
@@ -41,19 +46,27 @@ module Cells
41
46
  ActiveSupport::Deprecation.warn "Please pass the cell class into #expire_cell_state, as in expire_cell_state(DirectorCell, :count, :user_id => 1)"
42
47
  cell_class = Cell::Rails.class_from_cell_name(cell_class)
43
48
  end
44
-
49
+
45
50
  key = cell_class.state_cache_key(state, args)
46
51
  cell_class.expire_cache_key(key, opts)
47
52
  end
48
53
  end
49
54
 
50
55
  module ActionView
56
+ # Returns the cell instance for +name+. You may pass arbitrary options to your
57
+ # cell.
58
+ #
59
+ # = cell(:song, :title => "Creeping Out Sara").render(:show)
60
+ def cell_for(name, *args, &block)
61
+ controller.cell_for(name, *args, &block)
62
+ end
63
+ alias_method :cell, :cell_for # DISCUSS: make this configurable?
64
+
51
65
  # See Cells::Rails::ActionController#render_cell.
52
66
  def render_cell(name, state, *args, &block)
53
67
  ::Cell::Rails.render_cell_for(name, state, controller, *args, &block)
54
68
  end
55
69
  end
56
-
57
70
  end
58
71
  end
59
72
 
data/lib/cells/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Cells
2
- VERSION = '3.8.8'
2
+ VERSION = '3.9.0'
3
3
  end
@@ -1,8 +1,16 @@
1
1
  class BassistCell < Cell::Rails
2
- def play; render; end
2
+ def play
3
+ render
4
+ end
3
5
 
4
6
  def shout(args)
5
7
  @words = args[:words]
6
8
  render
7
9
  end
10
+
11
+ def provoke
12
+ controller.config.relative_url_root = "" if Cell.rails3_0?
13
+
14
+ render
15
+ end
8
16
  end
@@ -1,5 +1,5 @@
1
- <%= simple_form_for @fruit do |f| %>
2
- <%= f.input :title %>
1
+ <%= form_for @fruit do |f| %>
2
+ <%= f.text_field :title %>
3
3
  <%= f.button :submit %>
4
- <% end %>
4
+ <% end %>
5
5
  <%= url_for(:host => "apotomo.de") %>
@@ -0,0 +1,7 @@
1
+ %h1 Dashboard
2
+
3
+ = SongCell::Lyrics.new(controller, :song => song, :phrases => ["In the Mirror", "I can see"]).show
4
+
5
+ = SongCell::PlaysCell.new(controller, :song => song).call
6
+
7
+ = cell("song_cell/plays").call
@@ -0,0 +1 @@
1
+ %h3 #{title}
@@ -0,0 +1 @@
1
+ %li #{render :title}
@@ -0,0 +1,6 @@
1
+ -# notice how we use title from the superclass here.
2
+ %h3 Lyrics for #{title}
3
+
4
+ - phrases.each do |ln|
5
+ %li
6
+ = ln
@@ -0,0 +1 @@
1
+ Plays: 99
@@ -0,0 +1,3 @@
1
+ %h1 #{title}
2
+
3
+ = link_to "Permalink", song
@@ -0,0 +1 @@
1
+ = title
@@ -0,0 +1,7 @@
1
+ %h1 "Comments from #{link_to title, Musician.new}"
2
+
3
+ = local
4
+
5
+ =# form
6
+
7
+ =# comment.created_at
@@ -18,25 +18,23 @@ end
18
18
 
19
19
 
20
20
  class CellBaseTest < MiniTest::Spec
21
- describe "Cell::Base" do
22
- it "still have a working #url_for" do
23
- cell = Cell::Base.new
24
- cell.instance_eval do
25
- # You can use #default_url_options.
26
- def default_url_options
27
- {:host => "cells-project.org"}
28
- end
29
-
21
+ it "still have a working #url_for" do
22
+ cell = Cell::Base.new
23
+ cell.instance_eval do
24
+ # You can use #default_url_options.
25
+ def default_url_options
26
+ {:host => "cells-project.org"}
30
27
  end
31
- # You could also use a *_url or *_path helper method here.
32
- assert_equal "http://cells-project.org/dashboard/show", cell.url_for(:action => :show, :controller => :dashboard)
28
+
33
29
  end
34
-
35
- describe ".render_cell_for" do
36
- it "invokes controller-less cell" do
37
- Cell::Base.view_paths= ["test/app/cells"]
38
- assert_equal "YAAAaaargh!\n", Cell::Base.render_cell_for(:shouter, :sing, "Y")
39
- end
30
+ # You could also use a *_url or *_path helper method here.
31
+ assert_equal "http://cells-project.org/dashboard/show", cell.url_for(:action => :show, :controller => :dashboard)
32
+ end
33
+
34
+ describe ".render_cell_for" do
35
+ it "invokes controller-less cell" do
36
+ Cell::Base.view_paths= ["test/app/cells"]
37
+ assert_equal "YAAAaaargh!\n", Cell::Base.render_cell_for(:shouter, :sing, "Y")
40
38
  end
41
39
  end
42
40
  end
@@ -50,19 +48,19 @@ class CellModuleTest < MiniTest::Spec
50
48
  it "render the actual cell" do
51
49
  assert_equal "Doo", Cell::Rails.render_cell_for(:bassist, :play, @controller)
52
50
  end
53
-
51
+
54
52
  it "accept a block, passing the cell instance" do
55
53
  flag = false
56
54
  html = Cell::Rails.render_cell_for(:bassist, :play, @controller) do |cell|
57
55
  assert_equal BassistCell, cell.class
58
56
  flag = true
59
57
  end
60
-
58
+
61
59
  assert_equal "Doo", html
62
60
  assert flag
63
61
  end
64
62
  end
65
-
63
+
66
64
  describe "create_cell_for" do
67
65
  it "call the cell's builders, eventually returning a different class" do
68
66
  class DrummerCell < BassistCell
@@ -70,22 +68,22 @@ class CellModuleTest < MiniTest::Spec
70
68
  BassistCell
71
69
  end
72
70
  end
73
-
71
+
74
72
  assert_instance_of BassistCell, Cell::Rails.create_cell_for("cell_module_test/drummer", :play, @controller)
75
73
  end
76
74
  end
77
-
75
+
78
76
  describe "#create_cell_for with #build" do
79
77
  before do
80
78
  @controller.class_eval do
81
79
  attr_accessor :bassist
82
80
  end
83
-
81
+
84
82
  MusicianCell.build do
85
83
  BassistCell if bassist
86
84
  end
87
85
  end
88
-
86
+
89
87
  after do
90
88
  MusicianCell.class_eval do
91
89
  @builders = false
@@ -94,40 +92,40 @@ class CellModuleTest < MiniTest::Spec
94
92
  @builders = false
95
93
  end
96
94
  end
97
-
95
+
98
96
  it "execute the block in controller describe" do
99
97
  @controller.bassist = true
100
98
  assert_is_a BassistCell, Cell::Rails.create_cell_for(:musician, @controller)
101
99
  end
102
-
100
+
103
101
  it "limit the builder to the receiving class" do
104
102
  assert_is_a PianistCell, Cell::Rails.create_cell_for(:pianist, @controller) # don't inherit anything.
105
103
  @controller.bassist = true
106
104
  assert_is_a BassistCell, Cell::Rails.create_cell_for(:musician, @controller)
107
105
  end
108
-
106
+
109
107
  it "chain build blocks and execute them by ORing them in the same order" do
110
108
  MusicianCell.build do
111
109
  PianistCell unless bassist
112
110
  end
113
-
111
+
114
112
  MusicianCell.build do
115
113
  UnknownCell # it never be executed.
116
114
  end
117
-
115
+
118
116
  assert_is_a PianistCell, Cell::Rails.create_cell_for(:musician, @controller) # bassist is false.
119
117
  @controller.bassist = true
120
118
  assert_is_a BassistCell, Cell::Rails.create_cell_for(:musician, @controller)
121
119
  end
122
-
120
+
123
121
  it "use the original cell if no builder matches" do
124
122
  assert_is_a MusicianCell, Cell::Rails.create_cell_for(:musician, @controller) # bassist is false.
125
123
  end
126
-
124
+
127
125
  it "stop at the first builder returning a valid cell" do
128
-
126
+
129
127
  end
130
-
128
+
131
129
  it "pass options to the block" do
132
130
  BassistCell.build do |opts|
133
131
  SingerCell if opts[:sing_the_song]
@@ -135,38 +133,38 @@ class CellModuleTest < MiniTest::Spec
135
133
  assert_kind_of BassistCell, Cell::Rails.create_cell_for(:bassist, @controller, {})
136
134
  assert_kind_of SingerCell, Cell::Rails.create_cell_for(:bassist, @controller, {:sing_the_song => true})
137
135
  end
138
-
136
+
139
137
  it "create the original target class if no block matches" do
140
138
  assert_kind_of PianistCell, Cell::Rails.create_cell_for(:pianist, @controller)
141
139
  end
142
-
140
+
143
141
  it "builders it return an empty array per default" do
144
142
  assert_equal [], PianistCell.send(:builders)
145
143
  end
146
144
  end
147
-
145
+
148
146
  it "provide class_from_cell_name" do
149
147
  assert_equal BassistCell, ::Cell::Rails.class_from_cell_name('bassist')
150
148
  end
151
-
149
+
152
150
  if Cell.rails3_0?
153
151
  it "provide possible_paths_for_state" do
154
152
  assert_equal ["bad_guitarist/play", "bassist/play"], cell(:bad_guitarist).send(:possible_paths_for_state, :play)
155
153
  end
156
-
154
+
157
155
  it "provide Cell.cell_name" do
158
156
  assert_equal 'bassist', cell(:bassist).class.cell_name
159
157
  end
160
-
158
+
161
159
  it "provide cell_name for modules, too" do
162
160
  class SingerCell < Cell::Rails
163
161
  end
164
-
162
+
165
163
  assert_equal "cell_module_test/singer", CellModuleTest::SingerCell.cell_name
166
164
  end
167
165
  end
168
166
  end
169
-
167
+
170
168
  it "respond to #rails3_1_or_more?" do
171
169
  if Rails::VERSION::MAJOR == 3
172
170
  if Rails::VERSION::MINOR == 0
data/test/cell_test.rb ADDED
@@ -0,0 +1,28 @@
1
+ require "test_helper"
2
+
3
+ class CellTest < MiniTest::Spec
4
+ class ArtistCell < Cell::Rails
5
+ end
6
+ class SongCell < Cell::Base
7
+ include Cell::OptionsConstructor
8
+ end
9
+
10
+ describe "#initialize" do
11
+ it { Class.new(Cell::Base) { include Cell::OptionsConstructor }.new(:song => song=Object.new).song.must_equal song }
12
+ it { Class.new(Cell::Rack) { include Cell::OptionsConstructor }.new(Object, :song => song=Object.new).song.must_equal song }
13
+ it { Class.new(Cell::Rails) { include Cell::OptionsConstructor }.new(Object, :song => song=Object.new).song.must_equal song }
14
+ end
15
+
16
+ describe "::create_cell_for" do
17
+ it { Cell::Base.create_cell_for("cell_test/song", :song => song=Object.new).song.must_equal song }
18
+ end
19
+
20
+ describe "#cell" do
21
+ it { Cell::Rails.new(Object).cell("cell_test/artist").must_be_instance_of ArtistCell }
22
+ it { Cell::Base.new.cell("cell_test/song").must_be_instance_of SongCell }
23
+ end
24
+ end
25
+
26
+ class OptionsConstructorTest < MiniTest::Spec
27
+ it { Class.new(Cell::Base) { include Cell::OptionsConstructor }.new(:song => song=Object.new).song.must_equal song }
28
+ end