ad_hoc_template 0.0.1 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,399 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'spec_helper'
4
+ require 'ad_hoc_template'
5
+
6
+ describe AdHocTemplate do
7
+ describe AdHocTemplate::Parser do
8
+ describe "with the default tag type" do
9
+ it "returns a tree of TagNode and Leaf" do
10
+ expect(AdHocTemplate::Parser.parse("a test string with tags (<% the first tag %> and <% the second tag %>) in it")).to eq([["a test string with tags ("],
11
+ [[" the first tag "]],
12
+ [" and "],
13
+ [[" the second tag "]],
14
+ [") in it"]])
15
+ end
16
+
17
+ it "allows to have a nested tag" do
18
+ expect(AdHocTemplate::Parser.parse("a test string with a nested tag; <% an outer tag and <% an inner tag %> %>")).to eq([["a test string with a nested tag; "],
19
+ [[" an outer tag and "],
20
+ [[" an inner tag "]],
21
+ [" "]]])
22
+ end
23
+
24
+ it "may have iteration tags." do
25
+ tree = AdHocTemplate::Parser.parse("a test string with a nested tag: <%# an iteration tag and <% an inner tag %> #%> and <% another tag %>")
26
+ expect(tree).to eq([["a test string with a nested tag: "],
27
+ [[" an iteration tag and "],
28
+ [[" an inner tag "]],
29
+ [" "]],
30
+ [" and "],
31
+ [[" another tag "]]])
32
+ expect(tree[1]).to be_a_kind_of(AdHocTemplate::Parser::IterationTagNode)
33
+ end
34
+
35
+ it "may contain lines that consist only of an iteration tag" do
36
+ tree = AdHocTemplate::Parser.parse("<%#iterations
37
+ content
38
+ #%>
39
+ ")
40
+ expect(tree).to eq([[["content\n"]]])
41
+ end
42
+
43
+ it "must return an empty array when template is an empty string" do
44
+ tree = AdHocTemplate::Parser.parse("")
45
+ expect(tree).to eq([])
46
+ end
47
+
48
+
49
+ it "does not remove indents from the lines which contain only iteration tag" do
50
+ template_without_indent = <<TEMPLATE_WITHOUT_INDENT
51
+ A template with an iteration tag
52
+
53
+ <%#
54
+ This part will be repeated with <!--% variable %-->
55
+ #%>
56
+
57
+ TEMPLATE_WITHOUT_INDENT
58
+
59
+ template_with_indent = <<TEMPLATE
60
+ A template with an iteration tag
61
+
62
+ <%#
63
+ This part will be repeated with <!--% variable %-->
64
+ #%>
65
+
66
+ TEMPLATE
67
+
68
+ without_indent = AdHocTemplate::Parser.parse(template_without_indent)
69
+ with_indent = AdHocTemplate::Parser.parse(template_with_indent)
70
+
71
+ expect(with_indent).not_to eq(without_indent)
72
+ end
73
+ end
74
+
75
+ describe "with the square brackets tag type" do
76
+ it "returns a tree of TagNode and Leaf" do
77
+ expect(AdHocTemplate::Parser.parse("a test string with tags ([[ the first tag ]] and [[ the second tag ]]) in it", :square_brackets)).to eq([["a test string with tags ("],
78
+ [[" the first tag "]],
79
+ [" and "],
80
+ [[" the second tag "]],
81
+ [") in it"]])
82
+ end
83
+
84
+ it "allows to have a nested tag" do
85
+ expect(AdHocTemplate::Parser.parse("a test string with a nested tag; [[ an outer tag and [[ an inner tag ]] ]]", :square_brackets)).to eq([["a test string with a nested tag; "],
86
+ [[" an outer tag and "],
87
+ [[" an inner tag "]],
88
+ [" "]]])
89
+ end
90
+
91
+ it "may have iteration tags." do
92
+ tree = AdHocTemplate::Parser.parse("a test string with a nested tag: [[# an iteration tag and [[ an inner tag ]] #]] and [[ another tag ]]", :square_brackets)
93
+ expect(tree).to eq([["a test string with a nested tag: "],
94
+ [[" an iteration tag and "],
95
+ [[" an inner tag "]],
96
+ [" "]],
97
+ [" and "],
98
+ [[" another tag "]]])
99
+ expect(tree[1]).to be_a_kind_of(AdHocTemplate::Parser::IterationTagNode)
100
+ end
101
+
102
+ it "may contain lines that consist only of an iteration tag" do
103
+ tree = AdHocTemplate::Parser.parse("[[#iterations
104
+ content
105
+ #]]
106
+ ", :square_brackets)
107
+ expect(tree).to eq([[["content\n"]]])
108
+ end
109
+
110
+ it "must return an empty array when template is an empty string" do
111
+ tree = AdHocTemplate::Parser.parse("", :square_brackets)
112
+ expect(tree).to eq([])
113
+ end
114
+ end
115
+
116
+ describe "with the curly brackets tag type" do
117
+ it "returns a tree of TagNode and Leaf" do
118
+ expect(AdHocTemplate::Parser.parse("a test string with tags ({{ the first tag }} and {{ the second tag }}) in it", :curly_brackets)).to eq([["a test string with tags ("],
119
+ [[" the first tag "]],
120
+ [" and "],
121
+ [[" the second tag "]],
122
+ [") in it"]])
123
+ end
124
+
125
+ it "allows to have a nested tag" do
126
+ expect(AdHocTemplate::Parser.parse("a test string with a nested tag; {{ an outer tag and {{ an inner tag }} }}", :curly_brackets)).to eq([["a test string with a nested tag; "],
127
+ [[" an outer tag and "],
128
+ [[" an inner tag "]],
129
+ [" "]]])
130
+ end
131
+
132
+ it "may have iteration tags." do
133
+ tree = AdHocTemplate::Parser.parse("a test string with a nested tag: {{# an iteration tag and {{ an inner tag }} #}} and {{ another tag }}", :curly_brackets)
134
+ expect(tree).to eq([["a test string with a nested tag: "],
135
+ [[" an iteration tag and "],
136
+ [[" an inner tag "]],
137
+ [" "]],
138
+ [" and "],
139
+ [[" another tag "]]])
140
+ expect(tree[1]).to be_a_kind_of(AdHocTemplate::Parser::IterationTagNode)
141
+ end
142
+
143
+ it "may contain lines that consist only of an iteration tag" do
144
+ tree = AdHocTemplate::Parser.parse("{{#iterations
145
+ content
146
+ #}}
147
+ ", :curly_brackets)
148
+ expect(tree).to eq([[["content\n"]]])
149
+ end
150
+
151
+ it "must return an empty array when template is an empty string" do
152
+ tree = AdHocTemplate::Parser.parse("", :curly_brackets)
153
+ expect(tree).to eq([])
154
+ end
155
+ end
156
+
157
+ it("spaces at the head of a line should be preserved when the line is just after a start tag of IterationTagNode") do
158
+ tree = AdHocTemplate::Parser.parse("<%#iteration\n the second line\nthe third line")
159
+ expect(tree).to eq([[[" the second line\nthe third line"]]])
160
+ end
161
+
162
+ it("should not add a newline at the head of IterationTagNode when the type of the node is not specified") do
163
+ tree = AdHocTemplate::Parser.parse("a test string with tags\n<%#iteration_block\nthe value of sub_key1 is <%= sub_key1 %>.\n<%#\n the value of sub_key2 is <%= sub_key2 %>.\n#%>\n#%>")
164
+ expect(tree).to eq([["a test string with tags\n"], [["the value of sub_key1 is "], [["sub_key1 "]], [".\n"], [[" the value of sub_key2 is "], [["sub_key2 "]], [".\n"]]]])
165
+ end
166
+
167
+ describe "with the xml_like1 tag type" do
168
+ it "returns a tree of TagNode and Leaf" do
169
+ expect(AdHocTemplate::Parser.parse("a test string with tags (<!--% the first tag %--> and <!--% the second tag %-->) in it", :xml_like1)).to eq([["a test string with tags ("],
170
+ [[" the first tag "]],
171
+ [" and "],
172
+ [[" the second tag "]],
173
+ [") in it"]])
174
+ end
175
+
176
+ it "allows to have a nested tag" do
177
+ expect(AdHocTemplate::Parser.parse("a test string with a nested tag; <!--% an outer tag and <!--% an inner tag %--> %-->", :xml_like1)).to eq([["a test string with a nested tag; "],
178
+ [[" an outer tag and "],
179
+ [[" an inner tag "]],
180
+ [" "]]])
181
+ end
182
+
183
+ it "may have iteration tags." do
184
+ tree = AdHocTemplate::Parser.parse("a test string with a nested tag: <iterate> an iteration tag and <!--% an inner tag %--> </iterate> and <!--% another tag %-->", :xml_like1)
185
+ expect(tree).to eq([["a test string with a nested tag: "],
186
+ [[" an iteration tag and "],
187
+ [[" an inner tag "]],
188
+ [" "]],
189
+ [" and "],
190
+ [[" another tag "]]])
191
+ expect(tree[1]).to be_a_kind_of(AdHocTemplate::Parser::IterationTagNode)
192
+ end
193
+
194
+ it "may contain lines that consist only of an iteration tag" do
195
+ tree = AdHocTemplate::Parser.parse("<iterate>iterations
196
+ content
197
+ </iterate>
198
+ ", :xml_like1)
199
+ expect(tree).to eq([[["content\n"]]])
200
+ end
201
+
202
+ it "must return an empty array when template is an empty string" do
203
+ tree = AdHocTemplate::Parser.parse("", :xml_like1)
204
+ expect(tree).to eq([])
205
+ end
206
+
207
+ it("spaces at the head of a line should be preserved when the line is just after a start tag of IterationTagNode") do
208
+ tree = AdHocTemplate::Parser.parse("<iterate>iteration\n the second line\nthe third line</iterate>", :xml_like1)
209
+ expect(tree).to eq([[[" the second line\nthe third line"]]])
210
+ end
211
+
212
+ it("should not add a newline at the head of IterationTagNode when the type of the node is not specified") do
213
+ tree = AdHocTemplate::Parser.parse("a test string with tags\n<iterate>iteration_block\nthe value of sub_key1 is <!--%= sub_key1 %-->.\n<iterate>\n the value of sub_key2 is <!--%= sub_key2 %-->.\n</iterate>\n</iterate>", :xml_like1)
214
+ expect(tree).to eq([["a test string with tags\n"], [["the value of sub_key1 is "], [["sub_key1 "]], [".\n"], [[" the value of sub_key2 is "], [["sub_key2 "]], [".\n"]]]])
215
+ end
216
+
217
+ it "removes indents from the lines which contain only iteration tag" do
218
+ template_without_indent = <<TEMPLATE_WITHOUT_INDENT
219
+ A template with an iteration tag
220
+
221
+ <iterate>
222
+ This part will be repeated with <!--% variable %-->
223
+ </iterate>
224
+
225
+ TEMPLATE_WITHOUT_INDENT
226
+
227
+ template_with_indent = <<TEMPLATE
228
+ A template with an iteration tag
229
+
230
+ <iterate>
231
+ This part will be repeated with <!--% variable %-->
232
+ </iterate>
233
+
234
+ TEMPLATE
235
+
236
+ without_indent = AdHocTemplate::Parser.parse(template_without_indent, :xml_like1)
237
+ with_indent = AdHocTemplate::Parser.parse(template_with_indent, :xml_like1)
238
+
239
+ expect(with_indent).to eq(without_indent)
240
+ end
241
+ end
242
+
243
+ describe "with the xml_like2 tag type" do
244
+ it "returns a tree of TagNode and Leaf" do
245
+ expect(AdHocTemplate::Parser.parse("a test string with tags (<fill> the first tag </fill> and <fill> the second tag </fill>) in it", :xml_like2)).to eq([["a test string with tags ("],
246
+ [[" the first tag "]],
247
+ [" and "],
248
+ [[" the second tag "]],
249
+ [") in it"]])
250
+ end
251
+
252
+ it "allows to have a nested tag" do
253
+ expect(AdHocTemplate::Parser.parse("a test string with a nested tag; <fill> an outer tag and <fill> an inner tag </fill> </fill>", :xml_like2)).to eq([["a test string with a nested tag; "],
254
+ [[" an outer tag and "],
255
+ [[" an inner tag "]],
256
+ [" "]]])
257
+ end
258
+
259
+ it "may have iteration tags." do
260
+ tree = AdHocTemplate::Parser.parse("a test string with a nested tag: <iterate> an iteration tag and <fill> an inner tag </fill> </iterate> and <fill> another tag </fill>", :xml_like2)
261
+ expect(tree).to eq([["a test string with a nested tag: "],
262
+ [[" an iteration tag and "],
263
+ [[" an inner tag "]],
264
+ [" "]],
265
+ [" and "],
266
+ [[" another tag "]]])
267
+ expect(tree[1]).to be_a_kind_of(AdHocTemplate::Parser::IterationTagNode)
268
+ end
269
+
270
+ it "may contain lines that consist only of an iteration tag" do
271
+ tree = AdHocTemplate::Parser.parse("<iterate>iterations
272
+ content
273
+ </iterate>
274
+ ", :xml_like2)
275
+ expect(tree).to eq([[["content\n"]]])
276
+ end
277
+
278
+ it "must return an empty array when template is an empty string" do
279
+ tree = AdHocTemplate::Parser.parse("", :xml_like2)
280
+ expect(tree).to eq([])
281
+ end
282
+
283
+ it("spaces at the head of a line should be preserved when the line is just after a start tag of IterationTagNode") do
284
+ tree = AdHocTemplate::Parser.parse("<iterate>iteration\n the second line\nthe third line</iterate>", :xml_like2)
285
+ expect(tree).to eq([[[" the second line\nthe third line"]]])
286
+ end
287
+
288
+ it("should not add a newline at the head of IterationTagNode when the type of the node is not specified") do
289
+ tree = AdHocTemplate::Parser.parse("a test string with tags\n<iterate>iteration_block\nthe value of sub_key1 is <fill>= sub_key1 </fill>.\n<iterate>\n the value of sub_key2 is <fill>= sub_key2 </fill>.\n</iterate>\n</iterate>", :xml_like2)
290
+ expect(tree).to eq([["a test string with tags\n"], [["the value of sub_key1 is "], [["sub_key1 "]], [".\n"], [[" the value of sub_key2 is "], [["sub_key2 "]], [".\n"]]]])
291
+ end
292
+ end
293
+
294
+ describe "with the xml_comment_like tag type" do
295
+ it "returns a tree of TagNode and Leaf" do
296
+ expect(AdHocTemplate::Parser.parse("a test string with tags (<!--% the first tag %--> and <!--% the second tag %-->) in it", :xml_comment_like)).to eq([["a test string with tags ("],
297
+ [[" the first tag "]],
298
+ [" and "],
299
+ [[" the second tag "]],
300
+ [") in it"]])
301
+ end
302
+
303
+ it "allows to have a nested tag" do
304
+ expect(AdHocTemplate::Parser.parse("a test string with a nested tag; <!--% an outer tag and <!--% an inner tag %--> %-->", :xml_comment_like)).to eq([["a test string with a nested tag; "],
305
+ [[" an outer tag and "],
306
+ [[" an inner tag "]],
307
+ [" "]]])
308
+ end
309
+
310
+ it "may have iteration tags." do
311
+ tree = AdHocTemplate::Parser.parse("a test string with a nested tag: <!--%iterate%--> an iteration tag and <!--% an inner tag %--> <!--%/iterate%--> and <!--% another tag %-->", :xml_comment_like)
312
+ expect(tree).to eq([["a test string with a nested tag: "],
313
+ [[" an iteration tag and "],
314
+ [[" an inner tag "]],
315
+ [" "]],
316
+ [" and "],
317
+ [[" another tag "]]])
318
+ expect(tree[1]).to be_a_kind_of(AdHocTemplate::Parser::IterationTagNode)
319
+ end
320
+
321
+ it "may contain lines that consist only of an iteration tag" do
322
+ tree = AdHocTemplate::Parser.parse("<!--%iterate%-->iterations
323
+ content
324
+ <!--%/iterate%-->
325
+ ", :xml_comment_like)
326
+ expect(tree).to eq([[["content\n"]]])
327
+ end
328
+
329
+ it "must return an empty array when template is an empty string" do
330
+ tree = AdHocTemplate::Parser.parse("", :xml_comment_like)
331
+ expect(tree).to eq([])
332
+ end
333
+
334
+ it("spaces at the head of a line should be preserved when the line is just after a start tag of IterationTagNode") do
335
+ tree = AdHocTemplate::Parser.parse("<!--%iterate%-->iteration\n the second line\nthe third line<!--%/iterate%-->", :xml_comment_like)
336
+ expect(tree).to eq([[[" the second line\nthe third line"]]])
337
+ end
338
+
339
+ it("should not add a newline at the head of IterationTagNode when the type of the node is not specified") do
340
+ tree = AdHocTemplate::Parser.parse("a test string with tags\n<!--%iterate%-->iteration_block\nthe value of sub_key1 is <!--%= sub_key1 %-->.\n<!--%iterate%-->\n the value of sub_key2 is <!--%= sub_key2 %-->.\n<!--%/iterate%-->\n<!--%/iterate%-->", :xml_comment_like)
341
+ expect(tree).to eq([["a test string with tags\n"], [["the value of sub_key1 is "], [["sub_key1 "]], [".\n"], [[" the value of sub_key2 is "], [["sub_key2 "]], [".\n"]]]])
342
+ end
343
+
344
+ it "removes indents from the lines which contain only iteration tag" do
345
+ template_without_indent = <<TEMPLATE_WITHOUT_INDENT
346
+ A template with an iteration tag
347
+
348
+ <!--%iterate%-->
349
+ This part will be repeated with <!--% variable %-->
350
+ <!--%/iterate%-->
351
+
352
+ TEMPLATE_WITHOUT_INDENT
353
+
354
+ template_with_indent = <<TEMPLATE
355
+ A template with an iteration tag
356
+
357
+ <!--%iterate%-->
358
+ This part will be repeated with <!--% variable %-->
359
+ <!--%/iterate%-->
360
+
361
+ TEMPLATE
362
+
363
+ without_indent = AdHocTemplate::Parser.parse(template_without_indent, :xml_comment_like)
364
+ with_indent = AdHocTemplate::Parser.parse(template_with_indent, :xml_comment_like)
365
+
366
+ expect(with_indent).to eq(without_indent)
367
+ end
368
+ end
369
+
370
+ describe ".register_user_defined_tag_type" do
371
+ it "allow to defined a tag type in YAML format" do
372
+ tag_type_config = <<CONFIG
373
+ tag_name: xml_like3
374
+ tag: ["<!--%", "%-->"]
375
+ iteration_tag: ["<repeat>", "</repeat>"]
376
+ remove_indent: true
377
+ CONFIG
378
+ AdHocTemplate::Parser.register_user_defined_tag_type(tag_type_config)
379
+ defined_tag_type = AdHocTemplate::Parser::TagType[:xml_like3]
380
+ expect(defined_tag_type.iteration_start).to eq('<repeat>')
381
+ expect(defined_tag_type.iteration_end).to eq('</repeat>')
382
+ expect(defined_tag_type.remove_iteration_indent).to eq(true)
383
+ end
384
+
385
+ it "raises an error if a given definition does not contain sufficient information" do
386
+ tag_type_config = <<CONFIG
387
+ tag_name:
388
+ tag: ["<!--%", "%-->"]
389
+ iteration_tag: ["<repeat>", "</repeat>"]
390
+ remove_indent: true
391
+ CONFIG
392
+ expect {
393
+ AdHocTemplate::Parser.register_user_defined_tag_type(tag_type_config)
394
+ }.to raise_error(AdHocTemplate::Parser::UserDefinedTagTypeConfigError,
395
+ '"tag_name" should be defined.')
396
+ end
397
+ end
398
+ end
399
+ end