File: System\Windows\TextDecorationCollectionConverter.Tests.cs
Web Access
Project: src\src\Microsoft.DotNet.Wpf\tests\UnitTests\PresentationCore.Tests\PresentationCore.Tests.csproj (PresentationCore.Tests)
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
 
using System.ComponentModel.Design.Serialization;
using System.Globalization;
 
namespace System.Windows;
 
public class TextDecorationCollectionConverterTests
{
    [Theory]
    // Only valid type
    [InlineData(true, typeof(string))]
    // Invalid types
    [InlineData(false, typeof(TextDecorationCollection))]
    [InlineData(false, typeof(IEnumerable<TextDecoration>))]
    [InlineData(false, typeof(InstanceDescriptor))]
    public void CanConvertFrom_ReturnsExpected(bool expected, Type sourceType)
    {
        TextDecorationCollectionConverter converter = new();
 
        Assert.Equal(expected, converter.CanConvertFrom(sourceType));
    }
 
    [Theory]
    // Only valid type
    [InlineData(true, typeof(InstanceDescriptor))]
    // Invalid types
    [InlineData(false, typeof(TextDecorationCollection))]
    [InlineData(false, typeof(IEnumerable<TextDecoration>))]
    [InlineData(false, typeof(string))]
    public void CanConvertTo_ReturnsExpected(bool expected, Type destinationType)
    {
        TextDecorationCollectionConverter converter = new();
 
        Assert.Equal(expected, converter.CanConvertTo(destinationType));
    }
 
    [Theory]
    [MemberData(nameof(ConvertFrom_ReturnsExpected_Data))]
    public void ConvertFrom_ReturnsExpected(TextDecorationCollection expected, CultureInfo cultureInfo, string text)
    {
        TextDecorationCollectionConverter converter = new();
 
        TextDecorationCollection? converted = (TextDecorationCollection?)converter.ConvertFrom(null, cultureInfo, text);
 
        // Check count
        Assert.NotNull(converted);
        Assert.Equal(expected.Count, converted.Count);
 
        // We require the order to be exact as well
        for (int i = 0; i < expected.Count; i++)
        {
            Assert.Equal(expected[i], converted[i]);
        }
    }
 
    public static IEnumerable<object?[]> ConvertFrom_ReturnsExpected_Data
    {
        get
        {
            // "None" returns no items
            yield return new object[] { new TextDecorationCollection(), CultureInfo.InvariantCulture, string.Empty };
            yield return new object[] { new TextDecorationCollection(), CultureInfo.InvariantCulture, "          " };
            yield return new object[] { new TextDecorationCollection(), CultureInfo.InvariantCulture, "None" };
            yield return new object[] { new TextDecorationCollection(), CultureInfo.InvariantCulture, "      None     " };
 
            yield return new object[] { new TextDecorationCollection(), new CultureInfo("ru-RU"), string.Empty };
            yield return new object[] { new TextDecorationCollection(), new CultureInfo("no-NO"), "          " };
            yield return new object[] { new TextDecorationCollection(), new CultureInfo("no-NO"), "None" };
            yield return new object[] { new TextDecorationCollection(), new CultureInfo("ru-RU"), "      None     " };
 
            // Order matters here
            yield return new object[] { new TextDecorationCollection([TextDecorations.Strikethrough[0]]), new CultureInfo("no-NO"), "Strikethrough" };
            yield return new object[] { new TextDecorationCollection([TextDecorations.Strikethrough[0]]), new CultureInfo("ru-RU"), "Strikethrough           " };
 
            yield return new object[] { new TextDecorationCollection([TextDecorations.Underline[0], TextDecorations.Baseline[0]]),
                                        new CultureInfo("no-NO"),
                                        "Underline, Baseline" };
            yield return new object[] { new TextDecorationCollection([TextDecorations.Strikethrough[0], TextDecorations.Underline[0], TextDecorations.Baseline[0]]),
                                        new CultureInfo("ru-RU"),
                                        "  Strikethrough   ,Underline, Baseline " };
 
            yield return new object[] { new TextDecorationCollection([TextDecorations.Strikethrough[0], TextDecorations.Underline[0],
                                                                      TextDecorations.Baseline[0], TextDecorations.OverLine[0]]),
                                                                      new CultureInfo("fr-FR"), "  Strikethrough   ,Underline, Baseline        , Overline             " };
 
        }
    }
 
