Browse Source

[SL.Core] Merge pull request SixLabors/Core#6 from SixLabors/develop

create beta 1
af/octree-no-pixelmap
Scott Williams 9 years ago
committed by GitHub
parent
commit
146809d44c
  1. 13
      README.md
  2. 17
      SixLabors.Core.sln
  3. 8
      appveyor.yml
  4. 8
      build.cmd
  5. 1
      codecov.yml
  6. 9
      src/Shared/stylecop.json
  7. 4
      src/SixLabors.Core/Constants.cs
  8. 23
      src/SixLabors.Core/HashHelpers.cs
  9. 261
      src/SixLabors.Core/Helpers/DebugGuard.cs
  10. 266
      src/SixLabors.Core/Helpers/Guard.cs
  11. 28
      src/SixLabors.Core/Helpers/HashHelpers.cs
  12. 10
      src/SixLabors.Core/MathF.cs
  13. 8
      src/SixLabors.Core/Primitives/Matrix3x2Extensions.cs
  14. 42
      src/SixLabors.Core/Primitives/Point.cs
  15. 36
      src/SixLabors.Core/Primitives/PointF.cs
  16. 40
      src/SixLabors.Core/Primitives/Rectangle.cs
  17. 40
      src/SixLabors.Core/Primitives/RectangleF.cs
  18. 76
      src/SixLabors.Core/Primitives/Size.cs
  19. 68
      src/SixLabors.Core/Primitives/SizeF.cs
  20. 18
      src/SixLabors.Core/Properties/AssemblyInfo.cs
  21. 15
      src/SixLabors.Core/SixLabors.Core.csproj
  22. 9
      src/SixLabors.Core/stylecop.json
  23. 0
      src/SixLabors.ruleset
  24. 15
      stylecop.json
  25. 10
      tests/CodeCoverage/CodeCoverage.cmd
  26. 258
      tests/SixLabors.Core.Tests/Helpers/DebugGuardTests.cs
  27. 326
      tests/SixLabors.Core.Tests/Helpers/GuardTests.cs
  28. 24
      tests/SixLabors.Core.Tests/Primitives/PointFTests.cs
  29. 23
      tests/SixLabors.Core.Tests/Primitives/PointTests.cs
  30. 49
      tests/SixLabors.Core.Tests/Primitives/RectangleFTests.cs
  31. 33
      tests/SixLabors.Core.Tests/Primitives/RectangleTests.cs
  32. 22
      tests/SixLabors.Core.Tests/Primitives/SizeFTests.cs
  33. 22
      tests/SixLabors.Core.Tests/Primitives/SizeTests.cs
  34. 10
      tests/SixLabors.Core.Tests/SixLabors.Core.Tests.csproj
  35. 10
      tests/SixLabors.ruleset

13
README.md

