|
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
namespace System.Windows.Forms.Tests;
public class SinglyLinkedListTests
{
[Fact]
public void AddFirst()
{
SinglyLinkedList<int> list = new();
Assert.Equal(0, list.Count);
Assert.Null(list.First);
Assert.Null(list.Last);
list.AddFirst(1);
Assert.Equal(1, list.Count);
Assert.NotNull(list.First);
Assert.NotNull(list.Last);
Assert.Same(list.First, list.Last);
Assert.Null(list.First!.Next);
Assert.Equal(1, list.First);
list.AddFirst(2);
Assert.Equal(2, list.Count);
Assert.NotNull(list.First);
Assert.NotNull(list.Last);
Assert.NotSame(list.First, list.Last);
Assert.Same(list.First.Next, list.Last);
Assert.Null(list.Last!.Next);
Assert.Equal(2, list.First);
Assert.Equal(1, list.Last);
}
[Fact]
public void AddLast()
{
SinglyLinkedList<int> list = new();
Assert.Equal(0, list.Count);
Assert.Null(list.First);
Assert.Null(list.Last);
list.AddLast(1);
Assert.Equal(1, list.Count);
Assert.NotNull(list.First);
Assert.NotNull(list.Last);
Assert.Same(list.First, list.Last);
Assert.Null(list.First!.Next);
Assert.Equal(1, list.First);
list.AddLast(2);
Assert.Equal(2, list.Count);
Assert.NotNull(list.First);
Assert.NotNull(list.Last);
Assert.NotSame(list.First, list.Last);
Assert.Same(list.First.Next, list.Last);
Assert.Null(list.Last!.Next);
Assert.Equal(1, list.First);
Assert.Equal(2, list.Last);
}
[Fact]
public void MoveToFront()
{
SinglyLinkedList<int> list = new();
list.AddAll(1, 2, 3, 4, 5);
var enumerator = list.GetEnumerator();
Assert.True(enumerator.MoveNext());
enumerator.MoveCurrentToFront();
// Should be moved back in front
Assert.Null(enumerator.Current);
Assert.Equal(5, list.Count);
Assert.True(enumerator.MoveNext());
Assert.Equal(1, enumerator.Current);
Assert.True(enumerator.MoveNext());
Assert.Equal(2, enumerator.Current);
enumerator.MoveCurrentToFront();
Assert.Equal(1, enumerator.Current);
Assert.True(enumerator.MoveNext());
Assert.Equal(3, enumerator.Current);
Assert.True(enumerator.MoveNext());
Assert.Equal(4, enumerator.Current);
Assert.True(enumerator.MoveNext());
Assert.Equal(5, enumerator.Current);
enumerator.MoveCurrentToFront();
Assert.Equal(4, enumerator.Current);
Assert.False(enumerator.MoveNext());
Assert.Null(enumerator.Current);
Assert.Equal(5, list!.First);
Assert.Equal(new int[] { 5, 2, 1, 3, 4 }, list.WalkToList());
Assert.Equal(new int[] { 5, 2, 1, 3, 4 }, list.EnumerateToList());
}
[Fact]
public void MoveToFront_InvalidOperations()
{
SinglyLinkedList<int> list = new();
list.AddFirst(1);
var enumerator = list.GetEnumerator();
Assert.Throws<InvalidOperationException>(enumerator.MoveCurrentToFront);
Assert.True(enumerator.MoveNext());
enumerator.MoveCurrentToFront();
Assert.Throws<InvalidOperationException>(enumerator.MoveCurrentToFront);
}
[Fact]
public void RemoveCurrent()
{
SinglyLinkedList<int> list = new();
list.AddAll(1, 2, 3, 4, 5);
var enumerator = list.GetEnumerator();
Assert.True(enumerator.MoveNext());
enumerator.RemoveCurrent();
Assert.Equal(4, list.Count);
Assert.Null(enumerator.Current);
Assert.True(enumerator.MoveNext());
Assert.Equal(2, enumerator.Current);
Assert.True(enumerator.MoveNext());
Assert.Equal(3, enumerator.Current);
enumerator.RemoveCurrent();
Assert.Equal(3, list.Count);
Assert.Equal(2, enumerator.Current);
Assert.True(enumerator.MoveNext());
Assert.True(enumerator.MoveNext());
Assert.Equal(5, enumerator.Current);
enumerator.RemoveCurrent();
Assert.Equal(2, list.Count);
Assert.Equal(4, enumerator.Current);
Assert.False(enumerator.MoveNext());
Assert.Null(enumerator.Current);
Assert.Equal(new int[] { 2, 4 }, list.WalkToList());
Assert.Equal(new int[] { 2, 4 }, list.EnumerateToList());
}
[Fact]
public void RemoveCurrent_InvalidOperations()
{
SinglyLinkedList<int> list = new();
list.AddFirst(1);
list.AddLast(2);
var enumerator = list.GetEnumerator();
Assert.Throws<InvalidOperationException>(enumerator.RemoveCurrent);
Assert.True(enumerator.MoveNext());
enumerator.RemoveCurrent();
Assert.Throws<InvalidOperationException>(enumerator.RemoveCurrent);
}
}
internal static class ListExtensions
{
public static void AddAll<T>(this SinglyLinkedList<T> linkedList, params T[] values)
{
foreach (T value in values)
{
linkedList.AddLast(value);
}
}
public static List<T> WalkToList<T>(this SinglyLinkedList<T> linkedList)
{
List<T> list = new(linkedList.Count);
var node = linkedList.First;
while (node is not null)
{
list.Add(node);
node = node.Next;
}
return list;
}
public static List<T> EnumerateToList<T>(this SinglyLinkedList<T> linkedList)
{
List<T> list = new(linkedList.Count);
var enumerator = linkedList.GetEnumerator();
while (enumerator.MoveNext())
{
list.Add(enumerator.Current);
}
return list;
}
}
|