ad_hoc_template 0.3.0 → 0.4.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.
Files changed (48) hide show
  1. checksums.yaml +4 -4
  2. data/ad_hoc_template.gemspec +1 -1
  3. data/lib/ad_hoc_template/command_line_interface.rb +53 -26
  4. data/lib/ad_hoc_template/config_manager.rb +129 -0
  5. data/lib/ad_hoc_template/default_tag_formatter.rb +6 -1
  6. data/lib/ad_hoc_template/entry_format_generator.rb +83 -12
  7. data/lib/ad_hoc_template/parser.rb +64 -59
  8. data/lib/ad_hoc_template/recipe_manager.rb +168 -0
  9. data/lib/ad_hoc_template/record_reader.rb +73 -16
  10. data/lib/ad_hoc_template/utils.rb +29 -0
  11. data/lib/ad_hoc_template/version.rb +1 -1
  12. data/lib/ad_hoc_template.rb +77 -25
  13. data/samples/en/inner_iteration/data.aht +21 -0
  14. data/samples/en/inner_iteration/data.csv +5 -0
  15. data/samples/en/inner_iteration/data.yaml +14 -0
  16. data/samples/en/inner_iteration/data2.yaml +14 -0
  17. data/samples/en/inner_iteration/for_csv.sh +3 -0
  18. data/samples/en/inner_iteration/template.html +18 -0
  19. data/samples/en/recipe/main.aht +9 -0
  20. data/samples/en/recipe/template.html +20 -0
  21. data/samples/for_recipe.sh +3 -0
  22. data/samples/ja/inner_iteration/data.aht +21 -0
  23. data/samples/ja/inner_iteration/data.csv +5 -0
  24. data/samples/ja/inner_iteration/data.yaml +14 -0
  25. data/samples/ja/inner_iteration/data2.yaml +14 -0
  26. data/samples/ja/inner_iteration/for_csv.sh +3 -0
  27. data/samples/ja/inner_iteration/template.html +18 -0
  28. data/samples/ja/recipe/main.aht +9 -0
  29. data/samples/ja/recipe/template.html +20 -0
  30. data/samples/recipe.yaml +34 -0
  31. data/spec/ad_hoc_template_spec.rb +71 -1
  32. data/spec/command_line_interface_spec.rb +105 -11
  33. data/spec/config_manager_spec.rb +142 -0
  34. data/spec/default_tag_formatter_spec.rb +13 -0
  35. data/spec/entry_format_generator_spec.rb +160 -17
  36. data/spec/parser_spec.rb +64 -20
  37. data/spec/recipe_manager_spec.rb +419 -0
  38. data/spec/record_reader_spec.rb +122 -1
  39. data/spec/test_data/en/inner_iteration/data.csv +5 -0
  40. data/spec/test_data/en/recipe/expected_result.html +32 -0
  41. data/spec/test_data/en/recipe/main.aht +9 -0
  42. data/spec/test_data/en/recipe/template.html +20 -0
  43. data/spec/test_data/ja/inner_iteration/data.csv +5 -0
  44. data/spec/test_data/ja/recipe/expected_result.html +32 -0
  45. data/spec/test_data/ja/recipe/main.aht +9 -0
  46. data/spec/test_data/ja/recipe/template.html +20 -0
  47. data/spec/test_data/recipe.yaml +34 -0
  48. metadata +47 -4
@@ -2,9 +2,10 @@
2
2
 
3
3
  require 'spec_helper'
4
4
  require 'ad_hoc_template'
5
+ require 'stringio'
5
6
 
6
7
  describe AdHocTemplate do
7
- describe AdHocTemplate::EntryFormatGenerator::LabelChecker do
8
+ describe AdHocTemplate::EntryFormatGenerator do
8
9
  before do
9
10
  @template = <<TEMPLATE
10
11
  The first line in the main part
@@ -39,15 +40,17 @@ TEMPLATE
39
40
  "block" => nil}
40
41
  end
41
42
 
42
- it 'collects tag labels from a parsed template' do
43
- tree = AdHocTemplate::Parser.parse(@template)
44
- label_checker = AdHocTemplate::EntryFormatGenerator::LabelChecker.new
45
- tree.accept(label_checker)
46
- labels = label_checker.labels
47
- expect(labels).to eq(@expected_labels_as_ruby_objects)
43
+ describe AdHocTemplate::EntryFormatGenerator::LabelChecker do
44
+ it 'collects tag labels from a parsed template' do
45
+ tree = AdHocTemplate::Parser.parse(@template)
46
+ label_checker = AdHocTemplate::EntryFormatGenerator::LabelChecker.new
47
+ tree.accept(label_checker)
48
+ labels = label_checker.labels
49
+ expect(labels).to eq(@expected_labels_as_ruby_objects)
50
+ end
48
51
  end
