sablon 0.1.1 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile.lock +2 -2
- data/README.md +36 -5
- data/lib/sablon.rb +0 -3
- data/lib/sablon/configuration/html_tag.rb +1 -1
- data/lib/sablon/content.rb +56 -0
- data/lib/sablon/context.rb +2 -0
- data/lib/sablon/document_object_model/content_types.rb +35 -0
- data/lib/sablon/document_object_model/file_handler.rb +26 -0
- data/lib/sablon/document_object_model/model.rb +94 -0
- data/lib/sablon/document_object_model/numbering.rb +94 -0
- data/lib/sablon/document_object_model/relationships.rb +111 -0
- data/lib/sablon/environment.rb +13 -16
- data/lib/sablon/html/ast.rb +14 -13
- data/lib/sablon/html/ast_builder.rb +18 -5
- data/lib/sablon/html/node_properties.rb +3 -3
- data/lib/sablon/operations.rb +59 -0
- data/lib/sablon/processor/document.rb +48 -11
- data/lib/sablon/processor/section_properties.rb +11 -4
- data/lib/sablon/template.rb +88 -47
- data/lib/sablon/version.rb +1 -1
- data/misc/image-example.png +0 -0
- data/test/configuration_test.rb +22 -22
- data/test/content_test.rb +50 -0
- data/test/context_test.rb +37 -1
- data/test/environment_test.rb +4 -1
- data/test/executable_test.rb +0 -2
- data/test/fixtures/cv_sample.docx +0 -0
- data/test/fixtures/html_sample.docx +0 -0
- data/test/fixtures/images/c3po.jpg +0 -0
- data/test/fixtures/images/clone.jpg +0 -0
- data/test/fixtures/images/darth_vader.jpg +0 -0
- data/test/fixtures/images/r2d2.jpg +0 -0
- data/test/fixtures/images_sample.docx +0 -0
- data/test/fixtures/images_template.docx +0 -0
- data/test/fixtures/loops_sample.docx +0 -0
- data/test/fixtures/loops_template.docx +0 -0
- data/test/fixtures/recipe_sample.docx +0 -0
- data/test/fixtures/xml/image.xml +91 -0
- data/test/fixtures/xml/loop_with_unique_ids.xml +152 -0
- data/test/fixtures/xml/mock_document/word/document.xml +12 -0
- data/test/html/ast_test.rb +10 -5
- data/test/html/converter_style_test.rb +9 -9
- data/test/html/converter_test.rb +66 -81
- data/test/html/node_properties_test.rb +2 -2
- data/test/html_test.rb +2 -6
- data/test/processor/document_test.rb +80 -3
- data/test/processor/section_properties_test.rb +68 -0
- data/test/sablon_test.rb +77 -5
- data/test/test_helper.rb +109 -9
- metadata +33 -9
- data/lib/sablon/numbering.rb +0 -23
- data/lib/sablon/processor/numbering.rb +0 -47
- data/lib/sablon/relationship.rb +0 -47
- data/lib/sablon/test/assertions.rb +0 -22
- data/test/section_properties_test.rb +0 -41
@@ -81,13 +81,13 @@ class NodePropertiesTest < Sablon::TestCase
|
|
81
81
|
props = {}
|
82
82
|
props = Sablon::HTMLConverter::NodeProperties.new('w:pPr', props, @inc_props.new)
|
83
83
|
props['rStyle'] = 'FootnoteText'
|
84
|
-
assert_equal({
|
84
|
+
assert_equal({ rStyle: 'FootnoteText' }, props.instance_variable_get(:@properties))
|
85
85
|
end
|
86
86
|
|
87
87
|
def test_properties_filtered_on_init
|
88
88
|
props = { 'pStyle' => 'Paragraph', 'rStyle' => 'EndnoteText' }
|
89
89
|
props = Sablon::HTMLConverter::NodeProperties.new('w:rPr', props, %w[rStyle])
|
90
|
-
assert_equal({
|
90
|
+
assert_equal({ rStyle: 'EndnoteText' }, props.instance_variable_get(:@properties))
|
91
91
|
end
|
92
92
|
|
93
93
|
def test_transferred_properties
|
data/test/html_test.rb
CHANGED
@@ -3,7 +3,6 @@ require "test_helper"
|
|
3
3
|
require "support/html_snippets"
|
4
4
|
|
5
5
|
class SablonHTMLTest < Sablon::TestCase
|
6
|
-
include Sablon::Test::Assertions
|
7
6
|
include HTMLSnippets
|
8
7
|
|
9
8
|
def setup
|
@@ -14,7 +13,6 @@ class SablonHTMLTest < Sablon::TestCase
|
|
14
13
|
end
|
15
14
|
|
16
15
|
def test_generate_document_from_template_with_styles_and_html
|
17
|
-
uid_generator = UIDTestGenerator.new
|
18
16
|
template_path = @base_path + "fixtures/insertion_template.docx"
|
19
17
|
output_path = @base_path + "sandbox/html.docx"
|
20
18
|
template = Sablon.template template_path
|
@@ -25,9 +23,7 @@ class SablonHTMLTest < Sablon::TestCase
|
|
25
23
|
'html:github' => '<a href="http://www.github.com" style="color: #0000FF">GitHub</a>'
|
26
24
|
}
|
27
25
|
}
|
28
|
-
|
29
|
-
template.render_to_file output_path, context
|
30
|
-
end
|
26
|
+
template.render_to_file output_path, context
|
31
27
|
#
|
32
28
|
assert_docx_equal @sample_path, output_path
|
33
29
|
end
|
@@ -41,7 +37,7 @@ class SablonHTMLTest < Sablon::TestCase
|
|
41
37
|
e = assert_raises(ArgumentError) do
|
42
38
|
template.render_to_file output_path, context
|
43
39
|
end
|
44
|
-
assert_equal
|
40
|
+
assert_equal "Could not find w:abstractNum definition for style: 'ListNumber'", e.message
|
45
41
|
|
46
42
|
skip 'implement default styles'
|
47
43
|
end
|
@@ -311,7 +311,6 @@ class ProcessorDocumentTest < Sablon::TestCase
|
|
311
311
|
</w:tc>
|
312
312
|
</w:tr>
|
313
313
|
</w:tbl>
|
314
|
-
|
315
314
|
document
|
316
315
|
end
|
317
316
|
|
@@ -348,6 +347,22 @@ class ProcessorDocumentTest < Sablon::TestCase
|
|
348
347
|
assert_equal "Could not find end field for «technologies:each(technology)». Was looking for «technologies:endEach»", e.message
|
349
348
|
end
|
350
349
|
|
350
|
+
def test_loop_incrementing_unique_ids
|
351
|
+
context = {
|
352
|
+
fruits: %w[Apple Blueberry Cranberry Date].map { |i| { name: i } },
|
353
|
+
cars: %w[Silverado Serria Ram Tundra].map { |i| { name: i } }
|
354
|
+
}
|
355
|
+
#
|
356
|
+
xml = Nokogiri::XML(process(snippet('loop_with_unique_ids'), context))
|
357
|
+
#
|
358
|
+
# all unique ids should get incremented to stay unique
|
359
|
+
ids = xml.xpath("//*[local-name() = 'docPr']").map { |n| n.attr('id') }
|
360
|
+
assert_equal %w[1 2 3 4], ids
|
361
|
+
#
|
362
|
+
ids = xml.xpath("//*[local-name() = 'cNvPr']").map { |n| n.attr('id') }
|
363
|
+
assert_equal %w[1 2 3 4], ids
|
364
|
+
end
|
365
|
+
|
351
366
|
def test_conditional_with_missing_end_raises_error
|
352
367
|
e = assert_raises Sablon::TemplateError do
|
353
368
|
process(snippet("conditional_without_ending"), {})
|
@@ -446,7 +461,7 @@ class ProcessorDocumentTest < Sablon::TestCase
|
|
446
461
|
assert_xml_equal <<-document, result
|
447
462
|
<w:r><w:t xml:space="preserve">Before </w:t></w:r>
|
448
463
|
<w:r><w:t xml:space="preserve">After </w:t></w:r>
|
449
|
-
<w:p>
|
464
|
+
<w:p>
|
450
465
|
<w:r w:rsidR="004B49F0">
|
451
466
|
<w:rPr><w:noProof/></w:rPr>
|
452
467
|
<w:t>Contents of comment key</w:t>
|
@@ -455,10 +470,72 @@ class ProcessorDocumentTest < Sablon::TestCase
|
|
455
470
|
document
|
456
471
|
end
|
457
472
|
|
473
|
+
def test_image_replacement
|
474
|
+
base_path = Pathname.new(File.expand_path("../../", __FILE__))
|
475
|
+
image = Sablon.content(:image, base_path + "fixtures/images/r2d2.jpg")
|
476
|
+
result = process(snippet("image"), { "item" => { "image" => image } })
|
477
|
+
|
478
|
+
assert_xml_equal <<-document, result
|
479
|
+
<w:p>
|
480
|
+
</w:p>
|
481
|
+
<w:p>
|
482
|
+
<w:r>
|
483
|
+
<w:rPr>
|
484
|
+
<w:noProof/>
|
485
|
+
</w:rPr>
|
486
|
+
<w:drawing>
|
487
|
+
<wp:inline distT="0" distB="0" distL="0" distR="0">
|
488
|
+
<wp:extent cx="1875155" cy="1249045"/>
|
489
|
+
<wp:effectExtent l="0" t="0" r="0" b="0"/>
|
490
|
+
<wp:docPr id="2" name="Picture 2"/>
|
491
|
+
<wp:cNvGraphicFramePr>
|
492
|
+
<a:graphicFrameLocks xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main" noChangeAspect="1"/>
|
493
|
+
</wp:cNvGraphicFramePr>
|
494
|
+
<a:graphic xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main">
|
495
|
+
<a:graphicData uri="http://schemas.openxmlformats.org/drawingml/2006/picture">
|
496
|
+
<pic:pic xmlns:pic="http://schemas.openxmlformats.org/drawingml/2006/picture">
|
497
|
+
<pic:nvPicPr>
|
498
|
+
<pic:cNvPr id="2" name="r2d2.jpg"/>
|
499
|
+
<pic:cNvPicPr/>
|
500
|
+
</pic:nvPicPr>
|
501
|
+
<pic:blipFill>
|
502
|
+
<a:blip r:embed="rId1235\">
|
503
|
+
<a:extLst>
|
504
|
+
<a:ext uri="{28A0092B-C50C-407E-A947-70E740481C1C}">
|
505
|
+
<a14:useLocalDpi xmlns:a14="http://schemas.microsoft.com/office/drawing/2010/main" val="0"/>
|
506
|
+
</a:ext>
|
507
|
+
</a:extLst>
|
508
|
+
</a:blip>
|
509
|
+
<a:stretch>
|
510
|
+
<a:fillRect/>
|
511
|
+
</a:stretch>
|
512
|
+
</pic:blipFill>
|
513
|
+
<pic:spPr>
|
514
|
+
<a:xfrm>
|
515
|
+
<a:off x="0" y="0"/>
|
516
|
+
<a:ext cx="1875155" cy="1249045"/>
|
517
|
+
</a:xfrm>
|
518
|
+
<a:prstGeom prst="rect">
|
519
|
+
<a:avLst/>
|
520
|
+
</a:prstGeom>
|
521
|
+
</pic:spPr>
|
522
|
+
</pic:pic>
|
523
|
+
</a:graphicData>
|
524
|
+
</a:graphic>
|
525
|
+
</wp:inline>
|
526
|
+
</w:drawing>
|
527
|
+
</w:r>
|
528
|
+
</w:p>
|
529
|
+
<w:p>
|
530
|
+
</w:p>
|
531
|
+
document
|
532
|
+
end
|
533
|
+
|
458
534
|
private
|
459
535
|
|
460
536
|
def process(document, context)
|
461
|
-
env = Sablon::Environment.new(
|
537
|
+
env = Sablon::Environment.new(MockTemplate.new, context)
|
538
|
+
env.document.current_entry = 'word/document.xml'
|
462
539
|
@processor.process(wrap(document), env).to_xml
|
463
540
|
end
|
464
541
|
end
|
@@ -0,0 +1,68 @@
|
|
1
|
+
require "test_helper"
|
2
|
+
require "support/document_xml_helper"
|
3
|
+
|
4
|
+
class SectionPropertiesTest < Sablon::TestCase
|
5
|
+
include DocumentXMLHelper
|
6
|
+
|
7
|
+
def setup
|
8
|
+
@env = Sablon::Environment.new(nil, {})
|
9
|
+
end
|
10
|
+
|
11
|
+
def test_process
|
12
|
+
xml = <<-XML
|
13
|
+
<w:body>
|
14
|
+
<w:sectPr w:rsidR="00FC1AFD" w:rsidSect="006745DF">
|
15
|
+
<w:pgSz w:w="11900" w:h="16840"/>
|
16
|
+
<w:pgMar w:top="1440" w:right="1800" w:bottom="1440" w:left="1800" w:header="708" w:footer="708" w:gutter="0"/>
|
17
|
+
<w:pgNumType w:start="1"/>
|
18
|
+
<w:cols w:space="708"/>
|
19
|
+
<w:docGrid w:linePitch="360"/>
|
20
|
+
</w:sectPr>
|
21
|
+
</w:body>
|
22
|
+
XML
|
23
|
+
expected = xml.gsub(/w:start="1"/, 'w:start="123"')
|
24
|
+
xml = wrap(xml)
|
25
|
+
#
|
26
|
+
@env.section_properties = { start_page_number: 123 }
|
27
|
+
Sablon::Processor::SectionProperties.process(xml, @env)
|
28
|
+
#
|
29
|
+
assert_xml_equal expected, xml.to_s
|
30
|
+
end
|
31
|
+
|
32
|
+
def test_assign_start_page_number_with_pgNumType_tag
|
33
|
+
xml = wrap <<-XML
|
34
|
+
<w:body>
|
35
|
+
<w:sectPr w:rsidR="00FC1AFD" w:rsidSect="006745DF">
|
36
|
+
<w:pgSz w:w="11900" w:h="16840"/>
|
37
|
+
<w:pgMar w:top="1440" w:right="1800" w:bottom="1440" w:left="1800" w:header="708" w:footer="708" w:gutter="0"/>
|
38
|
+
<w:pgNumType w:start="1"/>
|
39
|
+
<w:cols w:space="708"/>
|
40
|
+
<w:docGrid w:linePitch="360"/>
|
41
|
+
</w:sectPr>
|
42
|
+
</w:body>
|
43
|
+
XML
|
44
|
+
#
|
45
|
+
properties = Sablon::Processor::SectionProperties.new(xml)
|
46
|
+
assert_equal "1", properties.start_page_number
|
47
|
+
properties.start_page_number = "23"
|
48
|
+
assert_equal "23", properties.start_page_number
|
49
|
+
end
|
50
|
+
|
51
|
+
def test_assign_start_page_number_without_pgNumType_tag
|
52
|
+
xml = wrap <<-XML
|
53
|
+
<w:body>
|
54
|
+
<w:sectPr w:rsidR="00FC1AFD" w:rsidSect="006745DF">
|
55
|
+
<w:pgSz w:w="11900" w:h="16840"/>
|
56
|
+
<w:pgMar w:top="1440" w:right="1800" w:bottom="1440" w:left="1800" w:header="708" w:footer="708" w:gutter="0"/>
|
57
|
+
<w:cols w:space="708"/>
|
58
|
+
<w:docGrid w:linePitch="360"/>
|
59
|
+
</w:sectPr>
|
60
|
+
</w:body>
|
61
|
+
XML
|
62
|
+
#
|
63
|
+
properties = Sablon::Processor::SectionProperties.new(xml)
|
64
|
+
assert_nil properties.start_page_number
|
65
|
+
properties.start_page_number = "16"
|
66
|
+
assert_equal "16", properties.start_page_number
|
67
|
+
end
|
68
|
+
end
|
data/test/sablon_test.rb
CHANGED
@@ -3,7 +3,6 @@ require "test_helper"
|
|
3
3
|
require "support/xml_snippets"
|
4
4
|
|
5
5
|
class SablonTest < Sablon::TestCase
|
6
|
-
include Sablon::Test::Assertions
|
7
6
|
include XMLSnippets
|
8
7
|
|
9
8
|
def setup
|
@@ -24,7 +23,7 @@ class SablonTest < Sablon::TestCase
|
|
24
23
|
referee = Struct.new(:name, :company, :position, :phone)
|
25
24
|
|
26
25
|
context = {
|
27
|
-
current_time:
|
26
|
+
current_time: '15.04.2015 14:57',
|
28
27
|
metadata: { generator: "Sablon" },
|
29
28
|
title: "Resume",
|
30
29
|
person: OpenStruct.new("first_name" => "Ronald", "last_name" => "Anderson",
|
@@ -85,8 +84,7 @@ class SablonTest < Sablon::TestCase
|
|
85
84
|
end
|
86
85
|
end
|
87
86
|
|
88
|
-
class
|
89
|
-
include Sablon::Test::Assertions
|
87
|
+
class SablonConditionalsTest < Sablon::TestCase
|
90
88
|
include XMLSnippets
|
91
89
|
|
92
90
|
def setup
|
@@ -99,7 +97,81 @@ class SablonTest < Sablon::TestCase
|
|
99
97
|
|
100
98
|
def test_generate_document_from_template
|
101
99
|
template = Sablon.template @template_path
|
102
|
-
context = {
|
100
|
+
context = {
|
101
|
+
paragraph: true,
|
102
|
+
inline: true,
|
103
|
+
table: true,
|
104
|
+
table_inline: true,
|
105
|
+
content: "Some Content"
|
106
|
+
}
|
107
|
+
#
|
108
|
+
context = { paragraph: true, inline: true, table: true, table_inline: true, content: "Some Content" }
|
109
|
+
template.render_to_file @output_path, context
|
110
|
+
assert_docx_equal @sample_path, @output_path
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
class SablonLoopsTest < Sablon::TestCase
|
115
|
+
include XMLSnippets
|
116
|
+
|
117
|
+
def setup
|
118
|
+
super
|
119
|
+
@base_path = Pathname.new(File.expand_path("../", __FILE__))
|
120
|
+
@template_path = @base_path + "fixtures/loops_template.docx"
|
121
|
+
@output_path = @base_path + "sandbox/loops.docx"
|
122
|
+
@sample_path = @base_path + "fixtures/loops_sample.docx"
|
123
|
+
end
|
124
|
+
|
125
|
+
def test_generate_document_from_template
|
126
|
+
template = Sablon.template @template_path
|
127
|
+
context = {
|
128
|
+
fruits: %w[Apple Blueberry Cranberry Date].map { |i| { name: i } },
|
129
|
+
cars: %w[Silverado Serria Ram Tundra].map { |i| { name: i } }
|
130
|
+
}
|
131
|
+
|
132
|
+
template.render_to_file @output_path, context
|
133
|
+
assert_docx_equal @sample_path, @output_path
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
class SablonImagesTest < Sablon::TestCase
|
138
|
+
def setup
|
139
|
+
super
|
140
|
+
@base_path = Pathname.new(File.expand_path("../", __FILE__))
|
141
|
+
@template_path = @base_path + "fixtures/images_template.docx"
|
142
|
+
@output_path = @base_path + "sandbox/images.docx"
|
143
|
+
@sample_path = @base_path + "fixtures/images_sample.docx"
|
144
|
+
@image_fixtures = @base_path + "fixtures/images"
|
145
|
+
end
|
146
|
+
|
147
|
+
def test_generate_document_from_template
|
148
|
+
template = Sablon.template @template_path
|
149
|
+
#
|
150
|
+
# setup two image contents to allow quick reuse
|
151
|
+
r2d2 = Sablon.content(:image, @image_fixtures.join('r2d2.jpg').to_s)
|
152
|
+
c3po = Sablon.content(:image, @image_fixtures.join('c3po.jpg'))
|
153
|
+
darth = Sablon.content(:image, @image_fixtures.join('darth_vader.jpg'))
|
154
|
+
#
|
155
|
+
im_data = StringIO.new(IO.binread(@image_fixtures.join('clone.jpg')))
|
156
|
+
trooper = Sablon.content(:image, im_data, filename: 'clone.jpg')
|
157
|
+
#
|
158
|
+
# with the following context setup all trooper should be reused and
|
159
|
+
# only a single file added to media. R2D2 should get duplicated in the
|
160
|
+
# media folder because it is used in two different context keys as
|
161
|
+
# separate instances. Darth Vader should not be duplicated because
|
162
|
+
# the ket "unused_darth" doesn't appear in the template
|
163
|
+
context = {
|
164
|
+
items: [
|
165
|
+
{ title: 'C-3PO', image: c3po },
|
166
|
+
{ title: 'R2-D2', image: r2d2 },
|
167
|
+
{ title: 'Darth Vader', 'image:image' => @image_fixtures.join('darth_vader.jpg') },
|
168
|
+
{ title: 'Storm Trooper', image: trooper }
|
169
|
+
],
|
170
|
+
'image:r2d2' => @image_fixtures.join('r2d2.jpg'),
|
171
|
+
'unused_darth' => darth,
|
172
|
+
trooper: trooper
|
173
|
+
}
|
174
|
+
|
103
175
|
template.render_to_file @output_path, context
|
104
176
|
assert_docx_equal @sample_path, @output_path
|
105
177
|
end
|
data/test/test_helper.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
require "bundler/setup"
|
2
|
-
|
2
|
+
require 'minitest/assertions'
|
3
3
|
require "minitest/autorun"
|
4
4
|
require "minitest/mock"
|
5
5
|
require "xmlsimple"
|
@@ -8,26 +8,126 @@ require "pathname"
|
|
8
8
|
|
9
9
|
$: << File.expand_path('../../lib', __FILE__)
|
10
10
|
require "sablon"
|
11
|
-
|
11
|
+
|
12
|
+
module Minitest
|
13
|
+
module Assertions
|
14
|
+
def assert_docx_equal(expected_path, actual_path)
|
15
|
+
#
|
16
|
+
# Parse document archives and generate a diff
|
17
|
+
xml_diffs = diff_docx_files(expected_path, actual_path)
|
18
|
+
#
|
19
|
+
# build error message
|
20
|
+
msg = 'The generated document does not match the sample. Please investigate file(s): '
|
21
|
+
msg += xml_diffs.keys.sort.join(', ')
|
22
|
+
xml_diffs.each do |name, diff_text|
|
23
|
+
msg += "\n#{'-' * 72}\nFile: #{name}\n#{diff_text}\n"
|
24
|
+
end
|
25
|
+
msg += '-' * 72 + "\n"
|
26
|
+
msg += "If the generated document is correct, the sample needs to be updated:\n"
|
27
|
+
msg += "\t cp #{actual_path} #{expected_path}"
|
28
|
+
#
|
29
|
+
raise Minitest::Assertion, msg unless xml_diffs.empty?
|
30
|
+
end
|
31
|
+
|
32
|
+
# Returns a hash of all XML files that differ in the docx file. This
|
33
|
+
# only checks files that have the extension ".xml" or ".rels".
|
34
|
+
def diff_docx_files(expected_path, actual_path)
|
35
|
+
expected = parse_docx(expected_path)
|
36
|
+
actual = parse_docx(actual_path)
|
37
|
+
xml_diffs = {}
|
38
|
+
#
|
39
|
+
expected.each do |entry_name, expect|
|
40
|
+
next unless entry_name =~ /.xml$|.rels$/
|
41
|
+
next unless expect != actual[entry_name]
|
42
|
+
#
|
43
|
+
xml_diffs[entry_name] = diff(expect, actual[entry_name])
|
44
|
+
end
|
45
|
+
#
|
46
|
+
xml_diffs
|
47
|
+
end
|
48
|
+
|
49
|
+
def parse_docx(path)
|
50
|
+
contents = {}
|
51
|
+
#
|
52
|
+
# step over all entries adding them to the hash to diff against
|
53
|
+
Zip::File.open(path).each do |entry|
|
54
|
+
next unless entry.file?
|
55
|
+
content = entry.get_input_stream.read
|
56
|
+
# normalize xml content
|
57
|
+
if entry.name =~ /.xml$|.rels$/
|
58
|
+
content = Nokogiri::XML(content).to_xml(indent: 2)
|
59
|
+
end
|
60
|
+
contents[entry.name] = content
|
61
|
+
end
|
62
|
+
#
|
63
|
+
contents
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
12
67
|
|
13
68
|
class Sablon::TestCase < MiniTest::Test
|
14
69
|
def teardown
|
15
70
|
super
|
16
71
|
end
|
17
72
|
|
18
|
-
class
|
73
|
+
class MockTemplate
|
74
|
+
attr_reader :document
|
75
|
+
|
76
|
+
def initialize
|
77
|
+
@path = nil
|
78
|
+
@document = MockDomModel.new
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
# catch all for method stubs that are needed during testing
|
83
|
+
class MockDomModel
|
84
|
+
attr_accessor :current_entry
|
85
|
+
attr_reader :current_rid, :zip_contents
|
86
|
+
|
87
|
+
# Simple class to reload mock document components from fixtures on demand
|
88
|
+
class ZipContents
|
89
|
+
def [](entry_name)
|
90
|
+
load_mock_content(entry_name)
|
91
|
+
end
|
92
|
+
|
93
|
+
private
|
94
|
+
|
95
|
+
# Loads and parses individual files to build the mock document
|
96
|
+
def load_mock_content(entry_name)
|
97
|
+
root = Pathname.new(File.dirname(__FILE__))
|
98
|
+
xml_path = root.join('fixtures', 'xml', 'mock_document', entry_name)
|
99
|
+
Nokogiri::XML(File.read(xml_path))
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
19
103
|
def initialize
|
20
|
-
@
|
21
|
-
@
|
104
|
+
@current_entry = nil
|
105
|
+
@current_rid = 1234
|
106
|
+
@current_rid_start = @current_rid
|
107
|
+
@current_numid = 0
|
108
|
+
@current_numid_start = @current_numid
|
109
|
+
@zip_contents = ZipContents.new
|
110
|
+
end
|
111
|
+
|
112
|
+
# Returns the corresponding DOM handled file
|
113
|
+
def [](entry_name)
|
114
|
+
Sablon::DOM.wrap_with_handler(entry_name, @zip_contents[entry_name])
|
22
115
|
end
|
23
116
|
|
24
|
-
def
|
25
|
-
@
|
26
|
-
|
117
|
+
def add_relationship(*)
|
118
|
+
"rId#{@current_rid += 1}"
|
119
|
+
end
|
120
|
+
|
121
|
+
def add_list_definition(style)
|
122
|
+
@current_numid += 1
|
123
|
+
Struct.new(:style, :numid).new(style, @current_numid)
|
27
124
|
end
|
28
125
|
|
29
126
|
def reset
|
30
|
-
@
|
127
|
+
@current_rid = @current_rid_start
|
128
|
+
@current_numid = @current_numid_start
|
31
129
|
end
|
130
|
+
|
131
|
+
alias add_media add_relationship
|
32
132
|
end
|
33
133
|
end
|