cells 4.0.5 → 4.1.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (172) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +2 -14
  3. data/CHANGES.md +34 -7
  4. data/Gemfile +2 -2
  5. data/README.md +18 -88
  6. data/benchmarks/class_builder.rb +37 -0
  7. data/benchmarks/collection.rb +47 -0
  8. data/cells.gemspec +5 -7
  9. data/lib/cell.rb +2 -11
  10. data/lib/cell/builder.rb +16 -0
  11. data/lib/cell/collection.rb +54 -0
  12. data/lib/cell/concept.rb +6 -7
  13. data/lib/cell/escaped.rb +1 -0
  14. data/lib/cell/layout.rb +50 -14
  15. data/lib/cell/testing.rb +6 -5
  16. data/lib/cell/util.rb +10 -1
  17. data/lib/cell/version.rb +1 -1
  18. data/lib/cell/view_model.rb +27 -56
  19. data/lib/cells.rb +1 -1
  20. data/test/builder_test.rb +4 -2
  21. data/test/cell_test.rb +9 -2
  22. data/test/concept_test.rb +9 -16
  23. data/test/context_test.rb +33 -0
  24. data/test/fixtures/cell_test/song/show_with_block.erb +1 -0
  25. data/test/fixtures/comment/layout/show.erb +1 -0
  26. data/test/fixtures/comment/show/show.erb +1 -0
  27. data/test/fixtures/song/with_block.erb +1 -0
  28. data/test/layout_test.rb +34 -1
  29. data/test/prefixes_test.rb +3 -3
  30. data/test/public_test.rb +43 -9
  31. data/test/render_test.rb +7 -3
  32. data/test/test_helper.rb +2 -38
  33. data/test/{test_case_test.rb → testing_test.rb} +2 -2
  34. metadata +16 -159
  35. data/gemfiles/rails3.2.gemfile +0 -16
  36. data/gemfiles/rails4.0.gemfile +0 -12
  37. data/gemfiles/rails4.1.gemfile +0 -12
  38. data/gemfiles/rails4.2.gemfile +0 -10
  39. data/lib/cell/caching/notification.rb +0 -15
  40. data/lib/cell/rails.rb +0 -98
  41. data/lib/cell/railtie.rb +0 -69
  42. data/lib/cell/test_case.rb +0 -12
  43. data/lib/cell/translation.rb +0 -19
  44. data/lib/rails/generators/cell/cell_generator.rb +0 -43
  45. data/lib/rails/generators/cell/templates/cell.rb.erb +0 -8
  46. data/lib/rails/generators/cell/templates/view.erb +0 -7
  47. data/lib/rails/generators/cell/templates/view.haml +0 -4
  48. data/lib/rails/generators/cell/templates/view.slim +0 -2
  49. data/lib/rails/generators/concept/concept_generator.rb +0 -38
  50. data/lib/rails/generators/concept/templates/concept.rb.erb +0 -7
  51. data/lib/rails/generators/concept/templates/view.erb +0 -7
  52. data/lib/rails/generators/concept/templates/view.haml +0 -4
  53. data/lib/rails/generators/concept/templates/view.slim +0 -2
  54. data/lib/rails/generators/test_unit/cell/cell_generator.rb +0 -21
  55. data/lib/rails/generators/test_unit/cell/templates/unit_test.rb.erb +0 -11
  56. data/lib/rails/generators/test_unit/concept/concept_generator.rb +0 -21
  57. data/lib/rails/generators/test_unit/concept/templates/unit_test.rb.erb +0 -11
  58. data/test/caching_test.rb +0 -305
  59. data/test/cell_generator_test.rb +0 -90
  60. data/test/concept_generator_test.rb +0 -40
  61. data/test/dummy/Rakefile +0 -7
  62. data/test/dummy/app/assets/javascripts/application.js +0 -2
  63. data/test/dummy/app/cells/album/assets/album.js +0 -1
  64. data/test/dummy/app/concepts/song/assets/songs.js +0 -1
  65. data/test/dummy/app/controllers/application_controller.rb +0 -4
  66. data/test/dummy/app/views/layouts/application.html.erb +0 -14
  67. data/test/dummy/app/views/musician/featured.html.erb +0 -1
  68. data/test/dummy/app/views/musician/featured_with_block.html.erb +0 -4
  69. data/test/dummy/app/views/musician/hamlet.html.erb +0 -1
  70. data/test/dummy/app/views/musician/title.erb +0 -1
  71. data/test/dummy/config.ru +0 -4
  72. data/test/dummy/config/application.rb +0 -41
  73. data/test/dummy/config/boot.rb +0 -10
  74. data/test/dummy/config/database.yml +0 -22
  75. data/test/dummy/config/environment.rb +0 -5
  76. data/test/dummy/config/locales/en.yml +0 -5
  77. data/test/dummy/config/routes.rb +0 -5
  78. data/test/dummy/script/rails +0 -6
  79. data/test/rails/translation_test.rb +0 -45
  80. data/test/rails4.2/.gitignore +0 -13
  81. data/test/rails4.2/Gemfile +0 -18
  82. data/test/rails4.2/README.rdoc +0 -3
  83. data/test/rails4.2/Rakefile +0 -6
  84. data/test/rails4.2/app/assets/images/.keep +0 -0
  85. data/test/rails4.2/app/assets/stylesheets/application.css.erb +0 -19
  86. data/test/rails4.2/app/cells/form_for/show.erb +0 -7
  87. data/test/rails4.2/app/cells/form_for_cell.rb +0 -7
  88. data/test/rails4.2/app/cells/form_tag/show.erb +0 -5
  89. data/test/rails4.2/app/cells/form_tag_cell.rb +0 -5
  90. data/test/rails4.2/app/cells/formtastic/show.erb +0 -12
  91. data/test/rails4.2/app/cells/formtastic_cell.rb +0 -9
  92. data/test/rails4.2/app/cells/simple_form/show.erb +0 -7
  93. data/test/rails4.2/app/cells/simple_form_cell.rb +0 -11
  94. data/test/rails4.2/app/cells/song/song.css +0 -1
  95. data/test/rails4.2/app/cells/song/with_escaped.erb +0 -1
  96. data/test/rails4.2/app/cells/song_cell.rb +0 -18
  97. data/test/rails4.2/app/controllers/application_controller.rb +0 -5
  98. data/test/rails4.2/app/controllers/concerns/.keep +0 -0
  99. data/test/rails4.2/app/controllers/index_controller.rb +0 -7
  100. data/test/rails4.2/app/controllers/songs_controller.rb +0 -25
  101. data/test/rails4.2/app/helpers/application_helper.rb +0 -2
  102. data/test/rails4.2/app/mailers/.keep +0 -0
  103. data/test/rails4.2/app/models/.keep +0 -0
  104. data/test/rails4.2/app/models/artist.rb +0 -25
  105. data/test/rails4.2/app/models/concerns/.keep +0 -0
  106. data/test/rails4.2/app/models/song.rb +0 -25
  107. data/test/rails4.2/app/views/index/index.html.erb +0 -6
  108. data/test/rails4.2/app/views/layouts/application.html.erb +0 -13
  109. data/test/rails4.2/app/views/songs/show.html.erb +0 -1
  110. data/test/rails4.2/app/views/songs/with_escaped.html.erb +0 -1
  111. data/test/rails4.2/bin/bundle +0 -3
  112. data/test/rails4.2/bin/rails +0 -4
  113. data/test/rails4.2/bin/rake +0 -4
  114. data/test/rails4.2/bin/setup +0 -29
  115. data/test/rails4.2/config.ru +0 -4
  116. data/test/rails4.2/config/application.rb +0 -38
  117. data/test/rails4.2/config/boot.rb +0 -3
  118. data/test/rails4.2/config/environment.rb +0 -5
  119. data/test/rails4.2/config/environments/development.rb +0 -25
  120. data/test/rails4.2/config/environments/production.rb +0 -64
  121. data/test/rails4.2/config/environments/test.rb +0 -42
  122. data/test/rails4.2/config/initializers/backtrace_silencers.rb +0 -7
  123. data/test/rails4.2/config/initializers/cookies_serializer.rb +0 -3
  124. data/test/rails4.2/config/initializers/filter_parameter_logging.rb +0 -4
  125. data/test/rails4.2/config/initializers/formtastic.rb +0 -2
  126. data/test/rails4.2/config/initializers/inflections.rb +0 -16
  127. data/test/rails4.2/config/initializers/mime_types.rb +0 -4
  128. data/test/rails4.2/config/initializers/session_store.rb +0 -3
  129. data/test/rails4.2/config/initializers/wrap_parameters.rb +0 -9
  130. data/test/rails4.2/config/locales/en.yml +0 -23
  131. data/test/rails4.2/config/routes.rb +0 -9
  132. data/test/rails4.2/config/secrets.yml +0 -22
  133. data/test/rails4.2/db/seeds.rb +0 -7
  134. data/test/rails4.2/engines/my_engine/.gitignore +0 -3
  135. data/test/rails4.2/engines/my_engine/Gemfile +0 -15
  136. data/test/rails4.2/engines/my_engine/MIT-LICENSE +0 -20
  137. data/test/rails4.2/engines/my_engine/README.rdoc +0 -3
  138. data/test/rails4.2/engines/my_engine/Rakefile +0 -24
  139. data/test/rails4.2/engines/my_engine/app/assets/images/my_engine/.keep +0 -0
  140. data/test/rails4.2/engines/my_engine/app/assets/stylesheets/my_engine/application.css +0 -15
  141. data/test/rails4.2/engines/my_engine/app/concepts/user/cell.rb +0 -8
  142. data/test/rails4.2/engines/my_engine/app/concepts/user/views/show.erb +0 -1
  143. data/test/rails4.2/engines/my_engine/app/concepts/user/views/user.scss +0 -3
  144. data/test/rails4.2/engines/my_engine/app/controllers/my_engine/application_controller.rb +0 -4
  145. data/test/rails4.2/engines/my_engine/app/controllers/my_engine/user_controller.rb +0 -7
  146. data/test/rails4.2/engines/my_engine/app/helpers/my_engine/application_helper.rb +0 -4
  147. data/test/rails4.2/engines/my_engine/app/models/my_engine/user.rb +0 -4
  148. data/test/rails4.2/engines/my_engine/app/views/layouts/my_engine/application.html.erb +0 -14
  149. data/test/rails4.2/engines/my_engine/app/views/my_engine/user/show.html.erb +0 -3
  150. data/test/rails4.2/engines/my_engine/bin/rails +0 -12
  151. data/test/rails4.2/engines/my_engine/config/routes.rb +0 -3
  152. data/test/rails4.2/engines/my_engine/db/migrate/20150530135920_create_my_engine_users.rb +0 -8
  153. data/test/rails4.2/engines/my_engine/lib/my_engine.rb +0 -6
  154. data/test/rails4.2/engines/my_engine/lib/my_engine/engine.rb +0 -9
  155. data/test/rails4.2/engines/my_engine/lib/my_engine/version.rb +0 -3
  156. data/test/rails4.2/engines/my_engine/lib/tasks/my_engine_tasks.rake +0 -4
  157. data/test/rails4.2/engines/my_engine/my_engine.gemspec +0 -24
  158. data/test/rails4.2/engines/my_engine/test/fixtures/my_engine/users.yml +0 -11
  159. data/test/rails4.2/engines/my_engine/test/models/my_engine/user_test.rb +0 -9
  160. data/test/rails4.2/lib/assets/.keep +0 -0
  161. data/test/rails4.2/lib/tasks/.keep +0 -0
  162. data/test/rails4.2/log/.keep +0 -0
  163. data/test/rails4.2/test/integration/asset_pipeline_test.rb +0 -17
  164. data/test/rails4.2/test/integration/controller_test.rb +0 -16
  165. data/test/rails4.2/test/integration/form_for_test.rb +0 -10
  166. data/test/rails4.2/test/integration/form_tag_test.rb +0 -11
  167. data/test/rails4.2/test/integration/formtastic_test.rb +0 -12
  168. data/test/rails4.2/test/integration/simple_form_test.rb +0 -11
  169. data/test/rails4.2/test/integration/url_helper_test.rb +0 -47
  170. data/test/rails4.2/test/test_helper.rb +0 -14
  171. data/test/rails4.2/vendor/assets/stylesheets/.keep +0 -0
  172. data/test/rails_extensions_test.rb +0 -51