    [Theory]
    // Starts with a separator
    [InlineData(",  Strikethrough   ,Underline, Baseline ")]
    // Ends with a separator
    [InlineData(" Strikethrough   ,Underline, Baseline, Overline, ")]
    // Duplicate item (must be unique)
    [InlineData("  Strikethrough  , Strikethrough, ,Underline, Baseline ")]
    [InlineData(" Underline, Underline ")]
    // None must be specified alone
    [InlineData("None,  Strikethrough   ,Underline, Baseline ")]
    [InlineData("None,  Strikethrough   ,Underline, Baseline, Overline ")]
    // Invalid decoration at the end
    [InlineData(" Strikethrough   ,Underline, Baseline, Overline, x ")]
    // Invalid decoration
    [InlineData(" Noneee ")]
    // Invalid data type
    [InlineData(double.PositiveInfinity)]
    [InlineData(1554554)]
    [InlineData(125.4d)]
    public void ConvertFrom_ThrowsArgumentException(object? source)
    {
        TextDecorationCollectionConverter converter = new();
 
        Assert.Throws<ArgumentException>(() => converter.ConvertFrom(null, null, source));
    }
 
    [Theory]
    [MemberData(nameof(ConvertFromString_ReturnsExpected_Data))]
    public void ConvertFromString_ReturnsExpected(TextDecorationCollection expected, string text)
    {
        TextDecorationCollection converted = TextDecorationCollectionConverter.ConvertFromString(text);
 
        // Check count
        Assert.Equal(expected.Count, converted.Count);
 
        // We require the order to be exact as well
        for (int i = 0; i < expected.Count; i++)
        {
            Assert.Equal(expected[i], converted[i]);
        }
    }
 
    public static IEnumerable<object?[]> ConvertFromString_ReturnsExpected_Data
    {
        get
        {
            // "None" returns no items
            yield return new object[] { new TextDecorationCollection(), string.Empty };
            yield return new object[] { new TextDecorationCollection(), "          " };
            yield return new object[] { new TextDecorationCollection(), "None" };
            yield return new object[] { new TextDecorationCollection(), "      None     " };
 
            // Order matters here
            yield return new object[] { new TextDecorationCollection([TextDecorations.Strikethrough[0]]), "Strikethrough" };
            yield return new object[] { new TextDecorationCollection([TextDecorations.Strikethrough[0]]), "Strikethrough           " };
 
            yield return new object[] { new TextDecorationCollection([TextDecorations.Underline[0], TextDecorations.Baseline[0]]), "Underline, Baseline" };
            yield return new object[] { new TextDecorationCollection([TextDecorations.Strikethrough[0], TextDecorations.Underline[0], TextDecorations.Baseline[0]]),
                                                                     "  Strikethrough   ,Underline, Baseline " };
 
            yield return new object[] { new TextDecorationCollection([TextDecorations.Strikethrough[0], TextDecorations.Underline[0],
                                                                      TextDecorations.Baseline[0], TextDecorations.OverLine[0]]),
                                                                     "  Strikethrough   ,Underline, Baseline        , Overline             " };
 
        }
    }
 
    [Fact]
    public void ConvertFromString_NullValue_ReturnsNull()
    {
        // null is simply null (NOTE: This differs from instance method ConvertFrom, that will throw on null value)
        TextDecorationCollection? converted = TextDecorationCollectionConverter.ConvertFromString(null);
 
        Assert.Null(converted);
    }
 
