# -*- coding: utf-8 -*- require "test_helper" require "support/document_xml_helper" require "support/xml_snippets" class ProcessorDocumentTest < Sablon::TestCase include DocumentXMLHelper include XMLSnippets def setup super @processor = Sablon::Processor::Document end def test_simple_field_replacement result = process(snippet("simple_field"), {"first_name" => "Jack"}) assert_equal "Hello! My Name is Jack , nice to meet you.", text(result) assert_xml_equal <<-document, result <w:p> <w:r><w:t xml:space="preserve">Hello! My Name is </w:t></w:r> <w:r w:rsidR="004B49F0"> <w:rPr><w:noProof/></w:rPr> <w:t>Jack</w:t> </w:r> <w:r w:rsidR="00BE47B1"><w:t xml:space="preserve">, nice to meet you.</w:t></w:r> </w:p> document end def test_simple_field_replacement_with_nil result = process(snippet("simple_field"), {"first_name" => nil}) assert_equal "Hello! My Name is , nice to meet you.", text(result) assert_xml_equal <<-document, result <w:p> <w:r><w:t xml:space="preserve">Hello! My Name is </w:t></w:r> <w:r w:rsidR="00BE47B1"><w:t xml:space="preserve">, nice to meet you.</w:t></w:r> </w:p> document end def test_simple_field_with_styling_replacement result = process(snippet("simple_field_with_styling"), {"system_name" => "Sablon 1 million"}) assert_equal "Generated by Sablon 1 million", text(result) assert_xml_equal <<-document, result <w:p> <w:r><w:t xml:space="preserve">Generated by </w:t></w:r> <w:r w:rsidR="002D39A9"> <w:rPr> <w:rFonts w:hint="eastAsia"/> <w:noProof/> </w:rPr> <w:t>Sablon 1 million</w:t> </w:r> </w:p> document end def test_context_can_contain_string_and_symbol_keys result = process(snippet("simple_fields"), {"first_name" => "Jack", last_name: "Davis"}) assert_equal "Jack Davis", text(result) end def test_complex_field_replacement result = process(snippet("complex_field"), {"last_name" => "Zane"}) assert_equal "Hello! My Name is Zane , nice to meet you.", text(result) assert_xml_equal <<-document, result <w:p> <w:r><w:t xml:space="preserve">Hello! My Name is </w:t></w:r> <w:r w:rsidR="004B49F0"> <w:rPr><w:b/><w:noProof/></w:rPr> <w:t>Zane</w:t> </w:r> <w:r w:rsidR="00BE47B1"><w:t xml:space="preserve">, nice to meet you.</w:t></w:r> </w:p> document end def test_complex_field_replacement_with_split_field result = process(snippet("edited_complex_field"), {"first_name" => "Daniel"}) assert_equal "Hello! My Name is Daniel , nice to meet you.", text(result) assert_xml_equal <<-document, result <w:p> <w:r><w:t xml:space="preserve">Hello! My Name is </w:t></w:r> <w:r w:rsidR="00441382"> <w:rPr><w:noProof/></w:rPr> <w:t>Daniel</w:t> </w:r> <w:r w:rsidR="00BE47B1"><w:t xml:space="preserve">, nice to meet you.</w:t></w:r> </w:p> document end def test_paragraph_block_replacement result = process(snippet("paragraph_loop"), {"technologies" => ["Ruby", "Rails"]}) assert_equal "Ruby Rails", text(result) assert_xml_equal <<-document, result <w:p w14:paraId="1081E316" w14:textId="3EAB5FDC" w:rsidR="00380EE8" w:rsidRDefault="00380EE8" w:rsidP="007F5CDE"> <w:pPr> <w:pStyle w:val="ListParagraph"/> <w:numPr> <w:ilvl w:val="0"/> <w:numId w:val="1"/> </w:numPr> </w:pPr> <w:r w:rsidR="009F01DA"> <w:rPr><w:noProof/></w:rPr> <w:t>Ruby</w:t> </w:r> </w:p><w:p w14:paraId="1081E316" w14:textId="3EAB5FDC" w:rsidR="00380EE8" w:rsidRDefault="00380EE8" w:rsidP="007F5CDE"> <w:pPr> <w:pStyle w:val="ListParagraph"/> <w:numPr> <w:ilvl w:val="0"/> <w:numId w:val="1"/> </w:numPr> </w:pPr> <w:r w:rsidR="009F01DA"> <w:rPr><w:noProof/></w:rPr> <w:t>Rails</w:t> </w:r> </w:p> document end def test_paragraph_block_within_table_cell result = process(snippet("paragraph_loop_within_table_cell"), {"technologies" => ["Puppet", "Chef"]}) assert_equal "Puppet Chef", text(result) assert_xml_equal <<-document, result <w:tbl> <w:tblGrid> <w:gridCol w:w="2202"/> </w:tblGrid> <w:tr w:rsidR="00757DAD"> <w:tc> <w:p> <w:r w:rsidR="004B49F0"> <w:rPr><w:noProof/></w:rPr> <w:t>Puppet</w:t> </w:r> </w:p> <w:p> <w:r w:rsidR="004B49F0"> <w:rPr><w:noProof/></w:rPr> <w:t>Chef</w:t> </w:r> </w:p> </w:tc> </w:tr> </w:tbl> document end def test_paragraph_block_within_empty_table_cell_and_blank_replacement result = process(snippet("paragraph_loop_within_table_cell"), {"technologies" => []}) assert_equal "", text(result) assert_xml_equal <<-document, result <w:tbl> <w:tblGrid> <w:gridCol w:w="2202"/> </w:tblGrid> <w:tr w:rsidR="00757DAD"> <w:tc> <w:p></w:p> </w:tc> </w:tr> </w:tbl> document end def test_adds_blank_paragraph_to_empty_table_cells result = process(snippet("corrupt_table"), {}) assert_xml_equal <<-document, result <w:tbl> <w:tblGrid> <w:gridCol w:w="2202"/> </w:tblGrid> <w:tr w:rsidR="00757DAD"> <w:tc> <w:p> Hans </w:p> </w:tc> <w:tc> <w:tcPr> <w:tcW w:w="5635" w:type="dxa"/> </w:tcPr> <w:p></w:p> </w:tc> </w:tr> <w:tr w:rsidR="00757DAD"> <w:tc> <w:tcPr> <w:tcW w:w="2202" w:type="dxa"/> </w:tcPr> <w:p> <w:r> <w:rPr><w:noProof/></w:rPr> <w:t>1.</w:t> </w:r> </w:p> </w:tc> <w:tc> <w:p> </w:p><w:p> <w:r w:rsidR="004B49F0"> <w:rPr><w:noProof/></w:rPr> <w:t>Chef</w:t> </w:r> </w:p> </w:tc> </w:tr> </w:tbl> document end def test_single_row_table_loop item = Struct.new(:index, :label, :rating) result = process(snippet("table_row_loop"), {"items" => [item.new("1.", "Milk", "***"), item.new("2.", "Sugar", "**")]}) assert_xml_equal <<-document, result <w:tbl> <w:tblPr> <w:tblStyle w:val="TableGrid"/> <w:tblW w:w="0" w:type="auto"/> <w:tblLook w:val="04A0" w:firstRow="1" w:lastRow="0" w:firstColumn="1" w:lastColumn="0" w:noHBand="0" w:noVBand="1"/> </w:tblPr> <w:tblGrid> <w:gridCol w:w="2202"/> <w:gridCol w:w="4285"/> <w:gridCol w:w="2029"/> </w:tblGrid> <w:tr w:rsidR="00757DAD" w14:paraId="1BD2E50A" w14:textId="77777777" w:rsidTr="006333C3"> <w:tc> <w:tcPr> <w:tcW w:w="2202" w:type="dxa"/> </w:tcPr> <w:p w14:paraId="41ACB3D9" w14:textId="77777777" w:rsidR="00757DAD" w:rsidRDefault="00757DAD" w:rsidP="006333C3"> <w:r> <w:rPr><w:noProof/></w:rPr> <w:t>1.</w:t> </w:r> </w:p> </w:tc> <w:tc> <w:tcPr> <w:tcW w:w="4285" w:type="dxa"/> </w:tcPr> <w:p w14:paraId="197C6F31" w14:textId="77777777" w:rsidR="00757DAD" w:rsidRDefault="00757DAD" w:rsidP="006333C3"> <w:r> <w:rPr><w:noProof/></w:rPr> <w:t>Milk</w:t> </w:r> </w:p> </w:tc> <w:tc> <w:tcPr> <w:tcW w:w="2029" w:type="dxa"/> </w:tcPr> <w:p w14:paraId="55C258BB" w14:textId="77777777" w:rsidR="00757DAD" w:rsidRDefault="00757DAD" w:rsidP="006333C3"> <w:r> <w:rPr><w:noProof/></w:rPr> <w:t>***</w:t> </w:r> </w:p> </w:tc> </w:tr><w:tr w:rsidR="00757DAD" w14:paraId="1BD2E50A" w14:textId="77777777" w:rsidTr="006333C3"> <w:tc> <w:tcPr> <w:tcW w:w="2202" w:type="dxa"/> </w:tcPr> <w:p w14:paraId="41ACB3D9" w14:textId="77777777" w:rsidR="00757DAD" w:rsidRDefault="00757DAD" w:rsidP="006333C3"> <w:r> <w:rPr><w:noProof/></w:rPr> <w:t>2.</w:t> </w:r> </w:p> </w:tc> <w:tc> <w:tcPr> <w:tcW w:w="4285" w:type="dxa"/> </w:tcPr> <w:p w14:paraId="197C6F31" w14:textId="77777777" w:rsidR="00757DAD" w:rsidRDefault="00757DAD" w:rsidP="006333C3"> <w:r> <w:rPr><w:noProof/></w:rPr> <w:t>Sugar</w:t> </w:r> </w:p> </w:tc> <w:tc> <w:tcPr> <w:tcW w:w="2029" w:type="dxa"/> </w:tcPr> <w:p w14:paraId="55C258BB" w14:textId="77777777" w:rsidR="00757DAD" w:rsidRDefault="00757DAD" w:rsidP="006333C3"> <w:r> <w:rPr><w:noProof/></w:rPr> <w:t>**</w:t> </w:r> </w:p> </w:tc> </w:tr> </w:tbl> document end def test_loop_over_collection_convertable_to_an_enumerable style_collection = Class.new do def to_ary ["CSS", "SCSS", "LESS"] end end result = process(snippet("paragraph_loop"), {"technologies" => style_collection.new}) assert_equal "CSS SCSS LESS", text(result) end def test_loop_over_collection_not_convertable_to_an_enumerable_raises_error not_a_collection = Class.new {} assert_raises Sablon::ContextError do process(snippet("paragraph_loop"), {"technologies" => not_a_collection.new}) end end def test_loop_with_missing_variable_raises_error e = assert_raises Sablon::ContextError do process(snippet("paragraph_loop"), {}) end assert_equal "The expression «technologies» should evaluate to an enumerable but was: nil", e.message end def test_loop_with_missing_end_raises_error e = assert_raises Sablon::TemplateError do process(snippet("loop_without_ending"), {}) end assert_equal "Could not find end field for «technologies:each(technology)». Was looking for «technologies:endEach»", e.message end def test_conditional_with_missing_end_raises_error e = assert_raises Sablon::TemplateError do process(snippet("conditional_without_ending"), {}) end assert_equal "Could not find end field for «middle_name:if». Was looking for «middle_name:endIf»", e.message end def test_multi_row_table_loop item = Struct.new(:index, :label, :body) context = {"foods" => [item.new("1.", "Milk", "Milk is a white liquid."), item.new("2.", "Sugar", "Sugar is the generalized name for carbohydrates.")]} result = process(snippet("table_multi_row_loop"), context) assert_equal "1. Milk Milk is a white liquid. 2. Sugar Sugar is the generalized name for carbohydrates.", text(result) end def test_conditional result = process(snippet("conditional"), {"middle_name" => "Michael"}) assert_equal "Anthony Michael Hall", text(result) result = process(snippet("conditional"), {"middle_name" => nil}) assert_equal "Anthony Hall", text(result) end def test_simple_field_conditional_inline result = process(snippet("conditional_inline"), {"middle_name" => true}) assert_equal "Anthony Michael Hall", text(result) end def test_complex_field_conditional_inline with_false = process(snippet("complex_field_inline_conditional"), {"boolean" => false}) assert_equal "ParagraphBefore Before After ParagraphAfter", text(with_false) with_true = process(snippet("complex_field_inline_conditional"), {"boolean" => true}) assert_equal "ParagraphBefore Before Content After ParagraphAfter", text(with_true) end def test_conditional_with_predicate result = process(snippet("conditional_with_predicate"), {"body" => ""}) assert_equal "some content", text(result) result = process(snippet("conditional_with_predicate"), {"body" => "not empty"}) assert_equal "", text(result) end def test_comment result = process(snippet("comment"), {}) assert_equal "Before After", text(result) end private def process(document, context) @processor.process(wrap(document), context).to_xml end end