package com.rschmitt.github.crystalmethod;

import com.github.rschmitt.crystalmethod.CrystalMethod;
import com.github.rschmitt.crystalmethod.Multimethod;
import org.junit.Test;
import org.testng.Assert;

import java.util.HashMap;
import java.util.Map;
import java.util.function.Function;

import static java.lang.String.format;
import static org.junit.Assert.assertEquals;

// TODO:
// cache dispatch fn lookups
// design hierarchy management features (if any), figure out where to stick them
// covariance? contravariance?
public class BasicTest {
    @Test
    public void testInvocation() {
        Map<Letter, Function<Integer, String>> dictionary = new HashMap<>();
        dictionary.put(Letter.A, this::letterA);
        dictionary.put(Letter.B, this::letterB);

        LetterMethod letterMethod = CrystalMethod.buildMultimethod(this::dispatch, dictionary, LetterMethod.class);

        assertEquals("a: 0", letterMethod.apply(0));
        assertEquals("b: 1", letterMethod.apply(1));
    }

    @Test
    public void testGetters() {
        Map<Letter, Function<Integer, String>> dictionary = new HashMap<>();

        LetterMethod letterMethod = CrystalMethod.buildMultimethod(this::dispatch, dictionary, LetterMethod.class);

        Assert.assertTrue(letterMethod.getDispatchMap().isEmpty());
        Assert.assertEquals(Letter.A, letterMethod.getDispatchFn().apply(2));
    }

    private Letter dispatch(Integer integer) {
        if (integer % 2 == 0) return Letter.A;
        else return Letter.B;
    }

    private String letterA(Integer integer) {
        return format("a: %d", integer);
    }

    private String letterB(Integer integer) {
        return format("b: %d", integer);
    }

    enum Letter {
        A, B
    }

    interface LetterMethod extends Multimethod<Letter, Integer, String> {
    }
}

@@ -162,43 +162,30 @@
 org.
-junit.Test;%0Aimport org.testng.Asser
+testng.annotations.Tes
 t;%0A%0A
@@ -330,13 +330,14 @@
 org.
-junit
+testng
 .Ass
@@ -353,16 +353,60 @@
 tEquals;
+%0Aimport static org.testng.Assert.assertTrue;
 %0A%0A// TOD
@@ -937,16 +937,8 @@
 als(
-%22a: 0%22, 
 lett
@@ -954,16 +954,24 @@
 apply(0)
+, %22a: 0%22
 );%0A     
@@ -990,16 +990,8 @@
 als(
-%22b: 1%22, 
 lett
@@ -1007,16 +1007,24 @@
 apply(1)
+, %22b: 1%22
 );%0A    %7D
@@ -1266,31 +1266,24 @@
 );%0A%0A        
-Assert.
 assertTrue(l
@@ -1331,23 +1331,16 @@
         
-Assert.
 assertEq
@@ -1344,26 +1344,16 @@
 tEquals(
-Letter.A, 
 letterMe
@@ -1381,16 +1381,26 @@
 apply(2)
+, Letter.A
 );%0A    %7D

Convert to TestNG