    [Theory]
    // Starts with a separator
    [InlineData(",  Strikethrough   ,Underline, Baseline ")]
    // Ends with a separator
    [InlineData(" Strikethrough   ,Underline, Baseline, Overline, ")]
    // Duplicate item (must be unique)
    [InlineData("  Strikethrough  , Strikethrough, ,Underline, Baseline ")]
    [InlineData(" Underline, Underline ")]
    // None must be specified alone
    [InlineData("None,  Strikethrough   ,Underline, Baseline ")]
    [InlineData("None,  Strikethrough   ,Underline, Baseline, Overline ")]
    // Invalid decoration at the end
    [InlineData(" Strikethrough   ,Underline, Baseline, Overline, x ")]
    // Invalid decoration
    [InlineData(" Noneee ")]
    public void ConvertFromString_ThrowsArgumentException(string text)
    {
        Assert.Throws<ArgumentException>(() => TextDecorationCollectionConverter.ConvertFromString(text));
    }
 
    [Theory]
    [MemberData(nameof(ConvertTo_ReturnsExpected_Data))]
    public void ConvertTo_ReturnsExpected(TextDecorationCollection expected, object? value, Type destinationType)
    {
        TextDecorationCollectionConverter converter = new();
 
        InstanceDescriptor? result = (InstanceDescriptor?)converter.ConvertTo(null, null, value, destinationType);
 
        Assert.NotNull(result);
 
        // Create instance using the InstanceDescriptor
        TextDecorationCollection? actual = (TextDecorationCollection?)result.Invoke();
 
        // Check instance
        Assert.NotNull(actual);
        Assert.Equal(expected.Count, actual.Count);
 
        // We require the order to be exact as well
        for (int i = 0; i < expected.Count; i++)
        {
            Assert.Equal(expected[i], actual[i]);
        }
    }
 
    public static IEnumerable<object[]> ConvertTo_ReturnsExpected_Data
    {
        get
        {
            // Single decoration
            yield return new object[] { new TextDecorationCollection(new TextDecoration[1] { TextDecorations.Underline[0] }),
                                        new TextDecorationCollection(new TextDecoration[1] { TextDecorations.Underline[0] }),
                                        typeof(InstanceDescriptor) };
 
            // Multiple decorations
            yield return new object[] { new TextDecorationCollection(new TextDecoration[3] { TextDecorations.Underline[0], TextDecorations.OverLine[0], TextDecorations.Baseline[0] }),
                                        new TextDecorationCollection(new TextDecoration[3] { TextDecorations.Underline[0], TextDecorations.OverLine[0], TextDecorations.Baseline[0] }),
                                        typeof(InstanceDescriptor) };
 
            // Source value just needs to be IEnumerable<TextDecoration>
 
            // T[]
            yield return new object[] { new TextDecorationCollection(new TextDecoration[3] { TextDecorations.Underline[0], TextDecorations.OverLine[0], TextDecorations.Baseline[0] }),
                                        new TextDecoration[3] { TextDecorations.Underline[0], TextDecorations.OverLine[0], TextDecorations.Baseline[0] }, typeof(InstanceDescriptor) };
 
            // List<T>
            yield return new object[] { new TextDecorationCollection(new TextDecoration[3] { TextDecorations.Underline[0], TextDecorations.OverLine[0], TextDecorations.Baseline[0] }),
                                        new List<TextDecoration> { TextDecorations.Underline[0], TextDecorations.OverLine[0], TextDecorations.Baseline[0] }, typeof(InstanceDescriptor) };
        }
    }
 
    [Theory]
    [MemberData(nameof(ConvertTo_ThrowsArgumentNullException_Data))]
    public void ConvertTo_ThrowsArgumentNullException(object value, Type destinationType)
    {
        TextDecorationCollectionConverter converter = new();
 
        Assert.Throws<ArgumentNullException>(() => converter.ConvertTo(null, null, value, destinationType));
    }
 
    public static IEnumerable<object?[]> ConvertTo_ThrowsArgumentNullException_Data
    {
        get
        {
            // null value and destinationType
            yield return new object?[] { null, null };
            // supported value, null destinationType
            yield return new object?[] { new TextDecorationCollection(), null };
        }
    }
 
    [Fact]
    public void ConvertTo_ThrowsNotSupportedException()
    {
        TextDecorationCollectionConverter converter = new();
 
        // supported value, bad destinationType
        Assert.Throws<NotSupportedException>(() => converter.ConvertTo(null, null, new TextDecorationCollection(), typeof(TextDecorationCollection)));
    }
}