This should fix #76928. This fix incorporates ideas from a patch
[mono.git] / mcs / class / corlib / Test / System / Int64Test.cs
1 // Int64Test.cs - NUnit Test Cases for the System.Int64 struct
2 //
3 // Author: Martin Weindel (martin.weindel@t-online.de)
4 //
5 // (C) Martin Weindel, 2001
6 // 
7 // tests ToString and Parse function with the culture independent 
8 // NumberFormatInfo.InvariantInfo
9
10 using NUnit.Framework;
11 using System;
12 using System.Globalization;
13 using System.Threading;
14
15 using AssertType = NUnit.Framework.Assert;
16
17     /// <summary>
18     /// Tests for System.Int64
19     /// </summary>
20 namespace MonoTests.System
21 {
22
23 [TestFixture]
24 public class Int64Test : Assertion
25 {
26         private const Int64 MyInt64_1 = -42;
27         private const Int64 MyInt64_2 = -9223372036854775808;
28         private const Int64 MyInt64_3 = 9223372036854775807;
29         private const string MyString1 = "-42";
30         private const string MyString2 = "-9223372036854775808";
31         private const string MyString3 = "9223372036854775807";
32         private string[] Formats1 = {"c", "d", "e", "f", "g", "n", "p", "x" };
33         private string[] Formats2 = {"c5", "d5", "e5", "f5", "g5", "n5", "p5", "x5" };
34         private string[] Results1 = {"", "-9223372036854775808", "-9.223372e+018", "-9223372036854775808.00",
35                                           "-9223372036854775808", "-9,223,372,036,854,775,808.00", "-922,337,203,685,477,580,800.00 %", "8000000000000000"};
36         private string[] Results2 = {"", "9223372036854775807", "9.22337e+018", "9223372036854775807.00000",
37                                           "9.2234e+18", "9,223,372,036,854,775,807.00000", "922,337,203,685,477,580,700.00000 %", "7fffffffffffffff"};
38         private string[] ResultsNfi1 = {"("+NumberFormatInfo.InvariantInfo.CurrencySymbol+"9,223,372,036,854,775,808.00)", "-9223372036854775808", "-9.223372e+018", "-9223372036854775808.00",
39                                           "-9223372036854775808", "-9,223,372,036,854,775,808.00", "-922,337,203,685,477,580,800.00 %", "8000000000000000"};
40         private string[] ResultsNfi2 = {""+NumberFormatInfo.InvariantInfo.CurrencySymbol+"9,223,372,036,854,775,807.00000", "9223372036854775807", "9.22337e+018", "9223372036854775807.00000",
41                                           "9.2234e+18", "9,223,372,036,854,775,807.00000", "922,337,203,685,477,580,700.00000 %", "7fffffffffffffff"};
42
43         private long[] vals
44         = { 0, Int64.MaxValue, Int64.MinValue,
45               1L, 12L, 123L, 1234L, -123L, 
46               1234567890123456L, 6543210987654321L };
47
48         private const long val1 = -1234567L;
49         private const long val2 = 1234567L;
50         private const string sval1Test1 = "  -1,234,567   ";
51         private const string sval1Test2 = "  -1234567   ";
52         //private const string sval1Test3 = "  -12345,,,,67   "; // interesting: this case works on SDK Beta2, but the specification says nothing about this case
53         private const string sval1Test4 = "  -12345 67   ";
54         private  string sval1Test5 = "  -"+NumberFormatInfo.InvariantInfo.CurrencySymbol+"1,234,567.00 ";
55         private  string sval1Test6 = "("+NumberFormatInfo.InvariantInfo.CurrencySymbol+"1,234,567.00)";
56         private const string sval1Test7 = "-1,234,567.00";
57         private const string sval1UserCur1 = "1234/5/67:000 XYZ-";
58         private const string sval2UserCur1 = "1234/5/67:000 XYZ";
59         private const string sval1UserPercent1 = "-%%%1~2~3~4~5~6~7~0~0;0";
60         private const string sval2UserPercent1 = "%%%1~2~3~4~5~6~7~0~0;0";
61         private const NumberStyles style1 =  NumberStyles.AllowLeadingWhite | NumberStyles.AllowLeadingSign
62                                         | NumberStyles.AllowTrailingWhite | NumberStyles.AllowThousands;
63         private NumberFormatInfo Nfi = NumberFormatInfo.InvariantInfo;
64         private NumberFormatInfo NfiUser;
65
66         private CultureInfo old_culture;
67
68         [SetUp]
69         public void SetUp () 
70         {
71                 old_culture = Thread.CurrentThread.CurrentCulture;
72
73                 // Set culture to en-US and don't let the user override.
74                 Thread.CurrentThread.CurrentCulture = new CultureInfo ("en-US", false);
75
76                 int cdd = NumberFormatInfo.CurrentInfo.CurrencyDecimalDigits;
77                 string csym = NumberFormatInfo.CurrentInfo.CurrencySymbol;
78                 string csuffix = (cdd > 0 ? "." : "").PadRight(cdd + (cdd > 0 ? 1 : 0), '0');
79                 
80                 string decimals = new String ('0', NumberFormatInfo.CurrentInfo.NumberDecimalDigits);
81                 string perPattern = new string[] {"n %","n%","%n"} [NumberFormatInfo.CurrentInfo.PercentPositivePattern];
82                 
83                 Results1[0] = "(" + csym + "9,223,372,036,854,775,808" + csuffix + ")";
84                 Results1[3] = "-9223372036854775808." + decimals;
85                 Results1[5] = "-9,223,372,036,854,775,808." + decimals;
86                 Results1[6] = perPattern.Replace ("n","-922,337,203,685,477,580,800.00");
87                 
88                 Results2[0] = csym + "9,223,372,036,854,775,807.00000";
89                 Results2[6] = perPattern.Replace ("n","922,337,203,685,477,580,700.00000");
90                 
91                 NfiUser = new NumberFormatInfo();
92                 NfiUser.CurrencyDecimalDigits = 3;
93                 NfiUser.CurrencyDecimalSeparator = ":";
94                 NfiUser.CurrencyGroupSeparator = "/";
95                 NfiUser.CurrencyGroupSizes = new int[] { 2,1,0 };
96                 NfiUser.CurrencyNegativePattern = 10;  // n $-
97                 NfiUser.CurrencyPositivePattern = 3;  // n $
98                 NfiUser.CurrencySymbol = "XYZ";
99                 NfiUser.PercentDecimalDigits = 1;
100                 NfiUser.PercentDecimalSeparator = ";";
101                 NfiUser.PercentGroupSeparator = "~";
102                 NfiUser.PercentGroupSizes = new int[] {1};
103                 NfiUser.PercentNegativePattern = 2;
104                 NfiUser.PercentPositivePattern = 2;
105                 NfiUser.PercentSymbol = "%%%";
106         }
107
108         [TearDown]
109         public void TearDown ()
110         {
111                 Thread.CurrentThread.CurrentCulture = old_culture;
112         }
113
114         public void TestMinMax()
115         {
116                 
117                 AssertEquals(Int64.MinValue, MyInt64_2);
118                 AssertEquals(Int64.MaxValue, MyInt64_3);
119         }
120         
121         public void TestCompareTo()
122         {
123                 Assert(MyInt64_3.CompareTo(MyInt64_2) > 0);
124                 Assert(MyInt64_2.CompareTo(MyInt64_2) == 0);
125                 Assert(MyInt64_1.CompareTo((object)(Int64)(-42)) == 0);
126                 Assert(MyInt64_2.CompareTo(MyInt64_3) < 0);
127                 try {
128                         MyInt64_2.CompareTo((object)(Int16)100);
129                         Fail("Should raise a System.ArgumentException");
130                 }
131                 catch (Exception e) {
132                         Assert(typeof(ArgumentException) == e.GetType());
133                 }
134         }
135
136         public void TestEquals()
137         {
138                 Assert(MyInt64_1.Equals(MyInt64_1));
139                 Assert(MyInt64_1.Equals((object)(Int64)(-42)));
140                 Assert(MyInt64_1.Equals((object)(SByte)(-42)) == false);
141                 Assert(MyInt64_1.Equals(MyInt64_2) == false);
142         }
143         
144         public void TestGetHashCode()
145         {
146                 try {
147                         MyInt64_1.GetHashCode();
148                         MyInt64_2.GetHashCode();
149                         MyInt64_3.GetHashCode();
150                 }
151                 catch {
152                         Fail("GetHashCode should not raise an exception here");
153                 }
154         }
155         
156     public void TestRoundTripGeneral() 
157     {
158         foreach(long lv in vals) 
159         {
160             string s = lv.ToString(Nfi);
161             long lv2 = Int64.Parse(s);
162             Assert(lv == lv2);
163             long lv3 = Int64.Parse(s, NumberStyles.Integer, Nfi);
164             Assert(lv == lv3);
165         }
166     }
167
168     public void TestRoundTripHex() 
169     {
170         foreach(long lv in vals) 
171         {
172             string s = lv.ToString("x", Nfi);
173             long lv2 = Int64.Parse(s, NumberStyles.HexNumber, Nfi);
174             Assert(lv == lv2);
175         }
176     }
177
178     public void TestParseNull()
179     {
180         try 
181         {
182             Int64.Parse(null);
183             Fail("Should raise System.ArgumentNullException"); 
184         } 
185         catch (ArgumentNullException) 
186         {
187             // ok
188         }
189     }
190
191     public void TestParse()
192     {
193         long lv;
194
195         lv = Int64.Parse(sval1Test1, style1, Nfi);
196         AssertEquals("Long value should be equal for Test1", val1, lv);
197
198         try
199         {
200             lv = Int64.Parse(sval1Test1, Nfi);
201             Fail("Should raise FormatException 1");
202         }
203         catch (FormatException)
204         {
205             // ok
206         }
207
208         lv = Int64.Parse(sval1Test2, style1, Nfi);
209         AssertEquals("Value should be the same for Test2 with style1", val1, lv);
210         lv = Int64.Parse(sval1Test2, Nfi);
211         AssertEquals("Value should be the same for Test2 without style1", val1, lv);
212
213         try
214         {
215             lv = Int64.Parse(sval1Test4, style1, Nfi);
216             Fail("Should raise FormatException 3");
217         }
218         catch (FormatException)
219         {
220             // ok
221         }
222
223         lv = Int64.Parse(sval1Test5, NumberStyles.Currency, Nfi);
224         AssertEquals("Value should be the same for Test5 and currency style", val1, lv);
225
226         //test Parse(string s)
227         Assert(MyInt64_1 == Int64.Parse(MyString1));
228         Assert(MyInt64_2 == Int64.Parse(MyString2));
229         Assert(MyInt64_3 == Int64.Parse(MyString3));
230         try {
231                 Int64.Parse(null);
232                 Fail("#1:Should raise a System.ArgumentNullException");
233         }
234         catch (Exception e) {
235                 Assert("#2", typeof(ArgumentNullException) == e.GetType());
236         }
237         try {
238                 Int64.Parse("not-a-number");
239                 Fail("#3:Should raise a System.FormatException");
240         }
241         catch (Exception e) {
242                 Assert("#4", typeof(FormatException) == e.GetType());
243         }
244         //test Parse(string s, NumberStyles style)
245         try {
246                 double OverInt = (double)Int64.MaxValue + 1;
247                 Int64.Parse(OverInt.ToString(), NumberStyles.Float);
248                 Fail("#5:Should raise a System.OverflowException");
249         }
250         catch (Exception e) {
251                 Assert("#6", typeof(OverflowException) == e.GetType());
252         }
253         try {
254                 Int64.Parse("10000000000000000", NumberStyles.HexNumber);
255                 Fail("#7:Should raise a System.OverflowException");
256         }
257         catch (Exception e) {
258                 Assert("#8", typeof(OverflowException) == e.GetType());
259         }
260         try {
261                 double OverInt = (double)Int64.MaxValue + 1;
262                 Int64.Parse(OverInt.ToString(), NumberStyles.Integer);
263                 Fail("#9:Should raise a System.FormatException");
264         }
265         catch (Exception e) {
266                 Assert("#10", typeof(FormatException) == e.GetType());
267         }
268         AssertEquals("A1", (long)42, Int64.Parse(" "+NumberFormatInfo.CurrentInfo.CurrencySymbol+"42 ", NumberStyles.Currency));
269         try {
270                 Int64.Parse(NumberFormatInfo.CurrentInfo.CurrencySymbol+"42", NumberStyles.Integer);
271                 Fail("#11:Should raise a System.FormatException");
272         }
273         catch (Exception e) {
274                 Assert("#12", typeof(FormatException) == e.GetType());
275         }
276         //test Parse(string s, IFormatProvider provider)
277         Assert("A2", -42 == Int64.Parse(" -42 ", Nfi));
278         try {
279                 Int64.Parse("%42", Nfi);
280                 Fail("#13:Should raise a System.FormatException");
281         }
282         catch (Exception e) {
283                 Assert("#14", typeof(FormatException) == e.GetType());
284         }
285         //test Parse(string s, NumberStyles style, IFormatProvider provider)
286         Assert("A3", 16 == Int64.Parse(" 10 ", NumberStyles.HexNumber, Nfi));
287         try {
288                 Int64.Parse(NumberFormatInfo.CurrentInfo.CurrencySymbol+"42", NumberStyles.Integer, Nfi);
289                 Fail("#15:Should raise a System.FormatException");
290         }
291         catch (Exception e) {
292                 Assert("#16", typeof(FormatException) == e.GetType());
293         }
294         try {
295                 long.Parse ("9223372036854775808");
296                 AssertType.Fail ("#17:should raise an OverflowException");
297         } catch (Exception e) {
298                 Assert("#18", typeof(OverflowException) == e.GetType());
299         }
300         try {
301                 long.Parse ("9223372036854775808", CultureInfo.InvariantCulture);
302                 AssertType.Fail ("#19:should raise an OverflowException");
303         } catch (Exception e) {
304                 Assert("#20", typeof(OverflowException) == e.GetType());
305         }
306     }
307
308     public void TestToString() 
309     {
310         string s;
311
312         s = val1.ToString("c", Nfi);
313         Assert("val1 does not become sval1Test6", s.Equals(sval1Test6));
314
315         s = val1.ToString("n", Nfi);
316         AssertEquals("val1 does not become sval1Test7", sval1Test7, s);
317
318         //test ToString()
319         AssertEquals("MyInt64_1.ToString()", MyString1, MyInt64_1.ToString());
320         AssertEquals("MyInt64_2.ToString()", MyString2, MyInt64_2.ToString());
321         AssertEquals("MyInt64_3.ToString()", MyString3, MyInt64_3.ToString());
322         //test ToString(string format)
323         for (int i=0; i < Formats1.Length; i++) {
324                 AssertEquals("MyInt64_2.ToString(Formats1["+i+"])", Results1[i], MyInt64_2.ToString(Formats1[i]));
325                 AssertEquals("MyInt64_3.ToString(Formats2["+i+"])", Results2[i], MyInt64_3.ToString(Formats2[i]));
326         }
327         //test ToString(string format, IFormatProvider provider);
328         for (int i=0; i < Formats1.Length; i++) {
329                 AssertEquals("MyInt64_2.ToString(Formats1["+i+"], Nfi)", ResultsNfi1[i], MyInt64_2.ToString(Formats1[i], Nfi));
330                 AssertEquals("MyInt64_3.ToString(Formats2["+i+"], Nfi)", ResultsNfi2[i], MyInt64_3.ToString(Formats2[i], Nfi));
331         }
332         try {
333                 MyInt64_1.ToString("z");
334                 Fail("Should raise a System.FormatException");
335         }
336         catch (Exception e) {
337                 AssertEquals("Exception is wrong type", typeof(FormatException), e.GetType());
338         }
339     }
340
341     public void TestUserCurrency()
342     {
343         string s= "";
344         long v;
345         int iTest = 1;
346         try {
347                 s = val1.ToString("c", NfiUser);
348                 iTest++;
349                 AssertEquals("Currency value type 1 is not what we want to try to parse", sval1UserCur1, s);
350                 iTest++;
351                 v = Int64.Parse(s, NumberStyles.Currency, NfiUser);
352                 iTest++;
353                 Assert(v == val1);
354         } catch (Exception e) {
355                 Fail ("1 Unexpected exception at iTest = " + iTest + ", s = " + s + ":e = " + e);
356         }
357    
358         iTest = 1;
359         try {
360                 s = val2.ToString("c", NfiUser);
361                 iTest++;
362                 AssertEquals("Currency value type 2 is not what we want to try to parse", sval2UserCur1, s);
363                 iTest++;
364                 v = Int64.Parse(s, NumberStyles.Currency, NfiUser);
365                 iTest++;
366                 Assert(v == val2);
367         } catch (Exception e) {
368                 Fail ("2 Unexpected exception at iTest = " + iTest + ":e = " + e);
369         }
370     }
371
372     public void TestUserPercent()
373     {
374         string s;
375
376         s = val1.ToString("p", NfiUser);
377         Assert(s.Equals(sval1UserPercent1));
378
379         s = val2.ToString("p", NfiUser);
380         Assert(s.Equals(sval2UserPercent1));
381     }
382
383                 [Test]
384                 public void Parse_MaxValue ()
385                 {
386                         AssertEquals ("9223372036854775807", Int64.MaxValue, Int64.Parse ("9223372036854775807"));
387                 }
388
389                 [Test]
390                 public void Parse_MinValue ()
391                 {
392                         AssertEquals ("-9223372036854775808,10", Int64.MinValue, Int64.Parse ("-9223372036854775808"));
393                 }
394
395                 [Test]
396                 [ExpectedException (typeof (OverflowException))]
397                 public void Parse_OverByOneMaxValue ()
398                 {
399                         Int64.Parse ("9223372036854775808");
400                 }
401
402                 [Test]
403                 [ExpectedException (typeof (OverflowException))]
404                 public void Parse_WayOverMaxValue ()
405                 {
406                         Int64.Parse ("1" + Int64.MaxValue.ToString ());
407                 }
408
409                 [Test]
410                 [ExpectedException (typeof (OverflowException))]
411                 public void Parse_OverByOneMinValue ()
412                 {
413                         Int64.Parse ("-9223372036854775809");
414                 }
415
416                 [Test]
417                 [ExpectedException (typeof (OverflowException))]
418                 public void Parse_WayOverMinValue ()
419                 {
420                         Int64.Parse (Int64.MinValue.ToString () + "1");
421                 }
422
423                 [Test]
424                 public void ToString_Defaults () 
425                 {
426                         Int64 i = 254;
427                         // everything defaults to "G"
428                         string def = i.ToString ("G");
429                         AssertEquals ("ToString()", def, i.ToString ());
430                         AssertEquals ("ToString((IFormatProvider)null)", def, i.ToString ((IFormatProvider)null));
431                         AssertEquals ("ToString((string)null)", def, i.ToString ((string)null));
432                         AssertEquals ("ToString(empty)", def, i.ToString (String.Empty));
433                         AssertEquals ("ToString(null,null)", def, i.ToString (null, null));
434                         AssertEquals ("ToString(empty,null)", def, i.ToString (String.Empty, null));
435
436                         AssertEquals ("ToString(G)", "254", def);
437                 }
438         }
439 }