This commit is contained in:
2026-06-12 23:34:00 +07:00
parent 790a5f8e10
commit d7e9bb7b5b
27 changed files with 1167 additions and 1020 deletions

View File

@@ -2,7 +2,7 @@
namespace QWERTYkez.Mensura.Tests;
public class AggregateUnitExtensions
public class AggregateUnitExtensionsTest
{
// Вспомогательный метод для создания объекта Length.
// Если у вас используется фабричный метод (например, Length.FromMeters), замените код внутри.

View File

@@ -1,6 +1,6 @@
namespace QWERTYkez.Mensura.Tests;
public class CastExtensions
public class CastExtensionsTest
{
private const double NormalValue1 = 42.42;
private const double NormalValue2 = 100.05;

View File

@@ -1,6 +1,6 @@
namespace QWERTYkez.Mensura.Tests
{
public class CollectionsDivideExtensionsTests
public class CollectionsDivideExtensionsTest
{
private const double Tolerance = 1e-12;
private static readonly Length scalarUnit = Length.Meter; // 1000 mm
@@ -31,7 +31,7 @@
var result = nullableUnitsArray.Div<Length>(scalarDouble);
Assert.Equal(3, result.Length);
Assert.Equal(1000 / 2.0, (double)result[0]!, Tolerance);
Assert.Null(result[1]);
Assert.Equal(0 / 2.0, (double)result[1]!, Tolerance);
Assert.Equal(1 / 2.0, (double)result[2]!, Tolerance);
}
@@ -52,7 +52,7 @@
var result = scalarDouble.Div<Length>(nullableUnitsArray);
Assert.Equal(3, result.Length);
Assert.Equal(2.0 / 1000, (double)result[0]!, Tolerance);
Assert.Null(result[1]);
Assert.Equal(2.0 / 0, (double)result[1]!, Tolerance);
Assert.Equal(2.0 / 1, (double)result[2]!, Tolerance);
}
@@ -73,7 +73,7 @@
var result = nullableUnitsList.Div<Length>(scalarDouble);
Assert.Equal(3, result.Count);
Assert.Equal(1000 / 2.0, (double)result[0]!, Tolerance);
Assert.Null(result[1]);
Assert.Equal(0 / 2.0, (double)result[1]!, Tolerance);
Assert.Equal(1 / 2.0, (double)result[2]!, Tolerance);
}
@@ -94,7 +94,7 @@
var result = scalarDouble.Div<Length>(nullableUnitsList);
Assert.Equal(3, result.Count);
Assert.Equal(2.0 / 1000, (double)result[0]!, Tolerance);
Assert.Null(result[1]);
Assert.Equal(2.0 / 0, (double)result[1]!, Tolerance);
Assert.Equal(2.0 / 1, (double)result[2]!, Tolerance);
}
@@ -115,7 +115,7 @@
Span<Length?> dest = new Length?[3];
((IReadOnlyCollection<Length?>)nullableUnitsArray).Div(scalarDouble, dest);
Assert.Equal(1000 / 2.0, (double)dest[0]!, Tolerance);
Assert.Null(dest[1]);
Assert.Equal(0 / 2.0, (double)dest[1]!, Tolerance);
Assert.Equal(1 / 2.0, (double)dest[2]!, Tolerance);
}
@@ -136,7 +136,7 @@
Span<Length?> dest = new Length?[3];
scalarDouble.Div((IReadOnlyCollection<Length?>)nullableUnitsArray, dest);
Assert.Equal(2.0 / 1000, (double)dest[0]!, Tolerance);
Assert.Null(dest[1]);
Assert.Equal(2.0 / 0, (double)dest[1]!, Tolerance);
Assert.Equal(2.0 / 1, (double)dest[2]!, Tolerance);
}
@@ -157,7 +157,7 @@
var result = ((IEnumerable<Length?>)nullableUnitsArray).Div<Length>(scalarDouble).ToList();
Assert.Equal(3, result.Count);
Assert.Equal(1000 / 2.0, (double)result[0]!, Tolerance);
Assert.Null(result[1]);
Assert.Equal(0 / 2.0, (double)result[1]!, Tolerance);
Assert.Equal(1 / 2.0, (double)result[2]!, Tolerance);
}
@@ -178,7 +178,7 @@
var result = scalarDouble.Div<Length>((IEnumerable<Length?>)nullableUnitsArray).ToList();
Assert.Equal(3, result.Count);
Assert.Equal(2.0 / 1000, (double)result[0]!, Tolerance);
Assert.Null(result[1]);
Assert.Equal(2.0 / 0, (double)result[1]!, Tolerance);
Assert.Equal(2.0 / 1, (double)result[2]!, Tolerance);
}
@@ -199,7 +199,7 @@
var result = nullableDoubleArray.Div(scalarUnit);
Assert.Equal(3, result.Length);
Assert.Equal(2.0 / 1000, (double)result[0]!, Tolerance);
Assert.Null(result[1]);
Assert.Equal(0 / 1000, (double)result[1]!, Tolerance);
Assert.Equal(3.0 / 1000, (double)result[2]!, Tolerance);
}
@@ -220,7 +220,7 @@
var result = scalarUnit.Div(nullableDoubleArray);
Assert.Equal(3, result.Length);
Assert.Equal(1000 / 2.0, (double)result[0]!, Tolerance);
Assert.Null(result[1]);
Assert.Equal(1000 / 0.0, (double)result[1]!, Tolerance);
Assert.Equal(1000 / 3.0, (double)result[2]!, Tolerance);
}
@@ -243,7 +243,7 @@
var result = list.Div(scalarUnit);
Assert.Equal(3, result.Count);
Assert.Equal(2.0 / 1000, (double)result[0]!, Tolerance);
Assert.Null(result[1]);
Assert.Equal(0 / 1000, (double)result[1]!, Tolerance);
Assert.Equal(3.0 / 1000, (double)result[2]!, Tolerance);
}
@@ -266,7 +266,7 @@
var result = scalarUnit.Div(list);
Assert.Equal(3, result.Count);
Assert.Equal(1000 / 2.0, (double)result[0]!, Tolerance);
Assert.Null(result[1]);
Assert.Equal(1000 / 0.0, (double)result[1]!, Tolerance);
Assert.Equal(1000 / 3.0, (double)result[2]!, Tolerance);
}

