express_admin 1.2.1 → 1.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (159) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/javascripts/express_admin.js +2 -0
  3. data/app/assets/javascripts/express_admin/admin.js +2 -0
  4. data/app/assets/stylesheets/express_admin.css +0 -5
  5. data/app/assets/stylesheets/express_admin/components/_definition.sass +8 -0
  6. data/app/assets/stylesheets/express_admin/components/_pane.sass +2 -2
  7. data/app/assets/stylesheets/express_admin/components/_sub_menu.sass +2 -2
  8. data/app/assets/stylesheets/express_admin/components/_widget_box.sass +4 -4
  9. data/app/assets/stylesheets/express_admin/globals/_foundation_overrides.sass +2 -1
  10. data/app/assets/stylesheets/express_admin/globals/_mixins.sass +0 -2
  11. data/app/assets/stylesheets/express_admin/plugins/_select2.sass +475 -68
  12. data/app/assets/stylesheets/express_admin/plugins/_tinymce.sass +2 -0
  13. data/app/assets/stylesheets/express_admin/screen.sass +6 -1
  14. data/app/assets/stylesheets/express_admin/sections/_header.sass +1 -0
  15. data/app/assets/stylesheets/express_admin/sections/_main_content.sass +6 -2
  16. data/app/assets/stylesheets/express_admin/sections/_main_region.sass +10 -7
  17. data/app/assets/stylesheets/express_admin/sections/_page_body.sass +6 -3
  18. data/app/assets/stylesheets/express_admin/sections/_page_sidebar.sass +6 -2
  19. data/app/assets/stylesheets/express_admin/sections/_sidebar_region.sass +4 -3
  20. data/app/assets/stylesheets/express_admin/shared/_buttons.sass +0 -1
  21. data/app/assets/stylesheets/express_admin/shared/_forms.sass +14 -2
  22. data/app/assets/stylesheets/express_admin/shared/_trees.sass +7 -3
  23. data/app/assets/stylesheets/ionicons/{ionicons.css.sass → ionicons.sass} +0 -0
  24. data/app/components/express_admin/addon_sidebar_component.rb +23 -34
  25. data/app/components/express_admin/definition_list.rb +38 -0
  26. data/app/components/express_admin/definition_table.rb +51 -0
  27. data/app/components/express_admin/flash_message_component.rb +5 -11
  28. data/app/components/express_admin/layout_component.rb +2 -9
  29. data/app/components/express_admin/main_region.rb +4 -4
  30. data/app/components/express_admin/mega_menu_component.rb +40 -34
  31. data/app/components/express_admin/page_header_component.rb +8 -18
  32. data/app/components/express_admin/pane.rb +13 -10
  33. data/app/components/express_admin/setting_form.rb +23 -20
  34. data/app/components/express_admin/sidebar_region.rb +6 -4
  35. data/app/components/express_admin/smart_form.rb +21 -18
  36. data/app/components/express_admin/smart_table.rb +44 -40
  37. data/app/components/express_admin/widget_box.rb +8 -8
  38. data/app/helpers/express_admin/admin_helper.rb +1 -1
  39. data/app/views/devise/sessions/new.html.et +63 -0
  40. data/app/views/layouts/express_admin/admin.html.et +8 -9
  41. data/app/views/shared/express_admin/_navigation_bar.html.et +6 -5
  42. data/config/tinymce.yml +29 -0
  43. data/lib/core_extensions/string_promptify.rb +9 -0
  44. data/lib/express_admin.rb +1 -0
  45. data/lib/express_admin/engine.rb +11 -9
  46. data/lib/express_admin/version.rb +1 -1
  47. data/lib/generators/express_admin/install/install_generator.rb +7 -0
  48. data/lib/generators/express_admin/install/templates/views/devise/sessions/new.html.et +1 -0
  49. data/test/dummy/app/views/demo/sign_in.html.et +6 -6
  50. data/test/dummy/db/test.sqlite3 +0 -0
  51. data/test/dummy/log/test.log +11361 -0
  52. data/test/dummy/test/components/smart_form_test.rb +57 -34
  53. data/test/dummy/test/components/smart_table_test.rb +35 -35
  54. data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/1EoyfDwFVtgMAOjo7HPkor8TQbVaioOFx9hildx_DTQ.cache +0 -0
  55. data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/4OPIkynisipUm8vKo57HUhBMWFSHBno_IH6OdpK29IA.cache +1 -0
  56. data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/4hK1AdPGHbXGkebvk-nSvhxtCdOSlMYNWvA43CvQKhI.cache +0 -0
  57. data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/6c0H20s6oHf45XogeDELaojxa0PX1NmirTTWV1ClcRw.cache +0 -0
  58. data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/9QvwPXfTSVmgQX6tdK9GuCn0--MZ8Z8eJJbHpUEq1p8.cache +1 -0
  59. data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/BoKdGhgi5NHfGTc42p9nltpEIYj_BBUxVdv7YhpBmmA.cache +0 -0
  60. data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/GJGMlSyTg1AvPCV_6PaLOTVEKbHeVKY1jhCoaKuRlxM.cache +1 -0
  61. data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/H0aD5KRj-4fhORkqWcWZfKPOQfu_ggvt4OmYOl4S5mw.cache +0 -0
  62. data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/IBLgVNsKBbJxN8NQnh6zTc3bC_OG-8BhtA3xCNDV6ks.cache +1 -0
  63. data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/Po8q4NrWy9Kymnz_HbOk-WbdGY_KuuXc6urGogTHe7U.cache +0 -0
  64. data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/V1aP9G-CVtOLR5PTnHleid8WC9TSfFAT1DzAygp_5CQ.cache +1 -0
  65. data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/WhePtBvZPmF1Jhdcc4glsjhxBJQo9Qw0CDgy_F8lClY.cache +0 -0
  66. data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/dVokuKbK8HbOtvPIksKGBAYE8x44l372dQ0gEISqbdo.cache +0 -0
  67. data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/oN1zSGeSEz4KhkAuUF_yFDsCVPkulfFjomEAjFzGdPc.cache +0 -0
  68. data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/qIeSoker4TjM7JYRQTOjgRd4nN0WeHnNY1GMK7Zpe8M.cache +0 -0
  69. data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/tTFLM1bjKSeg4nyH7GWbTY6JVvuYhNKFFvsOMS9h8O0.cache +0 -0
  70. data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/tzX-HHF4F70o-aSB9Z_duoPxFGDv3auYnrpko9SYafU.cache +1 -0
  71. data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/vMbWbI1SO5bEaiu2pRvV8NDmms_j5flYoRvCSJavhdU.cache +0 -0
  72. data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/ypZCDLo54Pz2ZoUxrxSEUjT5FYMAq8Ozp8OTOYDRdAE.cache +0 -0
  73. data/test/fixtures/categories.yml +8 -0
  74. data/test/test_helper.rb +34 -0
  75. data/vendor/gems/express_templates/CHANGELOG.md +12 -0
  76. data/vendor/gems/express_templates/Gemfile.lock +4 -1
  77. data/vendor/gems/express_templates/README.md +22 -41
  78. data/vendor/gems/express_templates/express_templates.gemspec +1 -0
  79. data/vendor/gems/express_templates/lib/arbre/patches.rb +50 -0
  80. data/vendor/gems/express_templates/lib/core_extensions/proc.rb +1 -0
  81. data/vendor/gems/express_templates/lib/express_templates.rb +2 -3
  82. data/vendor/gems/express_templates/lib/express_templates/compiler.rb +2 -7
  83. data/vendor/gems/express_templates/lib/express_templates/components.rb +1 -9
  84. data/vendor/gems/express_templates/lib/express_templates/components/base.rb +33 -37
  85. data/vendor/gems/express_templates/lib/express_templates/components/capabilities/resourceful.rb +30 -18
  86. data/vendor/gems/express_templates/lib/express_templates/components/configurable.rb +41 -0
  87. data/vendor/gems/express_templates/lib/express_templates/components/form_rails_support.rb +5 -6
  88. data/vendor/gems/express_templates/lib/express_templates/components/forms.rb +0 -1
  89. data/vendor/gems/express_templates/lib/express_templates/components/forms/basic_fields.rb +3 -6
  90. data/vendor/gems/express_templates/lib/express_templates/components/forms/checkbox.rb +1 -1
  91. data/vendor/gems/express_templates/lib/express_templates/components/forms/express_form.rb +15 -25
  92. data/vendor/gems/express_templates/lib/express_templates/components/forms/form_component.rb +20 -11
  93. data/vendor/gems/express_templates/lib/express_templates/components/forms/option_support.rb +2 -2
  94. data/vendor/gems/express_templates/lib/express_templates/components/forms/radio.rb +7 -8
  95. data/vendor/gems/express_templates/lib/express_templates/components/forms/select.rb +61 -37
  96. data/vendor/gems/express_templates/lib/express_templates/components/forms/select_collection.rb +2 -8
  97. data/vendor/gems/express_templates/lib/express_templates/components/forms/submit.rb +7 -6
  98. data/vendor/gems/express_templates/lib/express_templates/components/tree_for.rb +26 -42
  99. data/vendor/gems/express_templates/lib/express_templates/version.rb +1 -1
  100. data/vendor/gems/express_templates/test/components/base_test.rb +17 -15
  101. data/vendor/gems/express_templates/test/components/capabilities/resourceful_test.rb +3 -3
  102. data/vendor/gems/express_templates/test/components/configurable_test.rb +27 -21
  103. data/vendor/gems/express_templates/test/components/forms/basic_fields_test.rb +57 -17
  104. data/vendor/gems/express_templates/test/components/forms/checkbox_test.rb +16 -22
  105. data/vendor/gems/express_templates/test/components/forms/express_form_test.rb +23 -76
  106. data/vendor/gems/express_templates/test/components/forms/radio_test.rb +31 -27
  107. data/vendor/gems/express_templates/test/components/forms/select_test.rb +46 -71
  108. data/vendor/gems/express_templates/test/components/forms/submit_test.rb +10 -5
  109. data/vendor/gems/express_templates/test/components/tree_for_test.rb +24 -52
  110. data/vendor/gems/express_templates/test/dummy/app/views/hello/show.html.et +4 -3
  111. data/vendor/gems/express_templates/test/dummy/app/views/layouts/application.html.et +1 -1
  112. data/vendor/gems/express_templates/test/dummy/log/test.log +4296 -0
  113. data/vendor/gems/express_templates/test/express_templates_test.rb +5 -1
  114. data/vendor/gems/express_templates/test/handler_test.rb +19 -17
  115. data/vendor/gems/express_templates/test/performance_test.rb +11 -7
  116. data/vendor/gems/express_templates/test/test_helper.rb +162 -1
  117. metadata +58 -47
  118. data/app/assets/stylesheets/express_admin/components/_megadropdown.sass +0 -66
  119. data/vendor/gems/express_templates/diagrams/diagram.graffle +0 -2404
  120. data/vendor/gems/express_templates/diagrams/diagram_express_templates.png +0 -0
  121. data/vendor/gems/express_templates/diagrams/diagram_haml_erb.png +0 -0
  122. data/vendor/gems/express_templates/lib/express_templates/components/capabilities/adoptable.rb +0 -20
  123. data/vendor/gems/express_templates/lib/express_templates/components/capabilities/building.rb +0 -14
  124. data/vendor/gems/express_templates/lib/express_templates/components/capabilities/conditionality.rb +0 -54
  125. data/vendor/gems/express_templates/lib/express_templates/components/capabilities/configurable.rb +0 -90
  126. data/vendor/gems/express_templates/lib/express_templates/components/capabilities/iterating.rb +0 -75
  127. data/vendor/gems/express_templates/lib/express_templates/components/capabilities/parenting.rb +0 -72
  128. data/vendor/gems/express_templates/lib/express_templates/components/capabilities/rendering.rb +0 -30
  129. data/vendor/gems/express_templates/lib/express_templates/components/capabilities/templating.rb +0 -198
  130. data/vendor/gems/express_templates/lib/express_templates/components/capabilities/wrapping.rb +0 -84
  131. data/vendor/gems/express_templates/lib/express_templates/components/column.rb +0 -13
  132. data/vendor/gems/express_templates/lib/express_templates/components/container.rb +0 -7
  133. data/vendor/gems/express_templates/lib/express_templates/components/content_for.rb +0 -42
  134. data/vendor/gems/express_templates/lib/express_templates/components/for_each.rb +0 -30
  135. data/vendor/gems/express_templates/lib/express_templates/components/forms/form_support.rb +0 -13
  136. data/vendor/gems/express_templates/lib/express_templates/components/null_wrap.rb +0 -41
  137. data/vendor/gems/express_templates/lib/express_templates/components/row.rb +0 -28
  138. data/vendor/gems/express_templates/lib/express_templates/components/table_for.rb +0 -163
  139. data/vendor/gems/express_templates/lib/express_templates/components/unless_block.rb +0 -40
  140. data/vendor/gems/express_templates/lib/express_templates/expander.rb +0 -140
  141. data/vendor/gems/express_templates/lib/express_templates/macro.rb +0 -45
  142. data/vendor/gems/express_templates/lib/express_templates/markup.rb +0 -9
  143. data/vendor/gems/express_templates/lib/express_templates/markup/html_tag.rb +0 -62
  144. data/vendor/gems/express_templates/lib/express_templates/markup/tag.rb +0 -150
  145. data/vendor/gems/express_templates/lib/express_templates/markup/wrapper.rb +0 -94
  146. data/vendor/gems/express_templates/lib/express_templates/markup/yielder.rb +0 -21
  147. data/vendor/gems/express_templates/test/components/column_test.rb +0 -11
  148. data/vendor/gems/express_templates/test/components/conditionality_test.rb +0 -37
  149. data/vendor/gems/express_templates/test/components/container_test.rb +0 -66
  150. data/vendor/gems/express_templates/test/components/content_for_test.rb +0 -60
  151. data/vendor/gems/express_templates/test/components/iterating_test.rb +0 -127
  152. data/vendor/gems/express_templates/test/components/null_wrap_test.rb +0 -28
  153. data/vendor/gems/express_templates/test/components/row_test.rb +0 -16
  154. data/vendor/gems/express_templates/test/components/table_for_test.rb +0 -211
  155. data/vendor/gems/express_templates/test/expander_stack_test.rb +0 -41
  156. data/vendor/gems/express_templates/test/expander_test.rb +0 -99
  157. data/vendor/gems/express_templates/test/markup/tag_test.rb +0 -149
  158. data/vendor/gems/express_templates/test/markup/wrapper_test.rb +0 -42
  159. data/vendor/gems/express_templates/test/markup/yielder_test.rb +0 -9
