express_templates 0.5.0 → 0.7.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (95) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +22 -41
  3. data/lib/arbre/patches.rb +50 -0
  4. data/lib/core_extensions/proc.rb +1 -0
  5. data/lib/express_templates/compiler.rb +2 -7
  6. data/lib/express_templates/components/base.rb +33 -37
  7. data/lib/express_templates/components/capabilities/resourceful.rb +30 -18
  8. data/lib/express_templates/components/configurable.rb +41 -0
  9. data/lib/express_templates/components/form_rails_support.rb +5 -6
  10. data/lib/express_templates/components/forms/basic_fields.rb +3 -6
  11. data/lib/express_templates/components/forms/checkbox.rb +1 -1
  12. data/lib/express_templates/components/forms/express_form.rb +15 -25
  13. data/lib/express_templates/components/forms/form_component.rb +20 -11
  14. data/lib/express_templates/components/forms/option_support.rb +2 -2
  15. data/lib/express_templates/components/forms/radio.rb +7 -8
  16. data/lib/express_templates/components/forms/select.rb +61 -37
  17. data/lib/express_templates/components/forms/select_collection.rb +2 -8
  18. data/lib/express_templates/components/forms/submit.rb +7 -6
  19. data/lib/express_templates/components/forms.rb +0 -1
  20. data/lib/express_templates/components/tree_for.rb +26 -42
  21. data/lib/express_templates/components.rb +1 -9
  22. data/lib/express_templates/version.rb +1 -1
  23. data/lib/express_templates.rb +2 -3
  24. data/test/components/base_test.rb +17 -15
  25. data/test/components/capabilities/resourceful_test.rb +3 -3
  26. data/test/components/configurable_test.rb +27 -21
  27. data/test/components/forms/basic_fields_test.rb +57 -17
  28. data/test/components/forms/checkbox_test.rb +16 -22
  29. data/test/components/forms/express_form_test.rb +23 -76
  30. data/test/components/forms/radio_test.rb +31 -27
  31. data/test/components/forms/select_test.rb +46 -71
  32. data/test/components/forms/submit_test.rb +10 -5
  33. data/test/components/tree_for_test.rb +24 -52
  34. data/test/dummy/app/views/hello/show.html.et +4 -3
  35. data/test/dummy/app/views/layouts/application.html.et +1 -1
  36. data/test/dummy/log/test.log +4794 -0
  37. data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/-cDLO4NJHMndDHchOLz8KLD7QBc68WtaAbYxK2r6GsU.cache +0 -0
  38. data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/0t68EIwZ96sAqQSxFka9MQyIk4viw8ZIoREMCGiJRx0.cache +0 -0
  39. data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/2zt1IbQCnmzGyeZS_I4sYQzrgneSCKIJBRxcffVHlWY.cache +1 -0
  40. data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/EDVlXrcn_wEfaZ5nc_4QJBT7lPiIBcX96jBo7PBz-vc.cache +1 -0
  41. data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/Eso3tkb79hXQ1XdQgjbV03KyQwSeZFAHxVHImsjQ-HQ.cache +2 -0
  42. data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/I8LhheC1OlOyvp_qY8kWpqKcZFiqv_BO-l5bExvDEi0.cache +1 -0
  43. data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/Kf4VrP5sW-qzziYSN-m7p4nETjLiEwwwRfwUOm7rOr0.cache +0 -0
  44. data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/QJ0Z8hROMfWpY6f5Chb7GSuDHE4gpabKVQTr9BCZe9s.cache +1 -0
  45. data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/T1pSAx767vY7X1UDN0vdF7YGEkI5wMSVUKopsdvp7kI.cache +1 -0
  46. data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/VlSPFPDK05c7ImadRiRVKzsaa6e15RwX77QR3NYabME.cache +0 -0
  47. data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/Y7_BbgB9jgJIWYjDCsASySd26DTfPADAu_3DDnLlFog.cache +0 -0
  48. data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/g2xQygPqA5kMmp5L3wVGWaUIhdVsxFmOel9FF6M0Fuw.cache +0 -0
  49. data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/kaif59owjUr3HBharCH5GUxU6KoW_zXD9a9JiTjIYPY.cache +1 -0
  50. data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/p1cwnBd8RQBm9x5HzDmiiU7RhvnxhPX8VTfi0tTElJY.cache +3 -0
  51. data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/qT6_0ti_v6fAjS3wETXqvTkr6W0LP4PB942uLYQzWK8.cache +3 -0
  52. data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/y8T65xpx0s3RgT_YiqWEEXIaBsgK4woCNSuZ1zjQZBk.cache +2 -0
  53. data/test/express_templates_test.rb +5 -1
  54. data/test/handler_test.rb +19 -17
  55. data/test/performance_test.rb +11 -7
  56. data/test/test_helper.rb +162 -1
  57. metadata +50 -53
  58. data/lib/express_templates/components/capabilities/adoptable.rb +0 -20
  59. data/lib/express_templates/components/capabilities/building.rb +0 -14
  60. data/lib/express_templates/components/capabilities/conditionality.rb +0 -54
  61. data/lib/express_templates/components/capabilities/configurable.rb +0 -90
  62. data/lib/express_templates/components/capabilities/iterating.rb +0 -75
  63. data/lib/express_templates/components/capabilities/parenting.rb +0 -72
  64. data/lib/express_templates/components/capabilities/rendering.rb +0 -30
  65. data/lib/express_templates/components/capabilities/templating.rb +0 -198
  66. data/lib/express_templates/components/capabilities/wrapping.rb +0 -84
  67. data/lib/express_templates/components/column.rb +0 -13
  68. data/lib/express_templates/components/container.rb +0 -7
  69. data/lib/express_templates/components/content_for.rb +0 -42
  70. data/lib/express_templates/components/for_each.rb +0 -30
  71. data/lib/express_templates/components/forms/form_support.rb +0 -13
  72. data/lib/express_templates/components/null_wrap.rb +0 -41
  73. data/lib/express_templates/components/row.rb +0 -28
  74. data/lib/express_templates/components/table_for.rb +0 -163
  75. data/lib/express_templates/components/unless_block.rb +0 -40
  76. data/lib/express_templates/expander.rb +0 -140
  77. data/lib/express_templates/macro.rb +0 -45
  78. data/lib/express_templates/markup/html_tag.rb +0 -62
  79. data/lib/express_templates/markup/tag.rb +0 -150
  80. data/lib/express_templates/markup/wrapper.rb +0 -94
  81. data/lib/express_templates/markup/yielder.rb +0 -21
  82. data/lib/express_templates/markup.rb +0 -9
  83. data/test/components/column_test.rb +0 -11
  84. data/test/components/conditionality_test.rb +0 -37
  85. data/test/components/container_test.rb +0 -66
  86. data/test/components/content_for_test.rb +0 -60
  87. data/test/components/iterating_test.rb +0 -127
  88. data/test/components/null_wrap_test.rb +0 -28
  89. data/test/components/row_test.rb +0 -16
  90. data/test/components/table_for_test.rb +0 -211
  91. data/test/expander_stack_test.rb +0 -41
  92. data/test/expander_test.rb +0 -99
  93. data/test/markup/tag_test.rb +0 -149
  94. data/test/markup/wrapper_test.rb +0 -42
  95. 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,9 +0,0 @@
1
- module ExpressTemplates
2
- module Markup
3
- end
4
- end
5
-
6
- require 'express_templates/markup/tag'
7
- require 'express_templates/markup/html_tag'
8
- require 'express_templates/markup/wrapper'
9
- require 'express_templates/markup/yielder'
@@ -1,11 +0,0 @@
1
- require 'test_helper'
2
-
3
- class ColumnTest < ActiveSupport::TestCase
4
-
5
- ETC = ExpressTemplates::Components
6
-
7
- test "a column is configurable" do
8
- assert ETC::Column.ancestors.include?(ETC::Capabilities::Configurable)
9
- end
10
-
11
- 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
@@ -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