View File

@@ -1,6 +1,6 @@
namespace QWERTYkez.Mensura.Tests
{
public class CollectionsMinusExtensionsTests
public class CollectionsMinusExtensionsTest
{
private const double Tolerance = 1e-12;
private static readonly Length scalarUnit = Length.Meter; // 1000 mm
@@ -44,7 +44,7 @@
var result = nullableUnitsArray.Minus<Length>(scalarDouble);
Assert.Equal(3, result.Length);
Assert.Equal(1000 - 1000, (double)result[0]!, Tolerance);
Assert.Null(result[1]);
Assert.Equal(0 - 1000, (double)result[1]!, Tolerance);
Assert.Equal(1 - 1000, (double)result[2]!, Tolerance);
}
@@ -65,7 +65,7 @@
var result = scalarDouble.Minus<Length>(nullableUnitsArray);
Assert.Equal(3, result.Length);
Assert.Equal(1000 - 1000, (double)result[0]!, Tolerance);
Assert.Null(result[1]);
Assert.Equal(1000 - 0, (double)result[1]!, Tolerance);
Assert.Equal(1000 - 1, (double)result[2]!, Tolerance);
}
@@ -86,7 +86,7 @@
var result = nullableUnitsList.Minus<Length>(scalarDouble);
Assert.Equal(3, result.Count);
Assert.Equal(1000 - 1000, (double)result[0]!, Tolerance);
Assert.Null(result[1]);
Assert.Equal(0 - 1000, (double)result[1]!, Tolerance);
Assert.Equal(1 - 1000, (double)result[2]!, Tolerance);
}
@@ -107,7 +107,7 @@
var result = scalarDouble.Minus<Length>(nullableUnitsList);
Assert.Equal(3, result.Count);
Assert.Equal(1000 - 1000, (double)result[0]!, Tolerance);
Assert.Null(result[1]);
Assert.Equal(1000 - 0, (double)result[1]!, Tolerance);
Assert.Equal(1000 - 1, (double)result[2]!, Tolerance);
}
@@ -128,7 +128,7 @@
Span<Length?> dest = new Length?[3];
((IReadOnlyCollection<Length?>)nullableUnitsArray).Minus<Length>(scalarDouble, dest);
Assert.Equal(1000 - 1000, (double)dest[0]!, Tolerance);
Assert.Null(dest[1]);
Assert.Equal(0 - 1000, (double)dest[1]!, Tolerance);
Assert.Equal(1 - 1000, (double)dest[2]!, Tolerance);
}
@@ -149,7 +149,7 @@
Span<Length?> dest = new Length?[3];
scalarDouble.Minus<Length>((IReadOnlyCollection<Length?>)nullableUnitsArray, dest);
Assert.Equal(1000 - 1000, (double)dest[0]!, Tolerance);
Assert.Null(dest[1]);
Assert.Equal(1000 - 0, (double)dest[1]!, Tolerance);
Assert.Equal(1000 - 1, (double)dest[2]!, Tolerance);
}
@@ -170,7 +170,7 @@
var result = ((IEnumerable<Length?>)nullableUnitsArray).Minus<Length>(scalarDouble).ToList();
Assert.Equal(3, result.Count);
Assert.Equal(1000 - 1000, (double)result[0]!, Tolerance);
Assert.Null(result[1]);
Assert.Equal(0 - 1000, (double)result[1]!, Tolerance);
Assert.Equal(1 - 1000, (double)result[2]!, Tolerance);
}
@@ -191,7 +191,7 @@
var result = scalarDouble.Minus<Length>((IEnumerable<Length?>)nullableUnitsArray).ToList();
Assert.Equal(3, result.Count);
Assert.Equal(1000 - 1000, (double)result[0]!, Tolerance);
Assert.Null(result[1]);
Assert.Equal(1000 - 0, (double)result[1]!, Tolerance);
Assert.Equal(1000 - 1, (double)result[2]!, Tolerance);
}
@@ -212,7 +212,7 @@
var result = nullableDoubleArray.Minus(scalarUnit);
Assert.Equal(3, result.Length);
Assert.Equal(500 - 1000, (double)result[0]!, Tolerance);
Assert.Null(result[1]);
Assert.Equal(0 - 1000, (double)result[1]!, Tolerance);
Assert.Equal(200 - 1000, (double)result[2]!, Tolerance);
}
@@ -233,7 +233,7 @@
var result = scalarUnit.Minus(nullableDoubleArray);
Assert.Equal(3, result.Length);
Assert.Equal(1000 - 500, (double)result[0]!, Tolerance);
Assert.Null(result[1]);
Assert.Equal(1000 - 0, (double)result[1]!, Tolerance);
Assert.Equal(1000 - 200, (double)result[2]!, Tolerance);
}
@@ -254,7 +254,7 @@
var result = nullableDoubleList.Minus(scalarUnit);
Assert.Equal(3, result.Count);
Assert.Equal(500 - 1000, (double)result[0]!, Tolerance);
Assert.Null(result[1]);
Assert.Equal(0 - 1000, (double)result[1]!, Tolerance);
Assert.Equal(200 - 1000, (double)result[2]!, Tolerance);
}
@@ -275,7 +275,7 @@
var result = scalarUnit.Minus(nullableDoubleList);
Assert.Equal(3, result.Count);
Assert.Equal(1000 - 500, (double)result[0]!, Tolerance);
Assert.Null(result[1]);
Assert.Equal(1000 - 0, (double)result[1]!, Tolerance);
Assert.Equal(1000 - 200, (double)result[2]!, Tolerance);
}

