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,43 +1,37 @@
|
|
|
1
1
|
require 'test_helper'
|
|
2
2
|
|
|
3
3
|
class CheckboxTest < ActiveSupport::TestCase
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
fragment = -> {
|
|
7
|
-
checkbox :permission_granted
|
|
8
|
-
}
|
|
9
|
-
assert_raises(RuntimeError) {
|
|
10
|
-
ExpressTemplates.compile(&fragment)
|
|
11
|
-
}
|
|
4
|
+
def assigns
|
|
5
|
+
{resource: resource}
|
|
12
6
|
end
|
|
13
7
|
|
|
14
8
|
test "checkbox places the label before the input" do
|
|
15
|
-
|
|
9
|
+
html = arbre {
|
|
16
10
|
express_form(:account) {
|
|
17
11
|
checkbox :eula
|
|
18
12
|
}
|
|
19
13
|
}
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
assert_match
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
field_idx = compiled.index(field_helper)
|
|
14
|
+
label = '<label for="account_eula"'
|
|
15
|
+
field = 'input type="checkbox" value="1" name="account\[eula\]"'
|
|
16
|
+
assert_match /#{label}/, html
|
|
17
|
+
assert_match /#{field}/, html
|
|
18
|
+
label_idx = html.index(label)
|
|
19
|
+
field_idx = html.index(field.gsub('\\', ''))
|
|
27
20
|
assert (field_idx > label_idx), "label must come first"
|
|
28
21
|
end
|
|
29
22
|
|
|
30
23
|
test "checkbox respects label_after: true " do
|
|
31
|
-
|
|
24
|
+
html = arbre {
|
|
32
25
|
express_form(:account) {
|
|
33
26
|
checkbox :eula, label_after: true
|
|
34
27
|
}
|
|
35
28
|
}
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
29
|
+
label = '<label for="account_eula"'
|
|
30
|
+
field = 'input type="checkbox" value="1" name="account\[eula\]"'
|
|
31
|
+
assert_match /#{label}/, html
|
|
32
|
+
assert_match /#{field}/, html
|
|
33
|
+
label_idx = html.index(label)
|
|
34
|
+
field_idx = html.index(field.gsub('\\', ''))
|
|
41
35
|
assert (field_idx < label_idx), "label must come after when label_after: true"
|
|
42
36
|
end
|
|
43
37
|
|
|
@@ -1,108 +1,55 @@
|
|
|
1
1
|
require 'test_helper'
|
|
2
2
|
require 'ostruct'
|
|
3
3
|
|
|
4
|
-
class
|
|
5
|
-
|
|
6
|
-
def initialize(resource)
|
|
7
|
-
@resource = resource
|
|
8
|
-
end
|
|
4
|
+
class Foo
|
|
5
|
+
def self.columns ; [] ; end
|
|
9
6
|
end
|
|
10
7
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
body: 'Hello world',
|
|
16
|
-
email: 'some@email.com',
|
|
17
|
-
phone: '123123123',
|
|
18
|
-
url: 'http://someurl.com',
|
|
19
|
-
number: 123,
|
|
20
|
-
dropdown: 'yes',
|
|
21
|
-
gender: 'Male'
|
|
22
|
-
)
|
|
8
|
+
class ExpressFormTest < ActiveSupport::TestCase
|
|
9
|
+
|
|
10
|
+
def assigns
|
|
11
|
+
{resource: resource}
|
|
23
12
|
end
|
|
24
13
|
|
|
25
|
-
def simplest_form
|
|
26
|
-
|
|
27
|
-
fragment = -> {
|
|
14
|
+
def simplest_form
|
|
15
|
+
arbre {
|
|
28
16
|
express_form(:resource) {
|
|
29
17
|
submit value: 'Save it!'
|
|
30
18
|
}
|
|
31
19
|
}
|
|
32
|
-
return ctx, fragment
|
|
33
|
-
end
|
|
34
|
-
|
|
35
|
-
def express_form
|
|
36
|
-
"ExpressTemplates::Components::Forms::ExpressForm".constantize
|
|
37
|
-
end
|
|
38
|
-
|
|
39
|
-
test "express_form component exists" do
|
|
40
|
-
assert express_form
|
|
41
|
-
end
|
|
42
|
-
|
|
43
|
-
def compile_simplest_form
|
|
44
|
-
ctx, fragment = simplest_form(resource)
|
|
45
|
-
ExpressTemplates.compile(&fragment)
|
|
46
20
|
end
|
|
47
21
|
|
|
48
22
|
test "simplest form renders" do
|
|
49
|
-
assert
|
|
23
|
+
assert simplest_form
|
|
50
24
|
end
|
|
51
25
|
|
|
52
26
|
test "simplest form contains form tag" do
|
|
53
|
-
assert_match "<form",
|
|
54
|
-
end
|
|
55
|
-
|
|
56
|
-
test "simplest form contains rails form helpers" do
|
|
57
|
-
compiled_src = compile_simplest_form
|
|
58
|
-
assert_match "utf8_enforcer_tag", compiled_src
|
|
59
|
-
assert_match "method_tag(", compiled_src
|
|
60
|
-
assert_match "token_tag", compiled_src
|
|
61
|
-
end
|
|
62
|
-
|
|
63
|
-
test "simplest_form contains submit" do
|
|
64
|
-
assert_match 'submit_tag', compile_simplest_form
|
|
27
|
+
assert_match "<form", simplest_form
|
|
65
28
|
end
|
|
66
29
|
|
|
67
|
-
test "
|
|
68
|
-
|
|
69
|
-
expanded_nodes = ExpressTemplates::Expander.new(nil).expand(fragment.source_body)
|
|
70
|
-
assert_instance_of ExpressTemplates::Components::Forms::ExpressForm,
|
|
71
|
-
expanded_nodes.first.children.last.parent
|
|
30
|
+
test "express_form contents are inside the form" do
|
|
31
|
+
assert_match /<form.*submit.*\/form>/, simplest_form.gsub("\n",'')
|
|
72
32
|
end
|
|
73
33
|
|
|
74
|
-
test "
|
|
75
|
-
|
|
34
|
+
test "simplest form contains rails form helpers" do
|
|
35
|
+
compiled_src = simplest_form
|
|
36
|
+
assert_match "input name=\"utf8\" type=\"hidden\"", compiled_src
|
|
37
|
+
assert_match "input type=\"hidden\" name=\"_method\"", compiled_src
|
|
38
|
+
assert_match "name=\"authenticity_token\" value=\"AUTH_TOKEN\"", compiled_src
|
|
39
|
+
assert_match /<form.*authenticity_token.*\/form>/, compiled_src.gsub("\n",'')
|
|
76
40
|
end
|
|
77
41
|
|
|
78
|
-
test "
|
|
79
|
-
|
|
42
|
+
test "simplest_form contains submit" do
|
|
43
|
+
assert_match '<input type="submit" name="commit" value="Save" />', simplest_form
|
|
80
44
|
end
|
|
81
45
|
|
|
82
46
|
test "simplest_form uses form_action for the action" do
|
|
83
|
-
form_open_tag =
|
|
84
|
-
assert_match 'action
|
|
47
|
+
form_open_tag = simplest_form.match(/<form[^>]*>/)[0]
|
|
48
|
+
assert_match 'action="/resources"', form_open_tag
|
|
85
49
|
end
|
|
86
50
|
|
|
87
51
|
test "express_form default method is POST" do
|
|
88
|
-
|
|
89
|
-
assert_match 'method=\"POST\"', form_open_tag
|
|
52
|
+
assert_match 'method="POST"', simplest_form
|
|
90
53
|
end
|
|
91
54
|
|
|
92
|
-
test "express_form accepts :resource_name for removing namespace" do
|
|
93
|
-
fragment = -> {
|
|
94
|
-
express_form(:admin_foo, resource_name: 'foo') {
|
|
95
|
-
submit "Save!"
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
expanded_nodes = ExpressTemplates::Expander.new(nil).expand(fragment.source_body)
|
|
99
|
-
assert_equal 'foo', expanded_nodes.first.resource_name
|
|
100
|
-
end
|
|
101
|
-
|
|
102
|
-
# test "express_form has a namespace option with nil default" do
|
|
103
|
-
# form = ExpressTemplates::Components::Forms::ExpressForm
|
|
104
|
-
# assert_nil form.new(:person).namespace
|
|
105
|
-
# assert_equal 'express_engine', form.new(:person, namespace: 'express_engine').namespace
|
|
106
|
-
# end
|
|
107
|
-
|
|
108
55
|
end
|
|
@@ -2,17 +2,20 @@ require 'test_helper'
|
|
|
2
2
|
|
|
3
3
|
class RadioTest < ActiveSupport::TestCase
|
|
4
4
|
|
|
5
|
+
def assigns
|
|
6
|
+
{resource: resource}
|
|
7
|
+
end
|
|
8
|
+
|
|
5
9
|
test "radio requires a parent component" do
|
|
6
|
-
fragment = -> {
|
|
7
|
-
radio :preferred_email_format, ['HTML', 'Text']
|
|
8
|
-
}
|
|
9
10
|
assert_raises(RuntimeError) {
|
|
10
|
-
|
|
11
|
+
html = arbre {
|
|
12
|
+
radio :preferred_email_format, ['HTML', 'Text']
|
|
13
|
+
}
|
|
11
14
|
}
|
|
12
15
|
end
|
|
13
16
|
|
|
14
17
|
def radio_with_array_options
|
|
15
|
-
|
|
18
|
+
html = arbre {
|
|
16
19
|
express_form(:person) {
|
|
17
20
|
radio :preferred_email_format, ['HTML', 'Text']
|
|
18
21
|
}
|
|
@@ -20,18 +23,17 @@ class RadioTest < ActiveSupport::TestCase
|
|
|
20
23
|
end
|
|
21
24
|
|
|
22
25
|
test "radio has correct label field name and text" do
|
|
23
|
-
assert_match
|
|
24
|
-
|
|
26
|
+
assert_match /<label for="person_preferred_email_format"/,
|
|
27
|
+
radio_with_array_options
|
|
25
28
|
end
|
|
26
29
|
|
|
27
30
|
test "radio options present with class 'radio'" do
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
assert_match '_format, "HTML", class: "radio"', compiled
|
|
31
|
+
assert_match /<input.*class="radio"/,
|
|
32
|
+
radio_with_array_options
|
|
31
33
|
end
|
|
32
34
|
|
|
33
35
|
def radio_with_hash_options
|
|
34
|
-
|
|
36
|
+
html = arbre {
|
|
35
37
|
express_form(:person) {
|
|
36
38
|
radio :subscribed, {1 => 'Yes', 0 => 'No'}, wrapper_class: 'my-wrapper'
|
|
37
39
|
}
|
|
@@ -39,34 +41,36 @@ class RadioTest < ActiveSupport::TestCase
|
|
|
39
41
|
end
|
|
40
42
|
|
|
41
43
|
test "radio options may be specified with a hash" do
|
|
42
|
-
compiled =
|
|
43
|
-
assert_match '<label class
|
|
44
|
-
assert_match '
|
|
45
|
-
assert_match '
|
|
44
|
+
compiled = radio_with_hash_options
|
|
45
|
+
assert_match '<label class="my-wrapper">', compiled
|
|
46
|
+
assert_match 'input class="radio" type="radio" value="0" name="person[subscribed]" id="person_subscribed_0" />No', compiled
|
|
47
|
+
assert_match 'input class="radio" type="radio" value="1" name="person[subscribed]" id="person_subscribed_1" />Yes', compiled
|
|
46
48
|
end
|
|
47
49
|
|
|
48
50
|
test "radio throws error if given improper options" do
|
|
49
|
-
fragment = -> {
|
|
50
|
-
express_form(:person) {
|
|
51
|
-
radio :subscribed, "Garbage options"
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
51
|
assert_raises(RuntimeError) {
|
|
55
|
-
|
|
52
|
+
html = arbre {
|
|
53
|
+
express_form(:person) {
|
|
54
|
+
radio :subscribed, "Garbage options"
|
|
55
|
+
}
|
|
56
|
+
}
|
|
56
57
|
}
|
|
57
58
|
end
|
|
58
59
|
|
|
59
60
|
def radio_with_options_omitted
|
|
60
|
-
|
|
61
|
+
html = arbre {
|
|
61
62
|
express_form(:employee) {
|
|
62
63
|
radio :department_id
|
|
63
64
|
}
|
|
64
65
|
}
|
|
65
66
|
end
|
|
66
67
|
|
|
67
|
-
class ::Department
|
|
68
|
-
def self.
|
|
69
|
-
|
|
68
|
+
class ::Department < ::Gender
|
|
69
|
+
def self.order(*)
|
|
70
|
+
all
|
|
71
|
+
end
|
|
72
|
+
def self.all
|
|
73
|
+
return [new(1, 'Accounting'), new(2, 'Marketing')]
|
|
70
74
|
end
|
|
71
75
|
end
|
|
72
76
|
class ::Employee
|
|
@@ -84,8 +88,8 @@ class RadioTest < ActiveSupport::TestCase
|
|
|
84
88
|
end
|
|
85
89
|
|
|
86
90
|
test "radio options from collection when options omitted" do
|
|
87
|
-
assert_match
|
|
88
|
-
|
|
91
|
+
assert_match /input type="radio" value="1" name="employee\[department_id\]" id="employee_department_id_1"/,
|
|
92
|
+
radio_with_options_omitted
|
|
89
93
|
end
|
|
90
94
|
|
|
91
95
|
# test "radio supports html options"
|
|
@@ -2,144 +2,119 @@ require 'test_helper'
|
|
|
2
2
|
require 'ostruct'
|
|
3
3
|
class SelectTest < ActiveSupport::TestCase
|
|
4
4
|
|
|
5
|
+
def assigns
|
|
6
|
+
{resource: ::Person.new}
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
|
|
5
10
|
test "select requires a parent component" do
|
|
6
|
-
fragment = -> {
|
|
7
|
-
select :gender, ['Male', 'Female'], selected: 'Male'
|
|
8
|
-
}
|
|
9
11
|
assert_raises(RuntimeError) {
|
|
10
|
-
|
|
12
|
+
html = arbre {
|
|
13
|
+
select :gender, options: ['Male', 'Female'], selected: 'Male'
|
|
14
|
+
}
|
|
11
15
|
}
|
|
12
16
|
end
|
|
13
17
|
|
|
14
18
|
test "select comes with a label" do
|
|
15
|
-
|
|
19
|
+
html = arbre {
|
|
16
20
|
express_form(:person) {
|
|
17
21
|
select :gender
|
|
18
22
|
}
|
|
19
23
|
}
|
|
20
|
-
assert_match
|
|
24
|
+
assert_match /<label.*for="person_gender"/, html
|
|
21
25
|
end
|
|
22
26
|
|
|
23
|
-
test "select
|
|
24
|
-
|
|
27
|
+
test "select generates correct options when values are specified" do
|
|
28
|
+
html = arbre {
|
|
25
29
|
express_form(:person) {
|
|
26
|
-
select :gender, ['Male', 'Female'], selected: 'Male'
|
|
30
|
+
select :gender, options: ['Male', 'Female'], selected: 'Male'
|
|
27
31
|
}
|
|
28
32
|
}
|
|
29
|
-
assert_match
|
|
33
|
+
assert_match /<option.*selected="selected" value="Male"/, html
|
|
34
|
+
assert_match /<option.*value="Female"/, html
|
|
30
35
|
end
|
|
31
36
|
|
|
32
37
|
test "selected option is omitted selection is taken from model" do
|
|
33
|
-
|
|
38
|
+
html = arbre {
|
|
34
39
|
express_form(:person) {
|
|
35
|
-
select :gender, ['Male', 'Female']
|
|
40
|
+
select :gender, options: ['Male', 'Female']
|
|
36
41
|
}
|
|
37
42
|
}
|
|
38
|
-
assert_match
|
|
43
|
+
assert_match /<option.*selected="selected" value="Male"/, html
|
|
44
|
+
assert_match /<option.*value="Female"/, html
|
|
39
45
|
end
|
|
40
46
|
|
|
41
47
|
test "select generates options from data when options omitted" do
|
|
42
|
-
|
|
48
|
+
html = arbre {
|
|
43
49
|
express_form(:person) {
|
|
44
50
|
select :city
|
|
45
51
|
}
|
|
46
52
|
}
|
|
47
|
-
assert_match
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
class ::Gender
|
|
51
|
-
def self.columns
|
|
52
|
-
[OpenStruct.new(name: 'id'), OpenStruct.new(name: 'name')]
|
|
53
|
-
end
|
|
54
|
-
end
|
|
55
|
-
class ::Tagging
|
|
56
|
-
def self.columns
|
|
57
|
-
[OpenStruct.new(name: 'id'), OpenStruct.new(name: 'name')]
|
|
58
|
-
end
|
|
59
|
-
end
|
|
60
|
-
class ::Person
|
|
61
|
-
def self.reflect_on_association(name)
|
|
62
|
-
if name.eql? :gender
|
|
63
|
-
dummy_belongs_to_association = Object.new
|
|
64
|
-
class << dummy_belongs_to_association
|
|
65
|
-
def macro ; :belongs_to ; end
|
|
66
|
-
def klass ; ::Gender ; end
|
|
67
|
-
def polymorphic? ; false ; end
|
|
68
|
-
end
|
|
69
|
-
return dummy_belongs_to_association
|
|
70
|
-
end
|
|
71
|
-
if name.eql? :taggings
|
|
72
|
-
dummy_has_many_through_association = Object.new
|
|
73
|
-
class << dummy_has_many_through_association
|
|
74
|
-
def macro ; :has_many ; end
|
|
75
|
-
def klass ; ::Tagging ; end
|
|
76
|
-
def options ; {:through => :peron_tags} ; end
|
|
77
|
-
def polymorphic? ; false ; end
|
|
78
|
-
end
|
|
79
|
-
return dummy_has_many_through_association
|
|
80
|
-
end
|
|
81
|
-
end
|
|
53
|
+
assert_match /<option.*selected="selected" value="San Francisco"/, html
|
|
54
|
+
assert_match /<option.*value="Hong Kong"/, html
|
|
82
55
|
end
|
|
83
56
|
|
|
84
57
|
test "select uses options_from_collect... when field is relation" do
|
|
85
|
-
|
|
58
|
+
html = arbre {
|
|
86
59
|
express_form(:person) {
|
|
87
|
-
select :
|
|
60
|
+
select :gender_id
|
|
88
61
|
}
|
|
89
62
|
}
|
|
90
63
|
|
|
91
|
-
assert_match
|
|
92
|
-
|
|
64
|
+
assert_match /<option.*selected="selected" value="1"/, html
|
|
65
|
+
assert_match /<option.*value="2"/, html
|
|
93
66
|
end
|
|
94
67
|
|
|
95
68
|
test "select defaults to include_blank: true" do
|
|
96
|
-
|
|
69
|
+
html = arbre {
|
|
97
70
|
express_form(:person) {
|
|
98
71
|
select :gender
|
|
99
72
|
}
|
|
100
73
|
}
|
|
101
|
-
assert_match '
|
|
74
|
+
assert_match '<option value=""></option>', html
|
|
102
75
|
end
|
|
103
76
|
|
|
104
77
|
|
|
105
78
|
test "select defaults can be overridden" do
|
|
106
|
-
|
|
79
|
+
html = arbre {
|
|
107
80
|
express_form(:person) {
|
|
108
|
-
select :gender,
|
|
81
|
+
select :gender, include_blank: false
|
|
109
82
|
}
|
|
110
83
|
}
|
|
111
|
-
assert_no_match 'include_blank: true',
|
|
84
|
+
assert_no_match 'include_blank: true', html
|
|
112
85
|
end
|
|
113
86
|
|
|
114
87
|
test "select multiple: true if passed multiple true" do
|
|
115
|
-
|
|
88
|
+
html = arbre {
|
|
116
89
|
express_form(:person) {
|
|
117
|
-
select :taggings,
|
|
90
|
+
select :taggings, include_blank: false, multiple: true
|
|
118
91
|
}
|
|
119
92
|
}
|
|
120
|
-
assert_match 'multiple
|
|
93
|
+
assert_match 'multiple="multiple"', html
|
|
121
94
|
end
|
|
122
95
|
|
|
123
96
|
test "select multiple gets options from associated has_many_through collection" do
|
|
124
|
-
|
|
97
|
+
html = arbre {
|
|
125
98
|
express_form(:person) {
|
|
126
|
-
select :taggings,
|
|
99
|
+
select :taggings, include_blank: false, multiple: true
|
|
127
100
|
}
|
|
128
101
|
}
|
|
129
|
-
assert_match 'tagging_ids',
|
|
130
|
-
assert_match
|
|
131
|
-
|
|
102
|
+
assert_match 'tagging_ids', html
|
|
103
|
+
assert_match /<option selected="selected" value="1">Friend<\/option>/, html
|
|
104
|
+
assert_match /<option selected="selected" value="2">Enemy<\/option>/, html
|
|
105
|
+
assert_match /<option value="3">Frenemy<\/option>/, html
|
|
132
106
|
end
|
|
133
107
|
|
|
134
|
-
test "select_collection
|
|
135
|
-
|
|
108
|
+
test "select_collection works using collection_select" do
|
|
109
|
+
html = arbre {
|
|
136
110
|
express_form(:person) {
|
|
137
111
|
select_collection :taggings
|
|
138
112
|
}
|
|
139
113
|
}
|
|
140
|
-
assert_match 'tagging_ids',
|
|
141
|
-
assert_match
|
|
142
|
-
|
|
114
|
+
assert_match 'tagging_ids', html
|
|
115
|
+
assert_match /<option value="1">Friend<\/option>/, html
|
|
116
|
+
assert_match /<option value="2">Enemy<\/option>/, html
|
|
117
|
+
assert_match /<option value="3">Frenemy<\/option>/, html
|
|
143
118
|
end
|
|
144
119
|
|
|
145
120
|
|
|
@@ -1,12 +1,17 @@
|
|
|
1
1
|
require 'test_helper'
|
|
2
2
|
|
|
3
|
+
class Stuff
|
|
4
|
+
def self.columns
|
|
5
|
+
[]
|
|
6
|
+
end
|
|
7
|
+
end
|
|
8
|
+
|
|
3
9
|
class SubmitTest < ActiveSupport::TestCase
|
|
4
10
|
test "submit takes string param for value" do
|
|
5
|
-
fragment = -> {
|
|
6
|
-
|
|
7
|
-
submit "Save it!"
|
|
8
|
-
}
|
|
11
|
+
fragment = -> (ctx) {
|
|
12
|
+
submit "Save it!"
|
|
9
13
|
}
|
|
10
|
-
assert_match '
|
|
14
|
+
assert_match '<div class="field-wrapper"><input type="submit" name="commit" value="Save it!" /></div>',
|
|
15
|
+
arbre(&fragment)
|
|
11
16
|
end
|
|
12
17
|
end
|
|
@@ -24,43 +24,16 @@ class TreeForTest < ActiveSupport::TestCase
|
|
|
24
24
|
Role.new('Auditor')])])]
|
|
25
25
|
end
|
|
26
26
|
|
|
27
|
-
EXAMPLE_COMPILED = -> {
|
|
28
|
-
ExpressTemplates::Components::TreeFor.render_in(self) {
|
|
29
|
-
node_renderer = -> (role, renderer) {
|
|
30
|
-
ExpressTemplates::Indenter.for(:tree) do |ws, wsnl|
|
|
31
|
-
"#{wsnl}<li>"+
|
|
32
|
-
"#{role.name}"+
|
|
33
|
-
if role.children.any?
|
|
34
|
-
ExpressTemplates::Indenter.for(:tree) do |ws, wsnl|
|
|
35
|
-
"#{wsnl}<ul>" +
|
|
36
|
-
role.children.map do |child|
|
|
37
|
-
renderer.call(child, renderer)
|
|
38
|
-
end.join +
|
|
39
|
-
"#{wsnl}</ul>"
|
|
40
|
-
end +
|
|
41
|
-
"#{wsnl}</li>"
|
|
42
|
-
else
|
|
43
|
-
"</li>"
|
|
44
|
-
end
|
|
45
|
-
end
|
|
46
|
-
}
|
|
47
|
-
ExpressTemplates::Indenter.for(:tree) do |ws, wsnl|
|
|
48
|
-
"#{ws}<ul id=\"roles\" class=\"roles tree\">" +
|
|
49
|
-
@roles.map do |role|
|
|
50
|
-
node_renderer.call(role, node_renderer)
|
|
51
|
-
end.join +
|
|
52
|
-
"#{wsnl}</ul>\n"
|
|
53
|
-
end
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
|
|
57
27
|
EXAMPLE_MARKUP = <<-HTML
|
|
58
28
|
<ul id="roles" class="roles tree">
|
|
59
|
-
<li>
|
|
29
|
+
<li>
|
|
30
|
+
SuperAdmin
|
|
60
31
|
<ul>
|
|
61
|
-
<li>
|
|
32
|
+
<li>
|
|
33
|
+
Admin
|
|
62
34
|
<ul>
|
|
63
|
-
<li>
|
|
35
|
+
<li>
|
|
36
|
+
Publisher
|
|
64
37
|
<ul>
|
|
65
38
|
<li>Author</li>
|
|
66
39
|
</ul>
|
|
@@ -73,31 +46,30 @@ ExpressTemplates::Components::TreeFor.render_in(self) {
|
|
|
73
46
|
</ul>
|
|
74
47
|
HTML
|
|
75
48
|
|
|
76
|
-
def
|
|
77
|
-
|
|
78
|
-
fragment = -> {
|
|
79
|
-
tree_for(:roles) {
|
|
80
|
-
"{{role.name}}"
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
return ctx, fragment
|
|
49
|
+
def assigns
|
|
50
|
+
{roles: roles}
|
|
84
51
|
end
|
|
85
52
|
|
|
53
|
+
def simple_tree_for
|
|
54
|
+
arbre {
|
|
55
|
+
tree_for(:roles)
|
|
56
|
+
}.to_s
|
|
57
|
+
end
|
|
86
58
|
|
|
87
|
-
test "
|
|
88
|
-
assert_equal EXAMPLE_MARKUP,
|
|
59
|
+
test "tree_for renders correct markup with node.name as default" do
|
|
60
|
+
assert_equal EXAMPLE_MARKUP, simple_tree_for
|
|
89
61
|
end
|
|
90
62
|
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
63
|
+
def custom_tree_for
|
|
64
|
+
arbre {
|
|
65
|
+
tree_for(:roles) { |node|
|
|
66
|
+
text_node node.name.upcase
|
|
67
|
+
}
|
|
68
|
+
}
|
|
94
69
|
end
|
|
95
70
|
|
|
96
|
-
test "
|
|
97
|
-
|
|
98
|
-
ctx, fragment = simple_tree_for(roles)
|
|
99
|
-
assert_equal EXAMPLE_MARKUP, ExpressTemplates.render(ctx, &fragment)
|
|
100
|
-
end
|
|
71
|
+
test "tree_for accepts block with custom content" do
|
|
72
|
+
assert_match 'AUTHOR', custom_tree_for
|
|
101
73
|
end
|
|
102
74
|
|
|
103
|
-
end
|
|
75
|
+
end
|