@ -1,2 +1,11 @@
# Core
Point, Rectangle, Size Primitives for use across SixLabors libraries.
# SixLabers.Core
**SixLabors.Core** provides classes for use across SixLabors libraries.
[![Build status](https://ci.appveyor.com/api/projects/status/j1hvc99493b0jk3x/branch/develop?svg=true)](https://ci.appveyor.com/project/six-labors/core/branch/develop)
[![codecov](https://codecov.io/gh/SixLabors/Core/branch/develop/graph/badge.svg)](https://codecov.io/gh/SixLabors/Core)
[![GitHub license](https://img.shields.io/badge/license-Apache%202-blue.svg)](https://raw.githubusercontent.com/SixLabors/Core/master/LICENSE)
[![GitHub issues](https://img.shields.io/github/issues/SixLabors/Core.svg)](https://github.com/SixLabors/Core/issues)
[![GitHub stars](https://img.shields.io/github/stars/SixLabors/Core.svg)](https://github.com/SixLabors/Core/stargazers)
[![GitHub forks](https://img.shields.io/github/forks/SixLabors/Core.svg)](https://github.com/SixLabors/Core/network)

17
SixLabors.Core.sln

@ -1,13 +1,15 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0.26430.12
VisualStudioVersion = 15.0.26430.14
MinimumVisualStudioVersion = 10.0.40219.1
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "SolutionItems", "SolutionItems", "{C317F1B1-D75E-4C6D-83EB-80367343E0D7}"
ProjectSection(SolutionItems) = preProject
.editorconfig = .editorconfig
appveyor.yml = appveyor.yml
build.cmd = build.cmd
codecov.yml = codecov.yml
gitversion.yml = gitversion.yml
README.md = README.md
EndProjectSection
EndProject
@ -15,16 +17,15 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Source", "Source", "{815C06
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{56801022-D71A-4FBE-BC5B-CBA08E2284EC}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Shared", "Shared", "{9E574A07-F879-4811-9C41-5CBDC6BAFDB7}"
ProjectSection(SolutionItems) = preProject
src\Shared\AssemblyInfo.Common.cs = src\Shared\AssemblyInfo.Common.cs
src\Shared\stylecop.json = src\Shared\stylecop.json
EndProjectSection
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SixLabors.Core", "src\SixLabors.Core\SixLabors.Core.csproj", "{09E744EC-4852-4FC7-BE78-C1B399F17967}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SixLabors.Core.Tests", "tests\SixLabors.Core.Tests\SixLabors.Core.Tests.csproj", "{F836E8E6-B4D9-4208-8346-140C74678B91}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "CodeCoverage", "CodeCoverage", "{10A74B46-930F-49E3-A579-BC3A6A23321D}"
ProjectSection(SolutionItems) = preProject
tests\CodeCoverage\CodeCoverage.cmd = tests\CodeCoverage\CodeCoverage.cmd
EndProjectSection
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@ -44,9 +45,9 @@ Global
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{9E574A07-F879-4811-9C41-5CBDC6BAFDB7} = {815C0625-CD3D-440F-9F80-2D83856AB7AE}
{09E744EC-4852-4FC7-BE78-C1B399F17967} = {815C0625-CD3D-440F-9F80-2D83856AB7AE}
{F836E8E6-B4D9-4208-8346-140C74678B91} = {56801022-D71A-4FBE-BC5B-CBA08E2284EC}
{10A74B46-930F-49E3-A579-BC3A6A23321D} = {C317F1B1-D75E-4C6D-83EB-80367343E0D7}
EndGlobalSection
GlobalSection(Performance) = preSolution
HasPerformanceSessions = true

8
appveyor.yml

@ -24,6 +24,14 @@ deploy:
artifact: /.*\.nupkg/
on:
branch: master
- provider: NuGet
server: https://www.myget.org/F/sixlabors-unstable/api/v2/package
symbol_server: https://www.myget.org/F/sixlabors-unstable/symbols/api/v2/package
api_key:
secure: V/lEHP0UeMWIpWd0fiNlY2IgbCnJKQlGdRksECdJbOBdaE20Fl0RNL7WyqHe02o4
artifact: /.*\.nupkg/
on:
branch: develop
# prevent the double build when a branch has an active PR
skip_branch_with_pr: true

8
build.cmd

@ -2,14 +2,14 @@
if not "%GitVersion_NuGetVersion%" == "" (
dotnet restore /p:packageversion=%GitVersion_NuGetVersion%
)ELSE (
dotnet restore
)ELSE (
dotnet restore
)
ECHO Building nuget packages
if not "%GitVersion_NuGetVersion%" == "" (
dotnet build -c Release /p:packageversion=%GitVersion_NuGetVersion%
)ELSE (
)ELSE (
dotnet build -c Release
)
if not "%errorlevel%"=="0" goto failure
@ -19,7 +19,7 @@ dotnet test ./tests/SixLabors.Core.Tests/SixLabors.Primitives.Tests.csproj
if not "%GitVersion_NuGetVersion%" == "" (
dotnet pack ./src/SixLabors.Core/ -c Release --output ../../artifacts --no-build /p:packageversion=%GitVersion_NuGetVersion%
)ELSE (
)ELSE (
dotnet pack ./src/SixLabors.Core/ -c Release --output ../../artifacts --no-build
)

1
codecov.yml

@ -1,4 +1,5 @@
codecov:
branch: develop
notify:
require_ci_to_pass: true
comment: off

9
src/Shared/stylecop.json

@ -1,9 +0,0 @@
{
"$schema": "https://raw.githubusercontent.com/DotNetAnalyzers/StyleCopAnalyzers/master/StyleCop.Analyzers/StyleCop.Analyzers/Settings/stylecop.schema.json",
"settings": {
"documentationRules": {
"companyName": "Scott Williams",
"copyrightText": "Copyright (c) Scott Williams and contributors.\nLicensed under the Apache License, Version 2.0."
}
}
}

4
src/SixLabors.Core/Constants.cs

@ -1,7 +1,5 @@
// <copyright file="Constants.cs" company="Six Labors">
// Copyright (c) Six Labors and contributors.
// Copyright (c) Six Labors and contributors.
// Licensed under the Apache License, Version 2.0.
// </copyright>
namespace SixLabors
{

23
src/SixLabors.Core/HashHelpers.cs

@ -1,23 +0,0 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace SixLabors
{
// lifted from coreFX repo
internal static class HashHelpers
{
public static readonly int RandomSeed = Guid.NewGuid().GetHashCode();
public static int Combine(int h1, int h2)
{
unchecked
{
// RyuJIT optimizes this to use the ROL instruction
// Related GitHub pull request: dotnet/coreclr#1830
uint rol5 = ((uint)h1 << 5) | ((uint)h1 >> 27);
return ((int)rol5 + h1) ^ h2;
}
}
}
}

261
src/SixLabors.Core/Helpers/DebugGuard.cs

@ -0,0 +1,261 @@
// Copyright (c) Six Labors and contributors.
// Licensed under the Apache License, Version 2.0.
using System;
using System.Diagnostics;
namespace SixLabors
{
/// <summary>
/// Provides methods to protect against invalid parameters for a DEBUG build.
/// </summary>
[DebuggerStepThrough]
internal static class DebugGuard
{
/// <summary>
/// Verifies, that the method parameter with specified object value is not null
/// and throws an exception if it is found to be so.
/// </summary>
/// <param name="target">The target object, which cannot be null.</param>
/// <param name="parameterName">The name of the parameter that is to be checked.</param>
/// <exception cref="ArgumentNullException"><paramref name="target"/> is null</exception>
[Conditional("DEBUG")]
public static void NotNull(object target, string parameterName)
{
if (target == null)
{
throw new ArgumentNullException(parameterName);
}
}
/// <summary>
/// Verifies that the specified value is less than a maximum value
/// and throws an exception if it is not.
/// </summary>
/// <param name="value">The target value, which should be validated.</param>
/// <param name="max">The maximum value.</param>
/// <param name="parameterName">The name of the parameter that is to be checked.</param>
/// <typeparam name="TValue">The type of the value.</typeparam>
/// <exception cref="ArgumentException">
/// <paramref name="value"/> is greater than the maximum value.
/// </exception>
[Conditional("DEBUG")]
public static void MustBeLessThan<TValue>(TValue value, TValue max, string parameterName)
where TValue : IComparable<TValue>
{
if (value.CompareTo(max) >= 0)
{
throw new ArgumentOutOfRangeException(parameterName, $"Value must be less than {max}.");
}
}
/// <summary>
/// Verifies that the specified value is less than or equal to a maximum value
/// and throws an exception if it is not.
/// </summary>
/// <param name="value">The target value, which should be validated.</param>
/// <param name="max">The maximum value.</param>
/// <param name="parameterName">The name of the parameter that is to be checked.</param>
/// <typeparam name="TValue">The type of the value.</typeparam>
/// <exception cref="ArgumentException">
/// <paramref name="value"/> is greater than the maximum value.
/// </exception>
[Conditional("DEBUG")]
public static void MustBeLessThanOrEqualTo<TValue>(TValue value, TValue max, string parameterName)
where TValue : IComparable<TValue>
{
if (value.CompareTo(max) > 0)
{
throw new ArgumentOutOfRangeException(parameterName, $"Value must be less than or equal to {max}.");
}
}
/// <summary>
/// Verifies that the specified value is greater than a minimum value
/// and throws an exception if it is not.
/// </summary>
/// <param name="value">The target value, which should be validated.</param>
/// <param name="min">The minimum value.</param>
/// <param name="parameterName">The name of the parameter that is to be checked.</param>
/// <typeparam name="TValue">The type of the value.</typeparam>
/// <exception cref="ArgumentException">
/// <paramref name="value"/> is less than the minimum value.
/// </exception>
[Conditional("DEBUG")]
public static void MustBeGreaterThan<TValue>(TValue value, TValue min, string parameterName)
where TValue : IComparable<TValue>
{
if (value.CompareTo(min) <= 0)
{
throw new ArgumentOutOfRangeException(
parameterName,
$"Value must be greater than {min}.");
}
}
/// <summary>
/// Verifies that the specified value is greater than or equal to a minimum value
/// and throws an exception if it is not.
/// </summary>
/// <param name="value">The target value, which should be validated.</param>
/// <param name="min">The minimum value.</param>
/// <param name="parameterName">The name of the parameter that is to be checked.</param>
/// <typeparam name="TValue">The type of the value.</typeparam>
/// <exception cref="ArgumentException">
/// <paramref name="value"/> is less than the minimum value.
/// </exception>
[Conditional("DEBUG")]
public static void MustBeGreaterThanOrEqualTo<TValue>(TValue value, TValue min, string parameterName)
where TValue : IComparable<TValue>
{
if (value.CompareTo(min) < 0)
{
throw new ArgumentOutOfRangeException(parameterName, $"Value must be greater than or equal to {min}.");
}
}
/// <summary>
/// Verifies, that the method parameter with specified target value is true
/// and throws an exception if it is found to be so.
/// </summary>
/// <param name="target">
/// The target value, which cannot be false.
/// </param>
/// <param name="parameterName">
/// The name of the parameter that is to be checked.
/// </param>
/// <param name="message">
/// The error message, if any to add to the exception.
/// </param>
/// <exception cref="ArgumentException">
/// <paramref name="target"/> is false
/// </exception>
[Conditional("DEBUG")]
public static void IsTrue(bool target, string parameterName, string message)
{
if (!target)
{
throw new ArgumentException(message, parameterName);
}
}
/// <summary>
/// Verifies, that the method parameter with specified target value is false
/// and throws an exception if it is found to be so.
/// </summary>
/// <param name="target">The target value, which cannot be true.</param>
/// <param name="parameterName">The name of the parameter that is to be checked.</param>
/// <param name="message">The error message, if any to add to the exception.</param>
/// <exception cref="ArgumentException">
/// <paramref name="target"/> is true
/// </exception>
[Conditional("DEBUG")]
public static void IsFalse(bool target, string parameterName, string message)
{
if (target)
{
throw new ArgumentException(message, parameterName);
}
}
/// <summary>
/// Verifies, that the target span is of same size than the 'other' span.
/// </summary>
/// <typeparam name="T">The element type of the spans</typeparam>
/// <param name="target">The target span.</param>
/// <param name="other">The 'other' span to compare 'target' to.</param>
/// <param name="parameterName">The name of the parameter that is to be checked.</param>
/// <exception cref="ArgumentException">
/// <paramref name="target"/> is true
/// </exception>
[Conditional("DEBUG")]
public static void MustBeSameSized<T>(ReadOnlySpan<T> target, ReadOnlySpan<T> other, string parameterName)
where T : struct
{
if (target.Length != other.Length)
{
throw new ArgumentException("Span-s must be the same size.", parameterName);
}
}
/// <summary>
/// Verifies, that the target span is of same size than the 'other' span.
/// </summary>
/// <typeparam name="T">The element type of the spans</typeparam>
/// <param name="target">The target span.</param>
/// <param name="other">The 'other' span to compare 'target' to.</param>
/// <param name="parameterName">The name of the parameter that is to be checked.</param>
/// <exception cref="ArgumentException">
/// <paramref name="target"/> is true
/// </exception>
[Conditional("DEBUG")]
public static void MustBeSameSized<T>(Span<T> target, Span<T> other, string parameterName)
where T : struct
{
if (target.Length != other.Length)
{
throw new ArgumentException("Span-s must be the same size.", parameterName);
}
}
/// <summary>
/// Verifies, that the `target` span has the length of 'minSpan', or longer.
/// </summary>
/// <typeparam name="T">The element type of the spans</typeparam>
/// <param name="target">The target span.</param>
/// <param name="minSpan">The 'minSpan' span to compare 'target' to.</param>
/// <param name="parameterName">The name of the parameter that is to be checked.</param>
/// <exception cref="ArgumentException">
/// <paramref name="target"/> is true
/// </exception>
[Conditional("DEBUG")]
public static void MustBeSizedAtLeast<T>(ReadOnlySpan<T> target, ReadOnlySpan<T> minSpan, string parameterName)
where T : struct
{
if (target.Length < minSpan.Length)
{
throw new ArgumentException($"Span-s must be at least of length {minSpan.Length}.", parameterName);
}
}
/// <summary>
/// Verifies, that the `target` span has the length of 'minSpan', or longer.
/// </summary>
/// <typeparam name="T">The element type of the spans</typeparam>
/// <param name="target">The target span.</param>
/// <param name="minSpan">The 'minSpan' span to compare 'target' to.</param>
/// <param name="parameterName">The name of the parameter that is to be checked.</param>
/// <exception cref="ArgumentException">
/// <paramref name="target"/> is true
/// </exception>
[Conditional("DEBUG")]
public static void MustBeSizedAtLeast<T>(Span<T> target, Span<T> minSpan, string parameterName)
where T : struct
{
if (target.Length < minSpan.Length)
{
throw new ArgumentException($"Span-s must be at least of length {minSpan.Length}.", parameterName);
}
}
/// <summary>
/// Verifies, that the `target` array has declared the length or longer.
/// </summary>
/// <typeparam name="T">The element type of the spans</typeparam>
/// <param name="target">The target array.</param>
/// <param name="minLength">The min length the array must have.</param>
/// <param name="parameterName">The name of the parameter that is to be checked.</param>
/// <exception cref="ArgumentException">
/// <paramref name="target"/> is true
/// </exception>
[Conditional("DEBUG")]
public static void MustBeSizedAtLeast<T>(T[] target, int minLength, string parameterName)
where T : struct
{
if (target.Length < minLength)
{
throw new ArgumentException($"The size must be at least {minLength}.", parameterName);
}
}
}
}

266
src/SixLabors.Core/Helpers/Guard.cs

@ -0,0 +1,266 @@
// Copyright (c) Six Labors and contributors.
// Licensed under the Apache License, Version 2.0.
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
namespace SixLabors
{
/// <summary>
/// Provides methods to protect against invalid parameters.
/// </summary>
[DebuggerStepThrough]
internal static class Guard
{
/// <summary>
/// Verifies, that the method parameter with specified object value is not null
/// and throws an exception if it is found to be so.
/// </summary>
/// <param name="target">The target object, which cannot be null.</param>
/// <param name="parameterName">The name of the parameter that is to be checked.</param>
/// <param name="message">The error message, if any to add to the exception.</param>
/// <exception cref="ArgumentNullException"><paramref name="target"/> is null</exception>
public static void NotNull(object target, string parameterName, string message = "")
{
if (target == null)
{
if (!string.IsNullOrWhiteSpace(message))
{
throw new ArgumentNullException(parameterName, message);
}
throw new ArgumentNullException(parameterName);
}
}
/// <summary>
/// Verifies, that the string method parameter with specified object value and message
/// is not null, not empty and does not contain only blanks and throws an exception
/// if the object is null.
/// </summary>
/// <param name="target">The target string, which should be checked against being null or empty.</param>
/// <param name="parameterName">Name of the parameter.</param>
/// <param name="message">The error message, if any to add to the exception.</param>
/// <exception cref="ArgumentNullException"><paramref name="target"/> is null.</exception>
/// <exception cref="ArgumentException"><paramref name="target"/> is empty or contains only blanks.</exception>
public static void NotNullOrEmpty(string target, string parameterName, string message = "")
{
NotNull(target, parameterName, message);
if (string.IsNullOrWhiteSpace(target))
{
if (!string.IsNullOrWhiteSpace(message))
{
throw new ArgumentException(message, parameterName);
}
throw new ArgumentException("Value cannot be null, empty, or cannot contain only whitespace.", parameterName);
}
}
/// <summary>
/// Verifies, that the enumeration is not null and not empty.
/// </summary>
/// <typeparam name="T">The type of objects in the <paramref name="target"/></typeparam>
/// <param name="target">The target enumeration, which should be checked against being null or empty.</param>
/// <param name="parameterName">Name of the parameter.</param>
/// <param name="message">The error message, if any to add to the exception.</param>
/// <exception cref="ArgumentNullException"><paramref name="target"/> is null.</exception>
/// <exception cref="ArgumentException"><paramref name="target"/> is empty.</exception>
public static void NotNullOrEmpty<T>(IEnumerable<T> target, string parameterName, string message = "")
{
NotNull(target, parameterName, message);
if (!target.Any())
{
if (!string.IsNullOrWhiteSpace(message))
{
throw new ArgumentException(message, parameterName);
}
throw new ArgumentException("Value cannot be empty.", parameterName);
}
}
/// <summary>
/// Verifies that the specified value is less than a maximum value
/// and throws an exception if it is not.
/// </summary>
/// <param name="value">The target value, which should be validated.</param>
/// <param name="max">The maximum value.</param>
/// <param name="parameterName">The name of the parameter that is to be checked.</param>
/// <typeparam name="TValue">The type of the value.</typeparam>
/// <exception cref="ArgumentOutOfRangeException">
/// <paramref name="value"/> is greater than the maximum value.
/// </exception>
public static void MustBeLessThan<TValue>(TValue value, TValue max, string parameterName)
where TValue : IComparable<TValue>
{
if (value.CompareTo(max) >= 0)
{
throw new ArgumentOutOfRangeException(parameterName, $"Value must be less than {max}.");
}
}
/// <summary>
/// Verifies that the specified value is less than or equal to a maximum value
/// and throws an exception if it is not.
/// </summary>
/// <param name="value">The target value, which should be validated.</param>
/// <param name="max">The maximum value.</param>
/// <param name="parameterName">The name of the parameter that is to be checked.</param>
/// <typeparam name="TValue">The type of the value.</typeparam>
/// <exception cref="ArgumentOutOfRangeException">
/// <paramref name="value"/> is greater than the maximum value.
/// </exception>
public static void MustBeLessThanOrEqualTo<TValue>(TValue value, TValue max, string parameterName)
where TValue : IComparable<TValue>
{
if (value.CompareTo(max) > 0)
{
throw new ArgumentOutOfRangeException(parameterName, $"Value must be less than or equal to {max}.");
}
}
/// <summary>
/// Verifies that the specified value is greater than a minimum value
/// and throws an exception if it is not.
/// </summary>
/// <param name="value">The target value, which should be validated.</param>
/// <param name="min">The minimum value.</param>
/// <param name="parameterName">The name of the parameter that is to be checked.</param>
/// <typeparam name="TValue">The type of the value.</typeparam>
/// <exception cref="ArgumentOutOfRangeException">
/// <paramref name="value"/> is less than the minimum value.
/// </exception>
public static void MustBeGreaterThan<TValue>(TValue value, TValue min, string parameterName)
where TValue : IComparable<TValue>
{
if (value.CompareTo(min) <= 0)
{
throw new ArgumentOutOfRangeException(parameterName, $"Value must be greater than {min}.");
}
}
/// <summary>
/// Verifies that the specified value is greater than or equal to a minimum value
/// and throws an exception if it is not.
/// </summary>
/// <param name="value">The target value, which should be validated.</param>
/// <param name="min">The minimum value.</param>
/// <param name="parameterName">The name of the parameter that is to be checked.</param>
/// <typeparam name="TValue">The type of the value.</typeparam>
/// <exception cref="ArgumentOutOfRangeException">
/// <paramref name="value"/> is less than the minimum value.
/// </exception>
public static void MustBeGreaterThanOrEqualTo<TValue>(TValue value, TValue min, string parameterName)
where TValue : IComparable<TValue>
{
if (value.CompareTo(min) < 0)
{
throw new ArgumentOutOfRangeException(parameterName, $"Value must be greater than or equal to {min}.");
}
}
/// <summary>
/// Verifies that the specified value is greater than or equal to a minimum value and less than
/// or equal to a maximum value and throws an exception if it is not.
/// </summary>
/// <param name="value">The target value, which should be validated.</param>
/// <param name="min">The minimum value.</param>
/// <param name="max">The maximum value.</param>
/// <param name="parameterName">The name of the parameter that is to be checked.</param>
/// <typeparam name="TValue">The type of the value.</typeparam>
/// <exception cref="ArgumentOutOfRangeException">
/// <paramref name="value"/> is less than the minimum value of greater than the maximum value.
/// </exception>
public static void MustBeBetweenOrEqualTo<TValue>(TValue value, TValue min, TValue max, string parameterName)
where TValue : IComparable<TValue>
{
if (value.CompareTo(min) < 0 || value.CompareTo(max) > 0)
{
throw new ArgumentOutOfRangeException(parameterName, $"Value must be greater than or equal to {min} and less than or equal to {max}.");
}
}
/// <summary>
/// Verifies, that the method parameter with specified target value is true
/// and throws an exception if it is found to be so.
/// </summary>
/// <param name="value">
/// The target value, which cannot be false.
/// </param>
/// <param name="parameterName">
/// The name of the parameter that is to be checked.
/// </param>
/// <param name="message">
/// The error message, if any to add to the exception.
/// </param>
/// <exception cref="ArgumentException">
/// <paramref name="value"/> is false
/// </exception>
public static void IsTrue(bool value, string parameterName, string message)
{
if (!value)
{
throw new ArgumentException(message, parameterName);
}
}
/// <summary>
/// Verifies, that the method parameter with specified target value is false
/// and throws an exception if it is found to be so.
/// </summary>
/// <param name="value">The target value, which cannot be true.</param>
/// <param name="parameterName">The name of the parameter that is to be checked.</param>
/// <param name="message">The error message, if any to add to the exception.</param>
/// <exception cref="ArgumentException">
/// <paramref name="value"/> is true
/// </exception>
public static void IsFalse(bool value, string parameterName, string message)
{
if (value)
{
throw new ArgumentException(message, parameterName);
}
}
/// <summary>
/// Verifies, that the `target` span has the length of 'minLength', or longer.
/// </summary>
/// <typeparam name="T">The element type of the spans</typeparam>
/// <param name="value">The target span.</param>
/// <param name="minLength">The minimum length.</param>
/// <param name="parameterName">The name of the parameter that is to be checked.</param>
/// <exception cref="ArgumentException">
/// The length of <paramref name="value"/> is less than <paramref name="minLength"/>.
/// </exception>
public static void MustBeSizedAtLeast<T>(T[] value, int minLength, string parameterName)
{
if (value.Length < minLength)
{
throw new ArgumentException($"The size must be at least {minLength}.", parameterName);
}
}
/// <summary>
/// Verifies, that the `target` span has the length of 'minLength', or longer.
/// </summary>
/// <typeparam name="T">The element type of the spans</typeparam>
/// <param name="value">The target span.</param>
/// <param name="minLength">The minimum length.</param>
/// <param name="parameterName">The name of the parameter that is to be checked.</param>
/// <exception cref="ArgumentException">
/// The length of <paramref name="value"/> is less than <paramref name="minLength"/>.
/// </exception>
public static void MustBeSizedAtLeast<T>(ReadOnlySpan<T> value, int minLength, string parameterName)
{
if (value.Length < minLength)
{
throw new ArgumentException($"The size must be at least {minLength}.", parameterName);
}
}
}
}

28
src/SixLabors.Core/Helpers/HashHelpers.cs

@ -0,0 +1,28 @@
// Copyright (c) Six Labors and contributors.
// Licensed under the Apache License, Version 2.0.
namespace SixLabors
{
/// <summary>
/// Lifted from coreFX repo
/// </summary>
internal static class HashHelpers
{
/// <summary>
/// Combines the two specified hash codes.
/// </summary>
/// <param name="h1">Hash code one</param>
/// <param name="h2">Hash code two</param>
/// <returns>Returns a hash code for the two specified has codes.</returns>
public static int Combine(int h1, int h2)
{
unchecked
{
// RyuJIT optimizes this to use the ROL instruction
// Related GitHub pull request: dotnet/coreclr#1830
uint rol5 = ((uint)h1 << 5) | ((uint)h1 >> 27);
return ((int)rol5 + h1) ^ h2;
}
}
}
}

10
src/SixLabors.Core/MathF.cs

@ -1,13 +1,11 @@
// <copyright file="MathF.cs" company="Six Labors">
// Copyright (c) Six Labors and contributors.
// Copyright (c) Six Labors and contributors.
// Licensed under the Apache License, Version 2.0.
// </copyright>
using System;
using System.Runtime.CompilerServices;
namespace SixLabors
{
using System;
using System.Runtime.CompilerServices;
/// <summary>
/// Provides single-precision floating point constants and static methods for trigonometric, logarithmic, and other common mathematical functions.
/// </summary>

8
src/SixLabors.Core/Primitives/Matrix3x2Extensions.cs

@ -1,12 +1,10 @@
// <copyright file="Matrix3x2Extensions.cs" company="Six Labors">
// Copyright (c) Six Labors and contributors.
// Copyright (c) Six Labors and contributors.
// Licensed under the Apache License, Version 2.0.
// </copyright>
using System.Numerics;
namespace SixLabors.Primitives
{
using System.Numerics;
/// <summary>
/// Extension methods for the <see cref="Matrix3x2"/> struct.
/// </summary>

42
src/SixLabors.Core/Primitives/Point.cs

@ -1,15 +1,13 @@
// <copyright file="Point.cs" company="Six Labors">
// Copyright (c) Six Labors and contributors.
// Copyright (c) Six Labors and contributors.
// Licensed under the Apache License, Version 2.0.
// </copyright>
using System;
using System.ComponentModel;
using System.Numerics;
using System.Runtime.CompilerServices;
namespace SixLabors.Primitives
{
using System;
using System.ComponentModel;
using System.Numerics;
using System.Runtime.CompilerServices;
/// <summary>
/// Represents an ordered pair of integer x- and y-coordinates that defines a point in
/// a two-dimensional plane.
@ -182,7 +180,7 @@ namespace SixLabors.Primitives
/// Translates a <see cref="Point"/> by the negative of a given value
/// </summary>
/// <param name="point">The point on the left hand of the operand.</param>
/// <param name="size">The size on the right hand of the operand.</param>
/// <param name="value">The value on the right hand of the operand.</param>
/// <returns>The <see cref="Point"/></returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Point Multiply(Point point, int value) => new Point(unchecked(point.X * value), unchecked(point.Y * value));
@ -212,6 +210,17 @@ namespace SixLabors.Primitives
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Point Round(PointF point) => new Point(unchecked((int)MathF.Round(point.X)), unchecked((int)MathF.Round(point.Y)));
/// <summary>
/// Transforms a point by the given matrix.
/// </summary>
/// <param name="position">The source point.</param>
/// <param name="matrix">The transformation matrix.</param>
/// <returns>A transformed point.</returns>
public static PointF Transform(Point position, Matrix3x2 matrix)
{
return Vector2.Transform(position, matrix);
}
/// <summary>
/// Converts a <see cref="PointF"/> to a <see cref="Point"/> by performing a truncate operation on all the coordinates.
/// </summary>
@ -235,7 +244,7 @@ namespace SixLabors.Primitives
/// <param name="rotation">Rotation matrix used</param>
/// <returns>The rotated <see cref="Point"/></returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Point Rotate(Point point, System.Numerics.Matrix3x2 rotation) => Round(Vector2.Transform(new Vector2(point.X, point.Y), rotation));
public static Point Rotate(Point point, Matrix3x2 rotation) => Round(Vector2.Transform(new Vector2(point.X, point.Y), rotation));
/// <summary>
/// Skews a point using the given skew matrix.
@ -244,7 +253,7 @@ namespace SixLabors.Primitives
/// <param name="skew">Rotation matrix used</param>
/// <returns>The rotated <see cref="Point"/></returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Point Skew(Point point, System.Numerics.Matrix3x2 skew) => Round(Vector2.Transform(new Vector2(point.X, point.Y), skew));
public static Point Skew(Point point, Matrix3x2 skew) => Round(Vector2.Transform(new Vector2(point.X, point.Y), skew));
/// <summary>
/// Translates this <see cref="Point"/> by the specified amount.
@ -289,16 +298,5 @@ namespace SixLabors.Primitives
private static short LowInt16(int n) => unchecked((short)(n & 0xffff));
private int GetHashCode(Point point) => HashHelpers.Combine(point.X.GetHashCode(), point.Y.GetHashCode());
/// <summary>
/// Transforms a point by the given matrix.
/// </summary>
/// <param name="position"> The source point</param>
/// <param name="matrix">The transformation matrix.</param>
/// <returns></returns>
public static PointF Transform(Point position, Matrix3x2 matrix)
{
return Vector2.Transform(position, matrix);
}
}
}

36
src/SixLabors.Core/Primitives/PointF.cs

@ -1,15 +1,13 @@
// <copyright file="PointF.cs" company="Six Labors">
// Copyright (c) Six Labors and contributors.
// Copyright (c) Six Labors and contributors.
// Licensed under the Apache License, Version 2.0.
// </copyright>
using System;
using System.ComponentModel;
using System.Numerics;
using System.Runtime.CompilerServices;
namespace SixLabors.Primitives
{
using System;
using System.ComponentModel;
using System.Numerics;
using System.Runtime.CompilerServices;
/// <summary>
/// Represents an ordered pair of single precision floating point x- and y-coordinates that defines a point in
/// a two-dimensional plane.
@ -258,6 +256,17 @@ namespace SixLabors.Primitives
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static PointF Skew(PointF point, Matrix3x2 skew) => Vector2.Transform(new Vector2(point.X, point.Y), skew);
/// <summary>
/// Transforms a point by the given matrix.
/// </summary>
/// <param name="position">The source point.</param>
/// <param name="matrix">The transformation matrix.</param>
/// <returns>A transformed point.</returns>
public static PointF Transform(PointF position, Matrix3x2 matrix)
{
return Vector2.Transform(position, matrix);
}
/// <summary>
/// Translates this <see cref="PointF"/> by the specified amount.
/// </summary>
@ -303,16 +312,5 @@ namespace SixLabors.Primitives
/// A 32-bit signed integer that is the hash code for this instance.
/// </returns>
private int GetHashCode(PointF point) => HashHelpers.Combine(point.X.GetHashCode(), point.Y.GetHashCode());
/// <summary>
/// Transforms a point by the given matrix.
/// </summary>
/// <param name="position"> The source point</param>
/// <param name="matrix">The transformation matrix.</param>
/// <returns></returns>
public static PointF Transform(PointF position, Matrix3x2 matrix)
{
return Vector2.Transform(position, matrix);
}
}
}

40
src/SixLabors.Core/Primitives/Rectangle.cs

@ -1,15 +1,13 @@
// <copyright file="Rectangle.cs" company="Six Labors">
// Copyright (c) Six Labors and contributors.
// Copyright (c) Six Labors and contributors.
// Licensed under the Apache License, Version 2.0.
// </copyright>
using System;
using System.ComponentModel;
using System.Numerics;
using System.Runtime.CompilerServices;
namespace SixLabors.Primitives
{
using System;
using System.ComponentModel;
using System.Numerics;
using System.Runtime.CompilerServices;
/// <summary>
/// Stores a set of four integers that represent the location and size of a rectangle.
/// </summary>
@ -276,6 +274,19 @@ namespace SixLabors.Primitives
}
}
/// <summary>
/// Transforms a rectangle by the given matrix.
/// </summary>
/// <param name="rectangle">The source rectangle.</param>
/// <param name="matrix">The transformation matrix.</param>
/// <returns>A transformed rectangle.</returns>
public static RectangleF Transform(Rectangle rectangle, Matrix3x2 matrix)
{
PointF bottomRight = Point.Transform(new Point(rectangle.Right, rectangle.Bottom), matrix);
PointF topLeft = Point.Transform(rectangle.Location, matrix);
return new RectangleF(topLeft, new SizeF(bottomRight - topLeft));
}
/// <summary>
/// Converts a <see cref="RectangleF"/> to a <see cref="Rectangle"/> by performing a truncate operation on all the coordinates.
/// </summary>
@ -455,18 +466,5 @@ namespace SixLabors.Primitives
hashCode = HashHelpers.Combine(hashCode, rectangle.Height.GetHashCode());
return hashCode;
}
/// <summary>
/// Transforms a rectangle by the given matrix.
/// </summary>
/// <param name="rectangle">The source rectangle</param>
/// <param name="matrix">The transformation matrix.</param>
/// <returns></returns>
public static RectangleF Transform(Rectangle rectangle, Matrix3x2 matrix)
{
PointF bottomRight = Point.Transform(new Point(rectangle.Right, rectangle.Bottom), matrix);
PointF topLeft = Point.Transform(rectangle.Location, matrix);
return new RectangleF(topLeft, new SizeF(bottomRight - topLeft));
}
}
}

40
src/SixLabors.Core/Primitives/RectangleF.cs

@ -1,15 +1,13 @@
// <copyright file="RectangleF.cs" company="Six Labors">
// Copyright (c) Six Labors and contributors.
// Copyright (c) Six Labors and contributors.
// Licensed under the Apache License, Version 2.0.
// </copyright>
using System;
using System.ComponentModel;
using System.Numerics;
using System.Runtime.CompilerServices;
namespace SixLabors.Primitives
{
using System;
using System.ComponentModel;
using System.Numerics;
using System.Runtime.CompilerServices;
/// <summary>
/// Stores a set of four single precision floating points that represent the location and size of a rectangle.
/// </summary>
@ -251,6 +249,19 @@ namespace SixLabors.Primitives
return r;
}
/// <summary>
/// Transforms a rectangle by the given matrix.
/// </summary>
/// <param name="rectangle">The source rectangle.</param>
/// <param name="matrix">The transformation matrix.</param>
/// <returns>A transformed rectangle.</returns>
public static RectangleF Transform(RectangleF rectangle, Matrix3x2 matrix)
{
PointF bottomRight = PointF.Transform(new PointF(rectangle.Right, rectangle.Bottom), matrix);
PointF topLeft = PointF.Transform(rectangle.Location, matrix);
return new RectangleF(topLeft, new SizeF(bottomRight - topLeft));
}
/// <summary>
/// Creates a rectangle that represents the union between <paramref name="a"/> and <paramref name="b"/>.
/// </summary>
@ -388,18 +399,5 @@ namespace SixLabors.Primitives
hashCode = HashHelpers.Combine(hashCode, rectangle.Height.GetHashCode());
return hashCode;
}
/// <summary>
/// Transforms a rectangle by the given matrix.
/// </summary>
/// <param name="rectangle">The source rectangle</param>
/// <param name="matrix">The transformation matrix.</param>
/// <returns></returns>
public static RectangleF Transform(RectangleF rectangle, Matrix3x2 matrix)
{
PointF bottomRight = PointF.Transform(new PointF(rectangle.Right, rectangle.Bottom), matrix);
PointF topLeft = PointF.Transform(rectangle.Location, matrix);
return new RectangleF(topLeft, new SizeF(bottomRight - topLeft));
}
}
}

76
src/SixLabors.Core/Primitives/Size.cs

@ -1,15 +1,13 @@
// <copyright file="Size.cs" company="Six Labors">
// Copyright (c) Six Labors and contributors.
// Copyright (c) Six Labors and contributors.
// Licensed under the Apache License, Version 2.0.
// </copyright>
using System;
using System.ComponentModel;
using System.Numerics;
using System.Runtime.CompilerServices;
namespace SixLabors.Primitives
{
using System;
using System.ComponentModel;
using System.Numerics;
using System.Runtime.CompilerServices;
/// <summary>
/// Stores an ordered pair of integers, which specify a height and width.
/// </summary>
@ -216,24 +214,6 @@ namespace SixLabors.Primitives
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Size Subtract(Size left, Size right) => new Size(unchecked(left.Width - right.Width), unchecked(left.Height - right.Height));
/// <summary>
/// Multiplies <see cref="Size"/> by an <see cref="int"/> producing <see cref="Size"/>.
/// </summary>
/// <param name="size">Multiplicand of type <see cref="Size"/>.</param>
/// <param name="multiplier">Multiplier of type <see cref='int'>.</param>
/// <returns>Product of type <see cref="Size"/>.</returns>
private static Size Multiply(Size size, int multiplier) =>
new Size(unchecked(size.Width * multiplier), unchecked(size.Height * multiplier));
/// <summary>
/// Multiplies <see cref="Size"/> by a <see cref="float"/> producing <see cref="SizeF"/>.
/// </summary>
/// <param name="size">Multiplicand of type <see cref="Size"/>.</param>
/// <param name="multiplier">Multiplier of type <see cref="float"/>.</param>
/// <returns>Product of type SizeF.</returns>
private static SizeF Multiply(Size size, float multiplier) =>
new SizeF(size.Width * multiplier, size.Height * multiplier);
/// <summary>
/// Converts a <see cref="SizeF"/> to a <see cref="Size"/> by performing a ceiling operation on all the dimensions.
/// </summary>
@ -250,6 +230,19 @@ namespace SixLabors.Primitives
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Size Round(SizeF size) => new Size(unchecked((int)MathF.Round(size.Width)), unchecked((int)MathF.Round(size.Height)));
/// <summary>
/// Transforms a size by the given matrix.
/// </summary>
/// <param name="size">The source size</param>
/// <param name="matrix">The transformation matrix.</param>
/// <returns>A transformed size.</returns>
public static SizeF Transform(Size size, Matrix3x2 matrix)
{
var v = Vector2.Transform(new Vector2(size.Width, size.Height), matrix);
return new SizeF(v.X, v.Y);
}
/// <summary>
/// Converts a <see cref="SizeF"/> to a <see cref="Size"/> by performing a round operation on all the dimensions.
/// </summary>
@ -274,6 +267,24 @@ namespace SixLabors.Primitives
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public bool Equals(Size other) => this.Width == other.Width && this.Height == other.Height;
/// <summary>
/// Multiplies <see cref="Size"/> by an <see cref="int"/> producing <see cref="Size"/>.
/// </summary>
/// <param name="size">Multiplicand of type <see cref="Size"/>.</param>
/// <param name="multiplier">Multiplier of type <see cref="int"/>.</param>
/// <returns>Product of type <see cref="Size"/>.</returns>
private static Size Multiply(Size size, int multiplier) =>
new Size(unchecked(size.Width * multiplier), unchecked(size.Height * multiplier));
/// <summary>
/// Multiplies <see cref="Size"/> by a <see cref="float"/> producing <see cref="SizeF"/>.
/// </summary>
/// <param name="size">Multiplicand of type <see cref="Size"/>.</param>
/// <param name="multiplier">Multiplier of type <see cref="float"/>.</param>
/// <returns>Product of type SizeF.</returns>
private static SizeF Multiply(Size size, float multiplier) =>
new SizeF(size.Width * multiplier, size.Height * multiplier);
/// <summary>
/// Returns the hash code for this instance.
/// </summary>
@ -284,18 +295,5 @@ namespace SixLabors.Primitives
/// A 32-bit signed integer that is the hash code for this instance.
/// </returns>
private int GetHashCode(Size size) => HashHelpers.Combine(size.Width.GetHashCode(), size.Height.GetHashCode());
/// <summary>
/// Transforms a size by the given matrix.
/// </summary>
/// <param name="size">The source size</param>
/// <param name="matrix">The transformation matrix.</param>
/// <returns></returns>
public static SizeF Transform(Size size, Matrix3x2 matrix)
{
var v = Vector2.Transform(new Vector2(size.Width, size.Height), matrix);
return new SizeF(v.X, v.Y);
}
}
}

68
src/SixLabors.Core/Primitives/SizeF.cs

@ -1,15 +1,13 @@
// <copyright file="SizeF.cs" company="Six Labors">
// Copyright (c) Six Labors and contributors.
// Copyright (c) Six Labors and contributors.
// Licensed under the Apache License, Version 2.0.
// </copyright>
using System;
using System.ComponentModel;
using System.Numerics;
using System.Runtime.CompilerServices;
namespace SixLabors.Primitives
{
using System;
using System.ComponentModel;
using System.Numerics;
using System.Runtime.CompilerServices;
/// <summary>
/// Stores an ordered pair of single precision floating points, which specify a height and width.
/// </summary>
@ -72,6 +70,16 @@ namespace SixLabors.Primitives
[EditorBrowsable(EditorBrowsableState.Never)]
public bool IsEmpty => this.Equals(Empty);
/// <summary>
/// Creates a <see cref="Vector2"/> with the coordinates of the specified <see cref="PointF"/>.
/// </summary>
/// <param name="point">The point.</param>
/// <returns>
/// The <see cref="Vector2"/>.
/// </returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static implicit operator Vector2(SizeF point) => new Vector2(point.Width, point.Height);
/// <summary>
/// Creates a <see cref="Size"/> with the dimensions of the specified <see cref="SizeF"/> by truncating each of the dimensions.
/// </summary>
@ -177,13 +185,17 @@ namespace SixLabors.Primitives
public static SizeF Subtract(SizeF left, SizeF right) => new SizeF(left.Width - right.Width, left.Height - right.Height);
/// <summary>
/// Multiplies <see cref="SizeF"/> by a <see cref="float"/> producing <see cref="SizeF"/>.
/// Transforms a size by the given matrix.
/// </summary>
/// <param name="size">Multiplicand of type <see cref="SizeF"/>.</param>
/// <param name="multiplier">Multiplier of type <see cref="float"/>.</param>
/// <returns>Product of type SizeF.</returns>
private static SizeF Multiply(SizeF size, float multiplier) =>
new SizeF(size.Width * multiplier, size.Height * multiplier);
/// <param name="size">The source size.</param>
/// <param name="matrix">The transformation matrix.</param>
/// <returns>A transformed size.</returns>
public static SizeF Transform(SizeF size, Matrix3x2 matrix)
{
var v = Vector2.Transform(new Vector2(size.Width, size.Height), matrix);
return new SizeF(v.X, v.Y);
}
/// <inheritdoc/>
public override int GetHashCode()
@ -204,29 +216,15 @@ namespace SixLabors.Primitives
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public bool Equals(SizeF other) => this.Width.Equals(other.Width) && this.Height.Equals(other.Height);
private int GetHashCode(SizeF size) => HashHelpers.Combine(size.Width.GetHashCode(), size.Height.GetHashCode());
/// <summary>
/// Creates a <see cref="Vector2"/> with the coordinates of the specified <see cref="PointF"/>.
/// </summary>
/// <param name="point">The point.</param>
/// <returns>
/// The <see cref="Vector2"/>.
/// </returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static implicit operator Vector2(SizeF point) => new Vector2(point.Width, point.Height);
/// <summary>
/// Transforms a size by the given matrix.
/// Multiplies <see cref="SizeF"/> by a <see cref="float"/> producing <see cref="SizeF"/>.
/// </summary>
/// <param name="size">The source size</param>
/// <param name="matrix">The transformation matrix.</param>
/// <returns></returns>
public static SizeF Transform(SizeF size, Matrix3x2 matrix)
{
var v = Vector2.Transform(new Vector2(size.Width, size.Height), matrix);
/// <param name="size">Multiplicand of type <see cref="SizeF"/>.</param>
/// <param name="multiplier">Multiplier of type <see cref="float"/>.</param>
/// <returns>Product of type SizeF.</returns>
private static SizeF Multiply(SizeF size, float multiplier) =>
new SizeF(size.Width * multiplier, size.Height * multiplier);
return new SizeF(v.X, v.Y);
}
private int GetHashCode(SizeF size) => HashHelpers.Combine(size.Width.GetHashCode(), size.Height.GetHashCode());
}
}

18
src/Shared/AssemblyInfo.Common.cs → src/SixLabors.Core/Properties/AssemblyInfo.cs

@ -1,7 +1,5 @@
// <copyright file="AssemblyInfo.Common.cs" company="Scott Williams">
// Copyright (c) Scott Williams and contributors.
// Copyright (c) Six Labors and contributors.
// Licensed under the Apache License, Version 2.0.
// </copyright>
using System.Reflection;
using System.Resources;
@ -10,6 +8,7 @@ using System.Runtime.CompilerServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("SixLabors.Core")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("Six Labors")]
@ -29,9 +28,16 @@ using System.Runtime.CompilerServices;
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0.0")]
[assembly: AssemblyVersion("0.1.0")]
[assembly: AssemblyFileVersion("0.1.0")]
[assembly: AssemblyInformationalVersion("0.1.0-alpha02")]
// Ensure the internals can be tested.
[assembly: InternalsVisibleTo("SixLabors.Core.Tests")]
// Ensure the internals are visible to the other projects.
[assembly: InternalsVisibleTo("SixLabors.Exif")]
[assembly: InternalsVisibleTo("SixLabors.Fonts")]
[assembly: InternalsVisibleTo("SixLabors.ImageSharp")]
[assembly: InternalsVisibleTo("SixLabors.ImageSharp.Drawing")]
[assembly: InternalsVisibleTo("SixLabors.Shapes")]

15
src/SixLabors.Core/SixLabors.Core.csproj

@ -2,9 +2,8 @@
<PropertyGroup>
<Description>Low level primitives for use across Six Labors projects..</Description>
<AssemblyTitle>SixLabors.Primitives</AssemblyTitle>
<VersionPrefix Condition="$(packageversion) != ''">$(packageversion)</VersionPrefix>
<VersionPrefix Condition="$(packageversion) == ''">0.1.0-alpha1</VersionPrefix>
<VersionPrefix Condition="$(packageversion) == ''">0.1.0-alpha2</VersionPrefix>
<Authors>Six Labors</Authors>
<TargetFramework>netstandard1.1</TargetFramework>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
@ -26,16 +25,26 @@
<GenerateAssemblyVersionAttribute>false</GenerateAssemblyVersionAttribute>
<GenerateAssemblyFileVersionAttribute>false</GenerateAssemblyFileVersionAttribute>
<GenerateAssemblyInformationalVersionAttribute>false</GenerateAssemblyInformationalVersionAttribute>
<GenerateAssemblyTitleAttribute>false</GenerateAssemblyTitleAttribute>
<DebugType Condition="$(codecov) == 'true'">full</DebugType>
<RootNamespace>SixLabors</RootNamespace>
</PropertyGroup>
<PropertyGroup>
<CodeAnalysisRuleSet>..\SixLabors.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<ItemGroup>
<Compile Include="..\Shared\*.cs" Exclude="bin\**;obj\**;**\*.xproj;packages\**" />
<AdditionalFiles Include="..\..\stylecop.json" />
<Content Include="..\..\stylecop.json" Link="stylecop.json" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="StyleCop.Analyzers" Version="1.1.0-beta004">
<PrivateAssets>All</PrivateAssets>
</PackageReference>
<PackageReference Include="System.Numerics.Vectors" Version="4.3.0" />
<PackageReference Include="System.Memory" Version="4.4.0-preview1-25305-02" />
</ItemGroup>
</Project>

9
src/SixLabors.Core/stylecop.json

@ -1,9 +0,0 @@
{
"$schema": "https://raw.githubusercontent.com/DotNetAnalyzers/StyleCopAnalyzers/master/StyleCop.Analyzers/StyleCop.Analyzers/Settings/stylecop.schema.json",
"settings": {
"documentationRules": {
"companyName": "Six Labors",
"copyrightText": "Copyright (c) Six Labors and contributors.\nLicensed under the Apache License, Version 2.0."
}
}
}

0
SixLabors.Core.ruleset → src/SixLabors.ruleset

15
stylecop.json

@ -0,0 +1,15 @@
{
"$schema": "https://raw.githubusercontent.com/DotNetAnalyzers/StyleCopAnalyzers/master/StyleCop.Analyzers/StyleCop.Analyzers/Settings/stylecop.schema.json",
"settings":
{
"orderingRules":
{
"usingDirectivesPlacement": "outsideNamespace"
},
"documentationRules":
{
"xmlHeader": false,
"copyrightText": "Copyright (c) Six Labors and contributors.\nLicensed under the Apache License, Version 2.0."
}
}
}

10
tests/CodeCoverage/CodeCoverage.cmd

@ -7,12 +7,10 @@ nuget restore packages.config -PackagesDirectory .
cd ..
cd ..
dotnet restore SixLabors.Core.sln
dotnet build SixLabors.Core.sln --no-incremental -c debug /p:codecov=true
rem The -threshold options prevents this taking ages...
rem tests\CodeCoverage\OpenCover.4.6.519\tools\OpenCover.Console.exe -target:"dotnet.exe" -targetargs:"test tests\SixLabors.Shapes.Tests\SixLabors.Shapes.Tests.csproj --no-build -c Release /p:codecov=true" -threshold:10 -register:user -filter:"+[SixLabors.Shapes*]*" -excludebyattribute:*.ExcludeFromCodeCoverage* -hideskipped:All -returntargetcode -output:.\SixLabors.Shapes.Coverage.xml
tests\CodeCoverage\OpenCover.4.6.519\tools\OpenCover.Console.exe -target:"dotnet.exe" -targetargs:"test tests\SixLabors.Core.Tests\SixLabors.Core.Tests.csproj --no-build -c debug" -searchdirs:"tests\SixLabors.Core.Tests\bin\Release\netcoreapp1.1" -register:user -output:.\SixLabors.Core.Coverage.xml -hideskipped:All -returntargetcode -oldStyle -filter:"+[SixLabors.*]*"
dotnet restore SixLabors.Core.sln
dotnet build SixLabors.Core.sln --no-incremental -c release /p:codecov=true
tests\CodeCoverage\OpenCover.4.6.519\tools\OpenCover.Console.exe -target:"dotnet.exe" -targetargs:"test tests\SixLabors.Core.Tests\SixLabors.Core.Tests.csproj --no-build -c release" -searchdirs:"tests\SixLabors.Core.Tests\bin\Release\netcoreapp1.1" -register:user -output:.\SixLabors.Core.Coverage.xml -hideskipped:All -returntargetcode -oldStyle -filter:"+[SixLabors.*]*"
if %errorlevel% neq 0 exit /b %errorlevel%

258
tests/SixLabors.Core.Tests/Helpers/DebugGuardTests.cs

@ -0,0 +1,258 @@
// Copyright (c) Six Labors and contributors.
// Licensed under the Apache License, Version 2.0.
// tell this file to enable debug conditional method calls, i.e. all the debug guard calls
#define DEBUG
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using Xunit;
namespace SixLabors.Helpers.Tests
{
public class DebugGuardTests
{
[Fact]
public void AllStaticMethodsOnOnDebugGuardHaveDEBUGConditional()
{
var methods = typeof(DebugGuard).GetTypeInfo().GetMethods()
.Where(x => x.IsStatic);
foreach (var m in methods)
{
var attribs = m.GetCustomAttributes<ConditionalAttribute>();
Assert.True(attribs.Select(x => x.ConditionString).Contains("DEBUG"), $"Method '{m.Name}' does not have [Conditional(\"DEBUG\")] set.");
}
}
[Fact]
public void NotNull_TargetNotNull_ThrowsNoException()
{
DebugGuard.NotNull("test", "myParamName");
}
[Fact]
public void NotNull_TargetNull_ThrowsException()
{
Assert.Throws<ArgumentNullException>(() =>
{
DebugGuard.NotNull(null, "myParamName");
});
}
[Fact]
public void MustBeLessThan_IsLess_ThrowsNoException()
{
DebugGuard.MustBeLessThan(0, 1, "myParamName");
}
[Theory]
[InlineData(2, 1)]
[InlineData(1, 1)]
public void MustBeLessThan_IsGreaterOrEqual_ThrowsNoException(int value, int max)
{
var exception = Assert.Throws<ArgumentOutOfRangeException>(() =>
{
DebugGuard.MustBeLessThan(value, max, "myParamName");
});
Assert.Equal("myParamName", exception.ParamName);
Assert.True(exception.Message.Contains($"Value must be less than {max}."));
}
[Theory]
[InlineData(0, 1)]
[InlineData(1, 1)]
public void MustBeLessThanOrEqualTo_IsLessOrEqual_ThrowsNoException(int value, int max)
{
DebugGuard.MustBeLessThanOrEqualTo(value, max, "myParamName");
}
[Fact]
public void MustBeLessThanOrEqualTo_IsGreater_ThrowsNoException()
{
var exception = Assert.Throws<ArgumentOutOfRangeException>(() =>
{
DebugGuard.MustBeLessThanOrEqualTo(2, 1, "myParamName");
});
Assert.Equal("myParamName", exception.ParamName);
Assert.True(exception.Message.Contains($"Value must be less than or equal to 1."));
}
[Fact]
public void MustBeGreaterThan_IsGreater_ThrowsNoException()
{
DebugGuard.MustBeGreaterThan(2, 1, "myParamName");
}
[Theory]
[InlineData(1, 2)]
[InlineData(1, 1)]
public void MustBeGreaterThan_IsLessOrEqual_ThrowsNoException(int value, int min)
{
var exception = Assert.Throws<ArgumentOutOfRangeException>(() =>
{
DebugGuard.MustBeGreaterThan(value, min, "myParamName");
});
Assert.Equal("myParamName", exception.ParamName);
Assert.True(exception.Message.Contains($"Value must be greater than {min}."));
}
[Theory]
[InlineData(2, 1)]
[InlineData(1, 1)]
public void MustBeGreaterThanOrEqualTo_IsGreaterOrEqual_ThrowsNoException(int value, int min)
{
DebugGuard.MustBeGreaterThanOrEqualTo(value, min, "myParamName");
}
[Fact]
public void MustBeGreaterThanOrEqualTo_IsLess_ThrowsNoException()
{
var exception = Assert.Throws<ArgumentOutOfRangeException>(() =>
{
DebugGuard.MustBeGreaterThanOrEqualTo(1, 2, "myParamName");
});
Assert.Equal("myParamName", exception.ParamName);
Assert.True(exception.Message.Contains($"Value must be greater than or equal to 2."));
}
[Fact]
public void IsTrue_IsTrue_ThrowsNoException()
{
DebugGuard.IsTrue(true, "myParamName", "myTestMessage");
}
[Fact]
public void IsTrue_IsFalse_ThrowsException()
{
var exception = Assert.Throws<ArgumentException>(() =>
{
DebugGuard.IsTrue(false, "myParamName", "myTestMessage");
});
Assert.Equal("myParamName", exception.ParamName);
Assert.True(exception.Message.Contains("myTestMessage"));
}
[Fact]
public void IsFalse_IsFalse_ThrowsNoException()
{
DebugGuard.IsFalse(false, "myParamName", "myTestMessage");
}
[Fact]
public void IsFalse_IsTrue_ThrowsException()
{
var exception = Assert.Throws<ArgumentException>(() =>
{
DebugGuard.IsFalse(true, "myParamName", "myTestMessage");
});
Assert.Equal("myParamName", exception.ParamName);
Assert.True(exception.Message.Contains("myTestMessage"));
}
[Theory]
[InlineData(new int[] { 1, 2 }, 1)]
[InlineData(new int[] { 1, 2 }, 2)]
public void MustBeSizedAtLeast_Array_LengthIsGreaterOrEqual_ThrowsNoException(int[] value, int minLength)
{
DebugGuard.MustBeSizedAtLeast<int>(value, minLength, "myParamName");
}
[Fact]
public void MustBeSizedAtLeast_Array_LengthIsLess_ThrowsException()
{
var exception = Assert.Throws<ArgumentException>(() =>
{
DebugGuard.MustBeSizedAtLeast<int>(new int[] { 1, 2 }, 3, "myParamName");
});
Assert.Equal("myParamName", exception.ParamName);
Assert.Contains($"The size must be at least 3.", exception.Message);
}
[Fact]
public void MustBeSizedAtLeast_ReadOnlySpan_LengthIsLess_ThrowsException()
{
var exception = Assert.Throws<ArgumentException>(() =>
{
DebugGuard.MustBeSizedAtLeast(new ReadOnlySpan<int>(new int[2]), new ReadOnlySpan<int>(new int[3]), "myParamName");
});
Assert.Equal("myParamName", exception.ParamName);
Assert.Contains($"Span-s must be at least of length 3.", exception.Message);
}
[Fact]
public void MustBeSizedAtLeast_Span_LengthIsLess_ThrowsException()
{
var exception = Assert.Throws<ArgumentException>(() =>
{
DebugGuard.MustBeSizedAtLeast(new Span<int>(new int[2]), new Span<int>(new int[3]), "myParamName");
});
Assert.Equal("myParamName", exception.ParamName);
Assert.Contains($"Span-s must be at least of length 3.", exception.Message);
}
[Fact]
public void MustBeSameSized_ReadOnlySpan_LengthIsLess_ThrowsException()
{
var exception = Assert.Throws<ArgumentException>(() =>
{
DebugGuard.MustBeSameSized(new ReadOnlySpan<int>(new int[2]), new ReadOnlySpan<int>(new int[3]), "myParamName");
});
Assert.Equal("myParamName", exception.ParamName);
Assert.Contains($"Span-s must be the same size.", exception.Message);
}
[Fact]
public void MustBeSameSized_Span_LengthIsLess_ThrowsException()
{
var exception = Assert.Throws<ArgumentException>(() =>
{
DebugGuard.MustBeSameSized(new Span<int>(new int[2]), new Span<int>(new int[3]), "myParamName");
});
Assert.Equal("myParamName", exception.ParamName);
Assert.Contains($"Span-s must be the same size.", exception.Message);
}
[Theory]
[InlineData(2, 2)]
[InlineData(4, 3)]
public void MustBeSizedAtLeast_ReadOnlySpan_LengthIsEqualOrGreater_DoesNotThowException(int leftSize, int rightSize)
{
DebugGuard.MustBeSizedAtLeast(new ReadOnlySpan<int>(new int[leftSize]), new ReadOnlySpan<int>(new int[rightSize]), "myParamName");
}
[Theory]
[InlineData(2, 2)]
[InlineData(4, 3)]
public void MustBeSizedAtLeast_Span_LengthIsEqualOrGreater_DoesNotThowException(int leftSize, int rightSize)
{
DebugGuard.MustBeSizedAtLeast(new Span<int>(new int[leftSize]), new Span<int>(new int[rightSize]), "myParamName");
}
[Fact]
public void MustBeSameSized_ReadOnlySpan_LengthIsEqual_DoesNotThrowException()
{
DebugGuard.MustBeSameSized(new ReadOnlySpan<int>(new int[2]), new ReadOnlySpan<int>(new int[2]), "myParamName");
}
[Fact]
public void MustBeSameSized_Span_LengthIsEqual_DoesNotThrowException()
{
DebugGuard.MustBeSameSized(new Span<int>(new int[2]), new Span<int>(new int[2]), "myParamName");
}
}
}

326
tests/SixLabors.Core.Tests/Helpers/GuardTests.cs

@ -0,0 +1,326 @@
// Copyright (c) Six Labors and contributors.
// Licensed under the Apache License, Version 2.0.
using System;
using System.Collections.Generic;
using System.Linq;
using Xunit;
namespace SixLabors.Helpers.Tests
{
public class GuardTests
{
[Fact]
public void NotNull_TargetNotNull_ThrowsNoException()
{
Guard.NotNull("test", "myParamName");
}
[Fact]
public void NotNull_TargetNull_ThrowsException()
{
Assert.Throws<ArgumentNullException>(() =>
{
Guard.NotNull(null, "myParamName");
});
}
[Fact]
public void NotNull_TargetNullWithMessage_ThrowsException()
{
var exception = Assert.Throws<ArgumentNullException>(() =>
{
Guard.NotNull(null, "myParamName", "myTestMessage");
});
Assert.Equal("myParamName", exception.ParamName);
Assert.True(exception.Message.Contains("myTestMessage"));
}
[Fact]
public void NotNullOrEmpty_TargetNotNullOrEmpty_ThrowsNoException()
{
Guard.NotNullOrEmpty("test", "myParamName");
}
[Fact]
public void NotNullOrEmpty_TargetNull_ThrowsException()
{
Assert.Throws<ArgumentNullException>(() =>
{
Guard.NotNullOrEmpty(null, "myParamName");
});
}
[Fact]
public void NotNullOrEmpty_TargetWhitespace_ThrowsException()
{
Assert.Throws<ArgumentException>(() =>
{
Guard.NotNullOrEmpty("\n\n", "myParamName");
});
}
[Fact]
public void NotNullOrEmpty_TargetEmpty_ThrowsException()
{
var exception = Assert.Throws<ArgumentException>(() =>
{
Guard.NotNullOrEmpty(string.Empty, "myParamName");
});
Assert.Equal("myParamName", exception.ParamName);
Assert.True(exception.Message.Contains("Value cannot be null, empty, or cannot contain only whitespace."));
}
[Fact]
public void NotNullOrEmpty_TargetEmptyWithMessage_ThrowsException()
{
var exception = Assert.Throws<ArgumentException>(() =>
{
Guard.NotNullOrEmpty(string.Empty, "myParamName", "myTestMessage");
});
Assert.Equal("myParamName", exception.ParamName);
Assert.True(exception.Message.Contains("myTestMessage"));
}
[Fact]
public void NotNullOrEmptyIEnumerable_TargetNotNullOrEmpty_ThrowsNoException()
{
Guard.NotNullOrEmpty(new string[] { "test" }, "myParamName");
}
[Fact]
public void NotNullOrEmptyIEnumerable_TargetNull_ThrowsException()
{
Assert.Throws<ArgumentNullException>(() =>
{
Guard.NotNullOrEmpty((IEnumerable<string>)null, "myParamName");
});
}
[Fact]
public void NotNullOrEmptyIEnumerable_TargetEmpty_ThrowsException()
{
var exception = Assert.Throws<ArgumentException>(() =>
{
Guard.NotNullOrEmpty(new string[] { }, "myParamName");
});
Assert.Equal("myParamName", exception.ParamName);
Assert.True(exception.Message.Contains("Value cannot be empty."));
}
[Fact]
public void NotNullOrEmptyIEnumerable_TargetEmptyWithMessage_ThrowsException()
{
var exception = Assert.Throws<ArgumentException>(() =>
{
Guard.NotNullOrEmpty(new string[] { }, "myParamName", "myTestMessage");
});
Assert.Equal("myParamName", exception.ParamName);
Assert.True(exception.Message.Contains("myTestMessage"));
}
[Fact]
public void MustBeLessThan_IsLess_ThrowsNoException()
{
Guard.MustBeLessThan(0, 1, "myParamName");
}
[Theory]
[InlineData(2, 1)]
[InlineData(1, 1)]
public void MustBeLessThan_IsGreaterOrEqual_ThrowsNoException(int value, int max)
{
var exception = Assert.Throws<ArgumentOutOfRangeException>(() =>
{
Guard.MustBeLessThan(value, max, "myParamName");
});
Assert.Equal("myParamName", exception.ParamName);
Assert.True(exception.Message.Contains($"Value must be less than {max}."));
}
[Theory]
[InlineData(0, 1)]
[InlineData(1, 1)]
public void MustBeLessThanOrEqualTo_IsLessOrEqual_ThrowsNoException(int value, int max)
{
Guard.MustBeLessThanOrEqualTo(value, max, "myParamName");
}
[Fact]
public void MustBeLessThanOrEqualTo_IsGreater_ThrowsNoException()
{
var exception = Assert.Throws<ArgumentOutOfRangeException>(() =>
{
Guard.MustBeLessThanOrEqualTo(2, 1, "myParamName");
});
Assert.Equal("myParamName", exception.ParamName);
Assert.True(exception.Message.Contains($"Value must be less than or equal to 1."));
}
[Fact]
public void MustBeGreaterThan_IsGreater_ThrowsNoException()
{
Guard.MustBeGreaterThan(2, 1, "myParamName");
}
[Theory]
[InlineData(1, 2)]
[InlineData(1, 1)]
public void MustBeGreaterThan_IsLessOrEqual_ThrowsNoException(int value, int min)
{
var exception = Assert.Throws<ArgumentOutOfRangeException>(() =>
{
Guard.MustBeGreaterThan(value, min, "myParamName");
});
Assert.Equal("myParamName", exception.ParamName);
Assert.True(exception.Message.Contains($"Value must be greater than {min}."));
}
[Theory]
[InlineData(2, 1)]
[InlineData(1, 1)]
public void MustBeGreaterThanOrEqualTo_IsGreaterOrEqual_ThrowsNoException(int value, int min)
{
Guard.MustBeGreaterThanOrEqualTo(value, min, "myParamName");
}
[Fact]
public void MustBeGreaterThanOrEqualTo_IsLess_ThrowsNoException()
{
var exception = Assert.Throws<ArgumentOutOfRangeException>(() =>
{
Guard.MustBeGreaterThanOrEqualTo(1, 2, "myParamName");
});
Assert.Equal("myParamName", exception.ParamName);
Assert.True(exception.Message.Contains($"Value must be greater than or equal to 2."));
}
[Theory]
[InlineData(1, 1, 3)]
[InlineData(2, 1, 3)]
[InlineData(3, 1, 3)]
public void MustBeBetweenOrEqualTo_IsBetweenOrEqual_ThrowsNoException(int value, int min, int max)
{
Guard.MustBeBetweenOrEqualTo(value, min, max, "myParamName");
}
[Theory]
[InlineData(0, 1, 3)]
[InlineData(4, 1, 3)]
public void MustBeBetweenOrEqualTo_IsLessOrGreater_ThrowsNoException(int value, int min, int max)
{
var exception = Assert.Throws<ArgumentOutOfRangeException>(() =>
{
Guard.MustBeBetweenOrEqualTo(value, min, max, "myParamName");
});
Assert.Equal("myParamName", exception.ParamName);
Assert.True(exception.Message.Contains($"Value must be greater than or equal to {min} and less than or equal to {max}."));
}
[Fact]
public void IsTrue_IsTrue_ThrowsNoException()
{
Guard.IsTrue(true, "myParamName", "myTestMessage");
}
[Fact]
public void IsTrue_IsFalse_ThrowsException()
{
var exception = Assert.Throws<ArgumentException>(() =>
{
Guard.IsTrue(false, "myParamName", "myTestMessage");
});
Assert.Equal("myParamName", exception.ParamName);
Assert.True(exception.Message.Contains("myTestMessage"));
}
[Fact]
public void IsFalse_IsFalse_ThrowsNoException()
{
Guard.IsFalse(false, "myParamName", "myTestMessage");
}
[Fact]
public void IsFalse_IsTrue_ThrowsException()
{
var exception = Assert.Throws<ArgumentException>(() =>
{
Guard.IsFalse(true, "myParamName", "myTestMessage");
});
Assert.Equal("myParamName", exception.ParamName);
Assert.True(exception.Message.Contains("myTestMessage"));
}
[Theory]
[InlineData(2, 1)]
[InlineData(2, 2)]
public void MustBeSizedAtLeast_Array_LengthIsGreaterOrEqual_ThrowsNoException(int valueLength, int minLength)
{
Guard.MustBeSizedAtLeast<int>(new int[valueLength], minLength, "myParamName");
}
[Theory]
[InlineData(2, 1)]
[InlineData(2, 2)]
public void MustBeSizedAtLeast_Span_LengthIsGreaterOrEqual_ThrowsNoException(int valueLength, int minLength)
{
Guard.MustBeSizedAtLeast<int>(new Span<int>(new int[valueLength]), minLength, "myParamName");
}
[Theory]
[InlineData(2, 1)]
[InlineData(2, 2)]
public void MustBeSizedAtLeast_ReadOnlySpan_LengthIsGreaterOrEqual_ThrowsNoException(int valueLength, int minLength)
{
Guard.MustBeSizedAtLeast<int>(new ReadOnlySpan<int>(new int[valueLength]), minLength, "myParamName");
}
[Fact]
public void MustBeSizedAtLeast_Array_LengthIsLess_ThrowsException()
{
var exception = Assert.Throws<ArgumentException>(() =>
{
Guard.MustBeSizedAtLeast<int>(new int[] { 1, 2 }, 3, "myParamName");
});
Assert.Equal("myParamName", exception.ParamName);
Assert.True(exception.Message.Contains($"The size must be at least 3."));
}
[Fact]
public void MustBeSizedAtLeast_Span_LengthIsLess_ThrowsException()
{
var exception = Assert.Throws<ArgumentException>(() =>
{
Guard.MustBeSizedAtLeast<int>(new Span<int>(new int[2]), 3, "myParamName");
});
Assert.Equal("myParamName", exception.ParamName);
Assert.True(exception.Message.Contains($"The size must be at least 3."));
}
[Fact]
public void MustBeSizedAtLeast_ReadOnlySpan_LengthIsLess_ThrowsException()
{
var exception = Assert.Throws<ArgumentException>(() =>
{
Guard.MustBeSizedAtLeast<int>(new ReadOnlySpan<int>(new int[2]), 3, "myParamName");
});
Assert.Equal("myParamName", exception.ParamName);
Assert.True(exception.Message.Contains($"The size must be at least 3."));
}
}
}

24
tests/SixLabors.Core.Tests/Primitives/PointFTests.cs

@ -1,22 +1,20 @@
// <copyright file="PointFTests.cs" company="Six Labors">
// Copyright (c) Six Labors and contributors.
// Copyright (c) Six Labors and contributors.
// Licensed under the Apache License, Version 2.0.
// </copyright>
using System;
using System.Globalization;
using System.Numerics;
using System.Reflection;
using Xunit;
namespace SixLabors.Primitives.Tests
{
using System;
using System.Globalization;
using System.Numerics;
using System.Reflection;
using Xunit;
public class PointFTests
{
[Fact]
public void DefaultConstructorTest()
{
Assert.Equal(PointF.Empty, new PointF());
Assert.Equal(PointF.Empty, default(PointF));
}
[Theory]
@ -37,7 +35,7 @@ namespace SixLabors.Primitives.Tests
public void IsEmptyDefaultsTest()
{
Assert.True(PointF.Empty.IsEmpty);
Assert.True(new PointF().IsEmpty);
Assert.True(default(PointF).IsEmpty);
Assert.True(new PointF(0, 0).IsEmpty);
}
@ -151,7 +149,7 @@ namespace SixLabors.Primitives.Tests
}
[Fact]
public static void EqualityTest_NotPointF()
public void EqualityTest_NotPointF()
{
var point = new PointF(0, 0);
Assert.False(point.Equals(null));
@ -167,7 +165,7 @@ namespace SixLabors.Primitives.Tests
}
[Fact]
public static void GetHashCodeTest()
public void GetHashCodeTest()
{
var point = new PointF(10, 10);
Assert.Equal(point.GetHashCode(), new PointF(10, 10).GetHashCode());

23
tests/SixLabors.Core.Tests/Primitives/PointTests.cs

@ -1,21 +1,18 @@
// <copyright file="PointTests.cs" company="Six Labors">
// Copyright (c) Six Labors and contributors.
// Copyright (c) Six Labors and contributors.
// Licensed under the Apache License, Version 2.0.
// </copyright>
using System.Globalization;
using System.Numerics;
using Xunit;
namespace SixLabors.Primitives.Tests
{
using System.Globalization;
using System.Numerics;
using Xunit;
public class PointTests
{
[Fact]
public void DefaultConstructorTest()
{
Assert.Equal(Point.Empty, new Point());
Assert.Equal(Point.Empty, default(Point));
}
[Theory]
@ -47,7 +44,7 @@ namespace SixLabors.Primitives.Tests
public void IsEmptyDefaultsTest()
{
Assert.True(Point.Empty.IsEmpty);
Assert.True(new Point().IsEmpty);
Assert.True(default(Point).IsEmpty);
Assert.True(new Point(0, 0).IsEmpty);
}
@ -186,7 +183,7 @@ namespace SixLabors.Primitives.Tests
public void EqualityTest(int x, int y)
{
var p1 = new Point(x, y);
var p2 = new Point(x / 2 - 1, y / 2 - 1);
var p2 = new Point((x / 2) - 1, (y / 2) - 1);
var p3 = new Point(x, y);
Assert.True(p1 == p3);
@ -205,7 +202,7 @@ namespace SixLabors.Primitives.Tests
}
[Fact]
public static void EqualityTest_NotPoint()
public void EqualityTest_NotPoint()
{
var point = new Point(0, 0);
Assert.False(point.Equals(null));
@ -214,7 +211,7 @@ namespace SixLabors.Primitives.Tests
}
[Fact]
public static void GetHashCodeTest()
public void GetHashCodeTest()
{
var point = new Point(10, 10);
Assert.Equal(point.GetHashCode(), new Point(10, 10).GetHashCode());

49
tests/SixLabors.Core.Tests/Primitives/RectangleFTests.cs

@ -1,16 +1,13 @@
// <copyright file="RectangleFTests.cs" company="Six Labors">
// Copyright (c) Six Labors and contributors.
// Copyright (c) Six Labors and contributors.
// Licensed under the Apache License, Version 2.0.
// </copyright>
using System;
using System.Globalization;
using System.Reflection;
using Xunit;
namespace SixLabors.Primitives.Tests
{
using System;
using System.Globalization;
using System.Reflection;
using Xunit;
/// <summary>
/// Tests the <see cref="RectangleF"/> struct.
/// </summary>
@ -19,7 +16,7 @@ namespace SixLabors.Primitives.Tests
[Fact]
public void DefaultConstructorTest()
{
Assert.Equal(RectangleF.Empty, new RectangleF());
Assert.Equal(RectangleF.Empty, default(RectangleF));
}
[Theory]
@ -77,7 +74,7 @@ namespace SixLabors.Primitives.Tests
public void IsEmptyTest()
{
Assert.True(RectangleF.Empty.IsEmpty);
Assert.True(new RectangleF().IsEmpty);
Assert.True(default(RectangleF).IsEmpty);
Assert.True(new RectangleF(1, -2, -10, 10).IsEmpty);
Assert.True(new RectangleF(1, -2, 10, -10).IsEmpty);
Assert.True(new RectangleF(1, -2, 0, 0).IsEmpty);
@ -88,7 +85,7 @@ namespace SixLabors.Primitives.Tests
[Theory]
[InlineData(0, 0)]
[InlineData(float.MaxValue, float.MinValue)]
public static void LocationSetTest(float x, float y)
public void LocationSetTest(float x, float y)
{
var point = new PointF(x, y);
var rect = new RectangleF(10, 10, 10, 10) { Location = point };
@ -100,7 +97,7 @@ namespace SixLabors.Primitives.Tests
[Theory]
[InlineData(0, 0)]
[InlineData(float.MaxValue, float.MinValue)]
public static void SizeSetTest(float x, float y)
public void SizeSetTest(float x, float y)
{
var size = new SizeF(x, y);
var rect = new RectangleF(10, 10, 10, 10) { Size = size };
@ -125,7 +122,7 @@ namespace SixLabors.Primitives.Tests
}
[Fact]
public static void EqualityTestNotRectangleF()
public void EqualityTestNotRectangleF()
{
var rectangle = new RectangleF(0, 0, 0, 0);
Assert.False(rectangle.Equals(null));
@ -141,7 +138,7 @@ namespace SixLabors.Primitives.Tests
}
[Fact]
public static void GetHashCodeTest()
public void GetHashCodeTest()
{
var rect1 = new RectangleF(10, 10, 10, 10);
var rect2 = new RectangleF(10, 10, 10, 10);
@ -158,12 +155,12 @@ namespace SixLabors.Primitives.Tests
public void ContainsTest(float x, float y, float width, float height)
{
var rect = new RectangleF(x, y, width, height);
float X = (x + width) / 2;
float Y = (y + height) / 2;
var p = new PointF(X, Y);
var r = new RectangleF(X, Y, width / 2, height / 2);
float x1 = (x + width) / 2;
float y1 = (y + height) / 2;
var p = new PointF(x1, y1);
var r = new RectangleF(x1, y1, width / 2, height / 2);
Assert.False(rect.Contains(X, Y));
Assert.False(rect.Contains(x1, y1));
Assert.False(rect.Contains(p));
Assert.False(rect.Contains(r));
}
@ -175,7 +172,7 @@ namespace SixLabors.Primitives.Tests
public void InflateTest(float x, float y, float width, float height)
{
var rect = new RectangleF(x, y, width, height);
var inflatedRect = new RectangleF(x - width, y - height, width + 2 * width, height + 2 * height);
var inflatedRect = new RectangleF(x - width, y - height, width + (2 * width), height + (2 * height));
rect.Inflate(width, height);
Assert.Equal(inflatedRect, rect);
@ -201,7 +198,7 @@ namespace SixLabors.Primitives.Tests
}
[Fact]
public static void IntersectIntersectingRectsTest()
public void IntersectIntersectingRectsTest()
{
var rect1 = new RectangleF(0, 0, 5, 5);
var rect2 = new RectangleF(1, 1, 3, 3);
@ -255,13 +252,5 @@ namespace SixLabors.Primitives.Tests
var r = new RectangleF(5, 5.1F, 1.3F, 1);
Assert.Equal(string.Format(CultureInfo.CurrentCulture, "RectangleF [ X={0}, Y={1}, Width={2}, Height={3} ]", r.X, r.Y, r.Width, r.Height), r.ToString());
}
[InlineData(0, 0, 0, 0)]
[InlineData(5, -5, 0.2, -1.3)]
public void ToStringTestEmpty(float x, float y, float width, float height)
{
var r = new RectangleF(x, y, width, height);
Assert.Equal("RectangleF [ Empty ]", r.ToString());
}
}
}

33
tests/SixLabors.Core.Tests/Primitives/RectangleTests.cs

@ -1,15 +1,12 @@
// <copyright file="RectangleTests.cs" company="Six Labors">
// Copyright (c) Six Labors and contributors.
// Copyright (c) Six Labors and contributors.
// Licensed under the Apache License, Version 2.0.
// </copyright>
using System;
using System.Globalization;
using Xunit;
namespace SixLabors.Primitives.Tests
{
using System;
using System.Globalization;
using Xunit;
/// <summary>
/// Tests the <see cref="Rectangle"/> struct.
/// </summary>
@ -18,7 +15,7 @@ namespace SixLabors.Primitives.Tests
[Fact]
public void DefaultConstructorTest()
{
Assert.Equal(Rectangle.Empty, new Rectangle());
Assert.Equal(Rectangle.Empty, default(Rectangle));
}
[Theory]
@ -51,8 +48,8 @@ namespace SixLabors.Primitives.Tests
public void EmptyTest()
{
Assert.True(Rectangle.Empty.IsEmpty);
Assert.True(default(Rectangle).IsEmpty);
Assert.True(new Rectangle(0, 0, 0, 0).IsEmpty);
Assert.True(new Rectangle().IsEmpty);
}
[Theory]
@ -107,7 +104,7 @@ namespace SixLabors.Primitives.Tests
[Theory]
[InlineData(0, 0)]
[InlineData(int.MaxValue, int.MinValue)]
public static void LocationSetTest(int x, int y)
public void LocationSetTest(int x, int y)
{
var point = new Point(x, y);
var rect = new Rectangle(10, 10, 10, 10) { Location = point };
@ -119,7 +116,7 @@ namespace SixLabors.Primitives.Tests
[Theory]
[InlineData(0, 0)]
[InlineData(int.MaxValue, int.MinValue)]
public static void SizeSetTest(int x, int y)
public void SizeSetTest(int x, int y)
{
var size = new Size(x, y);
var rect = new Rectangle(10, 10, 10, 10) { Size = size };
@ -145,7 +142,7 @@ namespace SixLabors.Primitives.Tests
}
[Fact]
public static void EqualityTestNotRectangle()
public void EqualityTestNotRectangle()
{
var rectangle = new Rectangle(0, 0, 0, 0);
Assert.False(rectangle.Equals(null));
@ -154,7 +151,7 @@ namespace SixLabors.Primitives.Tests
}
[Fact]
public static void GetHashCodeTest()
public void GetHashCodeTest()
{
var rect1 = new Rectangle(10, 10, 10, 10);
var rect2 = new Rectangle(10, 10, 10, 10);
@ -193,7 +190,7 @@ namespace SixLabors.Primitives.Tests
[InlineData(0, int.MinValue, int.MaxValue, 0)]
public void ContainsTest(int x, int y, int width, int height)
{
var rect = new Rectangle(unchecked(2 * x - width), unchecked(2 * y - height), width, height);
var rect = new Rectangle(unchecked((2 * x) - width), unchecked((2 * y) - height), width, height);
var p = new Point(x, y);
var r = new Rectangle(x, y, width / 2, height / 2);
@ -211,7 +208,7 @@ namespace SixLabors.Primitives.Tests
Rectangle inflatedRect, rect = new Rectangle(x, y, width, height);
unchecked
{
inflatedRect = new Rectangle(x - width, y - height, width + 2 * width, height + 2 * height);
inflatedRect = new Rectangle(x - width, y - height, width + (2 * width), height + (2 * height));
}
Assert.Equal(inflatedRect, Rectangle.Inflate(rect, width, height));
@ -222,7 +219,7 @@ namespace SixLabors.Primitives.Tests
var s = new Size(x, y);
unchecked
{
inflatedRect = new Rectangle(rect.X - x, rect.Y - y, rect.Width + 2 * x, rect.Height + 2 * y);
inflatedRect = new Rectangle(rect.X - x, rect.Y - y, rect.Width + (2 * x), rect.Height + (2 * y));
}
rect.Inflate(s);
@ -243,7 +240,7 @@ namespace SixLabors.Primitives.Tests
}
[Fact]
public static void IntersectIntersectingRectsTest()
public void IntersectIntersectingRectsTest()
{
var rect1 = new Rectangle(0, 0, 5, 5);
var rect2 = new Rectangle(1, 1, 3, 3);

22
tests/SixLabors.Core.Tests/Primitives/SizeFTests.cs

@ -1,21 +1,19 @@
// <copyright file="SizeTests.cs" company="Six Labors">
// Copyright (c) Six Labors and contributors.
// Copyright (c) Six Labors and contributors.
// Licensed under the Apache License, Version 2.0.
// </copyright>
using System;
using System.Globalization;
using System.Reflection;
using Xunit;
namespace SixLabors.Primitives.Tests
{
using System;
using System.Globalization;
using System.Reflection;
using Xunit;
public class SizeFTests
{
[Fact]
public void DefaultConstructorTest()
{
Assert.Equal(SizeF.Empty, new SizeF());
Assert.Equal(SizeF.Empty, default(SizeF));
}
[Theory]
@ -47,7 +45,7 @@ namespace SixLabors.Primitives.Tests
public void IsEmptyDefaultsTest()
{
Assert.True(SizeF.Empty.IsEmpty);
Assert.True(new SizeF().IsEmpty);
Assert.True(default(SizeF).IsEmpty);
Assert.True(new SizeF(0, 0).IsEmpty);
}
@ -106,7 +104,7 @@ namespace SixLabors.Primitives.Tests
}
[Fact]
public static void EqualityTest_NotSizeF()
public void EqualityTest_NotSizeF()
{
var size = new SizeF(0, 0);
Assert.False(size.Equals(null));
@ -122,7 +120,7 @@ namespace SixLabors.Primitives.Tests
}
[Fact]
public static void GetHashCodeTest()
public void GetHashCodeTest()
{
var size = new SizeF(10, 10);
Assert.Equal(size.GetHashCode(), new SizeF(10, 10).GetHashCode());

22
tests/SixLabors.Core.Tests/Primitives/SizeTests.cs

@ -1,14 +1,12 @@
// <copyright file="SizeTests.cs" company="Six Labors">
// Copyright (c) Six Labors and contributors.
// Copyright (c) Six Labors and contributors.
// Licensed under the Apache License, Version 2.0.
// </copyright>
using System;
using System.Globalization;
using Xunit;
namespace SixLabors.Primitives.Tests
{
using System;
using System.Globalization;
using Xunit;
/// <summary>
/// Tests the <see cref="Size"/> struct.
/// </summary>
@ -17,7 +15,7 @@ namespace SixLabors.Primitives.Tests
[Fact]
public void DefaultConstructorTest()
{
Assert.Equal(Size.Empty, new Size());
Assert.Equal(Size.Empty, default(Size));
}
[Theory]
@ -43,7 +41,7 @@ namespace SixLabors.Primitives.Tests
public void IsEmptyDefaultsTest()
{
Assert.True(Size.Empty.IsEmpty);
Assert.True(new Size().IsEmpty);
Assert.True(default(Size).IsEmpty);
Assert.True(new Size(0, 0).IsEmpty);
}
@ -162,7 +160,7 @@ namespace SixLabors.Primitives.Tests
}
[Fact]
public static void EqualityTest_NotSize()
public void EqualityTest_NotSize()
{
var size = new Size(0, 0);
Assert.False(size.Equals(null));
@ -171,7 +169,7 @@ namespace SixLabors.Primitives.Tests
}
[Fact]
public static void GetHashCodeTest()
public void GetHashCodeTest()
{
var size = new Size(10, 10);
Assert.Equal(size.GetHashCode(), new Size(10, 10).GetHashCode());
@ -238,7 +236,6 @@ namespace SixLabors.Primitives.Tests
Assert.Equal(mulExpected, multiplier * sz1);
}
[Theory]
[InlineData(1000, 0.0f)]
[InlineData(1000, 1.0f)]
@ -285,7 +282,6 @@ namespace SixLabors.Primitives.Tests
Assert.Equal(mulExpected, multiplier * sz1);
}
[Fact]
public void DivideByZeroChecks()
{

10
tests/SixLabors.Core.Tests/SixLabors.Core.Tests.csproj

@ -16,7 +16,17 @@
<RootNamespace>SixLabors.Tests</RootNamespace>
</PropertyGroup>
<PropertyGroup>
<CodeAnalysisRuleSet>..\SixLabors.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<ItemGroup>
<AdditionalFiles Include="..\..\stylecop.json" />
<Content Include="..\..\stylecop.json" Link="stylecop.json" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="StyleCop.Analyzers" Version="1.1.0-beta004" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.0.0" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.2.0" />
<PackageReference Include="xunit" Version="2.2.0" />

10
tests/SixLabors.ruleset

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<RuleSet Name="Shaper2D" ToolsVersion="14.0">
<Rules AnalyzerId="StyleCop.Analyzers" RuleNamespace="StyleCop.Analyzers">
<Rule Id="SA1413" Action="None" />
<!-- Test only ignores -->
<Rule Id="SA0001" Action="None" />
<Rule Id="SA1117" Action="None" />
<Rule Id="SA1600" Action="None" />
</Rules>
</RuleSet>
Loading…
Cancel
Save