namespace QWERTYkez.Mensura.Tests { public class CollectionsMultiplyExtensionsTest { private const double Tolerance = 1e-12; private static readonly Length scalarUnit = Length.Meter; // 1000 mm private static readonly double scalarDouble = 2.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 = [5.0, 3.0]; private static readonly double?[] nullableDoubleArray = [5.0, null, 3.0]; private static readonly List doubleList = [5.0, 3.0]; private static readonly List nullableDoubleList = [5.0, null, 3.0]; // ====================== 1. T[] * double ====================== [Fact] public void Mul_TArray_Double_Returns_TArray() { var result = unitsArray.Mul(scalarDouble); Assert.Equal(2, result.Length); Assert.Equal(1000 * 2, (double)result[0], Tolerance); Assert.Equal(1 * 2, (double)result[1], Tolerance); } [Fact] public void Mul_TArray_Double_ByZero_Works() { var result = unitsArray.Mul(0.0); Assert.Equal(0, (double)result[0], Tolerance); Assert.Equal(0, (double)result[1], Tolerance); } // ====================== 2. T?[] * double ====================== [Fact] public void Mul_NullableTArray_Double_Returns_NullableTArray() { var result = nullableUnitsArray.Mul(scalarDouble); Assert.Equal(3, result.Length); Assert.Equal(1000 * 2, (double)result[0]!, Tolerance); Assert.Equal(0, (double)result[1]!, Tolerance); Assert.Equal(1 * 2, (double)result[2]!, Tolerance); } // ====================== 3. double * T[] ====================== [Fact] public void Mul_Double_TArray_Returns_TArray() { var result = scalarDouble.Mul(unitsArray); Assert.Equal(2, result.Length); Assert.Equal(2 * 1000, (double)result[0], Tolerance); Assert.Equal(2 * 1, (double)result[1], Tolerance); } // ====================== 4. double * T?[] ====================== [Fact] public void Mul_Double_NullableTArray_Returns_NullableTArray() { var result = scalarDouble.Mul(nullableUnitsArray); Assert.Equal(3, result.Length); Assert.Equal(2 * 1000, (double)result[0]!, Tolerance); Assert.Equal(0, (double)result[1]!, Tolerance); Assert.Equal(2 * 1, (double)result[2]!, Tolerance); } // ====================== 5. List * double ====================== [Fact] public void Mul_ListT_Double_Returns_ListT() { var result = unitsList.Mul(scalarDouble); Assert.Equal(2, result.Count); Assert.Equal(1000 * 2, (double)result[0], Tolerance); Assert.Equal(1 * 2, (double)result[1], Tolerance); } // ====================== 6. List * double ====================== [Fact] public void Mul_ListNullableT_Double_Returns_ListNullableT() { var result = nullableUnitsList.Mul(scalarDouble); Assert.Equal(3, result.Count); Assert.Equal(1000 * 2, (double)result[0]!, Tolerance); Assert.Equal(0, (double)result[1]!, Tolerance); Assert.Equal(1 * 2, (double)result[2]!, Tolerance); } // ====================== 7. double * List ====================== [Fact] public void Mul_Double_ListT_Returns_ListT() { var result = scalarDouble.Mul(unitsList); Assert.Equal(2, result.Count); Assert.Equal(2 * 1000, (double)result[0], Tolerance); Assert.Equal(2 * 1, (double)result[1], Tolerance); } // ====================== 8. double * List ====================== [Fact] public void Mul_Double_ListNullableT_Returns_ListNullableT() { var result = scalarDouble.Mul(nullableUnitsList); Assert.Equal(3, result.Count); Assert.Equal(2 * 1000, (double)result[0]!, Tolerance); Assert.Equal(0, (double)result[1]!, Tolerance); Assert.Equal(2 * 1, (double)result[2]!, Tolerance); } // ====================== 9. IReadOnlyCollection * double (Span) ====================== [Fact] public void Mul_IReadOnlyCollectionT_Double_Span() { Span dest = new Length[2]; ((IReadOnlyCollection)unitsArray).Mul(scalarDouble, dest); Assert.Equal(1000 * 2, (double)dest[0], Tolerance); Assert.Equal(1 * 2, (double)dest[1], Tolerance); } // ====================== 10. IReadOnlyCollection * double (Span) ====================== [Fact] public void Mul_IReadOnlyCollectionNullableT_Double_Span() { Span dest = new Length?[3]; ((IReadOnlyCollection)nullableUnitsArray).Mul(scalarDouble, dest); Assert.Equal(1000 * 2, (double)dest[0]!, Tolerance); Assert.Equal(0, (double)dest[1]!, Tolerance); Assert.Equal(1 * 2, (double)dest[2]!, Tolerance); } // ====================== 11. double * IReadOnlyCollection (Span) ====================== [Fact] public void Mul_Double_IReadOnlyCollectionT_Span() { Span dest = new Length[2]; scalarDouble.Mul((IReadOnlyCollection)unitsArray, dest); Assert.Equal(2 * 1000, (double)dest[0], Tolerance); Assert.Equal(2 * 1, (double)dest[1], Tolerance); } // ====================== 12. double * IReadOnlyCollection (Span) ====================== [Fact] public void Mul_Double_IReadOnlyCollectionNullableT_Span() { Span dest = new Length?[3]; scalarDouble.Mul((IReadOnlyCollection)nullableUnitsArray, dest); Assert.Equal(2 * 1000, (double)dest[0]!, Tolerance); Assert.Equal(0, (double)dest[1]!, Tolerance); Assert.Equal(2 * 1, (double)dest[2]!, Tolerance); } // ====================== 13. IEnumerable * double ====================== [Fact] public void Mul_IEnumerableT_Double_Returns_IEnumerableT() { var result = ((IEnumerable)unitsArray).Mul(scalarDouble).ToList(); Assert.Equal(2, result.Count); Assert.Equal(1000 * 2, (double)result[0], Tolerance); Assert.Equal(1 * 2, (double)result[1], Tolerance); } // ====================== 14. IEnumerable * double ====================== [Fact] public void Mul_IEnumerableNullableT_Double_Returns_IEnumerableNullableT() { var result = ((IEnumerable)nullableUnitsArray).Mul(scalarDouble).ToList(); Assert.Equal(3, result.Count); Assert.Equal(1000 * 2, (double)result[0]!, Tolerance); Assert.Equal(0, (double)result[1]!, Tolerance); Assert.Equal(1 * 2, (double)result[2]!, Tolerance); } // ====================== 15. double * IEnumerable ====================== [Fact] public void Mul_Double_IEnumerableT_Returns_IEnumerableT() { var result = scalarDouble.Mul((IEnumerable)unitsArray).ToList(); Assert.Equal(2, result.Count); Assert.Equal(2 * 1000, (double)result[0], Tolerance); Assert.Equal(2 * 1, (double)result[1], Tolerance); } // ====================== 16. double * IEnumerable ====================== [Fact] public void Mul_Double_IEnumerableNullableT_Returns_IEnumerableNullableT() { var result = scalarDouble.Mul((IEnumerable)nullableUnitsArray).ToList(); Assert.Equal(3, result.Count); Assert.Equal(2 * 1000, (double)result[0]!, Tolerance); Assert.Equal(0, (double)result[1]!, Tolerance); Assert.Equal(2 * 1, (double)result[2]!, Tolerance); } // ====================== 17. double[] * T ====================== [Fact] public void Mul_DoubleArray_T_Returns_TArray() { var result = doubleArray.Mul(scalarUnit); Assert.Equal(2, result.Length); Assert.Equal(5 * 1000, (double)result[0], Tolerance); Assert.Equal(3 * 1000, (double)result[1], Tolerance); } // ====================== 18. double?[] * T ====================== [Fact] public void Mul_NullableDoubleArray_T_Returns_NullableTArray() { var result = nullableDoubleArray.Mul(scalarUnit); Assert.Equal(3, result.Length); Assert.Equal(5 * 1000, (double)result[0]!, Tolerance); Assert.Equal(0, (double)result[1]!, Tolerance); Assert.Equal(3 * 1000, (double)result[2]!, Tolerance); } // ====================== 19. T * double[] ====================== [Fact] public void Mul_T_DoubleArray_Returns_TArray() { var result = scalarUnit.Mul(doubleArray); Assert.Equal(2, result.Length); Assert.Equal(1000 * 5, (double)result[0], Tolerance); Assert.Equal(1000 * 3, (double)result[1], Tolerance); } // ====================== 20. T * double?[] ====================== [Fact] public void Mul_T_NullableDoubleArray_Returns_NullableTArray() { var result = scalarUnit.Mul(nullableDoubleArray); Assert.Equal(3, result.Length); Assert.Equal(1000 * 5, (double)result[0]!, Tolerance); Assert.Equal(0, (double)result[1]!, Tolerance); Assert.Equal(1000 * 3, (double)result[2]!, Tolerance); } // ====================== 21. List * T ====================== [Fact] public void Mul_ListDouble_T_Returns_ListT() { var result = doubleList.Mul(scalarUnit); Assert.Equal(2, result.Count); Assert.Equal(5 * 1000, (double)result[0], Tolerance); Assert.Equal(3 * 1000, (double)result[1], Tolerance); } // ====================== 22. List * T ====================== [Fact] public void Mul_ListNullableDouble_T_Returns_ListNullableT() { var result = nullableDoubleList.Mul(scalarUnit); Assert.Equal(3, result.Count); Assert.Equal(5 * 1000, (double)result[0]!, Tolerance); Assert.Equal(0, (double)result[1]!, Tolerance); Assert.Equal(3 * 1000, (double)result[2]!, Tolerance); } // ====================== 23. T * List ====================== [Fact] public void Mul_T_ListDouble_Returns_ListT() { var result = scalarUnit.Mul(doubleList); Assert.Equal(2, result.Count); Assert.Equal(1000 * 5, (double)result[0], Tolerance); Assert.Equal(1000 * 3, (double)result[1], Tolerance); } // ====================== 24. T * List ====================== [Fact] public void Mul_T_ListNullableDouble_Returns_ListNullableT() { var result = scalarUnit.Mul(nullableDoubleList); Assert.Equal(3, result.Count); Assert.Equal(1000 * 5, (double)result[0]!, Tolerance); Assert.Equal(0, (double)result[1]!, Tolerance); Assert.Equal(1000 * 3, (double)result[2]!, Tolerance); } // ====================== 25. T * T[] -> double[] ====================== [Fact] public void Mul_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 Mul_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 Mul_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 Mul_NullArray_ReturnsNull() { Length[] nullArray = null!; var result = nullArray.Mul(5.0); Assert.Null(result); } [Fact] public void Mul_NullList_ReturnsNull() { List nullList = null!; var result = nullList.Mul(5.0); Assert.Null(result); } [Fact] public void Mul_EmptyArray_ReturnsEmptyArray() { var empty = Array.Empty(); var result = empty.Mul(5.0); Assert.Empty(result); } } }