Skip to content

Commit b7611e5

Browse files
authored
Merge pull request #121 from Unity-Technologies/uni-24602-fix-fbxprefab-tests
Uni 24602 fix fbxprefab tests
2 parents f75d07a + 5b14812 commit b7611e5

File tree

2 files changed

+108
-52
lines changed

2 files changed

+108
-52
lines changed

Assets/FbxExporters/Editor/UnitTests/ExporterTestBase.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,11 @@ namespace FbxExporters.UnitTests
1717
public abstract class ExporterTestBase
1818
{
1919
/// <summary>
20-
/// Sleep an amount of time (in ms) so we can safely assume that the timestamp on an fbx will change.
20+
/// Sleep an amount of time (in ms) so we can safely assume that the
21+
/// timestamp on an fbx will change.
2122
/// </summary>
2223
public void SleepForFileTimestamp() {
23-
System.Threading.Thread.Sleep(1000);
24+
System.Threading.Thread.Sleep(100);
2425
}
2526

2627
private string _testDirectory;

Assets/FbxExporters/Editor/UnitTests/FbxPrefabTest.cs

Lines changed: 105 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
using UnityEngine.TestTools;
44
using NUnit.Framework;
55
using System.Collections.Generic;
6+
using System.Linq;
67

78
namespace FbxExporters.UnitTests
89
{
@@ -12,6 +13,8 @@ public class FbxPrefabTest : ExporterTestBase
1213
FbxPrefab.FbxRepresentation m_originalRep;
1314

1415
GameObject m_source; // the fbx model
16+
FbxPrefab.FbxRepresentation m_originalHistory;
17+
1518
GameObject m_autoPrefab; // prefab that auto-updates
1619
GameObject m_manualPrefab; // prefab that doesn't auto-update
1720

@@ -49,61 +52,87 @@ void OnUpdate(FbxPrefab prefabInstance, IEnumerable<GameObject> updated)
4952
}
5053
}
5154