View File

@@ -1,6 +1,6 @@
namespace QWERTYkez.Mensura.Tests
{
public class CollectionsMultiplyExtensionsTests
public class CollectionsMultiplyExtensionsTest
{
private const double Tolerance = 1e-12;
private static readonly Length scalarUnit = Length.Meter; // 1000 mm
@@ -43,7 +43,7 @@
var result = nullableUnitsArray.Mul<Length>(scalarDouble);
Assert.Equal(3, result.Length);
Assert.Equal(1000 * 2, (double)result[0]!, Tolerance);
Assert.Null(result[1]); // null * 2 = null
Assert.Equal(0, (double)result[1]!, Tolerance);
Assert.Equal(1 * 2, (double)result[2]!, Tolerance);
}
@@ -64,7 +64,7 @@
var result = scalarDouble.Mul<Length>(nullableUnitsArray);
Assert.Equal(3, result.Length);
Assert.Equal(2 * 1000, (double)result[0]!, Tolerance);
Assert.Null(result[1]); // 2 * null = null
Assert.Equal(0, (double)result[1]!, Tolerance);
Assert.Equal(2 * 1, (double)result[2]!, Tolerance);
}
@@ -85,7 +85,7 @@
var result = nullableUnitsList.Mul<Length>(scalarDouble);
Assert.Equal(3, result.Count);
Assert.Equal(1000 * 2, (double)result[0]!, Tolerance);
Assert.Null(result[1]); // null * 2 = null
Assert.Equal(0, (double)result[1]!, Tolerance);
Assert.Equal(1 * 2, (double)result[2]!, Tolerance);
}
@@ -106,7 +106,7 @@
var result = scalarDouble.Mul<Length>(nullableUnitsList);
Assert.Equal(3, result.Count);
Assert.Equal(2 * 1000, (double)result[0]!, Tolerance);
Assert.Null(result[1]); // 2 * null = null
Assert.Equal(0, (double)result[1]!, Tolerance);
Assert.Equal(2 * 1, (double)result[2]!, Tolerance);
}
@@ -127,7 +127,7 @@
Span<Length?> dest = new Length?[3];
((IReadOnlyCollection<Length?>)nullableUnitsArray).Mul<Length>(scalarDouble, dest);
Assert.Equal(1000 * 2, (double)dest[0]!, Tolerance);
Assert.Null(dest[1]); // null * 2 = null
Assert.Equal(0, (double)dest[1]!, Tolerance);
Assert.Equal(1 * 2, (double)dest[2]!, Tolerance);
}
@@ -148,7 +148,7 @@
Span<Length?> dest = new Length?[3];
scalarDouble.Mul<Length>((IReadOnlyCollection<Length?>)nullableUnitsArray, dest);
Assert.Equal(2 * 1000, (double)dest[0]!, Tolerance);
Assert.Null(dest[1]); // 2 * null = null
Assert.Equal(0, (double)dest[1]!, Tolerance);
Assert.Equal(2 * 1, (double)dest[2]!, Tolerance);
}
@@ -169,7 +169,7 @@
var result = ((IEnumerable<Length?>)nullableUnitsArray).Mul<Length>(scalarDouble).ToList();
Assert.Equal(3, result.Count);
Assert.Equal(1000 * 2, (double)result[0]!, Tolerance);
Assert.Null(result[1]); // null * 2 = null
Assert.Equal(0, (double)result[1]!, Tolerance);
Assert.Equal(1 * 2, (double)result[2]!, Tolerance);
}
@@ -190,7 +190,7 @@
var result = scalarDouble.Mul<Length>((IEnumerable<Length?>)nullableUnitsArray).ToList();
Assert.Equal(3, result.Count);
Assert.Equal(2 * 1000, (double)result[0]!, Tolerance);
Assert.Null(result[1]); // 2 * null = null
Assert.Equal(0, (double)result[1]!, Tolerance);
Assert.Equal(2 * 1, (double)result[2]!, Tolerance);
}
@@ -211,7 +211,7 @@
var result = nullableDoubleArray.Mul(scalarUnit);
Assert.Equal(3, result.Length);
Assert.Equal(5 * 1000, (double)result[0]!, Tolerance);
Assert.Null(result[1]); // null * Length = null
Assert.Equal(0, (double)result[1]!, Tolerance);
Assert.Equal(3 * 1000, (double)result[2]!, Tolerance);
}
@@ -232,7 +232,7 @@
var result = scalarUnit.Mul(nullableDoubleArray);
Assert.Equal(3, result.Length);
Assert.Equal(1000 * 5, (double)result[0]!, Tolerance);
Assert.Null(result[1]); // Length * null = null
Assert.Equal(0, (double)result[1]!, Tolerance);
Assert.Equal(1000 * 3, (double)result[2]!, Tolerance);
}
@@ -253,7 +253,7 @@
var result = nullableDoubleList.Mul(scalarUnit);
Assert.Equal(3, result.Count);
Assert.Equal(5 * 1000, (double)result[0]!, Tolerance);
Assert.Null(result[1]); // null * Length = null
Assert.Equal(0, (double)result[1]!, Tolerance);
Assert.Equal(3 * 1000, (double)result[2]!, Tolerance);
}
@@ -274,7 +274,7 @@
var result = scalarUnit.Mul(nullableDoubleList);
Assert.Equal(3, result.Count);
Assert.Equal(1000 * 5, (double)result[0]!, Tolerance);
Assert.Null(result[1]); // Length * null = null
Assert.Equal(0, (double)result[1]!, Tolerance);
Assert.Equal(1000 * 3, (double)result[2]!, Tolerance);
}