@@ -0,0 +1,16 @@
1
+ require "uber/builder"
2
+
3
+ module Cell
4
+ module Builder
5
+ def self.included(base)
6
+ base.send :include, Uber::Builder
7
+ base.extend ClassMethods
8
+ end
9
+
10
+ module ClassMethods
11
+ def build(*args)
12
+ class_builder.call(*args).new(*args) # Uber::Builder::class_builder.
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,54 @@
1
+ module Cell
2
+ class Collection
3
+ def initialize(ary, options, cell_class)
4
+ options.delete(:collection)
5
+ @method = options.delete(:method) # TODO: remove in 5.0.
6
+ @join = options.delete(:collection_join) # TODO: remove in 5.0.
7
+
8
+ @ary = ary
9
+ @options = options
10
+ @cell_class = cell_class
11
+
12
+ deprecate_options!
13
+ end
14
+
15
+ def deprecate_options! # TODO: remove in 5.0.
16
+ warn "[Cells] The :method option is deprecated. Please use `call(method)` as documented here: http://trailblazer.to/gems/cells/api.html#collection" if @method
17
+ warn "[Cells] The :collection_join option is deprecated. Please use `join(\"<br>\")` as documented here: http://trailblazer.to/gems/cells/api.html#collection" if @collection_join
18
+ end
19
+
20
+ module Call
21
+ def call(state=:show)
22
+ join(@join) { |cell, i| cell.(@method || state) }
23
+ end
24
+ end
25
+ include Call
26
+
27
+ alias to_s call
28
+
29
+ # Iterate collection and build a cell for each item.
30
+ # The passed block receives that cell and the index.
31
+ # Its return value is captured and joined.
32
+ def join(separator="", &block)
33
+ @ary.each_with_index.collect do |model, i|
34
+ yield @cell_class.build(model, @options), i
35
+ end.
36
+ join(separator)
37
+ end
38
+
39
+ module Layout
40
+ def call(*) # WARNING: THIS IS NOT FINAL API.
41
+ layout = @options.delete(:layout) # we could also override #initialize and that there?
42
+
43
+ content = super # DISCUSS: that could come in via the pipeline argument.
44
+ ViewModel::Layout::External::Render.(content, @ary, layout, @options)
45
+ end
46
+ end
47
+ include Layout
48
+
49
+ end
50
+ end
51
+
52
+ # Collection#call
53
+ # |> Header#call
54
+ # |> Layout#call
@@ -1,12 +1,16 @@
1
+ require "cell/self_contained"
2
+
1
3
  module Cell