49
52
 
50
- it '.extract_labels collects tag labels from a parsed template' do
53
+ it '.extract_form collects tag labels from a parsed template' do
51
54
  expected_labels_in_default_format = <<YAML
52
55
  key:
53
56
  optional1:
@@ -61,12 +64,12 @@ key2:
61
64
  YAML
62
65
 
63
66
  tree = AdHocTemplate::Parser.parse(@template)
64
- labels = AdHocTemplate::EntryFormatGenerator.extract_labels(tree)
67
+ labels = AdHocTemplate::EntryFormatGenerator.extract_form(tree)
65
68
 
66
69
  expect(labels).to eq(expected_labels_in_default_format)
67
70
  end
68
71
 
69
- it '.extract_labels should ignore fallback tags if they do not any contain value tag' do
72
+ it '.extract_form should ignore fallback tags if they do not any contain value tag' do
70
73
  template = <<TEMPLATE
71
74
  main start
72
75
  <%#
@@ -88,12 +91,12 @@ var2:
88
91
  EXPECTED
89
92
 
90
93
  tree = AdHocTemplate::Parser.parse(template)
91
- labels = AdHocTemplate::EntryFormatGenerator.extract_labels(tree)
94
+ labels = AdHocTemplate::EntryFormatGenerator.extract_form(tree)
92
95
 
93
96
  expect(labels).to eq(expected)
94
97
  end
95
98
 
96
- it '.extract_labels should labels in fallback tags' do
99
+ it '.extract_form should collect labels in fallback tags' do
97
100
  template = <<TEMPLATE
98
101
  main start
99
102
  <%#
@@ -117,12 +120,12 @@ var2:
117
120
  EXPECTED
118
121
 
119
122
  tree = AdHocTemplate::Parser.parse(template)
120
- labels = AdHocTemplate::EntryFormatGenerator.extract_labels(tree)
123
+ labels = AdHocTemplate::EntryFormatGenerator.extract_form(tree)
121
124
 
122
125
  expect(labels).to eq(expected)
123
126
  end
124
127
 
125
- it '.extract_labels accepts :yaml as its second argument' do
128
+ it '.extract_form accepts :yaml as its second argument' do
126
129
  expected_labels_in_yaml = <<YAML
127
130
  ---
128
131
  key:
@@ -135,12 +138,12 @@ block:
135
138
  YAML
136
139
 
137
140
  tree = AdHocTemplate::Parser.parse(@template)
138
- labels = AdHocTemplate::EntryFormatGenerator.extract_labels(tree, :yaml)
141
+ labels = AdHocTemplate::EntryFormatGenerator.extract_form(tree, :yaml)
139
142
 
140
143
  expect(labels).to eq(expected_labels_in_yaml)
141
144
  end
142
145
 
143
- it '.extract_labels accepts :json as its second argument' do
146
+ it '.extract_form accepts :json as its second argument' do
144
147
  expected_labels_in_json = <<JSON
