/*
 * Copyright (c) 1998, 2021 Oracle and/or its affiliates. All rights reserved.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v. 2.0 which is available at
 * http://www.eclipse.org/legal/epl-2.0,
 * or the Eclipse Distribution License v. 1.0 which is available at
 * http://www.eclipse.org/org/documents/edl-v10.php.
 *
 * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
 */

// Contributors:
//     Oracle - initial API and implementation from Oracle TopLink
package org.eclipse.persistence.testing.oxm.xmlconversionmanager;

import javax.xml.namespace.QName;
import org.eclipse.persistence.exceptions.ConversionException;
import org.eclipse.persistence.internal.oxm.XMLConversionManager;
import org.eclipse.persistence.oxm.XMLConstants;
import org.eclipse.persistence.testing.oxm.OXTestCase;

public class QNameTestCases extends OXTestCase {
    private static final QName CONTROL_QNAME = new QName("local");
    private static final QName CONTROL_QNAME_NS = new QName("urn:test", "local");
    private static final String CONTROL_STRING = "local";
    private static final String CONTROL_STRING_NS = "{urn:test}local";

    // XML Conversion Manager
    private XMLConversionManager xcm;

    public QNameTestCases(String name) {
        super(name);
    }

    @Override
    public void setUp() {
        xcm = XMLConversionManager.getDefaultXMLManager();
    }

    public void testQNameToQName() {
        QName control = CONTROL_QNAME;
        QName test = (QName)xcm.convertObject(control, QName.class);
        assertEquals(control, test);
    }

    public void testQNameToString_default_null() {
        QName qName = null;
        QName control = null;
        String test = (String)xcm.convertObject(control, String.class);
        assertEquals(control, test);
    }

    public void testQNameToString_default() {
        QName qName = CONTROL_QNAME;
        String control = CONTROL_STRING;
        String test = (String)xcm.convertObject(qName, String.class);
        assertEquals(control, test);
    }

    public void testQNameToString_default_ns() {
        QName qName = CONTROL_QNAME_NS;
        String control = CONTROL_STRING_NS;
        String test = (String)xcm.convertObject(qName, String.class);
        assertEquals(control, test);
    }

    public void testQNameToString_qname() {
        QName qName = CONTROL_QNAME;
        String control = CONTROL_STRING;
        String test = (String)xcm.convertObject(qName, String.class, XMLConstants.QNAME_QNAME);
        assertEquals(control, test);
    }

    public void testQNameToString_qname_ns() {
        QName qName = CONTROL_QNAME_NS;
        String control = CONTROL_STRING_NS;
        String test = (String)xcm.convertObject(qName, String.class, XMLConstants.QNAME_QNAME);
        assertEquals(control, test);
    }

    public void testStringToQName_default_null() {
        String string = null;
        QName control = null;
        QName test = (QName)xcm.convertObject(string, QName.class);
        assertEquals(control, test);
    }

    public void testStringToQName_default() {
        String string = CONTROL_STRING;
        QName control = CONTROL_QNAME;
        QName test = (QName)xcm.convertObject(string, QName.class);
        assertEquals(control, test);
    }

    public void testStringToQName_default_ns() {
        String string = CONTROL_STRING_NS;
        QName control = CONTROL_QNAME_NS;
        QName test = (QName)xcm.convertObject(string, QName.class);
        assertEquals(control, test);
    }

    public void testStringToQName_qname() {
        String string = CONTROL_STRING;
        QName control = CONTROL_QNAME;
        QName test = (QName)xcm.convertObject(string, QName.class, XMLConstants.QNAME_QNAME);
        assertEquals(control, test);
    }

    public void testStringToQName_qname_ns() {
        String string = CONTROL_STRING_NS;
        QName control = CONTROL_QNAME_NS;
        QName test = (QName)xcm.convertObject(string, QName.class, XMLConstants.QNAME_QNAME);
        assertEquals(control, test);
    }

    public void testIntegerToQName_default() {
        try {
            Integer integer = Integer.valueOf(1);
            xcm.convertObject(integer, QName.class);
        } catch (ConversionException e) {
            assertTrue("The incorrect exception was thrown", e.getErrorCode() == ConversionException.COULD_NOT_BE_CONVERTED);
        }
    }

    public void testIntegerToQName_qname() {
        try {
            Integer integer = Integer.valueOf(1);
            xcm.convertObject(integer, QName.class, XMLConstants.QNAME_QNAME);
        } catch (ConversionException e) {
            assertTrue("The incorrect exception was thrown", e.getErrorCode() == ConversionException.COULD_NOT_BE_CONVERTED);
        }
    }
}
