namespace QWERTYkez.Mensura.Tests { public class CollectionsMinusExtensionsTest { private const double Tolerance = 1e-12; private static readonly Length scalarUnit = Length.Meter; // 1000 mm private static readonly double scalarDouble = 1000.0; // уменьшаемое/вычитаемое в мм // Коллекции единиц private static readonly Length[] unitsArray = [Length.Meter, Length._MilliMeter]; private static readonly Length?[] nullableUnitsArray = [Length.Meter, null, Length._MilliMeter]; private static readonly List unitsList = [Length.Meter, Length._MilliMeter]; private static readonly List nullableUnitsList = [Length.Meter, null, Length._MilliMeter]; // Коллекции double private static readonly double[] doubleArray = [500.0, 200.0]; // мм private static readonly double?[] nullableDoubleArray = [500.0, null, 200.0]; private static readonly List doubleList = [500.0, 200.0]; private static readonly List nullableDoubleList = [500.0, null, 200.0]; // ====================== 1. T[] - double (результат T[]) ====================== [Fact] public void Minus_TArray_Double_Returns_TArray() { // units - subtrahend var result = unitsArray.Minus(scalarDouble); Assert.Equal(2, result.Length); Assert.Equal(1000 - 1000, (double)result[0], Tolerance); Assert.Equal(1 - 1000, (double)result[1], Tolerance); } [Fact] public void Minus_TArray_Double_ByZero_Works() { var result = unitsArray.Minus(0.0); Assert.Equal(1000, (double)result[0], Tolerance); Assert.Equal(1, (double)result[1], Tolerance); } // ====================== 2. T?[] - double (результат T?[]) ====================== [Fact] public void Minus_NullableTArray_Double_Returns_NullableTArray() { var result = nullableUnitsArray.Minus(scalarDouble); Assert.Equal(3, result.Length); Assert.Equal(1000 - 1000, (double)result[0]!, Tolerance); Assert.Equal(0 - 1000, (double)result[1]!, Tolerance); Assert.Equal(1 - 1000, (double)result[2]!, Tolerance); } // ====================== 3. double - T[] (результат T[]) ====================== [Fact] public void Minus_Double_TArray_Returns_TArray() { var result = scalarDouble.Minus(unitsArray); Assert.Equal(2, result.Length); Assert.Equal(1000 - 1000, (double)result[0], Tolerance); Assert.Equal(1000 - 1, (double)result[1], Tolerance); } // ====================== 4. double - T?[] (результат T?[]) ====================== [Fact] public void Minus_Double_NullableTArray_Returns_NullableTArray() { var result = scalarDouble.Minus(nullableUnitsArray); Assert.Equal(3, result.Length); Assert.Equal(1000 - 1000, (double)result[0]!, Tolerance); Assert.Equal(1000 - 0, (double)result[1]!, Tolerance); Assert.Equal(1000 - 1, (double)result[2]!, Tolerance); } // ====================== 5. List - double ====================== [Fact] public void Minus_ListT_Double_Returns_ListT() { var result = unitsList.Minus(scalarDouble); Assert.Equal(2, result.Count); Assert.Equal(1000 - 1000, (double)result[0], Tolerance); Assert.Equal(1 - 1000, (double)result[1], Tolerance); } // ====================== 6. List - double ====================== [Fact] public void Minus_ListNullableT_Double_Returns_ListNullableT() { var result = nullableUnitsList.Minus(scalarDouble); Assert.Equal(3, result.Count); Assert.Equal(1000 - 1000, (double)result[0]!, Tolerance); Assert.Equal(0 - 1000, (double)result[1]!, Tolerance); Assert.Equal(1 - 1000, (double)result[2]!, Tolerance); } // ====================== 7. double - List ====================== [Fact] public void Minus_Double_ListT_Returns_ListT() { var result = scalarDouble.Minus(unitsList); Assert.Equal(2, result.Count); Assert.Equal(1000 - 1000, (double)result[0], Tolerance); Assert.Equal(1000 - 1, (double)result[1], Tolerance); } // ====================== 8. double - List ====================== [Fact] public void Minus_Double_ListNullableT_Returns_ListNullableT() { var result = scalarDouble.Minus(nullableUnitsList); Assert.Equal(3, result.Count); Assert.Equal(1000 - 1000, (double)result[0]!, Tolerance); Assert.Equal(1000 - 0, (double)result[1]!, Tolerance); Assert.Equal(1000 - 1, (double)result[2]!, Tolerance); } // ====================== 9. IReadOnlyCollection - double (Span) ====================== [Fact] public void Minus_IReadOnlyCollectionT_Double_Span() { Span dest = new Length[2]; ((IReadOnlyCollection)unitsArray).Minus(scalarDouble, dest); Assert.Equal(1000 - 1000, (double)dest[0], Tolerance); Assert.Equal(1 - 1000, (double)dest[1], Tolerance); } // ====================== 10. IReadOnlyCollection - double (Span) ====================== [Fact] public void Minus_IReadOnlyCollectionNullableT_Double_Span() { Span dest = new Length?[3]; ((IReadOnlyCollection)nullableUnitsArray).Minus(scalarDouble, dest); Assert.Equal(1000 - 1000, (double)dest[0]!, Tolerance); Assert.Equal(0 - 1000, (double)dest[1]!, Tolerance); Assert.Equal(1 - 1000, (double)dest[2]!, Tolerance); } // ====================== 11. double - IReadOnlyCollection (Span) ====================== [Fact] public void Minus_Double_IReadOnlyCollectionT_Span() { Span dest = new Length[2]; scalarDouble.Minus((IReadOnlyCollection)unitsArray, dest); Assert.Equal(1000 - 1000, (double)dest[0], Tolerance); Assert.Equal(1000 - 1, (double)dest[1], Tolerance); } // ====================== 12. double - IReadOnlyCollection (Span) ====================== [Fact] public void Minus_Double_IReadOnlyCollectionNullableT_Span() { Span dest = new Length?[3]; scalarDouble.Minus((IReadOnlyCollection)nullableUnitsArray, dest); Assert.Equal(1000 - 1000, (double)dest[0]!, Tolerance); Assert.Equal(1000 - 0, (double)dest[1]!, Tolerance); Assert.Equal(1000 - 1, (double)dest[2]!, Tolerance); } // ====================== 13. IEnumerable - double ====================== [Fact] public void Minus_IEnumerableT_Double_Returns_IEnumerableT() { var result = ((IEnumerable)unitsArray).Minus(scalarDouble).ToList(); Assert.Equal(2, result.Count); Assert.Equal(1000 - 1000, (double)result[0], Tolerance); Assert.Equal(1 - 1000, (double)result[1], Tolerance); } // ====================== 14. IEnumerable - double ====================== [Fact] public void Minus_IEnumerableNullableT_Double_Returns_IEnumerableNullableT() { var result = ((IEnumerable)nullableUnitsArray).Minus(scalarDouble).ToList(); Assert.Equal(3, result.Count); Assert.Equal(1000 - 1000, (double)result[0]!, Tolerance); Assert.Equal(0 - 1000, (double)result[1]!, Tolerance); Assert.Equal(1 - 1000, (double)result[2]!, Tolerance); } // ====================== 15. double - IEnumerable ====================== [Fact] public void Minus_Double_IEnumerableT_Returns_IEnumerableT() { var result = scalarDouble.Minus((IEnumerable)unitsArray).ToList(); Assert.Equal(2, result.Count); Assert.Equal(1000 - 1000, (double)result[0], Tolerance); Assert.Equal(1000 - 1, (double)result[1], Tolerance); } // ====================== 16. double - IEnumerable ====================== [Fact] public void Minus_Double_IEnumerableNullableT_Returns_IEnumerableNullableT() { var result = scalarDouble.Minus((IEnumerable)nullableUnitsArray).ToList(); Assert.Equal(3, result.Count); Assert.Equal(1000 - 1000, (double)result[0]!, Tolerance); Assert.Equal(1000 - 0, (double)result[1]!, Tolerance); Assert.Equal(1000 - 1, (double)result[2]!, Tolerance); } // ====================== 17. double[] - T ====================== [Fact] public void Minus_DoubleArray_T_Returns_TArray() { var result = doubleArray.Minus(scalarUnit); Assert.Equal(2, result.Length); Assert.Equal(500 - 1000, (double)result[0], Tolerance); Assert.Equal(200 - 1000, (double)result[1], Tolerance); } // ====================== 18. double?[] - T ====================== [Fact] public void Minus_NullableDoubleArray_T_Returns_NullableTArray() { var result = nullableDoubleArray.Minus(scalarUnit); Assert.Equal(3, result.Length); Assert.Equal(500 - 1000, (double)result[0]!, Tolerance); Assert.Equal(0 - 1000, (double)result[1]!, Tolerance); Assert.Equal(200 - 1000, (double)result[2]!, Tolerance); } // ====================== 19. T - double[] ====================== [Fact] public void Minus_T_DoubleArray_Returns_TArray() { var result = scalarUnit.Minus(doubleArray); Assert.Equal(2, result.Length); Assert.Equal(1000 - 500, (double)result[0], Tolerance); Assert.Equal(1000 - 200, (double)result[1], Tolerance); } // ====================== 20. T - double?[] ====================== [Fact] public void Minus_T_NullableDoubleArray_Returns_NullableTArray() { var result = scalarUnit.Minus(nullableDoubleArray); Assert.Equal(3, result.Length); Assert.Equal(1000 - 500, (double)result[0]!, Tolerance); Assert.Equal(1000 - 0, (double)result[1]!, Tolerance); Assert.Equal(1000 - 200, (double)result[2]!, Tolerance); } // ====================== 21. List - T ====================== [Fact] public void Minus_ListDouble_T_Returns_ListT() { var result = doubleList.Minus(scalarUnit); Assert.Equal(2, result.Count); Assert.Equal(500 - 1000, (double)result[0], Tolerance); Assert.Equal(200 - 1000, (double)result[1], Tolerance); } // ====================== 22. List - T ====================== [Fact] public void Minus_ListNullableDouble_T_Returns_ListNullableT() { var result = nullableDoubleList.Minus(scalarUnit); Assert.Equal(3, result.Count); Assert.Equal(500 - 1000, (double)result[0]!, Tolerance); Assert.Equal(0 - 1000, (double)result[1]!, Tolerance); Assert.Equal(200 - 1000, (double)result[2]!, Tolerance); } // ====================== 23. T - List ====================== [Fact] public void Minus_T_ListDouble_Returns_ListT() { var result = scalarUnit.Minus(doubleList); Assert.Equal(2, result.Count); Assert.Equal(1000 - 500, (double)result[0], Tolerance); Assert.Equal(1000 - 200, (double)result[1], Tolerance); } // ====================== 24. T - List ====================== [Fact] public void Minus_T_ListNullableDouble_Returns_ListNullableT() { var result = scalarUnit.Minus(nullableDoubleList); Assert.Equal(3, result.Count); Assert.Equal(1000 - 500, (double)result[0]!, Tolerance); Assert.Equal(1000 - 0, (double)result[1]!, Tolerance); Assert.Equal(1000 - 200, (double)result[2]!, Tolerance); } // ====================== 25. T - T[] -> double[] ====================== [Fact] public void Minus_T_TArray_Returns_DoubleArray() { var result = scalarUnit - unitsArray; Assert.Equal(2, result.Length); Assert.Equal(1000 - 1000, result[0]._Value, Tolerance); Assert.Equal(1000 - 1, result[1]._Value, Tolerance); } // Дополнительно: перегрузки, где результат double (без указания R) // Тестируем Minus(T[] units, T subtrahend) – возвращает double[] [Fact] public void Minus_TArray_T_Returns_DoubleArray() { var result = unitsArray - scalarUnit; Assert.Equal(2, result.Length); Assert.Equal(1000 - 1000, result[0]._Value, Tolerance); Assert.Equal(1 - 1000, result[1]._Value, Tolerance); } [Fact] public void Minus_ListT_T_Returns_DoubleList() { var result = unitsList - scalarUnit; Assert.Equal(2, result.Count); Assert.Equal(1000 - 1000, result[0]._Value, Tolerance); Assert.Equal(1 - 1000, result[1]._Value, Tolerance); } // Проверка пустых коллекций [Fact] public void Minus_EmptyArray_ReturnsEmptyArray() { var empty = Array.Empty(); var result = empty.Minus(5.0); Assert.Empty(result); } [Fact] public void Minus_NullArray_ReturnsNull() { Length[] nullArray = null!; var result = nullArray.Minus(5.0); Assert.Null(result); } [Fact] public void Minus_NullList_ReturnsNull() { List nullList = null!; var result = nullList.Minus(5.0); Assert.Null(result); } } }