// 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 CommunityToolkit.HighPerformance; using CommunityToolkit.HighPerformance.Helpers; using Microsoft.VisualStudio.TestTools.UnitTesting; namespace CommunityToolkit.HighPerformance.UnitTests.Extensions; [TestClass] public class Test_HashCodeExtensions { /// /// Gets the list of counts to test the extension for /// private static ReadOnlySpan TestCounts => new[] { 0, 1, 7, 128, 255, 256, short.MaxValue, 245_000 }; [TestMethod] public void Test_HashCodeOfT_VectorSupportedTypes_TestRepeatCount8() { TestForType(); TestForType(); TestForType(); } [TestMethod] public void Test_HashCodeOfT_VectorSupportedTypes_TestRepeatCount16() { TestForType(); TestForType(); } [TestMethod] public void Test_HashCodeOfT_VectorSupportedTypes_TestRepeatCount32() { TestForType(); TestForType(); TestForType(); } [TestMethod] public void Test_HashCodeOfT_VectorSupportedTypes_TestRepeatCount64() { TestForType(); TestForType(); TestForType(); } [TestMethod] public void Test_HashCodeOfT_VectorUnsupportedTypes_TestRepeat() { TestForType(); } /// /// Performs a test for a specified type. /// /// The type to test. private static void TestForType() where T : unmanaged, IEquatable { foreach (int count in TestCounts) { T[] data = CreateRandomData(count); HashCode hashCode1 = default; hashCode1.Add(data); int hash1 = hashCode1.ToHashCode(); HashCode hashCode2 = default; hashCode2.Add(data); int hash2 = hashCode2.ToHashCode(); int hash3 = HashCode.Combine(data); Assert.AreEqual(hash1, hash2, $"Failed {typeof(T)} test with count {count}: got {hash1} and then {hash2}"); Assert.AreEqual(hash1, hash3, $"Failed {typeof(T)} test with count {count}: got {hash1} and then {hash3}"); } } /// /// Creates a random array filled with random data. /// /// The type of items to put in the array. /// The number of array items to create. /// An array of random elements. private static T[] CreateRandomData(int count) where T : unmanaged { Random? random = new(count); T[] data = new T[count]; foreach (ref byte n in MemoryMarshal.AsBytes(data.AsSpan())) { n = (byte)random.Next(0, byte.MaxValue); } return data; } }