mirror of
https://github.com/bdunderscore/modular-avatar.git
synced 2025-01-01 12:15:05 +08:00
826 lines
31 KiB
C#
826 lines
31 KiB
C#
#if MA_VRCSDK3_AVATARS
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using nadena.dev.modular_avatar.core;
|
|
using nadena.dev.modular_avatar.core.editor;
|
|
using nadena.dev.modular_avatar.core.editor.menu;
|
|
using nadena.dev.modular_avatar.core.menu;
|
|
using NUnit.Framework;
|
|
using UnityEditor;
|
|
using UnityEngine;
|
|
using VRC.SDK3.Avatars.Components;
|
|
using VRC.SDK3.Avatars.ScriptableObjects;
|
|
using Object = UnityEngine.Object;
|
|
using Random = UnityEngine.Random;
|
|
|
|
namespace modular_avatar_tests.VirtualMenuTests
|
|
{
|
|
public class VirtualMenuTests : TestBase
|
|
{
|
|
private Texture2D testTex;
|
|
private List<UnityEngine.Object> toDestroy;
|
|
private int controlIndex;
|
|
|
|
public override void Setup()
|
|
{
|
|
base.Setup();
|
|
testTex = new Texture2D(1, 1);
|
|
toDestroy = new List<UnityEngine.Object>();
|
|
controlIndex = 0;
|
|
}
|
|
|
|
public override void Teardown()
|
|
{
|
|
base.Teardown();
|
|
Object.DestroyImmediate(testTex);
|
|
foreach (var obj in toDestroy)
|
|
{
|
|
Object.DestroyImmediate(obj);
|
|
}
|
|
}
|
|
|
|
private T Create<T>(string name = null) where T : ScriptableObject
|
|
{
|
|
if (name == null) name = GUID.Generate().ToString();
|
|
|
|
T val = ScriptableObject.CreateInstance<T>();
|
|
val.name = name;
|
|
|
|
toDestroy.Add(val);
|
|
|
|
return val;
|
|
}
|
|
|
|
[Test]
|
|
public void TestEmptyMenu()
|
|
{
|
|
var virtualMenu = new VirtualMenu(null);
|
|
virtualMenu.FreezeMenu();
|
|
|
|
Assert.AreEqual(1, virtualMenu.ResolvedMenu.Count);
|
|
var root = virtualMenu.ResolvedMenu[RootMenu.Instance];
|
|
Assert.AreEqual(0, root.Controls.Count);
|
|
Assert.AreSame(RootMenu.Instance, root.NodeKey);
|
|
}
|
|
|
|
[Test]
|
|
public void TestBasicMenu()
|
|
{
|
|
var rootMenu = Create<VRCExpressionsMenu>();
|
|
|
|
rootMenu.controls = new List<VRCExpressionsMenu.Control>()
|
|
{
|
|
GenerateTestControl(),
|
|
GenerateTestControl()
|
|
};
|
|
|
|
var virtualMenu = new VirtualMenu(rootMenu);
|
|
virtualMenu.FreezeMenu();
|
|
|
|
Assert.AreEqual(1, virtualMenu.ResolvedMenu.Count);
|
|
var root = virtualMenu.NodeForMenuAsset(rootMenu);
|
|
Assert.AreEqual(2, root.Controls.Count);
|
|
Assert.AreSame(rootMenu, root.SourceMenu());
|
|
AssertControlEquals(rootMenu.controls[0], root.Controls[0]);
|
|
AssertControlEquals(rootMenu.controls[1], root.Controls[1]);
|
|
}
|
|
|
|
[Test]
|
|
public void TestNativeMenuWithCycles()
|
|
{
|
|
var rootMenu = Create<VRCExpressionsMenu>("root");
|
|
var sub1 = Create<VRCExpressionsMenu>("sub1");
|
|
var sub2 = Create<VRCExpressionsMenu>("sub2");
|
|
|
|
rootMenu.controls = new List<VRCExpressionsMenu.Control>()
|
|
{
|
|
GenerateTestSubmenu(sub1)
|
|
};
|
|
|
|
sub1.controls = new List<VRCExpressionsMenu.Control>()
|
|
{
|
|
GenerateTestSubmenu(sub2)
|
|
};
|
|
|
|
sub2.controls = new List<VRCExpressionsMenu.Control>()
|
|
{
|
|
GenerateTestSubmenu(rootMenu)
|
|
};
|
|
|
|
var virtualMenu = new VirtualMenu(rootMenu);
|
|
virtualMenu.FreezeMenu();
|
|
|
|
Assert.AreEqual(3, virtualMenu.ResolvedMenu.Count);
|
|
var rootNode = virtualMenu.ResolvedMenu[virtualMenu.RootMenuKey];
|
|
var sub1Node = virtualMenu.NodeForMenuAsset(sub1);
|
|
var sub2Node = virtualMenu.NodeForMenuAsset(sub2);
|
|
|
|
Assert.AreEqual(1, rootNode.Controls.Count);
|
|
Assert.AreSame(virtualMenu.RootMenuKey, rootNode.NodeKey);
|
|
Assert.AreSame(sub1Node, rootNode.Controls[0].SubmenuNode);
|
|
Assert.IsNull(rootNode.Controls[0].subMenu);
|
|
|
|
Assert.AreEqual(1, sub1Node.Controls.Count);
|
|
Assert.AreSame(sub1, sub1Node.SourceMenu());
|
|
Assert.AreSame(sub2Node, sub1Node.Controls[0].SubmenuNode);
|
|
Assert.IsNull(sub1Node.Controls[0].subMenu);
|
|
|
|
Assert.AreEqual(1, sub2Node.Controls.Count);
|
|
Assert.AreSame(sub2, sub2Node.SourceMenu());
|
|
Assert.AreSame(rootNode, sub2Node.Controls[0].SubmenuNode);
|
|
Assert.IsNull(sub2Node.Controls[0].subMenu);
|
|
}
|
|
|
|
[Test]
|
|
public void TestBasicMenuInstaller()
|
|
{
|
|
VRCExpressionsMenu testMenu = Create<VRCExpressionsMenu>();
|
|
testMenu.controls = new List<VRCExpressionsMenu.Control>()
|
|
{
|
|
GenerateTestControl(),
|
|
GenerateTestControl()
|
|
};
|
|
|
|
var installer = CreateInstaller("test");
|
|
installer.menuToAppend = testMenu;
|
|
|
|
var virtualMenu = new VirtualMenu(null);
|
|
virtualMenu.RegisterMenuInstaller(installer);
|
|
virtualMenu.FreezeMenu();
|
|
|
|
Assert.AreEqual(1, virtualMenu.ResolvedMenu.Count);
|
|
var root = virtualMenu.ResolvedMenu[RootMenu.Instance];
|
|
Assert.AreEqual(2, root.Controls.Count);
|
|
Assert.AreSame(RootMenu.Instance, root.NodeKey);
|
|
AssertControlEquals(testMenu.controls[0], root.Controls[0]);
|
|
AssertControlEquals(testMenu.controls[1], root.Controls[1]);
|
|
}
|
|
|
|
[Test]
|
|
public void TestMenuItemInstaller()
|
|
{
|
|
var installer = CreateInstaller("test");
|
|
installer.menuToAppend = Create<VRCExpressionsMenu>();
|
|
|
|
var item = installer.gameObject.AddComponent<ModularAvatarMenuItem>();
|
|
item.Control = GenerateTestControl();
|
|
|
|
var virtualMenu = new VirtualMenu(null);
|
|
virtualMenu.RegisterMenuInstaller(installer);
|
|
virtualMenu.FreezeMenu();
|
|
|
|
item.Control.name = "test";
|
|
|
|
Assert.AreEqual(1, virtualMenu.ResolvedMenu.Count);
|
|
var root = virtualMenu.ResolvedMenu[RootMenu.Instance];
|
|
Assert.AreEqual(1, root.Controls.Count);
|
|
Assert.AreSame(RootMenu.Instance, root.NodeKey);
|
|
AssertControlEquals(item.Control, root.Controls[0]);
|
|
}
|
|
|
|
[Test]
|
|
public void TestInstallOntoInstaller()
|
|
{
|
|
var installer_a = CreateInstaller("a");
|
|
var installer_b = CreateInstaller("b");
|
|
var installer_c = CreateInstaller("c");
|
|
|
|
var menu_a = Create<VRCExpressionsMenu>();
|
|
var menu_b = Create<VRCExpressionsMenu>();
|
|
var menu_c = Create<VRCExpressionsMenu>();
|
|
|
|
menu_a.controls = new List<VRCExpressionsMenu.Control>()
|
|
{
|
|
GenerateTestControl()
|
|
};
|
|
menu_b.controls = new List<VRCExpressionsMenu.Control>()
|
|
{
|
|
GenerateTestControl()
|
|
};
|
|
menu_c.controls = new List<VRCExpressionsMenu.Control>()
|
|
{
|
|
GenerateTestControl()
|
|
};
|
|
|
|
installer_a.menuToAppend = menu_a;
|
|
installer_b.menuToAppend = menu_b;
|
|
installer_c.menuToAppend = menu_c;
|
|
|
|
installer_c.installTargetMenu = installer_a.menuToAppend;
|
|
|
|
VirtualMenu virtualMenu = new VirtualMenu(null);
|
|
virtualMenu.RegisterMenuInstaller(installer_a);
|
|
virtualMenu.RegisterMenuInstaller(installer_b);
|
|
virtualMenu.RegisterMenuInstaller(installer_c);
|
|
|
|
virtualMenu.FreezeMenu();
|
|
Assert.AreEqual(1, virtualMenu.ResolvedMenu.Count);
|
|
var rootMenu = virtualMenu.ResolvedMenu[RootMenu.Instance];
|
|
Assert.AreEqual(3, rootMenu.Controls.Count);
|
|
Assert.AreSame(RootMenu.Instance, rootMenu.NodeKey);
|
|
AssertControlEquals(menu_a.controls[0], rootMenu.Controls[0]);
|
|
AssertControlEquals(menu_c.controls[0], rootMenu.Controls[1]);
|
|
AssertControlEquals(menu_b.controls[0], rootMenu.Controls[2]);
|
|
}
|
|
|
|
[Test]
|
|
public void TestInstallSubmenu()
|
|
{
|
|
var installer_a = CreateInstaller("a");
|
|
|
|
var menu_a = Create<VRCExpressionsMenu>("a");
|
|
var menu_b = Create<VRCExpressionsMenu>("b");
|
|
menu_a.controls = new List<VRCExpressionsMenu.Control>()
|
|
{
|
|
GenerateTestSubmenu(menu_b)
|
|
};
|
|
menu_b.controls = new List<VRCExpressionsMenu.Control>()
|
|
{
|
|
GenerateTestControl()
|
|
};
|
|
|
|
installer_a.menuToAppend = menu_a;
|
|
|
|
VirtualMenu virtualMenu = new VirtualMenu(null);
|
|
virtualMenu.RegisterMenuInstaller(installer_a);
|
|
|
|
virtualMenu.FreezeMenu();
|
|
|
|
Assert.AreEqual(2, virtualMenu.ResolvedMenu.Count);
|
|
var rootMenu = virtualMenu.ResolvedMenu[RootMenu.Instance];
|
|
var subMenu = virtualMenu.NodeForMenuAsset(menu_b);
|
|
Assert.AreSame(subMenu, rootMenu.Controls[0].SubmenuNode);
|
|
Assert.AreSame(RootMenu.Instance, rootMenu.NodeKey);
|
|
Assert.AreSame(menu_b, ((ValueTuple<object, object>) subMenu.NodeKey).Item1);
|
|
Assert.AreEqual(1, subMenu.Controls.Count);
|
|
AssertControlEquals(menu_b.controls[0], subMenu.Controls[0]);
|
|
}
|
|
|
|
[Test]
|
|
public void TestYankInstaller()
|
|
{
|
|
var installer_a = CreateInstaller("a");
|
|
var installer_b = CreateInstaller("b");
|
|
|
|
var menu_a = Create<VRCExpressionsMenu>("a");
|
|
menu_a.controls = new List<VRCExpressionsMenu.Control>()
|
|
{
|
|
GenerateTestControl()
|
|
};
|
|
installer_a.menuToAppend = menu_a;
|
|
|
|
var item = installer_b.gameObject.AddComponent<ModularAvatarMenuItem>();
|
|
item.Control = GenerateTestControl();
|
|
item.Control.type = VRCExpressionsMenu.Control.ControlType.SubMenu;
|
|
item.MenuSource = SubmenuSource.Children;
|
|
|
|
var child = CreateChild(item.gameObject, "child");
|
|
var childItem = child.AddComponent<ModularAvatarMenuInstallTarget>();
|
|
childItem.installer = installer_a;
|
|
|
|
VirtualMenu virtualMenu = new VirtualMenu(null);
|
|
virtualMenu.RegisterMenuInstaller(installer_a);
|
|
virtualMenu.RegisterMenuInstaller(installer_b);
|
|
virtualMenu.RegisterMenuInstallTarget(childItem);
|
|
|
|
virtualMenu.FreezeMenu();
|
|
item.Control.name = "b";
|
|
|
|
Assert.AreEqual(2, virtualMenu.ResolvedMenu.Count);
|
|
var rootMenu = virtualMenu.ResolvedMenu[RootMenu.Instance];
|
|
var item_node = virtualMenu.ResolvedMenu[new MenuNodesUnder(item.gameObject)];
|
|
Assert.AreEqual(1, rootMenu.Controls.Count);
|
|
Assert.AreSame(RootMenu.Instance, rootMenu.NodeKey);
|
|
AssertControlEquals(item.Control, rootMenu.Controls[0]);
|
|
Assert.AreSame(item_node, rootMenu.Controls[0].SubmenuNode);
|
|
|
|
Assert.AreEqual(1, item_node.Controls.Count);
|
|
Assert.AreEqual(new MenuNodesUnder(item.gameObject), item_node.NodeKey);
|
|
AssertControlEquals(menu_a.controls[0], item_node.Controls[0]);
|
|
}
|
|
|
|
[Test]
|
|
public void WhenMenuInstallersLoop_LoopIsTerminated()
|
|
{
|
|
var installer_a = CreateInstaller("a");
|
|
var installer_b = CreateInstaller("b");
|
|
|
|
var menu_a = Create<VRCExpressionsMenu>("a");
|
|
menu_a.controls = new List<VRCExpressionsMenu.Control>()
|
|
{
|
|
GenerateTestControl()
|
|
};
|
|
installer_a.menuToAppend = menu_a;
|
|
|
|
var menu_b = Create<VRCExpressionsMenu>("b");
|
|
menu_b.controls = new List<VRCExpressionsMenu.Control>()
|
|
{
|
|
GenerateTestControl()
|
|
};
|
|
installer_b.menuToAppend = menu_b;
|
|
|
|
installer_a.installTargetMenu = menu_b;
|
|
installer_b.installTargetMenu = menu_a;
|
|
|
|
VirtualMenu virtualMenu = new VirtualMenu(menu_a);
|
|
virtualMenu.RegisterMenuInstaller(installer_a);
|
|
virtualMenu.RegisterMenuInstaller(installer_b);
|
|
|
|
virtualMenu.FreezeMenu();
|
|
|
|
Assert.AreEqual(1, virtualMenu.ResolvedMenu.Count);
|
|
var rootMenu = virtualMenu.NodeForMenuAsset(menu_a);
|
|
Assert.AreEqual(3, rootMenu.Controls.Count);
|
|
}
|
|
|
|
[Test]
|
|
public void TestExternalSubmenuSource_WithMenuInstaller()
|
|
{
|
|
var installer_a = CreateInstaller("a");
|
|
var installer_b = CreateInstaller("b");
|
|
|
|
var menu_a = Create<VRCExpressionsMenu>("a");
|
|
menu_a.controls = new List<VRCExpressionsMenu.Control>()
|
|
{
|
|
GenerateTestControl()
|
|
};
|
|
|
|
var menu_b = Create<VRCExpressionsMenu>("b");
|
|
menu_b.controls = new List<VRCExpressionsMenu.Control>()
|
|
{
|
|
GenerateTestControl()
|
|
};
|
|
|
|
var item_a = installer_a.gameObject.AddComponent<ModularAvatarMenuItem>();
|
|
item_a.Control = GenerateTestControl();
|
|
item_a.Control.type = VRCExpressionsMenu.Control.ControlType.SubMenu;
|
|
item_a.MenuSource = SubmenuSource.MenuAsset;
|
|
item_a.Control.subMenu = menu_a;
|
|
|
|
installer_b.menuToAppend = menu_b;
|
|
installer_b.installTargetMenu = menu_a;
|
|
|
|
VirtualMenu virtualMenu = new VirtualMenu(null);
|
|
virtualMenu.RegisterMenuInstaller(installer_a);
|
|
virtualMenu.RegisterMenuInstaller(installer_b);
|
|
|
|
virtualMenu.FreezeMenu();
|
|
|
|
var rootNode = virtualMenu.ResolvedMenu[RootMenu.Instance];
|
|
Assert.AreEqual(VRCExpressionsMenu.Control.ControlType.SubMenu, rootNode.Controls[0].type);
|
|
var menu_a_node = rootNode.Controls[0].SubmenuNode;
|
|
AssertControlEquals(menu_a.controls[0], menu_a_node.Controls[0]);
|
|
AssertControlEquals(menu_b.controls[0], menu_a_node.Controls[1]);
|
|
}
|
|
|
|
[Test]
|
|
public void MenuItem_NestedSubmenuNodes()
|
|
{
|
|
var installer_a = CreateInstaller("root");
|
|
var root_item = installer_a.gameObject.AddComponent<ModularAvatarMenuItem>();
|
|
root_item.Control = GenerateTestControl();
|
|
root_item.Control.type = VRCExpressionsMenu.Control.ControlType.SubMenu;
|
|
root_item.MenuSource = SubmenuSource.Children;
|
|
|
|
var mid_obj = CreateChild(root_item.gameObject, "mid");
|
|
var mid_item = mid_obj.AddComponent<ModularAvatarMenuItem>();
|
|
mid_item.Control = GenerateTestControl();
|
|
mid_item.Control.type = VRCExpressionsMenu.Control.ControlType.SubMenu;
|
|
mid_item.MenuSource = SubmenuSource.Children;
|
|
|
|
var leaf_obj = CreateChild(mid_obj, "leaf");
|
|
var leaf_item = leaf_obj.AddComponent<ModularAvatarMenuItem>();
|
|
leaf_item.Control = GenerateTestControl();
|
|
|
|
VirtualMenu virtualMenu = new VirtualMenu(null);
|
|
virtualMenu.RegisterMenuInstaller(installer_a);
|
|
|
|
virtualMenu.FreezeMenu();
|
|
|
|
var rootNode = virtualMenu.ResolvedMenu[RootMenu.Instance];
|
|
Assert.AreEqual(VRCExpressionsMenu.Control.ControlType.SubMenu, rootNode.Controls[0].type);
|
|
var mid_node = rootNode.Controls[0].SubmenuNode;
|
|
var leaf_node = mid_node.Controls[0].SubmenuNode;
|
|
|
|
Assert.AreEqual(1, rootNode.Controls.Count);
|
|
Assert.AreEqual(1, mid_node.Controls.Count);
|
|
Assert.AreEqual(1, leaf_node.Controls.Count);
|
|
|
|
root_item.Control.name = "root";
|
|
mid_item.Control.name = "mid";
|
|
leaf_item.Control.name = "leaf";
|
|
|
|
AssertControlEquals(root_item.Control, rootNode.Controls[0]);
|
|
AssertControlEquals(mid_item.Control, mid_node.Controls[0]);
|
|
AssertControlEquals(leaf_item.Control, leaf_node.Controls[0]);
|
|
}
|
|
|
|
[Test]
|
|
public void MenuItem_RemoteReference()
|
|
{
|
|
var installer_a = CreateInstaller("root");
|
|
var root_item = installer_a.gameObject.AddComponent<ModularAvatarMenuItem>();
|
|
|
|
var extern_root = CreateRoot("test");
|
|
var extern_obj = CreateChild(extern_root, "control");
|
|
var extern_item = extern_obj.AddComponent<ModularAvatarMenuItem>();
|
|
extern_item.Control = GenerateTestControl();
|
|
|
|
root_item.Control = GenerateTestControl();
|
|
root_item.Control.type = VRCExpressionsMenu.Control.ControlType.SubMenu;
|
|
root_item.MenuSource = SubmenuSource.Children;
|
|
root_item.menuSource_otherObjectChildren = extern_root;
|
|
|
|
VirtualMenu virtualMenu = new VirtualMenu(null);
|
|
virtualMenu.RegisterMenuInstaller(installer_a);
|
|
|
|
virtualMenu.FreezeMenu();
|
|
|
|
root_item.Control.name = "root";
|
|
extern_item.Control.name = "control";
|
|
|
|
var rootNode = virtualMenu.ResolvedMenu[RootMenu.Instance];
|
|
Assert.AreEqual(VRCExpressionsMenu.Control.ControlType.SubMenu, rootNode.Controls[0].type);
|
|
var extern_node = rootNode.Controls[0].SubmenuNode;
|
|
|
|
Assert.AreEqual(1, rootNode.Controls.Count);
|
|
Assert.AreEqual(1, extern_node.Controls.Count);
|
|
|
|
AssertControlEquals(root_item.Control, rootNode.Controls[0]);
|
|
AssertControlEquals(extern_item.Control, extern_node.Controls[0]);
|
|
}
|
|
|
|
[Test]
|
|
public void InstallerInstallsInstallTarget()
|
|
{
|
|
var installer_a = CreateInstaller("a");
|
|
var installer_b = CreateInstaller("b");
|
|
|
|
var menu_b = Create<VRCExpressionsMenu>("b");
|
|
menu_b.controls = new List<VRCExpressionsMenu.Control>()
|
|
{
|
|
GenerateTestControl()
|
|
};
|
|
installer_b.menuToAppend = menu_b;
|
|
|
|
var item_a = installer_a.gameObject.AddComponent<ModularAvatarMenuInstallTarget>();
|
|
item_a.installer = installer_b;
|
|
|
|
VirtualMenu virtualMenu = new VirtualMenu(null);
|
|
virtualMenu.RegisterMenuInstaller(installer_a);
|
|
virtualMenu.RegisterMenuInstaller(installer_b);
|
|
virtualMenu.RegisterMenuInstallTarget(item_a);
|
|
|
|
virtualMenu.FreezeMenu();
|
|
|
|
var rootNode = virtualMenu.ResolvedMenu[RootMenu.Instance];
|
|
Assert.AreEqual(1, rootNode.Controls.Count);
|
|
AssertControlEquals(menu_b.controls[0], rootNode.Controls[0]);
|
|
}
|
|
|
|
[Test]
|
|
public void TestSerializeMenu()
|
|
{
|
|
var menu_a = Create<VRCExpressionsMenu>("test");
|
|
var menu_b = Create<VRCExpressionsMenu>("test2");
|
|
var menu_c = Create<VRCExpressionsMenu>("test3");
|
|
|
|
menu_a.controls = new List<VRCExpressionsMenu.Control>()
|
|
{
|
|
GenerateTestControl(),
|
|
GenerateTestSubmenu(menu_b),
|
|
};
|
|
|
|
menu_b.controls = new List<VRCExpressionsMenu.Control>()
|
|
{
|
|
GenerateTestControl(),
|
|
GenerateTestSubmenu(menu_c),
|
|
};
|
|
|
|
menu_c.controls = new List<VRCExpressionsMenu.Control>()
|
|
{
|
|
GenerateTestSubmenu(menu_a),
|
|
};
|
|
|
|
var virtualMenu = new VirtualMenu(menu_a);
|
|
virtualMenu.FreezeMenu();
|
|
|
|
var assetSet = new HashSet<UnityEngine.Object>();
|
|
var serialized = virtualMenu.SerializeMenu(obj => assetSet.Add(obj));
|
|
|
|
Assert.AreEqual(3, assetSet.Count);
|
|
Assert.AreEqual(2, serialized.controls.Count);
|
|
|
|
AssertControlEquals(menu_a.controls[0], serialized.controls[0]);
|
|
AssertControlEquals(menu_a.controls[1], serialized.controls[1]);
|
|
|
|
var serialized_b = serialized.controls[1].subMenu;
|
|
Assert.AreEqual(2, serialized_b.controls.Count);
|
|
|
|
AssertControlEquals(menu_b.controls[0], serialized_b.controls[0]);
|
|
AssertControlEquals(menu_b.controls[1], serialized_b.controls[1]);
|
|
|
|
var serialized_c = serialized_b.controls[1].subMenu;
|
|
Assert.AreEqual(1, serialized_c.controls.Count);
|
|
|
|
AssertControlEquals(menu_c.controls[0], serialized_c.controls[0]);
|
|
|
|
Assert.True(assetSet.Contains(serialized));
|
|
Assert.True(assetSet.Contains(serialized_b));
|
|
Assert.True(assetSet.Contains(serialized_c));
|
|
}
|
|
|
|
[Test]
|
|
public void InstallTargetToInstallerToInstaller()
|
|
{
|
|
var menu_a = Create<VRCExpressionsMenu>();
|
|
var menu_b = Create<VRCExpressionsMenu>();
|
|
var menu_c = Create<VRCExpressionsMenu>();
|
|
menu_c.controls = new List<VRCExpressionsMenu.Control>
|
|
{
|
|
GenerateTestControl()
|
|
};
|
|
|
|
var node_a = CreateInstaller("root");
|
|
var item_a = node_a.gameObject.AddComponent<ModularAvatarMenuInstallTarget>();
|
|
|
|
var node_b = CreateInstaller("menu_b");
|
|
node_b.menuToAppend = menu_c;
|
|
|
|
var node_c = CreateInstaller("menu_c");
|
|
node_c.installTargetMenu = menu_c;
|
|
|
|
node_b.transform.parent = node_a.transform;
|
|
item_a.installer = node_b;
|
|
|
|
var virtualMenu = new VirtualMenu(menu_a);
|
|
virtualMenu.RegisterMenuInstallTarget(item_a);
|
|
virtualMenu.RegisterMenuInstaller(node_a);
|
|
virtualMenu.RegisterMenuInstaller(node_b);
|
|
virtualMenu.RegisterMenuInstaller(node_c);
|
|
|
|
virtualMenu.FreezeMenu();
|
|
|
|
var root = virtualMenu.NodeForMenuAsset(menu_a);
|
|
Assert.AreEqual(1, root.Controls.Count);
|
|
}
|
|
|
|
[Test]
|
|
public void multipleMenuAssets_areInstalledMultipleTimes()
|
|
{
|
|
var menu_a = Create<VRCExpressionsMenu>();
|
|
menu_a.controls.Add(new VRCExpressionsMenu.Control()
|
|
{
|
|
name = "control",
|
|
parameter = new VRCExpressionsMenu.Control.Parameter()
|
|
{
|
|
name = "p"
|
|
},
|
|
type = VRCExpressionsMenu.Control.ControlType.Toggle
|
|
});
|
|
|
|
var av_root = CreateRoot("avatar");
|
|
|
|
var node_a = CreateInstaller("menu_a");
|
|
node_a.transform.SetParent(av_root.transform);
|
|
node_a.menuToAppend = menu_a;
|
|
|
|
var node_b = CreateInstaller("menu_b");
|
|
node_b.transform.SetParent(av_root.transform);
|
|
node_b.menuToAppend = menu_a;
|
|
|
|
var virtualMenu = VirtualMenu.ForAvatar(av_root.GetComponent<VRCAvatarDescriptor>());
|
|
virtualMenu.FreezeMenu();
|
|
Assert.AreEqual(2, virtualMenu.RootMenuNode.Controls.Count);
|
|
}
|
|
|
|
[Test]
|
|
public void remapParams_isAppliedSeparatelyForEachDedup()
|
|
{
|
|
var menu_a = Create<VRCExpressionsMenu>();
|
|
menu_a.controls.Add(new VRCExpressionsMenu.Control()
|
|
{
|
|
name = "control",
|
|
parameter = new VRCExpressionsMenu.Control.Parameter()
|
|
{
|
|
name = "p"
|
|
},
|
|
type = VRCExpressionsMenu.Control.ControlType.Toggle
|
|
});
|
|
var menu_outer = Create<VRCExpressionsMenu>();
|
|
menu_outer.controls.Add(new VRCExpressionsMenu.Control()
|
|
{
|
|
name = "control",
|
|
type = VRCExpressionsMenu.Control.ControlType.SubMenu,
|
|
subMenu = menu_a
|
|
});
|
|
|
|
var av_root = CreateRoot("avatar");
|
|
|
|
var node_a = CreateInstaller("menu_a");
|
|
node_a.transform.SetParent(av_root.transform);
|
|
node_a.menuToAppend = menu_outer;
|
|
node_a.gameObject.AddComponent<ModularAvatarParameters>().parameters = new List<ParameterConfig>()
|
|
{
|
|
new ParameterConfig()
|
|
{
|
|
nameOrPrefix = "p",
|
|
remapTo = "a",
|
|
}
|
|
};
|
|
|
|
var node_b = CreateInstaller("menu_b");
|
|
node_b.transform.SetParent(av_root.transform);
|
|
node_b.menuToAppend = menu_outer;
|
|
node_b.gameObject.AddComponent<ModularAvatarParameters>().parameters = new List<ParameterConfig>()
|
|
{
|
|
new ParameterConfig()
|
|
{
|
|
nameOrPrefix = "p",
|
|
remapTo = "b",
|
|
}
|
|
};
|
|
|
|
var buildContext = new BuildContext(av_root.GetComponent<VRCAvatarDescriptor>());
|
|
new RenameParametersHook().OnPreprocessAvatar(av_root, buildContext);
|
|
|
|
var virtualMenu = VirtualMenu.ForAvatar(av_root.GetComponent<VRCAvatarDescriptor>(), buildContext);
|
|
virtualMenu.FreezeMenu();
|
|
|
|
Assert.IsTrue(virtualMenu.RootMenuNode.Controls.Any(c =>
|
|
c.SubmenuNode.Controls[0].parameter.name == "a"
|
|
));
|
|
Assert.IsTrue(virtualMenu.RootMenuNode.Controls.Any(c =>
|
|
c.SubmenuNode.Controls[0].parameter.name == "b"
|
|
));
|
|
}
|
|
|
|
[Test]
|
|
public void internalParameterTest()
|
|
{
|
|
var root = CreatePrefab("InternalParameterTest.prefab");
|
|
|
|
BuildContext buildContext = new BuildContext(root.GetComponent<VRCAvatarDescriptor>());
|
|
new RenameParametersHook().OnPreprocessAvatar(root, buildContext);
|
|
var virtualMenu = VirtualMenu.ForAvatar(root.GetComponent<VRCAvatarDescriptor>(), buildContext);
|
|
|
|
Assert.AreNotEqual("x", virtualMenu.RootMenuNode.Controls[0]
|
|
.SubmenuNode.Controls[0].parameter.name);
|
|
}
|
|
|
|
[Test]
|
|
public void UnusedSubParametersAreStripped()
|
|
{
|
|
var root = CreatePrefab("UnusedSubParametersAreStripped.prefab");
|
|
|
|
BuildContext buildContext = new BuildContext(root.GetComponent<VRCAvatarDescriptor>());
|
|
new RenameParametersHook().OnPreprocessAvatar(root, buildContext);
|
|
var virtualMenu = VirtualMenu.ForAvatar(root.GetComponent<VRCAvatarDescriptor>(), buildContext);
|
|
|
|
// Button
|
|
Assert.AreEqual(0, virtualMenu.RootMenuNode.Controls[0].SubmenuNode.Controls[0].subParameters.Length);
|
|
|
|
// Toggle
|
|
Assert.AreEqual(0, virtualMenu.RootMenuNode.Controls[0].SubmenuNode.Controls[1].subParameters.Length);
|
|
|
|
// SubMenu
|
|
Assert.AreEqual(0, virtualMenu.RootMenuNode.Controls[0].SubmenuNode.Controls[2].subParameters.Length);
|
|
|
|
// Two Axis
|
|
Assert.AreEqual(2, virtualMenu.RootMenuNode.Controls[0].SubmenuNode.Controls[3].subParameters.Length);
|
|
|
|
// Radial
|
|
Assert.AreEqual(1, virtualMenu.RootMenuNode.Controls[0].SubmenuNode.Controls[4].subParameters.Length);
|
|
|
|
// Four Axis
|
|
Assert.AreEqual(4, virtualMenu.RootMenuNode.Controls[0].SubmenuNode.Controls[5].subParameters.Length);
|
|
}
|
|
|
|
ModularAvatarMenuInstaller CreateInstaller(string name)
|
|
{
|
|
GameObject obj = new GameObject();
|
|
obj.name = name;
|
|
|
|
var installer = obj.AddComponent<ModularAvatarMenuInstaller>();
|
|
installer.name = name;
|
|
|
|
toDestroy.Add(obj);
|
|
|
|
return installer;
|
|
}
|
|
|
|
VRCExpressionsMenu.Control GenerateTestSubmenu(VRCExpressionsMenu menu)
|
|
{
|
|
var control = GenerateTestControl();
|
|
control.type = VRCExpressionsMenu.Control.ControlType.SubMenu;
|
|
control.subMenu = menu;
|
|
control.subParameters = Array.Empty<VRCExpressionsMenu.Control.Parameter>();
|
|
|
|
return control;
|
|
}
|
|
|
|
VRCExpressionsMenu.Control GenerateTestControl()
|
|
{
|
|
var control = new VRCExpressionsMenu.Control();
|
|
|
|
VRCExpressionsMenu.Control.ControlType[] types = new[]
|
|
{
|
|
VRCExpressionsMenu.Control.ControlType.Button,
|
|
// VRCExpressionsMenu.Control.ControlType.SubMenu,
|
|
VRCExpressionsMenu.Control.ControlType.Toggle,
|
|
VRCExpressionsMenu.Control.ControlType.RadialPuppet,
|
|
VRCExpressionsMenu.Control.ControlType.FourAxisPuppet,
|
|
VRCExpressionsMenu.Control.ControlType.TwoAxisPuppet,
|
|
};
|
|
|
|
control.type = types[Random.Range(0, types.Length)];
|
|
control.name = "Test Control " + controlIndex++;
|
|
control.parameter = new VRCExpressionsMenu.Control.Parameter();
|
|
control.parameter.name = "Test Parameter " + GUID.Generate();
|
|
control.icon = new Texture2D(1, 1);
|
|
control.labels = new[]
|
|
{
|
|
new VRCExpressionsMenu.Control.Label()
|
|
{
|
|
name = "label",
|
|
icon = testTex
|
|
}
|
|
};
|
|
if (control.type == VRCExpressionsMenu.Control.ControlType.RadialPuppet
|
|
|| control.type == VRCExpressionsMenu.Control.ControlType.FourAxisPuppet
|
|
|| control.type == VRCExpressionsMenu.Control.ControlType.TwoAxisPuppet)
|
|
{
|
|
control.subParameters = new[]
|
|
{
|
|
new VRCExpressionsMenu.Control.Parameter()
|
|
{
|
|
name = "Test Sub Parameter " + GUID.Generate()
|
|
}
|
|
};
|
|
} else
|
|
{
|
|
control.subParameters = Array.Empty<VRCExpressionsMenu.Control.Parameter>();
|
|
}
|
|
|
|
|
|
control.value = 0.42f;
|
|
control.style = VRCExpressionsMenu.Control.Style.Style3;
|
|
|
|
return control;
|
|
}
|
|
|
|
void AssertControlEquals(VRCExpressionsMenu.Control expected, VRCExpressionsMenu.Control actual)
|
|
{
|
|
Assert.AreEqual(expected.type, actual.type);
|
|
Assert.AreEqual(expected.name, actual.name);
|
|
Assert.AreEqual(expected.parameter.name, actual.parameter.name);
|
|
Assert.AreNotSame(expected.parameter, actual.parameter);
|
|
Assert.AreEqual(expected.icon, actual.icon);
|
|
Assert.AreEqual(expected.labels.Length, actual.labels.Length);
|
|
Assert.AreEqual(expected.labels[0].name, actual.labels[0].name);
|
|
Assert.AreEqual(expected.labels[0].icon, actual.labels[0].icon);
|
|
switch (expected.type)
|
|
{
|
|
case VRCExpressionsMenu.Control.ControlType.Button:
|
|
case VRCExpressionsMenu.Control.ControlType.Toggle:
|
|
case VRCExpressionsMenu.Control.ControlType.SubMenu:
|
|
Assert.AreEqual(0, actual.subParameters.Length);
|
|
break;
|
|
default:
|
|
{
|
|
Assert.AreEqual(expected.subParameters.Length, actual.subParameters.Length);
|
|
Assert.AreEqual(expected.subParameters[0].name, actual.subParameters[0].name);
|
|
Assert.AreNotSame(expected.subParameters[0], actual.subParameters[0]);
|
|
break;
|
|
}
|
|
}
|
|
|
|
Assert.AreEqual(expected.value, actual.value);
|
|
Assert.AreEqual(expected.style, actual.style);
|
|
}
|
|
}
|
|
|
|
internal static class TestHelpers
|
|
{
|
|
internal static VirtualMenuNode NodeForMenuAsset(this VirtualMenu menu, VRCExpressionsMenu asset)
|
|
{
|
|
return menu.ResolvedMenu.FirstOrDefault(
|
|
kvp => kvp.Key is ValueTuple<object, object> tuple && ReferenceEquals(tuple.Item1, asset)
|
|
).Value;
|
|
}
|
|
|
|
internal static VRCExpressionsMenu SourceMenu(this VirtualMenuNode node)
|
|
{
|
|
if (node.NodeKey is ValueTuple<object, object> tuple && tuple.Item1 is VRCExpressionsMenu menu)
|
|
{
|
|
return menu;
|
|
}
|
|
|
|
return null;
|
|
}
|
|
}
|
|
}
|
|
|
|
#endif |