@@ -3,91 +3,114 @@ require 'test_helper'
3
3
  module ExpressAdmin
4
4
 
5
5
  class SmartFormTest < ActiveSupport::TestCase
6
- def compiled_widget_form(*args)
7
- ExpressAdmin::SmartForm.new(:widget, *args).compile
6
+
7
+ def resource_assigns
8
+ {resource: Widget.new, collection: Widget.all}
9
+ end
10
+ def helpers
11
+ view = mock_action_view(resource_assigns)
12
+ class << view
13
+ def widget_path(widget_id)
14
+ "/widgets/#{widget_id.to_param}"
15
+ end
16
+ alias resource_path widget_path
17
+ def widgets_path
18
+ "/widgets"
19
+ end
20
+ alias collection_path widgets_path
21
+ def admin_widgets_path
22
+ "/admin/widgets"
23
+ end
24
+ end
25
+ view
26
+ end
27
+
28
+
29
+ def widget_form(*args)
30
+ arbre {
31
+ smart_form(:widgets, *args)
32
+ }
8
33
  end
9
34
 
10
35
  test "renders a form correct id" do
11
- assert_match '<form id=\"widget\"', compiled_widget_form
36
+ assert_match '<form id="widget"', widget_form
12
37
  end
13
38
 
14
39
  test "uses inherited_resources path helpers to set correct action" do
