sablon 0.1.1 → 0.2.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/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
|