using NUnit.Framework; using System; using System.Collections; using System.Collections.Generic; using System.Linq; using System.Reflection; using UnityEditor.Build.Content; using UnityEditor.Build.Pipeline.Utilities; using UnityEngine; namespace UnityEditor.Build.Pipeline.Tests { class HashingHelpersTests { class AssertExpectedLayout : Attribute { public Type CompareType; public AssertExpectedLayout(Type compareType) { CompareType = compareType; } } [AssertExpectedLayout(typeof(PreloadInfo))] class ExpectedPreloadInfo { public List preloadObjects { get; set; } } [AssertExpectedLayout(typeof(AssetBundleInfo))] class ExpectedAssetBundleInfo { public string bundleName { get; set; } public List bundleAssets { get; set; } } [AssertExpectedLayout(typeof(WriteCommand))] class ExpectedWriteCommand { public string fileName { get; set; } public string internalName { get; set; } public List serializeObjects { get; set; } } [AssertExpectedLayout(typeof(SerializationInfo))] class ExpectedSerializationInfo { public ObjectIdentifier serializationObject { get; set; } public long serializationIndex { get; set; } } [AssertExpectedLayout(typeof(ObjectIdentifier))] class ExpectedObjectIdentifier { public GUID guid { get; } public long localIdentifierInFile { get; } public FileType fileType { get; } public string filePath { get; } } public static IEnumerable CustomHashTypes { get { foreach (Type type in Assembly.GetExecutingAssembly().GetTypes()) foreach (AssertExpectedLayout attr in type.GetCustomAttributes(true)) { yield return new TestCaseData(type, attr.CompareType).SetName($"CompareLayout_{type.Name}_{attr.CompareType.Name}"); } } } // README! If this test fails, update the associated hashing function in HashingHelpers.cs and then // update the expected type above to reflect the new layout. // The purpose of this test is to make sure our custom hashing function is updated if the associate engine type changes. [Test, TestCaseSource(typeof(HashingHelpersTests), "CustomHashTypes")] public static void CompareLayout(Type expected, Type actual) { { PropertyInfo[] eInfo = expected.GetProperties(); PropertyInfo[] aInfo = actual.GetProperties(); Assert.AreEqual(eInfo.Length, aInfo.Length); for (int i = 0; i < eInfo.Length; i++) Assert.AreEqual(eInfo[i].PropertyType, aInfo[i].PropertyType); } { FieldInfo[] eInfo = expected.GetFields(); FieldInfo[] aInfo = actual.GetFields(); Assert.AreEqual(eInfo.Length, aInfo.Length); for (int i = 0; i < eInfo.Length; i++) Assert.AreEqual(eInfo[i].FieldType, aInfo[i].FieldType); } } [Test] public static void PreloadInfo_WhenValueChanges_HashesChange() { ObjectIdentifier obj1 = new ObjectIdentifier(); obj1.SetFilePath("TestPath"); PreloadInfo[] infos = new PreloadInfo[] { new PreloadInfo() { preloadObjects = new List() }, new PreloadInfo() { preloadObjects = new List() { new ObjectIdentifier() } }, new PreloadInfo() { preloadObjects = new List() { obj1 } }, }; HashSet set = new HashSet(infos.Select(x => HashingHelpers.GetHash128(x))); Assert.AreEqual(infos.Length, set.Count); } [Test] public static void SerializationInfo_WhenValueChanges_HashesChange() { ObjectIdentifier obj1 = new ObjectIdentifier(); obj1.SetFilePath("TestPath"); SerializationInfo[] infos = new SerializationInfo[] { new SerializationInfo() { serializationIndex = 0 }, new SerializationInfo() { serializationIndex = 1 }, new SerializationInfo() { serializationIndex = 0, serializationObject = obj1 } }; HashSet set = new HashSet(infos.Select(x => HashingHelpers.GetHash128(x))); Assert.AreEqual(infos.Length, set.Count); } [Test] public static void AssetBundleInfo_WhenValueChanges_HashesChange() { AssetBundleInfo[] infos = new AssetBundleInfo[] { new AssetBundleInfo() { bundleName = "Test" }, new AssetBundleInfo() { bundleName = "Test2" }, new AssetBundleInfo() { bundleAssets = new List() { new AssetLoadInfo() { address = "a1" } } }, new AssetBundleInfo() { bundleAssets = new List() { new AssetLoadInfo() { address = "a2" } } } }; HashSet set = new HashSet(infos.Select(x => HashingHelpers.GetHash128(x))); Assert.AreEqual(infos.Length, set.Count); } [Test] public static void AssetLoadInfo_WhenValueChanges_HashesChange() { AssetLoadInfo[] infos = new AssetLoadInfo[] { new AssetLoadInfo() { address = "Test" }, new AssetLoadInfo() { asset = GUID.Generate()}, new AssetLoadInfo() { includedObjects = new List(){ new ObjectIdentifier()} }, new AssetLoadInfo() { referencedObjects = new List() { new ObjectIdentifier() } } }; HashSet set = new HashSet(infos.Select(x => HashingHelpers.GetHash128(x))); Assert.AreEqual(infos.Length, set.Count); } [Test] public static void WriteCommand_WhenValueChanges_HashesChange() { WriteCommand[] infos = new WriteCommand[] { new WriteCommand() { fileName = "Test" }, new WriteCommand() { internalName = "Test2" }, new WriteCommand() { serializeObjects = new List() { new SerializationInfo() }}, new WriteCommand() { serializeObjects = new List() { new SerializationInfo() { serializationIndex = 2 } }} }; HashSet set = new HashSet(infos.Select(x => HashingHelpers.GetHash128(x))); Assert.AreEqual(infos.Length, set.Count); } } }