File: System\Xaml\XamlNodeListTests.cs
Web Access
Project: src\src\Microsoft.DotNet.Wpf\tests\UnitTests\System.Xaml.Tests\System.Xaml.Tests.csproj (System.Xaml.Tests)
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
 
using System.Reflection;
using Xunit;
 
namespace System.Xaml.Tests;
 
public class XamlNodeListTests
{
    [Fact]
    public void Ctor_XamlSchemaContext()
    {
        var context = new XamlSchemaContext();
        var list = new XamlNodeList(context);
        Assert.Equal(0, list.Count);
    }
 
    [Theory]
    [InlineData(0)]
    [InlineData(1)]
    public void Ctor_XamlSchemaContext_Int(int size)
    {
        var context = new XamlSchemaContext();
        var list = new XamlNodeList(context, size);
        Assert.Equal(0, list.Count);
    }
 
    [Fact]
    public void Ctor_NullSchemaContext_ThrowsArgumentNullException()
    {
        Assert.Throws<ArgumentNullException>("schemaContext", () => new XamlNodeList(null));
        Assert.Throws<ArgumentNullException>("schemaContext", () => new XamlNodeList(null, 64));
    }
 
    [Fact]
    public void Ctor_NegativeSize_ThrowsArgumentOutOfRangeException()
    {
        var context = new XamlSchemaContext();
        Assert.Throws<ArgumentOutOfRangeException>("capacity", () => new XamlNodeList(context, -1));
    }
 
    [Fact]
    public void GetReader_WriterClosed_ReturnsExpected()
    {
        var context = new XamlSchemaContext();
        var list = new XamlNodeList(context);
        list.Writer.Close();
 
        XamlReader reader = list.GetReader();
        Assert.Equal(XamlNodeType.None, reader.NodeType);
        Assert.False(reader.IsEof);
        Assert.Null(reader.Namespace);
        Assert.Null(reader.Type);
        Assert.Null(reader.Value);
        Assert.Null(reader.Member);
        Assert.Equal(context, reader.SchemaContext);
 
        IXamlIndexingReader indexingReader = Assert.IsAssignableFrom<IXamlIndexingReader>(reader);
        Assert.Equal(0, indexingReader.Count);
        Assert.Equal(-1, indexingReader.CurrentIndex);
    }
 
    [Fact]
    public void GetReader_ReadPastEof_ReturnsExpected()
    {
        var context = new XamlSchemaContext();
        var list = new XamlNodeList(context);
        list.Writer.WriteGetObject();
        list.Writer.WriteEndObject();
        list.Writer.Close();
 
        XamlReader reader = list.GetReader();
        IXamlIndexingReader indexingReader = Assert.IsAssignableFrom<IXamlIndexingReader>(reader);
 
        Assert.True(reader.Read());
        Assert.Equal(XamlNodeType.GetObject, reader.NodeType);
        Assert.False(reader.IsEof);
        Assert.Null(reader.Namespace);
        Assert.Null(reader.Type);
        Assert.Null(reader.Value);
        Assert.Null(reader.Member);
        Assert.Equal(2, indexingReader.Count);
        Assert.Equal(0, indexingReader.CurrentIndex);
 
        Assert.True(reader.Read());
        Assert.Equal(XamlNodeType.EndObject, reader.NodeType);
        Assert.False(reader.IsEof);
        Assert.Null(reader.Namespace);
        Assert.Null(reader.Type);
        Assert.Null(reader.Value);
        Assert.Null(reader.Member);
        Assert.Equal(2, indexingReader.Count);
        Assert.Equal(1, indexingReader.CurrentIndex);
 
        Assert.False(reader.Read());
        Assert.Equal(XamlNodeType.None, reader.NodeType);
        Assert.True(reader.IsEof);
        Assert.Null(reader.Namespace);
        Assert.Null(reader.Type);
        Assert.Null(reader.Value);
        Assert.Null(reader.Member);
        Assert.Equal(2, indexingReader.Count);
        Assert.Equal(2, indexingReader.CurrentIndex);
    }
 
    [Fact]
    public void GetReader_ReadWhenDisposed_ThrowsObjectDisposedException()
    {
        var list = new XamlNodeList(new XamlSchemaContext());
        list.Writer.Close();
 
        XamlReader reader = list.GetReader();
        reader.Close();
        
        Assert.Throws<ObjectDisposedException>(() => reader.Read());
    }
 