145
148
  {
146
149
  "key":null,
@@ -155,9 +158,149 @@ YAML
155
158
  JSON
156
159
 
157
160
  tree = AdHocTemplate::Parser.parse(@template)
158
- labels = AdHocTemplate::EntryFormatGenerator.extract_labels(tree, :json)
161
+ labels = AdHocTemplate::EntryFormatGenerator.extract_form(tree, :json)
159
162
 
160
163
  expect(JSON.parse(labels)).to eq(JSON.parse(expected_labels_in_json))
161
164
  end
165
+
166
+ it '.extract_form should extract labels from nested iteration tags' do
167
+ template =<<TEMPLATE
168
+ <%#authors:
169
+ Name: <%= name %>
170
+ Birthplace: <%= birthplace %>
171
+ Works:
172
+ <%#works|name:
173
+ * <%= title %>
174
+ #%>
175
+
176
+ <%#
177
+ <%#bio|name:
178
+ Born: <%= birth_date %>
179
+ #%>
180
+ #%>
181
+
182
+ #%>
183
+ TEMPLATE
184
+
185
+ expected_result =<<RESULT
186
+
187
+ ///@#authors
188
+
189
+ name:
190
+ birthplace:
191
+
192
+ ///@#authors|works|name
193
+
194
+ title:
195
+
196
+ ///@#authors|bio|name
197
+
198
+ birth_date:
199
+ RESULT
200
+
201
+ tree = AdHocTemplate::Parser.parse(template)
202
+ labels = AdHocTemplate::EntryFormatGenerator.extract_form(tree)
203
+
204
+ expect(labels).to eq(expected_result)
205
+ end
206
+
207
+ it '.extract_iteration_labels collects iteration labels in a template' do
208
+ template =<<TEMPLATE
209
+ <%#authors:
210
+ Name: <%= name %>
211
+ Birthplace: <%= birthplace %>
212
+ Works:
213
+ <%#works|name:
214
+ * <%= title %>
215
+ #%>
216
+
217
+ <%#
218
+ <%#bio|name:
219
+ Born: <%= birth_date %>
220
+ #%>
221
+ #%>
222
+
223
+ #%>
224
+ TEMPLATE
225
+
226
+ tree = AdHocTemplate::Parser.parse(template)
227
+ labels = AdHocTemplate::EntryFormatGenerator.extract_iteration_labels(tree)
228
+
229
+ expect(labels).to eq(["#authors", "#authors|works|name", "#authors|bio|name"])
230
+ end
231
+
232
+ it '.extract_recipe generates a recipe entry for a given template' do
233
+ template =<<TEMPLATE
234
+ <%#authors:
235
+ Name: <%= name %>
236
+ Birthplace: <%= birthplace %>
237
+ Works:
238
+ <%#works|name:
239
+ * <%= title %>
240
+ #%>
241
+
242
+ <%#
243
+ <%#bio|name:
244
+ Born: <%= birth_date %>
245
+ #%>
246
+ #%>
247
+
248
+ #%>
249
+ TEMPLATE
250
+
251
+ expected_recipe = <<RECIPE
252
+ ---
253
+ template: template.html
254
+ tag_type: :default
255
+ template_encoding: UTF-8
256
+ data:
257
+ data_format:
258
+ data_encoding:
259
+ output_file:
260
+ blocks:
261
+ - label: "#authors"
262
+ data:
263
+ data_format:
264
+ data_encoding:
265
+ - label: "#authors|works|name"
266
+ data:
267
+ data_format:
268
+ data_encoding:
269
+ - label: "#authors|bio|name"
270
+ data:
271
+ data_format:
272
+ data_encoding:
273
+ RECIPE
274
+
275
+ recipe = AdHocTemplate::EntryFormatGenerator.extract_recipe(template, 'template.html')
276
+ expect(recipe).to eq(expected_recipe)
277
+ end
278
+
279
+ it '.extract_recipes_from_template_files' do
280
+ recipe_entry = <<RECIPE
281
+ ---
282
+ template: template1.html
283
+ tag_type: :default
284
+ template_encoding: UTF-8
285
+ data:
286
+ data_format:
287
+ data_encoding:
288
+ output_file:
289
+ blocks:
290
+ - label: "#iteration_block"
291
+ data:
292
+ data_format:
293
+ data_encoding:
294
+ RECIPE
295
+ recipe_entry2 = recipe_entry.sub(/template1\.html/, 'template2.html')
296
+
297
+ template_names = %w(template1.html template2.html)
298
+ template_names.each do |template_name|
299
+ allow(AdHocTemplate::EntryFormatGenerator).to receive(:open).with(File.expand_path(template_name)).and_yield(StringIO.new(@template))
300
+ end
301
+
302
+ result = AdHocTemplate::EntryFormatGenerator.extract_recipes_from_template_files(template_names)
303
+ expect(result).to eq(recipe_entry + recipe_entry2)
304
+ end
162
305
  end
163
306
  end
data/spec/parser_spec.rb CHANGED
@@ -29,7 +29,7 @@ describe AdHocTemplate do
29
29
  [" "]],
30
30
  [" and "],
31
31
  [[" another tag "]]])
32
- expect(tree[1]).to be_a_kind_of(AdHocTemplate::Parser::IterationTagNode)
32
+ expect(tree[1]).to be_a_kind_of(AdHocTemplate::Parser::IterationNode)
33
33
  end
34
34
 
35
35
  it "may contain lines that consist only of an iteration tag" do
@@ -122,7 +122,7 @@ TEMPLATE
122
122
  [" "]],
123
123
  [" and "],
124
124
  [[" another tag "]]])
125
- expect(tree[1]).to be_a_kind_of(AdHocTemplate::Parser::IterationTagNode)
125
+ expect(tree[1]).to be_a_kind_of(AdHocTemplate::Parser::IterationNode)
126
126
  end
