package com.twitter.bijection;

import org.junit.Test;

import static junit.framework.Assert.assertEquals;

/**
 * Bijection is as useful in Java as in Scala, so these tests ensure correct
 * functionality while providing an example of use and implementation from Java.
 */
public class TestBijectionInJava {
    @Test
    public void testBasicBijection() {
        Bijection<String,Long> s2l = new StringToLong();

        for (long l = -1000; l < 1000; l++) {
            String s = Long.valueOf(l).toString();
            roundTrip(s2l, s, l);
            roundTrip(s2l.inverse(), l, s);

            roundTrip(s2l.andThen(s2l.inverse()).inverse(), s, s);
            roundTrip(s2l.inverse().compose(s2l), s, s);
            roundTrip(s2l.inverse().compose(s2l).inverse(), s, s);
        }
    }

    @Test
    public void testBase64Bijection() {
        Bijection$.MODULE$.bytes2Base64(); //TODO make access to this cleaner from Java
    }

    @Test
    public void testBase64BijectionGzip() {

    }

    private <T1, T2> void roundTrip(Bijection<T1,T2> bij, T1 d1, T2 d2) {
        Bijection<T2,T1> inv = bij.inverse();

        assertEquals(d2, bij.apply(d1));
        assertEquals(d2, inv.invert(d1));

        assertEquals(d1, bij.invert(bij.apply(d1)));
        assertEquals(d1, bij.invert(inv.invert(d1)));
        assertEquals(d1, inv.apply(bij.apply(d1)));
        assertEquals(d1, inv.apply(inv.invert(d1)));

        assertEquals(d1, bij.invert(d2));
        assertEquals(d1, inv.apply(d2));

        assertEquals(d2, bij.apply(bij.invert(d2)));
        assertEquals(d2, bij.apply(inv.apply(d2)));
        assertEquals(d2, inv.invert(bij.invert(d2)));
        assertEquals(d2, inv.invert(inv.apply(d2)));

        assertEquals(d1, bij.andThen(bij.inverse()).apply(d1));
        assertEquals(d1, bij.andThen(bij.inverse()).inverse().apply(d1));
        assertEquals(d1, bij.inverse().compose(bij).apply(d1));
        assertEquals(d1, (bij.inverse().compose(bij).inverse().apply(d1)));

        assertEquals(d2, inv.andThen(inv.inverse()).apply(d2));
        assertEquals(d2, inv.andThen(inv.inverse()).inverse().apply(d2));
        assertEquals(d2, inv.inverse().compose(inv).apply(d2));
        assertEquals(d2, (inv.inverse().compose(inv).inverse().apply(d2)));
    }

    public static class StringToLong extends AbstractBijection<String,Long> {
        @Override
        public Long apply(String a) {
            return Long.parseLong(a);
        }

        @Override
        public String invert(Long b) {
            return b.toString();
        }
    }
}

@@ -801,203 +801,496 @@
     
-@Test%0A    public void testBase64Bijection() %7B%0A        Bijection$.MODULE$.bytes2Base64(); //TODO make access to this cleaner from Java%0A    %7D%0A%0A    @Test%0A    public void testBase64BijectionGzip() %7B%0A
+//TODO include a more complete example using Base64 conversion, and GZip + Base64 version%0A    //TODO include a cleaner way to get to the scala Bijections than Bijection$.MODULE$.%0A    @Test%0A    public void testBase64Bijection() %7B%0A        Bijection%3Cbyte%5B%5D,Base64String%3E bytes2Base64 = Bijection$.MODULE$.bytes2Base64();%0A    %7D%0A%0A    @Test%0A    public void testBase64BijectionGzip() %7B%0A        Bijection%3Cbyte%5B%5D,GZippedBase64String%3E bytes2GZippedBase64 = Bijection$.MODULE$.bytes2GZippedBase64();
 %0A   

Add TODOs