express_templates 0.5.0 → 0.7.0
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 +4 -4
- data/README.md +22 -41
- data/lib/arbre/patches.rb +50 -0
- data/lib/core_extensions/proc.rb +1 -0
- data/lib/express_templates/compiler.rb +2 -7
- data/lib/express_templates/components/base.rb +33 -37
- data/lib/express_templates/components/capabilities/resourceful.rb +30 -18
- data/lib/express_templates/components/configurable.rb +41 -0
- data/lib/express_templates/components/form_rails_support.rb +5 -6
- data/lib/express_templates/components/forms/basic_fields.rb +3 -6
- data/lib/express_templates/components/forms/checkbox.rb +1 -1
- data/lib/express_templates/components/forms/express_form.rb +15 -25
- data/lib/express_templates/components/forms/form_component.rb +20 -11
- data/lib/express_templates/components/forms/option_support.rb +2 -2
- data/lib/express_templates/components/forms/radio.rb +7 -8
- data/lib/express_templates/components/forms/select.rb +61 -37
- data/lib/express_templates/components/forms/select_collection.rb +2 -8
- data/lib/express_templates/components/forms/submit.rb +7 -6
- data/lib/express_templates/components/forms.rb +0 -1
- data/lib/express_templates/components/tree_for.rb +26 -42
- data/lib/express_templates/components.rb +1 -9
- data/lib/express_templates/version.rb +1 -1
- data/lib/express_templates.rb +2 -3
- data/test/components/base_test.rb +17 -15
- data/test/components/capabilities/resourceful_test.rb +3 -3
- data/test/components/configurable_test.rb +27 -21
- data/test/components/forms/basic_fields_test.rb +57 -17
- data/test/components/forms/checkbox_test.rb +16 -22
- data/test/components/forms/express_form_test.rb +23 -76
- data/test/components/forms/radio_test.rb +31 -27
- data/test/components/forms/select_test.rb +46 -71
- data/test/components/forms/submit_test.rb +10 -5
- data/test/components/tree_for_test.rb +24 -52
- data/test/dummy/app/views/hello/show.html.et +4 -3
- data/test/dummy/app/views/layouts/application.html.et +1 -1
- data/test/dummy/log/test.log +4794 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/-cDLO4NJHMndDHchOLz8KLD7QBc68WtaAbYxK2r6GsU.cache +0 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/0t68EIwZ96sAqQSxFka9MQyIk4viw8ZIoREMCGiJRx0.cache +0 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/2zt1IbQCnmzGyeZS_I4sYQzrgneSCKIJBRxcffVHlWY.cache +1 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/EDVlXrcn_wEfaZ5nc_4QJBT7lPiIBcX96jBo7PBz-vc.cache +1 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/Eso3tkb79hXQ1XdQgjbV03KyQwSeZFAHxVHImsjQ-HQ.cache +2 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/I8LhheC1OlOyvp_qY8kWpqKcZFiqv_BO-l5bExvDEi0.cache +1 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/Kf4VrP5sW-qzziYSN-m7p4nETjLiEwwwRfwUOm7rOr0.cache +0 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/QJ0Z8hROMfWpY6f5Chb7GSuDHE4gpabKVQTr9BCZe9s.cache +1 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/T1pSAx767vY7X1UDN0vdF7YGEkI5wMSVUKopsdvp7kI.cache +1 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/VlSPFPDK05c7ImadRiRVKzsaa6e15RwX77QR3NYabME.cache +0 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/Y7_BbgB9jgJIWYjDCsASySd26DTfPADAu_3DDnLlFog.cache +0 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/g2xQygPqA5kMmp5L3wVGWaUIhdVsxFmOel9FF6M0Fuw.cache +0 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/kaif59owjUr3HBharCH5GUxU6KoW_zXD9a9JiTjIYPY.cache +1 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/p1cwnBd8RQBm9x5HzDmiiU7RhvnxhPX8VTfi0tTElJY.cache +3 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/qT6_0ti_v6fAjS3wETXqvTkr6W0LP4PB942uLYQzWK8.cache +3 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/y8T65xpx0s3RgT_YiqWEEXIaBsgK4woCNSuZ1zjQZBk.cache +2 -0
- data/test/express_templates_test.rb +5 -1
- data/test/handler_test.rb +19 -17
- data/test/performance_test.rb +11 -7
- data/test/test_helper.rb +162 -1
- metadata +50 -53
- data/lib/express_templates/components/capabilities/adoptable.rb +0 -20
- data/lib/express_templates/components/capabilities/building.rb +0 -14
- data/lib/express_templates/components/capabilities/conditionality.rb +0 -54
- data/lib/express_templates/components/capabilities/configurable.rb +0 -90
- data/lib/express_templates/components/capabilities/iterating.rb +0 -75
- data/lib/express_templates/components/capabilities/parenting.rb +0 -72
- data/lib/express_templates/components/capabilities/rendering.rb +0 -30
- data/lib/express_templates/components/capabilities/templating.rb +0 -198
- data/lib/express_templates/components/capabilities/wrapping.rb +0 -84
- data/lib/express_templates/components/column.rb +0 -13
- data/lib/express_templates/components/container.rb +0 -7
- data/lib/express_templates/components/content_for.rb +0 -42
- data/lib/express_templates/components/for_each.rb +0 -30
- data/lib/express_templates/components/forms/form_support.rb +0 -13
- data/lib/express_templates/components/null_wrap.rb +0 -41
- data/lib/express_templates/components/row.rb +0 -28
- data/lib/express_templates/components/table_for.rb +0 -163
- data/lib/express_templates/components/unless_block.rb +0 -40
- data/lib/express_templates/expander.rb +0 -140
- data/lib/express_templates/macro.rb +0 -45
- data/lib/express_templates/markup/html_tag.rb +0 -62
- data/lib/express_templates/markup/tag.rb +0 -150
- data/lib/express_templates/markup/wrapper.rb +0 -94
- data/lib/express_templates/markup/yielder.rb +0 -21
- data/lib/express_templates/markup.rb +0 -9
- data/test/components/column_test.rb +0 -11
- data/test/components/conditionality_test.rb +0 -37
- data/test/components/container_test.rb +0 -66
- data/test/components/content_for_test.rb +0 -60
- data/test/components/iterating_test.rb +0 -127
- data/test/components/null_wrap_test.rb +0 -28
- data/test/components/row_test.rb +0 -16
- data/test/components/table_for_test.rb +0 -211
- data/test/expander_stack_test.rb +0 -41
- data/test/expander_test.rb +0 -99
- data/test/markup/tag_test.rb +0 -149
- data/test/markup/wrapper_test.rb +0 -42
- data/test/markup/yielder_test.rb +0 -9
|
@@ -1,94 +0,0 @@
|
|
|
1
|
-
module ExpressTemplates
|
|
2
|
-
module Markup
|
|
3
|
-
# wrap locals and helpers for evaluation during render
|
|
4
|
-
class Wrapper
|
|
5
|
-
|
|
6
|
-
attr_accessor :name, :args
|
|
7
|
-
|
|
8
|
-
def initialize(name, *args, &block)
|
|
9
|
-
@name = name
|
|
10
|
-
@args = args
|
|
11
|
-
@block_src = block ? block.source : nil
|
|
12
|
-
end
|
|
13
|
-
|
|
14
|
-
def compile
|
|
15
|
-
# insure nils do not blow up view
|
|
16
|
-
%Q(%Q({{#{_compile}}}))
|
|
17
|
-
end
|
|
18
|
-
|
|
19
|
-
def to_template
|
|
20
|
-
_compile
|
|
21
|
-
end
|
|
22
|
-
|
|
23
|
-
def children
|
|
24
|
-
[]
|
|
25
|
-
end
|
|
26
|
-
|
|
27
|
-
private
|
|
28
|
-
def _compile
|
|
29
|
-
string = "#{name}"
|
|
30
|
-
|
|
31
|
-
if !@args.empty?
|
|
32
|
-
|
|
33
|
-
args_string = args.slice(0..-2).map do |arg|
|
|
34
|
-
if arg.respond_to?(:gsub) && arg.match(/^\{\{(.*)\}\}$/)
|
|
35
|
-
# strip double braces because otherwise these will be converted
|
|
36
|
-
# to "#{arg}" during final interpolation which is generally not
|
|
37
|
-
# the intention for arguments to helpers as these are ruby expressions
|
|
38
|
-
# not necessarily returning strings
|
|
39
|
-
$1
|
|
40
|
-
else
|
|
41
|
-
arg.inspect # 'value' or :value or ['a', 'b', 'c'] or {:key => 'value'}
|
|
42
|
-
end
|
|
43
|
-
end.join(', ')
|
|
44
|
-
|
|
45
|
-
last_arg = ''
|
|
46
|
-
if args.last.is_a?(Hash) # expand a hash
|
|
47
|
-
last_arg = _convert_hash_to_argument_string(args.last)
|
|
48
|
-
else
|
|
49
|
-
last_arg = args.last.inspect
|
|
50
|
-
end
|
|
51
|
-
args_string << (args_string.empty? ? last_arg : ", #{last_arg}")
|
|
52
|
-
string << "(#{args_string})"
|
|
53
|
-
end
|
|
54
|
-
|
|
55
|
-
if @block_src
|
|
56
|
-
string << " #{@block_src}"
|
|
57
|
-
end
|
|
58
|
-
|
|
59
|
-
return string
|
|
60
|
-
end
|
|
61
|
-
|
|
62
|
-
def _convert_hash_to_argument_string(hash)
|
|
63
|
-
use_hashrockets = hash.keys.any? {|key| key.to_s.match /-/}
|
|
64
|
-
unless hash.empty?
|
|
65
|
-
return hash.map do |key, value|
|
|
66
|
-
s = if use_hashrockets
|
|
67
|
-
if key.to_s.match /-/
|
|
68
|
-
"'#{key}' => "
|
|
69
|
-
else
|
|
70
|
-
":#{key} => "
|
|
71
|
-
end
|
|
72
|
-
else
|
|
73
|
-
"#{key}: "
|
|
74
|
-
end
|
|
75
|
-
|
|
76
|
-
case
|
|
77
|
-
when value.is_a?(String)
|
|
78
|
-
s << '"'+value+'"'
|
|
79
|
-
when value.is_a?(Hash)
|
|
80
|
-
s << value.inspect
|
|
81
|
-
when value.is_a?(Proc)
|
|
82
|
-
s << "(#{value.source}).call"
|
|
83
|
-
else
|
|
84
|
-
s << value.inspect # immediate values 1, 2.0, true etc
|
|
85
|
-
end
|
|
86
|
-
s
|
|
87
|
-
end.join(", ")
|
|
88
|
-
else
|
|
89
|
-
"{}" # empty hash
|
|
90
|
-
end
|
|
91
|
-
end
|
|
92
|
-
end
|
|
93
|
-
end
|
|
94
|
-
end
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
module ExpressTemplates
|
|
2
|
-
module Markup
|
|
3
|
-
class Yielder
|
|
4
|
-
def initialize(*args)
|
|
5
|
-
@arg = args.first
|
|
6
|
-
end
|
|
7
|
-
|
|
8
|
-
def compile
|
|
9
|
-
if @arg
|
|
10
|
-
"yield(#{@arg.inspect})" # usually a symbol but may be string
|
|
11
|
-
else
|
|
12
|
-
"yield"
|
|
13
|
-
end
|
|
14
|
-
end
|
|
15
|
-
|
|
16
|
-
def to_template
|
|
17
|
-
compile
|
|
18
|
-
end
|
|
19
|
-
end
|
|
20
|
-
end
|
|
21
|
-
end
|
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
require 'test_helper'
|
|
2
|
-
|
|
3
|
-
class ConditionalityTest < ActiveSupport::TestCase
|
|
4
|
-
|
|
5
|
-
def empty_title_context
|
|
6
|
-
ctx = Object.new
|
|
7
|
-
ctx.instance_variable_set(:@title, '')
|
|
8
|
-
ctx
|
|
9
|
-
end
|
|
10
|
-
|
|
11
|
-
def present_title_context
|
|
12
|
-
ctx = Object.new
|
|
13
|
-
ctx.instance_variable_set(:@title, 'Something')
|
|
14
|
-
ctx
|
|
15
|
-
end
|
|
16
|
-
|
|
17
|
-
class ConditionalRenderer < ExpressTemplates::Components::Base
|
|
18
|
-
include ExpressTemplates::Components::Capabilities::Conditionality
|
|
19
|
-
|
|
20
|
-
emits -> {
|
|
21
|
-
h1 "{{@title}}"
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
only_if -> { !@title.empty? }
|
|
25
|
-
end
|
|
26
|
-
|
|
27
|
-
test "when supplied condition is false, renders empty string" do
|
|
28
|
-
compiled_src = ConditionalRenderer.new.compile
|
|
29
|
-
assert_equal '', empty_title_context.instance_eval(compiled_src)
|
|
30
|
-
end
|
|
31
|
-
|
|
32
|
-
test "when supplied condition is true, renders the component" do
|
|
33
|
-
compiled_src = Interpolator.transform(ConditionalRenderer.new.compile)
|
|
34
|
-
assert_equal '<h1>Something</h1>', present_title_context.instance_eval(compiled_src)
|
|
35
|
-
end
|
|
36
|
-
|
|
37
|
-
end
|
|
@@ -1,66 +0,0 @@
|
|
|
1
|
-
require 'test_helper'
|
|
2
|
-
require 'minitest/mock'
|
|
3
|
-
|
|
4
|
-
class ContainerTest < ActiveSupport::TestCase
|
|
5
|
-
|
|
6
|
-
ETC = ExpressTemplates::Components
|
|
7
|
-
|
|
8
|
-
def any_container
|
|
9
|
-
Class.new(ETC::Container)
|
|
10
|
-
end
|
|
11
|
-
|
|
12
|
-
test "a Container is a Component" do
|
|
13
|
-
assert_kind_of ETC::Base, any_container.new
|
|
14
|
-
end
|
|
15
|
-
|
|
16
|
-
test "a container has children but initially has none" do
|
|
17
|
-
assert any_container.new.respond_to?(:children)
|
|
18
|
-
assert_equal [], any_container.new.children
|
|
19
|
-
end
|
|
20
|
-
|
|
21
|
-
def mock_children
|
|
22
|
-
child1, child2 = Minitest::Mock.new, Minitest::Mock.new
|
|
23
|
-
child1.expect(:compile, '"one"')
|
|
24
|
-
child2.expect(:compile, '"two"')
|
|
25
|
-
child1.expect(:kind_of?, false, [ExpressTemplates::Components::Capabilities::Adoptable])
|
|
26
|
-
child2.expect(:kind_of?, false, [ExpressTemplates::Components::Capabilities::Adoptable])
|
|
27
|
-
return child1, child2
|
|
28
|
-
end
|
|
29
|
-
|
|
30
|
-
class TestContainer < ETC::Container
|
|
31
|
-
emits -> { p { _yield } }
|
|
32
|
-
end
|
|
33
|
-
|
|
34
|
-
test "Container#compile calls #compile on its children" do
|
|
35
|
-
container = TestContainer.new
|
|
36
|
-
child1, child2 = mock_children
|
|
37
|
-
container.children = [child1, child2]
|
|
38
|
-
container.compile
|
|
39
|
-
child1.verify
|
|
40
|
-
child2.verify
|
|
41
|
-
end
|
|
42
|
-
|
|
43
|
-
test "renders children in place of _yield" do
|
|
44
|
-
container = TestContainer.new
|
|
45
|
-
child1, child2 = mock_children
|
|
46
|
-
container.children = [child1, child2]
|
|
47
|
-
|
|
48
|
-
assert_equal "<p>onetwo</p>", eval(container.compile)
|
|
49
|
-
end
|
|
50
|
-
|
|
51
|
-
class Context
|
|
52
|
-
def a_helper
|
|
53
|
-
"foo"
|
|
54
|
-
end
|
|
55
|
-
end
|
|
56
|
-
|
|
57
|
-
test "children with interpolations" do
|
|
58
|
-
markup = ExpressTemplates.render(Context.new) do
|
|
59
|
-
row {
|
|
60
|
-
p %q(Should say: {{a_helper}}.)
|
|
61
|
-
}
|
|
62
|
-
end
|
|
63
|
-
assert_equal "<div class=\"row\"><p>Should say: foo.</p></div>", markup
|
|
64
|
-
end
|
|
65
|
-
|
|
66
|
-
end
|
|
@@ -1,60 +0,0 @@
|
|
|
1
|
-
require 'test_helper'
|
|
2
|
-
|
|
3
|
-
class ContentForTest < ActiveSupport::TestCase
|
|
4
|
-
|
|
5
|
-
class Context
|
|
6
|
-
def content_for(label, markup=nil, &block)
|
|
7
|
-
@blocks ||= {}
|
|
8
|
-
if block || markup
|
|
9
|
-
@blocks[label] = block ? block.call : markup
|
|
10
|
-
nil
|
|
11
|
-
else
|
|
12
|
-
@blocks[label]
|
|
13
|
-
end
|
|
14
|
-
end
|
|
15
|
-
end
|
|
16
|
-
|
|
17
|
-
test "content_for accepts a block of express template" do
|
|
18
|
-
fragment = -> {
|
|
19
|
-
content_for(:whatever) { h1 'hello' }
|
|
20
|
-
}
|
|
21
|
-
context = Context.new
|
|
22
|
-
markup = ExpressTemplates.render(context, &fragment)
|
|
23
|
-
assert_equal %Q(<h1>hello</h1>), context.content_for(:whatever)
|
|
24
|
-
end
|
|
25
|
-
|
|
26
|
-
test "content_for accepts a second argument which contains markup" do
|
|
27
|
-
fragment = -> {
|
|
28
|
-
content_for :title, "Foo"
|
|
29
|
-
}
|
|
30
|
-
context = Context.new
|
|
31
|
-
markup = ExpressTemplates.render(context, &fragment)
|
|
32
|
-
assert_equal 'Foo', context.content_for(:title)
|
|
33
|
-
end
|
|
34
|
-
|
|
35
|
-
test "content_for without a body returns the markup" do
|
|
36
|
-
fragment = -> {
|
|
37
|
-
content_for :title
|
|
38
|
-
}
|
|
39
|
-
context = Context.new
|
|
40
|
-
context.content_for :title, "Foo"
|
|
41
|
-
markup = ExpressTemplates.render(context, &fragment)
|
|
42
|
-
assert_equal 'Foo', markup
|
|
43
|
-
end
|
|
44
|
-
|
|
45
|
-
test "content_for body is html_safe" do
|
|
46
|
-
arg_frag = -> {
|
|
47
|
-
content_for :title, "<h1>Foo</h1>"
|
|
48
|
-
}
|
|
49
|
-
context = Context.new
|
|
50
|
-
markup = ExpressTemplates.render(context, &arg_frag)
|
|
51
|
-
assert context.content_for(:title).html_safe?
|
|
52
|
-
|
|
53
|
-
block_frag = -> {
|
|
54
|
-
content_for(:title) { h1 "Foo" }
|
|
55
|
-
}
|
|
56
|
-
markup = ExpressTemplates.render(context, &block_frag)
|
|
57
|
-
assert context.content_for(:title).html_safe?
|
|
58
|
-
end
|
|
59
|
-
|
|
60
|
-
end
|
|
@@ -1,127 +0,0 @@
|
|
|
1
|
-
require 'test_helper'
|
|
2
|
-
|
|
3
|
-
class IteratingTest < ActiveSupport::TestCase
|
|
4
|
-
|
|
5
|
-
class Context
|
|
6
|
-
def initialize ; @things = ['bar', 'baz'] ; @empty = [] ; end
|
|
7
|
-
end
|
|
8
|
-
|
|
9
|
-
class ForEachLogic < ECB
|
|
10
|
-
emits -> {
|
|
11
|
-
for_each(:@things) {
|
|
12
|
-
span { thing }
|
|
13
|
-
}
|
|
14
|
-
}
|
|
15
|
-
end
|
|
16
|
-
|
|
17
|
-
test "#for_each expands to view logic" do
|
|
18
|
-
compiled = ForEachLogic.new.compile
|
|
19
|
-
assert_equal %q((@things.each_with_index.map do |thing, thing_index|
|
|
20
|
-
"<span>"+%Q(#{thing})+"</span>"
|
|
21
|
-
end).join), Interpolator.transform(compiled)
|
|
22
|
-
end
|
|
23
|
-
|
|
24
|
-
test "#for_each iterates markup for each value" do
|
|
25
|
-
compiled = ForEachLogic.new.compile
|
|
26
|
-
assert_equal '<span>bar</span><span>baz</span>',
|
|
27
|
-
Context.new.instance_eval(Interpolator.transform(compiled))
|
|
28
|
-
end
|
|
29
|
-
|
|
30
|
-
class AnyContainer < ExpressTemplates::Components::Container
|
|
31
|
-
emits -> {
|
|
32
|
-
p {
|
|
33
|
-
_yield
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
end
|
|
37
|
-
|
|
38
|
-
test "a template utilizing a component with for_each inside another component" do
|
|
39
|
-
fragment = -> {
|
|
40
|
-
any_container {
|
|
41
|
-
for_each_logic # <-- this is causing an exception when AnyContainer
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
compiled = ExpressTemplates.compile(&fragment)
|
|
45
|
-
assert_equal '<p><span>bar</span><span>baz</span></p>', Context.new.instance_eval(compiled)
|
|
46
|
-
end
|
|
47
|
-
|
|
48
|
-
class ForEachDeclarativeForm < ECB
|
|
49
|
-
emits -> {
|
|
50
|
-
span { thing }
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
for_each(:@things)
|
|
54
|
-
end
|
|
55
|
-
|
|
56
|
-
test ".for_each offers declarative form" do
|
|
57
|
-
compiled = ForEachLogic.new.compile
|
|
58
|
-
assert_equal '<span>bar</span><span>baz</span>',
|
|
59
|
-
Context.new.instance_eval(Interpolator.transform(compiled))
|
|
60
|
-
end
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
class MultiFragments < ECB
|
|
64
|
-
|
|
65
|
-
fragments item: -> {
|
|
66
|
-
li { thing }
|
|
67
|
-
},
|
|
68
|
-
|
|
69
|
-
wrapper: -> {
|
|
70
|
-
ul {
|
|
71
|
-
_yield
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
for_each -> { @things }, as: 'thing', emit: :item
|
|
76
|
-
|
|
77
|
-
wrap_with :wrapper
|
|
78
|
-
|
|
79
|
-
end
|
|
80
|
-
|
|
81
|
-
test ".wrap_with wraps via _yield special handler" do
|
|
82
|
-
compiled = MultiFragments.new.compile
|
|
83
|
-
assert_equal "<ul><li>bar</li><li>baz</li></ul>",
|
|
84
|
-
Context.new.instance_eval(Interpolator.transform(compiled))
|
|
85
|
-
end
|
|
86
|
-
|
|
87
|
-
class EmptyState < ECB
|
|
88
|
-
|
|
89
|
-
fragments item: -> {
|
|
90
|
-
li { thing }
|
|
91
|
-
},
|
|
92
|
-
|
|
93
|
-
wrapper: -> {
|
|
94
|
-
ul {
|
|
95
|
-
_yield
|
|
96
|
-
}
|
|
97
|
-
},
|
|
98
|
-
empty_state: -> {
|
|
99
|
-
p "Nothing here"
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
for_each -> { @empty }, as: 'thing', emit: :item, empty: :empty_state
|
|
103
|
-
|
|
104
|
-
wrap_with :wrapper, dont_wrap_if: -> { @empty.empty? }
|
|
105
|
-
|
|
106
|
-
end
|
|
107
|
-
|
|
108
|
-
test "empty state renders when collection is empty" do
|
|
109
|
-
compiled = EmptyState.new.compile
|
|
110
|
-
assert_equal '<p>Nothing here</p>', Context.new.instance_eval(compiled)
|
|
111
|
-
end
|
|
112
|
-
|
|
113
|
-
class EmptyEmptyState < ECB
|
|
114
|
-
emits -> {
|
|
115
|
-
whatever
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
for_each -> { @empty }
|
|
119
|
-
end
|
|
120
|
-
|
|
121
|
-
test "if collection is empty and no empty fragment specified, empty string is rendered" do
|
|
122
|
-
compiled = EmptyEmptyState.new.compile
|
|
123
|
-
assert_equal '', Context.new.instance_eval(compiled)
|
|
124
|
-
end
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
end
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
require 'test_helper'
|
|
2
|
-
|
|
3
|
-
class NullWrapTest < ActiveSupport::TestCase
|
|
4
|
-
|
|
5
|
-
ETC = ExpressTemplates::Components
|
|
6
|
-
|
|
7
|
-
test "a NullWrap is a Container" do
|
|
8
|
-
assert ETC::NullWrap.ancestors.include?(ETC::Capabilities::Parenting)
|
|
9
|
-
end
|
|
10
|
-
|
|
11
|
-
test "null_wrap accepts a string contianing a ruby string def" do
|
|
12
|
-
compiled_src = ETC::NullWrap.new("%q(<p>whatever<p>)").compile
|
|
13
|
-
assert_equal '<p>whatever<p>', eval(compiled_src)
|
|
14
|
-
end
|
|
15
|
-
|
|
16
|
-
test "null_wrap wraps template code" do
|
|
17
|
-
fragment = -> {
|
|
18
|
-
null_wrap {
|
|
19
|
-
p {
|
|
20
|
-
"whatever"
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
assert_equal '<p>whatever</p>', eval(ExpressTemplates.compile(&fragment))
|
|
25
|
-
end
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
end
|
data/test/components/row_test.rb
DELETED
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
require 'test_helper'
|
|
2
|
-
|
|
3
|
-
class RowTest < ActiveSupport::TestCase
|
|
4
|
-
|
|
5
|
-
ETC = ExpressTemplates::Components
|
|
6
|
-
|
|
7
|
-
test "a row is configurable" do
|
|
8
|
-
assert ETC::Row.ancestors.include?(ETC::Capabilities::Configurable)
|
|
9
|
-
end
|
|
10
|
-
|
|
11
|
-
test "id is optional" do
|
|
12
|
-
compiled_src = ETC::Row.new(nil).compile
|
|
13
|
-
assert_equal '<div class="row"></div>', eval(compiled_src)
|
|
14
|
-
end
|
|
15
|
-
|
|
16
|
-
end
|
|
@@ -1,211 +0,0 @@
|
|
|
1
|
-
require 'test_helper'
|
|
2
|
-
require 'ostruct'
|
|
3
|
-
|
|
4
|
-
class TableForTest < ActiveSupport::TestCase
|
|
5
|
-
|
|
6
|
-
class Context
|
|
7
|
-
def initialize(test_items)
|
|
8
|
-
@test_items = test_items
|
|
9
|
-
end
|
|
10
|
-
end
|
|
11
|
-
|
|
12
|
-
def test_items
|
|
13
|
-
[OpenStruct.new(id: 1, name: 'Foo', price: 1.23),
|
|
14
|
-
OpenStruct.new(id: 2, name: 'Bar', price: 5.49),
|
|
15
|
-
OpenStruct.new(id: 3, name: 'Baz', price: 99.97)]
|
|
16
|
-
end
|
|
17
|
-
|
|
18
|
-
EXAMPLE_COMPILED = -> {
|
|
19
|
-
ExpressTemplates::Components::TableFor.render_in(self) {
|
|
20
|
-
"
|
|
21
|
-
<table id=\"test_items\">
|
|
22
|
-
<thead>
|
|
23
|
-
<tr>
|
|
24
|
-
<th class=\"name\">Name</th>
|
|
25
|
-
<th class=\"price\">Price</th>
|
|
26
|
-
</tr>
|
|
27
|
-
</thead>
|
|
28
|
-
|
|
29
|
-
<tbody>"+(@test_items.each_with_index.map do |test_item, test_item_index|
|
|
30
|
-
"
|
|
31
|
-
<tr id=\"test_item-#{test_item.id}\" class=\"test_item\">
|
|
32
|
-
<td class=\"name\">#{test_item.name}</td>
|
|
33
|
-
<td class=\"price\">#{(-> (price) { '$%0.2f' % price }).call(test_item.price)}</td>
|
|
34
|
-
</tr>
|
|
35
|
-
"
|
|
36
|
-
end).join+" </tbody>
|
|
37
|
-
</table>
|
|
38
|
-
"
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
EXAMPLE_MARKUP = <<-HTML
|
|
43
|
-
|
|
44
|
-
<table id="test_items">
|
|
45
|
-
<thead>
|
|
46
|
-
<tr>
|
|
47
|
-
<th class="name">Name</th>
|
|
48
|
-
<th class="price">Price</th>
|
|
49
|
-
</tr>
|
|
50
|
-
</thead>
|
|
51
|
-
|
|
52
|
-
<tbody>
|
|
53
|
-
<tr id="test_item-1" class="test_item">
|
|
54
|
-
<td class="name">Foo</td>
|
|
55
|
-
<td class="price">$1.23</td>
|
|
56
|
-
</tr>
|
|
57
|
-
|
|
58
|
-
<tr id="test_item-2" class="test_item">
|
|
59
|
-
<td class="name">Bar</td>
|
|
60
|
-
<td class="price">$5.49</td>
|
|
61
|
-
</tr>
|
|
62
|
-
|
|
63
|
-
<tr id="test_item-3" class="test_item">
|
|
64
|
-
<td class="name">Baz</td>
|
|
65
|
-
<td class="price">$99.97</td>
|
|
66
|
-
</tr>
|
|
67
|
-
</tbody>
|
|
68
|
-
</table>
|
|
69
|
-
HTML
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
EXAMPLE_WITH_ACTIONS_COMPILED = -> {
|
|
73
|
-
ExpressTemplates::Components::TableFor.render_in(self) {
|
|
74
|
-
"
|
|
75
|
-
<table id=\"test_items\">
|
|
76
|
-
<thead>
|
|
77
|
-
<tr>
|
|
78
|
-
<th class=\"name\">Name</th>
|
|
79
|
-
<th class=\"price\">Price</th>
|
|
80
|
-
<th class=\"default_actions\">Actions</th>
|
|
81
|
-
</tr>
|
|
82
|
-
</thead>
|
|
83
|
-
|
|
84
|
-
<tbody>"+(@test_items.each_with_index.map do |test_item, test_item_index|
|
|
85
|
-
"
|
|
86
|
-
<tr id=\"test_item-#{test_item.id}\" class=\"test_item\">
|
|
87
|
-
<td class=\"name\">#{test_item.name}</td>
|
|
88
|
-
<td class=\"price\">#{(-> (price) { '$%0.2f' % price }).call(test_item.price)}</td>
|
|
89
|
-
<td class=\"default_actions\">
|
|
90
|
-
<a href='/test_items/#{test_item.id}'>Show</a>
|
|
91
|
-
<a href='/test_items/#{test_item.id}/edit'>Edit</a>
|
|
92
|
-
<a href='/test_items/#{test_item.id}' data-method='delete' data-confirm='Are you sure?'>Delete</a>
|
|
93
|
-
</td>
|
|
94
|
-
</tr>
|
|
95
|
-
"
|
|
96
|
-
end).join+" </tbody>
|
|
97
|
-
</table>
|
|
98
|
-
"
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
EXAMPLE_WITH_ACTIONS_MARKUP = <<-HTML
|
|
103
|
-
|
|
104
|
-
<table id="test_items">
|
|
105
|
-
<thead>
|
|
106
|
-
<tr>
|
|
107
|
-
<th class="name">Name</th>
|
|
108
|
-
<th class="price">Price</th>
|
|
109
|
-
<th class="default_actions">Actions</th>
|
|
110
|
-
</tr>
|
|
111
|
-
</thead>
|
|
112
|
-
|
|
113
|
-
<tbody>
|
|
114
|
-
<tr id="test_item-1" class="test_item">
|
|
115
|
-
<td class="name">Foo</td>
|
|
116
|
-
<td class="price">$1.23</td>
|
|
117
|
-
<td class="default_actions">
|
|
118
|
-
<a href='/test_items/1'>Show</a>
|
|
119
|
-
<a href='/test_items/1/edit'>Edit</a>
|
|
120
|
-
<a href='/test_items/1' data-method='delete' data-confirm='Are you sure?'>Delete</a>
|
|
121
|
-
</td>
|
|
122
|
-
</tr>
|
|
123
|
-
|
|
124
|
-
<tr id="test_item-2" class="test_item">
|
|
125
|
-
<td class="name">Bar</td>
|
|
126
|
-
<td class="price">$5.49</td>
|
|
127
|
-
<td class="default_actions">
|
|
128
|
-
<a href='/test_items/2'>Show</a>
|
|
129
|
-
<a href='/test_items/2/edit'>Edit</a>
|
|
130
|
-
<a href='/test_items/2' data-method='delete' data-confirm='Are you sure?'>Delete</a>
|
|
131
|
-
</td>
|
|
132
|
-
</tr>
|
|
133
|
-
|
|
134
|
-
<tr id="test_item-3" class="test_item">
|
|
135
|
-
<td class="name">Baz</td>
|
|
136
|
-
<td class="price">$99.97</td>
|
|
137
|
-
<td class="default_actions">
|
|
138
|
-
<a href='/test_items/3'>Show</a>
|
|
139
|
-
<a href='/test_items/3/edit'>Edit</a>
|
|
140
|
-
<a href='/test_items/3' data-method='delete' data-confirm='Are you sure?'>Delete</a>
|
|
141
|
-
</td>
|
|
142
|
-
</tr>
|
|
143
|
-
</tbody>
|
|
144
|
-
</table>
|
|
145
|
-
HTML
|
|
146
|
-
|
|
147
|
-
def simple_table(test_items)
|
|
148
|
-
ctx = Context.new(test_items)
|
|
149
|
-
fragment = -> {
|
|
150
|
-
table_for(:test_items) do |t|
|
|
151
|
-
t.column :name, header: "Name"
|
|
152
|
-
t.column :price, formatter: -> (price) { '$%0.2f' % price }
|
|
153
|
-
end
|
|
154
|
-
}
|
|
155
|
-
return ctx, fragment
|
|
156
|
-
end
|
|
157
|
-
|
|
158
|
-
def table_with_actions(test_items)
|
|
159
|
-
ctx = Context.new(test_items)
|
|
160
|
-
fragment = -> {
|
|
161
|
-
table_for(:test_items) do |t|
|
|
162
|
-
t.column :name
|
|
163
|
-
t.column :price, formatter: -> (price) { '$%0.2f' % price }
|
|
164
|
-
t.column :default_actions, header: "Actions", actions: [:show, :edit, :delete]
|
|
165
|
-
end
|
|
166
|
-
}
|
|
167
|
-
return ctx, fragment
|
|
168
|
-
end
|
|
169
|
-
|
|
170
|
-
def example_compiled_src
|
|
171
|
-
# necessary because the #source method is not perfect yet
|
|
172
|
-
# ideally we would have #source_body
|
|
173
|
-
EXAMPLE_COMPILED.source_body
|
|
174
|
-
end
|
|
175
|
-
|
|
176
|
-
def example_with_actions_compiled_src
|
|
177
|
-
EXAMPLE_WITH_ACTIONS_COMPILED.source_body
|
|
178
|
-
end
|
|
179
|
-
|
|
180
|
-
test "example view code evaluates to example markup" do
|
|
181
|
-
assert_equal EXAMPLE_MARKUP, Context.new(test_items).instance_eval(EXAMPLE_COMPILED.source_body)
|
|
182
|
-
assert_equal EXAMPLE_WITH_ACTIONS_MARKUP, Context.new(test_items).instance_eval(EXAMPLE_WITH_ACTIONS_COMPILED.source_body)
|
|
183
|
-
end
|
|
184
|
-
|
|
185
|
-
test "compiled source is legible and transparent" do
|
|
186
|
-
ExpressTemplates::Markup::Tag.formatted do
|
|
187
|
-
ctx, fragment = simple_table(test_items)
|
|
188
|
-
assert_equal example_compiled_src, ExpressTemplates.compile(&fragment)
|
|
189
|
-
actx, afragment = table_with_actions(test_items)
|
|
190
|
-
assert_equal example_with_actions_compiled_src, ExpressTemplates.compile(&afragment)
|
|
191
|
-
end
|
|
192
|
-
end
|
|
193
|
-
|
|
194
|
-
test "example compiled source renders the markup in the context" do
|
|
195
|
-
ctx, fragment = simple_table(test_items)
|
|
196
|
-
assert_equal EXAMPLE_MARKUP, ctx.instance_eval(example_compiled_src)
|
|
197
|
-
|
|
198
|
-
actx, afragment = table_with_actions(test_items)
|
|
199
|
-
assert_equal EXAMPLE_WITH_ACTIONS_MARKUP, actx.instance_eval(example_with_actions_compiled_src)
|
|
200
|
-
end
|
|
201
|
-
|
|
202
|
-
test "rendered component matches desired markup" do
|
|
203
|
-
ExpressTemplates::Markup::Tag.formatted do
|
|
204
|
-
ctx, fragment = simple_table(test_items)
|
|
205
|
-
assert_equal EXAMPLE_MARKUP, ExpressTemplates.render(ctx, &fragment)
|
|
206
|
-
|
|
207
|
-
actx, afragment = table_with_actions(test_items)
|
|
208
|
-
assert_equal EXAMPLE_WITH_ACTIONS_MARKUP, ExpressTemplates.render(actx, &afragment)
|
|
209
|
-
end
|
|
210
|
-
end
|
|
211
|
-
end
|