package collections

import kotlin.test.Test
import kotlin.test.fail

// These are examples of the kinds of imports that may be useful when writing tests.
import kotlin.test.assertEquals
import kotlin.test.assertFalse
import kotlin.test.assertTrue

class SinglyLinkedListExtraTests {

    /* TODO - replace this placeholder test with a number of your own tests.
    @Test
    fun `placeholder test`() {
        fail()
    }
    • The tests you write for remove should confirm that the method behaves correctly
    when invoked with an element that does appear in the list, and when invoked with
    an element that does not appear in the list.
    • Each test should be designed with a specific purpose, and the name of the test should
    reflect this purpose.
    • Think about “edge case” inputs to these functions when deciding on test inputs.
    */
    @Test
    fun `remove element in list`() {
        val list: ImperialMutableList<String> = SinglyLinkedList()
        list.add(0, "a")
        list.add(1, "b")
        list.add(2, "c")
        assertEquals(list.remove("b"),true)
        assertEquals(list.remove("c"),true)
        assertEquals(list.remove("a"),true)
    }

    @Test
    fun `removeAt in list`() {
        val list: ImperialMutableList<String> = SinglyLinkedList()
        list.add(0, "a")
        list.add(1, "b")
        list.add(2, "c")
        assertEquals(list.removeAt(1),"b")
        assertEquals(list.removeAt(1),"c")
        assertEquals(list.removeAt(0),"a")
    }

    @Test
    fun `remove element not in list`() {
        val list: ImperialMutableList<String> = SinglyLinkedList()
        list.add(0, "a")
        list.add(1, "b")
        list.add(2, "c")
        assertEquals(list.remove("d"),false)
        assertEquals(list.remove("a"),true)
        assertEquals(list.remove("b"),true)
        assertEquals(list.remove("c"),true)
        assertEquals(list.remove("d"),false)
    }

    @Test
    fun `remove empty list throws`() {
        val list: ImperialMutableList<String> = SinglyLinkedList()
        list.add(0, "a")
        list.add(1, "b")
        list.add(2, "c")
        assertEquals(list.removeAt(1),"b")
        assertEquals(list.removeAt(1),"c")
        assertEquals(list.removeAt(0),"a")
        try {
            list.removeAt(0)
        } catch (exception: IndexOutOfBoundsException) {
            // yay
        }
    }

    @Test
    fun `remove list out of bounds`() {
        val list: ImperialMutableList<String> = SinglyLinkedList()
        list.add(0, "a")
        list.add(1, "b")
        list.add(2, "c")
        try {
            list.removeAt(3)
        } catch (exception: IndexOutOfBoundsException) {
            // yay
        }
    }
}