127
127
 
128
128
  it "may contain lines that consist only of an iteration tag" do
@@ -163,7 +163,7 @@ content
163
163
  [" "]],
164
164
  [" and "],
165
165
  [[" another tag "]]])
166
- expect(tree[1]).to be_a_kind_of(AdHocTemplate::Parser::IterationTagNode)
166
+ expect(tree[1]).to be_a_kind_of(AdHocTemplate::Parser::IterationNode)
167
167
  end
168
168
 
169
169
  it "may contain lines that consist only of an iteration tag" do
@@ -180,12 +180,12 @@ content
180
180
  end
181
181
  end
182
182
 
183
- it("spaces at the head of a line should be preserved when the line is just after a start tag of IterationTagNode") do
183
+ it("spaces at the head of a line should be preserved when the line is just after a start tag of IterationNode") do
184
184
  tree = AdHocTemplate::Parser.parse("<%#iteration:\n the second line\nthe third line")
185
185
  expect(tree).to eq([[[" the second line\nthe third line"]]])
186
186
  end
187
187
 
188
- it("should not add a newline at the head of IterationTagNode when the type of the node is not specified") do
188
+ it("should not add a newline at the head of IterationNode when the type of the node is not specified") do
189
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#%>")
190
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"]]]])
191
191
  end
@@ -214,7 +214,7 @@ content
214
214
  [" "]],
215
215
  [" and "],
216
216
  [[" another tag "]]])
217
- expect(tree[1]).to be_a_kind_of(AdHocTemplate::Parser::IterationTagNode)
217
+ expect(tree[1]).to be_a_kind_of(AdHocTemplate::Parser::IterationNode)
218
218
  end
219
219
 
220
220
  it "may contain lines that consist only of an iteration tag" do
@@ -230,12 +230,12 @@ content
230
230
  expect(tree).to eq([])
231
231
  end
232
232
 
233
- it("spaces at the head of a line should be preserved when the line is just after a start tag of IterationTagNode") do
233
+ it("spaces at the head of a line should be preserved when the line is just after a start tag of IterationNode") do
234
234
  tree = AdHocTemplate::Parser.parse("<iterate>iteration:\n the second line\nthe third line</iterate>", :xml_like1)
235
235
  expect(tree).to eq([[[" the second line\nthe third line"]]])
236
236
  end
237
237
 
238
- it("should not add a newline at the head of IterationTagNode when the type of the node is not specified") do
238
+ it("should not add a newline at the head of IterationNode when the type of the node is not specified") do
239
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)
240
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"]]]])
241
241
  end
@@ -290,7 +290,7 @@ TEMPLATE
290
290
  [" "]],
291
291
  [" and "],
292
292
  [[" another tag "]]])
293
- expect(tree[1]).to be_a_kind_of(AdHocTemplate::Parser::IterationTagNode)
293
+ expect(tree[1]).to be_a_kind_of(AdHocTemplate::Parser::IterationNode)
294
294
  end
295
295
 
296
296
  it "may contain lines that consist only of an iteration tag" do
@@ -306,12 +306,12 @@ content
306
306
  expect(tree).to eq([])
307
307
  end
308
308
 
309
- it("spaces at the head of a line should be preserved when the line is just after a start tag of IterationTagNode") do
309
+ it("spaces at the head of a line should be preserved when the line is just after a start tag of IterationNode") do
310
310
  tree = AdHocTemplate::Parser.parse("<iterate>iteration:\n the second line\nthe third line</iterate>", :xml_like2)
311
311
  expect(tree).to eq([[[" the second line\nthe third line"]]])
312
312
  end
313
313
 
314
- it("should not add a newline at the head of IterationTagNode when the type of the node is not specified") do
314
+ it("should not add a newline at the head of IterationNode when the type of the node is not specified") do
315
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)
316
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"]]]])
317
317
  end
@@ -341,7 +341,7 @@ content
341
341
  [" "]],
342
342
  [" and "],
343
343
  [[" another tag "]]])
344
- expect(tree[1]).to be_a_kind_of(AdHocTemplate::Parser::IterationTagNode)
344
+ expect(tree[1]).to be_a_kind_of(AdHocTemplate::Parser::IterationNode)
345
345
  end
346
346
 
347
347
  it "may contain lines that consist only of an iteration tag" do
@@ -357,12 +357,12 @@ content
357
357
  expect(tree).to eq([])
358
358
  end
359
359
 
