/**
 * Unit test cases for the implementation of a Singly-Linked List.
 */

import static org.junit.jupiter.api.Assertions.*;
import org.junit.jupiter.api.Test;

public class SLinkedListTest
{
	/**
	 * the list to use for testing
	 */
	private SLinkedList<Integer> list;

	/**
	 * Returns a linked list with the given items.
	 * (the items in the list are in the same order as in the given array)
	 */
	private static <E> SLinkedList<E> load(E... items)
	{
		SLinkedList<E> list = new SLinkedList<E>();

		// if addLast works correctly, use this version (else use version below)
		for (E data : items) {
			list.addLast(data);
		}

//		// if only addFirst works, use this version (else use version above)
//		for (int i = items.length - 1; i >= 0; --i) {
//			list.addFirst(items[i]);
//		}

		return list;
	}

	@Test
	public void test_addFirst()
	{
		// testing empty list

		list = load();
		list.addFirst( a );
		assertEquals( list.toStringNext(), "[a]" );
//for DLL:	assertEquals( list.toStringPrev(), "[a]" );

		// testing single list

		list = load( a );
		list.addFirst( b );
		assertEquals( list.toStringNext(), "[b a]" );
//for DLL:	assertEquals( list.toStringPrev(), "[b a]" );

		// testing multi list

		list = load( a, b, c, d, e, f, g );
		list.addFirst( h );
		assertEquals( list.toStringNext(), "[h a b c d e f g]" );
//for DLL:	assertEquals( list.toStringPrev(), "[h a b c d e f g]" );
	}

	@Test
	public void test_isEmpty()
	{
		// testing empty list

		list = load();
		assertTrue( list.isEmpty() );
		assertEquals( list.toStringNext(), "[]" );
//for DLL:	assertEquals( list.toStringPrev(), "[]" );


		// testing single list

		list = load( a );
		assertFalse( list.isEmpty() );
		assertEquals( list.toStringNext(), "[a]" );
//for DLL:	assertEquals( list.toStringPrev(), "[a]" );


		// testing multi list

		list = load( a, b, c, d, e, f, g );
		assertFalse( list.isEmpty() );
		assertEquals( list.toStringNext(), "[a b c d e f g]" );
//for DLL:	assertEquals( list.toStringPrev(), "[a b c d e f g]" );
	}

	@Test
	public void test_getFirst()
	{
		// testing empty list

		list = load();
		assertThrowsExactly( WhichException.class, () -> list.getFirst() );
		assertEquals( list.toStringNext(), "[]" );
//for DLL:	assertEquals( list.toStringPrev(), "[]" );


		// testing single list

		list = load( a );
		assertTrue( list.getFirst() == a );
		assertEquals( list.toStringNext(), "[a]" );
//for DLL:	assertEquals( list.toStringPrev(), "[a]" );


		// testing multi list

		list = load( a, b, c, d, e, f, g );
		assertTrue( list.getFirst() == a );
		assertEquals( list.toStringNext(), "[a b c d e f g]" );
//for DLL:	assertEquals( list.toStringPrev(), "[a b c d e f g]" );
	}
}