sablon 0.0.2 → 0.0.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +3 -1
- data/lib/sablon.rb +3 -0
- data/lib/sablon/operations.rb +13 -1
- data/lib/sablon/processor.rb +4 -2
- data/lib/sablon/version.rb +1 -1
- data/test/expression_test.rb +17 -2
- data/test/fixtures/xml/complex_field.xml +22 -0
- data/test/fixtures/xml/conditional.xml +26 -0
- data/test/fixtures/xml/conditional_with_predicate.xml +19 -0
- data/test/fixtures/xml/conditional_without_ending.xml +18 -0
- data/test/fixtures/xml/edited_complex_field.xml +26 -0
- data/test/fixtures/xml/loop_without_ending.xml +46 -0
- data/test/fixtures/xml/paragraph_loop.xml +61 -0
- data/test/fixtures/xml/paragraph_loop_within_table_cell.xml +33 -0
- data/test/fixtures/xml/simple_field.xml +8 -0
- data/test/fixtures/xml/simple_fields.xml +12 -0
- data/test/fixtures/xml/table_multi_row_loop.xml +124 -0
- data/test/fixtures/xml/table_row_loop.xml +157 -0
- data/test/processor_test.rb +39 -499
- data/test/sablon_test.rb +11 -11
- data/test/support/xml_snippets.rb +9 -0
- metadata +28 -2
@@ -0,0 +1,157 @@
|
|
1
|
+
<w:tbl>
|
2
|
+
<w:tblPr>
|
3
|
+
<w:tblStyle w:val="TableGrid"/>
|
4
|
+
<w:tblW w:w="0" w:type="auto"/>
|
5
|
+
<w:tblLook w:val="04A0" w:firstRow="1" w:lastRow="0" w:firstColumn="1" w:lastColumn="0" w:noHBand="0" w:noVBand="1"/>
|
6
|
+
</w:tblPr>
|
7
|
+
<w:tblGrid>
|
8
|
+
<w:gridCol w:w="2202"/>
|
9
|
+
<w:gridCol w:w="4285"/>
|
10
|
+
<w:gridCol w:w="2029"/>
|
11
|
+
</w:tblGrid>
|
12
|
+
<w:tr w:rsidR="00757DAD" w14:paraId="229B7A39" w14:textId="77777777" w:rsidTr="006333C3">
|
13
|
+
<w:tc>
|
14
|
+
<w:tcPr>
|
15
|
+
<w:tcW w:w="2202" w:type="dxa"/>
|
16
|
+
</w:tcPr>
|
17
|
+
<w:p w14:paraId="3D472BF1" w14:textId="77777777" w:rsidR="00757DAD" w:rsidRDefault="00757DAD" w:rsidP="006333C3">
|
18
|
+
<w:r>
|
19
|
+
<w:fldChar w:fldCharType="begin"/>
|
20
|
+
</w:r>
|
21
|
+
<w:r>
|
22
|
+
<w:instrText xml:space="preserve"> MERGEFIELD items:each(item) \* MERGEFORMAT </w:instrText>
|
23
|
+
</w:r>
|
24
|
+
<w:r>
|
25
|
+
<w:fldChar w:fldCharType="separate"/>
|
26
|
+
</w:r>
|
27
|
+
<w:r>
|
28
|
+
<w:rPr><w:noProof/></w:rPr>
|
29
|
+
<w:t>«items:each(item)»</w:t>
|
30
|
+
</w:r>
|
31
|
+
<w:r>
|
32
|
+
<w:fldChar w:fldCharType="end"/>
|
33
|
+
</w:r>
|
34
|
+
</w:p>
|
35
|
+
</w:tc>
|
36
|
+
<w:tc>
|
37
|
+
<w:tcPr>
|
38
|
+
<w:tcW w:w="4285" w:type="dxa"/>
|
39
|
+
</w:tcPr>
|
40
|
+
<w:p w14:paraId="6E6D8DB2" w14:textId="77777777" w:rsidR="00757DAD" w:rsidRDefault="00757DAD" w:rsidP="006333C3"/>
|
41
|
+
</w:tc>
|
42
|
+
<w:tc>
|
43
|
+
<w:tcPr>
|
44
|
+
<w:tcW w:w="2029" w:type="dxa"/>
|
45
|
+
</w:tcPr>
|
46
|
+
<w:p w14:paraId="7BE1DB00" w14:textId="77777777" w:rsidR="00757DAD" w:rsidRDefault="00757DAD" w:rsidP="006333C3"/>
|
47
|
+
</w:tc>
|
48
|
+
</w:tr>
|
49
|
+
<w:tr w:rsidR="00757DAD" w14:paraId="1BD2E50A" w14:textId="77777777" w:rsidTr="006333C3">
|
50
|
+
<w:tc>
|
51
|
+
<w:tcPr>
|
52
|
+
<w:tcW w:w="2202" w:type="dxa"/>
|
53
|
+
</w:tcPr>
|
54
|
+
<w:p w14:paraId="41ACB3D9" w14:textId="77777777" w:rsidR="00757DAD" w:rsidRDefault="00757DAD" w:rsidP="006333C3">
|
55
|
+
<w:r>
|
56
|
+
<w:fldChar w:fldCharType="begin"/>
|
57
|
+
</w:r>
|
58
|
+
<w:r>
|
59
|
+
<w:instrText xml:space="preserve"> MERGEFIELD =item.index \* MERGEFORMAT </w:instrText>
|
60
|
+
</w:r>
|
61
|
+
<w:r>
|
62
|
+
<w:fldChar w:fldCharType="separate"/>
|
63
|
+
</w:r>
|
64
|
+
<w:r>
|
65
|
+
<w:rPr><w:noProof/></w:rPr>
|
66
|
+
<w:t>«=item.index»</w:t>
|
67
|
+
</w:r>
|
68
|
+
<w:r>
|
69
|
+
<w:fldChar w:fldCharType="end"/>
|
70
|
+
</w:r>
|
71
|
+
</w:p>
|
72
|
+
</w:tc>
|
73
|
+
<w:tc>
|
74
|
+
<w:tcPr>
|
75
|
+
<w:tcW w:w="4285" w:type="dxa"/>
|
76
|
+
</w:tcPr>
|
77
|
+
<w:p w14:paraId="197C6F31" w14:textId="77777777" w:rsidR="00757DAD" w:rsidRDefault="00757DAD" w:rsidP="006333C3">
|
78
|
+
<w:r>
|
79
|
+
<w:fldChar w:fldCharType="begin"/>
|
80
|
+
</w:r>
|
81
|
+
<w:r>
|
82
|
+
<w:instrText xml:space="preserve"> MERGEFIELD =item.label \* MERGEFORMAT </w:instrText>
|
83
|
+
</w:r>
|
84
|
+
<w:r>
|
85
|
+
<w:fldChar w:fldCharType="separate"/>
|
86
|
+
</w:r>
|
87
|
+
<w:r>
|
88
|
+
<w:rPr><w:noProof/></w:rPr>
|
89
|
+
<w:t>«=item.label»</w:t>
|
90
|
+
</w:r>
|
91
|
+
<w:r>
|
92
|
+
<w:fldChar w:fldCharType="end"/>
|
93
|
+
</w:r>
|
94
|
+
</w:p>
|
95
|
+
</w:tc>
|
96
|
+
<w:tc>
|
97
|
+
<w:tcPr>
|
98
|
+
<w:tcW w:w="2029" w:type="dxa"/>
|
99
|
+
</w:tcPr>
|
100
|
+
<w:p w14:paraId="55C258BB" w14:textId="77777777" w:rsidR="00757DAD" w:rsidRDefault="00757DAD" w:rsidP="006333C3">
|
101
|
+
<w:r>
|
102
|
+
<w:fldChar w:fldCharType="begin"/>
|
103
|
+
</w:r>
|
104
|
+
<w:r>
|
105
|
+
<w:instrText xml:space="preserve"> MERGEFIELD =item.rating \* MERGEFORMAT </w:instrText>
|
106
|
+
</w:r>
|
107
|
+
<w:r>
|
108
|
+
<w:fldChar w:fldCharType="separate"/>
|
109
|
+
</w:r>
|
110
|
+
<w:r>
|
111
|
+
<w:rPr><w:noProof/></w:rPr>
|
112
|
+
<w:t>«=item.rating»</w:t>
|
113
|
+
</w:r>
|
114
|
+
<w:r>
|
115
|
+
<w:fldChar w:fldCharType="end"/>
|
116
|
+
</w:r>
|
117
|
+
</w:p>
|
118
|
+
</w:tc>
|
119
|
+
</w:tr>
|
120
|
+
<w:tr w:rsidR="00757DAD" w14:paraId="2D3C09BC" w14:textId="77777777" w:rsidTr="006333C3">
|
121
|
+
<w:tc>
|
122
|
+
<w:tcPr>
|
123
|
+
<w:tcW w:w="2202" w:type="dxa"/>
|
124
|
+
</w:tcPr>
|
125
|
+
<w:p w14:paraId="04A961B7" w14:textId="77777777" w:rsidR="00757DAD" w:rsidRDefault="00757DAD" w:rsidP="006333C3">
|
126
|
+
<w:r>
|
127
|
+
<w:fldChar w:fldCharType="begin"/>
|
128
|
+
</w:r>
|
129
|
+
<w:r>
|
130
|
+
<w:instrText xml:space="preserve"> MERGEFIELD items:endEach \* MERGEFORMAT </w:instrText>
|
131
|
+
</w:r>
|
132
|
+
<w:r>
|
133
|
+
<w:fldChar w:fldCharType="separate"/>
|
134
|
+
</w:r>
|
135
|
+
<w:r>
|
136
|
+
<w:rPr><w:noProof/></w:rPr>
|
137
|
+
<w:t>«items:endEach»</w:t>
|
138
|
+
</w:r>
|
139
|
+
<w:r>
|
140
|
+
<w:fldChar w:fldCharType="end"/>
|
141
|
+
</w:r>
|
142
|
+
</w:p>
|
143
|
+
</w:tc>
|
144
|
+
<w:tc>
|
145
|
+
<w:tcPr>
|
146
|
+
<w:tcW w:w="4285" w:type="dxa"/>
|
147
|
+
</w:tcPr>
|
148
|
+
<w:p w14:paraId="71165BFB" w14:textId="77777777" w:rsidR="00757DAD" w:rsidRDefault="00757DAD" w:rsidP="006333C3"/>
|
149
|
+
</w:tc>
|
150
|
+
<w:tc>
|
151
|
+
<w:tcPr>
|
152
|
+
<w:tcW w:w="2029" w:type="dxa"/>
|
153
|
+
</w:tcPr>
|
154
|
+
<w:p w14:paraId="01D3965C" w14:textId="77777777" w:rsidR="00757DAD" w:rsidRDefault="00757DAD" w:rsidP="006333C3"/>
|
155
|
+
</w:tc>
|
156
|
+
</w:tr>
|
157
|
+
</w:tbl>
|
data/test/processor_test.rb
CHANGED
@@ -1,9 +1,11 @@
|
|
1
1
|
# -*- coding: utf-8 -*-
|
2
2
|
require "test_helper"
|
3
3
|
require "support/document_xml_helper"
|
4
|
+
require "support/xml_snippets"
|
4
5
|
|
5
6
|
class ProcessorTest < Sablon::TestCase
|
6
7
|
include DocumentXMLHelper
|
8
|
+
include XMLSnippets
|
7
9
|
|
8
10
|
def setup
|
9
11
|
super
|
@@ -11,17 +13,7 @@ class ProcessorTest < Sablon::TestCase
|
|
11
13
|
end
|
12
14
|
|
13
15
|
def test_simple_field_replacement
|
14
|
-
result = process(
|
15
|
-
<w:r><w:t xml:space="preserve">Hello! My Name is </w:t></w:r>
|
16
|
-
<w:fldSimple w:instr=" MERGEFIELD =first_name \\* MERGEFORMAT ">
|
17
|
-
<w:r w:rsidR="004B49F0">
|
18
|
-
<w:rPr><w:noProof/></w:rPr>
|
19
|
-
<w:t>«=first_name»</w:t>
|
20
|
-
</w:r>
|
21
|
-
</w:fldSimple>
|
22
|
-
<w:r w:rsidR="00BE47B1"><w:t xml:space="preserve">, nice to meet you.</w:t></w:r>
|
23
|
-
documentxml
|
24
|
-
|
16
|
+
result = process(snippet("simple_field"), {"first_name" => "Jack"})
|
25
17
|
|
26
18
|
assert_equal "Hello! My Name is Jack , nice to meet you.", text(result)
|
27
19
|
assert_xml_equal <<-document, result
|
@@ -34,31 +26,13 @@ class ProcessorTest < Sablon::TestCase
|
|
34
26
|
document
|
35
27
|
end
|
36
28
|
|
29
|
+
def test_context_can_contain_string_and_symbol_keys
|
30
|
+
result = process(snippet("simple_fields"), {"first_name" => "Jack", last_name: "Davis"})
|
31
|
+
assert_equal "Jack Davis", text(result)
|
32
|
+
end
|
33
|
+
|
37
34
|
def test_complex_field_replacement
|
38
|
-
result = process(
|
39
|
-
<w:r><w:t xml:space="preserve">Hello! My Name is </w:t></w:r>
|
40
|
-
<w:r w:rsidR="00BE47B1" w:rsidRPr="00BE47B1">
|
41
|
-
<w:rPr><w:b/></w:rPr>
|
42
|
-
<w:fldChar w:fldCharType="begin"/>
|
43
|
-
</w:r>
|
44
|
-
<w:r w:rsidR="00BE47B1" w:rsidRPr="00BE47B1">
|
45
|
-
<w:rPr><w:b/></w:rPr>
|
46
|
-
<w:instrText xml:space="preserve"> MERGEFIELD =last_name \\* MERGEFORMAT </w:instrText>
|
47
|
-
</w:r>
|
48
|
-
<w:r w:rsidR="00BE47B1" w:rsidRPr="00BE47B1">
|
49
|
-
<w:rPr><w:b/></w:rPr>
|
50
|
-
<w:fldChar w:fldCharType="separate"/>
|
51
|
-
</w:r>
|
52
|
-
<w:r w:rsidR="004B49F0">
|
53
|
-
<w:rPr><w:b/><w:noProof/></w:rPr>
|
54
|
-
<w:t>«=last_name»</w:t>
|
55
|
-
</w:r>
|
56
|
-
<w:r w:rsidR="00BE47B1" w:rsidRPr="00BE47B1">
|
57
|
-
<w:rPr><w:b/></w:rPr>
|
58
|
-
<w:fldChar w:fldCharType="end"/>
|
59
|
-
</w:r>
|
60
|
-
<w:r w:rsidR="00BE47B1"><w:t xml:space="preserve">, nice to meet you.</w:t></w:r>
|
61
|
-
documentxml
|
35
|
+
result = process(snippet("complex_field"), {"last_name" => "Zane"})
|
62
36
|
|
63
37
|
assert_equal "Hello! My Name is Zane , nice to meet you.", text(result)
|
64
38
|
assert_xml_equal <<-document, result
|
@@ -72,34 +46,7 @@ class ProcessorTest < Sablon::TestCase
|
|
72
46
|
end
|
73
47
|
|
74
48
|
def test_complex_field_replacement_with_split_field
|
75
|
-
result = process(
|
76
|
-
<w:r>
|
77
|
-
<w:t xml:space="preserve">Hello! My Name is </w:t>
|
78
|
-
</w:r>
|
79
|
-
<w:r w:rsidR="003C4780">
|
80
|
-
<w:fldChar w:fldCharType="begin" />
|
81
|
-
</w:r>
|
82
|
-
<w:r w:rsidR="003C4780">
|
83
|
-
<w:instrText xml:space="preserve"> MERGEFIELD </w:instrText>
|
84
|
-
</w:r>
|
85
|
-
<w:r w:rsidR="003A4504">
|
86
|
-
<w:instrText>=</w:instrText>
|
87
|
-
</w:r>
|
88
|
-
<w:r w:rsidR="003C4780">
|
89
|
-
<w:instrText xml:space="preserve">first_name \\* MERGEFORMAT </w:instrText>
|
90
|
-
</w:r>
|
91
|
-
<w:r w:rsidR="003C4780">
|
92
|
-
<w:fldChar w:fldCharType="separate" />
|
93
|
-
</w:r>
|
94
|
-
<w:r w:rsidR="00441382">
|
95
|
-
<w:rPr><w:noProof /></w:rPr>
|
96
|
-
<w:t>«=person.first_name»</w:t>
|
97
|
-
</w:r>
|
98
|
-
<w:r w:rsidR="003C4780">
|
99
|
-
<w:fldChar w:fldCharType="end" />
|
100
|
-
</w:r>
|
101
|
-
<w:r w:rsidR="00BE47B1"><w:t xml:space="preserve">, nice to meet you.</w:t></w:r>
|
102
|
-
documentxml
|
49
|
+
result = process(snippet("edited_complex_field"), {"first_name" => "Daniel"})
|
103
50
|
|
104
51
|
assert_equal "Hello! My Name is Daniel , nice to meet you.", text(result)
|
105
52
|
assert_xml_equal <<-document, result
|
@@ -113,69 +60,7 @@ class ProcessorTest < Sablon::TestCase
|
|
113
60
|
end
|
114
61
|
|
115
62
|
def test_paragraph_block_replacement
|
116
|
-
result = process(
|
117
|
-
<w:p w14:paraId="6CB29D92" w14:textId="164B70F4" w:rsidR="007F5CDE" w:rsidRDefault="007F5CDE" w:rsidP="007F5CDE">
|
118
|
-
<w:pPr>
|
119
|
-
<w:pStyle w:val="ListParagraph" />
|
120
|
-
<w:numPr>
|
121
|
-
<w:ilvl w:val="0" />
|
122
|
-
<w:numId w:val="1" />
|
123
|
-
</w:numPr>
|
124
|
-
</w:pPr>
|
125
|
-
<w:fldSimple w:instr=" MERGEFIELD technologies:each(technology) \\* MERGEFORMAT ">
|
126
|
-
<w:r>
|
127
|
-
<w:rPr><w:noProof /></w:rPr>
|
128
|
-
<w:t>«technologies:each(technology)»</w:t>
|
129
|
-
</w:r>
|
130
|
-
</w:fldSimple>
|
131
|
-
</w:p>
|
132
|
-
<w:p w14:paraId="1081E316" w14:textId="3EAB5FDC" w:rsidR="00380EE8" w:rsidRDefault="00380EE8" w:rsidP="007F5CDE">
|
133
|
-
<w:pPr>
|
134
|
-
<w:pStyle w:val="ListParagraph" />
|
135
|
-
<w:numPr>
|
136
|
-
<w:ilvl w:val="0" />
|
137
|
-
<w:numId w:val="1" />
|
138
|
-
</w:numPr>
|
139
|
-
</w:pPr>
|
140
|
-
<w:r>
|
141
|
-
<w:fldChar w:fldCharType="begin" />
|
142
|
-
</w:r>
|
143
|
-
<w:r>
|
144
|
-
<w:instrText xml:space="preserve"> </w:instrText>
|
145
|
-
</w:r>
|
146
|
-
<w:r w:rsidR="009F01DA">
|
147
|
-
<w:instrText>MERGEFIELD =technology</w:instrText>
|
148
|
-
</w:r>
|
149
|
-
<w:r>
|
150
|
-
<w:instrText xml:space="preserve"> \\* MERGEFORMAT </w:instrText>
|
151
|
-
</w:r>
|
152
|
-
<w:r>
|
153
|
-
<w:fldChar w:fldCharType="separate" />
|
154
|
-
</w:r>
|
155
|
-
<w:r w:rsidR="009F01DA">
|
156
|
-
<w:rPr><w:noProof /></w:rPr>
|
157
|
-
<w:t>«=technology»</w:t>
|
158
|
-
</w:r>
|
159
|
-
<w:r>
|
160
|
-
<w:fldChar w:fldCharType="end" />
|
161
|
-
</w:r>
|
162
|
-
</w:p>
|
163
|
-
<w:p w14:paraId="7F936853" w14:textId="078377AD" w:rsidR="00380EE8" w:rsidRPr="007F5CDE" w:rsidRDefault="00380EE8" w:rsidP="007F5CDE">
|
164
|
-
<w:pPr>
|
165
|
-
<w:pStyle w:val="ListParagraph" />
|
166
|
-
<w:numPr>
|
167
|
-
<w:ilvl w:val="0" />
|
168
|
-
<w:numId w:val="1" />
|
169
|
-
</w:numPr>
|
170
|
-
</w:pPr>
|
171
|
-
<w:fldSimple w:instr=" MERGEFIELD technologies:endEach \\* MERGEFORMAT ">
|
172
|
-
<w:r>
|
173
|
-
<w:rPr><w:noProof /></w:rPr>
|
174
|
-
<w:t>«technologies:endEach»</w:t>
|
175
|
-
</w:r>
|
176
|
-
</w:fldSimple>
|
177
|
-
</w:p>
|
178
|
-
document
|
63
|
+
result = process(snippet("paragraph_loop"), {"technologies" => ["Ruby", "Rails"]})
|
179
64
|
|
180
65
|
assert_equal "Ruby Rails", text(result)
|
181
66
|
assert_xml_equal <<-document, result
|
@@ -208,41 +93,7 @@ class ProcessorTest < Sablon::TestCase
|
|
208
93
|
end
|
209
94
|
|
210
95
|
def test_paragraph_block_within_table_cell
|
211
|
-
result = process(
|
212
|
-
<w:tbl>
|
213
|
-
<w:tblGrid>
|
214
|
-
<w:gridCol w:w="2202"/>
|
215
|
-
</w:tblGrid>
|
216
|
-
<w:tr w:rsidR="00757DAD">
|
217
|
-
<w:tc>
|
218
|
-
<w:p>
|
219
|
-
<w:fldSimple w:instr=" MERGEFIELD technologies:each(technology) \\* MERGEFORMAT ">
|
220
|
-
<w:r w:rsidR="004B49F0">
|
221
|
-
<w:rPr><w:noProof/></w:rPr>
|
222
|
-
<w:t>«technologies:each(technology)»</w:t>
|
223
|
-
</w:r>
|
224
|
-
</w:fldSimple>
|
225
|
-
</w:p>
|
226
|
-
<w:p>
|
227
|
-
<w:fldSimple w:instr=" MERGEFIELD =technology \\* MERGEFORMAT ">
|
228
|
-
<w:r w:rsidR="004B49F0">
|
229
|
-
<w:rPr><w:noProof/></w:rPr>
|
230
|
-
<w:t>«=technology»</w:t>
|
231
|
-
</w:r>
|
232
|
-
</w:fldSimple>
|
233
|
-
</w:p>
|
234
|
-
<w:p>
|
235
|
-
<w:fldSimple w:instr=" MERGEFIELD technologies:endEach \\* MERGEFORMAT ">
|
236
|
-
<w:r w:rsidR="004B49F0">
|
237
|
-
<w:rPr><w:noProof/></w:rPr>
|
238
|
-
<w:t>«technologies:endEach»</w:t>
|
239
|
-
</w:r>
|
240
|
-
</w:fldSimple>
|
241
|
-
</w:p>
|
242
|
-
</w:tc>
|
243
|
-
</w:tr>
|
244
|
-
</w:tbl>
|
245
|
-
document
|
96
|
+
result = process(snippet("paragraph_loop_within_table_cell"), {"technologies" => ["Puppet", "Chef"]})
|
246
97
|
|
247
98
|
assert_equal "Puppet Chef", text(result)
|
248
99
|
assert_xml_equal <<-document, result
|
@@ -272,165 +123,7 @@ class ProcessorTest < Sablon::TestCase
|
|
272
123
|
|
273
124
|
def test_single_row_table_loop
|
274
125
|
item = Struct.new(:index, :label, :rating)
|
275
|
-
result = process(
|
276
|
-
<w:tbl>
|
277
|
-
<w:tblPr>
|
278
|
-
<w:tblStyle w:val="TableGrid"/>
|
279
|
-
<w:tblW w:w="0" w:type="auto"/>
|
280
|
-
<w:tblLook w:val="04A0" w:firstRow="1" w:lastRow="0" w:firstColumn="1" w:lastColumn="0" w:noHBand="0" w:noVBand="1"/>
|
281
|
-
</w:tblPr>
|
282
|
-
<w:tblGrid>
|
283
|
-
<w:gridCol w:w="2202"/>
|
284
|
-
<w:gridCol w:w="4285"/>
|
285
|
-
<w:gridCol w:w="2029"/>
|
286
|
-
</w:tblGrid>
|
287
|
-
<w:tr w:rsidR="00757DAD" w14:paraId="229B7A39" w14:textId="77777777" w:rsidTr="006333C3">
|
288
|
-
<w:tc>
|
289
|
-
<w:tcPr>
|
290
|
-
<w:tcW w:w="2202" w:type="dxa"/>
|
291
|
-
</w:tcPr>
|
292
|
-
<w:p w14:paraId="3D472BF1" w14:textId="77777777" w:rsidR="00757DAD" w:rsidRDefault="00757DAD" w:rsidP="006333C3">
|
293
|
-
<w:r>
|
294
|
-
<w:fldChar w:fldCharType="begin"/>
|
295
|
-
</w:r>
|
296
|
-
<w:r>
|
297
|
-
<w:instrText xml:space="preserve"> MERGEFIELD items:each(item) \\* MERGEFORMAT </w:instrText>
|
298
|
-
</w:r>
|
299
|
-
<w:r>
|
300
|
-
<w:fldChar w:fldCharType="separate"/>
|
301
|
-
</w:r>
|
302
|
-
<w:r>
|
303
|
-
<w:rPr><w:noProof/></w:rPr>
|
304
|
-
<w:t>«items:each(item)»</w:t>
|
305
|
-
</w:r>
|
306
|
-
<w:r>
|
307
|
-
<w:fldChar w:fldCharType="end"/>
|
308
|
-
</w:r>
|
309
|
-
</w:p>
|
310
|
-
</w:tc>
|
311
|
-
<w:tc>
|
312
|
-
<w:tcPr>
|
313
|
-
<w:tcW w:w="4285" w:type="dxa"/>
|
314
|
-
</w:tcPr>
|
315
|
-
<w:p w14:paraId="6E6D8DB2" w14:textId="77777777" w:rsidR="00757DAD" w:rsidRDefault="00757DAD" w:rsidP="006333C3"/>
|
316
|
-
</w:tc>
|
317
|
-
<w:tc>
|
318
|
-
<w:tcPr>
|
319
|
-
<w:tcW w:w="2029" w:type="dxa"/>
|
320
|
-
</w:tcPr>
|
321
|
-
<w:p w14:paraId="7BE1DB00" w14:textId="77777777" w:rsidR="00757DAD" w:rsidRDefault="00757DAD" w:rsidP="006333C3"/>
|
322
|
-
</w:tc>
|
323
|
-
</w:tr>
|
324
|
-
<w:tr w:rsidR="00757DAD" w14:paraId="1BD2E50A" w14:textId="77777777" w:rsidTr="006333C3">
|
325
|
-
<w:tc>
|
326
|
-
<w:tcPr>
|
327
|
-
<w:tcW w:w="2202" w:type="dxa"/>
|
328
|
-
</w:tcPr>
|
329
|
-
<w:p w14:paraId="41ACB3D9" w14:textId="77777777" w:rsidR="00757DAD" w:rsidRDefault="00757DAD" w:rsidP="006333C3">
|
330
|
-
<w:r>
|
331
|
-
<w:fldChar w:fldCharType="begin"/>
|
332
|
-
</w:r>
|
333
|
-
<w:r>
|
334
|
-
<w:instrText xml:space="preserve"> MERGEFIELD =item.index \\* MERGEFORMAT </w:instrText>
|
335
|
-
</w:r>
|
336
|
-
<w:r>
|
337
|
-
<w:fldChar w:fldCharType="separate"/>
|
338
|
-
</w:r>
|
339
|
-
<w:r>
|
340
|
-
<w:rPr><w:noProof/></w:rPr>
|
341
|
-
<w:t>«=item.index»</w:t>
|
342
|
-
</w:r>
|
343
|
-
<w:r>
|
344
|
-
<w:fldChar w:fldCharType="end"/>
|
345
|
-
</w:r>
|
346
|
-
</w:p>
|
347
|
-
</w:tc>
|
348
|
-
<w:tc>
|
349
|
-
<w:tcPr>
|
350
|
-
<w:tcW w:w="4285" w:type="dxa"/>
|
351
|
-
</w:tcPr>
|
352
|
-
<w:p w14:paraId="197C6F31" w14:textId="77777777" w:rsidR="00757DAD" w:rsidRDefault="00757DAD" w:rsidP="006333C3">
|
353
|
-
<w:r>
|
354
|
-
<w:fldChar w:fldCharType="begin"/>
|
355
|
-
</w:r>
|
356
|
-
<w:r>
|
357
|
-
<w:instrText xml:space="preserve"> MERGEFIELD =item.label \\* MERGEFORMAT </w:instrText>
|
358
|
-
</w:r>
|
359
|
-
<w:r>
|
360
|
-
<w:fldChar w:fldCharType="separate"/>
|
361
|
-
</w:r>
|
362
|
-
<w:r>
|
363
|
-
<w:rPr><w:noProof/></w:rPr>
|
364
|
-
<w:t>«=item.label»</w:t>
|
365
|
-
</w:r>
|
366
|
-
<w:r>
|
367
|
-
<w:fldChar w:fldCharType="end"/>
|
368
|
-
</w:r>
|
369
|
-
</w:p>
|
370
|
-
</w:tc>
|
371
|
-
<w:tc>
|
372
|
-
<w:tcPr>
|
373
|
-
<w:tcW w:w="2029" w:type="dxa"/>
|
374
|
-
</w:tcPr>
|
375
|
-
<w:p w14:paraId="55C258BB" w14:textId="77777777" w:rsidR="00757DAD" w:rsidRDefault="00757DAD" w:rsidP="006333C3">
|
376
|
-
<w:r>
|
377
|
-
<w:fldChar w:fldCharType="begin"/>
|
378
|
-
</w:r>
|
379
|
-
<w:r>
|
380
|
-
<w:instrText xml:space="preserve"> MERGEFIELD =item.rating \\* MERGEFORMAT </w:instrText>
|
381
|
-
</w:r>
|
382
|
-
<w:r>
|
383
|
-
<w:fldChar w:fldCharType="separate"/>
|
384
|
-
</w:r>
|
385
|
-
<w:r>
|
386
|
-
<w:rPr><w:noProof/></w:rPr>
|
387
|
-
<w:t>«=item.rating»</w:t>
|
388
|
-
</w:r>
|
389
|
-
<w:r>
|
390
|
-
<w:fldChar w:fldCharType="end"/>
|
391
|
-
</w:r>
|
392
|
-
</w:p>
|
393
|
-
</w:tc>
|
394
|
-
</w:tr>
|
395
|
-
<w:tr w:rsidR="00757DAD" w14:paraId="2D3C09BC" w14:textId="77777777" w:rsidTr="006333C3">
|
396
|
-
<w:tc>
|
397
|
-
<w:tcPr>
|
398
|
-
<w:tcW w:w="2202" w:type="dxa"/>
|
399
|
-
</w:tcPr>
|
400
|
-
<w:p w14:paraId="04A961B7" w14:textId="77777777" w:rsidR="00757DAD" w:rsidRDefault="00757DAD" w:rsidP="006333C3">
|
401
|
-
<w:r>
|
402
|
-
<w:fldChar w:fldCharType="begin"/>
|
403
|
-
</w:r>
|
404
|
-
<w:r>
|
405
|
-
<w:instrText xml:space="preserve"> MERGEFIELD items:endEach \\* MERGEFORMAT </w:instrText>
|
406
|
-
</w:r>
|
407
|
-
<w:r>
|
408
|
-
<w:fldChar w:fldCharType="separate"/>
|
409
|
-
</w:r>
|
410
|
-
<w:r>
|
411
|
-
<w:rPr><w:noProof/></w:rPr>
|
412
|
-
<w:t>«items:endEach»</w:t>
|
413
|
-
</w:r>
|
414
|
-
<w:r>
|
415
|
-
<w:fldChar w:fldCharType="end"/>
|
416
|
-
</w:r>
|
417
|
-
</w:p>
|
418
|
-
</w:tc>
|
419
|
-
<w:tc>
|
420
|
-
<w:tcPr>
|
421
|
-
<w:tcW w:w="4285" w:type="dxa"/>
|
422
|
-
</w:tcPr>
|
423
|
-
<w:p w14:paraId="71165BFB" w14:textId="77777777" w:rsidR="00757DAD" w:rsidRDefault="00757DAD" w:rsidP="006333C3"/>
|
424
|
-
</w:tc>
|
425
|
-
<w:tc>
|
426
|
-
<w:tcPr>
|
427
|
-
<w:tcW w:w="2029" w:type="dxa"/>
|
428
|
-
</w:tcPr>
|
429
|
-
<w:p w14:paraId="01D3965C" w14:textId="77777777" w:rsidR="00757DAD" w:rsidRDefault="00757DAD" w:rsidP="006333C3"/>
|
430
|
-
</w:tc>
|
431
|
-
</w:tr>
|
432
|
-
</w:tbl>
|
433
|
-
document
|
126
|
+
result = process(snippet("table_row_loop"), {"items" => [item.new("1.", "Milk", "***"), item.new("2.", "Sugar", "**")]})
|
434
127
|
|
435
128
|
assert_xml_equal <<-document, result
|
436
129
|
<w:tbl>
|
@@ -518,202 +211,49 @@ class ProcessorTest < Sablon::TestCase
|
|
518
211
|
document
|
519
212
|
end
|
520
213
|
|
214
|
+
def test_loop_with_missing_variable_raises_error
|
215
|
+
e = assert_raises Sablon::ContextError do
|
216
|
+
process(snippet("paragraph_loop"), {})
|
217
|
+
end
|
218
|
+
assert_equal "The expression «technologies» should evaluate to an enumerable but was: nil", e.message
|
219
|
+
end
|
220
|
+
|
221
|
+
def test_loop_with_missing_end_raises_error
|
222
|
+
e = assert_raises Sablon::TemplateError do
|
223
|
+
process(snippet("loop_without_ending"), {})
|
224
|
+
end
|
225
|
+
assert_equal "Could not find end field for «technologies:each(technology)». Was looking for «technologies:endEach»", e.message
|
226
|
+
end
|
227
|
+
|
228
|
+
def test_conditional_with_missing_end_raises_error
|
229
|
+
e = assert_raises Sablon::TemplateError do
|
230
|
+
process(snippet("conditional_without_ending"), {})
|
231
|
+
end
|
232
|
+
assert_equal "Could not find end field for «middle_name:if». Was looking for «middle_name:endIf»", e.message
|
233
|
+
end
|
234
|
+
|
521
235
|
def test_multi_row_table_loop
|
522
236
|
item = Struct.new(:index, :label, :body)
|
523
237
|
context = {"foods" => [item.new("1.", "Milk", "Milk is a white liquid."),
|
524
238
|
item.new("2.", "Sugar", "Sugar is the generalized name for carbohydrates.")]}
|
525
|
-
result = process(
|
526
|
-
<w:tbl>
|
527
|
-
<w:tr w:rsidR="00F23752" w14:paraId="3FF89DEC" w14:textId="77777777" w:rsidTr="00213ACD">
|
528
|
-
<w:tc>
|
529
|
-
<w:tcPr>
|
530
|
-
<w:tcW w:w="2235" w:type="dxa" />
|
531
|
-
<w:shd w:val="clear" w:color="auto" w:fill="auto" />
|
532
|
-
</w:tcPr>
|
533
|
-
<w:p w14:paraId="7630A6C6" w14:textId="699D0C71" w:rsidR="00F23752" w:rsidRDefault="00F23752" w:rsidP="003F16E3">
|
534
|
-
<w:fldSimple w:instr=" MERGEFIELD foods:each(food) \\* MERGEFORMAT ">
|
535
|
-
<w:r w:rsidR="00213ACD">
|
536
|
-
<w:rPr><w:noProof /></w:rPr>
|
537
|
-
<w:t>«foods:each(food)»</w:t>
|
538
|
-
</w:r>
|
539
|
-
</w:fldSimple>
|
540
|
-
</w:p>
|
541
|
-
</w:tc>
|
542
|
-
<w:tc>
|
543
|
-
<w:tcPr>
|
544
|
-
<w:tcW w:w="6287" w:type="dxa" />
|
545
|
-
<w:shd w:val="clear" w:color="auto" w:fill="auto" />
|
546
|
-
</w:tcPr>
|
547
|
-
<w:p w14:paraId="437AFC74" w14:textId="77777777" w:rsidR="00F23752" w:rsidRDefault="00F23752" w:rsidP="003F16E3" />
|
548
|
-
</w:tc>
|
549
|
-
</w:tr>
|
550
|
-
<w:tr w:rsidR="00F23752" w14:paraId="320AE02B" w14:textId="77777777" w:rsidTr="00213ACD">
|
551
|
-
<w:tc>
|
552
|
-
<w:tcPr>
|
553
|
-
<w:tcW w:w="2235" w:type="dxa" />
|
554
|
-
<w:shd w:val="clear" w:color="auto" w:fill="8DB3E2" w:themeFill="text2" w:themeFillTint="66" />
|
555
|
-
</w:tcPr>
|
556
|
-
<w:p w14:paraId="3FCF3855" w14:textId="38FA7F3B" w:rsidR="00F23752" w:rsidRDefault="00F23752" w:rsidP="00F23752">
|
557
|
-
<w:fldSimple w:instr=" MERGEFIELD =food.index \\* MERGEFORMAT ">
|
558
|
-
<w:r w:rsidR="00213ACD">
|
559
|
-
<w:rPr><w:noProof /></w:rPr>
|
560
|
-
<w:t>«=food.index»</w:t>
|
561
|
-
</w:r>
|
562
|
-
</w:fldSimple>
|
563
|
-
</w:p>
|
564
|
-
</w:tc>
|
565
|
-
<w:tc>
|
566
|
-
<w:tcPr>
|
567
|
-
<w:tcW w:w="6287" w:type="dxa" />
|
568
|
-
<w:shd w:val="clear" w:color="auto" w:fill="8DB3E2" w:themeFill="text2" w:themeFillTint="66" />
|
569
|
-
</w:tcPr>
|
570
|
-
<w:p w14:paraId="0BB0E74E" w14:textId="4FA0D282" w:rsidR="00F23752" w:rsidRPr="00F576DA" w:rsidRDefault="00F23752" w:rsidP="00F23752">
|
571
|
-
<w:r w:rsidRPr="00F576DA">
|
572
|
-
<w:fldChar w:fldCharType="begin" />
|
573
|
-
</w:r>
|
574
|
-
<w:r w:rsidRPr="00F576DA">
|
575
|
-
<w:instrText xml:space="preserve"> MERGEFIELD =</w:instrText>
|
576
|
-
</w:r>
|
577
|
-
<w:r>
|
578
|
-
<w:instrText>food</w:instrText>
|
579
|
-
</w:r>
|
580
|
-
<w:r w:rsidRPr="00F576DA">
|
581
|
-
<w:instrText xml:space="preserve">.label \\* MERGEFORMAT </w:instrText>
|
582
|
-
</w:r>
|
583
|
-
<w:r w:rsidRPr="00F576DA">
|
584
|
-
<w:fldChar w:fldCharType="separate" />
|
585
|
-
</w:r>
|
586
|
-
<w:r w:rsidR="00213ACD">
|
587
|
-
<w:rPr>
|
588
|
-
<w:rFonts w:ascii="Comic Sans MS" w:hAnsi="Comic Sans MS" />
|
589
|
-
<w:noProof />
|
590
|
-
</w:rPr>
|
591
|
-
<w:t>«=food.label»</w:t>
|
592
|
-
</w:r>
|
593
|
-
<w:r w:rsidRPr="00F576DA">
|
594
|
-
<w:fldChar w:fldCharType="end" />
|
595
|
-
</w:r>
|
596
|
-
</w:p>
|
597
|
-
</w:tc>
|
598
|
-
</w:tr>
|
599
|
-
<w:tr w:rsidR="00213ACD" w14:paraId="1EA188ED" w14:textId="77777777" w:rsidTr="00213ACD">
|
600
|
-
<w:tc>
|
601
|
-
<w:tcPr>
|
602
|
-
<w:tcW w:w="8522" w:type="dxa" />
|
603
|
-
<w:gridSpan w:val="2" />
|
604
|
-
<w:shd w:val="clear" w:color="auto" w:fill="auto" />
|
605
|
-
</w:tcPr>
|
606
|
-
<w:p w14:paraId="3E9FF163" w14:textId="0F37CDFB" w:rsidR="00213ACD" w:rsidRDefault="00213ACD" w:rsidP="003F16E3">
|
607
|
-
<w:fldSimple w:instr=" MERGEFIELD =food.body \\* MERGEFORMAT ">
|
608
|
-
<w:r>
|
609
|
-
<w:rPr><w:noProof /></w:rPr>
|
610
|
-
<w:t>«=food.body»</w:t>
|
611
|
-
</w:r>
|
612
|
-
</w:fldSimple>
|
613
|
-
</w:p>
|
614
|
-
</w:tc>
|
615
|
-
</w:tr>
|
616
|
-
<w:tr w:rsidR="00213ACD" w14:paraId="34315A41" w14:textId="77777777" w:rsidTr="00213ACD">
|
617
|
-
<w:tc>
|
618
|
-
<w:tcPr>
|
619
|
-
<w:tcW w:w="2235" w:type="dxa" />
|
620
|
-
<w:shd w:val="clear" w:color="auto" w:fill="auto" />
|
621
|
-
</w:tcPr>
|
622
|
-
<w:p w14:paraId="1CA83F76" w14:textId="2622C490" w:rsidR="00213ACD" w:rsidRDefault="00213ACD" w:rsidP="003F16E3">
|
623
|
-
<w:r>
|
624
|
-
<w:fldChar w:fldCharType="begin" />
|
625
|
-
</w:r>
|
626
|
-
<w:r>
|
627
|
-
<w:instrText xml:space="preserve"> MERGEFIELD foods:endEach \\* MERGEFORMAT </w:instrText>
|
628
|
-
</w:r>
|
629
|
-
<w:r>
|
630
|
-
<w:fldChar w:fldCharType="separate" />
|
631
|
-
</w:r>
|
632
|
-
<w:r>
|
633
|
-
<w:rPr><w:noProof /></w:rPr>
|
634
|
-
<w:t>«foods:endEach»</w:t>
|
635
|
-
</w:r>
|
636
|
-
<w:r>
|
637
|
-
<w:fldChar w:fldCharType="end" />
|
638
|
-
</w:r>
|
639
|
-
</w:p>
|
640
|
-
</w:tc>
|
641
|
-
<w:tc>
|
642
|
-
<w:tcPr>
|
643
|
-
<w:tcW w:w="6287" w:type="dxa" />
|
644
|
-
<w:shd w:val="clear" w:color="auto" w:fill="auto" />
|
645
|
-
</w:tcPr>
|
646
|
-
<w:p w14:paraId="7D976602" w14:textId="77777777" w:rsidR="00213ACD" w:rsidRDefault="00213ACD" w:rsidP="003F16E3" />
|
647
|
-
</w:tc>
|
648
|
-
</w:tr>
|
649
|
-
</w:tbl>
|
650
|
-
document
|
239
|
+
result = process(snippet("table_multi_row_loop"), context)
|
651
240
|
|
652
241
|
assert_equal "1. Milk Milk is a white liquid. 2. Sugar Sugar is the generalized name for carbohydrates.", text(result)
|
653
242
|
end
|
654
243
|
|
655
244
|
def test_conditional
|
656
|
-
|
657
|
-
<w:r><w:t xml:space="preserve">Anthony</w:t></w:r>
|
658
|
-
<w:p>
|
659
|
-
<w:fldSimple w:instr=" MERGEFIELD middle_name:if \\* MERGEFORMAT ">
|
660
|
-
<w:r>
|
661
|
-
<w:rPr><w:noProof/></w:rPr>
|
662
|
-
<w:t>«middle_name:if»</w:t>
|
663
|
-
</w:r>
|
664
|
-
</w:fldSimple>
|
665
|
-
</w:p>
|
666
|
-
<w:p>
|
667
|
-
<w:fldSimple w:instr=" MERGEFIELD =middle_name \\* MERGEFORMAT ">
|
668
|
-
<w:r>
|
669
|
-
<w:rPr><w:noProof/></w:rPr>
|
670
|
-
<w:t>«=middle_name»</w:t>
|
671
|
-
</w:r>
|
672
|
-
</w:fldSimple>
|
673
|
-
</w:p>
|
674
|
-
<w:p>
|
675
|
-
<w:fldSimple w:instr=" MERGEFIELD middle_name:endIf \\* MERGEFORMAT ">
|
676
|
-
<w:r>
|
677
|
-
<w:rPr><w:noProof/></w:rPr>
|
678
|
-
<w:t>«middle_name:endIf»</w:t>
|
679
|
-
</w:r>
|
680
|
-
</w:fldSimple>
|
681
|
-
</w:p>
|
682
|
-
<w:r><w:t xml:space="preserve">Hall</w:t></w:r>
|
683
|
-
documentxml
|
684
|
-
result = process(document, {"middle_name" => "Michael"})
|
245
|
+
result = process(snippet("conditional"), {"middle_name" => "Michael"})
|
685
246
|
assert_equal "Anthony Michael Hall", text(result)
|
686
247
|
|
687
|
-
result = process(
|
248
|
+
result = process(snippet("conditional"), {"middle_name" => nil})
|
688
249
|
assert_equal "Anthony Hall", text(result)
|
689
250
|
end
|
690
251
|
|
691
252
|
def test_conditional_with_predicate
|
692
|
-
|
693
|
-
<w:p>
|
694
|
-
<w:fldSimple w:instr=" MERGEFIELD body:if(empty?) \\* MERGEFORMAT ">
|
695
|
-
<w:r>
|
696
|
-
<w:rPr><w:noProof/></w:rPr>
|
697
|
-
<w:t>«body:if(empty?)»</w:t>
|
698
|
-
</w:r>
|
699
|
-
</w:fldSimple>
|
700
|
-
</w:p>
|
701
|
-
<w:p>
|
702
|
-
<w:t>some content</w:t>
|
703
|
-
</w:p>
|
704
|
-
<w:p>
|
705
|
-
<w:fldSimple w:instr=" MERGEFIELD body:endIf \\* MERGEFORMAT ">
|
706
|
-
<w:r>
|
707
|
-
<w:rPr><w:noProof/></w:rPr>
|
708
|
-
<w:t>«body:endIf»</w:t>
|
709
|
-
</w:r>
|
710
|
-
</w:fldSimple>
|
711
|
-
</w:p>
|
712
|
-
documentxml
|
713
|
-
result = process(document, {"body" => ""})
|
253
|
+
result = process(snippet("conditional_with_predicate"), {"body" => ""})
|
714
254
|
assert_equal "some content", text(result)
|
715
255
|
|
716
|
-
result = process(
|
256
|
+
result = process(snippet("conditional_with_predicate"), {"body" => "not empty"})
|
717
257
|
assert_equal "", text(result)
|
718
258
|
end
|
719
259
|
|