4
+ # Cell::Concept is no longer under active development. Please switch to Trailblazer::Cell.
2
5
  class Concept < Cell::ViewModel
3
6
  abstract!
4
7
  self.view_paths = ["app/concepts"]
8
+ extend SelfContained
5
9
 
6
10
  # TODO: this should be in Helper or something. this should be the only entry point from controller/view.
7
11
  class << self
8
12
  def class_from_cell_name(name)
9
- name.camelize.constantize
13
+ util.constant_for(name)
10
14
  end
11
15
 
12
16
  def controller_path
@@ -14,12 +18,7 @@ module Cell
14
18
  end
15
19
  end
16
20
 
17
- alias_method :concept, :cell # Concept#concept does exactly what #cell does: delegate to class builder.
18
-
19
- # Get nested cell in instance.
20
- def cell(name, model=nil, options={})
21
- ViewModel.cell(name, model, options.merge(controller: parent_controller)) # #cell calls need to be delegated to ViewModel.
22
- end
21
+ alias_method :concept, :cell
23
22
 
24
23
  self_contained!
25
24
  end
@@ -23,6 +23,7 @@ module Cell::ViewModel::Escaped
23
23
 
24
24
  # Can be used as a helper in the cell, too.
25
25
  # Feel free to override and use a different escaping implementation.
