|
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using System;
using System.Collections.Generic;
using Microsoft.AspNetCore.Razor.PooledObjects;
using Xunit;
namespace Microsoft.AspNetCore.Razor.Language.Syntax;
public class SyntaxListTests
{
private static MarkupTextLiteralSyntax CreateMarkupTextLiteral(params ReadOnlySpan<SyntaxToken> tokens)
{
using var builder = new PooledArrayBuilder<SyntaxToken>(tokens.Length);
builder.AddRange(tokens);
return SyntaxFactory.MarkupTextLiteral(builder.ToList());
}
private static readonly SyntaxToken s_openAngle = SyntaxFactory.Token(SyntaxKind.OpenAngle, "<");
private static readonly SyntaxToken s_closeAngle = SyntaxFactory.Token(SyntaxKind.CloseAngle, ">");
private static readonly SyntaxToken s_leftBrace = SyntaxFactory.Token(SyntaxKind.LeftBrace, "{");
private static readonly SyntaxToken s_rightBrace = SyntaxFactory.Token(SyntaxKind.RightBrace, "}");
private static readonly SyntaxToken s_forwardSlash = SyntaxFactory.Token(SyntaxKind.ForwardSlash, "/");
[Fact]
public void Add_WhenListIsEmpty_AddsNodeAtEnd()
{
// Arrange
var emptyList = SyntaxList<SyntaxNode>.Empty;
var node = CreateMarkupTextLiteral(s_openAngle);
// Act
var newList = emptyList.Add(node);
// Assert
Assert.Empty(emptyList);
Assert.Single(newList);
Assert.True(node.IsEquivalentTo(newList[0]));
}
[Fact]
public void Add_WhenListHasNodes_AddsNodeAtEnd()
{
// Arrange
var existingNode = CreateMarkupTextLiteral(s_openAngle);
SyntaxList<SyntaxNode> originalList = [existingNode];
var nodeToAdd = CreateMarkupTextLiteral(s_closeAngle);
// Act
var newList = originalList.Add(nodeToAdd);
// Assert
Assert.Single(originalList);
Assert.Equal(2, newList.Count);
Assert.True(existingNode.IsEquivalentTo(newList[0]));
Assert.True(nodeToAdd.IsEquivalentTo(newList[1]));
}
[Fact]
public void Add_WithMultipleNodes_AddsNodesInOrder()
{
// Arrange
var node1 = CreateMarkupTextLiteral(s_openAngle);
var node2 = CreateMarkupTextLiteral(s_closeAngle);
var node3 = CreateMarkupTextLiteral(s_leftBrace);
// Act
var list = SyntaxList<SyntaxNode>.Empty;
var list1 = list.Add(node1);
var list2 = list1.Add(node2);
var list3 = list2.Add(node3);
// Assert
Assert.Empty(list);
Assert.Single(list1);
Assert.Equal(2, list2.Count);
Assert.Equal(3, list3.Count);
Assert.True(node1.IsEquivalentTo(list1[0]));
Assert.True(node1.IsEquivalentTo(list2[0]));
Assert.True(node2.IsEquivalentTo(list2[1]));
Assert.True(node1.IsEquivalentTo(list3[0]));
Assert.True(node2.IsEquivalentTo(list3[1]));
Assert.True(node3.IsEquivalentTo(list3[2]));
}
[Fact]
public void Add_ImplementsImmutability_DoesNotModifyOriginalList()
{
// Arrange
var node1 = CreateMarkupTextLiteral(s_openAngle);
var node2 = CreateMarkupTextLiteral(s_closeAngle);
SyntaxList<SyntaxNode> originalList = [node1];
// Act
var newList = originalList.Add(node2);
// Assert
Assert.Single(originalList);
Assert.True(node1.IsEquivalentTo(originalList[0]));
Assert.Equal(2, newList.Count);
}
[Fact]
public void Add_DelegatesToInsert_WithCorrectIndex()
{
// Arrange
var node1 = CreateMarkupTextLiteral(s_openAngle);
var node2 = CreateMarkupTextLiteral(s_closeAngle);
SyntaxList<SyntaxNode> originalList = [node1];
// Act
var addResult = originalList.Add(node2);
var insertResult = originalList.Insert(originalList.Count, node2);
// Assert
Assert.Equal(addResult.Count, insertResult.Count);
for (var i = 0; i < addResult.Count; i++)
{
Assert.True(addResult[i].IsEquivalentTo(insertResult[i]));
}
}
[Fact]
public void Add_ThrowsArgumentNullException_WhenNodeIsNull()
{
// Arrange
var list = SyntaxList<SyntaxNode>.Empty;
// Act & Assert
Assert.Throws<ArgumentNullException>(() => list.Add(null!));
}
[Fact]
public void AddRange_WithReadOnlySpan_WhenListIsEmpty_AddsAllNodes()
{
// Arrange
var emptyList = SyntaxList<SyntaxNode>.Empty;
SyntaxNode[] nodesToAdd = [
CreateMarkupTextLiteral(s_openAngle),
CreateMarkupTextLiteral(s_forwardSlash),
CreateMarkupTextLiteral(s_closeAngle)
];
// Act
var newList = emptyList.AddRange(nodesToAdd.AsSpan());
// Assert
Assert.Empty(emptyList);
Assert.Equal(nodesToAdd.Length, newList.Count);
for (var i = 0; i < nodesToAdd.Length; i++)
{
Assert.True(nodesToAdd[i].IsEquivalentTo(newList[i]));
}
}
[Fact]
public void AddRange_WithReadOnlySpan_WhenListHasNodes_AddsNodesToEnd()
{
// Arrange
var existingNode = CreateMarkupTextLiteral(s_openAngle);
SyntaxList<SyntaxNode> originalList = [existingNode];
SyntaxNode[] nodesToAdd = [
CreateMarkupTextLiteral(s_forwardSlash),
CreateMarkupTextLiteral(s_closeAngle)
];
// Act
var newList = originalList.AddRange(nodesToAdd.AsSpan());
// Assert
Assert.Single(originalList);
Assert.Equal(1 + nodesToAdd.Length, newList.Count);
Assert.True(existingNode.IsEquivalentTo(newList[0]));
Assert.True(nodesToAdd[0].IsEquivalentTo(newList[1]));
Assert.True(nodesToAdd[1].IsEquivalentTo(newList[2]));
}
[Fact]
public void AddRange_WithReadOnlySpan_WithEmptySpan_ReturnsSameList()
{
// Arrange
var node = CreateMarkupTextLiteral(s_openAngle);
SyntaxList<SyntaxNode> originalList = [node];
var emptySpan = ReadOnlySpan<SyntaxNode>.Empty;
// Act
var newList = originalList.AddRange(emptySpan);
// Assert
Assert.Equal(originalList.Count, newList.Count);
Assert.True(originalList[0].IsEquivalentTo(newList[0]));
}
[Fact]
public void AddRange_WithReadOnlySpan_ImplementsImmutability_DoesNotModifyOriginalList()
{
// Arrange
var existingNode = CreateMarkupTextLiteral(s_openAngle);
SyntaxList<SyntaxNode> originalList = [existingNode];
SyntaxNode[] nodesToAdd = [
CreateMarkupTextLiteral(s_forwardSlash),
CreateMarkupTextLiteral(s_closeAngle)
];
// Act
var newList = originalList.AddRange(nodesToAdd.AsSpan());
// Assert
Assert.Single(originalList);
Assert.True(existingNode.IsEquivalentTo(originalList[0]));
Assert.Equal(3, newList.Count);
}
[Fact]
public void AddRange_WithReadOnlySpan_DelegatesToInsertRange_WithCorrectIndex()
{
// Arrange
var existingNode = CreateMarkupTextLiteral(s_openAngle);
SyntaxList<SyntaxNode> originalList = [existingNode];
SyntaxNode[] nodesToAdd = [
CreateMarkupTextLiteral(s_forwardSlash),
CreateMarkupTextLiteral(s_closeAngle)
];
var span = nodesToAdd.AsSpan();
// Act
var addResult = originalList.AddRange(span);
var insertResult = originalList.InsertRange(originalList.Count, span);
// Assert
Assert.Equal(addResult.Count, insertResult.Count);
for (var i = 0; i < addResult.Count; i++)
{
Assert.True(addResult[i].IsEquivalentTo(insertResult[i]));
}
}
[Fact]
public void AddRange_WhenListIsEmpty_AddsAllNodes()
{
// Arrange
var emptyList = SyntaxList<SyntaxNode>.Empty;
SyntaxNode[] nodesToAdd = [
CreateMarkupTextLiteral(s_openAngle),
CreateMarkupTextLiteral(s_forwardSlash),
CreateMarkupTextLiteral(s_closeAngle)
];
// Act
var newList = emptyList.AddRange(nodesToAdd);
// Assert
Assert.Empty(emptyList);
Assert.Equal(nodesToAdd.Length, newList.Count);
for (var i = 0; i < nodesToAdd.Length; i++)
{
Assert.True(nodesToAdd[i].IsEquivalentTo(newList[i]));
}
}
[Fact]
public void AddRange_WhenListHasNodes_AddsNodesToEnd()
{
// Arrange
var existingNode = CreateMarkupTextLiteral(s_openAngle);
SyntaxList<SyntaxNode> originalList = [existingNode];
SyntaxNode[] nodesToAdd = [
CreateMarkupTextLiteral(s_forwardSlash),
CreateMarkupTextLiteral(s_closeAngle)
];
// Act
var newList = originalList.AddRange(nodesToAdd);
// Assert
Assert.Single(originalList);
Assert.Equal(1 + nodesToAdd.Length, newList.Count);
Assert.True(existingNode.IsEquivalentTo(newList[0]));
Assert.True(nodesToAdd[0].IsEquivalentTo(newList[1]));
Assert.True(nodesToAdd[1].IsEquivalentTo(newList[2]));
}
[Fact]
public void AddRange_WithEmptyCollection_ReturnsSameList()
{
// Arrange
var node = CreateMarkupTextLiteral(s_openAngle);
SyntaxList<SyntaxNode> originalList = [node];
var emptyNodes = Array.Empty<SyntaxNode>();
// Act
var newList = originalList.AddRange(emptyNodes);
// Assert
Assert.Equal(originalList.Count, newList.Count);
Assert.True(originalList[0].IsEquivalentTo(newList[0]));
}
[Fact]
public void AddRange_ImplementsImmutability_DoesNotModifyOriginalList()
{
// Arrange
var existingNode = CreateMarkupTextLiteral(s_openAngle);
SyntaxList<SyntaxNode> originalList = [existingNode];
SyntaxNode[] nodesToAdd = [
CreateMarkupTextLiteral(s_forwardSlash),
CreateMarkupTextLiteral(s_closeAngle)
];
// Act
var newList = originalList.AddRange(nodesToAdd);
// Assert
Assert.Single(originalList);
Assert.True(existingNode.IsEquivalentTo(originalList[0]));
Assert.Equal(3, newList.Count);
}
[Fact]
public void AddRange_DelegatesToInsertRange_WithCorrectIndex()
{
// Arrange
var existingNode = CreateMarkupTextLiteral(s_openAngle);
SyntaxList<SyntaxNode> originalList = [existingNode];
SyntaxNode[] nodesToAdd = [
CreateMarkupTextLiteral(s_forwardSlash),
CreateMarkupTextLiteral(s_closeAngle)
];
// Act
var addResult = originalList.AddRange(nodesToAdd);
var insertResult = originalList.InsertRange(originalList.Count, nodesToAdd);
// Assert
Assert.Equal(addResult.Count, insertResult.Count);
for (var i = 0; i < addResult.Count; i++)
{
Assert.True(addResult[i].IsEquivalentTo(insertResult[i]));
}
}
[Fact]
public void AddRange_ThrowsArgumentNullException_WhenNodesIsNull()
{
// Arrange
var list = SyntaxList<SyntaxNode>.Empty;
IEnumerable<SyntaxNode> newNodes = null!;
// Act & Assert
Assert.Throws<ArgumentNullException>(() => list.AddRange(newNodes));
}
[Fact]
public void AddRange_WithDifferentNodeTypes_AddsAllNodes()
{
// Arrange
var emptyList = SyntaxList<SyntaxNode>.Empty;
// Create different types of syntax nodes
SyntaxNode[] mixedNodes = [
CreateMarkupTextLiteral(s_openAngle),
SyntaxFactory.MarkupBlock(),
SyntaxFactory.MarkupTagHelperAttributeValue()
];
// Act
var newList = emptyList.AddRange(mixedNodes);
// Assert
Assert.Equal(mixedNodes.Length, newList.Count);
for (var i = 0; i < mixedNodes.Length; i++)
{
Assert.True(mixedNodes[i].IsEquivalentTo(newList[i]));
Assert.Equal(mixedNodes[i].Kind, newList[i].Kind);
}
}
[Fact]
public void AddRange_WithListAsSource_AddsAllNodes()
{
// Arrange
var emptyList = SyntaxList<SyntaxNode>.Empty;
List<SyntaxNode> nodesList = [
CreateMarkupTextLiteral(s_openAngle),
CreateMarkupTextLiteral(s_forwardSlash),
CreateMarkupTextLiteral(s_closeAngle)
];
// Act
var newList = emptyList.AddRange(nodesList);
// Assert
Assert.Equal(nodesList.Count, newList.Count);
for (var i = 0; i < nodesList.Count; i++)
{
Assert.True(nodesList[i].IsEquivalentTo(newList[i]));
}
}
[Fact]
public void AddRange_WithIEnumerableAsSource_AddsAllNodes()
{
// Arrange
var emptyList = SyntaxList<SyntaxNode>.Empty;
IEnumerable<SyntaxNode> nodes = [
CreateMarkupTextLiteral(s_openAngle),
CreateMarkupTextLiteral(s_forwardSlash),
CreateMarkupTextLiteral(s_closeAngle)
];
// Act
var newList = emptyList.AddRange(nodes);
// Assert
Assert.Equal(3, newList.Count);
var index = 0;
foreach (var node in nodes)
{
Assert.True(node.IsEquivalentTo(newList[index++]));
}
}
[Fact]
public void Insert_AtBeginning_InsertsNodeAtStart()
{
// Arrange
var node1 = CreateMarkupTextLiteral(s_closeAngle);
var node2 = CreateMarkupTextLiteral(s_rightBrace);
SyntaxList<SyntaxNode> originalList = [node1, node2];
var nodeToInsert = CreateMarkupTextLiteral(s_openAngle);
// Act
var newList = originalList.Insert(0, nodeToInsert);
// Assert
Assert.Equal(2, originalList.Count);
Assert.Equal(3, newList.Count);
Assert.True(nodeToInsert.IsEquivalentTo(newList[0]));
Assert.True(node1.IsEquivalentTo(newList[1]));
Assert.True(node2.IsEquivalentTo(newList[2]));
}
[Fact]
public void Insert_AtMiddle_InsertsNodeAtCorrectPosition()
{
// Arrange
var node1 = CreateMarkupTextLiteral(s_openAngle);
var node2 = CreateMarkupTextLiteral(s_closeAngle);
SyntaxList<SyntaxNode> originalList = [node1, node2];
var nodeToInsert = CreateMarkupTextLiteral(s_forwardSlash);
// Act
var newList = originalList.Insert(1, nodeToInsert);
// Assert
Assert.Equal(2, originalList.Count);
Assert.Equal(3, newList.Count);
Assert.True(node1.IsEquivalentTo(newList[0]));
Assert.True(nodeToInsert.IsEquivalentTo(newList[1]));
Assert.True(node2.IsEquivalentTo(newList[2]));
}
[Fact]
public void Insert_AtEnd_SameAsAdd()
{
// Arrange
var node1 = CreateMarkupTextLiteral(s_openAngle);
var node2 = CreateMarkupTextLiteral(s_forwardSlash);
SyntaxList<SyntaxNode> originalList = [node1, node2];
var nodeToInsert = CreateMarkupTextLiteral(s_closeAngle);
// Act
var insertResult = originalList.Insert(originalList.Count, nodeToInsert);
var addResult = originalList.Add(nodeToInsert);
// Assert
Assert.Equal(addResult.Count, insertResult.Count);
for (var i = 0; i < addResult.Count; i++)
{
Assert.True(addResult[i].IsEquivalentTo(insertResult[i]));
}
}
[Fact]
public void Insert_IntoEmptyList_CreatesSingleItemList()
{
// Arrange
var emptyList = SyntaxList<SyntaxNode>.Empty;
var node = CreateMarkupTextLiteral(s_openAngle);
// Act
var newList = emptyList.Insert(0, node);
// Assert
Assert.Empty(emptyList);
Assert.Single(newList);
Assert.True(node.IsEquivalentTo(newList[0]));
}
[Fact]
public void Insert_ImplementsImmutability_DoesNotModifyOriginalList()
{
// Arrange
var node1 = CreateMarkupTextLiteral(s_openAngle);
SyntaxList<SyntaxNode> originalList = [node1];
var nodeToInsert = CreateMarkupTextLiteral(s_forwardSlash);
// Act
var newList = originalList.Insert(0, nodeToInsert);
// Assert
Assert.Single(originalList);
Assert.True(node1.IsEquivalentTo(originalList[0]));
Assert.Equal(2, newList.Count);
}
[Fact]
public void Insert_ThrowsArgumentNullException_WhenNodeIsNull()
{
// Arrange
SyntaxList<SyntaxNode> list = [CreateMarkupTextLiteral(s_openAngle)];
// Act & Assert
Assert.Throws<ArgumentNullException>(() => list.Insert(0, null!));
}
[Fact]
public void Insert_ThrowsArgumentOutOfRangeException_WhenIndexIsNegative()
{
// Arrange
SyntaxList<SyntaxNode> list = [CreateMarkupTextLiteral(s_openAngle)];
var node = CreateMarkupTextLiteral(s_closeAngle);
// Act & Assert
Assert.Throws<ArgumentOutOfRangeException>(() => list.Insert(-1, node));
}
[Fact]
public void Insert_ThrowsArgumentOutOfRangeException_WhenIndexExceedsCount()
{
// Arrange
SyntaxList<SyntaxNode> list = [CreateMarkupTextLiteral(s_openAngle)];
var node = CreateMarkupTextLiteral(s_closeAngle);
// Act & Assert
Assert.Throws<ArgumentOutOfRangeException>(() => list.Insert(list.Count + 1, node));
}
[Fact]
public void InsertRange_WithReadOnlySpan_AtBeginning_InsertsNodesAtStart()
{
// Arrange
var existingNode = CreateMarkupTextLiteral(s_closeAngle);
SyntaxList<SyntaxNode> originalList = [existingNode];
SyntaxNode[] nodesToInsert = [
CreateMarkupTextLiteral(s_openAngle),
CreateMarkupTextLiteral(s_forwardSlash)
];
// Act
var newList = originalList.InsertRange(0, nodesToInsert.AsSpan());
// Assert
Assert.Single(originalList);
Assert.Equal(nodesToInsert.Length + 1, newList.Count);
Assert.True(nodesToInsert[0].IsEquivalentTo(newList[0]));
Assert.True(nodesToInsert[1].IsEquivalentTo(newList[1]));
Assert.True(existingNode.IsEquivalentTo(newList[2]));
}
[Fact]
public void InsertRange_WithReadOnlySpan_AtMiddle_InsertsNodesAtCorrectPosition()
{
// Arrange
var node1 = CreateMarkupTextLiteral(s_openAngle);
var node2 = CreateMarkupTextLiteral(s_closeAngle);
SyntaxList<SyntaxNode> originalList = [node1, node2];
SyntaxNode[] nodesToInsert = [
CreateMarkupTextLiteral(s_forwardSlash),
CreateMarkupTextLiteral(s_rightBrace)
];
// Act
var newList = originalList.InsertRange(1, nodesToInsert.AsSpan());
// Assert
Assert.Equal(2, originalList.Count);
Assert.Equal(originalList.Count + nodesToInsert.Length, newList.Count);
Assert.True(node1.IsEquivalentTo(newList[0]));
Assert.True(nodesToInsert[0].IsEquivalentTo(newList[1]));
Assert.True(nodesToInsert[1].IsEquivalentTo(newList[2]));
Assert.True(node2.IsEquivalentTo(newList[3]));
}
[Fact]
public void InsertRange_WithReadOnlySpan_AtEnd_SameAsAddRange()
{
// Arrange
var node1 = CreateMarkupTextLiteral(s_openAngle);
SyntaxList<SyntaxNode> originalList = [node1];
SyntaxNode[] nodesToInsert = [
CreateMarkupTextLiteral(s_forwardSlash),
CreateMarkupTextLiteral(s_closeAngle)
];
var span = nodesToInsert.AsSpan();
// Act
var insertResult = originalList.InsertRange(originalList.Count, span);
var addResult = originalList.AddRange(span);
// Assert
Assert.Equal(addResult.Count, insertResult.Count);
for (var i = 0; i < addResult.Count; i++)
{
Assert.True(addResult[i].IsEquivalentTo(insertResult[i]));
}
}
[Fact]
public void InsertRange_WithReadOnlySpan_WithEmptySpan_ReturnsSameList()
{
// Arrange
var node = CreateMarkupTextLiteral(s_openAngle);
SyntaxList<SyntaxNode> originalList = [node];
var emptySpan = ReadOnlySpan<SyntaxNode>.Empty;
// Act
var newList = originalList.InsertRange(0, emptySpan);
// Assert
Assert.Equal(originalList.Count, newList.Count);
Assert.True(originalList[0].IsEquivalentTo(newList[0]));
}
[Fact]
public void InsertRange_WithReadOnlySpan_IntoEmptyList_CreatesListWithAllNodes()
{
// Arrange
var emptyList = SyntaxList<SyntaxNode>.Empty;
SyntaxNode[] nodesToInsert = [
CreateMarkupTextLiteral(s_openAngle),
CreateMarkupTextLiteral(s_forwardSlash),
CreateMarkupTextLiteral(s_closeAngle)
];
// Act
var newList = emptyList.InsertRange(0, nodesToInsert.AsSpan());
// Assert
Assert.Empty(emptyList);
Assert.Equal(nodesToInsert.Length, newList.Count);
for (var i = 0; i < nodesToInsert.Length; i++)
{
Assert.True(nodesToInsert[i].IsEquivalentTo(newList[i]));
}
}
[Fact]
public void InsertRange_WithReadOnlySpan_ImplementsImmutability_DoesNotModifyOriginalList()
{
// Arrange
var existingNode = CreateMarkupTextLiteral(s_openAngle);
SyntaxList<SyntaxNode> originalList = [existingNode];
SyntaxNode[] nodesToInsert = [
CreateMarkupTextLiteral(s_forwardSlash),
CreateMarkupTextLiteral(s_closeAngle)
];
// Act
var newList = originalList.InsertRange(0, nodesToInsert.AsSpan());
// Assert
Assert.Single(originalList);
Assert.True(existingNode.IsEquivalentTo(originalList[0]));
Assert.Equal(3, newList.Count);
}
[Fact]
public void InsertRange_WithReadOnlySpan_ThrowsArgumentOutOfRangeException_WhenIndexIsNegative()
{
// Arrange
SyntaxList<SyntaxNode> list = [CreateMarkupTextLiteral(s_openAngle)];
SyntaxNode[] nodes = [CreateMarkupTextLiteral(s_closeAngle)];
// Act & Assert
Assert.Throws<ArgumentOutOfRangeException>(() => list.InsertRange(-1, nodes.AsSpan()));
}
[Fact]
public void InsertRange_WithReadOnlySpan_ThrowsArgumentOutOfRangeException_WhenIndexExceedsCount()
{
// Arrange
SyntaxList<SyntaxNode> list = [CreateMarkupTextLiteral(s_openAngle)];
SyntaxNode[] nodes = [CreateMarkupTextLiteral(s_closeAngle)];
// Act & Assert
Assert.Throws<ArgumentOutOfRangeException>(() => list.InsertRange(list.Count + 1, nodes.AsSpan()));
}
[Fact]
public void InsertRange_AtBeginning_InsertsNodesAtStart()
{
// Arrange
var existingNode = CreateMarkupTextLiteral(s_closeAngle);
SyntaxList<SyntaxNode> originalList = [existingNode];
SyntaxNode[] nodesToInsert = [
CreateMarkupTextLiteral(s_openAngle),
CreateMarkupTextLiteral(s_forwardSlash)
];
// Act
var newList = originalList.InsertRange(0, nodesToInsert);
// Assert
Assert.Single(originalList);
Assert.Equal(nodesToInsert.Length + 1, newList.Count);
Assert.True(nodesToInsert[0].IsEquivalentTo(newList[0]));
Assert.True(nodesToInsert[1].IsEquivalentTo(newList[1]));
Assert.True(existingNode.IsEquivalentTo(newList[2]));
}
[Fact]
public void InsertRange_AtMiddle_InsertsNodesAtCorrectPosition()
{
// Arrange
var node1 = CreateMarkupTextLiteral(s_openAngle);
var node2 = CreateMarkupTextLiteral(s_closeAngle);
SyntaxList<SyntaxNode> originalList = [node1, node2];
SyntaxNode[] nodesToInsert = [
CreateMarkupTextLiteral(s_forwardSlash),
CreateMarkupTextLiteral(s_rightBrace)
];
// Act
var newList = originalList.InsertRange(1, nodesToInsert);
// Assert
Assert.Equal(2, originalList.Count);
Assert.Equal(originalList.Count + nodesToInsert.Length, newList.Count);
Assert.True(node1.IsEquivalentTo(newList[0]));
Assert.True(nodesToInsert[0].IsEquivalentTo(newList[1]));
Assert.True(nodesToInsert[1].IsEquivalentTo(newList[2]));
Assert.True(node2.IsEquivalentTo(newList[3]));
}
[Fact]
public void InsertRange_AtEnd_SameAsAddRange()
{
// Arrange
var node1 = CreateMarkupTextLiteral(s_openAngle);
SyntaxList<SyntaxNode> originalList = [node1];
SyntaxNode[] nodesToInsert = [
CreateMarkupTextLiteral(s_forwardSlash),
CreateMarkupTextLiteral(s_closeAngle)
];
// Act
var insertResult = originalList.InsertRange(originalList.Count, nodesToInsert);
var addResult = originalList.AddRange(nodesToInsert);
// Assert
Assert.Equal(addResult.Count, insertResult.Count);
for (var i = 0; i < addResult.Count; i++)
{
Assert.True(addResult[i].IsEquivalentTo(insertResult[i]));
}
}
[Fact]
public void InsertRange_WithEmptyCollection_ReturnsSameList()
{
// Arrange
var node = CreateMarkupTextLiteral(s_openAngle);
SyntaxList<SyntaxNode> originalList = [node];
var emptyNodes = Array.Empty<SyntaxNode>();
// Act
var newList = originalList.InsertRange(0, emptyNodes);
// Assert
Assert.Equal(originalList.Count, newList.Count);
Assert.True(originalList[0].IsEquivalentTo(newList[0]));
}
[Fact]
public void InsertRange_IntoEmptyList_CreatesListWithAllNodes()
{
// Arrange
var emptyList = SyntaxList<SyntaxNode>.Empty;
SyntaxNode[] nodesToInsert = [
CreateMarkupTextLiteral(s_openAngle),
CreateMarkupTextLiteral(s_forwardSlash),
CreateMarkupTextLiteral(s_closeAngle)
];
// Act
var newList = emptyList.InsertRange(0, nodesToInsert);
// Assert
Assert.Empty(emptyList);
Assert.Equal(nodesToInsert.Length, newList.Count);
for (var i = 0; i < nodesToInsert.Length; i++)
{
Assert.True(nodesToInsert[i].IsEquivalentTo(newList[i]));
}
}
[Fact]
public void InsertRange_ImplementsImmutability_DoesNotModifyOriginalList()
{
// Arrange
var existingNode = CreateMarkupTextLiteral(s_openAngle);
SyntaxList<SyntaxNode> originalList = [existingNode];
SyntaxNode[] nodesToInsert = [
CreateMarkupTextLiteral(s_forwardSlash),
CreateMarkupTextLiteral(s_closeAngle)
];
// Act
var newList = originalList.InsertRange(0, nodesToInsert);
// Assert
Assert.Single(originalList);
Assert.True(existingNode.IsEquivalentTo(originalList[0]));
Assert.Equal(3, newList.Count);
}
[Fact]
public void InsertRange_ThrowsArgumentNullException_WhenNodesIsNull()
{
// Arrange
SyntaxList<SyntaxNode> list = [CreateMarkupTextLiteral(s_openAngle)];
IEnumerable<SyntaxNode> newNodes = null!;
// Act & Assert
Assert.Throws<ArgumentNullException>(() => list.InsertRange(0, newNodes));
}
[Fact]
public void InsertRange_ThrowsArgumentOutOfRangeException_WhenIndexIsNegative()
{
// Arrange
SyntaxList<SyntaxNode> list = [CreateMarkupTextLiteral(s_openAngle)];
var nodes = new[] { CreateMarkupTextLiteral(s_closeAngle) };
// Act & Assert
Assert.Throws<ArgumentOutOfRangeException>(() => list.InsertRange(-1, nodes));
}
[Fact]
public void InsertRange_ThrowsArgumentOutOfRangeException_WhenIndexExceedsCount()
{
// Arrange
SyntaxList<SyntaxNode> list = [CreateMarkupTextLiteral(s_openAngle)];
var nodes = new[] { CreateMarkupTextLiteral(s_closeAngle) };
// Act & Assert
Assert.Throws<ArgumentOutOfRangeException>(() => list.InsertRange(list.Count + 1, nodes));
}
[Fact]
public void InsertRange_WithListAsSource_InsertsAllNodes()
{
// Arrange
var existingNode = CreateMarkupTextLiteral(s_openAngle);
SyntaxList<SyntaxNode> originalList = [existingNode];
List<SyntaxNode> nodesToInsert = [
CreateMarkupTextLiteral(s_forwardSlash),
CreateMarkupTextLiteral(s_closeAngle)
];
// Act
var newList = originalList.InsertRange(0, nodesToInsert);
// Assert
Assert.Single(originalList);
Assert.Equal(nodesToInsert.Count + 1, newList.Count);
for (var i = 0; i < nodesToInsert.Count; i++)
{
Assert.True(nodesToInsert[i].IsEquivalentTo(newList[i]));
}
Assert.True(existingNode.IsEquivalentTo(newList[^1]));
}
[Fact]
public void InsertRange_WithIEnumerableAsSource_InsertsAllNodes()
{
// Arrange
var existingNode = CreateMarkupTextLiteral(s_closeAngle);
SyntaxList<SyntaxNode> originalList = [existingNode];
IEnumerable<SyntaxNode> nodesToInsert = [
CreateMarkupTextLiteral(s_openAngle),
CreateMarkupTextLiteral(s_forwardSlash)
];
// Act
var newList = originalList.InsertRange(0, nodesToInsert);
// Assert
Assert.Single(originalList);
Assert.Equal(3, newList.Count);
var index = 0;
foreach (var node in nodesToInsert)
{
Assert.True(node.IsEquivalentTo(newList[index++]));
}
Assert.True(existingNode.IsEquivalentTo(newList[^1]));
}
[Fact]
public void RemoveAt_SingleElementList_ReturnsEmptyList()
{
// Arrange
var node = CreateMarkupTextLiteral(s_openAngle);
SyntaxList<SyntaxNode> originalList = [node];
// Act
var newList = originalList.RemoveAt(0);
// Assert
Assert.Single(originalList);
Assert.Empty(newList);
}
[Fact]
public void RemoveAt_FromBeginning_RemovesCorrectNode()
{
// Arrange
var node1 = CreateMarkupTextLiteral(s_openAngle);
var node2 = CreateMarkupTextLiteral(s_forwardSlash);
var node3 = CreateMarkupTextLiteral(s_closeAngle);
SyntaxList<SyntaxNode> originalList = [node1, node2, node3];
// Act
var newList = originalList.RemoveAt(0);
// Assert
Assert.Equal(3, originalList.Count);
Assert.Equal(2, newList.Count);
Assert.True(node2.IsEquivalentTo(newList[0]));
Assert.True(node3.IsEquivalentTo(newList[1]));
}
[Fact]
public void RemoveAt_FromMiddle_RemovesCorrectNode()
{
// Arrange
var node1 = CreateMarkupTextLiteral(s_openAngle);
var node2 = CreateMarkupTextLiteral(s_forwardSlash);
var node3 = CreateMarkupTextLiteral(s_closeAngle);
SyntaxList<SyntaxNode> originalList = [node1, node2, node3];
// Act
var newList = originalList.RemoveAt(1);
// Assert
Assert.Equal(3, originalList.Count);
Assert.Equal(2, newList.Count);
Assert.True(node1.IsEquivalentTo(newList[0]));
Assert.True(node3.IsEquivalentTo(newList[1]));
}
[Fact]
public void RemoveAt_FromEnd_RemovesCorrectNode()
{
// Arrange
var node1 = CreateMarkupTextLiteral(s_openAngle);
var node2 = CreateMarkupTextLiteral(s_forwardSlash);
var node3 = CreateMarkupTextLiteral(s_closeAngle);
SyntaxList<SyntaxNode> originalList = [node1, node2, node3];
// Act
var newList = originalList.RemoveAt(2);
// Assert
Assert.Equal(3, originalList.Count);
Assert.Equal(2, newList.Count);
Assert.True(node1.IsEquivalentTo(newList[0]));
Assert.True(node2.IsEquivalentTo(newList[1]));
}
[Fact]
public void RemoveAt_ThrowsArgumentOutOfRangeException_WhenIndexIsNegative()
{
// Arrange
var node = CreateMarkupTextLiteral(s_openAngle);
SyntaxList<SyntaxNode> list = [node];
// Act & Assert
Assert.Throws<ArgumentOutOfRangeException>(() => list.RemoveAt(-1));
}
[Fact]
public void RemoveAt_ThrowsArgumentOutOfRangeException_WhenIndexExceedsOrEqualsCount()
{
// Arrange
var node = CreateMarkupTextLiteral(s_openAngle);
SyntaxList<SyntaxNode> list = [node];
// Act & Assert
Assert.Throws<ArgumentOutOfRangeException>(() => list.RemoveAt(list.Count));
}
[Fact]
public void RemoveAt_ImplementsImmutability_DoesNotModifyOriginalList()
{
// Arrange
var node1 = CreateMarkupTextLiteral(s_openAngle);
var node2 = CreateMarkupTextLiteral(s_forwardSlash);
SyntaxList<SyntaxNode> originalList = [node1, node2];
// Act
var newList = originalList.RemoveAt(0);
// Assert
Assert.Equal(2, originalList.Count);
Assert.True(node1.IsEquivalentTo(originalList[0]));
Assert.True(node2.IsEquivalentTo(originalList[1]));
Assert.Single(newList);
}
[Fact]
public void RemoveAt_DelegatesToRemove_WithCorrectNode()
{
// Arrange
var node1 = CreateMarkupTextLiteral(s_openAngle);
var node2 = CreateMarkupTextLiteral(s_forwardSlash);
SyntaxList<SyntaxNode> originalList = [node1, node2];
// Act
var removeAtResult = originalList.RemoveAt(0);
var removeResult = originalList.Remove(originalList[0]);
// Assert
Assert.Equal(removeResult.Count, removeAtResult.Count);
for (var i = 0; i < removeResult.Count; i++)
{
Assert.True(removeResult[i].IsEquivalentTo(removeAtResult[i]));
}
}
[Fact]
public void Remove_SingleElementList_ReturnsEmptyList()
{
// Arrange
var node = CreateMarkupTextLiteral(s_openAngle);
SyntaxList<SyntaxNode> originalList = [node];
// Act
var newList = originalList.Remove(originalList[0]);
// Assert
Assert.Single(originalList);
Assert.Empty(newList);
}
[Fact]
public void Remove_FromList_RemovesMatchingNode()
{
// Arrange
var node1 = CreateMarkupTextLiteral(s_openAngle);
var node2 = CreateMarkupTextLiteral(s_forwardSlash);
var node3 = CreateMarkupTextLiteral(s_closeAngle);
SyntaxList<SyntaxNode> originalList = [node1, node2, node3];
// Act
var newList = originalList.Remove(originalList[1]);
// Assert
Assert.Equal(3, originalList.Count);
Assert.Equal(2, newList.Count);
Assert.True(node1.IsEquivalentTo(newList[0]));
Assert.True(node3.IsEquivalentTo(newList[1]));
}
[Fact]
public void Remove_NodeNotInList_ReturnsSameList()
{
// Arrange
var node1 = CreateMarkupTextLiteral(s_openAngle);
var node2 = CreateMarkupTextLiteral(s_forwardSlash);
var nodeNotInList = CreateMarkupTextLiteral(s_closeAngle);
SyntaxList<SyntaxNode> originalList = [node1, node2];
// Act
var newList = originalList.Remove(nodeNotInList);
// Assert
Assert.Equal(2, originalList.Count);
Assert.Equal(2, newList.Count);
Assert.True(node1.IsEquivalentTo(newList[0]));
Assert.True(node2.IsEquivalentTo(newList[1]));
}
[Fact]
public void Remove_ImplementsImmutability_DoesNotModifyOriginalList()
{
// Arrange
var node1 = CreateMarkupTextLiteral(s_openAngle);
var node2 = CreateMarkupTextLiteral(s_forwardSlash);
SyntaxList<SyntaxNode> originalList = [node1, node2];
// Act
var newList = originalList.Remove(originalList[0]);
// Assert
Assert.Equal(2, originalList.Count);
Assert.True(node1.IsEquivalentTo(originalList[0]));
Assert.True(node2.IsEquivalentTo(originalList[1]));
Assert.Single(newList);
}
[Fact]
public void Remove_FromEmptyList_ReturnsEmptyList()
{
// Arrange
var emptyList = SyntaxList<SyntaxNode>.Empty;
var node = CreateMarkupTextLiteral(s_openAngle);
// Act
var newList = emptyList.Remove(node);
// Assert
Assert.Empty(emptyList);
Assert.Empty(newList);
}
[Fact]
public void Replace_SingleNodeList_ReplacesNode()
{
// Arrange
var original = CreateMarkupTextLiteral(s_openAngle);
var replacement = CreateMarkupTextLiteral(s_closeAngle);
SyntaxList<SyntaxNode> originalList = [original];
// Act
var newList = originalList.Replace(originalList[0], replacement);
// Assert
Assert.Single(originalList);
Assert.Single(newList);
Assert.True(original.IsEquivalentTo(originalList[0]));
Assert.True(replacement.IsEquivalentTo(newList[0]));
}
[Fact]
public void Replace_MultiNodeList_ReplacesCorrectNode()
{
// Arrange
var node1 = CreateMarkupTextLiteral(s_openAngle);
var node2 = CreateMarkupTextLiteral(s_forwardSlash);
var node3 = CreateMarkupTextLiteral(s_closeAngle);
SyntaxList<SyntaxNode> originalList = [node1, node2, node3];
var replacement = CreateMarkupTextLiteral(s_leftBrace);
// Act
var newList = originalList.Replace(originalList[1], replacement);
// Assert
Assert.Equal(3, originalList.Count);
Assert.Equal(3, newList.Count);
Assert.True(node1.IsEquivalentTo(newList[0]));
Assert.True(replacement.IsEquivalentTo(newList[1]));
Assert.True(node3.IsEquivalentTo(newList[2]));
}
[Fact]
public void Replace_ImplementsImmutability_DoesNotModifyOriginalList()
{
// Arrange
var node1 = CreateMarkupTextLiteral(s_openAngle);
var node2 = CreateMarkupTextLiteral(s_forwardSlash);
SyntaxList<SyntaxNode> originalList = [node1, node2];
var replacement = CreateMarkupTextLiteral(s_closeAngle);
// Act
var newList = originalList.Replace(originalList[0], replacement);
// Assert
Assert.Equal(2, originalList.Count);
Assert.True(node1.IsEquivalentTo(originalList[0]));
Assert.True(node2.IsEquivalentTo(originalList[1]));
Assert.Equal(2, newList.Count);
}
[Fact]
public void Replace_ThrowsArgumentNullException_WhenNodeInListIsNull()
{
// Arrange
var node = CreateMarkupTextLiteral(s_openAngle);
SyntaxList<SyntaxNode> list = [node];
var replacement = CreateMarkupTextLiteral(s_closeAngle);
// Act & Assert
Assert.Throws<ArgumentNullException>(() => list.Replace(null!, replacement));
}
[Fact]
public void Replace_ThrowsArgumentNullException_WhenNewNodeIsNull()
{
// Arrange
var node = CreateMarkupTextLiteral(s_openAngle);
SyntaxList<SyntaxNode> list = [node];
// Act & Assert
Assert.Throws<ArgumentNullException>(() => list.Replace(list[0], null!));
}
[Fact]
public void Replace_ThrowsArgumentOutOfRangeException_WhenNodeNotInList()
{
// Arrange
var node = CreateMarkupTextLiteral(s_openAngle);
var nodeNotInList = CreateMarkupTextLiteral(s_forwardSlash);
var replacement = CreateMarkupTextLiteral(s_closeAngle);
SyntaxList<SyntaxNode> list = [node];
// Act & Assert
Assert.Throws<ArgumentOutOfRangeException>(() => list.Replace(nodeNotInList, replacement));
}
[Fact]
public void Replace_DelegatesToReplaceRange_WithSingleElementArray()
{
// Arrange
var node1 = CreateMarkupTextLiteral(s_openAngle);
var node2 = CreateMarkupTextLiteral(s_forwardSlash);
SyntaxList<SyntaxNode> originalList = [node1, node2];
var replacement = CreateMarkupTextLiteral(s_closeAngle);
// Act
var replaceResult = originalList.Replace(originalList[0], replacement);
var replaceRangeResult = originalList.ReplaceRange(originalList[0], [replacement]);
// Assert
Assert.Equal(replaceResult.Count, replaceRangeResult.Count);
for (var i = 0; i < replaceResult.Count; i++)
{
Assert.True(replaceResult[i].IsEquivalentTo(replaceRangeResult[i]));
}
}
[Fact]
public void ReplaceRange_WithReadOnlySpan_SingleNodeList_ReplacesNodeWithMultipleNodes()
{
// Arrange
var original = CreateMarkupTextLiteral(s_openAngle);
SyntaxNode[] replacements = [
CreateMarkupTextLiteral(s_forwardSlash),
CreateMarkupTextLiteral(s_closeAngle)
];
SyntaxList<SyntaxNode> originalList = [original];
// Act
var newList = originalList.ReplaceRange(originalList[0], replacements.AsSpan());
// Assert
Assert.Single(originalList);
Assert.Equal(2, newList.Count);
Assert.True(replacements[0].IsEquivalentTo(newList[0]));
Assert.True(replacements[1].IsEquivalentTo(newList[1]));
}
[Fact]
public void ReplaceRange_WithReadOnlySpan_MultiNodeList_ReplacesCorrectNodeWithMultipleNodes()
{
// Arrange
var node1 = CreateMarkupTextLiteral(s_openAngle);
var node2 = CreateMarkupTextLiteral(s_forwardSlash);
var node3 = CreateMarkupTextLiteral(s_closeAngle);
SyntaxList<SyntaxNode> originalList = [node1, node2, node3];
SyntaxNode[] replacements = [
CreateMarkupTextLiteral(s_leftBrace),
CreateMarkupTextLiteral(s_rightBrace)
];
// Act
var newList = originalList.ReplaceRange(originalList[1], replacements.AsSpan());
// Assert
Assert.Equal(3, originalList.Count);
Assert.Equal(4, newList.Count);
Assert.True(node1.IsEquivalentTo(newList[0]));
Assert.True(replacements[0].IsEquivalentTo(newList[1]));
Assert.True(replacements[1].IsEquivalentTo(newList[2]));
Assert.True(node3.IsEquivalentTo(newList[3]));
}
[Fact]
public void ReplaceRange_WithReadOnlySpan_MultiNodeList_ReplacesNodeWithEmptySpan()
{
// Arrange
var node1 = CreateMarkupTextLiteral(s_openAngle);
var node2 = CreateMarkupTextLiteral(s_forwardSlash);
var node3 = CreateMarkupTextLiteral(s_closeAngle);
SyntaxList<SyntaxNode> originalList = [node1, node2, node3];
// Act
var newList = originalList.ReplaceRange(originalList[1], []);
// Assert
Assert.Equal(3, originalList.Count);
Assert.Equal(2, newList.Count);
Assert.True(node1.IsEquivalentTo(newList[0]));
Assert.True(node3.IsEquivalentTo(newList[1]));
}
[Fact]
public void ReplaceRange_WithReadOnlySpan_ImplementsImmutability_DoesNotModifyOriginalList()
{
// Arrange
var node1 = CreateMarkupTextLiteral(s_openAngle);
var node2 = CreateMarkupTextLiteral(s_forwardSlash);
SyntaxList<SyntaxNode> originalList = [node1, node2];
SyntaxNode[] replacements = [
CreateMarkupTextLiteral(s_leftBrace),
CreateMarkupTextLiteral(s_rightBrace)
];
// Act
var newList = originalList.ReplaceRange(originalList[0], replacements.AsSpan());
// Assert
Assert.Equal(2, originalList.Count);
Assert.True(node1.IsEquivalentTo(originalList[0]));
Assert.True(node2.IsEquivalentTo(originalList[1]));
Assert.Equal(3, newList.Count);
}
[Fact]
public void ReplaceRange_WithReadOnlySpan_ThrowsArgumentOutOfRangeException_WhenNodeNotInList()
{
// Arrange
var node = CreateMarkupTextLiteral(s_openAngle);
var nodeNotInList = CreateMarkupTextLiteral(s_forwardSlash);
SyntaxNode[] replacements = [CreateMarkupTextLiteral(s_closeAngle)];
SyntaxList<SyntaxNode> list = [node];
// Act & Assert
Assert.Throws<ArgumentOutOfRangeException>(() => list.ReplaceRange(nodeNotInList, replacements.AsSpan()));
}
[Fact]
public void ReplaceRange_SingleNodeList_ReplacesNodeWithMultipleNodes()
{
// Arrange
var original = CreateMarkupTextLiteral(s_openAngle);
var replacement1 = CreateMarkupTextLiteral(s_forwardSlash);
var replacement2 = CreateMarkupTextLiteral(s_closeAngle);
SyntaxList<SyntaxNode> originalList = [original];
// Act
var newList = originalList.ReplaceRange(originalList[0], [replacement1, replacement2]);
// Assert
Assert.Single(originalList);
Assert.Equal(2, newList.Count);
Assert.True(replacement1.IsEquivalentTo(newList[0]));
Assert.True(replacement2.IsEquivalentTo(newList[1]));
}
[Fact]
public void ReplaceRange_MultiNodeList_ReplacesCorrectNodeWithMultipleNodes()
{
// Arrange
var node1 = CreateMarkupTextLiteral(s_openAngle);
var node2 = CreateMarkupTextLiteral(s_forwardSlash);
var node3 = CreateMarkupTextLiteral(s_closeAngle);
SyntaxList<SyntaxNode> originalList = [node1, node2, node3];
var replacement1 = CreateMarkupTextLiteral(s_leftBrace);
var replacement2 = CreateMarkupTextLiteral(s_rightBrace);
// Act
var newList = originalList.ReplaceRange(originalList[1], [replacement1, replacement2]);
// Assert
Assert.Equal(3, originalList.Count);
Assert.Equal(4, newList.Count);
Assert.True(node1.IsEquivalentTo(newList[0]));
Assert.True(replacement1.IsEquivalentTo(newList[1]));
Assert.True(replacement2.IsEquivalentTo(newList[2]));
Assert.True(node3.IsEquivalentTo(newList[3]));
}
[Fact]
public void ReplaceRange_MultiNodeList_ReplacesNodeWithEmptyList()
{
// Arrange
var node1 = CreateMarkupTextLiteral(s_openAngle);
var node2 = CreateMarkupTextLiteral(s_forwardSlash);
var node3 = CreateMarkupTextLiteral(s_closeAngle);
SyntaxList<SyntaxNode> originalList = [node1, node2, node3];
// Act
var newList = originalList.ReplaceRange(originalList[1], []);
// Assert
Assert.Equal(3, originalList.Count);
Assert.Equal(2, newList.Count);
Assert.True(node1.IsEquivalentTo(newList[0]));
Assert.True(node3.IsEquivalentTo(newList[1]));
}
[Fact]
public void ReplaceRange_ImplementsImmutability_DoesNotModifyOriginalList()
{
// Arrange
var node1 = CreateMarkupTextLiteral(s_openAngle);
var node2 = CreateMarkupTextLiteral(s_forwardSlash);
SyntaxList<SyntaxNode> originalList = [node1, node2];
var replacement1 = CreateMarkupTextLiteral(s_leftBrace);
var replacement2 = CreateMarkupTextLiteral(s_rightBrace);
// Act
var newList = originalList.ReplaceRange(originalList[0], [replacement1, replacement2]);
// Assert
Assert.Equal(2, originalList.Count);
Assert.True(node1.IsEquivalentTo(originalList[0]));
Assert.True(node2.IsEquivalentTo(originalList[1]));
Assert.Equal(3, newList.Count);
}
[Fact]
public void ReplaceRange_ThrowsArgumentNullException_WhenNodeInListIsNull()
{
// Arrange
var node = CreateMarkupTextLiteral(s_openAngle);
SyntaxList<SyntaxNode> list = [node];
var replacements = new[] { CreateMarkupTextLiteral(s_closeAngle) };
// Act & Assert
Assert.Throws<ArgumentNullException>(() => list.ReplaceRange(null!, replacements));
}
[Fact]
public void ReplaceRange_ThrowsArgumentNullException_WhenNewNodesIsNull()
{
// Arrange
var node = CreateMarkupTextLiteral(s_openAngle);
SyntaxList<SyntaxNode> list = [node];
IEnumerable<SyntaxNode> newNodes = null!;
// Act & Assert
Assert.Throws<ArgumentNullException>(() => list.ReplaceRange(node, newNodes));
}
[Fact]
public void ReplaceRange_ThrowsArgumentOutOfRangeException_WhenNodeNotInList()
{
// Arrange
var node = CreateMarkupTextLiteral(s_openAngle);
var nodeNotInList = CreateMarkupTextLiteral(s_forwardSlash);
var replacements = new[] { CreateMarkupTextLiteral(s_closeAngle) };
SyntaxList<SyntaxNode> list = [node];
// Act & Assert
Assert.Throws<ArgumentOutOfRangeException>(() => list.ReplaceRange(nodeNotInList, replacements));
}
[Fact]
public void ReplaceRange_WithListAsSource_ReplacesNodeCorrectly()
{
// Arrange
var node = CreateMarkupTextLiteral(s_openAngle);
SyntaxList<SyntaxNode> list = [node];
List<SyntaxNode> replacements = [
CreateMarkupTextLiteral(s_forwardSlash),
CreateMarkupTextLiteral(s_closeAngle)
];
// Act
var newList = list.ReplaceRange(list[0], replacements);
// Assert
Assert.Equal(replacements.Count, newList.Count);
for (var i = 0; i < replacements.Count; i++)
{
Assert.True(replacements[i].IsEquivalentTo(newList[i]));
}
}
[Fact]
public void ReplaceRange_WithIEnumerableAsSource_ReplacesNodeCorrectly()
{
// Arrange
var node = CreateMarkupTextLiteral(s_openAngle);
SyntaxList<SyntaxNode> list = [node];
IEnumerable<SyntaxNode> replacements = [
CreateMarkupTextLiteral(s_forwardSlash),
CreateMarkupTextLiteral(s_closeAngle)
];
// Act
var newList = list.ReplaceRange(list[0], replacements);
// Assert
Assert.Equal(2, newList.Count);
var index = 0;
foreach (var replacement in replacements)
{
Assert.True(replacement.IsEquivalentTo(newList[index++]));
}
}
}
|