    [Fact]
    public void GetReader_SetCurrentIndex_SeeksToValue()
    {
        var context = new XamlSchemaContext();
        var list = new XamlNodeList(context);
        list.Writer.WriteGetObject();
        list.Writer.WriteEndObject();
        list.Writer.Close();
 
        XamlReader reader = list.GetReader();
        IXamlIndexingReader indexingReader = Assert.IsAssignableFrom<IXamlIndexingReader>(reader);
        indexingReader.CurrentIndex = 1;
        Assert.Equal(2, indexingReader.Count);
        Assert.Equal(1, indexingReader.CurrentIndex);
        Assert.Equal(XamlNodeType.EndObject, reader.NodeType);
        Assert.False(reader.IsEof);
        Assert.Null(reader.Namespace);
        Assert.Null(reader.Type);
        Assert.Null(reader.Value);
        Assert.Null(reader.Member);
        Assert.Equal(2, indexingReader.Count);
        Assert.Equal(1, indexingReader.CurrentIndex);
    }
 
    [Fact]
    public void GetReader_SetCurrentIndexEnd_SeeksToEof()
    {
        var context = new XamlSchemaContext();
        var list = new XamlNodeList(context);
        list.Writer.WriteGetObject();
        list.Writer.WriteEndObject();
        list.Writer.Close();
 
        XamlReader reader = list.GetReader();
        IXamlIndexingReader indexingReader = Assert.IsAssignableFrom<IXamlIndexingReader>(reader);
        indexingReader.CurrentIndex = 2;
        Assert.Equal(2, indexingReader.Count);
        Assert.Equal(2, indexingReader.CurrentIndex);
        Assert.Equal(XamlNodeType.None, reader.NodeType);
        Assert.True(reader.IsEof);
        Assert.Null(reader.Namespace);
        Assert.Null(reader.Type);
        Assert.Null(reader.Value);
        Assert.Null(reader.Member);
        Assert.Equal(2, indexingReader.Count);
        Assert.Equal(2, indexingReader.CurrentIndex);
    }
 
    [Fact]
    public void GetReader_SetCurrentIndexMinusOne_SeeksToStart()
    {
        var context = new XamlSchemaContext();
        var list = new XamlNodeList(context);
        list.Writer.WriteGetObject();
        list.Writer.WriteEndObject();
        list.Writer.Close();
 
        XamlReader reader = list.GetReader();
        IXamlIndexingReader indexingReader = Assert.IsAssignableFrom<IXamlIndexingReader>(reader);
        indexingReader.CurrentIndex = -1;
        Assert.Equal(2, indexingReader.Count);
        Assert.Equal(-1, indexingReader.CurrentIndex);
        Assert.Equal(XamlNodeType.None, reader.NodeType);
        Assert.False(reader.IsEof);
        Assert.Null(reader.Namespace);
        Assert.Null(reader.Type);
        Assert.Null(reader.Value);
        Assert.Null(reader.Member);
        Assert.Equal(2, indexingReader.Count);
        Assert.Equal(-1, indexingReader.CurrentIndex);
    }
 
    [Theory]
    [InlineData(-2)]
    [InlineData(3)]
    public void GetReader_SetInvalidIndex_ThrowsIndexOutOfRangeException(int value)
    {
        var context = new XamlSchemaContext();
        var list = new XamlNodeList(context);
        list.Writer.WriteGetObject();
        list.Writer.WriteEndObject();
        list.Writer.Close();
 
        XamlReader reader = list.GetReader();
        IXamlIndexingReader indexingReader = Assert.IsAssignableFrom<IXamlIndexingReader>(reader);
        Assert.Throws<IndexOutOfRangeException>(() => indexingReader.CurrentIndex = value);
    }
 
    [Fact]
    public void GetReader_WriterNotClosed_ThrowsXamlException()
    {
        var list = new XamlNodeList(new XamlSchemaContext());
        Assert.Throws<XamlException>(() => list.GetReader());
    }
 
    [Fact]
    public void Clear_Invoke_Success()
    {
        var list = new XamlNodeList(new XamlSchemaContext());
        list.Writer.WriteGetObject();
        list.Writer.Close();
        Assert.Equal(1, list.Count);
        Assert.NotNull(list.GetReader());
 
        list.Clear();
        Assert.Equal(0, list.Count);
        Assert.Throws<XamlException>(() => list.GetReader());
    }
 
    [Fact]
    public void Writer_Get_ReturnsExpected()
    {
        var list = new XamlNodeList(new XamlSchemaContext());
        XamlWriter writer = list.Writer;
        Assert.NotNull(writer);
        Assert.Same(writer, list.Writer);
    }
 