26
+ require "erb"
26
27
  def escape!(string)
27
28
  ::ERB::Util.html_escape(string)
28
29
  end
@@ -1,20 +1,56 @@
1
1
  module Cell
2
- # Set the layout per cell class. This is used in #render calls. Gets inherited to subclasses.
3
- module Layout
4
- def self.included(base)
5
- base.extend ClassMethods
6
- base.inheritable_attr :layout_name
7
- end
2
+ class ViewModel
3
+ # Set the layout per cell class. This is used in #render calls. Gets inherited to subclasses.
4
+ module Layout
5
+ def self.included(base)
6
+ base.extend ClassMethods
7
+ base.inheritable_attr :layout_name
8
+ end
8
9
 
9
- module ClassMethods
10
- def layout(name)
11
- self.layout_name = name
10
+ module ClassMethods
11
+ def layout(name)
12
+ self.layout_name = name
13
+ end
12
14
  end
13
- end
14
15
 
15
- def process_options!(options)
16
- options[:layout] ||= self.class.layout_name
17
- super
16
+ private
17
+ def process_options!(options)
18
+ options[:layout] ||= self.class.layout_name
19
+ super
20
+ end
21
+
22
+ def render_to_string(options, &block)
23
+ with_layout(options, super)
24
+ end
25
+
26
+ def with_layout(options, content)
27
+ return content unless layout = options[:layout]
28
+
29
+ render_layout(layout, options, content)
30
+ end
31
+
32
+ def render_layout(name, options, content)
33
+ template = find_template(options.merge view: name) # we could also allow a different layout engine, etc.
34
+ render_template(template, options) { content }
35
+ end
36
+
37
+ # Allows using a separate layout cell which will wrap the actual content.
38
+ # Use like cell(..., layout: Cell::Layout)
39
+ #
40
+ # Note that still allows the `render layout: :application` option.
41
+ module External
42
+ def call(*)
43
+ content = super
44
+ Render.(content, model, @options[:layout], @options)
45
+ end
46
+
47
+ Render = ->(content, model, layout, options) do # WARNING: THIS IS NOT FINAL API.
48
+ return content unless layout = layout # TODO: test when invoking cell without :layout.
49
+
50
+ # DISCUSS: should we allow instances, too? we could cache the layout cell.
51
+ layout.new(model, context: options[:context]).(&lambda { content })
52
+ end
53
+ end # External
18
54
  end
