ad_hoc_template 0.3.0 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
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