package pl.batorart.zajecia1607.datastructures;

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

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.function.Executable;

/**
 * Created by Artur_2 on 2017-07-16.
 */
public class MyListTest {

    private MyList<String> testList=new MyLinkedList<>();
    //private MyList<String> testList=new MyArrayList<>();

    @Test
    public void shouldLengthMethodWork(){
       MyList<Integer> l =new MyArrayList<>();
       l.add(new Integer(5));

       assertEquals(1, l.length());
    }
    @Test
    public void listLengthShouldIncrease(){
        for (int i = 0; i <120 ; i++) {
            testList.add(i+"ty wpis");
        }
        assertEquals(120,testList.length());
    }

    @Test
    public void longListReturns(){
        for (int i = 0; i <120 ; i++) {
            testList.add("wpis nr "+i);
        }
        testList.remove(10);
        assertEquals("wpis nr 111", testList.get(110));
    }

    @Test
    public void canAddAndRemoveElements(){
        testList.add("one");
        testList.add("two");
        testList.add("three");
        testList.add("four");
        testList.remove("three");
        String four= testList.get(2);

        assertEquals("four", four);
    }



    @Test
    public void addingAndRemovingShouldChangeLength(){
        testList.add("one");
        int length1=testList.length();
        testList.add("two");
        testList.remove(0);
        int lengthAgain1=testList.length();

        assertEquals(lengthAgain1,length1);
    }

    @Test
    public void shouldGetElementGivenIndeks(){
     
        testList.add("Zero");
        testList.add("One");
        testList.add("Two");

        assertEquals("One",testList.get(1));
    }
    @Test
    public void shouldGetFirstElement(){
        testList.add("Zero");
        testList.add("One");
        testList.add("Two");

        assertEquals("Zero",testList.first());
    }
    @Test
    public void shouldGetLastElement(){
        testList.add("Zero");
        testList.add("One");
        testList.add("Two");

        assertEquals("Two",testList.last());
    }

    @Test
    public void shouldBeAbleToStoreNulls(){
        testList.add(null);
        testList.add("zero");

        assertEquals(null,testList.get(0));
    }


    @Test
    public void containsShouldFind(){
        testList.add("one");
        testList.add("two");

        assertTrue(testList.contains("one"));
    }

    @Test
    public void containsShouldNotFind(){
        testList.add("one");
        testList.add("two");

        assertFalse(testList.contains("three"));
    }
    @Test
    public void containsOnNullList(){
        assertFalse(testList.contains("one"));
    }

    @Test
    public void shouldReturnZero(){
        testList.add("one");
        testList.add("two");

        assertEquals(0,testList.indexOf("one"));
    }

    @Test
    public void shouldReturnNegativeNullList(){
        assertEquals(-1,testList.indexOf("one"));
    }

    //czy taki test jest dobrym pomysłem (z dwiema metodami assert?) czy powinienem pisać dwa oddzielne
    @Test
    public void shouldReturnNegativeListCleared(){
        testList.add("one");
        testList.add("two");
        testList.clear();

        assertEquals(-1,testList.indexOf("one"));
        assertEquals("[]", testList.toString());
    }

    @Test
    public void shouldReturnListElements(){
        testList.add("one");
        testList.add(null);
        testList.add("two");

        assertEquals("[one, null, two]",testList.toString());
    }

    @Test
    public void shouldToStringWorkOnEmpty(){
        assertEquals("[]",testList.toString());
    }
    @Test
    public void shouldThrowNullPointer(){
        MyList<String> test=null;
        assertThrows(NullPointerException.class, new Executable() {
            @Override
            public void execute() throws Throwable {
                test.toString();
            }
        });
    }

}