19
55
  end
20
- end
56
+ end
@@ -12,13 +12,14 @@ module Cell
12
12
 
13
13
  private
14
14
  def cell_for(baseclass, name, model=nil, options={})
15
- cell = baseclass.cell(name, model, options.merge(controller: controller))
15
+ options[:context] ||= {}
16
+ options[:context][:controller] = controller
16
17
 
17
- if Cell::Testing.capybara? # leaving this here as most people use Capybara.
18
- return ::Capybara::string(cell) unless cell.is_a?(Cell::ViewModel) # HORRIBLE hack, will be fixed with new collection API in 4.1 :)
19
- cell.extend(Capybara)
20
- end
18
+ cell = baseclass.cell(name, model, options)
21
19
 
20
+ cell.extend(Capybara) if Cell::Testing.capybara? # leaving this here as most people use Capybara.
21
+ # apparently it's ok to only override ViewModel#call and capybararize the result.
22
+ # when joining in a Collection, the joint will still be capybararized.
22
23
  cell
23
24
  end
24
25
 
@@ -12,5 +12,14 @@ module Cell::Util
12
12
  tr("-", "_").
13
13
  downcase
14
14
  end
15
+
16
+ # WARNING: this API might change.
17
+ def self.constant_for(name)
18
+ constant = Object
19
+ name.split("/").each do |part|
20
+ constant = constant.const_get(part.split('_').collect(&:capitalize).join)
21
+ end
22
+ constant
23
+ end
15
24
  end
