Skip to content

Commit aa42771

Browse files
committed
add tests for value calculation
1 parent d6c8897 commit aa42771

1 file changed

Lines changed: 256 additions & 0 deletions

File tree

Lines changed: 256 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,256 @@
1+

2+
namespace FTMS.NET.Utils.UnitTests;
3+
4+
/// <summary>
5+
/// Unit tests for the <see cref="ValueCalculation"/> record's Calculate method.
6+
/// </summary>
7+
public partial class ValueCalculationTests
8+
{
9+
/// <summary>
10+
/// Tests that Calculate returns the correct result with default parameters (multiplier=1, exponents=0).
11+
/// The constant multiplier should be 1, so the result should equal the raw value.
12+
/// </summary>
13+
[Theory]
14+
[InlineData(0L, 0.0)]
15+
[InlineData(1L, 1.0)]
16+
[InlineData(-1L, -1.0)]
17+
[InlineData(100L, 100.0)]
18+
[InlineData(-100L, -100.0)]
19+
[InlineData(long.MaxValue, 9223372036854775807.0)]
20+
[InlineData(long.MinValue, -9223372036854775808.0)]
21+
public void Calculate_WithDefaultParameters_ReturnsRawValue(long rawValue, double expected)
22+
{
23+
// Arrange
24+
var calculation = new ValueCalculation();
25+
26+
// Act
27+
double result = calculation.Calculate(rawValue);
28+
29+
// Assert
30+
Assert.Equal(expected, result);
31+
}
32+
33+
/// <summary>
34+
/// Tests that Calculate returns zero when the raw value is zero, regardless of the multiplier.
35+
/// </summary>
36+
[Theory]
37+
[InlineData(1, 0, 0)]
38+
[InlineData(5, 0, 0)]
39+
[InlineData(-5, 0, 0)]
40+
[InlineData(100, 2, 3)]
41+
[InlineData(int.MaxValue, 10, 10)]
42+
public void Calculate_WithZeroRawValue_ReturnsZero(int multiplier, int decimalExponent, int binaryExponent)
43+
{
44+
// Arrange
45+
var calculation = new ValueCalculation(multiplier, decimalExponent, binaryExponent);
46+
47+
// Act
48+
double result = calculation.Calculate(0L);
49+
50+
// Assert
51+
Assert.Equal(0.0, result);
52+
}
53+
54+
/// <summary>
55+
/// Tests that Calculate correctly applies the multiplier to the raw value.
56+
/// With decimal and binary exponents at 0, the constant multiplier equals the multiplier parameter.
57+
/// </summary>
58+
[Theory]
59+
[InlineData(2, 10L, 20.0)]
60+
[InlineData(5, 3L, 15.0)]
61+
[InlineData(-2, 10L, -20.0)]
62+
[InlineData(-3, -5L, 15.0)]
63+
[InlineData(0, 100L, 0.0)]
64+
[InlineData(1, long.MaxValue, 9223372036854775807.0)]
65+
[InlineData(10, 100L, 1000.0)]
66+
public void Calculate_WithMultiplier_ReturnsScaledValue(int multiplier, long rawValue, double expected)
67+
{
68+
// Arrange
69+
var calculation = new ValueCalculation(Multiplier: multiplier, DecimalExponent: 0, BinaryExponent: 0);
70+
71+
// Act
72+
double result = calculation.Calculate(rawValue);
73+
74+
// Assert
75+
Assert.Equal(expected, result);
76+
}
77+
78+
/// <summary>
79+
/// Tests that Calculate correctly applies the decimal exponent (power of 10).
80+
/// The constant multiplier should be multiplied by 10^decimalExponent.
81+
/// </summary>
82+
[Theory]
83+
[InlineData(1, 2, 0, 5L, 500.0)] // 5 * (1 * 10^2 * 2^0) = 5 * 100 = 500
84+
[InlineData(1, 3, 0, 2L, 2000.0)] // 2 * (1 * 10^3 * 2^0) = 2 * 1000 = 2000
85+
[InlineData(1, -2, 0, 100L, 1.0)] // 100 * (1 * 10^-2 * 2^0) = 100 * 0.01 = 1
86+
[InlineData(2, 1, 0, 5L, 100.0)] // 5 * (2 * 10^1 * 2^0) = 5 * 20 = 100
87+
[InlineData(1, 0, 0, 10L, 10.0)] // 10 * (1 * 10^0 * 2^0) = 10 * 1 = 10
88+
public void Calculate_WithDecimalExponent_ReturnsCorrectValue(int multiplier, int decimalExponent, int binaryExponent, long rawValue, double expected)
89+
{
90+
// Arrange
91+
var calculation = new ValueCalculation(multiplier, decimalExponent, binaryExponent);
92+
93+
// Act
94+
double result = calculation.Calculate(rawValue);
95+
96+
// Assert
97+
Assert.Equal(expected, result);
98+
}
99+
100+
/// <summary>
101+
/// Tests that Calculate correctly applies the binary exponent (power of 2).
102+
/// The constant multiplier should be multiplied by 2^binaryExponent.
103+
/// </summary>
104+
[Theory]
105+
[InlineData(1, 0, 3, 5L, 40.0)] // 5 * (1 * 10^0 * 2^3) = 5 * 8 = 40
106+
[InlineData(1, 0, 4, 2L, 32.0)] // 2 * (1 * 10^0 * 2^4) = 2 * 16 = 32
107+
[InlineData(1, 0, -2, 16L, 4.0)] // 16 * (1 * 10^0 * 2^-2) = 16 * 0.25 = 4
108+
[InlineData(2, 0, 2, 5L, 40.0)] // 5 * (2 * 10^0 * 2^2) = 5 * 8 = 40
109+
[InlineData(1, 0, 0, 10L, 10.0)] // 10 * (1 * 10^0 * 2^0) = 10 * 1 = 10
110+
public void Calculate_WithBinaryExponent_ReturnsCorrectValue(int multiplier, int decimalExponent, int binaryExponent, long rawValue, double expected)
111+
{
112+
// Arrange
113+
var calculation = new ValueCalculation(multiplier, decimalExponent, binaryExponent);
114+
115+
// Act
116+
double result = calculation.Calculate(rawValue);
117+
118+
// Assert
119+
Assert.Equal(expected, result);
120+
}
121+
122+
/// <summary>
123+
/// Tests that Calculate correctly combines all three parameters (multiplier, decimal exponent, binary exponent).
124+
/// </summary>
125+
[Theory]
126+
[InlineData(2, 1, 2, 5L, 400.0)] // 5 * (2 * 10^1 * 2^2) = 5 * (2 * 10 * 4) = 5 * 80 = 400
127+
[InlineData(3, 2, 3, 1L, 2400.0)] // 1 * (3 * 10^2 * 2^3) = 3 * 100 * 8 = 2400
128+
[InlineData(5, -1, 1, 10L, 10.0)] // 10 * (5 * 10^-1 * 2^1) = 10 * (0.5 * 2) = 10 * 1 = 10
129+
[InlineData(1, 1, 1, 50L, 1000.0)] // 50 * (1 * 10^1 * 2^1) = 50 * 20 = 1000
130+
[InlineData(-2, 1, 1, 5L, -200.0)] // 5 * (-2 * 10^1 * 2^1) = 5 * (-40) = -200
131+
public void Calculate_WithCombinedParameters_ReturnsCorrectValue(int multiplier, int decimalExponent, int binaryExponent, long rawValue, double expected)
132+
{
133+
// Arrange
134+
var calculation = new ValueCalculation(multiplier, decimalExponent, binaryExponent);
135+
136+
// Act
137+
double result = calculation.Calculate(rawValue);
138+
139+
// Assert
140+
Assert.Equal(expected, result);
141+
}
142+
143+
/// <summary>
144+
/// Tests that Calculate handles negative raw values correctly.
145+
/// The sign of the raw value should be preserved in the result.
146+
/// </summary>
147+
[Theory]
148+
[InlineData(1, 0, 0, -10L, -10.0)]
149+
[InlineData(2, 0, 0, -5L, -10.0)]
150+
[InlineData(1, 2, 0, -1L, -100.0)]
151+
[InlineData(-2, 0, 0, -10L, 20.0)] // Negative multiplier with negative rawValue = positive
152+
[InlineData(5, 1, 1, -2L, -200.0)]
153+
public void Calculate_WithNegativeRawValue_ReturnsCorrectSignedResult(int multiplier, int decimalExponent, int binaryExponent, long rawValue, double expected)
154+
{
155+
// Arrange
156+
var calculation = new ValueCalculation(multiplier, decimalExponent, binaryExponent);
157+
158+
// Act
159+
double result = calculation.Calculate(rawValue);
160+
161+
// Assert
162+
Assert.Equal(expected, result);
163+
}
164+
165+
/// <summary>
166+
/// Tests that Calculate handles extreme raw values (long.MinValue and long.MaxValue) correctly.
167+
/// These tests verify that the calculation doesn't cause unexpected overflow behavior.
168+
/// </summary>
169+
[Theory]
170+
[InlineData(2, 0, 0, long.MaxValue, 1.8446744073709552E+19)] // long.MaxValue * 2
171+
[InlineData(2, 0, 0, long.MinValue, -1.8446744073709552E+19)] // long.MinValue * 2
172+
[InlineData(1, 1, 0, long.MaxValue, 9.223372036854776E+19)] // long.MaxValue * 10
173+
[InlineData(1, -10, 0, long.MaxValue, 922337203.6854776)] // long.MaxValue * 10^-10
174+
public void Calculate_WithExtremeRawValues_ReturnsCorrectValue(int multiplier, int decimalExponent, int binaryExponent, long rawValue, double expected)
175+
{
176+
// Arrange
177+
var calculation = new ValueCalculation(multiplier, decimalExponent, binaryExponent);
178+
179+
// Act
180+
double result = calculation.Calculate(rawValue);
181+
182+
// Assert
183+
Assert.Equal(expected, result, precision: 10);
184+
}
185+
186+
/// <summary>
187+
/// Tests that Calculate can produce positive infinity when the result exceeds double's maximum value.
188+
/// </summary>
189+
[Fact]
190+
public void Calculate_WithVeryLargeMultiplier_ReturnsPositiveInfinity()
191+
{
192+
// Arrange
193+
var calculation = new ValueCalculation(Multiplier: 1, DecimalExponent: 300, BinaryExponent: 10);
194+
195+
// Act
196+
double result = calculation.Calculate(long.MaxValue);
197+
198+
// Assert
199+
Assert.Equal(double.PositiveInfinity, result);
200+
}
201+
202+
/// <summary>
203+
/// Tests that Calculate can produce negative infinity when the result is below double's minimum value.
204+
/// </summary>
205+
[Fact]
206+
public void Calculate_WithVeryLargeMultiplierAndNegativeValue_ReturnsNegativeInfinity()
207+
{
208+
// Arrange
209+
var calculation = new ValueCalculation(Multiplier: 1, DecimalExponent: 300, BinaryExponent: 10);
210+
211+
// Act
212+
double result = calculation.Calculate(long.MinValue);
213+
214+
// Assert
215+
Assert.Equal(double.NegativeInfinity, result);
216+
}
217+
218+
/// <summary>
219+
/// Tests that Calculate returns values very close to zero when using large negative exponents.
220+
/// </summary>
221+
[Theory]
222+
[InlineData(1, -300, 0, 100L)]
223+
[InlineData(1, 0, -1000, 100L)]
224+
[InlineData(1, -150, -150, 1000L)]
225+
public void Calculate_WithVerySmallMultiplier_ReturnsValueCloseToZero(int multiplier, int decimalExponent, int binaryExponent, long rawValue)
226+
{
227+
// Arrange
228+
var calculation = new ValueCalculation(multiplier, decimalExponent, binaryExponent);
229+
230+
// Act
231+
double result = calculation.Calculate(rawValue);
232+
233+
// Assert
234+
Assert.True(result >= 0.0 && result < 1e-100);
235+
}
236+
237+
/// <summary>
238+
/// Tests that Calculate with a zero multiplier always returns zero.
239+
/// </summary>
240+
[Theory]
241+
[InlineData(0, 0, 0, 100L)]
242+
[InlineData(0, 5, 3, long.MaxValue)]
243+
[InlineData(0, -5, -3, long.MinValue)]
244+
[InlineData(0, 10, 10, -1000L)]
245+
public void Calculate_WithZeroMultiplier_ReturnsZero(int multiplier, int decimalExponent, int binaryExponent, long rawValue)
246+
{
247+
// Arrange
248+
var calculation = new ValueCalculation(multiplier, decimalExponent, binaryExponent);
249+
250+
// Act
251+
double result = calculation.Calculate(rawValue);
252+
253+
// Assert
254+
Assert.Equal(0.0, result);
255+
}
256+
}

0 commit comments

Comments
 (0)