    [Fact]
    public void Writer_WriteGetObject_Success()
    {
        var list = new XamlNodeList(new XamlSchemaContext());
        XamlWriter writer = list.Writer;
        writer.WriteGetObject();
        Assert.Equal(1, list.Count);
 
        writer.Close();
        XamlReader reader = list.GetReader();
        Assert.True(reader.Read());
        Assert.Equal(1, list.Count);
        Assert.Equal(XamlNodeType.GetObject, reader.NodeType);
        Assert.False(reader.IsEof);
        Assert.Null(reader.Namespace);
        Assert.Null(reader.Type);
        Assert.Null(reader.Value);
        Assert.Null(reader.Member);
    }
 
    [Fact]
    public void Writer_WriteGetObjectWhenDisposed_ThrowsObjectDisposedException()
    {
        var list = new XamlNodeList(new XamlSchemaContext());
        XamlWriter writer = list.Writer;
        writer.Close();
 
        Assert.Throws<ObjectDisposedException>(() => writer.WriteGetObject());
    }
 
    [Fact]
    public void Writer_WriteStartObject_Success()
    {
        var list = new XamlNodeList(new XamlSchemaContext());
        XamlWriter writer = list.Writer;
        writer.WriteStartObject(XamlLanguage.Object);
        Assert.Equal(1, list.Count);
 
        writer.Close();
        XamlReader reader = list.GetReader();
        Assert.True(reader.Read());
        Assert.Equal(1, list.Count);
        Assert.Equal(XamlNodeType.StartObject, reader.NodeType);
        Assert.False(reader.IsEof);
        Assert.Null(reader.Namespace);
        Assert.Equal(XamlLanguage.Object, reader.Type);
        Assert.Null(reader.Value);
        Assert.Null(reader.Member);
    }
 
    [Fact]
    public void Writer_WriteStartObjectWhenDisposed_ThrowsObjectDisposedException()
    {
        var list = new XamlNodeList(new XamlSchemaContext());
        XamlWriter writer = list.Writer;
        writer.Close();
 
        Assert.Throws<ObjectDisposedException>(() => writer.WriteStartObject(null));
    }
 
    [Fact]
    public void Writer_WriteEndObject_Success()
    {
        var list = new XamlNodeList(new XamlSchemaContext());
        XamlWriter writer = list.Writer;
        writer.WriteEndObject();
        Assert.Equal(1, list.Count);
 
        writer.Close();
        XamlReader reader = list.GetReader();
        Assert.True(reader.Read());
        Assert.Equal(1, list.Count);
        Assert.Equal(XamlNodeType.EndObject, reader.NodeType);
        Assert.False(reader.IsEof);
        Assert.Null(reader.Namespace);
        Assert.Null(reader.Type);
        Assert.Null(reader.Value);
        Assert.Null(reader.Member);
    }
 
    [Fact]
    public void Writer_WriteEndObjectWhenDisposed_ThrowsObjectDisposedException()
    {
        var list = new XamlNodeList(new XamlSchemaContext());
        XamlWriter writer = list.Writer;
        writer.Close();
 
        Assert.Throws<ObjectDisposedException>(() => writer.WriteEndObject());
    }
 
    [Fact]
    public void Writer_WriteStartMember_Success()
    {
        var list = new XamlNodeList(new XamlSchemaContext());
        XamlWriter writer = list.Writer;
        writer.WriteStartMember(XamlLanguage.Key);
        Assert.Equal(1, list.Count);
 
        writer.Close();
        XamlReader reader = list.GetReader();
        Assert.True(reader.Read());
        Assert.Equal(1, list.Count);
        Assert.Equal(XamlNodeType.StartMember, reader.NodeType);
        Assert.False(reader.IsEof);
        Assert.Null(reader.Namespace);
        Assert.Null(reader.Type);
        Assert.Null(reader.Value);
        Assert.Equal(XamlLanguage.Key, reader.Member);
    }
 
    [Fact]
    public void Writer_WriteStartMemberWhenDisposed_ThrowsObjectDisposedException()
    {
        var list = new XamlNodeList(new XamlSchemaContext());
        XamlWriter writer = list.Writer;
        writer.Close();
 
        Assert.Throws<ObjectDisposedException>(() => writer.WriteStartMember(null));
    }
 