15
- action_attrib = 'action=\"{{@widget.try(:persisted?) ? widget_path(@widget) : widgets_path}}\"'
16
- assert_match action_attrib, compiled_widget_form
40
+ action_attrib = 'action="/widgets"'
41
+ assert_match action_attrib, widget_form
17
42
  end
18
43
 
19
44
  test "action path can be overridden" do
20
- custom_action = '{{something_custom}}'
21
- action_attrib = 'action=\"'+custom_action+'\"'
22
- assert_match action_attrib, compiled_widget_form(action: custom_action)
45
+ custom_action = '/something_custom'
46
+ assert_match /action="#{custom_action}"/, widget_form(action: custom_action)
23
47
  end
24
48
 
25
49
  test "category field is a select" do
26
- assert_match 'select_tag("widget[category_id]"', compiled_widget_form
50
+ assert_match /<select.*name="widget\[category_id\]".*class="select2"/, widget_form
27
51
  end
28
52
 
29
53
  test "string field column2 is an input" do
30
- assert_match 'text_field(:widget, :column2)', compiled_widget_form
54
+ assert_match /<input.*type="text".*name="widget\[column2\]"/, widget_form
31
55
  end
32
56
 
33
57
  test "text field column3 is a text_area" do
34
- assert_match 'text_area(:widget, :column3)', compiled_widget_form
58
+ assert_match /<textarea.*rows="10".*name="widget\[column3\]"/, widget_form
35
59
  end