360
- it("spaces at the head of a line should be preserved when the line is just after a start tag of IterationTagNode") do
360
+ it("spaces at the head of a line should be preserved when the line is just after a start tag of IterationNode") do
361
361
  tree = AdHocTemplate::Parser.parse("<!--%iterate%-->iteration:\n the second line\nthe third line<!--%/iterate%-->", :xml_comment_like)
362
362
  expect(tree).to eq([[[" the second line\nthe third line"]]])
363
363
  end
364
364
 
365
- it("should not add a newline at the head of IterationTagNode when the type of the node is not specified") do
365
+ it("should not add a newline at the head of IterationNode when the type of the node is not specified") do
366
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)
367
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"]]]])
368
368
  end
@@ -427,7 +427,7 @@ iteration_tag: ["<repeat>", "</repeat>"]
427
427
  fallback_tag: ["<fallback>", "</fallback>"]
428
428
  remove_indent: true
429
429
  CONFIG
430
- iteration_tag_node = AdHocTemplate::Parser::IterationTagNode
430
+ iteration_tag_node = AdHocTemplate::Parser::IterationNode
431
431
  AdHocTemplate::Parser.register_user_defined_tag_type(tag_type_config)
432
432
  defined_tag_type = AdHocTemplate::Parser::TagType[:xml_like3]
433
433
  expect(defined_tag_type.head_of[iteration_tag_node]).to eq('<repeat>')
@@ -452,11 +452,14 @@ CONFIG
452
452
 
453
453
  describe "#contains_any_value_tag?" do
454
454
  it 'return true if any value tag is contained' do
455
- template_with_value_tag =<<TEMPLATE
455
+ template_with_value_tag =<<TEMPLATE
456
456
  main start
457
457
 
458
458
  <%#
459
459
  <%*
460
+ line without value tag
461
+ *%>
462
+ <%*
460
463
  line with <%= value tag %>
461
464
  *%>
462
465
  #%>
@@ -469,7 +472,7 @@ TEMPLATE
469
472
  end
470
473
 
471
474
  it 'return false if no value tag is contained' do
472
- template_without_value_tag =<<TEMPLATE
475
+ template_without_value_tag =<<TEMPLATE
473
476
  main start
474
477
 
475
478
  <%#
@@ -488,8 +491,49 @@ TEMPLATE
488
491
  end
489
492
  end
490
493
 
491
- describe AdHocTemplate::Parser::FallbackTagNode do
492
- it 'is expected to be parsed like IterationTagNode -- used inline' do
494
+ describe "#inner_iteration_tag_labels" do
495
+ it "returns labels of inner iteration tags" do
496
+ template =<<TEMPLATE
497
+ <%#authors:
498
+ Name: <%= name %>
499
+ Birthplace: <%= birthplace %>
500
+ Works:
501
+ <%#works|name:
502
+ * <%= title %>
503
+ <%#
504
+ <%#bio|name:
505
+ Born: <%= birth_date %>
506
+ #%>
507
+ #%>
508
+ #%>
509
+
510
+ #%>
511
+ TEMPLATE
512
+
513
+ tree = AdHocTemplate::Parser.parse(template)
514
+ expect(tree[0].inner_iteration_tag_labels).to eq (%w(#works|name #bio|name))
515
+ end
516
+
517
+ it "returns nil when there is no inner iteration tags" do
518
+ template =<<TEMPLATE
519
+ <%#
520
+ Name: <%= name %>
521
+ Birthplace: <%= birthplace %>
522
+ Works:
523
+ * <%= title %>
524
+ <%#
525
+ Born: <%= birth_date %>
526
+ #%>
527
+ #%>
528
+ TEMPLATE
529
+
530
+ tree = AdHocTemplate::Parser.parse(template)
531
+ expect(tree[0].inner_iteration_tag_labels).to be_nil
532
+ end
533
+ end
534
+
535
+ describe AdHocTemplate::Parser::FallbackNode do
536
+ it 'is expected to be parsed like IterationNode -- used inline' do
493
537
  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
538
  expected_tree = [
495
539
  ["main start "],
@@ -513,7 +557,7 @@ TEMPLATE
513
557
  fallback = tree[1][1]
514
558
 
515
559
  expect(tree).to eq(expected_tree)
516
- expect(fallback).to be_kind_of(AdHocTemplate::Parser::FallbackTagNode)
560
+ expect(fallback).to be_kind_of(AdHocTemplate::Parser::FallbackNode)
517
561
  end
518
562
  end
519
563
  end