ad_hoc_template 0.0.1 → 0.1.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/.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
|