package org.jboss.cache.optimistic;

import junit.framework.TestCase;
import org.jboss.cache.Fqn;

import java.util.ArrayList;
import java.util.List;

/**
 * Tests {@link FqnComparator}.
 * @author xenephon
 */
public class ComparatorTest extends TestCase
{
    FqnComparator comp = new FqnComparator();

    public void testSingleCompare()
    {
        Fqn fqn1 = Fqn.fromString("one");
        Fqn fqn2 = Fqn.fromString("two");

        assertTrue(comp.compare(fqn1, fqn2) < 0);
        assertTrue(comp.compare(fqn2, fqn1) > 0);
        assertTrue(comp.compare(fqn1, fqn1) == 0);
        assertTrue(comp.compare(fqn2, fqn2) == 0);
    }

    public void testNullCompare()
    {
        Fqn fqn1 = new Fqn(new ArrayList());
        Fqn fqn2 = new Fqn(new ArrayList());

        assertTrue(comp.compare(fqn1, fqn2) == 0);
        assertTrue(comp.compare(fqn2, fqn1) == 0);
        assertTrue(comp.compare(fqn1, fqn1) == 0);
        assertTrue(comp.compare(fqn2, fqn2) == 0);
    }

    public void testOneNullCompare()
    {
        Fqn fqn1 = new Fqn(new ArrayList());
        List temp = new ArrayList();
        temp.add("one");
        Fqn fqn2 = new Fqn(temp);

        assertTrue(comp.compare(fqn1, fqn2) < 0);
        assertTrue(comp.compare(fqn2, fqn1) > 0);
    }

    public void testNotComparableCompare()
    {
        Fqn fqn1 = new Fqn(new ArrayList());

        List temp = new ArrayList();
        temp.add("one");
        Fqn fqn2 = new Fqn(temp);

        assertTrue(comp.compare(fqn1, fqn2) < 0);
        assertTrue(comp.compare(fqn2, fqn1) > 0);
    }

    public void testMultiChildCompare()
    {

        Fqn fqn1 = Fqn.fromString("/one/two");

        Fqn fqn2 = Fqn.fromString("/one/two/three");

        assertTrue(comp.compare(fqn1, fqn2) < 0);
        assertTrue(comp.compare(fqn2, fqn1) > 0);

        assertTrue(comp.compare(fqn2, fqn2) == 0);

        assertTrue(comp.compare(fqn1, fqn1) == 0);
    }

    public void testMultiNotChildCompare()
    {

        Fqn fqn1 = Fqn.fromString("/one/two");

        Fqn fqn2 = Fqn.fromString("/three/four");

        assertTrue(comp.compare(fqn1, fqn2) < 0);
        assertTrue(comp.compare(fqn2, fqn1) > 0);

        assertTrue(comp.compare(fqn2, fqn2) == 0);

        assertTrue(comp.compare(fqn1, fqn1) == 0);
    }

    public void testPartialMultiNotChildCompare()
    {

        Fqn fqn1 = Fqn.fromString("/one/two");

        Fqn fqn2 = Fqn.fromString("/three");

        assertTrue(comp.compare(fqn1, fqn2) < 0);
        assertTrue(comp.compare(fqn2, fqn1) > 0);

        assertTrue(comp.compare(fqn2, fqn2) == 0);

        assertTrue(comp.compare(fqn1, fqn1) == 0);
    }

    public void testEqualsMultidCompare()
    {

        Fqn fqn1 = Fqn.fromString("/one/two");

        Fqn fqn2 = Fqn.fromString("/one/two");

        assertTrue(comp.compare(fqn1, fqn2) == 0);
        assertTrue(comp.compare(fqn2, fqn1) == 0);

        assertTrue(comp.compare(fqn2, fqn2) == 0);

        assertTrue(comp.compare(fqn1, fqn1) == 0);
    }

    public void testStringIntMultidCompare()
    {
        Fqn fqn1 = Fqn.fromString("/one/two");

        List temp = new ArrayList();
        temp.add(new Integer(1234));
        Fqn fqn2 = new Fqn(temp);

        assertTrue(comp.compare(fqn1, fqn2) > 0);
        assertTrue(comp.compare(fqn2, fqn1) < 0);

        assertTrue(comp.compare(fqn2, fqn2) == 0);

        assertTrue(comp.compare(fqn1, fqn1) == 0);
    }

    public void testOrdinaryObjectCompare()
    {
        Fqn fqn1 = new Fqn(new Object[] {new XYZ(), new ABC()});
        Fqn fqn2 = new Fqn(new Object[] {"XYZ", "ABC"});
        Fqn fqn3 = new Fqn(new Object[] {"XYZ", new ABC()});

        Fqn fqn4 = new Fqn(new Object[] {"XYZ", new XYZ()});

        assertEquals(0, comp.compare(fqn1, fqn2));
        assertEquals(0, comp.compare(fqn1, fqn3));
        assertEquals(0, comp.compare(fqn2, fqn3));
        assertEquals(true, comp.compare(fqn1, fqn4) < 0);
        assertEquals(true, comp.compare(fqn4, fqn1) > 0);
    }

    /*
    public void testNullComparator()
    {
        Fqn fqn1 = new Fqn(new Object[] {"a", null, "c"});
        Fqn fqn2 = new Fqn(new Object[] {"a", "d", "c"});
        Fqn fqn3 = new Fqn(new Object[] {"a", null});

        assertEquals(0, comp.compare(fqn1, fqn1));
        assertEquals(true, comp.compare(fqn1, fqn2) > 0);
        assertEquals(true, comp.compare(fqn2, fqn1) < 0);
        assertEquals(true, comp.compare(fqn1, fqn3) < 0);
        assertEquals(true, comp.compare(fqn3, fqn1) > 0);
    }
    */

    private static class XYZ {
       public String toString() { return "XYZ"; }
    }

    private static class ABC {
       public String toString() { return "ABC"; }
    }

}
