WuhuIslandTesting/Library/PackageCache/com.unity.addressables@1.21.12/Tests/Editor/Build/BuildLayoutGenerationTaskTests.cs
2025-01-07 02:06:59 +01:00

719 lines
27 KiB
C#

using NUnit.Framework;
using System;
using System.IO;
using System.Linq;
using System.Text;
using UnityEditor;
using UnityEditor.AddressableAssets.Build.BuildPipelineTasks;
using UnityEditor.AddressableAssets.Build.DataBuilders;
using UnityEditor.AddressableAssets.Build.Layout;
using UnityEditor.AddressableAssets.Settings;
using UnityEditor.AddressableAssets.Settings.GroupSchemas;
using UnityEditor.AddressableAssets.Tests;
using UnityEditor.Build.Pipeline.Utilities;
using UnityEditor.SceneManagement;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.U2D;
using UnityEditor.U2D;
using UnityEditor.Presets;
public class BuildLayoutGenerationTaskTests
{
AddressableAssetSettings m_Settings;
AddressableAssetSettings Settings
{
get
{
if (m_Settings == null)
{
var path = Path.Combine(TempPath, "Settings", "/AddressableAssetSettings.Tests.asset");
m_Settings = AssetDatabase.LoadAssetAtPath<AddressableAssetSettings>(path);
}
return m_Settings;
}
}
static string kTempPath = "Assets/BuildLayoutGenerationTaskTestsData";
static string TempPath;
static int ExecCount;
bool m_PrevGenerateBuildLayout;
ProjectConfigData.ReportFileFormat m_PrevFileFormat;
[OneTimeSetUp]
public void OneTimeSetup()
{
ExecCount = 0;
}
[SetUp]
public void Setup()
{
TempPath = kTempPath + (ExecCount++).ToString();
foreach (var fileFormat in Enum.GetValues(typeof(ProjectConfigData.ReportFileFormat)))
{
string layoutFile = BuildLayoutGenerationTask.GetLayoutFilePathForFormat((ProjectConfigData.ReportFileFormat)fileFormat);
if (File.Exists(layoutFile))
File.Delete(layoutFile);
}
m_PrevGenerateBuildLayout = ProjectConfigData.GenerateBuildLayout;
m_PrevFileFormat = ProjectConfigData.BuildLayoutReportFileFormat;
BuildScriptPackedMode.s_SkipCompilePlayerScripts = true;
ProjectConfigData.GenerateBuildLayout = true;
if (Directory.Exists(TempPath))
Directory.Delete(TempPath, true);
Directory.CreateDirectory(TempPath);
m_Settings = AddressableAssetSettings.Create(Path.Combine(TempPath, "Settings"), "AddressableAssetSettings.Tests", false, true);
}
[TearDown]
public void Teardown()
{
BuildScriptPackedMode.s_SkipCompilePlayerScripts = false;
ProjectConfigData.GenerateBuildLayout = m_PrevGenerateBuildLayout;
ProjectConfigData.BuildLayoutReportFileFormat = m_PrevFileFormat;
// Many of the tests keep recreating assets in the same path, so we need to unload them completely so they don't get reused by the next test
AssetDatabase.DeleteAsset(AssetDatabase.GetAssetPath(Settings));
Resources.UnloadAsset(Settings);
FileUtil.DeleteFileOrDirectory(TempPath);
FileUtil.DeleteFileOrDirectory(TempPath + ".meta");
AssetDatabase.Refresh();
}
string MakeAddressable(AddressableAssetGroup group, string guid, string address = null)
{
var entry = Settings.CreateOrMoveEntry(guid, group, false, false);
entry.address = address == null ? Path.GetFileNameWithoutExtension(entry.AssetPath) : address;
entry.BundleFileId = "GenericFileId";
return guid;
}
// Prefab asset emthods
static string CreatePrefabAsset(string name)
{
return CreatePrefabAsset($"{TempPath}/{name}.prefab", name);
}
static string CreatePrefabAsset(string assetPath, string objectName)
{
GameObject go = GameObject.CreatePrimitive(PrimitiveType.Cube);
go.name = objectName;
//this is to ensure that bundles are different for every run.
go.transform.localPosition = UnityEngine.Random.onUnitSphere;
PrefabUtility.SaveAsPrefabAsset(go, assetPath);
UnityEngine.Object.DestroyImmediate(go, false);
return AssetDatabase.AssetPathToGUID(assetPath);
}
static string CreateScriptableObjectAsset(string assetPath, string objectName)
{
TestObject.Create(objectName, assetPath);
return AssetDatabase.AssetPathToGUID(assetPath);
}
string CreateAddressablePrefab(string name, AddressableAssetGroup group)
{
string guid = CreatePrefabAsset($"{TempPath}/{name}.prefab", name);
return MakeAddressable(group, guid);
}
string CreateAddressableScriptableObject(string name, AddressableAssetGroup group)
{
string guid = CreateScriptableObjectAsset($"{TempPath}/{name}.asset", name);
return MakeAddressable(group, guid);
}
bool DeletePrefab(string name)
{
string path = $"{TempPath}/{name}.prefab";
return AssetDatabase.DeleteAsset(path);
}
bool DeleteScriptableObject(string name)
{
string path = $"{TempPath}/{name}.asset";
return AssetDatabase.DeleteAsset(path);
}
// Texture asset creation
static string CreateTexture(string name, int size = 32)
{
string assetPath = $"{TempPath}/{name}.png";
var texture = new Texture2D(size, size);
var data = ImageConversion.EncodeToPNG(texture);
UnityEngine.Object.DestroyImmediate(texture);
File.WriteAllBytes(assetPath, data);
AssetDatabase.ImportAsset(assetPath, ImportAssetOptions.ForceSynchronousImport | ImportAssetOptions.ForceUpdate);
return AssetDatabase.AssetPathToGUID(assetPath);
}
string CreateAddressableTexture(string name, AddressableAssetGroup group, int size = 32)
{
string guid = CreateTexture(name, size);
TextureImporter ti = (TextureImporter)AssetImporter.GetAtPath(AssetDatabase.GUIDToAssetPath(guid));
ti.isReadable = false;
ti.SaveAndReimport();
return MakeAddressable(group, guid);
}
static string CreateSpriteAtlas(string name, string guidTargetTexture)
{
var sa = new SpriteAtlas();
var targetObjects = new UnityEngine.Object[] {AssetDatabase.LoadAssetAtPath<Texture>(AssetDatabase.GUIDToAssetPath(guidTargetTexture))};
sa.Add(targetObjects);
string saPath = $"{TempPath}/{name}.spriteAtlas";
AssetDatabase.CreateAsset(sa, saPath);
AssetDatabase.Refresh();
return AssetDatabase.AssetPathToGUID(saPath);
}
bool DeleteSpriteAtlas(string name)
{
string assetPath = $"{TempPath}/{name}.spriteAtlas";
return AssetDatabase.DeleteAsset(assetPath);
}
static string CreateSpriteTexture(string name, int size, bool includesSource)
{
string guid = CreateTexture(name, size);
string texturePath = AssetDatabase.GUIDToAssetPath(guid);
TextureImporter importer = (TextureImporter)AssetImporter.GetAtPath(AssetDatabase.GUIDToAssetPath(guid));
importer.textureType = TextureImporterType.Sprite; // creates a sprite subobject
importer.spriteImportMode = SpriteImportMode.Single;
importer.SaveAndReimport();
return guid;
}
bool DeleteTexture(string name)
{
string assetPath = $"{TempPath}/{name}.png";
return AssetDatabase.DeleteAsset(assetPath);
}
/// <summary>
/// Adds a component to Prefab that references assetToReference
/// </summary>
/// <param name="prefabGUID"></param>
/// <param name="assetToReferenceGUID"></param>
void MakePefabReference(string prefabGUID, string assetToReferenceGUID)
{
GameObject prefab = AssetDatabase.LoadAssetAtPath<GameObject>(AssetDatabase.GUIDToAssetPath(prefabGUID));
UnityEngine.Object target = AssetDatabase.LoadAssetAtPath<UnityEngine.Object>(AssetDatabase.GUIDToAssetPath(assetToReferenceGUID));
prefab.AddComponent<TestBehaviourWithReference>().Reference = target;
}
AddressableAssetGroup CreateGroup(string name)
{
return Settings.CreateGroup(name, false, false, false, null, typeof(BundledAssetGroupSchema));
}
void PrintText(BuildLayout layout)
{
MemoryStream stream = new MemoryStream();
BuildLayoutPrinter.WriteBundleLayout(stream, layout);
string report = Encoding.ASCII.GetString(stream.ToArray());
Debug.Log(report);
}
internal BuildLayout BuildAndExtractLayout()
{
try
{
BuildLayout layout = null;
BuildLayoutGenerationTask.s_LayoutCompleteCallback = (x, y) => layout = y;
Settings.BuildPlayerContentImpl();
return layout;
}
finally
{
BuildLayoutGenerationTask.s_LayoutCompleteCallback = null;
}
}
class WebExtractSession : IDisposable
{
public string DataDirectory;
public string[] Files;
public WebExtractSession(string filePath)
{
DataDirectory = filePath + "_data";
if (Directory.Exists(DataDirectory))
throw new Exception("Bundle data directory already exists");
var baseDir = Path.GetDirectoryName(EditorApplication.applicationPath);
var webExtractFiles = Directory.GetFiles(baseDir, "WebExtract*", SearchOption.AllDirectories);
string webExtractPath = webExtractFiles[0];
Assert.IsTrue(File.Exists(filePath), "Param filePath does not point to an existing file.");
var process = new System.Diagnostics.Process
{
StartInfo =
{
FileName = webExtractPath,
Arguments = string.Format(@"""{0}""", filePath),
UseShellExecute = false,
RedirectStandardOutput = true
}
};
process.Start();
var output = process.StandardOutput.ReadToEnd();
process.WaitForExit();
var exitCode = process.ExitCode;
process.Close();
Assert.AreEqual(0, exitCode);
Files = Directory.GetFiles(DataDirectory);
}
public void Dispose()
{
Directory.Delete(DataDirectory, true);
}
}
internal void AssertEditorBundleDetailsMatchPhysicalBundle(string bundlePath, BuildLayout.Bundle bundle)
{
Assert.AreEqual(new FileInfo(bundlePath).Length, bundle.FileSize);
using (var wes = new WebExtractSession(bundlePath))
{
Assert.AreEqual(bundle.Files.Sum(x => x.SubFiles.Count), wes.Files.Length);
foreach (BuildLayout.SubFile sf in bundle.Files.SelectMany(x => x.SubFiles))
{
string filename = Path.Combine(wes.DataDirectory, sf.Name);
Assert.AreEqual(sf.Size, new FileInfo(filename).Length);
}
}
}
[Test]
public void WhenBundleReferencesAnotherBundle_ExternalReferenceExists()
{
string layoutFilePath = BuildLayoutGenerationTask.GetLayoutFilePathForFormat(ProjectConfigData.BuildLayoutReportFileFormat);
AddressableAssetGroup group = null;
AddressableAssetGroup group2 = null;
try
{
// setup
group = CreateGroup("Group1");
string prefabGUID = CreateAddressablePrefab("p1", group);
group2 = CreateGroup("Group2");
string g2p1GUID = CreateAddressablePrefab("g2p1", group2);
MakePefabReference(prefabGUID, g2p1GUID);
AssetDatabase.SaveAssets();
BuildLayout layout = BuildAndExtractLayout();
// Test
CollectionAssert.Contains(layout.Groups[0].Bundles[0].Dependencies, layout.Groups[1].Bundles[0]);
Assert.AreEqual(layout.Groups[0].Bundles[0].Files[0].Assets[0].ExternallyReferencedAssets[0], layout.Groups[1].Bundles[0].Files[0].Assets[0]);
}
finally // cleanup
{
if (group != null)
Settings.RemoveGroup(group);
if (group2 != null)
Settings.RemoveGroup(group2);
if (File.Exists(layoutFilePath))
File.Delete(layoutFilePath);
DeletePrefab("p1");
DeletePrefab("g2p1");
}
}
[Test]
public void WhenAssetImplicitlyPulledIntoBundle_ImplicitEntryAndReferencesCreated()
{
string layoutFilePath = BuildLayoutGenerationTask.GetLayoutFilePathForFormat(ProjectConfigData.BuildLayoutReportFileFormat);
AddressableAssetGroup group = null;
try
{
// setup
group = CreateGroup("Group1");
string prefabGUID = CreateAddressablePrefab("p1", group);
string aGUID = CreatePrefabAsset("p2");
MakePefabReference(prefabGUID, aGUID);
AssetDatabase.SaveAssets();
BuildLayout layout = BuildAndExtractLayout();
// Test
BuildLayout.DataFromOtherAsset oa = layout.Groups[0].Bundles[0].Files[0].OtherAssets.First(x => x.AssetPath.Contains("p2.prefab"));
Assert.AreEqual(aGUID, oa.AssetGuid);
}
finally // cleanup
{
if (group != null)
Settings.RemoveGroup(group);
if (File.Exists(layoutFilePath))
File.Delete(layoutFilePath);
DeletePrefab("p1");
DeletePrefab("p2");
}
}
[Test]
public void WhenBundleContainsMultipleFiles_FilesAndSizesMatchArchiveContent()
{
string layoutFilePath = BuildLayoutGenerationTask.GetLayoutFilePathForFormat(ProjectConfigData.BuildLayoutReportFileFormat);
string scenePath = $"{TempPath}/scene.unity";
AddressableAssetGroup groupScenes = null;
AddressableAssetGroup textureGroup = null;
try
{
// setup
groupScenes = CreateGroup("SceneGroup");
textureGroup = CreateGroup("TextureGroup");
Scene scene1 = EditorSceneManager.NewScene(NewSceneSetup.EmptyScene);
new GameObject().AddComponent<TestBehaviourWithReference>();
EditorSceneManager.SaveScene(scene1, scenePath);
Settings.CreateOrMoveEntry(AssetDatabase.AssetPathToGUID(scenePath), groupScenes);
EditorSceneManager.NewScene(NewSceneSetup.EmptyScene);
CreateAddressableTexture("t1", textureGroup, 256);
AssetDatabase.SaveAssets();
BuildLayout layout = BuildAndExtractLayout();
// Test
BundledAssetGroupSchema schema = Settings.groups.First(x => x.HasSchema<BundledAssetGroupSchema>()).GetSchema<BundledAssetGroupSchema>();
string path = schema.BuildPath.GetValue(Settings);
foreach (BuildLayout.Bundle bundle in layout.Groups.SelectMany(x => x.Bundles))
AssertEditorBundleDetailsMatchPhysicalBundle(Path.Combine(path, bundle.Name), bundle);
}
finally // cleanup
{
if (groupScenes != null)
Settings.RemoveGroup(groupScenes);
if (textureGroup != null)
Settings.RemoveGroup(textureGroup);
if (File.Exists(layoutFilePath))
File.Delete(layoutFilePath);
AssetDatabase.DeleteAsset(scenePath);
DeleteTexture("t1");
}
}
// Even though slim writes is true, the system will enable it if it needs to generate a build layout report
[Test]
public void WhenSlimWriteResultsIsTrue_LayoutStillGenerated()
{
ProjectConfigData.ReportFileFormat fileFormat = ProjectConfigData.ReportFileFormat.TXT;
string layoutFilePath = BuildLayoutGenerationTask.GetLayoutFilePathForFormat(fileFormat);
AddressableAssetGroup group = null;
bool prevSlim = ScriptableBuildPipeline.slimWriteResults;
ProjectConfigData.ReportFileFormat prevFileFormat = ProjectConfigData.BuildLayoutReportFileFormat;
try
{
// setup
ScriptableBuildPipeline.slimWriteResults = true;
ProjectConfigData.BuildLayoutReportFileFormat = fileFormat;
group = CreateGroup("Group1");
CreateAddressablePrefab("p1", group);
AssetDatabase.SaveAssets();
BuildAndExtractLayout();
FileAssert.Exists(layoutFilePath);
}
finally // cleanup
{
ScriptableBuildPipeline.slimWriteResults = prevSlim;
ProjectConfigData.BuildLayoutReportFileFormat = prevFileFormat;
if (group != null)
Settings.RemoveGroup(group);
if (File.Exists(layoutFilePath))
File.Delete(layoutFilePath);
DeletePrefab("p1");
}
}
[Test]
public void WhenBuildLayoutIsDisabled_BuildLayoutIsNotGenerated()
{
ProjectConfigData.ReportFileFormat fileFormat = ProjectConfigData.ReportFileFormat.TXT;
string layoutFilePath = BuildLayoutGenerationTask.GetLayoutFilePathForFormat(fileFormat);
AddressableAssetGroup group = null;
bool prevGenerateBuildLayout = ProjectConfigData.GenerateBuildLayout;
ProjectConfigData.ReportFileFormat prevFileFormat = ProjectConfigData.BuildLayoutReportFileFormat;
try
{
// setup
ProjectConfigData.GenerateBuildLayout = false;
ProjectConfigData.BuildLayoutReportFileFormat = fileFormat;
group = CreateGroup("Group1");
CreateAddressablePrefab("p1", group);
AssetDatabase.SaveAssets();
BuildAndExtractLayout();
// Test
FileAssert.DoesNotExist(layoutFilePath);
}
finally // cleanup
{
ProjectConfigData.GenerateBuildLayout = prevGenerateBuildLayout;
ProjectConfigData.BuildLayoutReportFileFormat = prevFileFormat;
if (group != null)
Settings.RemoveGroup(group);
if (File.Exists(layoutFilePath))
File.Delete(layoutFilePath);
DeletePrefab("p1");
}
}
[Test]
[TestCase(ProjectConfigData.ReportFileFormat.TXT)]
[TestCase(ProjectConfigData.ReportFileFormat.JSON)]
public void WhenBuildLayoutIsEnabled_BuildLayoutIsGenerated(ProjectConfigData.ReportFileFormat format)
{
string layoutFilePath = BuildLayoutGenerationTask.GetLayoutFilePathForFormat(format);
AddressableAssetGroup group = null;
bool prevGenerateBuildLayout = ProjectConfigData.GenerateBuildLayout;
ProjectConfigData.ReportFileFormat prevFileFormat = ProjectConfigData.BuildLayoutReportFileFormat;
try
{
// setup
ProjectConfigData.GenerateBuildLayout = true;
ProjectConfigData.BuildLayoutReportFileFormat = format;
group = CreateGroup("Group1");
CreateAddressablePrefab("p1", group);
AssetDatabase.SaveAssets();
BuildAndExtractLayout();
// Test
FileAssert.Exists(layoutFilePath);
if (format == ProjectConfigData.ReportFileFormat.JSON)
{
string text = File.ReadAllText(layoutFilePath);
var layout = JsonUtility.FromJson<BuildLayout>(text);
Assert.IsNotNull(layout);
}
}
finally // cleanup
{
ProjectConfigData.GenerateBuildLayout = prevGenerateBuildLayout;
ProjectConfigData.BuildLayoutReportFileFormat = prevFileFormat;
if (group != null)
Settings.RemoveGroup(group);
if (File.Exists(layoutFilePath))
File.Delete(layoutFilePath);
DeletePrefab("p1");
}
}
[Test]
public void WhenAssetHasStreamedData_IsReportedCorrectly()
{
string layoutFilePath = BuildLayoutGenerationTask.GetLayoutFilePathForFormat(ProjectConfigData.BuildLayoutReportFileFormat);
AddressableAssetGroup group = null;
try
{
// setup
group = CreateGroup("Group1");
CreateAddressableTexture("t1", group, 256);
AssetDatabase.SaveAssets();
BuildLayout layout = BuildAndExtractLayout();
// Test
Assert.IsTrue(layout.Groups[0].Bundles[0].Files[0].Assets[0].StreamedSize != 0);
BuildLayout.SubFile f = layout.Groups[0].Bundles[0].Files[0].SubFiles.First(x => x.Name.EndsWith(".resS"));
Assert.IsFalse(f.IsSerializedFile);
}
finally // cleanup
{
if (group != null)
Settings.RemoveGroup(group);
if (File.Exists(layoutFilePath))
File.Delete(layoutFilePath);
DeleteTexture("t1");
}
}
[Test]
public void WhenAllContentsOfAnAssetAreStripped_ExplicitAssetHasNoObjects()
{
string layoutFilePath = BuildLayoutGenerationTask.GetLayoutFilePathForFormat(ProjectConfigData.BuildLayoutReportFileFormat);
AddressableAssetGroup group = null;
string assetPath = $"{TempPath}/testpreset.preset";
try
{
// setup
Material obj = new Material(Shader.Find("Transparent/Diffuse"));
Preset myPreset = new Preset(obj);
AssetDatabase.CreateAsset(myPreset, assetPath);
GameObject.DestroyImmediate(obj);
AssetDatabase.ImportAsset(assetPath, ImportAssetOptions.ForceSynchronousImport | ImportAssetOptions.ForceUpdate);
string guid = AssetDatabase.AssetPathToGUID(assetPath);
group = CreateGroup("Group1");
MakeAddressable(group, guid);
AssetDatabase.SaveAssets();
BuildLayout layout = BuildAndExtractLayout();
// Test
Assert.AreEqual(0, layout.Groups[0].Bundles[0].Files[0].Assets[0].SerializedSize);
}
finally // cleanup
{
if (group != null)
Settings.RemoveGroup(group);
if (File.Exists(layoutFilePath))
File.Delete(layoutFilePath);
AssetDatabase.DeleteAsset(assetPath);
}
}
class SpritePackerScope : IDisposable
{
SpritePackerMode m_PrevMode;
public SpritePackerScope(SpritePackerMode mode)
{
m_PrevMode = EditorSettings.spritePackerMode;
EditorSettings.spritePackerMode = mode;
}
public void Dispose()
{
EditorSettings.spritePackerMode = m_PrevMode;
}
}
[Test]
public void WhenReferencedObjectIdentifiedWithFilename_ObjectRepresentedInDataFromOtherAssets()
{
using (new SpritePackerScope(SpritePackerMode.BuildTimeOnlyAtlas))
{
string layoutFilePath = BuildLayoutGenerationTask.GetLayoutFilePathForFormat(ProjectConfigData.BuildLayoutReportFileFormat);
AddressableAssetGroup group = null;
try
{
// setup
BuildCache.PurgeCache(false);
group = CreateGroup("Group1");
string textureGUID = CreateSpriteTexture("spritetexture", 256, false);
MakeAddressable(group, CreateSpriteAtlas("atlas", textureGUID));
AssetDatabase.SaveAssets();
BuildLayout layout = BuildAndExtractLayout();
// Test
BuildLayout.DataFromOtherAsset otherAssets = layout.Groups[0].Bundles[0].Files[0].Assets[0].InternalReferencedOtherAssets[0];
Assert.AreEqual(2, layout.Groups[0].Bundles[0].Files[0].Assets[0].InternalReferencedOtherAssets.Count);
CollectionAssert.Contains(otherAssets.ReferencingAssets, layout.Groups[0].Bundles[0].Files[0].Assets[0]);
}
finally // cleanup
{
if (group != null)
Settings.RemoveGroup(group);
if (File.Exists(layoutFilePath))
File.Delete(layoutFilePath);
DeleteSpriteAtlas("atlas");
DeleteTexture("spritetexture");
}
}
}
[Test]
public void WhenBuildRemoteCatalogIsDisabled_BuildLayoutContainsCatalogHash()
{
string layoutFilePath = BuildLayoutGenerationTask.GetLayoutFilePathForFormat(ProjectConfigData.BuildLayoutReportFileFormat);
AddressableAssetGroup group = null;
bool prevBuildRemoteCatalog = Settings.BuildRemoteCatalog;
try
{
// setup
group = CreateGroup("Group1");
CreateAddressablePrefab("p1", group);
AssetDatabase.SaveAssets();
BuildLayout layout = BuildAndExtractLayout();
// Test
Assert.IsFalse(string.IsNullOrEmpty(layout.AddressablesRuntimeSettings.CatalogHash), "Catalog Hash was not correctly written to the Layout");
Assert.AreEqual(32, layout.AddressablesRuntimeSettings.CatalogHash.Length, "Catalog Hash was not correctly written to the Layout, incorrect size for hash");
Assert.AreEqual(32, layout.BuildResultHash.Length, "Build is expected to have a result hash for the build");
}
finally // cleanup
{
Settings.BuildRemoteCatalog = prevBuildRemoteCatalog;
if (group != null)
Settings.RemoveGroup(group);
if (File.Exists(layoutFilePath))
File.Delete(layoutFilePath);
DeletePrefab("p1");
}
}
[Test]
public void WhenBuildContainsMonoScripts_LayoutDoesNotHaveReferencesToMonoScriptAssets()
{
string layoutFilePath = BuildLayoutGenerationTask.GetLayoutFilePathForFormat(ProjectConfigData.BuildLayoutReportFileFormat);
AddressableAssetGroup group = null;
bool prevBuildRemoteCatalog = Settings.BuildRemoteCatalog;
try
{
// setup
group = CreateGroup("Group1");
CreateAddressableScriptableObject("so1", group);
AssetDatabase.SaveAssets();
BuildLayout layout = BuildAndExtractLayout();
// Test
foreach (BuildLayout.ExplicitAsset explicitAsset in BuildLayoutHelpers.EnumerateAssets(layout))
{
foreach (var referencedAsset in explicitAsset.InternalReferencedExplicitAssets)
{
Assert.IsNotNull(referencedAsset, "Referenced Asset was null, this was likely a stripped MonoScript");
Assert.IsTrue(!referencedAsset.AssetPath.EndsWith(".cs") && referencedAsset.AssetPath.EndsWith(".dll"));
}
foreach (var referencedAsset in explicitAsset.ExternallyReferencedAssets)
{
Assert.IsNotNull(referencedAsset, "Referenced Asset was null, this was likely a stripped MonoScript");
Assert.IsTrue(!referencedAsset.AssetPath.EndsWith(".cs") && referencedAsset.AssetPath.EndsWith(".dll"));
}
foreach (var referencedAsset in explicitAsset.InternalReferencedOtherAssets)
{
Assert.IsNotNull(referencedAsset, "Referenced Asset was null, this was likely a stripped MonoScript");
Assert.IsTrue(!referencedAsset.AssetPath.EndsWith(".cs") && referencedAsset.AssetPath.EndsWith(".dll"));
}
}
}
finally // cleanup
{
Settings.BuildRemoteCatalog = prevBuildRemoteCatalog;
if (group != null)
Settings.RemoveGroup(group);
if (File.Exists(layoutFilePath))
File.Delete(layoutFilePath);
DeleteScriptableObject("so1");
}
}
}