    [Fact]
    public void Writer_WriteEndMember_Success()
    {
        var list = new XamlNodeList(new XamlSchemaContext());
        XamlWriter writer = list.Writer;
        writer.WriteEndMember();
        Assert.Equal(1, list.Count);
 
        writer.Close();
        XamlReader reader = list.GetReader();
        Assert.True(reader.Read());
        Assert.Equal(1, list.Count);
        Assert.Equal(XamlNodeType.EndMember, reader.NodeType);
        Assert.False(reader.IsEof);
        Assert.Null(reader.Namespace);
        Assert.Null(reader.Type);
        Assert.Null(reader.Value);
        Assert.Null(reader.Member);
    }
 
    [Fact]
    public void Writer_WriteEndMemberWhenDisposed_ThrowsObjectDisposedException()
    {
        var list = new XamlNodeList(new XamlSchemaContext());
        XamlWriter writer = list.Writer;
        writer.Close();
 
        Assert.Throws<ObjectDisposedException>(() => writer.WriteEndMember());
    }
 
    [Fact]
    public void Writer_WriteValue_Success()
    {
        var list = new XamlNodeList(new XamlSchemaContext());
        XamlWriter writer = list.Writer;
        writer.WriteValue(1);
        Assert.Equal(1, list.Count);
 
        writer.Close();
        XamlReader reader = list.GetReader();
        Assert.True(reader.Read());
        Assert.Equal(1, list.Count);
        Assert.Equal(XamlNodeType.Value, reader.NodeType);
        Assert.False(reader.IsEof);
        Assert.Null(reader.Namespace);
        Assert.Null(reader.Type);
        Assert.Equal(1, reader.Value);
        Assert.Null(reader.Member);
    }
 
    [Fact]
    public void Writer_WriteValueWhenDisposed_ThrowsObjectDisposedException()
    {
        var list = new XamlNodeList(new XamlSchemaContext());
        XamlWriter writer = list.Writer;
        writer.Close();
 
        Assert.Throws<ObjectDisposedException>(() => writer.WriteValue(null));
    }
 
    [Fact]
    public void Writer_WriteNamespace_Success()
    {
        var list = new XamlNodeList(new XamlSchemaContext());
        XamlWriter writer = list.Writer;
        var namespaceDeclaration = new NamespaceDeclaration("namespace", "prefix");
        writer.WriteNamespace(namespaceDeclaration);
        Assert.Equal(1, list.Count);
 
        writer.Close();
        XamlReader reader = list.GetReader();
        Assert.True(reader.Read());
        Assert.Equal(1, list.Count);
        Assert.Equal(XamlNodeType.NamespaceDeclaration, reader.NodeType);
        Assert.False(reader.IsEof);
        Assert.Equal(namespaceDeclaration, reader.Namespace);
        Assert.Null(reader.Type);
        Assert.Null(reader.Value);
        Assert.Null(reader.Member);
    }
 
    [Fact]
    public void Writer_WriteNamespaceWhenDisposed_ThrowsObjectDisposedException()
    {
        var list = new XamlNodeList(new XamlSchemaContext());
        XamlWriter writer = list.Writer;
        writer.Close();
 
        Assert.Throws<ObjectDisposedException>(() => writer.WriteNamespace(null));
    }
 
    [Fact]
    public void Writer_SetLineInfoBeforeWrite_Success()
    {
        var list = new XamlNodeList(new XamlSchemaContext());
        XamlWriter writer = list.Writer;
        IXamlLineInfoConsumer consumer = Assert.IsAssignableFrom<IXamlLineInfoConsumer>(writer);
        var namespaceDeclaration = new NamespaceDeclaration("namespace", "prefix");
        consumer.SetLineInfo(1, 2);
        writer.WriteNamespace(namespaceDeclaration);
        Assert.Equal(2, list.Count);
 
        writer.Close();
        XamlReader reader = list.GetReader();
        IXamlLineInfo lineInfo = Assert.IsAssignableFrom<IXamlLineInfo>(reader);
        Assert.True(lineInfo.HasLineInfo);
        Assert.Equal(0, lineInfo.LineNumber);
        Assert.Equal(0, lineInfo.LinePosition);
 
        Assert.True(reader.Read());
        Assert.Equal(2, list.Count);
        Assert.Equal(XamlNodeType.NamespaceDeclaration, reader.NodeType);
        Assert.False(reader.IsEof);
        Assert.Equal(namespaceDeclaration, reader.Namespace);
        Assert.Null(reader.Type);
        Assert.Null(reader.Value);
        Assert.Null(reader.Member);
 
        Assert.True(lineInfo.HasLineInfo);
        Assert.Equal(1, lineInfo.LineNumber);
        Assert.Equal(2, lineInfo.LinePosition);
    }
 
