Adding some formatter tests validating the updated float/double behavior (dotnet...
authorTanner Gooding <tagoo@outlook.com>
Wed, 27 Feb 2019 02:58:22 +0000 (18:58 -0800)
committerGitHub <noreply@github.com>
Wed, 27 Feb 2019 02:58:22 +0000 (18:58 -0800)
* Adding some formatter tests validating the updated float/double behavior

* Adding a regression test for ToString("R") on integral types, asserting it isn't supported

Commit migrated from https://github.com/dotnet/corefx/commit/54e341c9ba4ea452b098f2ec9dbcf58da7b33ed6

13 files changed:
src/libraries/Common/tests/System/RealFormatterTestsBase.netcoreapp.cs [new file with mode: 0644]
src/libraries/System.Memory/tests/ParsersAndFormatters/Formatter/RealFormatterTests.netcoreapp.cs [new file with mode: 0644]
src/libraries/System.Memory/tests/System.Memory.Tests.csproj
src/libraries/System.Runtime/tests/System.Runtime.Tests.csproj
src/libraries/System.Runtime/tests/System/ByteTests.cs
src/libraries/System.Runtime/tests/System/Int16Tests.cs
src/libraries/System.Runtime/tests/System/Int32Tests.cs
src/libraries/System.Runtime/tests/System/Int64Tests.cs
src/libraries/System.Runtime/tests/System/RealFormatterTests.netcoreapp.cs [new file with mode: 0644]
src/libraries/System.Runtime/tests/System/SByteTests.cs
src/libraries/System.Runtime/tests/System/UInt16Tests.cs
src/libraries/System.Runtime/tests/System/UInt32Tests.cs
src/libraries/System.Runtime/tests/System/UInt64Tests.cs

diff --git a/src/libraries/Common/tests/System/RealFormatterTestsBase.netcoreapp.cs b/src/libraries/Common/tests/System/RealFormatterTestsBase.netcoreapp.cs
new file mode 100644 (file)
index 0000000..755e308
--- /dev/null
@@ -0,0 +1,515 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System.Collections.Generic;
+using System.Linq;
+using Xunit;
+
+namespace System.Tests
+{
+    public abstract class RealFormatterTestsBase
+    {
+        // The following methods need to be implemented for the tests to run:
+        protected abstract string InvariantToStringDouble(double d, string format);
+        protected abstract string InvariantToStringSingle(float f, string format);
+
+        [ActiveIssue("https://github.com/dotnet/corefx/issues/35566")]
+        [Theory]
+        [InlineData(double.Epsilon, "¤0.00")]
+        [InlineData(double.MaxValue, "¤179,769,313,486,231,570,814,527,423,731,704,356,798,070,567,525,844,996,598,917,476,803,157,260,780,028,538,760,589,558,632,766,878,171,540,458,953,514,382,464,234,321,326,889,464,182,768,467,546,703,537,516,986,049,910,576,551,282,076,245,490,090,389,328,944,075,868,508,455,133,942,304,583,236,903,222,948,165,808,559,332,123,348,274,797,826,204,144,723,168,738,177,180,919,299,881,250,404,026,184,124,858,368.00")]
+        [InlineData(Math.E, "¤2.72")]
+        [InlineData(Math.PI, "¤3.14")]
+        [InlineData(0.0, "¤0.00")]
+        [InlineData(0.84551240822557006, "¤0.85")]
+        [InlineData(1.0, "¤1.00")]
+        [InlineData(1844674407370955.25, "¤1,844,674,407,370,955.25")]
+        public void TestFormatterDouble_C(double value, string expectedResult) => TestFormatterDouble_Standard(value, "C", expectedResult);
+
+        [ActiveIssue("https://github.com/dotnet/corefx/issues/35566")]
+        [Theory]
+        [InlineData(double.Epsilon, "¤0.0000")]
+        [InlineData(double.MaxValue, "¤179,769,313,486,231,570,814,527,423,731,704,356,798,070,567,525,844,996,598,917,476,803,157,260,780,028,538,760,589,558,632,766,878,171,540,458,953,514,382,464,234,321,326,889,464,182,768,467,546,703,537,516,986,049,910,576,551,282,076,245,490,090,389,328,944,075,868,508,455,133,942,304,583,236,903,222,948,165,808,559,332,123,348,274,797,826,204,144,723,168,738,177,180,919,299,881,250,404,026,184,124,858,368.0000")]
+        [InlineData(Math.E, "¤2.7183")]
+        [InlineData(Math.PI, "¤3.1416")]
+        [InlineData(0.0, "¤0.0000")]
+        [InlineData(0.84551240822557006, "¤0.8455")]
+        [InlineData(1.0, "¤1.0000")]
+        [InlineData(1844674407370955.25, "¤1,844,674,407,370,955.2500")]
+        public void TestFormatterDouble_C4(double value, string expectedResult) => TestFormatterDouble_Standard(value, "C4", expectedResult);
+
+        [ActiveIssue("https://github.com/dotnet/corefx/issues/35566")]
+        [Theory]
+        [InlineData(double.Epsilon, "¤0.00000000000000000000")]
+        [InlineData(double.MaxValue, "¤179,769,313,486,231,570,814,527,423,731,704,356,798,070,567,525,844,996,598,917,476,803,157,260,780,028,538,760,589,558,632,766,878,171,540,458,953,514,382,464,234,321,326,889,464,182,768,467,546,703,537,516,986,049,910,576,551,282,076,245,490,090,389,328,944,075,868,508,455,133,942,304,583,236,903,222,948,165,808,559,332,123,348,274,797,826,204,144,723,168,738,177,180,919,299,881,250,404,026,184,124,858,368.00000000000000000000")]
+        [InlineData(Math.E, "¤2.71828182845904509080")]
+        [InlineData(Math.PI, "¤3.14159265358979311600")]
+        [InlineData(0.0, "¤0.00000000000000000000")]
+        [InlineData(0.84551240822557006, "¤0.84551240822557005572")]
+        [InlineData(1.0, "¤1.00000000000000000000")]
+        [InlineData(1844674407370955.25, "¤1,844,674,407,370,955.25000000000000000000")]
+        public void TestFormatterDouble_C20(double value, string expectedResult) => TestFormatterDouble_Standard(value, "C20", expectedResult);
+
+        [Theory]
+        [InlineData(double.Epsilon, "4.940656E-324")]
+        [InlineData(double.MaxValue, "1.797693E+308")]
+        [InlineData(Math.E, "2.718282E+000")]
+        [InlineData(Math.PI, "3.141593E+000")]
+        [InlineData(0.0, "0.000000E+000")]
+        [InlineData(0.84551240822557006, "8.455124E-001")]
+        [InlineData(1.0, "1.000000E+000")]
+        [InlineData(1844674407370955.25, "1.844674E+015")]
+        public void TestFormatterDouble_E(double value, string expectedResult) => TestFormatterDouble_Standard(value, "E", expectedResult);
+
+        [Theory]
+        [InlineData(double.Epsilon, "4.9407E-324")]
+        [InlineData(double.MaxValue, "1.7977E+308")]
+        [InlineData(Math.E, "2.7183E+000")]
+        [InlineData(Math.PI, "3.1416E+000")]
+        [InlineData(0.0, "0.0000E+000")]
+        [InlineData(0.84551240822557006, "8.4551E-001")]
+        [InlineData(1.0, "1.0000E+000")]
+        [InlineData(1844674407370955.25, "1.8447E+015")]
+        public void TestFormatterDouble_E4(double value, string expectedResult) => TestFormatterDouble_Standard(value, "E4", expectedResult);
+
+        [Theory]
+        [InlineData(double.Epsilon, "4.94065645841246544177E-324")]
+        [InlineData(double.MaxValue, "1.79769313486231570815E+308")]
+        [InlineData(Math.E, "2.71828182845904509080E+000")]
+        [InlineData(Math.PI, "3.14159265358979311600E+000")]
+        [InlineData(0.0, "0.00000000000000000000E+000")]
+        [InlineData(0.84551240822557006, "8.45512408225570055720E-001")]
+        [InlineData(1.0, "1.00000000000000000000E+000")]
+        [InlineData(1844674407370955.25, "1.84467440737095525000E+015")]
+        public void TestFormatterDouble_E20(double value, string expectedResult) => TestFormatterDouble_Standard(value, "E20", expectedResult);
+
+        [Theory]
+        [InlineData(double.Epsilon, "0.00")]
+        [InlineData(double.MaxValue, "179769313486231570814527423731704356798070567525844996598917476803157260780028538760589558632766878171540458953514382464234321326889464182768467546703537516986049910576551282076245490090389328944075868508455133942304583236903222948165808559332123348274797826204144723168738177180919299881250404026184124858368.00")]
+        [InlineData(Math.E, "2.72")]
+        [InlineData(Math.PI, "3.14")]
+        [InlineData(0.0, "0.00")]
+        [InlineData(0.84551240822557006, "0.85")]
+        [InlineData(1.0, "1.00")]
+        [InlineData(1844674407370955.25, "1844674407370955.25")]
+        public void TestFormatterDouble_F(double value, string expectedResult) => TestFormatterDouble_Standard(value, "F", expectedResult);
+
+        [Theory]
+        [InlineData(double.Epsilon, "0.0000")]
+        [InlineData(double.MaxValue, "179769313486231570814527423731704356798070567525844996598917476803157260780028538760589558632766878171540458953514382464234321326889464182768467546703537516986049910576551282076245490090389328944075868508455133942304583236903222948165808559332123348274797826204144723168738177180919299881250404026184124858368.0000")]
+        [InlineData(Math.E, "2.7183")]
+        [InlineData(Math.PI, "3.1416")]
+        [InlineData(0.0, "0.0000")]
+        [InlineData(0.84551240822557006, "0.8455")]
+        [InlineData(1.0, "1.0000")]
+        [InlineData(1844674407370955.25, "1844674407370955.2500")]
+        public void TestFormatterDouble_F4(double value, string expectedResult) => TestFormatterDouble_Standard(value, "F4", expectedResult);
+
+        [Theory]
+        [InlineData(double.Epsilon, "0.00000000000000000000")]
+        [InlineData(double.MaxValue, "179769313486231570814527423731704356798070567525844996598917476803157260780028538760589558632766878171540458953514382464234321326889464182768467546703537516986049910576551282076245490090389328944075868508455133942304583236903222948165808559332123348274797826204144723168738177180919299881250404026184124858368.00000000000000000000")]
+        [InlineData(Math.E, "2.71828182845904509080")]
+        [InlineData(Math.PI, "3.14159265358979311600")]
+        [InlineData(0.0, "0.00000000000000000000")]
+        [InlineData(0.84551240822557006, "0.84551240822557005572")]
+        [InlineData(1.0, "1.00000000000000000000")]
+        [InlineData(1844674407370955.25, "1844674407370955.25000000000000000000")]
+        public void TestFormatterDouble_F20(double value, string expectedResult) => TestFormatterDouble_Standard(value, "F20", expectedResult);
+
+        [Theory]
+        [InlineData(double.Epsilon, "5E-324")]
+        [InlineData(double.MaxValue, "1.7976931348623157E+308")]
+        [InlineData(Math.E, "2.718281828459045")]
+        [InlineData(Math.PI, "3.141592653589793")]
+        [InlineData(0.0, "0")]
+        [InlineData(0.84551240822557006, "0.8455124082255701")]
+        [InlineData(1.0, "1")]
+        [InlineData(1844674407370955.25, "1844674407370955.2")]
+        public void TestFormatterDouble_G(double value, string expectedResult) => TestFormatterDouble_Standard(value, "G", expectedResult);
+
+        [Theory]
+        [InlineData(double.Epsilon, "4.941E-324")]
+        [InlineData(double.MaxValue, "1.798E+308")]
+        [InlineData(Math.E, "2.718")]
+        [InlineData(Math.PI, "3.142")]
+        [InlineData(0.0, "0")]
+        [InlineData(0.84551240822557006, "0.8455")]
+        [InlineData(1.0, "1")]
+        [InlineData(1844674407370955.25, "1.845E+15")]
+        public void TestFormatterDouble_G4(double value, string expectedResult) => TestFormatterDouble_Standard(value, "G4", expectedResult);
+
+        [Theory]
+        [InlineData(double.Epsilon, "4.9406564584124654418E-324")]
+        [InlineData(double.MaxValue, "1.7976931348623157081E+308")]
+        [InlineData(Math.E, "2.7182818284590450908")]
+        [InlineData(Math.PI, "3.141592653589793116")]
+        [InlineData(0.0, "0")]
+        [InlineData(0.84551240822557006, "0.84551240822557005572")]
+        [InlineData(1.0, "1")]
+        [InlineData(1844674407370955.25, "1844674407370955.25")]
+        public void TestFormatterDouble_G20(double value, string expectedResult) => TestFormatterDouble_Standard(value, "G20", expectedResult);
+
+        [Theory]
+        [InlineData(double.Epsilon, "0.00")]
+        [InlineData(double.MaxValue, "179,769,313,486,231,570,814,527,423,731,704,356,798,070,567,525,844,996,598,917,476,803,157,260,780,028,538,760,589,558,632,766,878,171,540,458,953,514,382,464,234,321,326,889,464,182,768,467,546,703,537,516,986,049,910,576,551,282,076,245,490,090,389,328,944,075,868,508,455,133,942,304,583,236,903,222,948,165,808,559,332,123,348,274,797,826,204,144,723,168,738,177,180,919,299,881,250,404,026,184,124,858,368.00")]
+        [InlineData(Math.E, "2.72")]
+        [InlineData(Math.PI, "3.14")]
+        [InlineData(0.0, "0.00")]
+        [InlineData(0.84551240822557006, "0.85")]
+        [InlineData(1.0, "1.00")]
+        [InlineData(1844674407370955.25, "1,844,674,407,370,955.25")]
+        public void TestFormatterDouble_N(double value, string expectedResult) => TestFormatterDouble_Standard(value, "N", expectedResult);
+
+        [Theory]
+        [InlineData(double.Epsilon, "0.0000")]
+        [InlineData(double.MaxValue, "179,769,313,486,231,570,814,527,423,731,704,356,798,070,567,525,844,996,598,917,476,803,157,260,780,028,538,760,589,558,632,766,878,171,540,458,953,514,382,464,234,321,326,889,464,182,768,467,546,703,537,516,986,049,910,576,551,282,076,245,490,090,389,328,944,075,868,508,455,133,942,304,583,236,903,222,948,165,808,559,332,123,348,274,797,826,204,144,723,168,738,177,180,919,299,881,250,404,026,184,124,858,368.0000")]
+        [InlineData(Math.E, "2.7183")]
+        [InlineData(Math.PI, "3.1416")]
+        [InlineData(0.0, "0.0000")]
+        [InlineData(0.84551240822557006, "0.8455")]
+        [InlineData(1.0, "1.0000")]
+        [InlineData(1844674407370955.25, "1,844,674,407,370,955.2500")]
+        public void TestFormatterDouble_N4(double value, string expectedResult) => TestFormatterDouble_Standard(value, "N4", expectedResult);
+
+        [Theory]
+        [InlineData(double.Epsilon, "0.00000000000000000000")]
+        [InlineData(double.MaxValue, "179,769,313,486,231,570,814,527,423,731,704,356,798,070,567,525,844,996,598,917,476,803,157,260,780,028,538,760,589,558,632,766,878,171,540,458,953,514,382,464,234,321,326,889,464,182,768,467,546,703,537,516,986,049,910,576,551,282,076,245,490,090,389,328,944,075,868,508,455,133,942,304,583,236,903,222,948,165,808,559,332,123,348,274,797,826,204,144,723,168,738,177,180,919,299,881,250,404,026,184,124,858,368.00000000000000000000")]
+        [InlineData(Math.E, "2.71828182845904509080")]
+        [InlineData(Math.PI, "3.14159265358979311600")]
+        [InlineData(0.0, "0.00000000000000000000")]
+        [InlineData(0.84551240822557006, "0.84551240822557005572")]
+        [InlineData(1.0, "1.00000000000000000000")]
+        [InlineData(1844674407370955.25, "1,844,674,407,370,955.25000000000000000000")]
+        public void TestFormatterDouble_N20(double value, string expectedResult) => TestFormatterDouble_Standard(value, "N20", expectedResult);
+
+        [Theory]
+        [InlineData(double.Epsilon, "0.00 %")]
+        [InlineData(double.MaxValue, "17,976,931,348,623,157,081,452,742,373,170,435,679,807,056,752,584,499,659,891,747,680,315,726,078,002,853,876,058,955,863,276,687,817,154,045,895,351,438,246,423,432,132,688,946,418,276,846,754,670,353,751,698,604,991,057,655,128,207,624,549,009,038,932,894,407,586,850,845,513,394,230,458,323,690,322,294,816,580,855,933,212,334,827,479,782,620,414,472,316,873,817,718,091,929,988,125,040,402,618,412,485,836,800.00 %")]
+        [InlineData(Math.E, "271.83 %")]
+        [InlineData(Math.PI, "314.16 %")]
+        [InlineData(0.0, "0.00 %")]
+        [InlineData(0.84551240822557006, "84.55 %")]
+        [InlineData(1.0, "100.00 %")]
+        [InlineData(1844674407370955.25, "184,467,440,737,095,525.00 %")]
+        public void TestFormatterDouble_P(double value, string expectedResult) => TestFormatterDouble_Standard(value, "P", expectedResult);
+
+        [Theory]
+        [InlineData(double.Epsilon, "0.0000 %")]
+        [InlineData(double.MaxValue, "17,976,931,348,623,157,081,452,742,373,170,435,679,807,056,752,584,499,659,891,747,680,315,726,078,002,853,876,058,955,863,276,687,817,154,045,895,351,438,246,423,432,132,688,946,418,276,846,754,670,353,751,698,604,991,057,655,128,207,624,549,009,038,932,894,407,586,850,845,513,394,230,458,323,690,322,294,816,580,855,933,212,334,827,479,782,620,414,472,316,873,817,718,091,929,988,125,040,402,618,412,485,836,800.0000 %")]
+        [InlineData(Math.E, "271.8282 %")]
+        [InlineData(Math.PI, "314.1593 %")]
+        [InlineData(0.0, "0.0000 %")]
+        [InlineData(0.84551240822557006, "84.5512 %")]
+        [InlineData(1.0, "100.0000 %")]
+        [InlineData(1844674407370955.25, "184,467,440,737,095,525.0000 %")]
+        public void TestFormatterDouble_P4(double value, string expectedResult) => TestFormatterDouble_Standard(value, "P4", expectedResult);
+
+        [Theory]
+        [InlineData(double.Epsilon, "0.00000000000000000000 %")]
+        [InlineData(double.MaxValue, "17,976,931,348,623,157,081,452,742,373,170,435,679,807,056,752,584,499,659,891,747,680,315,726,078,002,853,876,058,955,863,276,687,817,154,045,895,351,438,246,423,432,132,688,946,418,276,846,754,670,353,751,698,604,991,057,655,128,207,624,549,009,038,932,894,407,586,850,845,513,394,230,458,323,690,322,294,816,580,855,933,212,334,827,479,782,620,414,472,316,873,817,718,091,929,988,125,040,402,618,412,485,836,800.00000000000000000000 %")]
+        [InlineData(Math.E, "271.82818284590450907956 %")]
+        [InlineData(Math.PI, "314.15926535897931159980 %")]
+        [InlineData(0.0, "0.00000000000000000000 %")]
+        [InlineData(0.84551240822557006, "84.55124082255700557198 %")]
+        [InlineData(1.0, "100.00000000000000000000 %")]
+        [InlineData(1844674407370955.25, "184,467,440,737,095,525.00000000000000000000 %")]
+        public void TestFormatterDouble_P20(double value, string expectedResult) => TestFormatterDouble_Standard(value, "P20", expectedResult);
+
+        [Theory]
+        [InlineData(double.Epsilon, "5E-324")]
+        [InlineData(double.MaxValue, "1.7976931348623157E+308")]
+        [InlineData(Math.E, "2.718281828459045")]
+        [InlineData(Math.PI, "3.141592653589793")]
+        [InlineData(0.0, "0")]
+        [InlineData(0.84551240822557006, "0.8455124082255701")]
+        [InlineData(1.0, "1")]
+        [InlineData(1844674407370955.25, "1844674407370955.2")]
+        public void TestFormatterDouble_R(double value, string expectedResult) => TestFormatterDouble_Standard(value, "R", expectedResult);
+
+        [Theory]
+        [InlineData(double.Epsilon, "5E-324")]
+        [InlineData(double.MaxValue, "1.7976931348623157E+308")]
+        [InlineData(Math.E, "2.718281828459045")]
+        [InlineData(Math.PI, "3.141592653589793")]
+        [InlineData(0.0, "0")]
+        [InlineData(0.84551240822557006, "0.8455124082255701")]
+        [InlineData(1.0, "1")]
+        [InlineData(1844674407370955.25, "1844674407370955.2")]
+        public void TestFormatterDouble_R4(double value, string expectedResult) => TestFormatterDouble_Standard(value, "R4", expectedResult);
+
+        [Theory]
+        [InlineData(double.Epsilon, "5E-324")]
+        [InlineData(double.MaxValue, "1.7976931348623157E+308")]
+        [InlineData(Math.E, "2.718281828459045")]
+        [InlineData(Math.PI, "3.141592653589793")]
+        [InlineData(0.0, "0")]
+        [InlineData(0.84551240822557006, "0.8455124082255701")]
+        [InlineData(1.0, "1")]
+        [InlineData(1844674407370955.25, "1844674407370955.2")]
+        public void TestFormatterDouble_R20(double value, string expectedResult) => TestFormatterDouble_Standard(value, "R20", expectedResult);
+
+        public static IEnumerable<object[]> TestFormatterDouble_InvalidMemberData =>
+            from value in new[] { double.Epsilon, double.MaxValue, Math.E, Math.PI, 0.0, 0.84551240822557006, 1.0, 1844674407370955.25 }
+            from format in new[] { "D", "D4", "D20", "X", "X4", "X20" }
+            select new object[] { value, format };
+
+        [Theory]
+        [MemberData(nameof(TestFormatterDouble_InvalidMemberData))]
+        public void TestFormatterDouble_Invalid(double value, string format) => Assert.Throws<FormatException>(() => InvariantToStringDouble(value, format));
+
+        private void TestFormatterDouble_Standard(double value, string format, string expectedResult)
+        {
+            string actualResult = InvariantToStringDouble(value, format);
+            Assert.Equal(expectedResult, actualResult);
+        }
+
+        [ActiveIssue("https://github.com/dotnet/corefx/issues/35566")]
+        [Theory]
+        [InlineData(float.Epsilon, "¤0.00")]
+        [InlineData(float.MaxValue, "¤340,282,346,638,528,859,811,704,183,484,516,925,440.00")]
+        [InlineData(MathF.E, "¤2.72")]
+        [InlineData(MathF.PI, "¤3.14")]
+        [InlineData(0.0f, "¤0.00")]
+        [InlineData(0.845512390, "¤0.85")]
+        [InlineData(1.0f, "¤1.00")]
+        [InlineData(429496.72, "¤429,496.72")]
+        public void TestFormatterSingle_C(float value, string expectedResult) => TestFormatterSingle_Standard(value, "C", expectedResult);
+
+        [ActiveIssue("https://github.com/dotnet/corefx/issues/35566")]
+        [Theory]
+        [InlineData(float.Epsilon, "¤0.0000")]
+        [InlineData(float.MaxValue, "¤340,282,346,638,528,859,811,704,183,484,516,925,440.0000")]
+        [InlineData(MathF.E, "¤2.7183")]
+        [InlineData(MathF.PI, "¤3.1416")]
+        [InlineData(0.0f, "¤0.0000")]
+        [InlineData(0.845512390, "¤0.8455")]
+        [InlineData(1.0f, "¤1.0000")]
+        [InlineData(429496.72, "¤429,496.7188")]
+        public void TestFormatterSingle_C4(float value, string expectedResult) => TestFormatterSingle_Standard(value, "C4", expectedResult);
+
+        [ActiveIssue("https://github.com/dotnet/corefx/issues/35566")]
+        [Theory]
+        [InlineData(float.Epsilon, "¤0.00000000000000000000")]
+        [InlineData(float.MaxValue, "¤340,282,346,638,528,859,811,704,183,484,516,925,440.00000000000000000000")]
+        [InlineData(MathF.E, "¤2.71828174591064453125")]
+        [InlineData(MathF.PI, "¤3.14159274101257324219")]
+        [InlineData(0.0f, "¤0.00000000000000000000")]
+        [InlineData(0.845512390, "¤0.84551239013671875000")]
+        [InlineData(1.0f, "¤1.00000000000000000000")]
+        [InlineData(429496.72, "¤429,496.71875000000000000000")]
+        public void TestFormatterSingle_C20(float value, string expectedResult) => TestFormatterSingle_Standard(value, "C20", expectedResult);
+
+        [Theory]
+        [InlineData(float.Epsilon, "1.401298E-045")]
+        [InlineData(float.MaxValue, "3.402823E+038")]
+        [InlineData(MathF.E, "2.718282E+000")]
+        [InlineData(MathF.PI, "3.141593E+000")]
+        [InlineData(0.0f, "0.000000E+000")]
+        [InlineData(0.845512390, "8.455124E-001")]
+        [InlineData(1.0f, "1.000000E+000")]
+        [InlineData(429496.72, "4.294967E+005")]
+        public void TestFormatterSingle_E(float value, string expectedResult) => TestFormatterSingle_Standard(value, "E", expectedResult);
+
+        [Theory]
+        [InlineData(float.Epsilon, "1.4013E-045")]
+        [InlineData(float.MaxValue, "3.4028E+038")]
+        [InlineData(MathF.E, "2.7183E+000")]
+        [InlineData(MathF.PI, "3.1416E+000")]
+        [InlineData(0.0f, "0.0000E+000")]
+        [InlineData(0.845512390, "8.4551E-001")]
+        [InlineData(1.0f, "1.0000E+000")]
+        [InlineData(429496.72, "4.2950E+005")]
+        public void TestFormatterSingle_E4(float value, string expectedResult) => TestFormatterSingle_Standard(value, "E4", expectedResult);
+
+        [Theory]
+        [InlineData(float.Epsilon, "1.40129846432481707092E-045")]
+        [InlineData(float.MaxValue, "3.40282346638528859812E+038")]
+        [InlineData(MathF.E, "2.71828174591064453125E+000")]
+        [InlineData(MathF.PI, "3.14159274101257324219E+000")]
+        [InlineData(0.0f, "0.00000000000000000000E+000")]
+        [InlineData(0.845512390, "8.45512390136718750000E-001")]
+        [InlineData(1.0f, "1.00000000000000000000E+000")]
+        [InlineData(429496.72, "4.29496718750000000000E+005")]
+        public void TestFormatterSingle_E20(float value, string expectedResult) => TestFormatterSingle_Standard(value, "E20", expectedResult);
+
+        [Theory]
+        [InlineData(float.Epsilon, "0.00")]
+        [InlineData(float.MaxValue, "340282346638528859811704183484516925440.00")]
+        [InlineData(MathF.E, "2.72")]
+        [InlineData(MathF.PI, "3.14")]
+        [InlineData(0.0f, "0.00")]
+        [InlineData(0.845512390, "0.85")]
+        [InlineData(1.0f, "1.00")]
+        [InlineData(429496.72, "429496.72")]
+        public void TestFormatterSingle_F(float value, string expectedResult) => TestFormatterSingle_Standard(value, "F", expectedResult);
+
+        [Theory]
+        [InlineData(float.Epsilon, "0.0000")]
+        [InlineData(float.MaxValue, "340282346638528859811704183484516925440.0000")]
+        [InlineData(MathF.E, "2.7183")]
+        [InlineData(MathF.PI, "3.1416")]
+        [InlineData(0.0f, "0.0000")]
+        [InlineData(0.845512390, "0.8455")]
+        [InlineData(1.0f, "1.0000")]
+        [InlineData(429496.72, "429496.7188")]
+        public void TestFormatterSingle_F4(float value, string expectedResult) => TestFormatterSingle_Standard(value, "F4", expectedResult);
+
+        [Theory]
+        [InlineData(float.Epsilon, "0.00000000000000000000")]
+        [InlineData(float.MaxValue, "340282346638528859811704183484516925440.00000000000000000000")]
+        [InlineData(MathF.E, "2.71828174591064453125")]
+        [InlineData(MathF.PI, "3.14159274101257324219")]
+        [InlineData(0.0f, "0.00000000000000000000")]
+        [InlineData(0.845512390, "0.84551239013671875000")]
+        [InlineData(1.0f, "1.00000000000000000000")]
+        [InlineData(429496.72, "429496.71875000000000000000")]
+        public void TestFormatterSingle_F20(float value, string expectedResult) => TestFormatterSingle_Standard(value, "F20", expectedResult);
+
+        [Theory]
+        [InlineData(float.Epsilon, "1E-45")]
+        [InlineData(float.MaxValue, "3.4028235E+38")]
+        [InlineData(MathF.E, "2.7182817")]
+        [InlineData(MathF.PI, "3.1415927")]
+        [InlineData(0.0f, "0")]
+        [InlineData(0.845512390, "0.8455124")]
+        [InlineData(1.0f, "1")]
+        [InlineData(429496.72, "429496.72")]
+        public void TestFormatterSingle_G(float value, string expectedResult) => TestFormatterSingle_Standard(value, "G", expectedResult);
+
+        [Theory]
+        [InlineData(float.Epsilon, "1.401E-45")]
+        [InlineData(float.MaxValue, "3.403E+38")]
+        [InlineData(MathF.E, "2.718")]
+        [InlineData(MathF.PI, "3.142")]
+        [InlineData(0.0f, "0")]
+        [InlineData(0.845512390, "0.8455")]
+        [InlineData(1.0f, "1")]
+        [InlineData(429496.72, "4.295E+05")]
+        public void TestFormatterSingle_G4(float value, string expectedResult) => TestFormatterSingle_Standard(value, "G4", expectedResult);
+
+        [Theory]
+        [InlineData(float.Epsilon, "1.4012984643248170709E-45")]
+        [InlineData(float.MaxValue, "3.4028234663852885981E+38")]
+        [InlineData(MathF.E, "2.7182817459106445312")]
+        [InlineData(MathF.PI, "3.1415927410125732422")]
+        [InlineData(0.0f, "0")]
+        [InlineData(0.845512390, "0.84551239013671875")]
+        [InlineData(1.0f, "1")]
+        [InlineData(429496.72, "429496.71875")]
+        public void TestFormatterSingle_G20(float value, string expectedResult) => TestFormatterSingle_Standard(value, "G20", expectedResult);
+
+        [Theory]
+        [InlineData(float.Epsilon, "0.00")]
+        [InlineData(float.MaxValue, "340,282,346,638,528,859,811,704,183,484,516,925,440.00")]
+        [InlineData(MathF.E, "2.72")]
+        [InlineData(MathF.PI, "3.14")]
+        [InlineData(0.0f, "0.00")]
+        [InlineData(0.845512390, "0.85")]
+        [InlineData(1.0f, "1.00")]
+        [InlineData(429496.72, "429,496.72")]
+        public void TestFormatterSingle_N(float value, string expectedResult) => TestFormatterSingle_Standard(value, "N", expectedResult);
+
+        [Theory]
+        [InlineData(float.Epsilon, "0.0000")]
+        [InlineData(float.MaxValue, "340,282,346,638,528,859,811,704,183,484,516,925,440.0000")]
+        [InlineData(MathF.E, "2.7183")]
+        [InlineData(MathF.PI, "3.1416")]
+        [InlineData(0.0f, "0.0000")]
+        [InlineData(0.845512390, "0.8455")]
+        [InlineData(1.0f, "1.0000")]
+        [InlineData(429496.72, "429,496.7188")]
+        public void TestFormatterSingle_N4(float value, string expectedResult) => TestFormatterSingle_Standard(value, "N4", expectedResult);
+
+        [Theory]
+        [InlineData(float.Epsilon, "0.00000000000000000000")]
+        [InlineData(float.MaxValue, "340,282,346,638,528,859,811,704,183,484,516,925,440.00000000000000000000")]
+        [InlineData(MathF.E, "2.71828174591064453125")]
+        [InlineData(MathF.PI, "3.14159274101257324219")]
+        [InlineData(0.0f, "0.00000000000000000000")]
+        [InlineData(0.845512390, "0.84551239013671875000")]
+        [InlineData(1.0f, "1.00000000000000000000")]
+        [InlineData(429496.72, "429,496.71875000000000000000")]
+        public void TestFormatterSingle_N20(float value, string expectedResult) => TestFormatterSingle_Standard(value, "N20", expectedResult);
+
+        [Theory]
+        [InlineData(float.Epsilon, "0.00 %")]
+        [InlineData(float.MaxValue, "34,028,234,663,852,885,981,170,418,348,451,692,544,000.00 %")]
+        [InlineData(MathF.E, "271.83 %")]
+        [InlineData(MathF.PI, "314.16 %")]
+        [InlineData(0.0f, "0.00 %")]
+        [InlineData(0.845512390, "84.55 %")]
+        [InlineData(1.0f, "100.00 %")]
+        [InlineData(429496.72, "42,949,671.88 %")]
+        public void TestFormatterSingle_P(float value, string expectedResult) => TestFormatterSingle_Standard(value, "P", expectedResult);
+
+        [Theory]
+        [InlineData(float.Epsilon, "0.0000 %")]
+        [InlineData(float.MaxValue, "34,028,234,663,852,885,981,170,418,348,451,692,544,000.0000 %")]
+        [InlineData(MathF.E, "271.8282 %")]
+        [InlineData(MathF.PI, "314.1593 %")]
+        [InlineData(0.0f, "0.0000 %")]
+        [InlineData(0.845512390, "84.5512 %")]
+        [InlineData(1.0f, "100.0000 %")]
+        [InlineData(429496.72, "42,949,671.8750 %")]
+        public void TestFormatterSingle_P4(float value, string expectedResult) => TestFormatterSingle_Standard(value, "P4", expectedResult);
+
+        [Theory]
+        [InlineData(float.Epsilon, "0.00000000000000000000 %")]
+        [InlineData(float.MaxValue, "34,028,234,663,852,885,981,170,418,348,451,692,544,000.00000000000000000000 %")]
+        [InlineData(MathF.E, "271.82817459106445312500 %")]
+        [InlineData(MathF.PI, "314.15927410125732421875 %")]
+        [InlineData(0.0f, "0.00000000000000000000 %")]
+        [InlineData(0.845512390, "84.55123901367187500000 %")]
+        [InlineData(1.0f, "100.00000000000000000000 %")]
+        [InlineData(429496.72, "42,949,671.87500000000000000000 %")]
+        public void TestFormatterSingle_P20(float value, string expectedResult) => TestFormatterSingle_Standard(value, "P20", expectedResult);
+
+        [Theory]
+        [InlineData(float.Epsilon, "1E-45")]
+        [InlineData(float.MaxValue, "3.4028235E+38")]
+        [InlineData(MathF.E, "2.7182817")]
+        [InlineData(MathF.PI, "3.1415927")]
+        [InlineData(0.0f, "0")]
+        [InlineData(0.845512390, "0.8455124")]
+        [InlineData(1.0f, "1")]
+        [InlineData(429496.72, "429496.72")]
+        public void TestFormatterSingle_R(float value, string expectedResult) => TestFormatterSingle_Standard(value, "R", expectedResult);
+
+        [Theory]
+        [InlineData(float.Epsilon, "1E-45")]
+        [InlineData(float.MaxValue, "3.4028235E+38")]
+        [InlineData(MathF.E, "2.7182817")]
+        [InlineData(MathF.PI, "3.1415927")]
+        [InlineData(0.0f, "0")]
+        [InlineData(0.845512390, "0.8455124")]
+        [InlineData(1.0f, "1")]
+        [InlineData(429496.72, "429496.72")]
+        public void TestFormatterSingle_R4(float value, string expectedResult) => TestFormatterSingle_Standard(value, "R4", expectedResult);
+
+        [Theory]
+        [InlineData(float.Epsilon, "1E-45")]
+        [InlineData(float.MaxValue, "3.4028235E+38")]
+        [InlineData(MathF.E, "2.7182817")]
+        [InlineData(MathF.PI, "3.1415927")]
+        [InlineData(0.0f, "0")]
+        [InlineData(0.845512390, "0.8455124")]
+        [InlineData(1.0f, "1")]
+        [InlineData(429496.72, "429496.72")]
+        public void TestFormatterSingle_R20(float value, string expectedResult) => TestFormatterSingle_Standard(value, "R20", expectedResult);
+
+        public static IEnumerable<object[]> TestFormatterSingle_InvalidMemberData =>
+            from value in new[] { float.Epsilon, float.MaxValue, MathF.E, MathF.PI, 0.0, 0.845512390, 1.0, 429496.72 }
+            from format in new[] { "D", "D4", "D20", "X", "X4", "X20" }
+            select new object[] { value, format };
+
+        [Theory]
+        [MemberData(nameof(TestFormatterSingle_InvalidMemberData))]
+        public void TestFormatterSingle_Invalid(float value, string format) => Assert.Throws<FormatException>(() => InvariantToStringSingle(value, format));
+
+        private void TestFormatterSingle_Standard(float value, string format, string expectedResult)
+        {
+            string actualResult = InvariantToStringSingle(value, format);
+            Assert.Equal(expectedResult, actualResult);
+        }
+    }
+}
diff --git a/src/libraries/System.Memory/tests/ParsersAndFormatters/Formatter/RealFormatterTests.netcoreapp.cs b/src/libraries/System.Memory/tests/ParsersAndFormatters/Formatter/RealFormatterTests.netcoreapp.cs
new file mode 100644 (file)
index 0000000..a45006b
--- /dev/null
@@ -0,0 +1,35 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System.Globalization;
+using System.Tests;
+using Xunit;
+
+namespace System.Buffers.Text.Tests
+{
+    public class RealFormatterTests : RealFormatterTestsBase
+    {
+        // The actual tests are defined in: src\Common\tests\System\RealFormatterTestsBase.netcoreapp.cs
+
+        //  We need 1 additional byte, per length, for the terminating null
+        private const int DoubleNumberBufferLength = 767 + 1 + 1;  // 767 for the longest input + 1 for rounding: 4.9406564584124654E-324 
+        private const int SingleNumberBufferLength = 112 + 1 + 1;  // 112 for the longest input + 1 for rounding: 1.40129846E-45
+
+        protected override string InvariantToStringDouble(double d, string format)
+        {
+            Span<byte> s = stackalloc byte[DoubleNumberBufferLength];
+            bool formatSucceeded = Utf8Formatter.TryFormat(d, s, out int bytesWritten, StandardFormat.Parse(format));
+            Assert.True(formatSucceeded, $"Failed to format '{d.ToString(CultureInfo.InvariantCulture)}' using '{format}'.");
+            return s.Slice(0, bytesWritten).ToUtf16String();
+        }
+
+        protected override string InvariantToStringSingle(float f, string format)
+        {
+            Span<byte> s = stackalloc byte[SingleNumberBufferLength];
+            bool formatSucceeded = Utf8Formatter.TryFormat(f, s, out int bytesWritten, StandardFormat.Parse(format));
+            Assert.True(formatSucceeded, $"Failed to format '{f.ToString(CultureInfo.InvariantCulture)}' using '{format}'.");
+            return s.Slice(0, bytesWritten).ToUtf16String();
+        }
+    }
+}
index 03a2eb2..f535f50 100644 (file)
@@ -12,6 +12,8 @@
     <Compile Include="MemoryMarshal\AsReadOnlyRef.cs" />
     <Compile Include="MemoryMarshal\CreateSpan.cs" />
     <Compile Include="MemoryMarshal\CreateReadOnlySpan.cs" />
+    <Compile Include="$(CommonPath)\..\tests\System\RealFormatterTestsBase.netcoreapp.cs" Link="ParsersAndFormatters\Formatter\RealFormatterTestsBase.netcoreapp.cs" />
+    <Compile Include="ParsersAndFormatters\Formatter\RealFormatterTests.netcoreapp.cs" />
     <Compile Include="$(CommonPath)\..\tests\System\RealParserTestsBase.netcoreapp.cs" Link="ParsersAndFormatters\Parser\RealParserTestsBase.netcoreapp.cs" />
     <Compile Include="ParsersAndFormatters\Parser\RealParserTests.netcoreapp.cs" />
     <Compile Include="ReadOnlySpan\Contains.byte.cs" />
index e7c5f10..80a4a9e 100644 (file)
     <Compile Include="System\ArgIteratorTests.netcoreapp.cs" />
     <Compile Include="System\DoubleTests.netcoreapp.cs" />
     <Compile Include="System\SingleTests.netcoreapp.cs" />
+    <Compile Include="$(CommonPath)\..\tests\System\RealFormatterTestsBase.netcoreapp.cs" Link="System\RealFormatterTestsBase.netcoreapp.cs" />
+    <Compile Include="System\RealFormatterTests.netcoreapp.cs" />
     <Compile Include="$(CommonPath)\..\tests\System\RealParserTestsBase.netcoreapp.cs" Link="System\RealParserTestsBase.netcoreapp.cs" />
     <Compile Include="System\RealParserTests.netcoreapp.cs" />
   </ItemGroup>
index 1f746bd..cb12223 100644 (file)
@@ -155,6 +155,10 @@ namespace System.Tests
         public static void ToString_InvalidFormat_ThrowsFormatException()
         {
             byte b = 123;
+            Assert.Throws<FormatException>(() => b.ToString("r")); // Invalid format
+            Assert.Throws<FormatException>(() => b.ToString("r", null)); // Invalid format
+            Assert.Throws<FormatException>(() => b.ToString("R")); // Invalid format
+            Assert.Throws<FormatException>(() => b.ToString("R", null)); // Invalid format
             Assert.Throws<FormatException>(() => b.ToString("Y")); // Invalid format
             Assert.Throws<FormatException>(() => b.ToString("Y", null)); // Invalid format
         }
index 39525c9..1264754 100644 (file)
@@ -176,6 +176,10 @@ namespace System.Tests
         public static void ToString_InvalidFormat_ThrowsFormatException()
         {
             short i = 123;
+            Assert.Throws<FormatException>(() => i.ToString("r")); // Invalid format
+            Assert.Throws<FormatException>(() => i.ToString("r", null)); // Invalid format
+            Assert.Throws<FormatException>(() => i.ToString("R")); // Invalid format
+            Assert.Throws<FormatException>(() => i.ToString("R", null)); // Invalid format
             Assert.Throws<FormatException>(() => i.ToString("Y")); // Invalid format
             Assert.Throws<FormatException>(() => i.ToString("Y", null)); // Invalid format
         }
index dbfecf2..a5a34d6 100644 (file)
@@ -176,6 +176,10 @@ namespace System.Tests
         public static void ToString_InvalidFormat_ThrowsFormatException()
         {
             int i = 123;
+            Assert.Throws<FormatException>(() => i.ToString("r")); // Invalid format
+            Assert.Throws<FormatException>(() => i.ToString("r", null)); // Invalid format
+            Assert.Throws<FormatException>(() => i.ToString("R")); // Invalid format
+            Assert.Throws<FormatException>(() => i.ToString("R", null)); // Invalid format
             Assert.Throws<FormatException>(() => i.ToString("Y")); // Invalid format
             Assert.Throws<FormatException>(() => i.ToString("Y", null)); // Invalid format
         }
index 51de352..2d31151 100644 (file)
@@ -177,6 +177,10 @@ namespace System.Tests
         public static void ToString_InvalidFormat_ThrowsFormatException()
         {
             long i = 123;
+            Assert.Throws<FormatException>(() => i.ToString("r")); // Invalid format
+            Assert.Throws<FormatException>(() => i.ToString("r", null)); // Invalid format
+            Assert.Throws<FormatException>(() => i.ToString("R")); // Invalid format
+            Assert.Throws<FormatException>(() => i.ToString("R", null)); // Invalid format
             Assert.Throws<FormatException>(() => i.ToString("Y")); // Invalid format
             Assert.Throws<FormatException>(() => i.ToString("Y", null)); // Invalid format
         }
diff --git a/src/libraries/System.Runtime/tests/System/RealFormatterTests.netcoreapp.cs b/src/libraries/System.Runtime/tests/System/RealFormatterTests.netcoreapp.cs
new file mode 100644 (file)
index 0000000..03f1129
--- /dev/null
@@ -0,0 +1,23 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System.Globalization;
+
+namespace System.Tests
+{
+    public class RealFormatterTests : RealFormatterTestsBase
+    {
+        // The actual tests are defined in: src\Common\tests\System\RealFormatterTestsBase.netcoreapp.cs
+
+        protected override string InvariantToStringDouble(double d, string format)
+        {
+            return d.ToString(format, CultureInfo.InvariantCulture);
+        }
+
+        protected override string InvariantToStringSingle(float f, string format)
+        {
+            return f.ToString(format, CultureInfo.InvariantCulture);
+        }
+    }
+}
index 82b99a7..439b5a2 100644 (file)
@@ -171,9 +171,13 @@ namespace System.Tests
         [Fact]
         public static void ToString_InvalidFormat_ThrowsFormatException()
         {
-            IComparable comparable = (sbyte)123;
-            AssertExtensions.Throws<ArgumentException>(null, () => comparable.CompareTo("a")); // Obj is not a sbyte
-            AssertExtensions.Throws<ArgumentException>(null, () => comparable.CompareTo(234)); // Obj is not a sbyte
+            sbyte b = 123;
+            Assert.Throws<FormatException>(() => b.ToString("r")); // Invalid format
+            Assert.Throws<FormatException>(() => b.ToString("r", null)); // Invalid format
+            Assert.Throws<FormatException>(() => b.ToString("R")); // Invalid format
+            Assert.Throws<FormatException>(() => b.ToString("R", null)); // Invalid format
+            Assert.Throws<FormatException>(() => b.ToString("Y")); // Invalid format
+            Assert.Throws<FormatException>(() => b.ToString("Y", null)); // Invalid format
         }
 
         public static IEnumerable<object[]> Parse_Valid_TestData()
index d50ff5a..4c9a9f4 100644 (file)
@@ -158,6 +158,10 @@ namespace System.Tests
         public static void ToString_InvalidFormat_ThrowsFormatException()
         {
             ushort i = 123;
+            Assert.Throws<FormatException>(() => i.ToString("r")); // Invalid format
+            Assert.Throws<FormatException>(() => i.ToString("r", null)); // Invalid format
+            Assert.Throws<FormatException>(() => i.ToString("R")); // Invalid format
+            Assert.Throws<FormatException>(() => i.ToString("R", null)); // Invalid format
             Assert.Throws<FormatException>(() => i.ToString("Y")); // Invalid format
             Assert.Throws<FormatException>(() => i.ToString("Y", null)); // Invalid format
         }
index 8751273..5b8f54c 100644 (file)
@@ -160,6 +160,10 @@ namespace System.Tests
         public static void ToString_InvalidFormat_ThrowsFormatException()
         {
             uint i = 123;
+            Assert.Throws<FormatException>(() => i.ToString("r")); // Invalid format
+            Assert.Throws<FormatException>(() => i.ToString("r", null)); // Invalid format
+            Assert.Throws<FormatException>(() => i.ToString("R")); // Invalid format
+            Assert.Throws<FormatException>(() => i.ToString("R", null)); // Invalid format
             Assert.Throws<FormatException>(() => i.ToString("Y")); // Invalid format
             Assert.Throws<FormatException>(() => i.ToString("Y", null)); // Invalid format
         }
index 817972c..6394909 100644 (file)
@@ -159,6 +159,10 @@ namespace System.Tests
         public static void ToString_InvalidFormat_ThrowsFormatException()
         {
             ulong i = 123;
+            Assert.Throws<FormatException>(() => i.ToString("r")); // Invalid format
+            Assert.Throws<FormatException>(() => i.ToString("r", null)); // Invalid format
+            Assert.Throws<FormatException>(() => i.ToString("R")); // Invalid format
+            Assert.Throws<FormatException>(() => i.ToString("R", null)); // Invalid format
             Assert.Throws<FormatException>(() => i.ToString("Y")); // Invalid format
             Assert.Throws<FormatException>(() => i.ToString("Y", null)); // Invalid format
         }