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

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.junit.Test;
import static net.ranides.assira.junit.NewAssert.*;

/**
 *
 * @author Ranides Atterwim <ranides@gmail.com>
 */
public class NativeArrayListTest {
	
	@Test
    public void testWrap_primitive() {
		int[] array = new int[]{1,3,5,7};
		IntList list = NativeArrayList.wrap(array);
		assertEquals(Arrays.asList(1,3,5,7), list);
	}
	
	@Test
    public void testWrap_primitive_size() {
		int[] array = new int[]{1,3,5,7,9};
		IntList list = NativeArrayList.wrap(array, 0,4);
		assertEquals(Arrays.asList(1,3,5,7), list);
		
		assertThrows(ArrayIndexOutOfBoundsException.class, ()->{
			NativeArrayList.wrap(array, 0,9);
		});
	}
	
	@Test
	public void testWrap_Null() {
		assertEquals(1, NativeArrayList.wrap(null).hashCode());
		assertEquals(0, NativeArrayList.wrap(null).size());
		assertEquals(true, NativeArrayList.wrap(null).isEmpty());
	}
	
	@Test
    public void testWrap_object() {
		String[] array = new String[]{"1","2","3"};
		List<String> list = NativeArrayList.$wrap(array);
		list.set(1, "!");
		assertEquals("!", array[1]);
		assertEquals("1", list.get(0));
		assertEquals(3, list.size());
		
		assertEquals(Arrays.hashCode(array), list.hashCode());
		assertEquals(list, NativeArrayList.wrap(array));
		assertEquals(list, new ArrayList<>(NativeArrayList.wrap(array)));
		assertEquals(NativeArrayList.wrap(new String[]{".","1","!","3","."}, 1, 3), list);
		assertEquals(NativeArrayList.wrap(new String[]{"","",".","1","!","3","."}, 3, 3), list);
	}

	@Test
	public void testWrap_boolean() {
		boolean[] array = new boolean[]{false, false, true, false};
		List<Boolean> list = NativeArrayList.$wrap(array);
		list.set(1, true);
		assertEquals(true, array[1]);
		assertEquals(false, list.get(0));
		assertEquals(true, list.get(1));
		assertEquals(true, list.get(2));
		assertEquals(false, list.get(3));
		
		assertEquals(4, list.size());
		
		assertEquals(Arrays.hashCode(array), list.hashCode());
		assertEquals(list, NativeArrayList.wrap(array));
		assertEquals(list, new ArrayList<>(NativeArrayList.wrap(array)));
		assertEquals(NativeArrayList.wrap(new boolean[]{false,false,true,true,false,true}, 1, 4), list);
		assertEquals(NativeArrayList.wrap(new boolean[]{true,true,false,false,true,true,false,true}, 3, 4), list);
	}

	@Test
	public void testWrap_char() {
		char[] array = new char[]{1,2,3};
		List<Character> list = NativeArrayList.$wrap(array);
		list.set(1, (char)7);
		assertEquals((char)7, array[1]);
		assertEquals((char)1, (char)list.get(0));
		
		assertEquals(3, list.size());
		
		assertEquals(Arrays.hashCode(array), list.hashCode());
		assertEquals(list, NativeArrayList.wrap(array));
		assertEquals(list, new ArrayList<>(NativeArrayList.wrap(array)));
		assertEquals(NativeArrayList.wrap(new char[]{0,1,7,3,4}, 1, 3), list);
		assertEquals(NativeArrayList.wrap(new char[]{0,0,0,1,7,3,4}, 3, 3), list);
	}

	@Test
	public void testWrap_double() {
		double[] array = new double[]{1,2,3};
		List<Double> list = NativeArrayList.$wrap(array);
		list.set(1, (double)7);
		assertEquals((double)7, array[1], 0.1);
		assertEquals((double)1, (double)list.get(0), 0.1);
		
		assertEquals(3, list.size());
		
		assertEquals(Arrays.hashCode(array), list.hashCode());
		assertEquals(list, NativeArrayList.wrap(array));
		assertEquals(list, new ArrayList<>(NativeArrayList.wrap(array)));
		assertEquals(NativeArrayList.wrap(new double[]{0,1,7,3,4}, 1, 3), list);
		assertEquals(NativeArrayList.wrap(new double[]{0,0,0,1,7,3,4}, 3, 3), list);
	}