    [Fact]
    public void Writer_SetLineInfoAfterWrite_Success()
    {
        var list = new XamlNodeList(new XamlSchemaContext());
        XamlWriter writer = list.Writer;
        IXamlLineInfoConsumer consumer = Assert.IsAssignableFrom<IXamlLineInfoConsumer>(writer);
        var namespaceDeclaration = new NamespaceDeclaration("namespace", "prefix");
        writer.WriteNamespace(namespaceDeclaration);
        consumer.SetLineInfo(1, 2);
        Assert.Equal(2, list.Count);
 
        writer.Close();
        XamlReader reader = list.GetReader();
        IXamlLineInfo lineInfo = Assert.IsAssignableFrom<IXamlLineInfo>(reader);
        Assert.True(lineInfo.HasLineInfo);
        Assert.Equal(0, lineInfo.LineNumber);
        Assert.Equal(0, lineInfo.LinePosition);
 
        Assert.True(reader.Read());
        Assert.Equal(2, list.Count);
        Assert.Equal(XamlNodeType.NamespaceDeclaration, reader.NodeType);
 
        Assert.True(lineInfo.HasLineInfo);
        Assert.Equal(0, lineInfo.LineNumber);
        Assert.Equal(0, lineInfo.LinePosition);
    }
 
    [Fact]
    public void Writer_SetLineInfoMultipleTimes_Success()
    {
        var list = new XamlNodeList(new XamlSchemaContext());
        XamlWriter writer = list.Writer;
        IXamlLineInfoConsumer consumer = Assert.IsAssignableFrom<IXamlLineInfoConsumer>(writer);
        consumer.SetLineInfo(1, 2);
        consumer.SetLineInfo(2, 3);
        Assert.Equal(2, list.Count);
 
        writer.Close();
        XamlReader reader = list.GetReader();
        IXamlLineInfo lineInfo = Assert.IsAssignableFrom<IXamlLineInfo>(reader);
        Assert.True(lineInfo.HasLineInfo);
        Assert.Equal(0, lineInfo.LineNumber);
        Assert.Equal(0, lineInfo.LinePosition);
 
        Assert.False(reader.Read());
        Assert.Equal(2, list.Count);
        Assert.Equal(XamlNodeType.None, reader.NodeType);
 
        Assert.True(lineInfo.HasLineInfo);
        Assert.Equal(0, lineInfo.LineNumber);
        Assert.Equal(0, lineInfo.LinePosition);
    }
 
    [Fact]
    public void Writer_SetLineInfoWhenDisposed_ThrowsObjectDisposedException()
    {
        var list = new XamlNodeList(new XamlSchemaContext());
        XamlWriter writer = list.Writer;
        writer.Close();
 
        IXamlLineInfoConsumer consumer = Assert.IsAssignableFrom<IXamlLineInfoConsumer>(writer);
        Assert.Throws<ObjectDisposedException>(() => consumer.SetLineInfo(1, 2));
    }
 
    [Fact]
    public void Writer_GetShouldProvideLineInfo_ReturnTrue()
    {
        var list = new XamlNodeList(new XamlSchemaContext());
        IXamlLineInfoConsumer consumer = Assert.IsAssignableFrom<IXamlLineInfoConsumer>(list.Writer);
        Assert.True(consumer.ShouldProvideLineInfo);
    }
 
    [Fact]
    public void Writer_GetShouldProvideLineInfoWhenDisposed_ThrowsObjectDisposedException()
    {
        var list = new XamlNodeList(new XamlSchemaContext());
        XamlWriter writer = list.Writer;
        writer.Close();
 
        IXamlLineInfoConsumer consumer = Assert.IsAssignableFrom<IXamlLineInfoConsumer>(writer);
        Assert.Throws<ObjectDisposedException>(() => consumer.ShouldProvideLineInfo);
    }
 
    [Fact]
    public void Writer_CloseMultipleTimes_Success()
    {
        var list = new XamlNodeList(new XamlSchemaContext());
        XamlWriter writer = list.Writer;
        writer.Close();
        writer.Close();
    }
 
