TEST_F( SimplexSupportDoublyLinkedList, PushBackAddsElement )
{
    MockStruct* m = new MockStruct();
    DoublyLinkedList list;

    list.PushBack( m );

    ASSERT_EQ ( (MockStruct*)list.Last()->Value, m );
    delete(m);
}
TEST_F( SimplexSupportDoublyLinkedList, PushBackSetsFirstElementIfNoElementPresent )
{
    MockStruct* m = new MockStruct();
    DoublyLinkedList list;

    list.PushBack( m );

    ASSERT_EQ ( (MockStruct*)list.First()->Value, m );

    delete(m);
}
//
//  At
//
TEST_F( SimplexSupportDoublyLinkedList, AtReturnsObjectAtSpecifiedIndex )
{
    MockStruct* m1 = new MockStruct();
    MockStruct* m2 = new MockStruct();
    MockStruct* m3 = new MockStruct();

    DoublyLinkedList list;

    list.PushBack(m1);
    list.PushBack(m2);
    list.PushBack(m3);

    ASSERT_EQ(list.At(0)->Value, (MockStruct*)m1);
    ASSERT_EQ(list.At(1)->Value, (MockStruct*)m2);
    ASSERT_EQ(list.At(2)->Value, (MockStruct*)m3);

    delete(m1);
    delete(m2);
    delete(m3);
}
TEST_F( SimplexSupportDoublyLinkedList, PopBackUpdatesFirstWhenListIsEmptied )
{
    MockStruct* m = new MockStruct();
    DoublyLinkedList list;

    list.PushBack( m );
    list.PopBack();

    ASSERT_EQ ( list.First(), nullptr );
    delete(m);
}
TEST_F( SimplexSupportDoublyLinkedList, PushBackReservesMemoryToHoldOneNodeByDefault )
{
    ASSERT_EQ(mAllocator->GetAllocationCount(), 0);

    MockStruct* m = new MockStruct();
    DoublyLinkedList list;
    list.PushBack(m);

    ASSERT_EQ(mAllocator->GetAllocationCount(), 1);

    delete(m);
}
//
//  Destructor
//
TEST_F( SimplexSupportDoublyLinkedList, DestructorDeallocatesNodes )
{
    MockStruct* m1 = new MockStruct();
    MockStruct* m2 = new MockStruct();
    MockStruct* m3 = new MockStruct();

    DoublyLinkedList list;

    list.PushBack(m1);
    list.PushBack(m2);
    list.PushBack(m3);

    list.~DoublyLinkedList();

    ASSERT_EQ(mAllocator->GetAllocationCount(), 0);

    delete(m1);
    delete(m2);
    delete(m3);

}
//
//  RemoveAt
//
TEST_F( SimplexSupportDoublyLinkedList, RemoveAtLeavesAConsistentList )
{
    MockStruct* m1 = new MockStruct();
    MockStruct* m2 = new MockStruct();
    MockStruct* m3 = new MockStruct();

    DoublyLinkedList list;

    list.PushBack(m1);
    list.PushBack(m2);
    list.PushBack(m3);

    list.RemoveAt(1);

    ASSERT_EQ((MockStruct*)list.First()->Next->Value, m3);
    ASSERT_EQ((MockStruct*)list.Last()->Previous->Value, m1);

    delete(m1);
    delete(m2);
    delete(m3);
}
TEST_F( SimplexSupportDoublyLinkedList, PopBackReturnsObject )
{
    MockStruct* m1 = new MockStruct();

    DoublyLinkedList list;

    list.PushBack(m1);

    MockStruct*m2 = (MockStruct*) list.PopBack();

    ASSERT_EQ(m2, m1);

    delete(m1);
}
TEST_F( SimplexSupportDoublyLinkedList, LastReturnsLastAddedElement )
{
    MockStruct* m1 = new MockStruct();
    MockStruct* m2 = new MockStruct();
    MockStruct* m3 = new MockStruct();

    DoublyLinkedList list;

    list.PushBack(m1);

    ASSERT_EQ(list.Last()->Value, (MockStruct*)m1);

    list.PushBack(m2);

    ASSERT_EQ(list.Last()->Value, (MockStruct*)m2);

    list.PushBack(m3);

    ASSERT_EQ(list.Last()->Value, (MockStruct*)m3);

    delete(m1);
    delete(m2);
    delete(m3);
}
//
//  Last
//
TEST_F( SimplexSupportDoublyLinkedList, LastPreservesConnectionToPreviousLast )
{
    MockStruct* m1 = new MockStruct();
    MockStruct* m2 = new MockStruct();

    DoublyLinkedList list;

    list.PushBack(m1);
    list.PushBack(m2);

    ASSERT_EQ(list.Last()->Previous->Value, (MockStruct*)m1);

    delete(m1);
    delete(m2);
}
TEST_F( SimplexSupportDoublyLinkedList, PushBackSetsPreviousAndNextCorrectly )
{
    MockStruct* m1 = new MockStruct();
    MockStruct* m2 = new MockStruct();

    DoublyLinkedList list;

    list.PushBack( m1 );
    list.PushBack( m2 );

    ASSERT_EQ( list.Last()->Previous->Value, m1);
    ASSERT_EQ( list.First()->Next->Value, m2);

    delete(m1);
    delete(m2);
}
TEST_F( SimplexSupportDoublyLinkedList, RemoveAtReturnsValue )
{
    MockStruct* m1 = new MockStruct();
    MockStruct* m2 = new MockStruct();

    DoublyLinkedList list;

    list.PushBack(m1);
    list.PushBack(m2);

    MockStruct* result = (MockStruct*) list.RemoveAt(1);

    ASSERT_EQ(result, m2);

    delete(m1);
    delete(m2);
}
TEST_F( SimplexSupportDoublyLinkedList, PopBackDeallocatesNode )
{
    MockStruct* m = new MockStruct();

    DoublyLinkedList list;

    list.PushBack(m);

    ASSERT_EQ(mAllocator->GetAllocationCount(), 1);

    list.PopBack();

    ASSERT_EQ(mAllocator->GetAllocationCount(), 0);
    ASSERT_EQ(mAllocator->GetUsedMemory(), 0);

    delete(m);
}