/*   Copyright 2004 The Apache Software Foundation
 *
 *   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 xmlcursor.checkin;

import org.apache.xmlbeans.XmlCursor;
import org.apache.xmlbeans.XmlObject;
import org.junit.Test;
import tools.util.JarUtil;
import xmlcursor.common.BasicCursorTestCase;
import xmlcursor.common.Common;

import static org.junit.Assert.assertEquals;


public class GetDocChangeStampTest extends BasicCursorTestCase {
    @Test
    public void testGetDocChangeStampHasChanged() throws Exception {
        m_xo = XmlObject.Factory.parse(
                  JarUtil.getResourceFromJar(Common.TRANXML_FILE_XMLCURSOR_PO));
        m_xc = m_xo.newCursor();
        String ns="declare namespace po=\"http://xbean.test/xmlcursor/PurchaseOrder\";";

        m_xc.selectPath(ns+" $this//po:city");
        m_xc.toNextSelection();
        assertEquals("Mill Valley", m_xc.getTextValue());
        XmlCursor.ChangeStamp cs0 = m_xc.getDocChangeStamp();
        m_xc.setTextValue("Mowed Valley");
        assertEquals("Mowed Valley", m_xc.getTextValue());
        assertEquals(true, cs0.hasChanged());
    }

    @Test
    public void testGetDocChangeStampNotChanged() throws Exception {
        m_xo = XmlObject.Factory.parse(
                  JarUtil.getResourceFromJar(Common.TRANXML_FILE_XMLCURSOR_PO));
        String ns="declare namespace po=\"http://xbean.test/xmlcursor/PurchaseOrder\";";

        m_xc = m_xo.newCursor();
        m_xc.selectPath(ns+" $this//po:city");
        XmlCursor.ChangeStamp cs0 = m_xc.getDocChangeStamp();
        m_xc.toEndDoc();
        assertEquals(false, cs0.hasChanged());
        System.out.println(cs0);
    }
}