    [Fact]
    public void Writer_DisposeDisposingFalse_Success()
    {
        var list = new XamlNodeList(new XamlSchemaContext());
        XamlWriter writer = list.Writer;
        MethodInfo dispose = writer.GetType().GetMethod("Dispose", BindingFlags.Instance | BindingFlags.NonPublic)!;
        dispose.Invoke(writer, new object[] { false });
 
        IXamlLineInfoConsumer consumer = Assert.IsAssignableFrom<IXamlLineInfoConsumer>(writer);
        Assert.Throws<ObjectDisposedException>(() => consumer.ShouldProvideLineInfo);
    }
 
    [Fact]
    public void Writer_DisposeCallAddDelegate_ThrowsXamlException()
    {
        // Dead code in WriterDelegate.
        var list = new XamlNodeList(new XamlSchemaContext());
        XamlWriter writer = list.Writer;
        writer.Close();
 
        FieldInfo addDelegateField = writer.GetType().GetField("_addDelegate", BindingFlags.Instance | BindingFlags.NonPublic)!;
        Delegate addDelegate = Assert.IsAssignableFrom<Delegate>(addDelegateField.GetValue(writer));
 
        bool threwXamlException = true;
        try
        {
            addDelegate.DynamicInvoke(new object?[] { null, null });
        }
        catch (TargetInvocationException ex) when (ex.InnerException is XamlException)
        {
            threwXamlException = true;
        }
        Assert.True(threwXamlException);
    }
 
    [Fact]
    public void Writer_DisposeCallAddLineInfoDelegate_ThrowsXamlException()
    {
        // Dead code in WriterDelegate.
        var list = new XamlNodeList(new XamlSchemaContext());
        XamlWriter writer = list.Writer;
        writer.Close();
 
        FieldInfo addLineInfoDelegateField = writer.GetType().GetField("_addLineInfoDelegate", BindingFlags.Instance | BindingFlags.NonPublic)!;
        Delegate addLineInfoDelegate = Assert.IsAssignableFrom<Delegate>(addLineInfoDelegateField.GetValue(writer));
 
        bool threwXamlException = true;
        try
        {
            addLineInfoDelegate.DynamicInvoke(new object?[] { null, null });
        }
        catch (TargetInvocationException ex) when (ex.InnerException is XamlException)
        {
            threwXamlException = true;
        }
        Assert.True(threwXamlException);
    }
 
    [Fact]
    public void Add_WriterClosed_ThrowsXamlException()
    {
        // Use reflection to simulate potential thread race condition.
        var list = new XamlNodeList(new XamlSchemaContext());
        list.Writer.Close();
 
        MethodInfo addMethod = typeof(XamlNodeList).GetMethod("Add", BindingFlags.Instance | BindingFlags.NonPublic)!;
        bool threwXamlException = true;
        try
        {
            addMethod.Invoke(list, new object?[] { null, null });
        }
        catch (TargetInvocationException ex) when (ex.InnerException is XamlException)
        {
            threwXamlException = true;
        }
        Assert.True(threwXamlException);
    }
 
    [Fact]
    public void AddLineInfo_WriterClosed_ThrowsXamlException()
    {
        // Use reflection to simulate potential thread race condition.
        var list = new XamlNodeList(new XamlSchemaContext());
        list.Writer.Close();
 
        MethodInfo addLineInfoMethod = typeof(XamlNodeList).GetMethod("AddLineInfo", BindingFlags.Instance | BindingFlags.NonPublic)!;
        bool threwXamlException = true;
        try
        {
            addLineInfoMethod.Invoke(list, new object[] { 1, 2 });
        }
        catch (TargetInvocationException ex) when (ex.InnerException is XamlException)
        {
            threwXamlException = true;
        }
        Assert.True(threwXamlException);
    }
 
    [Fact]
    public void Index_WriterNotClosed_ThrowsXamlException()
    {
        // Use reflection to simulate potential thread race condition.
        var list = new XamlNodeList(new XamlSchemaContext());
 
        MethodInfo indexMethod = typeof(XamlNodeList).GetMethod("Index", BindingFlags.Instance | BindingFlags.NonPublic)!;
        bool threwXamlException = true;
        try
        {
            indexMethod.Invoke(list, new object[] { 1 });
        }
        catch (TargetInvocationException ex) when (ex.InnerException is XamlException)
        {
            threwXamlException = true;
        }
        Assert.True(threwXamlException);
    }
 
    private delegate void XamlNodeAddDelegate(XamlNodeType nodeType, object data);
    private delegate void XamlLineInfoAddDelegate(int lineNumber, int linePosition);
}