16
- end
25
+ end
@@ -1,3 +1,3 @@
1
1
  module Cell
2
- VERSION = "4.0.5"
2
+ VERSION = "4.1.0.rc1"
3
3
  end
@@ -3,13 +3,8 @@ module Cell
3
3
  extend Abstract
4
4
  abstract!
5
5
 
6
- def controller_path
7
- self.class.controller_path
8
- end
9
-
10
6
  extend Uber::InheritableAttr
11
7
  extend Uber::Delegates
12
- include Uber::Builder
13
8
 
14
9
  inheritable_attr :view_paths
15
10
  self.view_paths = ["app/cells"]
@@ -21,7 +16,6 @@ module Cell
21
16
  end
22
17
 
23
18
  include Prefixes
24
- extend SelfContained
25
19
  extend Util
26
20
 
27
21
  def self.controller_path
@@ -31,17 +25,10 @@ module Cell
31
25
  attr_reader :model
32
26
 
33
27
  module Helpers
34
- # Constantizes name, call builders and returns instance.
28
+ # Constantizes name if needed, call builders and returns instance.
35
29
  def cell(name, *args, &block) # classic Rails fuzzy API.
36
- class_from_cell_name(name).(*args, &block)
37
- end
38
-
39
- private
40
- # Renders collection of cells.
41
- def render_collection(array, options) # private.
42
- method = options.delete(:method) || :show
43
- join = options.delete(:collection_join)
44
- array.collect { |model| build(model, options).call(method) }.join(join).html_safe
30
+ constant = name.is_a?(Class) ? name : class_from_cell_name(name)
31
+ constant.(*args, &block)
45
32
  end
46
33
  end
47
34
  extend Helpers
@@ -51,82 +38,66 @@ module Cell
51
38
  delegates :model, *names # Uber::Delegates.
52
39
  end
53
40
 
54
- include Helpers
55
-
56
41
  # Public entry point. Use this to instantiate cells with builders.
57
42
  #
58
43
  # SongCell.(@song)
59
44
  # SongCell.(collection: Song.all)
60
45
  def call(model=nil, options={}, &block)
61
- if model.is_a?(Hash) and array = model.delete(:collection)
62
- return render_collection(array, model.merge(options))
46
+ if model.is_a?(Hash) and array = model[:collection]
47
+ return Collection.new(array, model.merge(options), self)
63
48
  end
64
49
 
65
50
  build(model, options)
66
51
  end
67
52
 
68
- def build(*args) # semi-public.
69
- class_builder.call(*args).new(*args) # Uber::Builder::class_builder.
70
- end
53
+ alias build new # semi-public for Cell::Builder
71
54
 
72
55
  private
73
56
  def class_from_cell_name(name)
74
- "#{name}_cell".camelize.constantize
57
+ util.constant_for("#{name}_cell")
75
58
  end
76
59
  end
77
60
 
78
- # Get nested cell in instance.
61
+ # Build nested cell in instance.
79
62
  def cell(name, model=nil, options={})
