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.
- checksums.yaml +4 -4
- data/.gitignore +2 -0
- data/Gemfile +1 -1
- data/README.md +1 -2
- data/ad_hoc_template.gemspec +1 -1
- data/lib/ad_hoc_template/command_line_interface.rb +94 -7
- data/lib/ad_hoc_template/parser.rb +160 -0
- data/lib/ad_hoc_template/record_reader.rb +281 -0
- data/lib/ad_hoc_template/version.rb +1 -1
- data/lib/ad_hoc_template.rb +29 -176
- data/spec/ad_hoc_template_spec.rb +308 -141
- data/spec/command_line_interface_spec.rb +393 -34
- data/spec/parser_spec.rb +399 -0
- data/spec/record_reader_spec.rb +377 -0
- metadata +11 -6
@@ -2,139 +2,14 @@ require 'spec_helper'
|
|
2
2
|
require 'ad_hoc_template'
|
3
3
|
|
4
4
|
describe AdHocTemplate do
|
5
|
+
|
5
6
|
it 'should have a version number' do
|
6
7
|
expect(AdHocTemplate::VERSION).to_not be_nil
|
7
8
|
end
|
8
9
|
|
9
|
-
describe AdHocTemplate::
|
10
|
-
|
11
|
-
|
12
|
-
[[" the first tag "]],
|
13
|
-
[" and "],
|
14
|
-
[[" the second tag "]],
|
15
|
-
[") in it"]])
|
16
|
-
end
|
17
|
-
|
18
|
-
it "allows to have a nested tag" do
|
19
|
-
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; "],
|
20
|
-
[[" an outer tag and "],
|
21
|
-
[[" an inner tag "]],
|
22
|
-
[" "]]])
|
23
|
-
end
|
24
|
-
|
25
|
-
it "may have iteration tags." do
|
26
|
-
tree = AdHocTemplate::Parser.parse("a test string with a nested tag: <%# an iteration tag and <% an inner tag %> #%> and <% another tag %>")
|
27
|
-
expect(tree).to eq([["a test string with a nested tag: "],
|
28
|
-
[[" an iteration tag and "],
|
29
|
-
[[" an inner tag "]],
|
30
|
-
[" "]],
|
31
|
-
[" and "],
|
32
|
-
[[" another tag "]]])
|
33
|
-
expect(tree[1]).to be_a_kind_of(AdHocTemplate::Parser::IterationTagNode)
|
34
|
-
end
|
35
|
-
end
|
36
|
-
|
37
|
-
describe AdHocTemplate::RecordReader do
|
38
|
-
it "can read several header type configurations at once." do
|
39
|
-
data = <<CONFIGS
|
40
|
-
|
41
|
-
key1-1: value1-1
|
42
|
-
key1-2: value1-2
|
43
|
-
|
44
|
-
key2-1: value2-1
|
45
|
-
key2-2: value2-2
|
46
|
-
|
47
|
-
key3-1: value3-1
|
48
|
-
key3-2: value3-2
|
49
|
-
|
50
|
-
CONFIGS
|
51
|
-
|
52
|
-
config = {}
|
53
|
-
AdHocTemplate::RecordReader.read_iteration_block(data.each_line.to_a, config, "#configs")
|
54
|
-
expect(config).to eq({"#configs"=>[{"key1-1"=>"value1-1", "key1-2"=>"value1-2"},
|
55
|
-
{"key2-1"=>"value2-1", "key2-2"=>"value2-2"},
|
56
|
-
{"key3-1"=>"value3-1", "key3-2"=>"value3-2"}]})
|
57
|
-
end
|
58
|
-
|
59
|
-
it "reads configuration data and turns them into a hash object" do
|
60
|
-
data = <<CONFIG
|
61
|
-
key1: value1
|
62
|
-
key2: value2
|
63
|
-
key3: value3
|
64
|
-
|
65
|
-
//@block1
|
66
|
-
|
67
|
-
the first line of block1
|
68
|
-
the second line of block1
|
69
|
-
|
70
|
-
the second paragraph in block1
|
71
|
-
|
72
|
-
//@block2
|
73
|
-
the first line of block2
|
74
|
-
the second line of block2
|
75
|
-
|
76
|
-
the second paragraph of block2
|
77
|
-
CONFIG
|
78
|
-
|
79
|
-
expected_config = {
|
80
|
-
"key1" => "value1",
|
81
|
-
"key2" => "value2",
|
82
|
-
"key3" => "value3",
|
83
|
-
"block1" => "the first line of block1\nthe second line of block1\n\nthe second paragraph in block1\n",
|
84
|
-
"block2" => "the first line of block2\nthe second line of block2\n\nthe second paragraph of block2\n"
|
85
|
-
}
|
86
|
-
expect(AdHocTemplate::RecordReader.read_record(data)).to eq(expected_config)
|
87
|
-
end
|
88
|
-
|
89
|
-
it "can read configuration data with 3 different kind of sections" do
|
90
|
-
data = <<CONFIG
|
91
|
-
key1: value1
|
92
|
-
key2: value2
|
93
|
-
key3: value3
|
94
|
-
|
95
|
-
//@#subconfigs
|
96
|
-
|
97
|
-
key1-1: value1-1
|
98
|
-
key1-2: value1-2
|
99
|
-
|
100
|
-
key2-1: value2-1
|
101
|
-
key2-2: value2-2
|
102
|
-
|
103
|
-
//@block
|
104
|
-
|
105
|
-
the first line of block
|
106
|
-
the second line of block
|
107
|
-
|
108
|
-
the second paragraph in block
|
109
|
-
|
110
|
-
CONFIG
|
111
|
-
|
112
|
-
expected_config = {
|
113
|
-
"key1" => "value1",
|
114
|
-
"key2" => "value2",
|
115
|
-
"key3" => "value3",
|
116
|
-
"#subconfigs" => [{"key1-1"=>"value1-1", "key1-2"=>"value1-2"}, {"key2-1"=>"value2-1", "key2-2"=>"value2-2"}],
|
117
|
-
"block" => "the first line of block\nthe second line of block\n\nthe second paragraph in block\n"
|
118
|
-
}
|
119
|
-
expect(AdHocTemplate::RecordReader.read_record(data)).to eq(expected_config)
|
120
|
-
end
|
121
|
-
end
|
122
|
-
|
123
|
-
describe AdHocTemplate::Converter do
|
124
|
-
it "returns the result of conversion." do
|
125
|
-
template = "a test string with tags (<%= key1 %> and <%= key2 %>) in it"
|
126
|
-
config_data = <<CONFIG
|
127
|
-
key1: value1
|
128
|
-
key2: value2
|
129
|
-
CONFIG
|
130
|
-
|
131
|
-
tree = AdHocTemplate::Parser.parse(template)
|
132
|
-
config = AdHocTemplate::RecordReader.read_record(config_data)
|
133
|
-
expect(AdHocTemplate::Converter.new(config).format(tree)).to eq("a test string with tags (value1 and value2) in it")
|
134
|
-
end
|
135
|
-
|
136
|
-
it "accepts a template with an iteration block and evaluate repeatedly the block" do
|
137
|
-
template = <<TEMPLATE
|
10
|
+
describe AdHocTemplate::DataLoader do
|
11
|
+
before do
|
12
|
+
@template_with_an_iteration_block = <<TEMPLATE
|
138
13
|
a test string with tags (<%= key1 %> and <%= key2 %>) in it
|
139
14
|
|
140
15
|
<%#iteration_block
|
@@ -145,7 +20,7 @@ the value of sub_key2 is <%= sub_key2 %>
|
|
145
20
|
<%= block %>
|
146
21
|
TEMPLATE
|
147
22
|
|
148
|
-
|
23
|
+
@config_data_with_an_iteration_block = <<CONFIG
|
149
24
|
key1: value1
|
150
25
|
key2: value2
|
151
26
|
key3: value3
|
@@ -167,7 +42,7 @@ the second paragraph in block
|
|
167
42
|
|
168
43
|
CONFIG
|
169
44
|
|
170
|
-
|
45
|
+
@expected_result_with_an_iteration_block = <<RESULT
|
171
46
|
a test string with tags (value1 and value2) in it
|
172
47
|
|
173
48
|
the value of sub_key1 is value1-1
|
@@ -176,16 +51,34 @@ the value of sub_key2 is value1-2
|
|
176
51
|
the value of sub_key1 is value2-1
|
177
52
|
the value of sub_key2 is value2-2
|
178
53
|
|
179
|
-
|
180
54
|
the first line of block
|
181
55
|
the second line of block
|
182
56
|
|
183
57
|
the second paragraph in block
|
184
58
|
|
185
59
|
RESULT
|
60
|
+
end
|
61
|
+
|
62
|
+
it "returns the result of conversion." do
|
63
|
+
template = "a test string with tags (<%= key1 %> and <%= key2 %>) in it"
|
64
|
+
config_data = <<CONFIG
|
65
|
+
key1: value1
|
66
|
+
key2: value2
|
67
|
+
CONFIG
|
68
|
+
|
186
69
|
tree = AdHocTemplate::Parser.parse(template)
|
187
70
|
config = AdHocTemplate::RecordReader.read_record(config_data)
|
188
|
-
expect(AdHocTemplate::
|
71
|
+
expect(AdHocTemplate::DataLoader.new(config).format(tree)).to eq("a test string with tags (value1 and value2) in it")
|
72
|
+
end
|
73
|
+
|
74
|
+
it "accepts a template with an iteration block and evaluate repeatedly the block" do
|
75
|
+
template = @template_with_an_iteration_block
|
76
|
+
config_data = @config_data_with_an_iteration_block
|
77
|
+
expected_result = @expected_result_with_an_iteration_block
|
78
|
+
|
79
|
+
tree = AdHocTemplate::Parser.parse(template)
|
80
|
+
config = AdHocTemplate::RecordReader.read_record(config_data)
|
81
|
+
expect(AdHocTemplate::DataLoader.new(config).format(tree)).to eq(expected_result)
|
189
82
|
end
|
190
83
|
|
191
84
|
it "may contains iteration blocks without key label." do
|
@@ -220,30 +113,304 @@ the second paragraph in block
|
|
220
113
|
|
221
114
|
CONFIG
|
222
115
|
|
223
|
-
expected_result = <<RESULT
|
116
|
+
expected_result = <<RESULT
|
224
117
|
a test string with tags (value1 and value2) in it
|
225
118
|
|
226
119
|
the value of key1 is value1
|
227
120
|
the value of key2 is value2
|
228
121
|
|
122
|
+
the first line of block
|
123
|
+
the second line of block
|
124
|
+
|
125
|
+
the second paragraph in block
|
126
|
+
|
127
|
+
RESULT
|
128
|
+
|
129
|
+
tree = AdHocTemplate::Parser.parse(template)
|
130
|
+
config = AdHocTemplate::RecordReader.read_record(config_data)
|
131
|
+
expect(AdHocTemplate::DataLoader.new(config).format(tree)).to eq(expected_result)
|
132
|
+
end
|
133
|
+
|
134
|
+
it "offers .format method for convenience" do
|
135
|
+
template = @template_with_an_iteration_block
|
136
|
+
config_data = @config_data_with_an_iteration_block
|
137
|
+
expected_result = @expected_result_with_an_iteration_block
|
138
|
+
|
139
|
+
tree = AdHocTemplate::Parser.parse(template)
|
140
|
+
config = AdHocTemplate::RecordReader.read_record(config_data)
|
141
|
+
tag_formatter = AdHocTemplate::DefaultTagFormatter.new
|
142
|
+
expect(AdHocTemplate::DataLoader.format(tree, config, tag_formatter)).to eq(expected_result)
|
143
|
+
end
|
229
144
|
|
145
|
+
it("should not add a newline at the head of IterationTagNode when the type of the node is not specified") do
|
146
|
+
template = <<TEMPLATE
|
147
|
+
a test string with tags
|
148
|
+
<%#iteration_block
|
149
|
+
the value of sub_key1 is <%= sub_key1 %>
|
150
|
+
<%#
|
151
|
+
the value of sub_key2 is <%= sub_key2 %>
|
152
|
+
#%>
|
153
|
+
|
154
|
+
#%>
|
155
|
+
<%= block %>
|
156
|
+
TEMPLATE
|
157
|
+
|
158
|
+
config_data = <<CONFIG
|
159
|
+
//@#iteration_block
|
160
|
+
|
161
|
+
sub_key1: value1-1
|
162
|
+
sub_key2: value1-2
|
163
|
+
|
164
|
+
sub_key1: value2-1
|
230
165
|
|
166
|
+
//@block
|
231
167
|
|
232
168
|
the first line of block
|
233
|
-
|
169
|
+
CONFIG
|
234
170
|
|
235
|
-
|
171
|
+
expected_result = <<RESULT
|
172
|
+
a test string with tags
|
173
|
+
the value of sub_key1 is value1-1
|
174
|
+
the value of sub_key2 is value1-2
|
175
|
+
|
176
|
+
the value of sub_key1 is value2-1
|
177
|
+
|
178
|
+
the first line of block
|
236
179
|
|
237
180
|
RESULT
|
238
181
|
tree = AdHocTemplate::Parser.parse(template)
|
239
182
|
config = AdHocTemplate::RecordReader.read_record(config_data)
|
240
|
-
|
183
|
+
tag_formatter = AdHocTemplate::DefaultTagFormatter.new
|
184
|
+
expect(AdHocTemplate::DataLoader.format(tree, config, tag_formatter)).to eq(expected_result)
|
241
185
|
end
|
242
186
|
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
187
|
+
describe "iteration block" do
|
188
|
+
before do
|
189
|
+
@template =<<TEMPLATE
|
190
|
+
The first line in the main part
|
191
|
+
|
192
|
+
<%#
|
193
|
+
The first line in the iteration part
|
194
|
+
|
195
|
+
<%#iteration_block
|
196
|
+
The value of key1 is <%= key1 %>
|
197
|
+
#%>
|
198
|
+
|
199
|
+
#%>
|
200
|
+
TEMPLATE
|
201
|
+
|
202
|
+
@template_with_nested_iteration_tag =<<TEMPLATE
|
203
|
+
The first line in the main part
|
204
|
+
|
205
|
+
<%#
|
206
|
+
The first line in the iteration part
|
207
|
+
|
208
|
+
Key value: <%= key %>
|
209
|
+
Optinal values: <%# <%= optional1 %> and <%= optional2 %> are in the record.
|
210
|
+
#%>
|
211
|
+
|
212
|
+
<%#iteration_block
|
213
|
+
The value of key1 is <%= key1 %>
|
214
|
+
<%#
|
215
|
+
The value of optional key2 is <%= key2 %>
|
216
|
+
#%>
|
217
|
+
#%>
|
218
|
+
|
219
|
+
#%>
|
220
|
+
TEMPLATE
|
221
|
+
|
222
|
+
@expected_result_when_data_provided =<<RESULT
|
223
|
+
The first line in the main part
|
224
|
+
|
225
|
+
The first line in the iteration part
|
226
|
+
|
227
|
+
The value of key1 is value1
|
228
|
+
The value of key1 is value1
|
229
|
+
|
230
|
+
RESULT
|
231
|
+
|
232
|
+
@expected_result_for_nested_iteration_tag_when_data_provided =<<RESULT
|
233
|
+
The first line in the main part
|
234
|
+
|
235
|
+
The first line in the iteration part
|
236
|
+
|
237
|
+
Key value: value
|
238
|
+
Optinal values: optinal value1 and [optional2] are in the record.
|
239
|
+
|
240
|
+
The value of key1 is value1
|
241
|
+
The value of key1 is value1
|
242
|
+
The value of optional key2 is value2
|
243
|
+
|
244
|
+
RESULT
|
245
|
+
end
|
246
|
+
|
247
|
+
describe "with data in default format" do
|
248
|
+
it "should not ignore the content of an iteration block when some data are provided" do
|
249
|
+
config_data = <<CONFIG
|
250
|
+
//@#iteration_block
|
251
|
+
|
252
|
+
key1: value1
|
253
|
+
|
254
|
+
key1: value1
|
255
|
+
CONFIG
|
256
|
+
|
257
|
+
expected_result = @expected_result_when_data_provided
|
258
|
+
|
259
|
+
tree = AdHocTemplate::Parser.parse(@template)
|
260
|
+
config = AdHocTemplate::RecordReader.read_record(config_data)
|
261
|
+
tag_formatter = AdHocTemplate::DefaultTagFormatter.new
|
262
|
+
|
263
|
+
expect(AdHocTemplate::DataLoader.format(tree, config, tag_formatter)).to eq(expected_result)
|
264
|
+
end
|
265
|
+
|
266
|
+
it "should ignore the content of an iteration block if no thing is provided" do
|
267
|
+
config_data = <<CONFIG
|
268
|
+
//@#iteration_block
|
269
|
+
|
270
|
+
CONFIG
|
271
|
+
|
272
|
+
expected_result =<<RESULT
|
273
|
+
The first line in the main part
|
274
|
+
|
275
|
+
RESULT
|
276
|
+
|
277
|
+
tree = AdHocTemplate::Parser.parse(@template)
|
278
|
+
config = AdHocTemplate::RecordReader.read_record(config_data)
|
279
|
+
tag_formatter = AdHocTemplate::DefaultTagFormatter.new
|
280
|
+
|
281
|
+
expect(AdHocTemplate::DataLoader.format(tree, config, tag_formatter)).to eq(expected_result)
|
282
|
+
end
|
283
|
+
|
284
|
+
it "may contain nested iteration blocks" do
|
285
|
+
config_data = <<CONFIG
|
286
|
+
key: value
|
287
|
+
optional1: optinal value1
|
288
|
+
|
289
|
+
//@#iteration_block
|
290
|
+
|
291
|
+
key1: value1
|
292
|
+
|
293
|
+
key1: value1
|
294
|
+
key2: value2
|
295
|
+
CONFIG
|
296
|
+
|
297
|
+
expected_result = @expected_result_for_nested_iteration_tag_when_data_provided
|
298
|
+
|
299
|
+
tree = AdHocTemplate::Parser.parse(@template_with_nested_iteration_tag)
|
300
|
+
config = AdHocTemplate::RecordReader.read_record(config_data)
|
301
|
+
tag_formatter = AdHocTemplate::DefaultTagFormatter.new
|
302
|
+
|
303
|
+
expect(AdHocTemplate::DataLoader.format(tree, config, tag_formatter)).to eq(expected_result)
|
304
|
+
end
|
305
|
+
|
306
|
+
it "should ignore nested iteration blocks unless data are provided" do
|
307
|
+
config_data = <<CONFIG
|
308
|
+
key:
|
309
|
+
optional1:
|
310
|
+
|
311
|
+
//@#iteration_block
|
312
|
+
|
313
|
+
key1:
|
314
|
+
|
315
|
+
key1:
|
316
|
+
key2:
|
317
|
+
CONFIG
|
318
|
+
|
319
|
+
expected_result =<<RESULT
|
320
|
+
The first line in the main part
|
321
|
+
|
322
|
+
RESULT
|
323
|
+
|
324
|
+
tree = AdHocTemplate::Parser.parse(@template_with_nested_iteration_tag)
|
325
|
+
config = AdHocTemplate::RecordReader.read_record(config_data)
|
326
|
+
tag_formatter = AdHocTemplate::DefaultTagFormatter.new
|
327
|
+
|
328
|
+
expect(AdHocTemplate::DataLoader.format(tree, config, tag_formatter)).to eq(expected_result)
|
329
|
+
end
|
330
|
+
end
|
331
|
+
|
332
|
+
describe "with data in YAML format" do
|
333
|
+
it "should not ignore the content of an iteration block when some data are provided" do
|
334
|
+
config_data = <<CONFIG
|
335
|
+
'#iteration_block':
|
336
|
+
- key1: value1
|
337
|
+
- key1: value1
|
338
|
+
CONFIG
|
339
|
+
|
340
|
+
expected_result = @expected_result_when_data_provided
|
341
|
+
|
342
|
+
tree = AdHocTemplate::Parser.parse(@template)
|
343
|
+
config = AdHocTemplate::RecordReader.read_record(config_data, :yaml)
|
344
|
+
tag_formatter = AdHocTemplate::DefaultTagFormatter.new
|
345
|
+
|
346
|
+
expect(AdHocTemplate::DataLoader.format(tree, config, tag_formatter)).to eq(expected_result)
|
347
|
+
end
|
348
|
+
|
349
|
+
it "should ignore the content of an iteration block if no thing is provided" do
|
350
|
+
config_data = <<CONFIG
|
351
|
+
'#iteration_block':
|
352
|
+
|
353
|
+
CONFIG
|
354
|
+
|
355
|
+
expected_result =<<RESULT
|
356
|
+
The first line in the main part
|
357
|
+
|
358
|
+
RESULT
|
359
|
+
|
360
|
+
tree = AdHocTemplate::Parser.parse(@template)
|
361
|
+
config = AdHocTemplate::RecordReader.read_record(config_data, :yaml)
|
362
|
+
tag_formatter = AdHocTemplate::DefaultTagFormatter.new
|
363
|
+
|
364
|
+
expect(AdHocTemplate::DataLoader.format(tree, config, tag_formatter)).to eq(expected_result)
|
365
|
+
end
|
366
|
+
|
367
|
+
it "may contain nested iteration blocks" do
|
368
|
+
config_data = <<CONFIG
|
369
|
+
key: value
|
370
|
+
optional1: optinal value1
|
371
|
+
'#iteration_block':
|
372
|
+
- key1: value1
|
373
|
+
- key1: value1
|
374
|
+
key2: value2
|
375
|
+
CONFIG
|
376
|
+
|
377
|
+
expected_result = @expected_result_for_nested_iteration_tag_when_data_provided
|
378
|
+
|
379
|
+
tree = AdHocTemplate::Parser.parse(@template_with_nested_iteration_tag)
|
380
|
+
config = AdHocTemplate::RecordReader.read_record(config_data, :yaml)
|
381
|
+
tag_formatter = AdHocTemplate::DefaultTagFormatter.new
|
382
|
+
|
383
|
+
expect(AdHocTemplate::DataLoader.format(tree, config, tag_formatter)).to eq(expected_result)
|
384
|
+
end
|
385
|
+
|
386
|
+
it "should ignore nested iteration blocks unless data are provided" do
|
387
|
+
config_data = <<CONFIG
|
388
|
+
key:
|
389
|
+
optional1:
|
390
|
+
'#iteration_block':
|
391
|
+
- key1:
|
392
|
+
- key1:
|
393
|
+
key2:
|
394
|
+
CONFIG
|
395
|
+
|
396
|
+
expected_result =<<RESULT
|
397
|
+
The first line in the main part
|
398
|
+
|
399
|
+
RESULT
|
400
|
+
|
401
|
+
tree = AdHocTemplate::Parser.parse(@template_with_nested_iteration_tag)
|
402
|
+
config = AdHocTemplate::RecordReader.read_record(config_data, :yaml)
|
403
|
+
tag_formatter = AdHocTemplate::DefaultTagFormatter.new
|
404
|
+
|
405
|
+
expect(AdHocTemplate::DataLoader.format(tree, config, tag_formatter)).to eq(expected_result)
|
406
|
+
end
|
407
|
+
end
|
247
408
|
end
|
248
409
|
end
|
410
|
+
|
411
|
+
it 'can convert &"<> into character entities' do
|
412
|
+
result = AdHocTemplate.convert('characters: &, ", < and >',
|
413
|
+
'a string with characters (<%h characters %>) that should be represented as character entities.')
|
414
|
+
expect(result).to eq('a string with characters (&, ", < and >) that should be represented as character entities.')
|
415
|
+
end
|
249
416
|
end
|