/*
 * $Header: /home/cvspublic/jakarta-slide/proposals/tamino/testsuite/junit/store/org/apache/slide/store/tamino/jdomobjects/XNodeRevisionDescriptorsTest.java,v 1.1 2004/03/25 16:18:14 juergen Exp $
 * $Revision: 1.1 $
 * $Date: 2004/03/25 16:18:14 $
 *
 * ====================================================================
 *
 * Copyright 1999-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 org.apache.slide.store.tamino.jdomobjects;

import java.io.IOException;
import java.util.Enumeration;
import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;
import junit.textui.TestRunner;
import org.apache.slide.content.NodeRevisionDescriptors;
import org.apache.slide.content.NodeRevisionNumber;
import org.apache.slide.util.JDom;
import org.jdom.Element;
import org.jdom.JDOMException;

public class XNodeRevisionDescriptorsTest extends TestCase {
    public XNodeRevisionDescriptorsTest(String name) {
        super( name );
    }

    public void testIsVersionedExplicit() throws JDOMException {
        NodeRevisionDescriptors slide;

        slide = create(
            "<descriptors isVersioned='true'>\n" +
            "  <initialRevision revisionNumber='1'/>\n" +
            "  <branchList/>\n" +
            "  <latestList/>\n" +
            "</descriptors>\n"
        );
        assertTrue(slide.isVersioned());
    }

    public void testIsVersionedImplicit() throws JDOMException {
        NodeRevisionDescriptors slide;

        slide = create(
            "<descriptors>\n" +
            "  <initialRevision revisionNumber='1'/>\n" +
            "  <branchList/>\n" +
            "  <latestList/>\n" +
            "</descriptors>\n"
        );
        assertFalse(slide.isVersioned());
    }

    public void testInitialRevision() throws JDOMException {
        NodeRevisionDescriptors slide;

        slide = create(
            "<descriptors>\n" +
            "  <initialRevision revisionNumber='2.12'/>\n" +
            "  <branchList/>\n" +
            "  <latestList/>\n" +
            "</descriptors>\n"
        );

        // caution: inital revision is not used yet!
        assertEquals(1, slide.getInitialRevision().getMajor());
        assertEquals(0, slide.getInitialRevision().getMinor());
    }

    public void testBranchList() throws JDOMException {
        NodeRevisionDescriptors slide;
        Enumeration revisions;

        slide = create(
            "<descriptors>\n" +
            "  <initialRevision revisionNumber='1'/>\n" +
            "  <branchList>\n" +
            "    <branch revisionNumber='7.8'/>\n" +
            "    <branch revisionNumber='9.10'>\n" +
            "      <successor revisionNumber='1.2'/>\n" +
            "      <successor revisionNumber='5.6'/>\n" +
            "    </branch>\n" +
            "  </branchList>\n" +
            "  <latestList/>\n" +
            "</descriptors>\n"
        );

        revisions = slide.enumerateRevisionNumbers();  // TODO: enumerateBranchNames

        checkNextRevision(slide, 7, 8, new int[] {}, new int[] {}, revisions);
        checkNextRevision(slide, 9, 10, new int[] { 1, 5 }, new int[] { 2, 6 }, revisions);
    }

    public void testLatestList() throws JDOMException {
        NodeRevisionDescriptors slide;
        Enumeration branches;
        String branch;

        slide = create(
            "<descriptors>\n" +
            "  <initialRevision revisionNumber='1'/>\n" +
            "  <branchList/>\n" +
            "  <latestList>\n" +
            "    <latestRevision branchName='b1' revisionNumber='1.2'/>\n" +
            "    <latestRevision branchName='b2' revisionNumber='6.7'/>\n" +
            "  </latestList>\n" +
            "</descriptors>\n"
        );

        branches = slide.enumerateBranchNames();

        // TODO: ordering depends on hashValue

        branch = (String) branches.nextElement();
        assertEquals("b2", branch);
        checkRevision(6, 7, slide.getLatestRevision(branch));

        branch = (String) branches.nextElement();
        assertEquals("b1", branch);
        checkRevision(1, 2, slide.getLatestRevision(branch));

    }

    private void checkNextRevision(NodeRevisionDescriptors slide, int major, int minor, int[] succMajor, int[] succMinor, Enumeration revisions) {
        if (succMajor.length != succMinor.length) {
            throw new IllegalArgumentException();
        }

        NodeRevisionNumber revision;
        Enumeration successors;
        int i;

        revision = (NodeRevisionNumber) revisions.nextElement();
        checkRevision(major, minor, revision);
        successors = slide.getSuccessors(revision);
        for (i = 0; i < succMajor.length; i++) {
            checkRevision(succMajor[i], succMinor[i], (NodeRevisionNumber) successors.nextElement());
        }
        assertFalse(successors.hasMoreElements());
    }

    private void checkRevision(int major, int minor, NodeRevisionNumber revision) {
        assertEquals(major, revision.getMajor());
        assertEquals(minor, revision.getMinor());
    }

    public NodeRevisionDescriptors create(String str) throws JDOMException {
        Element xml;
        NodeRevisionDescriptors slide;

        try {
            xml = JDom.forString(str).getRootElement();
        } catch (IOException e) {
            fail(e.getMessage());
            return null; // dummy
        }
        // do toSlide/toXml roundtrip to test getElement as well
        slide = XNodeRevisionDescriptors.toSlide(xml);
        xml = XNodeRevisionDescriptors.toXml(slide);
        return XNodeRevisionDescriptors.toSlide(xml);
    }

    /**
     ** Start precisely this test suite with the commandline interface.
     **
     ** @param args   commandline options (not used)
     **/
    public static void main( String[] args ) {
        TestRunner.run( suite() );
    }


    public static Test suite() {
        return new TestSuite(XNodeRevisionDescriptorsTest.class);
    }
}