View File

@@ -1,13 +1,6 @@
using System;
using System.Collections.Generic;
using System.Linq;
using QWERTYkez.Mensura.Units;
using QWERTYkez.Mensura.Extensions;
using Xunit;
namespace QWERTYkez.Mensura.Tests
namespace QWERTYkez.Mensura.Tests
{
public class CollectionsPlusExtensionsTests
public class CollectionsPlusExtensionsTest
{
private const double Tolerance = 1e-12;
private static readonly Length scalarUnit = Length.Meter; // 1000 mm
@@ -42,7 +35,7 @@ namespace QWERTYkez.Mensura.Tests
var result = nullableUnitsArray.Plus<Length>(scalarDouble);
Assert.Equal(3, result.Length);
Assert.Equal(1000 + 500, (double)result[0]!, Tolerance);
Assert.Null(result[1]); // null + число = null
Assert.Equal(0 + 500, (double)result[1]!, Tolerance);
Assert.Equal(1 + 500, (double)result[2]!, Tolerance);
}
@@ -63,7 +56,7 @@ namespace QWERTYkez.Mensura.Tests
var result = scalarDouble.Plus<Length>(nullableUnitsArray);
Assert.Equal(3, result.Length);
Assert.Equal(500 + 1000, (double)result[0]!, Tolerance);
Assert.Null(result[1]); // число + null = null
Assert.Equal(500 + 0, (double)result[1]!, Tolerance);
Assert.Equal(500 + 1, (double)result[2]!, Tolerance);
}
@@ -84,7 +77,7 @@ namespace QWERTYkez.Mensura.Tests
var result = nullableUnitsList.Plus<Length>(scalarDouble);
Assert.Equal(3, result.Count);
Assert.Equal(1000 + 500, (double)result[0]!, Tolerance);
Assert.Null(result[1]); // null + число = null
Assert.Equal(0 + 500, (double)result[1]!, Tolerance);
Assert.Equal(1 + 500, (double)result[2]!, Tolerance);
}
@@ -105,7 +98,7 @@ namespace QWERTYkez.Mensura.Tests
var result = scalarDouble.Plus<Length>(nullableUnitsList);
Assert.Equal(3, result.Count);
Assert.Equal(500 + 1000, (double)result[0]!, Tolerance);
Assert.Null(result[1]); // число + null = null
Assert.Equal(500 + 0, (double)result[1]!, Tolerance);
Assert.Equal(500 + 1, (double)result[2]!, Tolerance);
}
@@ -126,7 +119,7 @@ namespace QWERTYkez.Mensura.Tests
Span<Length?> dest = new Length?[3];
((IReadOnlyCollection<Length?>)nullableUnitsArray).Plus<Length>(scalarDouble, dest);
Assert.Equal(1000 + 500, (double)dest[0]!, Tolerance);
Assert.Null(dest[1]); // null + число = null
Assert.Equal(0 + 500, (double)dest[1]!, Tolerance);
Assert.Equal(1 + 500, (double)dest[2]!, Tolerance);
}
@@ -147,7 +140,7 @@ namespace QWERTYkez.Mensura.Tests
Span<Length?> dest = new Length?[3];
scalarDouble.Plus<Length>((IReadOnlyCollection<Length?>)nullableUnitsArray, dest);
Assert.Equal(500 + 1000, (double)dest[0]!, Tolerance);
Assert.Null(dest[1]); // число + null = null
Assert.Equal(500 + 0, (double)dest[1]!, Tolerance);
Assert.Equal(500 + 1, (double)dest[2]!, Tolerance);
}
@@ -168,7 +161,7 @@ namespace QWERTYkez.Mensura.Tests
var result = ((IEnumerable<Length?>)nullableUnitsArray).Plus<Length>(scalarDouble).ToList();
Assert.Equal(3, result.Count);
Assert.Equal(1000 + 500, (double)result[0]!, Tolerance);
Assert.Null(result[1]); // null + число = null
Assert.Equal(0 + 500, (double)result[1]!, Tolerance);
Assert.Equal(1 + 500, (double)result[2]!, Tolerance);
}
@@ -189,7 +182,7 @@ namespace QWERTYkez.Mensura.Tests
var result = scalarDouble.Plus<Length>((IEnumerable<Length?>)nullableUnitsArray).ToList();
Assert.Equal(3, result.Count);
Assert.Equal(500 + 1000, (double)result[0]!, Tolerance);
Assert.Null(result[1]); // число + null = null
Assert.Equal(500 + 0, (double)result[1]!, Tolerance);
Assert.Equal(500 + 1, (double)result[2]!, Tolerance);
}
@@ -210,7 +203,7 @@ namespace QWERTYkez.Mensura.Tests
var result = nullableDoubleArray.Plus(scalarUnit);
Assert.Equal(3, result.Length);
Assert.Equal(200 + 1000, (double)result[0]!, Tolerance);
Assert.Null(result[1]); // null + Length = null
Assert.Equal(0 + 1000, (double)result[1]!, Tolerance);
Assert.Equal(300 + 1000, (double)result[2]!, Tolerance);
}
@@ -231,7 +224,7 @@ namespace QWERTYkez.Mensura.Tests
var result = scalarUnit.Plus(nullableDoubleArray);
Assert.Equal(3, result.Length);
Assert.Equal(1000 + 200, (double)result[0]!, Tolerance);
Assert.Null(result[1]); // Length + null = null
Assert.Equal(1000 + 0, (double)result[1]!, Tolerance);
Assert.Equal(1000 + 300, (double)result[2]!, Tolerance);
}
@@ -252,7 +245,7 @@ namespace QWERTYkez.Mensura.Tests
var result = nullableDoubleList.Plus(scalarUnit);
Assert.Equal(3, result.Count);
Assert.Equal(200 + 1000, (double)result[0]!, Tolerance);
Assert.Null(result[1]); // null + Length = null
Assert.Equal(0 + 1000, (double)result[1]!, Tolerance);
Assert.Equal(300 + 1000, (double)result[2]!, Tolerance);
}
@@ -273,7 +266,7 @@ namespace QWERTYkez.Mensura.Tests
var result = scalarUnit.Plus(nullableDoubleList);
Assert.Equal(3, result.Count);
Assert.Equal(1000 + 200, (double)result[0]!, Tolerance);
Assert.Null(result[1]); // Length + null = null
Assert.Equal(1000 + 0, (double)result[1]!, Tolerance);
Assert.Equal(1000 + 300, (double)result[2]!, Tolerance);
}

