Consolidate .netcoreapp.cs test files in System.Runtime (dotnet/corefx#42100)
authorRoman Marusyk <Marusyk@users.noreply.github.com>
Mon, 28 Oct 2019 03:22:40 +0000 (04:22 +0100)
committerJan Kotas <jkotas@microsoft.com>
Mon, 28 Oct 2019 03:22:40 +0000 (20:22 -0700)
* Consolidate .netcoreapp.cs files because System.Runtime project is no longer cross-compiled

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

99 files changed:
src/libraries/System.Runtime/tests/Helpers.cs [moved from src/libraries/System.Runtime/tests/Helpers.netcoreapp.cs with 97% similarity]
src/libraries/System.Runtime/tests/System.Runtime.Tests.csproj
src/libraries/System.Runtime/tests/System/ActivatorTests.cs
src/libraries/System.Runtime/tests/System/ActivatorTests.netcoreapp.cs [deleted file]
src/libraries/System.Runtime/tests/System/ArgIteratorTests.cs [moved from src/libraries/System.Runtime/tests/System/ArgIteratorTests.netcoreapp.cs with 100% similarity]
src/libraries/System.Runtime/tests/System/ArraySegmentTests.cs
src/libraries/System.Runtime/tests/System/ArraySegmentTests.netcoreapp.cs [deleted file]
src/libraries/System.Runtime/tests/System/ArrayTests.cs
src/libraries/System.Runtime/tests/System/ArrayTests.netcoreapp.cs [deleted file]
src/libraries/System.Runtime/tests/System/BooleanTests.cs
src/libraries/System.Runtime/tests/System/BooleanTests.netcoreapp.cs [deleted file]
src/libraries/System.Runtime/tests/System/ByteTests.cs
src/libraries/System.Runtime/tests/System/ByteTests.netcoreapp.cs [deleted file]
src/libraries/System.Runtime/tests/System/CharTests.cs
src/libraries/System.Runtime/tests/System/CharTests.netcoreapp.cs [deleted file]
src/libraries/System.Runtime/tests/System/Collections/Generic/KeyValuePairTests.cs
src/libraries/System.Runtime/tests/System/Collections/Generic/KeyValuePairTests.netcoreapp.cs [deleted file]
src/libraries/System.Runtime/tests/System/ComponentModel/DefaultValueAttributeTests.cs
src/libraries/System.Runtime/tests/System/ComponentModel/DefaultValueAttributeTests.netcoreapp.cs [deleted file]
src/libraries/System.Runtime/tests/System/DateTimeOffsetTests.cs
src/libraries/System.Runtime/tests/System/DateTimeOffsetTests.netcoreapp.cs [deleted file]
src/libraries/System.Runtime/tests/System/DateTimeTests.cs
src/libraries/System.Runtime/tests/System/DateTimeTests.netcoreapp.cs [deleted file]
src/libraries/System.Runtime/tests/System/DecimalTests.cs
src/libraries/System.Runtime/tests/System/DecimalTests.netcoreapp.cs [deleted file]
src/libraries/System.Runtime/tests/System/DoubleTests.cs
src/libraries/System.Runtime/tests/System/DoubleTests.netcoreapp.cs [deleted file]
src/libraries/System.Runtime/tests/System/EnumTests.cs
src/libraries/System.Runtime/tests/System/EnumTests.netcoreapp.cs [deleted file]
src/libraries/System.Runtime/tests/System/FormattableStringTests.cs
src/libraries/System.Runtime/tests/System/FormattableStringTests.netcoreapp.cs [deleted file]
src/libraries/System.Runtime/tests/System/GCTests.cs
src/libraries/System.Runtime/tests/System/GCTests.netcoreapp.cs [deleted file]
src/libraries/System.Runtime/tests/System/GuidTests.cs
src/libraries/System.Runtime/tests/System/GuidTests.netcoreapp.cs [deleted file]
src/libraries/System.Runtime/tests/System/HashCodeTests.cs [moved from src/libraries/System.Runtime/tests/System/HashCodeTests.netcoreapp.cs with 100% similarity]
src/libraries/System.Runtime/tests/System/Int16Tests.cs
src/libraries/System.Runtime/tests/System/Int16Tests.netcoreapp.cs [deleted file]
src/libraries/System.Runtime/tests/System/Int32Tests.cs
src/libraries/System.Runtime/tests/System/Int32Tests.netcoreapp.cs [deleted file]
src/libraries/System.Runtime/tests/System/Int64Tests.cs
src/libraries/System.Runtime/tests/System/Int64Tests.netcoreapp.cs [deleted file]
src/libraries/System.Runtime/tests/System/IntPtrTests.cs
src/libraries/System.Runtime/tests/System/IntPtrTests.netcoreapp.cs [deleted file]
src/libraries/System.Runtime/tests/System/LazyTests.cs
src/libraries/System.Runtime/tests/System/LazyTests.netcoreapp.cs [deleted file]
src/libraries/System.Runtime/tests/System/RealFormatterTests.cs [moved from src/libraries/System.Runtime/tests/System/RealFormatterTests.netcoreapp.cs with 100% similarity]
src/libraries/System.Runtime/tests/System/Reflection/BindingFlagsDoNotWrap.cs [moved from src/libraries/System.Runtime/tests/System/Reflection/BindingFlagsDoNotWrap.netcoreapp.cs with 100% similarity]
src/libraries/System.Runtime/tests/System/Reflection/InvokeRefReturn.cs [moved from src/libraries/System.Runtime/tests/System/Reflection/InvokeRefReturn.netcoreapp.cs with 100% similarity]
src/libraries/System.Runtime/tests/System/Reflection/MethodBaseTests.cs
src/libraries/System.Runtime/tests/System/Reflection/MethodBaseTests.netcoreapp.cs [deleted file]
src/libraries/System.Runtime/tests/System/Reflection/SignatureTypes.cs [moved from src/libraries/System.Runtime/tests/System/Reflection/SignatureTypes.netcoreapp.cs with 100% similarity]
src/libraries/System.Runtime/tests/System/Reflection/TypeDelegatorTests.cs
src/libraries/System.Runtime/tests/System/Reflection/TypeDelegatorTests.netcoreapp.cs [deleted file]
src/libraries/System.Runtime/tests/System/Runtime/CompilerServices/AttributesTests.cs
src/libraries/System.Runtime/tests/System/Runtime/CompilerServices/AttributesTests.netcoreapp.cs [deleted file]
src/libraries/System.Runtime/tests/System/Runtime/CompilerServices/ConditionalWeakTableTests.cs
src/libraries/System.Runtime/tests/System/Runtime/CompilerServices/ConditionalWeakTableTests.netcoreapp.cs [deleted file]
src/libraries/System.Runtime/tests/System/Runtime/CompilerServices/MethodImplAttributeTests.cs [moved from src/libraries/System.Runtime/tests/System/Runtime/CompilerServices/MethodImplAttributeTests.netcoreapp.cs with 100% similarity]
src/libraries/System.Runtime/tests/System/Runtime/CompilerServices/RuntimeFeatureTests.cs [moved from src/libraries/System.Runtime/tests/System/Runtime/CompilerServices/RuntimeFeatureTests.netcoreapp.cs with 95% similarity]
src/libraries/System.Runtime/tests/System/Runtime/CompilerServices/RuntimeHelpersTests.cs
src/libraries/System.Runtime/tests/System/Runtime/CompilerServices/RuntimeHelpersTests.netcoreapp.cs [deleted file]
src/libraries/System.Runtime/tests/System/Runtime/ExceptionServices/ExceptionDispatchInfoTests.cs [moved from src/libraries/System.Runtime/tests/System/Runtime/ExceptionServices/ExceptionDispatchInfoTests.netcoreapp.cs with 98% similarity]
src/libraries/System.Runtime/tests/System/SByteTests.cs
src/libraries/System.Runtime/tests/System/SByteTests.netcoreapp.cs [deleted file]
src/libraries/System.Runtime/tests/System/SingleTests.cs
src/libraries/System.Runtime/tests/System/SingleTests.netcoreapp.cs [deleted file]
src/libraries/System.Runtime/tests/System/StringComparerTests.cs
src/libraries/System.Runtime/tests/System/StringComparerTests.netcoreapp.cs [deleted file]
src/libraries/System.Runtime/tests/System/StringGetHashCodeTests.cs
src/libraries/System.Runtime/tests/System/StringGetHashCodeTests.netcoreapp.cs [deleted file]
src/libraries/System.Runtime/tests/System/StringTests.cs [moved from src/libraries/System.Runtime/tests/System/StringTests.netcoreapp.cs with 100% similarity]
src/libraries/System.Runtime/tests/System/Text/ASCIIUtilityTests.cs [moved from src/libraries/System.Runtime/tests/System/Text/ASCIIUtilityTests.netcoreapp.cs with 99% similarity]
src/libraries/System.Runtime/tests/System/Text/RuneTests.TestData.cs [moved from src/libraries/System.Runtime/tests/System/Text/RuneTests.TestData.netcoreapp.cs with 100% similarity]
src/libraries/System.Runtime/tests/System/Text/RuneTests.cs [moved from src/libraries/System.Runtime/tests/System/Text/RuneTests.netcoreapp.cs with 100% similarity]
src/libraries/System.Runtime/tests/System/Text/StringBuilderTests.cs
src/libraries/System.Runtime/tests/System/Text/StringBuilderTests.netcoreapp.cs [deleted file]
src/libraries/System.Runtime/tests/System/Text/Unicode/UnicodeData.cs [moved from src/libraries/System.Runtime/tests/System/Text/Unicode/UnicodeData.netcoreapp.cs with 100% similarity]
src/libraries/System.Runtime/tests/System/Text/Unicode/Utf16UtilityTests.ValidateChars.cs [moved from src/libraries/System.Runtime/tests/System/Text/Unicode/Utf16UtilityTests.ValidateChars.netcoreapp.cs with 99% similarity]
src/libraries/System.Runtime/tests/System/Text/Unicode/Utf8Tests.ToBytes.netcoreapp.cs [deleted file]
src/libraries/System.Runtime/tests/System/Text/Unicode/Utf8Tests.cs [moved from src/libraries/System.Runtime/tests/System/Text/Unicode/Utf8Tests.ToChars.netcoreapp.cs with 51% similarity]
src/libraries/System.Runtime/tests/System/Text/Unicode/Utf8Tests.netcoreapp.cs [deleted file]
src/libraries/System.Runtime/tests/System/Text/Unicode/Utf8UtilityTests.ValidateBytes.cs [moved from src/libraries/System.Runtime/tests/System/Text/Unicode/Utf8UtilityTests.ValidateBytes.netcoreapp.cs with 99% similarity]
src/libraries/System.Runtime/tests/System/TimeSpanTests.cs
src/libraries/System.Runtime/tests/System/TimeSpanTests.netcoreapp.cs [deleted file]
src/libraries/System.Runtime/tests/System/Type/TypePropertyTests.cs
src/libraries/System.Runtime/tests/System/Type/TypePropertyTests.netcoreapp.cs [deleted file]
src/libraries/System.Runtime/tests/System/Type/TypeTests.cs
src/libraries/System.Runtime/tests/System/Type/TypeTests.netcoreapp.cs [deleted file]
src/libraries/System.Runtime/tests/System/UInt16Tests.cs
src/libraries/System.Runtime/tests/System/UInt16Tests.netcoreapp.cs [deleted file]
src/libraries/System.Runtime/tests/System/UInt32Tests.cs
src/libraries/System.Runtime/tests/System/UInt32Tests.netcoreapp.cs [deleted file]
src/libraries/System.Runtime/tests/System/UInt64Tests.cs
src/libraries/System.Runtime/tests/System/UInt64Tests.netcoreapp.cs [deleted file]
src/libraries/System.Runtime/tests/System/UIntPtrTests.cs
src/libraries/System.Runtime/tests/System/UIntPtrTests.netcoreapp.cs [deleted file]
src/libraries/System.Runtime/tests/System/VersionTests.cs
src/libraries/System.Runtime/tests/System/VersionTests.netcoreapp.cs [deleted file]

@@ -9,7 +9,7 @@ using System.Reflection.Emit;
 
 namespace System.Tests
 {
-    public static partial class Helpers
+    public static class Helpers
     {
         private static Type s_refEmitType;
 
index 9cec3de..c306add 100644 (file)
     <Compile Include="$(CommonTestPath)\System\Collections\IEnumerable.NonGeneric.Tests.cs">
       <Link>Common\System\Collections\IEnumerable.NonGeneric.Tests.cs</Link>
     </Compile>
+    <Compile Include="Helpers.cs" />
     <Compile Include="Microsoft\Win32\SafeHandles\CriticalHandleZeroOrMinusOneIsInvalid.cs" />
     <Compile Include="Microsoft\Win32\SafeHandles\SafeHandleZeroOrMinusOneIsInvalid.cs" />
     <Compile Include="System\AccessViolationExceptionTests.cs" />
     <Compile Include="System\ActivatorTests.cs" />
     <Compile Include="System\ActivatorTests.Generic.cs" />
+    <Compile Include="System\AmbiguousImplementationExceptionTests.cs" />
     <Compile Include="System\ArgumentExceptionTests.cs" />
     <Compile Include="System\ArgumentNullExceptionTests.cs" />
     <Compile Include="System\ArgumentOutOfRangeExceptionTests.cs" />
@@ -91,7 +93,9 @@
     <Compile Include="System\GCTests.cs" />
     <Compile Include="System\GuidTests.cs" />
     <Compile Include="System\HandleTests.cs" />
+    <Compile Include="System\HashCodeTests.cs" />
     <Compile Include="System\IndexOutOfRangeExceptionTests.cs" />
+    <Compile Include="System\IndexTests.cs" />
     <Compile Include="System\Int16Tests.cs" />
     <Compile Include="System\Int32Tests.cs" />
     <Compile Include="System\Int64Tests.cs" />
     <Compile Include="System\ParamArrayAttributeTests.cs" />
     <Compile Include="System\PlatformNotSupportedExceptionTests.cs" />
     <Compile Include="System\PseudoCustomAttributeTests.cs" />
+    <Compile Include="System\RangeTests.cs" />
     <Compile Include="System\RankExceptionTests.cs" />
     <Compile Include="System\SByteTests.cs" />
     <Compile Include="System\SingleTests.cs" />
     <Compile Include="System\StackOverflowExceptionTests.cs" />
     <Compile Include="System\StringComparerTests.cs" />
     <Compile Include="System\StringGetHashCodeTests.cs" />
+    <Compile Include="System\StringTests.cs" />
     <Compile Include="System\String.SplitTests.cs" />
     <Compile Include="System\SystemExceptionTests.cs" />
     <Compile Include="System\TimeoutExceptionTests.cs" />
     <Compile Include="System\TimeZoneInfoTests.cs" />
     <Compile Include="System\TimeZoneTests.cs" />
     <Compile Include="System\TimeZoneNotFoundExceptionTests.cs" />
+    <Compile Include="System\TypedReferenceTests.cs" />
     <Compile Include="System\TypeLoadExceptionTests.cs" />
     <Compile Include="System\TypeUnloadedExceptionTests.cs" />
     <Compile Include="System\TupleTests.cs" />
     <Compile Include="System\Reflection\AssemblyTitleAttributeTests.cs" />
     <Compile Include="System\Reflection\AssemblyTrademarkAttributeTests.cs" />
     <Compile Include="System\Reflection\AssemblyVersionAttributeTests.cs" />
+    <Compile Include="System\Reflection\BindingFlagsDoNotWrap.cs" />
     <Compile Include="System\Reflection\CustomAttributeDataTests.cs" />
     <Compile Include="System\Reflection\CustomAttributesTestData.cs" />
     <Compile Include="System\Reflection\CustomAttribute_Named_Typed_ArgumentTests.cs" />
     <Compile Include="System\Reflection\DefaultMemberAttributeTests.cs" />
+    <Compile Include="System\Reflection\InvokeRefReturn.cs" />
+    <Compile Include="System\Reflection\IsCollectibleTests.cs" />
     <Compile Include="System\Reflection\MethodBaseTests.cs" />
     <Compile Include="System\Reflection\MethodBodyTests.cs" />
     <Compile Include="System\Reflection\ModuleTests.cs" />
     <Compile Include="System\ExitCodeTests.Unix.cs" />
   </ItemGroup>
   <ItemGroup>
-    <Compile Include="System\HashCodeTests.netcoreapp.cs" />
-    <Compile Include="Helpers.netcoreapp.cs" />
-    <Compile Include="System\ActivatorTests.netcoreapp.cs" />
-    <Compile Include="System\AmbiguousImplementationExceptionTests.cs" />
-    <Compile Include="System\ArrayTests.netcoreapp.cs" />
-    <Compile Include="System\ArraySegmentTests.netcoreapp.cs" />
-    <Compile Include="System\BooleanTests.netcoreapp.cs" />
-    <Compile Include="System\ByteTests.netcoreapp.cs" />
-    <Compile Include="System\CharTests.netcoreapp.cs" />
-    <Compile Include="System\DateTimeTests.netcoreapp.cs" />
-    <Compile Include="System\DateTimeOffsetTests.netcoreapp.cs" />
-    <Compile Include="System\DecimalTests.netcoreapp.cs" />
-    <Compile Include="System\EnumTests.netcoreapp.cs" />
-    <Compile Include="System\FormattableStringTests.netcoreapp.cs" />
-    <Compile Include="System\GCTests.netcoreapp.cs" />
-    <Compile Include="System\GuidTests.netcoreapp.cs" />
-    <Compile Include="System\IndexTests.cs" />
-    <Compile Include="System\Int16Tests.netcoreapp.cs" />
-    <Compile Include="System\Int32Tests.netcoreapp.cs" />
-    <Compile Include="System\Int64Tests.netcoreapp.cs" />
-    <Compile Include="System\IntPtrTests.netcoreapp.cs" />
-    <Compile Include="System\Collections\Generic\KeyValuePairTests.netcoreapp.cs" />
-    <Compile Include="System\LazyTests.netcoreapp.cs" />
-    <Compile Include="System\RangeTests.cs" />
-    <Compile Include="System\SByteTests.netcoreapp.cs" />
-    <Compile Include="System\StringComparerTests.netcoreapp.cs" />
-    <Compile Include="System\StringGetHashCodeTests.netcoreapp.cs" />
-    <Compile Include="System\StringTests.netcoreapp.cs" />
-    <Compile Include="System\TimeSpanTests.netcoreapp.cs" />
-    <Compile Include="System\TypedReferenceTests.cs" />
-    <Compile Include="System\UIntPtrTests.netcoreapp.cs" />
-    <Compile Include="System\UInt16Tests.netcoreapp.cs" />
-    <Compile Include="System\UInt32Tests.netcoreapp.cs" />
-    <Compile Include="System\UInt64Tests.netcoreapp.cs" />
-    <Compile Include="System\VersionTests.netcoreapp.cs" />
-    <Compile Include="System\ComponentModel\DefaultValueAttributeTests.netcoreapp.cs" />
-    <Compile Include="System\Reflection\BindingFlagsDoNotWrap.netcoreapp.cs" />
-    <Compile Include="System\Reflection\InvokeRefReturn.netcoreapp.cs" />
-    <Compile Include="System\Reflection\IsCollectibleTests.cs" />
-    <!-- missing method 'AssemblyLoadContext..ctor(bool) -->
-    <Compile Include="System\Reflection\MethodBaseTests.netcoreapp.cs" />
-    <Compile Include="System\Reflection\SignatureTypes.netcoreapp.cs" />
-    <Compile Include="System\Reflection\TypeDelegatorTests.netcoreapp.cs" />
-    <Compile Include="System\Runtime\CompilerServices\AttributesTests.netcoreapp.cs" />
+    <Compile Include="System\Reflection\SignatureTypes.cs" />
     <Compile Include="System\Runtime\CompilerServices\CallerArgumentExpressionAttributeTests.cs" />
-    <Compile Include="System\Runtime\CompilerServices\ConditionalWeakTableTests.netcoreapp.cs" />
-    <Compile Include="System\Runtime\CompilerServices\MethodImplAttributeTests.netcoreapp.cs" />
-    <Compile Include="System\Runtime\CompilerServices\RuntimeHelpersTests.netcoreapp.cs" />
-    <Compile Include="System\Runtime\CompilerServices\RuntimeFeatureTests.netcoreapp.cs" />
+    <Compile Include="System\Runtime\CompilerServices\MethodImplAttributeTests.cs" />
+    <Compile Include="System\Runtime\CompilerServices\RuntimeFeatureTests.cs" />
     <Compile Include="System\Runtime\CompilerServices\RuntimeWrappedExceptionTests.cs" />
-    <Compile Include="System\Runtime\ExceptionServices\ExceptionDispatchInfoTests.netcoreapp.cs" />
-    <Compile Include="System\Text\ASCIIUtilityTests.netcoreapp.cs" />
-    <Compile Include="System\Text\RuneTests.netcoreapp.cs" />
-    <Compile Include="System\Text\RuneTests.TestData.netcoreapp.cs" />
-    <Compile Include="System\Text\StringBuilderTests.netcoreapp.cs" />
-    <Compile Include="System\Text\Unicode\UnicodeData.netcoreapp.cs" />
-    <Compile Include="System\Text\Unicode\Utf16UtilityTests.ValidateChars.netcoreapp.cs" />
-    <Compile Include="System\Text\Unicode\Utf8Tests.netcoreapp.cs" />
-    <Compile Include="System\Text\Unicode\Utf8Tests.ToBytes.netcoreapp.cs" />
-    <Compile Include="System\Text\Unicode\Utf8Tests.ToChars.netcoreapp.cs" />
-    <Compile Include="System\Text\Unicode\Utf8UtilityTests.ValidateBytes.netcoreapp.cs" />
-    <Compile Include="System\Type\TypePropertyTests.netcoreapp.cs" />
-    <Compile Include="System\Type\TypeTests.netcoreapp.cs" />
-    <Compile Include="System\ArgIteratorTests.netcoreapp.cs" />
-    <Compile Include="System\DoubleTests.netcoreapp.cs" />
-    <Compile Include="System\SingleTests.netcoreapp.cs" />
+    <Compile Include="System\Runtime\ExceptionServices\ExceptionDispatchInfoTests.cs" />
+    <Compile Include="System\Text\ASCIIUtilityTests.cs" />
+    <Compile Include="System\Text\RuneTests.cs" />
+    <Compile Include="System\Text\RuneTests.TestData.cs" />
+    <Compile Include="System\Text\Unicode\UnicodeData.cs" />
+    <Compile Include="System\Text\Unicode\Utf16UtilityTests.ValidateChars.cs" />
+    <Compile Include="System\Text\Unicode\Utf8Tests.cs" />
+    <Compile Include="System\Text\Unicode\Utf8UtilityTests.ValidateBytes.cs" />
+    <Compile Include="System\ArgIteratorTests.cs" />
     <Compile Include="$(CommonPath)\..\tests\System\RealFormatterTestsBase.netcoreapp.cs" Link="System\RealFormatterTestsBase.netcoreapp.cs" />
-    <Compile Include="System\RealFormatterTests.netcoreapp.cs" />
+    <Compile Include="System\RealFormatterTests.cs" />
     <Compile Include="$(CommonPath)\..\tests\System\RealParserTestsBase.netcoreapp.cs" Link="System\RealParserTestsBase.netcoreapp.cs" />
     <Compile Include="System\RealParserTests.netcoreapp.cs" />
   </ItemGroup>
index a32ac63..27c458e 100644 (file)
@@ -4,8 +4,13 @@
 
 using System;
 using System.Collections.Generic;
+using System.Diagnostics;
 using System.Globalization;
+using System.IO;
 using System.Reflection;
+using System.Reflection.Emit;
+using System.Runtime.Remoting;
+using Microsoft.DotNet.RemoteExecutor;
 using Xunit;
 
 namespace System.Tests
@@ -563,5 +568,266 @@ namespace System.Tests
             Activator.CreateInstance(typeof(ClassWithIsTestedAttribute), null, null);
             Activator.CreateInstance(typeof(ClassWithIsTestedAttribute), null, new object[] { });
         }
+
+        [Fact]
+        public void CreateInstance_NonPublicValueTypeWithPrivateDefaultConstructor_Success()
+        {
+            AssemblyName assemblyName = new AssemblyName("Assembly");
+            AssemblyBuilder assemblyBuilder = AssemblyBuilder.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.Run);
+            ModuleBuilder moduleBuilder = assemblyBuilder.DefineDynamicModule("Module");
+            TypeBuilder typeBuilder = moduleBuilder.DefineType("Type", TypeAttributes.Public, typeof(ValueType));
+
+            FieldBuilder fieldBuilder = typeBuilder.DefineField("_field", typeof(int), FieldAttributes.Public);
+            ConstructorBuilder constructorBuilder = typeBuilder.DefineConstructor(MethodAttributes.Private | MethodAttributes.SpecialName | MethodAttributes.RTSpecialName | MethodAttributes.HideBySig, CallingConventions.Standard, new Type[0]);
+
+            ILGenerator generator = constructorBuilder.GetILGenerator();
+            generator.Emit(OpCodes.Ldarg_0);
+            generator.Emit(OpCodes.Ldc_I4, -1);
+            generator.Emit(OpCodes.Stfld, fieldBuilder);
+            generator.Emit(OpCodes.Ret);
+
+            Type type = typeBuilder.CreateType();
+            FieldInfo field = type.GetField("_field");
+
+            // Activator holds a cache of constructors and the types to which they belong.
+            // Test caching behaviour by activating multiple times.
+            object v1 = Activator.CreateInstance(type, nonPublic: true);
+            Assert.Equal(-1, field.GetValue(v1));
+
+            object v2 = Activator.CreateInstance(type, nonPublic: true);
+            Assert.Equal(-1, field.GetValue(v2));
+        }
+
+        [Fact]
+        public void CreateInstance_PublicOnlyValueTypeWithPrivateDefaultConstructor_ThrowsMissingMethodException()
+        {
+            AssemblyName assemblyName = new AssemblyName("Assembly");
+            AssemblyBuilder assemblyBuilder = AssemblyBuilder.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.Run);
+            ModuleBuilder moduleBuilder = assemblyBuilder.DefineDynamicModule("Module");
+            TypeBuilder typeBuilder = moduleBuilder.DefineType("Type", TypeAttributes.Public, typeof(ValueType));
+
+            FieldBuilder fieldBuilder = typeBuilder.DefineField("_field", typeof(int), FieldAttributes.Public);
+            ConstructorBuilder constructorBuilder = typeBuilder.DefineConstructor(MethodAttributes.Private | MethodAttributes.SpecialName | MethodAttributes.RTSpecialName | MethodAttributes.HideBySig, CallingConventions.Standard, new Type[0]);
+
+            ILGenerator generator = constructorBuilder.GetILGenerator();
+            generator.Emit(OpCodes.Ldarg_0);
+            generator.Emit(OpCodes.Ldc_I4, -1);
+            generator.Emit(OpCodes.Stfld, fieldBuilder);
+            generator.Emit(OpCodes.Ret);
+
+            Type type = typeBuilder.CreateType();
+
+            Assert.Throws<MissingMethodException>(() => Activator.CreateInstance(type));
+            Assert.Throws<MissingMethodException>(() => Activator.CreateInstance(type, nonPublic: false));
+
+            // Put the private default constructor into the cache and make sure we still throw if public only.
+            Assert.NotNull(Activator.CreateInstance(type, nonPublic: true));
+
+            Assert.Throws<MissingMethodException>(() => Activator.CreateInstance(type));
+            Assert.Throws<MissingMethodException>(() => Activator.CreateInstance(type, nonPublic: false));
+        }
+
+        [Theory]
+        [MemberData(nameof(TestingCreateInstanceFromObjectHandleData))]
+        public static void TestingCreateInstanceFromObjectHandle(string physicalFileName, string assemblyFile, string type, string returnedFullNameType, Type exceptionType)
+        {
+            ObjectHandle oh = null;
+
+            if (exceptionType != null)
+            {
+                Assert.Throws(exceptionType, () => Activator.CreateInstanceFrom(assemblyFile: assemblyFile, typeName: type));
+            }
+            else
+            {
+                oh = Activator.CreateInstanceFrom(assemblyFile: assemblyFile, typeName: type);
+                CheckValidity(oh, returnedFullNameType);
+            }
+
+            if (exceptionType != null)
+            {
+                Assert.Throws(exceptionType, () => Activator.CreateInstanceFrom(assemblyFile: assemblyFile, typeName: type, null));
+            }
+            else
+            {
+                oh = Activator.CreateInstanceFrom(assemblyFile: assemblyFile, typeName: type, null);
+                CheckValidity(oh, returnedFullNameType);
+            }
+            Assert.True(File.Exists(physicalFileName));
+        }
+
+        public static TheoryData<string, string, string, string, Type> TestingCreateInstanceFromObjectHandleData => new TheoryData<string, string, string, string, Type>()
+        {
+            // string physicalFileName, string assemblyFile, string typeName, returnedFullNameType, expectedException
+            { "TestLoadAssembly.dll", "TestLoadAssembly.dll", "PublicClassSample", "PublicClassSample", null },
+            { "TestLoadAssembly.dll", "testloadassembly.dll", "publicclasssample", "PublicClassSample", typeof(TypeLoadException) },
+
+            { "TestLoadAssembly.dll", "TestLoadAssembly.dll", "PrivateClassSample", "PrivateClassSample", null },
+            { "TestLoadAssembly.dll", "testloadassembly.dll", "privateclasssample", "PrivateClassSample", typeof(TypeLoadException) },
+
+            { "TestLoadAssembly.dll", "TestLoadAssembly.dll", "PublicClassNoDefaultConstructorSample", "PublicClassNoDefaultConstructorSample", typeof(MissingMethodException) },
+            { "TestLoadAssembly.dll", "testloadassembly.dll", "publicclassnodefaultconstructorsample", "PublicClassNoDefaultConstructorSample", typeof(TypeLoadException) }
+        };
+
+        [Theory]
+        [MemberData(nameof(TestingCreateInstanceObjectHandleData))]
+        public static void TestingCreateInstanceObjectHandle(string assemblyName, string type, string returnedFullNameType, Type exceptionType, bool returnNull)
+        {
+            ObjectHandle oh = null;
+
+            if (exceptionType != null)
+            {
+                Assert.Throws(exceptionType, () => Activator.CreateInstance(assemblyName: assemblyName, typeName: type));
+            }
+            else
+            {
+                oh = Activator.CreateInstance(assemblyName: assemblyName, typeName: type);
+                if (returnNull)
+                {
+                    Assert.Null(oh);
+                }
+                else
+                {
+                    CheckValidity(oh, returnedFullNameType);
+                }
+            }
+
+            if (exceptionType != null)
+            {
+                Assert.Throws(exceptionType, () => Activator.CreateInstance(assemblyName: assemblyName, typeName: type, null));
+            }
+            else
+            {
+                oh = Activator.CreateInstance(assemblyName: assemblyName, typeName: type, null);
+                if (returnNull)
+                {
+                    Assert.Null(oh);
+                }
+                else
+                {
+                    CheckValidity(oh, returnedFullNameType);
+                }
+            }
+        }
+
+        public static TheoryData<string, string, string, Type, bool> TestingCreateInstanceObjectHandleData => new TheoryData<string, string, string, Type, bool>()
+        {
+            // string assemblyName, string typeName, returnedFullNameType, expectedException
+            { "TestLoadAssembly", "PublicClassSample", "PublicClassSample", null, false },
+            { "testloadassembly", "publicclasssample", "PublicClassSample", typeof(TypeLoadException), false },
+
+            { "TestLoadAssembly", "PrivateClassSample", "PrivateClassSample", null, false },
+            { "testloadassembly", "privateclasssample", "PrivateClassSample", typeof(TypeLoadException), false },
+
+            { "TestLoadAssembly", "PublicClassNoDefaultConstructorSample", "PublicClassNoDefaultConstructorSample", typeof(MissingMethodException), false },
+            { "testloadassembly", "publicclassnodefaultconstructorsample", "PublicClassNoDefaultConstructorSample", typeof(TypeLoadException), false },
+
+            { "mscorlib", "System.Nullable`1[[System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]", "", null, true }
+        };
+
+        [Theory]
+        [MemberData(nameof(TestingCreateInstanceFromObjectHandleFullSignatureData))]
+        public static void TestingCreateInstanceFromObjectHandleFullSignature(string physicalFileName, string assemblyFile, string type, bool ignoreCase, BindingFlags bindingAttr, Binder binder, object[] args, CultureInfo culture, object[] activationAttributes, string returnedFullNameType)
+        {
+            ObjectHandle oh = Activator.CreateInstanceFrom(assemblyFile: assemblyFile, typeName: type, ignoreCase: ignoreCase, bindingAttr: bindingAttr, binder: binder, args: args, culture: culture, activationAttributes: activationAttributes);
+            CheckValidity(oh, returnedFullNameType);
+            Assert.True(File.Exists(physicalFileName));
+        }
+
+        public static IEnumerable<object[]> TestingCreateInstanceFromObjectHandleFullSignatureData()
+        {
+            // string physicalFileName, string assemblyFile, string typeName, bool ignoreCase, BindingFlags bindingAttr, Binder binder, object[] args, CultureInfo culture, object[] activationAttributes, returnedFullNameType
+            yield return new object[] { "TestLoadAssembly.dll", "TestLoadAssembly.dll", "PublicClassSample", false, BindingFlags.Public | BindingFlags.Instance, Type.DefaultBinder, new object[0], CultureInfo.InvariantCulture, null, "PublicClassSample" };
+            yield return new object[] { "TestLoadAssembly.dll", "testloadassembly.dll", "publicclasssample", true, BindingFlags.Public | BindingFlags.Instance, Type.DefaultBinder, new object[0], CultureInfo.InvariantCulture, null, "PublicClassSample" };
+            yield return new object[] { "TestLoadAssembly.dll", "TestLoadAssembly.dll", "PublicClassSample", false, BindingFlags.Public | BindingFlags.Instance, Type.DefaultBinder, new object[1] { 1 }, CultureInfo.InvariantCulture, null, "PublicClassSample" };
+            yield return new object[] { "TestLoadAssembly.dll", "testloadassembly.dll", "publicclasssample", true, BindingFlags.Public | BindingFlags.Instance, Type.DefaultBinder, new object[1] { 1 }, CultureInfo.InvariantCulture, null, "PublicClassSample" };
+
+            yield return new object[] { "TestLoadAssembly.dll", "TestLoadAssembly.dll", "PrivateClassSample", false, BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance, Type.DefaultBinder, new object[0], CultureInfo.InvariantCulture, null, "PrivateClassSample" };
+            yield return new object[] { "TestLoadAssembly.dll", "testloadassembly.dll", "privateclasssample", true, BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance, Type.DefaultBinder, new object[0], CultureInfo.InvariantCulture, null, "PrivateClassSample" };
+            yield return new object[] { "TestLoadAssembly.dll", "TestLoadAssembly.dll", "PrivateClassSample", false, BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance, Type.DefaultBinder, new object[1] { 1 }, CultureInfo.InvariantCulture, null, "PrivateClassSample" };
+            yield return new object[] { "TestLoadAssembly.dll", "testloadassembly.dll", "privateclasssample", true, BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance, Type.DefaultBinder, new object[1] { 1 }, CultureInfo.InvariantCulture, null, "PrivateClassSample" };
+        }
+
+        [Theory]
+        [MemberData(nameof(TestingCreateInstanceObjectHandleFullSignatureData))]
+        public static void TestingCreateInstanceObjectHandleFullSignature(string assemblyName, string type, bool ignoreCase, BindingFlags bindingAttr, Binder binder, object[] args, CultureInfo culture, object[] activationAttributes, string returnedFullNameType, bool returnNull)
+        {
+            ObjectHandle oh = Activator.CreateInstance(assemblyName: assemblyName, typeName: type, ignoreCase: ignoreCase, bindingAttr: bindingAttr, binder: binder, args: args, culture: culture, activationAttributes: activationAttributes);
+            if (returnNull)
+            {
+                Assert.Null(oh);
+            }
+            else
+            {
+                CheckValidity(oh, returnedFullNameType);
+            }
+        }
+
+        public static IEnumerable<object[]> TestingCreateInstanceObjectHandleFullSignatureData()
+        {
+            // string assemblyName, string typeName, bool ignoreCase, BindingFlags bindingAttr, Binder binder, object[] args, CultureInfo culture, object[] activationAttributes, returnedFullNameType
+            yield return new object[] { "TestLoadAssembly", "PublicClassSample", false, BindingFlags.Public | BindingFlags.Instance, Type.DefaultBinder, new object[0], CultureInfo.InvariantCulture, null, "PublicClassSample" , false };
+            yield return new object[] { "testloadassembly", "publicclasssample", true, BindingFlags.Public | BindingFlags.Instance, Type.DefaultBinder, new object[0], CultureInfo.InvariantCulture, null, "PublicClassSample" , false };
+            yield return new object[] { "TestLoadAssembly", "PublicClassSample", false, BindingFlags.Public | BindingFlags.Instance, Type.DefaultBinder, new object[1] { 1 }, CultureInfo.InvariantCulture, null, "PublicClassSample" , false };
+            yield return new object[] { "testloadassembly", "publicclasssample", true, BindingFlags.Public | BindingFlags.Instance, Type.DefaultBinder, new object[1] { 1 }, CultureInfo.InvariantCulture, null, "PublicClassSample" , false };
+
+            yield return new object[] { "TestLoadAssembly", "PrivateClassSample", false, BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance, Type.DefaultBinder, new object[0], CultureInfo.InvariantCulture, null, "PrivateClassSample", false };
+            yield return new object[] { "testloadassembly", "privateclasssample", true, BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance, Type.DefaultBinder, new object[0], CultureInfo.InvariantCulture, null, "PrivateClassSample", false };
+            yield return new object[] { "TestLoadAssembly", "PrivateClassSample", false, BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance, Type.DefaultBinder, new object[1] { 1 }, CultureInfo.InvariantCulture, null, "PrivateClassSample", false };
+            yield return new object[] { "testloadassembly", "privateclasssample", true, BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance, Type.DefaultBinder, new object[1] { 1 }, CultureInfo.InvariantCulture, null, "PrivateClassSample", false };
+
+            yield return new object[] { null, typeof(PublicType).FullName, false, BindingFlags.Public | BindingFlags.Instance, Type.DefaultBinder, new object[0], CultureInfo.InvariantCulture, null, typeof(PublicType).FullName, false };
+            yield return new object[] { null, typeof(PrivateType).FullName, false, BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance, Type.DefaultBinder, new object[0], CultureInfo.InvariantCulture, null, typeof(PrivateType).FullName, false };
+
+            yield return new object[] { "mscorlib", "System.Nullable`1[[System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]", true, BindingFlags.Public | BindingFlags.Instance, Type.DefaultBinder, new object[0], CultureInfo.InvariantCulture, null, "", true };
+            yield return new object[] { "mscorlib", "SyStEm.NULLABLE`1[[System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]", true, BindingFlags.Public | BindingFlags.Instance, Type.DefaultBinder, new object[0], CultureInfo.InvariantCulture, null, "", true };
+        }
+
+        [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsWinUISupported))]
+        [PlatformSpecific(TestPlatforms.Windows)]
+        [MemberData(nameof(TestingCreateInstanceObjectHandleFullSignatureWinRTData))]
+        public static void TestingCreateInstanceObjectHandleFullSignatureWinRT(string assemblyName, string type, bool ignoreCase, BindingFlags bindingAttr, Binder binder, object[] args, CultureInfo culture, object[] activationAttributes, string returnedFullNameType)
+        {
+            ObjectHandle oh = Activator.CreateInstance(assemblyName: assemblyName, typeName: type, ignoreCase: ignoreCase, bindingAttr: bindingAttr, binder: binder, args: args, culture: culture, activationAttributes: activationAttributes);
+            CheckValidity(oh, returnedFullNameType);
+        }
+
+        public static IEnumerable<object[]> TestingCreateInstanceObjectHandleFullSignatureWinRTData()
+        {
+            // string assemblyName, string typeName, bool ignoreCase, BindingFlags bindingAttr, Binder binder, object[] args, CultureInfo culture, object[] activationAttributes, returnedFullNameType
+            yield return new object[] { "Windows, Version=255.255.255.255, Culture=neutral, PublicKeyToken=null, ContentType=WindowsRuntime", "Windows.Foundation.Collections.StringMap", false, BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance, Type.DefaultBinder, new object[0], CultureInfo.InvariantCulture, null, "Windows.Foundation.Collections.StringMap" };
+        }
+
+        private static void CheckValidity(ObjectHandle instance, string expected)
+        {
+            Assert.NotNull(instance);
+            Assert.Equal(expected, instance.Unwrap().GetType().FullName);
+        }
+
+        public class PublicType
+        {
+            public PublicType() { }
+        }
+
+        [Fact]
+        public static void CreateInstanceAssemblyResolve()
+        {
+            RemoteExecutor.Invoke(() =>
+            {
+                AppDomain.CurrentDomain.AssemblyResolve += (object sender, ResolveEventArgs args) => Assembly.LoadFile(Path.Combine(Directory.GetCurrentDirectory(), "TestLoadAssembly.dll"));
+                Assert.Throws<FileLoadException>(() => Activator.CreateInstance(",,,,", "PublicClassSample"));
+            }).Dispose();
+        }
+
+        [Fact]
+        public void CreateInstance_TypeBuilder_ThrowsNotSupportedException()
+        {
+            AssemblyName assemblyName = new AssemblyName("Assembly");
+            AssemblyBuilder assemblyBuilder = AssemblyBuilder.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.Run);
+            ModuleBuilder moduleBuilder = assemblyBuilder.DefineDynamicModule("Module");
+            TypeBuilder typeBuilder = moduleBuilder.DefineType("Type", TypeAttributes.Public);
+
+            Assert.Throws<ArgumentException>("type", () => Activator.CreateInstance(typeBuilder));
+            Assert.Throws<NotSupportedException>(() => Activator.CreateInstance(typeBuilder, new object[0]));
+        }
     }
 }
diff --git a/src/libraries/System.Runtime/tests/System/ActivatorTests.netcoreapp.cs b/src/libraries/System.Runtime/tests/System/ActivatorTests.netcoreapp.cs
deleted file mode 100644 (file)
index fb2f85f..0000000
+++ /dev/null
@@ -1,280 +0,0 @@
-// 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.Diagnostics;
-using System.Globalization;
-using System.IO;
-using System.Reflection;
-using System.Reflection.Emit;
-using System.Runtime.Remoting;
-using Microsoft.DotNet.RemoteExecutor;
-using Xunit;
-
-namespace System.Tests
-{
-    public partial class ActivatorTests
-    {
-        [Fact]
-        public void CreateInstance_NonPublicValueTypeWithPrivateDefaultConstructor_Success()
-        {
-            AssemblyName assemblyName = new AssemblyName("Assembly");
-            AssemblyBuilder assemblyBuilder = AssemblyBuilder.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.Run);
-            ModuleBuilder moduleBuilder = assemblyBuilder.DefineDynamicModule("Module");
-            TypeBuilder typeBuilder = moduleBuilder.DefineType("Type", TypeAttributes.Public, typeof(ValueType));
-
-            FieldBuilder fieldBuilder = typeBuilder.DefineField("_field", typeof(int), FieldAttributes.Public);
-            ConstructorBuilder constructorBuilder = typeBuilder.DefineConstructor(MethodAttributes.Private | MethodAttributes.SpecialName | MethodAttributes.RTSpecialName | MethodAttributes.HideBySig, CallingConventions.Standard, new Type[0]);
-
-            ILGenerator generator = constructorBuilder.GetILGenerator();
-            generator.Emit(OpCodes.Ldarg_0);
-            generator.Emit(OpCodes.Ldc_I4, -1);
-            generator.Emit(OpCodes.Stfld, fieldBuilder);
-            generator.Emit(OpCodes.Ret);
-
-            Type type = typeBuilder.CreateType();
-            FieldInfo field = type.GetField("_field");
-
-            // Activator holds a cache of constructors and the types to which they belong.
-            // Test caching behaviour by activating multiple times.
-            object v1 = Activator.CreateInstance(type, nonPublic: true);
-            Assert.Equal(-1, field.GetValue(v1));
-
-            object v2 = Activator.CreateInstance(type, nonPublic: true);
-            Assert.Equal(-1, field.GetValue(v2));
-        }
-
-        [Fact]
-        public void CreateInstance_PublicOnlyValueTypeWithPrivateDefaultConstructor_ThrowsMissingMethodException()
-        {
-            AssemblyName assemblyName = new AssemblyName("Assembly");
-            AssemblyBuilder assemblyBuilder = AssemblyBuilder.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.Run);
-            ModuleBuilder moduleBuilder = assemblyBuilder.DefineDynamicModule("Module");
-            TypeBuilder typeBuilder = moduleBuilder.DefineType("Type", TypeAttributes.Public, typeof(ValueType));
-
-            FieldBuilder fieldBuilder = typeBuilder.DefineField("_field", typeof(int), FieldAttributes.Public);
-            ConstructorBuilder constructorBuilder = typeBuilder.DefineConstructor(MethodAttributes.Private | MethodAttributes.SpecialName | MethodAttributes.RTSpecialName | MethodAttributes.HideBySig, CallingConventions.Standard, new Type[0]);
-
-            ILGenerator generator = constructorBuilder.GetILGenerator();
-            generator.Emit(OpCodes.Ldarg_0);
-            generator.Emit(OpCodes.Ldc_I4, -1);
-            generator.Emit(OpCodes.Stfld, fieldBuilder);
-            generator.Emit(OpCodes.Ret);
-
-            Type type = typeBuilder.CreateType();
-
-            Assert.Throws<MissingMethodException>(() => Activator.CreateInstance(type));
-            Assert.Throws<MissingMethodException>(() => Activator.CreateInstance(type, nonPublic: false));
-
-            // Put the private default constructor into the cache and make sure we still throw if public only.
-            Assert.NotNull(Activator.CreateInstance(type, nonPublic: true));
-
-            Assert.Throws<MissingMethodException>(() => Activator.CreateInstance(type));
-            Assert.Throws<MissingMethodException>(() => Activator.CreateInstance(type, nonPublic: false));
-        }
-
-        [Theory]
-        [MemberData(nameof(TestingCreateInstanceFromObjectHandleData))]
-        public static void TestingCreateInstanceFromObjectHandle(string physicalFileName, string assemblyFile, string type, string returnedFullNameType, Type exceptionType)
-        {
-            ObjectHandle oh = null;
-
-            if (exceptionType != null)
-            {
-                Assert.Throws(exceptionType, () => Activator.CreateInstanceFrom(assemblyFile: assemblyFile, typeName: type));
-            }
-            else
-            {
-                oh = Activator.CreateInstanceFrom(assemblyFile: assemblyFile, typeName: type);
-                CheckValidity(oh, returnedFullNameType);
-            }
-
-            if (exceptionType != null)
-            {
-                Assert.Throws(exceptionType, () => Activator.CreateInstanceFrom(assemblyFile: assemblyFile, typeName: type, null));
-            }
-            else
-            {
-                oh = Activator.CreateInstanceFrom(assemblyFile: assemblyFile, typeName: type, null);
-                CheckValidity(oh, returnedFullNameType);
-            }
-            Assert.True(File.Exists(physicalFileName));
-        }
-
-        public static TheoryData<string, string, string, string, Type> TestingCreateInstanceFromObjectHandleData => new TheoryData<string, string, string, string, Type>()
-        {
-            // string physicalFileName, string assemblyFile, string typeName, returnedFullNameType, expectedException
-            { "TestLoadAssembly.dll", "TestLoadAssembly.dll", "PublicClassSample", "PublicClassSample", null },
-            { "TestLoadAssembly.dll", "testloadassembly.dll", "publicclasssample", "PublicClassSample", typeof(TypeLoadException) },
-
-            { "TestLoadAssembly.dll", "TestLoadAssembly.dll", "PrivateClassSample", "PrivateClassSample", null },
-            { "TestLoadAssembly.dll", "testloadassembly.dll", "privateclasssample", "PrivateClassSample", typeof(TypeLoadException) },
-
-            { "TestLoadAssembly.dll", "TestLoadAssembly.dll", "PublicClassNoDefaultConstructorSample", "PublicClassNoDefaultConstructorSample", typeof(MissingMethodException) },
-            { "TestLoadAssembly.dll", "testloadassembly.dll", "publicclassnodefaultconstructorsample", "PublicClassNoDefaultConstructorSample", typeof(TypeLoadException) }
-        };
-
-        [Theory]
-        [MemberData(nameof(TestingCreateInstanceObjectHandleData))]
-        public static void TestingCreateInstanceObjectHandle(string assemblyName, string type, string returnedFullNameType, Type exceptionType, bool returnNull)
-        {
-            ObjectHandle oh = null;
-
-            if (exceptionType != null)
-            {
-                Assert.Throws(exceptionType, () => Activator.CreateInstance(assemblyName: assemblyName, typeName: type));
-            }
-            else
-            {
-                oh = Activator.CreateInstance(assemblyName: assemblyName, typeName: type);
-                if (returnNull)
-                {
-                    Assert.Null(oh);
-                }
-                else
-                {
-                    CheckValidity(oh, returnedFullNameType);
-                }
-            }
-
-            if (exceptionType != null)
-            {
-                Assert.Throws(exceptionType, () => Activator.CreateInstance(assemblyName: assemblyName, typeName: type, null));
-            }
-            else
-            {
-                oh = Activator.CreateInstance(assemblyName: assemblyName, typeName: type, null);
-                if (returnNull)
-                {
-                    Assert.Null(oh);
-                }
-                else
-                {
-                    CheckValidity(oh, returnedFullNameType);
-                }
-            }
-        }
-
-        public static TheoryData<string, string, string, Type, bool> TestingCreateInstanceObjectHandleData => new TheoryData<string, string, string, Type, bool>()
-        {
-            // string assemblyName, string typeName, returnedFullNameType, expectedException
-            { "TestLoadAssembly", "PublicClassSample", "PublicClassSample", null, false },
-            { "testloadassembly", "publicclasssample", "PublicClassSample", typeof(TypeLoadException), false },
-
-            { "TestLoadAssembly", "PrivateClassSample", "PrivateClassSample", null, false },
-            { "testloadassembly", "privateclasssample", "PrivateClassSample", typeof(TypeLoadException), false },
-
-            { "TestLoadAssembly", "PublicClassNoDefaultConstructorSample", "PublicClassNoDefaultConstructorSample", typeof(MissingMethodException), false },
-            { "testloadassembly", "publicclassnodefaultconstructorsample", "PublicClassNoDefaultConstructorSample", typeof(TypeLoadException), false },
-
-            { "mscorlib", "System.Nullable`1[[System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]", "", null, true }
-        };
-
-        [Theory]
-        [MemberData(nameof(TestingCreateInstanceFromObjectHandleFullSignatureData))]
-        public static void TestingCreateInstanceFromObjectHandleFullSignature(string physicalFileName, string assemblyFile, string type, bool ignoreCase, BindingFlags bindingAttr, Binder binder, object[] args, CultureInfo culture, object[] activationAttributes, string returnedFullNameType)
-        {
-            ObjectHandle oh = Activator.CreateInstanceFrom(assemblyFile: assemblyFile, typeName: type, ignoreCase: ignoreCase, bindingAttr: bindingAttr, binder: binder, args: args, culture: culture, activationAttributes: activationAttributes);
-            CheckValidity(oh, returnedFullNameType);
-            Assert.True(File.Exists(physicalFileName));
-        }
-
-        public static IEnumerable<object[]> TestingCreateInstanceFromObjectHandleFullSignatureData()
-        {
-            // string physicalFileName, string assemblyFile, string typeName, bool ignoreCase, BindingFlags bindingAttr, Binder binder, object[] args, CultureInfo culture, object[] activationAttributes, returnedFullNameType
-            yield return new object[] { "TestLoadAssembly.dll", "TestLoadAssembly.dll", "PublicClassSample", false, BindingFlags.Public | BindingFlags.Instance, Type.DefaultBinder, new object[0], CultureInfo.InvariantCulture, null, "PublicClassSample" };
-            yield return new object[] { "TestLoadAssembly.dll", "testloadassembly.dll", "publicclasssample", true, BindingFlags.Public | BindingFlags.Instance, Type.DefaultBinder, new object[0], CultureInfo.InvariantCulture, null, "PublicClassSample" };
-            yield return new object[] { "TestLoadAssembly.dll", "TestLoadAssembly.dll", "PublicClassSample", false, BindingFlags.Public | BindingFlags.Instance, Type.DefaultBinder, new object[1] { 1 }, CultureInfo.InvariantCulture, null, "PublicClassSample" };
-            yield return new object[] { "TestLoadAssembly.dll", "testloadassembly.dll", "publicclasssample", true, BindingFlags.Public | BindingFlags.Instance, Type.DefaultBinder, new object[1] { 1 }, CultureInfo.InvariantCulture, null, "PublicClassSample" };
-
-            yield return new object[] { "TestLoadAssembly.dll", "TestLoadAssembly.dll", "PrivateClassSample", false, BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance, Type.DefaultBinder, new object[0], CultureInfo.InvariantCulture, null, "PrivateClassSample" };
-            yield return new object[] { "TestLoadAssembly.dll", "testloadassembly.dll", "privateclasssample", true, BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance, Type.DefaultBinder, new object[0], CultureInfo.InvariantCulture, null, "PrivateClassSample" };
-            yield return new object[] { "TestLoadAssembly.dll", "TestLoadAssembly.dll", "PrivateClassSample", false, BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance, Type.DefaultBinder, new object[1] { 1 }, CultureInfo.InvariantCulture, null, "PrivateClassSample" };
-            yield return new object[] { "TestLoadAssembly.dll", "testloadassembly.dll", "privateclasssample", true, BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance, Type.DefaultBinder, new object[1] { 1 }, CultureInfo.InvariantCulture, null, "PrivateClassSample" };
-        }
-
-        [Theory]
-        [MemberData(nameof(TestingCreateInstanceObjectHandleFullSignatureData))]
-        public static void TestingCreateInstanceObjectHandleFullSignature(string assemblyName, string type, bool ignoreCase, BindingFlags bindingAttr, Binder binder, object[] args, CultureInfo culture, object[] activationAttributes, string returnedFullNameType, bool returnNull)
-        {
-            ObjectHandle oh = Activator.CreateInstance(assemblyName: assemblyName, typeName: type, ignoreCase: ignoreCase, bindingAttr: bindingAttr, binder: binder, args: args, culture: culture, activationAttributes: activationAttributes);
-            if (returnNull)
-            {
-                Assert.Null(oh);
-            }
-            else
-            {
-                CheckValidity(oh, returnedFullNameType);
-            }
-        }
-
-        public static IEnumerable<object[]> TestingCreateInstanceObjectHandleFullSignatureData()
-        {
-            // string assemblyName, string typeName, bool ignoreCase, BindingFlags bindingAttr, Binder binder, object[] args, CultureInfo culture, object[] activationAttributes, returnedFullNameType
-            yield return new object[] { "TestLoadAssembly", "PublicClassSample", false, BindingFlags.Public | BindingFlags.Instance, Type.DefaultBinder, new object[0], CultureInfo.InvariantCulture, null, "PublicClassSample" , false };
-            yield return new object[] { "testloadassembly", "publicclasssample", true, BindingFlags.Public | BindingFlags.Instance, Type.DefaultBinder, new object[0], CultureInfo.InvariantCulture, null, "PublicClassSample" , false };
-            yield return new object[] { "TestLoadAssembly", "PublicClassSample", false, BindingFlags.Public | BindingFlags.Instance, Type.DefaultBinder, new object[1] { 1 }, CultureInfo.InvariantCulture, null, "PublicClassSample" , false };
-            yield return new object[] { "testloadassembly", "publicclasssample", true, BindingFlags.Public | BindingFlags.Instance, Type.DefaultBinder, new object[1] { 1 }, CultureInfo.InvariantCulture, null, "PublicClassSample" , false };
-
-            yield return new object[] { "TestLoadAssembly", "PrivateClassSample", false, BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance, Type.DefaultBinder, new object[0], CultureInfo.InvariantCulture, null, "PrivateClassSample", false };
-            yield return new object[] { "testloadassembly", "privateclasssample", true, BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance, Type.DefaultBinder, new object[0], CultureInfo.InvariantCulture, null, "PrivateClassSample", false };
-            yield return new object[] { "TestLoadAssembly", "PrivateClassSample", false, BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance, Type.DefaultBinder, new object[1] { 1 }, CultureInfo.InvariantCulture, null, "PrivateClassSample", false };
-            yield return new object[] { "testloadassembly", "privateclasssample", true, BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance, Type.DefaultBinder, new object[1] { 1 }, CultureInfo.InvariantCulture, null, "PrivateClassSample", false };
-
-            yield return new object[] { null, typeof(PublicType).FullName, false, BindingFlags.Public | BindingFlags.Instance, Type.DefaultBinder, new object[0], CultureInfo.InvariantCulture, null, typeof(PublicType).FullName, false };
-            yield return new object[] { null, typeof(PrivateType).FullName, false, BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance, Type.DefaultBinder, new object[0], CultureInfo.InvariantCulture, null, typeof(PrivateType).FullName, false };
-
-            yield return new object[] { "mscorlib", "System.Nullable`1[[System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]", true, BindingFlags.Public | BindingFlags.Instance, Type.DefaultBinder, new object[0], CultureInfo.InvariantCulture, null, "", true };
-            yield return new object[] { "mscorlib", "SyStEm.NULLABLE`1[[System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]", true, BindingFlags.Public | BindingFlags.Instance, Type.DefaultBinder, new object[0], CultureInfo.InvariantCulture, null, "", true };
-        }
-
-        [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsWinUISupported))]
-        [PlatformSpecific(TestPlatforms.Windows)]
-        [MemberData(nameof(TestingCreateInstanceObjectHandleFullSignatureWinRTData))]
-        public static void TestingCreateInstanceObjectHandleFullSignatureWinRT(string assemblyName, string type, bool ignoreCase, BindingFlags bindingAttr, Binder binder, object[] args, CultureInfo culture, object[] activationAttributes, string returnedFullNameType)
-        {
-            ObjectHandle oh = Activator.CreateInstance(assemblyName: assemblyName, typeName: type, ignoreCase: ignoreCase, bindingAttr: bindingAttr, binder: binder, args: args, culture: culture, activationAttributes: activationAttributes);
-            CheckValidity(oh, returnedFullNameType);
-        }
-
-        public static IEnumerable<object[]> TestingCreateInstanceObjectHandleFullSignatureWinRTData()
-        {
-            // string assemblyName, string typeName, bool ignoreCase, BindingFlags bindingAttr, Binder binder, object[] args, CultureInfo culture, object[] activationAttributes, returnedFullNameType
-            yield return new object[] { "Windows, Version=255.255.255.255, Culture=neutral, PublicKeyToken=null, ContentType=WindowsRuntime", "Windows.Foundation.Collections.StringMap", false, BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance, Type.DefaultBinder, new object[0], CultureInfo.InvariantCulture, null, "Windows.Foundation.Collections.StringMap" };
-        }
-
-        private static void CheckValidity(ObjectHandle instance, string expected)
-        {
-            Assert.NotNull(instance);
-            Assert.Equal(expected, instance.Unwrap().GetType().FullName);
-        }
-
-        public class PublicType
-        {
-            public PublicType() { }
-        }
-
-        [Fact]
-        public static void CreateInstanceAssemblyResolve()
-        {
-            RemoteExecutor.Invoke(() =>
-            {
-                AppDomain.CurrentDomain.AssemblyResolve += (object sender, ResolveEventArgs args) => Assembly.LoadFile(Path.Combine(Directory.GetCurrentDirectory(), "TestLoadAssembly.dll"));
-                Assert.Throws<FileLoadException>(() => Activator.CreateInstance(",,,,", "PublicClassSample"));
-            }).Dispose();
-        }
-
-        [Fact]
-        public void CreateInstance_TypeBuilder_ThrowsNotSupportedException()
-        {
-            AssemblyName assemblyName = new AssemblyName("Assembly");
-            AssemblyBuilder assemblyBuilder = AssemblyBuilder.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.Run);
-            ModuleBuilder moduleBuilder = assemblyBuilder.DefineDynamicModule("Module");
-            TypeBuilder typeBuilder = moduleBuilder.DefineType("Type", TypeAttributes.Public);
-
-            Assert.Throws<ArgumentException>("type", () => Activator.CreateInstance(typeBuilder));
-            Assert.Throws<NotSupportedException>(() => Activator.CreateInstance(typeBuilder, new object[0]));
-        }
-    }
-}
index 343e93d..986c7ca 100644 (file)
@@ -88,6 +88,116 @@ namespace System.Tests
             AssertExtensions.Throws<ArgumentException>(null, () => new ArraySegment<T>(new T[10], 10, 1)); // Offset + count > array.Length
             AssertExtensions.Throws<ArgumentException>(null, () => new ArraySegment<T>(new T[10], 9, 2)); // Offset + count > array.Length
         }
+
+        [Fact]
+        public void CopyTo_Default_ThrowsInvalidOperationException()
+        {
+            // Source is default
+            Assert.Throws<InvalidOperationException>(() => default(ArraySegment<T>).CopyTo(new T[0]));
+            Assert.Throws<InvalidOperationException>(() => default(ArraySegment<T>).CopyTo(new T[0], 0));
+            Assert.Throws<InvalidOperationException>(() => ((ICollection<T>)default(ArraySegment<T>)).CopyTo(new T[0], 0));
+            Assert.Throws<InvalidOperationException>(() => default(ArraySegment<T>).CopyTo(new ArraySegment<T>(new T[0])));
+
+            // Destination is default
+            Assert.Throws<InvalidOperationException>(() => new ArraySegment<T>(new T[0]).CopyTo(default(ArraySegment<T>)));
+        }
+
+        [Fact]
+        public void Empty()
+        {
+            ArraySegment<T> empty = ArraySegment<T>.Empty;
+
+            // Assert.NotEqual uses its own Comparer, when it is comparing IEnumerables it calls GetEnumerator()
+            // ArraySegment<T>.GetEnumerator() throws InvalidOperationException when the array is null and default() returns null
+            Assert.True(default(ArraySegment<T>) != empty);
+
+            // Check that two Empty invocations return equal ArraySegments.
+            Assert.Equal(empty, ArraySegment<T>.Empty);
+
+            // Check that two Empty invocations return ArraySegments with a cached empty array.
+            // An empty array is necessary to ensure that someone doesn't use the indexer to store data in the array Empty refers to.
+            Assert.Same(empty.Array, ArraySegment<T>.Empty.Array);
+            Assert.Equal(0, empty.Array.Length);
+            Assert.Equal(0, empty.Offset);
+            Assert.Equal(0, empty.Count);
+        }
+
+        [Fact]
+        public void GetEnumerator_TypeProperties()
+        {
+            var arraySegment = new ArraySegment<T>(new T[1], 0, 1);
+            var ienumerableoft = (IEnumerable<T>)arraySegment;
+            var ienumerable = (IEnumerable)arraySegment;
+
+            ArraySegment<T>.Enumerator enumerator = arraySegment.GetEnumerator();
+            Assert.IsType<ArraySegment<T>.Enumerator>(enumerator);
+            Assert.IsAssignableFrom<IEnumerator<T>>(enumerator);
+            Assert.IsAssignableFrom<IEnumerator>(enumerator);
+
+            IEnumerator<T> ienumeratoroft = ienumerableoft.GetEnumerator();
+            IEnumerator ienumerator = ienumerable.GetEnumerator();
+
+            Assert.Equal(enumerator.GetType(), ienumeratoroft.GetType());
+            Assert.Equal(ienumeratoroft.GetType(), ienumerator.GetType());
+        }
+
+        [Fact]
+        public void GetEnumerator_Default_ThrowsInvalidOperationException()
+        {
+            Assert.Throws<InvalidOperationException>(() => default(ArraySegment<T>).GetEnumerator());
+        }
+
+        [Fact]
+        public void Slice_Default_ThrowsInvalidOperationException()
+        {
+            Assert.Throws<InvalidOperationException>(() => default(ArraySegment<T>).Slice(0));
+            Assert.Throws<InvalidOperationException>(() => default(ArraySegment<T>).Slice(0, 0));
+        }
+
+        [Fact]
+        public void ToArray_Default_ThrowsInvalidOperationException()
+        {
+            Assert.Throws<InvalidOperationException>(() => default(ArraySegment<T>).ToArray());
+        }
+
+        [Fact]
+        public void ToArray_Empty_ReturnsSameArray()
+        {
+            T[] cachedArray = ArraySegment<T>.Empty.ToArray();
+            Assert.Same(cachedArray, ArraySegment<T>.Empty.ToArray());
+            Assert.Same(cachedArray, new ArraySegment<T>(new T[0]).ToArray());
+            Assert.Same(cachedArray, new ArraySegment<T>(new T[1], 0, 0).ToArray());
+        }
+
+        [Fact]
+        public void ToArray_NonEmptyArray_DoesNotReturnSameArray()
+        {
+            // Prevent a faulty implementation like `if (Count == 0) { return Array; }`
+            var emptyArraySegment = new ArraySegment<T>(new T[1], 0, 0);
+            Assert.NotSame(emptyArraySegment.Array, emptyArraySegment.ToArray());
+        }
+
+        [Fact]
+        public void Cast_FromNullArray_ReturnsDefault()
+        {
+            ArraySegment<T> fromNull = null;
+            Assert.Null(fromNull.Array);
+            Assert.Equal(0, fromNull.Offset);
+            Assert.Equal(0, fromNull.Count);
+
+            Assert.True(default(ArraySegment<T>) == null);
+            Assert.True(new ArraySegment<T>(Array.Empty<T>()) != null);
+        }
+
+        [Fact]
+        public void Cast_FromValidArray_ReturnsSegmentForWholeArray()
+        {
+            var array = new T[42];
+            ArraySegment<T> fromArray = array;
+            Assert.Same(array, fromArray.Array);
+            Assert.Equal(0, fromArray.Offset);
+            Assert.Equal(42, fromArray.Count);
+        }
     }
 
     public class ArraySegment_Tests_string : ArraySegment_Tests<string>
@@ -272,5 +382,352 @@ namespace System.Tests
                 (enumerator as IEnumerator<int>).Reset();
             }
         }
+
+        [Theory]
+        [MemberData(nameof(Conversion_FromArray_TestData))]
+        public static void Conversion_FromArray(int[] array)
+        {
+            ArraySegment<int> implicitlyConverted = array;
+            ArraySegment<int> explicitlyConverted = (ArraySegment<int>)array;
+
+            var expected = new ArraySegment<int>(array);
+            Assert.Equal(expected, implicitlyConverted);
+            Assert.Equal(expected, explicitlyConverted);
+        }
+
+        public static IEnumerable<object[]> Conversion_FromArray_TestData()
+        {
+            yield return new object[] { new int[0] };
+            yield return new object[] { new int[1] };
+        }
+
+        [Theory]
+        [MemberData(nameof(ArraySegment_TestData))]
+        public static void CopyTo(ArraySegment<int> arraySegment)
+        {
+            const int CopyPadding = 5;
+            const int DestinationSegmentPadding = 3;
+
+            int count = arraySegment.Count;
+
+            var destinationModel = new int[count + 2 * CopyPadding];
+
+            // CopyTo(T[])
+            CopyAndInvoke(destinationModel, destination =>
+            {
+                arraySegment.CopyTo(destination);
+
+                Assert.Equal(Enumerable.Repeat(default(int), 2 * CopyPadding), destination.Skip(count));
+
+                Assert.Equal(arraySegment, destination.Take(count));
+            });
+
+            // CopyTo(T[], int)
+            CopyAndInvoke(destinationModel, destination =>
+            {
+                arraySegment.CopyTo(destination, CopyPadding);
+
+                Assert.Equal(Enumerable.Repeat(default(int), CopyPadding), destination.Take(CopyPadding));
+                Assert.Equal(Enumerable.Repeat(default(int), CopyPadding), destination.Skip(CopyPadding + count));
+
+                Assert.Equal(arraySegment, destination.Skip(CopyPadding).Take(count));
+            });
+
+            // ICollection<T>.CopyTo(T[], int)
+            CopyAndInvoke(destinationModel, destination =>
+            {
+                ((ICollection<int>)arraySegment).CopyTo(destination, CopyPadding);
+
+                Assert.Equal(Enumerable.Repeat(default(int), CopyPadding), destination.Take(CopyPadding));
+                Assert.Equal(Enumerable.Repeat(default(int), CopyPadding), destination.Skip(CopyPadding + count));
+
+                Assert.Equal(arraySegment, destination.Skip(CopyPadding).Take(count));
+            });
+
+            // CopyTo(ArraySegment<T>)
+            CopyAndInvoke(destinationModel, destination =>
+            {
+                // We want to make sure this overload is handling edge cases correctly, like ArraySegments that
+                // do not begin at the array's start, do not end at the array's end, or have a bigger count than
+                // the source ArraySegment. Construct an ArraySegment that will test all of these conditions.
+                int destinationIndex = DestinationSegmentPadding;
+                int destinationCount = destination.Length - 2 * DestinationSegmentPadding;
+                var destinationSegment = new ArraySegment<int>(destination, destinationIndex, destinationCount);
+
+                arraySegment.CopyTo(destinationSegment);
+
+                Assert.Equal(Enumerable.Repeat(default(int), destinationIndex), destination.Take(destinationIndex));
+                int remainder = destination.Length - destinationIndex - count;
+                Assert.Equal(Enumerable.Repeat(default(int), remainder), destination.Skip(destinationIndex + count));
+
+                Assert.Equal(arraySegment, destination.Skip(destinationIndex).Take(count));
+            });
+        }
+
+        private static void CopyAndInvoke<T>(T[] array, Action<T[]> action) => action(array.ToArray());
+
+        [Theory]
+        [MemberData(nameof(ArraySegment_TestData))]
+        public static void CopyTo_Invalid(ArraySegment<int> arraySegment)
+        {
+            int count = arraySegment.Count;
+
+            // ArraySegment.CopyTo calls Array.Copy internally, so the exception parameter names come from there.
+
+            // Destination is null
+            AssertExtensions.Throws<ArgumentNullException>("destinationArray", () => arraySegment.CopyTo(null));
+            AssertExtensions.Throws<ArgumentNullException>("destinationArray", () => arraySegment.CopyTo(null, 0));
+
+            // Destination index not within range
+            AssertExtensions.Throws<ArgumentOutOfRangeException>("destinationIndex", () => arraySegment.CopyTo(new int[0], -1));
+
+            // Destination array too small arraySegment.Count + destinationIndex > destinationArray.Length
+            AssertExtensions.Throws<ArgumentException>("destinationArray", () => arraySegment.CopyTo(new int[arraySegment.Count * 2], arraySegment.Count + 1));
+
+            if (arraySegment.Any())
+            {
+                // Destination not large enough
+                AssertExtensions.Throws<ArgumentException>("destinationArray", () => arraySegment.CopyTo(new int[count - 1]));
+                AssertExtensions.Throws<ArgumentException>("destinationArray", () => arraySegment.CopyTo(new int[count - 1], 0));
+                AssertExtensions.Throws<ArgumentException>("destination", null, () => arraySegment.CopyTo(new ArraySegment<int>(new int[count - 1])));
+
+                // Don't write beyond the limits of the destination in cases where source.Count > destination.Count
+                AssertExtensions.Throws<ArgumentException>("destination", null, () => arraySegment.CopyTo(new ArraySegment<int>(new int[count], 1, 0))); // destination.Array can't fit source at destination.Offset
+                AssertExtensions.Throws<ArgumentException>("destination", null, () => arraySegment.CopyTo(new ArraySegment<int>(new int[count], 0, count - 1))); // destination.Array can fit source at destination.Offset, but destination can't
+            }
+        }
+
+        [Theory]
+        [MemberData(nameof(ArraySegment_TestData))]
+        public static void GetEnumerator(ArraySegment<int> arraySegment)
+        {
+            int[] array = arraySegment.Array;
+            int index = arraySegment.Offset;
+            int count = arraySegment.Count;
+
+            ArraySegment<int>.Enumerator enumerator = arraySegment.GetEnumerator();
+
+            var actual = new List<int>();
+
+            while (enumerator.MoveNext())
+            {
+                actual.Add(enumerator.Current);
+            }
+
+            // After MoveNext returns false once, it should return false the second time.
+            Assert.False(enumerator.MoveNext());
+
+            IEnumerable<int> expected = array.Skip(index).Take(count);
+            Assert.Equal(expected, actual);
+        }
+
+        [Theory]
+        [MemberData(nameof(ArraySegment_TestData))]
+        public static void GetEnumerator_Dispose(ArraySegment<int> arraySegment)
+        {
+            int[] array = arraySegment.Array;
+            int index = arraySegment.Offset;
+
+            ArraySegment<int>.Enumerator enumerator = arraySegment.GetEnumerator();
+
+            bool expected = arraySegment.Count > 0;
+
+            // Dispose shouldn't do anything. Call it twice and then assert like nothing happened.
+            enumerator.Dispose();
+            enumerator.Dispose();
+
+            Assert.Equal(expected, enumerator.MoveNext());
+            if (expected)
+            {
+                Assert.Equal(array[index], enumerator.Current);
+            }
+        }
+
+        [Theory]
+        [MemberData(nameof(ArraySegment_TestData))]
+        public static void GetEnumerator_Reset(ArraySegment<int> arraySegment)
+        {
+            int[] array = arraySegment.Array;
+            int index = arraySegment.Offset;
+            int count = arraySegment.Count;
+
+            var enumerator = (IEnumerator<int>)arraySegment.GetEnumerator();
+
+            int[] expected = array.Skip(index).Take(count).ToArray();
+
+            // Reset at a variety of different positions to ensure the implementation
+            // isn't something like `position -= CONSTANT`.
+            for (int i = 0; i < 3; i++)
+            {
+                for (int j = 0; j < i; j++)
+                {
+                    if (enumerator.MoveNext())
+                    {
+                        Assert.Equal(expected[j], enumerator.Current);
+                    }
+                }
+
+                enumerator.Reset();
+            }
+        }
+
+        [Theory]
+        [MemberData(nameof(ArraySegment_TestData))]
+        public static void GetEnumerator_Invalid(ArraySegment<int> arraySegment)
+        {
+            ArraySegment<int>.Enumerator enumerator = arraySegment.GetEnumerator();
+
+            // Before beginning
+            Assert.Throws<InvalidOperationException>(() => enumerator.Current);
+            Assert.Throws<InvalidOperationException>(() => ((IEnumerator<int>)enumerator).Current);
+            Assert.Throws<InvalidOperationException>(() => ((IEnumerator)enumerator).Current);
+
+            while (enumerator.MoveNext()) ;
+
+            // After end
+            Assert.Throws<InvalidOperationException>(() => enumerator.Current);
+            Assert.Throws<InvalidOperationException>(() => ((IEnumerator<int>)enumerator).Current);
+            Assert.Throws<InvalidOperationException>(() => ((IEnumerator)enumerator).Current);
+        }
+
+        [Theory]
+        [MemberData(nameof(ArraySegment_TestData))]
+        public static void GetSetItem_InRange(ArraySegment<int> arraySegment)
+        {
+            int[] array = arraySegment.Array;
+            int index = arraySegment.Offset;
+            int count = arraySegment.Count;
+
+            int[] expected = array.Skip(index).Take(count).ToArray();
+
+            for (int i = 0; i < count; i++)
+            {
+                Assert.Equal(expected[i], arraySegment[i]);
+                Assert.Equal(expected[i], ((IList<int>)arraySegment)[i]);
+                Assert.Equal(expected[i], ((IReadOnlyList<int>)arraySegment)[i]);
+            }
+
+            var r = new Random(0);
+
+            for (int i = 0; i < count; i++)
+            {
+                int next = r.Next(int.MinValue, int.MaxValue);
+
+                // When we modify the underlying array, the indexer should return the updated values.
+                array[arraySegment.Offset + i] ^= next;
+                Assert.Equal(expected[i] ^ next, arraySegment[i]);
+
+                // When the indexer's set method is called, the underlying array should be modified.
+                arraySegment[i] ^= next;
+                Assert.Equal(expected[i], array[arraySegment.Offset + i]);
+            }
+        }
+
+        [Theory]
+        [MemberData(nameof(ArraySegment_TestData))]
+        public static void GetSetItem_NotInRange_Invalid(ArraySegment<int> arraySegment)
+        {
+            int[] array = arraySegment.Array;
+
+            // Before array start
+            Assert.Throws<ArgumentOutOfRangeException>(() => arraySegment[-arraySegment.Offset - 1]);
+            Assert.Throws<ArgumentOutOfRangeException>(() => arraySegment[-arraySegment.Offset - 1] = default(int));
+
+            // After array start (if Offset > 0), before start
+            Assert.Throws<ArgumentOutOfRangeException>(() => arraySegment[-1]);
+            Assert.Throws<ArgumentOutOfRangeException>(() => arraySegment[-1] = default(int));
+
+            // Before array end (if Offset + Count < Array.Length), after end
+            Assert.Throws<ArgumentOutOfRangeException>(() => arraySegment[arraySegment.Count]);
+            Assert.Throws<ArgumentOutOfRangeException>(() => arraySegment[arraySegment.Count] = default(int));
+
+            // After array end
+            Assert.Throws<ArgumentOutOfRangeException>(() => arraySegment[-arraySegment.Offset + array.Length]);
+            Assert.Throws<ArgumentOutOfRangeException>(() => arraySegment[-arraySegment.Offset + array.Length] = default(int));
+        }
+
+        [Theory]
+        [MemberData(nameof(Slice_TestData))]
+        public static void Slice(ArraySegment<int> arraySegment, int index, int count)
+        {
+            var expected = new ArraySegment<int>(arraySegment.Array, arraySegment.Offset + index, count);
+
+            if (index + count == arraySegment.Count)
+            {
+                Assert.Equal(expected, arraySegment.Slice(index));
+            }
+
+            Assert.Equal(expected, arraySegment.Slice(index, count));
+        }
+
+        public static IEnumerable<object[]> Slice_TestData()
+        {
+            IEnumerable<ArraySegment<int>> arraySegments = ArraySegment_TestData().Select(array => array.Single()).Cast<ArraySegment<int>>();
+
+            foreach (ArraySegment<int> arraySegment in arraySegments)
+            {
+                yield return new object[] { arraySegment, 0, 0 }; // Preserve start, no items
+                yield return new object[] { arraySegment, 0, arraySegment.Count }; // Preserve start, preserve count (noop)
+                yield return new object[] { arraySegment, arraySegment.Count, 0 }; // Start at end, no items
+
+                if (arraySegment.Any())
+                {
+                    yield return new object[] { arraySegment, 1, 0 }; // Start at middle or end, no items
+                    yield return new object[] { arraySegment, 1, arraySegment.Count - 1 }; // Start at middle or end, rest of items
+                    yield return new object[] { arraySegment, arraySegment.Count - 1, 1 }; // Preserve start or start at middle, one item
+                }
+
+                yield return new object[] { arraySegment, 0, arraySegment.Count / 2 }; // Preserve start, multiple items, end at middle
+                yield return new object[] { arraySegment, arraySegment.Count / 2, arraySegment.Count / 2 }; // Start at middle, multiple items, end at middle (due to integer division truncation) or preserve end
+                yield return new object[] { arraySegment, arraySegment.Count / 4, arraySegment.Count / 2 }; // Start at middle, multiple items, end at middle
+            }
+        }
+
+        [Theory]
+        [MemberData(nameof(Slice_Invalid_TestData))]
+        public static void Slice_Invalid(ArraySegment<int> arraySegment, int index, int count)
+        {
+            if (index + count == arraySegment.Count)
+            {
+                AssertExtensions.Throws<ArgumentOutOfRangeException>("index", () => arraySegment.Slice(index));
+            }
+
+            AssertExtensions.Throws<ArgumentOutOfRangeException>("index", () => arraySegment.Slice(index, count));
+        }
+
+        public static IEnumerable<object[]> Slice_Invalid_TestData()
+        {
+            var arraySegment = new ArraySegment<int>(new int[3], offset: 1, count: 1);
+
+            yield return new object[] { arraySegment, -arraySegment.Offset, arraySegment.Offset };
+            yield return new object[] { arraySegment, -arraySegment.Offset, arraySegment.Offset + arraySegment.Count };
+            yield return new object[] { arraySegment, -arraySegment.Offset, arraySegment.Array.Length };
+            yield return new object[] { arraySegment, 0, arraySegment.Array.Length - arraySegment.Offset };
+            yield return new object[] { arraySegment, arraySegment.Count, arraySegment.Array.Length - arraySegment.Offset - arraySegment.Count };
+        }
+
+        [Theory]
+        [MemberData(nameof(ArraySegment_TestData))]
+        public static void ToArray(ArraySegment<int> arraySegment)
+        {
+            // ToList is called here so we copy the data and raise an assert if ToArray modifies the underlying array.
+            List<int> expected = arraySegment.Array.Skip(arraySegment.Offset).Take(arraySegment.Count).ToList();
+            Assert.Equal(expected, arraySegment.ToArray());
+        }
+
+        public static IEnumerable<object[]> ArraySegment_TestData()
+        {
+            var arraySegments = new (int[] array, int index, int count)[]
+            {
+                (array: new int[0], index: 0, 0), // Empty array
+                (array: new[] { 3, 4, 5, 6 }, index: 0, count: 4), // Full span of non-empty array
+                (array: new[] { 3, 4, 5, 6 }, index: 0, count: 3), // Starts at beginning, ends in middle
+                (array: new[] { 3, 4, 5, 6 }, index: 1, count: 3), // Starts in middle, ends at end
+                (array: new[] { 3, 4, 5, 6 }, index: 1, count: 2), // Starts in middle, ends in middle
+                (array: new[] { 3, 4, 5, 6 }, index: 1, count: 0) // Non-empty array, count == 0
+            };
+
+            return arraySegments.Select(aseg => new object[] { new ArraySegment<int>(aseg.array, aseg.index, aseg.count) });
+        }
     }
 }
diff --git a/src/libraries/System.Runtime/tests/System/ArraySegmentTests.netcoreapp.cs b/src/libraries/System.Runtime/tests/System/ArraySegmentTests.netcoreapp.cs
deleted file mode 100644 (file)
index 3247fd1..0000000
+++ /dev/null
@@ -1,474 +0,0 @@
-// 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;
-using System.Collections.Generic;
-using System.Linq;
-using Xunit;
-
-namespace System.Tests
-{
-    public abstract partial class ArraySegment_Tests<T>
-    {
-        [Fact]
-        public void CopyTo_Default_ThrowsInvalidOperationException()
-        {
-            // Source is default
-            Assert.Throws<InvalidOperationException>(() => default(ArraySegment<T>).CopyTo(new T[0]));
-            Assert.Throws<InvalidOperationException>(() => default(ArraySegment<T>).CopyTo(new T[0], 0));
-            Assert.Throws<InvalidOperationException>(() => ((ICollection<T>)default(ArraySegment<T>)).CopyTo(new T[0], 0));
-            Assert.Throws<InvalidOperationException>(() => default(ArraySegment<T>).CopyTo(new ArraySegment<T>(new T[0])));
-
-            // Destination is default
-            Assert.Throws<InvalidOperationException>(() => new ArraySegment<T>(new T[0]).CopyTo(default(ArraySegment<T>)));
-        }
-
-        [Fact]
-        public void Empty()
-        {
-            ArraySegment<T> empty = ArraySegment<T>.Empty;
-
-            // Assert.NotEqual uses its own Comparer, when it is comparing IEnumerables it calls GetEnumerator()
-            // ArraySegment<T>.GetEnumerator() throws InvalidOperationException when the array is null and default() returns null
-            Assert.True(default(ArraySegment<T>) != empty);
-
-            // Check that two Empty invocations return equal ArraySegments.
-            Assert.Equal(empty, ArraySegment<T>.Empty);
-
-            // Check that two Empty invocations return ArraySegments with a cached empty array.
-            // An empty array is necessary to ensure that someone doesn't use the indexer to store data in the array Empty refers to.
-            Assert.Same(empty.Array, ArraySegment<T>.Empty.Array);
-            Assert.Equal(0, empty.Array.Length);
-            Assert.Equal(0, empty.Offset);
-            Assert.Equal(0, empty.Count);
-        }
-
-        [Fact]
-        public void GetEnumerator_TypeProperties()
-        {
-            var arraySegment = new ArraySegment<T>(new T[1], 0, 1);
-            var ienumerableoft = (IEnumerable<T>)arraySegment;
-            var ienumerable = (IEnumerable)arraySegment;
-
-            ArraySegment<T>.Enumerator enumerator = arraySegment.GetEnumerator();
-            Assert.IsType<ArraySegment<T>.Enumerator>(enumerator);
-            Assert.IsAssignableFrom<IEnumerator<T>>(enumerator);
-            Assert.IsAssignableFrom<IEnumerator>(enumerator);
-
-            IEnumerator<T> ienumeratoroft = ienumerableoft.GetEnumerator();
-            IEnumerator ienumerator = ienumerable.GetEnumerator();
-
-            Assert.Equal(enumerator.GetType(), ienumeratoroft.GetType());
-            Assert.Equal(ienumeratoroft.GetType(), ienumerator.GetType());
-        }
-
-        [Fact]
-        public void GetEnumerator_Default_ThrowsInvalidOperationException()
-        {
-            Assert.Throws<InvalidOperationException>(() => default(ArraySegment<T>).GetEnumerator());
-        }
-
-        [Fact]
-        public void Slice_Default_ThrowsInvalidOperationException()
-        {
-            Assert.Throws<InvalidOperationException>(() => default(ArraySegment<T>).Slice(0));
-            Assert.Throws<InvalidOperationException>(() => default(ArraySegment<T>).Slice(0, 0));
-        }
-
-        [Fact]
-        public void ToArray_Default_ThrowsInvalidOperationException()
-        {
-            Assert.Throws<InvalidOperationException>(() => default(ArraySegment<T>).ToArray());
-        }
-
-        [Fact]
-        public void ToArray_Empty_ReturnsSameArray()
-        {
-            T[] cachedArray = ArraySegment<T>.Empty.ToArray();
-            Assert.Same(cachedArray, ArraySegment<T>.Empty.ToArray());
-            Assert.Same(cachedArray, new ArraySegment<T>(new T[0]).ToArray());
-            Assert.Same(cachedArray, new ArraySegment<T>(new T[1], 0, 0).ToArray());
-        }
-
-        [Fact]
-        public void ToArray_NonEmptyArray_DoesNotReturnSameArray()
-        {
-            // Prevent a faulty implementation like `if (Count == 0) { return Array; }`
-            var emptyArraySegment = new ArraySegment<T>(new T[1], 0, 0);
-            Assert.NotSame(emptyArraySegment.Array, emptyArraySegment.ToArray());
-        }
-
-        [Fact]
-        public void Cast_FromNullArray_ReturnsDefault()
-        {
-            ArraySegment<T> fromNull = null;
-            Assert.Null(fromNull.Array);
-            Assert.Equal(0, fromNull.Offset);
-            Assert.Equal(0, fromNull.Count);
-
-            Assert.True(default(ArraySegment<T>) == null);
-            Assert.True(new ArraySegment<T>(Array.Empty<T>()) != null);
-        }
-
-        [Fact]
-        public void Cast_FromValidArray_ReturnsSegmentForWholeArray()
-        {
-            var array = new T[42];
-            ArraySegment<T> fromArray = array;
-            Assert.Same(array, fromArray.Array);
-            Assert.Equal(0, fromArray.Offset);
-            Assert.Equal(42, fromArray.Count);
-        }
-    }
-
-    public static partial class ArraySegment_Tests
-    {
-        [Theory]
-        [MemberData(nameof(Conversion_FromArray_TestData))]
-        public static void Conversion_FromArray(int[] array)
-        {
-            ArraySegment<int> implicitlyConverted = array;
-            ArraySegment<int> explicitlyConverted = (ArraySegment<int>)array;
-
-            var expected = new ArraySegment<int>(array);
-            Assert.Equal(expected, implicitlyConverted);
-            Assert.Equal(expected, explicitlyConverted);
-        }
-
-        public static IEnumerable<object[]> Conversion_FromArray_TestData()
-        {
-            yield return new object[] { new int[0] };
-            yield return new object[] { new int[1] };
-        }
-
-        [Theory]
-        [MemberData(nameof(ArraySegment_TestData))]
-        public static void CopyTo(ArraySegment<int> arraySegment)
-        {
-            const int CopyPadding = 5;
-            const int DestinationSegmentPadding = 3;
-
-            int count = arraySegment.Count;
-
-            var destinationModel = new int[count + 2 * CopyPadding];
-
-            // CopyTo(T[])
-            CopyAndInvoke(destinationModel, destination =>
-            {
-                arraySegment.CopyTo(destination);
-
-                Assert.Equal(Enumerable.Repeat(default(int), 2 * CopyPadding), destination.Skip(count));
-
-                Assert.Equal(arraySegment, destination.Take(count));
-            });
-
-            // CopyTo(T[], int)
-            CopyAndInvoke(destinationModel, destination =>
-            {
-                arraySegment.CopyTo(destination, CopyPadding);
-
-                Assert.Equal(Enumerable.Repeat(default(int), CopyPadding), destination.Take(CopyPadding));
-                Assert.Equal(Enumerable.Repeat(default(int), CopyPadding), destination.Skip(CopyPadding + count));
-
-                Assert.Equal(arraySegment, destination.Skip(CopyPadding).Take(count));
-            });
-
-            // ICollection<T>.CopyTo(T[], int)
-            CopyAndInvoke(destinationModel, destination =>
-            {
-                ((ICollection<int>)arraySegment).CopyTo(destination, CopyPadding);
-
-                Assert.Equal(Enumerable.Repeat(default(int), CopyPadding), destination.Take(CopyPadding));
-                Assert.Equal(Enumerable.Repeat(default(int), CopyPadding), destination.Skip(CopyPadding + count));
-
-                Assert.Equal(arraySegment, destination.Skip(CopyPadding).Take(count));
-            });
-
-            // CopyTo(ArraySegment<T>)
-            CopyAndInvoke(destinationModel, destination =>
-            {
-                // We want to make sure this overload is handling edge cases correctly, like ArraySegments that
-                // do not begin at the array's start, do not end at the array's end, or have a bigger count than
-                // the source ArraySegment. Construct an ArraySegment that will test all of these conditions.
-                int destinationIndex = DestinationSegmentPadding;
-                int destinationCount = destination.Length - 2 * DestinationSegmentPadding;
-                var destinationSegment = new ArraySegment<int>(destination, destinationIndex, destinationCount);
-
-                arraySegment.CopyTo(destinationSegment);
-
-                Assert.Equal(Enumerable.Repeat(default(int), destinationIndex), destination.Take(destinationIndex));
-                int remainder = destination.Length - destinationIndex - count;
-                Assert.Equal(Enumerable.Repeat(default(int), remainder), destination.Skip(destinationIndex + count));
-
-                Assert.Equal(arraySegment, destination.Skip(destinationIndex).Take(count));
-            });
-        }
-
-        private static void CopyAndInvoke<T>(T[] array, Action<T[]> action) => action(array.ToArray());
-
-        [Theory]
-        [MemberData(nameof(ArraySegment_TestData))]
-        public static void CopyTo_Invalid(ArraySegment<int> arraySegment)
-        {
-            int count = arraySegment.Count;
-
-            // ArraySegment.CopyTo calls Array.Copy internally, so the exception parameter names come from there.
-
-            // Destination is null
-            AssertExtensions.Throws<ArgumentNullException>("destinationArray", () => arraySegment.CopyTo(null));
-            AssertExtensions.Throws<ArgumentNullException>("destinationArray", () => arraySegment.CopyTo(null, 0));
-
-            // Destination index not within range
-            AssertExtensions.Throws<ArgumentOutOfRangeException>("destinationIndex", () => arraySegment.CopyTo(new int[0], -1));
-
-            // Destination array too small arraySegment.Count + destinationIndex > destinationArray.Length
-            AssertExtensions.Throws<ArgumentException>("destinationArray", () => arraySegment.CopyTo(new int[arraySegment.Count * 2], arraySegment.Count + 1));
-
-            if (arraySegment.Any())
-            {
-                // Destination not large enough
-                AssertExtensions.Throws<ArgumentException>("destinationArray", () => arraySegment.CopyTo(new int[count - 1]));
-                AssertExtensions.Throws<ArgumentException>("destinationArray", () => arraySegment.CopyTo(new int[count - 1], 0));
-                AssertExtensions.Throws<ArgumentException>("destination", null, () => arraySegment.CopyTo(new ArraySegment<int>(new int[count - 1])));
-
-                // Don't write beyond the limits of the destination in cases where source.Count > destination.Count
-                AssertExtensions.Throws<ArgumentException>("destination", null, () => arraySegment.CopyTo(new ArraySegment<int>(new int[count], 1, 0))); // destination.Array can't fit source at destination.Offset
-                AssertExtensions.Throws<ArgumentException>("destination", null, () => arraySegment.CopyTo(new ArraySegment<int>(new int[count], 0, count - 1))); // destination.Array can fit source at destination.Offset, but destination can't
-            }
-        }
-
-        [Theory]
-        [MemberData(nameof(ArraySegment_TestData))]
-        public static void GetEnumerator(ArraySegment<int> arraySegment)
-        {
-            int[] array = arraySegment.Array;
-            int index = arraySegment.Offset;
-            int count = arraySegment.Count;
-
-            ArraySegment<int>.Enumerator enumerator = arraySegment.GetEnumerator();
-
-            var actual = new List<int>();
-
-            while (enumerator.MoveNext())
-            {
-                actual.Add(enumerator.Current);
-            }
-
-            // After MoveNext returns false once, it should return false the second time.
-            Assert.False(enumerator.MoveNext());
-
-            IEnumerable<int> expected = array.Skip(index).Take(count);
-            Assert.Equal(expected, actual);
-        }
-
-        [Theory]
-        [MemberData(nameof(ArraySegment_TestData))]
-        public static void GetEnumerator_Dispose(ArraySegment<int> arraySegment)
-        {
-            int[] array = arraySegment.Array;
-            int index = arraySegment.Offset;
-
-            ArraySegment<int>.Enumerator enumerator = arraySegment.GetEnumerator();
-
-            bool expected = arraySegment.Count > 0;
-
-            // Dispose shouldn't do anything. Call it twice and then assert like nothing happened.
-            enumerator.Dispose();
-            enumerator.Dispose();
-
-            Assert.Equal(expected, enumerator.MoveNext());
-            if (expected)
-            {
-                Assert.Equal(array[index], enumerator.Current);
-            }
-        }
-
-        [Theory]
-        [MemberData(nameof(ArraySegment_TestData))]
-        public static void GetEnumerator_Reset(ArraySegment<int> arraySegment)
-        {
-            int[] array = arraySegment.Array;
-            int index = arraySegment.Offset;
-            int count = arraySegment.Count;
-
-            var enumerator = (IEnumerator<int>)arraySegment.GetEnumerator();
-
-            int[] expected = array.Skip(index).Take(count).ToArray();
-
-            // Reset at a variety of different positions to ensure the implementation
-            // isn't something like `position -= CONSTANT`.
-            for (int i = 0; i < 3; i++)
-            {
-                for (int j = 0; j < i; j++)
-                {
-                    if (enumerator.MoveNext())
-                    {
-                        Assert.Equal(expected[j], enumerator.Current);
-                    }
-                }
-
-                enumerator.Reset();
-            }
-        }
-
-        [Theory]
-        [MemberData(nameof(ArraySegment_TestData))]
-        public static void GetEnumerator_Invalid(ArraySegment<int> arraySegment)
-        {
-            ArraySegment<int>.Enumerator enumerator = arraySegment.GetEnumerator();
-
-            // Before beginning
-            Assert.Throws<InvalidOperationException>(() => enumerator.Current);
-            Assert.Throws<InvalidOperationException>(() => ((IEnumerator<int>)enumerator).Current);
-            Assert.Throws<InvalidOperationException>(() => ((IEnumerator)enumerator).Current);
-
-            while (enumerator.MoveNext()) ;
-
-            // After end
-            Assert.Throws<InvalidOperationException>(() => enumerator.Current);
-            Assert.Throws<InvalidOperationException>(() => ((IEnumerator<int>)enumerator).Current);
-            Assert.Throws<InvalidOperationException>(() => ((IEnumerator)enumerator).Current);
-        }
-
-        [Theory]
-        [MemberData(nameof(ArraySegment_TestData))]
-        public static void GetSetItem_InRange(ArraySegment<int> arraySegment)
-        {
-            int[] array = arraySegment.Array;
-            int index = arraySegment.Offset;
-            int count = arraySegment.Count;
-
-            int[] expected = array.Skip(index).Take(count).ToArray();
-
-            for (int i = 0; i < count; i++)
-            {
-                Assert.Equal(expected[i], arraySegment[i]);
-                Assert.Equal(expected[i], ((IList<int>)arraySegment)[i]);
-                Assert.Equal(expected[i], ((IReadOnlyList<int>)arraySegment)[i]);
-            }
-
-            var r = new Random(0);
-
-            for (int i = 0; i < count; i++)
-            {
-                int next = r.Next(int.MinValue, int.MaxValue);
-
-                // When we modify the underlying array, the indexer should return the updated values.
-                array[arraySegment.Offset + i] ^= next;
-                Assert.Equal(expected[i] ^ next, arraySegment[i]);
-
-                // When the indexer's set method is called, the underlying array should be modified.
-                arraySegment[i] ^= next;
-                Assert.Equal(expected[i], array[arraySegment.Offset + i]);
-            }
-        }
-
-        [Theory]
-        [MemberData(nameof(ArraySegment_TestData))]
-        public static void GetSetItem_NotInRange_Invalid(ArraySegment<int> arraySegment)
-        {
-            int[] array = arraySegment.Array;
-
-            // Before array start
-            Assert.Throws<ArgumentOutOfRangeException>(() => arraySegment[-arraySegment.Offset - 1]);
-            Assert.Throws<ArgumentOutOfRangeException>(() => arraySegment[-arraySegment.Offset - 1] = default(int));
-
-            // After array start (if Offset > 0), before start
-            Assert.Throws<ArgumentOutOfRangeException>(() => arraySegment[-1]);
-            Assert.Throws<ArgumentOutOfRangeException>(() => arraySegment[-1] = default(int));
-
-            // Before array end (if Offset + Count < Array.Length), after end
-            Assert.Throws<ArgumentOutOfRangeException>(() => arraySegment[arraySegment.Count]);
-            Assert.Throws<ArgumentOutOfRangeException>(() => arraySegment[arraySegment.Count] = default(int));
-
-            // After array end
-            Assert.Throws<ArgumentOutOfRangeException>(() => arraySegment[-arraySegment.Offset + array.Length]);
-            Assert.Throws<ArgumentOutOfRangeException>(() => arraySegment[-arraySegment.Offset + array.Length] = default(int));
-        }
-
-        [Theory]
-        [MemberData(nameof(Slice_TestData))]
-        public static void Slice(ArraySegment<int> arraySegment, int index, int count)
-        {
-            var expected = new ArraySegment<int>(arraySegment.Array, arraySegment.Offset + index, count);
-
-            if (index + count == arraySegment.Count)
-            {
-                Assert.Equal(expected, arraySegment.Slice(index));
-            }
-
-            Assert.Equal(expected, arraySegment.Slice(index, count));
-        }
-
-        public static IEnumerable<object[]> Slice_TestData()
-        {
-            IEnumerable<ArraySegment<int>> arraySegments = ArraySegment_TestData().Select(array => array.Single()).Cast<ArraySegment<int>>();
-
-            foreach (ArraySegment<int> arraySegment in arraySegments)
-            {
-                yield return new object[] { arraySegment, 0, 0 }; // Preserve start, no items
-                yield return new object[] { arraySegment, 0, arraySegment.Count }; // Preserve start, preserve count (noop)
-                yield return new object[] { arraySegment, arraySegment.Count, 0 }; // Start at end, no items
-
-                if (arraySegment.Any())
-                {
-                    yield return new object[] { arraySegment, 1, 0 }; // Start at middle or end, no items
-                    yield return new object[] { arraySegment, 1, arraySegment.Count - 1 }; // Start at middle or end, rest of items
-                    yield return new object[] { arraySegment, arraySegment.Count - 1, 1 }; // Preserve start or start at middle, one item
-                }
-
-                yield return new object[] { arraySegment, 0, arraySegment.Count / 2 }; // Preserve start, multiple items, end at middle
-                yield return new object[] { arraySegment, arraySegment.Count / 2, arraySegment.Count / 2 }; // Start at middle, multiple items, end at middle (due to integer division truncation) or preserve end
-                yield return new object[] { arraySegment, arraySegment.Count / 4, arraySegment.Count / 2 }; // Start at middle, multiple items, end at middle
-            }
-        }
-
-        [Theory]
-        [MemberData(nameof(Slice_Invalid_TestData))]
-        public static void Slice_Invalid(ArraySegment<int> arraySegment, int index, int count)
-        {
-            if (index + count == arraySegment.Count)
-            {
-                AssertExtensions.Throws<ArgumentOutOfRangeException>("index", () => arraySegment.Slice(index));
-            }
-
-            AssertExtensions.Throws<ArgumentOutOfRangeException>("index", () => arraySegment.Slice(index, count));
-        }
-
-        public static IEnumerable<object[]> Slice_Invalid_TestData()
-        {
-            var arraySegment = new ArraySegment<int>(new int[3], offset: 1, count: 1);
-
-            yield return new object[] { arraySegment, -arraySegment.Offset, arraySegment.Offset };
-            yield return new object[] { arraySegment, -arraySegment.Offset, arraySegment.Offset + arraySegment.Count };
-            yield return new object[] { arraySegment, -arraySegment.Offset, arraySegment.Array.Length };
-            yield return new object[] { arraySegment, 0, arraySegment.Array.Length - arraySegment.Offset };
-            yield return new object[] { arraySegment, arraySegment.Count, arraySegment.Array.Length - arraySegment.Offset - arraySegment.Count };
-        }
-
-        [Theory]
-        [MemberData(nameof(ArraySegment_TestData))]
-        public static void ToArray(ArraySegment<int> arraySegment)
-        {
-            // ToList is called here so we copy the data and raise an assert if ToArray modifies the underlying array.
-            List<int> expected = arraySegment.Array.Skip(arraySegment.Offset).Take(arraySegment.Count).ToList();
-            Assert.Equal(expected, arraySegment.ToArray());
-        }
-
-        public static IEnumerable<object[]> ArraySegment_TestData()
-        {
-            var arraySegments = new (int[] array, int index, int count)[]
-            {
-                (array: new int[0], index: 0, 0), // Empty array
-                (array: new[] { 3, 4, 5, 6 }, index: 0, count: 4), // Full span of non-empty array
-                (array: new[] { 3, 4, 5, 6 }, index: 0, count: 3), // Starts at beginning, ends in middle
-                (array: new[] { 3, 4, 5, 6 }, index: 1, count: 3), // Starts in middle, ends at end
-                (array: new[] { 3, 4, 5, 6 }, index: 1, count: 2), // Starts in middle, ends in middle
-                (array: new[] { 3, 4, 5, 6 }, index: 1, count: 0) // Non-empty array, count == 0
-            };
-
-            return arraySegments.Select(aseg => new object[] { new ArraySegment<int>(aseg.array, aseg.index, aseg.count) });
-        }
-    }
-}
index 4375e6d..bf0ef63 100644 (file)
@@ -7,11 +7,12 @@ using System.Collections.Generic;
 using System.Collections.ObjectModel;
 using System.Linq;
 using System.Reflection;
+using System.Runtime.CompilerServices;
 using Xunit;
 
 namespace System.Tests
 {
-    public partial class ArrayTests
+    public class ArrayTests
     {
         [Fact]
         public static void IList_GetSetItem()
@@ -4064,6 +4065,188 @@ namespace System.Tests
             Array.Reverse((Array)new int*[1]);
         }
 
+        public static IEnumerable<object[]> Fill_Generic_TestData()
+        {
+            var data = Enumerable.Empty<object[]>();
+
+            var r = new Random(0x051778f7);
+            int[] lengths = { 0, 1, 2, 3, 5, 8, 13 };
+
+            foreach (int length in lengths)
+            {
+                IEnumerable<int> source = Enumerable.Range(1, length).Select(_ => r.Next());
+
+                data = data.Concat(GenerateFillData(source, r.Next(), i => i))
+                    .Concat(GenerateFillData(source, r.Next(), i => unchecked((byte)i)))
+                    .Concat(GenerateFillData(source, r.Next(), i => unchecked((short)i)))
+                    .Concat(GenerateFillData(source, r.Next(), i => (long)i))
+                    .Concat(GenerateFillData(source, r.Next(), i => new StrongBox<int>(i)))
+                    .Concat(GenerateFillData(source, r.Next(), i => i.ToString()))
+                    .Concat(GenerateFillData(source, r.Next(), i => unchecked((ByteEnum)i)))
+                    .Concat(GenerateFillData(source, r.Next(), i => unchecked((Int16Enum)i)))
+                    .Concat(GenerateFillData(source, r.Next(), i => (Int32Enum)i))
+                    .Concat(GenerateFillData(source, r.Next(), i => (Int64Enum)i))
+                    .Concat(GenerateFillData(source, r.Next(), i => new object()));
+            }
+
+            return data;
+        }
+
+        public static IEnumerable<object[]> GenerateFillData<TSource, TResult>(IEnumerable<TSource> source, TSource seed, Func<TSource, TResult> transform)
+        {
+            int count = source.Count();
+            TResult repeatedValue = transform(seed);
+            // Force evaluation so neither `source` or `transform` are re-run if the sequence is enumerated more than once.
+            IEnumerable<TResult> transformed = source.Select(transform).ToList();
+
+            yield return new object[] { transformed, repeatedValue, 0, count }; // Fill the entire array.
+            yield return new object[] { transformed, repeatedValue, 0, count / 2 }; // Fill the beginning of the array.
+            yield return new object[] { transformed, repeatedValue, count / 2, count / 2 }; // Fill the end of the array, assuming `length` is even.
+            yield return new object[] { transformed, repeatedValue, count / 4, count / 2 }; // Fill the middle of the array.
+            yield return new object[] { transformed, repeatedValue, count, 0 }; // Fill nothing.
+        }
+
+        [Theory]
+        [MemberData(nameof(Fill_Generic_TestData))]
+        public static void Fill_Generic<T>(IEnumerable<T> source, T value, int startIndex, int count)
+        {
+            if (startIndex == 0 && count == source.Count())
+            {
+                T[] array = source.ToArray();
+                Array.Fill(array, value);
+                Assert.Equal(Enumerable.Repeat(value, count), array);
+            }
+
+            {
+                T[] array = source.ToArray();
+
+                // Before calling Fill, we want to capture the segments before/after the filled region.
+                // We want to ensure that in addition to filling in what it's supposed to, Fill does
+                // not touch the adjacent segments.
+                T[] before = source.Take(startIndex).ToArray();
+                T[] after = source.Skip(startIndex + count).ToArray();
+
+                Array.Fill(array, value, startIndex, count);
+
+                Assert.Equal(before, array.Take(startIndex));
+                Assert.Equal(Enumerable.Repeat(value, count), array.Skip(startIndex).Take(count));
+                Assert.Equal(after, array.Skip(startIndex + count));
+            }
+        }
+
+        [Fact]
+        public void Fill_NullArray_ThrowsArgumentNullException()
+        {
+            AssertExtensions.Throws<ArgumentNullException>("array", () => Array.Fill(null, 1));
+            AssertExtensions.Throws<ArgumentNullException>("array", () => Array.Fill(null, 1, 0, 0));
+        }
+
+        [Theory]
+        [InlineData(-1)]
+        [InlineData(2)]
+        public void Fill_InvalidStartIndex_ThrowsArgumentOutOfRangeException(int startIndex)
+        {
+            AssertExtensions.Throws<ArgumentOutOfRangeException>("startIndex", () => Array.Fill(new string[1], "", startIndex, 0));
+        }
+
+        [Theory]
+        [InlineData(1, 0, -1)]
+        [InlineData(0, 0, 1)]
+        [InlineData(3, 3, 1)]
+        [InlineData(3, 2, 2)]
+        [InlineData(3, 1, 3)]
+        [InlineData(3, 0, 4)]
+        public void Fill_InvalidStartIndexCount_ThrowsArgumentOutOfRangeException(int arrayLength, int startIndex, int count)
+        {
+            AssertExtensions.Throws<ArgumentOutOfRangeException>("count", () => Array.Fill(new string[arrayLength], "", startIndex, count));
+        }
+
+        public static IEnumerable<object[]> Reverse_Generic_Int_TestData()
+        {
+            // TODO: use (or merge this data into) Reverse_TestData if/when xunit/xunit#965 is merged
+            yield return new object[] { new int[] { 1, 2, 3 }, 0, 3, new int[] { 3, 2, 1 } };
+            yield return new object[] { new int[] { 1, 2, 3 }, 0, 2, new int[] { 2, 1, 3 } };
+            yield return new object[] { new int[] { 1, 2, 3 }, 1, 2, new int[] { 1, 3, 2 } };
+
+            // Nothing to reverse
+            yield return new object[] { new int[] { 1, 2, 3 }, 2, 1, new int[] { 1, 2, 3 } };
+            yield return new object[] { new int[] { 1, 2, 3 }, 0, 1, new int[] { 1, 2, 3 } };
+            yield return new object[] { new int[] { 1, 2, 3 }, 0, 0, new int[] { 1, 2, 3 } };
+            yield return new object[] { new int[] { 1, 2, 3 }, 3, 0, new int[] { 1, 2, 3 } };
+            yield return new object[] { new int[0], 0, 0, new int[0] };
+        }
+
+        [Theory]
+        [MemberData(nameof(Reverse_Generic_Int_TestData))]
+        public static void Reverse_Generic(int[] array, int index, int length, int[] expected)
+        {
+            if (index == 0 && length == array.Length)
+            {
+                int[] arrayClone1 = (int[])array.Clone();
+                Array.Reverse(arrayClone1);
+                Assert.Equal(expected, arrayClone1);
+            }
+            int[] arrayClone2 = (int[])array.Clone();
+            Array.Reverse(arrayClone2, index, length);
+            Assert.Equal(expected, arrayClone2);
+        }
+
+        [Fact]
+        public static void Reverse_Generic_NullArray_ThrowsArgumentNullException()
+        {
+            AssertExtensions.Throws<ArgumentNullException>("array", () => Array.Reverse((string[])null));
+            AssertExtensions.Throws<ArgumentNullException>("array", () => Array.Reverse((string[])null, 0, 0));
+        }
+
+        [Fact]
+        public static void Reverse_Generic_NegativeIndex_ThrowsArgumentOutOfRangeException()
+        {
+            AssertExtensions.Throws<ArgumentOutOfRangeException>("index", () => Array.Reverse(new string[0], -1, 0));
+        }
+
+        [Fact]
+        public static void Reverse_Generic_NegativeLength_ThrowsArgumentOutOfRangeException()
+        {
+            AssertExtensions.Throws<ArgumentOutOfRangeException>("length", () => Array.Reverse(new string[0], 0, -1));
+        }
+
+        [Theory]
+        [InlineData(0, 0, 1)]
+        [InlineData(3, 4, 0)]
+        [InlineData(3, 3, 1)]
+        [InlineData(3, 2, 2)]
+        [InlineData(3, 1, 3)]
+        [InlineData(3, 0, 4)]
+        public static void Reverse_Generic_InvalidOffsetPlusLength_ThrowsArgumentException(int arrayLength, int index, int length)
+        {
+            AssertExtensions.Throws<ArgumentException>(null, () => Array.Reverse(new string[arrayLength], index, length));
+        }
+
+        [Fact]
+        public static void Reverse_NonSZArrayWithMinValueLowerBound()
+        {
+            Array array = NonZeroLowerBoundArray(new int[] { 1, 2, 3 }, int.MinValue);
+
+            Reverse(array, int.MinValue, 0, new int[] { 1, 2, 3 });
+            Reverse(array, int.MinValue, 1, new int[] { 1, 2, 3 });
+            Reverse(array, int.MinValue, 2, new int[] { 2, 1, 3 });
+        }
+
+        [Fact]
+        public void CreateInstance_TypeNotRuntimeType_ThrowsArgumentException()
+        {
+            // This cannot be a [Theory] due to https://github.com/xunit/xunit/issues/1325.
+            foreach (Type elementType in Helpers.NonRuntimeTypes)
+            {
+                AssertExtensions.Throws<ArgumentException>("elementType", () => Array.CreateInstance(elementType, 1));
+                AssertExtensions.Throws<ArgumentException>("elementType", () => Array.CreateInstance(elementType, 1, 1));
+                AssertExtensions.Throws<ArgumentException>("elementType", () => Array.CreateInstance(elementType, 1, 1, 1));
+                AssertExtensions.Throws<ArgumentException>("elementType", () => Array.CreateInstance(elementType, new int[1]));
+                AssertExtensions.Throws<ArgumentException>("elementType", () => Array.CreateInstance(elementType, new long[1]));
+                AssertExtensions.Throws<ArgumentException>("elementType", () => Array.CreateInstance(elementType, new int[1], new int[1]));
+            }
+        }
+
         private static void VerifyArray(Array array, Type elementType, int[] lengths, int[] lowerBounds, object repeatedValue)
         {
             VerifyArray(array, elementType, lengths, lowerBounds);
diff --git a/src/libraries/System.Runtime/tests/System/ArrayTests.netcoreapp.cs b/src/libraries/System.Runtime/tests/System/ArrayTests.netcoreapp.cs
deleted file mode 100644 (file)
index 457556f..0000000
+++ /dev/null
@@ -1,196 +0,0 @@
-// 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 System.Runtime.CompilerServices;
-using Xunit;
-
-namespace System.Tests
-{
-    public partial class ArrayTests
-    {
-        public static IEnumerable<object[]> Fill_Generic_TestData()
-        {
-            var data = Enumerable.Empty<object[]>();
-
-            var r = new Random(0x051778f7);
-            int[] lengths = { 0, 1, 2, 3, 5, 8, 13 };
-
-            foreach (int length in lengths)
-            {
-                IEnumerable<int> source = Enumerable.Range(1, length).Select(_ => r.Next());
-
-                data = data.Concat(GenerateFillData(source, r.Next(), i => i))
-                    .Concat(GenerateFillData(source, r.Next(), i => unchecked((byte)i)))
-                    .Concat(GenerateFillData(source, r.Next(), i => unchecked((short)i)))
-                    .Concat(GenerateFillData(source, r.Next(), i => (long)i))
-                    .Concat(GenerateFillData(source, r.Next(), i => new StrongBox<int>(i)))
-                    .Concat(GenerateFillData(source, r.Next(), i => i.ToString()))
-                    .Concat(GenerateFillData(source, r.Next(), i => unchecked((ByteEnum)i)))
-                    .Concat(GenerateFillData(source, r.Next(), i => unchecked((Int16Enum)i)))
-                    .Concat(GenerateFillData(source, r.Next(), i => (Int32Enum)i))
-                    .Concat(GenerateFillData(source, r.Next(), i => (Int64Enum)i))
-                    .Concat(GenerateFillData(source, r.Next(), i => new object()));
-            }
-
-            return data;
-        }
-
-        public static IEnumerable<object[]> GenerateFillData<TSource, TResult>(IEnumerable<TSource> source, TSource seed, Func<TSource, TResult> transform)
-        {
-            int count = source.Count();
-            TResult repeatedValue = transform(seed);
-            // Force evaluation so neither `source` or `transform` are re-run if the sequence is enumerated more than once.
-            IEnumerable<TResult> transformed = source.Select(transform).ToList();
-
-            yield return new object[] { transformed, repeatedValue, 0, count }; // Fill the entire array.
-            yield return new object[] { transformed, repeatedValue, 0, count / 2 }; // Fill the beginning of the array.
-            yield return new object[] { transformed, repeatedValue, count / 2, count / 2 }; // Fill the end of the array, assuming `length` is even.
-            yield return new object[] { transformed, repeatedValue, count / 4, count / 2 }; // Fill the middle of the array.
-            yield return new object[] { transformed, repeatedValue, count, 0 }; // Fill nothing.
-        }
-
-        [Theory]
-        [MemberData(nameof(Fill_Generic_TestData))]
-        public static void Fill_Generic<T>(IEnumerable<T> source, T value, int startIndex, int count)
-        {
-            if (startIndex == 0 && count == source.Count())
-            {
-                T[] array = source.ToArray();
-                Array.Fill(array, value);
-                Assert.Equal(Enumerable.Repeat(value, count), array);
-            }
-
-            {
-                T[] array = source.ToArray();
-
-                // Before calling Fill, we want to capture the segments before/after the filled region.
-                // We want to ensure that in addition to filling in what it's supposed to, Fill does
-                // not touch the adjacent segments.
-                T[] before = source.Take(startIndex).ToArray();
-                T[] after = source.Skip(startIndex + count).ToArray();
-
-                Array.Fill(array, value, startIndex, count);
-
-                Assert.Equal(before, array.Take(startIndex));
-                Assert.Equal(Enumerable.Repeat(value, count), array.Skip(startIndex).Take(count));
-                Assert.Equal(after, array.Skip(startIndex + count));
-            }
-        }
-
-        [Fact]
-        public void Fill_NullArray_ThrowsArgumentNullException()
-        {
-            AssertExtensions.Throws<ArgumentNullException>("array", () => Array.Fill(null, 1));
-            AssertExtensions.Throws<ArgumentNullException>("array", () => Array.Fill(null, 1, 0, 0));
-        }
-
-        [Theory]
-        [InlineData(-1)]
-        [InlineData(2)]
-        public void Fill_InvalidStartIndex_ThrowsArgumentOutOfRangeException(int startIndex)
-        {
-            AssertExtensions.Throws<ArgumentOutOfRangeException>("startIndex", () => Array.Fill(new string[1], "", startIndex, 0));
-        }
-
-        [Theory]
-        [InlineData(1, 0, -1)]
-        [InlineData(0, 0, 1)]
-        [InlineData(3, 3, 1)]
-        [InlineData(3, 2, 2)]
-        [InlineData(3, 1, 3)]
-        [InlineData(3, 0, 4)]
-        public void Fill_InvalidStartIndexCount_ThrowsArgumentOutOfRangeException(int arrayLength, int startIndex, int count)
-        {
-            AssertExtensions.Throws<ArgumentOutOfRangeException>("count", () => Array.Fill(new string[arrayLength], "", startIndex, count));
-        }
-
-        public static IEnumerable<object[]> Reverse_Generic_Int_TestData()
-        {
-            // TODO: use (or merge this data into) Reverse_TestData if/when xunit/xunit#965 is merged
-            yield return new object[] { new int[] { 1, 2, 3 }, 0, 3, new int[] { 3, 2, 1 } };
-            yield return new object[] { new int[] { 1, 2, 3 }, 0, 2, new int[] { 2, 1, 3 } };
-            yield return new object[] { new int[] { 1, 2, 3 }, 1, 2, new int[] { 1, 3, 2 } };
-
-            // Nothing to reverse
-            yield return new object[] { new int[] { 1, 2, 3 }, 2, 1, new int[] { 1, 2, 3 } };
-            yield return new object[] { new int[] { 1, 2, 3 }, 0, 1, new int[] { 1, 2, 3 } };
-            yield return new object[] { new int[] { 1, 2, 3 }, 0, 0, new int[] { 1, 2, 3 } };
-            yield return new object[] { new int[] { 1, 2, 3 }, 3, 0, new int[] { 1, 2, 3 } };
-            yield return new object[] { new int[0], 0, 0, new int[0] };
-        }
-
-        [Theory]
-        [MemberData(nameof(Reverse_Generic_Int_TestData))]
-        public static void Reverse_Generic(int[] array, int index, int length, int[] expected)
-        {
-            if (index == 0 && length == array.Length)
-            {
-                int[] arrayClone1 = (int[])array.Clone();
-                Array.Reverse(arrayClone1);
-                Assert.Equal(expected, arrayClone1);
-            }
-            int[] arrayClone2 = (int[])array.Clone();
-            Array.Reverse(arrayClone2, index, length);
-            Assert.Equal(expected, arrayClone2);
-        }
-
-        [Fact]
-        public static void Reverse_Generic_NullArray_ThrowsArgumentNullException()
-        {
-            AssertExtensions.Throws<ArgumentNullException>("array", () => Array.Reverse((string[])null));
-            AssertExtensions.Throws<ArgumentNullException>("array", () => Array.Reverse((string[])null, 0, 0));
-        }
-
-        [Fact]
-        public static void Reverse_Generic_NegativeIndex_ThrowsArgumentOutOfRangeException()
-        {
-            AssertExtensions.Throws<ArgumentOutOfRangeException>("index", () => Array.Reverse(new string[0], -1, 0));
-        }
-
-        [Fact]
-        public static void Reverse_Generic_NegativeLength_ThrowsArgumentOutOfRangeException()
-        {
-            AssertExtensions.Throws<ArgumentOutOfRangeException>("length", () => Array.Reverse(new string[0], 0, -1));
-        }
-
-        [Theory]
-        [InlineData(0, 0, 1)]
-        [InlineData(3, 4, 0)]
-        [InlineData(3, 3, 1)]
-        [InlineData(3, 2, 2)]
-        [InlineData(3, 1, 3)]
-        [InlineData(3, 0, 4)]
-        public static void Reverse_Generic_InvalidOffsetPlusLength_ThrowsArgumentException(int arrayLength, int index, int length)
-        {
-            AssertExtensions.Throws<ArgumentException>(null, () => Array.Reverse(new string[arrayLength], index, length));
-        }
-
-        [Fact]
-        public static void Reverse_NonSZArrayWithMinValueLowerBound()
-        {
-            Array array = NonZeroLowerBoundArray(new int[] { 1, 2, 3 }, int.MinValue);
-
-            Reverse(array, int.MinValue, 0, new int[] { 1, 2, 3 });
-            Reverse(array, int.MinValue, 1, new int[] { 1, 2, 3 });
-            Reverse(array, int.MinValue, 2, new int[] { 2, 1, 3 });
-        }
-
-        [Fact]
-        public void CreateInstance_TypeNotRuntimeType_ThrowsArgumentException()
-        {
-            // This cannot be a [Theory] due to https://github.com/xunit/xunit/issues/1325.
-            foreach (Type elementType in Helpers.NonRuntimeTypes)
-            {
-                AssertExtensions.Throws<ArgumentException>("elementType", () => Array.CreateInstance(elementType, 1));
-                AssertExtensions.Throws<ArgumentException>("elementType", () => Array.CreateInstance(elementType, 1, 1));
-                AssertExtensions.Throws<ArgumentException>("elementType", () => Array.CreateInstance(elementType, 1, 1, 1));
-                AssertExtensions.Throws<ArgumentException>("elementType", () => Array.CreateInstance(elementType, new int[1]));
-                AssertExtensions.Throws<ArgumentException>("elementType", () => Array.CreateInstance(elementType, new long[1]));
-                AssertExtensions.Throws<ArgumentException>("elementType", () => Array.CreateInstance(elementType, new int[1], new int[1]));
-            }
-        }
-    }
-}
index f56c28a..bb6073f 100644 (file)
@@ -146,5 +146,68 @@ namespace System.Tests
         {
             Assert.Equal(TypeCode.Boolean, true.GetTypeCode());
         }
+
+        public static IEnumerable<object[]> Parse_ValidWithOffsetCount_TestData()
+        {
+            foreach (object[] inputs in Parse_Valid_TestData())
+            {
+                yield return new object[] { inputs[0], 0, ((string)inputs[0]).Length, inputs[1] };
+            }
+
+            yield return new object[] { " \0 \0  TrueFalse   \0 ", 6, 4, true };
+            yield return new object[] { " \0 \0  TrueFalse   \0 ", 10, 5, false };
+        }
+
+        [Theory]
+        [MemberData(nameof(Parse_ValidWithOffsetCount_TestData))]
+        public static void Parse_Span_Valid(string value, int offset, int count, bool expected)
+        {
+            Assert.Equal(expected, bool.Parse(value.AsSpan(offset, count)));
+
+            Assert.True(bool.TryParse(value.AsSpan(offset, count), out bool result));
+            Assert.Equal(expected, result);
+        }
+
+        [Theory]
+        [MemberData(nameof(Parse_Invalid_TestData))]
+        public static void Parse_Span_Invalid(string value, Type exceptionType)
+        {
+            if (value != null)
+            {
+                Assert.Throws(exceptionType, () => bool.Parse(value.AsSpan()));
+
+                Assert.False(bool.TryParse(value.AsSpan(), out bool result));
+                Assert.False(result);
+            }
+        }
+
+        [Theory]
+        [InlineData(true, "True")]
+        [InlineData(false, "False")]
+        public static void TryFormat(bool i, string expected)
+        {
+            char[] actual;
+            int charsWritten;
+
+            // Just right
+            actual = new char[expected.Length];
+            Assert.True(i.TryFormat(actual.AsSpan(), out charsWritten));
+            Assert.Equal(expected.Length, charsWritten);
+            Assert.Equal(expected, new string(actual));
+
+            // Longer than needed
+            actual = new char[expected.Length + 1];
+            Assert.True(i.TryFormat(actual.AsSpan(), out charsWritten));
+            Assert.Equal(expected.Length, charsWritten);
+            Assert.Equal(expected, new string(actual, 0, charsWritten));
+
+            // Too short
+            if (expected.Length > 0)
+            {
+                actual = new char[expected.Length - 1];
+                Assert.False(i.TryFormat(actual.AsSpan(), out charsWritten));
+                Assert.Equal(0, charsWritten);
+            }
+        }
     }
 }
diff --git a/src/libraries/System.Runtime/tests/System/BooleanTests.netcoreapp.cs b/src/libraries/System.Runtime/tests/System/BooleanTests.netcoreapp.cs
deleted file mode 100644 (file)
index 3d23b79..0000000
+++ /dev/null
@@ -1,75 +0,0 @@
-// 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 Xunit;
-
-namespace System.Tests
-{
-    public partial class BooleanTests
-    {
-        public static IEnumerable<object[]> Parse_ValidWithOffsetCount_TestData()
-        {
-            foreach (object[] inputs in Parse_Valid_TestData())
-            {
-                yield return new object[] { inputs[0], 0, ((string)inputs[0]).Length, inputs[1] };
-            }
-
-            yield return new object[] { " \0 \0  TrueFalse   \0 ", 6, 4, true };
-            yield return new object[] { " \0 \0  TrueFalse   \0 ", 10, 5, false };
-        }
-
-        [Theory]
-        [MemberData(nameof(Parse_ValidWithOffsetCount_TestData))]
-        public static void Parse_Span_Valid(string value, int offset, int count, bool expected)
-        {
-            Assert.Equal(expected, bool.Parse(value.AsSpan(offset, count)));
-
-            Assert.True(bool.TryParse(value.AsSpan(offset, count), out bool result));
-            Assert.Equal(expected, result);
-        }
-
-        [Theory]
-        [MemberData(nameof(Parse_Invalid_TestData))]
-        public static void Parse_Span_Invalid(string value, Type exceptionType)
-        {
-            if (value != null)
-            {
-                Assert.Throws(exceptionType, () => bool.Parse(value.AsSpan()));
-
-                Assert.False(bool.TryParse(value.AsSpan(), out bool result));
-                Assert.False(result);
-            }
-        }
-
-        [Theory]
-        [InlineData(true, "True")]
-        [InlineData(false, "False")]
-        public static void TryFormat(bool i, string expected)
-        {
-            char[] actual;
-            int charsWritten;
-
-            // Just right
-            actual = new char[expected.Length];
-            Assert.True(i.TryFormat(actual.AsSpan(), out charsWritten));
-            Assert.Equal(expected.Length, charsWritten);
-            Assert.Equal(expected, new string(actual));
-
-            // Longer than needed
-            actual = new char[expected.Length + 1];
-            Assert.True(i.TryFormat(actual.AsSpan(), out charsWritten));
-            Assert.Equal(expected.Length, charsWritten);
-            Assert.Equal(expected, new string(actual, 0, charsWritten));
-
-            // Too short
-            if (expected.Length > 0)
-            {
-                actual = new char[expected.Length - 1];
-                Assert.False(i.TryFormat(actual.AsSpan(), out charsWritten));
-                Assert.Equal(0, charsWritten);
-            }
-        }
-    }
-}
index 570abba..5522c8e 100644 (file)
@@ -8,7 +8,7 @@ using Xunit;
 
 namespace System.Tests
 {
-    public partial class ByteTests
+    public class ByteTests
     {
         [Fact]
         public static void Ctor_Empty()
@@ -288,5 +288,106 @@ namespace System.Tests
             AssertExtensions.Throws<ArgumentException>(paramName, () => byte.Parse("1", style));
             AssertExtensions.Throws<ArgumentException>(paramName, () => byte.Parse("1", style, null));
         }
+
+        public static IEnumerable<object[]> Parse_ValidWithOffsetCount_TestData()
+        {
+            foreach (object[] inputs in Parse_Valid_TestData())
+            {
+                yield return new object[] { inputs[0], 0, ((string)inputs[0]).Length, inputs[1], inputs[2], inputs[3] };
+            }
+
+            yield return new object[] { "123", 0, 2, NumberStyles.Integer, null, (byte)12 };
+            yield return new object[] { "+123", 0, 2, NumberStyles.Integer, null, (byte)1 };
+            yield return new object[] { "+123", 1, 3, NumberStyles.Integer, null, (byte)123 };
+            yield return new object[] { "  123  ", 4, 1, NumberStyles.Integer, null, (byte)3 };
+            yield return new object[] { "12", 1, 1, NumberStyles.HexNumber, null, (byte)0x2 };
+            yield return new object[] { "10", 0, 1, NumberStyles.AllowThousands, null, (byte)1 };
+            yield return new object[] { "$100", 0, 2, NumberStyles.Currency, new NumberFormatInfo() { CurrencySymbol = "$" }, (byte)1 };
+        }
+
+
+        [Theory]
+        [MemberData(nameof(Parse_ValidWithOffsetCount_TestData))]
+        public static void Parse_Span_Valid(string value, int offset, int count, NumberStyles style, IFormatProvider provider, byte expected)
+        {
+            byte result;
+
+            // Default style and provider
+            if (style == NumberStyles.Integer && provider == null)
+            {
+                Assert.True(byte.TryParse(value.AsSpan(offset, count), out result));
+                Assert.Equal(expected, result);
+            }
+
+            Assert.Equal(expected, byte.Parse(value.AsSpan(offset, count), style, provider));
+
+            Assert.True(byte.TryParse(value.AsSpan(offset, count), style, provider, out result));
+            Assert.Equal(expected, result);
+        }
+
+        [Theory]
+        [MemberData(nameof(Parse_Invalid_TestData))]
+        public static void Parse_Span_Invalid(string value, NumberStyles style, IFormatProvider provider, Type exceptionType)
+        {
+            if (value != null)
+            {
+                byte result;
+
+                // Default style and provider
+                if (style == NumberStyles.Integer && provider == null)
+                {
+                    Assert.False(byte.TryParse(value.AsSpan(), out result));
+                    Assert.Equal(0u, result);
+                }
+
+                Assert.Throws(exceptionType, () => byte.Parse(value.AsSpan(), style, provider));
+
+                Assert.False(byte.TryParse(value.AsSpan(), style, provider, out result));
+                Assert.Equal(0u, result);
+            }
+        }
+
+        [Theory]
+        [MemberData(nameof(ToString_TestData))]
+        public static void TryFormat(byte i, string format, IFormatProvider provider, string expected)
+        {
+            char[] actual;
+            int charsWritten;
+
+            // Just right
+            actual = new char[expected.Length];
+            Assert.True(i.TryFormat(actual.AsSpan(), out charsWritten, format, provider));
+            Assert.Equal(expected.Length, charsWritten);
+            Assert.Equal(expected, new string(actual));
+
+            // Longer than needed
+            actual = new char[expected.Length + 1];
+            Assert.True(i.TryFormat(actual.AsSpan(), out charsWritten, format, provider));
+            Assert.Equal(expected.Length, charsWritten);
+            Assert.Equal(expected, new string(actual, 0, charsWritten));
+
+            // Too short
+            if (expected.Length > 0)
+            {
+                actual = new char[expected.Length - 1];
+                Assert.False(i.TryFormat(actual.AsSpan(), out charsWritten, format, provider));
+                Assert.Equal(0, charsWritten);
+            }
+
+            if (format != null)
+            {
+                // Upper format
+                actual = new char[expected.Length];
+                Assert.True(i.TryFormat(actual.AsSpan(), out charsWritten, format.ToUpperInvariant(), provider));
+                Assert.Equal(expected.Length, charsWritten);
+                Assert.Equal(expected.ToUpperInvariant(), new string(actual));
+
+                // Lower format
+                actual = new char[expected.Length];
+                Assert.True(i.TryFormat(actual.AsSpan(), out charsWritten, format.ToLowerInvariant(), provider));
+                Assert.Equal(expected.Length, charsWritten);
+                Assert.Equal(expected.ToLowerInvariant(), new string(actual));
+            }
+        }
     }
 }
diff --git a/src/libraries/System.Runtime/tests/System/ByteTests.netcoreapp.cs b/src/libraries/System.Runtime/tests/System/ByteTests.netcoreapp.cs
deleted file mode 100644 (file)
index 01103fc..0000000
+++ /dev/null
@@ -1,114 +0,0 @@
-// 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.Globalization;
-using Xunit;
-
-namespace System.Tests
-{
-    public partial class ByteTests
-    {
-        public static IEnumerable<object[]> Parse_ValidWithOffsetCount_TestData()
-        {
-            foreach (object[] inputs in Parse_Valid_TestData())
-            {
-                yield return new object[] { inputs[0], 0, ((string)inputs[0]).Length, inputs[1], inputs[2], inputs[3] };
-            }
-
-            yield return new object[] { "123", 0, 2, NumberStyles.Integer, null, (byte)12 };
-            yield return new object[] { "+123", 0, 2, NumberStyles.Integer, null, (byte)1 };
-            yield return new object[] { "+123", 1, 3, NumberStyles.Integer, null, (byte)123 };
-            yield return new object[] { "  123  ", 4, 1, NumberStyles.Integer, null, (byte)3 };
-            yield return new object[] { "12", 1, 1, NumberStyles.HexNumber, null, (byte)0x2 };
-            yield return new object[] { "10", 0, 1, NumberStyles.AllowThousands, null, (byte)1 };
-            yield return new object[] { "$100", 0, 2, NumberStyles.Currency, new NumberFormatInfo() { CurrencySymbol = "$" }, (byte)1 };
-        }
-
-
-        [Theory]
-        [MemberData(nameof(Parse_ValidWithOffsetCount_TestData))]
-        public static void Parse_Span_Valid(string value, int offset, int count, NumberStyles style, IFormatProvider provider, byte expected)
-        {
-            byte result;
-
-            // Default style and provider
-            if (style == NumberStyles.Integer && provider == null)
-            {
-                Assert.True(byte.TryParse(value.AsSpan(offset, count), out result));
-                Assert.Equal(expected, result);
-            }
-
-            Assert.Equal(expected, byte.Parse(value.AsSpan(offset, count), style, provider));
-
-            Assert.True(byte.TryParse(value.AsSpan(offset, count), style, provider, out result));
-            Assert.Equal(expected, result);
-        }
-
-        [Theory]
-        [MemberData(nameof(Parse_Invalid_TestData))]
-        public static void Parse_Span_Invalid(string value, NumberStyles style, IFormatProvider provider, Type exceptionType)
-        {
-            if (value != null)
-            {
-                byte result;
-
-                // Default style and provider
-                if (style == NumberStyles.Integer && provider == null)
-                {
-                    Assert.False(byte.TryParse(value.AsSpan(), out result));
-                    Assert.Equal(0u, result);
-                }
-
-                Assert.Throws(exceptionType, () => byte.Parse(value.AsSpan(), style, provider));
-
-                Assert.False(byte.TryParse(value.AsSpan(), style, provider, out result));
-                Assert.Equal(0u, result);
-            }
-        }
-
-        [Theory]
-        [MemberData(nameof(ToString_TestData))]
-        public static void TryFormat(byte i, string format, IFormatProvider provider, string expected)
-        {
-            char[] actual;
-            int charsWritten;
-
-            // Just right
-            actual = new char[expected.Length];
-            Assert.True(i.TryFormat(actual.AsSpan(), out charsWritten, format, provider));
-            Assert.Equal(expected.Length, charsWritten);
-            Assert.Equal(expected, new string(actual));
-
-            // Longer than needed
-            actual = new char[expected.Length + 1];
-            Assert.True(i.TryFormat(actual.AsSpan(), out charsWritten, format, provider));
-            Assert.Equal(expected.Length, charsWritten);
-            Assert.Equal(expected, new string(actual, 0, charsWritten));
-
-            // Too short
-            if (expected.Length > 0)
-            {
-                actual = new char[expected.Length - 1];
-                Assert.False(i.TryFormat(actual.AsSpan(), out charsWritten, format, provider));
-                Assert.Equal(0, charsWritten);
-            }
-
-            if (format != null)
-            {
-                // Upper format
-                actual = new char[expected.Length];
-                Assert.True(i.TryFormat(actual.AsSpan(), out charsWritten, format.ToUpperInvariant(), provider));
-                Assert.Equal(expected.Length, charsWritten);
-                Assert.Equal(expected.ToUpperInvariant(), new string(actual));
-
-                // Lower format
-                actual = new char[expected.Length];
-                Assert.True(i.TryFormat(actual.AsSpan(), out charsWritten, format.ToLowerInvariant(), provider));
-                Assert.Equal(expected.Length, charsWritten);
-                Assert.Equal(expected.ToLowerInvariant(), new string(actual));
-            }
-        }
-    }
-}
index b7a6a47..055c046 100644 (file)
@@ -5,11 +5,13 @@
 using System.Collections.Generic;
 using System.Globalization;
 using System.Text;
+using System.Text.Unicode.Tests;
 using Xunit;
+using Xunit.Sdk;
 
 namespace System.Tests
 {
-    public partial class CharTests
+    public class CharTests
     {
         [Theory]
         [InlineData('h', 'h', 0)]
@@ -1106,5 +1108,159 @@ namespace System.Tests
             Assert.Equal(lowerForm, char.ToLower(upperForm, ci));
             Assert.Equal(upperForm, char.ToUpper(lowerForm, ci));
         }
+
+        [OuterLoop]
+        [Fact]
+        public static void GetUnicodeCategory_Char_AllInputs()
+        {
+            // This tests calls char.GetUnicodeCategory for every possible input, ensuring that
+            // the runtime agrees with the data in the core Unicode files.
+
+            for (uint i = 0; i <= char.MaxValue; i++)
+            {
+                UnicodeCategory expected;
+
+                // The code points in the switch block below must be special-cased
+                // because they switched categories between versions of the Unicode
+                // specification. For compatibility reasons Char keeps its own copy
+                // of the categories for the first 256 code points, as it's locked
+                // to an earlier version of the standard. For an example of a code
+                // point that switched categories, see the discussion on U+00AD
+                // SOFT HYPHEN at https://www.unicode.org/versions/Unicode4.0.0/.
+
+                switch (i)
+                {
+                    case '\u00a7':
+                    case '\u00b6':
+                        expected = UnicodeCategory.OtherSymbol;
+                        break;
+
+                    case '\u00aa':
+                    case '\u00ba':
+                        expected = UnicodeCategory.LowercaseLetter;
+                        break;
+
+                    case '\u00ad':
+                        expected = UnicodeCategory.DashPunctuation;
+                        break;
+
+                    default:
+                        expected = UnicodeData.GetUnicodeCategory(i);
+                        break;
+                }
+
+                if (expected != char.GetUnicodeCategory((char)i))
+                {
+                    // We'll build up the exception message ourselves so the dev knows what code point failed.
+                    throw new AssertActualExpectedException(
+                        expected: expected,
+                        actual: char.GetUnicodeCategory((char)i),
+                        userMessage: FormattableString.Invariant($@"char.GetUnicodeCategory('\u{i:X4}') returned wrong value."));
+                }
+            }
+        }
+
+        [OuterLoop]
+        [Fact]
+        public static void IsLetter_Char_AllInputs()
+        {
+            // This tests calls char.IsLetter for every possible input, ensuring that
+            // the runtime agrees with the data in the core Unicode files.
+
+            for (uint i = 0; i <= char.MaxValue; i++)
+            {
+                if (UnicodeData.IsLetter((char)i) != char.IsLetter((char)i))
+                {
+                    // We'll build up the exception message ourselves so the dev knows what code point failed.
+                    throw new AssertActualExpectedException(
+                        expected: UnicodeData.IsLetter((char)i),
+                        actual: char.IsLetter((char)i),
+                        userMessage: FormattableString.Invariant($@"char.IsLetter('\u{i:X4}') returned wrong value."));
+                }
+            }
+        }
+
+        [OuterLoop]
+        [Fact]
+        public static void IsLower_Char_AllInputs()
+        {
+            // This tests calls char.IsLower for every possible input, ensuring that
+            // the runtime agrees with the data in the core Unicode files.
+
+            for (uint i = 0; i <= char.MaxValue; i++)
+            {
+                bool expected;
+
+                switch (i)
+                {
+                    case '\u00AA': // FEMININE ORDINAL INDICATOR
+                    case '\u00BA': // MASCULINE ORDINAL INDICATOR
+
+                        // In Unicode 6.1 the code points U+00AA and U+00BA were reassigned
+                        // from category Ll to category Lo. However, for compatibility reasons,
+                        // Char uses the older version of the Unicode standard for code points
+                        // in the range U+0000..U+00FF. So we'll special-case these here.
+                        // More info: https://www.unicode.org/review/pri181/
+
+                        expected = true;
+                        break;
+
+                    default:
+                        expected = UnicodeData.GetUnicodeCategory((char)i) == UnicodeCategory.LowercaseLetter;
+                        break;
+                }
+
+                if (expected != char.IsLower((char)i))
+                {
+                    // We'll build up the exception message ourselves so the dev knows what code point failed.
+                    throw new AssertActualExpectedException(
+                        expected: expected,
+                        actual: char.IsLower((char)i),
+                        userMessage: FormattableString.Invariant($@"char.IsLower('\u{i:X4}') returned wrong value."));
+                }
+            }
+        }
+
+        [OuterLoop]
+        [Fact]
+        public static void IsUpper_Char_AllInputs()
+        {
+            // This tests calls char.IsUpper for every possible input, ensuring that
+            // the runtime agrees with the data in the core Unicode files.
+
+            for (uint i = 0; i <= char.MaxValue; i++)
+            {
+                bool expected = UnicodeData.GetUnicodeCategory((char)i) == UnicodeCategory.UppercaseLetter;
+
+                if (expected != char.IsUpper((char)i))
+                {
+                    // We'll build up the exception message ourselves so the dev knows what code point failed.
+                    throw new AssertActualExpectedException(
+                        expected: expected,
+                        actual: char.IsUpper((char)i),
+                        userMessage: FormattableString.Invariant($@"char.IsUpper('\u{i:X4}') returned wrong value."));
+                }
+            }
+        }
+
+        [OuterLoop]
+        [Fact]
+        public static void IsWhiteSpace_Char_AllInputs()
+        {
+            // This tests calls char.IsWhiteSpace for every possible input, ensuring that
+            // the runtime agrees with the data in the core Unicode files.
+
+            for (uint i = 0; i <= char.MaxValue; i++)
+            {
+                if (UnicodeData.IsWhiteSpace(i) != char.IsWhiteSpace((char)i))
+                {
+                    // We'll build up the exception message ourselves so the dev knows what code point failed.
+                    throw new AssertActualExpectedException(
+                        expected: UnicodeData.IsWhiteSpace(i),
+                        actual: char.IsWhiteSpace((char)i),
+                        userMessage: FormattableString.Invariant($@"char.IsWhiteSpace('\u{i:X4}') returned wrong value."));
+                }
+            }
+        }
     }
 }
diff --git a/src/libraries/System.Runtime/tests/System/CharTests.netcoreapp.cs b/src/libraries/System.Runtime/tests/System/CharTests.netcoreapp.cs
deleted file mode 100644 (file)
index 5af4344..0000000
+++ /dev/null
@@ -1,168 +0,0 @@
-// 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.Text.Unicode.Tests;
-using Xunit;
-using Xunit.Sdk;
-
-namespace System.Tests
-{
-    public partial class CharTests
-    {
-        [OuterLoop]
-        [Fact]
-        public static void GetUnicodeCategory_Char_AllInputs()
-        {
-            // This tests calls char.GetUnicodeCategory for every possible input, ensuring that
-            // the runtime agrees with the data in the core Unicode files.
-
-            for (uint i = 0; i <= char.MaxValue; i++)
-            {
-                UnicodeCategory expected;
-
-                // The code points in the switch block below must be special-cased
-                // because they switched categories between versions of the Unicode
-                // specification. For compatibility reasons Char keeps its own copy
-                // of the categories for the first 256 code points, as it's locked
-                // to an earlier version of the standard. For an example of a code
-                // point that switched categories, see the discussion on U+00AD
-                // SOFT HYPHEN at https://www.unicode.org/versions/Unicode4.0.0/.
-
-                switch (i)
-                {
-                    case '\u00a7':
-                    case '\u00b6':
-                        expected = UnicodeCategory.OtherSymbol;
-                        break;
-
-                    case '\u00aa':
-                    case '\u00ba':
-                        expected = UnicodeCategory.LowercaseLetter;
-                        break;
-
-                    case '\u00ad':
-                        expected = UnicodeCategory.DashPunctuation;
-                        break;
-
-                    default:
-                        expected = UnicodeData.GetUnicodeCategory(i);
-                        break;
-                }
-
-                if (expected != char.GetUnicodeCategory((char)i))
-                {
-                    // We'll build up the exception message ourselves so the dev knows what code point failed.
-                    throw new AssertActualExpectedException(
-                        expected: expected,
-                        actual: char.GetUnicodeCategory((char)i),
-                        userMessage: FormattableString.Invariant($@"char.GetUnicodeCategory('\u{i:X4}') returned wrong value."));
-                }
-            }
-        }
-
-        [OuterLoop]
-        [Fact]
-        public static void IsLetter_Char_AllInputs()
-        {
-            // This tests calls char.IsLetter for every possible input, ensuring that
-            // the runtime agrees with the data in the core Unicode files.
-
-            for (uint i = 0; i <= char.MaxValue; i++)
-            {
-                if (UnicodeData.IsLetter((char)i) != char.IsLetter((char)i))
-                {
-                    // We'll build up the exception message ourselves so the dev knows what code point failed.
-                    throw new AssertActualExpectedException(
-                        expected: UnicodeData.IsLetter((char)i),
-                        actual: char.IsLetter((char)i),
-                        userMessage: FormattableString.Invariant($@"char.IsLetter('\u{i:X4}') returned wrong value."));
-                }
-            }
-        }
-
-        [OuterLoop]
-        [Fact]
-        public static void IsLower_Char_AllInputs()
-        {
-            // This tests calls char.IsLower for every possible input, ensuring that
-            // the runtime agrees with the data in the core Unicode files.
-
-            for (uint i = 0; i <= char.MaxValue; i++)
-            {
-                bool expected;
-
-                switch (i)
-                {
-                    case '\u00AA': // FEMININE ORDINAL INDICATOR
-                    case '\u00BA': // MASCULINE ORDINAL INDICATOR
-
-                        // In Unicode 6.1 the code points U+00AA and U+00BA were reassigned
-                        // from category Ll to category Lo. However, for compatibility reasons,
-                        // Char uses the older version of the Unicode standard for code points
-                        // in the range U+0000..U+00FF. So we'll special-case these here.
-                        // More info: https://www.unicode.org/review/pri181/
-
-                        expected = true;
-                        break;
-
-                    default:
-                        expected = UnicodeData.GetUnicodeCategory((char)i) == UnicodeCategory.LowercaseLetter;
-                        break;
-                }
-
-                if (expected != char.IsLower((char)i))
-                {
-                    // We'll build up the exception message ourselves so the dev knows what code point failed.
-                    throw new AssertActualExpectedException(
-                        expected: expected,
-                        actual: char.IsLower((char)i),
-                        userMessage: FormattableString.Invariant($@"char.IsLower('\u{i:X4}') returned wrong value."));
-                }
-            }
-        }
-
-        [OuterLoop]
-        [Fact]
-        public static void IsUpper_Char_AllInputs()
-        {
-            // This tests calls char.IsUpper for every possible input, ensuring that
-            // the runtime agrees with the data in the core Unicode files.
-
-            for (uint i = 0; i <= char.MaxValue; i++)
-            {
-                bool expected = UnicodeData.GetUnicodeCategory((char)i) == UnicodeCategory.UppercaseLetter;
-
-                if (expected != char.IsUpper((char)i))
-                {
-                    // We'll build up the exception message ourselves so the dev knows what code point failed.
-                    throw new AssertActualExpectedException(
-                        expected: expected,
-                        actual: char.IsUpper((char)i),
-                        userMessage: FormattableString.Invariant($@"char.IsUpper('\u{i:X4}') returned wrong value."));
-                }
-            }
-        }
-
-        [OuterLoop]
-        [Fact]
-        public static void IsWhiteSpace_Char_AllInputs()
-        {
-            // This tests calls char.IsWhiteSpace for every possible input, ensuring that
-            // the runtime agrees with the data in the core Unicode files.
-
-            for (uint i = 0; i <= char.MaxValue; i++)
-            {
-                if (UnicodeData.IsWhiteSpace(i) != char.IsWhiteSpace((char)i))
-                {
-                    // We'll build up the exception message ourselves so the dev knows what code point failed.
-                    throw new AssertActualExpectedException(
-                        expected: UnicodeData.IsWhiteSpace(i),
-                        actual: char.IsWhiteSpace((char)i),
-                        userMessage: FormattableString.Invariant($@"char.IsWhiteSpace('\u{i:X4}') returned wrong value."));
-                }
-            }
-        }
-    }
-}
index c4bcf03..7666aeb 100644 (file)
@@ -6,7 +6,7 @@ using Xunit;
 
 namespace System.Collections.Generic.Tests
 {
-    public partial class KeyValuePairTests
+    public class KeyValuePairTests
     {
         [Fact]
         public void Ctor_KeyValue_ReturnsExpected()
@@ -43,5 +43,13 @@ namespace System.Collections.Generic.Tests
             var keyValuePair = new KeyValuePair<string, string>(null, null);
             Assert.Equal("[, ]", keyValuePair.ToString());
         }
+
+        [Fact]
+        public void Create_ReturnsExpected()
+        {
+            KeyValuePair<int, string> keyValuePair = KeyValuePair.Create(1, "2");
+            Assert.Equal(1, keyValuePair.Key);
+            Assert.Equal("2", keyValuePair.Value);
+        }
     }
 }
diff --git a/src/libraries/System.Runtime/tests/System/Collections/Generic/KeyValuePairTests.netcoreapp.cs b/src/libraries/System.Runtime/tests/System/Collections/Generic/KeyValuePairTests.netcoreapp.cs
deleted file mode 100644 (file)
index 3b84d01..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-// 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 Xunit;
-
-namespace System.Collections.Generic.Tests
-{
-    public partial class KeyValuePairTests
-    {
-        [Fact]
-        public void Create_ReturnsExpected()
-        {
-            KeyValuePair<int, string> keyValuePair = KeyValuePair.Create(1, "2");
-            Assert.Equal(1, keyValuePair.Key);
-            Assert.Equal("2", keyValuePair.Value);
-        }
-    }
-}
index 19b3104..038ee85 100644 (file)
@@ -11,7 +11,7 @@ using Xunit;
 
 namespace System.ComponentModel.Tests
 {
-    public partial class DefaultValueAttributeTests
+    public class DefaultValueAttributeTests
     {
         [Fact]
         public static void Ctor()
@@ -23,9 +23,16 @@ namespace System.ComponentModel.Tests
             Assert.Equal(3.14f, new DefaultValueAttribute(3.14f).Value);
 
             Assert.Equal((byte)1, new DefaultValueAttribute((byte)1).Value);
+            Assert.Equal((sbyte)42, new DefaultValueAttribute((sbyte)42).Value);
+
             Assert.Equal(42, new DefaultValueAttribute(42).Value);
+            Assert.Equal((uint)42, new DefaultValueAttribute((uint)42).Value);
+
             Assert.Equal(42L, new DefaultValueAttribute(42L).Value);
+            Assert.Equal((ulong)42, new DefaultValueAttribute((ulong)42).Value);
+
             Assert.Equal((short)42, new DefaultValueAttribute((short)42).Value);
+            Assert.Equal((ushort)42, new DefaultValueAttribute((ushort)42).Value);
 
             Assert.Equal('c', new DefaultValueAttribute('c').Value);
             Assert.Equal("test", new DefaultValueAttribute("test").Value);
diff --git a/src/libraries/System.Runtime/tests/System/ComponentModel/DefaultValueAttributeTests.netcoreapp.cs b/src/libraries/System.Runtime/tests/System/ComponentModel/DefaultValueAttributeTests.netcoreapp.cs
deleted file mode 100644 (file)
index 178de91..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-// 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 Xunit;
-
-namespace System.ComponentModel.Tests
-{
-    public partial class DefaultValueAttributeTests
-    {
-        [Fact]
-        public static void Ctor_netcoreapp11()
-        {
-            Assert.Equal((sbyte)42, new DefaultValueAttribute((sbyte)42).Value);
-            Assert.Equal((ushort)42, new DefaultValueAttribute((ushort)42).Value);
-            Assert.Equal((uint)42, new DefaultValueAttribute((uint)42).Value);
-            Assert.Equal((ulong)42, new DefaultValueAttribute((ulong)42).Value);
-        }
-    }
-}
index 7c9a42c..fef1844 100644 (file)
@@ -10,7 +10,7 @@ using Xunit;
 
 namespace System.Tests
 {
-    public static partial class DateTimeOffsetTests
+    public static class DateTimeOffsetTests
     {
         [Fact]
         public static void MaxValue()
@@ -1275,5 +1275,98 @@ namespace System.Tests
         {
             Assert.Equal(expected, dateTimeOffset.ToString(format, culture));
         }
+
+        [Fact]
+        public static void ToString_ParseSpan_RoundtripsSuccessfully()
+        {
+            DateTimeOffset expected = DateTimeOffset.MaxValue;
+            string expectedString = expected.ToString();
+
+            Assert.Equal(expectedString, DateTimeOffset.Parse(expectedString.AsSpan()).ToString());
+            Assert.Equal(expectedString, DateTimeOffset.Parse(expectedString.AsSpan(), null).ToString());
+            Assert.Equal(expectedString, DateTimeOffset.Parse(expectedString.AsSpan(), null, DateTimeStyles.None).ToString());
+
+            Assert.True(DateTimeOffset.TryParse(expectedString.AsSpan(), out DateTimeOffset actual));
+            Assert.Equal(expectedString, actual.ToString());
+            Assert.True(DateTimeOffset.TryParse(expectedString.AsSpan(), null, DateTimeStyles.None, out actual));
+            Assert.Equal(expectedString, actual.ToString());
+        }
+
+        [Theory]
+        [InlineData("r")]
+        [InlineData("o")]
+        public static void ToString_Slice_ParseSpan_RoundtripsSuccessfully(string roundtripFormat)
+        {
+            string expectedString = DateTimeOffset.UtcNow.ToString(roundtripFormat);
+            ReadOnlySpan<char> expectedSpan = ("abcd" + expectedString + "1234").AsSpan("abcd".Length, expectedString.Length);
+
+            Assert.Equal(expectedString, DateTimeOffset.Parse(expectedSpan).ToString(roundtripFormat));
+            Assert.Equal(expectedString, DateTimeOffset.Parse(expectedSpan, null).ToString(roundtripFormat));
+            Assert.Equal(expectedString, DateTimeOffset.Parse(expectedSpan, null, DateTimeStyles.None).ToString(roundtripFormat));
+
+            Assert.True(DateTimeOffset.TryParse(expectedSpan, out DateTimeOffset actual));
+            Assert.Equal(expectedString, actual.ToString(roundtripFormat));
+            Assert.True(DateTimeOffset.TryParse(expectedSpan, null, DateTimeStyles.None, out actual));
+            Assert.Equal(expectedString, actual.ToString(roundtripFormat));
+        }
+
+        [Fact]
+        public static void ToString_ParseExactSpan_RoundtripsSuccessfully()
+        {
+            DateTimeOffset expected = DateTimeOffset.MaxValue;
+            string expectedString = expected.ToString("u");
+
+            Assert.Equal(expectedString, DateTimeOffset.ParseExact(expectedString, "u", null, DateTimeStyles.None).ToString("u"));
+            Assert.Equal(expectedString, DateTimeOffset.ParseExact(expectedString, new[] { "u" }, null, DateTimeStyles.None).ToString("u"));
+
+            Assert.True(DateTimeOffset.TryParseExact(expectedString, "u", null, DateTimeStyles.None, out DateTimeOffset actual));
+            Assert.Equal(expectedString, actual.ToString("u"));
+            Assert.True(DateTimeOffset.TryParseExact(expectedString, new[] { "u" }, null, DateTimeStyles.None, out actual));
+            Assert.Equal(expectedString, actual.ToString("u"));
+        }
+
+        [Fact]
+        public static void TryFormat_ToString_EqualResults()
+        {
+            DateTimeOffset expected = DateTimeOffset.MaxValue;
+            string expectedString = expected.ToString();
+
+            // Just the right amount of space, succeeds
+            Span<char> actual = new char[expectedString.Length];
+            Assert.True(expected.TryFormat(actual, out int charsWritten));
+            Assert.Equal(expectedString.Length, charsWritten);
+            Assert.Equal<char>(expectedString.ToCharArray(), actual.ToArray());
+
+            // Too little space, fails
+            actual = new char[expectedString.Length - 1];
+            Assert.False(expected.TryFormat(actual, out charsWritten));
+            Assert.Equal(0, charsWritten);
+
+            // More than enough space, succeeds
+            actual = new char[expectedString.Length + 1];
+            Assert.True(expected.TryFormat(actual, out charsWritten));
+            Assert.Equal(expectedString.Length, charsWritten);
+            Assert.Equal<char>(expectedString.ToCharArray(), actual.Slice(0, expectedString.Length).ToArray());
+            Assert.Equal(0, actual[actual.Length - 1]);
+        }
+
+        [Theory]
+        [MemberData(nameof(ToString_MatchesExpected_MemberData))]
+        public static void TryFormat_MatchesExpected(DateTimeOffset dateTimeOffset, string format, IFormatProvider provider, string expected)
+        {
+            var destination = new char[expected.Length];
+
+            Assert.False(dateTimeOffset.TryFormat(destination.AsSpan(0, destination.Length - 1), out _, format, provider));
+
+            Assert.True(dateTimeOffset.TryFormat(destination, out int charsWritten, format, provider));
+            Assert.Equal(destination.Length, charsWritten);
+            Assert.Equal(expected, new string(destination));
+        }
+
+        [Fact]
+        public static void UnixEpoch()
+        {
+            VerifyDateTimeOffset(DateTimeOffset.UnixEpoch, 1970, 1, 1, 0, 0, 0, 0, TimeSpan.Zero);
+        }
     }
 }
diff --git a/src/libraries/System.Runtime/tests/System/DateTimeOffsetTests.netcoreapp.cs b/src/libraries/System.Runtime/tests/System/DateTimeOffsetTests.netcoreapp.cs
deleted file mode 100644 (file)
index c927975..0000000
+++ /dev/null
@@ -1,105 +0,0 @@
-// 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 Xunit;
-
-namespace System.Tests
-{
-    public static partial class DateTimeOffsetTests
-    {
-        [Fact]
-        public static void ToString_ParseSpan_RoundtripsSuccessfully()
-        {
-            DateTimeOffset expected = DateTimeOffset.MaxValue;
-            string expectedString = expected.ToString();
-
-            Assert.Equal(expectedString, DateTimeOffset.Parse(expectedString.AsSpan()).ToString());
-            Assert.Equal(expectedString, DateTimeOffset.Parse(expectedString.AsSpan(), null).ToString());
-            Assert.Equal(expectedString, DateTimeOffset.Parse(expectedString.AsSpan(), null, DateTimeStyles.None).ToString());
-
-            Assert.True(DateTimeOffset.TryParse(expectedString.AsSpan(), out DateTimeOffset actual));
-            Assert.Equal(expectedString, actual.ToString());
-            Assert.True(DateTimeOffset.TryParse(expectedString.AsSpan(), null, DateTimeStyles.None, out actual));
-            Assert.Equal(expectedString, actual.ToString());
-        }
-
-        [Theory]
-        [InlineData("r")]
-        [InlineData("o")]
-        public static void ToString_Slice_ParseSpan_RoundtripsSuccessfully(string roundtripFormat)
-        {
-            string expectedString = DateTimeOffset.UtcNow.ToString(roundtripFormat);
-            ReadOnlySpan<char> expectedSpan = ("abcd" + expectedString + "1234").AsSpan("abcd".Length, expectedString.Length);
-
-            Assert.Equal(expectedString, DateTimeOffset.Parse(expectedSpan).ToString(roundtripFormat));
-            Assert.Equal(expectedString, DateTimeOffset.Parse(expectedSpan, null).ToString(roundtripFormat));
-            Assert.Equal(expectedString, DateTimeOffset.Parse(expectedSpan, null, DateTimeStyles.None).ToString(roundtripFormat));
-
-            Assert.True(DateTimeOffset.TryParse(expectedSpan, out DateTimeOffset actual));
-            Assert.Equal(expectedString, actual.ToString(roundtripFormat));
-            Assert.True(DateTimeOffset.TryParse(expectedSpan, null, DateTimeStyles.None, out actual));
-            Assert.Equal(expectedString, actual.ToString(roundtripFormat));
-        }
-
-        [Fact]
-        public static void ToString_ParseExactSpan_RoundtripsSuccessfully()
-        {
-            DateTimeOffset expected = DateTimeOffset.MaxValue;
-            string expectedString = expected.ToString("u");
-
-            Assert.Equal(expectedString, DateTimeOffset.ParseExact(expectedString, "u", null, DateTimeStyles.None).ToString("u"));
-            Assert.Equal(expectedString, DateTimeOffset.ParseExact(expectedString, new[] { "u" }, null, DateTimeStyles.None).ToString("u"));
-
-            Assert.True(DateTimeOffset.TryParseExact(expectedString, "u", null, DateTimeStyles.None, out DateTimeOffset actual));
-            Assert.Equal(expectedString, actual.ToString("u"));
-            Assert.True(DateTimeOffset.TryParseExact(expectedString, new[] { "u" }, null, DateTimeStyles.None, out actual));
-            Assert.Equal(expectedString, actual.ToString("u"));
-        }
-
-        [Fact]
-        public static void TryFormat_ToString_EqualResults()
-        {
-            DateTimeOffset expected = DateTimeOffset.MaxValue;
-            string expectedString = expected.ToString();
-
-            // Just the right amount of space, succeeds
-            Span<char> actual = new char[expectedString.Length];
-            Assert.True(expected.TryFormat(actual, out int charsWritten));
-            Assert.Equal(expectedString.Length, charsWritten);
-            Assert.Equal<char>(expectedString.ToCharArray(), actual.ToArray());
-
-            // Too little space, fails
-            actual = new char[expectedString.Length - 1];
-            Assert.False(expected.TryFormat(actual, out charsWritten));
-            Assert.Equal(0, charsWritten);
-
-            // More than enough space, succeeds
-            actual = new char[expectedString.Length + 1];
-            Assert.True(expected.TryFormat(actual, out charsWritten));
-            Assert.Equal(expectedString.Length, charsWritten);
-            Assert.Equal<char>(expectedString.ToCharArray(), actual.Slice(0, expectedString.Length).ToArray());
-            Assert.Equal(0, actual[actual.Length - 1]);
-        }
-
-        [Theory]
-        [MemberData(nameof(ToString_MatchesExpected_MemberData))]
-        public static void TryFormat_MatchesExpected(DateTimeOffset dateTimeOffset, string format, IFormatProvider provider, string expected)
-        {
-            var destination = new char[expected.Length];
-
-            Assert.False(dateTimeOffset.TryFormat(destination.AsSpan(0, destination.Length - 1), out _, format, provider));
-
-            Assert.True(dateTimeOffset.TryFormat(destination, out int charsWritten, format, provider));
-            Assert.Equal(destination.Length, charsWritten);
-            Assert.Equal(expected, new string(destination));
-        }
-
-        [Fact]
-        public static void UnixEpoch()
-        {
-            VerifyDateTimeOffset(DateTimeOffset.UnixEpoch, 1970, 1, 1, 0, 0, 0, 0, TimeSpan.Zero);
-        }
-    }
-}
index a390144..ff8964f 100644 (file)
@@ -12,7 +12,7 @@ using Xunit;
 
 namespace System.Tests
 {
-    public partial class DateTimeTests
+    public class DateTimeTests
     {
         [Fact]
         public static void MaxValue()
@@ -2273,5 +2273,98 @@ namespace System.Tests
                 return DateTime.MaxValue;
             }
         }
+
+        [Theory]
+        [MemberData(nameof(StandardFormatSpecifiers))]
+        public static void TryFormat_MatchesToString(string format)
+        {
+            DateTime dt = DateTime.UtcNow;
+            string expected = dt.ToString(format);
+
+            // Just the right length, succeeds
+            Span<char> dest = new char[expected.Length];
+            Assert.True(dt.TryFormat(dest, out int charsWritten, format));
+            Assert.Equal(expected.Length, charsWritten);
+            Assert.Equal<char>(expected.ToCharArray(), dest.ToArray());
+
+            // Too short, fails
+            dest = new char[expected.Length - 1];
+            Assert.False(dt.TryFormat(dest, out charsWritten, format));
+            Assert.Equal(0, charsWritten);
+
+            // Longer than needed, succeeds
+            dest = new char[expected.Length + 1];
+            Assert.True(dt.TryFormat(dest, out charsWritten, format));
+            Assert.Equal(expected.Length, charsWritten);
+            Assert.Equal<char>(expected.ToCharArray(), dest.Slice(0, expected.Length).ToArray());
+            Assert.Equal(0, dest[dest.Length - 1]);
+        }
+
+        [Theory]
+        [MemberData(nameof(ToString_MatchesExpected_MemberData))]
+        public static void TryFormat_MatchesExpected(DateTime dateTime, string format, IFormatProvider provider, string expected)
+        {
+            var destination = new char[expected.Length];
+
+            Assert.False(dateTime.TryFormat(destination.AsSpan(0, destination.Length - 1), out _, format, provider));
+
+            Assert.True(dateTime.TryFormat(destination, out int charsWritten, format, provider));
+            Assert.Equal(destination.Length, charsWritten);
+            Assert.Equal(expected, new string(destination));
+        }
+
+        [Theory]
+        [MemberData(nameof(Parse_ValidInput_Succeeds_MemberData))]
+        public static void Parse_Span_ValidInput_Succeeds(string input, CultureInfo culture, DateTime? expected)
+        {
+            Assert.Equal(expected, DateTime.Parse(input.AsSpan(), culture));
+        }
+
+        [Theory]
+        [MemberData(nameof(ParseExact_ValidInput_Succeeds_MemberData))]
+        public static void ParseExact_Span_ValidInput_Succeeds(string input, string format, CultureInfo culture, DateTimeStyles style, DateTime? expected)
+        {
+            DateTime result1 = DateTime.ParseExact(input.AsSpan(), format, culture, style);
+            DateTime result2 = DateTime.ParseExact(input.AsSpan(), new[] { format }, culture, style);
+
+            Assert.True(DateTime.TryParseExact(input.AsSpan(), format, culture, style, out DateTime result3));
+            Assert.True(DateTime.TryParseExact(input.AsSpan(), new[] { format }, culture, style, out DateTime result4));
+
+            Assert.Equal(result1, result2);
+            Assert.Equal(result1, result3);
+            Assert.Equal(result1, result4);
+
+            if (expected != null) // some inputs don't roundtrip well
+            {
+                // Normalize values to make comparison easier
+                if (expected.Value.Kind != DateTimeKind.Utc)
+                {
+                    expected = expected.Value.ToUniversalTime();
+                }
+                if (result1.Kind != DateTimeKind.Utc)
+                {
+                    result1 = result1.ToUniversalTime();
+                }
+
+                Assert.Equal(expected, result1);
+            }
+        }
+
+        [Theory]
+        [MemberData(nameof(ParseExact_InvalidInputs_Fail_MemberData))]
+        public static void ParseExact_Span_InvalidInputs_Fail(string input, string format, CultureInfo culture, DateTimeStyles style)
+        {
+            Assert.Throws<FormatException>(() => DateTime.ParseExact(input.AsSpan(), format, culture, style));
+            Assert.Throws<FormatException>(() => DateTime.ParseExact(input.AsSpan(), new[] { format }, culture, style));
+
+            Assert.False(DateTime.TryParseExact(input.AsSpan(), format, culture, style, out DateTime result));
+            Assert.False(DateTime.TryParseExact(input.AsSpan(), new[] { format }, culture, style, out result));
+        }
+
+        [Fact]
+        public static void UnixEpoch()
+        {
+            VerifyDateTime(DateTime.UnixEpoch, 1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc);
+        }
     }
 }
diff --git a/src/libraries/System.Runtime/tests/System/DateTimeTests.netcoreapp.cs b/src/libraries/System.Runtime/tests/System/DateTimeTests.netcoreapp.cs
deleted file mode 100644 (file)
index 13eee84..0000000
+++ /dev/null
@@ -1,105 +0,0 @@
-// 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 Xunit;
-
-namespace System.Tests
-{
-    public partial class DateTimeTests
-    {
-        [Theory]
-        [MemberData(nameof(StandardFormatSpecifiers))]
-        public static void TryFormat_MatchesToString(string format)
-        {
-            DateTime dt = DateTime.UtcNow;
-            string expected = dt.ToString(format);
-
-            // Just the right length, succeeds
-            Span<char> dest = new char[expected.Length];
-            Assert.True(dt.TryFormat(dest, out int charsWritten, format));
-            Assert.Equal(expected.Length, charsWritten);
-            Assert.Equal<char>(expected.ToCharArray(), dest.ToArray());
-
-            // Too short, fails
-            dest = new char[expected.Length - 1];
-            Assert.False(dt.TryFormat(dest, out charsWritten, format));
-            Assert.Equal(0, charsWritten);
-
-            // Longer than needed, succeeds
-            dest = new char[expected.Length + 1];
-            Assert.True(dt.TryFormat(dest, out charsWritten, format));
-            Assert.Equal(expected.Length, charsWritten);
-            Assert.Equal<char>(expected.ToCharArray(), dest.Slice(0, expected.Length).ToArray());
-            Assert.Equal(0, dest[dest.Length - 1]);
-        }
-
-        [Theory]
-        [MemberData(nameof(ToString_MatchesExpected_MemberData))]
-        public static void TryFormat_MatchesExpected(DateTime dateTime, string format, IFormatProvider provider, string expected)
-        {
-            var destination = new char[expected.Length];
-
-            Assert.False(dateTime.TryFormat(destination.AsSpan(0, destination.Length - 1), out _, format, provider));
-
-            Assert.True(dateTime.TryFormat(destination, out int charsWritten, format, provider));
-            Assert.Equal(destination.Length, charsWritten);
-            Assert.Equal(expected, new string(destination));
-        }
-
-        [Theory]
-        [MemberData(nameof(Parse_ValidInput_Succeeds_MemberData))]
-        public static void Parse_Span_ValidInput_Succeeds(string input, CultureInfo culture, DateTime? expected)
-        {
-            Assert.Equal(expected, DateTime.Parse(input.AsSpan(), culture));
-        }
-
-        [Theory]
-        [MemberData(nameof(ParseExact_ValidInput_Succeeds_MemberData))]
-        public static void ParseExact_Span_ValidInput_Succeeds(string input, string format, CultureInfo culture, DateTimeStyles style, DateTime? expected)
-        {
-            DateTime result1 = DateTime.ParseExact(input.AsSpan(), format, culture, style);
-            DateTime result2 = DateTime.ParseExact(input.AsSpan(), new[] { format }, culture, style);
-
-            Assert.True(DateTime.TryParseExact(input.AsSpan(), format, culture, style, out DateTime result3));
-            Assert.True(DateTime.TryParseExact(input.AsSpan(), new[] { format }, culture, style, out DateTime result4));
-
-            Assert.Equal(result1, result2);
-            Assert.Equal(result1, result3);
-            Assert.Equal(result1, result4);
-
-            if (expected != null) // some inputs don't roundtrip well
-            {
-                // Normalize values to make comparison easier
-                if (expected.Value.Kind != DateTimeKind.Utc)
-                {
-                    expected = expected.Value.ToUniversalTime();
-                }
-                if (result1.Kind != DateTimeKind.Utc)
-                {
-                    result1 = result1.ToUniversalTime();
-                }
-
-                Assert.Equal(expected, result1);
-            }
-        }
-
-        [Theory]
-        [MemberData(nameof(ParseExact_InvalidInputs_Fail_MemberData))]
-        public static void ParseExact_Span_InvalidInputs_Fail(string input, string format, CultureInfo culture, DateTimeStyles style)
-        {
-            Assert.Throws<FormatException>(() => DateTime.ParseExact(input.AsSpan(), format, culture, style));
-            Assert.Throws<FormatException>(() => DateTime.ParseExact(input.AsSpan(), new[] { format }, culture, style));
-
-            Assert.False(DateTime.TryParseExact(input.AsSpan(), format, culture, style, out DateTime result));
-            Assert.False(DateTime.TryParseExact(input.AsSpan(), new[] { format }, culture, style, out result));
-        }
-
-        [Fact]
-        public static void UnixEpoch()
-        {
-            VerifyDateTime(DateTime.UnixEpoch, 1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc);
-        }
-    }
-}
index 8d2b8ed..f132752 100644 (file)
@@ -12,7 +12,7 @@ using Xunit;
 
 namespace System.Tests
 {
-    public partial class DecimalTests
+    public class DecimalTests
     {
         [Fact]
         public void MaxValue_Get_ReturnsExpected()
@@ -2179,5 +2179,127 @@ namespace System.Tests
                 return new BigDecimal(res, (byte)scale);
             }
         }
+
+        [Theory]
+        [InlineData(MidpointRounding.ToEven - 1)]
+        [InlineData(MidpointRounding.ToPositiveInfinity + 1)]
+        public void Round_InvalidMidpointRounding_ThrowsArgumentException(MidpointRounding mode)
+        {
+            AssertExtensions.Throws<ArgumentException>("mode", () => decimal.Round(1, 2, mode));
+        }
+
+        public static IEnumerable<object[]> Parse_ValidWithOffsetCount_TestData()
+        {
+            foreach (object[] inputs in Parse_Valid_TestData())
+            {
+                yield return new object[] { inputs[0], 0, ((string)inputs[0]).Length, inputs[1], inputs[2], inputs[3] };
+            }
+
+            yield return new object[] { "-123", 1, 3, NumberStyles.Number, null, 123m };
+            yield return new object[] { "-123", 0, 3, NumberStyles.Number, null, -12m };
+            yield return new object[] { 1000.ToString("N0"), 0, 4, NumberStyles.AllowThousands, null, 100m };
+            yield return new object[] { 1000.ToString("N0"), 2, 3, NumberStyles.AllowThousands, null, 0m };
+            yield return new object[] { "(123)", 1, 3, NumberStyles.AllowParentheses, new NumberFormatInfo() { NumberDecimalSeparator = "." }, 123m };
+            yield return new object[] { "1234567890123456789012345.678456", 1, 4, NumberStyles.Number, new NumberFormatInfo() { NumberDecimalSeparator = "." }, 2345m };
+        }
+
+        [Theory]
+        [MemberData(nameof(Parse_ValidWithOffsetCount_TestData))]
+        public static void Parse_Span_Valid(string value, int offset, int count, NumberStyles style, IFormatProvider provider, decimal expected)
+        {
+            bool isDefaultProvider = provider == null || provider == NumberFormatInfo.CurrentInfo;
+            decimal result;
+            if ((style & ~NumberStyles.Number) == 0 && style != NumberStyles.None)
+            {
+                // Use Parse(string) or Parse(string, IFormatProvider)
+                if (isDefaultProvider)
+                {
+                    Assert.True(decimal.TryParse(value.AsSpan(offset, count), out result));
+                    Assert.Equal(expected, result);
+
+                    Assert.Equal(expected, decimal.Parse(value.AsSpan(offset, count)));
+                }
+
+                Assert.Equal(expected, decimal.Parse(value.AsSpan(offset, count), provider: provider));
+            }
+
+            Assert.Equal(expected, decimal.Parse(value.AsSpan(offset, count), style, provider));
+
+            Assert.True(decimal.TryParse(value.AsSpan(offset, count), style, provider, out result));
+            Assert.Equal(expected, result);
+        }
+
+        [Theory]
+        [MemberData(nameof(Parse_Invalid_TestData))]
+        public static void Parse_Span_Invalid(string value, NumberStyles style, IFormatProvider provider, Type exceptionType)
+        {
+            if (value != null)
+            {
+                Assert.Throws(exceptionType, () => decimal.Parse(value.AsSpan(), style, provider));
+
+                Assert.False(decimal.TryParse(value.AsSpan(), style, provider, out decimal result));
+                Assert.Equal(0, result);
+            }
+        }
+
+        [Fact]
+        public static void TryFormat()
+        {
+            using (new ThreadCultureChange(CultureInfo.InvariantCulture))
+            {
+                foreach (object[] testdata in ToString_TestData())
+                {
+                    decimal localI = (decimal)testdata[0];
+                    string localFormat = (string)testdata[1];
+                    IFormatProvider localProvider = (IFormatProvider)testdata[2];
+                    string localExpected = (string)testdata[3];
+
+                    try
+                    {
+                        char[] actual;
+                        int charsWritten;
+
+                        // Just right
+                        actual = new char[localExpected.Length];
+                        Assert.True(localI.TryFormat(actual.AsSpan(), out charsWritten, localFormat, localProvider));
+                        Assert.Equal(localExpected.Length, charsWritten);
+                        Assert.Equal(localExpected, new string(actual));
+
+                        // Longer than needed
+                        actual = new char[localExpected.Length + 1];
+                        Assert.True(localI.TryFormat(actual.AsSpan(), out charsWritten, localFormat, localProvider));
+                        Assert.Equal(localExpected.Length, charsWritten);
+                        Assert.Equal(localExpected, new string(actual, 0, charsWritten));
+
+                        // Too short
+                        if (localExpected.Length > 0)
+                        {
+                            actual = new char[localExpected.Length - 1];
+                            Assert.False(localI.TryFormat(actual.AsSpan(), out charsWritten, localFormat, localProvider));
+                            Assert.Equal(0, charsWritten);
+                        }
+
+                        if (localFormat != null)
+                        {
+                            // Upper localFormat
+                            actual = new char[localExpected.Length];
+                            Assert.True(localI.TryFormat(actual.AsSpan(), out charsWritten, localFormat.ToUpperInvariant(), localProvider));
+                            Assert.Equal(localExpected.Length, charsWritten);
+                            Assert.Equal(localExpected.ToUpperInvariant(), new string(actual));
+
+                            // Lower format
+                            actual = new char[localExpected.Length];
+                            Assert.True(localI.TryFormat(actual.AsSpan(), out charsWritten, localFormat.ToLowerInvariant(), localProvider));
+                            Assert.Equal(localExpected.Length, charsWritten);
+                            Assert.Equal(localExpected.ToLowerInvariant(), new string(actual));
+                        }
+                    }
+                    catch (Exception exc)
+                    {
+                        throw new Exception($"Failed on `{localI}`, `{localFormat}`, `{localProvider}`, `{localExpected}`. {exc}");
+                    }
+                }
+            }
+        }
     }
 }
diff --git a/src/libraries/System.Runtime/tests/System/DecimalTests.netcoreapp.cs b/src/libraries/System.Runtime/tests/System/DecimalTests.netcoreapp.cs
deleted file mode 100644 (file)
index fcd5b81..0000000
+++ /dev/null
@@ -1,136 +0,0 @@
-// 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.Globalization;
-using Microsoft.DotNet.RemoteExecutor;
-using Xunit;
-
-namespace System.Tests
-{
-    public partial class DecimalTests
-    {
-        [Theory]
-        [InlineData(MidpointRounding.ToEven - 1)]
-        [InlineData(MidpointRounding.ToPositiveInfinity + 1)]
-        public void Round_InvalidMidpointRounding_ThrowsArgumentException(MidpointRounding mode)
-        {
-            AssertExtensions.Throws<ArgumentException>("mode", () => decimal.Round(1, 2, mode));
-        }
-
-        public static IEnumerable<object[]> Parse_ValidWithOffsetCount_TestData()
-        {
-            foreach (object[] inputs in Parse_Valid_TestData())
-            {
-                yield return new object[] { inputs[0], 0, ((string)inputs[0]).Length, inputs[1], inputs[2], inputs[3] };
-            }
-
-            yield return new object[] { "-123", 1, 3, NumberStyles.Number, null, 123m };
-            yield return new object[] { "-123", 0, 3, NumberStyles.Number, null, -12m };
-            yield return new object[] { 1000.ToString("N0"), 0, 4, NumberStyles.AllowThousands, null, 100m };
-            yield return new object[] { 1000.ToString("N0"), 2, 3, NumberStyles.AllowThousands, null, 0m };
-            yield return new object[] { "(123)", 1, 3, NumberStyles.AllowParentheses, new NumberFormatInfo() { NumberDecimalSeparator = "." }, 123m };
-            yield return new object[] { "1234567890123456789012345.678456", 1, 4, NumberStyles.Number, new NumberFormatInfo() { NumberDecimalSeparator = "." }, 2345m };
-        }
-
-        [Theory]
-        [MemberData(nameof(Parse_ValidWithOffsetCount_TestData))]
-        public static void Parse_Span_Valid(string value, int offset, int count, NumberStyles style, IFormatProvider provider, decimal expected)
-        {
-            bool isDefaultProvider = provider == null || provider == NumberFormatInfo.CurrentInfo;
-            decimal result;
-            if ((style & ~NumberStyles.Number) == 0 && style != NumberStyles.None)
-            {
-                // Use Parse(string) or Parse(string, IFormatProvider)
-                if (isDefaultProvider)
-                {
-                    Assert.True(decimal.TryParse(value.AsSpan(offset, count), out result));
-                    Assert.Equal(expected, result);
-
-                    Assert.Equal(expected, decimal.Parse(value.AsSpan(offset, count)));
-                }
-
-                Assert.Equal(expected, decimal.Parse(value.AsSpan(offset, count), provider: provider));
-            }
-
-            Assert.Equal(expected, decimal.Parse(value.AsSpan(offset, count), style, provider));
-
-            Assert.True(decimal.TryParse(value.AsSpan(offset, count), style, provider, out result));
-            Assert.Equal(expected, result);
-        }
-
-        [Theory]
-        [MemberData(nameof(Parse_Invalid_TestData))]
-        public static void Parse_Span_Invalid(string value, NumberStyles style, IFormatProvider provider, Type exceptionType)
-        {
-            if (value != null)
-            {
-                Assert.Throws(exceptionType, () => decimal.Parse(value.AsSpan(), style, provider));
-
-                Assert.False(decimal.TryParse(value.AsSpan(), style, provider, out decimal result));
-                Assert.Equal(0, result);
-            }
-        }
-
-        [Fact]
-        public static void TryFormat()
-        {
-            using (new ThreadCultureChange(CultureInfo.InvariantCulture))
-            {
-                foreach (object[] testdata in ToString_TestData())
-                {
-                    decimal localI = (decimal)testdata[0];
-                    string localFormat = (string)testdata[1];
-                    IFormatProvider localProvider = (IFormatProvider)testdata[2];
-                    string localExpected = (string)testdata[3];
-
-                    try
-                    {
-                        char[] actual;
-                        int charsWritten;
-
-                        // Just right
-                        actual = new char[localExpected.Length];
-                        Assert.True(localI.TryFormat(actual.AsSpan(), out charsWritten, localFormat, localProvider));
-                        Assert.Equal(localExpected.Length, charsWritten);
-                        Assert.Equal(localExpected, new string(actual));
-
-                        // Longer than needed
-                        actual = new char[localExpected.Length + 1];
-                        Assert.True(localI.TryFormat(actual.AsSpan(), out charsWritten, localFormat, localProvider));
-                        Assert.Equal(localExpected.Length, charsWritten);
-                        Assert.Equal(localExpected, new string(actual, 0, charsWritten));
-
-                        // Too short
-                        if (localExpected.Length > 0)
-                        {
-                            actual = new char[localExpected.Length - 1];
-                            Assert.False(localI.TryFormat(actual.AsSpan(), out charsWritten, localFormat, localProvider));
-                            Assert.Equal(0, charsWritten);
-                        }
-
-                        if (localFormat != null)
-                        {
-                            // Upper localFormat
-                            actual = new char[localExpected.Length];
-                            Assert.True(localI.TryFormat(actual.AsSpan(), out charsWritten, localFormat.ToUpperInvariant(), localProvider));
-                            Assert.Equal(localExpected.Length, charsWritten);
-                            Assert.Equal(localExpected.ToUpperInvariant(), new string(actual));
-
-                            // Lower format
-                            actual = new char[localExpected.Length];
-                            Assert.True(localI.TryFormat(actual.AsSpan(), out charsWritten, localFormat.ToLowerInvariant(), localProvider));
-                            Assert.Equal(localExpected.Length, charsWritten);
-                            Assert.Equal(localExpected.ToLowerInvariant(), new string(actual));
-                        }
-                    }
-                    catch (Exception exc)
-                    {
-                        throw new Exception($"Failed on `{localI}`, `{localFormat}`, `{localProvider}`, `{localExpected}`. {exc}");
-                    }
-                }
-            }
-        }
-    }
-}
index c1b4fe3..de096f5 100644 (file)
@@ -11,7 +11,7 @@ using Xunit;
 
 namespace System.Tests
 {
-    public partial class DoubleTests
+    public class DoubleTests
     {
         // NOTE: Consider duplicating any tests added here in SingleTests.cs
 
@@ -492,5 +492,215 @@ namespace System.Tests
             Assert.Throws<FormatException>(() => d.ToString("Y")); // Invalid format
             Assert.Throws<FormatException>(() => d.ToString("Y", null)); // Invalid format
         }
+
+        [Theory]
+        [InlineData(double.NegativeInfinity, false)]    // Negative Infinity
+        [InlineData(double.MinValue, true)]             // Min Negative Normal
+        [InlineData(-2.2250738585072014E-308, true)]    // Max Negative Normal
+        [InlineData(-2.2250738585072009E-308, true)]    // Min Negative Subnormal
+        [InlineData(-4.94065645841247E-324, true)]      // Max Negative Subnormal
+        [InlineData(-0.0, true)]                        // Negative Zero
+        [InlineData(double.NaN, false)]                 // NaN
+        [InlineData(0.0, true)]                         // Positive Zero
+        [InlineData(4.94065645841247E-324, true)]       // Min Positive Subnormal
+        [InlineData(2.2250738585072009E-308, true)]     // Max Positive Subnormal
+        [InlineData(2.2250738585072014E-308, true)]     // Min Positive Normal
+        [InlineData(double.MaxValue, true)]             // Max Positive Normal
+        [InlineData(double.PositiveInfinity, false)]    // Positive Infinity
+        public static void IsFinite(double d, bool expected)
+        {
+            Assert.Equal(expected, double.IsFinite(d));
+        }
+
+        [Theory]
+        [InlineData(double.NegativeInfinity, true)]     // Negative Infinity
+        [InlineData(double.MinValue, true)]             // Min Negative Normal
+        [InlineData(-2.2250738585072014E-308, true)]    // Max Negative Normal
+        [InlineData(-2.2250738585072009E-308, true)]    // Min Negative Subnormal
+        [InlineData(-4.94065645841247E-324, true)]      // Max Negative Subnormal
+        [InlineData(-0.0, true)]                        // Negative Zero
+        [InlineData(double.NaN, true)]                  // NaN
+        [InlineData(0.0, false)]                        // Positive Zero
+        [InlineData(4.94065645841247E-324, false)]      // Min Positive Subnormal
+        [InlineData(2.2250738585072009E-308, false)]    // Max Positive Subnormal
+        [InlineData(2.2250738585072014E-308, false)]    // Min Positive Normal
+        [InlineData(double.MaxValue, false)]            // Max Positive Normal
+        [InlineData(double.PositiveInfinity, false)]    // Positive Infinity
+        public static void IsNegative(double d, bool expected)
+        {
+            Assert.Equal(expected, double.IsNegative(d));
+        }
+
+        [Theory]
+        [InlineData(double.NegativeInfinity, false)]    // Negative Infinity
+        [InlineData(double.MinValue, true)]             // Min Negative Normal
+        [InlineData(-2.2250738585072014E-308, true)]    // Max Negative Normal
+        [InlineData(-2.2250738585072009E-308, false)]   // Min Negative Subnormal
+        [InlineData(-4.94065645841247E-324, false)]     // Max Negative Subnormal
+        [InlineData(-0.0, false)]                       // Negative Zero
+        [InlineData(double.NaN, false)]                 // NaN
+        [InlineData(0.0, false)]                        // Positive Zero
+        [InlineData(4.94065645841247E-324, false)]      // Min Positive Subnormal
+        [InlineData(2.2250738585072009E-308, false)]    // Max Positive Subnormal
+        [InlineData(2.2250738585072014E-308, true)]     // Min Positive Normal
+        [InlineData(double.MaxValue, true)]             // Max Positive Normal
+        [InlineData(double.PositiveInfinity, false)]    // Positive Infinity
+        public static void IsNormal(double d, bool expected)
+        {
+            Assert.Equal(expected, double.IsNormal(d));
+        }
+
+        [Theory]
+        [InlineData(double.NegativeInfinity, false)]    // Negative Infinity
+        [InlineData(double.MinValue, false)]            // Min Negative Normal
+        [InlineData(-2.2250738585072014E-308, false)]   // Max Negative Normal
+        [InlineData(-2.2250738585072009E-308, true)]    // Min Negative Subnormal
+        [InlineData(-4.94065645841247E-324, true)]      // Max Negative Subnormal
+        [InlineData(-0.0, false)]                       // Negative Zero
+        [InlineData(double.NaN, false)]                 // NaN
+        [InlineData(0.0, false)]                        // Positive Zero
+        [InlineData(4.94065645841247E-324, true)]       // Min Positive Subnormal
+        [InlineData(2.2250738585072009E-308, true)]     // Max Positive Subnormal
+        [InlineData(2.2250738585072014E-308, false)]    // Min Positive Normal
+        [InlineData(double.MaxValue, false)]            // Max Positive Normal
+        [InlineData(double.PositiveInfinity, false)]    // Positive Infinity
+        public static void IsSubnormal(double d, bool expected)
+        {
+            Assert.Equal(expected, double.IsSubnormal(d));
+        }
+
+        public static IEnumerable<object[]> Parse_ValidWithOffsetCount_TestData()
+        {
+            foreach (object[] inputs in Parse_Valid_TestData())
+            {
+                yield return new object[] { inputs[0], 0, ((string)inputs[0]).Length, inputs[1], inputs[2], inputs[3] };
+            }
+
+            const NumberStyles DefaultStyle = NumberStyles.Float | NumberStyles.AllowThousands;
+            yield return new object[] { "-123", 0, 3, DefaultStyle, null, (double)-12 };
+            yield return new object[] { "-123", 1, 3, DefaultStyle, null, (double)123 };
+            yield return new object[] { "1E23", 0, 3, DefaultStyle, null, 1E2 };
+            yield return new object[] { "(123)", 1, 3, NumberStyles.AllowParentheses, new NumberFormatInfo() { NumberDecimalSeparator = "." }, 123 };
+            yield return new object[] { "-Infinity", 1, 8, NumberStyles.Any, NumberFormatInfo.InvariantInfo, double.PositiveInfinity };
+        }
+
+        [Theory]
+        [MemberData(nameof(Parse_ValidWithOffsetCount_TestData))]
+        public static void Parse_Span_Valid(string value, int offset, int count, NumberStyles style, IFormatProvider provider, double expected)
+        {
+            bool isDefaultProvider = provider == null || provider == NumberFormatInfo.CurrentInfo;
+            double result;
+            if ((style & ~(NumberStyles.Float | NumberStyles.AllowThousands)) == 0 && style != NumberStyles.None)
+            {
+                // Use Parse(string) or Parse(string, IFormatProvider)
+                if (isDefaultProvider)
+                {
+                    Assert.True(double.TryParse(value.AsSpan(offset, count), out result));
+                    Assert.Equal(expected, result);
+
+                    Assert.Equal(expected, double.Parse(value.AsSpan(offset, count)));
+                }
+
+                Assert.Equal(expected, double.Parse(value.AsSpan(offset, count), provider: provider));
+            }
+
+            Assert.Equal(expected, double.Parse(value.AsSpan(offset, count), style, provider));
+
+            Assert.True(double.TryParse(value.AsSpan(offset, count), style, provider, out result));
+            Assert.Equal(expected, result);
+        }
+
+        [Theory]
+        [MemberData(nameof(Parse_Invalid_TestData))]
+        public static void Parse_Span_Invalid(string value, NumberStyles style, IFormatProvider provider, Type exceptionType)
+        {
+            if (value != null)
+            {
+                Assert.Throws(exceptionType, () => double.Parse(value.AsSpan(), style, provider));
+
+                Assert.False(double.TryParse(value.AsSpan(), style, provider, out double result));
+                Assert.Equal(0, result);
+            }
+        }
+
+        [Fact]
+        public static void TryFormat()
+        {
+            using (new ThreadCultureChange(CultureInfo.InvariantCulture))
+            {
+                foreach (var testdata in ToString_TestData_NotNetFramework())
+                {
+                    double localI = (double)testdata[0];
+                    string localFormat = (string)testdata[1];
+                    IFormatProvider localProvider = (IFormatProvider)testdata[2];
+                    string localExpected = (string)testdata[3];
+
+                    try
+                    {
+                        char[] actual;
+                        int charsWritten;
+
+                        // Just right
+                        actual = new char[localExpected.Length];
+                        Assert.True(localI.TryFormat(actual.AsSpan(), out charsWritten, localFormat, localProvider));
+                        Assert.Equal(localExpected.Length, charsWritten);
+                        Assert.Equal(localExpected, new string(actual));
+
+                        // Longer than needed
+                        actual = new char[localExpected.Length + 1];
+                        Assert.True(localI.TryFormat(actual.AsSpan(), out charsWritten, localFormat, localProvider));
+                        Assert.Equal(localExpected.Length, charsWritten);
+                        Assert.Equal(localExpected, new string(actual, 0, charsWritten));
+
+                        // Too short
+                        if (localExpected.Length > 0)
+                        {
+                            actual = new char[localExpected.Length - 1];
+                            Assert.False(localI.TryFormat(actual.AsSpan(), out charsWritten, localFormat, localProvider));
+                            Assert.Equal(0, charsWritten);
+                        }
+                    }
+                    catch (Exception exc)
+                    {
+                        throw new Exception($"Failed on `{localI}`, `{localFormat}`, `{localProvider}`, `{localExpected}`. {exc}");
+                    }
+                }
+            }
+        }
+
+        public static IEnumerable<object[]> ToStringRoundtrip_TestData()
+        {
+            yield return new object[] { double.NegativeInfinity };
+            yield return new object[] { double.MinValue };
+            yield return new object[] { -Math.PI };
+            yield return new object[] { -Math.E };
+            yield return new object[] { -double.Epsilon };
+            yield return new object[] { -0.84551240822557006 };
+            yield return new object[] { -0.0 };
+            yield return new object[] { double.NaN };
+            yield return new object[] { 0.0 };
+            yield return new object[] { 0.84551240822557006 };
+            yield return new object[] { double.Epsilon };
+            yield return new object[] { Math.E };
+            yield return new object[] { Math.PI };
+            yield return new object[] { double.MaxValue };
+            yield return new object[] { double.PositiveInfinity };
+        }
+
+        [Theory]
+        [MemberData(nameof(ToStringRoundtrip_TestData))]
+        public static void ToStringRoundtrip(double value)
+        {
+            double result = double.Parse(value.ToString());
+            Assert.Equal(BitConverter.DoubleToInt64Bits(value), BitConverter.DoubleToInt64Bits(result));
+        }
+
+        [Theory]
+        [MemberData(nameof(ToStringRoundtrip_TestData))]
+        public static void ToStringRoundtrip_R(double value)
+        {
+            double result = double.Parse(value.ToString("R"));
+            Assert.Equal(BitConverter.DoubleToInt64Bits(value), BitConverter.DoubleToInt64Bits(result));
+        }
     }
 }
diff --git a/src/libraries/System.Runtime/tests/System/DoubleTests.netcoreapp.cs b/src/libraries/System.Runtime/tests/System/DoubleTests.netcoreapp.cs
deleted file mode 100644 (file)
index 056145b..0000000
+++ /dev/null
@@ -1,226 +0,0 @@
-// 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.Globalization;
-using Microsoft.DotNet.RemoteExecutor;
-using Xunit;
-
-#pragma warning disable xUnit1025 // reporting duplicate test cases due to not distinguishing 0.0 from -0.0, NaN from -NaN
-
-namespace System.Tests
-{
-    public partial class DoubleTests
-    {
-        [Theory]
-        [InlineData(double.NegativeInfinity, false)]    // Negative Infinity
-        [InlineData(double.MinValue, true)]             // Min Negative Normal
-        [InlineData(-2.2250738585072014E-308, true)]    // Max Negative Normal
-        [InlineData(-2.2250738585072009E-308, true)]    // Min Negative Subnormal
-        [InlineData(-4.94065645841247E-324, true)]      // Max Negative Subnormal
-        [InlineData(-0.0, true)]                        // Negative Zero
-        [InlineData(double.NaN, false)]                 // NaN
-        [InlineData(0.0, true)]                         // Positive Zero
-        [InlineData(4.94065645841247E-324, true)]       // Min Positive Subnormal
-        [InlineData(2.2250738585072009E-308, true)]     // Max Positive Subnormal
-        [InlineData(2.2250738585072014E-308, true)]     // Min Positive Normal
-        [InlineData(double.MaxValue, true)]             // Max Positive Normal
-        [InlineData(double.PositiveInfinity, false)]    // Positive Infinity
-        public static void IsFinite(double d, bool expected)
-        {
-            Assert.Equal(expected, double.IsFinite(d));
-        }
-
-        [Theory]
-        [InlineData(double.NegativeInfinity, true)]     // Negative Infinity
-        [InlineData(double.MinValue, true)]             // Min Negative Normal
-        [InlineData(-2.2250738585072014E-308, true)]    // Max Negative Normal
-        [InlineData(-2.2250738585072009E-308, true)]    // Min Negative Subnormal
-        [InlineData(-4.94065645841247E-324, true)]      // Max Negative Subnormal
-        [InlineData(-0.0, true)]                        // Negative Zero
-        [InlineData(double.NaN, true)]                  // NaN
-        [InlineData(0.0, false)]                        // Positive Zero
-        [InlineData(4.94065645841247E-324, false)]      // Min Positive Subnormal
-        [InlineData(2.2250738585072009E-308, false)]    // Max Positive Subnormal
-        [InlineData(2.2250738585072014E-308, false)]    // Min Positive Normal
-        [InlineData(double.MaxValue, false)]            // Max Positive Normal
-        [InlineData(double.PositiveInfinity, false)]    // Positive Infinity
-        public static void IsNegative(double d, bool expected)
-        {
-            Assert.Equal(expected, double.IsNegative(d));
-        }
-
-        [Theory]
-        [InlineData(double.NegativeInfinity, false)]    // Negative Infinity
-        [InlineData(double.MinValue, true)]             // Min Negative Normal
-        [InlineData(-2.2250738585072014E-308, true)]    // Max Negative Normal
-        [InlineData(-2.2250738585072009E-308, false)]   // Min Negative Subnormal
-        [InlineData(-4.94065645841247E-324, false)]     // Max Negative Subnormal
-        [InlineData(-0.0, false)]                       // Negative Zero
-        [InlineData(double.NaN, false)]                 // NaN
-        [InlineData(0.0, false)]                        // Positive Zero
-        [InlineData(4.94065645841247E-324, false)]      // Min Positive Subnormal
-        [InlineData(2.2250738585072009E-308, false)]    // Max Positive Subnormal
-        [InlineData(2.2250738585072014E-308, true)]     // Min Positive Normal
-        [InlineData(double.MaxValue, true)]             // Max Positive Normal
-        [InlineData(double.PositiveInfinity, false)]    // Positive Infinity
-        public static void IsNormal(double d, bool expected)
-        {
-            Assert.Equal(expected, double.IsNormal(d));
-        }
-
-        [Theory]
-        [InlineData(double.NegativeInfinity, false)]    // Negative Infinity
-        [InlineData(double.MinValue, false)]            // Min Negative Normal
-        [InlineData(-2.2250738585072014E-308, false)]   // Max Negative Normal
-        [InlineData(-2.2250738585072009E-308, true)]    // Min Negative Subnormal
-        [InlineData(-4.94065645841247E-324, true)]      // Max Negative Subnormal
-        [InlineData(-0.0, false)]                       // Negative Zero
-        [InlineData(double.NaN, false)]                 // NaN
-        [InlineData(0.0, false)]                        // Positive Zero
-        [InlineData(4.94065645841247E-324, true)]       // Min Positive Subnormal
-        [InlineData(2.2250738585072009E-308, true)]     // Max Positive Subnormal
-        [InlineData(2.2250738585072014E-308, false)]    // Min Positive Normal
-        [InlineData(double.MaxValue, false)]            // Max Positive Normal
-        [InlineData(double.PositiveInfinity, false)]    // Positive Infinity
-        public static void IsSubnormal(double d, bool expected)
-        {
-            Assert.Equal(expected, double.IsSubnormal(d));
-        }
-
-        public static IEnumerable<object[]> Parse_ValidWithOffsetCount_TestData()
-        {
-            foreach (object[] inputs in Parse_Valid_TestData())
-            {
-                yield return new object[] { inputs[0], 0, ((string)inputs[0]).Length, inputs[1], inputs[2], inputs[3] };
-            }
-
-            const NumberStyles DefaultStyle = NumberStyles.Float | NumberStyles.AllowThousands;
-            yield return new object[] { "-123", 0, 3, DefaultStyle, null, (double)-12 };
-            yield return new object[] { "-123", 1, 3, DefaultStyle, null, (double)123 };
-            yield return new object[] { "1E23", 0, 3, DefaultStyle, null, 1E2 };
-            yield return new object[] { "(123)", 1, 3, NumberStyles.AllowParentheses, new NumberFormatInfo() { NumberDecimalSeparator = "." }, 123 };
-            yield return new object[] { "-Infinity", 1, 8, NumberStyles.Any, NumberFormatInfo.InvariantInfo, double.PositiveInfinity };
-        }
-
-        [Theory]
-        [MemberData(nameof(Parse_ValidWithOffsetCount_TestData))]
-        public static void Parse_Span_Valid(string value, int offset, int count, NumberStyles style, IFormatProvider provider, double expected)
-        {
-            bool isDefaultProvider = provider == null || provider == NumberFormatInfo.CurrentInfo;
-            double result;
-            if ((style & ~(NumberStyles.Float | NumberStyles.AllowThousands)) == 0 && style != NumberStyles.None)
-            {
-                // Use Parse(string) or Parse(string, IFormatProvider)
-                if (isDefaultProvider)
-                {
-                    Assert.True(double.TryParse(value.AsSpan(offset, count), out result));
-                    Assert.Equal(expected, result);
-
-                    Assert.Equal(expected, double.Parse(value.AsSpan(offset, count)));
-                }
-
-                Assert.Equal(expected, double.Parse(value.AsSpan(offset, count), provider: provider));
-            }
-
-            Assert.Equal(expected, double.Parse(value.AsSpan(offset, count), style, provider));
-
-            Assert.True(double.TryParse(value.AsSpan(offset, count), style, provider, out result));
-            Assert.Equal(expected, result);
-        }
-
-        [Theory]
-        [MemberData(nameof(Parse_Invalid_TestData))]
-        public static void Parse_Span_Invalid(string value, NumberStyles style, IFormatProvider provider, Type exceptionType)
-        {
-            if (value != null)
-            {
-                Assert.Throws(exceptionType, () => double.Parse(value.AsSpan(), style, provider));
-
-                Assert.False(double.TryParse(value.AsSpan(), style, provider, out double result));
-                Assert.Equal(0, result);
-            }
-        }
-
-        [Fact]
-        public static void TryFormat()
-        {
-            using (new ThreadCultureChange(CultureInfo.InvariantCulture))
-            {
-                foreach (var testdata in ToString_TestData_NotNetFramework())
-                {
-                    double localI = (double)testdata[0];
-                    string localFormat = (string)testdata[1];
-                    IFormatProvider localProvider = (IFormatProvider)testdata[2];
-                    string localExpected = (string)testdata[3];
-
-                    try
-                    {
-                        char[] actual;
-                        int charsWritten;
-
-                        // Just right
-                        actual = new char[localExpected.Length];
-                        Assert.True(localI.TryFormat(actual.AsSpan(), out charsWritten, localFormat, localProvider));
-                        Assert.Equal(localExpected.Length, charsWritten);
-                        Assert.Equal(localExpected, new string(actual));
-
-                        // Longer than needed
-                        actual = new char[localExpected.Length + 1];
-                        Assert.True(localI.TryFormat(actual.AsSpan(), out charsWritten, localFormat, localProvider));
-                        Assert.Equal(localExpected.Length, charsWritten);
-                        Assert.Equal(localExpected, new string(actual, 0, charsWritten));
-
-                        // Too short
-                        if (localExpected.Length > 0)
-                        {
-                            actual = new char[localExpected.Length - 1];
-                            Assert.False(localI.TryFormat(actual.AsSpan(), out charsWritten, localFormat, localProvider));
-                            Assert.Equal(0, charsWritten);
-                        }
-                    }
-                    catch (Exception exc)
-                    {
-                        throw new Exception($"Failed on `{localI}`, `{localFormat}`, `{localProvider}`, `{localExpected}`. {exc}");
-                    }
-                }
-            }
-        }
-
-        public static IEnumerable<object[]> ToStringRoundtrip_TestData()
-        {
-            yield return new object[] { double.NegativeInfinity };
-            yield return new object[] { double.MinValue };
-            yield return new object[] { -Math.PI };
-            yield return new object[] { -Math.E };
-            yield return new object[] { -double.Epsilon };
-            yield return new object[] { -0.84551240822557006 };
-            yield return new object[] { -0.0 };
-            yield return new object[] { double.NaN };
-            yield return new object[] { 0.0 };
-            yield return new object[] { 0.84551240822557006 };
-            yield return new object[] { double.Epsilon };
-            yield return new object[] { Math.E };
-            yield return new object[] { Math.PI };
-            yield return new object[] { double.MaxValue };
-            yield return new object[] { double.PositiveInfinity };
-        }
-
-        [Theory]
-        [MemberData(nameof(ToStringRoundtrip_TestData))]
-        public static void ToStringRoundtrip(double value)
-        {
-            double result = double.Parse(value.ToString());
-            Assert.Equal(BitConverter.DoubleToInt64Bits(value), BitConverter.DoubleToInt64Bits(result));
-        }
-
-        [Theory]
-        [MemberData(nameof(ToStringRoundtrip_TestData))]
-        public static void ToStringRoundtrip_R(double value)
-        {
-            double result = double.Parse(value.ToString("R"));
-            Assert.Equal(BitConverter.DoubleToInt64Bits(value), BitConverter.DoubleToInt64Bits(result));
-        }
-    }
-}
index ca353e2..2d4d385 100644 (file)
@@ -5,11 +5,12 @@
 using System.Collections.Generic;
 using System.Linq;
 using System.Reflection;
+using System.Reflection.Emit;
 using Xunit;
 
 namespace System.Tests
 {
-    public partial class EnumTests
+    public class EnumTests
     {
         public static IEnumerable<object[]> Parse_TestData()
         {
@@ -130,12 +131,14 @@ namespace System.Tests
                 Assert.Equal(expected, result);
 
                 Assert.Equal(expected, Enum.Parse(expected.GetType(), value));
+                Assert.Equal(expected, Enum.Parse<T>(value));
             }
 
             Assert.True(Enum.TryParse(value, ignoreCase, out result));
             Assert.Equal(expected, result);
 
             Assert.Equal(expected, Enum.Parse(expected.GetType(), value, ignoreCase));
+            Assert.Equal(expected, Enum.Parse<T>(value, ignoreCase));
         }
 
         public static IEnumerable<object[]> Parse_Invalid_TestData()
@@ -226,19 +229,35 @@ namespace System.Tests
 
         private static void Parse_Generic_Invalid<T>(Type enumType, string value, bool ignoreCase, Type exceptionType) where T : struct
         {
-            T result;
+            object result = null;
             if (!ignoreCase)
             {
-                Assert.False(Enum.TryParse(value, out result));
-                Assert.Equal(default(T), result);
-
-                Assert.Throws(exceptionType, () => Enum.Parse(enumType, value));
+                if (enumType != null && enumType.IsEnum)
+                {
+                    Assert.False(Enum.TryParse(enumType, value, out result));
+                    Assert.Equal(default(object), result);
+
+                    Assert.Throws(exceptionType, () => Enum.Parse<T>(value));
+                }
+                else
+                {
+                    Assert.Throws(exceptionType, () => Enum.TryParse(enumType, value, out result));
+                    Assert.Equal(default(object), result);
+                }
             }
 
-            Assert.False(Enum.TryParse(value, ignoreCase, out result));
-            Assert.Equal(default(T), result);
+            if (enumType != null && enumType.IsEnum)
+            {
+                Assert.False(Enum.TryParse(enumType, value, ignoreCase, out result));
+                Assert.Equal(default(object), result);
 
-            Assert.Throws(exceptionType, () => Enum.Parse(enumType, value, ignoreCase));
+                Assert.Throws(exceptionType, () => Enum.Parse<T>(value, ignoreCase));
+            }
+            else
+            {
+                Assert.Throws(exceptionType, () => Enum.TryParse(enumType, value, ignoreCase, out result));
+                Assert.Equal(default(object), result);
+            }
         }
 
         public static IEnumerable<object[]> GetName_TestData()
@@ -1589,5 +1608,155 @@ namespace System.Tests
             Assert.Throws<FormatException>(() => Enum.Format(typeof(SimpleEnum), SimpleEnum.Red, "   \t")); // Format is whitespace
             Assert.Throws<FormatException>(() => Enum.Format(typeof(SimpleEnum), SimpleEnum.Red, "t")); // No such format
         }
+
+        public static IEnumerable<object[]> UnsupportedEnumType_TestData()
+        {
+#if NETCOREAPP
+            yield return new object[] { s_floatEnumType, 1.0f };
+            yield return new object[] { s_doubleEnumType, 1.0 };
+            yield return new object[] { s_intPtrEnumType, (IntPtr)1 };
+            yield return new object[] { s_uintPtrEnumType, (UIntPtr)1 };
+#else
+            return Array.Empty<object[]>();
+#endif
+        }
+
+        [Theory]
+        [MemberData(nameof(UnsupportedEnumType_TestData))]
+        public static void GetName_Unsupported_ThrowsArgumentException(Type enumType, object value)
+        {
+            AssertExtensions.Throws<ArgumentException>("value", () => Enum.GetName(enumType, value));
+        }
+
+        [Theory]
+        [MemberData(nameof(UnsupportedEnumType_TestData))]
+        public static void IsDefined_UnsupportedEnumType_ThrowsInvalidOperationException(Type enumType, object value)
+        {
+            Exception ex = Assert.ThrowsAny<Exception>(() => Enum.IsDefined(enumType, value));
+            string exName = ex.GetType().Name;
+            Assert.True(exName == nameof(InvalidOperationException) || exName == "ContractException");
+        }
+
+        public static IEnumerable<object[]> UnsupportedEnum_TestData()
+        {
+            yield return new object[] { Enum.ToObject(s_floatEnumType, 1) };
+            yield return new object[] { Enum.ToObject(s_doubleEnumType, 2) };
+            yield return new object[] { Enum.ToObject(s_intPtrEnumType, 1) };
+            yield return new object[] { Enum.ToObject(s_uintPtrEnumType, 2) };
+        }
+
+        [Theory]
+        [MemberData(nameof(UnsupportedEnum_TestData))]
+        public static void ToString_UnsupportedEnumType_ThrowsArgumentException(Enum e)
+        {
+            Exception formatXException = Assert.ThrowsAny<Exception>(() => e.ToString("X"));
+            string formatXExceptionName = formatXException.GetType().Name;
+            Assert.True(formatXExceptionName == nameof(InvalidOperationException) || formatXExceptionName == "ContractException");
+        }
+
+        [Theory]
+        [MemberData(nameof(UnsupportedEnumType_TestData))]
+        public static void Format_UnsupportedEnumType_ThrowsArgumentException(Type enumType, object value)
+        {
+            Exception formatGException = Assert.ThrowsAny<Exception>(() => Enum.Format(enumType, value, "G"));
+            string formatGExceptionName = formatGException.GetType().Name;
+            Assert.True(formatGExceptionName == nameof(InvalidOperationException) || formatGExceptionName == "ContractException");
+
+            Exception formatXException = Assert.ThrowsAny<Exception>(() => Enum.Format(enumType, value, "X"));
+            string formatXExceptionName = formatXException.GetType().Name;
+            Assert.True(formatXExceptionName == nameof(InvalidOperationException) || formatXExceptionName == "ContractException");
+
+            Exception formatFException = Assert.ThrowsAny<Exception>(() => Enum.Format(enumType, value, "F"));
+            string formatFExceptionName = formatFException.GetType().Name;
+            Assert.True(formatFExceptionName == nameof(InvalidOperationException) || formatFExceptionName == "ContractException");
+        }
+
+        private static EnumBuilder GetNonRuntimeEnumTypeBuilder(Type underlyingType)
+        {
+            AssemblyBuilder assembly = AssemblyBuilder.DefineDynamicAssembly(new AssemblyName("Name"), AssemblyBuilderAccess.Run);
+            ModuleBuilder module = assembly.DefineDynamicModule("Name");
+
+            return module.DefineEnum("TestName_" + underlyingType.Name, TypeAttributes.Public, underlyingType);
+        }
+
+        private static Type s_boolEnumType = GetBoolEnumType();
+        private static Type GetBoolEnumType()
+        {
+            EnumBuilder enumBuilder = GetNonRuntimeEnumTypeBuilder(typeof(bool));
+            enumBuilder.DefineLiteral("Value1", true);
+            enumBuilder.DefineLiteral("Value2", false);
+
+            return enumBuilder.CreateTypeInfo().AsType();
+        }
+
+        private static Type s_charEnumType = GetCharEnumType();
+        private static Type GetCharEnumType()
+        {
+            EnumBuilder enumBuilder = GetNonRuntimeEnumTypeBuilder(typeof(char));
+            enumBuilder.DefineLiteral("Value1", (char)1);
+            enumBuilder.DefineLiteral("Value2", (char)2);
+
+            enumBuilder.DefineLiteral("Value0x3f06", (char)0x3f06);
+            enumBuilder.DefineLiteral("Value0x3000", (char)0x3000);
+            enumBuilder.DefineLiteral("Value0x0f06", (char)0x0f06);
+            enumBuilder.DefineLiteral("Value0x1000", (char)0x1000);
+            enumBuilder.DefineLiteral("Value0x0000", (char)0x0000);
+            enumBuilder.DefineLiteral("Value0x0010", (char)0x0010);
+            enumBuilder.DefineLiteral("Value0x3f16", (char)0x3f16);
+
+            return enumBuilder.CreateTypeInfo().AsType();
+        }
+
+        private static Type s_floatEnumType = GetFloatEnumType();
+        private static Type GetFloatEnumType()
+        {
+            EnumBuilder enumBuilder = GetNonRuntimeEnumTypeBuilder(typeof(float));
+            enumBuilder.DefineLiteral("Value1", 1.0f);
+            enumBuilder.DefineLiteral("Value2", 2.0f);
+
+            enumBuilder.DefineLiteral("Value0x3f06", (float)0x3f06);
+            enumBuilder.DefineLiteral("Value0x3000", (float)0x3000);
+            enumBuilder.DefineLiteral("Value0x0f06", (float)0x0f06);
+            enumBuilder.DefineLiteral("Value0x1000", (float)0x1000);
+            enumBuilder.DefineLiteral("Value0x0000", (float)0x0000);
+            enumBuilder.DefineLiteral("Value0x0010", (float)0x0010);
+            enumBuilder.DefineLiteral("Value0x3f16", (float)0x3f16);
+
+            return enumBuilder.CreateTypeInfo().AsType();
+        }
+
+        private static Type s_doubleEnumType = GetDoubleEnumType();
+        private static Type GetDoubleEnumType()
+        {
+            EnumBuilder enumBuilder = GetNonRuntimeEnumTypeBuilder(typeof(double));
+            enumBuilder.DefineLiteral("Value1", 1.0);
+            enumBuilder.DefineLiteral("Value2", 2.0);
+
+            enumBuilder.DefineLiteral("Value0x3f06", (double)0x3f06);
+            enumBuilder.DefineLiteral("Value0x3000", (double)0x3000);
+            enumBuilder.DefineLiteral("Value0x0f06", (double)0x0f06);
+            enumBuilder.DefineLiteral("Value0x1000", (double)0x1000);
+            enumBuilder.DefineLiteral("Value0x0000", (double)0x0000);
+            enumBuilder.DefineLiteral("Value0x0010", (double)0x0010);
+            enumBuilder.DefineLiteral("Value0x3f16", (double)0x3f16);
+
+            return enumBuilder.CreateTypeInfo().AsType();
+        }
+
+        private static Type s_intPtrEnumType = GetIntPtrEnumType();
+        private static Type GetIntPtrEnumType()
+        {
+            EnumBuilder enumBuilder = GetNonRuntimeEnumTypeBuilder(typeof(IntPtr));
+
+            return enumBuilder.CreateTypeInfo().AsType();
+        }
+
+        private static Type s_uintPtrEnumType = GetUIntPtrEnumType();
+        private static Type GetUIntPtrEnumType()
+        {
+            EnumBuilder enumBuilder = GetNonRuntimeEnumTypeBuilder(typeof(UIntPtr));
+
+            return enumBuilder.CreateTypeInfo().AsType();
+        }
     }
 }
diff --git a/src/libraries/System.Runtime/tests/System/EnumTests.netcoreapp.cs b/src/libraries/System.Runtime/tests/System/EnumTests.netcoreapp.cs
deleted file mode 100644 (file)
index 51fd0f5..0000000
+++ /dev/null
@@ -1,229 +0,0 @@
-// 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.Reflection;
-using System.Reflection.Emit;
-using Xunit;
-
-namespace System.Tests
-{
-    public partial class EnumTests
-    {
-        [Theory]
-        [MemberData(nameof(Parse_TestData))]
-        public static void Parse_NetCoreApp11<T>(string value, bool ignoreCase, T expected) where T : struct
-        {
-            object result;
-            if (!ignoreCase)
-            {
-                Assert.True(Enum.TryParse(expected.GetType(), value, out result));
-                Assert.Equal(expected, result);
-
-                Assert.Equal(expected, Enum.Parse<T>(value));
-            }
-
-            Assert.True(Enum.TryParse(expected.GetType(), value, ignoreCase, out result));
-            Assert.Equal(expected, result);
-
-            Assert.Equal(expected, Enum.Parse<T>(value, ignoreCase));
-        }
-
-        [Theory]
-        [MemberData(nameof(Parse_Invalid_TestData))]
-        public static void Parse_Invalid_NetCoreApp11(Type enumType, string value, bool ignoreCase, Type exceptionType)
-        {
-            Type typeArgument = enumType == null || !enumType.IsValueType ? typeof(SimpleEnum) : enumType;
-            MethodInfo parseMethod = typeof(EnumTests).GetTypeInfo().GetMethod(nameof(Parse_Generic_Invalid_NetCoreApp11), BindingFlags.Static | BindingFlags.NonPublic).MakeGenericMethod(typeArgument);
-            parseMethod.Invoke(null, new object[] { enumType, value, ignoreCase, exceptionType });
-        }
-
-        private static void Parse_Generic_Invalid_NetCoreApp11<T>(Type enumType, string value, bool ignoreCase, Type exceptionType) where T : struct
-        {
-            object result = null;
-            if (!ignoreCase)
-            {
-                if (enumType != null && enumType.IsEnum)
-                {
-                    Assert.False(Enum.TryParse(enumType, value, out result));
-                    Assert.Equal(default(object), result);
-
-                    Assert.Throws(exceptionType, () => Enum.Parse<T>(value));
-                }
-                else
-                {
-                    Assert.Throws(exceptionType, () => Enum.TryParse(enumType, value, out result));
-                    Assert.Equal(default(object), result);
-                }
-            }
-
-            if (enumType != null && enumType.IsEnum)
-            {
-                Assert.False(Enum.TryParse(enumType, value, ignoreCase, out result));
-                Assert.Equal(default(object), result);
-
-                Assert.Throws(exceptionType, () => Enum.Parse<T>(value, ignoreCase));
-            }
-            else
-            {
-                Assert.Throws(exceptionType, () => Enum.TryParse(enumType, value, ignoreCase, out result));
-                Assert.Equal(default(object), result);
-            }
-        }
-
-        public static IEnumerable<object[]> UnsupportedEnumType_TestData()
-        {
-#if NETCOREAPP
-            yield return new object[] { s_floatEnumType, 1.0f };
-            yield return new object[] { s_doubleEnumType, 1.0 };
-            yield return new object[] { s_intPtrEnumType, (IntPtr)1 };
-            yield return new object[] { s_uintPtrEnumType, (UIntPtr)1 };
-#else
-            return Array.Empty<object[]>();
-#endif
-        }
-
-        [Theory]
-        [MemberData(nameof(UnsupportedEnumType_TestData))]
-        public static void GetName_Unsupported_ThrowsArgumentException(Type enumType, object value)
-        {
-            AssertExtensions.Throws<ArgumentException>("value", () => Enum.GetName(enumType, value));
-        }
-
-        [Theory]
-        [MemberData(nameof(UnsupportedEnumType_TestData))]
-        public static void IsDefined_UnsupportedEnumType_ThrowsInvalidOperationException(Type enumType, object value)
-        {
-            Exception ex = Assert.ThrowsAny<Exception>(() => Enum.IsDefined(enumType, value));
-            string exName = ex.GetType().Name;
-            Assert.True(exName == nameof(InvalidOperationException) || exName == "ContractException");
-        }
-
-        public static IEnumerable<object[]> UnsupportedEnum_TestData()
-        {
-#if NETCOREAPP
-            yield return new object[] { Enum.ToObject(s_floatEnumType, 1) };
-            yield return new object[] { Enum.ToObject(s_doubleEnumType, 2) };
-            yield return new object[] { Enum.ToObject(s_intPtrEnumType, 1) };
-            yield return new object[] { Enum.ToObject(s_uintPtrEnumType, 2) };
-#else
-            return Array.Empty<object[]>();
-#endif
-        }
-
-        [Theory]
-        [MemberData(nameof(UnsupportedEnum_TestData))]
-        public static void ToString_UnsupportedEnumType_ThrowsArgumentException(Enum e)
-        {
-            Exception formatXException = Assert.ThrowsAny<Exception>(() => e.ToString("X"));
-            string formatXExceptionName = formatXException.GetType().Name;
-            Assert.True(formatXExceptionName == nameof(InvalidOperationException) || formatXExceptionName == "ContractException");
-        }
-
-        [Theory]
-        [MemberData(nameof(UnsupportedEnumType_TestData))]
-        public static void Format_UnsupportedEnumType_ThrowsArgumentException(Type enumType, object value)
-        {
-            Exception formatGException = Assert.ThrowsAny<Exception>(() => Enum.Format(enumType, value, "G"));
-            string formatGExceptionName = formatGException.GetType().Name;
-            Assert.True(formatGExceptionName == nameof(InvalidOperationException) || formatGExceptionName == "ContractException");
-
-            Exception formatXException = Assert.ThrowsAny<Exception>(() => Enum.Format(enumType, value, "X"));
-            string formatXExceptionName = formatXException.GetType().Name;
-            Assert.True(formatXExceptionName == nameof(InvalidOperationException) || formatXExceptionName == "ContractException");
-
-            Exception formatFException = Assert.ThrowsAny<Exception>(() => Enum.Format(enumType, value, "F"));
-            string formatFExceptionName = formatFException.GetType().Name;
-            Assert.True(formatFExceptionName == nameof(InvalidOperationException) || formatFExceptionName == "ContractException");
-        }
-
-        private static EnumBuilder GetNonRuntimeEnumTypeBuilder(Type underlyingType)
-        {
-            AssemblyBuilder assembly = AssemblyBuilder.DefineDynamicAssembly(new AssemblyName("Name"), AssemblyBuilderAccess.Run);
-            ModuleBuilder module = assembly.DefineDynamicModule("Name");
-
-            return module.DefineEnum("TestName_" + underlyingType.Name, TypeAttributes.Public, underlyingType);
-        }
-
-        private static Type s_boolEnumType = GetBoolEnumType();
-        private static Type GetBoolEnumType()
-        {
-            EnumBuilder enumBuilder = GetNonRuntimeEnumTypeBuilder(typeof(bool));
-            enumBuilder.DefineLiteral("Value1", true);
-            enumBuilder.DefineLiteral("Value2", false);
-
-            return enumBuilder.CreateTypeInfo().AsType();
-        }
-
-        private static Type s_charEnumType = GetCharEnumType();
-        private static Type GetCharEnumType()
-        {
-            EnumBuilder enumBuilder = GetNonRuntimeEnumTypeBuilder(typeof(char));
-            enumBuilder.DefineLiteral("Value1", (char)1);
-            enumBuilder.DefineLiteral("Value2", (char)2);
-
-            enumBuilder.DefineLiteral("Value0x3f06", (char)0x3f06);
-            enumBuilder.DefineLiteral("Value0x3000", (char)0x3000);
-            enumBuilder.DefineLiteral("Value0x0f06", (char)0x0f06);
-            enumBuilder.DefineLiteral("Value0x1000", (char)0x1000);
-            enumBuilder.DefineLiteral("Value0x0000", (char)0x0000);
-            enumBuilder.DefineLiteral("Value0x0010", (char)0x0010);
-            enumBuilder.DefineLiteral("Value0x3f16", (char)0x3f16);
-
-            return enumBuilder.CreateTypeInfo().AsType();
-        }
-
-        private static Type s_floatEnumType = GetFloatEnumType();
-        private static Type GetFloatEnumType()
-        {
-            EnumBuilder enumBuilder = GetNonRuntimeEnumTypeBuilder(typeof(float));
-            enumBuilder.DefineLiteral("Value1", 1.0f);
-            enumBuilder.DefineLiteral("Value2", 2.0f);
-
-            enumBuilder.DefineLiteral("Value0x3f06", (float)0x3f06);
-            enumBuilder.DefineLiteral("Value0x3000", (float)0x3000);
-            enumBuilder.DefineLiteral("Value0x0f06", (float)0x0f06);
-            enumBuilder.DefineLiteral("Value0x1000", (float)0x1000);
-            enumBuilder.DefineLiteral("Value0x0000", (float)0x0000);
-            enumBuilder.DefineLiteral("Value0x0010", (float)0x0010);
-            enumBuilder.DefineLiteral("Value0x3f16", (float)0x3f16);
-
-            return enumBuilder.CreateTypeInfo().AsType();
-        }
-
-        private static Type s_doubleEnumType = GetDoubleEnumType();
-        private static Type GetDoubleEnumType()
-        {
-            EnumBuilder enumBuilder = GetNonRuntimeEnumTypeBuilder(typeof(double));
-            enumBuilder.DefineLiteral("Value1", 1.0);
-            enumBuilder.DefineLiteral("Value2", 2.0);
-
-            enumBuilder.DefineLiteral("Value0x3f06", (double)0x3f06);
-            enumBuilder.DefineLiteral("Value0x3000", (double)0x3000);
-            enumBuilder.DefineLiteral("Value0x0f06", (double)0x0f06);
-            enumBuilder.DefineLiteral("Value0x1000", (double)0x1000);
-            enumBuilder.DefineLiteral("Value0x0000", (double)0x0000);
-            enumBuilder.DefineLiteral("Value0x0010", (double)0x0010);
-            enumBuilder.DefineLiteral("Value0x3f16", (double)0x3f16);
-
-            return enumBuilder.CreateTypeInfo().AsType();
-        }
-
-        private static Type s_intPtrEnumType = GetIntPtrEnumType();
-        private static Type GetIntPtrEnumType()
-        {
-            EnumBuilder enumBuilder = GetNonRuntimeEnumTypeBuilder(typeof(IntPtr));
-
-            return enumBuilder.CreateTypeInfo().AsType();
-        }
-
-        private static Type s_uintPtrEnumType = GetUIntPtrEnumType();
-        private static Type GetUIntPtrEnumType()
-        {
-            EnumBuilder enumBuilder = GetNonRuntimeEnumTypeBuilder(typeof(UIntPtr));
-
-            return enumBuilder.CreateTypeInfo().AsType();
-        }
-    }
-}
index d8c1a49..8faa9ec 100644 (file)
@@ -9,7 +9,7 @@ using Xunit;
 
 namespace System.Tests
 {
-    public partial class FormattableStringTests
+    public class FormattableStringTests
     {
         [Fact]
         public static void Invariant_Null_ThrowsArgumentNullException()
@@ -50,5 +50,32 @@ namespace System.Tests
             }
         }
 
+        [Fact]
+        public static void CurrentCulture_ImplicityAndExplicitMethodsReturnSameString()
+        {
+            double d = 123.456;
+            string text1 = $"This will be formatted using current culture {d}";
+            string text2 = FormattableString.CurrentCulture($"This will be formatted using current culture {d}");
+            Assert.Equal(text1, text2);
+        }
+
+        [Fact]
+        public static void CurrentCulture_Null_ThrowsArgumentNullException()
+        {
+            AssertExtensions.Throws<ArgumentNullException>("formattable", () => FormattableString.CurrentCulture(null));
+        }
+
+        [Fact]
+        public static void CurrentCulture_DutchCulture_FormatsDoubleBasedOnCurrentCulture()
+        {
+            var dutchCulture = new CultureInfo("nl");
+            using (new ThreadCultureChange(dutchCulture))
+            {
+                double d = 123.456;
+                string expected = string.Format(dutchCulture, "Dutch decimal separator is comma {0}", d);
+                string actual = FormattableString.CurrentCulture($"Dutch decimal separator is comma {d}");
+                Assert.Equal(expected, actual);
+            }
+        }
     }
 }
diff --git a/src/libraries/System.Runtime/tests/System/FormattableStringTests.netcoreapp.cs b/src/libraries/System.Runtime/tests/System/FormattableStringTests.netcoreapp.cs
deleted file mode 100644 (file)
index f87b454..0000000
+++ /dev/null
@@ -1,42 +0,0 @@
-// 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.Diagnostics;
-using System.Globalization;
-using Microsoft.DotNet.RemoteExecutor;
-using Xunit;
-
-namespace System.Tests
-{
-    public partial class FormattableStringTests
-    {
-        [Fact]
-        public static void CurrentCulture_ImplicityAndExplicitMethodsReturnSameString()
-        {
-            double d = 123.456;
-            string text1 = $"This will be formatted using current culture {d}";
-            string text2 = FormattableString.CurrentCulture($"This will be formatted using current culture {d}");
-            Assert.Equal(text1, text2);
-        }
-
-        [Fact]
-        public static void CurrentCulture_Null_ThrowsArgumentNullException()
-        {
-            AssertExtensions.Throws<ArgumentNullException>("formattable", () => FormattableString.CurrentCulture(null));
-        }
-
-        [Fact]
-        public static void CurrentCulture_DutchCulture_FormatsDoubleBasedOnCurrentCulture()
-        {
-            var dutchCulture = new CultureInfo("nl");
-            using (new ThreadCultureChange(dutchCulture))
-            {
-                double d = 123.456;
-                string expected = string.Format(dutchCulture, "Dutch decimal separator is comma {0}", d);
-                string actual = FormattableString.CurrentCulture($"Dutch decimal separator is comma {d}");
-                Assert.Equal(expected, actual);
-            }
-        }
-    }
-}
index 6ae1d76..e501284 100644 (file)
@@ -2,7 +2,9 @@
 // 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;
 using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
 using System.Diagnostics;
 using System.Threading;
 using System.Runtime;
@@ -11,7 +13,7 @@ using Xunit;
 
 namespace System.Tests
 {
-    public static partial class GCTests
+    public static class GCTests
     {
         private static bool s_is32Bits = IntPtr.Size == 4; // Skip IntPtr tests on 32-bit platforms
 
@@ -762,5 +764,130 @@ namespace System.Tests
             Thread.Sleep(500);
             GC.CancelFullGCNotification();
         }
+
+        [Theory]
+        [InlineData(1000)]
+        [InlineData(100000)]
+        public static void GetAllocatedBytesForCurrentThread(int size)
+        {
+            long start = GC.GetAllocatedBytesForCurrentThread();
+
+            GC.KeepAlive(new string('a', size));
+
+            long end = GC.GetAllocatedBytesForCurrentThread();
+
+            Assert.True((end - start) > size, $"Allocated too little: start: {start} end: {end} size: {size}");
+            Assert.True((end - start) < 5 * size, $"Allocated too much: start: {start} end: {end} size: {size}");
+        }
+
+        [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotArmProcess))] // [ActiveIssue(37378)]
+        public static void GetGCMemoryInfo()
+        {
+            RemoteExecutor.Invoke(() =>
+            {
+                // Allows to update the value returned by GC.GetGCMemoryInfo
+                GC.Collect();
+
+                GCMemoryInfo memoryInfo1 = GC.GetGCMemoryInfo();
+
+                Assert.InRange(memoryInfo1.HighMemoryLoadThresholdBytes, 1, long.MaxValue);
+                Assert.InRange(memoryInfo1.MemoryLoadBytes, 1, long.MaxValue);
+                Assert.InRange(memoryInfo1.TotalAvailableMemoryBytes, 1, long.MaxValue);
+                Assert.InRange(memoryInfo1.HeapSizeBytes, 1, long.MaxValue);
+                Assert.InRange(memoryInfo1.FragmentedBytes, 0, long.MaxValue);
+
+                GCHandle[] gch = new GCHandle[64 * 1024];
+                for (int i = 0; i < gch.Length * 2; ++i)
+                {
+                    byte[] arr = new byte[64];
+                    if (i % 2 == 0)
+                    {
+                        gch[i / 2] = GCHandle.Alloc(arr, GCHandleType.Pinned);
+                    }
+                }
+
+                // Allows to update the value returned by GC.GetGCMemoryInfo
+                GC.Collect();
+
+                GCMemoryInfo memoryInfo2 = GC.GetGCMemoryInfo();
+
+                string scenario = null;
+                try
+                {
+                    scenario = nameof(memoryInfo2.HighMemoryLoadThresholdBytes);
+                    Assert.Equal(memoryInfo2.HighMemoryLoadThresholdBytes, memoryInfo1.HighMemoryLoadThresholdBytes);
+
+                    // Even though we have allocated, the overall load may decrease or increase depending what other processes are doing.
+                    // It cannot go above total available though.
+                    scenario = nameof(memoryInfo2.MemoryLoadBytes);
+                    Assert.InRange(memoryInfo2.MemoryLoadBytes, 1, memoryInfo1.TotalAvailableMemoryBytes);
+
+                    scenario = nameof(memoryInfo2.TotalAvailableMemoryBytes);
+                    Assert.Equal(memoryInfo2.TotalAvailableMemoryBytes, memoryInfo1.TotalAvailableMemoryBytes);
+
+                    scenario = nameof(memoryInfo2.HeapSizeBytes);
+                    Assert.InRange(memoryInfo2.HeapSizeBytes, memoryInfo1.HeapSizeBytes + 1, long.MaxValue);
+
+                    scenario = nameof(memoryInfo2.FragmentedBytes);
+                    Assert.InRange(memoryInfo2.FragmentedBytes, memoryInfo1.FragmentedBytes + 1, long.MaxValue);
+
+                    scenario = null;
+                }
+                finally
+                {
+                    if (scenario != null)
+                    {
+                        System.Console.WriteLine("FAILED: " + scenario);
+                    }
+                }
+            }).Dispose();
+        }
+
+        [Fact]
+        public static void GetTotalAllocatedBytes()
+        {
+            byte[] stash;
+
+            long CallGetTotalAllocatedBytesAndCheck(long previous, out long differenceBetweenPreciseAndImprecise)
+            {
+                long precise = GC.GetTotalAllocatedBytes(true);
+                long imprecise = GC.GetTotalAllocatedBytes(false);
+
+                if (precise <= 0)
+                {
+                    throw new Exception($"Bytes allocated is not positive, this is unlikely. precise = {precise}");
+                }
+
+                if (imprecise < precise)
+                {
+                    throw new Exception($"Imprecise total bytes allocated less than precise, imprecise is required to be a conservative estimate (that estimates high). imprecise = {imprecise}, precise = {precise}");
+                }
+
+                if (previous > precise)
+                {
+                    throw new Exception($"Expected more memory to be allocated. previous = {previous}, precise = {precise}, difference = {previous - precise}");
+                }
+
+                differenceBetweenPreciseAndImprecise = imprecise - precise;
+                return precise;
+            }
+
+            long CallGetTotalAllocatedBytes(long previous)
+            {
+                long differenceBetweenPreciseAndImprecise;
+                previous = CallGetTotalAllocatedBytesAndCheck(previous, out differenceBetweenPreciseAndImprecise);
+                stash = new byte[differenceBetweenPreciseAndImprecise];
+                previous = CallGetTotalAllocatedBytesAndCheck(previous, out differenceBetweenPreciseAndImprecise);
+                return previous;
+            }
+
+            long previous = 0;
+
+            for (int i = 0; i < 1000; ++i)
+            {
+                stash = new byte[1234];
+                previous = CallGetTotalAllocatedBytes(previous);
+            }
+        }
     }
 }
diff --git a/src/libraries/System.Runtime/tests/System/GCTests.netcoreapp.cs b/src/libraries/System.Runtime/tests/System/GCTests.netcoreapp.cs
deleted file mode 100644 (file)
index f2bd13a..0000000
+++ /dev/null
@@ -1,139 +0,0 @@
-// 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;
-using System.Runtime.InteropServices;
-using Microsoft.DotNet.RemoteExecutor;
-using Xunit;
-
-namespace System.Tests
-{
-    public static partial class GCTests
-    {
-        [Theory]
-        [InlineData(1000)]
-        [InlineData(100000)]
-        public static void GetAllocatedBytesForCurrentThread(int size)
-        {
-            long start = GC.GetAllocatedBytesForCurrentThread();
-
-            GC.KeepAlive(new string('a', size));
-
-            long end = GC.GetAllocatedBytesForCurrentThread();
-
-            Assert.True((end - start) > size, $"Allocated too little: start: {start} end: {end} size: {size}");
-            Assert.True((end - start) < 5 * size, $"Allocated too much: start: {start} end: {end} size: {size}");
-        }
-
-        [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotArmProcess))] // [ActiveIssue(37378)]
-        public static void GetGCMemoryInfo()
-        {
-            RemoteExecutor.Invoke(() =>
-            {
-                // Allows to update the value returned by GC.GetGCMemoryInfo
-                GC.Collect();
-
-                GCMemoryInfo memoryInfo1 = GC.GetGCMemoryInfo();
-
-                Assert.InRange(memoryInfo1.HighMemoryLoadThresholdBytes, 1, long.MaxValue);
-                Assert.InRange(memoryInfo1.MemoryLoadBytes, 1, long.MaxValue);
-                Assert.InRange(memoryInfo1.TotalAvailableMemoryBytes, 1, long.MaxValue);
-                Assert.InRange(memoryInfo1.HeapSizeBytes, 1, long.MaxValue);
-                Assert.InRange(memoryInfo1.FragmentedBytes, 0, long.MaxValue);
-
-                GCHandle[] gch = new GCHandle[64 * 1024];
-                for (int i = 0; i < gch.Length * 2; ++i)
-                {
-                    byte[] arr = new byte[64];
-                    if (i % 2 == 0)
-                    {
-                        gch[i / 2] = GCHandle.Alloc(arr, GCHandleType.Pinned);
-                    }
-                }
-
-                // Allows to update the value returned by GC.GetGCMemoryInfo
-                GC.Collect();
-
-                GCMemoryInfo memoryInfo2 = GC.GetGCMemoryInfo();
-
-                string scenario = null;
-                try
-                {
-                    scenario = nameof(memoryInfo2.HighMemoryLoadThresholdBytes);
-                    Assert.Equal(memoryInfo2.HighMemoryLoadThresholdBytes, memoryInfo1.HighMemoryLoadThresholdBytes);
-
-                    // Even though we have allocated, the overall load may decrease or increase depending what other processes are doing.
-                    // It cannot go above total available though.
-                    scenario = nameof(memoryInfo2.MemoryLoadBytes);
-                    Assert.InRange(memoryInfo2.MemoryLoadBytes, 1, memoryInfo1.TotalAvailableMemoryBytes);
-
-                    scenario = nameof(memoryInfo2.TotalAvailableMemoryBytes);
-                    Assert.Equal(memoryInfo2.TotalAvailableMemoryBytes, memoryInfo1.TotalAvailableMemoryBytes);
-
-                    scenario = nameof(memoryInfo2.HeapSizeBytes);
-                    Assert.InRange(memoryInfo2.HeapSizeBytes, memoryInfo1.HeapSizeBytes + 1, long.MaxValue);
-
-                    scenario = nameof(memoryInfo2.FragmentedBytes);
-                    Assert.InRange(memoryInfo2.FragmentedBytes, memoryInfo1.FragmentedBytes + 1, long.MaxValue);
-
-                    scenario = null;
-                }
-                finally
-                {
-                    if (scenario != null)
-                    {
-                        System.Console.WriteLine("FAILED: " + scenario);
-                    }
-                }
-            }).Dispose();
-        }
-
-        [Fact]
-        public static void GetTotalAllocatedBytes()
-        {
-            byte[] stash;
-
-            long CallGetTotalAllocatedBytesAndCheck(long previous, out long differenceBetweenPreciseAndImprecise)
-            {
-                long precise = GC.GetTotalAllocatedBytes(true);
-                long imprecise = GC.GetTotalAllocatedBytes(false);
-
-                if (precise <= 0)
-                {
-                    throw new Exception($"Bytes allocated is not positive, this is unlikely. precise = {precise}");
-                }
-
-                if (imprecise < precise)
-                {
-                    throw new Exception($"Imprecise total bytes allocated less than precise, imprecise is required to be a conservative estimate (that estimates high). imprecise = {imprecise}, precise = {precise}");
-                }
-
-                if (previous > precise)
-                {
-                    throw new Exception($"Expected more memory to be allocated. previous = {previous}, precise = {precise}, difference = {previous - precise}");
-                }
-
-                differenceBetweenPreciseAndImprecise = imprecise - precise;
-                return precise;
-            }
-
-            long CallGetTotalAllocatedBytes(long previous)
-            {
-                long differenceBetweenPreciseAndImprecise;
-                previous = CallGetTotalAllocatedBytesAndCheck(previous, out differenceBetweenPreciseAndImprecise);
-                stash = new byte[differenceBetweenPreciseAndImprecise];
-                previous = CallGetTotalAllocatedBytesAndCheck(previous, out differenceBetweenPreciseAndImprecise);
-                return previous;
-            }
-
-            long previous = 0;
-
-            for (int i = 0; i < 1000; ++i)
-            {
-                stash = new byte[1234];
-                previous = CallGetTotalAllocatedBytes(previous);
-            }
-        }
-    }
-}
index ac04a5a..1cd179b 100644 (file)
@@ -9,7 +9,7 @@ using Xunit;
 
 namespace System.Tests
 {
-    public static partial class GuidTests
+    public static class GuidTests
     {
         private static readonly Guid s_testGuid = new Guid("a8a110d5-fc49-43c5-bf46-802db8f843ff");
         private static readonly Guid s_fullGuid = new Guid(uint.MaxValue, ushort.MaxValue, ushort.MaxValue, byte.MaxValue, byte.MaxValue, byte.MaxValue, byte.MaxValue, byte.MaxValue, byte.MaxValue, byte.MaxValue, byte.MaxValue);
@@ -761,5 +761,120 @@ namespace System.Tests
         {
             Assert.Equal(expected, Math.Sign(guid.CompareTo(obj)));
         }
+
+        [Theory]
+        [MemberData(nameof(Ctor_ByteArray_TestData))]
+        public static void Ctor_ReadOnlySpan(byte[] b, Guid expected)
+        {
+            Assert.Equal(expected, new Guid(new ReadOnlySpan<byte>(b)));
+        }
+
+        [Theory]
+        [InlineData(15)]
+        [InlineData(17)]
+        public static void CtorSpan_InvalidLengthByteArray_ThrowsArgumentException(int length)
+        {
+            AssertExtensions.Throws<ArgumentException>("b", null, () => new Guid(new ReadOnlySpan<byte>(new byte[length])));
+        }
+
+        [Theory]
+        [MemberData(nameof(Ctor_ByteArray_TestData))]
+        public static void TryWriteBytes_ValidLength_ReturnsTrue(byte[] b, Guid guid)
+        {
+            var bytes = new byte[16];
+            Assert.True(guid.TryWriteBytes(new Span<byte>(bytes)));
+            Assert.Equal(b, bytes);
+        }
+
+        [Theory]
+        [InlineData(0)]
+        [InlineData(15)]
+        public static void TryWriteBytes_LengthTooShort_ReturnsFalse(int length)
+        {
+            Assert.False(s_testGuid.TryWriteBytes(new Span<byte>(new byte[length])));
+        }
+
+        [Theory]
+        [MemberData(nameof(InvalidFormat_TestData))]
+        public static void TryFormat_InvalidFormat_ThrowsFormatException(string format)
+        {
+            Assert.Throws<FormatException>(() => s_testGuid.TryFormat(new Span<char>(), out int charsWritten, format));
+            Assert.Throws<FormatException>(() => s_testGuid.TryFormat(new Span<char>(), out int charsWritten, format.ToUpperInvariant()));
+        }
+
+        [Theory]
+        [MemberData(nameof(ToString_TestData))]
+        public static void TryFormat_LengthTooSmall_ReturnsFalse(Guid guid, string format, string expected)
+        {
+            _ = expected;
+            Assert.False(guid.TryFormat(new Span<char>(new char[guid.ToString(format).Length - 1]), out int charsWritten, format));
+            Assert.Equal(0, charsWritten);
+        }
+
+        [Theory]
+        [MemberData(nameof(ToString_TestData))]
+        public static void TryFormat_CharsWritten_EqualsZero_WhenSpanTooSmall(Guid guid, string format, string expected)
+        {
+            _ = expected;
+            Assert.False(guid.TryFormat(new Span<char>(new char[guid.ToString(format).Length - 1]), out int charsWritten, format));
+            Assert.Equal(0, charsWritten);
+        }
+
+        [Theory]
+        [MemberData(nameof(ToString_TestData))]
+        public static void TryFormat_ValidLength_ReturnsTrue(Guid guid, string format, string expected)
+        {
+            char[] chars = new char[guid.ToString(format).Length];
+            Assert.True(guid.TryFormat(new Span<char>(chars), out int charsWritten, format));
+            Assert.Equal(chars, expected.ToCharArray());
+        }
+
+        [Theory]
+        [MemberData(nameof(GuidStrings_Valid_TestData))]
+        public static void Parse_Span_ValidInput_Success(string input, string format, Guid expected)
+        {
+            Assert.Equal(expected, Guid.Parse(input.AsSpan()));
+            Assert.Equal(expected, Guid.ParseExact(input.AsSpan(), format.ToUpperInvariant()));
+            Assert.Equal(expected, Guid.ParseExact(input.AsSpan(), format.ToLowerInvariant())); // Format should be case insensitive
+
+            Guid result;
+
+            Assert.True(Guid.TryParse(input.AsSpan(), out result));
+            Assert.Equal(expected, result);
+
+            Assert.True(Guid.TryParseExact(input.AsSpan(), format.ToUpperInvariant(), out result));
+            Assert.Equal(expected, result);
+
+            Assert.True(Guid.TryParseExact(input.AsSpan(), format.ToLowerInvariant(), out result)); // Format should be case insensitive
+            Assert.Equal(expected, result);
+        }
+
+        [Theory]
+        [MemberData(nameof(GuidStrings_Invalid_TestData))]
+        public static void Parse_Span_InvalidInput_Fails(string input, Type exceptionType)
+        {
+            if (input == null)
+            {
+                return;
+            }
+
+            // Overflow exceptions throw as format exceptions in Parse
+            if (exceptionType.Equals(typeof(OverflowException)))
+            {
+                exceptionType = typeof(FormatException);
+            }
+            Assert.Throws(exceptionType, () => Guid.Parse(input.AsSpan()));
+
+            Assert.False(Guid.TryParse(input.AsSpan(), out Guid result));
+            Assert.Equal(Guid.Empty, result);
+
+            foreach (string format in new[] { "N", "D", "B", "P", "X" })
+            {
+                Assert.Throws(exceptionType, () => Guid.ParseExact(input.AsSpan(), format));
+
+                Assert.False(Guid.TryParseExact(input.AsSpan(), format, out result));
+                Assert.Equal(Guid.Empty, result);
+            }
+        }
     }
 }
diff --git a/src/libraries/System.Runtime/tests/System/GuidTests.netcoreapp.cs b/src/libraries/System.Runtime/tests/System/GuidTests.netcoreapp.cs
deleted file mode 100644 (file)
index 83faf85..0000000
+++ /dev/null
@@ -1,126 +0,0 @@
-// 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 Xunit;
-
-namespace System.Tests
-{
-    public static partial class GuidTests
-    {
-        [Theory]
-        [MemberData(nameof(Ctor_ByteArray_TestData))]
-        public static void Ctor_ReadOnlySpan(byte[] b, Guid expected)
-        {
-            Assert.Equal(expected, new Guid(new ReadOnlySpan<byte>(b)));
-        }
-
-        [Theory]
-        [InlineData(15)]
-        [InlineData(17)]
-        public static void CtorSpan_InvalidLengthByteArray_ThrowsArgumentException(int length)
-        {
-            AssertExtensions.Throws<ArgumentException>("b", null, () => new Guid(new ReadOnlySpan<byte>(new byte[length])));
-        }
-
-        [Theory]
-        [MemberData(nameof(Ctor_ByteArray_TestData))]
-        public static void TryWriteBytes_ValidLength_ReturnsTrue(byte[] b, Guid guid)
-        {
-            var bytes = new byte[16];
-            Assert.True(guid.TryWriteBytes(new Span<byte>(bytes)));
-            Assert.Equal(b, bytes);
-        }
-
-        [Theory]
-        [InlineData(0)]
-        [InlineData(15)]
-        public static void TryWriteBytes_LengthTooShort_ReturnsFalse(int length)
-        {
-            Assert.False(s_testGuid.TryWriteBytes(new Span<byte>(new byte[length])));
-        }
-
-        [Theory]
-        [MemberData(nameof(InvalidFormat_TestData))]
-        public static void TryFormat_InvalidFormat_ThrowsFormatException(string format)
-        {
-            Assert.Throws<FormatException>(() => s_testGuid.TryFormat(new Span<char>(), out int charsWritten, format));
-            Assert.Throws<FormatException>(() => s_testGuid.TryFormat(new Span<char>(), out int charsWritten, format.ToUpperInvariant()));
-        }
-
-        [Theory]
-        [MemberData(nameof(ToString_TestData))]
-        public static void TryFormat_LengthTooSmall_ReturnsFalse(Guid guid, string format, string expected)
-        {
-            _ = expected;
-            Assert.False(guid.TryFormat(new Span<char>(new char[guid.ToString(format).Length - 1]), out int charsWritten, format));
-            Assert.Equal(0, charsWritten);
-        }
-
-        [Theory]
-        [MemberData(nameof(ToString_TestData))]
-        public static void TryFormat_CharsWritten_EqualsZero_WhenSpanTooSmall(Guid guid, string format, string expected)
-        {
-            _ = expected;
-            Assert.False(guid.TryFormat(new Span<char>(new char[guid.ToString(format).Length - 1]), out int charsWritten, format));
-            Assert.Equal(0, charsWritten);
-        }
-
-        [Theory]
-        [MemberData(nameof(ToString_TestData))]
-        public static void TryFormat_ValidLength_ReturnsTrue(Guid guid, string format, string expected)
-        {
-            char[] chars = new char[guid.ToString(format).Length];
-            Assert.True(guid.TryFormat(new Span<char>(chars), out int charsWritten, format));
-            Assert.Equal(chars, expected.ToCharArray());
-        }
-
-        [Theory]
-        [MemberData(nameof(GuidStrings_Valid_TestData))]
-        public static void Parse_Span_ValidInput_Success(string input, string format, Guid expected)
-        {
-            Assert.Equal(expected, Guid.Parse(input.AsSpan()));
-            Assert.Equal(expected, Guid.ParseExact(input.AsSpan(), format.ToUpperInvariant()));
-            Assert.Equal(expected, Guid.ParseExact(input.AsSpan(), format.ToLowerInvariant())); // Format should be case insensitive
-
-            Guid result;
-
-            Assert.True(Guid.TryParse(input.AsSpan(), out result));
-            Assert.Equal(expected, result);
-
-            Assert.True(Guid.TryParseExact(input.AsSpan(), format.ToUpperInvariant(), out result));
-            Assert.Equal(expected, result);
-
-            Assert.True(Guid.TryParseExact(input.AsSpan(), format.ToLowerInvariant(), out result)); // Format should be case insensitive
-            Assert.Equal(expected, result);
-        }
-
-        [Theory]
-        [MemberData(nameof(GuidStrings_Invalid_TestData))]
-        public static void Parse_Span_InvalidInput_Fails(string input, Type exceptionType)
-        {
-            if (input == null)
-            {
-                return;
-            }
-
-            // Overflow exceptions throw as format exceptions in Parse
-            if (exceptionType.Equals(typeof(OverflowException)))
-            {
-                exceptionType = typeof(FormatException);
-            }
-            Assert.Throws(exceptionType, () => Guid.Parse(input.AsSpan()));
-
-            Assert.False(Guid.TryParse(input.AsSpan(), out Guid result));
-            Assert.Equal(Guid.Empty, result);
-
-            foreach (string format in new[] { "N", "D", "B", "P", "X" })
-            {
-                Assert.Throws(exceptionType, () => Guid.ParseExact(input.AsSpan(), format));
-
-                Assert.False(Guid.TryParseExact(input.AsSpan(), format, out result));
-                Assert.Equal(Guid.Empty, result);
-            }
-        }
-    }
-}
index 1264754..46b286d 100644 (file)
@@ -8,7 +8,7 @@ using Xunit;
 
 namespace System.Tests
 {
-    public partial class Int16Tests
+    public class Int16Tests
     {
         [Fact]
         public static void Ctor_Empty()
@@ -314,5 +314,106 @@ namespace System.Tests
             AssertExtensions.Throws<ArgumentException>(paramName, () => short.Parse("1", style));
             AssertExtensions.Throws<ArgumentException>(paramName, () => short.Parse("1", style, null));
         }
+
+        public static IEnumerable<object[]> Parse_ValidWithOffsetCount_TestData()
+        {
+            foreach (object[] inputs in Parse_Valid_TestData())
+            {
+                yield return new object[] { inputs[0], 0, ((string)inputs[0]).Length, inputs[1], inputs[2], inputs[3] };
+            }
+
+            yield return new object[] { "-32767", 1, 5, NumberStyles.Integer, null, (short)32767 };
+            yield return new object[] { "-32768", 0, 5, NumberStyles.Integer, null, (short)-3276 };
+            yield return new object[] { "abc", 0, 2, NumberStyles.HexNumber, null, (short)0xab };
+            yield return new object[] { "abc", 1, 2, NumberStyles.HexNumber, null, (short)0xbc };
+            yield return new object[] { "(123)", 1, 3, NumberStyles.AllowParentheses, null, (short)123 };
+            yield return new object[] { "123", 0, 1, NumberStyles.Integer, new NumberFormatInfo(), (short)1 };
+            yield return new object[] { "$1,000", 1, 5, NumberStyles.Currency, new NumberFormatInfo() { CurrencySymbol = "$" }, (short)1000 };
+            yield return new object[] { "$1,000", 0, 2, NumberStyles.Currency, new NumberFormatInfo() { CurrencySymbol = "$" }, (short)1 };
+        }
+
+        [Theory]
+        [MemberData(nameof(Parse_ValidWithOffsetCount_TestData))]
+        public static void Parse_Span_Valid(string value, int offset, int count, NumberStyles style, IFormatProvider provider, short expected)
+        {
+            short result;
+
+            // Default style and provider
+            if (style == NumberStyles.Integer && provider == null)
+            {
+                Assert.True(short.TryParse(value.AsSpan(offset, count), out result));
+                Assert.Equal(expected, result);
+            }
+
+            Assert.Equal(expected, short.Parse(value.AsSpan(offset, count), style, provider));
+
+            Assert.True(short.TryParse(value.AsSpan(offset, count), style, provider, out result));
+            Assert.Equal(expected, result);
+        }
+
+        [Theory]
+        [MemberData(nameof(Parse_Invalid_TestData))]
+        public static void Parse_Span_Invalid(string value, NumberStyles style, IFormatProvider provider, Type exceptionType)
+        {
+            if (value != null)
+            {
+                short result;
+
+                // Default style and provider
+                if (style == NumberStyles.Integer && provider == null)
+                {
+                    Assert.False(short.TryParse(value.AsSpan(), out result));
+                    Assert.Equal(0, result);
+                }
+
+                Assert.Throws(exceptionType, () => short.Parse(value.AsSpan(), style, provider));
+
+                Assert.False(short.TryParse(value.AsSpan(), style, provider, out result));
+                Assert.Equal(0, result);
+            }
+        }
+
+        [Theory]
+        [MemberData(nameof(ToString_TestData))]
+        public static void TryFormat(short i, string format, IFormatProvider provider, string expected)
+        {
+            char[] actual;
+            int charsWritten;
+
+            // Just right
+            actual = new char[expected.Length];
+            Assert.True(i.TryFormat(actual.AsSpan(), out charsWritten, format, provider));
+            Assert.Equal(expected.Length, charsWritten);
+            Assert.Equal(expected, new string(actual));
+
+            // Longer than needed
+            actual = new char[expected.Length + 1];
+            Assert.True(i.TryFormat(actual.AsSpan(), out charsWritten, format, provider));
+            Assert.Equal(expected.Length, charsWritten);
+            Assert.Equal(expected, new string(actual, 0, charsWritten));
+
+            // Too short
+            if (expected.Length > 0)
+            {
+                actual = new char[expected.Length - 1];
+                Assert.False(i.TryFormat(actual.AsSpan(), out charsWritten, format, provider));
+                Assert.Equal(0, charsWritten);
+            }
+
+            if (format != null)
+            {
+                // Upper format
+                actual = new char[expected.Length];
+                Assert.True(i.TryFormat(actual.AsSpan(), out charsWritten, format.ToUpperInvariant(), provider));
+                Assert.Equal(expected.Length, charsWritten);
+                Assert.Equal(expected.ToUpperInvariant(), new string(actual));
+
+                // Lower format
+                actual = new char[expected.Length];
+                Assert.True(i.TryFormat(actual.AsSpan(), out charsWritten, format.ToLowerInvariant(), provider));
+                Assert.Equal(expected.Length, charsWritten);
+                Assert.Equal(expected.ToLowerInvariant(), new string(actual));
+            }
+        }
     }
 }
diff --git a/src/libraries/System.Runtime/tests/System/Int16Tests.netcoreapp.cs b/src/libraries/System.Runtime/tests/System/Int16Tests.netcoreapp.cs
deleted file mode 100644 (file)
index c2ad54c..0000000
+++ /dev/null
@@ -1,114 +0,0 @@
-// 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.Globalization;
-using Xunit;
-
-namespace System.Tests
-{
-    public partial class Int16Tests
-    {
-        public static IEnumerable<object[]> Parse_ValidWithOffsetCount_TestData()
-        {
-            foreach (object[] inputs in Parse_Valid_TestData())
-            {
-                yield return new object[] { inputs[0], 0, ((string)inputs[0]).Length, inputs[1], inputs[2], inputs[3] };
-            }
-
-            yield return new object[] { "-32767", 1, 5, NumberStyles.Integer, null, (short)32767 };
-            yield return new object[] { "-32768", 0, 5, NumberStyles.Integer, null, (short)-3276 };
-            yield return new object[] { "abc", 0, 2, NumberStyles.HexNumber, null, (short)0xab };
-            yield return new object[] { "abc", 1, 2, NumberStyles.HexNumber, null, (short)0xbc };
-            yield return new object[] { "(123)", 1, 3, NumberStyles.AllowParentheses, null, (short)123 };
-            yield return new object[] { "123", 0, 1, NumberStyles.Integer, new NumberFormatInfo(), (short)1 };
-            yield return new object[] { "$1,000", 1, 5, NumberStyles.Currency, new NumberFormatInfo() { CurrencySymbol = "$" }, (short)1000 };
-            yield return new object[] { "$1,000", 0, 2, NumberStyles.Currency, new NumberFormatInfo() { CurrencySymbol = "$" }, (short)1 };
-        }
-
-        [Theory]
-        [MemberData(nameof(Parse_ValidWithOffsetCount_TestData))]
-        public static void Parse_Span_Valid(string value, int offset, int count, NumberStyles style, IFormatProvider provider, short expected)
-        {
-            short result;
-
-            // Default style and provider
-            if (style == NumberStyles.Integer && provider == null)
-            {
-                Assert.True(short.TryParse(value.AsSpan(offset, count), out result));
-                Assert.Equal(expected, result);
-            }
-
-            Assert.Equal(expected, short.Parse(value.AsSpan(offset, count), style, provider));
-
-            Assert.True(short.TryParse(value.AsSpan(offset, count), style, provider, out result));
-            Assert.Equal(expected, result);
-        }
-
-        [Theory]
-        [MemberData(nameof(Parse_Invalid_TestData))]
-        public static void Parse_Span_Invalid(string value, NumberStyles style, IFormatProvider provider, Type exceptionType)
-        {
-            if (value != null)
-            {
-                short result;
-
-                // Default style and provider
-                if (style == NumberStyles.Integer && provider == null)
-                {
-                    Assert.False(short.TryParse(value.AsSpan(), out result));
-                    Assert.Equal(0, result);
-                }
-
-                Assert.Throws(exceptionType, () => short.Parse(value.AsSpan(), style, provider));
-
-                Assert.False(short.TryParse(value.AsSpan(), style, provider, out result));
-                Assert.Equal(0, result);
-            }
-        }
-
-        [Theory]
-        [MemberData(nameof(ToString_TestData))]
-        public static void TryFormat(short i, string format, IFormatProvider provider, string expected)
-        {
-            char[] actual;
-            int charsWritten;
-
-            // Just right
-            actual = new char[expected.Length];
-            Assert.True(i.TryFormat(actual.AsSpan(), out charsWritten, format, provider));
-            Assert.Equal(expected.Length, charsWritten);
-            Assert.Equal(expected, new string(actual));
-
-            // Longer than needed
-            actual = new char[expected.Length + 1];
-            Assert.True(i.TryFormat(actual.AsSpan(), out charsWritten, format, provider));
-            Assert.Equal(expected.Length, charsWritten);
-            Assert.Equal(expected, new string(actual, 0, charsWritten));
-
-            // Too short
-            if (expected.Length > 0)
-            {
-                actual = new char[expected.Length - 1];
-                Assert.False(i.TryFormat(actual.AsSpan(), out charsWritten, format, provider));
-                Assert.Equal(0, charsWritten);
-            }
-
-            if (format != null)
-            {
-                // Upper format
-                actual = new char[expected.Length];
-                Assert.True(i.TryFormat(actual.AsSpan(), out charsWritten, format.ToUpperInvariant(), provider));
-                Assert.Equal(expected.Length, charsWritten);
-                Assert.Equal(expected.ToUpperInvariant(), new string(actual));
-
-                // Lower format
-                actual = new char[expected.Length];
-                Assert.True(i.TryFormat(actual.AsSpan(), out charsWritten, format.ToLowerInvariant(), provider));
-                Assert.Equal(expected.Length, charsWritten);
-                Assert.Equal(expected.ToLowerInvariant(), new string(actual));
-            }
-        }
-    }
-}
index dd62439..2a338f0 100644 (file)
@@ -8,7 +8,7 @@ using Xunit;
 
 namespace System.Tests
 {
-    public partial class Int32Tests
+    public class Int32Tests
     {
         [Fact]
         public static void Ctor_Empty()
@@ -677,5 +677,153 @@ namespace System.Tests
             nfi.CurrencySymbol = "$";
             Assert.Equal("$1234", 1234.ToString("C0", nfi));
         }
+
+        public static IEnumerable<object[]> Parse_ValidWithOffsetCount_TestData()
+        {
+            foreach (object[] inputs in Parse_Valid_TestData())
+            {
+                yield return new object[] { inputs[0], 0, ((string)inputs[0]).Length, inputs[1], inputs[2], inputs[3] };
+            }
+
+            NumberFormatInfo samePositiveNegativeFormat = new NumberFormatInfo()
+            {
+                PositiveSign = "|",
+                NegativeSign = "|"
+            };
+
+            NumberFormatInfo emptyPositiveFormat = new NumberFormatInfo() { PositiveSign = "" };
+            NumberFormatInfo emptyNegativeFormat = new NumberFormatInfo() { NegativeSign = "" };
+
+            // None
+            yield return new object[] { "2147483647", 1, 9, NumberStyles.None, null, 147483647 };
+            yield return new object[] { "2147483647", 1, 1, NumberStyles.None, null, 1 };
+            yield return new object[] { "123\0\0", 2, 2, NumberStyles.None, null, 3 };
+
+            // Hex
+            yield return new object[] { "abc", 0, 1, NumberStyles.HexNumber, null, 0xa };
+            yield return new object[] { "ABC", 1, 1, NumberStyles.HexNumber, null, 0xB };
+            yield return new object[] { "FFFFFFFF", 6, 2, NumberStyles.HexNumber, null, 0xFF };
+            yield return new object[] { "FFFFFFFF", 0, 1, NumberStyles.HexNumber, null, 0xF };
+
+            // Currency
+            yield return new object[] { "-$1000", 1, 5, NumberStyles.Currency, new NumberFormatInfo()
+            {
+                CurrencySymbol = "$",
+                CurrencyGroupSeparator = "|",
+                NumberGroupSeparator = "/"
+            }, 1000 };
+
+            NumberFormatInfo emptyCurrencyFormat = new NumberFormatInfo() { CurrencySymbol = "" };
+            yield return new object[] { "100", 1, 2, NumberStyles.Currency, emptyCurrencyFormat, 0 };
+            yield return new object[] { "100", 0, 1, NumberStyles.Currency, emptyCurrencyFormat, 1 };
+
+            // If CurrencySymbol and Negative are the same, NegativeSign is preferred
+            NumberFormatInfo sameCurrencyNegativeSignFormat = new NumberFormatInfo()
+            {
+                NegativeSign = "|",
+                CurrencySymbol = "|"
+            };
+            yield return new object[] { "1000", 1, 3, NumberStyles.AllowCurrencySymbol | NumberStyles.AllowLeadingSign, sameCurrencyNegativeSignFormat, 0 };
+            yield return new object[] { "|1000", 0, 2, NumberStyles.AllowCurrencySymbol | NumberStyles.AllowLeadingSign, sameCurrencyNegativeSignFormat, -1 };
+
+            // Any
+            yield return new object[] { "123", 0, 2, NumberStyles.Any, null, 12 };
+
+            // AllowLeadingSign
+            yield return new object[] { "-2147483648", 0, 10, NumberStyles.AllowLeadingSign, null, -214748364 };
+
+            // AllowTrailingSign
+            yield return new object[] { "123-", 0, 3, NumberStyles.AllowTrailingSign, null, 123 };
+
+            // AllowExponent
+            yield return new object[] { "1E2", 0, 1, NumberStyles.AllowExponent, null, 1 };
+            yield return new object[] { "1E+2", 3, 1, NumberStyles.AllowExponent, null, 2 };
+            yield return new object[] { "(1E2)", 1, 3, NumberStyles.AllowExponent | NumberStyles.AllowParentheses, null, 1E2 };
+            yield return new object[] { "-1E2", 1, 3, NumberStyles.AllowExponent | NumberStyles.AllowLeadingSign, null, 1E2 };
+        }
+
+        [Theory]
+        [MemberData(nameof(Parse_ValidWithOffsetCount_TestData))]
+        public static void Parse_Span_Valid(string value, int offset, int count, NumberStyles style, IFormatProvider provider, int expected)
+        {
+            int result;
+
+            // Default style and provider
+            if (style == NumberStyles.Integer && provider == null)
+            {
+                Assert.True(int.TryParse(value.AsSpan(offset, count), out result));
+                Assert.Equal(expected, result);
+            }
+
+            Assert.Equal(expected, int.Parse(value.AsSpan(offset, count), style, provider));
+
+            Assert.True(int.TryParse(value.AsSpan(offset, count), style, provider, out result));
+            Assert.Equal(expected, result);
+        }
+
+        [Theory]
+        [MemberData(nameof(Parse_Invalid_TestData))]
+        public static void Parse_Span_Invalid(string value, NumberStyles style, IFormatProvider provider, Type exceptionType)
+        {
+            if (value != null)
+            {
+                int result;
+
+                // Default style and provider
+                if (style == NumberStyles.Integer && provider == null)
+                {
+                    Assert.False(int.TryParse(value.AsSpan(), out result));
+                    Assert.Equal(0, result);
+                }
+
+                Assert.Throws(exceptionType, () => int.Parse(value.AsSpan(), style, provider));
+
+                Assert.False(int.TryParse(value.AsSpan(), style, provider, out result));
+                Assert.Equal(0, result);
+            }
+        }
+
+        [Theory]
+        [MemberData(nameof(ToString_TestData))]
+        public static void TryFormat(int i, string format, IFormatProvider provider, string expected)
+        {
+            char[] actual;
+            int charsWritten;
+
+            // Just right
+            actual = new char[expected.Length];
+            Assert.True(i.TryFormat(actual.AsSpan(), out charsWritten, format, provider));
+            Assert.Equal(expected.Length, charsWritten);
+            Assert.Equal(expected, new string(actual));
+
+            // Longer than needed
+            actual = new char[expected.Length + 1];
+            Assert.True(i.TryFormat(actual.AsSpan(), out charsWritten, format, provider));
+            Assert.Equal(expected.Length, charsWritten);
+            Assert.Equal(expected, new string(actual, 0, charsWritten));
+
+            // Too short
+            if (expected.Length > 0)
+            {
+                actual = new char[expected.Length - 1];
+                Assert.False(i.TryFormat(actual.AsSpan(), out charsWritten, format, provider));
+                Assert.Equal(0, charsWritten);
+            }
+
+            if (format != null)
+            {
+                // Upper format
+                actual = new char[expected.Length];
+                Assert.True(i.TryFormat(actual.AsSpan(), out charsWritten, format.ToUpperInvariant(), provider));
+                Assert.Equal(expected.Length, charsWritten);
+                Assert.Equal(expected.ToUpperInvariant(), new string(actual));
+
+                // Lower format
+                actual = new char[expected.Length];
+                Assert.True(i.TryFormat(actual.AsSpan(), out charsWritten, format.ToLowerInvariant(), provider));
+                Assert.Equal(expected.Length, charsWritten);
+                Assert.Equal(expected.ToLowerInvariant(), new string(actual));
+            }
+        }
     }
 }
diff --git a/src/libraries/System.Runtime/tests/System/Int32Tests.netcoreapp.cs b/src/libraries/System.Runtime/tests/System/Int32Tests.netcoreapp.cs
deleted file mode 100644 (file)
index 086744b..0000000
+++ /dev/null
@@ -1,161 +0,0 @@
-// 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.Globalization;
-using Xunit;
-
-namespace System.Tests
-{
-    public partial class Int32Tests
-    {
-        public static IEnumerable<object[]> Parse_ValidWithOffsetCount_TestData()
-        {
-            foreach (object[] inputs in Parse_Valid_TestData())
-            {
-                yield return new object[] { inputs[0], 0, ((string)inputs[0]).Length, inputs[1], inputs[2], inputs[3] };
-            }
-
-            NumberFormatInfo samePositiveNegativeFormat = new NumberFormatInfo()
-            {
-                PositiveSign = "|",
-                NegativeSign = "|"
-            };
-
-            NumberFormatInfo emptyPositiveFormat = new NumberFormatInfo() { PositiveSign = "" };
-            NumberFormatInfo emptyNegativeFormat = new NumberFormatInfo() { NegativeSign = "" };
-
-            // None
-            yield return new object[] { "2147483647", 1, 9, NumberStyles.None, null, 147483647 };
-            yield return new object[] { "2147483647", 1, 1, NumberStyles.None, null, 1 };
-            yield return new object[] { "123\0\0", 2, 2, NumberStyles.None, null, 3 };
-
-            // Hex
-            yield return new object[] { "abc", 0, 1, NumberStyles.HexNumber, null, 0xa };
-            yield return new object[] { "ABC", 1, 1, NumberStyles.HexNumber, null, 0xB };
-            yield return new object[] { "FFFFFFFF", 6, 2, NumberStyles.HexNumber, null, 0xFF };
-            yield return new object[] { "FFFFFFFF", 0, 1, NumberStyles.HexNumber, null, 0xF };
-
-            // Currency
-            yield return new object[] { "-$1000", 1, 5, NumberStyles.Currency, new NumberFormatInfo()
-            {
-                CurrencySymbol = "$",
-                CurrencyGroupSeparator = "|",
-                NumberGroupSeparator = "/"
-            }, 1000 };
-
-            NumberFormatInfo emptyCurrencyFormat = new NumberFormatInfo() { CurrencySymbol = "" };
-            yield return new object[] { "100", 1, 2, NumberStyles.Currency, emptyCurrencyFormat, 0 };
-            yield return new object[] { "100", 0, 1, NumberStyles.Currency, emptyCurrencyFormat, 1 };
-
-            // If CurrencySymbol and Negative are the same, NegativeSign is preferred
-            NumberFormatInfo sameCurrencyNegativeSignFormat = new NumberFormatInfo()
-            {
-                NegativeSign = "|",
-                CurrencySymbol = "|"
-            };
-            yield return new object[] { "1000", 1, 3, NumberStyles.AllowCurrencySymbol | NumberStyles.AllowLeadingSign, sameCurrencyNegativeSignFormat, 0 };
-            yield return new object[] { "|1000", 0, 2, NumberStyles.AllowCurrencySymbol | NumberStyles.AllowLeadingSign, sameCurrencyNegativeSignFormat, -1 };
-
-            // Any
-            yield return new object[] { "123", 0, 2, NumberStyles.Any, null, 12 };
-
-            // AllowLeadingSign
-            yield return new object[] { "-2147483648", 0, 10, NumberStyles.AllowLeadingSign, null, -214748364 };
-
-            // AllowTrailingSign
-            yield return new object[] { "123-", 0, 3, NumberStyles.AllowTrailingSign, null, 123 };
-
-            // AllowExponent
-            yield return new object[] { "1E2", 0, 1, NumberStyles.AllowExponent, null, 1 };
-            yield return new object[] { "1E+2", 3, 1, NumberStyles.AllowExponent, null, 2 };
-            yield return new object[] { "(1E2)", 1, 3, NumberStyles.AllowExponent | NumberStyles.AllowParentheses, null, 1E2 };
-            yield return new object[] { "-1E2", 1, 3, NumberStyles.AllowExponent | NumberStyles.AllowLeadingSign, null, 1E2 };
-        }
-
-        [Theory]
-        [MemberData(nameof(Parse_ValidWithOffsetCount_TestData))]
-        public static void Parse_Span_Valid(string value, int offset, int count, NumberStyles style, IFormatProvider provider, int expected)
-        {
-            int result;
-
-            // Default style and provider
-            if (style == NumberStyles.Integer && provider == null)
-            {
-                Assert.True(int.TryParse(value.AsSpan(offset, count), out result));
-                Assert.Equal(expected, result);
-            }
-
-            Assert.Equal(expected, int.Parse(value.AsSpan(offset, count), style, provider));
-
-            Assert.True(int.TryParse(value.AsSpan(offset, count), style, provider, out result));
-            Assert.Equal(expected, result);
-        }
-
-        [Theory]
-        [MemberData(nameof(Parse_Invalid_TestData))]
-        public static void Parse_Span_Invalid(string value, NumberStyles style, IFormatProvider provider, Type exceptionType)
-        {
-            if (value != null)
-            {
-                int result;
-
-                // Default style and provider
-                if (style == NumberStyles.Integer && provider == null)
-                {
-                    Assert.False(int.TryParse(value.AsSpan(), out result));
-                    Assert.Equal(0, result);
-                }
-
-                Assert.Throws(exceptionType, () => int.Parse(value.AsSpan(), style, provider));
-
-                Assert.False(int.TryParse(value.AsSpan(), style, provider, out result));
-                Assert.Equal(0, result);
-            }
-        }
-
-        [Theory]
-        [MemberData(nameof(ToString_TestData))]
-        public static void TryFormat(int i, string format, IFormatProvider provider, string expected)
-        {
-            char[] actual;
-            int charsWritten;
-
-            // Just right
-            actual = new char[expected.Length];
-            Assert.True(i.TryFormat(actual.AsSpan(), out charsWritten, format, provider));
-            Assert.Equal(expected.Length, charsWritten);
-            Assert.Equal(expected, new string(actual));
-
-            // Longer than needed
-            actual = new char[expected.Length + 1];
-            Assert.True(i.TryFormat(actual.AsSpan(), out charsWritten, format, provider));
-            Assert.Equal(expected.Length, charsWritten);
-            Assert.Equal(expected, new string(actual, 0, charsWritten));
-
-            // Too short
-            if (expected.Length > 0)
-            {
-                actual = new char[expected.Length - 1];
-                Assert.False(i.TryFormat(actual.AsSpan(), out charsWritten, format, provider));
-                Assert.Equal(0, charsWritten);
-            }
-
-            if (format != null)
-            {
-                // Upper format
-                actual = new char[expected.Length];
-                Assert.True(i.TryFormat(actual.AsSpan(), out charsWritten, format.ToUpperInvariant(), provider));
-                Assert.Equal(expected.Length, charsWritten);
-                Assert.Equal(expected.ToUpperInvariant(), new string(actual));
-
-                // Lower format
-                actual = new char[expected.Length];
-                Assert.True(i.TryFormat(actual.AsSpan(), out charsWritten, format.ToLowerInvariant(), provider));
-                Assert.Equal(expected.Length, charsWritten);
-                Assert.Equal(expected.ToLowerInvariant(), new string(actual));
-            }
-        }
-    }
-}
index 2d31151..d005869 100644 (file)
@@ -9,7 +9,7 @@ using Xunit;
 
 namespace System.Tests
 {
-    public partial class Int64Tests
+    public class Int64Tests
     {
         [Fact]
         public static void Ctor_Empty()
@@ -330,5 +330,104 @@ namespace System.Tests
             AssertExtensions.Throws<ArgumentException>(paramName, () => long.Parse("1", style));
             AssertExtensions.Throws<ArgumentException>(paramName, () => long.Parse("1", style, null));
         }
+
+        public static IEnumerable<object[]> Parse_ValidWithOffsetCount_TestData()
+        {
+            foreach (object[] inputs in Parse_Valid_TestData())
+            {
+                yield return new object[] { inputs[0], 0, ((string)inputs[0]).Length, inputs[1], inputs[2], inputs[3] };
+            }
+
+            yield return new object[] { "-9223372036854775808", 0, 19, NumberStyles.Integer, null, -922337203685477580 };
+            yield return new object[] { "09223372036854775807", 1, 19, NumberStyles.Integer, null, 9223372036854775807 };
+            yield return new object[] { "9223372036854775807", 0, 1, NumberStyles.Integer, null, 9 };
+            yield return new object[] { "ABC", 0, 2, NumberStyles.HexNumber, null, (long)0xAB };
+            yield return new object[] { "(123)", 1, 3, NumberStyles.AllowParentheses, null, (long)123 };
+            yield return new object[] { "$1,000", 0, 2, NumberStyles.Currency, new NumberFormatInfo() { CurrencySymbol = "$" }, (long)1 };
+        }
+
+        [Theory]
+        [MemberData(nameof(Parse_ValidWithOffsetCount_TestData))]
+        public static void Parse_Span_Valid(string value, int offset, int count, NumberStyles style, IFormatProvider provider, long expected)
+        {
+            long result;
+
+            // Default style and provider
+            if (style == NumberStyles.Integer && provider == null)
+            {
+                Assert.True(long.TryParse(value.AsSpan(offset, count), out result));
+                Assert.Equal(expected, result);
+            }
+
+            Assert.Equal(expected, long.Parse(value.AsSpan(offset, count), style, provider));
+
+            Assert.True(long.TryParse(value.AsSpan(offset, count), style, provider, out result));
+            Assert.Equal(expected, result);
+        }
+
+        [Theory]
+        [MemberData(nameof(Parse_Invalid_TestData))]
+        public static void Parse_Span_Invalid(string value, NumberStyles style, IFormatProvider provider, Type exceptionType)
+        {
+            if (value != null)
+            {
+                long result;
+
+                // Default style and provider
+                if (style == NumberStyles.Integer && provider == null)
+                {
+                    Assert.False(long.TryParse(value.AsSpan(), out result));
+                    Assert.Equal(0, result);
+                }
+
+                Assert.Throws(exceptionType, () => long.Parse(value.AsSpan(), style, provider));
+
+                Assert.False(long.TryParse(value.AsSpan(), style, provider, out result));
+                Assert.Equal(0, result);
+            }
+        }
+
+        [Theory]
+        [MemberData(nameof(ToString_TestData))]
+        public static void TryFormat(long i, string format, IFormatProvider provider, string expected)
+        {
+            char[] actual;
+            int charsWritten;
+
+            // Just right
+            actual = new char[expected.Length];
+            Assert.True(i.TryFormat(actual.AsSpan(), out charsWritten, format, provider));
+            Assert.Equal(expected.Length, charsWritten);
+            Assert.Equal(expected, new string(actual));
+
+            // Longer than needed
+            actual = new char[expected.Length + 1];
+            Assert.True(i.TryFormat(actual.AsSpan(), out charsWritten, format, provider));
+            Assert.Equal(expected.Length, charsWritten);
+            Assert.Equal(expected, new string(actual, 0, charsWritten));
+
+            // Too short
+            if (expected.Length > 0)
+            {
+                actual = new char[expected.Length - 1];
+                Assert.False(i.TryFormat(actual.AsSpan(), out charsWritten, format, provider));
+                Assert.Equal(0, charsWritten);
+            }
+
+            if (format != null)
+            {
+                // Upper format
+                actual = new char[expected.Length];
+                Assert.True(i.TryFormat(actual.AsSpan(), out charsWritten, format.ToUpperInvariant(), provider));
+                Assert.Equal(expected.Length, charsWritten);
+                Assert.Equal(expected.ToUpperInvariant(), new string(actual));
+
+                // Lower format
+                actual = new char[expected.Length];
+                Assert.True(i.TryFormat(actual.AsSpan(), out charsWritten, format.ToLowerInvariant(), provider));
+                Assert.Equal(expected.Length, charsWritten);
+                Assert.Equal(expected.ToLowerInvariant(), new string(actual));
+            }
+        }
     }
 }
diff --git a/src/libraries/System.Runtime/tests/System/Int64Tests.netcoreapp.cs b/src/libraries/System.Runtime/tests/System/Int64Tests.netcoreapp.cs
deleted file mode 100644 (file)
index 8a7bc04..0000000
+++ /dev/null
@@ -1,112 +0,0 @@
-// 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.Globalization;
-using Xunit;
-
-namespace System.Tests
-{
-    public partial class Int64Tests
-    {
-        public static IEnumerable<object[]> Parse_ValidWithOffsetCount_TestData()
-        {
-            foreach (object[] inputs in Parse_Valid_TestData())
-            {
-                yield return new object[] { inputs[0], 0, ((string)inputs[0]).Length, inputs[1], inputs[2], inputs[3] };
-            }
-
-            yield return new object[] { "-9223372036854775808", 0, 19, NumberStyles.Integer, null, -922337203685477580 };
-            yield return new object[] { "09223372036854775807", 1, 19, NumberStyles.Integer, null, 9223372036854775807 };
-            yield return new object[] { "9223372036854775807", 0, 1, NumberStyles.Integer, null, 9 };
-            yield return new object[] { "ABC", 0, 2, NumberStyles.HexNumber, null, (long)0xAB };
-            yield return new object[] { "(123)", 1, 3, NumberStyles.AllowParentheses, null, (long)123 };
-            yield return new object[] { "$1,000", 0, 2, NumberStyles.Currency, new NumberFormatInfo() { CurrencySymbol = "$" }, (long)1 };
-        }
-
-        [Theory]
-        [MemberData(nameof(Parse_ValidWithOffsetCount_TestData))]
-        public static void Parse_Span_Valid(string value, int offset, int count, NumberStyles style, IFormatProvider provider, long expected)
-        {
-            long result;
-
-            // Default style and provider
-            if (style == NumberStyles.Integer && provider == null)
-            {
-                Assert.True(long.TryParse(value.AsSpan(offset, count), out result));
-                Assert.Equal(expected, result);
-            }
-
-            Assert.Equal(expected, long.Parse(value.AsSpan(offset, count), style, provider));
-
-            Assert.True(long.TryParse(value.AsSpan(offset, count), style, provider, out result));
-            Assert.Equal(expected, result);
-        }
-
-        [Theory]
-        [MemberData(nameof(Parse_Invalid_TestData))]
-        public static void Parse_Span_Invalid(string value, NumberStyles style, IFormatProvider provider, Type exceptionType)
-        {
-            if (value != null)
-            {
-                long result;
-
-                // Default style and provider
-                if (style == NumberStyles.Integer && provider == null)
-                {
-                    Assert.False(long.TryParse(value.AsSpan(), out result));
-                    Assert.Equal(0, result);
-                }
-
-                Assert.Throws(exceptionType, () => long.Parse(value.AsSpan(), style, provider));
-
-                Assert.False(long.TryParse(value.AsSpan(), style, provider, out result));
-                Assert.Equal(0, result);
-            }
-        }
-
-        [Theory]
-        [MemberData(nameof(ToString_TestData))]
-        public static void TryFormat(long i, string format, IFormatProvider provider, string expected)
-        {
-            char[] actual;
-            int charsWritten;
-
-            // Just right
-            actual = new char[expected.Length];
-            Assert.True(i.TryFormat(actual.AsSpan(), out charsWritten, format, provider));
-            Assert.Equal(expected.Length, charsWritten);
-            Assert.Equal(expected, new string(actual));
-
-            // Longer than needed
-            actual = new char[expected.Length + 1];
-            Assert.True(i.TryFormat(actual.AsSpan(), out charsWritten, format, provider));
-            Assert.Equal(expected.Length, charsWritten);
-            Assert.Equal(expected, new string(actual, 0, charsWritten));
-
-            // Too short
-            if (expected.Length > 0)
-            {
-                actual = new char[expected.Length - 1];
-                Assert.False(i.TryFormat(actual.AsSpan(), out charsWritten, format, provider));
-                Assert.Equal(0, charsWritten);
-            }
-
-            if (format != null)
-            {
-                // Upper format
-                actual = new char[expected.Length];
-                Assert.True(i.TryFormat(actual.AsSpan(), out charsWritten, format.ToUpperInvariant(), provider));
-                Assert.Equal(expected.Length, charsWritten);
-                Assert.Equal(expected.ToUpperInvariant(), new string(actual));
-
-                // Lower format
-                actual = new char[expected.Length];
-                Assert.True(i.TryFormat(actual.AsSpan(), out charsWritten, format.ToLowerInvariant(), provider));
-                Assert.Equal(expected.Length, charsWritten);
-                Assert.Equal(expected.ToLowerInvariant(), new string(actual));
-            }
-        }
-    }
-}
index 31828f1..dca7832 100644 (file)
@@ -8,7 +8,7 @@ using Xunit;
 
 namespace System.Tests
 {
-    public static partial class IntPtrTests
+    public static class IntPtrTests
     {
         private static unsafe bool Is64Bit => sizeof(void*) == 8;
 
@@ -116,6 +116,9 @@ namespace System.Tests
                 Assert.Equal(expected, ptr1 == ptr2);
                 Assert.Equal(!expected, ptr1 != ptr2);
                 Assert.Equal(expected, ptr1.GetHashCode().Equals(ptr2.GetHashCode()));
+
+                IEquatable<IntPtr> iEquatable = ptr1;
+                Assert.Equal(expected, iEquatable.Equals((IntPtr)obj));
             }
             Assert.Equal(expected, ptr1.Equals(obj));
             Assert.Equal(ptr1.GetHashCode(), ptr1.GetHashCode());
diff --git a/src/libraries/System.Runtime/tests/System/IntPtrTests.netcoreapp.cs b/src/libraries/System.Runtime/tests/System/IntPtrTests.netcoreapp.cs
deleted file mode 100644 (file)
index d7497e6..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-// 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;
-using System.Collections.Generic;
-using Xunit;
-
-namespace System.Tests
-{
-    public static partial class IntPtrTests
-    {
-        [Theory]
-        [MemberData(nameof(Equals_TestData))]
-        public static void Equals_NetCoreApp11(IntPtr ptr, object obj, bool expected)
-        {
-            if (!(obj is IntPtr))
-            {
-                return;
-            }
-
-            IEquatable<IntPtr> iEquatable = ptr;
-            Assert.Equal(expected, iEquatable.Equals((IntPtr)obj));
-        }
-    }
-}
index 0736195..f2ccfdd 100644 (file)
@@ -9,7 +9,7 @@ using Xunit;
 
 namespace System.Tests
 {
-    public static partial class LazyTests
+    public static class LazyTests
     {
         [Fact]
         public static void Ctor()
@@ -535,6 +535,49 @@ namespace System.Tests
             Assert.Equal(template, d);
         }
 
+        [Fact]
+        public static void Ctor_Value_ReferenceType()
+        {
+            var lazyString = new Lazy<string>("abc");
+            VerifyLazy(lazyString, "abc", hasValue: true, isValueCreated: true);
+        }
+
+        [Fact]
+        public static void Ctor_Value_ValueType()
+        {
+            var lazyObject = new Lazy<int>(123);
+            VerifyLazy(lazyObject, 123, hasValue: true, isValueCreated: true);
+        }
+
+        [Fact]
+        public static void EnsureInitialized_FuncInitializationWithoutTrackingBool_Uninitialized()
+        {
+            string template = "foo";
+            string target = null;
+            object syncLock = null;
+            Assert.Equal(template, LazyInitializer.EnsureInitialized(ref target, ref syncLock, () => template));
+            Assert.Equal(template, target);
+            Assert.NotNull(syncLock);
+        }
+
+        [Fact]
+        public static void EnsureInitialized_FuncInitializationWithoutTrackingBool_Initialized()
+        {
+            string template = "foo";
+            string target = template;
+            object syncLock = null;
+            Assert.Equal(template, LazyInitializer.EnsureInitialized(ref target, ref syncLock, () => template + "bar"));
+            Assert.Equal(template, target);
+            Assert.Null(syncLock);
+        }
+
+        [Fact]
+        public static void EnsureInitializer_FuncInitializationWithoutTrackingBool_Null()
+        {
+            string target = null;
+            object syncLock = null;
+            Assert.Throws<InvalidOperationException>(() => LazyInitializer.EnsureInitialized(ref target, ref syncLock, () => null));
+        }
         private static void VerifyLazy<T>(Lazy<T> lazy, T expectedValue, bool hasValue, bool isValueCreated)
         {
             Assert.Equal(isValueCreated, lazy.IsValueCreated);
diff --git a/src/libraries/System.Runtime/tests/System/LazyTests.netcoreapp.cs b/src/libraries/System.Runtime/tests/System/LazyTests.netcoreapp.cs
deleted file mode 100644 (file)
index bb85e8f..0000000
+++ /dev/null
@@ -1,56 +0,0 @@
-// 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.Threading;
-using Xunit;
-
-namespace System.Tests
-{
-    public static partial class LazyTests
-    {
-        [Fact]
-        public static void Ctor_Value_ReferenceType()
-        {
-            var lazyString = new Lazy<string>("abc");
-            VerifyLazy(lazyString, "abc", hasValue: true, isValueCreated: true);
-        }
-
-        [Fact]
-        public static void Ctor_Value_ValueType()
-        {
-            var lazyObject = new Lazy<int>(123);
-            VerifyLazy(lazyObject, 123, hasValue: true, isValueCreated: true);
-        }
-
-        [Fact]
-        public static void EnsureInitialized_FuncInitializationWithoutTrackingBool_Uninitialized()
-        {
-            string template = "foo";
-            string target = null;
-            object syncLock = null;
-            Assert.Equal(template, LazyInitializer.EnsureInitialized(ref target, ref syncLock, () => template));
-            Assert.Equal(template, target);
-            Assert.NotNull(syncLock);
-        }
-
-        [Fact]
-        public static void EnsureInitialized_FuncInitializationWithoutTrackingBool_Initialized()
-        {
-            string template = "foo";
-            string target = template;
-            object syncLock = null;
-            Assert.Equal(template, LazyInitializer.EnsureInitialized(ref target, ref syncLock, () => template + "bar"));
-            Assert.Equal(template, target);
-            Assert.Null(syncLock);
-        }
-
-        [Fact]
-        public static void EnsureInitializer_FuncInitializationWithoutTrackingBool_Null()
-        {
-            string target = null;
-            object syncLock = null;
-            Assert.Throws<InvalidOperationException>(() => LazyInitializer.EnsureInitialized(ref target, ref syncLock, () => null));
-        }
-    }
-}
index a2cce63..0883838 100644 (file)
@@ -23,19 +23,6 @@ namespace System.Reflection.Tests
         }
 
         [Fact]
-        public static void Test_GetCurrentMethod_GenericMethodDefinition()
-        {
-            MethodBase m = MyFakeGenericMethod<byte>();
-
-            Assert.Equal("MyFakeGenericMethod", m.Name);
-            Assert.Equal("MethodBaseTests", m.ReflectedType.Name);
-            Assert.True(m.IsGenericMethod);
-            Assert.True(m.IsGenericMethodDefinition);
-            Assert.Equal(1, m.GetGenericArguments().Length);
-            Assert.Equal("T", m.GetGenericArguments()[0].Name);
-        }
-
-        [Fact]
         public static void Test_GetCurrentMethod_Inlineable()
         {
             // Verify that the result is not affected by inlining optimizations
@@ -91,12 +78,6 @@ namespace System.Reflection.Tests
 #endif
         }
 
-        public static MethodBase MyFakeGenericMethod<T>()
-        {
-            MethodBase m = MethodBase.GetCurrentMethod();
-            return m;
-        }
-
         private static int MyAnotherMethod(int x)
         {
             return x+1;
@@ -119,5 +100,38 @@ namespace System.Reflection.Tests
             }
         }
 #pragma warning restore xUnit1013 // Public method should be marked as test
+
+        [Fact]
+        public static void Test_GetCurrentMethod_ConstructedGenericMethod()
+        {
+            MethodInfo mi = typeof(MethodBaseTests).GetMethod(nameof(MyFakeGenericMethod), BindingFlags.NonPublic | BindingFlags.Static);
+            MethodBase m = mi.MakeGenericMethod(typeof(byte));
+
+            Assert.Equal(nameof(MyFakeGenericMethod), m.Name);
+            Assert.Equal(typeof(MethodBaseTests), m.ReflectedType);
+            Assert.True(m.IsGenericMethod);
+            Assert.False(m.IsGenericMethodDefinition);
+            Assert.True(m.IsConstructedGenericMethod);
+            Assert.Equal(1, m.GetGenericArguments().Length);
+            Assert.Equal(typeof(byte), m.GetGenericArguments()[0]);
+        }
+
+        [Fact]
+        public static void Test_GetCurrentMethod_GenericMethodDefinition()
+        {
+            MethodBase m = typeof(MethodBaseTests).GetMethod(nameof(MyFakeGenericMethod), BindingFlags.NonPublic | BindingFlags.Static);
+
+            Assert.Equal(nameof(MyFakeGenericMethod), m.Name);
+            Assert.Equal(typeof(MethodBaseTests), m.ReflectedType);
+            Assert.True(m.IsGenericMethod);
+            Assert.True(m.IsGenericMethodDefinition);
+            Assert.False(m.IsConstructedGenericMethod);
+            Assert.Equal(1, m.GetGenericArguments().Length);
+            Assert.Equal("T", m.GetGenericArguments()[0].Name);
+        }
+
+        private static void MyFakeGenericMethod<T>()
+        {
+        }
     }
 }
diff --git a/src/libraries/System.Runtime/tests/System/Reflection/MethodBaseTests.netcoreapp.cs b/src/libraries/System.Runtime/tests/System/Reflection/MethodBaseTests.netcoreapp.cs
deleted file mode 100644 (file)
index 643e372..0000000
+++ /dev/null
@@ -1,44 +0,0 @@
-// 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 Xunit;
-
-namespace System.Reflection.Tests
-{
-    public class MethodBaseNetcoreTests
-    {
-        [Fact]
-        public static void Test_GetCurrentMethod_ConstructedGenericMethod()
-        {
-            MethodInfo mi = typeof(MethodBaseNetcoreTests).GetMethod(nameof(MyFakeGenericMethod), BindingFlags.NonPublic | BindingFlags.Instance);
-            MethodBase m = mi.MakeGenericMethod(typeof(byte));
-
-            Assert.Equal(nameof(MyFakeGenericMethod), m.Name);
-            Assert.Equal(typeof(MethodBaseNetcoreTests), m.ReflectedType);
-            Assert.True(m.IsGenericMethod);
-            Assert.False(m.IsGenericMethodDefinition);
-            Assert.True(m.IsConstructedGenericMethod);
-            Assert.Equal(1, m.GetGenericArguments().Length);
-            Assert.Equal(typeof(byte), m.GetGenericArguments()[0]);
-        }
-
-        [Fact]
-        public static void Test_GetCurrentMethod_GenericMethodDefinition()
-        {
-            MethodBase m = typeof(MethodBaseNetcoreTests).GetMethod(nameof(MyFakeGenericMethod), BindingFlags.NonPublic | BindingFlags.Instance);
-
-            Assert.Equal(nameof(MyFakeGenericMethod), m.Name);
-            Assert.Equal(typeof(MethodBaseNetcoreTests), m.ReflectedType);
-            Assert.True(m.IsGenericMethod);
-            Assert.True(m.IsGenericMethodDefinition);
-            Assert.False(m.IsConstructedGenericMethod);
-            Assert.Equal(1, m.GetGenericArguments().Length);
-            Assert.Equal("T", m.GetGenericArguments()[0].Name);
-        }
-
-        private void MyFakeGenericMethod<T>()
-        {
-        }
-    }
-}
index 9ac2711..1c03661 100644 (file)
@@ -2,6 +2,7 @@
 // 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 Xunit;
 
 namespace System.Reflection.Tests
@@ -42,5 +43,42 @@ namespace System.Reflection.Tests
             Assert.True(new TypeDelegator(typeof(TypeCode)).IsValueType);
             Assert.True(new TypeDelegator(typeof(TypeCode)).IsEnum);
         }
+
+        public static IEnumerable<object[]> SZArrayOrNotTypes()
+        {
+            yield return new object[] { typeof(int[]), true };
+            yield return new object[] { typeof(string[]), true };
+            yield return new object[] { typeof(void), false };
+            yield return new object[] { typeof(int), false };
+            yield return new object[] { typeof(int[]).MakeByRefType(), false };
+            yield return new object[] { typeof(int[,]), false };
+            if (PlatformDetection.IsNonZeroLowerBoundArraySupported)
+            {
+                yield return new object[] { Array.CreateInstance(typeof(int), new[] { 2 }, new[] { -1 }).GetType(), false };
+                yield return new object[] { Array.CreateInstance(typeof(int), new[] { 2 }, new[] { 1 }).GetType(), false };
+            }
+            yield return new object[] { Array.CreateInstance(typeof(int), new[] { 2 }, new[] { 0 }).GetType(), true };
+            yield return new object[] { typeof(int[][]), true };
+            yield return new object[] { Type.GetType("System.Int32[]"), true };
+            yield return new object[] { Type.GetType("System.Int32[*]"), false };
+            yield return new object[] { Type.GetType("System.Int32"), false };
+            yield return new object[] { typeof(int).MakeArrayType(), true };
+            yield return new object[] { typeof(int).MakeArrayType(1), false };
+            yield return new object[] { typeof(int).MakeArrayType().MakeArrayType(), true };
+            yield return new object[] { typeof(int).MakeArrayType(2), false };
+            yield return new object[] { typeof(Outside<int>.Inside<string>), false };
+            yield return new object[] { typeof(Outside<int>.Inside<string>[]), true };
+            yield return new object[] { typeof(Outside<int>.Inside<string>[,]), false };
+            if (PlatformDetection.IsNonZeroLowerBoundArraySupported)
+            {
+                yield return new object[] { Array.CreateInstance(typeof(Outside<int>.Inside<string>), new[] { 2 }, new[] { -1 }).GetType(), false };
+            }
+        }
+
+        [Theory, MemberData(nameof(SZArrayOrNotTypes))]
+        public void IsSZArray(Type type, bool expected)
+        {
+            Assert.Equal(expected, new TypeDelegator(type).IsSZArray);
+        }
     }
 }
diff --git a/src/libraries/System.Runtime/tests/System/Reflection/TypeDelegatorTests.netcoreapp.cs b/src/libraries/System.Runtime/tests/System/Reflection/TypeDelegatorTests.netcoreapp.cs
deleted file mode 100644 (file)
index 8009dc9..0000000
+++ /dev/null
@@ -1,49 +0,0 @@
-// 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 Xunit;
-
-namespace System.Reflection.Tests
-{
-    public class TypeDelegatorNetcoreTests
-    {
-        public static IEnumerable<object[]> SZArrayOrNotTypes()
-        {
-            yield return new object[] { typeof(int[]), true };
-            yield return new object[] { typeof(string[]), true };
-            yield return new object[] { typeof(void), false };
-            yield return new object[] { typeof(int), false };
-            yield return new object[] { typeof(int[]).MakeByRefType(), false };
-            yield return new object[] { typeof(int[,]), false };
-            if (PlatformDetection.IsNonZeroLowerBoundArraySupported)
-            {
-                yield return new object[] { Array.CreateInstance(typeof(int), new[] { 2 }, new[] { -1 }).GetType(), false };
-                yield return new object[] { Array.CreateInstance(typeof(int), new[] { 2 }, new[] { 1 }).GetType(), false };
-            }
-            yield return new object[] { Array.CreateInstance(typeof(int), new[] { 2 }, new[] { 0 }).GetType(), true };
-            yield return new object[] { typeof(int[][]), true };
-            yield return new object[] { Type.GetType("System.Int32[]"), true };
-            yield return new object[] { Type.GetType("System.Int32[*]"), false };
-            yield return new object[] { Type.GetType("System.Int32"), false };
-            yield return new object[] { typeof(int).MakeArrayType(), true };
-            yield return new object[] { typeof(int).MakeArrayType(1), false };
-            yield return new object[] { typeof(int).MakeArrayType().MakeArrayType(), true };
-            yield return new object[] { typeof(int).MakeArrayType(2), false };
-            yield return new object[] { typeof(Outside<int>.Inside<string>), false };
-            yield return new object[] { typeof(Outside<int>.Inside<string>[]), true };
-            yield return new object[] { typeof(Outside<int>.Inside<string>[,]), false };
-            if (PlatformDetection.IsNonZeroLowerBoundArraySupported)
-            {
-                yield return new object[] { Array.CreateInstance(typeof(Outside<int>.Inside<string>), new[] { 2 }, new[] { -1 }).GetType(), false };
-            }
-        }
-
-        [Theory, MemberData(nameof(SZArrayOrNotTypes))]
-        public void IsSZArray(Type type, bool expected)
-        {
-            Assert.Equal(expected, new TypeDelegator(type).IsSZArray);
-        }
-    }
-}
index c1d141f..66ba84f 100644 (file)
@@ -6,7 +6,7 @@ using Xunit;
 
 namespace System.Runtime.CompilerServices.Tests
 {
-    public static partial class AttributesTests
+    public static class AttributesTests
     {
         [Fact]
         public static void AccessedThroughPropertyAttributeTests()
@@ -252,5 +252,33 @@ namespace System.Runtime.CompilerServices.Tests
         {
             new UnsafeValueTypeAttribute();
         }
+
+        [Fact]
+        public static void AsyncMethodBuilderAttributeTests()
+        {
+            var attr1 = new AsyncMethodBuilderAttribute(null);
+            Assert.Null(attr1.BuilderType);
+
+            var attr2 = new AsyncMethodBuilderAttribute(typeof(AttributesTests));
+            Assert.Equal(typeof(AttributesTests), attr2.BuilderType);
+        }
+
+        [Fact]
+        public static void IsByRefLikeAttributeTests()
+        {
+            new IsByRefLikeAttribute();
+        }
+
+        [Fact]
+        public static void IsReadOnlyAttributeTests()
+        {
+            new IsReadOnlyAttribute();
+        }
+
+        [Fact]
+        public static void EnumeratorCancellationAttributeTests()
+        {
+            new EnumeratorCancellationAttribute();
+        }
     }
 }
diff --git a/src/libraries/System.Runtime/tests/System/Runtime/CompilerServices/AttributesTests.netcoreapp.cs b/src/libraries/System.Runtime/tests/System/Runtime/CompilerServices/AttributesTests.netcoreapp.cs
deleted file mode 100644 (file)
index 089b81d..0000000
+++ /dev/null
@@ -1,39 +0,0 @@
-// 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 Xunit;
-
-namespace System.Runtime.CompilerServices.Tests
-{
-    public static partial class AttributesTests
-    {
-        [Fact]
-        public static void AsyncMethodBuilderAttributeTests()
-        {
-            var attr1 = new AsyncMethodBuilderAttribute(null);
-            Assert.Null(attr1.BuilderType);
-
-            var attr2 = new AsyncMethodBuilderAttribute(typeof(AttributesTests));
-            Assert.Equal(typeof(AttributesTests), attr2.BuilderType);
-        }
-
-        [Fact]
-        public static void IsByRefLikeAttributeTests()
-        {
-            new IsByRefLikeAttribute();
-        }
-
-        [Fact]
-        public static void IsReadOnlyAttributeTests()
-        {
-            new IsReadOnlyAttribute();
-        }
-
-        [Fact]
-        public static void EnumeratorCancellationAttributeTests()
-        {
-            new EnumeratorCancellationAttribute();
-        }
-    }
-}
index c7964cd..069826a 100644 (file)
@@ -2,14 +2,17 @@
 // 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.Linq;
+using System;
+using System.Collections.Generic;
 using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Linq;
 using System.Threading.Tasks;
 using Xunit;
 
 namespace System.Runtime.CompilerServices.Tests
 {
-    public partial class ConditionalWeakTableTests
+    public class ConditionalWeakTableTests
     {
         [Fact]
         public static void InvalidArgs_Throws()
@@ -318,5 +321,285 @@ namespace System.Runtime.CompilerServices.Tests
                 // Do it a couple of times, to make sure the table is still usable after a clear.
             }
         }
+
+        [Fact]
+        public static void AddOrUpdateDataTest()
+        {
+            var cwt = new ConditionalWeakTable<string, string>();
+            string key = "key1";
+            cwt.AddOrUpdate(key, "value1");
+
+            string value;
+            Assert.True(cwt.TryGetValue(key, out value));
+            Assert.Equal("value1", value);
+            Assert.Equal(value, cwt.GetOrCreateValue(key));
+            Assert.Equal(value, cwt.GetValue(key, k => "value1"));
+
+            Assert.Throws<ArgumentNullException>(() => cwt.AddOrUpdate(null, "value2"));
+
+            cwt.AddOrUpdate(key, "value2");
+            Assert.True(cwt.TryGetValue(key, out value));
+            Assert.Equal("value2", value);
+            Assert.Equal(value, cwt.GetOrCreateValue(key));
+            Assert.Equal(value, cwt.GetValue(key, k => "value1"));
+        }
+
+        [Fact]
+        public static void Clear_EmptyTable()
+        {
+            var cwt = new ConditionalWeakTable<object, object>();
+            cwt.Clear(); // no exception
+            cwt.Clear();
+        }
+
+        [Fact]
+        public static void Clear_AddThenEmptyRepeatedly_ItemsRemoved()
+        {
+            var cwt = new ConditionalWeakTable<object, object>();
+            object key = new object(), value = new object();
+            object result;
+            for (int i = 0; i < 3; i++)
+            {
+                cwt.Add(key, value);
+
+                Assert.True(cwt.TryGetValue(key, out result));
+                Assert.Same(value, result);
+
+                cwt.Clear();
+
+                Assert.False(cwt.TryGetValue(key, out result));
+                Assert.Null(result);
+            }
+        }
+
+        [Fact]
+        public static void Clear_AddMany_Clear_AllItemsRemoved()
+        {
+            var cwt = new ConditionalWeakTable<object, object>();
+
+            object[] keys = Enumerable.Range(0, 33).Select(_ => new object()).ToArray();
+            object[] values = Enumerable.Range(0, keys.Length).Select(_ => new object()).ToArray();
+            for (int i = 0; i < keys.Length; i++)
+            {
+                cwt.Add(keys[i], values[i]);
+            }
+
+            Assert.Equal(keys.Length, ((IEnumerable<KeyValuePair<object, object>>)cwt).Count());
+
+            cwt.Clear();
+
+            Assert.Equal(0, ((IEnumerable<KeyValuePair<object, object>>)cwt).Count());
+
+            GC.KeepAlive(keys);
+            GC.KeepAlive(values);
+        }
+
+        [Fact]
+        public static void GetEnumerator_Empty_ReturnsEmptyEnumerator()
+        {
+            var cwt = new ConditionalWeakTable<object, object>();
+            var enumerable = (IEnumerable<KeyValuePair<object, object>>)cwt;
+            Assert.Equal(0, enumerable.Count());
+        }
+
+        [Fact]
+        public static void GetEnumerator_AddedAndRemovedItems_AppropriatelyShowUpInEnumeration()
+        {
+            var cwt = new ConditionalWeakTable<object, object>();
+            var enumerable = (IEnumerable<KeyValuePair<object, object>>)cwt;
+
+            object key1 = new object(), value1 = new object();
+
+            for (int i = 0; i < 20; i++) // adding and removing multiple times, across internal container boundary
+            {
+                cwt.Add(key1, value1);
+                Assert.Equal(1, enumerable.Count());
+                Assert.Equal(new KeyValuePair<object, object>(key1, value1), enumerable.First());
+
+                Assert.True(cwt.Remove(key1));
+                Assert.Equal(0, enumerable.Count());
+            }
+
+            GC.KeepAlive(key1);
+            GC.KeepAlive(value1);
+        }
+
+        [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsPreciseGcSupported))]
+        public static void GetEnumerator_CollectedItemsNotEnumerated()
+        {
+            var cwt = new ConditionalWeakTable<object, object>();
+            var enumerable = (IEnumerable<KeyValuePair<object, object>>)cwt;
+
+            // Delegate to add collectible items to the table, separated out
+            // to avoid the JIT extending the lifetimes of the temporaries
+            Action<ConditionalWeakTable<object, object>> addItem =
+                t => t.Add(new object(), new object());
+
+            for (int i = 0; i < 10; i++) addItem(cwt);
+            GC.Collect();
+            Assert.Equal(0, enumerable.Count());
+        }
+
+        [Fact]
+        public static void GetEnumerator_MultipleEnumeratorsReturnSameResults()
+        {
+            var cwt = new ConditionalWeakTable<object, object>();
+            var enumerable = (IEnumerable<KeyValuePair<object, object>>)cwt;
+
+            object[] keys = Enumerable.Range(0, 33).Select(_ => new object()).ToArray();
+            object[] values = Enumerable.Range(0, keys.Length).Select(_ => new object()).ToArray();
+            for (int i = 0; i < keys.Length; i++)
+            {
+                cwt.Add(keys[i], values[i]);
+            }
+
+            using (IEnumerator<KeyValuePair<object, object>> enumerator1 = enumerable.GetEnumerator())
+            using (IEnumerator<KeyValuePair<object, object>> enumerator2 = enumerable.GetEnumerator())
+            {
+                while (enumerator1.MoveNext())
+                {
+                    Assert.True(enumerator2.MoveNext());
+                    Assert.Equal(enumerator1.Current, enumerator2.Current);
+                }
+                Assert.False(enumerator2.MoveNext());
+            }
+
+            GC.KeepAlive(keys);
+            GC.KeepAlive(values);
+        }
+
+        [Fact]
+        public static void GetEnumerator_RemovedItems_RemovedFromResults()
+        {
+            var cwt = new ConditionalWeakTable<object, object>();
+            var enumerable = (IEnumerable<KeyValuePair<object, object>>)cwt;
+
+            object[] keys = Enumerable.Range(0, 33).Select(_ => new object()).ToArray();
+            object[] values = Enumerable.Range(0, keys.Length).Select(_ => new object()).ToArray();
+            for (int i = 0; i < keys.Length; i++)
+            {
+                cwt.Add(keys[i], values[i]);
+            }
+
+            for (int i = 0; i < keys.Length; i++)
+            {
+                Assert.Equal(keys.Length - i, enumerable.Count());
+                Assert.Equal(
+                    Enumerable.Range(i, keys.Length - i).Select(j => new KeyValuePair<object, object>(keys[j], values[j])),
+                    enumerable);
+                cwt.Remove(keys[i]);
+            }
+            Assert.Equal(0, enumerable.Count());
+
+            GC.KeepAlive(keys);
+            GC.KeepAlive(values);
+        }
+
+        [Fact]
+        public static void GetEnumerator_ItemsAddedAfterGetEnumeratorNotIncluded()
+        {
+            var cwt = new ConditionalWeakTable<object, object>();
+            var enumerable = (IEnumerable<KeyValuePair<object, object>>)cwt;
+
+            object key1 = new object(), key2 = new object(), value1 = new object(), value2 = new object();
+
+            cwt.Add(key1, value1);
+            IEnumerator<KeyValuePair<object, object>> enumerator1 = enumerable.GetEnumerator();
+            cwt.Add(key2, value2);
+            IEnumerator<KeyValuePair<object, object>> enumerator2 = enumerable.GetEnumerator();
+
+            Assert.True(enumerator1.MoveNext());
+            Assert.Equal(new KeyValuePair<object, object>(key1, value1), enumerator1.Current);
+            Assert.False(enumerator1.MoveNext());
+
+            Assert.True(enumerator2.MoveNext());
+            Assert.Equal(new KeyValuePair<object, object>(key1, value1), enumerator2.Current);
+            Assert.True(enumerator2.MoveNext());
+            Assert.Equal(new KeyValuePair<object, object>(key2, value2), enumerator2.Current);
+            Assert.False(enumerator2.MoveNext());
+
+            enumerator1.Dispose();
+            enumerator2.Dispose();
+
+            GC.KeepAlive(key1);
+            GC.KeepAlive(key2);
+            GC.KeepAlive(value1);
+            GC.KeepAlive(value2);
+        }
+
+        [Fact]
+        public static void GetEnumerator_ItemsRemovedAfterGetEnumeratorNotIncluded()
+        {
+            var cwt = new ConditionalWeakTable<object, object>();
+            var enumerable = (IEnumerable<KeyValuePair<object, object>>)cwt;
+
+            object key1 = new object(), key2 = new object(), value1 = new object(), value2 = new object();
+
+            cwt.Add(key1, value1);
+            cwt.Add(key2, value2);
+            IEnumerator<KeyValuePair<object, object>> enumerator1 = enumerable.GetEnumerator();
+            cwt.Remove(key1);
+            IEnumerator<KeyValuePair<object, object>> enumerator2 = enumerable.GetEnumerator();
+
+            Assert.True(enumerator1.MoveNext());
+            Assert.Equal(new KeyValuePair<object, object>(key2, value2), enumerator1.Current);
+            Assert.False(enumerator1.MoveNext());
+
+            Assert.True(enumerator2.MoveNext());
+            Assert.Equal(new KeyValuePair<object, object>(key2, value2), enumerator2.Current);
+            Assert.False(enumerator2.MoveNext());
+
+            enumerator1.Dispose();
+            enumerator2.Dispose();
+
+            GC.KeepAlive(key1);
+            GC.KeepAlive(key2);
+            GC.KeepAlive(value1);
+            GC.KeepAlive(value2);
+        }
+
+        [Fact]
+        public static void GetEnumerator_ItemsClearedAfterGetEnumeratorNotIncluded()
+        {
+            var cwt = new ConditionalWeakTable<object, object>();
+            var enumerable = (IEnumerable<KeyValuePair<object, object>>)cwt;
+
+            object key1 = new object(), key2 = new object(), value1 = new object(), value2 = new object();
+
+            cwt.Add(key1, value1);
+            cwt.Add(key2, value2);
+            IEnumerator<KeyValuePair<object, object>> enumerator1 = enumerable.GetEnumerator();
+            cwt.Clear();
+            IEnumerator<KeyValuePair<object, object>> enumerator2 = enumerable.GetEnumerator();
+
+            Assert.False(enumerator1.MoveNext());
+            Assert.False(enumerator2.MoveNext());
+
+            enumerator1.Dispose();
+            enumerator2.Dispose();
+
+            GC.KeepAlive(key1);
+            GC.KeepAlive(key2);
+            GC.KeepAlive(value1);
+            GC.KeepAlive(value2);
+        }
+
+        [Fact]
+        public static void GetEnumerator_Current_ThrowsOnInvalidUse()
+        {
+            var cwt = new ConditionalWeakTable<object, object>();
+            var enumerable = (IEnumerable<KeyValuePair<object, object>>)cwt;
+
+            object key1 = new object(), value1 = new object();
+            cwt.Add(key1, value1);
+
+            using (IEnumerator<KeyValuePair<object, object>> enumerator = enumerable.GetEnumerator())
+            {
+                Assert.Throws<InvalidOperationException>(() => enumerator.Current); // before first MoveNext
+            }
+
+            GC.KeepAlive(key1);
+            GC.KeepAlive(value1);
+        }
     }
 }
diff --git a/src/libraries/System.Runtime/tests/System/Runtime/CompilerServices/ConditionalWeakTableTests.netcoreapp.cs b/src/libraries/System.Runtime/tests/System/Runtime/CompilerServices/ConditionalWeakTableTests.netcoreapp.cs
deleted file mode 100644 (file)
index ca44f62..0000000
+++ /dev/null
@@ -1,295 +0,0 @@
-// 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;
-using System.Collections.Generic;
-using System.Runtime.CompilerServices;
-using System.Linq;
-using Xunit;
-
-namespace System.Runtime.CompilerServices.Tests
-{
-    public partial class ConditionalWeakTableTests
-    {
-        [Fact]
-        public static void AddOrUpdateDataTest()
-        {
-            var cwt = new ConditionalWeakTable<string, string>();
-            string key = "key1";
-            cwt.AddOrUpdate(key, "value1");
-
-            string value;
-            Assert.True(cwt.TryGetValue(key, out value));
-            Assert.Equal("value1", value);
-            Assert.Equal(value, cwt.GetOrCreateValue(key));
-            Assert.Equal(value, cwt.GetValue(key, k => "value1"));
-
-            Assert.Throws<ArgumentNullException>(() => cwt.AddOrUpdate(null, "value2"));
-
-            cwt.AddOrUpdate(key, "value2");
-            Assert.True(cwt.TryGetValue(key, out value));
-            Assert.Equal("value2", value);
-            Assert.Equal(value, cwt.GetOrCreateValue(key));
-            Assert.Equal(value, cwt.GetValue(key, k => "value1"));
-        }
-
-        [Fact]
-        public static void Clear_EmptyTable()
-        {
-            var cwt = new ConditionalWeakTable<object, object>();
-            cwt.Clear(); // no exception
-            cwt.Clear();
-        }
-
-        [Fact]
-        public static void Clear_AddThenEmptyRepeatedly_ItemsRemoved()
-        {
-            var cwt = new ConditionalWeakTable<object, object>();
-            object key = new object(), value = new object();
-            object result;
-            for (int i = 0; i < 3; i++)
-            {
-                cwt.Add(key, value);
-
-                Assert.True(cwt.TryGetValue(key, out result));
-                Assert.Same(value, result);
-
-                cwt.Clear();
-
-                Assert.False(cwt.TryGetValue(key, out result));
-                Assert.Null(result);
-            }
-        }
-
-        [Fact]
-        public static void Clear_AddMany_Clear_AllItemsRemoved()
-        {
-            var cwt = new ConditionalWeakTable<object, object>();
-
-            object[] keys = Enumerable.Range(0, 33).Select(_ => new object()).ToArray();
-            object[] values = Enumerable.Range(0, keys.Length).Select(_ => new object()).ToArray();
-            for (int i = 0; i < keys.Length; i++)
-            {
-                cwt.Add(keys[i], values[i]);
-            }
-
-            Assert.Equal(keys.Length, ((IEnumerable<KeyValuePair<object, object>>)cwt).Count());
-
-            cwt.Clear();
-
-            Assert.Equal(0, ((IEnumerable<KeyValuePair<object, object>>)cwt).Count());
-
-            GC.KeepAlive(keys);
-            GC.KeepAlive(values);
-        }
-
-        [Fact]
-        public static void GetEnumerator_Empty_ReturnsEmptyEnumerator()
-        {
-            var cwt = new ConditionalWeakTable<object, object>();
-            var enumerable = (IEnumerable<KeyValuePair<object, object>>)cwt;
-            Assert.Equal(0, enumerable.Count());
-        }
-
-        [Fact]
-        public static void GetEnumerator_AddedAndRemovedItems_AppropriatelyShowUpInEnumeration()
-        {
-            var cwt = new ConditionalWeakTable<object, object>();
-            var enumerable = (IEnumerable<KeyValuePair<object, object>>)cwt;
-
-            object key1 = new object(), value1 = new object();
-
-            for (int i = 0; i < 20; i++) // adding and removing multiple times, across internal container boundary
-            {
-                cwt.Add(key1, value1);
-                Assert.Equal(1, enumerable.Count());
-                Assert.Equal(new KeyValuePair<object, object>(key1, value1), enumerable.First());
-
-                Assert.True(cwt.Remove(key1));
-                Assert.Equal(0, enumerable.Count());
-            }
-
-            GC.KeepAlive(key1);
-            GC.KeepAlive(value1);
-        }
-
-        [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsPreciseGcSupported))]
-        public static void GetEnumerator_CollectedItemsNotEnumerated()
-        {
-            var cwt = new ConditionalWeakTable<object, object>();
-            var enumerable = (IEnumerable<KeyValuePair<object, object>>)cwt;
-
-            // Delegate to add collectible items to the table, separated out
-            // to avoid the JIT extending the lifetimes of the temporaries
-            Action<ConditionalWeakTable<object, object>> addItem =
-                t => t.Add(new object(), new object());
-
-            for (int i = 0; i < 10; i++) addItem(cwt);
-            GC.Collect();
-            Assert.Equal(0, enumerable.Count());
-        }
-
-        [Fact]
-        public static void GetEnumerator_MultipleEnumeratorsReturnSameResults()
-        {
-            var cwt = new ConditionalWeakTable<object, object>();
-            var enumerable = (IEnumerable<KeyValuePair<object, object>>)cwt;
-
-            object[] keys = Enumerable.Range(0, 33).Select(_ => new object()).ToArray();
-            object[] values = Enumerable.Range(0, keys.Length).Select(_ => new object()).ToArray();
-            for (int i = 0; i < keys.Length; i++)
-            {
-                cwt.Add(keys[i], values[i]);
-            }
-
-            using (IEnumerator<KeyValuePair<object, object>> enumerator1 = enumerable.GetEnumerator())
-            using (IEnumerator<KeyValuePair<object, object>> enumerator2 = enumerable.GetEnumerator())
-            {
-                while (enumerator1.MoveNext())
-                {
-                    Assert.True(enumerator2.MoveNext());
-                    Assert.Equal(enumerator1.Current, enumerator2.Current);
-                }
-                Assert.False(enumerator2.MoveNext());
-            }
-
-            GC.KeepAlive(keys);
-            GC.KeepAlive(values);
-        }
-
-        [Fact]
-        public static void GetEnumerator_RemovedItems_RemovedFromResults()
-        {
-            var cwt = new ConditionalWeakTable<object, object>();
-            var enumerable = (IEnumerable<KeyValuePair<object, object>>)cwt;
-
-            object[] keys = Enumerable.Range(0, 33).Select(_ => new object()).ToArray();
-            object[] values = Enumerable.Range(0, keys.Length).Select(_ => new object()).ToArray();
-            for (int i = 0; i < keys.Length; i++)
-            {
-                cwt.Add(keys[i], values[i]);
-            }
-
-            for (int i = 0; i < keys.Length; i++)
-            {
-                Assert.Equal(keys.Length - i, enumerable.Count());
-                Assert.Equal(
-                    Enumerable.Range(i, keys.Length - i).Select(j => new KeyValuePair<object, object>(keys[j], values[j])),
-                    enumerable);
-                cwt.Remove(keys[i]);
-            }
-            Assert.Equal(0, enumerable.Count());
-
-            GC.KeepAlive(keys);
-            GC.KeepAlive(values);
-        }
-
-        [Fact]
-        public static void GetEnumerator_ItemsAddedAfterGetEnumeratorNotIncluded()
-        {
-            var cwt = new ConditionalWeakTable<object, object>();
-            var enumerable = (IEnumerable<KeyValuePair<object, object>>)cwt;
-
-            object key1 = new object(), key2 = new object(), value1 = new object(), value2 = new object();
-
-            cwt.Add(key1, value1);
-            IEnumerator<KeyValuePair<object, object>> enumerator1 = enumerable.GetEnumerator();
-            cwt.Add(key2, value2);
-            IEnumerator<KeyValuePair<object, object>> enumerator2 = enumerable.GetEnumerator();
-
-            Assert.True(enumerator1.MoveNext());
-            Assert.Equal(new KeyValuePair<object, object>(key1, value1), enumerator1.Current);
-            Assert.False(enumerator1.MoveNext());
-
-            Assert.True(enumerator2.MoveNext());
-            Assert.Equal(new KeyValuePair<object, object>(key1, value1), enumerator2.Current);
-            Assert.True(enumerator2.MoveNext());
-            Assert.Equal(new KeyValuePair<object, object>(key2, value2), enumerator2.Current);
-            Assert.False(enumerator2.MoveNext());
-
-            enumerator1.Dispose();
-            enumerator2.Dispose();
-
-            GC.KeepAlive(key1);
-            GC.KeepAlive(key2);
-            GC.KeepAlive(value1);
-            GC.KeepAlive(value2);
-        }
-
-        [Fact]
-        public static void GetEnumerator_ItemsRemovedAfterGetEnumeratorNotIncluded()
-        {
-            var cwt = new ConditionalWeakTable<object, object>();
-            var enumerable = (IEnumerable<KeyValuePair<object, object>>)cwt;
-
-            object key1 = new object(), key2 = new object(), value1 = new object(), value2 = new object();
-
-            cwt.Add(key1, value1);
-            cwt.Add(key2, value2);
-            IEnumerator<KeyValuePair<object, object>> enumerator1 = enumerable.GetEnumerator();
-            cwt.Remove(key1);
-            IEnumerator<KeyValuePair<object, object>> enumerator2 = enumerable.GetEnumerator();
-
-            Assert.True(enumerator1.MoveNext());
-            Assert.Equal(new KeyValuePair<object, object>(key2, value2), enumerator1.Current);
-            Assert.False(enumerator1.MoveNext());
-
-            Assert.True(enumerator2.MoveNext());
-            Assert.Equal(new KeyValuePair<object, object>(key2, value2), enumerator2.Current);
-            Assert.False(enumerator2.MoveNext());
-
-            enumerator1.Dispose();
-            enumerator2.Dispose();
-
-            GC.KeepAlive(key1);
-            GC.KeepAlive(key2);
-            GC.KeepAlive(value1);
-            GC.KeepAlive(value2);
-        }
-
-        [Fact]
-        public static void GetEnumerator_ItemsClearedAfterGetEnumeratorNotIncluded()
-        {
-            var cwt = new ConditionalWeakTable<object, object>();
-            var enumerable = (IEnumerable<KeyValuePair<object, object>>)cwt;
-
-            object key1 = new object(), key2 = new object(), value1 = new object(), value2 = new object();
-
-            cwt.Add(key1, value1);
-            cwt.Add(key2, value2);
-            IEnumerator<KeyValuePair<object, object>> enumerator1 = enumerable.GetEnumerator();
-            cwt.Clear();
-            IEnumerator<KeyValuePair<object, object>> enumerator2 = enumerable.GetEnumerator();
-
-            Assert.False(enumerator1.MoveNext());
-            Assert.False(enumerator2.MoveNext());
-
-            enumerator1.Dispose();
-            enumerator2.Dispose();
-
-            GC.KeepAlive(key1);
-            GC.KeepAlive(key2);
-            GC.KeepAlive(value1);
-            GC.KeepAlive(value2);
-        }
-
-        [Fact]
-        public static void GetEnumerator_Current_ThrowsOnInvalidUse()
-        {
-            var cwt = new ConditionalWeakTable<object, object>();
-            var enumerable = (IEnumerable<KeyValuePair<object, object>>)cwt;
-
-            object key1 = new object(), value1 = new object();
-            cwt.Add(key1, value1);
-
-            using (IEnumerator<KeyValuePair<object, object>> enumerator = enumerable.GetEnumerator())
-            {
-                Assert.Throws<InvalidOperationException>(() => enumerator.Current); // before first MoveNext
-            }
-
-            GC.KeepAlive(key1);
-            GC.KeepAlive(value1);
-        }
-    }
-}
index 266196a..bd4054d 100644 (file)
@@ -7,11 +7,12 @@ using System.Reflection;
 using System.Collections;
 using System.Collections.Generic;
 using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
 using Xunit;
 
 namespace System.Runtime.CompilerServices.Tests
 {
-    public static partial class RuntimeHelpersTests
+    public static class RuntimeHelpersTests
     {
         [Fact]
         public static void GetHashCodeTest()
@@ -178,30 +179,104 @@ namespace System.Runtime.CompilerServices.Tests
             RuntimeHelpers.PrepareDelegate((Func<int>)(() => 1) + (Func<int>)(() => 2));
             RuntimeHelpers.PrepareDelegate(null);
         }
-    }
 
-    public struct Age
-    {
-        public int years;
-        public int months;
-    }
+        [Fact]
+        public static void TryEnsureSufficientExecutionStack_SpaceAvailable_ReturnsTrue()
+        {
+            Assert.True(RuntimeHelpers.TryEnsureSufficientExecutionStack());
+        }
 
-    public class FixedClass
-    {
-        [FixedAddressValueType]
-        public static Age FixedAge;
+        [Fact]
+        public static void TryEnsureSufficientExecutionStack_NoSpaceAvailable_ReturnsFalse()
+        {
+            FillStack(depth: 0);
+        }
 
-        public static unsafe IntPtr AddressOfFixedAge()
+        [MethodImpl(MethodImplOptions.NoInlining)]
+        private static void FillStack(int depth)
         {
-            fixed (Age* pointer = &FixedAge)
+            // This test will fail with a StackOverflowException if TryEnsureSufficientExecutionStack() doesn't
+            // return false. No exception is thrown and the test finishes when TryEnsureSufficientExecutionStack()
+            // returns true.
+            if (!RuntimeHelpers.TryEnsureSufficientExecutionStack())
             {
-                return (IntPtr)pointer;
+                Assert.Throws<InsufficientExecutionStackException>(() => RuntimeHelpers.EnsureSufficientExecutionStack());
+                return;
+            }
+            else if (depth < 2048)
+            {
+                FillStack(depth + 1);
             }
         }
-    }
 
-    public static partial class RuntimeHelpersTests
-    {
+        [Fact]
+        public static void GetUninitializedObject_InvalidArguments_ThrowsException()
+        {
+            AssertExtensions.Throws<ArgumentNullException>("type", () => RuntimeHelpers.GetUninitializedObject(null));
+
+            AssertExtensions.Throws<ArgumentException>(null, () => RuntimeHelpers.GetUninitializedObject(typeof(string))); // special type
+            Assert.Throws<MemberAccessException>(() => RuntimeHelpers.GetUninitializedObject(typeof(System.IO.Stream))); // abstract type
+            Assert.Throws<MemberAccessException>(() => RuntimeHelpers.GetUninitializedObject(typeof(System.Collections.IEnumerable))); // interface
+            Assert.Throws<MemberAccessException>(() => RuntimeHelpers.GetUninitializedObject(typeof(System.Collections.Generic.List<>))); // generic definition
+            Assert.Throws<NotSupportedException>(() => RuntimeHelpers.GetUninitializedObject(typeof(TypedReference))); // byref-like type
+        }
+
+        [Fact]
+        public static void GetUninitializedObject_DoesNotRunConstructor()
+        {
+            Assert.Equal(42, new ObjectWithDefaultCtor().Value);
+            Assert.Equal(0, ((ObjectWithDefaultCtor)RuntimeHelpers.GetUninitializedObject(typeof(ObjectWithDefaultCtor))).Value);
+        }
+
+        [Fact]
+        public static void GetUninitializedObject_Nullable()
+        {
+            // Nullable returns the underlying type instead
+            Assert.Equal(typeof(int), RuntimeHelpers.GetUninitializedObject(typeof(Nullable<int>)).GetType());
+        }
+
+        private class ObjectWithDefaultCtor
+        {
+            public int Value = 42;
+        }
+
+        [Fact]
+        public static void IsReferenceOrContainsReferences()
+        {
+            Assert.False(RuntimeHelpers.IsReferenceOrContainsReferences<int>());
+            Assert.True(RuntimeHelpers.IsReferenceOrContainsReferences<string>());
+            Assert.False(RuntimeHelpers.IsReferenceOrContainsReferences<Guid>());
+            Assert.False(RuntimeHelpers.IsReferenceOrContainsReferences<StructWithoutReferences>());
+            Assert.True(RuntimeHelpers.IsReferenceOrContainsReferences<StructWithReferences>());
+        }
+
+        [Fact]
+        public static void ArrayRangeHelperTest()
+        {
+            int[] a = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
+            Range range = Range.All;
+            Assert.Equal(a, RuntimeHelpers.GetSubArray(a, range));
+
+            range = new Range(Index.FromStart(1), Index.FromEnd(5));
+            Assert.Equal(new int [] { 2, 3, 4, 5}, RuntimeHelpers.GetSubArray(a, range));
+
+            range = new Range(Index.FromStart(0), Index.FromStart(a.Length + 1));
+            Assert.Throws<ArgumentOutOfRangeException>(() => { int [] array = RuntimeHelpers.GetSubArray(a, range); });
+        }
+
+        [StructLayoutAttribute(LayoutKind.Sequential)]
+        private struct StructWithoutReferences
+        {
+            public int a, b, c;
+        }
+
+        [StructLayoutAttribute(LayoutKind.Sequential)]
+        private struct StructWithReferences
+        {
+            public int a, b, c;
+            public object d;
+        }
+
         [Fact]
         public static void FixedAddressValueTypeTest()
         {
@@ -218,4 +293,24 @@ namespace System.Runtime.CompilerServices.Tests
             Assert.Equal(fixedPtr1, fixedPtr2);
         }
     }
+
+    public struct Age
+    {
+        public int years;
+        public int months;
+    }
+
+    public class FixedClass
+    {
+        [FixedAddressValueType]
+        public static Age FixedAge;
+
+        public static unsafe IntPtr AddressOfFixedAge()
+        {
+            fixed (Age* pointer = &FixedAge)
+            {
+                return (IntPtr)pointer;
+            }
+        }
+    }
 }
diff --git a/src/libraries/System.Runtime/tests/System/Runtime/CompilerServices/RuntimeHelpersTests.netcoreapp.cs b/src/libraries/System.Runtime/tests/System/Runtime/CompilerServices/RuntimeHelpersTests.netcoreapp.cs
deleted file mode 100644 (file)
index 3c71a58..0000000
+++ /dev/null
@@ -1,110 +0,0 @@
-// 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.Runtime.InteropServices;
-
-using Xunit;
-
-namespace System.Runtime.CompilerServices.Tests
-{
-    public static partial class RuntimeHelpersTests
-    {
-        [Fact]
-        public static void TryEnsureSufficientExecutionStack_SpaceAvailable_ReturnsTrue()
-        {
-            Assert.True(RuntimeHelpers.TryEnsureSufficientExecutionStack());
-        }
-
-        [Fact]
-        public static void TryEnsureSufficientExecutionStack_NoSpaceAvailable_ReturnsFalse()
-        {
-            FillStack(depth: 0);
-        }
-
-        [MethodImpl(MethodImplOptions.NoInlining)]
-        private static void FillStack(int depth)
-        {
-            // This test will fail with a StackOverflowException if TryEnsureSufficientExecutionStack() doesn't
-            // return false. No exception is thrown and the test finishes when TryEnsureSufficientExecutionStack()
-            // returns true.
-            if (!RuntimeHelpers.TryEnsureSufficientExecutionStack())
-            {
-                Assert.Throws<InsufficientExecutionStackException>(() => RuntimeHelpers.EnsureSufficientExecutionStack());
-                return;
-            }
-            else if (depth < 2048)
-            {
-                FillStack(depth + 1);
-            }
-        }
-
-        [Fact]
-        public static void GetUninitializedObject_InvalidArguments_ThrowsException()
-        {
-            AssertExtensions.Throws<ArgumentNullException>("type", () => RuntimeHelpers.GetUninitializedObject(null));
-
-            AssertExtensions.Throws<ArgumentException>(null, () => RuntimeHelpers.GetUninitializedObject(typeof(string))); // special type
-            Assert.Throws<MemberAccessException>(() => RuntimeHelpers.GetUninitializedObject(typeof(System.IO.Stream))); // abstract type
-            Assert.Throws<MemberAccessException>(() => RuntimeHelpers.GetUninitializedObject(typeof(System.Collections.IEnumerable))); // interface
-            Assert.Throws<MemberAccessException>(() => RuntimeHelpers.GetUninitializedObject(typeof(System.Collections.Generic.List<>))); // generic definition
-            Assert.Throws<NotSupportedException>(() => RuntimeHelpers.GetUninitializedObject(typeof(TypedReference))); // byref-like type
-        }
-
-        [Fact]
-        public static void GetUninitializedObject_DoesNotRunConstructor()
-        {
-            Assert.Equal(42, new ObjectWithDefaultCtor().Value);
-            Assert.Equal(0, ((ObjectWithDefaultCtor)RuntimeHelpers.GetUninitializedObject(typeof(ObjectWithDefaultCtor))).Value);
-        }
-
-        [Fact]
-        public static void GetUninitializedObject_Nullable()
-        {
-            // Nullable returns the underlying type instead
-            Assert.Equal(typeof(int), RuntimeHelpers.GetUninitializedObject(typeof(Nullable<int>)).GetType());
-        }
-
-        private class ObjectWithDefaultCtor
-        {
-            public int Value = 42;
-        }
-
-        [Fact]
-        public static void IsReferenceOrContainsReferences()
-        {
-            Assert.False(RuntimeHelpers.IsReferenceOrContainsReferences<int>());
-            Assert.True(RuntimeHelpers.IsReferenceOrContainsReferences<string>());
-            Assert.False(RuntimeHelpers.IsReferenceOrContainsReferences<Guid>());
-            Assert.False(RuntimeHelpers.IsReferenceOrContainsReferences<StructWithoutReferences>());
-            Assert.True(RuntimeHelpers.IsReferenceOrContainsReferences<StructWithReferences>());
-        }
-
-        [Fact]
-        public static void ArrayRangeHelperTest()
-        {
-            int[] a = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
-            Range range = Range.All;
-            Assert.Equal(a, RuntimeHelpers.GetSubArray(a, range));
-
-            range = new Range(Index.FromStart(1), Index.FromEnd(5));
-            Assert.Equal(new int [] { 2, 3, 4, 5}, RuntimeHelpers.GetSubArray(a, range));
-
-            range = new Range(Index.FromStart(0), Index.FromStart(a.Length + 1));
-            Assert.Throws<ArgumentOutOfRangeException>(() => { int [] array = RuntimeHelpers.GetSubArray(a, range); });
-        }
-
-        [StructLayoutAttribute(LayoutKind.Sequential)]
-        private struct StructWithoutReferences
-        {
-            public int a, b, c;
-        }
-
-        [StructLayoutAttribute(LayoutKind.Sequential)]
-        private struct StructWithReferences
-        {
-            public int a, b, c;
-            public object d;
-        }
-    }
-}
index 439b5a2..3256c29 100644 (file)
@@ -309,5 +309,104 @@ namespace System.Tests
             AssertExtensions.Throws<ArgumentException>(paramName, () => sbyte.Parse("1", style));
             AssertExtensions.Throws<ArgumentException>(paramName, () => sbyte.Parse("1", style, null));
         }
+
+        public static IEnumerable<object[]> Parse_ValidWithOffsetCount_TestData()
+        {
+            foreach (object[] inputs in Parse_Valid_TestData())
+            {
+                yield return new object[] { inputs[0], 0, ((string)inputs[0]).Length, inputs[1], inputs[2], inputs[3] };
+            }
+
+            yield return new object[] { "-123", 0, 2, NumberStyles.Integer, null, (sbyte)-1 };
+            yield return new object[] { "-123", 1, 3, NumberStyles.Integer, null, (sbyte)123 };
+            yield return new object[] { "12", 0, 1, NumberStyles.HexNumber, null, (sbyte)0x1 };
+            yield return new object[] { "12", 1, 1, NumberStyles.HexNumber, null, (sbyte)0x2 };
+            yield return new object[] { "(123)", 1, 3, NumberStyles.AllowParentheses, null, (sbyte)123 };
+            yield return new object[] { "$100", 1, 1, NumberStyles.Currency, new NumberFormatInfo() { CurrencySymbol = "$" }, (sbyte)1 };
+        }
+
+        [Theory]
+        [MemberData(nameof(Parse_ValidWithOffsetCount_TestData))]
+        public static void Parse_Span_Valid(string value, int offset, int count, NumberStyles style, IFormatProvider provider, sbyte expected)
+        {
+            sbyte result;
+
+            // Default style and provider
+            if (style == NumberStyles.Integer && provider == null)
+            {
+                Assert.True(sbyte.TryParse(value.AsSpan(offset, count), out result));
+                Assert.Equal(expected, result);
+            }
+
+            Assert.Equal(expected, sbyte.Parse(value.AsSpan(offset, count), style, provider));
+
+            Assert.True(sbyte.TryParse(value.AsSpan(offset, count), style, provider, out result));
+            Assert.Equal(expected, result);
+        }
+
+        [Theory]
+        [MemberData(nameof(Parse_Invalid_TestData))]
+        public static void Parse_Span_Invalid(string value, NumberStyles style, IFormatProvider provider, Type exceptionType)
+        {
+            if (value != null)
+            {
+                sbyte result;
+
+                // Default style and provider
+                if (style == NumberStyles.Integer && provider == null)
+                {
+                    Assert.False(sbyte.TryParse(value.AsSpan(), out result));
+                    Assert.Equal(0, result);
+                }
+
+                Assert.Throws(exceptionType, () => sbyte.Parse(value.AsSpan(), style, provider));
+
+                Assert.False(sbyte.TryParse(value.AsSpan(), style, provider, out result));
+                Assert.Equal(0, result);
+            }
+        }
+
+        [Theory]
+        [MemberData(nameof(ToString_TestData))]
+        public static void TryFormat(sbyte i, string format, IFormatProvider provider, string expected)
+        {
+            char[] actual;
+            int charsWritten;
+
+            // Just right
+            actual = new char[expected.Length];
+            Assert.True(i.TryFormat(actual.AsSpan(), out charsWritten, format, provider));
+            Assert.Equal(expected.Length, charsWritten);
+            Assert.Equal(expected, new string(actual));
+
+            // Longer than needed
+            actual = new char[expected.Length + 1];
+            Assert.True(i.TryFormat(actual.AsSpan(), out charsWritten, format, provider));
+            Assert.Equal(expected.Length, charsWritten);
+            Assert.Equal(expected, new string(actual, 0, charsWritten));
+
+            // Too short
+            if (expected.Length > 0)
+            {
+                actual = new char[expected.Length - 1];
+                Assert.False(i.TryFormat(actual.AsSpan(), out charsWritten, format, provider));
+                Assert.Equal(0, charsWritten);
+            }
+
+            if (format != null)
+            {
+                // Upper format
+                actual = new char[expected.Length];
+                Assert.True(i.TryFormat(actual.AsSpan(), out charsWritten, format.ToUpperInvariant(), provider));
+                Assert.Equal(expected.Length, charsWritten);
+                Assert.Equal(expected.ToUpperInvariant(), new string(actual));
+
+                // Lower format
+                actual = new char[expected.Length];
+                Assert.True(i.TryFormat(actual.AsSpan(), out charsWritten, format.ToLowerInvariant(), provider));
+                Assert.Equal(expected.Length, charsWritten);
+                Assert.Equal(expected.ToLowerInvariant(), new string(actual));
+            }
+        }
     }
 }
diff --git a/src/libraries/System.Runtime/tests/System/SByteTests.netcoreapp.cs b/src/libraries/System.Runtime/tests/System/SByteTests.netcoreapp.cs
deleted file mode 100644 (file)
index 513b9b5..0000000
+++ /dev/null
@@ -1,112 +0,0 @@
-// 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.Globalization;
-using Xunit;
-
-namespace System.Tests
-{
-    public partial class SByteTests
-    {
-        public static IEnumerable<object[]> Parse_ValidWithOffsetCount_TestData()
-        {
-            foreach (object[] inputs in Parse_Valid_TestData())
-            {
-                yield return new object[] { inputs[0], 0, ((string)inputs[0]).Length, inputs[1], inputs[2], inputs[3] };
-            }
-
-            yield return new object[] { "-123", 0, 2, NumberStyles.Integer, null, (sbyte)-1 };
-            yield return new object[] { "-123", 1, 3, NumberStyles.Integer, null, (sbyte)123 };
-            yield return new object[] { "12", 0, 1, NumberStyles.HexNumber, null, (sbyte)0x1 };
-            yield return new object[] { "12", 1, 1, NumberStyles.HexNumber, null, (sbyte)0x2 };
-            yield return new object[] { "(123)", 1, 3, NumberStyles.AllowParentheses, null, (sbyte)123 };
-            yield return new object[] { "$100", 1, 1, NumberStyles.Currency, new NumberFormatInfo() { CurrencySymbol = "$" }, (sbyte)1 };
-        }
-
-        [Theory]
-        [MemberData(nameof(Parse_ValidWithOffsetCount_TestData))]
-        public static void Parse_Span_Valid(string value, int offset, int count, NumberStyles style, IFormatProvider provider, sbyte expected)
-        {
-            sbyte result;
-
-            // Default style and provider
-            if (style == NumberStyles.Integer && provider == null)
-            {
-                Assert.True(sbyte.TryParse(value.AsSpan(offset, count), out result));
-                Assert.Equal(expected, result);
-            }
-
-            Assert.Equal(expected, sbyte.Parse(value.AsSpan(offset, count), style, provider));
-
-            Assert.True(sbyte.TryParse(value.AsSpan(offset, count), style, provider, out result));
-            Assert.Equal(expected, result);
-        }
-
-        [Theory]
-        [MemberData(nameof(Parse_Invalid_TestData))]
-        public static void Parse_Span_Invalid(string value, NumberStyles style, IFormatProvider provider, Type exceptionType)
-        {
-            if (value != null)
-            {
-                sbyte result;
-
-                // Default style and provider
-                if (style == NumberStyles.Integer && provider == null)
-                {
-                    Assert.False(sbyte.TryParse(value.AsSpan(), out result));
-                    Assert.Equal(0, result);
-                }
-
-                Assert.Throws(exceptionType, () => sbyte.Parse(value.AsSpan(), style, provider));
-
-                Assert.False(sbyte.TryParse(value.AsSpan(), style, provider, out result));
-                Assert.Equal(0, result);
-            }
-        }
-
-        [Theory]
-        [MemberData(nameof(ToString_TestData))]
-        public static void TryFormat(sbyte i, string format, IFormatProvider provider, string expected)
-        {
-            char[] actual;
-            int charsWritten;
-
-            // Just right
-            actual = new char[expected.Length];
-            Assert.True(i.TryFormat(actual.AsSpan(), out charsWritten, format, provider));
-            Assert.Equal(expected.Length, charsWritten);
-            Assert.Equal(expected, new string(actual));
-
-            // Longer than needed
-            actual = new char[expected.Length + 1];
-            Assert.True(i.TryFormat(actual.AsSpan(), out charsWritten, format, provider));
-            Assert.Equal(expected.Length, charsWritten);
-            Assert.Equal(expected, new string(actual, 0, charsWritten));
-
-            // Too short
-            if (expected.Length > 0)
-            {
-                actual = new char[expected.Length - 1];
-                Assert.False(i.TryFormat(actual.AsSpan(), out charsWritten, format, provider));
-                Assert.Equal(0, charsWritten);
-            }
-
-            if (format != null)
-            {
-                // Upper format
-                actual = new char[expected.Length];
-                Assert.True(i.TryFormat(actual.AsSpan(), out charsWritten, format.ToUpperInvariant(), provider));
-                Assert.Equal(expected.Length, charsWritten);
-                Assert.Equal(expected.ToUpperInvariant(), new string(actual));
-
-                // Lower format
-                actual = new char[expected.Length];
-                Assert.True(i.TryFormat(actual.AsSpan(), out charsWritten, format.ToLowerInvariant(), provider));
-                Assert.Equal(expected.Length, charsWritten);
-                Assert.Equal(expected.ToLowerInvariant(), new string(actual));
-            }
-        }
-    }
-}
index b7c6bf9..a030d0c 100644 (file)
@@ -491,5 +491,218 @@ namespace System.Tests
             Assert.Throws<FormatException>(() => f.ToString("Y")); // Invalid format
             Assert.Throws<FormatException>(() => f.ToString("Y", null)); // Invalid format
         }
+
+        [Theory]
+        [InlineData(float.NegativeInfinity, false)]     // Negative Infinity
+        [InlineData(float.MinValue, true)]              // Min Negative Normal
+        [InlineData(-1.17549435E-38f, true)]            // Max Negative Normal
+        [InlineData(-1.17549421E-38f, true)]            // Min Negative Subnormal
+        [InlineData(-1.401298E-45, true)]               // Max Negative Subnormal
+        [InlineData(-0.0f, true)]                       // Negative Zero
+        [InlineData(float.NaN, false)]                  // NaN
+        [InlineData(0.0f, true)]                        // Positive Zero
+        [InlineData(1.401298E-45, true)]                // Min Positive Subnormal
+        [InlineData(1.17549421E-38f, true)]             // Max Positive Subnormal
+        [InlineData(1.17549435E-38f, true)]             // Min Positive Normal
+        [InlineData(float.MaxValue, true)]              // Max Positive Normal
+        [InlineData(float.PositiveInfinity, false)]     // Positive Infinity
+        public static void IsFinite(float d, bool expected)
+        {
+            Assert.Equal(expected, float.IsFinite(d));
+        }
+
+        [Theory]
+        [InlineData(float.NegativeInfinity, true)]      // Negative Infinity
+        [InlineData(float.MinValue, true)]              // Min Negative Normal
+        [InlineData(-1.17549435E-38f, true)]            // Max Negative Normal
+        [InlineData(-1.17549421E-38f, true)]            // Min Negative Subnormal
+        [InlineData(-1.401298E-45, true)]               // Max Negative Subnormal
+        [InlineData(-0.0f, true)]                       // Negative Zero
+        [InlineData(float.NaN, true)]                   // NaN
+        [InlineData(0.0f, false)]                       // Positive Zero
+        [InlineData(1.401298E-45, false)]               // Min Positive Subnormal
+        [InlineData(1.17549421E-38f, false)]            // Max Positive Subnormal
+        [InlineData(1.17549435E-38f, false)]            // Min Positive Normal
+        [InlineData(float.MaxValue, false)]             // Max Positive Normal
+        [InlineData(float.PositiveInfinity, false)]     // Positive Infinity
+        public static void IsNegative(float d, bool expected)
+        {
+            Assert.Equal(expected, float.IsNegative(d));
+        }
+
+        [Theory]
+        [InlineData(float.NegativeInfinity, false)]     // Negative Infinity
+        [InlineData(float.MinValue, true)]              // Min Negative Normal
+        [InlineData(-1.17549435E-38f, true)]            // Max Negative Normal
+        [InlineData(-1.17549421E-38f, false)]           // Min Negative Subnormal
+        [InlineData(-1.401298E-45, false)]              // Max Negative Subnormal
+        [InlineData(-0.0f, false)]                      // Negative Zero
+        [InlineData(float.NaN, false)]                  // NaN
+        [InlineData(0.0f, false)]                       // Positive Zero
+        [InlineData(1.401298E-45, false)]               // Min Positive Subnormal
+        [InlineData(1.17549421E-38f, false)]            // Max Positive Subnormal
+        [InlineData(1.17549435E-38f, true)]             // Min Positive Normal
+        [InlineData(float.MaxValue, true)]              // Max Positive Normal
+        [InlineData(float.PositiveInfinity, false)]     // Positive Infinity
+        public static void IsNormal(float d, bool expected)
+        {
+            Assert.Equal(expected, float.IsNormal(d));
+        }
+
+        [Theory]
+        [InlineData(float.NegativeInfinity, false)]     // Negative Infinity
+        [InlineData(float.MinValue, false)]             // Min Negative Normal
+        [InlineData(-1.17549435E-38f, false)]           // Max Negative Normal
+        [InlineData(-1.17549421E-38f, true)]            // Min Negative Subnormal
+        [InlineData(-1.401298E-45, true)]               // Max Negative Subnormal
+        [InlineData(-0.0f, false)]                      // Negative Zero
+        [InlineData(float.NaN, false)]                  // NaN
+        [InlineData(0.0f, false)]                       // Positive Zero
+        [InlineData(1.401298E-45, true)]                // Min Positive Subnormal
+        [InlineData(1.17549421E-38f, true)]             // Max Positive Subnormal
+        [InlineData(1.17549435E-38f, false)]            // Min Positive Normal
+        [InlineData(float.MaxValue, false)]             // Max Positive Normal
+        [InlineData(float.PositiveInfinity, false)]     // Positive Infinity
+        public static void IsSubnormal(float d, bool expected)
+        {
+            Assert.Equal(expected, float.IsSubnormal(d));
+        }
+
+        public static IEnumerable<object[]> Parse_ValidWithOffsetCount_TestData()
+        {
+            foreach (object[] inputs in Parse_Valid_TestData())
+            {
+                yield return new object[] { inputs[0], 0, ((string)inputs[0]).Length, inputs[1], inputs[2], inputs[3] };
+            }
+
+            const NumberStyles DefaultStyle = NumberStyles.Float | NumberStyles.AllowThousands;
+
+            yield return new object[] { "-123", 1, 3, DefaultStyle, null, (float)123 };
+            yield return new object[] { "-123", 0, 3, DefaultStyle, null, (float)-12 };
+            yield return new object[] { "1E23", 0, 3, DefaultStyle, null, (float)1E2 };
+            yield return new object[] { "123", 0, 2, NumberStyles.Float, new NumberFormatInfo(), (float)12 };
+            yield return new object[] { "$1,000", 1, 3, NumberStyles.Currency, new NumberFormatInfo() { CurrencySymbol = "$", CurrencyGroupSeparator = "," }, (float)10 };
+            yield return new object[] { "(123)", 1, 3, NumberStyles.AllowParentheses, new NumberFormatInfo() { NumberDecimalSeparator = "." }, (float)123 };
+            yield return new object[] { "-Infinity", 1, 8, NumberStyles.Any, NumberFormatInfo.InvariantInfo, float.PositiveInfinity };
+        }
+
+        [Theory]
+        [MemberData(nameof(Parse_ValidWithOffsetCount_TestData))]
+        public static void Parse_Span_Valid(string value, int offset, int count, NumberStyles style, IFormatProvider provider, float expected)
+        {
+            bool isDefaultProvider = provider == null || provider == NumberFormatInfo.CurrentInfo;
+            float result;
+            if ((style & ~(NumberStyles.Float | NumberStyles.AllowThousands)) == 0 && style != NumberStyles.None)
+            {
+                // Use Parse(string) or Parse(string, IFormatProvider)
+                if (isDefaultProvider)
+                {
+                    Assert.True(float.TryParse(value.AsSpan(offset, count), out result));
+                    Assert.Equal(expected, result);
+
+                    Assert.Equal(expected, float.Parse(value.AsSpan(offset, count)));
+                }
+
+                Assert.Equal(expected, float.Parse(value.AsSpan(offset, count), provider: provider));
+            }
+
+            Assert.Equal(expected, float.Parse(value.AsSpan(offset, count), style, provider));
+
+            Assert.True(float.TryParse(value.AsSpan(offset, count), style, provider, out result));
+            Assert.Equal(expected, result);
+        }
+
+        [Theory]
+        [MemberData(nameof(Parse_Invalid_TestData))]
+        public static void Parse_Span_Invalid(string value, NumberStyles style, IFormatProvider provider, Type exceptionType)
+        {
+            if (value != null)
+            {
+                Assert.Throws(exceptionType, () => float.Parse(value.AsSpan(), style, provider));
+
+                Assert.False(float.TryParse(value.AsSpan(), style, provider, out float result));
+                Assert.Equal(0, result);
+            }
+        }
+
+        [Fact]
+        public static void TryFormat()
+        {
+            using (new ThreadCultureChange(CultureInfo.InvariantCulture))
+            {
+                foreach (object[] testdata in ToString_TestData())
+                {
+                    float localI = (float)testdata[0];
+                    string localFormat = (string)testdata[1];
+                    IFormatProvider localProvider = (IFormatProvider)testdata[2];
+                    string localExpected = (string)testdata[3];
+
+                    try
+                    {
+                        char[] actual;
+                        int charsWritten;
+
+                        // Just right
+                        actual = new char[localExpected.Length];
+                        Assert.True(localI.TryFormat(actual.AsSpan(), out charsWritten, localFormat, localProvider));
+                        Assert.Equal(localExpected.Length, charsWritten);
+                        Assert.Equal(localExpected, new string(actual));
+
+                        // Longer than needed
+                        actual = new char[localExpected.Length + 1];
+                        Assert.True(localI.TryFormat(actual.AsSpan(), out charsWritten, localFormat, localProvider));
+                        Assert.Equal(localExpected.Length, charsWritten);
+                        Assert.Equal(localExpected, new string(actual, 0, charsWritten));
+
+                        // Too short
+                        if (localExpected.Length > 0)
+                        {
+                            actual = new char[localExpected.Length - 1];
+                            Assert.False(localI.TryFormat(actual.AsSpan(), out charsWritten, localFormat, localProvider));
+                            Assert.Equal(0, charsWritten);
+                        }
+                    }
+                    catch (Exception exc)
+                    {
+                        throw new Exception($"Failed on `{localI}`, `{localFormat}`, `{localProvider}`, `{localExpected}`. {exc}");
+                    }
+                }
+            }
+        }
+
+        public static IEnumerable<object[]> ToStringRoundtrip_TestData()
+        {
+            yield return new object[] { float.NegativeInfinity };
+            yield return new object[] { float.MinValue };
+            yield return new object[] { -MathF.PI };
+            yield return new object[] { -MathF.E };
+            yield return new object[] { -float.Epsilon };
+            yield return new object[] { -0.845512408f };
+            yield return new object[] { -0.0f };
+            yield return new object[] { float.NaN };
+            yield return new object[] { 0.0f };
+            yield return new object[] { 0.845512408f };
+            yield return new object[] { float.Epsilon };
+            yield return new object[] { MathF.E };
+            yield return new object[] { MathF.PI };
+            yield return new object[] { float.MaxValue };
+            yield return new object[] { float.PositiveInfinity };
+        }
+
+        [Theory]
+        [MemberData(nameof(ToStringRoundtrip_TestData))]
+        public static void ToStringRoundtrip(float value)
+        {
+            float result = float.Parse(value.ToString());
+            Assert.Equal(BitConverter.SingleToInt32Bits(value), BitConverter.SingleToInt32Bits(result));
+        }
+
+        [Theory]
+        [MemberData(nameof(ToStringRoundtrip_TestData))]
+        public static void ToStringRoundtrip_R(float value)
+        {
+            float result = float.Parse(value.ToString("R"));
+            Assert.Equal(BitConverter.SingleToInt32Bits(value), BitConverter.SingleToInt32Bits(result));
+        }
     }
 }
diff --git a/src/libraries/System.Runtime/tests/System/SingleTests.netcoreapp.cs b/src/libraries/System.Runtime/tests/System/SingleTests.netcoreapp.cs
deleted file mode 100644 (file)
index 22423d4..0000000
+++ /dev/null
@@ -1,229 +0,0 @@
-// 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.Globalization;
-using Microsoft.DotNet.RemoteExecutor;
-using Xunit;
-
-#pragma warning disable xUnit1025 // reporting duplicate test cases due to not distinguishing 0.0 from -0.0, NaN from -NaN
-
-namespace System.Tests
-{
-    public partial class SingleTests
-    {
-        [Theory]
-        [InlineData(float.NegativeInfinity, false)]     // Negative Infinity
-        [InlineData(float.MinValue, true)]              // Min Negative Normal
-        [InlineData(-1.17549435E-38f, true)]            // Max Negative Normal
-        [InlineData(-1.17549421E-38f, true)]            // Min Negative Subnormal
-        [InlineData(-1.401298E-45, true)]               // Max Negative Subnormal
-        [InlineData(-0.0f, true)]                       // Negative Zero
-        [InlineData(float.NaN, false)]                  // NaN
-        [InlineData(0.0f, true)]                        // Positive Zero
-        [InlineData(1.401298E-45, true)]                // Min Positive Subnormal
-        [InlineData(1.17549421E-38f, true)]             // Max Positive Subnormal
-        [InlineData(1.17549435E-38f, true)]             // Min Positive Normal
-        [InlineData(float.MaxValue, true)]              // Max Positive Normal
-        [InlineData(float.PositiveInfinity, false)]     // Positive Infinity
-        public static void IsFinite(float d, bool expected)
-        {
-            Assert.Equal(expected, float.IsFinite(d));
-        }
-
-        [Theory]
-        [InlineData(float.NegativeInfinity, true)]      // Negative Infinity
-        [InlineData(float.MinValue, true)]              // Min Negative Normal
-        [InlineData(-1.17549435E-38f, true)]            // Max Negative Normal
-        [InlineData(-1.17549421E-38f, true)]            // Min Negative Subnormal
-        [InlineData(-1.401298E-45, true)]               // Max Negative Subnormal
-        [InlineData(-0.0f, true)]                       // Negative Zero
-        [InlineData(float.NaN, true)]                   // NaN
-        [InlineData(0.0f, false)]                       // Positive Zero
-        [InlineData(1.401298E-45, false)]               // Min Positive Subnormal
-        [InlineData(1.17549421E-38f, false)]            // Max Positive Subnormal
-        [InlineData(1.17549435E-38f, false)]            // Min Positive Normal
-        [InlineData(float.MaxValue, false)]             // Max Positive Normal
-        [InlineData(float.PositiveInfinity, false)]     // Positive Infinity
-        public static void IsNegative(float d, bool expected)
-        {
-            Assert.Equal(expected, float.IsNegative(d));
-        }
-
-        [Theory]
-        [InlineData(float.NegativeInfinity, false)]     // Negative Infinity
-        [InlineData(float.MinValue, true)]              // Min Negative Normal
-        [InlineData(-1.17549435E-38f, true)]            // Max Negative Normal
-        [InlineData(-1.17549421E-38f, false)]           // Min Negative Subnormal
-        [InlineData(-1.401298E-45, false)]              // Max Negative Subnormal
-        [InlineData(-0.0f, false)]                      // Negative Zero
-        [InlineData(float.NaN, false)]                  // NaN
-        [InlineData(0.0f, false)]                       // Positive Zero
-        [InlineData(1.401298E-45, false)]               // Min Positive Subnormal
-        [InlineData(1.17549421E-38f, false)]            // Max Positive Subnormal
-        [InlineData(1.17549435E-38f, true)]             // Min Positive Normal
-        [InlineData(float.MaxValue, true)]              // Max Positive Normal
-        [InlineData(float.PositiveInfinity, false)]     // Positive Infinity
-        public static void IsNormal(float d, bool expected)
-        {
-            Assert.Equal(expected, float.IsNormal(d));
-        }
-
-        [Theory]
-        [InlineData(float.NegativeInfinity, false)]     // Negative Infinity
-        [InlineData(float.MinValue, false)]             // Min Negative Normal
-        [InlineData(-1.17549435E-38f, false)]           // Max Negative Normal
-        [InlineData(-1.17549421E-38f, true)]            // Min Negative Subnormal
-        [InlineData(-1.401298E-45, true)]               // Max Negative Subnormal
-        [InlineData(-0.0f, false)]                      // Negative Zero
-        [InlineData(float.NaN, false)]                  // NaN
-        [InlineData(0.0f, false)]                       // Positive Zero
-        [InlineData(1.401298E-45, true)]                // Min Positive Subnormal
-        [InlineData(1.17549421E-38f, true)]             // Max Positive Subnormal
-        [InlineData(1.17549435E-38f, false)]            // Min Positive Normal
-        [InlineData(float.MaxValue, false)]             // Max Positive Normal
-        [InlineData(float.PositiveInfinity, false)]     // Positive Infinity
-        public static void IsSubnormal(float d, bool expected)
-        {
-            Assert.Equal(expected, float.IsSubnormal(d));
-        }
-
-        public static IEnumerable<object[]> Parse_ValidWithOffsetCount_TestData()
-        {
-            foreach (object[] inputs in Parse_Valid_TestData())
-            {
-                yield return new object[] { inputs[0], 0, ((string)inputs[0]).Length, inputs[1], inputs[2], inputs[3] };
-            }
-
-            const NumberStyles DefaultStyle = NumberStyles.Float | NumberStyles.AllowThousands;
-
-            yield return new object[] { "-123", 1, 3, DefaultStyle, null, (float)123 };
-            yield return new object[] { "-123", 0, 3, DefaultStyle, null, (float)-12 };
-            yield return new object[] { "1E23", 0, 3, DefaultStyle, null, (float)1E2 };
-            yield return new object[] { "123", 0, 2, NumberStyles.Float, new NumberFormatInfo(), (float)12 };
-            yield return new object[] { "$1,000", 1, 3, NumberStyles.Currency, new NumberFormatInfo() { CurrencySymbol = "$", CurrencyGroupSeparator = "," }, (float)10 };
-            yield return new object[] { "(123)", 1, 3, NumberStyles.AllowParentheses, new NumberFormatInfo() { NumberDecimalSeparator = "." }, (float)123 };
-            yield return new object[] { "-Infinity", 1, 8, NumberStyles.Any, NumberFormatInfo.InvariantInfo, float.PositiveInfinity };
-        }
-
-        [Theory]
-        [MemberData(nameof(Parse_ValidWithOffsetCount_TestData))]
-        public static void Parse_Span_Valid(string value, int offset, int count, NumberStyles style, IFormatProvider provider, float expected)
-        {
-            bool isDefaultProvider = provider == null || provider == NumberFormatInfo.CurrentInfo;
-            float result;
-            if ((style & ~(NumberStyles.Float | NumberStyles.AllowThousands)) == 0 && style != NumberStyles.None)
-            {
-                // Use Parse(string) or Parse(string, IFormatProvider)
-                if (isDefaultProvider)
-                {
-                    Assert.True(float.TryParse(value.AsSpan(offset, count), out result));
-                    Assert.Equal(expected, result);
-
-                    Assert.Equal(expected, float.Parse(value.AsSpan(offset, count)));
-                }
-
-                Assert.Equal(expected, float.Parse(value.AsSpan(offset, count), provider: provider));
-            }
-
-            Assert.Equal(expected, float.Parse(value.AsSpan(offset, count), style, provider));
-
-            Assert.True(float.TryParse(value.AsSpan(offset, count), style, provider, out result));
-            Assert.Equal(expected, result);
-        }
-
-        [Theory]
-        [MemberData(nameof(Parse_Invalid_TestData))]
-        public static void Parse_Span_Invalid(string value, NumberStyles style, IFormatProvider provider, Type exceptionType)
-        {
-            if (value != null)
-            {
-                Assert.Throws(exceptionType, () => float.Parse(value.AsSpan(), style, provider));
-
-                Assert.False(float.TryParse(value.AsSpan(), style, provider, out float result));
-                Assert.Equal(0, result);
-            }
-        }
-
-        [Fact]
-        public static void TryFormat()
-        {
-            using (new ThreadCultureChange(CultureInfo.InvariantCulture))
-            {
-                foreach (object[] testdata in ToString_TestData())
-                {
-                    float localI = (float)testdata[0];
-                    string localFormat = (string)testdata[1];
-                    IFormatProvider localProvider = (IFormatProvider)testdata[2];
-                    string localExpected = (string)testdata[3];
-
-                    try
-                    {
-                        char[] actual;
-                        int charsWritten;
-
-                        // Just right
-                        actual = new char[localExpected.Length];
-                        Assert.True(localI.TryFormat(actual.AsSpan(), out charsWritten, localFormat, localProvider));
-                        Assert.Equal(localExpected.Length, charsWritten);
-                        Assert.Equal(localExpected, new string(actual));
-
-                        // Longer than needed
-                        actual = new char[localExpected.Length + 1];
-                        Assert.True(localI.TryFormat(actual.AsSpan(), out charsWritten, localFormat, localProvider));
-                        Assert.Equal(localExpected.Length, charsWritten);
-                        Assert.Equal(localExpected, new string(actual, 0, charsWritten));
-
-                        // Too short
-                        if (localExpected.Length > 0)
-                        {
-                            actual = new char[localExpected.Length - 1];
-                            Assert.False(localI.TryFormat(actual.AsSpan(), out charsWritten, localFormat, localProvider));
-                            Assert.Equal(0, charsWritten);
-                        }
-                    }
-                    catch (Exception exc)
-                    {
-                        throw new Exception($"Failed on `{localI}`, `{localFormat}`, `{localProvider}`, `{localExpected}`. {exc}");
-                    }
-                }
-            }
-        }
-
-        public static IEnumerable<object[]> ToStringRoundtrip_TestData()
-        {
-            yield return new object[] { float.NegativeInfinity };
-            yield return new object[] { float.MinValue };
-            yield return new object[] { -MathF.PI };
-            yield return new object[] { -MathF.E };
-            yield return new object[] { -float.Epsilon };
-            yield return new object[] { -0.845512408f };
-            yield return new object[] { -0.0f };
-            yield return new object[] { float.NaN };
-            yield return new object[] { 0.0f };
-            yield return new object[] { 0.845512408f };
-            yield return new object[] { float.Epsilon };
-            yield return new object[] { MathF.E };
-            yield return new object[] { MathF.PI };
-            yield return new object[] { float.MaxValue };
-            yield return new object[] { float.PositiveInfinity };
-        }
-
-        [Theory]
-        [MemberData(nameof(ToStringRoundtrip_TestData))]
-        public static void ToStringRoundtrip(float value)
-        {
-            float result = float.Parse(value.ToString());
-            Assert.Equal(BitConverter.SingleToInt32Bits(value), BitConverter.SingleToInt32Bits(result));
-        }
-
-        [Theory]
-        [MemberData(nameof(ToStringRoundtrip_TestData))]
-        public static void ToStringRoundtrip_R(float value)
-        {
-            float result = float.Parse(value.ToString("R"));
-            Assert.Equal(BitConverter.SingleToInt32Bits(value), BitConverter.SingleToInt32Bits(result));
-        }
-    }
-}
index d3ef247..08bdba5 100644 (file)
@@ -7,7 +7,7 @@ using Xunit;
 
 namespace System.Tests
 {
-    public partial class StringComparerTests
+    public class StringComparerTests
     {
         [Fact]
         public void Create_InvalidArguments_Throws()
@@ -109,5 +109,32 @@ namespace System.Tests
             Assert.False(c.Equals("42", 84));
             Assert.False(c.Equals(42, "84"));
         }
+
+        [Fact]
+        public void CreateCultureOptions_InvalidArguments_Throws()
+        {
+            Assert.Throws<ArgumentNullException>(() => StringComparer.Create(null, CompareOptions.None));
+        }
+
+        [Fact]
+        public void CreateCultureOptions_CreatesValidComparer()
+        {
+            StringComparer c = StringComparer.Create(CultureInfo.InvariantCulture, CompareOptions.IgnoreCase);
+            Assert.NotNull(c);
+            Assert.True(c.Equals((object)"hello", (object)"HEllO"));
+            Assert.True(c.Equals("hello", "HEllO"));
+            Assert.False(c.Equals((object)"bello", (object)"HEllO"));
+            Assert.False(c.Equals("bello", "HEllO"));
+
+            object obj = new object();
+            Assert.Equal(c.GetHashCode((object)"hello"), c.GetHashCode((object)"hello"));
+            Assert.Equal(c.GetHashCode("hello"), c.GetHashCode("hello"));
+            Assert.Equal(c.GetHashCode("hello"), c.GetHashCode((object)"hello"));
+            Assert.Equal(obj.GetHashCode(), c.GetHashCode(obj));
+            Assert.Equal(42.CompareTo(84), c.Compare(42, 84));
+            Assert.Throws<ArgumentException>(() => c.Compare("42", 84));
+            Assert.Equal(1, c.Compare("42", null));
+            Assert.Throws<ArgumentException>(() => c.Compare(42, "84"));
+        }
     }
 }
diff --git a/src/libraries/System.Runtime/tests/System/StringComparerTests.netcoreapp.cs b/src/libraries/System.Runtime/tests/System/StringComparerTests.netcoreapp.cs
deleted file mode 100644 (file)
index a31986c..0000000
+++ /dev/null
@@ -1,39 +0,0 @@
-// 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 Xunit;
-
-namespace System.Tests
-{
-    public partial class StringComparerTests
-    {
-        [Fact]
-        public void CreateCultureOptions_InvalidArguments_Throws()
-        {
-            Assert.Throws<ArgumentNullException>(() => StringComparer.Create(null, CompareOptions.None));
-        }
-
-        [Fact]
-        public void CreateCultureOptions_CreatesValidComparer()
-        {
-            StringComparer c = StringComparer.Create(CultureInfo.InvariantCulture, CompareOptions.IgnoreCase);
-            Assert.NotNull(c);
-            Assert.True(c.Equals((object)"hello", (object)"HEllO"));
-            Assert.True(c.Equals("hello", "HEllO"));
-            Assert.False(c.Equals((object)"bello", (object)"HEllO"));
-            Assert.False(c.Equals("bello", "HEllO"));
-
-            object obj = new object();
-            Assert.Equal(c.GetHashCode((object)"hello"), c.GetHashCode((object)"hello"));
-            Assert.Equal(c.GetHashCode("hello"), c.GetHashCode("hello"));
-            Assert.Equal(c.GetHashCode("hello"), c.GetHashCode((object)"hello"));
-            Assert.Equal(obj.GetHashCode(), c.GetHashCode(obj));
-            Assert.Equal(42.CompareTo(84), c.Compare(42, 84));
-            Assert.Throws<ArgumentException>(() => c.Compare("42", 84));
-            Assert.Equal(1, c.Compare("42", null));
-            Assert.Throws<ArgumentException>(() => c.Compare(42, "84"));
-        }
-    }
-}
index ce4f672..82dbbb4 100644 (file)
@@ -10,7 +10,7 @@ using Xunit;
 
 namespace System.Tests
 {
-    public partial class StringGetHashCodeTests
+    public class StringGetHashCodeTests
     {
         /// <summary>
         /// Ensure that hash codes are randomized by getting the hash in two processes
@@ -61,5 +61,44 @@ namespace System.Tests
             () => { return CultureInfo.CurrentCulture.CompareInfo.GetHashCode("abc", CompareOptions.Ordinal); },
             () => { return CultureInfo.CurrentCulture.CompareInfo.GetHashCode("abc", CompareOptions.OrdinalIgnoreCase); }
         };
+
+        [Theory]
+        [MemberData(nameof(GetHashCodeOrdinalIgnoreCase_TestData))]
+        public void GetHashCode_OrdinalIgnoreCase_ReturnsSameHashCodeAsUpperCaseOrdinal(string input)
+        {
+            // As an implementation detail, the OrdinalIgnoreCase hash code calculation is simply the hash code
+            // of the upper-invariant version of the input string.
+
+            Assert.Equal(input.ToUpperInvariant().GetHashCode(), input.GetHashCode(StringComparison.OrdinalIgnoreCase));
+        }
+
+        public static IEnumerable<object[]> GetHashCodeOrdinalIgnoreCase_TestData()
+        {
+            // 0 through 8 char lowercase & uppercase ASCII strings
+            // tests the various branches within the hash code calculation routines
+
+            for (int i = 0; i <= 8; i++)
+            {
+                yield return new object[] { "abcdefgh".Substring(0, i) };
+                yield return new object[] { "ABCDEFGH".Substring(0, i) };
+            }
+
+            // 16 char mixed case mostly-ASCII string plus one non-ASCII character inserted at various locations
+            // tests fallback logic for OrdinalIgnoreCase hash
+
+            for (int i = 0; i <= 16; i++)
+            {
+                yield return new object[] { "AaBbCcDdEeFfGgHh".Insert(i, "\u00E9" /* LATIN SMALL LETTER E WITH ACUTE */) };
+                yield return new object[] { "AaBbCcDdEeFfGgHh".Insert(i, "\u044D" /* CYRILLIC SMALL LETTER E */) };
+                yield return new object[] { "AaBbCcDdEeFfGgHh".Insert(i, "\u0131" /* LATIN SMALL LETTER DOTLESS I */) };
+            }
+
+            // Various texts copied from Microsoft's non-U.S. home pages, for further localization tests
+
+            yield return new object[] { "\u0418\u0433\u0440\u044B \u0438 \u0440\u0430\u0437\u0432\u043B\u0435\u0447\u0435\u043D\u0438\u044F \u0431\u0435\u0437 \u0433\u0440\u0430\u043D\u0438\u0446 \u0432 \u0444\u043E\u0440\u043C\u0430\u0442\u0435 4K." }; // ru-RU
+            yield return new object[] { "Poder port\u00E1til." }; // es-ES
+            yield return new object[] { "\u60F3\u50CF\u3092\u8D85\u3048\u305F\u3001\u30D1\u30D5\u30A9\u30FC\u30DE\u30F3\u30B9\u3092\u3002" }; // ja-JP
+            yield return new object[] { "\u00C9l\u00E9gant et performant." }; // fr-FR
+        }
     }
 }
diff --git a/src/libraries/System.Runtime/tests/System/StringGetHashCodeTests.netcoreapp.cs b/src/libraries/System.Runtime/tests/System/StringGetHashCodeTests.netcoreapp.cs
deleted file mode 100644 (file)
index f3479d3..0000000
+++ /dev/null
@@ -1,51 +0,0 @@
-// 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 Xunit;
-
-namespace System.Tests
-{
-    public partial class StringGetHashCodeTests
-    {
-        [Theory]
-        [MemberData(nameof(GetHashCodeOrdinalIgnoreCase_TestData))]
-        public void GetHashCode_OrdinalIgnoreCase_ReturnsSameHashCodeAsUpperCaseOrdinal(string input)
-        {
-            // As an implementation detail, the OrdinalIgnoreCase hash code calculation is simply the hash code
-            // of the upper-invariant version of the input string.
-
-            Assert.Equal(input.ToUpperInvariant().GetHashCode(), input.GetHashCode(StringComparison.OrdinalIgnoreCase));
-        }
-
-        public static IEnumerable<object[]> GetHashCodeOrdinalIgnoreCase_TestData()
-        {
-            // 0 through 8 char lowercase & uppercase ASCII strings
-            // tests the various branches within the hash code calculation routines
-
-            for (int i = 0; i <= 8; i++)
-            {
-                yield return new object[] { "abcdefgh".Substring(0, i) };
-                yield return new object[] { "ABCDEFGH".Substring(0, i) };
-            }
-
-            // 16 char mixed case mostly-ASCII string plus one non-ASCII character inserted at various locations
-            // tests fallback logic for OrdinalIgnoreCase hash
-
-            for (int i = 0; i <= 16; i++)
-            {
-                yield return new object[] { "AaBbCcDdEeFfGgHh".Insert(i, "\u00E9" /* LATIN SMALL LETTER E WITH ACUTE */) };
-                yield return new object[] { "AaBbCcDdEeFfGgHh".Insert(i, "\u044D" /* CYRILLIC SMALL LETTER E */) };
-                yield return new object[] { "AaBbCcDdEeFfGgHh".Insert(i, "\u0131" /* LATIN SMALL LETTER DOTLESS I */) };
-            }
-
-            // Various texts copied from Microsoft's non-U.S. home pages, for further localization tests
-
-            yield return new object[] { "\u0418\u0433\u0440\u044B \u0438 \u0440\u0430\u0437\u0432\u043B\u0435\u0447\u0435\u043D\u0438\u044F \u0431\u0435\u0437 \u0433\u0440\u0430\u043D\u0438\u0446 \u0432 \u0444\u043E\u0440\u043C\u0430\u0442\u0435 4K." }; // ru-RU
-            yield return new object[] { "Poder port\u00E1til." }; // es-ES
-            yield return new object[] { "\u60F3\u50CF\u3092\u8D85\u3048\u305F\u3001\u30D1\u30D5\u30A9\u30FC\u30DE\u30F3\u30B9\u3092\u3002" }; // ja-JP
-            yield return new object[] { "\u00C9l\u00E9gant et performant." }; // fr-FR
-        }
-    }
-}
@@ -13,7 +13,7 @@ namespace System.Text.Tests
 {
     // Since many of the methods we'll be testing are internal, we'll need to invoke
     // them via reflection.
-    public static unsafe partial class AsciiUtilityTests
+    public static unsafe class AsciiUtilityTests
     {
         private const int SizeOfVector128 = 128 / 8;
 
index d6d9388..7862302 100644 (file)
@@ -5,6 +5,7 @@
 using System.Collections.Generic;
 using System.Diagnostics;
 using System.Globalization;
+using System.Linq;
 using System.Tests;
 using Microsoft.DotNet.RemoteExecutor;
 using Xunit;
@@ -1782,5 +1783,453 @@ namespace System.Text.Tests
             public string Format(string format, object arg, IFormatProvider formatProvider) => "abc";
             public object GetFormat(Type formatType) => this;
         }
+
+        [Fact]
+        public static void AppendJoin_NullValues_ThrowsArgumentNullException()
+        {
+            AssertExtensions.Throws<ArgumentNullException>("values", () => new StringBuilder().AppendJoin('|', (object[])null));
+            AssertExtensions.Throws<ArgumentNullException>("values", () => new StringBuilder().AppendJoin('|', (IEnumerable<object>)null));
+            AssertExtensions.Throws<ArgumentNullException>("values", () => new StringBuilder().AppendJoin('|', (string[])null));
+            AssertExtensions.Throws<ArgumentNullException>("values", () => new StringBuilder().AppendJoin("|", (object[])null));
+            AssertExtensions.Throws<ArgumentNullException>("values", () => new StringBuilder().AppendJoin("|", (IEnumerable<object>)null));
+            AssertExtensions.Throws<ArgumentNullException>("values", () => new StringBuilder().AppendJoin("|", (string[])null));
+        }
+
+        [Theory]
+        [InlineData(new object[0], "")]
+        [InlineData(new object[] { null }, "")]
+        [InlineData(new object[] { 10 }, "10")]
+        [InlineData(new object[] { null, null }, "|")]
+        [InlineData(new object[] { null, 20 }, "|20")]
+        [InlineData(new object[] { 10, null }, "10|")]
+        [InlineData(new object[] { 10, 20 }, "10|20")]
+        [InlineData(new object[] { null, null, null }, "||")]
+        [InlineData(new object[] { null, null, 30 }, "||30")]
+        [InlineData(new object[] { null, 20, null }, "|20|")]
+        [InlineData(new object[] { null, 20, 30 }, "|20|30")]
+        [InlineData(new object[] { 10, null, null }, "10||")]
+        [InlineData(new object[] { 10, null, 30 }, "10||30")]
+        [InlineData(new object[] { 10, 20, null }, "10|20|")]
+        [InlineData(new object[] { 10, 20, 30 }, "10|20|30")]
+        [InlineData(new object[] { "" }, "")]
+        [InlineData(new object[] { "", "" }, "|")]
+        public static void AppendJoin_TestValues(object[] values, string expected)
+        {
+            var stringValues = Array.ConvertAll(values, _ => _?.ToString());
+            var enumerable = values.Select(_ => _);
+
+            Assert.Equal(expected, new StringBuilder().AppendJoin('|', values).ToString());
+            Assert.Equal(expected, new StringBuilder().AppendJoin('|', enumerable).ToString());
+            Assert.Equal(expected, new StringBuilder().AppendJoin('|', stringValues).ToString());
+            Assert.Equal(expected, new StringBuilder().AppendJoin("|", values).ToString());
+            Assert.Equal(expected, new StringBuilder().AppendJoin("|", enumerable).ToString());
+            Assert.Equal(expected, new StringBuilder().AppendJoin("|", stringValues).ToString());
+        }
+
+        [Fact]
+        public static void AppendJoin_NullToStringValues()
+        {
+            AppendJoin_TestValues(new object[] { new NullToStringObject() }, "");
+            AppendJoin_TestValues(new object[] { new NullToStringObject(), new NullToStringObject() }, "|");
+        }
+
+        private sealed class NullToStringObject
+        {
+            public override string ToString() => null;
+        }
+
+        [Theory]
+        [InlineData(null, "123")]
+        [InlineData("", "123")]
+        [InlineData(" ", "1 2 3")]
+        [InlineData(", ", "1, 2, 3")]
+        public static void AppendJoin_TestStringSeparators(string separator, string expected)
+        {
+            Assert.Equal(expected, new StringBuilder().AppendJoin(separator, new object[] { 1, 2, 3 }).ToString());
+            Assert.Equal(expected, new StringBuilder().AppendJoin(separator, Enumerable.Range(1, 3)).ToString());
+            Assert.Equal(expected, new StringBuilder().AppendJoin(separator, new string[] { "1", "2", "3" }).ToString());
+        }
+
+
+        private static StringBuilder CreateBuilderWithNoSpareCapacity()
+        {
+            return new StringBuilder(0, 5).Append("Hello");
+        }
+
+        [Theory]
+        [InlineData(null, new object[] { null, null })]
+        [InlineData("", new object[] { "", "" })]
+        [InlineData(" ", new object[] { })]
+        [InlineData(", ", new object[] { "" })]
+        public static void AppendJoin_NoValues_NoSpareCapacity_DoesNotThrow(string separator, object[] values)
+        {
+            var stringValues = Array.ConvertAll(values, _ => _?.ToString());
+            var enumerable = values.Select(_ => _);
+
+            if (separator?.Length == 1)
+            {
+                CreateBuilderWithNoSpareCapacity().AppendJoin(separator[0], values);
+                CreateBuilderWithNoSpareCapacity().AppendJoin(separator[0], enumerable);
+                CreateBuilderWithNoSpareCapacity().AppendJoin(separator[0], stringValues);
+            }
+            CreateBuilderWithNoSpareCapacity().AppendJoin(separator, values);
+            CreateBuilderWithNoSpareCapacity().AppendJoin(separator, enumerable);
+            CreateBuilderWithNoSpareCapacity().AppendJoin(separator, stringValues);
+        }
+
+        [Theory]
+        [InlineData(null, new object[] { " " })]
+        [InlineData(" ", new object[] { " " })]
+        [InlineData(" ", new object[] { null, null })]
+        [InlineData(" ", new object[] { "", "" })]
+        public static void AppendJoin_NoSpareCapacity_ThrowsArgumentOutOfRangeException(string separator, object[] values)
+        {
+            var builder = new StringBuilder(0, 5);
+            builder.Append("Hello");
+
+            var stringValues = Array.ConvertAll(values, _ => _?.ToString());
+            var enumerable = values.Select(_ => _);
+
+            if (separator?.Length == 1)
+            {
+                AssertExtensions.Throws<ArgumentOutOfRangeException>(s_noCapacityParamName, () => CreateBuilderWithNoSpareCapacity().AppendJoin(separator[0], values));
+                AssertExtensions.Throws<ArgumentOutOfRangeException>(s_noCapacityParamName, () => CreateBuilderWithNoSpareCapacity().AppendJoin(separator[0], enumerable));
+                AssertExtensions.Throws<ArgumentOutOfRangeException>(s_noCapacityParamName, () => CreateBuilderWithNoSpareCapacity().AppendJoin(separator[0], stringValues));
+            }
+            AssertExtensions.Throws<ArgumentOutOfRangeException>(s_noCapacityParamName, () => CreateBuilderWithNoSpareCapacity().AppendJoin(separator, values));
+            AssertExtensions.Throws<ArgumentOutOfRangeException>(s_noCapacityParamName, () => CreateBuilderWithNoSpareCapacity().AppendJoin(separator, enumerable));
+            AssertExtensions.Throws<ArgumentOutOfRangeException>(s_noCapacityParamName, () => CreateBuilderWithNoSpareCapacity().AppendJoin(separator, stringValues));
+        }
+
+        [Theory]
+        [InlineData("Hello", new char[] { 'a' }, "Helloa")]
+        [InlineData("Hello", new char[] { 'b', 'c', 'd' }, "Hellobcd")]
+        [InlineData("Hello", new char[] { 'b', '\0', 'd' }, "Hellob\0d")]
+        [InlineData("", new char[] { 'e', 'f', 'g' }, "efg")]
+        [InlineData("Hello", new char[0], "Hello")]
+        public static void Append_CharSpan(string original, char[] value, string expected)
+        {
+            var builder = new StringBuilder(original);
+            builder.Append(new ReadOnlySpan<char>(value));
+            Assert.Equal(expected, builder.ToString());
+        }
+
+        [Theory]
+        [InlineData("Hello", new char[] { 'a' }, "Helloa")]
+        [InlineData("Hello", new char[] { 'b', 'c', 'd' }, "Hellobcd")]
+        [InlineData("Hello", new char[] { 'b', '\0', 'd' }, "Hellob\0d")]
+        [InlineData("", new char[] { 'e', 'f', 'g' }, "efg")]
+        [InlineData("Hello", new char[0], "Hello")]
+        public static void Append_CharMemory(string original, char[] value, string expected)
+        {
+            var builder = new StringBuilder(original);
+            builder.Append(value.AsMemory());
+            Assert.Equal(expected, builder.ToString());
+        }
+
+        [Theory]
+        [InlineData(1)]
+        [InlineData(10000)]
+        public static void Clear_AppendAndInsertBeforeClearManyTimes_CapacityStaysWithinRange(int times)
+        {
+            var builder = new StringBuilder();
+            var originalCapacity = builder.Capacity;
+            var s = new string(' ', 10);
+            int oldLength = 0;
+            for (int i = 0; i < times; i++)
+            {
+                builder.Append(s);
+                builder.Append(s);
+                builder.Append(s);
+                builder.Insert(0, s);
+                builder.Insert(0, s);
+                oldLength = builder.Length;
+
+                builder.Clear();
+            }
+            Assert.InRange(builder.Capacity, 1, oldLength * 1.2);
+        }
+
+        [Fact]
+        public static void Clear_InitialCapacityMuchLargerThanLength_CapacityReducedToInitialCapacity()
+        {
+            var builder = new StringBuilder(100);
+            var initialCapacity = builder.Capacity;
+            builder.Append(new string('a', 40));
+            builder.Insert(0, new string('a', 10));
+            builder.Insert(0, new string('a', 10));
+            builder.Insert(0, new string('a', 10));
+            var oldCapacity = builder.Capacity;
+            var oldLength = builder.Length;
+            builder.Clear();
+            Assert.NotEqual(oldCapacity, builder.Capacity);
+            Assert.Equal(initialCapacity, builder.Capacity);
+            Assert.NotInRange(builder.Capacity, 1, oldLength * 1.2);
+            Assert.InRange(builder.Capacity, 1, Math.Max(initialCapacity, oldLength * 1.2));
+        }
+
+        [Fact]
+        public static void Clear_StringBuilderHasTwoChunks_OneChunkIsEmpty_ClearReducesCapacity()
+        {
+            var sb = new StringBuilder(string.Empty);
+            int initialCapacity = sb.Capacity;
+            for (int i = 0; i < initialCapacity; i++)
+            {
+                sb.Append('a');
+            }
+            sb.Insert(0, 'a');
+            while (sb.Length > 1)
+            {
+                sb.Remove(1, 1);
+            }
+            int oldCapacity = sb.Capacity;
+            sb.Clear();
+            Assert.Equal(oldCapacity - 1, sb.Capacity);
+            Assert.Equal(initialCapacity, sb.Capacity);
+        }
+
+        [Theory]
+        [InlineData("Hello", 0, new char[] { '\0', '\0', '\0', '\0', '\0' }, 5, new char[] { 'H', 'e', 'l', 'l', 'o' })]
+        [InlineData("Hello", 0, new char[] { '\0', '\0', '\0', '\0' }, 4, new char[] { 'H', 'e', 'l', 'l' })]
+        [InlineData("Hello", 1, new char[] { '\0', '\0', '\0', '\0', '\0' }, 4, new char[] { 'e', 'l', 'l', 'o', '\0' })]
+        public static void CopyTo_CharSpan(string value, int sourceIndex, char[] destination, int count, char[] expected)
+        {
+            var builder = new StringBuilder(value);
+            builder.CopyTo(sourceIndex, new Span<char>(destination), count);
+            Assert.Equal(expected, destination);
+        }
+
+        [Fact]
+        public static void CopyTo_CharSpan_StringBuilderWithMultipleChunks()
+        {
+            StringBuilder builder = StringBuilderWithMultipleChunks();
+            char[] destination = new char[builder.Length];
+            builder.CopyTo(0, new Span<char>(destination), destination.Length);
+            Assert.Equal(s_chunkSplitSource.ToCharArray(), destination);
+        }
+
+        [Fact]
+        public static void CopyTo_CharSpan_Invalid()
+        {
+            var builder = new StringBuilder("Hello");
+
+            AssertExtensions.Throws<ArgumentOutOfRangeException>("sourceIndex", () => builder.CopyTo(-1, new Span<char>(new char[10]), 0)); // Source index < 0
+            AssertExtensions.Throws<ArgumentOutOfRangeException>("sourceIndex", () => builder.CopyTo(6, new Span<char>(new char[10]), 0)); // Source index > builder.Length
+
+            AssertExtensions.Throws<ArgumentOutOfRangeException>("count", () => builder.CopyTo(0, new Span<char>(new char[10]), -1)); // Count < 0
+
+            AssertExtensions.Throws<ArgumentException>(null, () => builder.CopyTo(5, new Span<char>(new char[10]), 1)); // Source index + count > builder.Length
+            AssertExtensions.Throws<ArgumentException>(null, () => builder.CopyTo(4, new Span<char>(new char[10]), 2)); // Source index + count > builder.Length
+
+            AssertExtensions.Throws<ArgumentException>(null, () => builder.CopyTo(0, new Span<char>(new char[10]), 11)); // count > destinationArray.Length
+        }
+
+        [Theory]
+        [InlineData("Hello", 0, new char[] { '\0' }, "\0Hello")]
+        [InlineData("Hello", 3, new char[] { 'a', 'b', 'c' }, "Helabclo")]
+        [InlineData("Hello", 5, new char[] { 'd', 'e', 'f' }, "Hellodef")]
+        [InlineData("Hello", 0, new char[0], "Hello")]
+        public static void Insert_CharSpan(string original, int index, char[] value, string expected)
+        {
+            var builder = new StringBuilder(original);
+            builder.Insert(index, new ReadOnlySpan<char>(value));
+            Assert.Equal(expected, builder.ToString());
+        }
+
+        [Fact]
+        public static void Insert_CharSpan_Invalid()
+        {
+            var builder = new StringBuilder(0, 5);
+            builder.Append("Hello");
+
+            AssertExtensions.Throws<ArgumentOutOfRangeException>("index", () => builder.Insert(-1, new ReadOnlySpan<char>(new char[0]))); // Index < 0
+            AssertExtensions.Throws<ArgumentOutOfRangeException>("index", () => builder.Insert(builder.Length + 1, new ReadOnlySpan<char>(new char[0]))); // Index > builder.Length
+            AssertExtensions.Throws<ArgumentOutOfRangeException>("requiredLength", () => builder.Insert(builder.Length, new ReadOnlySpan<char>(new char[1]))); // New length > builder.MaxCapacity
+        }
+
+        public static IEnumerable<object[]> Append_StringBuilder_TestData()
+        {
+            string mediumString = new string('a', 30);
+            string largeString = new string('b', 1000);
+
+            var sb1 = new StringBuilder("Hello");
+            var sb2 = new StringBuilder("one");
+            var sb3 = new StringBuilder(20).Append(mediumString);
+
+            yield return new object[] { new StringBuilder("Hello"), sb1, "HelloHello" };
+            yield return new object[] { new StringBuilder("Hello"), sb2, "Helloone" };
+            yield return new object[] { new StringBuilder("Hello"), new StringBuilder(), "Hello" };
+
+            yield return new object[] { new StringBuilder("one"), sb3, "one" + mediumString };
+
+            yield return new object[] { new StringBuilder(20).Append(mediumString), sb3, mediumString + mediumString };
+            yield return new object[] { new StringBuilder(10).Append(mediumString), sb3, mediumString + mediumString };
+
+            yield return new object[] { new StringBuilder(20).Append(largeString), sb3, largeString + mediumString };
+            yield return new object[] { new StringBuilder(10).Append(largeString), sb3, largeString + mediumString };
+
+            yield return new object[] { new StringBuilder(10), sb3, mediumString };
+            yield return new object[] { new StringBuilder(30), sb3, mediumString };
+            yield return new object[] { new StringBuilder(10), new StringBuilder(20), string.Empty};
+
+            yield return new object[] { sb1, null, "Hello" };
+            yield return new object[] { sb1, sb1, "HelloHello" };
+        }
+
+        [Theory]
+        [MemberData(nameof(Append_StringBuilder_TestData))]
+        public static void Append_StringBuilder(StringBuilder s1, StringBuilder s2, string s)
+        {
+            Assert.Equal(s, s1.Append(s2).ToString());
+        }
+
+        public static IEnumerable<object[]> Append_StringBuilder_Substring_TestData()
+        {
+            string mediumString = new string('a', 30);
+            string largeString = new string('b', 1000);
+
+            var sb1 = new StringBuilder("Hello");
+            var sb2 = new StringBuilder("one");
+            var sb3 = new StringBuilder(20).Append(mediumString);
+
+            yield return new object[] { new StringBuilder("Hello"), sb1, 0, 5, "HelloHello" };
+            yield return new object[] { new StringBuilder("Hello"), sb1, 0, 0, "Hello" };
+            yield return new object[] { new StringBuilder("Hello"), sb1, 2, 3, "Hellollo" };
+            yield return new object[] { new StringBuilder("Hello"), sb1, 2, 2, "Helloll" };
+            yield return new object[] { new StringBuilder("Hello"), sb1, 2, 0, "Hello" };
+            yield return new object[] { new StringBuilder("Hello"), new StringBuilder(), 0, 0, "Hello" };
+            yield return new object[] { new StringBuilder("Hello"), null, 0, 0, "Hello" };
+            yield return new object[] { new StringBuilder(), new StringBuilder("Hello"), 2, 3, "llo" };
+            yield return new object[] { new StringBuilder("Hello"), sb2, 0, 3, "Helloone" };
+
+            yield return new object[] { new StringBuilder("one"), sb3, 5, 25, "one" + new string('a', 25) };
+            yield return new object[] { new StringBuilder("one"), sb3, 5, 20, "one" + new string('a', 20) };
+            yield return new object[] { new StringBuilder("one"), sb3, 10, 10, "one" + new string('a', 10) };
+
+            yield return new object[] { new StringBuilder(20).Append(mediumString), sb3, 20, 10, new string('a', 40) };
+            yield return new object[] { new StringBuilder(10).Append(mediumString), sb3, 10, 10, new string('a', 40) };
+
+            yield return new object[] { new StringBuilder(20).Append(largeString), new StringBuilder(20).Append(largeString), 100, 50, largeString + new string('b', 50) };
+            yield return new object[] { new StringBuilder(10).Append(mediumString), new StringBuilder(20).Append(largeString), 20, 10, mediumString + new string('b', 10) };
+            yield return new object[] { new StringBuilder(10).Append(mediumString), new StringBuilder(20).Append(largeString), 100, 50, mediumString + new string('b', 50) };
+
+            yield return new object[] { sb1, sb1, 2, 3, "Hellollo" };
+            yield return new object[] { sb2, sb2, 2, 0, "one" };
+        }
+
+        [Theory]
+        [MemberData(nameof(Append_StringBuilder_Substring_TestData))]
+        public static void Append_StringBuilder_Substring(StringBuilder s1, StringBuilder s2, int startIndex, int count, string s)
+        {
+            Assert.Equal(s, s1.Append(s2, startIndex, count).ToString());
+        }
+
+        [Fact]
+        public static void Append_StringBuilder_InvalidInput()
+        {
+            StringBuilder sb = new StringBuilder(5, 5).Append("Hello");
+
+            Assert.Throws<ArgumentOutOfRangeException>(() => sb.Append(sb, -1, 0));
+            Assert.Throws<ArgumentOutOfRangeException>(() => sb.Append(sb, 0, -1));
+            Assert.Throws<ArgumentOutOfRangeException>(() => sb.Append(sb, 4, 5));
+
+            Assert.Throws<ArgumentNullException>(() => sb.Append( (StringBuilder)null, 2, 2));
+            Assert.Throws<ArgumentNullException>(() => sb.Append((StringBuilder)null, 2, 3));
+            Assert.Throws<ArgumentOutOfRangeException>(() => new StringBuilder(3, 6).Append("Hello").Append(sb));
+            Assert.Throws<ArgumentOutOfRangeException>(() => new StringBuilder(3, 6).Append("Hello").Append("Hello"));
+
+            Assert.Throws<ArgumentOutOfRangeException>(() => sb.Append(sb));
+        }
+
+        public static IEnumerable<object[]> Equals_String_TestData()
+        {
+            string mediumString = new string('a', 30);
+            string largeString = new string('a', 1000);
+            string extraLargeString = new string('a', 41000); // 8000 is the maximum chunk size
+
+            var sb1 = new StringBuilder("Hello");
+            var sb2 = new StringBuilder(20).Append(mediumString);
+            var sb3 = new StringBuilder(20).Append(largeString);
+            var sb4 = new StringBuilder(20).Append(extraLargeString);
+
+            yield return new object[] { sb1, "Hello", true };
+            yield return new object[] { sb1, "Hel", false };
+            yield return new object[] { sb1, "Hellz", false };
+            yield return new object[] { sb1, "Helloz", false };
+            yield return new object[] { sb1, "", false };
+            yield return new object[] { new StringBuilder(), "", true };
+            yield return new object[] { new StringBuilder(), "Hello", false };
+            yield return new object[] { sb2, mediumString, true };
+            yield return new object[] { sb2, "H", false };
+            yield return new object[] { sb3, largeString, true };
+            yield return new object[] { sb3, "H", false };
+            yield return new object[] { sb3, new string('a', 999) + 'b', false };
+            yield return new object[] { sb4, extraLargeString, true };
+            yield return new object[] { sb4, "H", false };
+        }
+
+        [Theory]
+        [MemberData(nameof(Equals_String_TestData))]
+        public static void Equals(StringBuilder sb1, string value, bool expected)
+        {
+            Assert.Equal(expected, sb1.Equals(value.AsSpan()));
+        }
+
+        [Fact]
+        public static void ForEach()
+        {
+            // Test on a variety of lengths, at least up to the point of 9 8K chunks = 72K because this is where
+            // we start using a different technique for creating the ChunkEnumerator.   200 * 500 = 100K which hits this.
+            for (int i = 0; i < 200; i++)
+            {
+                StringBuilder inBuilder = new StringBuilder();
+                for (int j = 0; j < i; j++)
+                {
+                    // Make some unique strings that are at least 500 bytes long.
+                    inBuilder.Append(j);
+                    inBuilder.Append("_abcdefghijklmnopqrstuvwxyz01234567890__Abcdefghijklmnopqrstuvwxyz01234567890__ABcdefghijklmnopqrstuvwxyz01_");
+                    inBuilder.Append("_abcdefghijklmnopqrstuvwxyz01234567890__Abcdefghijklmnopqrstuvwxyz01234567890__ABcdefghijklmnopqrstuvwxyz0123_");
+                    inBuilder.Append("_abcdefghijklmnopqrstuvwxyz01234567890__Abcdefghijklmnopqrstuvwxyz01234567890__ABcdefghijklmnopqrstuvwxyz012345_");
+                    inBuilder.Append("_abcdefghijklmnopqrstuvwxyz01234567890__Abcdefghijklmnopqrstuvwxyz01234567890__ABcdefghijklmnopqrstuvwxyz012345678_");
+                    inBuilder.Append("_abcdefghijklmnopqrstuvwxyz01234567890__Abcdefghijklmnopqrstuvwxyz01234567890__ABcdefghijklmnopqrstuvwxyz01234567890_");
+                }
+
+                // Copy the string out (not using StringBuilder).
+                string outStr = "";
+                foreach (ReadOnlyMemory<char> chunk in inBuilder.GetChunks())
+                    outStr += new string(chunk.Span);
+
+                // The strings formed by concatenating the chunks should be the same as the value in the StringBuilder.
+                Assert.Equal(outStr, inBuilder.ToString());
+            }
+        }
+
+        [Fact]
+        public static void EqualsIgnoresCapacity()
+        {
+            var sb1 = new StringBuilder(5);
+            var sb2 = new StringBuilder(10);
+
+            Assert.True(sb1.Equals(sb2));
+
+            sb1.Append("12345");
+            sb2.Append("12345");
+
+            Assert.True(sb1.Equals(sb2));
+        }
+
+        [Fact]
+        public static void EqualsIgnoresMaxCapacity()
+        {
+            var sb1 = new StringBuilder(5, 5);
+            var sb2 = new StringBuilder(5, 10);
+
+            Assert.True(sb1.Equals(sb2));
+
+            sb1.Append("12345");
+            sb2.Append("12345");
+
+            Assert.True(sb1.Equals(sb2));
+        }
     }
 }
diff --git a/src/libraries/System.Runtime/tests/System/Text/StringBuilderTests.netcoreapp.cs b/src/libraries/System.Runtime/tests/System/Text/StringBuilderTests.netcoreapp.cs
deleted file mode 100644 (file)
index e854c3c..0000000
+++ /dev/null
@@ -1,462 +0,0 @@
-// 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.Diagnostics;
-using System.Linq;
-using Xunit;
-
-namespace System.Text.Tests
-{
-    public partial class StringBuilderTests
-    {
-        [Fact]
-        public static void AppendJoin_NullValues_ThrowsArgumentNullException()
-        {
-            AssertExtensions.Throws<ArgumentNullException>("values", () => new StringBuilder().AppendJoin('|', (object[])null));
-            AssertExtensions.Throws<ArgumentNullException>("values", () => new StringBuilder().AppendJoin('|', (IEnumerable<object>)null));
-            AssertExtensions.Throws<ArgumentNullException>("values", () => new StringBuilder().AppendJoin('|', (string[])null));
-            AssertExtensions.Throws<ArgumentNullException>("values", () => new StringBuilder().AppendJoin("|", (object[])null));
-            AssertExtensions.Throws<ArgumentNullException>("values", () => new StringBuilder().AppendJoin("|", (IEnumerable<object>)null));
-            AssertExtensions.Throws<ArgumentNullException>("values", () => new StringBuilder().AppendJoin("|", (string[])null));
-        }
-
-        [Theory]
-        [InlineData(new object[0], "")]
-        [InlineData(new object[] { null }, "")]
-        [InlineData(new object[] { 10 }, "10")]
-        [InlineData(new object[] { null, null }, "|")]
-        [InlineData(new object[] { null, 20 }, "|20")]
-        [InlineData(new object[] { 10, null }, "10|")]
-        [InlineData(new object[] { 10, 20 }, "10|20")]
-        [InlineData(new object[] { null, null, null }, "||")]
-        [InlineData(new object[] { null, null, 30 }, "||30")]
-        [InlineData(new object[] { null, 20, null }, "|20|")]
-        [InlineData(new object[] { null, 20, 30 }, "|20|30")]
-        [InlineData(new object[] { 10, null, null }, "10||")]
-        [InlineData(new object[] { 10, null, 30 }, "10||30")]
-        [InlineData(new object[] { 10, 20, null }, "10|20|")]
-        [InlineData(new object[] { 10, 20, 30 }, "10|20|30")]
-        [InlineData(new object[] { "" }, "")]
-        [InlineData(new object[] { "", "" }, "|")]
-        public static void AppendJoin_TestValues(object[] values, string expected)
-        {
-            var stringValues = Array.ConvertAll(values, _ => _?.ToString());
-            var enumerable = values.Select(_ => _);
-
-            Assert.Equal(expected, new StringBuilder().AppendJoin('|', values).ToString());
-            Assert.Equal(expected, new StringBuilder().AppendJoin('|', enumerable).ToString());
-            Assert.Equal(expected, new StringBuilder().AppendJoin('|', stringValues).ToString());
-            Assert.Equal(expected, new StringBuilder().AppendJoin("|", values).ToString());
-            Assert.Equal(expected, new StringBuilder().AppendJoin("|", enumerable).ToString());
-            Assert.Equal(expected, new StringBuilder().AppendJoin("|", stringValues).ToString());
-        }
-
-        [Fact]
-        public static void AppendJoin_NullToStringValues()
-        {
-            AppendJoin_TestValues(new object[] { new NullToStringObject() }, "");
-            AppendJoin_TestValues(new object[] { new NullToStringObject(), new NullToStringObject() }, "|");
-        }
-
-        private sealed class NullToStringObject
-        {
-            public override string ToString() => null;
-        }
-
-        [Theory]
-        [InlineData(null, "123")]
-        [InlineData("", "123")]
-        [InlineData(" ", "1 2 3")]
-        [InlineData(", ", "1, 2, 3")]
-        public static void AppendJoin_TestStringSeparators(string separator, string expected)
-        {
-            Assert.Equal(expected, new StringBuilder().AppendJoin(separator, new object[] { 1, 2, 3 }).ToString());
-            Assert.Equal(expected, new StringBuilder().AppendJoin(separator, Enumerable.Range(1, 3)).ToString());
-            Assert.Equal(expected, new StringBuilder().AppendJoin(separator, new string[] { "1", "2", "3" }).ToString());
-        }
-
-
-        private static StringBuilder CreateBuilderWithNoSpareCapacity()
-        {
-            return new StringBuilder(0, 5).Append("Hello");
-        }
-
-        [Theory]
-        [InlineData(null, new object[] { null, null })]
-        [InlineData("", new object[] { "", "" })]
-        [InlineData(" ", new object[] { })]
-        [InlineData(", ", new object[] { "" })]
-        public static void AppendJoin_NoValues_NoSpareCapacity_DoesNotThrow(string separator, object[] values)
-        {
-            var stringValues = Array.ConvertAll(values, _ => _?.ToString());
-            var enumerable = values.Select(_ => _);
-
-            if (separator?.Length == 1)
-            {
-                CreateBuilderWithNoSpareCapacity().AppendJoin(separator[0], values);
-                CreateBuilderWithNoSpareCapacity().AppendJoin(separator[0], enumerable);
-                CreateBuilderWithNoSpareCapacity().AppendJoin(separator[0], stringValues);
-            }
-            CreateBuilderWithNoSpareCapacity().AppendJoin(separator, values);
-            CreateBuilderWithNoSpareCapacity().AppendJoin(separator, enumerable);
-            CreateBuilderWithNoSpareCapacity().AppendJoin(separator, stringValues);
-        }
-
-        [Theory]
-        [InlineData(null, new object[] { " " })]
-        [InlineData(" ", new object[] { " " })]
-        [InlineData(" ", new object[] { null, null })]
-        [InlineData(" ", new object[] { "", "" })]
-        public static void AppendJoin_NoSpareCapacity_ThrowsArgumentOutOfRangeException(string separator, object[] values)
-        {
-            var builder = new StringBuilder(0, 5);
-            builder.Append("Hello");
-
-            var stringValues = Array.ConvertAll(values, _ => _?.ToString());
-            var enumerable = values.Select(_ => _);
-
-            if (separator?.Length == 1)
-            {
-                AssertExtensions.Throws<ArgumentOutOfRangeException>(s_noCapacityParamName, () => CreateBuilderWithNoSpareCapacity().AppendJoin(separator[0], values));
-                AssertExtensions.Throws<ArgumentOutOfRangeException>(s_noCapacityParamName, () => CreateBuilderWithNoSpareCapacity().AppendJoin(separator[0], enumerable));
-                AssertExtensions.Throws<ArgumentOutOfRangeException>(s_noCapacityParamName, () => CreateBuilderWithNoSpareCapacity().AppendJoin(separator[0], stringValues));
-            }
-            AssertExtensions.Throws<ArgumentOutOfRangeException>(s_noCapacityParamName, () => CreateBuilderWithNoSpareCapacity().AppendJoin(separator, values));
-            AssertExtensions.Throws<ArgumentOutOfRangeException>(s_noCapacityParamName, () => CreateBuilderWithNoSpareCapacity().AppendJoin(separator, enumerable));
-            AssertExtensions.Throws<ArgumentOutOfRangeException>(s_noCapacityParamName, () => CreateBuilderWithNoSpareCapacity().AppendJoin(separator, stringValues));
-        }
-
-        [Theory]
-        [InlineData("Hello", new char[] { 'a' }, "Helloa")]
-        [InlineData("Hello", new char[] { 'b', 'c', 'd' }, "Hellobcd")]
-        [InlineData("Hello", new char[] { 'b', '\0', 'd' }, "Hellob\0d")]
-        [InlineData("", new char[] { 'e', 'f', 'g' }, "efg")]
-        [InlineData("Hello", new char[0], "Hello")]
-        public static void Append_CharSpan(string original, char[] value, string expected)
-        {
-            var builder = new StringBuilder(original);
-            builder.Append(new ReadOnlySpan<char>(value));
-            Assert.Equal(expected, builder.ToString());
-        }
-
-        [Theory]
-        [InlineData("Hello", new char[] { 'a' }, "Helloa")]
-        [InlineData("Hello", new char[] { 'b', 'c', 'd' }, "Hellobcd")]
-        [InlineData("Hello", new char[] { 'b', '\0', 'd' }, "Hellob\0d")]
-        [InlineData("", new char[] { 'e', 'f', 'g' }, "efg")]
-        [InlineData("Hello", new char[0], "Hello")]
-        public static void Append_CharMemory(string original, char[] value, string expected)
-        {
-            var builder = new StringBuilder(original);
-            builder.Append(value.AsMemory());
-            Assert.Equal(expected, builder.ToString());
-        }
-
-        [Theory]
-        [InlineData(1)]
-        [InlineData(10000)]
-        public static void Clear_AppendAndInsertBeforeClearManyTimes_CapacityStaysWithinRange(int times)
-        {
-            var builder = new StringBuilder();
-            var originalCapacity = builder.Capacity;
-            var s = new string(' ', 10);
-            int oldLength = 0;
-            for (int i = 0; i < times; i++)
-            {
-                builder.Append(s);
-                builder.Append(s);
-                builder.Append(s);
-                builder.Insert(0, s);
-                builder.Insert(0, s);
-                oldLength = builder.Length;
-
-                builder.Clear();
-            }
-            Assert.InRange(builder.Capacity, 1, oldLength * 1.2);
-        }
-
-        [Fact]
-        public static void Clear_InitialCapacityMuchLargerThanLength_CapacityReducedToInitialCapacity()
-        {
-            var builder = new StringBuilder(100);
-            var initialCapacity = builder.Capacity;
-            builder.Append(new string('a', 40));
-            builder.Insert(0, new string('a', 10));
-            builder.Insert(0, new string('a', 10));
-            builder.Insert(0, new string('a', 10));
-            var oldCapacity = builder.Capacity;
-            var oldLength = builder.Length;
-            builder.Clear();
-            Assert.NotEqual(oldCapacity, builder.Capacity);
-            Assert.Equal(initialCapacity, builder.Capacity);
-            Assert.NotInRange(builder.Capacity, 1, oldLength * 1.2);
-            Assert.InRange(builder.Capacity, 1, Math.Max(initialCapacity, oldLength * 1.2));
-        }
-
-        [Fact]
-        public static void Clear_StringBuilderHasTwoChunks_OneChunkIsEmpty_ClearReducesCapacity()
-        {
-            var sb = new StringBuilder(string.Empty);
-            int initialCapacity = sb.Capacity;
-            for (int i = 0; i < initialCapacity; i++)
-            {
-                sb.Append('a');
-            }
-            sb.Insert(0, 'a');
-            while (sb.Length > 1)
-            {
-                sb.Remove(1, 1);
-            }
-            int oldCapacity = sb.Capacity;
-            sb.Clear();
-            Assert.Equal(oldCapacity - 1, sb.Capacity);
-            Assert.Equal(initialCapacity, sb.Capacity);
-        }
-
-        [Theory]
-        [InlineData("Hello", 0, new char[] { '\0', '\0', '\0', '\0', '\0' }, 5, new char[] { 'H', 'e', 'l', 'l', 'o' })]
-        [InlineData("Hello", 0, new char[] { '\0', '\0', '\0', '\0' }, 4, new char[] { 'H', 'e', 'l', 'l' })]
-        [InlineData("Hello", 1, new char[] { '\0', '\0', '\0', '\0', '\0' }, 4, new char[] { 'e', 'l', 'l', 'o', '\0' })]
-        public static void CopyTo_CharSpan(string value, int sourceIndex, char[] destination, int count, char[] expected)
-        {
-            var builder = new StringBuilder(value);
-            builder.CopyTo(sourceIndex, new Span<char>(destination), count);
-            Assert.Equal(expected, destination);
-        }
-
-        [Fact]
-        public static void CopyTo_CharSpan_StringBuilderWithMultipleChunks()
-        {
-            StringBuilder builder = StringBuilderWithMultipleChunks();
-            char[] destination = new char[builder.Length];
-            builder.CopyTo(0, new Span<char>(destination), destination.Length);
-            Assert.Equal(s_chunkSplitSource.ToCharArray(), destination);
-        }
-
-        [Fact]
-        public static void CopyTo_CharSpan_Invalid()
-        {
-            var builder = new StringBuilder("Hello");
-
-            AssertExtensions.Throws<ArgumentOutOfRangeException>("sourceIndex", () => builder.CopyTo(-1, new Span<char>(new char[10]), 0)); // Source index < 0
-            AssertExtensions.Throws<ArgumentOutOfRangeException>("sourceIndex", () => builder.CopyTo(6, new Span<char>(new char[10]), 0)); // Source index > builder.Length
-
-            AssertExtensions.Throws<ArgumentOutOfRangeException>("count", () => builder.CopyTo(0, new Span<char>(new char[10]), -1)); // Count < 0
-
-            AssertExtensions.Throws<ArgumentException>(null, () => builder.CopyTo(5, new Span<char>(new char[10]), 1)); // Source index + count > builder.Length
-            AssertExtensions.Throws<ArgumentException>(null, () => builder.CopyTo(4, new Span<char>(new char[10]), 2)); // Source index + count > builder.Length
-
-            AssertExtensions.Throws<ArgumentException>(null, () => builder.CopyTo(0, new Span<char>(new char[10]), 11)); // count > destinationArray.Length
-        }
-
-        [Theory]
-        [InlineData("Hello", 0, new char[] { '\0' }, "\0Hello")]
-        [InlineData("Hello", 3, new char[] { 'a', 'b', 'c' }, "Helabclo")]
-        [InlineData("Hello", 5, new char[] { 'd', 'e', 'f' }, "Hellodef")]
-        [InlineData("Hello", 0, new char[0], "Hello")]
-        public static void Insert_CharSpan(string original, int index, char[] value, string expected)
-        {
-            var builder = new StringBuilder(original);
-            builder.Insert(index, new ReadOnlySpan<char>(value));
-            Assert.Equal(expected, builder.ToString());
-        }
-
-        [Fact]
-        public static void Insert_CharSpan_Invalid()
-        {
-            var builder = new StringBuilder(0, 5);
-            builder.Append("Hello");
-
-            AssertExtensions.Throws<ArgumentOutOfRangeException>("index", () => builder.Insert(-1, new ReadOnlySpan<char>(new char[0]))); // Index < 0
-            AssertExtensions.Throws<ArgumentOutOfRangeException>("index", () => builder.Insert(builder.Length + 1, new ReadOnlySpan<char>(new char[0]))); // Index > builder.Length
-            AssertExtensions.Throws<ArgumentOutOfRangeException>("requiredLength", () => builder.Insert(builder.Length, new ReadOnlySpan<char>(new char[1]))); // New length > builder.MaxCapacity
-        }
-
-        public static IEnumerable<object[]> Append_StringBuilder_TestData()
-        {
-            string mediumString = new string('a', 30);
-            string largeString = new string('b', 1000);
-
-            var sb1 = new StringBuilder("Hello");
-            var sb2 = new StringBuilder("one");
-            var sb3 = new StringBuilder(20).Append(mediumString);
-
-            yield return new object[] { new StringBuilder("Hello"), sb1, "HelloHello" };
-            yield return new object[] { new StringBuilder("Hello"), sb2, "Helloone" };
-            yield return new object[] { new StringBuilder("Hello"), new StringBuilder(), "Hello" };
-
-            yield return new object[] { new StringBuilder("one"), sb3, "one" + mediumString };
-
-            yield return new object[] { new StringBuilder(20).Append(mediumString), sb3, mediumString + mediumString };
-            yield return new object[] { new StringBuilder(10).Append(mediumString), sb3, mediumString + mediumString };
-
-            yield return new object[] { new StringBuilder(20).Append(largeString), sb3, largeString + mediumString };
-            yield return new object[] { new StringBuilder(10).Append(largeString), sb3, largeString + mediumString };
-
-            yield return new object[] { new StringBuilder(10), sb3, mediumString };
-            yield return new object[] { new StringBuilder(30), sb3, mediumString };
-            yield return new object[] { new StringBuilder(10), new StringBuilder(20), string.Empty};
-
-            yield return new object[] { sb1, null, "Hello" };
-            yield return new object[] { sb1, sb1, "HelloHello" };
-        }
-
-        [Theory]
-        [MemberData(nameof(Append_StringBuilder_TestData))]
-        public static void Append_StringBuilder(StringBuilder s1, StringBuilder s2, string s)
-        {
-            Assert.Equal(s, s1.Append(s2).ToString());
-        }
-
-        public static IEnumerable<object[]> Append_StringBuilder_Substring_TestData()
-        {
-            string mediumString = new string('a', 30);
-            string largeString = new string('b', 1000);
-
-            var sb1 = new StringBuilder("Hello");
-            var sb2 = new StringBuilder("one");
-            var sb3 = new StringBuilder(20).Append(mediumString);
-
-            yield return new object[] { new StringBuilder("Hello"), sb1, 0, 5, "HelloHello" };
-            yield return new object[] { new StringBuilder("Hello"), sb1, 0, 0, "Hello" };
-            yield return new object[] { new StringBuilder("Hello"), sb1, 2, 3, "Hellollo" };
-            yield return new object[] { new StringBuilder("Hello"), sb1, 2, 2, "Helloll" };
-            yield return new object[] { new StringBuilder("Hello"), sb1, 2, 0, "Hello" };
-            yield return new object[] { new StringBuilder("Hello"), new StringBuilder(), 0, 0, "Hello" };
-            yield return new object[] { new StringBuilder("Hello"), null, 0, 0, "Hello" };
-            yield return new object[] { new StringBuilder(), new StringBuilder("Hello"), 2, 3, "llo" };
-            yield return new object[] { new StringBuilder("Hello"), sb2, 0, 3, "Helloone" };
-
-            yield return new object[] { new StringBuilder("one"), sb3, 5, 25, "one" + new string('a', 25) };
-            yield return new object[] { new StringBuilder("one"), sb3, 5, 20, "one" + new string('a', 20) };
-            yield return new object[] { new StringBuilder("one"), sb3, 10, 10, "one" + new string('a', 10) };
-
-            yield return new object[] { new StringBuilder(20).Append(mediumString), sb3, 20, 10, new string('a', 40) };
-            yield return new object[] { new StringBuilder(10).Append(mediumString), sb3, 10, 10, new string('a', 40) };
-
-            yield return new object[] { new StringBuilder(20).Append(largeString), new StringBuilder(20).Append(largeString), 100, 50, largeString + new string('b', 50) };
-            yield return new object[] { new StringBuilder(10).Append(mediumString), new StringBuilder(20).Append(largeString), 20, 10, mediumString + new string('b', 10) };
-            yield return new object[] { new StringBuilder(10).Append(mediumString), new StringBuilder(20).Append(largeString), 100, 50, mediumString + new string('b', 50) };
-
-            yield return new object[] { sb1, sb1, 2, 3, "Hellollo" };
-            yield return new object[] { sb2, sb2, 2, 0, "one" };
-        }
-
-        [Theory]
-        [MemberData(nameof(Append_StringBuilder_Substring_TestData))]
-        public static void Append_StringBuilder_Substring(StringBuilder s1, StringBuilder s2, int startIndex, int count, string s)
-        {
-            Assert.Equal(s, s1.Append(s2, startIndex, count).ToString());
-        }
-
-        [Fact]
-        public static void Append_StringBuilder_InvalidInput()
-        {
-            StringBuilder sb = new StringBuilder(5, 5).Append("Hello");
-
-            Assert.Throws<ArgumentOutOfRangeException>(() => sb.Append(sb, -1, 0));
-            Assert.Throws<ArgumentOutOfRangeException>(() => sb.Append(sb, 0, -1));
-            Assert.Throws<ArgumentOutOfRangeException>(() => sb.Append(sb, 4, 5));
-
-            Assert.Throws<ArgumentNullException>(() => sb.Append( (StringBuilder)null, 2, 2));
-            Assert.Throws<ArgumentNullException>(() => sb.Append((StringBuilder)null, 2, 3));
-            Assert.Throws<ArgumentOutOfRangeException>(() => new StringBuilder(3, 6).Append("Hello").Append(sb));
-            Assert.Throws<ArgumentOutOfRangeException>(() => new StringBuilder(3, 6).Append("Hello").Append("Hello"));
-
-            Assert.Throws<ArgumentOutOfRangeException>(() => sb.Append(sb));
-        }
-
-        public static IEnumerable<object[]> Equals_String_TestData()
-        {
-            string mediumString = new string('a', 30);
-            string largeString = new string('a', 1000);
-            string extraLargeString = new string('a', 41000); // 8000 is the maximum chunk size
-
-            var sb1 = new StringBuilder("Hello");
-            var sb2 = new StringBuilder(20).Append(mediumString);
-            var sb3 = new StringBuilder(20).Append(largeString);
-            var sb4 = new StringBuilder(20).Append(extraLargeString);
-
-            yield return new object[] { sb1, "Hello", true };
-            yield return new object[] { sb1, "Hel", false };
-            yield return new object[] { sb1, "Hellz", false };
-            yield return new object[] { sb1, "Helloz", false };
-            yield return new object[] { sb1, "", false };
-            yield return new object[] { new StringBuilder(), "", true };
-            yield return new object[] { new StringBuilder(), "Hello", false };
-            yield return new object[] { sb2, mediumString, true };
-            yield return new object[] { sb2, "H", false };
-            yield return new object[] { sb3, largeString, true };
-            yield return new object[] { sb3, "H", false };
-            yield return new object[] { sb3, new string('a', 999) + 'b', false };
-            yield return new object[] { sb4, extraLargeString, true };
-            yield return new object[] { sb4, "H", false };
-        }
-
-        [Theory]
-        [MemberData(nameof(Equals_String_TestData))]
-        public static void Equals(StringBuilder sb1, string value, bool expected)
-        {
-            Assert.Equal(expected, sb1.Equals(value.AsSpan()));
-        }
-
-        [Fact]
-        public static void ForEach()
-        {
-            // Test on a variety of lengths, at least up to the point of 9 8K chunks = 72K because this is where
-            // we start using a different technique for creating the ChunkEnumerator.   200 * 500 = 100K which hits this.
-            for (int i = 0; i < 200; i++)
-            {
-                StringBuilder inBuilder = new StringBuilder();
-                for (int j = 0; j < i; j++)
-                {
-                    // Make some unique strings that are at least 500 bytes long.
-                    inBuilder.Append(j);
-                    inBuilder.Append("_abcdefghijklmnopqrstuvwxyz01234567890__Abcdefghijklmnopqrstuvwxyz01234567890__ABcdefghijklmnopqrstuvwxyz01_");
-                    inBuilder.Append("_abcdefghijklmnopqrstuvwxyz01234567890__Abcdefghijklmnopqrstuvwxyz01234567890__ABcdefghijklmnopqrstuvwxyz0123_");
-                    inBuilder.Append("_abcdefghijklmnopqrstuvwxyz01234567890__Abcdefghijklmnopqrstuvwxyz01234567890__ABcdefghijklmnopqrstuvwxyz012345_");
-                    inBuilder.Append("_abcdefghijklmnopqrstuvwxyz01234567890__Abcdefghijklmnopqrstuvwxyz01234567890__ABcdefghijklmnopqrstuvwxyz012345678_");
-                    inBuilder.Append("_abcdefghijklmnopqrstuvwxyz01234567890__Abcdefghijklmnopqrstuvwxyz01234567890__ABcdefghijklmnopqrstuvwxyz01234567890_");
-                }
-
-                // Copy the string out (not using StringBuilder).
-                string outStr = "";
-                foreach (ReadOnlyMemory<char> chunk in inBuilder.GetChunks())
-                    outStr += new string(chunk.Span);
-
-                // The strings formed by concatenating the chunks should be the same as the value in the StringBuilder.
-                Assert.Equal(outStr, inBuilder.ToString());
-            }
-        }
-
-        [Fact]
-        public static void EqualsIgnoresCapacity()
-        {
-            var sb1 = new StringBuilder(5);
-            var sb2 = new StringBuilder(10);
-
-            Assert.True(sb1.Equals(sb2));
-
-            sb1.Append("12345");
-            sb2.Append("12345");
-
-            Assert.True(sb1.Equals(sb2));
-        }
-
-        [Fact]
-        public static void EqualsIgnoresMaxCapacity()
-        {
-            var sb1 = new StringBuilder(5, 5);
-            var sb2 = new StringBuilder(5, 10);
-
-            Assert.True(sb1.Equals(sb2));
-
-            sb1.Append("12345");
-            sb2.Append("12345");
-
-            Assert.True(sb1.Equals(sb2));
-        }
-    }
-}
@@ -12,7 +12,7 @@ using Xunit;
 
 namespace System.Text.Unicode.Tests
 {
-    public partial class Utf16UtilityTests
+    public class Utf16UtilityTests
     {
         private unsafe delegate char* GetPointerToFirstInvalidCharDel(char* pInputBuffer, int inputLength, out long utf8CodeUnitCountAdjustment, out int scalarCountAdjustment);
         private static readonly Lazy<GetPointerToFirstInvalidCharDel> _getPointerToFirstInvalidCharFn = CreateGetPointerToFirstInvalidCharFn();
diff --git a/src/libraries/System.Runtime/tests/System/Text/Unicode/Utf8Tests.ToBytes.netcoreapp.cs b/src/libraries/System.Runtime/tests/System/Text/Unicode/Utf8Tests.ToBytes.netcoreapp.cs
deleted file mode 100644 (file)
index 5432da0..0000000
+++ /dev/null
@@ -1,304 +0,0 @@
-// 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.Buffers;
-using System.Linq;
-using Xunit;
-
-namespace System.Text.Unicode.Tests
-{
-    public partial class Utf8Tests
-    {
-        [Theory]
-        [InlineData("", "")] // empty string is OK
-        [InlineData(X_UTF16, X_UTF8)]
-        [InlineData(E_ACUTE_UTF16, E_ACUTE_UTF8)]
-        [InlineData(EURO_SYMBOL_UTF16, EURO_SYMBOL_UTF8)]
-        public void ToBytes_WithSmallValidBuffers(string utf16Input, string expectedUtf8TranscodingHex)
-        {
-            // These test cases are for the "slow processing" code path at the end of TranscodeToUtf8,
-            // so inputs should be less than 2 chars.
-
-            Assert.InRange(utf16Input.Length, 0, 1);
-
-            ToBytes_Test_Core(
-                utf16Input: utf16Input,
-                destinationSize: expectedUtf8TranscodingHex.Length / 2,
-                replaceInvalidSequences: false,
-                isFinalChunk: false,
-                expectedOperationStatus: OperationStatus.Done,
-                expectedNumCharsRead: utf16Input.Length,
-                expectedUtf8Transcoding: DecodeHex(expectedUtf8TranscodingHex));
-        }
-
-        [Theory]
-        [InlineData("AB")] // 2 ASCII chars, hits fast inner loop
-        [InlineData("ABCD")] // 4 ASCII chars, hits fast inner loop
-        [InlineData("ABCDEF")] // 6 ASCII chars, hits fast inner loop
-        [InlineData("ABCDEFGH")] // 8 ASCII chars, hits fast inner loop
-        [InlineData("ABCDEFGHIJ")] // 10 ASCII chars, hits fast inner loop
-        [InlineData("ABCDEF" + E_ACUTE_UTF16 + "HIJ")] // interrupts inner loop due to non-ASCII char in first char of first DWORD
-        [InlineData("ABCDEFG" + EURO_SYMBOL_UTF16 + "IJ")] // interrupts inner loop due to non-ASCII char in second char of first DWORD
-        [InlineData("ABCDEFGH" + E_ACUTE_UTF16 + "J")] // interrupts inner loop due to non-ASCII char in first char of second DWORD
-        [InlineData("ABCDEFGHI" + EURO_SYMBOL_UTF16)] // interrupts inner loop due to non-ASCII char in second char of second DWORD
-        [InlineData(X_UTF16 + E_ACUTE_UTF16)] // drains first ASCII char then falls down to slow path
-        [InlineData(X_UTF16 + E_ACUTE_UTF16 + E_ACUTE_UTF16)] // drains first ASCII char then consumes 2x 2-byte sequences at once
-        [InlineData(E_ACUTE_UTF16 + X_UTF16)] // no first ASCII char to drain, consumes 2-byte seq followed by ASCII char
-        [InlineData(E_ACUTE_UTF16 + E_ACUTE_UTF16 + E_ACUTE_UTF16 + E_ACUTE_UTF16)] // stay within 2x 2-byte sequence processing loop
-        [InlineData(E_ACUTE_UTF16 + E_ACUTE_UTF16 + E_ACUTE_UTF16 + X_UTF16)] // break out of 2x 2-byte seq loop due to ASCII data in second char of DWORD
-        [InlineData(E_ACUTE_UTF16 + E_ACUTE_UTF16 + X_UTF16 + X_UTF16)] // break out of 2x 2-byte seq loop due to ASCII data in first char of DWORD
-        [InlineData(E_ACUTE_UTF16 + E_ACUTE_UTF16 + E_ACUTE_UTF16 + EURO_SYMBOL_UTF16)] // break out of 2x 2-byte seq loop due to 3-byte data
-        [InlineData(E_ACUTE_UTF16 + EURO_SYMBOL_UTF16)] // 2-byte logic sees next char isn't ASCII, cannot read full DWORD from remaining input buffer, falls down to slow drain loop
-        [InlineData(EURO_SYMBOL_UTF16 + EURO_SYMBOL_UTF16 + X_UTF16)] // 2x 3-byte logic can't read a full DWORD from next part of buffer, falls down to slow drain loop
-        [InlineData(EURO_SYMBOL_UTF16 + X_UTF16)] // 3-byte processing loop consumes trailing ASCII char, but can't read next DWORD, falls down to slow drain loop
-        [InlineData(EURO_SYMBOL_UTF16 + X_UTF16 + X_UTF16)] // 3-byte processing loop consumes trailing ASCII char, but can't read next DWORD, falls down to slow drain loop
-        [InlineData(EURO_SYMBOL_UTF16 + E_ACUTE_UTF16)] // 3-byte processing loop can't consume next ASCII char, can't read DWORD, falls down to slow drain loop
-        [InlineData(EURO_SYMBOL_UTF16 + EURO_SYMBOL_UTF16 + EURO_SYMBOL_UTF16 + EURO_SYMBOL_UTF16)] // stay within 2x 3-byte sequence processing loop
-        [InlineData(EURO_SYMBOL_UTF16 + EURO_SYMBOL_UTF16 + X_UTF16 + EURO_SYMBOL_UTF16 + EURO_SYMBOL_UTF16 + EURO_SYMBOL_UTF16)] // consume stray ASCII char at beginning of DWORD after 2x 3-byte sequence
-        [InlineData(EURO_SYMBOL_UTF16 + EURO_SYMBOL_UTF16 + EURO_SYMBOL_UTF16 + X_UTF16 + EURO_SYMBOL_UTF16 + EURO_SYMBOL_UTF16)] // consume stray ASCII char at end of DWORD after 2x 3-byte sequence
-        [InlineData(EURO_SYMBOL_UTF16 + E_ACUTE_UTF16 + X_UTF16)] // consume 2-byte sequence as second char in DWORD which begins with 3-byte encoded char
-        [InlineData(EURO_SYMBOL_UTF16 + GRINNING_FACE_UTF16)] // 3-byte sequence followed by 4-byte sequence
-        [InlineData(EURO_SYMBOL_UTF16 + EURO_SYMBOL_UTF16 + GRINNING_FACE_UTF16)] // 2x 3-byte sequence followed by 4-byte sequence
-        [InlineData(GRINNING_FACE_UTF16)] // single 4-byte surrogate char pair
-        [InlineData(GRINNING_FACE_UTF16 + EURO_SYMBOL_UTF16)] // 4-byte surrogate char pair, cannot read next DWORD, falls down to slow drain loop
-        public void ToBytes_WithLargeValidBuffers(string utf16Input)
-        {
-            // These test cases are for the "fast processing" code which is the main loop of TranscodeToUtf8,
-            // so inputs should be at least 2 chars.
-
-            Assert.True(utf16Input.Length >= 2);
-
-            // We're going to run the tests with destination buffer lengths ranging from 0 all the way
-            // to buffers large enough to hold the full output. This allows us to test logic that
-            // detects whether we're about to overrun our destination buffer and instead returns DestinationTooSmall.
-
-            Rune[] enumeratedScalars = utf16Input.EnumerateRunes().ToArray();
-
-            // 0-length buffer test
-            ToBytes_Test_Core(
-                utf16Input: utf16Input,
-                destinationSize: 0,
-                replaceInvalidSequences: false,
-                isFinalChunk: false,
-                expectedOperationStatus: OperationStatus.DestinationTooSmall,
-                expectedNumCharsRead: 0,
-                expectedUtf8Transcoding: ReadOnlySpan<byte>.Empty);
-
-            int expectedNumCharsConsumed = 0;
-            byte[] concatenatedUtf8 = Array.Empty<byte>();
-
-            for (int i = 0; i < enumeratedScalars.Length; i++)
-            {
-                Rune thisScalar = enumeratedScalars[i];
-
-                // provide partial destination buffers all the way up to (but not including) enough to hold the next full scalar encoding
-                for (int j = 1; j < thisScalar.Utf8SequenceLength; j++)
-                {
-                    ToBytes_Test_Core(
-                        utf16Input: utf16Input,
-                        destinationSize: concatenatedUtf8.Length + j,
-                        replaceInvalidSequences: false,
-                        isFinalChunk: false,
-                        expectedOperationStatus: OperationStatus.DestinationTooSmall,
-                        expectedNumCharsRead: expectedNumCharsConsumed,
-                        expectedUtf8Transcoding: concatenatedUtf8);
-                }
-
-                // now provide a destination buffer large enough to hold the next full scalar encoding
-
-                expectedNumCharsConsumed += thisScalar.Utf16SequenceLength;
-                concatenatedUtf8 = concatenatedUtf8.Concat(ToUtf8(thisScalar)).ToArray();
-
-                ToBytes_Test_Core(
-                   utf16Input: utf16Input,
-                   destinationSize: concatenatedUtf8.Length,
-                   replaceInvalidSequences: false,
-                   isFinalChunk: false,
-                   expectedOperationStatus: (i == enumeratedScalars.Length - 1) ? OperationStatus.Done : OperationStatus.DestinationTooSmall,
-                   expectedNumCharsRead: expectedNumCharsConsumed,
-                   expectedUtf8Transcoding: concatenatedUtf8);
-            }
-
-            // now throw lots of ASCII data at the beginning so that we exercise the vectorized code paths
-
-            utf16Input = new string('x', 64) + utf16Input;
-            concatenatedUtf8 = utf16Input.EnumerateRunes().SelectMany(ToUtf8).ToArray();
-
-            ToBytes_Test_Core(
-                utf16Input: utf16Input,
-                destinationSize: concatenatedUtf8.Length,
-                replaceInvalidSequences: false,
-                isFinalChunk: true,
-                expectedOperationStatus: OperationStatus.Done,
-                expectedNumCharsRead: utf16Input.Length,
-                expectedUtf8Transcoding: concatenatedUtf8);
-
-            // now throw some non-ASCII data at the beginning so that we *don't* exercise the vectorized code paths
-
-            utf16Input = WOMAN_CARTWHEELING_MEDSKIN_UTF16 + utf16Input[64..];
-            concatenatedUtf8 = utf16Input.EnumerateRunes().SelectMany(ToUtf8).ToArray();
-
-            ToBytes_Test_Core(
-                utf16Input: utf16Input,
-                destinationSize: concatenatedUtf8.Length,
-                replaceInvalidSequences: false,
-                isFinalChunk: true,
-                expectedOperationStatus: OperationStatus.Done,
-                expectedNumCharsRead: utf16Input.Length,
-                expectedUtf8Transcoding: concatenatedUtf8);
-        }
-
-        [Theory]
-        [InlineData('\uD800', OperationStatus.NeedMoreData)] // standalone high surrogate
-        [InlineData('\uDFFF', OperationStatus.InvalidData)] // standalone low surrogate
-        public void ToBytes_WithOnlyStandaloneSurrogates(char charValue, OperationStatus expectedOperationStatus)
-        {
-            ToBytes_Test_Core(
-                utf16Input: new[] { charValue },
-                destinationSize: 0,
-                replaceInvalidSequences: false,
-                isFinalChunk: false,
-                expectedOperationStatus: expectedOperationStatus,
-                expectedNumCharsRead: 0,
-                expectedUtf8Transcoding: Span<byte>.Empty);
-        }
-
-        [Theory]
-        [InlineData("<LOW><HIGH>", 0, "")] // swapped surrogate pair characters
-        [InlineData("A<LOW><HIGH>", 1, "41")] // consume standalone ASCII char, then swapped surrogate pair characters
-        [InlineData("A<HIGH>B", 1, "41")] // consume standalone ASCII char, then standalone high surrogate char
-        [InlineData("A<LOW>B", 1, "41")] // consume standalone ASCII char, then standalone low surrogate char
-        [InlineData("AB<HIGH><HIGH>", 2, "4142")] // consume two ASCII chars, then standalone high surrogate char
-        [InlineData("AB<LOW><LOW>", 2, "4142")] // consume two ASCII chars, then standalone low surrogate char
-        public void ToBytes_WithInvalidSurrogates(string utf16Input, int expectedNumCharsConsumed, string expectedUtf8TranscodingHex)
-        {
-            // xUnit can't handle ill-formed strings in [InlineData], so we replace here.
-
-            utf16Input = utf16Input.Replace("<HIGH>", "\uD800").Replace("<LOW>", "\uDFFF");
-
-            // These test cases are for the "fast processing" code which is the main loop of TranscodeToUtf8,
-            // so inputs should be at least 2 chars.
-
-            Assert.True(utf16Input.Length >= 2);
-
-            ToBytes_Test_Core(
-                utf16Input: utf16Input,
-                destinationSize: expectedUtf8TranscodingHex.Length / 2,
-                replaceInvalidSequences: false,
-                isFinalChunk: false,
-                expectedOperationStatus: OperationStatus.InvalidData,
-                expectedNumCharsRead: expectedNumCharsConsumed,
-                expectedUtf8Transcoding: DecodeHex(expectedUtf8TranscodingHex));
-
-            // Now try the tests again with a larger buffer.
-            // This ensures that running out of destination space wasn't the reason we failed.
-
-            ToBytes_Test_Core(
-                utf16Input: utf16Input,
-                destinationSize: (expectedUtf8TranscodingHex.Length) / 2 + 16,
-                replaceInvalidSequences: false,
-                isFinalChunk: false,
-                expectedOperationStatus: OperationStatus.InvalidData,
-                expectedNumCharsRead: expectedNumCharsConsumed,
-                expectedUtf8Transcoding: DecodeHex(expectedUtf8TranscodingHex));
-        }
-
-        [Theory]
-        [InlineData("<LOW><HIGH>", REPLACEMENT_CHAR_UTF8)] // standalone low surr. and incomplete high surr.
-        [InlineData("<HIGH><HIGH>", REPLACEMENT_CHAR_UTF8)] // standalone high surr. and incomplete high surr.
-        [InlineData("<LOW><LOW>", REPLACEMENT_CHAR_UTF8 + REPLACEMENT_CHAR_UTF8)] // standalone low surr. and incomplete low surr.
-        [InlineData("A<LOW>B<LOW>C<HIGH>D", "41" + REPLACEMENT_CHAR_UTF8 + "42" + REPLACEMENT_CHAR_UTF8 + "43" + REPLACEMENT_CHAR_UTF8 + "44")] // standalone low, low, high surrounded by other data
-        public void ToBytes_WithReplacements(string utf16Input, string expectedUtf8TranscodingHex)
-        {
-            // xUnit can't handle ill-formed strings in [InlineData], so we replace here.
-
-            utf16Input = utf16Input.Replace("<HIGH>", "\uD800").Replace("<LOW>", "\uDFFF");
-
-            bool isFinalCharHighSurrogate = char.IsHighSurrogate(utf16Input.Last());
-
-            ToBytes_Test_Core(
-                utf16Input: utf16Input,
-                destinationSize: expectedUtf8TranscodingHex.Length / 2,
-                replaceInvalidSequences: true,
-                isFinalChunk: false,
-                expectedOperationStatus: (isFinalCharHighSurrogate) ? OperationStatus.NeedMoreData : OperationStatus.Done,
-                expectedNumCharsRead: (isFinalCharHighSurrogate) ? (utf16Input.Length - 1) : utf16Input.Length,
-                expectedUtf8Transcoding: DecodeHex(expectedUtf8TranscodingHex));
-
-            if (isFinalCharHighSurrogate)
-            {
-                // Also test with isFinalChunk = true
-                ToBytes_Test_Core(
-                    utf16Input: utf16Input,
-                    destinationSize: expectedUtf8TranscodingHex.Length / 2 + Rune.ReplacementChar.Utf8SequenceLength /* for replacement char */,
-                    replaceInvalidSequences: true,
-                    isFinalChunk: true,
-                    expectedOperationStatus: OperationStatus.Done,
-                    expectedNumCharsRead: utf16Input.Length,
-                    expectedUtf8Transcoding: DecodeHex(expectedUtf8TranscodingHex + REPLACEMENT_CHAR_UTF8));
-            }
-        }
-
-        [Theory]
-        [InlineData(E_ACUTE_UTF16 + "<LOW>", true, 1, OperationStatus.DestinationTooSmall, E_ACUTE_UTF8)] // not enough output buffer to hold U+FFFD
-        [InlineData(E_ACUTE_UTF16 + "<LOW>", true, 2, OperationStatus.Done, E_ACUTE_UTF8 + REPLACEMENT_CHAR_UTF8)] // replace standalone low surr. at end
-        [InlineData(E_ACUTE_UTF16 + "<HIGH>", true, 1, OperationStatus.DestinationTooSmall, E_ACUTE_UTF8)] // not enough output buffer to hold U+FFFD
-        [InlineData(E_ACUTE_UTF16 + "<HIGH>", true, 2, OperationStatus.Done, E_ACUTE_UTF8 + REPLACEMENT_CHAR_UTF8)] // replace standalone high surr. at end
-        [InlineData(E_ACUTE_UTF16 + "<HIGH>", false, 1, OperationStatus.NeedMoreData, E_ACUTE_UTF8)] // don't replace standalone high surr. at end
-        [InlineData(E_ACUTE_UTF16 + "<HIGH>" + X_UTF16, true, 2, OperationStatus.DestinationTooSmall, E_ACUTE_UTF8 + REPLACEMENT_CHAR_UTF8)] // not enough output buffer to hold 'X'
-        [InlineData(E_ACUTE_UTF16 + "<HIGH>" + X_UTF16, false, 2, OperationStatus.DestinationTooSmall, E_ACUTE_UTF8 + REPLACEMENT_CHAR_UTF8)] // not enough output buffer to hold 'X'
-        [InlineData(E_ACUTE_UTF16 + "<HIGH>" + X_UTF16, true, 3, OperationStatus.Done, E_ACUTE_UTF8 + REPLACEMENT_CHAR_UTF8 + X_UTF8)] // replacement followed by 'X'
-        [InlineData(E_ACUTE_UTF16 + "<HIGH>" + X_UTF16, false, 3, OperationStatus.Done, E_ACUTE_UTF8 + REPLACEMENT_CHAR_UTF8 + X_UTF8)] // replacement followed by 'X'
-        public void ToBytes_WithReplacements_AndCustomBufferSizes(string utf16Input, bool isFinalChunk, int expectedNumCharsConsumed, OperationStatus expectedOperationStatus, string expectedUtf8TranscodingHex)
-        {
-            // xUnit can't handle ill-formed strings in [InlineData], so we replace here.
-
-            utf16Input = utf16Input.Replace("<HIGH>", "\uD800").Replace("<LOW>", "\uDFFF");
-
-            ToBytes_Test_Core(
-                utf16Input: utf16Input,
-                destinationSize: expectedUtf8TranscodingHex.Length / 2,
-                replaceInvalidSequences: true,
-                isFinalChunk: isFinalChunk,
-                expectedOperationStatus: expectedOperationStatus,
-                expectedNumCharsRead: expectedNumCharsConsumed,
-                expectedUtf8Transcoding: DecodeHex(expectedUtf8TranscodingHex));
-        }
-
-        [Fact]
-        public void ToBytes_AllPossibleScalarValues()
-        {
-            ToBytes_Test_Core(
-                utf16Input: s_allScalarsAsUtf16.Span,
-                destinationSize: s_allScalarsAsUtf8.Length,
-                replaceInvalidSequences: false,
-                isFinalChunk: false,
-                expectedOperationStatus: OperationStatus.Done,
-                expectedNumCharsRead: s_allScalarsAsUtf16.Length,
-                expectedUtf8Transcoding: s_allScalarsAsUtf8.Span);
-        }
-
-        private static void ToBytes_Test_Core(ReadOnlySpan<char> utf16Input, int destinationSize, bool replaceInvalidSequences, bool isFinalChunk, OperationStatus expectedOperationStatus, int expectedNumCharsRead, ReadOnlySpan<byte> expectedUtf8Transcoding)
-        {
-            // Arrange
-
-            using (BoundedMemory<char> boundedSource = BoundedMemory.AllocateFromExistingData(utf16Input))
-            using (BoundedMemory<byte> boundedDestination = BoundedMemory.Allocate<byte>(destinationSize))
-            {
-                boundedSource.MakeReadonly();
-
-                // Act
-
-                OperationStatus actualOperationStatus = Utf8.FromUtf16(boundedSource.Span, boundedDestination.Span, out int actualNumCharsRead, out int actualNumBytesWritten, replaceInvalidSequences, isFinalChunk);
-
-                // Assert
-
-                Assert.Equal(expectedOperationStatus, actualOperationStatus);
-                Assert.Equal(expectedNumCharsRead, actualNumCharsRead);
-                Assert.Equal(expectedUtf8Transcoding.Length, actualNumBytesWritten);
-                Assert.Equal(expectedUtf8Transcoding.ToArray(), boundedDestination.Span.Slice(0, actualNumBytesWritten).ToArray());
-            }
-        }
-    }
-}
 // See the LICENSE file in the project root for more information.
 
 using System.Buffers;
+using System.Collections.Generic;
+using System.Globalization;
 using System.Linq;
+using System.Text.RegularExpressions;
 using Xunit;
 
 namespace System.Text.Unicode.Tests
 {
-    public partial class Utf8Tests
+    public class Utf8Tests
     {
+        private const string X_UTF8 = "58"; // U+0058 LATIN CAPITAL LETTER X, 1 byte
+        private const string X_UTF16 = "X";
+
+        private const string Y_UTF8 = "59"; // U+0058 LATIN CAPITAL LETTER Y, 1 byte
+        private const string Y_UTF16 = "Y";
+
+        private const string Z_UTF8 = "5A"; // U+0058 LATIN CAPITAL LETTER Z, 1 byte
+        private const string Z_UTF16 = "Z";
+
+        private const string E_ACUTE_UTF8 = "C3A9"; // U+00E9 LATIN SMALL LETTER E WITH ACUTE, 2 bytes
+        private const string E_ACUTE_UTF16 = "\u00E9";
+
+        private const string EURO_SYMBOL_UTF8 = "E282AC"; // U+20AC EURO SIGN, 3 bytes
+        private const string EURO_SYMBOL_UTF16 = "\u20AC";
+
+        private const string REPLACEMENT_CHAR_UTF8 = "EFBFBD"; // U+FFFD REPLACEMENT CHAR, 3 bytes
+        private const string REPLACEMENT_CHAR_UTF16 = "\uFFFD";
+
+        private const string GRINNING_FACE_UTF8 = "F09F9880"; // U+1F600 GRINNING FACE, 4 bytes
+        private const string GRINNING_FACE_UTF16 = "\U0001F600";
+
+        private const string WOMAN_CARTWHEELING_MEDSKIN_UTF16 = "\U0001F938\U0001F3FD\u200D\u2640\uFE0F"; // U+1F938 U+1F3FD U+200D U+2640 U+FE0F WOMAN CARTWHEELING: MEDIUM SKIN TONE
+
+        // All valid scalars [ U+0000 .. U+D7FF ] and [ U+E000 .. U+10FFFF ].
+        private static readonly IEnumerable<Rune> s_allValidScalars = Enumerable.Range(0x0000, 0xD800).Concat(Enumerable.Range(0xE000, 0x110000 - 0xE000)).Select(value => new Rune(value));
+
+        private static readonly ReadOnlyMemory<char> s_allScalarsAsUtf16;
+        private static readonly ReadOnlyMemory<byte> s_allScalarsAsUtf8;
+
+        static Utf8Tests()
+        {
+            List<char> allScalarsAsUtf16 = new List<char>();
+            List<byte> allScalarsAsUtf8 = new List<byte>();
+
+            foreach (Rune rune in s_allValidScalars)
+            {
+                allScalarsAsUtf16.AddRange(ToUtf16(rune));
+                allScalarsAsUtf8.AddRange(ToUtf8(rune));
+            }
+
+            s_allScalarsAsUtf16 = allScalarsAsUtf16.ToArray().AsMemory();
+            s_allScalarsAsUtf8 = allScalarsAsUtf8.ToArray().AsMemory();
+        }
+
+        /*
+         * COMMON UTILITIES FOR UNIT TESTS
+         */
+
+        public static byte[] DecodeHex(ReadOnlySpan<char> inputHex)
+        {
+            Assert.True(Regex.IsMatch(inputHex.ToString(), "^([0-9a-fA-F]{2})*$"), "Input must be an even number of hex characters.");
+
+            byte[] retVal = new byte[inputHex.Length / 2];
+            for (int i = 0; i < retVal.Length; i++)
+            {
+                retVal[i] = byte.Parse(inputHex.Slice(i * 2, 2), NumberStyles.AllowHexSpecifier, CultureInfo.InvariantCulture);
+            }
+            return retVal;
+        }
+
+        // !! IMPORTANT !!
+        // Don't delete this implementation, as we use it as a reference to make sure the framework's
+        // transcoding logic is correct.
+        public static byte[] ToUtf8(Rune rune)
+        {
+            Assert.True(Rune.IsValid(rune.Value), $"Rune with value U+{(uint)rune.Value:X4} is not well-formed.");
+
+            if (rune.Value < 0x80)
+            {
+                return new[]
+                {
+                    (byte)rune.Value
+                };
+            }
+            else if (rune.Value < 0x0800)
+            {
+                return new[]
+                {
+                    (byte)((rune.Value >> 6) | 0xC0),
+                    (byte)((rune.Value & 0x3F) | 0x80)
+                };
+            }
+            else if (rune.Value < 0x10000)
+            {
+                return new[]
+                {
+                    (byte)((rune.Value >> 12) | 0xE0),
+                    (byte)(((rune.Value >> 6) & 0x3F) | 0x80),
+                    (byte)((rune.Value & 0x3F) | 0x80)
+                };
+            }
+            else
+            {
+                return new[]
+                {
+                    (byte)((rune.Value >> 18) | 0xF0),
+                    (byte)(((rune.Value >> 12) & 0x3F) | 0x80),
+                    (byte)(((rune.Value >> 6) & 0x3F) | 0x80),
+                    (byte)((rune.Value & 0x3F) | 0x80)
+                };
+            }
+        }
+
+        // !! IMPORTANT !!
+        // Don't delete this implementation, as we use it as a reference to make sure the framework's
+        // transcoding logic is correct.
+        private static char[] ToUtf16(Rune rune)
+        {
+            Assert.True(Rune.IsValid(rune.Value), $"Rune with value U+{(uint)rune.Value:X4} is not well-formed.");
+
+            if (rune.IsBmp)
+            {
+                return new[]
+                {
+                    (char)rune.Value
+                };
+            }
+            else
+            {
+                return new[]
+                {
+                    (char)((rune.Value >> 10) + 0xD800 - 0x40),
+                    (char)((rune.Value & 0x03FF) + 0xDC00)
+                };
+            }
+        }
+
+        [Theory]
+        [InlineData("", "")] // empty string is OK
+        [InlineData(X_UTF16, X_UTF8)]
+        [InlineData(E_ACUTE_UTF16, E_ACUTE_UTF8)]
+        [InlineData(EURO_SYMBOL_UTF16, EURO_SYMBOL_UTF8)]
+        public void ToBytes_WithSmallValidBuffers(string utf16Input, string expectedUtf8TranscodingHex)
+        {
+            // These test cases are for the "slow processing" code path at the end of TranscodeToUtf8,
+            // so inputs should be less than 2 chars.
+
+            Assert.InRange(utf16Input.Length, 0, 1);
+
+            ToBytes_Test_Core(
+                utf16Input: utf16Input,
+                destinationSize: expectedUtf8TranscodingHex.Length / 2,
+                replaceInvalidSequences: false,
+                isFinalChunk: false,
+                expectedOperationStatus: OperationStatus.Done,
+                expectedNumCharsRead: utf16Input.Length,
+                expectedUtf8Transcoding: DecodeHex(expectedUtf8TranscodingHex));
+        }
+
+        [Theory]
+        [InlineData("AB")] // 2 ASCII chars, hits fast inner loop
+        [InlineData("ABCD")] // 4 ASCII chars, hits fast inner loop
+        [InlineData("ABCDEF")] // 6 ASCII chars, hits fast inner loop
+        [InlineData("ABCDEFGH")] // 8 ASCII chars, hits fast inner loop
+        [InlineData("ABCDEFGHIJ")] // 10 ASCII chars, hits fast inner loop
+        [InlineData("ABCDEF" + E_ACUTE_UTF16 + "HIJ")] // interrupts inner loop due to non-ASCII char in first char of first DWORD
+        [InlineData("ABCDEFG" + EURO_SYMBOL_UTF16 + "IJ")] // interrupts inner loop due to non-ASCII char in second char of first DWORD
+        [InlineData("ABCDEFGH" + E_ACUTE_UTF16 + "J")] // interrupts inner loop due to non-ASCII char in first char of second DWORD
+        [InlineData("ABCDEFGHI" + EURO_SYMBOL_UTF16)] // interrupts inner loop due to non-ASCII char in second char of second DWORD
+        [InlineData(X_UTF16 + E_ACUTE_UTF16)] // drains first ASCII char then falls down to slow path
+        [InlineData(X_UTF16 + E_ACUTE_UTF16 + E_ACUTE_UTF16)] // drains first ASCII char then consumes 2x 2-byte sequences at once
+        [InlineData(E_ACUTE_UTF16 + X_UTF16)] // no first ASCII char to drain, consumes 2-byte seq followed by ASCII char
+        [InlineData(E_ACUTE_UTF16 + E_ACUTE_UTF16 + E_ACUTE_UTF16 + E_ACUTE_UTF16)] // stay within 2x 2-byte sequence processing loop
+        [InlineData(E_ACUTE_UTF16 + E_ACUTE_UTF16 + E_ACUTE_UTF16 + X_UTF16)] // break out of 2x 2-byte seq loop due to ASCII data in second char of DWORD
+        [InlineData(E_ACUTE_UTF16 + E_ACUTE_UTF16 + X_UTF16 + X_UTF16)] // break out of 2x 2-byte seq loop due to ASCII data in first char of DWORD
+        [InlineData(E_ACUTE_UTF16 + E_ACUTE_UTF16 + E_ACUTE_UTF16 + EURO_SYMBOL_UTF16)] // break out of 2x 2-byte seq loop due to 3-byte data
+        [InlineData(E_ACUTE_UTF16 + EURO_SYMBOL_UTF16)] // 2-byte logic sees next char isn't ASCII, cannot read full DWORD from remaining input buffer, falls down to slow drain loop
+        [InlineData(EURO_SYMBOL_UTF16 + EURO_SYMBOL_UTF16 + X_UTF16)] // 2x 3-byte logic can't read a full DWORD from next part of buffer, falls down to slow drain loop
+        [InlineData(EURO_SYMBOL_UTF16 + X_UTF16)] // 3-byte processing loop consumes trailing ASCII char, but can't read next DWORD, falls down to slow drain loop
+        [InlineData(EURO_SYMBOL_UTF16 + X_UTF16 + X_UTF16)] // 3-byte processing loop consumes trailing ASCII char, but can't read next DWORD, falls down to slow drain loop
+        [InlineData(EURO_SYMBOL_UTF16 + E_ACUTE_UTF16)] // 3-byte processing loop can't consume next ASCII char, can't read DWORD, falls down to slow drain loop
+        [InlineData(EURO_SYMBOL_UTF16 + EURO_SYMBOL_UTF16 + EURO_SYMBOL_UTF16 + EURO_SYMBOL_UTF16)] // stay within 2x 3-byte sequence processing loop
+        [InlineData(EURO_SYMBOL_UTF16 + EURO_SYMBOL_UTF16 + X_UTF16 + EURO_SYMBOL_UTF16 + EURO_SYMBOL_UTF16 + EURO_SYMBOL_UTF16)] // consume stray ASCII char at beginning of DWORD after 2x 3-byte sequence
+        [InlineData(EURO_SYMBOL_UTF16 + EURO_SYMBOL_UTF16 + EURO_SYMBOL_UTF16 + X_UTF16 + EURO_SYMBOL_UTF16 + EURO_SYMBOL_UTF16)] // consume stray ASCII char at end of DWORD after 2x 3-byte sequence
+        [InlineData(EURO_SYMBOL_UTF16 + E_ACUTE_UTF16 + X_UTF16)] // consume 2-byte sequence as second char in DWORD which begins with 3-byte encoded char
+        [InlineData(EURO_SYMBOL_UTF16 + GRINNING_FACE_UTF16)] // 3-byte sequence followed by 4-byte sequence
+        [InlineData(EURO_SYMBOL_UTF16 + EURO_SYMBOL_UTF16 + GRINNING_FACE_UTF16)] // 2x 3-byte sequence followed by 4-byte sequence
+        [InlineData(GRINNING_FACE_UTF16)] // single 4-byte surrogate char pair
+        [InlineData(GRINNING_FACE_UTF16 + EURO_SYMBOL_UTF16)] // 4-byte surrogate char pair, cannot read next DWORD, falls down to slow drain loop
+        public void ToBytes_WithLargeValidBuffers(string utf16Input)
+        {
+            // These test cases are for the "fast processing" code which is the main loop of TranscodeToUtf8,
+            // so inputs should be at least 2 chars.
+
+            Assert.True(utf16Input.Length >= 2);
+
+            // We're going to run the tests with destination buffer lengths ranging from 0 all the way
+            // to buffers large enough to hold the full output. This allows us to test logic that
+            // detects whether we're about to overrun our destination buffer and instead returns DestinationTooSmall.
+
+            Rune[] enumeratedScalars = utf16Input.EnumerateRunes().ToArray();
+
+            // 0-length buffer test
+            ToBytes_Test_Core(
+                utf16Input: utf16Input,
+                destinationSize: 0,
+                replaceInvalidSequences: false,
+                isFinalChunk: false,
+                expectedOperationStatus: OperationStatus.DestinationTooSmall,
+                expectedNumCharsRead: 0,
+                expectedUtf8Transcoding: ReadOnlySpan<byte>.Empty);
+
+            int expectedNumCharsConsumed = 0;
+            byte[] concatenatedUtf8 = Array.Empty<byte>();
+
+            for (int i = 0; i < enumeratedScalars.Length; i++)
+            {
+                Rune thisScalar = enumeratedScalars[i];
+
+                // provide partial destination buffers all the way up to (but not including) enough to hold the next full scalar encoding
+                for (int j = 1; j < thisScalar.Utf8SequenceLength; j++)
+                {
+                    ToBytes_Test_Core(
+                        utf16Input: utf16Input,
+                        destinationSize: concatenatedUtf8.Length + j,
+                        replaceInvalidSequences: false,
+                        isFinalChunk: false,
+                        expectedOperationStatus: OperationStatus.DestinationTooSmall,
+                        expectedNumCharsRead: expectedNumCharsConsumed,
+                        expectedUtf8Transcoding: concatenatedUtf8);
+                }
+
+                // now provide a destination buffer large enough to hold the next full scalar encoding
+
+                expectedNumCharsConsumed += thisScalar.Utf16SequenceLength;
+                concatenatedUtf8 = concatenatedUtf8.Concat(ToUtf8(thisScalar)).ToArray();
+
+                ToBytes_Test_Core(
+                   utf16Input: utf16Input,
+                   destinationSize: concatenatedUtf8.Length,
+                   replaceInvalidSequences: false,
+                   isFinalChunk: false,
+                   expectedOperationStatus: (i == enumeratedScalars.Length - 1) ? OperationStatus.Done : OperationStatus.DestinationTooSmall,
+                   expectedNumCharsRead: expectedNumCharsConsumed,
+                   expectedUtf8Transcoding: concatenatedUtf8);
+            }
+
+            // now throw lots of ASCII data at the beginning so that we exercise the vectorized code paths
+
+            utf16Input = new string('x', 64) + utf16Input;
+            concatenatedUtf8 = utf16Input.EnumerateRunes().SelectMany(ToUtf8).ToArray();
+
+            ToBytes_Test_Core(
+                utf16Input: utf16Input,
+                destinationSize: concatenatedUtf8.Length,
+                replaceInvalidSequences: false,
+                isFinalChunk: true,
+                expectedOperationStatus: OperationStatus.Done,
+                expectedNumCharsRead: utf16Input.Length,
+                expectedUtf8Transcoding: concatenatedUtf8);
+
+            // now throw some non-ASCII data at the beginning so that we *don't* exercise the vectorized code paths
+
+            utf16Input = WOMAN_CARTWHEELING_MEDSKIN_UTF16 + utf16Input[64..];
+            concatenatedUtf8 = utf16Input.EnumerateRunes().SelectMany(ToUtf8).ToArray();
+
+            ToBytes_Test_Core(
+                utf16Input: utf16Input,
+                destinationSize: concatenatedUtf8.Length,
+                replaceInvalidSequences: false,
+                isFinalChunk: true,
+                expectedOperationStatus: OperationStatus.Done,
+                expectedNumCharsRead: utf16Input.Length,
+                expectedUtf8Transcoding: concatenatedUtf8);
+        }
+
+        [Theory]
+        [InlineData('\uD800', OperationStatus.NeedMoreData)] // standalone high surrogate
+        [InlineData('\uDFFF', OperationStatus.InvalidData)] // standalone low surrogate
+        public void ToBytes_WithOnlyStandaloneSurrogates(char charValue, OperationStatus expectedOperationStatus)
+        {
+            ToBytes_Test_Core(
+                utf16Input: new[] { charValue },
+                destinationSize: 0,
+                replaceInvalidSequences: false,
+                isFinalChunk: false,
+                expectedOperationStatus: expectedOperationStatus,
+                expectedNumCharsRead: 0,
+                expectedUtf8Transcoding: Span<byte>.Empty);
+        }
+
+        [Theory]
+        [InlineData("<LOW><HIGH>", 0, "")] // swapped surrogate pair characters
+        [InlineData("A<LOW><HIGH>", 1, "41")] // consume standalone ASCII char, then swapped surrogate pair characters
+        [InlineData("A<HIGH>B", 1, "41")] // consume standalone ASCII char, then standalone high surrogate char
+        [InlineData("A<LOW>B", 1, "41")] // consume standalone ASCII char, then standalone low surrogate char
+        [InlineData("AB<HIGH><HIGH>", 2, "4142")] // consume two ASCII chars, then standalone high surrogate char
+        [InlineData("AB<LOW><LOW>", 2, "4142")] // consume two ASCII chars, then standalone low surrogate char
+        public void ToBytes_WithInvalidSurrogates(string utf16Input, int expectedNumCharsConsumed, string expectedUtf8TranscodingHex)
+        {
+            // xUnit can't handle ill-formed strings in [InlineData], so we replace here.
+
+            utf16Input = utf16Input.Replace("<HIGH>", "\uD800").Replace("<LOW>", "\uDFFF");
+
+            // These test cases are for the "fast processing" code which is the main loop of TranscodeToUtf8,
+            // so inputs should be at least 2 chars.
+
+            Assert.True(utf16Input.Length >= 2);
+
+            ToBytes_Test_Core(
+                utf16Input: utf16Input,
+                destinationSize: expectedUtf8TranscodingHex.Length / 2,
+                replaceInvalidSequences: false,
+                isFinalChunk: false,
+                expectedOperationStatus: OperationStatus.InvalidData,
+                expectedNumCharsRead: expectedNumCharsConsumed,
+                expectedUtf8Transcoding: DecodeHex(expectedUtf8TranscodingHex));
+
+            // Now try the tests again with a larger buffer.
+            // This ensures that running out of destination space wasn't the reason we failed.
+
+            ToBytes_Test_Core(
+                utf16Input: utf16Input,
+                destinationSize: (expectedUtf8TranscodingHex.Length) / 2 + 16,
+                replaceInvalidSequences: false,
+                isFinalChunk: false,
+                expectedOperationStatus: OperationStatus.InvalidData,
+                expectedNumCharsRead: expectedNumCharsConsumed,
+                expectedUtf8Transcoding: DecodeHex(expectedUtf8TranscodingHex));
+        }
+
+        [Theory]
+        [InlineData("<LOW><HIGH>", REPLACEMENT_CHAR_UTF8)] // standalone low surr. and incomplete high surr.
+        [InlineData("<HIGH><HIGH>", REPLACEMENT_CHAR_UTF8)] // standalone high surr. and incomplete high surr.
+        [InlineData("<LOW><LOW>", REPLACEMENT_CHAR_UTF8 + REPLACEMENT_CHAR_UTF8)] // standalone low surr. and incomplete low surr.
+        [InlineData("A<LOW>B<LOW>C<HIGH>D", "41" + REPLACEMENT_CHAR_UTF8 + "42" + REPLACEMENT_CHAR_UTF8 + "43" + REPLACEMENT_CHAR_UTF8 + "44")] // standalone low, low, high surrounded by other data
+        public void ToBytes_WithReplacements(string utf16Input, string expectedUtf8TranscodingHex)
+        {
+            // xUnit can't handle ill-formed strings in [InlineData], so we replace here.
+
+            utf16Input = utf16Input.Replace("<HIGH>", "\uD800").Replace("<LOW>", "\uDFFF");
+
+            bool isFinalCharHighSurrogate = char.IsHighSurrogate(utf16Input.Last());
+
+            ToBytes_Test_Core(
+                utf16Input: utf16Input,
+                destinationSize: expectedUtf8TranscodingHex.Length / 2,
+                replaceInvalidSequences: true,
+                isFinalChunk: false,
+                expectedOperationStatus: (isFinalCharHighSurrogate) ? OperationStatus.NeedMoreData : OperationStatus.Done,
+                expectedNumCharsRead: (isFinalCharHighSurrogate) ? (utf16Input.Length - 1) : utf16Input.Length,
+                expectedUtf8Transcoding: DecodeHex(expectedUtf8TranscodingHex));
+
+            if (isFinalCharHighSurrogate)
+            {
+                // Also test with isFinalChunk = true
+                ToBytes_Test_Core(
+                    utf16Input: utf16Input,
+                    destinationSize: expectedUtf8TranscodingHex.Length / 2 + Rune.ReplacementChar.Utf8SequenceLength /* for replacement char */,
+                    replaceInvalidSequences: true,
+                    isFinalChunk: true,
+                    expectedOperationStatus: OperationStatus.Done,
+                    expectedNumCharsRead: utf16Input.Length,
+                    expectedUtf8Transcoding: DecodeHex(expectedUtf8TranscodingHex + REPLACEMENT_CHAR_UTF8));
+            }
+        }
+
+        [Theory]
+        [InlineData(E_ACUTE_UTF16 + "<LOW>", true, 1, OperationStatus.DestinationTooSmall, E_ACUTE_UTF8)] // not enough output buffer to hold U+FFFD
+        [InlineData(E_ACUTE_UTF16 + "<LOW>", true, 2, OperationStatus.Done, E_ACUTE_UTF8 + REPLACEMENT_CHAR_UTF8)] // replace standalone low surr. at end
+        [InlineData(E_ACUTE_UTF16 + "<HIGH>", true, 1, OperationStatus.DestinationTooSmall, E_ACUTE_UTF8)] // not enough output buffer to hold U+FFFD
+        [InlineData(E_ACUTE_UTF16 + "<HIGH>", true, 2, OperationStatus.Done, E_ACUTE_UTF8 + REPLACEMENT_CHAR_UTF8)] // replace standalone high surr. at end
+        [InlineData(E_ACUTE_UTF16 + "<HIGH>", false, 1, OperationStatus.NeedMoreData, E_ACUTE_UTF8)] // don't replace standalone high surr. at end
+        [InlineData(E_ACUTE_UTF16 + "<HIGH>" + X_UTF16, true, 2, OperationStatus.DestinationTooSmall, E_ACUTE_UTF8 + REPLACEMENT_CHAR_UTF8)] // not enough output buffer to hold 'X'
+        [InlineData(E_ACUTE_UTF16 + "<HIGH>" + X_UTF16, false, 2, OperationStatus.DestinationTooSmall, E_ACUTE_UTF8 + REPLACEMENT_CHAR_UTF8)] // not enough output buffer to hold 'X'
+        [InlineData(E_ACUTE_UTF16 + "<HIGH>" + X_UTF16, true, 3, OperationStatus.Done, E_ACUTE_UTF8 + REPLACEMENT_CHAR_UTF8 + X_UTF8)] // replacement followed by 'X'
+        [InlineData(E_ACUTE_UTF16 + "<HIGH>" + X_UTF16, false, 3, OperationStatus.Done, E_ACUTE_UTF8 + REPLACEMENT_CHAR_UTF8 + X_UTF8)] // replacement followed by 'X'
+        public void ToBytes_WithReplacements_AndCustomBufferSizes(string utf16Input, bool isFinalChunk, int expectedNumCharsConsumed, OperationStatus expectedOperationStatus, string expectedUtf8TranscodingHex)
+        {
+            // xUnit can't handle ill-formed strings in [InlineData], so we replace here.
+
+            utf16Input = utf16Input.Replace("<HIGH>", "\uD800").Replace("<LOW>", "\uDFFF");
+
+            ToBytes_Test_Core(
+                utf16Input: utf16Input,
+                destinationSize: expectedUtf8TranscodingHex.Length / 2,
+                replaceInvalidSequences: true,
+                isFinalChunk: isFinalChunk,
+                expectedOperationStatus: expectedOperationStatus,
+                expectedNumCharsRead: expectedNumCharsConsumed,
+                expectedUtf8Transcoding: DecodeHex(expectedUtf8TranscodingHex));
+        }
+
+        [Fact]
+        public void ToBytes_AllPossibleScalarValues()
+        {
+            ToBytes_Test_Core(
+                utf16Input: s_allScalarsAsUtf16.Span,
+                destinationSize: s_allScalarsAsUtf8.Length,
+                replaceInvalidSequences: false,
+                isFinalChunk: false,
+                expectedOperationStatus: OperationStatus.Done,
+                expectedNumCharsRead: s_allScalarsAsUtf16.Length,
+                expectedUtf8Transcoding: s_allScalarsAsUtf8.Span);
+        }
+
+        private static void ToBytes_Test_Core(ReadOnlySpan<char> utf16Input, int destinationSize, bool replaceInvalidSequences, bool isFinalChunk, OperationStatus expectedOperationStatus, int expectedNumCharsRead, ReadOnlySpan<byte> expectedUtf8Transcoding)
+        {
+            // Arrange
+
+            using (BoundedMemory<char> boundedSource = BoundedMemory.AllocateFromExistingData(utf16Input))
+            using (BoundedMemory<byte> boundedDestination = BoundedMemory.Allocate<byte>(destinationSize))
+            {
+                boundedSource.MakeReadonly();
+
+                // Act
+
+                OperationStatus actualOperationStatus = Utf8.FromUtf16(boundedSource.Span, boundedDestination.Span, out int actualNumCharsRead, out int actualNumBytesWritten, replaceInvalidSequences, isFinalChunk);
+
+                // Assert
+
+                Assert.Equal(expectedOperationStatus, actualOperationStatus);
+                Assert.Equal(expectedNumCharsRead, actualNumCharsRead);
+                Assert.Equal(expectedUtf8Transcoding.Length, actualNumBytesWritten);
+                Assert.Equal(expectedUtf8Transcoding.ToArray(), boundedDestination.Span.Slice(0, actualNumBytesWritten).ToArray());
+            }
+        }
+
         [Theory]
         [InlineData("80", 0, "")] // sequence cannot begin with continuation character
         [InlineData("8182", 0, "")] // sequence cannot begin with continuation character
diff --git a/src/libraries/System.Runtime/tests/System/Text/Unicode/Utf8Tests.netcoreapp.cs b/src/libraries/System.Runtime/tests/System/Text/Unicode/Utf8Tests.netcoreapp.cs
deleted file mode 100644 (file)
index f57c769..0000000
+++ /dev/null
@@ -1,143 +0,0 @@
-// 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.Buffers;
-using System.Collections.Generic;
-using System.Globalization;
-using System.Linq;
-using System.Text.RegularExpressions;
-using Xunit;
-
-namespace System.Text.Unicode.Tests
-{
-    public partial class Utf8Tests
-    {
-        private const string X_UTF8 = "58"; // U+0058 LATIN CAPITAL LETTER X, 1 byte
-        private const string X_UTF16 = "X";
-
-        private const string Y_UTF8 = "59"; // U+0058 LATIN CAPITAL LETTER Y, 1 byte
-        private const string Y_UTF16 = "Y";
-
-        private const string Z_UTF8 = "5A"; // U+0058 LATIN CAPITAL LETTER Z, 1 byte
-        private const string Z_UTF16 = "Z";
-
-        private const string E_ACUTE_UTF8 = "C3A9"; // U+00E9 LATIN SMALL LETTER E WITH ACUTE, 2 bytes
-        private const string E_ACUTE_UTF16 = "\u00E9";
-
-        private const string EURO_SYMBOL_UTF8 = "E282AC"; // U+20AC EURO SIGN, 3 bytes
-        private const string EURO_SYMBOL_UTF16 = "\u20AC";
-
-        private const string REPLACEMENT_CHAR_UTF8 = "EFBFBD"; // U+FFFD REPLACEMENT CHAR, 3 bytes
-        private const string REPLACEMENT_CHAR_UTF16 = "\uFFFD";
-
-        private const string GRINNING_FACE_UTF8 = "F09F9880"; // U+1F600 GRINNING FACE, 4 bytes
-        private const string GRINNING_FACE_UTF16 = "\U0001F600";
-
-        private const string WOMAN_CARTWHEELING_MEDSKIN_UTF16 = "\U0001F938\U0001F3FD\u200D\u2640\uFE0F"; // U+1F938 U+1F3FD U+200D U+2640 U+FE0F WOMAN CARTWHEELING: MEDIUM SKIN TONE
-
-        // All valid scalars [ U+0000 .. U+D7FF ] and [ U+E000 .. U+10FFFF ].
-        private static readonly IEnumerable<Rune> s_allValidScalars = Enumerable.Range(0x0000, 0xD800).Concat(Enumerable.Range(0xE000, 0x110000 - 0xE000)).Select(value => new Rune(value));
-
-        private static readonly ReadOnlyMemory<char> s_allScalarsAsUtf16;
-        private static readonly ReadOnlyMemory<byte> s_allScalarsAsUtf8;
-
-        static Utf8Tests()
-        {
-            List<char> allScalarsAsUtf16 = new List<char>();
-            List<byte> allScalarsAsUtf8 = new List<byte>();
-
-            foreach (Rune rune in s_allValidScalars)
-            {
-                allScalarsAsUtf16.AddRange(ToUtf16(rune));
-                allScalarsAsUtf8.AddRange(ToUtf8(rune));
-            }
-
-            s_allScalarsAsUtf16 = allScalarsAsUtf16.ToArray().AsMemory();
-            s_allScalarsAsUtf8 = allScalarsAsUtf8.ToArray().AsMemory();
-        }
-
-        /*
-         * COMMON UTILITIES FOR UNIT TESTS
-         */
-
-        public static byte[] DecodeHex(ReadOnlySpan<char> inputHex)
-        {
-            Assert.True(Regex.IsMatch(inputHex.ToString(), "^([0-9a-fA-F]{2})*$"), "Input must be an even number of hex characters.");
-
-            byte[] retVal = new byte[inputHex.Length / 2];
-            for (int i = 0; i < retVal.Length; i++)
-            {
-                retVal[i] = byte.Parse(inputHex.Slice(i * 2, 2), NumberStyles.AllowHexSpecifier, CultureInfo.InvariantCulture);
-            }
-            return retVal;
-        }
-
-        // !! IMPORTANT !!
-        // Don't delete this implementation, as we use it as a reference to make sure the framework's
-        // transcoding logic is correct.
-        public static byte[] ToUtf8(Rune rune)
-        {
-            Assert.True(Rune.IsValid(rune.Value), $"Rune with value U+{(uint)rune.Value:X4} is not well-formed.");
-
-            if (rune.Value < 0x80)
-            {
-                return new[]
-                {
-                    (byte)rune.Value
-                };
-            }
-            else if (rune.Value < 0x0800)
-            {
-                return new[]
-                {
-                    (byte)((rune.Value >> 6) | 0xC0),
-                    (byte)((rune.Value & 0x3F) | 0x80)
-                };
-            }
-            else if (rune.Value < 0x10000)
-            {
-                return new[]
-                {
-                    (byte)((rune.Value >> 12) | 0xE0),
-                    (byte)(((rune.Value >> 6) & 0x3F) | 0x80),
-                    (byte)((rune.Value & 0x3F) | 0x80)
-                };
-            }
-            else
-            {
-                return new[]
-                {
-                    (byte)((rune.Value >> 18) | 0xF0),
-                    (byte)(((rune.Value >> 12) & 0x3F) | 0x80),
-                    (byte)(((rune.Value >> 6) & 0x3F) | 0x80),
-                    (byte)((rune.Value & 0x3F) | 0x80)
-                };
-            }
-        }
-
-        // !! IMPORTANT !!
-        // Don't delete this implementation, as we use it as a reference to make sure the framework's
-        // transcoding logic is correct.
-        private static char[] ToUtf16(Rune rune)
-        {
-            Assert.True(Rune.IsValid(rune.Value), $"Rune with value U+{(uint)rune.Value:X4} is not well-formed.");
-
-            if (rune.IsBmp)
-            {
-                return new[]
-                {
-                    (char)rune.Value
-                };
-            }
-            else
-            {
-                return new[]
-                {
-                    (char)((rune.Value >> 10) + 0xD800 - 0x40),
-                    (char)((rune.Value & 0x03FF) + 0xDC00)
-                };
-            }
-        }
-    }
-}
@@ -10,7 +10,7 @@ using Xunit;
 
 namespace System.Text.Unicode.Tests
 {
-    public partial class Utf8UtilityTests
+    public class Utf8UtilityTests
     {
         private unsafe delegate byte* GetPointerToFirstInvalidByteDel(byte* pInputBuffer, int inputLength, out int utf16CodeUnitCountAdjustment, out int scalarCountAdjustment);
         private static readonly Lazy<GetPointerToFirstInvalidByteDel> _getPointerToFirstInvalidByteFn = CreateGetPointerToFirstInvalidByteFn();
index b559667..965e5ae 100644 (file)
@@ -9,7 +9,7 @@ using Xunit;
 
 namespace System.Tests
 {
-    public partial class TimeSpanTests
+    public class TimeSpanTests
     {
         [Fact]
         public static void MaxValue()
@@ -1070,5 +1070,320 @@ namespace System.Tests
         {
             Assert.Equal(expected, Math.Sign(timeSpan1.CompareTo(obj)));
         }
+
+        public static IEnumerable<object[]> MultiplicationTestData()
+        {
+            yield return new object[] {new TimeSpan(2, 30, 0), 2.0, new TimeSpan(5, 0, 0)};
+            yield return new object[] {new TimeSpan(14, 2, 30, 0), 192.0, TimeSpan.FromDays(2708)};
+            yield return new object[] {TimeSpan.FromDays(366), Math.PI, new TimeSpan(993446995288779)};
+            yield return new object[] {TimeSpan.FromDays(366), -Math.E, new TimeSpan(-859585952922633)};
+            yield return new object[] {TimeSpan.FromDays(29.530587981), 13.0, TimeSpan.FromDays(29.530587981 * 13.0) };
+            yield return new object[] {TimeSpan.FromDays(-29.530587981), -12.0, TimeSpan.FromDays(-29.530587981 * -12.0) };
+            yield return new object[] {TimeSpan.FromDays(-29.530587981), 0.0, TimeSpan.Zero};
+            yield return new object[] {TimeSpan.MaxValue, 0.5, TimeSpan.FromTicks((long)(long.MaxValue * 0.5))};
+        }
+
+        // ParseDifferentLengthFractionWithLeadingZerosData mainly testing the behavior we have fixed in net core
+        // which is the way we normalize the parsed fraction and possibly rounding it.
+        public static IEnumerable<object[]> ParseDifferentLengthFractionWithLeadingZerosData()
+        {
+            yield return new object[] {"00:00:00.00000001",   new TimeSpan(0)};
+            yield return new object[] {"00:00:00.00000005",   new TimeSpan(1)};
+            yield return new object[] {"00:00:00.09999999",   new TimeSpan(1_000_000)};
+            yield return new object[] {"00:00:00.0268435455", new TimeSpan(268435)};
+            yield return new object[] {"00:00:00.01",         new TimeSpan(1_00_000)};
+            yield return new object[] {"0:00:00.01000000",    new TimeSpan(100_000)};
+            yield return new object[] {"0:00:00.010000000",   new TimeSpan(100_000)};
+            yield return new object[] {"0:00:00.0123456",     new TimeSpan(123456)};
+            yield return new object[] {"0:00:00.00123456",    new TimeSpan(12346)};
+            yield return new object[] {"0:00:00.00000098",    new TimeSpan(10)};
+            yield return new object[] {"0:00:00.00000099",    new TimeSpan(10)};
+        }
+
+        [Theory, MemberData(nameof(ParseDifferentLengthFractionWithLeadingZerosData))]
+        public static void Multiplication(string input, TimeSpan expected)
+        {
+            Assert.Equal(expected, TimeSpan.Parse(input, CultureInfo.InvariantCulture));
+            Assert.Equal(expected, TimeSpan.ParseExact(input, "g", CultureInfo.InvariantCulture));
+        }
+
+        [Theory, MemberData(nameof(MultiplicationTestData))]
+        public static void Multiplication(TimeSpan timeSpan, double factor, TimeSpan expected)
+        {
+            Assert.Equal(expected, timeSpan * factor);
+            Assert.Equal(expected, factor * timeSpan);
+        }
+
+        [Fact]
+        public static void OverflowingMultiplication()
+        {
+            Assert.Throws<OverflowException>(() => TimeSpan.MaxValue * 1.000000001);
+            Assert.Throws<OverflowException>(() => -1.000000001 * TimeSpan.MaxValue);
+        }
+
+        [Fact]
+        public static void NaNMultiplication()
+        {
+            AssertExtensions.Throws<ArgumentException>("factor", () => TimeSpan.FromDays(1) * double.NaN);
+            AssertExtensions.Throws<ArgumentException>("factor", () => double.NaN * TimeSpan.FromDays(1));
+        }
+
+        [Theory, MemberData(nameof(MultiplicationTestData))]
+        public static void Division(TimeSpan timeSpan, double factor, TimeSpan expected)
+        {
+            Assert.Equal(factor, expected / timeSpan, 14);
+            double divisor = 1.0 / factor;
+            Assert.Equal(expected, timeSpan / divisor);
+        }
+
+        [Fact]
+        public static void DivideByZero()
+        {
+            Assert.Throws<OverflowException>(() => TimeSpan.FromDays(1) / 0);
+            Assert.Throws<OverflowException>(() => TimeSpan.FromDays(-1) / 0);
+            Assert.Throws<OverflowException>(() => TimeSpan.Zero / 0);
+            Assert.Equal(double.PositiveInfinity, TimeSpan.FromDays(1) / TimeSpan.Zero);
+            Assert.Equal(double.NegativeInfinity, TimeSpan.FromDays(-1) / TimeSpan.Zero);
+            Assert.True(double.IsNaN(TimeSpan.Zero / TimeSpan.Zero));
+        }
+
+        [Fact]
+        public static void NaNDivision()
+        {
+            AssertExtensions.Throws<ArgumentException>("divisor", () => TimeSpan.FromDays(1) / double.NaN);
+        }
+
+        [Theory, MemberData(nameof(MultiplicationTestData))]
+        public static void NamedMultiplication(TimeSpan timeSpan, double factor, TimeSpan expected)
+        {
+            Assert.Equal(expected, timeSpan.Multiply(factor));
+        }
+
+        [Fact]
+        public static void NamedOverflowingMultiplication()
+        {
+            Assert.Throws<OverflowException>(() => TimeSpan.MaxValue.Multiply(1.000000001));
+        }
+
+        [Fact]
+        public static void NamedNaNMultiplication()
+        {
+            AssertExtensions.Throws<ArgumentException>("factor", () => TimeSpan.FromDays(1).Multiply(double.NaN));
+        }
+
+        [Theory, MemberData(nameof(MultiplicationTestData))]
+        public static void NamedDivision(TimeSpan timeSpan, double factor, TimeSpan expected)
+        {
+            Assert.Equal(factor, expected.Divide(timeSpan), 14);
+            double divisor = 1.0 / factor;
+            Assert.Equal(expected, timeSpan.Divide(divisor));
+        }
+
+        [Fact]
+        public static void NamedDivideByZero()
+        {
+            Assert.Throws<OverflowException>(() => TimeSpan.FromDays(1).Divide(0));
+            Assert.Throws<OverflowException>(() => TimeSpan.FromDays(-1).Divide(0));
+            Assert.Throws<OverflowException>(() => TimeSpan.Zero.Divide(0));
+            Assert.Equal(double.PositiveInfinity, TimeSpan.FromDays(1).Divide(TimeSpan.Zero));
+            Assert.Equal(double.NegativeInfinity, TimeSpan.FromDays(-1).Divide(TimeSpan.Zero));
+            Assert.True(double.IsNaN(TimeSpan.Zero.Divide(TimeSpan.Zero)));
+        }
+
+        [Fact]
+        public static void NamedNaNDivision()
+        {
+            AssertExtensions.Throws<ArgumentException>("divisor", () => TimeSpan.FromDays(1).Divide(double.NaN));
+        }
+
+        public static IEnumerable<object[]> Parse_ValidWithOffsetCount_TestData()
+        {
+            foreach (object[] inputs in Parse_Valid_TestData())
+            {
+                yield return new object[] { inputs[0], 0, ((string)inputs[0]).Length, inputs[1], inputs[2] };
+            }
+
+            yield return new object[] { "     12:24:02      ", 5, 8, null, new TimeSpan(0, 12, 24, 2, 0) };
+            yield return new object[] { "     12:24:02      ", 6, 7, null, new TimeSpan(0, 2, 24, 2, 0) };
+            yield return new object[] { "     12:24:02      ", 6, 6, null, new TimeSpan(0, 2, 24, 0, 0) };
+            yield return new object[] { "12:24:02.01", 0, 8, CultureInfo.InvariantCulture, new TimeSpan(0, 12, 24, 2, 0) };
+            yield return new object[] { "1:1:1.00000001", 0, 7, CultureInfo.InvariantCulture, new TimeSpan(1, 1, 1) };
+            yield return new object[] { "1:1:.00000001", 0, 6, CultureInfo.InvariantCulture, new TimeSpan(36600000000) };
+            yield return new object[] { "24:00:00", 1, 7, null, new TimeSpan(4, 0, 0) };
+        }
+
+        [Theory]
+        [MemberData(nameof(Parse_ValidWithOffsetCount_TestData))]
+        public static void Parse_Span(string inputString, int offset, int count, IFormatProvider provider, TimeSpan expected)
+        {
+            ReadOnlySpan<char> input = inputString.AsSpan(offset, count);
+            TimeSpan result;
+
+            // Default provider.
+            if (provider == null)
+            {
+                Assert.True(TimeSpan.TryParse(input, out result));
+                Assert.Equal(expected, result);
+            }
+
+            Assert.Equal(expected, TimeSpan.Parse(input, provider));
+            Assert.True(TimeSpan.TryParse(input, provider, out result));
+            Assert.Equal(expected, result);
+
+            // Also negate
+            if (!char.IsWhiteSpace(input[0]))
+            {
+                input = ("-" + inputString.Substring(offset, count)).AsSpan();
+                expected = -expected;
+
+                Assert.Equal(expected, TimeSpan.Parse(input, provider));
+                Assert.True(TimeSpan.TryParse(input, provider, out result));
+                Assert.Equal(expected, result);
+            }
+        }
+
+        [Theory]
+        [MemberData(nameof(Parse_Invalid_TestData))]
+        public static void Parse_Span_Invalid(string inputString, IFormatProvider provider, Type exceptionType)
+        {
+            if (inputString != null)
+            {
+                Assert.Throws(exceptionType, () => TimeSpan.Parse(inputString.AsSpan(), provider));
+                Assert.False(TimeSpan.TryParse(inputString.AsSpan(), provider, out TimeSpan result));
+                Assert.Equal(TimeSpan.Zero, result);
+            }
+        }
+
+        [Theory]
+        [MemberData(nameof(ParseExact_Valid_TestData))]
+        public static void ParseExact_Span_Valid(string inputString, string format, TimeSpan expected)
+        {
+            ReadOnlySpan<char> input = inputString.AsSpan();
+
+            TimeSpan result;
+            Assert.Equal(expected, TimeSpan.ParseExact(input, format, new CultureInfo("en-US")));
+            Assert.Equal(expected, TimeSpan.ParseExact(input, format, new CultureInfo("en-US"), TimeSpanStyles.None));
+            Assert.Equal(expected, TimeSpan.ParseExact(input, new[] { format }, new CultureInfo("en-US")));
+            Assert.Equal(expected, TimeSpan.ParseExact(input, new[] { format }, new CultureInfo("en-US"), TimeSpanStyles.None));
+
+            Assert.True(TimeSpan.TryParseExact(input, format, new CultureInfo("en-US"), out result));
+            Assert.Equal(expected, result);
+
+            Assert.True(TimeSpan.TryParseExact(input, format, new CultureInfo("en-US"), TimeSpanStyles.None, out result));
+            Assert.Equal(expected, result);
+
+            Assert.True(TimeSpan.TryParseExact(input, new[] { format }, new CultureInfo("en-US"), out result));
+            Assert.Equal(expected, result);
+
+            Assert.True(TimeSpan.TryParseExact(input, new[] { format }, new CultureInfo("en-US"), TimeSpanStyles.None, out result));
+            Assert.Equal(expected, result);
+
+            if (format != "c" && format != "t" && format != "T" && format != "g" && format != "G")
+            {
+                // TimeSpanStyles is interpreted only for custom formats
+                Assert.Equal(expected.Negate(), TimeSpan.ParseExact(input, format, new CultureInfo("en-US"), TimeSpanStyles.AssumeNegative));
+
+                Assert.True(TimeSpan.TryParseExact(input, format, new CultureInfo("en-US"), TimeSpanStyles.AssumeNegative, out result));
+                Assert.Equal(expected.Negate(), result);
+            }
+            else
+            {
+                // Inputs that can be parsed in standard formats with ParseExact should also be parsable with Parse
+                Assert.Equal(expected, TimeSpan.Parse(input, CultureInfo.InvariantCulture));
+
+                Assert.True(TimeSpan.TryParse(input, CultureInfo.InvariantCulture, out result));
+                Assert.Equal(expected, result);
+            }
+        }
+
+        [Theory]
+        [MemberData(nameof(ParseExact_Invalid_TestData))]
+        public static void ParseExactTest_Span_Invalid(string inputString, string format, Type exceptionType)
+        {
+            if (inputString != null && format != null)
+            {
+                Assert.Throws(exceptionType, () => TimeSpan.ParseExact(inputString.AsSpan(), format, new CultureInfo("en-US")));
+
+                TimeSpan result;
+                Assert.False(TimeSpan.TryParseExact(inputString.AsSpan(), format, new CultureInfo("en-US"), out result));
+                Assert.Equal(TimeSpan.Zero, result);
+
+                Assert.False(TimeSpan.TryParseExact(inputString.AsSpan(), format, new CultureInfo("en-US"), TimeSpanStyles.None, out result));
+                Assert.Equal(TimeSpan.Zero, result);
+
+                Assert.False(TimeSpan.TryParseExact(inputString.AsSpan(), new[] { format }, new CultureInfo("en-US"), out result));
+                Assert.Equal(TimeSpan.Zero, result);
+
+                Assert.False(TimeSpan.TryParseExact(inputString.AsSpan(), new[] { format }, new CultureInfo("en-US"), TimeSpanStyles.None, out result));
+                Assert.Equal(TimeSpan.Zero, result);
+            }
+        }
+
+        [Fact]
+        public static void ParseExactMultiple_Span_InvalidNullEmptyFormats()
+        {
+            TimeSpan result;
+
+            AssertExtensions.Throws<ArgumentNullException>("formats", () => TimeSpan.ParseExact("12:34:56".AsSpan(), (string[])null, null));
+            Assert.False(TimeSpan.TryParseExact("12:34:56".AsSpan(), (string[])null, null, out result));
+
+            Assert.Throws<FormatException>(() => TimeSpan.ParseExact("12:34:56".AsSpan(), new string[0], null));
+            Assert.False(TimeSpan.TryParseExact("12:34:56".AsSpan(), new string[0], null, out result));
+        }
+
+        [Theory]
+        [MemberData(nameof(ParseExact_InvalidStyles_TestData))]
+        public void ParseExact_InvalidStylesSpan_ThrowsArgumentException(TimeSpanStyles styles)
+        {
+            TimeSpan result;
+
+            string inputString = "00:00:00";
+            AssertExtensions.Throws<ArgumentException>("styles", () => TimeSpan.ParseExact(inputString.AsSpan(), "s", new CultureInfo("en-US"), styles));
+            AssertExtensions.Throws<ArgumentException>("styles", () => TimeSpan.ParseExact(inputString.AsSpan(), new string[] { "s" }, new CultureInfo("en-US"), styles));
+            AssertExtensions.Throws<ArgumentException>("styles", () => TimeSpan.TryParseExact(inputString.AsSpan(), "s", new CultureInfo("en-US"), styles, out result));
+            AssertExtensions.Throws<ArgumentException>("styles", () => TimeSpan.TryParseExact(inputString.AsSpan(), new string[] { "s" }, new CultureInfo("en-US"), styles, out result));
+        }
+
+        [Theory]
+        [MemberData(nameof(ToString_TestData))]
+        public static void TryFormat_Valid(TimeSpan input, string format, CultureInfo info, string expected)
+        {
+            int charsWritten;
+            Span<char> dst;
+
+            dst = new char[expected.Length - 1];
+            Assert.False(input.TryFormat(dst, out charsWritten, format, info));
+            Assert.Equal(0, charsWritten);
+
+            dst = new char[expected.Length];
+            Assert.True(input.TryFormat(dst, out charsWritten, format, info));
+            Assert.Equal(expected.Length, charsWritten);
+            Assert.Equal(expected, new string(dst));
+
+            dst = new char[expected.Length + 1];
+            Assert.True(input.TryFormat(dst, out charsWritten, format, info));
+            Assert.Equal(expected.Length, charsWritten);
+            Assert.Equal(expected, new string(dst.Slice(0, dst.Length - 1)));
+            Assert.Equal(0, dst[dst.Length - 1]);
+        }
+
+        [Theory]
+        [MemberData(nameof(ToString_InvalidFormat_TestData))]
+        public void TryFormat_InvalidFormat_ThrowsFormatException(string invalidFormat)
+        {
+            char[] dst = new char[1];
+            Assert.Throws<FormatException>(() => new TimeSpan().TryFormat(dst.AsSpan(), out int charsWritten, invalidFormat, null));
+        }
+
+        [Fact]
+        public static void ConvertToTimeSpanPrecisionTest()
+        {
+            Assert.Equal(12345, TimeSpan.FromMilliseconds(1.23456).Ticks);
+            Assert.Equal(12345, TimeSpan.FromMilliseconds(1.234567).Ticks);
+
+            Assert.Equal(12345600, TimeSpan.FromSeconds(1.23456).Ticks);
+
+            Assert.Equal(1.23456 * 60 * 10_000_000, TimeSpan.FromMinutes(1.23456).Ticks);
+        }
     }
 }
diff --git a/src/libraries/System.Runtime/tests/System/TimeSpanTests.netcoreapp.cs b/src/libraries/System.Runtime/tests/System/TimeSpanTests.netcoreapp.cs
deleted file mode 100644 (file)
index 13b7969..0000000
+++ /dev/null
@@ -1,328 +0,0 @@
-// 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.Globalization;
-using Xunit;
-
-namespace System.Tests
-{
-    public partial class TimeSpanTests
-    {
-        public static IEnumerable<object[]> MultiplicationTestData()
-        {
-            yield return new object[] {new TimeSpan(2, 30, 0), 2.0, new TimeSpan(5, 0, 0)};
-            yield return new object[] {new TimeSpan(14, 2, 30, 0), 192.0, TimeSpan.FromDays(2708)};
-            yield return new object[] {TimeSpan.FromDays(366), Math.PI, new TimeSpan(993446995288779)};
-            yield return new object[] {TimeSpan.FromDays(366), -Math.E, new TimeSpan(-859585952922633)};
-            yield return new object[] {TimeSpan.FromDays(29.530587981), 13.0, TimeSpan.FromDays(29.530587981 * 13.0) };
-            yield return new object[] {TimeSpan.FromDays(-29.530587981), -12.0, TimeSpan.FromDays(-29.530587981 * -12.0) };
-            yield return new object[] {TimeSpan.FromDays(-29.530587981), 0.0, TimeSpan.Zero};
-            yield return new object[] {TimeSpan.MaxValue, 0.5, TimeSpan.FromTicks((long)(long.MaxValue * 0.5))};
-        }
-
-        // ParseDifferentLengthFractionWithLeadingZerosData mainly testing the behavior we have fixed in net core
-        // which is the way we normalize the parsed fraction and possibly rounding it.
-        public static IEnumerable<object[]> ParseDifferentLengthFractionWithLeadingZerosData()
-        {
-            yield return new object[] {"00:00:00.00000001",   new TimeSpan(0)};
-            yield return new object[] {"00:00:00.00000005",   new TimeSpan(1)};
-            yield return new object[] {"00:00:00.09999999",   new TimeSpan(1_000_000)};
-            yield return new object[] {"00:00:00.0268435455", new TimeSpan(268435)};
-            yield return new object[] {"00:00:00.01",         new TimeSpan(1_00_000)};
-            yield return new object[] {"0:00:00.01000000",    new TimeSpan(100_000)};
-            yield return new object[] {"0:00:00.010000000",   new TimeSpan(100_000)};
-            yield return new object[] {"0:00:00.0123456",     new TimeSpan(123456)};
-            yield return new object[] {"0:00:00.00123456",    new TimeSpan(12346)};
-            yield return new object[] {"0:00:00.00000098",    new TimeSpan(10)};
-            yield return new object[] {"0:00:00.00000099",    new TimeSpan(10)};
-        }
-
-        [Theory, MemberData(nameof(ParseDifferentLengthFractionWithLeadingZerosData))]
-        public static void Multiplication(string input, TimeSpan expected)
-        {
-            Assert.Equal(expected, TimeSpan.Parse(input, CultureInfo.InvariantCulture));
-            Assert.Equal(expected, TimeSpan.ParseExact(input, "g", CultureInfo.InvariantCulture));
-        }
-
-        [Theory, MemberData(nameof(MultiplicationTestData))]
-        public static void Multiplication(TimeSpan timeSpan, double factor, TimeSpan expected)
-        {
-            Assert.Equal(expected, timeSpan * factor);
-            Assert.Equal(expected, factor * timeSpan);
-        }
-
-        [Fact]
-        public static void OverflowingMultiplication()
-        {
-            Assert.Throws<OverflowException>(() => TimeSpan.MaxValue * 1.000000001);
-            Assert.Throws<OverflowException>(() => -1.000000001 * TimeSpan.MaxValue);
-        }
-
-        [Fact]
-        public static void NaNMultiplication()
-        {
-            AssertExtensions.Throws<ArgumentException>("factor", () => TimeSpan.FromDays(1) * double.NaN);
-            AssertExtensions.Throws<ArgumentException>("factor", () => double.NaN * TimeSpan.FromDays(1));
-        }
-
-        [Theory, MemberData(nameof(MultiplicationTestData))]
-        public static void Division(TimeSpan timeSpan, double factor, TimeSpan expected)
-        {
-            Assert.Equal(factor, expected / timeSpan, 14);
-            double divisor = 1.0 / factor;
-            Assert.Equal(expected, timeSpan / divisor);
-        }
-
-        [Fact]
-        public static void DivideByZero()
-        {
-            Assert.Throws<OverflowException>(() => TimeSpan.FromDays(1) / 0);
-            Assert.Throws<OverflowException>(() => TimeSpan.FromDays(-1) / 0);
-            Assert.Throws<OverflowException>(() => TimeSpan.Zero / 0);
-            Assert.Equal(double.PositiveInfinity, TimeSpan.FromDays(1) / TimeSpan.Zero);
-            Assert.Equal(double.NegativeInfinity, TimeSpan.FromDays(-1) / TimeSpan.Zero);
-            Assert.True(double.IsNaN(TimeSpan.Zero / TimeSpan.Zero));
-        }
-
-        [Fact]
-        public static void NaNDivision()
-        {
-            AssertExtensions.Throws<ArgumentException>("divisor", () => TimeSpan.FromDays(1) / double.NaN);
-        }
-
-        [Theory, MemberData(nameof(MultiplicationTestData))]
-        public static void NamedMultiplication(TimeSpan timeSpan, double factor, TimeSpan expected)
-        {
-            Assert.Equal(expected, timeSpan.Multiply(factor));
-        }
-
-        [Fact]
-        public static void NamedOverflowingMultiplication()
-        {
-            Assert.Throws<OverflowException>(() => TimeSpan.MaxValue.Multiply(1.000000001));
-        }
-
-        [Fact]
-        public static void NamedNaNMultiplication()
-        {
-            AssertExtensions.Throws<ArgumentException>("factor", () => TimeSpan.FromDays(1).Multiply(double.NaN));
-        }
-
-        [Theory, MemberData(nameof(MultiplicationTestData))]
-        public static void NamedDivision(TimeSpan timeSpan, double factor, TimeSpan expected)
-        {
-            Assert.Equal(factor, expected.Divide(timeSpan), 14);
-            double divisor = 1.0 / factor;
-            Assert.Equal(expected, timeSpan.Divide(divisor));
-        }
-
-        [Fact]
-        public static void NamedDivideByZero()
-        {
-            Assert.Throws<OverflowException>(() => TimeSpan.FromDays(1).Divide(0));
-            Assert.Throws<OverflowException>(() => TimeSpan.FromDays(-1).Divide(0));
-            Assert.Throws<OverflowException>(() => TimeSpan.Zero.Divide(0));
-            Assert.Equal(double.PositiveInfinity, TimeSpan.FromDays(1).Divide(TimeSpan.Zero));
-            Assert.Equal(double.NegativeInfinity, TimeSpan.FromDays(-1).Divide(TimeSpan.Zero));
-            Assert.True(double.IsNaN(TimeSpan.Zero.Divide(TimeSpan.Zero)));
-        }
-
-        [Fact]
-        public static void NamedNaNDivision()
-        {
-            AssertExtensions.Throws<ArgumentException>("divisor", () => TimeSpan.FromDays(1).Divide(double.NaN));
-        }
-
-        public static IEnumerable<object[]> Parse_ValidWithOffsetCount_TestData()
-        {
-            foreach (object[] inputs in Parse_Valid_TestData())
-            {
-                yield return new object[] { inputs[0], 0, ((string)inputs[0]).Length, inputs[1], inputs[2] };
-            }
-
-            yield return new object[] { "     12:24:02      ", 5, 8, null, new TimeSpan(0, 12, 24, 2, 0) };
-            yield return new object[] { "     12:24:02      ", 6, 7, null, new TimeSpan(0, 2, 24, 2, 0) };
-            yield return new object[] { "     12:24:02      ", 6, 6, null, new TimeSpan(0, 2, 24, 0, 0) };
-            yield return new object[] { "12:24:02.01", 0, 8, CultureInfo.InvariantCulture, new TimeSpan(0, 12, 24, 2, 0) };
-            yield return new object[] { "1:1:1.00000001", 0, 7, CultureInfo.InvariantCulture, new TimeSpan(1, 1, 1) };
-            yield return new object[] { "1:1:.00000001", 0, 6, CultureInfo.InvariantCulture, new TimeSpan(36600000000) };
-            yield return new object[] { "24:00:00", 1, 7, null, new TimeSpan(4, 0, 0) };
-        }
-
-        [Theory]
-        [MemberData(nameof(Parse_ValidWithOffsetCount_TestData))]
-        public static void Parse_Span(string inputString, int offset, int count, IFormatProvider provider, TimeSpan expected)
-        {
-            ReadOnlySpan<char> input = inputString.AsSpan(offset, count);
-            TimeSpan result;
-
-            // Default provider.
-            if (provider == null)
-            {
-                Assert.True(TimeSpan.TryParse(input, out result));
-                Assert.Equal(expected, result);
-            }
-
-            Assert.Equal(expected, TimeSpan.Parse(input, provider));
-            Assert.True(TimeSpan.TryParse(input, provider, out result));
-            Assert.Equal(expected, result);
-
-            // Also negate
-            if (!char.IsWhiteSpace(input[0]))
-            {
-                input = ("-" + inputString.Substring(offset, count)).AsSpan();
-                expected = -expected;
-
-                Assert.Equal(expected, TimeSpan.Parse(input, provider));
-                Assert.True(TimeSpan.TryParse(input, provider, out result));
-                Assert.Equal(expected, result);
-            }
-        }
-
-        [Theory]
-        [MemberData(nameof(Parse_Invalid_TestData))]
-        public static void Parse_Span_Invalid(string inputString, IFormatProvider provider, Type exceptionType)
-        {
-            if (inputString != null)
-            {
-                Assert.Throws(exceptionType, () => TimeSpan.Parse(inputString.AsSpan(), provider));
-                Assert.False(TimeSpan.TryParse(inputString.AsSpan(), provider, out TimeSpan result));
-                Assert.Equal(TimeSpan.Zero, result);
-            }
-        }
-
-        [Theory]
-        [MemberData(nameof(ParseExact_Valid_TestData))]
-        public static void ParseExact_Span_Valid(string inputString, string format, TimeSpan expected)
-        {
-            ReadOnlySpan<char> input = inputString.AsSpan();
-
-            TimeSpan result;
-            Assert.Equal(expected, TimeSpan.ParseExact(input, format, new CultureInfo("en-US")));
-            Assert.Equal(expected, TimeSpan.ParseExact(input, format, new CultureInfo("en-US"), TimeSpanStyles.None));
-            Assert.Equal(expected, TimeSpan.ParseExact(input, new[] { format }, new CultureInfo("en-US")));
-            Assert.Equal(expected, TimeSpan.ParseExact(input, new[] { format }, new CultureInfo("en-US"), TimeSpanStyles.None));
-
-            Assert.True(TimeSpan.TryParseExact(input, format, new CultureInfo("en-US"), out result));
-            Assert.Equal(expected, result);
-
-            Assert.True(TimeSpan.TryParseExact(input, format, new CultureInfo("en-US"), TimeSpanStyles.None, out result));
-            Assert.Equal(expected, result);
-
-            Assert.True(TimeSpan.TryParseExact(input, new[] { format }, new CultureInfo("en-US"), out result));
-            Assert.Equal(expected, result);
-
-            Assert.True(TimeSpan.TryParseExact(input, new[] { format }, new CultureInfo("en-US"), TimeSpanStyles.None, out result));
-            Assert.Equal(expected, result);
-
-            if (format != "c" && format != "t" && format != "T" && format != "g" && format != "G")
-            {
-                // TimeSpanStyles is interpreted only for custom formats
-                Assert.Equal(expected.Negate(), TimeSpan.ParseExact(input, format, new CultureInfo("en-US"), TimeSpanStyles.AssumeNegative));
-
-                Assert.True(TimeSpan.TryParseExact(input, format, new CultureInfo("en-US"), TimeSpanStyles.AssumeNegative, out result));
-                Assert.Equal(expected.Negate(), result);
-            }
-            else
-            {
-                // Inputs that can be parsed in standard formats with ParseExact should also be parsable with Parse
-                Assert.Equal(expected, TimeSpan.Parse(input, CultureInfo.InvariantCulture));
-
-                Assert.True(TimeSpan.TryParse(input, CultureInfo.InvariantCulture, out result));
-                Assert.Equal(expected, result);
-            }
-        }
-
-        [Theory]
-        [MemberData(nameof(ParseExact_Invalid_TestData))]
-        public static void ParseExactTest_Span_Invalid(string inputString, string format, Type exceptionType)
-        {
-            if (inputString != null && format != null)
-            {
-                Assert.Throws(exceptionType, () => TimeSpan.ParseExact(inputString.AsSpan(), format, new CultureInfo("en-US")));
-
-                TimeSpan result;
-                Assert.False(TimeSpan.TryParseExact(inputString.AsSpan(), format, new CultureInfo("en-US"), out result));
-                Assert.Equal(TimeSpan.Zero, result);
-
-                Assert.False(TimeSpan.TryParseExact(inputString.AsSpan(), format, new CultureInfo("en-US"), TimeSpanStyles.None, out result));
-                Assert.Equal(TimeSpan.Zero, result);
-
-                Assert.False(TimeSpan.TryParseExact(inputString.AsSpan(), new[] { format }, new CultureInfo("en-US"), out result));
-                Assert.Equal(TimeSpan.Zero, result);
-
-                Assert.False(TimeSpan.TryParseExact(inputString.AsSpan(), new[] { format }, new CultureInfo("en-US"), TimeSpanStyles.None, out result));
-                Assert.Equal(TimeSpan.Zero, result);
-            }
-        }
-
-        [Fact]
-        public static void ParseExactMultiple_Span_InvalidNullEmptyFormats()
-        {
-            TimeSpan result;
-
-            AssertExtensions.Throws<ArgumentNullException>("formats", () => TimeSpan.ParseExact("12:34:56".AsSpan(), (string[])null, null));
-            Assert.False(TimeSpan.TryParseExact("12:34:56".AsSpan(), (string[])null, null, out result));
-
-            Assert.Throws<FormatException>(() => TimeSpan.ParseExact("12:34:56".AsSpan(), new string[0], null));
-            Assert.False(TimeSpan.TryParseExact("12:34:56".AsSpan(), new string[0], null, out result));
-        }
-
-        [Theory]
-        [MemberData(nameof(ParseExact_InvalidStyles_TestData))]
-        public void ParseExact_InvalidStylesSpan_ThrowsArgumentException(TimeSpanStyles styles)
-        {
-            TimeSpan result;
-
-            string inputString = "00:00:00";
-            AssertExtensions.Throws<ArgumentException>("styles", () => TimeSpan.ParseExact(inputString.AsSpan(), "s", new CultureInfo("en-US"), styles));
-            AssertExtensions.Throws<ArgumentException>("styles", () => TimeSpan.ParseExact(inputString.AsSpan(), new string[] { "s" }, new CultureInfo("en-US"), styles));
-            AssertExtensions.Throws<ArgumentException>("styles", () => TimeSpan.TryParseExact(inputString.AsSpan(), "s", new CultureInfo("en-US"), styles, out result));
-            AssertExtensions.Throws<ArgumentException>("styles", () => TimeSpan.TryParseExact(inputString.AsSpan(), new string[] { "s" }, new CultureInfo("en-US"), styles, out result));
-        }
-
-        [Theory]
-        [MemberData(nameof(ToString_TestData))]
-        public static void TryFormat_Valid(TimeSpan input, string format, CultureInfo info, string expected)
-        {
-            int charsWritten;
-            Span<char> dst;
-
-            dst = new char[expected.Length - 1];
-            Assert.False(input.TryFormat(dst, out charsWritten, format, info));
-            Assert.Equal(0, charsWritten);
-
-            dst = new char[expected.Length];
-            Assert.True(input.TryFormat(dst, out charsWritten, format, info));
-            Assert.Equal(expected.Length, charsWritten);
-            Assert.Equal(expected, new string(dst));
-
-            dst = new char[expected.Length + 1];
-            Assert.True(input.TryFormat(dst, out charsWritten, format, info));
-            Assert.Equal(expected.Length, charsWritten);
-            Assert.Equal(expected, new string(dst.Slice(0, dst.Length - 1)));
-            Assert.Equal(0, dst[dst.Length - 1]);
-        }
-
-        [Theory]
-        [MemberData(nameof(ToString_InvalidFormat_TestData))]
-        public void TryFormat_InvalidFormat_ThrowsFormatException(string invalidFormat)
-        {
-            char[] dst = new char[1];
-            Assert.Throws<FormatException>(() => new TimeSpan().TryFormat(dst.AsSpan(), out int charsWritten, invalidFormat, null));
-        }
-
-        [Fact]
-        public static void ConvertToTimeSpanPrecisionTest()
-        {
-            Assert.Equal(12345, TimeSpan.FromMilliseconds(1.23456).Ticks);
-            Assert.Equal(12345, TimeSpan.FromMilliseconds(1.234567).Ticks);
-
-            Assert.Equal(12345600, TimeSpan.FromSeconds(1.23456).Ticks);
-
-            Assert.Equal(1.23456 * 60 * 10_000_000, TimeSpan.FromMinutes(1.23456).Ticks);
-        }
-    }
-}
index 01fb958..480ebb1 100644 (file)
@@ -7,7 +7,7 @@ using Xunit;
 
 namespace System.Tests.Types
 {
-    public abstract partial class TypePropertyTestBase
+    public abstract class TypePropertyTestBase
     {
         public abstract Type CreateType();
 
@@ -311,6 +311,42 @@ namespace System.Tests.Types
         {
             Assert.Equal(UnderlyingSystemType, CreateType().UnderlyingSystemType);
         }
+
+        [Fact]
+        public void IsGenericMethodParameter_Get_ReturnsExpected()
+        {
+            Assert.Equal(IsGenericMethodParameter, CreateType().IsGenericMethodParameter);
+        }
+
+        [Fact]
+        public void IsGenericTypeParameter_Get_ReturnsExpected()
+        {
+            Assert.Equal(IsGenericTypeParameter, CreateType().IsGenericTypeParameter);
+        }
+
+        [Fact]
+        public void IsSignatureType_Get_ReturnsExpected()
+        {
+            Assert.Equal(IsSignatureType, CreateType().IsSignatureType);
+        }
+
+        [Fact]
+        public void IsSZArray_Get_ReturnsExpected()
+        {
+            Assert.Equal(IsSZArray, CreateType().IsSZArray);
+        }
+
+        [Fact]
+        public void IsTypeDefinition_Get_ReturnsExpected()
+        {
+            Assert.Equal(IsTypeDefinition, CreateType().IsTypeDefinition);
+        }
+
+        [Fact]
+        public void IsVariableBoundArray_Get_ReturnsExpected()
+        {
+            Assert.Equal(IsVariableBoundArray, CreateType().IsVariableBoundArray);
+        }
     }
 
     public abstract class ArrayTypeTestBase : TypePropertyTestBase
diff --git a/src/libraries/System.Runtime/tests/System/Type/TypePropertyTests.netcoreapp.cs b/src/libraries/System.Runtime/tests/System/Type/TypePropertyTests.netcoreapp.cs
deleted file mode 100644 (file)
index 169b2ad..0000000
+++ /dev/null
@@ -1,48 +0,0 @@
-// 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.Reflection;
-using Xunit;
-
-namespace System.Tests.Types
-{
-    public abstract partial class TypePropertyTestBase
-    {
-        [Fact]
-        public void IsGenericMethodParameter_Get_ReturnsExpected()
-        {
-            Assert.Equal(IsGenericMethodParameter, CreateType().IsGenericMethodParameter);
-        }
-
-        [Fact]
-        public void IsGenericTypeParameter_Get_ReturnsExpected()
-        {
-            Assert.Equal(IsGenericTypeParameter, CreateType().IsGenericTypeParameter);
-        }
-
-        [Fact]
-        public void IsSignatureType_Get_ReturnsExpected()
-        {
-            Assert.Equal(IsSignatureType, CreateType().IsSignatureType);
-        }
-
-        [Fact]
-        public void IsSZArray_Get_ReturnsExpected()
-        {
-            Assert.Equal(IsSZArray, CreateType().IsSZArray);
-        }
-
-        [Fact]
-        public void IsTypeDefinition_Get_ReturnsExpected()
-        {
-            Assert.Equal(IsTypeDefinition, CreateType().IsTypeDefinition);
-        }
-
-        [Fact]
-        public void IsVariableBoundArray_Get_ReturnsExpected()
-        {
-            Assert.Equal(IsVariableBoundArray, CreateType().IsVariableBoundArray);
-        }
-    }
-}
index f14da21..d95c9b9 100644 (file)
@@ -5,7 +5,9 @@
 using System.Collections.Generic;
 using System.Diagnostics;
 using System.IO;
+using System.Linq;
 using System.Reflection;
+using System.Runtime.CompilerServices;
 using Microsoft.DotNet.RemoteExecutor;
 using Xunit;
 
@@ -37,6 +39,27 @@ namespace System.Tests
 {
     public partial class TypeTests
     {
+        private static readonly IList<Type> NonArrayBaseTypes;
+
+        static TypeTests()
+        {
+            NonArrayBaseTypes = new List<Type>()
+            {
+                typeof(int),
+                typeof(void),
+                typeof(int*),
+                typeof(Outside),
+                typeof(Outside<int>),
+                typeof(Outside<>).GetTypeInfo().GenericTypeParameters[0],
+                new object().GetType().GetType()
+            };
+
+            if (PlatformDetection.IsWindows)
+            {
+                NonArrayBaseTypes.Add(Type.GetTypeFromCLSID(default(Guid)));
+            }
+        }
+
         [Fact]
         public void FilterName_Get_ReturnsExpected()
         {
@@ -285,6 +308,262 @@ namespace System.Tests
             Assert.Throws<PlatformNotSupportedException>(() => Type.ReflectionOnlyGetType("", true, true));
             Assert.Throws<PlatformNotSupportedException>(() => Type.ReflectionOnlyGetType("System.Tests.TypeTests", false, true));
         }
+
+        [Fact]
+        public void IsSZArray_FalseForNonArrayTypes()
+        {
+            foreach (Type type in NonArrayBaseTypes)
+            {
+                Assert.False(type.IsSZArray);
+            }
+        }
+
+        [Fact]
+        public void IsSZArray_TrueForSZArrayTypes()
+        {
+            foreach (Type type in NonArrayBaseTypes.Select(nonArrayBaseType => nonArrayBaseType.MakeArrayType()))
+            {
+                Assert.True(type.IsSZArray);
+            }
+        }
+
+        [Fact]
+        public void IsSZArray_FalseForVariableBoundArrayTypes()
+        {
+            foreach (Type type in NonArrayBaseTypes.Select(nonArrayBaseType => nonArrayBaseType.MakeArrayType(1)))
+            {
+                Assert.False(type.IsSZArray);
+            }
+
+            foreach (Type type in NonArrayBaseTypes.Select(nonArrayBaseType => nonArrayBaseType.MakeArrayType(2)))
+            {
+                Assert.False(type.IsSZArray);
+            }
+        }
+
+        [Fact]
+        public void IsSZArray_FalseForNonArrayByRefType()
+        {
+            Assert.False(typeof(int).MakeByRefType().IsSZArray);
+        }
+
+        [Fact]
+        public void IsSZArray_FalseForByRefSZArrayType()
+        {
+            Assert.False(typeof(int[]).MakeByRefType().IsSZArray);
+        }
+
+
+        [Fact]
+        public void IsSZArray_FalseForByRefVariableArrayType()
+        {
+            Assert.False(typeof(int[,]).MakeByRefType().IsSZArray);
+        }
+
+        [Fact]
+        public void IsVariableBoundArray_FalseForNonArrayTypes()
+        {
+            foreach (Type type in NonArrayBaseTypes)
+            {
+                Assert.False(type.IsVariableBoundArray);
+            }
+        }
+
+        [Fact]
+        public void IsVariableBoundArray_FalseForSZArrayTypes()
+        {
+            foreach (Type type in NonArrayBaseTypes.Select(nonArrayBaseType => nonArrayBaseType.MakeArrayType()))
+            {
+                Assert.False(type.IsVariableBoundArray);
+            }
+        }
+
+        [Fact]
+        public void IsVariableBoundArray_TrueForVariableBoundArrayTypes()
+        {
+            foreach (Type type in NonArrayBaseTypes.Select(nonArrayBaseType => nonArrayBaseType.MakeArrayType(1)))
+            {
+                Assert.True(type.IsVariableBoundArray);
+            }
+
+            foreach (Type type in NonArrayBaseTypes.Select(nonArrayBaseType => nonArrayBaseType.MakeArrayType(2)))
+            {
+                Assert.True(type.IsVariableBoundArray);
+            }
+        }
+
+        [Fact]
+        public void IsVariableBoundArray_FalseForNonArrayByRefType()
+        {
+            Assert.False(typeof(int).MakeByRefType().IsVariableBoundArray);
+        }
+
+        [Fact]
+        public void IsVariableBoundArray_FalseForByRefSZArrayType()
+        {
+            Assert.False(typeof(int[]).MakeByRefType().IsVariableBoundArray);
+        }
+
+
+        [Fact]
+        public void IsVariableBoundArray_FalseForByRefVariableArrayType()
+        {
+            Assert.False(typeof(int[,]).MakeByRefType().IsVariableBoundArray);
+        }
+
+        [Theory]
+        [MemberData(nameof(DefinedTypes))]
+        public void IsTypeDefinition_True(Type type)
+        {
+            Assert.True(type.IsTypeDefinition);
+        }
+
+        [Theory]
+        [MemberData(nameof(NotDefinedTypes))]
+        public void IsTypeDefinition_False(Type type)
+        {
+            Assert.False(type.IsTypeDefinition);
+        }
+
+        // In the unlikely event we ever add new values to the CorElementType enumeration, CoreCLR will probably miss it because of the way IsTypeDefinition
+        // works. It's likely that such a type will live in the core assembly so to improve our chances of catching this situation, test IsTypeDefinition
+        // on every type exposed out of that assembly.
+        //
+        // Skipping this on .NET Native because:
+        //  - We really don't want to opt in all the metadata in System.Private.CoreLib
+        //  - The .NET Native implementation of IsTypeDefinition is not the one that works by enumerating selected values off CorElementType.
+        //    It has much less need of a test like this.
+        [Fact]
+        public void IsTypeDefinition_AllDefinedTypesInCoreAssembly()
+        {
+            foreach (Type type in typeof(object).Assembly.DefinedTypes)
+            {
+                Assert.True(type.IsTypeDefinition, "IsTypeDefinition expected to be true for type " + type);
+            }
+        }
+
+        public static IEnumerable<object[]> DefinedTypes
+        {
+            get
+            {
+                yield return new object[] { typeof(void) };
+                yield return new object[] { typeof(int) };
+                yield return new object[] { typeof(Outside) };
+                yield return new object[] { typeof(Outside.Inside) };
+                yield return new object[] { typeof(Outside<>) };
+                yield return new object[] { typeof(IEnumerable<>) };
+                yield return new object[] { 3.GetType().GetType() };  // This yields a reflection-blocked type on .NET Native - which is implemented separately
+
+                if (PlatformDetection.IsWindows)
+                    yield return new object[] { Type.GetTypeFromCLSID(default(Guid)) };
+            }
+        }
+
+        public static IEnumerable<object[]> NotDefinedTypes
+        {
+            get
+            {
+                Type theT = typeof(Outside<>).GetTypeInfo().GenericTypeParameters[0];
+
+                yield return new object[] { typeof(int[]) };
+                yield return new object[] { theT.MakeArrayType(1) }; // Using an open type as element type gets around .NET Native nonsupport of rank-1 multidim arrays
+                yield return new object[] { typeof(int[,]) };
+
+                yield return new object[] { typeof(int).MakeByRefType() };
+
+                yield return new object[] { typeof(int).MakePointerType() };
+
+                yield return new object[] { typeof(Outside<int>) };
+                yield return new object[] { typeof(Outside<int>.Inside<int>) };
+
+                yield return new object[] { theT };
+            }
+        }
+
+        [Theory]
+        [MemberData(nameof(IsByRefLikeTestData))]
+        public static void TestIsByRefLike(Type type, bool expected)
+        {
+            Assert.Equal(expected, type.IsByRefLike);
+        }
+
+        public static IEnumerable<object[]> IsByRefLikeTestData
+        {
+            get
+            {
+                Type theT = typeof(Outside<>).GetTypeInfo().GenericTypeParameters[0];
+
+                yield return new object[] { typeof(ArgIterator), true };
+                yield return new object[] { typeof(ByRefLikeStruct), true };
+                yield return new object[] { typeof(RegularStruct), false };
+                yield return new object[] { typeof(RuntimeArgumentHandle), true };
+                yield return new object[] { typeof(Span<>), true };
+                yield return new object[] { typeof(Span<>).MakeGenericType(theT), true };
+                yield return new object[] { typeof(Span<int>), true };
+                yield return new object[] { typeof(Span<int>).MakeByRefType(), false };
+                yield return new object[] { typeof(Span<int>).MakePointerType(), false };
+                yield return new object[] { typeof(TypedReference), true };
+                yield return new object[] { theT, false };
+                yield return new object[] { typeof(int[]), false };
+                yield return new object[] { typeof(int[,]), false };
+                yield return new object[] { typeof(object), false };
+                if (PlatformDetection.IsWindows) // GetTypeFromCLSID is Windows only
+                {
+                    yield return new object[] { Type.GetTypeFromCLSID(default(Guid)), false };
+                }
+            }
+        }
+
+        private ref struct ByRefLikeStruct
+        {
+            public ByRefLikeStruct(int dummy)
+            {
+                S = default(Span<int>);
+            }
+
+            public Span<int> S;
+        }
+
+        private struct RegularStruct
+        {
+        }
+
+        [Theory]
+        [MemberData(nameof(IsGenericParameterTestData))]
+        public static void TestIsGenericParameter(Type type, bool isGenericParameter, bool isGenericTypeParameter, bool isGenericMethodParameter)
+        {
+            Assert.Equal(isGenericParameter, type.IsGenericParameter);
+            Assert.Equal(isGenericTypeParameter, type.IsGenericTypeParameter);
+            Assert.Equal(isGenericMethodParameter, type.IsGenericMethodParameter);
+        }
+
+        public static IEnumerable<object[]> IsGenericParameterTestData
+        {
+            get
+            {
+                yield return new object[] { typeof(void), false, false, false };
+                yield return new object[] { typeof(int), false, false, false };
+                yield return new object[] { typeof(int[]), false, false, false };
+                yield return new object[] { typeof(int).MakeArrayType(1), false, false, false };
+                yield return new object[] { typeof(int[,]), false, false, false };
+                yield return new object[] { typeof(int).MakeByRefType(), false, false, false };
+                yield return new object[] { typeof(int).MakePointerType(), false, false, false };
+                yield return new object[] { typeof(DummyGenericClassForTypeTests<>), false, false, false };
+                yield return new object[] { typeof(DummyGenericClassForTypeTests<int>), false, false, false };
+                if (PlatformDetection.IsWindows) // GetTypeFromCLSID is Windows only
+                {
+                    yield return new object[] { Type.GetTypeFromCLSID(default(Guid)), false, false, false };
+                }
+
+                Type theT = typeof(Outside<>).GetTypeInfo().GenericTypeParameters[0];
+                yield return new object[] { theT, true, true, false };
+
+                Type theM = typeof(TypeTests).GetMethod(nameof(GenericMethod), BindingFlags.NonPublic | BindingFlags.Static).GetGenericArguments()[0];
+                yield return new object[] { theM, true, false, true };
+            }
+        }
+
+        private static void GenericMethod<M>() { }
     }
 
     public class TypeTestsExtended    {
@@ -478,3 +757,5 @@ namespace System.Tests
     public interface GenericInterface<T> { }
     public interface GenericInterface<T, U> { }
 }
+
+internal class DummyGenericClassForTypeTests<T> { }
diff --git a/src/libraries/System.Runtime/tests/System/Type/TypeTests.netcoreapp.cs b/src/libraries/System.Runtime/tests/System/Type/TypeTests.netcoreapp.cs
deleted file mode 100644 (file)
index 85d0943..0000000
+++ /dev/null
@@ -1,294 +0,0 @@
-// 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 System.Reflection;
-using System.Runtime.CompilerServices;
-using Xunit;
-
-namespace System.Tests
-{
-    public class TypeTestsNetcore
-    {
-        private static readonly IList<Type> NonArrayBaseTypes;
-
-        static TypeTestsNetcore()
-        {
-            NonArrayBaseTypes = new List<Type>()
-            {
-                typeof(int),
-                typeof(void),
-                typeof(int*),
-                typeof(Outside),
-                typeof(Outside<int>),
-                typeof(Outside<>).GetTypeInfo().GenericTypeParameters[0],
-                new object().GetType().GetType()
-            };
-
-            if (PlatformDetection.IsWindows)
-            {
-                NonArrayBaseTypes.Add(Type.GetTypeFromCLSID(default(Guid)));
-            }
-        }
-
-        [Fact]
-        public void IsSZArray_FalseForNonArrayTypes()
-        {
-            foreach (Type type in NonArrayBaseTypes)
-            {
-                Assert.False(type.IsSZArray);
-            }
-        }
-
-        [Fact]
-        public void IsSZArray_TrueForSZArrayTypes()
-        {
-            foreach (Type type in NonArrayBaseTypes.Select(nonArrayBaseType => nonArrayBaseType.MakeArrayType()))
-            {
-                Assert.True(type.IsSZArray);
-            }
-        }
-
-        [Fact]
-        public void IsSZArray_FalseForVariableBoundArrayTypes()
-        {
-            foreach (Type type in NonArrayBaseTypes.Select(nonArrayBaseType => nonArrayBaseType.MakeArrayType(1)))
-            {
-                Assert.False(type.IsSZArray);
-            }
-
-            foreach (Type type in NonArrayBaseTypes.Select(nonArrayBaseType => nonArrayBaseType.MakeArrayType(2)))
-            {
-                Assert.False(type.IsSZArray);
-            }
-        }
-
-        [Fact]
-        public void IsSZArray_FalseForNonArrayByRefType()
-        {
-            Assert.False(typeof(int).MakeByRefType().IsSZArray);
-        }
-
-        [Fact]
-        public void IsSZArray_FalseForByRefSZArrayType()
-        {
-            Assert.False(typeof(int[]).MakeByRefType().IsSZArray);
-        }
-
-
-        [Fact]
-        public void IsSZArray_FalseForByRefVariableArrayType()
-        {
-            Assert.False(typeof(int[,]).MakeByRefType().IsSZArray);
-        }
-
-        [Fact]
-        public void IsVariableBoundArray_FalseForNonArrayTypes()
-        {
-            foreach (Type type in NonArrayBaseTypes)
-            {
-                Assert.False(type.IsVariableBoundArray);
-            }
-        }
-
-        [Fact]
-        public void IsVariableBoundArray_FalseForSZArrayTypes()
-        {
-            foreach (Type type in NonArrayBaseTypes.Select(nonArrayBaseType => nonArrayBaseType.MakeArrayType()))
-            {
-                Assert.False(type.IsVariableBoundArray);
-            }
-        }
-
-        [Fact]
-        public void IsVariableBoundArray_TrueForVariableBoundArrayTypes()
-        {
-            foreach (Type type in NonArrayBaseTypes.Select(nonArrayBaseType => nonArrayBaseType.MakeArrayType(1)))
-            {
-                Assert.True(type.IsVariableBoundArray);
-            }
-
-            foreach (Type type in NonArrayBaseTypes.Select(nonArrayBaseType => nonArrayBaseType.MakeArrayType(2)))
-            {
-                Assert.True(type.IsVariableBoundArray);
-            }
-        }
-
-        [Fact]
-        public void IsVariableBoundArray_FalseForNonArrayByRefType()
-        {
-            Assert.False(typeof(int).MakeByRefType().IsVariableBoundArray);
-        }
-
-        [Fact]
-        public void IsVariableBoundArray_FalseForByRefSZArrayType()
-        {
-            Assert.False(typeof(int[]).MakeByRefType().IsVariableBoundArray);
-        }
-
-
-        [Fact]
-        public void IsVariableBoundArray_FalseForByRefVariableArrayType()
-        {
-            Assert.False(typeof(int[,]).MakeByRefType().IsVariableBoundArray);
-        }
-
-        [Theory]
-        [MemberData(nameof(DefinedTypes))]
-        public void IsTypeDefinition_True(Type type)
-        {
-            Assert.True(type.IsTypeDefinition);
-        }
-
-        [Theory]
-        [MemberData(nameof(NotDefinedTypes))]
-        public void IsTypeDefinition_False(Type type)
-        {
-            Assert.False(type.IsTypeDefinition);
-        }
-
-        // In the unlikely event we ever add new values to the CorElementType enumeration, CoreCLR will probably miss it because of the way IsTypeDefinition
-        // works. It's likely that such a type will live in the core assembly so to improve our chances of catching this situation, test IsTypeDefinition
-        // on every type exposed out of that assembly.
-        //
-        // Skipping this on .NET Native because:
-        //  - We really don't want to opt in all the metadata in System.Private.CoreLib
-        //  - The .NET Native implementation of IsTypeDefinition is not the one that works by enumerating selected values off CorElementType.
-        //    It has much less need of a test like this.
-        [Fact]
-        public void IsTypeDefinition_AllDefinedTypesInCoreAssembly()
-        {
-            foreach (Type type in typeof(object).Assembly.DefinedTypes)
-            {
-                Assert.True(type.IsTypeDefinition, "IsTypeDefinition expected to be true for type " + type);
-            }
-        }
-
-        public static IEnumerable<object[]> DefinedTypes
-        {
-            get
-            {
-                yield return new object[] { typeof(void) };
-                yield return new object[] { typeof(int) };
-                yield return new object[] { typeof(Outside) };
-                yield return new object[] { typeof(Outside.Inside) };
-                yield return new object[] { typeof(Outside<>) };
-                yield return new object[] { typeof(IEnumerable<>) };
-                yield return new object[] { 3.GetType().GetType() };  // This yields a reflection-blocked type on .NET Native - which is implemented separately
-
-                if (PlatformDetection.IsWindows)
-                    yield return new object[] { Type.GetTypeFromCLSID(default(Guid)) };
-            }
-        }
-
-        public static IEnumerable<object[]> NotDefinedTypes
-        {
-            get
-            {
-                Type theT = typeof(Outside<>).GetTypeInfo().GenericTypeParameters[0];
-
-                yield return new object[] { typeof(int[]) };
-                yield return new object[] { theT.MakeArrayType(1) }; // Using an open type as element type gets around .NET Native nonsupport of rank-1 multidim arrays
-                yield return new object[] { typeof(int[,]) };
-
-                yield return new object[] { typeof(int).MakeByRefType() };
-
-                yield return new object[] { typeof(int).MakePointerType() };
-
-                yield return new object[] { typeof(Outside<int>) };
-                yield return new object[] { typeof(Outside<int>.Inside<int>) };
-
-                yield return new object[] { theT };
-            }
-        }
-
-        [Theory]
-        [MemberData(nameof(IsByRefLikeTestData))]
-        public static void TestIsByRefLike(Type type, bool expected)
-        {
-            Assert.Equal(expected, type.IsByRefLike);
-        }
-
-        public static IEnumerable<object[]> IsByRefLikeTestData
-        {
-            get
-            {
-                Type theT = typeof(Outside<>).GetTypeInfo().GenericTypeParameters[0];
-
-                yield return new object[] { typeof(ArgIterator), true };
-                yield return new object[] { typeof(ByRefLikeStruct), true };
-                yield return new object[] { typeof(RegularStruct), false };
-                yield return new object[] { typeof(RuntimeArgumentHandle), true };
-                yield return new object[] { typeof(Span<>), true };
-                yield return new object[] { typeof(Span<>).MakeGenericType(theT), true };
-                yield return new object[] { typeof(Span<int>), true };
-                yield return new object[] { typeof(Span<int>).MakeByRefType(), false };
-                yield return new object[] { typeof(Span<int>).MakePointerType(), false };
-                yield return new object[] { typeof(TypedReference), true };
-                yield return new object[] { theT, false };
-                yield return new object[] { typeof(int[]), false };
-                yield return new object[] { typeof(int[,]), false };
-                yield return new object[] { typeof(object), false };
-                if (PlatformDetection.IsWindows) // GetTypeFromCLSID is Windows only
-                {
-                    yield return new object[] { Type.GetTypeFromCLSID(default(Guid)), false };
-                }
-            }
-        }
-
-        private ref struct ByRefLikeStruct
-        {
-            public ByRefLikeStruct(int dummy)
-            {
-                S = default(Span<int>);
-            }
-
-            public Span<int> S;
-        }
-
-        private struct RegularStruct
-        {
-        }
-
-        [Theory]
-        [MemberData(nameof(IsGenericParameterTestData))]
-        public static void TestIsGenericParameter(Type type, bool isGenericParameter, bool isGenericTypeParameter, bool isGenericMethodParameter)
-        {
-            Assert.Equal(isGenericParameter, type.IsGenericParameter);
-            Assert.Equal(isGenericTypeParameter, type.IsGenericTypeParameter);
-            Assert.Equal(isGenericMethodParameter, type.IsGenericMethodParameter);
-        }
-
-        public static IEnumerable<object[]> IsGenericParameterTestData
-        {
-            get
-            {
-                yield return new object[] { typeof(void), false, false, false };
-                yield return new object[] { typeof(int), false, false, false };
-                yield return new object[] { typeof(int[]), false, false, false };
-                yield return new object[] { typeof(int).MakeArrayType(1), false, false, false };
-                yield return new object[] { typeof(int[,]), false, false, false };
-                yield return new object[] { typeof(int).MakeByRefType(), false, false, false };
-                yield return new object[] { typeof(int).MakePointerType(), false, false, false };
-                yield return new object[] { typeof(DummyGenericClassForTypeTestsNetcore<>), false, false, false };
-                yield return new object[] { typeof(DummyGenericClassForTypeTestsNetcore<int>), false, false, false };
-                if (PlatformDetection.IsWindows) // GetTypeFromCLSID is Windows only
-                {
-                    yield return new object[] { Type.GetTypeFromCLSID(default(Guid)), false, false, false };
-                }
-
-                Type theT = typeof(Outside<>).GetTypeInfo().GenericTypeParameters[0];
-                yield return new object[] { theT, true, true, false };
-
-                Type theM = typeof(TypeTestsNetcore).GetMethod(nameof(GenericMethod), BindingFlags.NonPublic | BindingFlags.Static).GetGenericArguments()[0];
-                yield return new object[] { theM, true, false, true };
-            }
-        }
-
-        private static void GenericMethod<M>() { }
-    }
-}
-
-internal class DummyGenericClassForTypeTestsNetcore<T> { }
index ef837a5..ccc9f47 100644 (file)
@@ -8,7 +8,7 @@ using Xunit;
 
 namespace System.Tests
 {
-    public partial class UInt16Tests
+    public class UInt16Tests
     {
         [Fact]
         public static void Ctor_Empty()
@@ -290,5 +290,105 @@ namespace System.Tests
             AssertExtensions.Throws<ArgumentException>(paramName, () => ushort.Parse("1", style));
             AssertExtensions.Throws<ArgumentException>(paramName, () => ushort.Parse("1", style, null));
         }
+
+        public static IEnumerable<object[]> Parse_ValidWithOffsetCount_TestData()
+        {
+            foreach (object[] inputs in Parse_Valid_TestData())
+            {
+                yield return new object[] { inputs[0], 0, ((string)inputs[0]).Length, inputs[1], inputs[2], inputs[3] };
+            }
+
+            yield return new object[] { "123", 0, 2, NumberStyles.Integer, null, (ushort)12 };
+            yield return new object[] { "123", 1, 2, NumberStyles.Integer, null, (ushort)23 };
+            yield return new object[] { "+123", 0, 2, NumberStyles.Integer, null, (ushort)1 };
+            yield return new object[] { "+123", 1, 3, NumberStyles.Integer, null, (ushort)123 };
+            yield return new object[] { "AJK", 0, 1, NumberStyles.HexNumber, new NumberFormatInfo(), (ushort)0XA };
+            yield return new object[] { "$1,000", 0, 2, NumberStyles.Currency, new NumberFormatInfo() { CurrencySymbol = "$" }, (ushort)1 };
+            yield return new object[] { "$1,000", 1, 3, NumberStyles.Currency, new NumberFormatInfo() { CurrencySymbol = "$" }, (ushort)10 };
+        }
+
+        [Theory]
+        [MemberData(nameof(Parse_ValidWithOffsetCount_TestData))]
+        public static void Parse_Span_Valid(string value, int offset, int count, NumberStyles style, IFormatProvider provider, ushort expected)
+        {
+            ushort result;
+
+            // Default style and provider
+            if (style == NumberStyles.Integer && provider == null)
+            {
+                Assert.True(ushort.TryParse(value.AsSpan(offset, count), out result));
+                Assert.Equal(expected, result);
+            }
+
+            Assert.Equal(expected, ushort.Parse(value.AsSpan(offset, count), style, provider));
+
+            Assert.True(ushort.TryParse(value.AsSpan(offset, count), style, provider, out result));
+            Assert.Equal(expected, result);
+        }
+
+        [Theory]
+        [MemberData(nameof(Parse_Invalid_TestData))]
+        public static void Parse_Span_Invalid(string value, NumberStyles style, IFormatProvider provider, Type exceptionType)
+        {
+            if (value != null)
+            {
+                ushort result;
+
+                // Default style and provider
+                if (style == NumberStyles.Integer && provider == null)
+                {
+                    Assert.False(ushort.TryParse(value.AsSpan(), out result));
+                    Assert.Equal(0u, result);
+                }
+
+                Assert.Throws(exceptionType, () => ushort.Parse(value.AsSpan(), style, provider));
+
+                Assert.False(ushort.TryParse(value.AsSpan(), style, provider, out result));
+                Assert.Equal(0u, result);
+            }
+        }
+
+        [Theory]
+        [MemberData(nameof(ToString_TestData))]
+        public static void TryFormat(ushort i, string format, IFormatProvider provider, string expected)
+        {
+            char[] actual;
+            int charsWritten;
+
+            // Just right
+            actual = new char[expected.Length];
+            Assert.True(i.TryFormat(actual.AsSpan(), out charsWritten, format, provider));
+            Assert.Equal(expected.Length, charsWritten);
+            Assert.Equal(expected, new string(actual));
+
+            // Longer than needed
+            actual = new char[expected.Length + 1];
+            Assert.True(i.TryFormat(actual.AsSpan(), out charsWritten, format, provider));
+            Assert.Equal(expected.Length, charsWritten);
+            Assert.Equal(expected, new string(actual, 0, charsWritten));
+
+            // Too short
+            if (expected.Length > 0)
+            {
+                actual = new char[expected.Length - 1];
+                Assert.False(i.TryFormat(actual.AsSpan(), out charsWritten, format, provider));
+                Assert.Equal(0, charsWritten);
+            }
+
+            if (format != null)
+            {
+                // Upper format
+                actual = new char[expected.Length];
+                Assert.True(i.TryFormat(actual.AsSpan(), out charsWritten, format.ToUpperInvariant(), provider));
+                Assert.Equal(expected.Length, charsWritten);
+                Assert.Equal(expected.ToUpperInvariant(), new string(actual));
+
+                // Lower format
+                actual = new char[expected.Length];
+                Assert.True(i.TryFormat(actual.AsSpan(), out charsWritten, format.ToLowerInvariant(), provider));
+                Assert.Equal(expected.Length, charsWritten);
+                Assert.Equal(expected.ToLowerInvariant(), new string(actual));
+            }
+        }
     }
 }
diff --git a/src/libraries/System.Runtime/tests/System/UInt16Tests.netcoreapp.cs b/src/libraries/System.Runtime/tests/System/UInt16Tests.netcoreapp.cs
deleted file mode 100644 (file)
index a6e8301..0000000
+++ /dev/null
@@ -1,113 +0,0 @@
-// 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.Globalization;
-using Xunit;
-
-namespace System.Tests
-{
-    public partial class UInt16Tests
-    {
-        public static IEnumerable<object[]> Parse_ValidWithOffsetCount_TestData()
-        {
-            foreach (object[] inputs in Parse_Valid_TestData())
-            {
-                yield return new object[] { inputs[0], 0, ((string)inputs[0]).Length, inputs[1], inputs[2], inputs[3] };
-            }
-
-            yield return new object[] { "123", 0, 2, NumberStyles.Integer, null, (ushort)12 };
-            yield return new object[] { "123", 1, 2, NumberStyles.Integer, null, (ushort)23 };
-            yield return new object[] { "+123", 0, 2, NumberStyles.Integer, null, (ushort)1 };
-            yield return new object[] { "+123", 1, 3, NumberStyles.Integer, null, (ushort)123 };
-            yield return new object[] { "AJK", 0, 1, NumberStyles.HexNumber, new NumberFormatInfo(), (ushort)0XA };
-            yield return new object[] { "$1,000", 0, 2, NumberStyles.Currency, new NumberFormatInfo() { CurrencySymbol = "$" }, (ushort)1 };
-            yield return new object[] { "$1,000", 1, 3, NumberStyles.Currency, new NumberFormatInfo() { CurrencySymbol = "$" }, (ushort)10 };
-        }
-
-        [Theory]
-        [MemberData(nameof(Parse_ValidWithOffsetCount_TestData))]
-        public static void Parse_Span_Valid(string value, int offset, int count, NumberStyles style, IFormatProvider provider, ushort expected)
-        {
-            ushort result;
-
-            // Default style and provider
-            if (style == NumberStyles.Integer && provider == null)
-            {
-                Assert.True(ushort.TryParse(value.AsSpan(offset, count), out result));
-                Assert.Equal(expected, result);
-            }
-
-            Assert.Equal(expected, ushort.Parse(value.AsSpan(offset, count), style, provider));
-
-            Assert.True(ushort.TryParse(value.AsSpan(offset, count), style, provider, out result));
-            Assert.Equal(expected, result);
-        }
-
-        [Theory]
-        [MemberData(nameof(Parse_Invalid_TestData))]
-        public static void Parse_Span_Invalid(string value, NumberStyles style, IFormatProvider provider, Type exceptionType)
-        {
-            if (value != null)
-            {
-                ushort result;
-
-                // Default style and provider
-                if (style == NumberStyles.Integer && provider == null)
-                {
-                    Assert.False(ushort.TryParse(value.AsSpan(), out result));
-                    Assert.Equal(0u, result);
-                }
-
-                Assert.Throws(exceptionType, () => ushort.Parse(value.AsSpan(), style, provider));
-
-                Assert.False(ushort.TryParse(value.AsSpan(), style, provider, out result));
-                Assert.Equal(0u, result);
-            }
-        }
-
-        [Theory]
-        [MemberData(nameof(ToString_TestData))]
-        public static void TryFormat(ushort i, string format, IFormatProvider provider, string expected)
-        {
-            char[] actual;
-            int charsWritten;
-
-            // Just right
-            actual = new char[expected.Length];
-            Assert.True(i.TryFormat(actual.AsSpan(), out charsWritten, format, provider));
-            Assert.Equal(expected.Length, charsWritten);
-            Assert.Equal(expected, new string(actual));
-
-            // Longer than needed
-            actual = new char[expected.Length + 1];
-            Assert.True(i.TryFormat(actual.AsSpan(), out charsWritten, format, provider));
-            Assert.Equal(expected.Length, charsWritten);
-            Assert.Equal(expected, new string(actual, 0, charsWritten));
-
-            // Too short
-            if (expected.Length > 0)
-            {
-                actual = new char[expected.Length - 1];
-                Assert.False(i.TryFormat(actual.AsSpan(), out charsWritten, format, provider));
-                Assert.Equal(0, charsWritten);
-            }
-
-            if (format != null)
-            {
-                // Upper format
-                actual = new char[expected.Length];
-                Assert.True(i.TryFormat(actual.AsSpan(), out charsWritten, format.ToUpperInvariant(), provider));
-                Assert.Equal(expected.Length, charsWritten);
-                Assert.Equal(expected.ToUpperInvariant(), new string(actual));
-
-                // Lower format
-                actual = new char[expected.Length];
-                Assert.True(i.TryFormat(actual.AsSpan(), out charsWritten, format.ToLowerInvariant(), provider));
-                Assert.Equal(expected.Length, charsWritten);
-                Assert.Equal(expected.ToLowerInvariant(), new string(actual));
-            }
-        }
-    }
-}
index 9265c13..a31df0e 100644 (file)
@@ -9,7 +9,7 @@ using Xunit;
 
 namespace System.Tests
 {
-    public partial class UInt32Tests
+    public class UInt32Tests
     {
         [Fact]
         public static void Ctor_Empty()
@@ -308,5 +308,105 @@ namespace System.Tests
             AssertExtensions.Throws<ArgumentException>(paramName, () => uint.Parse("1", style));
             AssertExtensions.Throws<ArgumentException>(paramName, () => uint.Parse("1", style, null));
         }
+
+        public static IEnumerable<object[]> Parse_ValidWithOffsetCount_TestData()
+        {
+            foreach (object[] inputs in Parse_Valid_TestData())
+            {
+                yield return new object[] { inputs[0], 0, ((string)inputs[0]).Length, inputs[1], inputs[2], inputs[3] };
+            }
+
+            yield return new object[] { "123", 0, 2, NumberStyles.Integer, null, (uint)12 };
+            yield return new object[] { "123", 1, 2, NumberStyles.Integer, null, (uint)23 };
+            yield return new object[] { "4294967295", 0, 1, NumberStyles.Integer, null, 4 };
+            yield return new object[] { "4294967295", 9, 1, NumberStyles.Integer, null, 5 };
+            yield return new object[] { "12", 0, 1, NumberStyles.HexNumber, null, (uint)0x1 };
+            yield return new object[] { "12", 1, 1, NumberStyles.HexNumber, null, (uint)0x2 };
+            yield return new object[] { "$1,000", 1, 3, NumberStyles.Currency, new NumberFormatInfo() { CurrencySymbol = "$" }, (uint)10 };
+        }
+
+        [Theory]
+        [MemberData(nameof(Parse_ValidWithOffsetCount_TestData))]
+        public static void Parse_Span_Valid(string value, int offset, int count, NumberStyles style, IFormatProvider provider, uint expected)
+        {
+            uint result;
+
+            // Default style and provider
+            if (style == NumberStyles.Integer && provider == null)
+            {
+                Assert.True(uint.TryParse(value.AsSpan(offset, count), out result));
+                Assert.Equal(expected, result);
+            }
+
+            Assert.Equal(expected, uint.Parse(value.AsSpan(offset, count), style, provider));
+
+            Assert.True(uint.TryParse(value.AsSpan(offset, count), style, provider, out result));
+            Assert.Equal(expected, result);
+        }
+
+        [Theory]
+        [MemberData(nameof(Parse_Invalid_TestData))]
+        public static void Parse_Span_Invalid(string value, NumberStyles style, IFormatProvider provider, Type exceptionType)
+        {
+            if (value != null)
+            {
+                uint result;
+
+                // Default style and provider
+                if (style == NumberStyles.Integer && provider == null)
+                {
+                    Assert.False(uint.TryParse(value.AsSpan(), out result));
+                    Assert.Equal(0u, result);
+                }
+
+                Assert.Throws(exceptionType, () => uint.Parse(value.AsSpan(), style, provider));
+
+                Assert.False(uint.TryParse(value.AsSpan(), style, provider, out result));
+                Assert.Equal(0u, result);
+            }
+        }
+
+        [Theory]
+        [MemberData(nameof(ToString_TestData))]
+        public static void TryFormat(uint i, string format, IFormatProvider provider, string expected)
+        {
+            char[] actual;
+            int charsWritten;
+
+            // Just right
+            actual = new char[expected.Length];
+            Assert.True(i.TryFormat(actual.AsSpan(), out charsWritten, format, provider));
+            Assert.Equal(expected.Length, charsWritten);
+            Assert.Equal(expected, new string(actual));
+
+            // Longer than needed
+            actual = new char[expected.Length + 1];
+            Assert.True(i.TryFormat(actual.AsSpan(), out charsWritten, format, provider));
+            Assert.Equal(expected.Length, charsWritten);
+            Assert.Equal(expected, new string(actual, 0, charsWritten));
+
+            // Too short
+            if (expected.Length > 0)
+            {
+                actual = new char[expected.Length - 1];
+                Assert.False(i.TryFormat(actual.AsSpan(), out charsWritten, format, provider));
+                Assert.Equal(0, charsWritten);
+            }
+
+            if (format != null)
+            {
+                // Upper format
+                actual = new char[expected.Length];
+                Assert.True(i.TryFormat(actual.AsSpan(), out charsWritten, format.ToUpperInvariant(), provider));
+                Assert.Equal(expected.Length, charsWritten);
+                Assert.Equal(expected.ToUpperInvariant(), new string(actual));
+
+                // Lower format
+                actual = new char[expected.Length];
+                Assert.True(i.TryFormat(actual.AsSpan(), out charsWritten, format.ToLowerInvariant(), provider));
+                Assert.Equal(expected.Length, charsWritten);
+                Assert.Equal(expected.ToLowerInvariant(), new string(actual));
+            }
+        }
     }
 }
diff --git a/src/libraries/System.Runtime/tests/System/UInt32Tests.netcoreapp.cs b/src/libraries/System.Runtime/tests/System/UInt32Tests.netcoreapp.cs
deleted file mode 100644 (file)
index 1225062..0000000
+++ /dev/null
@@ -1,113 +0,0 @@
-// 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.Globalization;
-using Xunit;
-
-namespace System.Tests
-{
-    public partial class UInt32Tests
-    {
-        public static IEnumerable<object[]> Parse_ValidWithOffsetCount_TestData()
-        {
-            foreach (object[] inputs in Parse_Valid_TestData())
-            {
-                yield return new object[] { inputs[0], 0, ((string)inputs[0]).Length, inputs[1], inputs[2], inputs[3] };
-            }
-
-            yield return new object[] { "123", 0, 2, NumberStyles.Integer, null, (uint)12 };
-            yield return new object[] { "123", 1, 2, NumberStyles.Integer, null, (uint)23 };
-            yield return new object[] { "4294967295", 0, 1, NumberStyles.Integer, null, 4 };
-            yield return new object[] { "4294967295", 9, 1, NumberStyles.Integer, null, 5 };
-            yield return new object[] { "12", 0, 1, NumberStyles.HexNumber, null, (uint)0x1 };
-            yield return new object[] { "12", 1, 1, NumberStyles.HexNumber, null, (uint)0x2 };
-            yield return new object[] { "$1,000", 1, 3, NumberStyles.Currency, new NumberFormatInfo() { CurrencySymbol = "$" }, (uint)10 };
-        }
-
-        [Theory]
-        [MemberData(nameof(Parse_ValidWithOffsetCount_TestData))]
-        public static void Parse_Span_Valid(string value, int offset, int count, NumberStyles style, IFormatProvider provider, uint expected)
-        {
-            uint result;
-
-            // Default style and provider
-            if (style == NumberStyles.Integer && provider == null)
-            {
-                Assert.True(uint.TryParse(value.AsSpan(offset, count), out result));
-                Assert.Equal(expected, result);
-            }
-
-            Assert.Equal(expected, uint.Parse(value.AsSpan(offset, count), style, provider));
-
-            Assert.True(uint.TryParse(value.AsSpan(offset, count), style, provider, out result));
-            Assert.Equal(expected, result);
-        }
-
-        [Theory]
-        [MemberData(nameof(Parse_Invalid_TestData))]
-        public static void Parse_Span_Invalid(string value, NumberStyles style, IFormatProvider provider, Type exceptionType)
-        {
-            if (value != null)
-            {
-                uint result;
-
-                // Default style and provider
-                if (style == NumberStyles.Integer && provider == null)
-                {
-                    Assert.False(uint.TryParse(value.AsSpan(), out result));
-                    Assert.Equal(0u, result);
-                }
-
-                Assert.Throws(exceptionType, () => uint.Parse(value.AsSpan(), style, provider));
-
-                Assert.False(uint.TryParse(value.AsSpan(), style, provider, out result));
-                Assert.Equal(0u, result);
-            }
-        }
-
-        [Theory]
-        [MemberData(nameof(ToString_TestData))]
-        public static void TryFormat(uint i, string format, IFormatProvider provider, string expected)
-        {
-            char[] actual;
-            int charsWritten;
-
-            // Just right
-            actual = new char[expected.Length];
-            Assert.True(i.TryFormat(actual.AsSpan(), out charsWritten, format, provider));
-            Assert.Equal(expected.Length, charsWritten);
-            Assert.Equal(expected, new string(actual));
-
-            // Longer than needed
-            actual = new char[expected.Length + 1];
-            Assert.True(i.TryFormat(actual.AsSpan(), out charsWritten, format, provider));
-            Assert.Equal(expected.Length, charsWritten);
-            Assert.Equal(expected, new string(actual, 0, charsWritten));
-
-            // Too short
-            if (expected.Length > 0)
-            {
-                actual = new char[expected.Length - 1];
-                Assert.False(i.TryFormat(actual.AsSpan(), out charsWritten, format, provider));
-                Assert.Equal(0, charsWritten);
-            }
-
-            if (format != null)
-            {
-                // Upper format
-                actual = new char[expected.Length];
-                Assert.True(i.TryFormat(actual.AsSpan(), out charsWritten, format.ToUpperInvariant(), provider));
-                Assert.Equal(expected.Length, charsWritten);
-                Assert.Equal(expected.ToUpperInvariant(), new string(actual));
-
-                // Lower format
-                actual = new char[expected.Length];
-                Assert.True(i.TryFormat(actual.AsSpan(), out charsWritten, format.ToLowerInvariant(), provider));
-                Assert.Equal(expected.Length, charsWritten);
-                Assert.Equal(expected.ToLowerInvariant(), new string(actual));
-            }
-        }
-    }
-}
index 5976972..3c8b0c5 100644 (file)
@@ -9,7 +9,7 @@ using Xunit;
 
 namespace System.Tests
 {
-    public partial class UInt64Tests
+    public class UInt64Tests
     {
         [Fact]
         public static void Ctor_Empty()
@@ -319,5 +319,104 @@ namespace System.Tests
             AssertExtensions.Throws<ArgumentException>(paramName, () => ulong.Parse("1", style));
             AssertExtensions.Throws<ArgumentException>(paramName, () => ulong.Parse("1", style, null));
         }
+
+        public static IEnumerable<object[]> Parse_ValidWithOffsetCount_TestData()
+        {
+            foreach (object[] inputs in Parse_Valid_TestData())
+            {
+                yield return new object[] { inputs[0], 0, ((string)inputs[0]).Length, inputs[1], inputs[2], inputs[3] };
+            }
+
+            yield return new object[] { "+123", 1, 3, NumberStyles.Integer, null, (ulong)123 };
+            yield return new object[] { "+123", 0, 3, NumberStyles.Integer, null, (ulong)12 };
+            yield return new object[] { "  123  ", 1, 2, NumberStyles.Integer, null, (ulong)1 };
+            yield return new object[] { "12", 0, 1, NumberStyles.HexNumber, null, (ulong)0x1 };
+            yield return new object[] { "ABC", 1, 1, NumberStyles.HexNumber, null, (ulong)0xb };
+            yield return new object[] { "$1,000", 1, 3, NumberStyles.Currency, new NumberFormatInfo() { CurrencySymbol = "$" }, (ulong)10 };
+        }
+
+        [Theory]
+        [MemberData(nameof(Parse_ValidWithOffsetCount_TestData))]
+        public static void Parse_Span_Valid(string value, int offset, int count, NumberStyles style, IFormatProvider provider, ulong expected)
+        {
+            ulong result;
+
+            // Default style and provider
+            if (style == NumberStyles.Integer && provider == null)
+            {
+                Assert.True(ulong.TryParse(value.AsSpan(offset, count), out result));
+                Assert.Equal(expected, result);
+            }
+
+            Assert.Equal(expected, ulong.Parse(value.AsSpan(offset, count), style, provider));
+
+            Assert.True(ulong.TryParse(value.AsSpan(offset, count), style, provider, out result));
+            Assert.Equal(expected, result);
+        }
+
+        [Theory]
+        [MemberData(nameof(Parse_Invalid_TestData))]
+        public static void Parse_Span_Invalid(string value, NumberStyles style, IFormatProvider provider, Type exceptionType)
+        {
+            if (value != null)
+            {
+                ulong result;
+
+                // Default style and provider
+                if (style == NumberStyles.Integer && provider == null)
+                {
+                    Assert.False(ulong.TryParse(value.AsSpan(), out result));
+                    Assert.Equal(0u, result);
+                }
+
+                Assert.Throws(exceptionType, () => ulong.Parse(value.AsSpan(), style, provider));
+
+                Assert.False(ulong.TryParse(value.AsSpan(), style, provider, out result));
+                Assert.Equal(0u, result);
+            }
+        }
+
+        [Theory]
+        [MemberData(nameof(ToString_TestData))]
+        public static void TryFormat(ulong i, string format, IFormatProvider provider, string expected)
+        {
+            char[] actual;
+            int charsWritten;
+
+            // Just right
+            actual = new char[expected.Length];
+            Assert.True(i.TryFormat(actual.AsSpan(), out charsWritten, format, provider));
+            Assert.Equal(expected.Length, charsWritten);
+            Assert.Equal(expected, new string(actual));
+
+            // Longer than needed
+            actual = new char[expected.Length + 1];
+            Assert.True(i.TryFormat(actual.AsSpan(), out charsWritten, format, provider));
+            Assert.Equal(expected.Length, charsWritten);
+            Assert.Equal(expected, new string(actual, 0, charsWritten));
+
+            // Too short
+            if (expected.Length > 0)
+            {
+                actual = new char[expected.Length - 1];
+                Assert.False(i.TryFormat(actual.AsSpan(), out charsWritten, format, provider));
+                Assert.Equal(0, charsWritten);
+            }
+
+            if (format != null)
+            {
+                // Upper format
+                actual = new char[expected.Length];
+                Assert.True(i.TryFormat(actual.AsSpan(), out charsWritten, format.ToUpperInvariant(), provider));
+                Assert.Equal(expected.Length, charsWritten);
+                Assert.Equal(expected.ToUpperInvariant(), new string(actual));
+
+                // Lower format
+                actual = new char[expected.Length];
+                Assert.True(i.TryFormat(actual.AsSpan(), out charsWritten, format.ToLowerInvariant(), provider));
+                Assert.Equal(expected.Length, charsWritten);
+                Assert.Equal(expected.ToLowerInvariant(), new string(actual));
+            }
+        }
     }
 }
diff --git a/src/libraries/System.Runtime/tests/System/UInt64Tests.netcoreapp.cs b/src/libraries/System.Runtime/tests/System/UInt64Tests.netcoreapp.cs
deleted file mode 100644 (file)
index d10e757..0000000
+++ /dev/null
@@ -1,112 +0,0 @@
-// 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.Globalization;
-using Xunit;
-
-namespace System.Tests
-{
-    public partial class UInt64Tests
-    {
-        public static IEnumerable<object[]> Parse_ValidWithOffsetCount_TestData()
-        {
-            foreach (object[] inputs in Parse_Valid_TestData())
-            {
-                yield return new object[] { inputs[0], 0, ((string)inputs[0]).Length, inputs[1], inputs[2], inputs[3] };
-            }
-
-            yield return new object[] { "+123", 1, 3, NumberStyles.Integer, null, (ulong)123 };
-            yield return new object[] { "+123", 0, 3, NumberStyles.Integer, null, (ulong)12 };
-            yield return new object[] { "  123  ", 1, 2, NumberStyles.Integer, null, (ulong)1 };
-            yield return new object[] { "12", 0, 1, NumberStyles.HexNumber, null, (ulong)0x1 };
-            yield return new object[] { "ABC", 1, 1, NumberStyles.HexNumber, null, (ulong)0xb };
-            yield return new object[] { "$1,000", 1, 3, NumberStyles.Currency, new NumberFormatInfo() { CurrencySymbol = "$" }, (ulong)10 };
-        }
-
-        [Theory]
-        [MemberData(nameof(Parse_ValidWithOffsetCount_TestData))]
-        public static void Parse_Span_Valid(string value, int offset, int count, NumberStyles style, IFormatProvider provider, ulong expected)
-        {
-            ulong result;
-
-            // Default style and provider
-            if (style == NumberStyles.Integer && provider == null)
-            {
-                Assert.True(ulong.TryParse(value.AsSpan(offset, count), out result));
-                Assert.Equal(expected, result);
-            }
-
-            Assert.Equal(expected, ulong.Parse(value.AsSpan(offset, count), style, provider));
-
-            Assert.True(ulong.TryParse(value.AsSpan(offset, count), style, provider, out result));
-            Assert.Equal(expected, result);
-        }
-
-        [Theory]
-        [MemberData(nameof(Parse_Invalid_TestData))]
-        public static void Parse_Span_Invalid(string value, NumberStyles style, IFormatProvider provider, Type exceptionType)
-        {
-            if (value != null)
-            {
-                ulong result;
-
-                // Default style and provider
-                if (style == NumberStyles.Integer && provider == null)
-                {
-                    Assert.False(ulong.TryParse(value.AsSpan(), out result));
-                    Assert.Equal(0u, result);
-                }
-
-                Assert.Throws(exceptionType, () => ulong.Parse(value.AsSpan(), style, provider));
-
-                Assert.False(ulong.TryParse(value.AsSpan(), style, provider, out result));
-                Assert.Equal(0u, result);
-            }
-        }
-
-        [Theory]
-        [MemberData(nameof(ToString_TestData))]
-        public static void TryFormat(ulong i, string format, IFormatProvider provider, string expected)
-        {
-            char[] actual;
-            int charsWritten;
-
-            // Just right
-            actual = new char[expected.Length];
-            Assert.True(i.TryFormat(actual.AsSpan(), out charsWritten, format, provider));
-            Assert.Equal(expected.Length, charsWritten);
-            Assert.Equal(expected, new string(actual));
-
-            // Longer than needed
-            actual = new char[expected.Length + 1];
-            Assert.True(i.TryFormat(actual.AsSpan(), out charsWritten, format, provider));
-            Assert.Equal(expected.Length, charsWritten);
-            Assert.Equal(expected, new string(actual, 0, charsWritten));
-
-            // Too short
-            if (expected.Length > 0)
-            {
-                actual = new char[expected.Length - 1];
-                Assert.False(i.TryFormat(actual.AsSpan(), out charsWritten, format, provider));
-                Assert.Equal(0, charsWritten);
-            }
-
-            if (format != null)
-            {
-                // Upper format
-                actual = new char[expected.Length];
-                Assert.True(i.TryFormat(actual.AsSpan(), out charsWritten, format.ToUpperInvariant(), provider));
-                Assert.Equal(expected.Length, charsWritten);
-                Assert.Equal(expected.ToUpperInvariant(), new string(actual));
-
-                // Lower format
-                actual = new char[expected.Length];
-                Assert.True(i.TryFormat(actual.AsSpan(), out charsWritten, format.ToLowerInvariant(), provider));
-                Assert.Equal(expected.Length, charsWritten);
-                Assert.Equal(expected.ToLowerInvariant(), new string(actual));
-            }
-        }
-    }
-}
index f4c922e..53cd55b 100644 (file)
@@ -8,7 +8,7 @@ using Xunit;
 
 namespace System.Tests
 {
-    public static partial class UIntPtrTests
+    public static class UIntPtrTests
     {
         private static unsafe bool Is64Bit => sizeof(void*) == 8;
 
@@ -113,6 +113,9 @@ namespace System.Tests
                 Assert.Equal(expected, ptr1 == ptr2);
                 Assert.Equal(!expected, ptr1 != ptr2);
                 Assert.Equal(expected, ptr1.GetHashCode().Equals(ptr2.GetHashCode()));
+
+                IEquatable<UIntPtr> iEquatable = ptr1;
+                Assert.Equal(expected, iEquatable.Equals((UIntPtr)obj));
             }
             Assert.Equal(expected, ptr1.Equals(obj));
             Assert.Equal(ptr1.GetHashCode(), ptr1.GetHashCode());
diff --git a/src/libraries/System.Runtime/tests/System/UIntPtrTests.netcoreapp.cs b/src/libraries/System.Runtime/tests/System/UIntPtrTests.netcoreapp.cs
deleted file mode 100644 (file)
index d55a968..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-// 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;
-using System.Collections.Generic;
-using Xunit;
-
-namespace System.Tests
-{
-    public static partial class UIntPtrTests
-    {
-        [Theory]
-        [MemberData(nameof(Equals_TestData))]
-        public static void Equals_NetCoreApp11(UIntPtr ptr, object obj, bool expected)
-        {
-            if (!(obj is UIntPtr))
-            {
-                return;
-            }
-
-            IEquatable<UIntPtr> iEquatable = ptr;
-            Assert.Equal(expected, iEquatable.Equals((UIntPtr)obj));
-        }
-    }
-}
index 423652f..b9f3a4a 100644 (file)
@@ -7,7 +7,7 @@ using Xunit;
 
 namespace System.Tests
 {
-    public partial class VersionTests
+    public class VersionTests
     {
         [Fact]
         public void Ctor_Default()
@@ -322,5 +322,89 @@ namespace System.Tests
             Assert.Equal(version.Build, clone.Build);
             Assert.Equal(version.Revision, clone.Revision);
         }
+
+        public static IEnumerable<object[]> Parse_ValidWithOffsetCount_TestData()
+        {
+            foreach (object[] inputs in Parse_Valid_TestData())
+            {
+                yield return new object[] { inputs[0], 0, ((string)inputs[0]).Length, inputs[1] };
+            }
+
+            yield return new object[] { "1.2.3", 0, 3, new Version(1, 2) };
+            yield return new object[] { "1.2.3", 2, 3, new Version(2, 3) };
+            yield return new object[] { "2  .3.    4.  \t\r\n15  ", 0, 11, new Version(2, 3, 4) };
+            yield return new object[] { "+1.+2.+3.+4", 3, 5, new Version(2, 3) };
+        }
+
+        [Theory]
+        [MemberData(nameof(Parse_ValidWithOffsetCount_TestData))]
+        public static void Parse_Span_ValidInput_ReturnsExpected(string input, int offset, int count, Version expected)
+        {
+            if (input == null)
+            {
+                return;
+            }
+
+            Assert.Equal(expected, Version.Parse(input.AsSpan(offset, count)));
+
+            Assert.True(Version.TryParse(input.AsSpan(offset, count), out Version version));
+            Assert.Equal(expected, version);
+        }
+
+        [Theory]
+        [MemberData(nameof(Parse_Invalid_TestData))]
+        public static void Parse_Span_InvalidInput_ThrowsException(string input, Type exceptionType)
+        {
+            if (input == null)
+            {
+                return;
+            }
+
+            Assert.Throws(exceptionType, () => Version.Parse(input.AsSpan()));
+
+            Assert.False(Version.TryParse(input.AsSpan(), out Version version));
+            Assert.Null(version);
+        }
+
+        [Theory]
+        [MemberData(nameof(ToString_TestData))]
+        public static void TryFormat_Invoke_WritesExpected(Version version, string[] expected)
+        {
+            char[] dest;
+            int charsWritten;
+
+            for (int i = 0; i < expected.Length; i++)
+            {
+                if (i > 0)
+                {
+                    // Too small
+                    dest = new char[expected[i].Length - 1];
+                    Assert.False(version.TryFormat(dest, i, out charsWritten));
+                    Assert.Equal(0, charsWritten);
+                }
+
+                // Just right
+                dest = new char[expected[i].Length];
+                Assert.True(version.TryFormat(dest, i, out charsWritten));
+                Assert.Equal(expected[i].Length, charsWritten);
+                Assert.Equal(expected[i], new string(dest, 0, charsWritten));
+
+                // More than needed
+                dest = new char[expected[i].Length + 10];
+                Assert.True(version.TryFormat(dest, i, out charsWritten));
+                Assert.Equal(expected[i].Length, charsWritten);
+                Assert.Equal(expected[i], new string(dest, 0, charsWritten));
+            }
+
+            int maxFieldCount = expected.Length - 1;
+            dest = new char[expected[maxFieldCount].Length];
+            Assert.True(version.TryFormat(dest, out charsWritten));
+            Assert.Equal(expected[maxFieldCount].Length, charsWritten);
+            Assert.Equal(expected[maxFieldCount], new string(dest, 0, charsWritten));
+
+            dest = new char[0];
+            AssertExtensions.Throws<ArgumentException>("fieldCount", () => version.TryFormat(dest, -1, out charsWritten)); // Index < 0
+            AssertExtensions.Throws<ArgumentException>("fieldCount", () => version.TryFormat(dest, maxFieldCount + 1, out charsWritten)); // Index > version.fieldCount
+        }
     }
 }
diff --git a/src/libraries/System.Runtime/tests/System/VersionTests.netcoreapp.cs b/src/libraries/System.Runtime/tests/System/VersionTests.netcoreapp.cs
deleted file mode 100644 (file)
index f33a046..0000000
+++ /dev/null
@@ -1,96 +0,0 @@
-// 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 Xunit;
-
-namespace System.Tests
-{
-    public partial class VersionTests
-    {
-        public static IEnumerable<object[]> Parse_ValidWithOffsetCount_TestData()
-        {
-            foreach (object[] inputs in Parse_Valid_TestData())
-            {
-                yield return new object[] { inputs[0], 0, ((string)inputs[0]).Length, inputs[1] };
-            }
-
-            yield return new object[] { "1.2.3", 0, 3, new Version(1, 2) };
-            yield return new object[] { "1.2.3", 2, 3, new Version(2, 3) };
-            yield return new object[] { "2  .3.    4.  \t\r\n15  ", 0, 11, new Version(2, 3, 4) };
-            yield return new object[] { "+1.+2.+3.+4", 3, 5, new Version(2, 3) };
-        }
-
-        [Theory]
-        [MemberData(nameof(Parse_ValidWithOffsetCount_TestData))]
-        public static void Parse_Span_ValidInput_ReturnsExpected(string input, int offset, int count, Version expected)
-        {
-            if (input == null)
-            {
-                return;
-            }
-
-            Assert.Equal(expected, Version.Parse(input.AsSpan(offset, count)));
-
-            Assert.True(Version.TryParse(input.AsSpan(offset, count), out Version version));
-            Assert.Equal(expected, version);
-        }
-
-        [Theory]
-        [MemberData(nameof(Parse_Invalid_TestData))]
-        public static void Parse_Span_InvalidInput_ThrowsException(string input, Type exceptionType)
-        {
-            if (input == null)
-            {
-                return;
-            }
-
-            Assert.Throws(exceptionType, () => Version.Parse(input.AsSpan()));
-
-            Assert.False(Version.TryParse(input.AsSpan(), out Version version));
-            Assert.Null(version);
-        }
-
-        [Theory]
-        [MemberData(nameof(ToString_TestData))]
-        public static void TryFormat_Invoke_WritesExpected(Version version, string[] expected)
-        {
-            char[] dest;
-            int charsWritten;
-
-            for (int i = 0; i < expected.Length; i++)
-            {
-                if (i > 0)
-                {
-                    // Too small
-                    dest = new char[expected[i].Length - 1];
-                    Assert.False(version.TryFormat(dest, i, out charsWritten));
-                    Assert.Equal(0, charsWritten);
-                }
-
-                // Just right
-                dest = new char[expected[i].Length];
-                Assert.True(version.TryFormat(dest, i, out charsWritten));
-                Assert.Equal(expected[i].Length, charsWritten);
-                Assert.Equal(expected[i], new string(dest, 0, charsWritten));
-
-                // More than needed
-                dest = new char[expected[i].Length + 10];
-                Assert.True(version.TryFormat(dest, i, out charsWritten));
-                Assert.Equal(expected[i].Length, charsWritten);
-                Assert.Equal(expected[i], new string(dest, 0, charsWritten));
-            }
-
-            int maxFieldCount = expected.Length - 1;
-            dest = new char[expected[maxFieldCount].Length];
-            Assert.True(version.TryFormat(dest, out charsWritten));
-            Assert.Equal(expected[maxFieldCount].Length, charsWritten);
-            Assert.Equal(expected[maxFieldCount], new string(dest, 0, charsWritten));
-
-            dest = new char[0];
-            AssertExtensions.Throws<ArgumentException>("fieldCount", () => version.TryFormat(dest, -1, out charsWritten)); // Index < 0
-            AssertExtensions.Throws<ArgumentException>("fieldCount", () => version.TryFormat(dest, maxFieldCount + 1, out charsWritten)); // Index > version.fieldCount
-        }
-    }
-}