80
- self.class.cell(name, model, options.merge(controller: parent_controller))
63
+ self.class.cell(name, model, options.merge(context: context))
81
64
  end
82
65
 
83
- def initialize(model=nil, options={}) # in Ruby 2: def m(model: nil, controller:nil, **options) that'll make the controller optional.
84
- # options = options.clone # DISCUSS: this could be time consuming when rendering many of em.
85
- @parent_controller = options[:controller] # TODO: filter out controller in a performant way.
86
-
66
+ def initialize(model=nil, options={})
87
67
  setup!(model, options)
88
68
  end
89
- attr_reader :parent_controller
90
- alias_method :controller, :parent_controller
69
+
70
+ def context # TODO: explicit test.
71
+ @options[:context]
72
+ end
91
73
 
92
74
  module Rendering
93
75
  # Invokes the passed method (defaults to :show) while respecting caching.
94
76
  # In Rails, the return value gets marked html_safe.
95
- #
96
- # Yields +self+ to an optional block.
97
- def call(state=:show, *args)
98
- content = render_state(state, *args)
99
- yield self if block_given?
100
-
77
+ def call(state=:show, *args, &block)
78
+ content = render_state(state, *args, &block)
101
79
  content.to_s
102
80
  end
103
81
 
82
+ # Since 4.1, you get the #show method for free.
83
+ def show(&block)
84
+ render(&block)
85
+ end
86
+
104
87
  # render :show
105
- def render(options={})
88
+ def render(options={}, &block)
106
89
  options = normalize_options(options)
107
- render_to_string(options)
90
+ render_to_string(options, &block)
108
91
  end
109
92
 
110
93
  private
111
- def render_to_string(options)
94
+ def render_to_string(options, &block)
112
95
  template = find_template(options)
113
-
114
- content = render_template(template, options)
115
-
116
- # TODO: allow other (global) layout dirs.
117
- with_layout(options, content)
118
- end
119
-
120
- def render_state(*args)
121
- __send__(*args)
96
+ render_template(template, options, &block)
122
97
  end
123
98
 
124
- def with_layout(options, content)
125
- return content unless layout = options[:layout]
126
-
127
- template = find_template(options.merge view: layout) # we could also allow a different layout engine, etc.
128
-
129
- render_template(template, options) { content }
99
+ def render_state(*args, &block)
100
+ __send__(*args, &block)
130
101
  end
131
102
 
132
103
  def render_template(template, options, &block)
@@ -1 +1 @@
1
- require 'cell'
1
+ require "cell"
@@ -5,6 +5,8 @@ class BuilderTest < MiniTest::Spec
5
5
  Hit = Struct.new(:title)
6
6
 
7
7
  class SongCell < Cell::ViewModel
8
+ include Cell::Builder
9
+
8
10
  builds do |model, options|
9
11
  if model.is_a? Hit
10
12
  HitCell
@@ -52,10 +54,10 @@ class BuilderTest < MiniTest::Spec
52
54
  it { SongCell.(Hit.new("Frenzy")).must_be_instance_of HitCell }
53
55
 
54
56
  # with collection.
55
- it { SongCell.(collection: [Song.new("Nation States"), Hit.new("New York")]).must_equal "* Nation States* **New York**" }
57
+ it { SongCell.(collection: [Song.new("Nation States"), Hit.new("New York")]).().must_equal "* Nation States* **New York**" }
56
58
 
57
59
  # with Concept
58
60
  class Track < Cell::Concept
59
61
  end
60
62
  it { Track.().must_be_instance_of Track }
61
- end
63
+ end
@@ -2,12 +2,19 @@ require 'test_helper'
2
2
 
3
3
  class CellTest < MiniTest::Spec
4
4
  class SongCell < Cell::ViewModel
5
+ self.view_paths = ['test/fixtures']
6
+
5
7
  def show
6
8
  end
9
+
10
+ def show_with_block(&block)
11
+ render(&block)
12
+ end
7
13
  end
