using System; using System.Collections.Generic; using System.Linq; using QWERTYkez.Mensura.Units; using QWERTYkez.Mensura.Extensions; using Xunit; namespace QWERTYkez.Mensura.Tests { public class CollectionsPlusExtensionsTests { private const double Tolerance = 1e-12; private static readonly Length scalarUnit = Length.Meter; // 1000 mm private static readonly double scalarDouble = 500.0; // прибавляемое значение в мм // Коллекции единиц private static readonly Length[] unitsArray = new[] { Length.Meter, Length._MilliMeter }; private static readonly Length?[] nullableUnitsArray = new Length?[] { Length.Meter, null, Length._MilliMeter }; private static readonly List unitsList = new List { Length.Meter, Length._MilliMeter }; private static readonly List nullableUnitsList = new List { Length.Meter, null, Length._MilliMeter }; // Коллекции double private static readonly double[] doubleArray = new double[] { 200.0, 300.0 }; private static readonly double?[] nullableDoubleArray = new double?[] { 200.0, null, 300.0 }; private static readonly List doubleList = new List { 200.0, 300.0 }; private static readonly List nullableDoubleList = new List { 200.0, null, 300.0 }; // ====================== 1. T[] + double ====================== [Fact] public void Plus_TArray_Double_Returns_TArray() { var result = unitsArray.Plus(scalarDouble); Assert.Equal(2, result.Length); Assert.Equal(1000 + 500, (double)result[0], Tolerance); Assert.Equal(1 + 500, (double)result[1], Tolerance); } // ====================== 2. T?[] + double ====================== [Fact] public void Plus_NullableTArray_Double_Returns_NullableTArray() { var result = nullableUnitsArray.Plus(scalarDouble); Assert.Equal(3, result.Length); Assert.Equal(1000 + 500, (double)result[0]!, Tolerance); Assert.Null(result[1]); // null + число = null Assert.Equal(1 + 500, (double)result[2]!, Tolerance); } // ====================== 3. double + T[] ====================== [Fact] public void Plus_Double_TArray_Returns_TArray() { var result = scalarDouble.Plus(unitsArray); Assert.Equal(2, result.Length); Assert.Equal(500 + 1000, (double)result[0], Tolerance); Assert.Equal(500 + 1, (double)result[1], Tolerance); } // ====================== 4. double + T?[] ====================== [Fact] public void Plus_Double_NullableTArray_Returns_NullableTArray() { var result = scalarDouble.Plus(nullableUnitsArray); Assert.Equal(3, result.Length); Assert.Equal(500 + 1000, (double)result[0]!, Tolerance); Assert.Null(result[1]); // число + null = null Assert.Equal(500 + 1, (double)result[2]!, Tolerance); } // ====================== 5. List + double ====================== [Fact] public void Plus_ListT_Double_Returns_ListT() { var result = unitsList.Plus(scalarDouble); Assert.Equal(2, result.Count); Assert.Equal(1000 + 500, (double)result[0], Tolerance); Assert.Equal(1 + 500, (double)result[1], Tolerance); } // ====================== 6. List + double ====================== [Fact] public void Plus_ListNullableT_Double_Returns_ListNullableT() { var result = nullableUnitsList.Plus(scalarDouble); Assert.Equal(3, result.Count); Assert.Equal(1000 + 500, (double)result[0]!, Tolerance); Assert.Null(result[1]); // null + число = null Assert.Equal(1 + 500, (double)result[2]!, Tolerance); } // ====================== 7. double + List ====================== [Fact] public void Plus_Double_ListT_Returns_ListT() { var result = scalarDouble.Plus(unitsList); Assert.Equal(2, result.Count); Assert.Equal(500 + 1000, (double)result[0], Tolerance); Assert.Equal(500 + 1, (double)result[1], Tolerance); } // ====================== 8. double + List ====================== [Fact] public void Plus_Double_ListNullableT_Returns_ListNullableT() { var result = scalarDouble.Plus(nullableUnitsList); Assert.Equal(3, result.Count); Assert.Equal(500 + 1000, (double)result[0]!, Tolerance); Assert.Null(result[1]); // число + null = null Assert.Equal(500 + 1, (double)result[2]!, Tolerance); } // ====================== 9. IReadOnlyCollection + double (Span) ====================== [Fact] public void Plus_IReadOnlyCollectionT_Double_Span() { Span dest = new Length[2]; ((IReadOnlyCollection)unitsArray).Plus(scalarDouble, dest); Assert.Equal(1000 + 500, (double)dest[0], Tolerance); Assert.Equal(1 + 500, (double)dest[1], Tolerance); } // ====================== 10. IReadOnlyCollection + double (Span) ====================== [Fact] public void Plus_IReadOnlyCollectionNullableT_Double_Span() { Span dest = new Length?[3]; ((IReadOnlyCollection)nullableUnitsArray).Plus(scalarDouble, dest); Assert.Equal(1000 + 500, (double)dest[0]!, Tolerance); Assert.Null(dest[1]); // null + число = null Assert.Equal(1 + 500, (double)dest[2]!, Tolerance); } // ====================== 11. double + IReadOnlyCollection (Span) ====================== [Fact] public void Plus_Double_IReadOnlyCollectionT_Span() { Span dest = new Length[2]; scalarDouble.Plus((IReadOnlyCollection)unitsArray, dest); Assert.Equal(500 + 1000, (double)dest[0], Tolerance); Assert.Equal(500 + 1, (double)dest[1], Tolerance); } // ====================== 12. double + IReadOnlyCollection (Span) ====================== [Fact] public void Plus_Double_IReadOnlyCollectionNullableT_Span() { Span dest = new Length?[3]; scalarDouble.Plus((IReadOnlyCollection)nullableUnitsArray, dest); Assert.Equal(500 + 1000, (double)dest[0]!, Tolerance); Assert.Null(dest[1]); // число + null = null Assert.Equal(500 + 1, (double)dest[2]!, Tolerance); } // ====================== 13. IEnumerable + double ====================== [Fact] public void Plus_IEnumerableT_Double_Returns_IEnumerableT() { var result = ((IEnumerable)unitsArray).Plus(scalarDouble).ToList(); Assert.Equal(2, result.Count); Assert.Equal(1000 + 500, (double)result[0], Tolerance); Assert.Equal(1 + 500, (double)result[1], Tolerance); } // ====================== 14. IEnumerable + double ====================== [Fact] public void Plus_IEnumerableNullableT_Double_Returns_IEnumerableNullableT() { var result = ((IEnumerable)nullableUnitsArray).Plus(scalarDouble).ToList(); Assert.Equal(3, result.Count); Assert.Equal(1000 + 500, (double)result[0]!, Tolerance); Assert.Null(result[1]); // null + число = null Assert.Equal(1 + 500, (double)result[2]!, Tolerance); } // ====================== 15. double + IEnumerable ====================== [Fact] public void Plus_Double_IEnumerableT_Returns_IEnumerableT() { var result = scalarDouble.Plus((IEnumerable)unitsArray).ToList(); Assert.Equal(2, result.Count); Assert.Equal(500 + 1000, (double)result[0], Tolerance); Assert.Equal(500 + 1, (double)result[1], Tolerance); } // ====================== 16. double + IEnumerable ====================== [Fact] public void Plus_Double_IEnumerableNullableT_Returns_IEnumerableNullableT() { var result = scalarDouble.Plus((IEnumerable)nullableUnitsArray).ToList(); Assert.Equal(3, result.Count); Assert.Equal(500 + 1000, (double)result[0]!, Tolerance); Assert.Null(result[1]); // число + null = null Assert.Equal(500 + 1, (double)result[2]!, Tolerance); } // ====================== 17. double[] + T ====================== [Fact] public void Plus_DoubleArray_T_Returns_TArray() { var result = doubleArray.Plus(scalarUnit); Assert.Equal(2, result.Length); Assert.Equal(200 + 1000, (double)result[0], Tolerance); Assert.Equal(300 + 1000, (double)result[1], Tolerance); } // ====================== 18. double?[] + T ====================== [Fact] public void Plus_NullableDoubleArray_T_Returns_NullableTArray() { 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(300 + 1000, (double)result[2]!, Tolerance); } // ====================== 19. T + double[] ====================== [Fact] public void Plus_T_DoubleArray_Returns_TArray() { var result = scalarUnit.Plus(doubleArray); Assert.Equal(2, result.Length); Assert.Equal(1000 + 200, (double)result[0], Tolerance); Assert.Equal(1000 + 300, (double)result[1], Tolerance); } // ====================== 20. T + double?[] ====================== [Fact] public void Plus_T_NullableDoubleArray_Returns_NullableTArray() { 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 + 300, (double)result[2]!, Tolerance); } // ====================== 21. List + T ====================== [Fact] public void Plus_ListDouble_T_Returns_ListT() { var result = doubleList.Plus(scalarUnit); Assert.Equal(2, result.Count); Assert.Equal(200 + 1000, (double)result[0], Tolerance); Assert.Equal(300 + 1000, (double)result[1], Tolerance); } // ====================== 22. List + T ====================== [Fact] public void Plus_ListNullableDouble_T_Returns_ListNullableT() { 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(300 + 1000, (double)result[2]!, Tolerance); } // ====================== 23. T + List ====================== [Fact] public void Plus_T_ListDouble_Returns_ListT() { var result = scalarUnit.Plus(doubleList); Assert.Equal(2, result.Count); Assert.Equal(1000 + 200, (double)result[0], Tolerance); Assert.Equal(1000 + 300, (double)result[1], Tolerance); } // ====================== 24. T + List ====================== [Fact] public void Plus_T_ListNullableDouble_Returns_ListNullableT() { 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 + 300, (double)result[2]!, Tolerance); } // ====================== 25. T + T[] -> double[] ====================== [Fact] public void Plus_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) [Fact] public void Plus_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 Plus_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); } // ====================== Обработка null коллекций ====================== [Fact] public void Plus_NullArray_ReturnsNull() { Length[] nullArray = null; var result = nullArray.Plus(5.0); Assert.Null(result); } [Fact] public void Plus_NullList_ReturnsNull() { List nullList = null; var result = nullList.Plus(5.0); Assert.Null(result); } [Fact] public void Plus_EmptyArray_ReturnsEmptyArray() { var empty = Array.Empty(); var result = empty.Plus(5.0); Assert.Empty(result); } } }