cells 4.1.7 → 4.1.8
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.
- checksums.yaml +5 -5
- data/CHANGES.md +5 -0
- data/README.md +18 -19
- data/cells.gemspec +30 -22
- data/lib/cell/version.rb +1 -1
- data/lib/cell/view_model.rb +1 -2
- metadata +58 -78
- data/.gitignore +0 -9
- data/.travis.yml +0 -16
- data/Gemfile +0 -10
- data/Rakefile +0 -28
- data/TODO.md +0 -12
- data/benchmarks/class_builder.rb +0 -37
- data/benchmarks/collection.rb +0 -47
- data/test/builder_test.rb +0 -63
- data/test/cache_test.rb +0 -32
- data/test/cell_benchmark.rb +0 -32
- data/test/cell_test.rb +0 -20
- data/test/concept_test.rb +0 -87
- data/test/context_test.rb +0 -44
- data/test/fixtures/bassist/play.erb +0 -1
- data/test/fixtures/cell_test/song/show_with_block.erb +0 -1
- data/test/fixtures/comment/layout/show.erb +0 -1
- data/test/fixtures/comment/show/show.erb +0 -1
- data/test/fixtures/concepts/record/views/layout.erb +0 -1
- data/test/fixtures/concepts/record/views/show.erb +0 -1
- data/test/fixtures/concepts/record/views/song.erb +0 -1
- data/test/fixtures/inherit_views_test/popper/tap.erb +0 -1
- data/test/fixtures/inherit_views_test/tapper/play.erb +0 -1
- data/test/fixtures/inherit_views_test/tapper/tap.erb +0 -1
- data/test/fixtures/partial_test/with_partial/show.erb +0 -1
- data/test/fixtures/partials/_show.html.erb +0 -1
- data/test/fixtures/partials/_show.xml.erb +0 -1
- data/test/fixtures/song/ivar.erb +0 -1
- data/test/fixtures/song/show.erb +0 -1
- data/test/fixtures/song/with_block.erb +0 -1
- data/test/fixtures/song/with_erb.erb +0 -4
- data/test/fixtures/song/with_html.erb +0 -1
- data/test/fixtures/song/with_locals.erb +0 -2
- data/test/fixtures/song_with_layout/happy.erb +0 -1
- data/test/fixtures/song_with_layout/merry.erb +0 -1
- data/test/fixtures/song_with_layout/show.erb +0 -1
- data/test/fixtures/song_with_layout/show_with_layout.erb +0 -1
- data/test/fixtures/templates_caching_test/song/show.erb +0 -1
- data/test/fixtures/url_helper_test/song/edit.erb +0 -8
- data/test/fixtures/url_helper_test/song/with_block.erb +0 -2
- data/test/fixtures/url_helper_test/song/with_capture.erb +0 -4
- data/test/fixtures/url_helper_test/song/with_content_tag.erb +0 -6
- data/test/fixtures/url_helper_test/song/with_form_for_block.erb +0 -3
- data/test/fixtures/url_helper_test/song/with_link_to.erb +0 -3
- data/test/layout_test.rb +0 -88
- data/test/partial_test.rb +0 -35
- data/test/prefixes_test.rb +0 -133
- data/test/property_test.rb +0 -48
- data/test/public_test.rb +0 -99
- data/test/render_test.rb +0 -115
- data/test/templates_test.rb +0 -44
- data/test/test_helper.rb +0 -13
- data/test/testing_test.rb +0 -59
- data/test/twin_test.rb +0 -26
data/test/property_test.rb
DELETED
@@ -1,48 +0,0 @@
|
|
1
|
-
require "test_helper"
|
2
|
-
|
3
|
-
class PropertyTest < MiniTest::Spec
|
4
|
-
class SongCell < Cell::ViewModel
|
5
|
-
property :title
|
6
|
-
|
7
|
-
def title
|
8
|
-
super + "</b>"
|
9
|
-
end
|
10
|
-
end
|
11
|
-
|
12
|
-
let (:song) { Struct.new(:title).new("<b>She Sells And Sand Sandwiches") }
|
13
|
-
# ::property creates automatic accessor.
|
14
|
-
it { SongCell.(song).title.must_equal "<b>She Sells And Sand Sandwiches</b>" }
|
15
|
-
end
|
16
|
-
|
17
|
-
|
18
|
-
class EscapedPropertyTest < MiniTest::Spec
|
19
|
-
class SongCell < Cell::ViewModel
|
20
|
-
include Escaped
|
21
|
-
property :title
|
22
|
-
property :artist
|
23
|
-
property :copyright, :lyrics
|
24
|
-
|
25
|
-
def title(*)
|
26
|
-
"#{super}</b>" # super + "</b>" still escapes, but this is Rails.
|
27
|
-
end
|
28
|
-
|
29
|
-
def raw_title
|
30
|
-
title(escape: false)
|
31
|
-
end
|
32
|
-
end
|
33
|
-
|
34
|
-
let (:song) do
|
35
|
-
Struct
|
36
|
-
.new(:title, :artist, :copyright, :lyrics)
|
37
|
-
.new("<b>She Sells And Sand Sandwiches", Object, "<a>Copy</a>", "<i>Words</i>")
|
38
|
-
end
|
39
|
-
|
40
|
-
# ::property escapes, everywhere.
|
41
|
-
it { SongCell.(song).title.must_equal "<b>She Sells And Sand Sandwiches</b>" }
|
42
|
-
it { SongCell.(song).copyright.must_equal "<a>Copy</a>" }
|
43
|
-
it { SongCell.(song).lyrics.must_equal "<i>Words</i>" }
|
44
|
-
# no escaping for non-strings.
|
45
|
-
it { SongCell.(song).artist.must_equal Object }
|
46
|
-
# no escaping when escape: false
|
47
|
-
it { SongCell.(song).raw_title.must_equal "<b>She Sells And Sand Sandwiches</b>" }
|
48
|
-
end
|
data/test/public_test.rb
DELETED
@@ -1,99 +0,0 @@
|
|
1
|
-
require 'test_helper'
|
2
|
-
|
3
|
-
class PublicTest < MiniTest::Spec
|
4
|
-
class SongCell < Cell::ViewModel
|
5
|
-
def initialize(*args)
|
6
|
-
@initialize_args = *args
|
7
|
-
end
|
8
|
-
attr_reader :initialize_args
|
9
|
-
|
10
|
-
def show
|
11
|
-
initialize_args.inspect
|
12
|
-
end
|
13
|
-
|
14
|
-
def detail
|
15
|
-
"* #{initialize_args}"
|
16
|
-
end
|
17
|
-
end
|
18
|
-
|
19
|
-
class Songs < Cell::Concept
|
20
|
-
end
|
21
|
-
|
22
|
-
# ViewModel.cell returns the cell instance.
|
23
|
-
it { Cell::ViewModel.cell("public_test/song").must_be_instance_of SongCell }
|
24
|
-
it { Cell::ViewModel.cell(PublicTest::SongCell).must_be_instance_of SongCell }
|
25
|
-
|
26
|
-
# Concept.cell simply camelizes the string before constantizing.
|
27
|
-
it { Cell::Concept.cell("public_test/songs").must_be_instance_of Songs }
|
28
|
-
|
29
|
-
it { Cell::Concept.cell(PublicTest::Songs).must_be_instance_of Songs }
|
30
|
-
|
31
|
-
# ViewModel.cell passes options to cell.
|
32
|
-
it { Cell::ViewModel.cell("public_test/song", Object, genre: "Metal").initialize_args.must_equal [Object, {genre:"Metal"}] }
|
33
|
-
|
34
|
-
# ViewModel.cell(collection: []) renders cells.
|
35
|
-
it { Cell::ViewModel.cell("public_test/song", collection: [Object, Module]).to_s.must_equal '[Object, {}][Module, {}]' }
|
36
|
-
|
37
|
-
# DISCUSS: should cell.() be the default?
|
38
|
-
# ViewModel.cell(collection: []) renders cells with custom join.
|
39
|
-
it do
|
40
|
-
Gem::Deprecate::skip_during do
|
41
|
-
Cell::ViewModel.cell("public_test/song", collection: [Object, Module]).join('<br/>') do |cell|
|
42
|
-
cell.()
|
43
|
-
end.must_equal '[Object, {}]<br/>[Module, {}]'
|
44
|
-
end
|
45
|
-
end
|
46
|
-
|
47
|
-
# ViewModel.cell(collection: []) passes generic options to cell.
|
48
|
-
it { Cell::ViewModel.cell("public_test/song", collection: [Object, Module], genre: 'Metal', context: { ready: true }).to_s.must_equal "[Object, {:genre=>\"Metal\", :context=>{:ready=>true}}][Module, {:genre=>\"Metal\", :context=>{:ready=>true}}]" }
|
49
|
-
|
50
|
-
# ViewModel.cell(collection: [], method: :detail) invokes #detail instead of #show.
|
51
|
-
# TODO: remove in 5.0.
|
52
|
-
it do
|
53
|
-
Gem::Deprecate::skip_during do
|
54
|
-
Cell::ViewModel.cell("public_test/song", collection: [Object, Module], method: :detail).to_s.must_equal '* [Object, {}]* [Module, {}]'
|
55
|
-
end
|
56
|
-
end
|
57
|
-
|
58
|
-
# ViewModel.cell(collection: []).() invokes #show.
|
59
|
-
it { Cell::ViewModel.cell("public_test/song", collection: [Object, Module]).().must_equal '[Object, {}][Module, {}]' }
|
60
|
-
|
61
|
-
# ViewModel.cell(collection: []).(:detail) invokes #detail instead of #show.
|
62
|
-
it { Cell::ViewModel.cell("public_test/song", collection: [Object, Module]).(:detail).must_equal '* [Object, {}]* [Module, {}]' }
|
63
|
-
|
64
|
-
# #cell(collection: [], genre: "Fusion").() doesn't change options hash.
|
65
|
-
it do
|
66
|
-
Cell::ViewModel.cell("public_test/song", options = { genre: "Fusion", collection: [Object] }).()
|
67
|
-
options.to_s.must_equal "{:genre=>\"Fusion\", :collection=>[Object]}"
|
68
|
-
end
|
69
|
-
|
70
|
-
# it do
|
71
|
-
# content = ""
|
72
|
-
# Cell::ViewModel.cell("public_test/song", collection: [Object, Module]).each_with_index do |cell, i|
|
73
|
-
# content += (i == 1 ? cell.(:detail) : cell.())
|
74
|
-
# end
|
75
|
-
|
76
|
-
# content.must_equal '[Object, {}]* [Module, {}]'
|
77
|
-
# end
|
78
|
-
|
79
|
-
# cell(collection: []).join captures return value and joins it for you.
|
80
|
-
it do
|
81
|
-
Cell::ViewModel.cell("public_test/song", collection: [Object, Module]).join do |cell, i|
|
82
|
-
i == 1 ? cell.(:detail) : cell.()
|
83
|
-
end.must_equal '[Object, {}]* [Module, {}]'
|
84
|
-
end
|
85
|
-
|
86
|
-
# cell(collection: []).join("<") captures return value and joins it for you with join.
|
87
|
-
it do
|
88
|
-
Cell::ViewModel.cell("public_test/song", collection: [Object, Module]).join(">") do |cell, i|
|
89
|
-
i == 1 ? cell.(:detail) : cell.()
|
90
|
-
end.must_equal '[Object, {}]>* [Module, {}]'
|
91
|
-
end
|
92
|
-
|
93
|
-
# 'join' can be used without a block:
|
94
|
-
it do
|
95
|
-
Cell::ViewModel.cell(
|
96
|
-
"public_test/song", collection: [Object, Module]
|
97
|
-
).join('---').must_equal('[Object, {}]---[Module, {}]')
|
98
|
-
end
|
99
|
-
end
|
data/test/render_test.rb
DELETED
@@ -1,115 +0,0 @@
|
|
1
|
-
require 'test_helper'
|
2
|
-
|
3
|
-
class SongCell < Cell::ViewModel
|
4
|
-
self.view_paths = ['test/fixtures']
|
5
|
-
# include ::Cell::Erb
|
6
|
-
|
7
|
-
def show
|
8
|
-
render
|
9
|
-
end
|
10
|
-
|
11
|
-
def ivar
|
12
|
-
@title = "Carnage"
|
13
|
-
render
|
14
|
-
end
|
15
|
-
|
16
|
-
def unknown
|
17
|
-
render
|
18
|
-
end
|
19
|
-
|
20
|
-
def string
|
21
|
-
"Right"
|
22
|
-
end
|
23
|
-
|
24
|
-
# TODO: just pass hash.
|
25
|
-
def with_locals
|
26
|
-
render locals: {length: 280, title: "Shot Across The Bow"}
|
27
|
-
end
|
28
|
-
|
29
|
-
def with_erb
|
30
|
-
render template_engine: :erb
|
31
|
-
end
|
32
|
-
|
33
|
-
def with_view_name
|
34
|
-
@title = "Man Of Steel"
|
35
|
-
render :ivar
|
36
|
-
end
|
37
|
-
|
38
|
-
def receiving_options(layout=:default)
|
39
|
-
"#{layout}"
|
40
|
-
end
|
41
|
-
|
42
|
-
def with_html
|
43
|
-
render
|
44
|
-
end
|
45
|
-
|
46
|
-
def send
|
47
|
-
"send"
|
48
|
-
end
|
49
|
-
|
50
|
-
def with_block
|
51
|
-
render { "Clean Sheets" + render(:with_html) }
|
52
|
-
end
|
53
|
-
|
54
|
-
private
|
55
|
-
def title
|
56
|
-
"Papertiger"
|
57
|
-
end
|
58
|
-
end
|
59
|
-
|
60
|
-
class RenderTest < MiniTest::Spec
|
61
|
-
# render show.haml calling method, implicit render.
|
62
|
-
it { SongCell.new(nil).show.must_equal "Papertiger" }
|
63
|
-
|
64
|
-
# render ivar.haml using instance variable.
|
65
|
-
it { SongCell.new(nil).ivar.must_equal "Carnage" }
|
66
|
-
|
67
|
-
# render string.
|
68
|
-
it { SongCell.new(nil).string.must_equal "Right" }
|
69
|
-
|
70
|
-
# #call renders :show
|
71
|
-
it { SongCell.new(nil).call.must_equal "Papertiger" }
|
72
|
-
|
73
|
-
# call(:form) renders :form
|
74
|
-
it { SongCell.new(nil).call(:with_view_name).must_equal "Man Of Steel" }
|
75
|
-
|
76
|
-
# works with state called `send`
|
77
|
-
it { SongCell.new(nil).call(:send).must_equal "send" }
|
78
|
-
|
79
|
-
# throws an exception when not found.
|
80
|
-
it do
|
81
|
-
exception = assert_raises(Cell::TemplateMissingError) { SongCell.new(nil).unknown }
|
82
|
-
exception.message.must_equal "Template missing: view: `unknown.erb` prefixes: [\"test/fixtures/song\"]"
|
83
|
-
end
|
84
|
-
|
85
|
-
# allows locals
|
86
|
-
it { SongCell.new(nil).with_locals.must_equal "Shot Across The Bow280" }
|
87
|
-
|
88
|
-
# render :form is a shortcut.
|
89
|
-
it { SongCell.new(nil).with_view_name.must_equal "Man Of Steel" }
|
90
|
-
|
91
|
-
# :template_engine renders ERB.
|
92
|
-
# it { SongCell.new(nil).with_erb.must_equal "ERB:\n<span>\n Papertiger\n</span>" }
|
93
|
-
|
94
|
-
# view: "show.html"
|
95
|
-
|
96
|
-
# allows passing in options DISCUSS: how to handle that in cache block/builder?
|
97
|
-
it { SongCell.new(nil).receiving_options.must_equal "default" }
|
98
|
-
it { SongCell.new(nil).receiving_options(:fancy).must_equal "fancy" }
|
99
|
-
it { SongCell.new(nil).call(:receiving_options, :fancy).must_equal "fancy" }
|
100
|
-
|
101
|
-
# doesn't escape HTML.
|
102
|
-
it { SongCell.new(nil).call(:with_html).must_equal "<p>Yew!</p>" }
|
103
|
-
|
104
|
-
# render {} with block
|
105
|
-
it { SongCell.new(nil).with_block.must_equal "Yo! Clean Sheets<p>Yew!</p>" }
|
106
|
-
end
|
107
|
-
|
108
|
-
# test inheritance
|
109
|
-
|
110
|
-
# test view: :bla and :bla
|
111
|
-
# with layout and locals.
|
112
|
-
# with layout and :text
|
113
|
-
|
114
|
-
# render with format (e.g. when using ERB for one view)
|
115
|
-
# should we allow changing the format "per run", so a cell can do .js and .haml? or should that be configurable on class level?
|
data/test/templates_test.rb
DELETED
@@ -1,44 +0,0 @@
|
|
1
|
-
require 'test_helper'
|
2
|
-
|
3
|
-
|
4
|
-
class TemplatesTest < MiniTest::Spec
|
5
|
-
Templates = Cell::Templates
|
6
|
-
|
7
|
-
# existing.
|
8
|
-
it { Templates.new[['test/fixtures/bassist'], 'play.erb', {template_class: Cell::Erb::Template}].file.must_equal 'test/fixtures/bassist/play.erb' }
|
9
|
-
|
10
|
-
# not existing.
|
11
|
-
it { assert_nil(Templates.new[['test/fixtures/bassist'], 'not-here.erb', {}]) }
|
12
|
-
|
13
|
-
|
14
|
-
# different caches for different classes
|
15
|
-
|
16
|
-
# same cache for subclasses
|
17
|
-
|
18
|
-
end
|
19
|
-
|
20
|
-
|
21
|
-
class TemplatesCachingTest < MiniTest::Spec
|
22
|
-
class SongCell < Cell::ViewModel
|
23
|
-
self.view_paths = ['test/fixtures']
|
24
|
-
# include Cell::Erb
|
25
|
-
|
26
|
-
def show
|
27
|
-
render
|
28
|
-
end
|
29
|
-
end
|
30
|
-
|
31
|
-
# templates are cached once and forever.
|
32
|
-
it do
|
33
|
-
cell = cell("templates_caching_test/song")
|
34
|
-
|
35
|
-
cell.call(:show).must_equal 'The Great Mind Eraser'
|
36
|
-
|
37
|
-
SongCell.templates.instance_eval do
|
38
|
-
def create; raise; end
|
39
|
-
end
|
40
|
-
|
41
|
-
# cached, NO new tilt template.
|
42
|
-
cell.call(:show).must_equal 'The Great Mind Eraser'
|
43
|
-
end
|
44
|
-
end
|
data/test/test_helper.rb
DELETED
@@ -1,13 +0,0 @@
|
|
1
|
-
require "minitest/autorun"
|
2
|
-
require "cells"
|
3
|
-
require "cells-erb"
|
4
|
-
|
5
|
-
Cell::ViewModel.send(:include, Cell::Erb) if Cell.const_defined?(:Erb) # FIXME: should happen in inititalizer.
|
6
|
-
|
7
|
-
MiniTest::Spec.class_eval do
|
8
|
-
include Cell::Testing
|
9
|
-
end
|
10
|
-
|
11
|
-
class BassistCell < Cell::ViewModel
|
12
|
-
self.view_paths = ['test/fixtures']
|
13
|
-
end
|
data/test/testing_test.rb
DELETED
@@ -1,59 +0,0 @@
|
|
1
|
-
require 'test_helper'
|
2
|
-
|
3
|
-
class TestCaseTest < MiniTest::Spec
|
4
|
-
class SongCell < Cell::ViewModel
|
5
|
-
def show
|
6
|
-
"Give It All!"
|
7
|
-
end
|
8
|
-
end
|
9
|
-
|
10
|
-
class Song
|
11
|
-
class Cell < Cell::Concept
|
12
|
-
end
|
13
|
-
end
|
14
|
-
|
15
|
-
let (:song) { Object.new }
|
16
|
-
|
17
|
-
# #cell returns the instance
|
18
|
-
describe "#cell" do
|
19
|
-
subject { cell("test_case_test/song", song) }
|
20
|
-
|
21
|
-
it { subject.must_be_instance_of SongCell }
|
22
|
-
it { subject.model.must_equal song }
|
23
|
-
|
24
|
-
it { cell("test_case_test/song", collection: [song, song]).().must_equal "Give It All!Give It All!" }
|
25
|
-
end
|
26
|
-
|
27
|
-
|
28
|
-
describe "#concept" do
|
29
|
-
subject { concept("test_case_test/song/cell", song) }
|
30
|
-
|
31
|
-
it { subject.must_be_instance_of Song::Cell }
|
32
|
-
it { subject.model.must_equal song }
|
33
|
-
end
|
34
|
-
end
|
35
|
-
|
36
|
-
# capybara support
|
37
|
-
require "capybara"
|
38
|
-
|
39
|
-
class CapybaraTest < MiniTest::Spec
|
40
|
-
class CapybaraCell < Cell::ViewModel
|
41
|
-
def show
|
42
|
-
"<b>Grunt</b>"
|
43
|
-
end
|
44
|
-
end
|
45
|
-
|
46
|
-
describe "capybara support" do
|
47
|
-
subject { cell("capybara_test/capybara", nil) }
|
48
|
-
|
49
|
-
before { Cell::Testing.capybara = true } # yes, a global switch!
|
50
|
-
after { Cell::Testing.capybara = false }
|
51
|
-
|
52
|
-
it { subject.(:show).has_selector?('b').must_equal true }
|
53
|
-
|
54
|
-
it { cell("capybara_test/capybara", collection: [1, 2]).().has_selector?('b').must_equal true }
|
55
|
-
|
56
|
-
# FIXME: this kinda sucks, what if you want the string in a Capybara environment?
|
57
|
-
it { subject.(:show).to_s.must_match "<b>Grunt</b>" }
|
58
|
-
end
|
59
|
-
end
|
data/test/twin_test.rb
DELETED
@@ -1,26 +0,0 @@
|
|
1
|
-
# require 'test_helper'
|
2
|
-
# require 'cell/twin'
|
3
|
-
|
4
|
-
# class TwinTest < MiniTest::Spec
|
5
|
-
# class SongCell < Cell::ViewModel
|
6
|
-
# class Twin < Disposable::Twin
|
7
|
-
# property :title
|
8
|
-
# option :online?
|
9
|
-
# end
|
10
|
-
|
11
|
-
# include Cell::Twin
|
12
|
-
# twin Twin
|
13
|
-
|
14
|
-
# def show
|
15
|
-
# "#{title} is #{online?}"
|
16
|
-
# end
|
17
|
-
|
18
|
-
# def title
|
19
|
-
# super.downcase
|
20
|
-
# end
|
21
|
-
# end
|
22
|
-
|
23
|
-
# let (:model) { OpenStruct.new(title: "Kenny") }
|
24
|
-
|
25
|
-
# it { SongCell.new( model, :online? => true).call.must_equal "kenny is true" }
|
26
|
-
# end
|