1+ namespace Atc . Kusto . Tests . Extensions ;
2+
3+ public sealed class SqlDecimalExtensionsTests
4+ {
5+ [ Theory ]
6+ [ InlineData ( 123.45 ) ]
7+ [ InlineData ( 0 ) ]
8+ [ InlineData ( - 456.78 ) ]
9+ [ InlineData ( 999999999.99 ) ]
10+ [ InlineData ( 0.01 ) ]
11+ [ InlineData ( 0.001 ) ]
12+ [ InlineData ( 0.0001 ) ]
13+ public void ToDecimal_Should_Convert_Values_Correctly ( decimal value )
14+ {
15+ // Arrange
16+ var sqlDecimal = new SqlDecimal ( value ) ;
17+
18+ // Act
19+ var result = sqlDecimal . ToDecimal ( ) ;
20+
21+ // Assert
22+ result . Should ( ) . Be ( value ) ;
23+ }
24+
25+ [ Fact ]
26+ public void ToDecimal_Should_Handle_Maximum_Precision_Within_Limits ( )
27+ {
28+ // Arrange - Create a SqlDecimal with 28 digits precision, 10 scale (within .NET limits)
29+ var sqlDecimal = new SqlDecimal ( 28 , 10 , true , 1234567890 , 123456789 , 12345 , 0 ) ;
30+ var expectedValue = ( decimal ) sqlDecimal ;
31+
32+ // Act
33+ var result = sqlDecimal . ToDecimal ( ) ;
34+
35+ // Assert
36+ result . Should ( ) . Be ( expectedValue ) ;
37+ }
38+
39+ [ Fact ]
40+ public void ToDecimal_Should_Handle_Zero_Scale ( )
41+ {
42+ // Arrange - Integer value (no decimal places)
43+ var sqlDecimal = new SqlDecimal ( 10 , 0 , true , 1234567890 , 0 , 0 , 0 ) ;
44+ var expectedValue = ( decimal ) sqlDecimal ;
45+
46+ // Act
47+ var result = sqlDecimal . ToDecimal ( ) ;
48+
49+ // Assert
50+ result . Should ( ) . Be ( expectedValue ) ;
51+ }
52+
53+ [ Fact ]
54+ public void ToDecimal_Should_Handle_Maximum_Scale ( )
55+ {
56+ // Arrange - Maximum scale of 27
57+ const decimal value = 1.123456789012345678901234567m ; // 27 decimal places
58+ var sqlDecimal = new SqlDecimal ( value ) ;
59+
60+ // Act
61+ var result = sqlDecimal . ToDecimal ( ) ;
62+
63+ // Assert
64+ result . Should ( ) . Be ( value ) ;
65+ }
66+
67+ [ Fact ]
68+ public void ToDecimal_Should_Handle_Negative_Values ( )
69+ {
70+ // Arrange
71+ const decimal value = - 123456.789m ;
72+ var sqlDecimal = new SqlDecimal ( value ) ;
73+
74+ // Act
75+ var result = sqlDecimal . ToDecimal ( ) ;
76+
77+ // Assert
78+ result . Should ( ) . Be ( value ) ;
79+ }
80+
81+ [ Fact ]
82+ public void ToDecimal_Should_Adjust_Scale_When_Total_Precision_Requires_It ( )
83+ {
84+ // Arrange - Create SqlDecimal with valid but high precision
85+ // 18 integer digits + 10 scale = 28 total (at limit, should convert directly)
86+ const decimal value = 123456789012345678.9876543210m ;
87+ var sqlDecimal = new SqlDecimal ( value ) ;
88+
89+ // Act
90+ var result = sqlDecimal . ToDecimal ( ) ;
91+
92+ // Assert
93+ result . Should ( ) . Be ( value ) ;
94+ }
95+
96+ [ Fact ]
97+ public void ToDecimal_Should_Throw_When_Value_Has_Too_Many_Integer_Digits ( )
98+ {
99+ // Arrange - SqlDecimal constructor validates, so we create a scenario
100+ // where conversion logic would detect the issue
101+ // We'll use Parse to create a SqlDecimal from a string that represents
102+ // a value with more integer digits than .NET decimal can handle
103+ const string bigValue = "123456789012345678901234567890.5" ; // 30 integer digits
104+ var sqlDecimal = SqlDecimal . Parse ( bigValue ) ;
105+
106+ // Act
107+ Action act = ( ) => sqlDecimal . ToDecimal ( ) ;
108+
109+ // Assert
110+ act . Should ( ) . Throw < OverflowException > ( ) . WithMessage ( "*Integer part*exceeds*decimal capacity*" ) ;
111+ }
112+
113+ [ Fact ]
114+ public void ToDecimal_Should_Handle_SqlDecimal_With_Low_Precision ( )
115+ {
116+ // Arrange - Very small precision
117+ var sqlDecimal = new SqlDecimal ( 5 , 2 , true , 12345 , 0 , 0 , 0 ) ; // 123.45
118+ var expectedValue = ( decimal ) sqlDecimal ;
119+
120+ // Act
121+ var result = sqlDecimal . ToDecimal ( ) ;
122+
123+ // Assert
124+ result . Should ( ) . Be ( expectedValue ) ;
125+ }
126+
127+ [ Fact ]
128+ public void ToDecimal_Should_Handle_SqlDecimal_With_High_Scale ( )
129+ {
130+ // Arrange - High scale relative to precision
131+ var sqlDecimal = new SqlDecimal ( 20 , 18 , true , 12345678 , 0 , 0 , 0 ) ; // Very small number with many decimals
132+
133+ // Act
134+ var result = sqlDecimal . ToDecimal ( ) ;
135+
136+ // Assert
137+ result . Should ( ) . NotBe ( 0 ) ;
138+ }
139+
140+ [ Fact ]
141+ public void ToDecimal_Should_Handle_Large_Positive_Values ( )
142+ {
143+ // Arrange - Large value that fits within .NET decimal constraints
144+ const decimal value = 999999999999999999999999.9999m ; // 24 integer + 4 decimal = 28 total
145+ var sqlDecimal = new SqlDecimal ( value ) ;
146+
147+ // Act
148+ var result = sqlDecimal . ToDecimal ( ) ;
149+
150+ // Assert
151+ result . Should ( ) . Be ( value ) ;
152+ }
153+
154+ [ Fact ]
155+ public void ToDecimal_Should_Handle_Large_Negative_Values ( )
156+ {
157+ // Arrange - Large negative value that fits within .NET decimal constraints
158+ const decimal value = - 999999999999999999999999.9999m ; // 24 integer + 4 decimal = 28 total
159+ var sqlDecimal = new SqlDecimal ( value ) ;
160+
161+ // Act
162+ var result = sqlDecimal . ToDecimal ( ) ;
163+
164+ // Assert
165+ result . Should ( ) . Be ( value ) ;
166+ }
167+
168+ [ Fact ]
169+ public void ToDecimal_Should_Preserve_Precision_When_Within_Limits ( )
170+ {
171+ // Arrange - Value with 28 total digits (max for .NET decimal)
172+ const decimal value = 1234567890123456.7890123456m ; // 16 integer + 10 decimal = 26 total
173+ var sqlDecimal = new SqlDecimal ( value ) ;
174+
175+ // Act
176+ var result = sqlDecimal . ToDecimal ( ) ;
177+
178+ // Assert
179+ result . Should ( ) . Be ( value ) ;
180+ }
181+
182+ [ Fact ]
183+ public void ToDecimal_Should_Be_Idempotent ( )
184+ {
185+ // Arrange
186+ const decimal value = 12345.6789m ;
187+ var sqlDecimal = new SqlDecimal ( value ) ;
188+
189+ // Act
190+ var result1 = sqlDecimal . ToDecimal ( ) ;
191+ var result2 = sqlDecimal . ToDecimal ( ) ;
192+
193+ // Assert
194+ result1 . Should ( ) . Be ( result2 ) ;
195+ result1 . Should ( ) . Be ( value ) ;
196+ }
197+ }
0 commit comments