Hi,

The attached patch reports a different exception depending on whether
the type of the passed in value is an Enum or not. This is clearly
documented in the .NET Framework SDK and verified by improved unit tests
(see patch).

The patch also avoids looking up the underlying type of enum twice, when
the format specifier is "D" or "d".

Let me know if it's ok to commit.

Gert
Index: System/ChangeLog
===================================================================
--- System/ChangeLog	(revision 66386)
+++ System/ChangeLog	(working copy)
@@ -1,3 +1,9 @@
+2006-10-07 Gert Driesen <[EMAIL PROTECTED]>
+
+	* Enum.cs: Use different exception message depending on whether the
+	type of the passed in value is an Enum or not. Avoid looking up the
+	enum's underlying type twice in case of "D" or "d" format specifier.
+
 2006-10-06 Gonzalo Paniagua Javier <[EMAIL PROTECTED]>
 
 	* TermInfoDriver.cs: don't allow backspace if we're at the beginning
Index: System/Enum.cs
===================================================================
--- System/Enum.cs	(revision 66386)
+++ System/Enum.cs	(working copy)
@@ -664,13 +664,22 @@
 				throw new ArgumentNullException ("format");
 
 			if (!enumType.IsEnum)
-				throw new ArgumentException ("enumType is not an Enum Type.");
+				throw new ArgumentException ("Type provided must be an Enum.");
 			
 			Type vType = value.GetType();