55+
static KeyValuePair<string, FbxPrefab.FbxRepresentation> StackItem(
56+
string name, FbxPrefab.FbxRepresentation rep)
57+
{
58+
return new KeyValuePair<string, FbxPrefab.FbxRepresentation>(name, rep);
59+
}
60+
5261
public static void AssertAreIdentical(
5362
FbxPrefab.FbxRepresentation a,
5463
FbxPrefab.FbxRepresentation b) {
5564
// A bit of a laborious comparison scheme. This is due to the
5665
// round-trip through FBX causing tiny errors in the transforms.
57-
var astack = new List<FbxPrefab.FbxRepresentation> ();
58-
astack.Add(a);
59-
var bstack = new List<FbxPrefab.FbxRepresentation> ();
60-
bstack.Add(b);
66+
var astack = new List<KeyValuePair<string, FbxPrefab.FbxRepresentation>> ();
67+
astack.Add(StackItem("(root)", a));
68+
var bstack = new List<KeyValuePair<string, FbxPrefab.FbxRepresentation>> ();
69+
bstack.Add(StackItem("(root)", b));
6170

6271
var aDummy = new GameObject("aDummy").transform;
6372
var bDummy = new GameObject("bDummy").transform;
6473
while (astack.Count > 0) {
6574
Assert.AreEqual(astack.Count, bstack.Count); // should never fail
66-
a = astack[astack.Count - 1]; astack.RemoveAt(astack.Count - 1);
67-
b = bstack[bstack.Count - 1]; bstack.RemoveAt(bstack.Count - 1);
75+
var aKvp = astack[astack.Count - 1]; astack.RemoveAt(astack.Count - 1);
76+
var bKvp = bstack[bstack.Count - 1]; bstack.RemoveAt(bstack.Count - 1);
77+
78+
var aName = aKvp.Key;
79+
var bName = bKvp.Key;
80+
Assert.AreEqual(aName, bName);
81+
82+
a = aKvp.Value;
83+
b = bKvp.Value;
6884

6985
// Verify that they have the same children (by name).
7086
var achildren = a.ChildNames;
7187
var bchildren = b.ChildNames;
72-
Assert.That(achildren, Is.EquivalentTo(bchildren));
88+
Assert.That(bchildren, Is.EquivalentTo(achildren), aName + " children");
7389

74-
// Add the children to each stack.
90+
// Add the children to each stack. It's important to get the
91+
// same order for both stacks.
7592
foreach(var child in achildren) {
76-
astack.Add(a.GetChild(child));
77-
bstack.Add(b.GetChild(child));
93+
astack.Add(StackItem(child, a.GetChild(child)));
94+
bstack.Add(StackItem(child, b.GetChild(child)));
7895
}
7996

8097
// Verify that they have the same components.
8198
var atypes = a.ComponentTypes;
8299
var btypes = b.ComponentTypes;
83-
Assert.That(atypes, Is.EquivalentTo(btypes));
100+
101+
Assert.That(btypes, Is.EquivalentTo(atypes), aName + " component types");
84102

85103
foreach(var t in atypes) {
86104
var avalues = a.GetComponentValues(t);
87105
var bvalues = b.GetComponentValues(t);
88-
Assert.AreEqual(avalues.Count, bvalues.Count);
89-
90-
if (t != "UnityEngine.Transform") {
91-
Assert.AreEqual(avalues, bvalues);
92-
} else {
106+
Assert.AreEqual(avalues.Count, bvalues.Count, aName + " component multiplicity");
107+
108+
//
109+
// TODO: test that the values match up.
110+
// Exceptions:
111+
// - Transforms we expect small changes.
112+
// - MeshFilter and MeshRenderer we expect guids to change
113+
//
114+
if (t == "UnityEngine.MeshFilter") {
115+
// TODO: test that everything but the guid matches
116+
} else if (t == "UnityEngine.MeshRenderer") {
117+
// TODO: test that everything but the guid matches
118+
} else if (t == "UnityEngine.Transform") {
93119
// Verify that the transforms are nearly (but don't require bitwise) equal.
94120
EditorJsonUtility.FromJsonOverwrite(avalues[0], aDummy);
95121
EditorJsonUtility.FromJsonOverwrite(bvalues[0], bDummy);
96122
var dist = Vector3.Distance(aDummy.localPosition, bDummy.localPosition);
97-
Assert.That(dist, Is.LessThan(1e-6), () => string.Format("position {0} vs {1} dist {2}",
98-
aDummy.localPosition, bDummy.localPosition, dist));
123+
Assert.That(dist, Is.LessThan(1e-6), () => string.Format("{3}: position {0} vs {1} dist {2}",
124+
aDummy.localPosition, bDummy.localPosition, dist, aName));
99125

100126
dist = Vector3.Distance(aDummy.localScale, bDummy.localScale);
101-
Assert.That(dist, Is.LessThan(1e-6), () => string.Format("scale {0} vs {1} dist {2}",
102-
aDummy.localScale, bDummy.localScale, dist));
127+
Assert.That(dist, Is.LessThan(1e-6), () => string.Format("{3}: scale {0} vs {1} dist {2}",
128+
aDummy.localScale, bDummy.localScale, dist, aName));
103129

104130
dist = Quaternion.Angle(aDummy.localRotation, bDummy.localRotation);
105-
Assert.That(dist, Is.LessThan(1e-6), () => string.Format("rotation {0} vs {1} angle {2}",
106-
aDummy.localRotation.eulerAngles, bDummy.localRotation.eulerAngles, dist));
131+
Assert.That(dist, Is.LessThan(1e-6), () => string.Format("{3}: rotation {0} vs {1} angle {2}",
132+
aDummy.localRotation.eulerAngles, bDummy.localRotation.eulerAngles, dist, aName));
133+
} else {
134+
// Default: test that the components are precisely identical.
135+
Assert.AreEqual(avalues, bvalues, string.Format("{0}: type {1}", aName, t));
107136
}
108137
}
109138
}
@@ -126,6 +155,7 @@ public void Init() {
126155
var fbxAsset = FbxExporters.Editor.ModelExporter.ExportObject(
127156
GetRandomFbxFilePath(), m_original);
128157
m_source = AssetDatabase.LoadMainAssetAtPath(fbxAsset) as GameObject;
158+
m_originalHistory = Rep(m_source);
129159
Assert.IsTrue(m_source);
130160

131161
// Create an FbxPrefab linked to the Fbx file. Make it auto-update.
@@ -161,12 +191,19 @@ FbxPrefab.FbxRepresentation History(GameObject go) {
161191

162192
GameObject ModifySourceFbx()
163193
{
164-
// Modify the source fbx file:
194+
// Generate this change:
165195
// - delete parent1
196+
// - move parent2
166197
// - add parent3
167-
var newModel = PrefabUtility.InstantiatePrefab(m_source) as GameObject;
198+
// Simulate that we're doing this in Maya, so parent3 doesn't come
199+
// with a collider.
200+
var newModel = CreateHierarchy();
168201
GameObject.DestroyImmediate(newModel.transform.Find("Parent1").gameObject);
169-
CreateGameObject("Parent3", newModel.transform);
202+
var parent3 = CreateGameObject("Parent3", newModel.transform);
203+
Object.DestroyImmediate(parent3.GetComponent<BoxCollider>());
204+
205+
var parent2 = newModel.transform.Find("Parent2");
206+
parent2.localPosition += new Vector3(1,2,3);
170207

171208
// Export it to clobber the old FBX file.
172209
// Sleep one second first to make sure the timestamp differs
@@ -183,47 +220,48 @@ GameObject ModifySourceFbx()
183220

184221
[Test]
185222
public void BasicTest() {
186-
// Check the history is good at the start
223+
// Verify we start in the right place.
187224
AssertAreIdentical(m_originalRep, Rep(m_manualPrefab));
188225
AssertAreIdentical(m_originalRep, Rep(m_autoPrefab));
189-
AssertAreIdentical(m_originalRep, History(m_manualPrefab));
190-
AssertAreIdentical(m_originalRep, History(m_autoPrefab));
226+
227+
// Verify history is as we expect. It differs from the originalRep
228+
// in that it doesn't have box colliders.
229+
AssertAreIdentical(m_originalHistory, History(m_manualPrefab));
230+
AssertAreIdentical(m_originalHistory, History(m_autoPrefab));
191231

192232
FbxPrefab.FbxRepresentation newHierarchy;
233+
FbxPrefab.FbxRepresentation newHistory;
193234
using(var updateSet = new UpdateListener(m_autoPrefab)) {
194235
Debug.Log("Testing auto update");
195236
newHierarchy = Rep(ModifySourceFbx());
237+
newHistory = Rep(m_source);
196238
AssertAreDifferent(m_originalRep, newHierarchy);
197239

198-
// Make sure the fbx source changed.
199-
AssertAreDifferent(m_originalRep, Rep(m_source));
200-
AssertAreIdentical(newHierarchy, Rep(m_source));
240+
// Make sure the fbx source changed (testing the test).
241+
AssertAreDifferent(m_originalHistory, Rep(m_source));
201242

202-
// Make sure the auto-update prefab changed.
203-
AssertAreIdentical(newHierarchy, Rep(m_autoPrefab));
204-
AssertAreIdentical(newHierarchy, History(m_autoPrefab));
205-
206-
// Make sure the manual-update prefab didn't.
243+
// Make sure the manual-update prefab didn't change.
207244
AssertAreIdentical(m_originalRep, Rep(m_manualPrefab));
208-
AssertAreIdentical(m_originalRep, History(m_manualPrefab));
245+
AssertAreIdentical(m_originalHistory, History(m_manualPrefab));
209246

210-
// Make sure we got the right changes.
247+
// Make sure we got the right changes. Parent2 got its
248+
// transform changed, Parent3 was created.
211249
Assert.AreEqual (1, updateSet.NumUpdates);
212250
Assert.That (updateSet.Updated, Is.EquivalentTo (new string [] {
213-
// TODO: UNI-24579 - we should only be seeing Parent3 here,
214-
// the other two are for transform changes, but
215-
// they shouldn't have changed at all
216-
"Parent2", "Parent3", "Child3"
251+
"Parent2", "Parent3"
217252
}
218253
));
254+
255+
// Make sure the auto-update prefab changed.
256+
AssertAreIdentical(newHierarchy, Rep(m_autoPrefab));
219257
}
220258

221259
// Manual update, make sure it updated.
222260
Debug.Log("Testing manual update");
223261
var manualPrefabComponent = m_manualPrefab.GetComponent<FbxPrefab>();
224262
manualPrefabComponent.SyncPrefab();
225263
AssertAreIdentical(newHierarchy, Rep(m_manualPrefab));
226-
AssertAreIdentical(newHierarchy, History(m_manualPrefab));
264+
AssertAreIdentical(newHistory, History(m_manualPrefab));
227265

228266
// Check some corner cases.
229267
Assert.AreEqual(m_source, manualPrefabComponent.GetFbxAsset());
@@ -245,10 +283,10 @@ public void BasicTest() {
245283
Assert.That( () => manualPrefabComponent.SetSourceModel(null), Throws.Nothing );
246284
Assert.IsNull(manualPrefabComponent.GetFbxAsset());
247285
AssertAreIdentical(newHierarchy, Rep(m_manualPrefab));
248-
AssertAreIdentical(newHierarchy, History(m_manualPrefab));
286+
AssertAreIdentical(newHistory, History(m_manualPrefab));
249287
Assert.That( () => manualPrefabComponent.SyncPrefab(), Throws.Nothing );
250288
AssertAreIdentical(newHierarchy, Rep(m_manualPrefab));
251-
AssertAreIdentical(newHierarchy, History(m_manualPrefab));
289+
AssertAreIdentical(newHistory, History(m_manualPrefab));
252290

253291
// Switch to some other model, which looks like the original model
254292
// (but is a totally different file). This will cause an update
@@ -259,24 +297,41 @@ public void BasicTest() {
259297
Assert.IsTrue(newSource);
260298
Debug.Log("Testing SetSourceModel relink");
261299
manualPrefabComponent.SetSourceModel(newSource);
262-
AssertAreIdentical(m_originalRep, Rep(m_manualPrefab));
263-
AssertAreIdentical(m_originalRep, History(m_manualPrefab));
300+
301+
// Generate the answer we expect: the original but Parent1 and
302+
// hierarchy are without collider. That's because we deleted them,
303+
// and got them back. Parent2 should be back to the origin.
304+
var expectedHierarchy = GameObject.Instantiate(m_original);
305+
var parent1 = expectedHierarchy.transform.Find("Parent1");
306+
foreach(var collider in parent1.GetComponentsInChildren<BoxCollider>()) {
307+
Object.DestroyImmediate(collider);
308+
}
309+
var expectedRep = Rep(expectedHierarchy);
310+
var expectedHistory = m_originalHistory;
311+
312+
AssertAreIdentical(expectedHistory, History(m_manualPrefab));
313+
AssertAreIdentical(expectedRep, Rep(m_manualPrefab));
264314
}
265315

266316
[Test]
267317
public void ManualToAuto() {
268318
// Check what happens when we go from manual to auto-update.
319+
Debug.Log("ManualToAuto: modifying source");
269320
var newHierarchy = Rep(ModifySourceFbx());
321+
var newHistory = Rep(m_source);
322+
270323
AssertAreIdentical(m_originalRep, Rep(m_manualPrefab));
271-
AssertAreIdentical(m_originalRep, History(m_manualPrefab));
324+
AssertAreIdentical(m_originalHistory, History(m_manualPrefab));
272325

326+
Debug.Log("ManualToAuto: setting manual to manual");
273327
m_manualPrefab.GetComponent<FbxPrefab>().SetAutoUpdate(false);
274328
AssertAreIdentical(m_originalRep, Rep(m_manualPrefab));
275-
AssertAreIdentical(m_originalRep, History(m_manualPrefab));
329+
AssertAreIdentical(m_originalHistory, History(m_manualPrefab));
276330

331+
Debug.Log("ManualToAuto: setting manual to auto");
277332
m_manualPrefab.GetComponent<FbxPrefab>().SetAutoUpdate(true);
278333
AssertAreIdentical(newHierarchy, Rep(m_manualPrefab));
279-
AssertAreIdentical(newHierarchy, History(m_manualPrefab));
334+
AssertAreIdentical(newHistory, History(m_manualPrefab));
280335
}
281336
}
282337

0 commit comments

Comments
 (0)