/* * Copyright 2003-2011 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package groovy.xml import org.custommonkey.xmlunit.XMLUnit import org.custommonkey.xmlunit.Diff /** * Common test cases for StreamingMarkupBuilder and MarkupBuilder. * * @author Paul King * @author Scott Stirling * @author Pilho Kim */ abstract class BuilderTestSupport extends GroovyTestCase { protected abstract assertExpectedXml(Closure markup, String expectedXml) protected abstract assertExpectedXml(Closure markup, Closure configureBuilder, String expectedXml) protected checkXml(String expectedXml, StringWriter writer) { XMLUnit.ignoreWhitespace = true def xmlDiff = new Diff(expectedXml, writer.toString()) assert xmlDiff.similar(), xmlDiff.toString() + "\n" + writer.toString() } void testHref() { def m = { a(href: "http://groovy.codehaus.org", "groovy") } assertExpectedXml m, "groovy" } void testHrefDoubleQuotes() { def m = { a(href: "http://groovy.codehaus.org", "groovy") } assertExpectedXml m, { it.useDoubleQuotes = true }, 'groovy' } void testNestedQuotesSingle() { def m = { root { one( foo:"bar('baz')", 'foo("baz")' ) two( foo:'bar("baz")', "foo('baz')" ) } } assertExpectedXml m, 'foo("baz")foo(\'baz\')' } void testNestedQuotesDouble() { def m = { root { one( foo:"bar('baz')", 'foo("baz")' ) two( foo:'bar("baz")', "foo('baz')" ) } } assertExpectedXml m, { it.useDoubleQuotes = true }, 'foo("baz")foo(\'baz\')' } void testExpandEmptyElements() { def m = { html { head() body { textarea(left: 40) textarea('') } } } assertExpectedXml m, { it.useDoubleQuotes = true }, '''''' } void testTree() { def m = { root2(a: 5, b: 7) { elem1('hello1') elem2('hello2') nestedElem(x: 'abc', y: 'def') { child(z: 'def') child2() } nestedElem2(z: 'zzz') { child(z: 'def') child2("hello") } } } assertExpectedXml m, '''\ hello1 hello2 hello ''' } /** * Checks against a regression bug whereby some empty elements were not closed. */ void testMarkupForClosingTags() { def list = ['first', 'second', 'third'] def m = { ELEM1() { list.each() {r -> ELEM2(id: r, type: '2') { ELEM3A(id: r) ELEM3B(type: '3', 'text') } } } } assertExpectedXml m, '''\ text text text ''' } void testMixedMarkup() { def m = { // uncomment if you want entities like   (and add to expected too) // mkp.yieldUnescaped '''''' html { body { p { mkp.yield 'The ' i('quick') mkp.yieldUnescaped ' brown fox jumped over the lazy dog & sleepy cat' } } } } assertExpectedXml m, '''\

The quick brown fox jumped over the lazy dog & sleepy cat

''' } void testMixedMarkupWithEntityExpansion() { def m = { p { em('Usually') mkp.yield ' Hearts & Diamonds ' b('beats') mkp.yieldUnescaped ' Spades & Clubs' } } assertExpectedXml m, '''\

Usually Hearts & Diamonds beats Spades & Clubs

''' } void testMixedMarkupWithEmptyNodes() { def m = { p { mkp.yield 'Red: Hearts & Diamonds' br() mkp.yieldUnescaped 'Black: Spades & Clubs' } } assertExpectedXml m, '''\

Red: Hearts & Diamonds\n
Black: Spades & Clubs \n

''' } /** * Tests that the Builder escapes element content correctly, even * when the content contains line-endings. */ void testEscapingMultiLineContent() { def m = { element('''This is multi-line content with characters, such as <, that require escaping. The other characters consist of: * > - greater than * & - ampersand ''') } assertExpectedXml m, '''\ This is multi-line content with characters, such as <, that require escaping. The other characters consist of: * > - greater than * & - ampersand ''' } void testNewlineCarriageReturnTabExpansion() { def m = { root { a( b:'''one\n\r\ttwo''' ) { c( 'one\n\r\ttwo' ) } } } assertExpectedXml m, """one\n\r\ttwo""" } void testObjectOperationsInMarkup() { def m = { root { (1..3).each { item() } } } assertExpectedXml m, "" } /** * Fix for GROOVY-3786 * * yield and yieldUnescaped should call toString() if a non-String object is passed as argument */ void testYieldObjectToStringRepresentation() { def m = { table { td(id: 999) { mkp.yield 999 } td(id: 99) { mkp.yieldUnescaped 99 } } } assertExpectedXml m, "
99999
" } /** * test special builder mkp functionality */ void testSmallTreeWithMkpFunctionality() { def m = { mkp.xmlDeclaration(version: '1.0') mkp.pi("xml-stylesheet": [href: "mystyle.css", type: "text/css"]) root1(a: 5, b: 7) { elem1('hello1') elem2('hello2') mkp.comment('hello3') comment('hello4', [:]) comment(value: 'hello5') comment {} elem3(x: 7) } } assertExpectedXml m, '''\ hello1 hello2 hello4 ''' } }