ad_hoc_template 0.2.0 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +1 -1
- data/lib/ad_hoc_template.rb +24 -3
- data/lib/ad_hoc_template/command_line_interface.rb +27 -11
- data/lib/ad_hoc_template/entry_format_generator.rb +49 -0
- data/lib/ad_hoc_template/parser.rb +127 -58
- data/lib/ad_hoc_template/pseudohiki_formatter.rb +1 -1
- data/lib/ad_hoc_template/record_reader.rb +294 -160
- data/lib/ad_hoc_template/version.rb +1 -1
- data/spec/ad_hoc_template_spec.rb +151 -5
- data/spec/command_line_interface_spec.rb +107 -7
- data/spec/entry_format_generator_spec.rb +163 -0
- data/spec/parser_spec.rb +114 -18
- data/spec/pseudohiki_formatter_spec.rb +2 -2
- data/spec/record_reader_spec.rb +253 -9
- metadata +6 -3
data/spec/parser_spec.rb
CHANGED
@@ -33,7 +33,7 @@ describe AdHocTemplate do
|
|
33
33
|
end
|
34
34
|
|
35
35
|
it "may contain lines that consist only of an iteration tag" do
|
36
|
-
tree = AdHocTemplate::Parser.parse("<%#iterations
|
36
|
+
tree = AdHocTemplate::Parser.parse("<%#iterations:
|
37
37
|
content
|
38
38
|
#%>
|
39
39
|
")
|
@@ -70,6 +70,32 @@ TEMPLATE
|
|
70
70
|
|
71
71
|
expect(with_indent).not_to eq(without_indent)
|
72
72
|
end
|
73
|
+
|
74
|
+
it "may contains nested tags and the first inner tag may not have preceding strings" do
|
75
|
+
template = "main start <%#<%= var1 %> inner part <%= var2 %> inner end #%> main end"
|
76
|
+
tree = AdHocTemplate::Parser.parse(template)
|
77
|
+
expect(tree).to eq([
|
78
|
+
["main start "],
|
79
|
+
[
|
80
|
+
[["var1 "]],
|
81
|
+
[" inner part "],
|
82
|
+
[["var2 "]],
|
83
|
+
[" inner end "]],
|
84
|
+
[" main end"]])
|
85
|
+
end
|
86
|
+
|
87
|
+
it "tags may be put side by side without any string in between" do
|
88
|
+
template = "main start <%# inner start<%= var1 %><%= var2 %>inner end #%> main end"
|
89
|
+
tree = AdHocTemplate::Parser.parse(template)
|
90
|
+
expect(tree).to eq([
|
91
|
+
["main start "],
|
92
|
+
[
|
93
|
+
[" inner start"],
|
94
|
+
[["var1 "]],
|
95
|
+
[["var2 "]],
|
96
|
+
["inner end "]],
|
97
|
+
[" main end"]])
|
98
|
+
end
|
73
99
|
end
|
74
100
|
|
75
101
|
describe "with the square brackets tag type" do
|
@@ -100,7 +126,7 @@ TEMPLATE
|
|
100
126
|
end
|
101
127
|
|
102
128
|
it "may contain lines that consist only of an iteration tag" do
|
103
|
-
tree = AdHocTemplate::Parser.parse("[[#iterations
|
129
|
+
tree = AdHocTemplate::Parser.parse("[[#iterations:
|
104
130
|
content
|
105
131
|
#]]
|
106
132
|
", :square_brackets)
|
@@ -141,7 +167,7 @@ content
|
|
141
167
|
end
|
142
168
|
|
143
169
|
it "may contain lines that consist only of an iteration tag" do
|
144
|
-
tree = AdHocTemplate::Parser.parse("{{#iterations
|
170
|
+
tree = AdHocTemplate::Parser.parse("{{#iterations:
|
145
171
|
content
|
146
172
|
#}}
|
147
173
|
", :curly_brackets)
|
@@ -155,12 +181,12 @@ content
|
|
155
181
|
end
|
156
182
|
|
157
183
|
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
|
184
|
+
tree = AdHocTemplate::Parser.parse("<%#iteration:\n the second line\nthe third line")
|
159
185
|
expect(tree).to eq([[[" the second line\nthe third line"]]])
|
160
186
|
end
|
161
187
|
|
162
188
|
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
|
189
|
+
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
190
|
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
191
|
end
|
166
192
|
|
@@ -192,7 +218,7 @@ content
|
|
192
218
|
end
|
193
219
|
|
194
220
|
it "may contain lines that consist only of an iteration tag" do
|
195
|
-
tree = AdHocTemplate::Parser.parse("<iterate>iterations
|
221
|
+
tree = AdHocTemplate::Parser.parse("<iterate>iterations:
|
196
222
|
content
|
197
223
|
</iterate>
|
198
224
|
", :xml_like1)
|
@@ -205,12 +231,12 @@ content
|
|
205
231
|
end
|
206
232
|
|
207
233
|
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
|
234
|
+
tree = AdHocTemplate::Parser.parse("<iterate>iteration:\n the second line\nthe third line</iterate>", :xml_like1)
|
209
235
|
expect(tree).to eq([[[" the second line\nthe third line"]]])
|
210
236
|
end
|
211
237
|
|
212
238
|
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
|
239
|
+
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
240
|
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
241
|
end
|
216
242
|
|
@@ -268,7 +294,7 @@ TEMPLATE
|
|
268
294
|
end
|
269
295
|
|
270
296
|
it "may contain lines that consist only of an iteration tag" do
|
271
|
-
tree = AdHocTemplate::Parser.parse("<iterate>iterations
|
297
|
+
tree = AdHocTemplate::Parser.parse("<iterate>iterations:
|
272
298
|
content
|
273
299
|
</iterate>
|
274
300
|
", :xml_like2)
|
@@ -281,12 +307,12 @@ content
|
|
281
307
|
end
|
282
308
|
|
283
309
|
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
|
310
|
+
tree = AdHocTemplate::Parser.parse("<iterate>iteration:\n the second line\nthe third line</iterate>", :xml_like2)
|
285
311
|
expect(tree).to eq([[[" the second line\nthe third line"]]])
|
286
312
|
end
|
287
313
|
|
288
314
|
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
|
315
|
+
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
316
|
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
317
|
end
|
292
318
|
end
|
@@ -319,7 +345,7 @@ content
|
|
319
345
|
end
|
320
346
|
|
321
347
|
it "may contain lines that consist only of an iteration tag" do
|
322
|
-
tree = AdHocTemplate::Parser.parse("<!--%iterate%-->iterations
|
348
|
+
tree = AdHocTemplate::Parser.parse("<!--%iterate%-->iterations:
|
323
349
|
content
|
324
350
|
<!--%/iterate%-->
|
325
351
|
", :xml_comment_like)
|
@@ -332,12 +358,12 @@ content
|
|
332
358
|
end
|
333
359
|
|
334
360
|
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
|
361
|
+
tree = AdHocTemplate::Parser.parse("<!--%iterate%-->iteration:\n the second line\nthe third line<!--%/iterate%-->", :xml_comment_like)
|
336
362
|
expect(tree).to eq([[[" the second line\nthe third line"]]])
|
337
363
|
end
|
338
364
|
|
339
365
|
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
|
366
|
+
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
367
|
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
368
|
end
|
343
369
|
|
@@ -370,7 +396,7 @@ TEMPLATE
|
|
370
396
|
template_without_indent = <<TEMPLATE_WITHOUT_INDENT
|
371
397
|
A template with an iteration tag
|
372
398
|
|
373
|
-
<!--%iterate%-->label
|
399
|
+
<!--%iterate%-->label:
|
374
400
|
This part will be repeated with <!--% variable %-->
|
375
401
|
<!--%/iterate%-->
|
376
402
|
|
@@ -379,7 +405,7 @@ TEMPLATE_WITHOUT_INDENT
|
|
379
405
|
template_with_indent = <<TEMPLATE
|
380
406
|
A template with an iteration tag
|
381
407
|
|
382
|
-
<!--%iterate%-->label
|
408
|
+
<!--%iterate%-->label:
|
383
409
|
This part will be repeated with <!--% variable %-->
|
384
410
|
<!--%/iterate%-->
|
385
411
|
|
@@ -398,12 +424,14 @@ TEMPLATE
|
|
398
424
|
tag_name: xml_like3
|
399
425
|
tag: ["<!--%", "%-->"]
|
400
426
|
iteration_tag: ["<repeat>", "</repeat>"]
|
427
|
+
fallback_tag: ["<fallback>", "</fallback>"]
|
401
428
|
remove_indent: true
|
402
429
|
CONFIG
|
430
|
+
iteration_tag_node = AdHocTemplate::Parser::IterationTagNode
|
403
431
|
AdHocTemplate::Parser.register_user_defined_tag_type(tag_type_config)
|
404
432
|
defined_tag_type = AdHocTemplate::Parser::TagType[:xml_like3]
|
405
|
-
expect(defined_tag_type.
|
406
|
-
expect(defined_tag_type.
|
433
|
+
expect(defined_tag_type.head_of[iteration_tag_node]).to eq('<repeat>')
|
434
|
+
expect(defined_tag_type.tail_of[iteration_tag_node]).to eq('</repeat>')
|
407
435
|
expect(defined_tag_type.remove_iteration_indent).to eq(true)
|
408
436
|
end
|
409
437
|
|
@@ -412,6 +440,7 @@ CONFIG
|
|
412
440
|
tag_name:
|
413
441
|
tag: ["<!--%", "%-->"]
|
414
442
|
iteration_tag: ["<repeat>", "</repeat>"]
|
443
|
+
fallback_tag: ["<fallback>", "</fallback>"]
|
415
444
|
remove_indent: true
|
416
445
|
CONFIG
|
417
446
|
expect {
|
@@ -420,5 +449,72 @@ CONFIG
|
|
420
449
|
'"tag_name" should be defined.')
|
421
450
|
end
|
422
451
|
end
|
452
|
+
|
453
|
+
describe "#contains_any_value_tag?" do
|
454
|
+
it 'return true if any value tag is contained' do
|
455
|
+
template_with_value_tag =<<TEMPLATE
|
456
|
+
main start
|
457
|
+
|
458
|
+
<%#
|
459
|
+
<%*
|
460
|
+
line with <%= value tag %>
|
461
|
+
*%>
|
462
|
+
#%>
|
463
|
+
|
464
|
+
|
465
|
+
main end
|
466
|
+
TEMPLATE
|
467
|
+
parsed = AdHocTemplate::Parser.parse(template_with_value_tag)
|
468
|
+
expect(parsed[1].contains_any_value_tag?).to be_truthy
|
469
|
+
end
|
470
|
+
|
471
|
+
it 'return false if no value tag is contained' do
|
472
|
+
template_without_value_tag =<<TEMPLATE
|
473
|
+
main start
|
474
|
+
|
475
|
+
<%#
|
476
|
+
<%*
|
477
|
+
line without value tag
|
478
|
+
*%>
|
479
|
+
#%>
|
480
|
+
|
481
|
+
|
482
|
+
main end
|
483
|
+
TEMPLATE
|
484
|
+
|
485
|
+
parsed = AdHocTemplate::Parser.parse(template_without_value_tag)
|
486
|
+
|
487
|
+
expect(parsed[1].contains_any_value_tag?).to be_falsy
|
488
|
+
end
|
489
|
+
end
|
490
|
+
|
491
|
+
describe AdHocTemplate::Parser::FallbackTagNode do
|
492
|
+
it 'is expected to be parsed like IterationTagNode -- used inline' do
|
493
|
+
source = 'main start <%# <%* content in fallback_tag <%= tag node in fallback tag %> fallback end *%> optional content with <%#iterations: in iteration tag <%= item %> #%> iteration part end #%> main end'
|
494
|
+
expected_tree = [
|
495
|
+
["main start "],
|
496
|
+
[
|
497
|
+
[" "],
|
498
|
+
[
|
499
|
+
[" content in fallback_tag "],
|
500
|
+
[["tag node in fallback tag "]],
|
501
|
+
[" fallback end "]
|
502
|
+
],
|
503
|
+
[" optional content with "],
|
504
|
+
[
|
505
|
+
["in iteration tag "],
|
506
|
+
[["item "]],
|
507
|
+
[" "]],
|
508
|
+
[" iteration part end "]],
|
509
|
+
[" main end"]
|
510
|
+
]
|
511
|
+
|
512
|
+
tree = AdHocTemplate::Parser.parse(source)
|
513
|
+
fallback = tree[1][1]
|
514
|
+
|
515
|
+
expect(tree).to eq(expected_tree)
|
516
|
+
expect(fallback).to be_kind_of(AdHocTemplate::Parser::FallbackTagNode)
|
517
|
+
end
|
518
|
+
end
|
423
519
|
end
|
424
520
|
end
|
@@ -23,7 +23,7 @@ CONFIG
|
|
23
23
|
|
24
24
|
template = <<TEMPLATE
|
25
25
|
<ul>
|
26
|
-
<%#iteration
|
26
|
+
<%#iteration:
|
27
27
|
<li>
|
28
28
|
<ul>
|
29
29
|
<li><%ph key1 %></li>
|
@@ -62,7 +62,7 @@ the second paragraph in block
|
|
62
62
|
|
63
63
|
RESULT
|
64
64
|
|
65
|
-
result = AdHocTemplate.
|
65
|
+
result = AdHocTemplate.render(config_data, template)
|
66
66
|
expect(result).to eq(expected_result)
|
67
67
|
end
|
68
68
|
end
|
data/spec/record_reader_spec.rb
CHANGED
@@ -223,8 +223,15 @@ YAML
|
|
223
223
|
expect(yaml_reader).to eq(record_reader)
|
224
224
|
end
|
225
225
|
|
226
|
-
it '.
|
227
|
-
yaml = AdHocTemplate::RecordReader::YAMLReader.
|
226
|
+
it '.dump converts the format of data from default to yaml' do
|
227
|
+
yaml = AdHocTemplate::RecordReader::YAMLReader.dump(@config_source)
|
228
|
+
|
229
|
+
expect(yaml).to eq(@yaml_dump)
|
230
|
+
end
|
231
|
+
|
232
|
+
it '.dump accepts parsed data too' do
|
233
|
+
parsed_data = AdHocTemplate::RecordReader.read_record(@config_source)
|
234
|
+
yaml = AdHocTemplate::RecordReader::YAMLReader.dump(parsed_data)
|
228
235
|
|
229
236
|
expect(yaml).to eq(@yaml_dump)
|
230
237
|
end
|
@@ -275,7 +282,22 @@ CONFIG
|
|
275
282
|
JSON
|
276
283
|
|
277
284
|
@json_dump = <<JSON
|
278
|
-
{
|
285
|
+
{
|
286
|
+
"key1": "value1",
|
287
|
+
"key2": "value2",
|
288
|
+
"key3": "value3",
|
289
|
+
"#subconfigs": [
|
290
|
+
{
|
291
|
+
"key1-1": "value1-1",
|
292
|
+
"key1-2": "value1-2"
|
293
|
+
},
|
294
|
+
{
|
295
|
+
"key2-1": "value2-1",
|
296
|
+
"key2-2": "value2-2"
|
297
|
+
}
|
298
|
+
],
|
299
|
+
"block": "the first line of block\\nthe second line of block\\n\\nthe second paragraph in block\\n"
|
300
|
+
}
|
279
301
|
JSON
|
280
302
|
end
|
281
303
|
|
@@ -293,8 +315,15 @@ JSON
|
|
293
315
|
expect(json_reader).to eq(record_reader)
|
294
316
|
end
|
295
317
|
|
296
|
-
it '.
|
297
|
-
json = AdHocTemplate::RecordReader::JSONReader.
|
318
|
+
it '.dump converts the format of data from default to json' do
|
319
|
+
json = AdHocTemplate::RecordReader::JSONReader.dump(@config_source)
|
320
|
+
|
321
|
+
expect(json).to eq(@json_dump.chomp)
|
322
|
+
end
|
323
|
+
|
324
|
+
it '.dump accepts parsed data too' do
|
325
|
+
parsed_data = AdHocTemplate::RecordReader.read_record(@config_source)
|
326
|
+
json = AdHocTemplate::RecordReader::JSONReader.dump(parsed_data)
|
298
327
|
|
299
328
|
expect(json).to eq(@json_dump.chomp)
|
300
329
|
end
|
@@ -319,6 +348,32 @@ key3: value3-3
|
|
319
348
|
|
320
349
|
CONFIG
|
321
350
|
|
351
|
+
@csv_incompatible_config_source = <<CONFIG
|
352
|
+
key: value
|
353
|
+
|
354
|
+
///@#subconfigs
|
355
|
+
|
356
|
+
key1: value1-1
|
357
|
+
key2: value1-2
|
358
|
+
key3: value1-3
|
359
|
+
|
360
|
+
key1: value2-1
|
361
|
+
key2: value2-2
|
362
|
+
key3: value2-3
|
363
|
+
|
364
|
+
key1: value3-1
|
365
|
+
key2: value3-2
|
366
|
+
key3: value3-3
|
367
|
+
|
368
|
+
CONFIG
|
369
|
+
|
370
|
+
@config_source_without_iteration = <<CONFIG
|
371
|
+
key1: value1
|
372
|
+
key2: value2
|
373
|
+
key3: value3
|
374
|
+
CONFIG
|
375
|
+
|
376
|
+
|
322
377
|
@csv_source = <<CSV
|
323
378
|
key1,key2,key3
|
324
379
|
value1-1,value1-2,value1-3
|
@@ -334,6 +389,78 @@ value3-1 value3-2 value3-3
|
|
334
389
|
TSV
|
335
390
|
end
|
336
391
|
|
392
|
+
it '.dump can convert data in default format to CSV when the data have just one record' do
|
393
|
+
expected_csv = <<CSV
|
394
|
+
key1,key2,key3
|
395
|
+
value1,value2,value3
|
396
|
+
CSV
|
397
|
+
parsed_data = AdHocTemplate::RecordReader.read_record(@config_source_without_iteration)
|
398
|
+
csv = AdHocTemplate::RecordReader::CSVReader.dump(parsed_data)
|
399
|
+
|
400
|
+
expect(csv).to eq(expected_csv)
|
401
|
+
end
|
402
|
+
|
403
|
+
it '.dump can convert data in default format to CSV when the data consist of just one iteration block' do
|
404
|
+
parsed_data = AdHocTemplate::RecordReader.read_record(@config_source)
|
405
|
+
csv = AdHocTemplate::RecordReader::CSVReader.dump(parsed_data)
|
406
|
+
|
407
|
+
expect(csv).to eq(@csv_source)
|
408
|
+
end
|
409
|
+
|
410
|
+
it '.dump may return CSV data that contain empty fields' do
|
411
|
+
config_source = <<CONFIG
|
412
|
+
///@#subconfigs
|
413
|
+
|
414
|
+
key1: value1-1
|
415
|
+
key3: value1-3
|
416
|
+
|
417
|
+
key1: value2-1
|
418
|
+
key2: value2-2
|
419
|
+
key3: value2-3
|
420
|
+
|
421
|
+
key3: value3-3
|
422
|
+
|
423
|
+
CONFIG
|
424
|
+
|
425
|
+
expected_csv = <<CSV
|
426
|
+
key1,key2,key3
|
427
|
+
value1-1,,value1-3
|
428
|
+
value2-1,value2-2,value2-3
|
429
|
+
,,value3-3
|
430
|
+
CSV
|
431
|
+
|
432
|
+
parsed_data = AdHocTemplate::RecordReader.read_record(config_source)
|
433
|
+
csv = AdHocTemplate::RecordReader::CSVReader.dump(parsed_data)
|
434
|
+
|
435
|
+
expect(csv).to eq(expected_csv)
|
436
|
+
end
|
437
|
+
|
438
|
+
it '.dump raises an exception when the structure of given data is too complex' do
|
439
|
+
parsed_data = AdHocTemplate::RecordReader.read_record(@csv_incompatible_config_source)
|
440
|
+
error_type = AdHocTemplate::RecordReader::CSVReader::NotSupportedError
|
441
|
+
|
442
|
+
expect do
|
443
|
+
AdHocTemplate::RecordReader::CSVReader.dump(parsed_data)
|
444
|
+
end.to raise_error(error_type)
|
445
|
+
end
|
446
|
+
|
447
|
+
it '.dump can generate TSV data too' do
|
448
|
+
col_sep = AdHocTemplate::RecordReader::CSVReader::COL_SEP[:tsv]
|
449
|
+
parsed_data = AdHocTemplate::RecordReader.read_record(@config_source)
|
450
|
+
tsv = AdHocTemplate::RecordReader::CSVReader.dump(parsed_data, col_sep)
|
451
|
+
|
452
|
+
expect(tsv).to eq(@tsv_source)
|
453
|
+
end
|
454
|
+
|
455
|
+
it 'TSV.dump is an alias of CSV.dump except for its default col_sep value' do
|
456
|
+
col_sep = AdHocTemplate::RecordReader::CSVReader::COL_SEP[:tsv]
|
457
|
+
parsed_data = AdHocTemplate::RecordReader.read_record(@config_source)
|
458
|
+
tsv_by_csv_reader = AdHocTemplate::RecordReader::CSVReader.dump(parsed_data, col_sep)
|
459
|
+
tsv = AdHocTemplate::RecordReader::TSVReader.dump(parsed_data)
|
460
|
+
|
461
|
+
expect(tsv).to eq(tsv_by_csv_reader)
|
462
|
+
end
|
463
|
+
|
337
464
|
it 'reads CSV data and turns it into a Ruby object' do
|
338
465
|
config = AdHocTemplate::RecordReader.read_record(@config_source)
|
339
466
|
csv = AdHocTemplate::RecordReader::CSVReader.read_record(@csv_source, "subconfigs")
|
@@ -362,16 +489,133 @@ TSV
|
|
362
489
|
end
|
363
490
|
|
364
491
|
it '.read_record is called from RecordReader.read_record if the format of source data is specified' do
|
365
|
-
csv_reader = AdHocTemplate::RecordReader::CSVReader.read_record(@
|
366
|
-
record_reader = AdHocTemplate::RecordReader.read_record(@
|
492
|
+
csv_reader = AdHocTemplate::RecordReader::CSVReader.read_record(@tsv_source, tsv: "subconfigs")
|
493
|
+
record_reader = AdHocTemplate::RecordReader.read_record(@tsv_source, tsv: "subconfigs")
|
367
494
|
|
368
|
-
csv_reader_without_label = AdHocTemplate::RecordReader::CSVReader.read_record(@
|
369
|
-
record_reader_without_label = AdHocTemplate::RecordReader.read_record(@
|
495
|
+
csv_reader_without_label = AdHocTemplate::RecordReader::CSVReader.read_record(@tsv_source, :tsv)
|
496
|
+
record_reader_without_label = AdHocTemplate::RecordReader.read_record(@tsv_source, :tsv)
|
370
497
|
|
371
498
|
|
372
499
|
expect(csv_reader).to eq(record_reader)
|
373
500
|
expect(csv_reader_without_label).to eq(record_reader_without_label)
|
374
501
|
end
|
502
|
+
|
503
|
+
it 'TSV.read_record is an alias of CSV.dump except for its default col_sep value' do
|
504
|
+
csv_reader = AdHocTemplate::RecordReader::CSVReader.read_record(@tsv_source, tsv: "subconfigs")
|
505
|
+
tsv_reader = AdHocTemplate::RecordReader::TSVReader.read_record(@tsv_source, "subconfigs")
|
506
|
+
|
507
|
+
expect(tsv_reader).to eq(csv_reader)
|
508
|
+
end
|
509
|
+
end
|
510
|
+
end
|
511
|
+
|
512
|
+
describe AdHocTemplate::RecordReader::DefaultFormReader do
|
513
|
+
before do
|
514
|
+
@config_source = <<CONFIG
|
515
|
+
key1: value1
|
516
|
+
key2: value2
|
517
|
+
key3: value3
|
518
|
+
|
519
|
+
///@#subconfigs
|
520
|
+
|
521
|
+
key1-1: value1-1
|
522
|
+
key1-2: value1-2
|
523
|
+
|
524
|
+
key2-1: value2-1
|
525
|
+
key2-2: value2-2
|
526
|
+
|
527
|
+
///@block
|
528
|
+
|
529
|
+
the first line of block
|
530
|
+
the second line of block
|
531
|
+
|
532
|
+
the second paragraph in block
|
533
|
+
|
534
|
+
CONFIG
|
535
|
+
|
536
|
+
@yaml_source = <<YAML
|
537
|
+
key1: value1
|
538
|
+
key2: value2
|
539
|
+
key3: value3
|
540
|
+
'#subconfigs':
|
541
|
+
- key1-1: value1-1
|
542
|
+
key1-2: value1-2
|
543
|
+
- key2-1: value2-1
|
544
|
+
key2-2: value2-2
|
545
|
+
block: |
|
546
|
+
the first line of block
|
547
|
+
the second line of block
|
548
|
+
|
549
|
+
the second paragraph in block
|
550
|
+
YAML
|
551
|
+
end
|
552
|
+
|
553
|
+
it ',dump accepts non-empty data' do
|
554
|
+
parsed_data = AdHocTemplate::RecordReader::YAMLReader.read_record(@yaml_source)
|
555
|
+
dump_data = AdHocTemplate::RecordReader::DefaultFormReader.dump(parsed_data)
|
556
|
+
expected_data = @config_source.sub(/(#{$/}+)\Z/, $/)
|
557
|
+
|
558
|
+
expect(dump_data).to eq(expected_data)
|
559
|
+
end
|
560
|
+
|
561
|
+
describe 'private methods' do
|
562
|
+
it '.categorize_keys devide keys into 3 groups' do
|
563
|
+
parsed_data = AdHocTemplate::RecordReader::YAMLReader.read_record(@yaml_source)
|
564
|
+
iteration_keys, key_value_keys, block_keys = AdHocTemplate::RecordReader::DefaultFormReader.send :categorize_keys, parsed_data
|
565
|
+
|
566
|
+
expect(iteration_keys).to eq(%w(#subconfigs))
|
567
|
+
expect(key_value_keys).to eq(%w(key1 key2 key3))
|
568
|
+
expect(block_keys).to eq (%w(block))
|
569
|
+
end
|
570
|
+
|
571
|
+
it '.format_key_value_pairs returns a YAML like key-value pairs' do
|
572
|
+
expected_result = <<RESULT
|
573
|
+
key1: value1
|
574
|
+
key2: value2
|
575
|
+
key3: value3
|
576
|
+
RESULT
|
577
|
+
|
578
|
+
parsed_data = AdHocTemplate::RecordReader::YAMLReader.read_record(@yaml_source)
|
579
|
+
iteration_keys, key_value_keys, block_keys = AdHocTemplate::RecordReader::DefaultFormReader.send :categorize_keys, parsed_data
|
580
|
+
format_result = AdHocTemplate::RecordReader::DefaultFormReader.send :format_key_value_pairs, key_value_keys, parsed_data
|
581
|
+
|
582
|
+
expect(format_result).to eq(expected_result)
|
583
|
+
end
|
584
|
+
|
585
|
+
it '.format_key_value_block returns a header with label and multi-line value' do
|
586
|
+
expected_result = <<RESULT
|
587
|
+
///@block
|
588
|
+
|
589
|
+
the first line of block
|
590
|
+
the second line of block
|
591
|
+
|
592
|
+
the second paragraph in block
|
593
|
+
RESULT
|
594
|
+
|
595
|
+
parsed_data = AdHocTemplate::RecordReader::YAMLReader.read_record(@yaml_source)
|
596
|
+
iteration_keys, key_value_keys, block_keys = AdHocTemplate::RecordReader::DefaultFormReader.send :categorize_keys, parsed_data
|
597
|
+
format_result = AdHocTemplate::RecordReader::DefaultFormReader.send :format_key_value_block, block_keys, parsed_data
|
598
|
+
|
599
|
+
expect(format_result).to eq(expected_result)
|
600
|
+
end
|
601
|
+
|
602
|
+
it '.format_iteration_block returns a header and sub-records YAML like key-value pairs' do
|
603
|
+
expected_result = <<RESULT
|
604
|
+
///@#subconfigs
|
605
|
+
|
606
|
+
key1-1: value1-1
|
607
|
+
key1-2: value1-2
|
608
|
+
|
609
|
+
key2-1: value2-1
|
610
|
+
key2-2: value2-2
|
611
|
+
RESULT
|
612
|
+
|
613
|
+
parsed_data = AdHocTemplate::RecordReader::YAMLReader.read_record(@yaml_source)
|
614
|
+
iteration_keys, key_value_keys, block_keys = AdHocTemplate::RecordReader::DefaultFormReader.send :categorize_keys, parsed_data
|
615
|
+
format_result = AdHocTemplate::RecordReader::DefaultFormReader.send :format_iteration_block, iteration_keys, parsed_data
|
616
|
+
|
617
|
+
expect(format_result).to eq(expected_result)
|
618
|
+
end
|
375
619
|
end
|
376
620
|
end
|
377
621
|
end
|