View File

@@ -1,6 +1,6 @@
namespace QWERTYkez.Mensura.Tests;
public class CollectionsPow2Extensions
public class CollectionsPow2ExtensionsTest
{
[Fact]
public void Pow2_Array_CalculatesCorrectly()

View File

@@ -1,6 +1,6 @@
namespace QWERTYkez.Mensura.Tests;
public class Pow3ExtensionsTests
public class CollectionsPow3ExtensionsTest
{
[Fact]
public void Pow3_Array_CalculatesCorrectly()

View File

@@ -1,6 +1,6 @@
namespace QWERTYkez.Mensura.Tests;
public class CollectionsPowNExtensions
public class CollectionsPowNExtensionsTest
{
private const double BaseVal = 3.0;
private const double Expected = 9.0; // 3^2 = 9

View File

@@ -1,6 +1,6 @@
namespace QWERTYkez.Mensura.Tests;
public class CollectionsRootOfCubeExtensions
public class CollectionsRootOfCubeExtensionsTest
{
[Fact]
public void Cbrt_Array_CalculatesCorrectly()
@@ -23,7 +23,7 @@ public class CollectionsRootOfCubeExtensions
var result = source.Cbrt<Length, Length>();
Assert.Equal(4, result[0]?._Value);
Assert.Null(result[1]);
Assert.Equal(0, result[1]?._Value);
Assert.Equal(6, result[2]?._Value);
}

View File

@@ -1,6 +1,6 @@
namespace QWERTYkez.Mensura.Tests;
public class CollectionsRootOfSquareExtensions
public class CollectionsRootOfSquareExtensionsTest
{
[Fact]
public void Sqrt_Array_ShouldCalculateCorrectly()
@@ -28,7 +28,7 @@ public class CollectionsRootOfSquareExtensions
// Assert
Assert.Equal(5, result[0]?._Value);
Assert.Null(result[1]);
Assert.Equal(0, result[1]?._Value);
Assert.Equal(10, result[2]?._Value);
}

View File

@@ -1,164 +0,0 @@
namespace QWERTYkez.Mensura.Tests;
public class DoubleExtensions
{
#region 1. Тесты скалярных типов (Обычные, Экзотические и Nullable)
[Fact]
public void ToDouble_Should_Convert_ExoticTypes_Without_InvalidCastException()
{
// Проверяем типы, которые раньше могли падать в рантайме из-за Convert.ToDouble(object)
Half halfValue = (Half)3.14f;
Int128 int128Value = Int128.Parse("1234567890123456789012345");
UInt128 uInt128Value = UInt128.Parse("9876543210987654321098765");
nint nintValue = 42;
// Act & Assert
Assert.Equal(3.14, halfValue.ToDouble(), 2);
Assert.Equal((double)int128Value, int128Value.ToDouble());
Assert.Equal((double)uInt128Value, uInt128Value.ToDouble());
Assert.Equal(42.0, nintValue.ToDouble());
}
[Theory]
[InlineData((int)100, 100.0)]
[InlineData((byte)5, 5.0)]
[InlineData((float)1.5f, 1.5)]
public void ToDouble_StandardScalars_ShouldConvertCorrectly(object input, double expected)
{
double result = input switch
{
int i => i.ToDouble(),
byte b => b.ToDouble(),
float f => f.ToDouble(),
_ => throw new ArgumentException("Unsupported type in test")
};
Assert.Equal(expected, result);
}
[Fact]
public void ToDouble_NullableScalars_Should_Return_Zero_When_Null()
{
// Arrange
int? nullInt = null;
Half? nullHalf = null;
Int128? nullInt128 = null;
int? validInt = 10;
Half? validHalf = (Half)2.5f;
// Act & Assert
Assert.Equal(0d, nullInt.ToDouble());
Assert.Equal(0d, nullHalf.ToDouble());
Assert.Equal(0d, nullInt128.ToDouble());
Assert.Equal(10d, validInt.ToDouble());
Assert.Equal(2.5d, validHalf.ToDouble(), 1);
}
#endregion
#region 2. Тесты SIMD и оптимизаций коллекций (Различные длины массивов)
[Theory]
[InlineData(0)] // Пустой массив
[InlineData(1)] // 1 элемент (чисто скалярный fallback)
[InlineData(7)] // Нечетное число элементов
[InlineData(16)] // Кратный размер (размер Vector128/Vector256)
[InlineData(35)] // Большой массив с остатком для скалярного хвоста
public void ToDouble_ArrayAndList_Should_Correctly_Map_Via_SIMD_Or_Fallback(int count)
{
// Arrange
float[] sourceArray = [.. Enumerable.Range(1, count).Select(x => x * 1.5f)];
List<float> sourceList = [.. sourceArray];
double[] destFromArray = new double[count];
double[] destFromList = new double[count];
// Act
// Явное приведение к IReadOnlyCollection устраняет ошибку CS0121 (неоднозначность вызова)
((IReadOnlyCollection<float>)sourceArray).ToDouble(destFromArray);
((IReadOnlyCollection<float>)sourceList).ToDouble(destFromList);
// Assert
for (int i = 0; i < count; i++)
{
double expected = sourceArray[i];
Assert.Equal(expected, destFromArray[i]);
Assert.Equal(expected, destFromList[i]);
}
}
#endregion
#region 3. Тесты Nullable-коллекций (Проверка на null-элементы внутри)
[Fact]
public void ToDouble_Nullable_Collections_Should_Keep_Nulls_In_Destination()
{
// Arrange
UInt128?[] sourceArray = [10, null, 20, null, 30];
double?[] destination = new double?[sourceArray.Length];
// Act
((IReadOnlyCollection<UInt128?>)sourceArray).ToDouble(destination);
// Assert
Assert.Equal(10d, destination[0]);
Assert.Null(destination[1]);
Assert.Equal(20d, destination[2]);
Assert.Null(destination[3]);
Assert.Equal(30d, destination[4]);
}
#endregion
#region 4. Тесты LINQ / Отложенного выполнения (IEnumerable)
[Fact]
public void ToDouble_IEnumerable_Extension_Should_Handle_Execution_Types_Correctly()
{
// Arrange
int[] array = [1, 2, 3];
List<int> list = [4, 5, 6];
IEnumerable<int> genericEnum = Enumerable.Range(7, 3);
// Act
var resFromArray = array.ToDouble(); // Быстрый бранч для массива
var resFromList = list.ToDouble(); // Быстрый бранч для списка
var resFromEnum = genericEnum.ToDouble(); // Медленный итератор по IEnumerable
// Assert
Assert.Equal([1d, 2d, 3d], resFromArray);
Assert.Equal([4d, 5d, 6d], resFromList);
Assert.Equal([7d, 8d, 9d], resFromEnum);
}
#endregion
#region 5. Тесты безопасности и валидации аргументов
[Fact]
public void ToDouble_Should_Throw_ArgumentException_When_Destination_Is_Too_Short()
{
// Arrange
int[] source = [1, 2, 3, 4, 5];
double[] destinationTooShort = new double[4]; // Нужен размер >= 5
// Act & Assert
Assert.Throws<ArgumentException>(() => ((IReadOnlyCollection<int>)source).ToDouble(destinationTooShort));
}
[Fact]
public void ToDouble_Should_Do_Nothing_And_Return_When_Collection_Is_Empty_Or_Null()
{
// Arrange
int[]? nullArray = null;
int[] emptyArray = [];
double[] destination = new double[5];
// Act & Assert (Не должно выбрасывать NullReferenceException или ArgumentException)
((IReadOnlyCollection<int>?)nullArray)!.ToDouble(destination);
((IReadOnlyCollection<int>)emptyArray).ToDouble(destination);
Assert.All(destination, x => Assert.Equal(0d, x)); // Назначение осталось нетронутым (все нули по умолчанию)
}
#endregion
}

View File

@@ -0,0 +1,394 @@
using System;
using System.Collections.Generic;
using System.Linq;
using QWERTYkez.Mensura.Extensions;
using Xunit;
namespace QWERTYkez.Mensura.Tests
{
public class DoubleExtensionsTests
{
private const double Tolerance = 1e-12;
#region Single value conversions (non-nullable)
[Theory]
[InlineData(0)]
[InlineData(1)]
[InlineData(255)]
public void ToDouble_Byte_ReturnsExpected(byte value) => Assert.Equal(value, value.ToDouble());
[Theory]
[InlineData(-128)]
[InlineData(0)]
[InlineData(127)]
public void ToDouble_SByte_ReturnsExpected(sbyte value) => Assert.Equal(value, value.ToDouble());
[Theory]
[InlineData(-32768)]
[InlineData(0)]
[InlineData(32767)]
public void ToDouble_Short_ReturnsExpected(short value) => Assert.Equal(value, value.ToDouble());
[Theory]
[InlineData(0)]
[InlineData(1)]
[InlineData(65535)]
public void ToDouble_UShort_ReturnsExpected(ushort value) => Assert.Equal(value, value.ToDouble());
[Theory]
[InlineData(-2147483648)]
[InlineData(0)]
[InlineData(2147483647)]
public void ToDouble_Int_ReturnsExpected(int value) => Assert.Equal(value, value.ToDouble());
[Theory]
[InlineData(0U)]
[InlineData(1U)]
[InlineData(uint.MaxValue)]
public void ToDouble_UInt_ReturnsExpected(uint value) => Assert.Equal(value, value.ToDouble());
[Theory]
[InlineData(-9223372036854775808)]
[InlineData(0)]
[InlineData(9223372036854775807)]
public void ToDouble_Long_ReturnsExpected(long value) => Assert.Equal((double)value, value.ToDouble(), Tolerance);
[Theory]
[InlineData(0UL)]
[InlineData(1UL)]
[InlineData(ulong.MaxValue)]
public void ToDouble_ULong_ReturnsExpected(ulong value) => Assert.Equal((double)value, value.ToDouble(), Tolerance);
[Theory]
[InlineData(-123456789)]
[InlineData(0)]
[InlineData(123456789)]
public void ToDouble_NInt_ReturnsExpected(nint value) => Assert.Equal(value, value.ToDouble());
[Theory]
[InlineData(0u)]
[InlineData(123456789u)]
public void ToDouble_NUInt_ReturnsExpected(nuint value) => Assert.Equal((double)value, value.ToDouble());
[Theory]
[InlineData(0.0f)]
[InlineData(123.456f)]
[InlineData(-987.654f)]
[InlineData(float.Epsilon)]
[InlineData(float.MaxValue)]
public void ToDouble_Float_ReturnsExpected(float value) => Assert.Equal((double)value, value.ToDouble(), Tolerance);
[Theory]
[InlineData(0.0)]
[InlineData(123.456)]
[InlineData(-987.654)]
public void ToDouble_Decimal_ReturnsExpected(decimal value) => Assert.Equal((double)value, value.ToDouble(), Tolerance);
[Theory]
[InlineData(0.0)]
[InlineData(123.456)]
[InlineData(-987.654)]
public void ToDouble_Half_ReturnsExpected(Half value) => Assert.Equal((double)value, value.ToDouble(), Tolerance);
#endregion
#region Single value conversions (nullable)
[Fact]
public void ToDouble_NullableByte_Null_ReturnsZero() => Assert.Equal(0.0, ((byte?)null).ToDouble());
[Fact]
public void ToDouble_NullableSByte_Null_ReturnsZero() => Assert.Equal(0.0, ((sbyte?)null).ToDouble());
[Fact]
public void ToDouble_NullableShort_Null_ReturnsZero() => Assert.Equal(0.0, ((short?)null).ToDouble());
[Fact]
public void ToDouble_NullableUShort_Null_ReturnsZero() => Assert.Equal(0.0, ((ushort?)null).ToDouble());
[Fact]
public void ToDouble_NullableInt_Null_ReturnsZero() => Assert.Equal(0.0, ((int?)null).ToDouble());
[Fact]
public void ToDouble_NullableUInt_Null_ReturnsZero() => Assert.Equal(0.0, ((uint?)null).ToDouble());
[Fact]
public void ToDouble_NullableLong_Null_ReturnsZero() => Assert.Equal(0.0, ((long?)null).ToDouble());
[Fact]
public void ToDouble_NullableULong_Null_ReturnsZero() => Assert.Equal(0.0, ((ulong?)null).ToDouble());
[Fact]
public void ToDouble_NullableNInt_Null_ReturnsZero() => Assert.Equal(0.0, ((nint?)null).ToDouble());
[Fact]
public void ToDouble_NullableNUInt_Null_ReturnsZero() => Assert.Equal(0.0, ((nuint?)null).ToDouble());
[Fact]
public void ToDouble_NullableFloat_Null_ReturnsZero() => Assert.Equal(0.0, ((float?)null).ToDouble());
[Fact]
public void ToDouble_NullableDecimal_Null_ReturnsZero() => Assert.Equal(0.0, ((decimal?)null).ToDouble());
[Fact]
public void ToDouble_NullableHalf_Null_ReturnsZero() => Assert.Equal(0.0, ((Half?)null).ToDouble());
#endregion
#region NET7_0_OR_GREATER
#if NET7_0_OR_GREATER
[Theory]
[InlineData(0)]
[InlineData(1)]
[InlineData(-1)]
[InlineData(long.MaxValue)]
public void ToDouble_Int128_ReturnsExpected(Int128 value) => Assert.Equal((double)value, value.ToDouble(), Tolerance);
[Theory]
[InlineData(0)]
[InlineData(1)]
[InlineData(ulong.MaxValue)]
public void ToDouble_UInt128_ReturnsExpected(UInt128 value) => Assert.Equal((double)value, value.ToDouble(), Tolerance);
[Fact]
public void ToDouble_NullableInt128_Null_ReturnsZero() => Assert.Equal(0.0, ((Int128?)null).ToDouble());
[Fact]
public void ToDouble_NullableUInt128_Null_ReturnsZero() => Assert.Equal(0.0, ((UInt128?)null).ToDouble());
#endif
#endregion
#region IEnumerable<T> -> IEnumerable<double> (non-nullable)
[Fact]
public void ToDouble_IEnumerableByte_ReturnsCorrect()
{
byte[] source = [1, 2, 3];
var result = source.ToDouble();
Assert.Equal(new double[] { 1, 2, 3 }, result);
}
[Fact]
public void ToDouble_IEnumerableByte_Empty_ReturnsEmpty()
{
var source = Array.Empty<byte>();
var result = source.ToDouble();
Assert.Empty(result);
}
[Fact]
public void ToDouble_IEnumerableByte_Null_Throws() => Assert.Null(((IEnumerable<byte>)null!).ToDouble());
[Fact]
public void ToDouble_IEnumerableInt_ReturnsCorrect()
{
int[] source = [-5, 0, 10];
var result = source.ToDouble();
Assert.Equal(new double[] { -5, 0, 10 }, result);
}
[Fact]
public void ToDouble_IEnumerableInt_Null_Throws() => Assert.Null(((IEnumerable<int>)null!).ToDouble());
#endregion
#region IEnumerable<T?> -> IEnumerable<double?>
[Fact]
public void ToDouble_IEnumerableNullableInt_ReturnsCorrect()
{
int?[] source = [1, null, 3];
var result = source.ToDouble();
Assert.Equal(3, result.Length);
Assert.Equal(1.0, result.First());
Assert.Null(result.Skip(1).First());
Assert.Equal(3.0, result.Last());
}
[Fact]
public void ToDouble_IEnumerableNullableInt_Null_Throws() => Assert.Null(((IEnumerable<int?>)null!).ToDouble());
#endregion
#region Array and List conversions (non-nullable)
[Fact]
public void ToDouble_ByteArray_ReturnsDoubleArray()
{
byte[] arr = [10, 20];
var result = arr.ToDouble();
Assert.Equal(new double[] { 10, 20 }, result);
}
[Fact]
public void ToDouble_ByteArray_Null_ReturnsNull() => Assert.Null(((byte[])null!).ToDouble());
[Fact]
public void ToDouble_ByteList_ReturnsDoubleList()
{
var list = new List<byte> { 10, 20 };
var result = list.ToDouble();
Assert.Equal([10, 20], result);
}
[Fact]
public void ToDouble_ByteList_Null_ReturnsNull() => Assert.Null(((List<byte>)null!).ToDouble());
[Fact]
public void ToDouble_IntArray_ReturnsDoubleArray()
{
int[] arr = [-5, 0, 7];
var result = arr.ToDouble();
Assert.Equal(new double[] { -5, 0, 7 }, result);
}
[Fact]
public void ToDouble_IntList_ReturnsDoubleList()
{
var list = new List<int> { -5, 0, 7 };
var result = list.ToDouble();
Assert.Equal([-5, 0, 7], result);
}
#endregion
#region Array and List conversions (nullable)
[Fact]
public void ToDouble_NullableIntArray_ReturnsNullableDoubleArray()
{
int?[] arr = [1, null, 3];
var result = arr.ToDouble();
Assert.Equal(3, result.Length);
Assert.Equal(1.0, result[0]);
Assert.Null(result[1]);
Assert.Equal(3.0, result[2]);
}
[Fact]
public void ToDouble_NullableIntArray_Null_ReturnsNull() => Assert.Null(((int?[])null!).ToDouble());
[Fact]
public void ToDouble_NullableIntList_ReturnsNullableDoubleList()
{
var list = new List<int?> { 1, null, 3 };
var result = list.ToDouble();
Assert.Equal(3, result.Count);
Assert.Equal(1.0, result[0]);
Assert.Null(result[1]);
Assert.Equal(3.0, result[2]);
}
[Fact]
public void ToDouble_NullableIntList_Null_ReturnsNull() => Assert.Null(((List<int?>)null!).ToDouble());
#endregion
#region IReadOnlyCollection<T> -> Span<double>
[Fact]
public void ToDouble_IReadOnlyCollectionByte_Span_Works()
{
byte[] source = [1, 2];
Span<double> dest = new double[source.Length];
((IReadOnlyCollection<byte>)source).ToDouble(dest);
Assert.Equal(1.0, dest[0]);
Assert.Equal(2.0, dest[1]);
}
[Fact]
public void ToDouble_IReadOnlyCollectionByte_EmptySpan_Works()
{
byte[] source = [];
Span<double> dest = [];
((IReadOnlyCollection<byte>)source).ToDouble(dest);
}
[Fact]
public void ToDouble_IReadOnlyCollectionByte_DestinationTooShort_Throws()
{
byte[] source = [1, 2];
Assert.Throws<ArgumentException>(() =>
{
Span<double> dest = new double[1];
((IReadOnlyCollection<byte>)source).ToDouble(dest);
});
}
[Fact]
public void ToDouble_IReadOnlyCollectionNullableInt_Span_HandlesNulls()
{
int?[] source = [1, null, 3];
Span<double?> dest = new double?[3];
((IReadOnlyCollection<int?>)source).ToDouble(dest);
Assert.Equal(1.0, dest[0]);
Assert.Null(dest[1]);
Assert.Equal(3.0, dest[2]);
}
#endregion
#region Span conversions (ToDoubleCore) - через массивы
[Fact]
public void IntSpan_ToDouble_ConversionWorks()
{
int[] source = [1, 2, 3];
var result = source.ToDouble();
Assert.Equal(new double[] { 1, 2, 3 }, result);
}
[Fact]
public void FloatSpan_ToDouble_ConversionWorks()
{
float[] source = [1.1f, -2.2f];
var result = source.ToDouble();
Assert.Equal(1.1f, result[0], Tolerance);
Assert.Equal(-2.2f, result[1], Tolerance);
}
[Fact]
public void NullableDecimalSpan_ToDouble_HandlesNulls()
{
decimal?[] source = [1.5m, null, -3.3m];
var result = source.ToDouble();
Assert.Equal(3, result.Length);
Assert.Equal(1.5, result[0]!.Value, Tolerance);
Assert.Null(result[1]);
Assert.Equal(-3.3, result[2]!.Value, Tolerance);
}
#endregion
#region Edge cases
[Fact]
public void ToDouble_LongMaxValue_DoesNotOverflow()
{
long max = long.MaxValue;
double result = max.ToDouble();
Assert.Equal((double)max, result, Tolerance);
}
[Fact]
public void ToDouble_ULongMaxValue_DoesNotOverflow()
{
ulong max = ulong.MaxValue;
double result = max.ToDouble();
Assert.Equal((double)max, result, Tolerance);
}
[Fact]
public void ToDouble_Decimal_HighPrecision_DoesNotCrash()
{
decimal huge = decimal.MaxValue;
var result = huge.ToDouble();
Assert.False(double.IsInfinity(result));
}
#endregion
}
}