36
60
 
37
61
  test "datetime field column4 is a datetime_field" do
38
- assert_match 'datetime_field(:widget, :column4)', compiled_widget_form
62
+ assert_match /<input.*type="datetime".*name="widget\[column4\]"/, widget_form
39
63
  end
40
64
 
41
- test "boolean field column4 is a checkbox" do
42
- assert_match 'check_box(:widget, :column5, {}, "1", "0")', compiled_widget_form
65
+ test "boolean field column5 is a checkbox" do
66
+ assert_match /<input.*type="checkbox".*name="widget\[column5\]"/, widget_form
43
67
  end
44
68
 
45
- test "integer column is a number_field" do
46
- assert_match 'number_field(:widget, :column7)', compiled_widget_form
69
+ test "integer column7 is a number_field" do
70
+ assert_match /<input.*type="number".*name="widget\[column7\]"/, widget_form
47
71
  end
48
72
 
49
73
  test "timestamps are not editable" do
50
- assert_match 'Created At: {{@widget.try(:created_at)}}', compiled_widget_form
51
- assert_match 'Updated At: {{@widget.try(:updated_at)}}', compiled_widget_form
74
+ assert_match /Created At:.*\n/, widget_form
75
+ assert_match /Updated At:.*\n/, widget_form
52
76
  end
53
77
 
54
78
  test "fields have labels" do
