/*
 * $Id: XMLStreamUtilsTest.java,v 1.2 2004-05-25 15:22:28 cniles Exp $
 * 
 * Copyright (c) 2004, Christian Niles, Unit12
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 * 
 *              *   Redistributions of source code must retain the above copyright
 *          notice, this list of conditions and the following disclaimer.
 * 
 *          *   Redistributions in binary form must reproduce the above copyright
 *          notice, this list of conditions and the following disclaimer in the
 *          documentation and/or other materials provided with the distribution.
 * 
 *      *   Neither the name of Christian Niles, Unit12, nor the names of its
 *          contributors may be used to endorse or promote products derived from
 *          this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 * 
 */
package javanet.staxutils;

import java.io.InputStream;

import javax.xml.namespace.QName;
import javax.xml.stream.XMLEventReader;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;
import javax.xml.stream.events.StartElement;
import javax.xml.stream.events.XMLEvent;

import junit.framework.TestCase;

/**
 * @author christian
 * @version $Revision: 1.2 $
 */
public class XMLStreamUtilsTest extends TestCase {

    /**
     * Constructor for XMLStreamUtilsTest.
     * @param arg0
     */
    public XMLStreamUtilsTest(String arg0) {

        super(arg0);
    }

    public void testSkipStreamElement() throws XMLStreamException {

        XMLStreamReader reader = getSampleXMLStreamReader();
        try {

            while (!reader.isStartElement() && reader.hasNext()) {

                reader.next();

            }

            assertTrue("Reader didn't get to root", reader.isStartElement());
            XMLStreamUtils.skipElement(reader);

            assertTrue("Didn't end in an end-element state",
                    reader.isEndElement());
            assertEquals("Didn't end on end person tag", new QName("person"),
                    reader.getName());

        } finally {

            reader.close();

        }

    }

    public void testSkipElementEvents() throws XMLStreamException {

        XMLEventReader reader = getSampleXMLEventReader();
        try {

            StartElement rootElem = XMLStreamUtils.nextElement(reader);
            reader.nextEvent(); // consume start tag

            // skip name element
            StartElement nameElem = XMLStreamUtils.nextElement(reader);
            XMLStreamUtils.skipElement(reader);

            StartElement phoneElem = XMLStreamUtils.nextElement(reader);
            assertNotNull("phone tag was null", phoneElem);
            assertEquals("Expected phone start tag", new QName("phone"),
                    phoneElem.getName());

            reader.nextEvent();
            XMLStreamUtils.skipElementContent(reader);
            assertTrue("expected phone end tag", reader.nextEvent()
                    .isEndElement());

            StartElement addrElem = XMLStreamUtils.nextElement(reader);
            assertNotNull("address tag was null", addrElem);
            assertEquals("Expected address start tag", new QName("address"),
                    addrElem.getName());

        } finally {

            reader.close();

        }

    }

    public void testReadTextElement() throws XMLStreamException {

        XMLEventReader reader = getSampleXMLEventReader();
        try {

            StartElement rootElem = XMLStreamUtils.nextElement(reader);
            reader.nextEvent(); // consume start tag

            StartElement nameElem = XMLStreamUtils.nextElement(reader);
            String name = XMLStreamUtils.readTextElement(reader, null);
            assertEquals("Name didn't match", "John Doe", name);

            StartElement phoneElem = XMLStreamUtils.nextElement(reader);
            assertNotNull("phone tag was null", phoneElem);

        } finally {

            reader.close();

        }

    }

    public void testNextTag() throws XMLStreamException {

        XMLEventReader reader = getSampleXMLEventReader();
        try {

            XMLEvent rootTag = XMLStreamUtils.nextTag(reader);

            assertTrue("root tag wasn't StartElement", rootTag.isStartElement());
            assertEquals("stream not at StartElement after root", new QName(
                    "person"), reader.nextEvent().asStartElement().getName());

            XMLEvent nameTag = XMLStreamUtils.nextTag(reader);

            assertTrue("expected name start tag", nameTag.isStartElement());
            assertEquals("not name start tag", new QName("name"),
                    reader.nextEvent().asStartElement().getName());

            XMLEvent nameEnd = XMLStreamUtils.nextTag(reader);
            assertTrue("expected name end tag", nameEnd.isEndElement());
            assertEquals("not name end tag", new QName("name"),
                    reader.nextEvent().asEndElement().getName());

        } finally {

            reader.close();

        }

    }

    public void testNextElement() throws XMLStreamException {

        XMLEventReader reader = getSampleXMLEventReader();
        try {

            StartElement rootElem = XMLStreamUtils.nextElement(reader);

            assertEquals("Root element didn't match person",
                    new QName("person"), rootElem.getName());

            StartElement rootElem2 = reader.nextEvent().asStartElement();
            assertEquals("Root elements didn't match", rootElem, rootElem2);

            StartElement nameElem = XMLStreamUtils.nextElement(reader,
                    new QName("name"));
            assertNotNull("next name elem was null", nameElem);

        } finally {

            reader.close();

        }

    }

    private XMLStreamReader getSampleXMLStreamReader()
            throws XMLStreamException {

        // load sample XML
        ClassLoader loader = Thread.currentThread().getContextClassLoader();
        InputStream testSource = loader.getResourceAsStream("javanet/staxutils/XMLStreamUtils.xml");

        XMLInputFactory factory = XMLInputFactory.newInstance();
        return factory.createXMLStreamReader(testSource);

    }

    private XMLEventReader getSampleXMLEventReader() throws XMLStreamException {

        // load sample XML
        ClassLoader loader = Thread.currentThread().getContextClassLoader();
        InputStream testSource = loader.getResourceAsStream("javanet/staxutils/XMLStreamUtils.xml");

        XMLInputFactory factory = XMLInputFactory.newInstance();
        return factory.createXMLEventReader(testSource);

    }

}