	@Test
	public void testWrap_float() {
		float[] array = new float[]{1,2,3};
		List<Float> list = NativeArrayList.$wrap(array);
		list.set(1, (float)7);
		assertEquals((float)7, array[1], 0.1f);
		assertEquals((float)1, (float)list.get(0), 0.1f);
		
		assertEquals(3, list.size());
		
		assertEquals(Arrays.hashCode(array), list.hashCode());
		assertEquals(list, NativeArrayList.wrap(array));
		assertEquals(list, new ArrayList<>(NativeArrayList.wrap(array)));
		assertEquals(NativeArrayList.wrap(new float[]{0,1,7,3,4}, 1, 3), list);
		assertEquals(NativeArrayList.wrap(new float[]{0,0,0,1,7,3,4}, 3, 3), list);
	}

	@Test
	public void testWrap_long() {
		long[] array = new long[]{1,2,3};
		List<Long> list = NativeArrayList.$wrap(array);
		list.set(1, (long)7);
		assertEquals((long)7, array[1]);
		assertEquals((long)1, (long)list.get(0));
		
		assertEquals(3, list.size());
		
		assertEquals(Arrays.hashCode(array), list.hashCode());
		assertEquals(list, NativeArrayList.wrap(array));
		assertEquals(list, new ArrayList<>(NativeArrayList.wrap(array)));
		assertEquals(NativeArrayList.wrap(new long[]{0,1,7,3,4}, 1, 3), list);
		assertEquals(NativeArrayList.wrap(new long[]{0,0,0,1,7,3,4}, 3, 3), list);
	}

	@Test
	public void testWrap_int() {
		int[] array = new int[]{1,2,3};
		List<Integer> list = NativeArrayList.wrap(array);
		list.set(1, (int)7);
		assertEquals((int)7, array[1]);
		assertEquals((int)1, (int)list.get(0));
		
		assertEquals(3, list.size());
		
		assertEquals(Arrays.hashCode(array), list.hashCode());
		assertEquals(list, NativeArrayList.wrap(array));
		assertEquals(list, new ArrayList<>(NativeArrayList.wrap(array)));
		assertEquals(NativeArrayList.$wrap(new int[]{0,1,7,3,4}, 1, 3), list);
		assertEquals(NativeArrayList.$wrap(new int[]{0,0,0,1,7,3,4}, 3, 3), list);
	}

	@Test
	public void testWrap_short() {
		short[] array = new short[]{1,2,3};
		List<Short> list = NativeArrayList.$wrap(array);
		list.set(1, (short)7);
		assertEquals((short)7, array[1]);
		assertEquals((short)1, (short)list.get(0));
		
		assertEquals(3, list.size());
		
		assertEquals(Arrays.hashCode(array), list.hashCode());
		assertEquals(list, NativeArrayList.wrap(array));
		assertEquals(list, new ArrayList<>(NativeArrayList.wrap(array)));
		assertEquals(NativeArrayList.wrap(new short[]{0,1,7,3,4}, 1, 3), list);
		assertEquals(NativeArrayList.wrap(new short[]{0,0,0,1,7,3,4}, 3, 3), list);
	}

	@Test
	public void testWrap_byte() {
		byte[] array = new byte[]{1,2,3};
		List<Byte> list = NativeArrayList.$wrap(array);
		list.set(1, (byte)7);
		assertEquals((byte)7, array[1]);
		assertEquals((byte)1, (byte)list.get(0));
		
		assertEquals(3, list.size());
		
		assertEquals(Arrays.hashCode(array), list.hashCode());
		assertEquals(list, NativeArrayList.wrap(array));
		assertEquals(list, new ArrayList<>(NativeArrayList.$wrap(array)));
		assertEquals(NativeArrayList.$wrap(new byte[]{0,1,7,3,4}, 1, 3), list);
		assertEquals(NativeArrayList.$wrap(new byte[]{0,0,0,1,7,3,4}, 3, 3), list);
	}
	
}