55
- #%Q({{label_tag(\"widget_category_id\", \"Category\")}})
56
- matches = compiled_widget_form.scan /label_tag\(\\"\w+\\", \"\w+\"\)/
79
+ matches = widget_form.scan /<label.*>/
57
80
  assert 7, matches.length
58
81
 
59
- assert_match '%Q({{label_tag("widget_category_id", "Category")}})', compiled_widget_form
82
+ assert_match '<label for="widget_category_id">Category</label>', widget_form
60
83
  end
61
84
 
62
85
  test "fields are wrapped in a div" do
63
- assert_match '<div class=\"field-wrapper\">', compiled_widget_form
86
+ assert_match '<div class="field-wrapper">', widget_form
64
87
  end
65
88
 
66
89
  test 'path prefix is provided' do
67
- action_attrib = 'action=\"{{@widget.try(:persisted?) ? admin_widget_path(@widget) : admin_widgets_path}}\"'
68
- assert_match action_attrib, compiled_widget_form(path_prefix: 'admin')
90
+ action_attrib = 'action="/admin/widgets"'
91
+ assert_match action_attrib, widget_form(path_prefix: 'admin')
69
92
  end
70
93
 
71
- test "options_from_collection_for_select used for the related collection" do
72
- assert_match 'options_from_collection_for_select(Category.all.select(:id, :name).order(:name)',
73
- compiled_widget_form
94
+ test "options for select come from the related collection" do
95
+ assert_match /<option.*>Toys<\/option>/, widget_form
96
+ assert_match /<option.*>Tools<\/option>/, widget_form
74
97
  end
75
98
 
76
- test "options_from_collection_for_select use when a namespace is specified" do
77
- assert_match 'options_from_collection_for_select(ExampleEngine::Category.all.select(:id, :name).order(:name)',
78
- compiled_widget_form(namespace: "example_engine")
99
+ test "options for select work when a namespace is specified" do
100
+ assert_match /<option.*>Toys<\/option>/, widget_form(namespace: "example_engine")
101
+ assert_match /<option.*>Tools<\/option>/, widget_form(namespace: "example_engine")
79
102
  end
80
103
 
81
- test "collection_select with collection_ids is used for has_many_through associations" do
82
- assert_match /collection_select.*tag_ids.*multiple: true/, compiled_widget_form
104
+ test "multiple select is used for has_many_through associations" do
105
+ assert_match /select.*multiple="multiple".*name="widget\[tag_ids\]\[\]"/, widget_form
83
106
  end
84
107
 
85
108
  test "excluded fields are excluded" do
86
- refute_match 'column3', compiled_widget_form(exclude: [:column3])
109
+ refute_match 'column3', widget_form(exclude: [:column3])
87
110
  end
88
111
 
89
112
  test "virtual attributes may be included" do
90
- assert_match 'password', compiled_widget_form(virtual: [:password])
113
+ assert_match 'password', widget_form(virtual: [:password])
91
114
  end
92
115
  end
93
116
  end
@@ -4,10 +4,25 @@ module Components
4
4
 
5
5
  class SmartTableTest < ActiveSupport::TestCase
6
6
 
7
- fixtures :widgets
8
-
7
+ fixtures :widgets, :categories
8
+
9
+ def resource_assigns
10
+ {resource: Widget.new, collection: Widget.all}
11
+ end
12
+ def helpers
13
+ view = mock_action_view(resource_assigns)
14
+ class << view
15
+ def widget_path(widget_id)
16
+ "/widgets/#{widget_id.to_param}"
17
+ end
18
+ alias resource_path widget_path
19
+ end
20
+ view
21
+ end
9
22
  def compiled_widget_table(*args)
10
- ExpressAdmin::SmartTable.new(:widgets, *args).compile
23
+ arbre {
24
+ smart_table(:widgets, *args)
25
+ }
11
26
  end
12
27
 
13
28
  test "should have hidden columns" do
@@ -15,12 +30,13 @@ module Components
15
30
  assert_no_match 'column7', compiled_widget_table
16
31
  end
17
32
 
18
- test "iterates over collection setting local var correctly" do
19
- assert_match '(@widgets.each_with_index.map do |widget, widget_index|', compiled_widget_table
33
+ test "iterates over collection setting table row id correctly" do
34
+ assert_match 'widget:298486374', compiled_widget_table
35
+ assert_match 'widget:980190962', compiled_widget_table
20
36
  end
21
37
 
22
- test "renders cell contents within a substitution" do
23
- assert_match /\{\{[^\{\}]*widget.column2[^\{\}]*\}\}/, compiled_widget_table
38
+ test "renders cell contents" do
39
+ assert_match '<td class="column2">Hammer</td>', compiled_widget_table
24
40
  end
25
41
 
26
42
  # this behavior could change after we implement support for decorators
@@ -31,7 +47,8 @@ module Components
31
47
  test "table cell shows related item name or display name" do
32
48
  # note this will move to a helper that will intelligently look
33
49
  # for decorated methods such as name or display_name
34
- assert_match 'widget.category.try(:name) || widget.category.to_s', compiled_widget_table
50
+ assert_match '<td class="category_id">Toys</td>', compiled_widget_table
51
+ assert_match '<td class="category_id">Tools</td>', compiled_widget_table
35
52
  end
36
53
 
37
54
  test "table displays only columns specified if columns option provided" do
@@ -46,11 +63,11 @@ module Components
46
63
 
47
64
  test "table column titles may be customized" do
48
65
  compiled = compiled_widget_table(columns: {"Column3 is the Best" => :column3})
49
- assert_match /<th class=\\"column3\\">Column3 is the Best/, compiled
66
+ assert_match /<th class="column3">Column3 is the Best/, compiled
50
67
  end
51
68
 
52
- def widget_table_with_proc_column
53
- return -> {
69
+ def compiled_widget_table_with_proc_column
70
+ arbre {
54
71
  smart_table(:widgets, columns: {
55
72
  "This column will error" => -> (widget) { doesnt_work },
56
73
  "This column will be fine" => -> (widget) { widget.column2.upcase },
@@ -58,51 +75,34 @@ module Components
58
75
  }
59
76
  end
60
77
 
61
- def compiled_widget_table_with_proc_column
62
- ExpressTemplates.compile(&widget_table_with_proc_column)
63
- end
64
-
65
-
66
- test "table cell values may be specified as procs" do
67
- assert_match '-> (widget) { doesnt_work }', compiled_widget_table_with_proc_column
68
- end
69
-
70
- class DummyView
71
- def initialize
72
- @widgets = Widget.all
73
- end
74
- def widget_path(*args) ; "does not matter" ; end
75
- def link_to(*args) ; widget_path(*args) ; end
76
- end
77
-
78
78
  test "table cell has 'Error' if a value specified as a proc throws an exception" do
79
- assert_match 'Error', DummyView.new.instance_eval(compiled_widget_table_with_proc_column)
79
+ assert_match 'Error', compiled_widget_table_with_proc_column
80
80
  end
81
81
 
82
82
  test "table cell contains result of proc.call if no exception is raised" do
83
- assert_match 'LEGO', DummyView.new.instance_eval(compiled_widget_table_with_proc_column)
83
+ assert_match 'LEGO', compiled_widget_table_with_proc_column
84
84
  end
85
85
 
86
86
  test "table cell class is valid when proc is used" do
87
- assert_match 'class=\"this_column_will_error\"', compiled_widget_table_with_proc_column
87
+ assert_match 'class="this_column_will_error"', compiled_widget_table_with_proc_column
88
88
  end
89
89
 
90
90
  test "attribute accessor appended with _link generates a link" do
91
- fragment = -> {
91
+ fragment = arbre {
92
92
  smart_table(:widgets, columns: {
93
93
  'A link column' => :column3_link
94
94
  })
95
95
  }
96
- assert_match 'link_to widget.column3, widget_path(widget.id)', ExpressTemplates.compile(&fragment)
96
+ assert_match /column3.*href="\/widgets\/(\d+)/, fragment
97
97
  end
98
98
 
99
99
  test "timestamp accessor appeneded with _in_words generates code that uses time_ago_in_words" do
100
- fragment = -> {
100
+ fragment = arbre {
101
101
  smart_table(:widgets, columns: {
102
102
  'Created' => :created_at_in_words
103
103
  })
104
104
  }
105
- assert_match "\(widget.created_at \? time_ago_in_words\(widget.created_at\)\+' ago' : 'never'\)", ExpressTemplates.compile(&fragment)
105
+ assert_match /class="created_at.*less than a minute ago/, fragment
106
106
  end
107
107
 
108
108
  end
@@ -0,0 +1 @@
1
+ I"file:///Users/steve/Projects/appexpress/appexpress-io2/vendor/gems/express_site/vendor/gems/express_admin/test/dummy/app/assets/javascripts/demo.js?type=application/javascript&pipeline=self&id=dd456b9bf2c00ff3390f8a427657ca58f7ca18178971575c058e25d3e4688ca1:ET
@@ -0,0 +1 @@
1
+ I"�file:///Users/steve/Projects/appexpress/appexpress-io2/vendor/gems/express_site/vendor/gems/express_admin/test/dummy/app/assets/stylesheets/application.css?type=text/css&id=38bc076e35fb96e70bed4aa4a965d1264ece561d2e9929768e77073124f85493:ET
@@ -0,0 +1 @@
1
+ I"�file:///Users/steve/Projects/appexpress/appexpress-io2/vendor/gems/express_site/vendor/gems/express_admin/test/dummy/app/assets/stylesheets/application.css?type=text/css&pipeline=self&id=2ab8b9bedfbaa3206a5049828222e419849530855b290a7d3a73ce17666ceae8:ET
@@ -0,0 +1 @@
1
+ I"�file:///Users/steve/Projects/appexpress/appexpress-io2/vendor/gems/express_site/vendor/gems/express_admin/test/dummy/app/assets/javascripts/application.js?type=application/javascript&id=772903df259a1ef79dc73c8765d2fdcc5c93b7087bcf05f12aab804d3e80042c:ET
@@ -0,0 +1 @@
1
+ I"file:///Users/steve/Projects/appexpress/appexpress-io2/vendor/gems/express_site/vendor/gems/express_admin/test/dummy/app/assets/javascripts/application.js?type=application/javascript&pipeline=self&id=16055f28135a48516774deca69704a58124ce122a415d2213d2a541207d3f42d:ET
@@ -0,0 +1 @@
1
+ I"�file:///Users/steve/Projects/appexpress/appexpress-io2/vendor/gems/express_site/vendor/gems/express_admin/test/dummy/app/assets/stylesheets/demo.css.scss?type=text/css&pipeline=self&id=38c2a2a9551d19522ed73c7495a6d97a9421df70758c93c4e4b848aa4905348f:ET
@@ -0,0 +1,8 @@
1
+ # Read about fixtures at
2
+ # http://api.rubyonrails.org/classes/ActiveRecord/Fixtures.html
3
+
4
+ toys:
5
+ name: Toys
6
+
7
+ tools:
8
+ name: Tools
data/test/test_helper.rb CHANGED
@@ -10,6 +10,7 @@ require "minitest/rails"
10
10
  require "minitest/rails/capybara"
11
11
  require 'minitest/rg'
12
12
 
13
+ require 'pry'
13
14
 
14
15
  # Filter out Minitest backtrace while allowing backtrace from other libraries
15
16
  # to be shown.
@@ -36,3 +37,36 @@ module ExampleEngine
36
37
  has_many :widgets, class_name: 'ExampleEngine::Widget'
37
38
  end
38
39
  end
40
+ module AdditionalHelpers
41
+
42
+ def protect_against_forgery?
43
+ true
44
+ end
45
+
46
+ def form_authenticity_token
47
+ "AUTH_TOKEN"
48
+ end
49
+
50
+ end
51
+
52
+ module ActiveSupport
53
+ class TestCase
54
+ def arbre(assigns = {}, &block)
55
+ Arbre::Context.new assigns, helpers, &block
56
+ end
57
+ def mock_action_view(assigns = {})
58
+ controller = ActionView::TestCase::TestController.new
59
+ ActionView::Base.send :include, ActionView::Helpers
60
+ ActionView::Base.send :include, ActionView::Helpers::UrlHelper
61
+ ActionView::Base.send :include, AdditionalHelpers
62
+ view = ActionView::Base.new(ActionController::Base.view_paths, assigns, controller)
63
+ eigenklass = class << view
64
+ self
65
+ end
66
+ assigns.each do |helper_name,value|
67
+ eigenklass.send(:define_method, helper_name) { value }
68
+ end
69
+ view
70
+ end
71
+ end
72
+ end
@@ -0,0 +1,12 @@
1
+ # ExpressTemplates Changelog
2
+
3
+ ## Version 0.6.0
4
+
5
+ * Switched out the Expander and related classes to use arbre gem instead
6
+ * This is mostly backward compatible but introduces some breaking changes:
7
+ - dom ids must be specified with an id: key instead of as first parameter
8
+ - some capabilities have been removed as they are no longer necessary
9
+ - must use normal ruby control-flow in template fragements instead of for_each, unless_block, etc.
10
+ - wrapping must be accomplished using methods and blocks instead of wrap_with
11
+ - css class names must be specified as class: parameters instead of using .class_name methods
12
+
@@ -1,8 +1,9 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- express_templates (0.5.0)
4
+ express_templates (0.7.0)
5
5
  activesupport (~> 4.2)
6
+ arbre
6
7
  parslet (~> 1.6)
7
8
 
8
9
  GEM
@@ -44,6 +45,8 @@ GEM
44
45
  thread_safe (~> 0.3, >= 0.3.4)
45
46
  tzinfo (~> 1.1)
46
47
  ansi (1.5.0)
48
+ arbre (1.0.3)
49
+ activesupport (>= 3.0.0)
47
50
  arel (6.0.0)
48
51
  better_errors (2.1.1)
49
52
  coderay (>= 1.0.0)
@@ -2,6 +2,10 @@
2
2
 
3
3
  Provides a DSL for HTML templates using a declarative style of Ruby as an alternative to Erb or HAML.
4
4
 
5
+ Although originally we implemented our own DSL and used a code generation approach,
6
+ this gem now uses [ActiveAdmin's arbre](https://github.com/activeadmin/arbre). Arbre is widely
7
+ used as part of ActiveAdmin, has a long history and many contributors and is conceptually much simpler.
8
+
5
9
  ## Usage
6
10
 
7
11
  Add this to your gemfile:
@@ -26,7 +30,7 @@ html(lang: "en") {
26
30
  csrf_meta_tags
27
31
  }
28
32
  body {
29
- yield
33
+ current_arbre_element.add_child yield
30
34
  javascript_include_tag "application"
31
35
  }
32
36
  }
@@ -36,35 +40,18 @@ Everything should work as you would expect.
36
40
 
37
41
  Set your editor syntax for .et files to Ruby.
38
42
 
39
- You will now have also be able to utilize components which are found with documentation and examples in <tt>ExpressTemplates::Components<tt>.
40
-
41
- ## History
42
-
43
- To understand ExpressTemplates, you must first understand the standard tools of ERB and Haml which have been with us for quite some time.
44
-
45
- ![Haml/Erb Diagram](https://raw.githubusercontent.com/aelogica/express_templates/master/diagrams/diagram_haml_erb.png "Haml/Erb Diagram")
46
-
47
- Both of these provide a language for embedding other languages. Erb embeds Ruby between <% %> style tags. This is similar to the way we worked with PHP and for those who can remember "embedded Perl" in 1990s. Erb places no constraints on either the text into which the Ruby is embedded, nor on the Ruby which may be placed within the delimiters which comprise Erb's simple grammar.
48
-
49
- Haml introduced a number of innovations or improvements upon Erb. Through Haml's use of significant whitespace and indentation, it ensures well-formed markup. This noticably slows template compilation, however, due to caching it generally goes unnoticed. Haml added better support for mixing grammars in a single file as is common practice with Javascript. Haml introduced abbreviated methods for specifying CSS classes and HTML entity attribute values with the result of generally cleaning up view code.
43
+ You can now utilize components which are found with documentation and examples in <tt>ExpressTemplates::Components<tt>.
50
44
 
51
- Both Haml and Erb compile down to Ruby code which must be eval()'d in a View Context as per the interface required by Rails' ActionView.
45
+ Components are the real strength of both arbre and express_templates.
52
46
 
53
- ## Expansion
47
+ express_templates now *is* arbre + some components + some conventions. ExpressTemplates::Components::Base provides a little syntactic sugar in the form of the emits class method.
54
48
 
55
- ExpressTemplates introduces an earlier step in this process, "expansion", which may be likened to a kind of macro system. This is introduced to facilitate reusable view components in the form of normal object-oriented Ruby classes.
49
+ In terms of conventions, we use brace blocks { } to indicate html structure and do/end blocks to indicate control flow.
56
50
 
57
- ![Diagram depciting Haml/Erb](https://raw.githubusercontent.com/aelogica/express_templates/master/diagrams/diagram_express_templates.png "Diagram depciting Haml/Erb")
51
+ Control flow should only be used in Components. This is currently not enforced but it will be in the future.
58
52
 
59
- ## Constraints - Important!
53
+ The purpose of express_templates is to provide a foundation for a library of reusable UX components which we can enhance for drag-and-drop style UX construction and template editing.
60
54
 
61
- ExpressTemplates imposes some constraints. The most important constraint is that your view templates must be declarative in style. They should not contain conditional logic. Declarative code is easier to read and reason about. It also requires fewer tests since declarative code is build on presumably well-tested primitives.
62
-
63
- With ExpressTemplates, one *must not* place conditional logic or iterators anywhere in template code. All logic *must* be encapsulated in components. Strange things will happen if you try to put logic in the template or a template fragment. In the future I may issue warnings or disallow it by examinging the output of Ruby's tokenizer.
64
-
65
- If you have been around long enough to see a few Rails codebases grow out of control, and you have had to manage or watch the efforts of less-experienced developers closely, you know that one of the major causes of trouble and wasted effort is copy-and-paste code and logic errors in the view. Another common problem is the "blank slate" issue wherein every view must be constructed new with little chance for higher-level reuse of code. Diligent use of partials and helpers can do much to DRY up view code but deciding where to put them or how to share them between projects can be difficult. Rarely is view logic tested except in integration.
66
-
67
- ExpressTemplates only enforces what is already considered a best practice by many, while introducing new possilibities for well-ordered UX libraries similar to what developers working with commercial frameworks for desktop operating systems or mobile devices enjoy.
68
55
 
69
56
  ## Block Structure
70
57
 
@@ -90,8 +77,6 @@ Let us suppose that an @three variable exists in the view context with the value
90
77
  </ul>
91
78
  ```
92
79
 
93
- yield and local variables which we may expect to be available in a ViewContext are also wrapped for evaluation later.
94
-
95
80
  ## Components
96
81
 
97
82
  Given the constraint that logic must not go in the template, where does one put it? The answer is we make a component!
@@ -108,27 +93,23 @@ We can make a simple component like so:
108
93
 
109
94
  ```ruby
110
95
  class ListComponent < ExpressTemplates::Components::Base
111
- emits inner: -> {
112
- li {
113
- item
114
- }
115
- },
116
- outer: -> {
117
- ul {
118
- _yield
119
- }
120
- }
121
-
122
- for_each -> { @list }, emit: :inner
123
-
124
- wrap_with :outer
96
+ emits -> {
97
+ ul {
98
+ # assumes view provides list
99
+ list.each do |item|
100
+ li {
101
+ item
102
+ }
103
+ end
104
+ }
105
+ }
125
106
  end
126
107
  ```
127
108
 
128
109
  This would be used in a view template just as if it were a tag, like so:
129
110
 
130
111
  ```ruby
131
- div.active {
112
+ div(class: "active") {
132
113
  list_component
133
114
  }
134
115
  ```