first commit

This commit is contained in:
lethanhsonvsp
2025-11-17 15:16:36 +07:00
commit a40d0921eb
17012 changed files with 2652386 additions and 0 deletions

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 936bea4b2545c4a4fad2e623b0f6371f
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 3ddaad49a7bcb4087b403f2225d54840
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,197 @@
using UnityEngine;
using UnityEditor;
using NUnit.Framework;
using UnityEngine.TextCore.LowLevel;
namespace TMPro
{
[Category("Text Parsing & Layout")]
class FontEngineTests
{
[OneTimeSetUp]
public void Setup()
{
// Check if "TextMesh Pro" folder is present in project
string folderPath = AssetDatabase.GUIDToAssetPath("f54d1bd14bd3ca042bd867b519fee8cc");
if (string.IsNullOrEmpty(folderPath))
{
// Import TMP Essential Resources and TMP Examples & Extras
TMP_PackageResourceImporter.ImportResources(true, true, false);
}
}
[TestCase("e3265ab4bf004d28a9537516768c1c75", "Liberation Sans", "Regular")]
[TestCase("4beb055f07aaff244873dec698d0363e", "Roboto", "Bold")]
[TestCase("997a43b767814dd0a7642ec9b78cba41", "Anton", "Regular")]
public void CreateFontAsset_from_FilePath(string fontFileGUID, string familyName, string styleName)
{
string filePath = AssetDatabase.GUIDToAssetPath(fontFileGUID);
TMP_FontAsset fontAsset = TMP_FontAsset.CreateFontAsset(filePath, 0, 90, 9, GlyphRenderMode.SDFAA, 512, 512);
Assert.NotNull(fontAsset);
Assert.AreEqual(fontAsset.faceInfo.familyName, familyName);
Assert.AreEqual(fontAsset.faceInfo.styleName, styleName);
}
[TestCase("e3265ab4bf004d28a9537516768c1c75", "Liberation Sans", "Regular")]
[TestCase("4beb055f07aaff244873dec698d0363e", "Roboto", "Bold")]
[TestCase("997a43b767814dd0a7642ec9b78cba41", "Anton", "Regular")]
public void CreateFontAsset_from_FontObject(string fontFileGUID, string familyName, string styleName)
{
string filePath = AssetDatabase.GUIDToAssetPath(fontFileGUID);
Font font = AssetDatabase.LoadAssetAtPath<Font>(filePath);
TMP_FontAsset fontAsset = TMP_FontAsset.CreateFontAsset(font, 90, 9, GlyphRenderMode.SDFAA, 512, 512);
Assert.NotNull(fontAsset);
Assert.AreEqual(fontAsset.faceInfo.familyName, familyName);
Assert.AreEqual(fontAsset.faceInfo.styleName, styleName);
}
[TestCase("e3265ab4bf004d28a9537516768c1c75", "Liberation Sans", "Regular")]
public void TryAddCharacters_SanityCheck(string fontFileGUID, string familyName, string styleName)
{
string filePath = AssetDatabase.GUIDToAssetPath(fontFileGUID);
TMP_FontAsset fontAsset = TMP_FontAsset.CreateFontAsset(filePath, 0, 90, 9, GlyphRenderMode.SDFAA, 512, 512);
Assert.NotNull(fontAsset);
fontAsset.TryAddCharacters("abc");
Assert.IsTrue(fontAsset.HasCharacters("abc"));
}
// =============================================
// FONT ENGINE - OPENTYPE TESTS
// =============================================
#if TEXTCORE_FONT_ENGINE_1_5_OR_NEWER
[TestCase("e3265ab4bf004d28a9537516768c1c75", 1)]
[TestCase("4beb055f07aaff244873dec698d0363e", 623)]
[TestCase("24007ea0bd4d6b2418f4caf1b06e2cb4", 43)]
public void GetSingleSubstitutionRecords(string fontFileGUID, int recordCount)
{
string filePath = AssetDatabase.GUIDToAssetPath(fontFileGUID);
if (FontEngine.LoadFontFace(filePath) != FontEngineError.Success)
return;
UnityEngine.TextCore.LowLevel.SingleSubstitutionRecord[] records = FontEngine.GetAllSingleSubstitutionRecords();
if (records == null)
return;
Assert.AreEqual(recordCount, records.Length);
}
[TestCase("47a9b34e6f77bbd4d94f512d266bcd0c", 77)] // Inter - Regular
public void GetAlternateSubstitutionRecords(string fontFileGUID, int recordCount)
{
string filePath = AssetDatabase.GUIDToAssetPath(fontFileGUID);
if (FontEngine.LoadFontFace(filePath) != FontEngineError.Success)
return;
UnityEngine.TextCore.LowLevel.AlternateSubstitutionRecord[] records = FontEngine.GetAllAlternateSubstitutionRecords();
if (records == null)
return;
Assert.AreEqual(recordCount, records.Length);
}
[TestCase("e3265ab4bf004d28a9537516768c1c75", 184)]
[TestCase("4beb055f07aaff244873dec698d0363e", 177)]
[TestCase("c9f6d0e7bc8541498c9a4799ba184ede", 5)]
public void GetLigatures(string fontFileGUID, int recordCount)
{
string filePath = AssetDatabase.GUIDToAssetPath(fontFileGUID);
if (FontEngine.LoadFontFace(filePath) != FontEngineError.Success)
return;
UnityEngine.TextCore.LowLevel.LigatureSubstitutionRecord[] records = FontEngine.GetAllLigatureSubstitutionRecords();
if (records == null)
return;
Assert.AreEqual(recordCount, records.Length);
}
[TestCase("e3265ab4bf004d28a9537516768c1c75", 2016)]
[TestCase("4beb055f07aaff244873dec698d0363e", 70027)]
[TestCase("c9f6d0e7bc8541498c9a4799ba184ede", 1940)]
public void GetPairAdjustmentRecords(string fontFileGUID, int recordCount)
{
string filePath = AssetDatabase.GUIDToAssetPath(fontFileGUID);
if (FontEngine.LoadFontFace(filePath) != FontEngineError.Success)
return;
GlyphPairAdjustmentRecord[] records = FontEngine.GetAllPairAdjustmentRecords();
if (records == null)
return;
Assert.AreEqual(recordCount, records.Length);
}
[TestCase("e3265ab4bf004d28a9537516768c1c75", 8911)]
[TestCase("4beb055f07aaff244873dec698d0363e", 0)]
[TestCase("24007ea0bd4d6b2418f4caf1b06e2cb4", 432)]
public void GetMarkToBaseAdjustmentRecords(string fontFileGUID, int recordCount)
{
string filePath = AssetDatabase.GUIDToAssetPath(fontFileGUID);
if (FontEngine.LoadFontFace(filePath) != FontEngineError.Success)
return;
UnityEngine.TextCore.LowLevel.MarkToBaseAdjustmentRecord[] records = FontEngine.GetAllMarkToBaseAdjustmentRecords();
if (records == null)
return;
Assert.AreEqual(recordCount, records.Length);
}
[TestCase("e3265ab4bf004d28a9537516768c1c75", 0)]
[TestCase("4beb055f07aaff244873dec698d0363e", 0)]
[TestCase("24007ea0bd4d6b2418f4caf1b06e2cb4", 324)]
public void GetMarkToMarkAdjustmentRecords(string fontFileGUID, int recordCount)
{
string filePath = AssetDatabase.GUIDToAssetPath(fontFileGUID);
if (FontEngine.LoadFontFace(filePath) != FontEngineError.Success)
return;
UnityEngine.TextCore.LowLevel.MarkToMarkAdjustmentRecord[] records = FontEngine.GetAllMarkToMarkAdjustmentRecords();
if (records == null)
return;
Assert.AreEqual(recordCount, records.Length);
}
// GetOpenTypeFontFeatureList throws NotImplementedException with new FontEngine changes to support FontFeature (TEXTCORE_FONT_ENGINE_1_5_OR_NEWER)
/*
[TestCase("e3265ab4bf004d28a9537516768c1c75", 0)]
[TestCase("4beb055f07aaff244873dec698d0363e", 0)]
[TestCase("24007ea0bd4d6b2418f4caf1b06e2cb4", 324)]
[TestCase("47a9b34e6f77bbd4d94f512d266bcd0c", 324)]
[TestCase("d01f31227e1b4cd49bc293f44aab2253", 324)]
public void GetFontFeatureList(string fontFileGUID, int recordCount)
{
string filePath = AssetDatabase.GUIDToAssetPath(fontFileGUID);
if (FontEngine.LoadFontFace(filePath) != FontEngineError.Success)
return;
OpenTypeFeature[] fontFeatureList = FontEngine.GetOpenTypeFontFeatureList();
if (fontFeatureList == null)
return;
Assert.AreEqual(recordCount, fontFeatureList.Length);
} */
#endif
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: ec4b2559effa72e42a09339d71efef3d
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,37 @@
using NUnit.Framework;
using UnityEditor;
using UnityEditor.SceneManagement;
using UnityEngine.SceneManagement;
namespace TMPro
{
public class TMP_ControlTests
{
Scene scene;
[SetUp]
public void Setup()
{
// Create a new scene and open it
scene = EditorSceneManager.NewScene(NewSceneSetup.EmptyScene);
}
[TestCase("GameObject/UI/Dropdown - TextMeshPro")]
[TestCase("GameObject/UI/Button - TextMeshPro")]
[TestCase("GameObject/UI/Input Field - TextMeshPro")]
[TestCase("GameObject/UI/Text - TextMeshPro")]
public void TMPControlCreationAndUndoTest(string menuItem)
{
Assert.AreEqual(0, scene.rootCount);
EditorApplication.ExecuteMenuItem(menuItem);
// After creating a TMP control, objects in the scene should be Canvas, EventSystem, and the TMP control
Assert.AreEqual(2, scene.rootCount);
Undo.PerformUndo();
// After undoing, the scene should be back to its original state
Assert.AreEqual(0, scene.rootCount);
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 5c221dffa89042038c946376c731c918
timeCreated: 1705430351

View File

@@ -0,0 +1,407 @@
using UnityEngine;
using UnityEditor;
using NUnit.Framework;
using System.IO;
namespace TMPro
{
[Category("Text Parsing & Layout")]
class TMP_EditorTests
{
private TextMeshPro m_TextComponent;
// Characters: 22 Spaces: 4 Words: 5 Lines:
private const string m_TextBlock_00 = "A simple line of text.";
// Characters: 104 Spaces: 14 Words: 15 Lines:
private const string m_TextBlock_01 = "Unity 2017 introduces new features that help teams of artists and developers build experiences together.";
// Characters: 1500 Spaces: 228 Words: 241
private const string m_TextBlock_02 = "The European languages are members of the same family. Their separate existence is a myth. For science, music, sport, etc, Europe uses the same vocabulary. The languages only differ in their grammar, their pronunciation and their most common words." +
"Everyone realizes why a new common language would be desirable: one could refuse to pay expensive translators.To achieve this, it would be necessary to have uniform grammar, pronunciation and more common words.If several languages coalesce, the grammar of the resulting language is more simple and regular than that of the individual languages." +
"The new common language will be more simple and regular than the existing European languages.It will be as simple as Occidental; in fact, it will be Occidental.To an English person, it will seem like simplified English, as a skeptical Cambridge friend of mine told me what Occidental is. The European languages are members of the same family." +
"Their separate existence is a myth. For science, music, sport, etc, Europe uses the same vocabulary.The languages only differ in their grammar, their pronunciation and their most common words.Everyone realizes why a new common language would be desirable: one could refuse to pay expensive translators.To achieve this, it would be necessary to" +
"have uniform grammar, pronunciation and more common words.If several languages coalesce, the grammar of the resulting language is more simple and regular than that of the individual languages.The new common language will be";
// Characters: 2500 Spaces: 343 Words: 370
private const string m_TextBlock_03 = "Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec quam felis, ultricies nec, pellentesque eu, pretium quis, sem. Nulla consequat massa quis enim. Donec pede justo, fringilla vel, aliquet nec, vulputate eget, arcu. In enim justo, rhoncus ut, imperdiet a, venenatis vitae, justo. " +
"Nullam dictum felis eu pede mollis pretium.Integer tincidunt.Cras dapibus.Vivamus elementum semper nisi. Aenean vulputate eleifend tellus. Aenean leo ligula, porttitor eu, consequat vitae, eleifend ac, enim.Aliquam lorem ante, dapibus in, viverra quis, feugiat a, tellus.Phasellus viverra nulla ut metus varius laoreet.Quisque rutrum. Aenean imperdiet. Etiam ultricies nisi vel augue.Curabitur ullamcorper ultricies nisi. " +
"Nam eget dui.Etiam rhoncus. Maecenas tempus, tellus eget condimentum rhoncus, sem quam semper libero, sit amet adipiscing sem neque sed ipsum.Nam quam nunc, blandit vel, luctus pulvinar, hendrerit id, lorem.Maecenas nec odio et ante tincidunt tempus.Donec vitae sapien ut libero venenatis faucibus.Nullam quis ante.Etiam sit amet orci eget eros faucibus tincidunt. Duis leo. Sed fringilla mauris sit amet nibh. " +
"Donec sodales sagittis magna. Sed consequat, leo eget bibendum sodales, augue velit cursus nunc, quis gravida magna mi a libero. Fusce vulputate eleifend sapien. Vestibulum purus quam, scelerisque ut, mollis sed, nonummy id, metus.Nullam accumsan lorem in dui.Cras ultricies mi eu turpis hendrerit fringilla.Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; In ac dui quis mi consectetuer lacinia. Nam pretium turpis et arcu. " +
"Duis arcu tortor, suscipit eget, imperdiet nec, imperdiet iaculis, ipsum. Sed aliquam ultrices mauris.Integer ante arcu, accumsan a, consectetuer eget, posuere ut, mauris.Praesent adipiscing. Phasellus ullamcorper ipsum rutrum nunc.Nunc nonummy metus.Vestibulum volutpat pretium libero. Cras id dui.Aenean ut eros et nisl sagittis vestibulum.Nullam nulla eros, ultricies sit amet, nonummy id, imperdiet feugiat, pede.Sed lectus. Donec mollis hendrerit risus. Phasellus nec sem in justo pellentesque facilisis. " +
"Etiam imperdiet imperdiet orci. Nunc nec neque.Phasellus leo dolor, tempus non, auctor et, hendrerit quis, nisi.Curabitur ligula sapien, tincidunt non, euismod vitae, posuere imperdiet, leo.Maecenas malesuada. Praesent nan. The end of this of this long block of text.";
// Characters: 3423 Spaces: 453 Words: 500
private const string m_TextBlock_04 = "Lorem ipsum dolor sit amet, consectetuer adipiscing elit.Aenean commodo ligula eget dolor.Aenean massa.Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus.Donec quam felis, ultricies nec, pellentesque eu, pretium quis, sem.Nulla consequat massa quis enim.Donec pede justo, fringilla vel, aliquet nec, vulputate eget, arcu.In enim justo, rhoncus ut, imperdiet a, venenatis vitae, justo.Nullam dictum felis eu pede mollis pretium.Integer tincidunt. Cras dapibus. Vivamus elementum semper nisi. Aenean vulputate eleifend tellus." +
"Aenean leo ligula, porttitor eu, consequat vitae, eleifend ac, enim.Aliquam lorem ante, dapibus in, viverra quis, feugiat a, tellus.Phasellus viverra nulla ut metus varius laoreet.Quisque rutrum. Aenean imperdiet. Etiam ultricies nisi vel augue.Curabitur ullamcorper ultricies nisi. Nam eget dui.Etiam rhoncus. Maecenas tempus, tellus eget condimentum rhoncus, sem quam semper libero, sit amet adipiscing sem neque sed ipsum.Nam quam nunc, blandit vel, luctus pulvinar, hendrerit id, lorem.Maecenas nec odio et ante tincidunt tempus.Donec vitae sapien ut libero venenatis faucibus.Nullam quis ante." +
"Etiam sit amet orci eget eros faucibus tincidunt. Duis leo. Sed fringilla mauris sit amet nibh. Donec sodales sagittis magna. Sed consequat, leo eget bibendum sodales, augue velit cursus nunc, quis gravida magna mi a libero. Fusce vulputate eleifend sapien. Vestibulum purus quam, scelerisque ut, mollis sed, nonummy id, metus.Nullam accumsan lorem in dui.Cras ultricies mi eu turpis hendrerit fringilla.Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; In ac dui quis mi consectetuer lacinia.Nam pretium turpis et arcu." +
"Duis arcu tortor, suscipit eget, imperdiet nec, imperdiet iaculis, ipsum. Sed aliquam ultrices mauris.Integer ante arcu, accumsan a, consectetuer eget, posuere ut, mauris.Praesent adipiscing. Phasellus ullamcorper ipsum rutrum nunc.Nunc nonummy metus.Vestibulum volutpat pretium libero. Cras id dui.Aenean ut eros et nisl sagittis vestibulum.Nullam nulla eros, ultricies sit amet, nonummy id, imperdiet feugiat, pede.Sed lectus. Donec mollis hendrerit risus. Phasellus nec sem in justo pellentesque facilisis.Etiam imperdiet imperdiet orci. Nunc nec neque." +
"Phasellus leo dolor, tempus non, auctor et, hendrerit quis, nisi.Curabitur ligula sapien, tincidunt non, euismod vitae, posuere imperdiet, leo.Maecenas malesuada. Praesent congue erat at massa.Sed cursus turpis vitae tortor.Donec posuere vulputate arcu. Phasellus accumsan cursus velit. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Sed aliquam, nisi quis porttitor congue, elit erat euismod orci, ac placerat dolor lectus quis orci.Phasellus consectetuer vestibulum elit.Aenean tellus metus, bibendum sed, posuere ac, mattis non, nunc.Vestibulum fringilla pede sit amet augue." +
"In turpis. Pellentesque posuere. Praesent turpis. Aenean posuere, tortor sed cursus feugiat, nunc augue blandit nunc, eu sollicitudin urna dolor sagittis lacus. Donec elit libero, sodales nec, volutpat a, suscipit non, turpis.Nullam sagittis. Suspendisse pulvinar, augue ac venenatis condimentum, sem libero volutpat nibh, nec pellentesque velit pede quis nunc. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Fusce id purus.Ut varius tincidunt libero.Phasellus dolor.Maecenas vestibulum mollis";
//
private const string m_TextBlock_05 = "This block of text contains <b>bold</b> and <i>italicized</i> characters.";
private const string m_TextBlock_06 = "<align=center><style=H1><#ffffff><u>Multiple<#80f0ff> Alignment</color> per text object</u></color></style></align><line-height=2em>\n" +
"</line-height> The <<#ffffa0>align</color>> tag in TextMesh<#40a0ff>Pro</color> provides the ability to control the alignment of lines and paragraphs which is essential when working with text.\n" +
"<align=left> You may want some block of text to be<#80f0ff>left aligned</color> <<#ffffa0>align=<#80f0ff>left</color></color>> which is sort of the standard.</align>\n" +
"<style=Quote><#ffffa0>\"Using <#80f0ff>Center Alignment</color> <<#ffffa0>align=<#80f0ff>center</color></color>> for a title or displaying a quote is another good example of text alignment.\"</color></style>\n" +
"<align=right><#80f0ff>Right Alignment</color> <<#ffffa0>align=<#80f0ff>right</color></color>> can be useful to create contrast between lines and paragraphs of text.\n" +
"<align=justified><#80f0ff>Justified Alignment</color> <<#ffffa0>align=<#80f0ff>justified</color></color>> results in text that is flush on both the left and right margins. Used well, justified type can look clean and classy.\n" +
"<style=Quote><align=left><#ffffa0>\"Text formatting and alignment has a huge impact on how people will read and perceive your text.\"</color>\n" +
"<size=65%><align=right> -Stephan Bouchard</style>";
private readonly string[] testStrings = new string[] { m_TextBlock_00, m_TextBlock_01, m_TextBlock_02, m_TextBlock_03, m_TextBlock_04, m_TextBlock_05, m_TextBlock_06 };
[OneTimeSetUp]
public void Setup()
{
if (Directory.Exists(Path.GetFullPath("Assets/TextMesh Pro")) || Directory.Exists(Path.GetFullPath("Packages/com.unity.textmeshpro.tests/TextMesh Pro")))
{
GameObject textObject = new GameObject("Text Object");
m_TextComponent = textObject.AddComponent<TextMeshPro>();
m_TextComponent.fontSize = 18;
}
else
{
Debug.Log("Skipping over Editor tests as TMP Essential Resources are missing from the current test project.");
Assert.Ignore();
}
}
[Test]
[TestCase("/Package Resources/TMP Essential Resources.unitypackage", "ce4ff17ca867d2b48b5c8a4181611901")]
[TestCase("/Package Resources/TMP Examples & Extras.unitypackage", "bc00e25696e4132499f56528d3fed2e3")]
[TestCase("/PackageConversionData.json", "05f5bfd584002f948982a1498890f9a9")]
public void InternalResourceCheck(string filePath, string guid)
{
string packageRelativePath = EditorUtilities.TMP_EditorUtility.packageRelativePath;
string packageFullPath = EditorUtilities.TMP_EditorUtility.packageFullPath;
Assert.AreEqual(AssetDatabase.AssetPathToGUID(packageRelativePath + filePath), guid);
Assert.IsTrue(File.Exists(packageFullPath + filePath));
}
// =============================================
// Font Asset Creation Tests
// =============================================
// =============================================
// Text Parsing and Layout Tests
// =============================================
[Test]
[TestCase(4, 3423, 453, 500, 1)]
[TestCase(3, 2500, 343, 370, 1)]
[TestCase(2, 1500, 228, 241, 1)]
[TestCase(1, 104, 14, 15, 1)]
[TestCase(0, 22, 4, 5, 1)]
public void TextParsing_TextInfoTest_WordWrappingDisabled(int sourceTextIndex, int characterCount, int spaceCount, int wordCount, int lineCount)
{
m_TextComponent.text = testStrings[sourceTextIndex];
m_TextComponent.textWrappingMode = TextWrappingModes.NoWrap;
m_TextComponent.alignment = TextAlignmentOptions.TopLeft;
// Size the RectTransform
m_TextComponent.rectTransform.sizeDelta = new Vector2(50, 5);
// Force text generation to populate the TextInfo data structure.
m_TextComponent.ForceMeshUpdate();
Assert.AreEqual(m_TextComponent.textInfo.characterCount, characterCount);
Assert.AreEqual(m_TextComponent.textInfo.spaceCount, spaceCount);
Assert.AreEqual(m_TextComponent.textInfo.wordCount, wordCount);
Assert.AreEqual(m_TextComponent.textInfo.lineCount, lineCount);
}
[Test]
[TestCase(4, 3423, 453, 500, 29)]
[TestCase(3, 2500, 343, 370, 21)]
[TestCase(2, 1500, 228, 241, 13)]
[TestCase(1, 104, 14, 15, 1)]
[TestCase(0, 22, 4, 5, 1)]
public void TextParsing_TextInfoTest_WordWrappingEnabled(int sourceTextIndex, int characterCount, int spaceCount, int wordCount, int lineCount)
{
m_TextComponent.text = testStrings[sourceTextIndex];
m_TextComponent.textWrappingMode = TextWrappingModes.Normal;
m_TextComponent.alignment = TextAlignmentOptions.TopLeft;
// Size the RectTransform
m_TextComponent.rectTransform.sizeDelta = new Vector2(100, 50);
// Force text generation to populate the TextInfo data structure.
m_TextComponent.ForceMeshUpdate();
Assert.AreEqual(m_TextComponent.textInfo.characterCount, characterCount);
Assert.AreEqual(m_TextComponent.textInfo.spaceCount, spaceCount);
Assert.AreEqual(m_TextComponent.textInfo.wordCount, wordCount);
Assert.AreEqual(m_TextComponent.textInfo.lineCount, lineCount);
}
[Test]
[TestCase(4, 3423, 453, 500, 27)]
[TestCase(3, 2500, 343, 370, 20)]
[TestCase(2, 1500, 228, 241, 13)]
public void TextParsing_TextInfoTest_TopJustifiedAlignment(int sourceTextIndex, int characterCount, int spaceCount, int wordCount, int lineCount)
{
m_TextComponent.text = testStrings[sourceTextIndex];
m_TextComponent.textWrappingMode = TextWrappingModes.Normal;
m_TextComponent.alignment = TextAlignmentOptions.TopJustified;
// Size the RectTransform
m_TextComponent.rectTransform.sizeDelta = new Vector2(100, 50);
// Force text generation to populate the TextInfo data structure.
m_TextComponent.ForceMeshUpdate();
Assert.AreEqual(m_TextComponent.textInfo.characterCount, characterCount);
Assert.AreEqual(m_TextComponent.textInfo.spaceCount, spaceCount);
Assert.AreEqual(m_TextComponent.textInfo.wordCount, wordCount);
Assert.AreEqual(m_TextComponent.textInfo.lineCount, lineCount);
}
[Test]
[TestCase(6, 768, 124, 126, 14)]
[TestCase(5, 59, 8, 9, 1)]
public void TextParsing_TextInfoTest_RichText(int sourceTextIndex, int characterCount, int spaceCount, int wordCount, int lineCount)
{
m_TextComponent.text = testStrings[sourceTextIndex];
m_TextComponent.textWrappingMode = TextWrappingModes.Normal;
m_TextComponent.alignment = TextAlignmentOptions.TopLeft;
// Size the RectTransform
m_TextComponent.rectTransform.sizeDelta = new Vector2(70, 35);
// Force text generation to populate the TextInfo data structure.
m_TextComponent.ForceMeshUpdate();
Assert.AreEqual(m_TextComponent.textInfo.characterCount, characterCount);
Assert.AreEqual(m_TextComponent.textInfo.spaceCount, spaceCount);
Assert.AreEqual(m_TextComponent.textInfo.wordCount, wordCount);
Assert.AreEqual(m_TextComponent.textInfo.lineCount, lineCount);
}
// =============================================
// Markup tag specific tests
// =============================================
[Test]
[TestCase("<scale=1.0>ABC</scale>", -35.0f, -33.8069763f, -33.8069763f, -32.6139526f, -32.6139526f, -31.3162785f)]
[TestCase("<scale=0.8>ABC</scale>", -35.0f, -34.0455818f, -34.0455818f, -33.0911636f, -33.0911636f, -32.0530243f)]
[TestCase("<scale=1.2>ABC</scale>", -35.0f, -33.5683708f, -33.5683708f, -32.1367455f, -32.1367455f, -30.5795345f)]
public void MarkupTag_Scale(string sourceText, float origin1, float advance1, float origin2, float advance2, float origin3, float advance3)
{
m_TextComponent.text = sourceText;
m_TextComponent.textWrappingMode = TextWrappingModes.Normal;
m_TextComponent.alignment = TextAlignmentOptions.TopLeft;
// Size the RectTransform
m_TextComponent.rectTransform.sizeDelta = new Vector2(70, 35);
// Force text generation to populate the TextInfo data structure.
m_TextComponent.ForceMeshUpdate();
Assert.AreEqual(origin1, m_TextComponent.textInfo.characterInfo[0].origin);
Assert.AreEqual(advance1, m_TextComponent.textInfo.characterInfo[0].xAdvance);
Assert.AreEqual(origin2, m_TextComponent.textInfo.characterInfo[1].origin);
Assert.AreEqual(advance2, m_TextComponent.textInfo.characterInfo[1].xAdvance);
Assert.AreEqual(origin3, m_TextComponent.textInfo.characterInfo[2].origin);
Assert.AreEqual(advance3, m_TextComponent.textInfo.characterInfo[2].xAdvance);
}
[Test]
[TestCase("<size=12>ABC</size>", -35.0f, -34.2046509f, -34.2046509f, -33.4093018f, -33.4093018f, -32.5441856f)]
[TestCase("<size=-6>ABC</size>", -35.0f, -34.2046509f, -34.2046509f, -33.4093018f, -33.4093018f, -32.5441856f)]
[TestCase("<size=+6>ABC</size>", -35.0f, -33.4093018f, -33.4093018f, -31.8186054f, -31.8186054f, -30.0883713f)]
[TestCase("<size=50%>ABC</size>", -35.0f, -34.4034882f, -34.4034882f, -33.8069763f, -33.8069763f, -33.1581383f)]
[TestCase("<size=150%>DEF</size>", -35.0f, -33.0534897f, -33.0534897f, -31.2639542f, -31.2639542f, -29.6000004f)]
[TestCase("<size=0.5em>ABC</size>", -35.0f, -34.4034882f, -34.4034882f, -33.8069763f, -33.8069763f, -33.1581383f)]
[TestCase("<size=1.5em>DEF</size>", -35.0f, -33.0534897f, -33.0534897f, -31.2639542f, -31.2639542f, -29.6000004f)]
public void MarkupTag_Size(string sourceText, float origin1, float advance1, float origin2, float advance2, float origin3, float advance3)
{
m_TextComponent.text = sourceText;
m_TextComponent.textWrappingMode = TextWrappingModes.Normal;
m_TextComponent.alignment = TextAlignmentOptions.TopLeft;
// Size the RectTransform
m_TextComponent.rectTransform.sizeDelta = new Vector2(70, 35);
// Force text generation to populate the TextInfo data structure.
m_TextComponent.ForceMeshUpdate();
Assert.AreEqual(origin1, m_TextComponent.textInfo.characterInfo[0].origin);
Assert.AreEqual(advance1, m_TextComponent.textInfo.characterInfo[0].xAdvance);
Assert.AreEqual(origin2, m_TextComponent.textInfo.characterInfo[1].origin);
Assert.AreEqual(advance2, m_TextComponent.textInfo.characterInfo[1].xAdvance);
Assert.AreEqual(origin3, m_TextComponent.textInfo.characterInfo[2].origin);
Assert.AreEqual(advance3, m_TextComponent.textInfo.characterInfo[2].xAdvance);
}
[Test]
[TestCase("<cspace=30>ABC</cspace>", -35.0f, -30.8069763f, -30.8069763f, -26.6139526f, -26.6139526f, -25.3162804f)]
[TestCase("<cspace=2em>ABC</cspace>", -35.0f, -30.2069759f, -30.2069759f, -25.4139519f, -25.4139519f, -24.1162796f)]
public void MarkupTag_Cspace(string sourceText, float origin1, float advance1, float origin2, float advance2, float origin3, float advance3)
{
m_TextComponent.text = sourceText;
m_TextComponent.textWrappingMode = TextWrappingModes.Normal;
m_TextComponent.alignment = TextAlignmentOptions.TopLeft;
// Size the RectTransform
m_TextComponent.rectTransform.sizeDelta = new Vector2(70, 35);
// Force text generation to populate the TextInfo data structure.
m_TextComponent.ForceMeshUpdate();
Assert.AreEqual(origin1, m_TextComponent.textInfo.characterInfo[0].origin);
Assert.AreEqual(advance1, m_TextComponent.textInfo.characterInfo[0].xAdvance);
Assert.AreEqual(origin2, m_TextComponent.textInfo.characterInfo[1].origin);
Assert.AreEqual(advance2, m_TextComponent.textInfo.characterInfo[1].xAdvance);
Assert.AreEqual(origin3, m_TextComponent.textInfo.characterInfo[2].origin);
Assert.AreEqual(advance3, m_TextComponent.textInfo.characterInfo[2].xAdvance);
}
[Test]
[TestCase("<mspace=30>ABC</mspace>", -34.0965118f, -32.0f, -31.1279068f, -29.0f, -28.1593018f, -26.0f)]
[TestCase("<mspace=2em>ABC</mspace>", -33.7965126f, -31.3999996f, -30.2279072f, -27.7999992f, -26.6593018f, -24.2000008f)]
public void MarkupTag_Mspace(string sourceText, float origin1, float advance1, float origin2, float advance2, float origin3, float advance3)
{
m_TextComponent.text = sourceText;
m_TextComponent.textWrappingMode = TextWrappingModes.Normal;
m_TextComponent.alignment = TextAlignmentOptions.TopLeft;
// Size the RectTransform
m_TextComponent.rectTransform.sizeDelta = new Vector2(70, 35);
// Force text generation to populate the TextInfo data structure.
m_TextComponent.ForceMeshUpdate();
Assert.AreEqual(origin1, m_TextComponent.textInfo.characterInfo[0].origin);
Assert.AreEqual(advance1, m_TextComponent.textInfo.characterInfo[0].xAdvance);
Assert.AreEqual(origin2, m_TextComponent.textInfo.characterInfo[1].origin);
Assert.AreEqual(advance2, m_TextComponent.textInfo.characterInfo[1].xAdvance);
Assert.AreEqual(origin3, m_TextComponent.textInfo.characterInfo[2].origin);
Assert.AreEqual(advance3, m_TextComponent.textInfo.characterInfo[2].xAdvance);
}
[Test]
[TestCase("A<space=18>B<space=18>C", -35.0f, -33.8069763f, -32.0069771f, -30.8139534f, -29.0139542f, -27.7162781f)]
[TestCase("A<space=1em>B<space=1em>C", -35.0f, -33.8069763f, -32.0069771f, -30.8139534f, -29.0139542f, -27.7162781f)]
public void MarkupTag_Space(string sourceText, float origin1, float advance1, float origin2, float advance2, float origin3, float advance3)
{
m_TextComponent.text = sourceText;
m_TextComponent.textWrappingMode = TextWrappingModes.Normal;
m_TextComponent.alignment = TextAlignmentOptions.TopLeft;
// Size the RectTransform
m_TextComponent.rectTransform.sizeDelta = new Vector2(70, 35);
// Force text generation to populate the TextInfo data structure.
m_TextComponent.ForceMeshUpdate();
Assert.AreEqual(origin1, m_TextComponent.textInfo.characterInfo[0].origin);
Assert.AreEqual(advance1, m_TextComponent.textInfo.characterInfo[0].xAdvance);
Assert.AreEqual(origin2, m_TextComponent.textInfo.characterInfo[1].origin);
Assert.AreEqual(advance2, m_TextComponent.textInfo.characterInfo[1].xAdvance);
Assert.AreEqual(origin3, m_TextComponent.textInfo.characterInfo[2].origin);
Assert.AreEqual(advance3, m_TextComponent.textInfo.characterInfo[2].xAdvance);
}
[Test]
[TestCase("A<pos=10%>B<pos=20%>C", -35.0f, -33.8069763f, -28.0f, -26.8069763f, -21.0f, -19.7023258f)]
[TestCase("A<pos=70>B<pos=140>C", -35.0f, -33.8069763f, -28.0f, -26.8069763f, -21.0f, -19.7023258f)]
[TestCase("A<pos=1.5em>B<pos=3em>CC", -35.0f, -33.8069763f, -32.2999992f, -31.1069775f, -29.6000004f, -28.3023262f)]
public void MarkupTag_Pos(string sourceText, float origin1, float advance1, float origin2, float advance2, float origin3, float advance3)
{
m_TextComponent.text = sourceText;
m_TextComponent.textWrappingMode = TextWrappingModes.Normal;
m_TextComponent.alignment = TextAlignmentOptions.TopLeft;
// Size the RectTransform
m_TextComponent.rectTransform.sizeDelta = new Vector2(70, 35);
// Force text generation to populate the TextInfo data structure.
m_TextComponent.ForceMeshUpdate();
Assert.AreEqual(origin1, m_TextComponent.textInfo.characterInfo[0].origin);
Assert.AreEqual(advance1, m_TextComponent.textInfo.characterInfo[0].xAdvance);
Assert.AreEqual(origin2, m_TextComponent.textInfo.characterInfo[1].origin);
Assert.AreEqual(advance2, m_TextComponent.textInfo.characterInfo[1].xAdvance);
Assert.AreEqual(origin3, m_TextComponent.textInfo.characterInfo[2].origin);
Assert.AreEqual(advance3, m_TextComponent.textInfo.characterInfo[2].xAdvance);
}
[Test]
[TestCase("<indent=18>ABC", -33.2000008f, -32.0069771f, -32.0069771f, -30.8139534f, -30.8139534f, -29.5162792f)]
[TestCase("<indent=1em>ABC", -33.2000008f, -32.0069771f, -32.0069771f, -30.8139534f, -30.8139534f, -29.5162792f)]
[TestCase("<indent=2.5%>ABC", -33.25f, -32.0569763f, -32.0569763f, -30.8639526f, -30.8639526f, -29.5662804f)]
public void MarkupTag_Indent(string sourceText, float origin1, float advance1, float origin2, float advance2, float origin3, float advance3)
{
m_TextComponent.text = sourceText;
m_TextComponent.textWrappingMode = TextWrappingModes.Normal;
m_TextComponent.alignment = TextAlignmentOptions.TopLeft;
// Size the RectTransform
m_TextComponent.rectTransform.sizeDelta = new Vector2(70, 35);
// Force text generation to populate the TextInfo data structure.
m_TextComponent.ForceMeshUpdate();
Assert.AreEqual(origin1, m_TextComponent.textInfo.characterInfo[0].origin);
Assert.AreEqual(advance1, m_TextComponent.textInfo.characterInfo[0].xAdvance);
Assert.AreEqual(origin2, m_TextComponent.textInfo.characterInfo[1].origin);
Assert.AreEqual(advance2, m_TextComponent.textInfo.characterInfo[1].xAdvance);
Assert.AreEqual(origin3, m_TextComponent.textInfo.characterInfo[2].origin);
Assert.AreEqual(advance3, m_TextComponent.textInfo.characterInfo[2].xAdvance);
}
#if TMP_TEST_RESOURCES
const string k_SpriteAssetPath = "Assets/TextMesh Pro/Resources/Sprite Assets/MixedIndexTest.asset";
[Test]
public void SpriteAssetIndexAreValidAfterReordering()
{
var spriteAsset = AssetDatabase.LoadAssetAtPath<TMP_SpriteAsset>(k_SpriteAssetPath);
if (spriteAsset == null)
{
Debug.LogError("Failed to load Sprite Asset at path: " + k_SpriteAssetPath);
return;
}
string text = $"<sprite name=\"cta_obsidianjade\">";
m_TextComponent.spriteAsset = spriteAsset;
m_TextComponent.text = text;
m_TextComponent.ForceMeshUpdate();
Assert.AreEqual(203, m_TextComponent.textInfo.characterInfo[0].textElement.glyphIndex, $"Mismatch between sprite index. Expected 203 but was {m_TextComponent.textInfo.characterInfo[0].textElement.glyphIndex}");
}
#endif
// Add tests that check position of individual characters in a complex block of text.
// These test also use the data contained inside the TMP_TextInfo class.
//[OneTimeTearDown]
//public void Cleanup()
//{
// // Remove TMP Essential Resources if they were imported in the project as a result of running tests.
// if (TMPro_EventManager.temporaryResourcesImported == true)
// {
// if (Directory.Exists(Path.GetFullPath("Assets/TextMesh Pro")))
// {
// AssetDatabase.DeleteAsset("Assets/TextMesh Pro");
// TMPro_EventManager.temporaryResourcesImported = false;
// }
// }
//}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 592f7288ed0df2c4b884e2cd9baac023
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,17 @@
{
"name": "Unity.TextMeshPro.Editor.Tests",
"references": [
"Unity.TextMeshPro",
"Unity.TextMeshPro.Editor"
],
"optionalUnityReferences": [
"TestAssemblies"
],
"defineConstraints": [
"UNITY_INCLUDE_TESTS"
],
"includePlatforms": [
"Editor"
],
"excludePlatforms": []
}

View File

@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 656e461844099ae43a609ff6109b0877
AssemblyDefinitionImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: fae3ac1997e164d1eba5fa5c417cbefd
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: b86b117346968ac4d9cc63e4385becb7
folderAsset: yes
timeCreated: 1459501450
licenseType: Pro
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,40 @@
using NUnit.Framework;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.TestTools;
using UnityEditor.SceneManagement;
using UnityEditor;
public class AssertionFailureOnOutputVertexCount
{
const string scenePath = "Assets/AssertionFailureOnOutputVertexCountTestScene.unity";
[Test]
public void AssertionFailureOnOutputVertexCountTest()
{
var newScene = EditorSceneManager.NewScene(UnityEditor.SceneManagement.NewSceneSetup.DefaultGameObjects, UnityEditor.SceneManagement.NewSceneMode.Single);
var canvasMaster = new GameObject("Canvas", typeof(Canvas), typeof(CanvasScaler), typeof(GraphicRaycaster));
var canvasChild = new GameObject("Canvas Child", typeof(Canvas), typeof(CanvasScaler), typeof(GraphicRaycaster));
canvasChild.transform.SetParent(canvasMaster.transform);
var panel1 = new GameObject("Panel", typeof(CanvasRenderer), typeof(UnityEngine.UI.Image));
panel1.transform.SetParent(canvasMaster.transform);
var panel2 = new GameObject("Panel", typeof(CanvasRenderer), typeof(UnityEngine.UI.Image));
panel2.transform.SetParent(canvasChild.transform);
// Saving a scene would trigger the error case 893551
EditorSceneManager.SaveScene(newScene, scenePath);
Debug.Log("Success");
LogAssert.Expect(LogType.Log, "Success");
}
[TearDown]
public void TearDown()
{
#if UNITY_EDITOR
AssetDatabase.DeleteAsset(scenePath);
#endif
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: bede4033d9f359b41878c4cda6a910b3
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,56 @@
using NUnit.Framework;
using System.Collections;
using UnityEngine;
using UnityEngine.TestTools;
using UnityEngine.UI;
public class CanvasElementsMaintainValidPositionsWhenCameraOrthoSizeIsZero
{
GameObject image;
GameObject canvas;
GameObject camera;
[SetUp]
public void TestSetup()
{
canvas = new GameObject("Canvas", typeof(Canvas));
image = new GameObject("Image", typeof(Image));
image.transform.SetParent(canvas.transform);
camera = new GameObject("Camera", typeof(Camera));
var cameraComponent = camera.GetComponent<Camera>();
cameraComponent.orthographic = true;
var canvasComponent = canvas.GetComponent<Canvas>();
canvasComponent.worldCamera = camera.GetComponent<Camera>();
canvasComponent.renderMode = RenderMode.ScreenSpaceCamera;
}
[TearDown]
public void TearDown()
{
GameObject.DestroyImmediate(canvas);
GameObject.DestroyImmediate(camera);
}
[UnityTest]
public IEnumerator TestCanvasElementsMaintainValidPositionsWhenCameraOrthoSizeIsZero()
{
var cameraComponent = camera.GetComponent<Camera>();
cameraComponent.orthographicSize = 0;
yield return null;
Assert.AreNotEqual(image.transform.position.x, float.NaN);
Assert.AreNotEqual(image.transform.position.y, float.NaN);
cameraComponent.orthographicSize = 2;
yield return null;
Assert.AreEqual(image.transform.position.x, 0.0f);
Assert.AreEqual(image.transform.position.y, 0.0f);
Assert.Pass();
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 35a0d10199de49f4db0128003bfd3bda
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,47 @@
using UnityEngine;
using NUnit.Framework;
using UnityEngine.UI;
[TestFixture]
[Category("RegressionTest")]
[Description("CoveredBugID = 913932")]
public class CanvasWidthAssertionErrorWithRectTransform
{
GameObject m_CanvasMaster;
GameObject m_CanvasChild;
[SetUp]
public void TestSetup()
{
m_CanvasMaster = new GameObject("Canvas", typeof(Canvas), typeof(CanvasScaler), typeof(GraphicRaycaster));
m_CanvasChild = new GameObject("Canvas", typeof(Canvas), typeof(CanvasScaler), typeof(GraphicRaycaster));
}
[Test]
public void CanvasWidthAssertionErrorCheckOnModifyingRectTransform()
{
// Creating canvas and child canvas
m_CanvasChild.transform.SetParent(m_CanvasMaster.transform);
// Getting the rect Transform and modifying it
RectTransform rt = m_CanvasChild.GetComponent<RectTransform>();
rt.anchorMin = new Vector2(0, 0);
rt.anchorMax = new Vector2(1, 1);
rt.offsetMin = new Vector2(rt.offsetMin.x, 1000);
rt.offsetMax = new Vector2(rt.offsetMax.x, 200);
rt.offsetMin = new Vector2(rt.offsetMin.y, 1);
rt.offsetMax = new Vector2(rt.offsetMax.y, 0);
//Assertion failed: Assertion failed on expression: 'width >= 0 should not happen
Assert.Pass();
}
[TearDown]
public void TearDown()
{
GameObject.DestroyImmediate(m_CanvasMaster);
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 4585b5feb801bdb44b0e5eafdd95a3be
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,81 @@
using NUnit.Framework;
using UnityEngine;
using UnityEngine.UI;
[Category("Canvas")]
public class RootCanvasTests : TestBehaviourBase<UnityEngine.Canvas>
{
// A simple nested canvas hierarchy
// m_TestObject
// └ rootCanvasChild
// └ emptyChildGameObject
// └ baseCanvas
private UnityEngine.Canvas rootCanvasChild;
private GameObject emptyChildGameObject;
private UnityEngine.Canvas baseCanvas;
[SetUp]
public override void TestSetup()
{
base.TestSetup();
var rootChildGO = new GameObject("root child");
rootCanvasChild = rootChildGO.AddComponent<Canvas>();
emptyChildGameObject = new GameObject("empty");
var baseGO = new GameObject("base");
baseCanvas = baseGO.AddComponent<Canvas>();
baseCanvas.transform.SetParent(emptyChildGameObject.transform);
emptyChildGameObject.transform.SetParent(rootChildGO.transform);
rootChildGO.transform.SetParent(m_TestObject.transform);
}
[Test]
public void IsRootCanvasTest()
{
Assert.IsFalse(baseCanvas.isRootCanvas);
Assert.IsFalse(rootCanvasChild.isRootCanvas);
Assert.IsTrue(m_TestObject.isRootCanvas);
}
[Test]
public void CorrectRootCanvasReturned()
{
Assert.AreEqual(m_TestObject, m_TestObject.rootCanvas);
Assert.AreEqual(m_TestObject, rootCanvasChild.rootCanvas);
Assert.AreEqual(m_TestObject, baseCanvas.rootCanvas);
}
[Test]
public void NotRootCanvasAnchorsDontGetReset()
{
var rect = rootCanvasChild.GetComponent<RectTransform>();
rect.anchorMin = Vector2.zero;
rect.anchorMax = Vector2.one;
Assert.IsTrue(rect.anchorMin == Vector2.zero);
Assert.IsTrue(rect.anchorMax == Vector2.one);
m_TestObject.gameObject.SetActive(false);
Assert.IsTrue(rect.anchorMin == Vector2.zero);
Assert.IsTrue(rect.anchorMax == Vector2.one);
}
[Test]
public void ChildOfDisabledCanvasCantReceiveClicks()
{
rootCanvasChild.gameObject.AddComponent<Image>();
var raycasts = GraphicRegistry.GetRaycastableGraphicsForCanvas(rootCanvasChild);
Assert.IsTrue(raycasts.Count == 1);
m_TestObject.gameObject.SetActive(false);
raycasts = GraphicRegistry.GetRaycastableGraphicsForCanvas(rootCanvasChild);
Assert.IsTrue(raycasts.Count == 0);
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 798968d841703b54bb9d08b1da6bc52f
timeCreated: 1459501500
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,14 @@
using UnityEngine;
using NUnit.Framework;
namespace Tests
{
public class UISystemProfilerAddMarkerWithNullObjectDoesNotCrash
{
[Test]
public void AddMarkerShouldNotCrashWithNullObject()
{
UISystemProfilerApi.AddMarker("Test", null);
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 0ca81982e37e893498abf804c12a22c7
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: ae242449e9279d44789513b922d3178a
folderAsset: yes
timeCreated: 1493922593
licenseType: Pro
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,41 @@
using UnityEngine;
using UnityEngine.TestTools;
using NUnit.Framework;
using System.Collections;
using UnityEditor.SceneManagement;
public class ChangingHierarchyOfCanvasRenderer
{
[Test]
public void ChangingHierarchyOfCanvasRenderer_DoesntCrash()
{
// Canvas
// - Middle
// - Renderer
// OtherCanvas
var canvasObject = new GameObject("Canvas");
canvasObject.AddComponent<Canvas>();
var otherCanvasObject = new GameObject("OtherCanvas");
otherCanvasObject.AddComponent<Canvas>();
var middleObject = new GameObject("Middle");
middleObject.transform.parent = canvasObject.transform;
var renderObject = new GameObject("Render");
renderObject.AddComponent<CanvasRenderer>();
renderObject.transform.parent = middleObject.transform;
renderObject.SetActive(false);
// Translation causes IgnoreNextTransformChanged to be set on Renderer
canvasObject.transform.Translate(1, 1, 1);
// Reparenting after ignore
middleObject.transform.parent = otherCanvasObject.transform;
// Destroy the original canvas, and create a new scene to force destruction of everything else
GameObject.DestroyImmediate(canvasObject);
EditorSceneManager.NewScene(NewSceneSetup.EmptyScene);
Assert.Pass();
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: c825bad77a42dd341a8f0a5ef9cd5f4c
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,58 @@
using UnityEngine;
using UnityEngine.TestTools;
using NUnit.Framework;
using System.Collections;
using UnityEngine.UI;
public class ParentCanvasIsSane
{
GameObject rootCanvas;
GameObject rootObject;
GameObject child1;
CanvasGroup c1CanvasGroup;
GameObject child2;
GameObject child3;
[SetUp]
public void TestSetup()
{
// root GO
// root Canvas
// L child1 GO (RectTransform, CanvasGroup)
// L child2 GO (RectTransform)
// L child3 GO (Image)
rootCanvas = new GameObject("root Canvas");
rootCanvas.AddComponent<Canvas>();
rootCanvas.AddComponent<CanvasScaler>();
rootObject = new GameObject("root GO");
child1 = new GameObject("child1 GO");
child1.AddComponent<RectTransform>();
c1CanvasGroup = child1.AddComponent<CanvasGroup>();
child2 = new GameObject("child2 GO");
child2.AddComponent<RectTransform>();
child3 = new GameObject("child3 GO");
child3.AddComponent<Image>();
child3.transform.SetParent(child2.transform);
child2.transform.SetParent(child1.transform);
child1.transform.SetParent(rootCanvas.transform);
}
[UnityTest]
public IEnumerator RecalculatingAlphaOnReparentedInactiveObjectsDoesNotCrash()
{
Assert.IsNotNull(child3.GetComponent<CanvasRenderer>());
c1CanvasGroup.alpha = 0.5f;
child1.SetActive(false);
child1.transform.SetParent(rootObject.transform, true);
// This will crash if child3.GetComponent<CanvasRenderer>().m_ParentCanvas is not null.
yield return null;
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: dcb49b07db5e5f64e876b498105314f1
timeCreated: 1493922633
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 1f71aeacc4a9f1a40b22a1a590331f6b
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,34 @@
using System.Collections;
using UnityEngine;
using UnityEngine.TestTools;
using UnityEngine.UI;
using UnityEditor;
using NUnit.Framework;
public class DropdownOptionsListDrawer : WrapperWindowFixture
{
public class Fixture : MonoBehaviour
{
public Dropdown.OptionDataList options = new Dropdown.OptionDataList();
}
[UnityTest]
public IEnumerator PropertyDrawerDoesNotThrowExceptionWhenObjectIsDisposed()
{
var go = new GameObject();
var component = go.AddComponent<Fixture>();
var so = new SerializedObject(component);
var win = GetWindow((wnd) => {
Assert.DoesNotThrow(() => EditorGUILayout.PropertyField(so.FindProperty("options")));
so.Dispose();
so = new SerializedObject(component);
Assert.DoesNotThrow(() => EditorGUILayout.PropertyField(so.FindProperty("options")));
return true;
});
while (win.TestCompleted == false)
{
yield return null;
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: b180d0cec21671c45a32a9ce99bff2f5
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 98d14ab1acf42df4f88a0561822ac807
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,38 @@
using NUnit.Framework;
using UnityEngine;
using UnityEngine.EventSystems;
public class EventTriggerRemoveDuringExecution
{
[Test]
[Description("ArgumentOutOfRange Exception is thrown when removing handler in callback in EventTrigger (case 1401557)")]
public void EventTrigger_DoesNotThrowExceptionWhenRemovingEventDuringExecution()
{
var go = new GameObject();
var eventTrigger = go.AddComponent<EventTrigger>();
var eventSystem = go.AddComponent<EventSystem>();
var entry1 = new EventTrigger.Entry { eventID = EventTriggerType.PointerDown };
var entry2 = new EventTrigger.Entry { eventID = EventTriggerType.PointerDown };
bool executed1 = false;
bool executed2 = false;
entry1.callback.AddListener(e =>
{
executed1 = true;
eventTrigger.triggers.Remove(entry2);
});
entry2.callback.AddListener(e => executed2 = true);
eventTrigger.triggers.Add(entry1);
eventTrigger.triggers.Add(entry2);
Assert.DoesNotThrow(() => eventTrigger.OnPointerDown(new PointerEventData(eventSystem)));
Assert.True(executed1, "Expected Event 1 to be called but it was not.");
Assert.False(executed2, "Expected Event 2 to not be called as it was removed by event 1.");
Assert.That(eventTrigger.triggers, Does.Not.Contains(entry2));
Assert.That(eventTrigger.triggers, Does.Contain(entry1));
Object.DestroyImmediate(go);
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 4adb1f65bbae8004a88d8f5bc3523298
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,47 @@
using NUnit.Framework;
using UnityEngine;
using UnityEditor.EventSystems;
using UnityEngine.EventSystems;
[TestFixture]
public class InputModuleTests
{
private EventSystem m_EventSystem;
[SetUp]
public void Setup()
{
m_EventSystem = new GameObject("EventSystem").AddComponent<EventSystem>();
}
[TearDown]
public void TearDown()
{
Object.DestroyImmediate(m_EventSystem.gameObject);
}
[Test]
public void InputModuleComponentFactory_AddComponent_CanBeOverriden()
{
// First call creates a StandaloneInputModule
var inputModule = InputModuleComponentFactory.AddInputModule(m_EventSystem.gameObject);
Assert.IsInstanceOf<StandaloneInputModule>(inputModule);
Object.DestroyImmediate(inputModule);
// After setting the override to a custom type, further calls use the custom type
InputModuleComponentFactory.SetInputModuleComponentOverride(go => go.AddComponent<TestInputModule>());
inputModule = InputModuleComponentFactory.AddInputModule(m_EventSystem.gameObject);
Assert.IsInstanceOf<TestInputModule>(inputModule);
Object.DestroyImmediate(inputModule);
// After setting the override to null, further calls use the StandaloneInputModule again
InputModuleComponentFactory.SetInputModuleComponentOverride(null);
inputModule = InputModuleComponentFactory.AddInputModule(m_EventSystem.gameObject);
Assert.IsInstanceOf<StandaloneInputModule>(inputModule);
}
public class TestInputModule : BaseInputModule
{
public override void Process() { }
}
}

View File

@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 03fb1af6e1585964a8d5c2437a191324

View File

@@ -0,0 +1,74 @@
using System;
using System.Reflection;
using System.Collections.Generic;
using UnityEngine.EventSystems;
using UnityEditor;
using NUnit.Framework;
public class InterceptedEventsPreviewTests
{
[Test]
public void InterceptedEventsPreviewCacheUsingTypeCacheReturnsSameTypes()
{
var typeCacheEventInterfaces = new List<Type>();
TypeCache.TypeCollection types = TypeCache.GetTypesDerivedFrom<IEventSystemHandler>();
foreach (var type in types)
{
if (!type.IsInterface)
continue;
typeCacheEventInterfaces.Add(type);
}
var appDomainEventInterfaces = new List<Type>();
foreach (var type in GetAccessibleTypesInLoadedAssemblies())
{
if (!type.IsInterface)
continue;
appDomainEventInterfaces.Add(type);
}
Assert.AreNotEqual(typeCacheEventInterfaces.Count, appDomainEventInterfaces.Count, "Did not find the same number of EventInterface types");
for (int i = 0; i < typeCacheEventInterfaces.Count; ++i)
{
Assert.Contains(typeCacheEventInterfaces[i], appDomainEventInterfaces);
}
}
private static IEnumerable<Type> GetAccessibleTypesInLoadedAssemblies()
{
var assemblies = AppDomain.CurrentDomain.GetAssemblies();
for (var i = 0; i < assemblies.Length; ++i)
{
Type[] types;
var assembly = assemblies[i];
if (assembly == null)
continue;
try
{
types = assembly.GetTypes();
}
catch (ReflectionTypeLoadException e)
{
// assembly.GetTypes() might fail in case the Assembly cannot resolve all its references,
// or in case it was built targetting a newer version of .NET.
// In case the resolution fails for some types, we can still access the ones that have been
// properly loaded.
types = e.Types;
}
for (var j = 0; j < types.Length; ++j)
{
var type = types[j];
if (type == null)
continue;
yield return type;
}
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 2aff4fada0516c64a8537a20bfe1b699
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: c16c54fe03afb5740bcc0a2a295cb79d
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,45 @@
using NUnit.Framework;
namespace Core.InputField
{
public class CharacterLimitValidation : TestBehaviourBase<UnityEngine.UI.InputField>
{
[Test]
public void LimitCanNotBeNegative()
{
const int testValue = -1;
m_TestObject.characterLimit = testValue;
Assert.AreNotEqual(testValue, m_TestObject.characterLimit);
}
[Test]
public void TextLengthShorterThanLimit()
{
const string testValue = "Test";
m_TestObject.characterLimit = 10;
m_TestObject.text = testValue;
Assert.AreEqual(testValue, m_TestObject.text);
}
[Test]
public void TextLengthEqualToLimit()
{
const string testValue = "0123456789";
m_TestObject.characterLimit = 10;
m_TestObject.text = testValue;
Assert.AreEqual(testValue, m_TestObject.text);
}
[Test]
public void TextLengthGreaterThanLimit()
{
m_TestObject.characterLimit = 10;
m_TestObject.text = "01234567891234567890";
Assert.AreEqual(10, m_TestObject.text.Length);
Assert.AreEqual("0123456789", m_TestObject.text);
}
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 4b8be68229770db4ea3c78ab0d854325
timeCreated: 1456921340
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,94 @@
using NUnit.Framework;
using ContentType = UnityEngine.UI.InputField.ContentType;
namespace Core.InputField
{
public class ContentValidation : TestBehaviourBase<UnityEngine.UI.InputField>
{
[Test]
[TestCase(ContentType.Alphanumeric, "0", "0")]
[TestCase(ContentType.Alphanumeric, "1", "1")]
[TestCase(ContentType.Alphanumeric, "123456", "123456")]
[TestCase(ContentType.Alphanumeric, "0123456", "0123456")]
[TestCase(ContentType.Alphanumeric, "111110123456", "111110123456")]
[TestCase(ContentType.Alphanumeric, "123456", "123456")]
[TestCase(ContentType.Alphanumeric, "-1.0", "10")]
[TestCase(ContentType.Alphanumeric, "-00.45", "0045")]
[TestCase(ContentType.Alphanumeric, "-1111101.23456", "111110123456")]
[TestCase(ContentType.Alphanumeric, "Test", "Test")]
[TestCase(ContentType.Alphanumeric, "-1-", "1")]
[TestCase(ContentType.Alphanumeric, "--1", "1")]
[TestCase(ContentType.Alphanumeric, "123456abc", "123456abc")]
[TestCase(ContentType.Alphanumeric, "qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM0123456789", "qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM0123456789")]
[TestCase(ContentType.DecimalNumber, "0", "0")]
[TestCase(ContentType.DecimalNumber, "1", "1")]
[TestCase(ContentType.DecimalNumber, "123456", "123456")]
[TestCase(ContentType.DecimalNumber, "0123456", "0123456")]
[TestCase(ContentType.DecimalNumber, "111110123456", "111110123456")]
//[TestCase(ContentType.DecimalNumber, "3.14", "3.14")]
//[TestCase(ContentType.DecimalNumber, "1.23", "1.23")]
//[TestCase(ContentType.DecimalNumber, "1.0", "1.0")]
//[TestCase(ContentType.DecimalNumber, "00.45", "00.45")]
//[TestCase(ContentType.DecimalNumber, "1111101.23456", "1111101.23456")]
//[TestCase(ContentType.DecimalNumber, "-1", "-1")]
[TestCase(ContentType.DecimalNumber, "-123456", "-123456")]
[TestCase(ContentType.DecimalNumber, "-0123456", "-0123456")]
[TestCase(ContentType.DecimalNumber, "-111110123456", "-111110123456")]
//[TestCase(ContentType.DecimalNumber, "-3.14", "-3.14")]
//[TestCase(ContentType.DecimalNumber, "-1.23", "-1.23")]
//[TestCase(ContentType.DecimalNumber, "-1.0", "-1.0")]
//[TestCase(ContentType.DecimalNumber, "-00.45", "-00.45")]
//[TestCase(ContentType.DecimalNumber, "-1111101.23456", "-1111101.23456")]
[TestCase(ContentType.DecimalNumber, "Test", "")]
[TestCase(ContentType.DecimalNumber, "-1-", "-1")]
//[TestCase(ContentType.DecimalNumber, "-0", "0")]
[TestCase(ContentType.DecimalNumber, "--1", "-1")]
[TestCase(ContentType.DecimalNumber, "123456abc", "123456")]
//[TestCase(ContentType.DecimalNumber, "12.34.5#6abc", "12.3456")]
[TestCase(ContentType.EmailAddress, "name@domain.com", "name@domain.com")]
[TestCase(ContentType.EmailAddress, "name@@@domain.com", "name@domain.com")]
[TestCase(ContentType.EmailAddress, "name@domain.co.uk", "name@domain.co.uk")]
[TestCase(ContentType.EmailAddress, "name.other@domain-site.co.uk", "name.other@domain-site.co.uk")]
[TestCase(ContentType.EmailAddress, "name!#$%&'*+-/=?^_`{|}~@domain.com", "name!#$%&'*+-/=?^_`{|}~@domain.com")]
[TestCase(ContentType.IntegerNumber, "0", "0")]
[TestCase(ContentType.IntegerNumber, "1", "1")]
[TestCase(ContentType.IntegerNumber, "123456", "123456")]
[TestCase(ContentType.IntegerNumber, "0123456", "0123456")]
[TestCase(ContentType.IntegerNumber, "111110123456", "111110123456")]
[TestCase(ContentType.IntegerNumber, "-1", "-1")]
[TestCase(ContentType.IntegerNumber, "-123456", "-123456")]
[TestCase(ContentType.IntegerNumber, "-0123456", "-0123456")]
[TestCase(ContentType.IntegerNumber, "-111110123456", "-111110123456")]
[TestCase(ContentType.IntegerNumber, "3.14", "314")]
[TestCase(ContentType.IntegerNumber, "Test", "")]
[TestCase(ContentType.IntegerNumber, "-1-", "-1")]
//[TestCase(ContentType.IntegerNumber, "-0", "0")]
//[TestCase(ContentType.IntegerNumber, "-0", "")]
[TestCase(ContentType.IntegerNumber, "--1", "-1")]
[TestCase(ContentType.IntegerNumber, "123456abc", "123456")]
[TestCase(ContentType.IntegerNumber, "12.34.5#6abc", "123456")]
[TestCase(ContentType.Name, "john smith", "John Smith")]
[TestCase(ContentType.Name, "mary jane", "Mary Jane")]
[TestCase(ContentType.Name, "jOHn smIth", "John Smith")]
[TestCase(ContentType.Name, "john123 smith123", "John Smith")]
[TestCase(ContentType.Name, "Bucky O'Hare", "Bucky O'Hare")]
[TestCase(ContentType.Name, "bucky o'Har'e", "Bucky O'Hare")]
[TestCase(ContentType.Name, "first second third", "First Second Third")]
[TestCase(ContentType.Pin, "012345", "012345")]
[TestCase(ContentType.Pin, "012345abc", "012345")]
[TestCase(ContentType.Pin, "0a1b2c3#45", "012345")]
[TestCase(ContentType.Pin, "-012345", "-012345")]
[TestCase(ContentType.Pin, " 012345", "012345")]
public void ValueIsValidatedCorrectly(ContentType type, string testValue, string expected)
{
m_TestObject.contentType = type;
m_TestObject.text = testValue;
Assert.AreEqual(expected, m_TestObject.text);
}
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 5a2e98b03511c6f43bc645238cd40857
timeCreated: 1457018121
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: 305ca32be1aa5504aa182f583895dfe4
folderAsset: yes
timeCreated: 1458135852
licenseType: Pro
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,42 @@
using NUnit.Framework;
using UnityEngine;
using UnityEngine.UI;
public class RectMask2DCulling : TestBehaviourBase<UnityEngine.Canvas>
{
[Test]
public void CullFlagNotResetWhenReparented740604()
{
var noMaskGameObject = new GameObject("noMaskGO");
noMaskGameObject.AddComponent<RectTransform>();
var maskGameObject = new GameObject("MaskGO");
var rectMask2D = maskGameObject.AddComponent<RectMask2D>();
noMaskGameObject.transform.SetParent(m_TestObject.transform);
maskGameObject.transform.SetParent(m_TestObject.transform);
noMaskGameObject.GetComponent<RectTransform>().sizeDelta = new Vector2(800, 800);
maskGameObject.GetComponent<RectTransform>().sizeDelta = new Vector2(400, 400);
var imageGameObject = new GameObject("ImageGO");
var image = imageGameObject.AddComponent<Image>();
imageGameObject.transform.SetParent(maskGameObject.transform);
imageGameObject.GetComponent<RectTransform>().sizeDelta = new Vector2(100, 100);
// Start with image inside RectMask2D area so that it's no culled
rectMask2D.PerformClipping();
Assert.IsFalse(image.canvasRenderer.cull);
// Move image outside of RectMask2D so that it is culled
imageGameObject.GetComponent<RectTransform>().position = new Vector2(275, 275);
rectMask2D.PerformClipping();
Assert.IsTrue(image.canvasRenderer.cull);
// Change parent to noMask so that it's unaffected by RectMask2D and isn't culled
imageGameObject.transform.SetParent(noMaskGameObject.transform);
rectMask2D.PerformClipping();
Assert.IsFalse(image.canvasRenderer.cull);
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 4402dcee6e9969549bf5b33f11533208
timeCreated: 1458135886
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,18 @@
using UnityEngine;
using NUnit.Framework;
public class RectTransformPosition
{
[Test]
public void SettingPositionBeforeGameObjectIsActivatedWorks_953409()
{
var positionToSet = new Vector3(1, 2, 3);
var go = new GameObject("RectTransform", typeof(RectTransform));
go.SetActive(false);
go.transform.position = positionToSet;
go.SetActive(true);
Assert.AreEqual(positionToSet, go.transform.position, "Expected RectTransform position to be set but it was not.");
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: fb660d86885d89a499a31c6ab6f26269
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 4cfe5ade9a1375e40aed87618b92bd12
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,54 @@
using NUnit.Framework;
using UnityEngine.UI;
using UnityEngine;
[Category("Slider")]
public class SliderRectRefernces : Behaviour
{
private Slider slider;
private GameObject emptyGO;
private GameObject rootGO;
[SetUp]
public void TestSetup()
{
rootGO = new GameObject("root child");
rootGO.AddComponent<Canvas>();
var sliderGameObject = new GameObject("Slider");
slider = sliderGameObject.AddComponent<Slider>();
emptyGO = new GameObject("base", typeof(RectTransform));
sliderGameObject.transform.SetParent(rootGO.transform);
emptyGO.transform.SetParent(sliderGameObject.transform);
}
[TearDown]
public void TearDown()
{
GameObject.DestroyImmediate(rootGO);
}
[Test]
public void AssigningSelfResultsInNullReferenceField()
{
slider.fillRect = (RectTransform)slider.transform;
Assert.IsNull(slider.fillRect);
slider.handleRect = (RectTransform)slider.transform;
Assert.IsNull(slider.handleRect);
}
[Test]
public void AssigningOtherObjectResultsInCorrectReferenceField()
{
slider.fillRect = (RectTransform)emptyGO.transform;
Assert.IsNotNull(slider.fillRect);
Assert.AreEqual(slider.fillRect, (RectTransform)emptyGO.transform);
slider.handleRect = (RectTransform)emptyGO.transform;
Assert.IsNotNull(slider.handleRect);
Assert.AreEqual(slider.handleRect, (RectTransform)emptyGO.transform);
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 373b4c78c0396334288fa5ff8e7b7350
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,20 @@
using NUnit.Framework;
using UnityEngine;
public class TestBehaviourBase<T> where T : Behaviour
{
protected T m_TestObject;
[SetUp]
public virtual void TestSetup()
{
var gameObject = new GameObject();
m_TestObject = gameObject.AddComponent<T>();
}
[TearDown]
public virtual void Teardown()
{
GameObject.DestroyImmediate(m_TestObject.gameObject);
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 393b15da08c88194dbbcacd6ee15a89c
timeCreated: 1456926887
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: 4f9ac6e545d53f94b9f09c85b9576f36
folderAsset: yes
timeCreated: 1485515713
licenseType: Pro
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,60 @@
using System;
using NUnit.Framework;
using UnityEngine;
[Category("Text")]
public class FontCreatedByScript
{
static Font CreateDefaultFontWithOneCharacter(int character)
{
var font = new Font();
CharacterInfo[] characterInfo = new CharacterInfo[1];
characterInfo[0].index = character;
font.characterInfo = characterInfo;
return font;
}
[Test]
public static void GetCharacterInfo_FindsCharacterInfoThatIsInSet()
{
char character = 'A';
int charIndex = Convert.ToInt32(character);
var font = CreateDefaultFontWithOneCharacter(charIndex);
CharacterInfo result = new CharacterInfo();
Assert.IsTrue(font.GetCharacterInfo(character, out result), "Could not find character info for '" + character + "' even though the Font contains it.");
Assert.AreEqual(charIndex, result.index, "Incorrect character info was returned for " + character);
}
[Test]
public static void GetCharacterInfo_DoesNotFindCharacterInfoThatIsNotInSet()
{
char character = 'A';
char characterNotInSet = 'X';
int charIndex = Convert.ToInt32(character);
var font = CreateDefaultFontWithOneCharacter(charIndex);
CharacterInfo result;
Assert.IsFalse(font.GetCharacterInfo(characterNotInSet, out result), "Found character info for '" + characterNotInSet + "' even though the Font does not contain it.");
}
[Test]
public static void HasCharacterReturns8BitChars()
{
char character = 'A';
int charIndex = Convert.ToInt32(character);
var font = CreateDefaultFontWithOneCharacter(charIndex);
Assert.IsTrue(font.HasCharacter(character), "HasCharacter returned false even though it should have " + character);
}
[Test]
public static void HasCharacterReturns16BitChars()
{
char character = '\u03A9';
int charIndex = Convert.ToInt32(character);
var font = CreateDefaultFontWithOneCharacter(charIndex);
Assert.IsTrue(font.HasCharacter(character), "HasCharacter returned false even though it should have " + character);
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 812aaaefaab404448a3e4db49dfa5206
timeCreated: 1485515717
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: e7689eda3a8b1a847a8b197dbe90d9a6
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 24333a116497b144f9782b1160984b57
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,120 @@
using System;
using NUnit.Framework;
using System.Collections;
using System.Linq;
using UnityEditor;
using UnityEditor.UIElements;
using UnityEngine;
using UnityEngine.TestTools;
using UnityEngine.UI;
using UnityEngine.UIElements;
using UnityEngine.Search;
[Timeout(360000)]
public class PropertyDrawerTests
{
class PropertyDrawerTestsWindow : EditorWindow
{
public Navigation navigation;
public SpriteState spriteState;
public Dropdown.OptionDataList optionDataList;
[SearchContext("t:gameObject is:gameObject", "gameObject")]
public GameObject searchContext;
SerializedObject serializedObject;
void CreateGUI()
{
serializedObject = new SerializedObject(this);
Add(nameof(navigation));
Add(nameof(spriteState));
Add(nameof(optionDataList));
Add(nameof(searchContext));
rootVisualElement.Bind(serializedObject);
// Forces visual tree update
Rebuild();
}
void Add(string propertyName)
{
rootVisualElement.Add(new PropertyField() { bindingPath = propertyName });
}
public SerializedProperty Property(string propertyName) => serializedObject.FindProperty(propertyName);
public void Rebuild() => rootVisualElement.Bind(serializedObject);
}
static PropertyDrawerTestsWindow window;
[UnitySetUp]
[MenuItem("Tests/Open Property Drawer Test Window")]
public static IEnumerator SetUp()
{
VisualTreeBindingsUpdater.disableBindingsThrottling = true;
window = EditorWindow.GetWindow<PropertyDrawerTestsWindow>();
window.Repaint();
window.Show();
yield return null;
}
[TearDown]
public void TearDown()
{
VisualTreeBindingsUpdater.disableBindingsThrottling = false;
window.Close();
}
[UnityTest]
public IEnumerator NavigationDrawer_IsVisible()
{
yield return null;
Assert.IsNotNull(window.rootVisualElement.Query<VisualElement>("Navigation").Build().First());
}
[UnityTest]
public IEnumerator SpriteStateDrawer_IsVisible()
{
yield return null;
Assert.IsNotNull(window.rootVisualElement.Q("SpriteState"));
}
[UnityTest]
[Ignore("UUM-18482")]
public IEnumerator DropdownOptionDataListDrawer_IsVisible()
{
yield return null;
Assert.IsNotNull(window.rootVisualElement.Q("DropdownOptionDataList"), $"Item is null. Root object count: {window.rootVisualElement.childCount}");
}
[UnityTest]
public IEnumerator SearchContextDrawer_IsVisible()
{
yield return null;
Assert.IsNotNull(window.rootVisualElement.Q("SearchContext"));
}
// Fake expected result in order to make TestCaseAttribute to work with UnityTest
[UnityTest]
[TestCase(new object[] { Navigation.Mode.None, 0}, ExpectedResult = null)]
[TestCase(new object[] { Navigation.Mode.Horizontal, 1 }, ExpectedResult = null)]
[TestCase(new object[] { Navigation.Mode.Vertical, 1 }, ExpectedResult = null)]
[TestCase(new object[] { Navigation.Mode.Automatic, 0 }, ExpectedResult = null)]
[TestCase(new object[] { Navigation.Mode.Explicit, 4 }, ExpectedResult = null)]
[TestCase(new object[] { (Navigation.Mode.Explicit | Navigation.Mode.Horizontal), 0 }, ExpectedResult = null)]
[TestCase(new object[] { (Navigation.Mode.Automatic | Navigation.Mode.Explicit), 0 }, ExpectedResult = null)]
public static IEnumerator NavigationDrawer_ShowsCorrectAdditionalControlCount(Enum mode, int expectedCount)
{
var field = window.rootVisualElement.Q<EnumFlagsField>("unity-input-navigation.m_Mode");
field.value = mode;
yield return null;
var indent = window.rootVisualElement.Q<VisualElement>("Navigation").Q<VisualElement>("Indent");
var visibleChildren = indent.Children().Count(child => child.resolvedStyle.display != DisplayStyle.None);
Assert.AreEqual(expectedCount, visibleChildren, $"{expectedCount} additional Navigation object properties should be " +
$"visible when 'Mode' is set to '{(Navigation.Mode)window.Property("navigation.m_Mode").enumValueFlag}'");
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 433d3b96b2a40a5479d3d7d8495882ed
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,14 @@
{
"name": "UnityEditor.UI.EditorTests",
"references": [
"UnityEditor.UI",
"UnityEngine.UI"
],
"optionalUnityReferences": [
"TestAssemblies"
],
"includePlatforms": [
"Editor"
],
"excludePlatforms": []
}

View File

@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 7c04f0dfa9243c04681a55d90d3ff3fc
AssemblyDefinitionImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: e90cc37a5ccf4a44dbecc5b7172ec512
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,83 @@
using NUnit.Framework;
using UnityEditor.Events;
using UnityEngine;
using UnityEngine.Events;
public class UnityEventInvoke
{
class SimpleCounter : MonoBehaviour
{
public int m_Count = 0;
public void Add()
{
++m_Count;
}
public void NoOp(int i)
{
}
}
GameObject m_CounterObject;
SimpleCounter Counter { get; set; }
[SetUp]
public void TestSetup()
{
m_CounterObject = new GameObject("Counter");
Counter = m_CounterObject.AddComponent<SimpleCounter>();
}
[TearDown]
public void TearDown()
{
GameObject.DestroyImmediate(m_CounterObject);
}
[Test]
[Description("Using a CachedInvokableCall in a UnityEvent should not go re-trigger all the calls stored in the UnityEvent. Case-950588")]
public void UnityEvent_InvokeCallsListenerOnce()
{
var _event = new UnityEvent();
UnityEventTools.AddPersistentListener(_event, new UnityAction(Counter.Add));
_event.SetPersistentListenerState(0, UnityEventCallState.EditorAndRuntime);
_event.Invoke();
Assert.AreEqual(1, Counter.m_Count);
for (int i = 1; i < 5; ++i)
{
UnityEventTools.AddIntPersistentListener(_event, new UnityAction<int>(Counter.NoOp), i);
_event.SetPersistentListenerState(i, UnityEventCallState.EditorAndRuntime);
}
_event.Invoke();
Assert.AreEqual(2, Counter.m_Count);
}
[Test]
[Description("Using a CachedInvokableCall in a UnityEvent should not go re-trigger all the calls stored in the UnityEvent. Case-950588")]
public void UnityEvent_EditMode_InvokeDoesNotCallRuntimeListener()
{
var _event = new UnityEvent();
UnityEventTools.AddPersistentListener(_event, new UnityAction(Counter.Add));
Assert.AreEqual(UnityEventCallState.RuntimeOnly, _event.GetPersistentListenerState(0));
Assert.False(Application.isPlaying);
_event.Invoke();
Assert.AreEqual(0, Counter.m_Count, "Expected Event to not be called when not in play mode and event is marked as Runtime only");
for (int i = 1; i < 5; ++i)
{
UnityEventTools.AddIntPersistentListener(_event, new UnityAction<int>(Counter.NoOp), i);
}
_event.Invoke();
Assert.AreEqual(0, Counter.m_Count, "Expected Event to not be called when not in play mode and event is marked as Runtime only");
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 977190a4db46de442aed27279d247df4
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,65 @@
using System;
using System.Collections;
using NUnit.Framework;
using UnityEditor;
using UnityEngine;
public class WrapperWindowFixture
{
private static WrapperWindow s_MostRecentWrapperWindow;
public class WrapperWindow : EditorWindow
{
// Return true to end the test
public Func<WrapperWindow, bool> onGUIDelegate;
public bool TestCompleted { get; set; }
public void OnGUI()
{
if (onGUIDelegate != null)
{
TestCompleted = onGUIDelegate.Invoke(this);
if (TestCompleted)
onGUIDelegate = null;
}
}
}
public static WrapperWindow GetWindow(Func<WrapperWindow, bool> onGUIDelegate, bool utility = false)
{
return GetWindow(onGUIDelegate, 800, 600, utility);
}
public static WrapperWindow GetWindow(Func<WrapperWindow, bool> onGUIDelegate, int width, int height, bool utility = false)
{
WrapperWindow window;
if (utility)
window = EditorWindow.GetWindow<WrapperWindow>(true);
else
{
window = ScriptableObject.CreateInstance<WrapperWindow>();
window.hideFlags = HideFlags.DontSave;
}
window.onGUIDelegate = onGUIDelegate;
window.position = new Rect(0, 0, width, height);
window.Show();
s_MostRecentWrapperWindow = window;
return window;
}
[TearDown]
public void CloseMostRecentWrapperWindow()
{
if (s_MostRecentWrapperWindow == null)
return;
s_MostRecentWrapperWindow.Close();
s_MostRecentWrapperWindow = null;
}
protected static void RegisterWrapperWindow(WrapperWindow window)
{
s_MostRecentWrapperWindow = window;
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: fc31799bd6dc1f74a8adfee1acd05a9b
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: c545241cf2e56ec4997d7677f01ef43d
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 914613548ded44a43a59eb9852503f18
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,48 @@
using UnityEngine;
using NUnit.Framework;
using System.IO;
using System.Collections.Generic;
using UnityEngine.UI;
using UnityEngine.EventSystems;
namespace TMPro
{
public class TMP_CanvasTests
{
[OneTimeSetUp]
public void Setup()
{
if (!Directory.Exists(Path.GetFullPath("Assets/TextMesh Pro")))
{
Debug.Log("Skipping over Editor tests as TMP Essential Resources are missing from the current test project.");
Assert.Ignore();
return;
}
}
[Test]
public void EnablingAndDisablingCanvasDoesNotRegenerateText() // (UUM-45320)
{
var go = new GameObject();
var canvas = go.AddComponent<Canvas>();
var goChild = new GameObject();
var text = goChild.AddComponent<TextMeshProUGUI>();
goChild.transform.SetParent(go.transform);
// Force text to be generated
text.text = "Hello World";
text.ForceMeshUpdate();
Assert.IsFalse(text.havePropertiesChanged, "Text should not have changed yet");
canvas.enabled = false;
canvas.enabled = true;
Assert.IsFalse(text.havePropertiesChanged, "Text should not have changed after enabling / disabling canvas");
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 5348cbfcd4f74699b33fe6b43747a016
timeCreated: 1703006962

View File

@@ -0,0 +1,278 @@
using UnityEngine;
using NUnit.Framework;
using System.IO;
using System.Collections.Generic;
using UnityEngine.UI;
using UnityEngine.EventSystems;
namespace TMPro
{
[Category("Text Parsing & Layout")]
class TMP_RuntimeTests
{
private TextMeshPro m_TextComponent;
// Characters: 22 Spaces: 4 Words: 5 Lines:
private const string m_TextBlock_00 = "A simple line of text.";
// Characters: 104 Spaces: 14 Words: 15 Lines:
private const string m_TextBlock_01 = "Unity 2017 introduces new features that help teams of artists and developers build experiences together.";
// Characters: 1500 Spaces: 228 Words: 241
private const string m_TextBlock_02 = "The European languages are members of the same family. Their separate existence is a myth. For science, music, sport, etc, Europe uses the same vocabulary. The languages only differ in their grammar, their pronunciation and their most common words." +
"Everyone realizes why a new common language would be desirable: one could refuse to pay expensive translators.To achieve this, it would be necessary to have uniform grammar, pronunciation and more common words.If several languages coalesce, the grammar of the resulting language is more simple and regular than that of the individual languages." +
"The new common language will be more simple and regular than the existing European languages.It will be as simple as Occidental; in fact, it will be Occidental.To an English person, it will seem like simplified English, as a skeptical Cambridge friend of mine told me what Occidental is. The European languages are members of the same family." +
"Their separate existence is a myth. For science, music, sport, etc, Europe uses the same vocabulary.The languages only differ in their grammar, their pronunciation and their most common words.Everyone realizes why a new common language would be desirable: one could refuse to pay expensive translators.To achieve this, it would be necessary to" +
"have uniform grammar, pronunciation and more common words.If several languages coalesce, the grammar of the resulting language is more simple and regular than that of the individual languages.The new common language will be";
// Characters: 2500 Spaces: 343 Words: 370
private const string m_TextBlock_03 = "Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec quam felis, ultricies nec, pellentesque eu, pretium quis, sem. Nulla consequat massa quis enim. Donec pede justo, fringilla vel, aliquet nec, vulputate eget, arcu. In enim justo, rhoncus ut, imperdiet a, venenatis vitae, justo. " +
"Nullam dictum felis eu pede mollis pretium.Integer tincidunt.Cras dapibus.Vivamus elementum semper nisi. Aenean vulputate eleifend tellus. Aenean leo ligula, porttitor eu, consequat vitae, eleifend ac, enim.Aliquam lorem ante, dapibus in, viverra quis, feugiat a, tellus.Phasellus viverra nulla ut metus varius laoreet.Quisque rutrum. Aenean imperdiet. Etiam ultricies nisi vel augue.Curabitur ullamcorper ultricies nisi. " +
"Nam eget dui.Etiam rhoncus. Maecenas tempus, tellus eget condimentum rhoncus, sem quam semper libero, sit amet adipiscing sem neque sed ipsum.Nam quam nunc, blandit vel, luctus pulvinar, hendrerit id, lorem.Maecenas nec odio et ante tincidunt tempus.Donec vitae sapien ut libero venenatis faucibus.Nullam quis ante.Etiam sit amet orci eget eros faucibus tincidunt. Duis leo. Sed fringilla mauris sit amet nibh. " +
"Donec sodales sagittis magna. Sed consequat, leo eget bibendum sodales, augue velit cursus nunc, quis gravida magna mi a libero. Fusce vulputate eleifend sapien. Vestibulum purus quam, scelerisque ut, mollis sed, nonummy id, metus.Nullam accumsan lorem in dui.Cras ultricies mi eu turpis hendrerit fringilla.Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; In ac dui quis mi consectetuer lacinia. Nam pretium turpis et arcu. " +
"Duis arcu tortor, suscipit eget, imperdiet nec, imperdiet iaculis, ipsum. Sed aliquam ultrices mauris.Integer ante arcu, accumsan a, consectetuer eget, posuere ut, mauris.Praesent adipiscing. Phasellus ullamcorper ipsum rutrum nunc.Nunc nonummy metus.Vestibulum volutpat pretium libero. Cras id dui.Aenean ut eros et nisl sagittis vestibulum.Nullam nulla eros, ultricies sit amet, nonummy id, imperdiet feugiat, pede.Sed lectus. Donec mollis hendrerit risus. Phasellus nec sem in justo pellentesque facilisis. " +
"Etiam imperdiet imperdiet orci. Nunc nec neque.Phasellus leo dolor, tempus non, auctor et, hendrerit quis, nisi.Curabitur ligula sapien, tincidunt non, euismod vitae, posuere imperdiet, leo.Maecenas malesuada. Praesent nan. The end of this of this long block of text.";
// Characters: 3423 Spaces: 453 Words: 500
private const string m_TextBlock_04 = "Lorem ipsum dolor sit amet, consectetuer adipiscing elit.Aenean commodo ligula eget dolor.Aenean massa.Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus.Donec quam felis, ultricies nec, pellentesque eu, pretium quis, sem.Nulla consequat massa quis enim.Donec pede justo, fringilla vel, aliquet nec, vulputate eget, arcu.In enim justo, rhoncus ut, imperdiet a, venenatis vitae, justo.Nullam dictum felis eu pede mollis pretium.Integer tincidunt. Cras dapibus. Vivamus elementum semper nisi. Aenean vulputate eleifend tellus." +
"Aenean leo ligula, porttitor eu, consequat vitae, eleifend ac, enim.Aliquam lorem ante, dapibus in, viverra quis, feugiat a, tellus.Phasellus viverra nulla ut metus varius laoreet.Quisque rutrum. Aenean imperdiet. Etiam ultricies nisi vel augue.Curabitur ullamcorper ultricies nisi. Nam eget dui.Etiam rhoncus. Maecenas tempus, tellus eget condimentum rhoncus, sem quam semper libero, sit amet adipiscing sem neque sed ipsum.Nam quam nunc, blandit vel, luctus pulvinar, hendrerit id, lorem.Maecenas nec odio et ante tincidunt tempus.Donec vitae sapien ut libero venenatis faucibus.Nullam quis ante." +
"Etiam sit amet orci eget eros faucibus tincidunt. Duis leo. Sed fringilla mauris sit amet nibh. Donec sodales sagittis magna. Sed consequat, leo eget bibendum sodales, augue velit cursus nunc, quis gravida magna mi a libero. Fusce vulputate eleifend sapien. Vestibulum purus quam, scelerisque ut, mollis sed, nonummy id, metus.Nullam accumsan lorem in dui.Cras ultricies mi eu turpis hendrerit fringilla.Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; In ac dui quis mi consectetuer lacinia.Nam pretium turpis et arcu." +
"Duis arcu tortor, suscipit eget, imperdiet nec, imperdiet iaculis, ipsum. Sed aliquam ultrices mauris.Integer ante arcu, accumsan a, consectetuer eget, posuere ut, mauris.Praesent adipiscing. Phasellus ullamcorper ipsum rutrum nunc.Nunc nonummy metus.Vestibulum volutpat pretium libero. Cras id dui.Aenean ut eros et nisl sagittis vestibulum.Nullam nulla eros, ultricies sit amet, nonummy id, imperdiet feugiat, pede.Sed lectus. Donec mollis hendrerit risus. Phasellus nec sem in justo pellentesque facilisis.Etiam imperdiet imperdiet orci. Nunc nec neque." +
"Phasellus leo dolor, tempus non, auctor et, hendrerit quis, nisi.Curabitur ligula sapien, tincidunt non, euismod vitae, posuere imperdiet, leo.Maecenas malesuada. Praesent congue erat at massa.Sed cursus turpis vitae tortor.Donec posuere vulputate arcu. Phasellus accumsan cursus velit. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Sed aliquam, nisi quis porttitor congue, elit erat euismod orci, ac placerat dolor lectus quis orci.Phasellus consectetuer vestibulum elit.Aenean tellus metus, bibendum sed, posuere ac, mattis non, nunc.Vestibulum fringilla pede sit amet augue." +
"In turpis. Pellentesque posuere. Praesent turpis. Aenean posuere, tortor sed cursus feugiat, nunc augue blandit nunc, eu sollicitudin urna dolor sagittis lacus. Donec elit libero, sodales nec, volutpat a, suscipit non, turpis.Nullam sagittis. Suspendisse pulvinar, augue ac venenatis condimentum, sem libero volutpat nibh, nec pellentesque velit pede quis nunc. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Fusce id purus.Ut varius tincidunt libero.Phasellus dolor.Maecenas vestibulum mollis";
//
private const string m_TextBlock_05 = "This block of text contains <b>bold</b> and <i>italicized</i> characters.";
private const string m_TextBlock_06 = "<align=center><style=H1><#ffffff><u>Multiple<#80f0ff> Alignment</color> per text object</u></color></style></align><line-height=2em>\n" +
"</line-height> The <<#ffffa0>align</color>> tag in TextMesh<#40a0ff>Pro</color> provides the ability to control the alignment of lines and paragraphs which is essential when working with text.\n" +
"<align=left> You may want some block of text to be<#80f0ff>left aligned</color> <<#ffffa0>align=<#80f0ff>left</color></color>> which is sort of the standard.</align>\n" +
"<style=Quote><#ffffa0>\"Using <#80f0ff>Center Alignment</color> <<#ffffa0>align=<#80f0ff>center</color></color>> for a title or displaying a quote is another good example of text alignment.\"</color></style>\n" +
"<align=right><#80f0ff>Right Alignment</color> <<#ffffa0>align=<#80f0ff>right</color></color>> can be useful to create contrast between lines and paragraphs of text.\n" +
"<align=justified><#80f0ff>Justified Alignment</color> <<#ffffa0>align=<#80f0ff>justified</color></color>> results in text that is flush on both the left and right margins. Used well, justified type can look clean and classy.\n" +
"<style=Quote><align=left><#ffffa0>\"Text formatting and alignment has a huge impact on how people will read and perceive your text.\"</color>\n" +
"<size=65%><align=right> -Stephan Bouchard</style>";
private readonly string[] testStrings = new string[] { m_TextBlock_00, m_TextBlock_01, m_TextBlock_02, m_TextBlock_03, m_TextBlock_04, m_TextBlock_05, m_TextBlock_06 };
[OneTimeSetUp]
public void Setup()
{
if (Directory.Exists(Path.GetFullPath("Assets/TextMesh Pro")) || Directory.Exists(Path.GetFullPath("Packages/com.unity.textmeshpro.tests/TextMesh Pro")))
{
GameObject textObject = new GameObject("Text Object");
m_TextComponent = textObject.AddComponent<TextMeshPro>();
m_TextComponent.fontSize = 18;
}
else
{
Debug.Log("Skipping over Editor tests as TMP Essential Resources are missing from the current test project.");
Assert.Ignore();
return;
}
}
public static IEnumerable<object[]> TestCases_Parsing_TextInfo_WordWrapDisabled()
{
yield return new object[] { 0, 22, 4, 5, 1 };
yield return new object[] { 1, 104, 14, 15, 1 };
yield return new object[] { 2, 1500, 228, 241, 1 };
yield return new object[] { 3, 2500, 343, 370, 1 };
yield return new object[] { 4, 3423, 453, 500, 1 };
}
[Test, TestCaseSource("TestCases_Parsing_TextInfo_WordWrapDisabled")]
public void Parsing_TextInfo_WordWrapDisabled(int sourceTextIndex, int characterCount, int spaceCount, int wordCount, int lineCount)
{
m_TextComponent.text = testStrings[sourceTextIndex];
m_TextComponent.textWrappingMode = TextWrappingModes.NoWrap;
m_TextComponent.alignment = TextAlignmentOptions.TopLeft;
// Size the RectTransform
m_TextComponent.rectTransform.sizeDelta = new Vector2(50, 5);
// Force text generation to populate the TextInfo data structure.
m_TextComponent.ForceMeshUpdate();
Assert.AreEqual(m_TextComponent.textInfo.characterCount, characterCount);
Assert.AreEqual(m_TextComponent.textInfo.spaceCount, spaceCount);
Assert.AreEqual(m_TextComponent.textInfo.wordCount, wordCount);
Assert.AreEqual(m_TextComponent.textInfo.lineCount, lineCount);
}
public static IEnumerable<object[]> TestCases_Parsing_TextInfo_WordWrapEnabled()
{
yield return new object[] { 0, 22, 4, 5, 1 };
yield return new object[] { 1, 104, 14, 15, 1 };
yield return new object[] { 2, 1500, 228, 241, 13 };
yield return new object[] { 3, 2500, 343, 370, 21 };
yield return new object[] { 4, 3423, 453, 500, 29 };
}
[Test, TestCaseSource("TestCases_Parsing_TextInfo_WordWrapEnabled")]
public void Parsing_TextInfo_WordWrapEnabled(int sourceTextIndex, int characterCount, int spaceCount, int wordCount, int lineCount)
{
m_TextComponent.text = testStrings[sourceTextIndex];
m_TextComponent.textWrappingMode = TextWrappingModes.Normal;
m_TextComponent.alignment = TextAlignmentOptions.TopLeft;
// Size the RectTransform
m_TextComponent.rectTransform.sizeDelta = new Vector2(100, 50);
// Force text generation to populate the TextInfo data structure.
m_TextComponent.ForceMeshUpdate();
Assert.AreEqual(m_TextComponent.textInfo.characterCount, characterCount);
Assert.AreEqual(m_TextComponent.textInfo.spaceCount, spaceCount);
Assert.AreEqual(m_TextComponent.textInfo.wordCount, wordCount);
Assert.AreEqual(m_TextComponent.textInfo.lineCount, lineCount);
}
public static IEnumerable<object[]> TestCases_Parsing_TextInfo_AlignmentTopJustified()
{
yield return new object[] { 2, 1500, 228, 241, 13 };
yield return new object[] { 3, 2500, 343, 370, 20 };
yield return new object[] { 4, 3423, 453, 500, 27 };
}
[Test, TestCaseSource("TestCases_Parsing_TextInfo_AlignmentTopJustified")]
public void Parsing_TextInfo_AlignmentTopJustified(int sourceTextIndex, int characterCount, int spaceCount, int wordCount, int lineCount)
{
m_TextComponent.text = testStrings[sourceTextIndex];
m_TextComponent.textWrappingMode = TextWrappingModes.Normal;
m_TextComponent.alignment = TextAlignmentOptions.TopJustified;
// Size the RectTransform
m_TextComponent.rectTransform.sizeDelta = new Vector2(100, 50);
// Force text generation to populate the TextInfo data structure.
m_TextComponent.ForceMeshUpdate();
Assert.AreEqual(m_TextComponent.textInfo.characterCount, characterCount);
Assert.AreEqual(m_TextComponent.textInfo.spaceCount, spaceCount);
Assert.AreEqual(m_TextComponent.textInfo.wordCount, wordCount);
Assert.AreEqual(m_TextComponent.textInfo.lineCount, lineCount);
}
public static IEnumerable<object[]> TestCases_Parsing_TextInfo_RichText()
{
yield return new object[] { 5, 59, 8, 9, 1 };
yield return new object[] { 6, 768, 124, 126, 14 };
}
[Test, TestCaseSource("TestCases_Parsing_TextInfo_RichText")]
public void Parsing_TextInfo_RichText(int sourceTextIndex, int characterCount, int spaceCount, int wordCount, int lineCount)
{
m_TextComponent.text = testStrings[sourceTextIndex];
m_TextComponent.textWrappingMode = TextWrappingModes.Normal;
m_TextComponent.alignment = TextAlignmentOptions.TopLeft;
// Size the RectTransform
m_TextComponent.rectTransform.sizeDelta = new Vector2(70, 35);
// Force text generation to populate the TextInfo data structure.
m_TextComponent.ForceMeshUpdate();
Assert.AreEqual(m_TextComponent.textInfo.characterCount, characterCount);
Assert.AreEqual(m_TextComponent.textInfo.spaceCount, spaceCount);
Assert.AreEqual(m_TextComponent.textInfo.wordCount, wordCount);
Assert.AreEqual(m_TextComponent.textInfo.lineCount, lineCount);
}
public static IEnumerable<object[]> TestCases_MultiLineNewline_OnLastLine_WhenPressedEnter_Caret_ShouldNotGoto_NextLine()
{
yield return new object[] { 1, 1 };
yield return new object[] { 2, 2 };
yield return new object[] { 3, 3 };
yield return new object[] { 4, 4 };
yield return new object[] { 5, 5 };
yield return new object[] { 6, 6 };
}
[Test, TestCaseSource(nameof(TestCases_MultiLineNewline_OnLastLine_WhenPressedEnter_Caret_ShouldNotGoto_NextLine))]
public void MultiLineNewline_OnLastLine_WhenPressedEnter_Caret_ShouldNotGoto_NextLine(int lineLimit,
int expectedLineCount)
{
MultiLineNewline_LineLimit_ExpectedLineCount_Logic(lineLimit, lineLimit, 3);
Assert.AreEqual(m_TextComponent.textInfo.lineCount, expectedLineCount);
}
private void MultiLineNewline_LineLimit_ExpectedLineCount_Logic(int lineLimitValue, int lineLimitApplied,
int extraKeyDownEventCount)
{
GameObject cameraObject = new GameObject("Camera Object", typeof(Camera));
GameObject canvasObject = new GameObject("Canvas Object", typeof(Canvas), typeof(GraphicRaycaster));
canvasObject.GetComponent<Canvas>().renderMode = RenderMode.ScreenSpaceOverlay;
GameObject inputObject = new GameObject("Input Object", typeof(TMP_InputField));
inputObject.transform.parent = canvasObject.transform;
inputObject.AddComponent<Image>();
TMP_InputField m_InputField = inputObject.GetComponent<TMP_InputField>();
m_InputField.targetGraphic = inputObject.GetComponent<Image>();
m_InputField.textComponent = m_TextComponent;
m_InputField.lineType = TMP_InputField.LineType.MultiLineNewline;
m_InputField.lineLimit = lineLimitValue;
GameObject eventGameObject = new GameObject("Event Object", typeof(EventSystem), typeof(StandaloneInputModule));
Event enterKeyDownEvent = new Event { type = EventType.KeyDown, keyCode = KeyCode.KeypadEnter, modifiers = EventModifiers.None, character = '\n' };
m_InputField.text = "POTUS";
EventSystem.current.SetSelectedGameObject(inputObject);
m_InputField.ActivateInputField();
int count = lineLimitApplied + extraKeyDownEventCount;
while (count > 0)
{
m_InputField.ProcessEvent(enterKeyDownEvent);
m_InputField.ForceLabelUpdate();
count--;
}
m_InputField.textComponent.ForceMeshUpdate();
CanvasUpdateRegistry.RegisterCanvasElementForGraphicRebuild(m_InputField);
m_InputField.DeactivateInputField();
GameObject.Destroy(eventGameObject);
GameObject.Destroy(inputObject);
GameObject.Destroy(canvasObject);
GameObject.Destroy(cameraObject);
}
public static IEnumerable<object[]> TestCases_MultiLineNewLine_NegativeOrZeroLineLimit_AddsNewLine()
{
yield return new object[] { 0, 0, 1 };
yield return new object[] { 0, 0, 4 };
yield return new object[] { -1, 0, 2 };
}
[Test, TestCaseSource(nameof(TestCases_MultiLineNewLine_NegativeOrZeroLineLimit_AddsNewLine))]
public void MultiLineNewLine_NegativeOrZeroLineLimit_AddsNewLine(int lineLimitValue, int lineLimitApplied,
int extraKeyDownEventCount)
{
MultiLineNewline_LineLimit_ExpectedLineCount_Logic(lineLimitValue, lineLimitApplied, extraKeyDownEventCount);
Assert.AreEqual(m_TextComponent.textInfo.lineCount, extraKeyDownEventCount + 1);
}
//[OneTimeTearDown]
//public void Cleanup()
//{
// // Remove TMP Essential Resources if they were imported in the project as a result of running tests.
// if (TMPro_EventManager.temporaryResourcesImported == true)
// {
// string testResourceFolderPath = Path.GetFullPath("Assets/TextMesh Pro");
// if (Directory.Exists(testResourceFolderPath))
// {
// Directory.Delete(testResourceFolderPath);
// File.Delete(Path.GetFullPath("Assets/TextMesh Pro.meta"));
// }
// TMPro_EventManager.temporaryResourcesImported = false;
// }
//}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 9de24983a2c6cbe4f925c3e98a79b804
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,14 @@
{
"name": "Unity.TextMeshPro.Tests",
"references": [
"Unity.TextMeshPro"
],
"optionalUnityReferences": [
"TestAssemblies"
],
"defineConstraints": [
"UNITY_INCLUDE_TESTS"
],
"includePlatforms": [],
"excludePlatforms": []
}

View File

@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: bb05cab7d802aa5468f8f2f86840d984
AssemblyDefinitionImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 53caebc5909234b4ebe1fcaf3dc913a5
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 239dd6edc8e5cd14585c03e09e86a747
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,151 @@
using System.Collections;
using System.IO;
using NUnit.Framework;
using UnityEditor;
using UnityEngine.EventSystems;
using UnityEngine.TestTools;
using UnityEngine.UI;
using UnityEngine;
public class ButtonTests : IPrebuildSetup
{
GameObject m_PrefabRoot;
const string kPrefabPath = "Assets/Resources/ButtonPrefab.prefab";
public void Setup()
{
#if UNITY_EDITOR
var rootGO = new GameObject("rootGo");
var canvasGO = new GameObject("Canvas", typeof(Canvas));
canvasGO.transform.SetParent(rootGO.transform);
var canvas = canvasGO.GetComponent<Canvas>();
canvas.referencePixelsPerUnit = 100;
GameObject eventSystemGO = new GameObject("EventSystem", typeof(EventSystem));
eventSystemGO.transform.SetParent(rootGO.transform);
GameObject TestButtonGO = new GameObject("TestButton", typeof(RectTransform), typeof(TestButton));
TestButtonGO.transform.SetParent(canvasGO.transform);
if (!Directory.Exists("Assets/Resources/"))
Directory.CreateDirectory("Assets/Resources/");
PrefabUtility.SaveAsPrefabAsset(rootGO, kPrefabPath);
GameObject.DestroyImmediate(rootGO);
#endif
}
[SetUp]
public void TestSetup()
{
m_PrefabRoot = Object.Instantiate(Resources.Load("ButtonPrefab")) as GameObject;
}
[TearDown]
public void TearDown()
{
GameObject.DestroyImmediate(m_PrefabRoot);
}
[OneTimeTearDown]
public void OneTimeTearDown()
{
#if UNITY_EDITOR
AssetDatabase.DeleteAsset(kPrefabPath);
#endif
}
[Test]
public void PressShouldCallClickHandler()
{
Button button = m_PrefabRoot.GetComponentInChildren<Button>();
bool called = false;
button.onClick.AddListener(() => { called = true; });
button.OnPointerClick(new PointerEventData(m_PrefabRoot.GetComponentInChildren<EventSystem>()) { button = PointerEventData.InputButton.Left });
Assert.True(called);
}
[Test]
public void PressInactiveShouldNotCallClickHandler()
{
Button button = m_PrefabRoot.GetComponentInChildren<Button>();
bool called = false;
button.enabled = false;
button.onClick.AddListener(() => { called = true; });
button.OnPointerClick(new PointerEventData(m_PrefabRoot.GetComponentInChildren<EventSystem>()) { button = PointerEventData.InputButton.Left });
Assert.False(called);
}
[Test]
public void PressNotInteractableShouldNotCallClickHandler()
{
Button button = m_PrefabRoot.GetComponentInChildren<Button>();
bool called = false;
button.interactable = false;
button.onClick.AddListener(() => { called = true; });
button.OnPointerClick(new PointerEventData(m_PrefabRoot.GetComponentInChildren<EventSystem>()) { button = PointerEventData.InputButton.Left });
Assert.False(called);
}
[Test]
public void SelectShouldHoldThePreviousStateAfterDisablingAndEnabling()
{
TestButton button = m_PrefabRoot.GetComponentInChildren<TestButton>();
button.onClick.AddListener(() => {
button.Select();
button.enabled = false;
});
button.OnPointerClick(new PointerEventData(m_PrefabRoot.GetComponentInChildren<EventSystem>()) { button = PointerEventData.InputButton.Left });
Assert.False(button.enabled, "Expected button to not be enabled");
button.enabled = true;
Assert.True(button.isStateSelected, "Expected selected state to be true");
}
[Test]
public void SubmitShouldCallClickHandler()
{
Button button = m_PrefabRoot.GetComponentInChildren<Button>();
bool called = false;
button.onClick.AddListener(() => { called = true; });
button.OnSubmit(null);
Assert.True(called);
}
[Test]
public void SubmitInactiveShouldNotCallClickHandler()
{
Button button = m_PrefabRoot.GetComponentInChildren<Button>();
bool called = false;
button.enabled = false;
button.onClick.AddListener(() => { called = true; });
button.OnSubmit(new PointerEventData(m_PrefabRoot.GetComponentInChildren<EventSystem>()) { button = PointerEventData.InputButton.Left });
Assert.False(called);
}
[Test]
public void SubmitNotInteractableShouldNotCallClickHandler()
{
Button button = m_PrefabRoot.GetComponentInChildren<Button>();
bool called = false;
button.interactable = false;
button.onClick.AddListener(() => { called = true; });
button.OnSubmit(new PointerEventData(m_PrefabRoot.GetComponentInChildren<EventSystem>()) { button = PointerEventData.InputButton.Left });
Assert.False(called);
}
[UnityTest]
public IEnumerator SubmitShouldTransitionToPressedStateAndBackToNormal()
{
TestButton button = m_PrefabRoot.GetComponentInChildren<TestButton>();
Assert.True(button.IsTransitionToNormal(0));
button.OnSubmit(null);
Assert.True(button.isStateNormal);
Assert.True(button.IsTransitionToPressed(1));
yield return new WaitWhile(() => button.StateTransitionCount == 2);
// 3rd transition back to normal should have started
Assert.True(button.IsTransitionToNormal(2));
yield return null;
Assert.True(button.isStateNormal);
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 1ef2923b9c5521948a04299da53ae750
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,31 @@
using System.Collections.Generic;
using UnityEngine.UI;
class TestButton : Button
{
public bool isStateNormal { get { return currentSelectionState == SelectionState.Normal; } }
public bool isStateHighlighted { get { return currentSelectionState == SelectionState.Highlighted; } }
public bool isStatePressed { get { return currentSelectionState == SelectionState.Pressed; } }
public bool isStateDisabled { get { return currentSelectionState == SelectionState.Disabled; } }
public bool isStateSelected { get { return currentSelectionState == SelectionState.Selected; } }
private bool IsTransitionTo(int index, SelectionState selectionState)
{
return index < m_StateTransitions.Count && m_StateTransitions[index] == selectionState;
}
public bool IsTransitionToNormal(int index) { return IsTransitionTo(index, SelectionState.Normal); }
public bool IsTransitionToHighlighted(int index) { return IsTransitionTo(index, SelectionState.Highlighted); }
public bool IsTransitionToPressed(int index) { return IsTransitionTo(index, SelectionState.Pressed); }
public bool IsTransitionToDisabled(int index) { return IsTransitionTo(index, SelectionState.Disabled); }
private readonly List<SelectionState> m_StateTransitions = new List<SelectionState>();
public int StateTransitionCount { get { return m_StateTransitions.Count; } }
protected override void DoStateTransition(SelectionState state, bool instant)
{
m_StateTransitions.Add(state);
base.DoStateTransition(state, instant);
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 4f5ed95515938d14189b094f8654d0bd
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 9a3557da07c729b4eb774b8e30e157a4
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,9 @@
using UnityEngine;
public class BridgeScriptForRetainingObjects : MonoBehaviour
{
public const string bridgeObjectName = "BridgeGameObject";
public GameObject canvasGO;
public GameObject nestedCanvasGO;
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 1a26e19d51cbfac42a02631ad1f9e39e
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,203 @@
using UnityEngine;
using UnityEngine.TestTools;
using NUnit.Framework;
using System.Collections;
using UnityEngine.UI;
[TestFixture]
public class CanvasGroupTests
{
GameObject m_CanvasObject;
CanvasGroup m_CanvasGroup;
CanvasRenderer m_ChildCanvasRenderer;
CanvasGroup m_ChildCanvasGroup;
CanvasRenderer m_GrandChildCanvasRenderer;
CanvasGroup m_GrandChildCanvasGroup;
GameObject m_CanvasTwoObject;
CanvasGroup m_CanvasTwoGroup;
CanvasRenderer m_ChildCanvasTwoRenderer;
const float m_CanvasAlpha = 0.25f;
const float m_ChildAlpha = 0.5f;
const float m_GrandChildAlpha = 0.8f;
[SetUp]
public void TestSetup()
{
m_CanvasObject = new GameObject("Canvas", typeof(Canvas));
m_CanvasGroup = m_CanvasObject.AddComponent<CanvasGroup>();
m_CanvasGroup.alpha = m_CanvasAlpha;
var childObject = new GameObject("Child Object", typeof(Image));
childObject.transform.SetParent(m_CanvasObject.transform);
m_ChildCanvasGroup = childObject.AddComponent<CanvasGroup>();
m_ChildCanvasGroup.alpha = m_ChildAlpha;
m_ChildCanvasRenderer = childObject.GetComponent<CanvasRenderer>();
var grandChildObject = new GameObject("Grand Child Object", typeof(Image));
grandChildObject.transform.SetParent(childObject.transform);
m_GrandChildCanvasGroup = grandChildObject.AddComponent<CanvasGroup>();
m_GrandChildCanvasGroup.alpha = m_GrandChildAlpha;
m_GrandChildCanvasRenderer = grandChildObject.GetComponent<CanvasRenderer>();
m_CanvasTwoObject = new GameObject("CanvasTwo", typeof(Canvas));
m_CanvasTwoObject.transform.SetParent(m_CanvasObject.transform);
m_CanvasTwoGroup = m_CanvasTwoObject.AddComponent<CanvasGroup>();
m_CanvasTwoGroup.alpha = m_CanvasAlpha;
var childTwoObject = new GameObject("Child Two Object", typeof(Image));
childTwoObject.transform.SetParent(m_CanvasTwoObject.transform);
m_ChildCanvasTwoRenderer = childTwoObject.GetComponent<CanvasRenderer>();
}
[TearDown]
public void TearDown()
{
GameObject.DestroyImmediate(m_CanvasObject);
}
private void SetUpCanvasGroupState()
{
m_CanvasGroup.enabled = false;
m_CanvasGroup.ignoreParentGroups = false;
m_ChildCanvasGroup.enabled = false;
m_ChildCanvasGroup.ignoreParentGroups = false;
m_GrandChildCanvasGroup.enabled = false;
m_GrandChildCanvasGroup.ignoreParentGroups = false;
m_CanvasTwoGroup.enabled = false;
m_CanvasTwoGroup.ignoreParentGroups = false;
}
[Test]
public void EnabledCanvasGroupEffectSelfAndChildrenAlpha()
{
// Set up the states of the canvas groups for the tests.
SetUpCanvasGroupState();
// With no enabled CanvasGroup the Alphas should be 1
Assert.AreEqual(1.0f, m_ChildCanvasRenderer.GetInheritedAlpha());
Assert.AreEqual(1.0f, m_GrandChildCanvasRenderer.GetInheritedAlpha());
// Enable the child CanvasGroup. It and its children should now have the same alpha value.
m_ChildCanvasGroup.enabled = true;
Assert.AreEqual(m_ChildAlpha, m_ChildCanvasRenderer.GetInheritedAlpha());
Assert.AreEqual(m_ChildAlpha, m_GrandChildCanvasRenderer.GetInheritedAlpha());
}
[Test]
public void EnabledCanvasGroupOnACanvasEffectAllChildrenAlpha()
{
// Set up the states of the canvas groups for the tests.
SetUpCanvasGroupState();
// With no enabled CanvasGroup the Alphas should be 1
Assert.AreEqual(1.0f, m_ChildCanvasRenderer.GetInheritedAlpha());
Assert.AreEqual(1.0f, m_GrandChildCanvasRenderer.GetInheritedAlpha());
// Children under a different nest canvas should also obey the alpha
Assert.AreEqual(1.0f, m_ChildCanvasTwoRenderer.GetInheritedAlpha());
// Enable the Canvas CanvasGroup. All of the Canvas children should now have the same alpha value.
m_CanvasGroup.enabled = true;
Assert.AreEqual(m_CanvasAlpha, m_ChildCanvasRenderer.GetInheritedAlpha());
Assert.AreEqual(m_CanvasAlpha, m_GrandChildCanvasRenderer.GetInheritedAlpha());
// Children under a different nest canvas should also obey the alpha
Assert.AreEqual(m_CanvasAlpha, m_ChildCanvasTwoRenderer.GetInheritedAlpha());
}
[Test]
public void EnabledCanvasGroupOnLeafChildEffectOnlyThatChild()
{
// Set up the states of the canvas groups for the tests.
SetUpCanvasGroupState();
// With no enabled CanvasGroup the Alphas should be 1
Assert.AreEqual(1.0f, m_ChildCanvasRenderer.GetInheritedAlpha());
Assert.AreEqual(1.0f, m_GrandChildCanvasRenderer.GetInheritedAlpha());
// Enable the Leaf child CanvasGroup. Only it should have a modified alpha
m_GrandChildCanvasGroup.enabled = true;
Assert.AreEqual(1.0f, m_ChildCanvasRenderer.GetInheritedAlpha());
Assert.AreEqual(m_GrandChildAlpha, m_GrandChildCanvasRenderer.GetInheritedAlpha());
}
[Test]
public void EnabledCanvasGroupOnCanvasAndChildMultipleAlphaValuesCorrectly()
{
// Set up the states of the canvas groups for the tests.
SetUpCanvasGroupState();
// With no enabled CanvasGroup the Alphas should be 1
Assert.AreEqual(1.0f, m_ChildCanvasRenderer.GetInheritedAlpha());
Assert.AreEqual(1.0f, m_GrandChildCanvasRenderer.GetInheritedAlpha());
// Enable the Canvas CanvasGroup. All of the Canvas children should now have the same alpha value.
m_CanvasGroup.enabled = true;
m_ChildCanvasGroup.enabled = true;
Assert.AreEqual(m_CanvasAlpha * m_ChildAlpha, m_ChildCanvasRenderer.GetInheritedAlpha());
Assert.AreEqual(m_CanvasAlpha * m_ChildAlpha, m_GrandChildCanvasRenderer.GetInheritedAlpha());
}
[Test]
public void EnabledCanvasGroupOnCanvasAndChildWithChildIgnoringParentGroupMultipleAlphaValuesCorrectly()
{
// Set up the states of the canvas groups for the tests.
SetUpCanvasGroupState();
// With no enabled CanvasGroup the Alphas should be 1
Assert.AreEqual(1.0f, m_ChildCanvasRenderer.GetInheritedAlpha());
Assert.AreEqual(1.0f, m_GrandChildCanvasRenderer.GetInheritedAlpha());
// Enable the Canvas CanvasGroup. All of the Canvas children should now have the same alpha value.
m_CanvasGroup.enabled = true;
m_ChildCanvasGroup.enabled = true;
m_ChildCanvasGroup.ignoreParentGroups = true;
Assert.AreEqual(m_ChildAlpha, m_ChildCanvasRenderer.GetInheritedAlpha());
Assert.AreEqual(m_ChildAlpha, m_GrandChildCanvasRenderer.GetInheritedAlpha());
}
[Test]
public void EnabledCanvasGroupOnCanvasAndChildrenWithAllChildrenIgnoringParentGroupMultipleAlphaValuesCorrectly()
{
// Set up the states of the canvas groups for the tests.
SetUpCanvasGroupState();
// With no enabled CanvasGroup the Alphas should be 1
Assert.AreEqual(1.0f, m_ChildCanvasRenderer.GetInheritedAlpha());
Assert.AreEqual(1.0f, m_GrandChildCanvasRenderer.GetInheritedAlpha());
// Enable the Canvas CanvasGroup. All of the Canvas children should now have the same alpha value.
m_CanvasGroup.enabled = true;
m_ChildCanvasGroup.enabled = true;
m_GrandChildCanvasGroup.enabled = true;
m_ChildCanvasGroup.ignoreParentGroups = true;
m_GrandChildCanvasGroup.ignoreParentGroups = true;
Assert.AreEqual(m_ChildAlpha, m_ChildCanvasRenderer.GetInheritedAlpha());
Assert.AreEqual(m_GrandChildAlpha, m_GrandChildCanvasRenderer.GetInheritedAlpha());
}
[Test]
public void EnabledCanvasGroupOnNestedCanvasIgnoringParentGroupMultipleAlphaValuesCorrectly()
{
// Set up the states of the canvas groups for the tests.
SetUpCanvasGroupState();
// With no enabled CanvasGroup the Alphas should be 1
Assert.AreEqual(1.0f, m_ChildCanvasTwoRenderer.GetInheritedAlpha());
// Enable the Canvas CanvasGroup. All of the Canvas children should now have the same alpha value.
m_CanvasGroup.enabled = true;
m_CanvasTwoGroup.enabled = true;
m_CanvasTwoGroup.ignoreParentGroups = true;
Assert.AreEqual(m_CanvasAlpha, m_ChildCanvasTwoRenderer.GetInheritedAlpha());
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: a14a59f2a5c757e469c3e4e17b798c2e
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,47 @@
using System;
using System.Collections;
using UnityEngine;
using UnityEngine.TestTools;
using NUnit.Framework;
using UnityEngine.SceneManagement;
using UnityEditor;
[TestFixture]
public class CanvasResizeCorrectlyForRenderTexture
{
Canvas m_Canvas;
Camera m_Camera;
RenderTexture m_RenderTexture;
[Test]
public void CanvasResizeCorrectly()
{
var cameraGameObject = new GameObject("PreviewCamera", typeof(Camera));
var canvasGameObject = new GameObject("Canvas", typeof(Canvas));
m_Camera = cameraGameObject.GetComponent<Camera>();
m_Canvas = canvasGameObject.GetComponent<Canvas>();
m_Canvas.renderMode = RenderMode.ScreenSpaceCamera;
m_Canvas.worldCamera = m_Camera;
var rectTransform = canvasGameObject.transform as RectTransform;
m_Canvas.updateRectTransformForStandalone = StandaloneRenderResize.Disabled;
m_RenderTexture = new RenderTexture(100, 100, 0);
m_Camera.targetTexture = m_RenderTexture;
m_Camera.Render();
Assert.AreNotEqual(new Vector2(100, 100), rectTransform.sizeDelta);
m_Canvas.updateRectTransformForStandalone = StandaloneRenderResize.Enabled;
m_Camera.Render();
Assert.AreEqual(new Vector2(100, 100), rectTransform.sizeDelta);
}
[TearDown]
public void TearDown()
{
GameObject.DestroyImmediate(m_Canvas.gameObject);
GameObject.DestroyImmediate(m_Camera.gameObject);
UnityEngine.Object.DestroyImmediate(m_RenderTexture);
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: d4dbe29df1b294c4f8f0a2fb529d19fd
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,54 @@
using UnityEngine;
using UnityEngine.TestTools;
using NUnit.Framework;
using System.Collections;
using UnityEngine.UI;
[TestFixture]
[Category("RegressionTest")]
[Description("CoveredBugID = 734299")]
public class CanvasScalerWithChildTextObjectDoesNotCrash
{
GameObject m_CanvasObject;
[SetUp]
public void TestSetup()
{
#if UNITY_EDITOR
UnityEditor.EditorApplication.ExecuteMenuItem("Window/General/Game");
#endif
}
[UnityTest]
public IEnumerator CanvasScalerWithChildTextObjectWithTextFontDoesNotCrash()
{
//This adds a Canvas component as well
m_CanvasObject = new GameObject("Canvas");
var canvasScaler = m_CanvasObject.AddComponent<CanvasScaler>();
m_CanvasObject.GetComponent<Canvas>().renderMode = RenderMode.ScreenSpaceCamera;
//the crash only reproduces if the text component is a child of the game object
//that has the CanvasScaler component and if it has an actual font and text set
var textObject = new GameObject("Text").AddComponent<UnityEngine.UI.Text>();
textObject.font = Font.CreateDynamicFontFromOSFont("Arial", 14);
textObject.text = "New Text";
textObject.transform.SetParent(m_CanvasObject.transform);
canvasScaler.uiScaleMode = CanvasScaler.ScaleMode.ScaleWithScreenSize;
canvasScaler.referenceResolution = new Vector2(1080, 1020);
//The crash happens when setting the referenceResolution to a small value
canvasScaler.referenceResolution = new Vector2(9, 9);
//We need to wait a few milliseconds for the crash to happen, otherwise Debug.Log will
//get executed and the test will pass
yield return new WaitForSeconds(0.1f);
Assert.That(true);
}
[TearDown]
public void TearDown()
{
GameObject.DestroyImmediate(m_CanvasObject);
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 13d161b14bb3ab74e8a9634e26fb7a5e
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,64 @@
using System;
using System.Collections;
using UnityEngine;
using UnityEngine.TestTools;
using NUnit.Framework;
using UnityEngine.SceneManagement;
using UnityEditor;
[TestFixture]
public class CanvasSizeCorrectInAwakeAndStart : IPrebuildSetup
{
const string k_SceneName = "CanvasSizeCorrectInAwakeAndStartScene";
GameObject m_CanvasGameObject;
Scene m_InitScene;
public void Setup()
{
#if UNITY_EDITOR
Action codeToExecute = delegate()
{
var canvasGO = new GameObject("CanvasToAddImage", typeof(Canvas));
var imageGO = new GameObject("ImageOnCanvas", typeof(UnityEngine.UI.Image));
imageGO.transform.localPosition = Vector3.one;
imageGO.transform.SetParent(canvasGO.transform);
imageGO.AddComponent<CanvasSizeCorrectInAwakeAndStartScript>();
canvasGO.GetComponent<Canvas>().renderMode = RenderMode.ScreenSpaceOverlay;
imageGO.SetActive(false);
};
CreateSceneUtility.CreateScene(k_SceneName, codeToExecute);
#endif
}
[SetUp]
public void TestSetup()
{
m_InitScene = SceneManager.GetActiveScene();
}
[UnityTest]
public IEnumerator CanvasSizeIsCorrectInAwakeAndStart()
{
AsyncOperation operation = SceneManager.LoadSceneAsync(k_SceneName, LoadSceneMode.Additive);
yield return operation;
SceneManager.SetActiveScene(SceneManager.GetSceneByName(k_SceneName));
m_CanvasGameObject = GameObject.Find("CanvasToAddImage");
var imageGO = m_CanvasGameObject.transform.Find("ImageOnCanvas");
imageGO.gameObject.SetActive(true);
var component = imageGO.GetComponent<CanvasSizeCorrectInAwakeAndStartScript>();
yield return new WaitUntil(() => component.isAwakeCalled && component.isStartCalled);
}
[TearDown]
public void TearDown()
{
GameObject.DestroyImmediate(m_CanvasGameObject);
SceneManager.SetActiveScene(m_InitScene);
SceneManager.UnloadSceneAsync(k_SceneName);
#if UNITY_EDITOR
AssetDatabase.DeleteAsset("Assets/" + k_SceneName + ".unity");
#endif
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: ec35c13a8280a8d4e817bc4afd8a95de
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,21 @@
using NUnit.Framework;
using UnityEngine;
using UnityEngine.TestTools.Utils;
public class CanvasSizeCorrectInAwakeAndStartScript : MonoBehaviour
{
public bool isStartCalled { get; private set; }
public bool isAwakeCalled { get; private set; }
protected void Awake()
{
Assert.That(transform.position, Is.Not.EqualTo(Vector3.zero).Using(new Vector3EqualityComparer(0.0f)));
isAwakeCalled = true;
}
protected void Start()
{
Assert.That(transform.position, Is.Not.EqualTo(Vector3.zero).Using(new Vector3EqualityComparer(0.0f)));
isStartCalled = true;
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: df1ba932d4ce4534e97a0f10c85cd3c9
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,85 @@
using UnityEngine;
using UnityEngine.TestTools;
using NUnit.Framework;
using System.Collections;
using UnityEngine.TestTools.Utils;
[TestFixture]
public class CheckMeshColorsAndColors32Match
{
GameObject m_CanvasGO;
GameObject m_ColorMeshGO;
GameObject m_Color32MeshGO;
Texture2D m_ScreenTexture;
[SetUp]
public void TestSetup()
{
// Create Canvas
m_CanvasGO = new GameObject("Canvas");
Canvas canvas = m_CanvasGO.AddComponent<Canvas>();
canvas.renderMode = RenderMode.ScreenSpaceOverlay;
// Create Color UI GameObject
m_ColorMeshGO = new GameObject("ColorMesh");
CanvasRenderer colorMeshCanvasRenderer = m_ColorMeshGO.AddComponent<CanvasRenderer>();
RectTransform colorMeshRectTransform = m_ColorMeshGO.AddComponent<RectTransform>();
colorMeshRectTransform.pivot = colorMeshRectTransform.anchorMin = colorMeshRectTransform.anchorMax = Vector2.zero;
m_ColorMeshGO.transform.SetParent(m_CanvasGO.transform);
// Create Color32 UI GameObject
m_Color32MeshGO = new GameObject("Color32Mesh");
CanvasRenderer color32MeshCanvasRenderer = m_Color32MeshGO.AddComponent<CanvasRenderer>();
RectTransform color32MeshRectTransform = m_Color32MeshGO.AddComponent<RectTransform>();
color32MeshRectTransform.pivot = color32MeshRectTransform.anchorMin = color32MeshRectTransform.anchorMax = Vector2.zero;
m_Color32MeshGO.transform.SetParent(m_CanvasGO.transform);
Material material = new Material(Shader.Find("UI/Default"));
// Setup Color mesh and add it to Color CanvasRenderer
Mesh meshColor = new Mesh();
meshColor.vertices = new Vector3[3] { new Vector3(0, 0, 0), new Vector3(0, 10, 0), new Vector3(10, 0, 0) };
meshColor.triangles = new int[3] { 0, 1, 2 };
meshColor.normals = new Vector3[3] { Vector3.zero, Vector3.zero, Vector3.zero };
meshColor.colors = new Color[3] { Color.white, Color.white, Color.white };
meshColor.uv = new Vector2[3] { new Vector2(0, 0), new Vector2(0, 1), new Vector2(1, 0) };
colorMeshCanvasRenderer.SetMesh(meshColor);
colorMeshCanvasRenderer.SetMaterial(material, null);
// Setup Color32 mesh and add it to Color32 CanvasRenderer
Mesh meshColor32 = new Mesh();
meshColor32.vertices = new Vector3[3] { new Vector3(10, 0, 0), new Vector3(10, 10, 0), new Vector3(20, 0, 0) };
meshColor32.triangles = new int[3] { 0, 1, 2 };
meshColor32.normals = new Vector3[3] { Vector3.zero, Vector3.zero, Vector3.zero };
meshColor32.colors32 = new Color32[3] { Color.white, Color.white, Color.white };
meshColor32.uv = new Vector2[3] { new Vector2(0, 0), new Vector2(0, 1), new Vector2(1, 0) };
color32MeshCanvasRenderer.SetMesh(meshColor32);
color32MeshCanvasRenderer.SetMaterial(material, null);
}
[TearDown]
public void TearDown()
{
GameObject.DestroyImmediate(m_CanvasGO);
GameObject.DestroyImmediate(m_ScreenTexture);
}
[Ignore("UnityTest yielded WaitForEndOfFrame, which is not evoked in batchmode.")]
[UnityTest]
public IEnumerator CheckMeshColorsAndColors32Matches()
{
yield return new WaitForEndOfFrame();
// Create a Texture2D
m_ScreenTexture = new Texture2D(Screen.width, Screen.height, TextureFormat.RGB24, false);
m_ScreenTexture.ReadPixels(new Rect(0, 0, Screen.width, Screen.height), 0, 0);
m_ScreenTexture.Apply();
Color screenPixelColorForMeshColor = m_ScreenTexture.GetPixel(1, 0);
Color screenPixelColorForMesh32Color = m_ScreenTexture.GetPixel(11, 0);
Assert.That(screenPixelColorForMesh32Color, Is.EqualTo(screenPixelColorForMeshColor).Using(new ColorEqualityComparer(0.0f)), "UI Mesh with Colors does not match UI Mesh with Colors32");
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 9390296e78291b543b2f4a9761ef8139
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,74 @@
using UnityEngine;
using UnityEngine.TestTools;
using NUnit.Framework;
using System.Collections;
using UnityEngine.UI;
[TestFixture]
[UnityPlatform(include = new RuntimePlatform[] { RuntimePlatform.OSXEditor, RuntimePlatform.LinuxEditor, RuntimePlatform.WindowsEditor })]
[Category("RegressionTest")]
[Description("CoveredBugID = 904415")]
public class CoroutineWorksIfUIObjectIsAttached
{
GameObject m_CanvasMaster;
GameObject m_ImageObject;
[SetUp]
public void TestSetup()
{
m_CanvasMaster = new GameObject("Canvas", typeof(Canvas), typeof(CanvasScaler), typeof(GraphicRaycaster));
m_ImageObject = new GameObject("Image", typeof(Image));
m_ImageObject.SetActive(false);
}
[UnityTest]
public IEnumerator CoroutineWorksOnAttachingUIObject()
{
// Generating Basic scene
m_CanvasMaster.AddComponent<CoroutineObject>();
yield return null;
m_ImageObject.transform.SetParent(m_CanvasMaster.transform);
m_ImageObject.AddComponent<BugObject>();
m_ImageObject.SetActive(true);
yield return null;
yield return null;
yield return null;
Assert.That(m_CanvasMaster.GetComponent<CoroutineObject>().coroutineCount, Is.GreaterThan(1), "The Coroutine wasn't supposed to stop but continue to run, something made it stopped");
}
[TearDown]
public void TearDown()
{
GameObject.DestroyImmediate(m_CanvasMaster);
GameObject.DestroyImmediate(m_ImageObject);
}
}
public class BugObject : MonoBehaviour
{
void Awake()
{
GameObject newObject = new GameObject("NewGameObjectThatTriggersBug");
newObject.transform.SetParent(transform);
newObject.AddComponent<Text>();
}
}
public class CoroutineObject : MonoBehaviour
{
public int coroutineCount { get; private set; }
public IEnumerator Start()
{
// This coroutine should not stop and continue adding to the timer
while (true)
{
coroutineCount++;
yield return null;
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 8573c56c34e616248a3881b2c56280ef
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,25 @@
using System;
using System.Linq;
using UnityEngine;
using UnityEngine.SceneManagement;
class CreateSceneUtility
{
public static void CreateScene(string sceneName, Action delegateToExecute)
{
#if UNITY_EDITOR
string scenePath = "Assets/" + sceneName + ".unity";
var initScene = SceneManager.GetActiveScene();
var list = UnityEditor.EditorBuildSettings.scenes.ToList();
var newScene = UnityEditor.SceneManagement.EditorSceneManager.NewScene(UnityEditor.SceneManagement.NewSceneSetup.DefaultGameObjects, UnityEditor.SceneManagement.NewSceneMode.Additive);
GameObject.DestroyImmediate(Camera.main.GetComponent<AudioListener>());
delegateToExecute();
UnityEditor.SceneManagement.EditorSceneManager.SaveScene(newScene, scenePath);
UnityEditor.SceneManagement.EditorSceneManager.UnloadSceneAsync(newScene);
list.Add(new UnityEditor.EditorBuildSettingsScene(scenePath, true));
UnityEditor.EditorBuildSettings.scenes = list.ToArray();
SceneManager.SetActiveScene(initScene);
#endif
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: db339ef553721e94999125c0b9f909dc
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,102 @@
using System.IO;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.TestTools;
using NUnit.Framework;
using System.Collections;
using UnityEditor;
public class NestedCanvas : IPrebuildSetup
{
Object m_GO1;
Object m_GO2;
const string kPrefabPath = "Assets/Resources/NestedCanvasPrefab.prefab";
public void Setup()
{
#if UNITY_EDITOR
var rootGO = new GameObject("RootGO");
var rootCanvasGO = new GameObject("Canvas", typeof(Canvas), typeof(CanvasGroup));
rootCanvasGO.transform.SetParent(rootGO.transform);
var nestedCanvas = new GameObject("Nested Canvas", typeof(Canvas), typeof(Image));
nestedCanvas.transform.SetParent(rootCanvasGO.transform);
var nestedCanvasCamera = new GameObject("Nested Canvas Camera", typeof(Camera));
nestedCanvasCamera.transform.SetParent(rootCanvasGO.transform);
var rootCanvas = rootCanvasGO.GetComponent<Canvas>();
rootCanvas.renderMode = RenderMode.WorldSpace;
rootCanvas.worldCamera = nestedCanvasCamera.GetComponent<Camera>();
if (!Directory.Exists("Assets/Resources/"))
Directory.CreateDirectory("Assets/Resources/");
UnityEditor.PrefabUtility.SaveAsPrefabAsset(rootGO, kPrefabPath);
GameObject.DestroyImmediate(rootGO);
#endif
}
[UnityTest]
[Description("[UI] Button does not interact after nested canvas is used(case 892913)")]
public IEnumerator WorldCanvas_CanFindCameraAfterDisablingAndEnablingRootCanvas()
{
m_GO1 = Object.Instantiate(Resources.Load("NestedCanvasPrefab"));
yield return null;
var nestedCanvasGo = GameObject.Find("Nested Canvas");
var nestedCanvas = nestedCanvasGo.GetComponent<Canvas>();
Assert.IsNotNull(nestedCanvas.worldCamera, "Expected the nested canvas worldCamera to NOT be null after loading the scene.");
nestedCanvasGo.transform.parent.gameObject.SetActive(false);
nestedCanvasGo.transform.parent.gameObject.SetActive(true);
Assert.IsNotNull(nestedCanvas.worldCamera, "Expected the nested canvas worldCamera to NOT be null after the parent canvas has been re-enabled.");
}
[UnityTest]
public IEnumerator WorldCanvas_CanFindTheSameCameraAfterDisablingAndEnablingRootCanvas()
{
m_GO2 = Object.Instantiate(Resources.Load("NestedCanvasPrefab"));
yield return null;
var nestedCanvasGo = GameObject.Find("Nested Canvas");
var nestedCanvas = nestedCanvasGo.GetComponent<Canvas>();
var worldCamera = nestedCanvas.worldCamera;
nestedCanvasGo.transform.parent.gameObject.SetActive(false);
nestedCanvasGo.transform.parent.gameObject.SetActive(true);
Assert.AreEqual(worldCamera, nestedCanvas.worldCamera, "Expected the same world camera to be returned after the root canvas was disabled and then re-enabled.");
}
[UnityTest]
public IEnumerator NestedCanvasHasProperInheritedAlpha()
{
GameObject root = (GameObject)Object.Instantiate(Resources.Load("NestedCanvasPrefab"));
CanvasGroup group = root.GetComponentInChildren<CanvasGroup>();
Image image = root.GetComponentInChildren<Image>();
group.alpha = 0.5f;
yield return null;
Assert.True(image.canvasRenderer.GetInheritedAlpha() == 0.5f);
GameObject.DestroyImmediate(root);
}
[TearDown]
public void TearDown()
{
GameObject.DestroyImmediate(m_GO1);
GameObject.DestroyImmediate(m_GO2);
}
[OneTimeTearDown]
public void OneTimeTearDown()
{
#if UNITY_EDITOR
AssetDatabase.DeleteAsset(kPrefabPath);
#endif
}
}

Some files were not shown because too many files have changed in this diff Show More