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

import java.math.BigDecimal;
import net.ranides.assira.reflection.mockup.ForClassTraits;
import org.junit.Test;
import static org.junit.Assert.*;

/**
 *
 * @author Ranides Atterwim <ranides@gmail.com>
 */
public class ClassTraitsTest {
    
    @Test
    public void testIsPrimitive() {
        assertTrue( ClassTraits.isPrimitive(byte.class));
        assertTrue( ClassTraits.isPrimitive(short.class));
        assertTrue( ClassTraits.isPrimitive(int.class));
        assertTrue( ClassTraits.isPrimitive(long.class));
        assertTrue( ClassTraits.isPrimitive(char.class));
        assertTrue( ClassTraits.isPrimitive(float.class));
        assertTrue( ClassTraits.isPrimitive(double.class));
        assertTrue( ClassTraits.isPrimitive(boolean.class));
        assertTrue( ClassTraits.isPrimitive(void.class));
        
        assertFalse( ClassTraits.isPrimitive(Byte.class));
        assertFalse( ClassTraits.isPrimitive(Integer.class));
        assertFalse( ClassTraits.isPrimitive(Number.class));
    }
    
    @Test
    public void testIsPrimitiveArray() {
        assertTrue( ClassTraits.isPrimitiveArray(byte[].class));
        assertTrue( ClassTraits.isPrimitiveArray(short[].class));
        assertTrue( ClassTraits.isPrimitiveArray(int[].class));
        
        assertFalse( ClassTraits.isPrimitiveArray(byte.class));
        
        assertFalse( ClassTraits.isPrimitiveArray(Byte[].class));
        assertFalse( ClassTraits.isPrimitiveArray(Integer[].class));
        assertFalse( ClassTraits.isPrimitiveArray(Number[].class));
    }
    
    @Test
    public void testModifiers() throws Exception {
        
        assertTrue(ClassTraits.isAbstract(ForClassTraits.ABSTRACT) );
        assertTrue(ClassTraits.isFinal(ForClassTraits.FINAL) );
        assertTrue(ClassTraits.isInterface(ForClassTraits.INTERFACE) );
        assertTrue(ClassTraits.isPrivate(ForClassTraits.PRIVATE) );
        assertTrue(ClassTraits.isProtected(ForClassTraits.PROTECTED) );
        assertTrue(ClassTraits.isPublic(ForClassTraits.PUBLIC) );
        assertTrue(ClassTraits.isStatic(ForClassTraits.STATIC) );
        
        assertFalse(ClassTraits.isAbstract(ForClassTraits.NOTHING) );
        assertFalse(ClassTraits.isFinal(ForClassTraits.NOTHING) );
        assertFalse(ClassTraits.isInterface(ForClassTraits.NOTHING) );
        assertFalse(ClassTraits.isPrivate(ForClassTraits.NOTHING) );
        assertFalse(ClassTraits.isProtected(ForClassTraits.NOTHING) );
        assertFalse(ClassTraits.isPublic(ForClassTraits.NOTHING) );
        assertFalse(ClassTraits.isStatic(ForClassTraits.NOTHING) );

        assertTrue(ClassTraits.isPackage(ForClassTraits.NOTHING) );
        assertFalse(ClassTraits.isPackage(ForClassTraits.PRIVATE) );
        assertFalse(ClassTraits.isPackage(ForClassTraits.PUBLIC) );
        assertFalse(ClassTraits.isPackage(ForClassTraits.PROTECTED) );
    }
    
    @Test
    public void testIsBoxed() {
        assertTrue( ClassTraits.isBoxed(Byte.class));
        assertTrue( ClassTraits.isBoxed(Short.class));
        assertTrue( ClassTraits.isBoxed(Integer.class));
        assertTrue( ClassTraits.isBoxed(Long.class));
        assertTrue( ClassTraits.isBoxed(Character.class));
        assertTrue( ClassTraits.isBoxed(Float.class));
        assertTrue( ClassTraits.isBoxed(Double.class));
        assertTrue( ClassTraits.isBoxed(Boolean.class));
        assertTrue( ClassTraits.isBoxed(Void.class));
        
        assertFalse( ClassTraits.isBoxed(byte.class));
        assertFalse( ClassTraits.isBoxed(int.class));
        assertFalse( ClassTraits.isBoxed(Number.class));
    }
    
    @Test
    public void testIsBool() {
        
        assertTrue( ClassTraits.isBool(Boolean.class));
        assertTrue( ClassTraits.isBool(boolean.class));
        
        assertFalse( ClassTraits.isBool(Number.class));
    }
    
    @Test
    public void testIsNumber() {
        assertTrue( ClassTraits.isNumber(Byte.class));
        assertTrue( ClassTraits.isNumber(Short.class));
        assertTrue( ClassTraits.isNumber(Integer.class));
        assertTrue( ClassTraits.isNumber(Long.class));
        assertTrue( ClassTraits.isNumber(Float.class));
        assertTrue( ClassTraits.isNumber(Double.class));
        
        assertTrue( ClassTraits.isNumber(byte.class));
        assertTrue( ClassTraits.isNumber(short.class));
        assertTrue( ClassTraits.isNumber(int.class));
        assertTrue( ClassTraits.isNumber(long.class));
        assertTrue( ClassTraits.isNumber(float.class));
        assertTrue( ClassTraits.isNumber(double.class));
        
        assertTrue( ClassTraits.isNumber(Number.class));
        assertTrue( ClassTraits.isNumber(BigDecimal.class));

        // char isn't number, if you use it as unsigned short, that's a hack
        assertFalse( ClassTraits.isNumber(Character.class));
        assertFalse( ClassTraits.isNumber(char.class));
        
        assertFalse( ClassTraits.isNumber(Boolean.class));
        assertFalse( ClassTraits.isNumber(Void.class));
        assertFalse( ClassTraits.isNumber(boolean.class));
        assertFalse( ClassTraits.isNumber(void.class));

    }
    
