|
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
namespace System.Drawing.Drawing2D.Tests;
public class CustomLineCapTests
{
public static IEnumerable<object[]> Ctor_Path_Path_LineCap_Float_TestData()
{
yield return new object[] { new GraphicsPath(), null, LineCap.Flat, 0f, LineCap.Flat };
yield return new object[] { new GraphicsPath(), null, LineCap.Square, 1f, LineCap.Square };
yield return new object[] { new GraphicsPath(), null, LineCap.Round, -1f, LineCap.Round };
yield return new object[] { new GraphicsPath(), null, LineCap.Triangle, float.MaxValue, LineCap.Triangle };
// All of these "anchor" values yield a "Flat" LineCap.
yield return new object[] { new GraphicsPath(), null, LineCap.NoAnchor, 0f, LineCap.Flat };
yield return new object[] { new GraphicsPath(), null, LineCap.SquareAnchor, 0f, LineCap.Flat };
yield return new object[] { new GraphicsPath(), null, LineCap.DiamondAnchor, 0f, LineCap.Flat };
yield return new object[] { new GraphicsPath(), null, LineCap.ArrowAnchor, 0f, LineCap.Flat };
// Boxy cap
GraphicsPath strokePath = new();
strokePath.AddRectangle(new Rectangle(0, 0, 10, 10));
yield return new object[] { null, strokePath, LineCap.Square, 0f, LineCap.Square };
// Hook-shaped cap
strokePath = new GraphicsPath();
strokePath.AddLine(new Point(0, 0), new Point(0, 5));
strokePath.AddLine(new Point(0, 5), new Point(5, 1));
strokePath.AddLine(new Point(5, 1), new Point(3, 1));
yield return new object[] { null, strokePath, LineCap.Flat, 0f, LineCap.Flat };
// Fill path -- Must intercept the Y-axis.
GraphicsPath fillPath = new();
fillPath.AddLine(new Point(-5, -10), new Point(0, 10));
fillPath.AddLine(new Point(0, 10), new Point(5, -10));
fillPath.AddLine(new Point(5, -10), new Point(-5, -10));
yield return new object[] { fillPath, null, LineCap.Flat, 0f, LineCap.Flat };
}
[Theory]
[MemberData(nameof(Ctor_Path_Path_LineCap_Float_TestData))]
public void Ctor_Path_Path_LineCap_Float(GraphicsPath fillPath, GraphicsPath strokePath, LineCap baseCap, float baseInset, LineCap expectedCap)
{
using (fillPath)
using (strokePath)
using (CustomLineCap customLineCap = new(fillPath, strokePath, baseCap, baseInset))
{
Assert.Equal(expectedCap, customLineCap.BaseCap);
Assert.Equal(baseInset, customLineCap.BaseInset);
Assert.Equal(LineJoin.Miter, customLineCap.StrokeJoin);
Assert.Equal(1f, customLineCap.WidthScale);
}
}
[Theory]
// These values are outside the valid range of the LineCap enum.
[InlineData(LineCap.Flat - 1)]
[InlineData(LineCap.Custom + 1)]
public void Ctor_InvalidLineCap_ReturnsFlat(LineCap baseCap)
{
using GraphicsPath fillPath = new();
using GraphicsPath strokePath = new();
using CustomLineCap customLineCap = new(fillPath, strokePath, baseCap, 0f);
Assert.Equal(LineCap.Flat, customLineCap.BaseCap);
}
[Fact]
public void Ctor_FillPath_Incomplete_ThrowsArgumentException()
{
using GraphicsPath fillPath = new();
fillPath.AddLine(new Point(0, -10), new Point(0, 10));
AssertExtensions.Throws<ArgumentException>(null, () => new CustomLineCap(fillPath, null));
}
[Fact]
public void Ctor_FillPath_DoesNotCrossYAxis_ThrowsNotImplementedException()
{
// Closed fillPath, but does not cross the Y-axis.
using GraphicsPath fillPath = new();
fillPath.AddLine(new Point(-5, 5), new Point(5, 5));
fillPath.AddLine(new Point(5, 5), new Point(5, 1));
fillPath.AddLine(new Point(5, 1), new Point(-5, 5));
Assert.Throws<NotImplementedException>(() => new CustomLineCap(fillPath, null));
}
[Theory]
[InlineData(LineCap.Square, LineCap.Square)]
[InlineData(LineCap.Round, LineCap.Round)]
[InlineData(LineCap.Triangle, LineCap.Triangle)]
public void SetThenGetStrokeCaps_Success(LineCap startCap, LineCap endCap)
{
using GraphicsPath strokePath = new();
using CustomLineCap customLineCap = new(null, strokePath);
customLineCap.SetStrokeCaps(startCap, endCap);
customLineCap.GetStrokeCaps(out LineCap retrievedStartCap, out LineCap retrievedEndCap);
Assert.Equal(startCap, retrievedStartCap);
Assert.Equal(endCap, retrievedEndCap);
}
[Theory]
[InlineData(LineCap.SquareAnchor, LineCap.SquareAnchor)]
[InlineData(LineCap.Custom, LineCap.Custom)]
[InlineData(LineCap.Square, LineCap.Custom)]
[InlineData(LineCap.Custom, LineCap.SquareAnchor)]
[InlineData(LineCap.Flat - 1, LineCap.Flat)] // Below valid enum range
[InlineData(LineCap.Custom + 1, LineCap.Flat)] // Above valid enum range
public void SetStrokeCaps_InvalidLineCap_ThrowsArgumentException(LineCap startCap, LineCap endCap)
{
using GraphicsPath strokePath = new();
using CustomLineCap customLineCap = new(null, strokePath);
AssertExtensions.Throws<ArgumentException>(null, () => customLineCap.SetStrokeCaps(startCap, endCap));
// start and end cap should be unchanged.
customLineCap.GetStrokeCaps(out LineCap retrievedStartCap, out LineCap retrievedEndCap);
Assert.Equal(LineCap.Flat, retrievedStartCap);
Assert.Equal(LineCap.Flat, retrievedEndCap);
}
[Theory]
[InlineData(LineJoin.Miter)] // Default value
[InlineData(LineJoin.Bevel)]
[InlineData(LineJoin.Round)]
[InlineData(LineJoin.MiterClipped)]
// Invalid (non-enum) values are allowed. Their values are stored and returned unchanged.
[InlineData(LineJoin.Miter - 1)]
[InlineData(LineJoin.MiterClipped + 1)]
public void StrokeJoin_SetThenGet_Success(LineJoin lineJoin)
{
using GraphicsPath strokePath = new();
using CustomLineCap customLineCap = new(null, strokePath);
customLineCap.StrokeJoin = lineJoin;
Assert.Equal(lineJoin, customLineCap.StrokeJoin);
}
[Theory]
[InlineData(LineCap.Flat)] // Default value
[InlineData(LineCap.Square)]
[InlineData(LineCap.Round)]
[InlineData(LineCap.Triangle)]
public void BaseCap_SetThenGet_Success(LineCap baseCap)
{
using GraphicsPath strokePath = new();
using CustomLineCap customLineCap = new(null, strokePath);
customLineCap.BaseCap = baseCap;
Assert.Equal(baseCap, customLineCap.BaseCap);
}
[Theory]
[InlineData(LineCap.NoAnchor)]
[InlineData(LineCap.SquareAnchor)]
[InlineData(LineCap.RoundAnchor)]
[InlineData(LineCap.DiamondAnchor)]
[InlineData(LineCap.Custom)]
[InlineData(LineCap.Flat - 1)]
[InlineData(LineCap.Custom + 1)]
public void BaseCap_Set_InvalidLineCap_ThrowsArgumentException(LineCap baseCap)
{
using GraphicsPath strokePath = new();
using CustomLineCap customLineCap = new(null, strokePath);
AssertExtensions.Throws<ArgumentException>(null, () => customLineCap.BaseCap = baseCap);
Assert.Equal(LineCap.Flat, customLineCap.BaseCap);
}
[Theory]
[InlineData(0f)]
[InlineData(1f)]
[InlineData(10f)]
[InlineData(10000f)]
[InlineData(-1f)]
[InlineData(-10f)]
[InlineData(-10000f)]
[InlineData(float.MaxValue)]
[InlineData(float.MinValue)]
[InlineData(float.PositiveInfinity)]
[InlineData(float.NegativeInfinity)]
[InlineData(float.NaN)]
public void BaseInset_SetThenGet_Success(float value)
{
using GraphicsPath strokePath = new();
using CustomLineCap customLineCap = new(null, strokePath);
customLineCap.BaseInset = value;
Assert.Equal(value, customLineCap.BaseInset);
}
[Theory]
[InlineData(0f)]
[InlineData(1f)]
[InlineData(10f)]
[InlineData(10000f)]
[InlineData(-1f)]
[InlineData(-10f)]
[InlineData(-10000f)]
[InlineData(float.MaxValue)]
[InlineData(float.MinValue)]
[InlineData(float.PositiveInfinity)]
[InlineData(float.NegativeInfinity)]
[InlineData(float.NaN)]
public void WidthScale_SetThenGet_Success(float value)
{
using GraphicsPath strokePath = new();
using CustomLineCap customLineCap = new(null, strokePath);
customLineCap.WidthScale = value;
Assert.Equal(value, customLineCap.WidthScale);
}
[Fact]
public void Disposed_MembersThrow()
{
using GraphicsPath strokePath = new();
using CustomLineCap customLineCap = new(null, strokePath);
customLineCap.Dispose();
AssertExtensions.Throws<ArgumentException>(null, () => customLineCap.StrokeJoin);
AssertExtensions.Throws<ArgumentException>(null, () => customLineCap.BaseCap);
AssertExtensions.Throws<ArgumentException>(null, () => customLineCap.BaseInset);
AssertExtensions.Throws<ArgumentException>(null, () => customLineCap.WidthScale);
AssertExtensions.Throws<ArgumentException>(null, customLineCap.Clone);
AssertExtensions.Throws<ArgumentException>(null, () => customLineCap.SetStrokeCaps(LineCap.Flat, LineCap.Flat));
AssertExtensions.Throws<ArgumentException>(null, () => customLineCap.GetStrokeCaps(out LineCap startCap, out LineCap endCap));
}
}
|