@@ -80,6 +80,107 @@ public void DecimalGetUnscaledValueShouldProduceExpectedResultValueAndScale(int
8080 Assert . Equal ( expected , actual ) ;
8181 }
8282
83+ [ Theory ( DisplayName = "Decimal.SetScale should preserve or pad when scale is less or equal" ) ]
84+ [ InlineData ( "123.0" , 2 , "123.00" ) ]
85+ [ InlineData ( "123.00" , 2 , "123.00" ) ]
86+ [ InlineData ( "123.000" , 2 , "123.00" ) ]
87+ [ InlineData ( "0.0" , 2 , "0.00" ) ]
88+ [ InlineData ( "123.12" , 2 , "123.12" ) ]
89+ public void DecimalSetScaleShouldPreserveOrPadWhenScaleIsLessOrEqual ( string inputStr , int scale , string expectedStr )
90+ {
91+ // Given
92+ decimal input = decimal . Parse ( inputStr ) ;
93+ decimal expected = decimal . Parse ( expectedStr ) ;
94+
95+ // When
96+ decimal result = input . SetScale ( scale ) ;
97+
98+ // Then
99+ Assert . Equal ( expected , result ) ;
100+ }
101+
102+ [ Theory ( DisplayName = "Decimal.SetScale should truncate when no precision loss" ) ]
103+ [ InlineData ( "123.1200" , 2 , "123.12" ) ]
104+ [ InlineData ( "0.1000" , 1 , "0.1" ) ]
105+ [ InlineData ( "999.0000" , 3 , "999.000" ) ]
106+ public void DecimalSetScaleShouldTruncateWhenNoPrecisionLoss ( string inputStr , int scale , string expectedStr )
107+ {
108+ // Given
109+ decimal input = decimal . Parse ( inputStr ) ;
110+ decimal expected = decimal . Parse ( expectedStr ) ;
111+
112+ // When
113+ decimal result = input . SetScale ( scale ) ;
114+
115+ // Then
116+ Assert . Equal ( expected , result ) ;
117+ }
118+
119+ [ Theory ( DisplayName = "Decimal.SetScale should throw when truncation would lose precision" ) ]
120+ [ InlineData ( "123.456" , 2 ) ]
121+ [ InlineData ( "1.001" , 2 ) ]
122+ [ InlineData ( "0.123456789" , 5 ) ]
123+ public void DecimalSetScaleShouldThrowWhenTruncationWouldLosePrecision ( string inputStr , int scale )
124+ {
125+ // Given
126+ decimal input = decimal . Parse ( inputStr ) ;
127+
128+ // When / Then
129+ Assert . Throws < InvalidOperationException > ( ( ) => input . SetScale ( scale ) ) ;
130+ }
131+
132+ [ Theory ( DisplayName = "Decimal.SetScale(rounding) should apply correct rounding" ) ]
133+ [ InlineData ( "123.456" , 2 , MidpointRounding . AwayFromZero , "123.46" ) ]
134+ [ InlineData ( "123.454" , 2 , MidpointRounding . AwayFromZero , "123.45" ) ]
135+ [ InlineData ( "123.455" , 2 , MidpointRounding . ToZero , "123.45" ) ]
136+ [ InlineData ( "123.455" , 2 , MidpointRounding . ToEven , "123.46" ) ]
137+ [ InlineData ( "0.125" , 2 , MidpointRounding . ToEven , "0.12" ) ]
138+ [ InlineData ( "0.135" , 2 , MidpointRounding . ToEven , "0.14" ) ]
139+ public void DecimalSetScaleWithRoundingShouldApplyCorrectRounding ( string inputStr , int scale , MidpointRounding mode , string expectedStr )
140+ {
141+ // Given
142+ decimal input = decimal . Parse ( inputStr ) ;
143+ decimal expected = decimal . Parse ( expectedStr ) ;
144+
145+ // When
146+ decimal result = input . SetScale ( scale , mode ) ;
147+
148+ // Then
149+ Assert . Equal ( expected , result ) ;
150+ }
151+
152+ [ Theory ( DisplayName = "Decimal.SetScale(rounding) should truncate when no precision loss" ) ]
153+ [ InlineData ( "123.0000" , 2 , MidpointRounding . AwayFromZero , "123.00" ) ]
154+ [ InlineData ( "1.000" , 1 , MidpointRounding . ToEven , "1.0" ) ]
155+ public void DecimalSetScaleWithRoundingShouldTruncateWhenNoPrecisionLoss ( string inputStr , int scale , MidpointRounding mode , string expectedStr )
156+ {
157+ // Given
158+ decimal input = decimal . Parse ( inputStr ) ;
159+ decimal expected = decimal . Parse ( expectedStr ) ;
160+
161+ // When
162+ decimal result = input . SetScale ( scale , mode ) ;
163+
164+ // Then
165+ Assert . Equal ( expected , result ) ;
166+ }
167+
168+ [ Fact ( DisplayName = "Decimal.SetScale should throw when scale is negative" ) ]
169+ public void DecimalSetScaleShouldThrowWhenScaleIsNegative ( )
170+ {
171+ // Given / When / Then
172+ Exception exception = Assert . Throws < ArgumentException > ( ( ) => 123.45m . SetScale ( - 1 ) ) ;
173+ Assert . Contains ( "Scale must be greater than, or equal to zero." , exception . Message ) ;
174+ }
175+
176+ [ Fact ( DisplayName = "Decimal.SetScale(rounding) should throw when scale is negative" ) ]
177+ public void DecimalSetScaleWithRoundingShouldThrowWhenScaleIsNegative ( )
178+ {
179+ // Given / When / Then
180+ Exception exception = Assert . Throws < ArgumentException > ( ( ) => 123.45m . SetScale ( - 1 , MidpointRounding . AwayFromZero ) ) ;
181+ Assert . Contains ( "Scale must be greater than, or equal to zero." , exception . Message ) ;
182+ }
183+
83184 [ Theory ( DisplayName = "INumber<T>.IsBetween should produce the expected result" ) ]
84185 [ InlineData ( 0 , 0 , 0 , true ) ]
85186 [ InlineData ( 0 , 0 , 1 , true ) ]
0 commit comments