    @Test
    public void testIsSuper_int() {
        assertTrue(ClassTraits.isSuper(int.class, Integer.class));
        assertTrue(ClassTraits.isSuper(Integer.class, int.class));
        assertTrue(ClassTraits.isSuper(Number.class, Integer.class));
        assertTrue(ClassTraits.isSuper(Number.class, int.class));
        assertFalse(ClassTraits.isSuper(int.class, byte.class));
        assertFalse(ClassTraits.isSuper(Integer.class, Byte.class));
    }
    
    @Test
    public void testIsSuper_long() {
        assertTrue(ClassTraits.isSuper(long.class, Long.class));
        assertTrue(ClassTraits.isSuper(Long.class, long.class));
        assertTrue(ClassTraits.isSuper(Number.class, Long.class));
        assertTrue(ClassTraits.isSuper(Number.class, long.class));
        assertFalse(ClassTraits.isSuper(long.class, byte.class));
        assertFalse(ClassTraits.isSuper(Long.class, Byte.class));
    }
    
    @Test
    public void testIsSuper_float() {
        assertTrue(ClassTraits.isSuper(float.class, Float.class));
        assertTrue(ClassTraits.isSuper(Float.class, float.class));
        assertTrue(ClassTraits.isSuper(Number.class, Float.class));
        assertTrue(ClassTraits.isSuper(Number.class, float.class));
        assertFalse(ClassTraits.isSuper(float.class, byte.class));
        assertFalse(ClassTraits.isSuper(Float.class, Byte.class));
    }
    
    @Test
    public void testIsSuper_double() {
        assertTrue(ClassTraits.isSuper(double.class, Double.class));
        assertTrue(ClassTraits.isSuper(Double.class, double.class));
        assertTrue(ClassTraits.isSuper(Number.class, Double.class));
        assertTrue(ClassTraits.isSuper(Number.class, double.class));
        assertFalse(ClassTraits.isSuper(double.class, byte.class));
        assertFalse(ClassTraits.isSuper(Double.class, Byte.class));
    }
    
    @Test
    public void testIsSuper_byte() {
        assertTrue(ClassTraits.isSuper(byte.class, Byte.class));
        assertTrue(ClassTraits.isSuper(Byte.class, byte.class));
        assertTrue(ClassTraits.isSuper(Number.class, Byte.class));
        assertTrue(ClassTraits.isSuper(Number.class, byte.class));
        assertFalse(ClassTraits.isSuper(byte.class, double.class));
        assertFalse(ClassTraits.isSuper(Byte.class, Double.class));
    }
    
    @Test
    public void testIsSuper_short() {        
        assertTrue(ClassTraits.isSuper(short.class, Short.class));
        assertTrue(ClassTraits.isSuper(Short.class, short.class));
        assertTrue(ClassTraits.isSuper(Number.class, Short.class));
        assertTrue(ClassTraits.isSuper(Number.class, short.class));
        assertFalse(ClassTraits.isSuper(short.class, byte.class));
        assertFalse(ClassTraits.isSuper(Short.class, Byte.class));
    }
    
    @Test
    public void testIsSuper_boolean() {
        assertTrue(ClassTraits.isSuper(boolean.class, Boolean.class));
        assertTrue(ClassTraits.isSuper(Boolean.class, boolean.class));
        assertFalse(ClassTraits.isSuper(boolean.class, byte.class));
        assertFalse(ClassTraits.isSuper(Boolean.class, Byte.class));
    }
    
    @Test
    public void testIsSuper_char() {        
        assertTrue(ClassTraits.isSuper(char.class, Character.class));
        assertTrue(ClassTraits.isSuper(Character.class, char.class));
        assertFalse(ClassTraits.isSuper(char.class, byte.class));
        assertFalse(ClassTraits.isSuper(Character.class, Byte.class));
    }
    
    @Test
    public void testIsSuper_object() {
        assertTrue(ClassTraits.isSuper(CharSequence.class, CharSequence.class));
        assertTrue(ClassTraits.isSuper(CharSequence.class, String.class));
        assertTrue(ClassTraits.isSuper(Object.class, String.class));
        
        assertFalse(ClassTraits.isSuper(String.class, CharSequence.class));
        assertFalse(ClassTraits.isSuper(String.class, Object.class));
        
        assertTrue(ClassTraits.isSuper(Object.class, int.class));
        
        assertTrue(ClassTraits.isSuper(void.class, void.class));
        assertTrue(ClassTraits.isSuper(Void.class, void.class));
        assertTrue(ClassTraits.isSuper(Object.class, void.class));
    }
    
    @Test
    public void testIsSuper_list() {
        Class<?> a = int.class;
        Class<?> b = Integer.class;
        Class<?> c = Number.class;
        
        assertTrue(ClassTraits.isSuper(new Class[]{}, new Class[]{}));
        assertTrue(ClassTraits.isSuper(new Class[]{a}, new Class[]{a}));
        assertTrue(ClassTraits.isSuper(new Class[]{b,c}, new Class[]{a,b}));
        
        assertFalse(ClassTraits.isSuper(new Class[]{a,a,a}, new Class[]{a,a}));
        assertFalse(ClassTraits.isSuper(new Class[]{a,a,a}, new Class[]{a,a,c}));
        assertFalse(ClassTraits.isSuper(new Class[]{a,a,a}, new Class[]{a,a,void.class}));
    }
    
}