-			if (vType != enumType && vType != Enum.GetUnderlyingType (enumType))
-				throw new ArgumentException (string.Format(CultureInfo.InvariantCulture,
-					"Object must be the same type as the enum. The type passed in " +
-					"was {0}; the enum type was {1}.", vType.FullName, enumType.FullName));
+			Type underlyingType = Enum.GetUnderlyingType (enumType);
+			if (vType.IsEnum) {
+				if (vType != enumType)
+					throw new ArgumentException (string.Format(CultureInfo.InvariantCulture,
+						"Object must be the same type as the enum. The type" +
+						" passed in was {0}; the enum type was {1}.",
+						vType.FullName, enumType.FullName));
+			} else if (vType != underlyingType) {
+				throw new ArgumentException (string.Format (CultureInfo.InvariantCulture,
+					"Enum underlying type and the object must be the same type" +
+					" or object. Type passed in was {0}; the enum underlying" +
+					" type was {1}.", vType.FullName, underlyingType.FullName));
+			}
 
 			if (format.Length != 1)
 				throw new FormatException ("Format String can be only \"G\",\"g\",\"X\"," + 
@@ -701,7 +710,7 @@
 				break;
 			case 'D':
 			case 'd':
-				if (Enum.GetUnderlyingType (enumType) == typeof (ulong)) {
+				if (underlyingType == typeof (ulong)) {
 					ulong ulongValue = Convert.ToUInt64 (value);
 					retVal = ulongValue.ToString ();
 				} else {
Index: Test/System/ChangeLog
===================================================================
--- Test/System/ChangeLog	(revision 66386)
+++ Test/System/ChangeLog	(working copy)
@@ -1,3 +1,8 @@
+2006-10-07  Gert Driesen  <[EMAIL PROTECTED]>
+
+	* EnumTest.cs: Improved TestFormat_Args tests to check whether correct
+	exception is thrown.
+
 2006-09-05  Raja R Harinath  <[EMAIL PROTECTED]>
 
 	* DateTimeTest.cs (Kind): Add test for DateTime.Today.
Index: Test/System/EnumTest.cs
===================================================================
--- Test/System/EnumTest.cs	(revision 66386)
+++ Test/System/EnumTest.cs	(working copy)
@@ -84,62 +84,72 @@
 		try {
 			TestingEnum x = TestingEnum.Test;
 			Enum.Format(null, x, "G");
-			Fail("null first arg not caught.");
-		} catch (ArgumentNullException) {
-			// do nothing
+			Fail("#A1: null first arg not caught.");
+		} catch (ArgumentNullException ex) {
+			AssertEquals ("#A2", "enumType", ex.ParamName);
 		} catch (Exception e) {
-			Fail("first arg null, wrong exception: " + e.ToString());
+			Fail("#A3: first arg null, wrong exception: " + e.ToString());
 		}
 
 		try {
 			Enum.Format(typeof(TestingEnum), null, "G");
-			Fail("null second arg not caught.");
-		} catch (ArgumentNullException) {
-			// do nothing
+			Fail("#B1: null second arg not caught.");
+		} catch (ArgumentNullException ex) {
+			AssertEquals ("#B2", "value", ex.ParamName);
 		} catch (Exception e) {
-			Fail("second arg null, wrong exception: " + e.ToString());
+			Fail("#B3: second arg null, wrong exception: " + e.ToString());
 		}
 
 		try {
 			TestingEnum x = TestingEnum.Test;
 			Enum.Format(x.GetType(), x, null);
-			Fail("null third arg not caught.");
-		} catch (ArgumentNullException) {
-			// do nothing
+			Fail("#C1: null third arg not caught.");
+		} catch (ArgumentNullException ex) {
+			AssertEquals ("#C2", "format", ex.ParamName);
 		} catch (Exception e) {
-			Fail("third arg null, wrong exception: " + e.ToString());
+			Fail("#C3: third arg null, wrong exception: " + e.ToString());
 		}
 
 		try {
 			TestingEnum x = TestingEnum.Test;
 			Enum.Format(typeof(string), x, "G");
-			Fail("bad type arg not caught.");
+			Fail("#D1: bad type arg not caught.");
 		} catch (ArgumentException) {
-			// do nothing
+			// Type provided must be an Enum
 		} catch (Exception e) {
-			Fail("bad type, wrong exception: " + e.ToString());
+			Fail("#D2: bad type, wrong exception: " + e.ToString());
 		}
 
 		try {
 			TestingEnum x = TestingEnum.Test;
 			TestingEnum2 y = TestingEnum2.Test;
 			Enum.Format(y.GetType(), x, "G");
-			Fail("wrong enum type not caught.");
-		} catch (ArgumentException) {
-			// do nothing
+			Fail("#E1: wrong enum type not caught.");
+		} catch (ArgumentException ex) {
+			// Object must be the same type as the enum. The type passed in was
+			// MonoTests.System.EnumTest.TestingEnum2; the enum type was
+			// MonoTests.System.EnumTest.TestingEnum
+			AssertNotNull ("#E2", ex.Message);
+			Assert ("#E3", ex.Message.IndexOf (typeof (TestingEnum2).FullName) != -1);
+			Assert ("#E4", ex.Message.IndexOf (typeof (TestingEnum).FullName) != -1);
 		} catch (Exception e) {
-			Fail("wrong enum type, wrong exception: " + e.ToString());
+			Fail("#E5: wrong enum type, wrong exception: " + e.ToString());
 		}
 
 		try {
 			String bad = "huh?";
 			TestingEnum x = TestingEnum.Test;
 			Enum.Format(x.GetType(), bad, "G");
-			Fail("non-enum object not caught.");
-		} catch (ArgumentException) {
-			// do nothing
+			Fail("#F1: non-enum object not caught.");
+		} catch (ArgumentException ex) {
+			// Enum underlying type and the object must be the same type or
+			// object. Type passed in was String.String; the enum underlying
+			// was System.Int32
+			AssertNotNull ("#F2", ex.Message);
+			Assert ("#F3", ex.Message.IndexOf (typeof (string).FullName) != -1);
+			Assert ("#F4", ex.Message.IndexOf (typeof (int).FullName) != -1);
 		} catch (Exception e) {
-			Fail("non-enum object, wrong exception: " + e.ToString());
+			Fail("#F5: non-enum object, wrong exception: " + e.ToString());
 		}
 
 		string[] codes = {"a", "b", "c", "ad", "e", "af", "ag", "h", 
@@ -159,17 +169,17 @@
 			}
 		}
 
-		TestingEnum ex = TestingEnum.Test;
-		AssertEquals("decimal format wrong", 
-			     "3", Enum.Format(ex.GetType(), ex, "d"));
+		TestingEnum test = TestingEnum.Test;
+		AssertEquals("decimal format wrong",
+				 "3", Enum.Format (test.GetType (), test, "d"));
 		AssertEquals("decimal format wrong for ulong enums", 
 			     "18446744073709551615", Enum.Format(typeof(TestingEnum3), TestingEnum3.Test, "d"));
-		AssertEquals("named format wrong", 
-			     "Test", Enum.Format(ex.GetType(), ex, "g"));
-		AssertEquals("hex format wrong", 
-			     "00000003", Enum.Format(ex.GetType(), ex, "x"));
-		AssertEquals("bitfield format wrong", 
-			     "Test", Enum.Format(ex.GetType(), ex, "f"));
+		AssertEquals("named format wrong",
+				 "Test", Enum.Format (test.GetType (), test, "g"));
+		AssertEquals("hex format wrong",
+				 "00000003", Enum.Format (test.GetType (), test, "x"));
+		AssertEquals("bitfield format wrong",
+				 "Test", Enum.Format (test.GetType (), test, "f"));
 	}
 
 	public void TestFormat_FormatSpecifier ()
_______________________________________________
Mono-devel-list mailing list
Mono-devel-list@lists.ximian.com
http://lists.ximian.com/mailman/listinfo/mono-devel-list

Reply via email to