8
- # ::rails_version
9
- it { Cell.rails_version.must_equal Gem::Version.new(ActionPack::VERSION::STRING) }
10
14
 
11
15
  # #options
12
16
  it { SongCell.new(nil, genre: "Punkrock").send(:options)[:genre].must_equal "Punkrock" }
17
+
18
+ # #block
19
+ it { SongCell.new(nil, genre: "Punkrock").(:show_with_block) { "hello" }.must_equal "<b>hello</b>\n" }
13
20
  end
@@ -27,7 +27,7 @@ module Record
27
27
 
28
28
 
29
29
  def description
30
- "A Tribute To Rancid, with #{@options[:tracks]} songs! [#{parent_controller}]"
30
+ "A Tribute To Rancid, with #{@options[:tracks]} songs! [#{context}]"
31
31
  end
32
32
  end
33
33
  end
@@ -48,10 +48,10 @@ end
48
48
 
49
49
  class ConceptTest < MiniTest::Spec
50
50
  describe "::controller_path" do
51
- it { Record::Cell.new.controller_path.must_equal "record" }
52
- it { Record::Cell::Song.new.controller_path.must_equal "record/song" }
53
- it { Record::Cells::Cell.new.controller_path.must_equal "record/cells" }
54
- it { Record::Cells::Cell::Song.new.controller_path.must_equal "record/cells/song" }
51
+ it { Record::Cell.new.class.controller_path.must_equal "record" }
52
+ it { Record::Cell::Song.new.class.controller_path.must_equal "record/song" }
53
+ it { Record::Cells::Cell.new.class.controller_path.must_equal "record/cells" }
54
+ it { Record::Cells::Cell::Song.new.class.controller_path.must_equal "record/cells/song" }
55
55
  end
56
56
 
57
57
 
@@ -74,19 +74,12 @@ class ConceptTest < MiniTest::Spec
74
74
  it { Cell::Concept.cell("record/cell/song").show.must_equal "Lalala" }
75
75
  end
76
76
 
77
-
78
- class RecordCell < Cell::ViewModel
79
- def description
80
- "Record! A Tribute To Rancid, with #{@options[:tracks]} songs! [#{parent_controller}]"
81
- end
82
- end
83
-
84
77
  describe "#cell (in state)" do
85
78
  # test with controller, but remove tests when we don't need it anymore.
86
- it { Cell::Concept.cell("record/cell", nil, controller: Object).cell("concept_test/record", nil, tracks: 24).(:description).must_equal "Record! A Tribute To Rancid, with 24 songs! [Object]" }
87
- it { Cell::Concept.cell("record/cell", nil, controller: Object).concept("record/cell", nil, tracks: 24).(:description).must_equal "A Tribute To Rancid, with 24 songs! [Object]" }
79
+ it { Cell::Concept.cell("record/cell", nil, context: { controller: Object }).cell("record/cell", nil).must_be_instance_of Record::Cell }
80
+ it { Cell::Concept.cell("record/cell", nil, context: { controller: Object }).concept("record/cell", nil, tracks: 24).(:description).must_equal "A Tribute To Rancid, with 24 songs! [{:controller=>Object}]" }
88
81
  # concept(.., collection: ..)
89
- it { Cell::Concept.cell("record/cell", nil, controller: Object).
90
- concept("record/cell", collection: [1,2], tracks: 24, method: :description).must_equal "A Tribute To Rancid, with 24 songs! [Object]A Tribute To Rancid, with 24 songs! [Object]" }
82
+ it { Cell::Concept.cell("record/cell", nil, context: { controller: Object }).
83
+ concept("record/cell", collection: [1,2], tracks: 24, method: :description).().must_equal "A Tribute To Rancid, with 24 songs! [{:controller=>Object}]A Tribute To Rancid, with 24 songs! [{:controller=>Object}]" }
91
84
  end
92
85
  end