/*
 * @author Ranides Atterwim <ranides@gmail.com>
 * @copyright Ranides Atterwim
 * @license WTFPL
 * @url http://ranides.net/projects/assira
 */
package net.ranides.assira.reflection;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import net.ranides.assira.generic.TypeToken;
import net.ranides.assira.reflection.util.ReflectFormat;
import org.junit.Test;
import static org.junit.Assert.*;

/**
 *
 * @author Ranides Atterwim <ranides@gmail.com>
 */
public class TypeFactoryTest {
    
    private static GenericClass cc(Class<?> clazz, GenericClass... params) {
        return TypeFactory.construct(clazz, params);
    }
    
    @Test
    public void testCC() {
        GenericClass gen1 = cc(Map.class, cc(String.class), cc(ArrayList.class, cc(Float.class)) );
        GenericClass gen2 = cc(Map.class, cc(String.class), cc(LinkedList.class, cc(Double.class)) );
        GenericClass gen3 = cc(Map.class, cc(String.class), cc(LinkedList.class, cc(Double.class)) );
        
        assertEquals("Map<String, ArrayList<Float>>", gen1.toString());
        assertEquals("Map<String, LinkedList<Double>>", gen2.toString());
        
        assertEquals(gen2, gen3);
    }

    @Test
    public <X> void testToken() {
        assertEquals(Map.class, new TypeToken<Map<String,Float>>(){}.rawType() );
        assertEquals(Float.class, new TypeToken<Float>(){}.rawType() );
        
        GenericClass gen3  = new TypeToken<Map<String,List<Map.Entry<Double,Float>>>>(){};
        GenericClass gen3e = new TypeToken<Map<String,List<Map.Entry<? extends Double,Float>>>>(){};
        GenericClass gen3s = new TypeToken<Map<String,List<Map.Entry<? super Double,Float>>>>(){};
        
        assertEquals(Float.class, gen3.params()[1].params()[0].params()[1].rawType() );
        
        assertEquals("Map<String, List<Entry<Double, Float>>>", ReflectFormat.signature(gen3));
        assertEquals("Map<String, List<Entry<Double, Float>>>", ReflectFormat.signature(gen3e));
        assertEquals("Map<String, List<Entry<Double, Float>>>", ReflectFormat.signature(gen3s));

        GenericClass gen4 = new TypeToken<Map<String,List<Map.Entry<?,Float>>>>(){};
        assertEquals("Map<String, List<Entry<Object, Float>>>", ReflectFormat.signature(gen4));
        
        assertEquals(0, gen4.params()[0].params().length);
        
        GenericClass gen5 = new TypeToken<Map<String,List<Map.Entry<X,Float>>>>(){};
        assertEquals("Map<String, List<Entry<X, Float>>>", ReflectFormat.signature(gen5));
        assertEquals("X", gen5.params()[1].params()[0].params()[0].name());
    }
    
}
