1 // EnumTest.cs - NUnit Test Cases for the System.Enum class
3 // David Brandt (bucky@keystreams.com)
5 // (C) Ximian, Inc. http://www.ximian.com
11 using System.Reflection;
14 namespace MonoTests.System
17 public class EnumTest : TestCase
21 protected override void SetUp()
25 protected override void TearDown()
29 enum TestingEnum {This, Is, A, Test};
30 enum TestingEnum2 {This, Is, A, Test};
31 enum TestingEnum3: ulong {This, Is, A, Test = ulong.MaxValue };
33 public void TestCompareTo() {
34 Enum e1 = new TestingEnum();
35 Enum e2 = new TestingEnum();
36 Enum e3 = new TestingEnum2();
38 AssertEquals("An enum should equal itself",
40 AssertEquals("An enum should equal a copy",
43 TestingEnum x = TestingEnum.This;
44 TestingEnum y = TestingEnum.Is;
45 AssertEquals("should equal", 0, x.CompareTo(x));
46 AssertEquals("less than", -1, x.CompareTo(y));
47 AssertEquals("greater than", 1, y.CompareTo(x));
50 bool errorThrown = false;
53 } catch (ArgumentException) {
56 Assert("1) Compare type mismatch not caught.",
60 bool errorThrown = false;
62 ((Enum)e1).CompareTo((Enum)e3);
63 } catch (ArgumentException) {
66 Assert("2) Compare type mismatch not caught.",
71 public void TestEquals() {
72 Enum e1 = new TestingEnum();
73 Enum e2 = new TestingEnum();
74 Enum e3 = new TestingEnum2();
76 Assert("An enum should equal itself", e1.Equals(e1));
77 Assert("An enum should equal a copy", e1.Equals(e2));
79 Assert("Shouldn't match", !e1.Equals(e3));
80 Assert("Shouldn't match null", !e1.Equals(null));
83 public void TestFormat_Args() {
85 TestingEnum x = TestingEnum.Test;
86 Enum.Format(null, x, "G");
87 Fail("#A1: null first arg not caught.");
88 } catch (ArgumentNullException ex) {
89 AssertEquals ("#A2", "enumType", ex.ParamName);
90 } catch (Exception e) {
91 Fail("#A3: first arg null, wrong exception: " + e.ToString());
95 Enum.Format(typeof(TestingEnum), null, "G");
96 Fail("#B1: null second arg not caught.");
97 } catch (ArgumentNullException ex) {
98 AssertEquals ("#B2", "value", ex.ParamName);
99 } catch (Exception e) {
100 Fail("#B3: second arg null, wrong exception: " + e.ToString());
104 TestingEnum x = TestingEnum.Test;
105 Enum.Format(x.GetType(), x, null);
106 Fail("#C1: null third arg not caught.");
107 } catch (ArgumentNullException ex) {
108 AssertEquals ("#C2", "format", ex.ParamName);
109 } catch (Exception e) {
110 Fail("#C3: third arg null, wrong exception: " + e.ToString());
114 TestingEnum x = TestingEnum.Test;
115 Enum.Format(typeof(string), x, "G");
116 Fail("#D1: bad type arg not caught.");
117 } catch (ArgumentException) {
118 // Type provided must be an Enum
119 } catch (Exception e) {
120 Fail("#D2: bad type, wrong exception: " + e.ToString());
124 TestingEnum x = TestingEnum.Test;
125 TestingEnum2 y = TestingEnum2.Test;
126 Enum.Format(y.GetType(), x, "G");
127 Fail("#E1: wrong enum type not caught.");
128 } catch (ArgumentException ex) {
129 // Object must be the same type as the enum. The type passed in was
130 // MonoTests.System.EnumTest.TestingEnum2; the enum type was
131 // MonoTests.System.EnumTest.TestingEnum
132 AssertNotNull ("#E2", ex.Message);
133 Assert ("#E3", ex.Message.IndexOf (typeof (TestingEnum2).FullName) != -1);
134 Assert ("#E4", ex.Message.IndexOf (typeof (TestingEnum).FullName) != -1);
135 } catch (Exception e) {
136 Fail("#E5: wrong enum type, wrong exception: " + e.ToString());
141 TestingEnum x = TestingEnum.Test;
142 Enum.Format(x.GetType(), bad, "G");
143 Fail("#F1: non-enum object not caught.");
144 } catch (ArgumentException ex) {
145 // Enum underlying type and the object must be the same type or
146 // object. Type passed in was String.String; the enum underlying
148 AssertNotNull ("#F2", ex.Message);
149 Assert ("#F3", ex.Message.IndexOf (typeof (string).FullName) != -1);
150 Assert ("#F4", ex.Message.IndexOf (typeof (int).FullName) != -1);
151 } catch (Exception e) {
152 Fail("#F5: non-enum object, wrong exception: " + e.ToString());
155 string[] codes = {"a", "b", "c", "ad", "e", "af", "ag", "h",
156 "i", "j", "k", "l", "m", "n", "o", "p",
157 "q", "r", "s", "t", "u", "v", "w", "ax",
159 foreach (string code in codes) {
161 TestingEnum x = TestingEnum.Test;
162 Enum.Format(x.GetType(), x, code);
163 Fail ("bad format code not caught - " + code);
164 } catch (FormatException) {
166 } catch (Exception e) {
167 Fail (String.Format ("bad format code ({0}), wrong exception: {1}",
168 code, e.ToString()));
172 TestingEnum test = TestingEnum.Test;
173 AssertEquals("decimal format wrong",
174 "3", Enum.Format (test.GetType (), test, "d"));
175 AssertEquals("decimal format wrong for ulong enums",
176 "18446744073709551615", Enum.Format(typeof(TestingEnum3), TestingEnum3.Test, "d"));
177 AssertEquals("named format wrong",
178 "Test", Enum.Format (test.GetType (), test, "g"));
179 AssertEquals("hex format wrong",
180 "00000003", Enum.Format (test.GetType (), test, "x"));
181 AssertEquals("bitfield format wrong",
182 "Test", Enum.Format (test.GetType (), test, "f"));
185 public void TestFormat_FormatSpecifier ()
187 ParameterAttributes pa =
188 ParameterAttributes.In | ParameterAttributes.HasDefault;
189 const string fFormatOutput = "In, HasDefault";
190 const string xFormatOutput = "00001001";
191 string fOutput = Enum.Format (pa.GetType(), pa, "f");
192 AssertEquals ("#F_FS:f", fFormatOutput, fOutput);
193 string xOutput = Enum.Format (pa.GetType(), pa, "x");
194 AssertEquals ("#F_FS:x", xFormatOutput, xOutput);
197 public void TestGetHashCode() {
198 Enum e1 = new TestingEnum();
199 Enum e2 = new TestingEnum2();
201 AssertEquals("hash code is deterministic",
202 e1.GetHashCode(), e1.GetHashCode());
205 public void GetName() {
207 bool errorThrown = false;
209 TestingEnum x = TestingEnum.Test;
210 Enum.GetName(null, x);
211 } catch (ArgumentNullException) {
214 Assert("null first arg not caught.",
218 bool errorThrown = false;
220 TestingEnum x = TestingEnum.Test;
221 Enum.GetName(x.GetType(), null);
222 } catch (ArgumentNullException) {
225 Assert("null second arg not caught.",
229 bool errorThrown = false;
232 TestingEnum x = TestingEnum.Test;
233 Enum.GetName(bad.GetType(), x);
234 } catch (ArgumentException) {
237 Assert("non-enum type not caught.",
241 bool errorThrown = false;
243 TestingEnum x = TestingEnum.Test;
244 TestingEnum2 y = TestingEnum2.Test;
245 Enum.GetName(y.GetType(), x);
246 } catch (ArgumentException) {
249 Assert("wrong enum type not caught.",
253 bool errorThrown = false;
256 TestingEnum x = TestingEnum.Test;
257 Enum.GetName(x.GetType(), bad);
258 } catch (ArgumentException) {
261 Assert("non-enum object not caught.",
265 TestingEnum x = TestingEnum.This;
266 TestingEnum y = TestingEnum.Is;
267 TestingEnum z = TestingEnum.A;
269 AssertEquals("first name doesn't match",
270 "This", Enum.GetName(x.GetType(), x));
271 AssertEquals("second name doesn't match",
272 "Is", Enum.GetName(y.GetType(), y));
273 AssertEquals("third name doesn't match",
274 "A", Enum.GetName(z.GetType(), z));
278 public void TestGetNames() {
280 bool errorThrown = false;
283 } catch (ArgumentNullException) {
286 Assert("null type not caught.",
290 TestingEnum x = TestingEnum.This;
291 string[] match = {"This", "Is", "A", "Test"};
292 string[] names = Enum.GetNames(x.GetType());
293 AssertNotNull("Got no names", names);
294 AssertEquals("names wrong size",
295 match.Length, names.Length);
296 for (int i = 0; i < names.Length; i++) {
297 AssertEquals("name mismatch",
303 public void TestGetTypeCode() {
304 TestingEnum x = TestingEnum.This;
305 TestingEnum y = new TestingEnum();
306 AssertEquals("01 bad type code",
307 TypeCode.Int32, x.GetTypeCode());
308 AssertEquals("02 bad type code",
309 TypeCode.Int32, y.GetTypeCode());
312 enum TestShortEnum : short { zero, one, two, three, four, five, six};
313 public void TestGetUnderlyingType() {
315 bool errorThrown = false;
317 Enum.GetUnderlyingType(null);
318 } catch (ArgumentNullException) {
321 Assert("null type not caught.",
325 bool errorThrown = false;
328 Enum.GetUnderlyingType(bad.GetType());
329 } catch (ArgumentException) {
332 Assert("non-enum type not caught.",
338 Enum t1 = new TestingEnum();
339 Enum t2 = new TestShortEnum();
340 AssertEquals("Wrong default underlying type",
342 Enum.GetUnderlyingType(t1.GetType()));
343 AssertEquals("Not short underlying type",
345 Enum.GetUnderlyingType(t2.GetType()));
349 public void TestGetValues() {
351 bool errorThrown = false;
353 Enum.GetValues(null);
354 } catch (ArgumentNullException) {
357 Assert("null type not caught.",
361 bool errorThrown = false;
364 Enum.GetValues(bad.GetType());
365 } catch (ArgumentException) {
368 Assert("non-enum type not caught.",
372 Enum t1 = new TestingEnum();
373 Array a1 = Enum.GetValues(t1.GetType());
374 for (int i= 0; i < a1.Length; i++) {
375 AssertEquals("wrong enum value",
381 Enum t1 = new TestShortEnum();
382 Array a1 = Enum.GetValues(t1.GetType());
383 for (short i= 0; i < a1.Length; i++) {
384 AssertEquals("wrong short enum value",
391 public void TestIsDefined() {
393 bool errorThrown = false;
395 Enum.IsDefined(null, 1);
396 } catch (ArgumentNullException) {
399 Assert("null first arg not caught.",
403 bool errorThrown = false;
405 TestingEnum x = TestingEnum.Test;
406 Enum.IsDefined(x.GetType(), null);
407 } catch (ArgumentNullException) {
410 Assert("null second arg not caught.",
414 bool errorThrown = false;
418 Enum.IsDefined(bad.GetType(), i);
419 } catch (ArgumentException) {
422 Assert("non-enum type not caught.",
427 TestingEnum x = TestingEnum.Test;
429 Enum.IsDefined(x.GetType(), i);
430 Fail("wrong underlying type not caught.");
431 } catch (ArgumentException) {
432 } catch (Exception e) {
433 Fail("wrong Exception thrown ("+e.ToString()+")for underlying type not caught.");
436 // spec says yes, MS impl says no.
438 //bool errorThrown = false;
440 //String bad = "huh?";
441 //TestingEnum x = TestingEnum.Test;
442 //Enum.IsDefined(x.GetType(), bad);
443 //} catch (ExecutionEngineException) {
444 //errorThrown = true;
446 //Assert("non-enum object not caught.",
450 Enum t1 = new TestingEnum();
453 i < Enum.GetValues(t1.GetType()).Length; i++) {
454 Assert("should have value for i=" + i,
455 Enum.IsDefined(t1.GetType(), i));
457 Assert("Shouldn't have value",
458 !Enum.IsDefined(t1.GetType(), i));
462 public void TestParse1() {
464 bool errorThrown = false;
466 String name = "huh?";
467 Enum.Parse(null, name);
468 } catch (ArgumentNullException) {
471 Assert("null first arg not caught.",
475 bool errorThrown = false;
477 TestingEnum x = TestingEnum.Test;
478 Enum.Parse(x.GetType(), null);
479 } catch (ArgumentNullException) {
482 Assert("null second arg not caught.",
486 bool errorThrown = false;
489 Enum.Parse(bad.GetType(), bad);
490 } catch (ArgumentException) {
493 Assert("non-enum type not caught.",
497 bool errorThrown = false;
499 TestingEnum x = TestingEnum.Test;
501 Enum.Parse(x.GetType(), bad);
502 } catch (ArgumentException) {
505 Assert("empty string not caught.",
509 bool errorThrown = false;
511 TestingEnum x = TestingEnum.Test;
513 Enum.Parse(x.GetType(), bad);
514 } catch (ArgumentException) {
517 Assert("space-only string not caught.",
521 bool errorThrown = false;
524 TestingEnum x = TestingEnum.Test;
525 Enum.Parse(x.GetType(), bad);
526 } catch (ArgumentException) {
529 Assert("not-in-enum error not caught.",
533 TestingEnum t1 = new TestingEnum();
534 AssertEquals("parse first enum",
536 Enum.Parse(t1.GetType(), "This"));
537 AssertEquals("parse second enum",
539 Enum.Parse(t1.GetType(), "Is"));
540 AssertEquals("parse third enum",
542 Enum.Parse(t1.GetType(), "A"));
543 AssertEquals("parse last enum",
545 Enum.Parse(t1.GetType(), "Test"));
547 AssertEquals("parse last enum with whitespace",
549 Enum.Parse(t1.GetType(), " \n\nTest\t"));
551 AssertEquals("parse bitwise-or enum",
553 Enum.Parse(t1.GetType(), "This,Is"));
554 AssertEquals("parse bitwise-or enum",
556 Enum.Parse(t1.GetType(), "This,Test"));
557 AssertEquals("parse bitwise-or enum",
559 Enum.Parse(t1.GetType(), "This,Is,A"));
561 AssertEquals("parse bitwise-or enum with whitespace",
563 Enum.Parse(t1.GetType(), " \n\tThis \t\n, Is,A \n"));
566 public void TestParse2() {
568 bool errorThrown = false;
570 String name = "huh?";
571 Enum.Parse(null, name, true);
572 } catch (ArgumentNullException) {
575 Assert("null first arg not caught.",
579 bool errorThrown = false;
581 TestingEnum x = TestingEnum.Test;
582 Enum.Parse(x.GetType(), null, true);
583 } catch (ArgumentNullException) {
586 Assert("null second arg not caught.",
590 bool errorThrown = false;
593 Enum.Parse(bad.GetType(), bad, true);
594 } catch (ArgumentException) {
597 Assert("non-enum type not caught.",
601 bool errorThrown = false;
603 TestingEnum x = TestingEnum.Test;
605 Enum.Parse(x.GetType(), bad, true);
606 } catch (ArgumentException) {
609 Assert("empty string not caught.",
613 bool errorThrown = false;
615 TestingEnum x = TestingEnum.Test;
617 Enum.Parse(x.GetType(), bad, true);
618 } catch (ArgumentException) {
621 Assert("space-only string not caught.",
625 bool errorThrown = false;
628 TestingEnum x = TestingEnum.Test;
629 Enum.Parse(x.GetType(), bad, true);
630 } catch (ArgumentException) {
633 Assert("not-in-enum error not caught.",
637 bool errorThrown = false;
640 TestingEnum x = TestingEnum.Test;
641 Enum.Parse(x.GetType(), bad, false);
642 } catch (ArgumentException) {
645 Assert("not-in-enum error not caught.",
649 TestingEnum t1 = new TestingEnum();
650 AssertEquals("parse first enum",
652 Enum.Parse(t1.GetType(), "this", true));
653 AssertEquals("parse second enum",
655 Enum.Parse(t1.GetType(), "is", true));
656 AssertEquals("parse third enum",
658 Enum.Parse(t1.GetType(), "a", true));
659 AssertEquals("parse last enum",
661 Enum.Parse(t1.GetType(), "test", true));
663 AssertEquals("parse last enum with whitespace",
665 Enum.Parse(t1.GetType(), " \n\ntest\t", true));
667 AssertEquals("parse bitwise-or enum",
669 Enum.Parse(t1.GetType(), "This,is", true));
670 AssertEquals("parse bitwise-or enum",
672 Enum.Parse(t1.GetType(), "This,test", true));
673 AssertEquals("parse bitwise-or enum",
675 Enum.Parse(t1.GetType(), "This,is,A", true));
677 AssertEquals("parse bitwise-or enum with whitespace",
679 Enum.Parse(t1.GetType(), " \n\tThis \t\n, is,a \n",
685 public void ParseValue() {
686 TestingEnum3 t1 = new TestingEnum3();
687 AssertEquals ("Parse numeric value", TestingEnum3.Test, Enum.Parse(t1.GetType(), "18446744073709551615", false));
690 public void TestToObject() {
692 bool errorThrown = false;
694 Enum.ToObject(null, 1);
695 } catch (ArgumentNullException) {
698 Assert("null type not caught.",
702 bool errorThrown = false;
704 Enum.ToObject("huh?".GetType(), 1);
705 } catch (ArgumentException) {
708 Assert("null type not caught.",
712 TestingEnum t1 = new TestingEnum();
713 AssertEquals("Should get object",
715 Enum.ToObject(t1.GetType(), 0));
717 // TODO - should probably test all the different underlying types
721 enum SomeEnum {a,b,c};
724 enum SomeByteEnum : byte {a,b,c};
727 enum SomeInt64Enum : long {a,b,c};
729 public void TestToString() {
733 AssertEquals("invalid string", "This",
734 TestingEnum.This.ToString());
736 AssertEquals("invalid string", "Is",
737 TestingEnum.Is.ToString());
739 AssertEquals("invalid string", "A",
740 TestingEnum.A.ToString());
742 AssertEquals("invalid string", "Test",
743 TestingEnum.Test.ToString());
745 Enum is1 = TestingEnum.Is;
748 AssertEquals("decimal parse wrong",
749 "1", is1.ToString("d"));
751 AssertEquals("named format wrong",
752 "Is", is1.ToString("g"));
754 AssertEquals("hex format wrong",
755 "00000001", is1.ToString("x"));
757 AssertEquals("bitfield format wrong",
758 "Is", is1.ToString("f"));
761 AssertEquals("bitfield with flags format wrong for Int32 enum",
762 "b, c", ((SomeEnum)3).ToString("f"));
764 AssertEquals("bitfield with flags format wrong for Byte enum",
765 "b, c", ((SomeByteEnum)3).ToString("f"));
767 AssertEquals("bitfield with flags format wrong for Int64 enum",
768 "b, c", ((SomeInt64Enum)3).ToString("f"));
771 AssertEquals("bitfield with unknown flags format wrong for Int32 enum",
772 "12", ((SomeEnum)12).ToString("f"));
774 AssertEquals("bitfield with unknown flags format wrong for Byte enum",
775 "12", ((SomeByteEnum)12).ToString("f"));
777 AssertEquals("bitfield with unknown flags format wrong for Int64 enum",
778 "12", ((SomeInt64Enum)12).ToString("f"));
780 } catch (Exception e) {
781 Fail ("Unexpected exception at i = " + i + " with e=" + e);
801 public void FlagTest ()
803 int [] evalues = new int [4] {0,1,2,3};
804 E [] e = new E [4] {E.Aa, E.Bb, E.Cc, E.Dd};
806 for (int i = 0; i < 4; ++i) {
807 Assertion.AssertEquals ("#" + i,
809 Enum.Format (typeof (E), evalues [i], "f"));
815 public void FlagTest2 () {
816 int invalidValue = 1000;
818 Assertion.AssertEquals ("#01",
819 invalidValue.ToString (),
820 Enum.Format (typeof (E2), invalidValue, "g"));
823 enum E3 {A=0,B=1,C=2,D=3,}
824 enum UE : ulong {A=1,B=2,C=4,D=8,}
825 enum EA {A=0, B=2, C=3, D=4}
828 public void AnotherFormatBugPinned ()
830 Assertion.AssertEquals ("#01", "100", Enum.Format (typeof (E3), 100, "f"));
834 public void LogicBugPinned ()
837 string[] names=new string[] {"A","B","C","D",};
838 string[] fmtSpl=null;
839 UE ue = UE.A | UE.B | UE.C | UE.D;
841 //all flags must be in format return
842 format = Enum.Format (typeof (UE), ue, "f");
843 fmtSpl = format.Split (',');
844 for( int i=0 ; i<fmtSpl.Length ; ++i )
845 fmtSpl [i] = fmtSpl[i].Trim ();
847 foreach (string nval in fmtSpl)
848 Assertion.Assert (nval + " is not a valid enum value name", Array.IndexOf (names, nval) >= 0);
850 foreach (string nval in names)
851 Assertion.Assert (nval + " is not contained in format return.", Array.IndexOf (fmtSpl, nval) >= 0);
853 // TODO - ToString with IFormatProviders
856 enum FlagsNegativeTestEnum {
860 Negative = unchecked((int)0xFFFF0000)
864 public void FlagTest3 () {
865 FlagsNegativeTestEnum t;
867 t = FlagsNegativeTestEnum.None;
868 Assertion.AssertEquals("#01", "None", t.ToString());
869 t = FlagsNegativeTestEnum.One;
870 Assertion.AssertEquals("#02", "One", t.ToString());