ProjectZ/Assets/Mirror/Tests/Editor/SyncListTest.cs

435 lines
14 KiB
C#
Raw Normal View History

2024-02-19 21:00:36 +03:00
using System;
using System.Collections.Generic;
using NUnit.Framework;
namespace Mirror.Tests
{
[TestFixture]
public class SyncListTest
{
SyncList<string> serverSyncList;
SyncList<string> clientSyncList;
int serverSyncListDirtyCalled;
int clientSyncListDirtyCalled;
public static void SerializeAllTo<T>(T fromList, T toList) where T : SyncObject
{
NetworkWriter writer = new NetworkWriter();
fromList.OnSerializeAll(writer);
NetworkReader reader = new NetworkReader(writer.ToArray());
toList.OnDeserializeAll(reader);
int writeLength = writer.Position;
int readLength = reader.Position;
Assert.That(writeLength == readLength, $"OnSerializeAll and OnDeserializeAll calls write the same amount of data\n writeLength={writeLength}\n readLength={readLength}");
}
public static void SerializeDeltaTo<T>(T fromList, T toList) where T : SyncObject
{
NetworkWriter writer = new NetworkWriter();
fromList.OnSerializeDelta(writer);
NetworkReader reader = new NetworkReader(writer.ToArray());
toList.OnDeserializeDelta(reader);
fromList.ClearChanges();
int writeLength = writer.Position;
int readLength = reader.Position;
Assert.That(writeLength == readLength, $"OnSerializeDelta and OnDeserializeDelta calls write the same amount of data\n writeLength={writeLength}\n readLength={readLength}");
}
[SetUp]
public void SetUp()
{
serverSyncList = new SyncList<string>();
clientSyncList = new SyncList<string>();
// add some data to the list
serverSyncList.Add("Hello");
serverSyncList.Add("World");
serverSyncList.Add("!");
SerializeAllTo(serverSyncList, clientSyncList);
// set up dirty callbacks for testing
// AFTER adding the example data. we already know we added that data.
serverSyncList.OnDirty = () => ++serverSyncListDirtyCalled;
clientSyncList.OnDirty = () => ++clientSyncListDirtyCalled;
serverSyncListDirtyCalled = 0;
clientSyncListDirtyCalled = 0;
}
[Test]
public void TestInit()
{
Assert.That(clientSyncList, Is.EquivalentTo(new[] { "Hello", "World", "!" }));
}
// test the '= List<int>{1,2,3}' constructor.
// it calls .Add(1); .Add(2); .Add(3) in the constructor.
// (the OnDirty change broke this and we didn't have a test before)
[Test]
public void CurlyBracesConstructor()
{
SyncList<int> list = new SyncList<int>{1,2,3};
Assert.That(list.Count, Is.EqualTo(3));
}
[Test]
public void TestAdd()
{
serverSyncList.Add("yay");
SerializeDeltaTo(serverSyncList, clientSyncList);
Assert.That(clientSyncList, Is.EquivalentTo(new[] { "Hello", "World", "!", "yay" }));
}
[Test]
public void TestAddRange()
{
serverSyncList.AddRange(new[] { "One", "Two", "Three" });
SerializeDeltaTo(serverSyncList, clientSyncList);
Assert.That(clientSyncList, Is.EqualTo(new[] { "Hello", "World", "!", "One", "Two", "Three" }));
}
[Test]
public void TestClear()
{
serverSyncList.Clear();
SerializeDeltaTo(serverSyncList, clientSyncList);
Assert.That(clientSyncList, Is.EquivalentTo(new string[] {}));
}
[Test]
public void TestInsert()
{
serverSyncList.Insert(0, "yay");
SerializeDeltaTo(serverSyncList, clientSyncList);
Assert.That(clientSyncList, Is.EquivalentTo(new[] { "yay", "Hello", "World", "!" }));
}
[Test]
public void TestInsertRange()
{
serverSyncList.InsertRange(1, new[] { "One", "Two", "Three" });
SerializeDeltaTo(serverSyncList, clientSyncList);
Assert.That(clientSyncList, Is.EqualTo(new[] { "Hello", "One", "Two", "Three", "World", "!" }));
}
[Test]
public void TestSet()
{
serverSyncList[1] = "yay";
SerializeDeltaTo(serverSyncList, clientSyncList);
Assert.That(clientSyncList[1], Is.EqualTo("yay"));
Assert.That(clientSyncList, Is.EquivalentTo(new[] { "Hello", "yay", "!" }));
}
[Test]
public void TestSetNull()
{
serverSyncList[1] = null;
SerializeDeltaTo(serverSyncList, clientSyncList);
Assert.That(clientSyncList[1], Is.EqualTo(null));
Assert.That(clientSyncList, Is.EquivalentTo(new[] { "Hello", null, "!" }));
serverSyncList[1] = "yay";
SerializeDeltaTo(serverSyncList, clientSyncList);
Assert.That(clientSyncList, Is.EquivalentTo(new[] { "Hello", "yay", "!" }));
}
[Test]
public void TestRemoveAll()
{
serverSyncList.RemoveAll(entry => entry.Contains("l"));
SerializeDeltaTo(serverSyncList, clientSyncList);
Assert.That(clientSyncList, Is.EquivalentTo(new[] { "!" }));
}
[Test]
public void TestRemoveAllNone()
{
serverSyncList.RemoveAll(entry => entry == "yay");
SerializeDeltaTo(serverSyncList, clientSyncList);
Assert.That(clientSyncList, Is.EquivalentTo(new[] { "Hello", "World", "!" }));
}
[Test]
public void TestRemoveAt()
{
serverSyncList.RemoveAt(1);
SerializeDeltaTo(serverSyncList, clientSyncList);
Assert.That(clientSyncList, Is.EquivalentTo(new[] { "Hello", "!" }));
}
[Test]
public void TestRemove()
{
serverSyncList.Remove("World");
SerializeDeltaTo(serverSyncList, clientSyncList);
Assert.That(clientSyncList, Is.EquivalentTo(new[] { "Hello", "!" }));
}
[Test]
public void TestFindIndex()
{
int index = serverSyncList.FindIndex(entry => entry == "World");
Assert.That(index, Is.EqualTo(1));
}
[Test]
public void TestFind()
{
string element = serverSyncList.Find(entry => entry == "World");
Assert.That(element, Is.EqualTo("World"));
}
[Test]
public void TestNoFind()
{
string nonexistent = serverSyncList.Find(entry => entry == "yay");
Assert.That(nonexistent, Is.Null);
}
[Test]
public void TestFindAll()
{
List<string> results = serverSyncList.FindAll(entry => entry.Contains("l"));
Assert.That(results, Is.EquivalentTo(new[] { "Hello", "World" }));
}
[Test]
public void TestFindAllNonExistent()
{
List<string> nonexistent = serverSyncList.FindAll(entry => entry == "yay");
Assert.That(nonexistent, Is.Empty);
}
[Test]
public void TestMultSync()
{
serverSyncList.Add("1");
SerializeDeltaTo(serverSyncList, clientSyncList);
// add some delta and see if it applies
serverSyncList.Add("2");
SerializeDeltaTo(serverSyncList, clientSyncList);
Assert.That(clientSyncList, Is.EquivalentTo(new[] { "Hello", "World", "!", "1", "2" }));
}
[Test]
public void SyncListIntTest()
{
SyncList<int> serverList = new SyncList<int>();
SyncList<int> clientList = new SyncList<int>();
serverList.Add(1);
serverList.Add(2);
serverList.Add(3);
SerializeDeltaTo(serverList, clientList);
Assert.That(clientList, Is.EquivalentTo(new[] { 1, 2, 3 }));
}
[Test]
public void SyncListBoolTest()
{
SyncList<bool> serverList = new SyncList<bool>();
SyncList<bool> clientList = new SyncList<bool>();
serverList.Add(true);
serverList.Add(false);
serverList.Add(true);
SerializeDeltaTo(serverList, clientList);
Assert.That(clientList, Is.EquivalentTo(new[] { true, false, true }));
}
[Test]
public void SyncListUIntTest()
{
SyncList<uint> serverList = new SyncList<uint>();
SyncList<uint> clientList = new SyncList<uint>();
serverList.Add(1U);
serverList.Add(2U);
serverList.Add(3U);
SerializeDeltaTo(serverList, clientList);
Assert.That(clientList, Is.EquivalentTo(new[] { 1U, 2U, 3U }));
}
[Test]
public void SyncListFloatTest()
{
SyncList<float> serverList = new SyncList<float>();
SyncList<float> clientList = new SyncList<float>();
serverList.Add(1.0F);
serverList.Add(2.0F);
serverList.Add(3.0F);
SerializeDeltaTo(serverList, clientList);
Assert.That(clientList, Is.EquivalentTo(new[] { 1.0F, 2.0F, 3.0F }));
}
[Test]
public void CallbackTest()
{
bool called = false;
clientSyncList.Callback += (op, index, oldItem, newItem) =>
{
called = true;
Assert.That(op, Is.EqualTo(SyncList<string>.Operation.OP_ADD));
Assert.That(index, Is.EqualTo(3));
Assert.That(oldItem, Is.EqualTo(default(string)));
Assert.That(newItem, Is.EqualTo("yay"));
};
serverSyncList.Add("yay");
SerializeDeltaTo(serverSyncList, clientSyncList);
Assert.That(called, Is.True);
}
[Test]
public void CallbackRemoveTest()
{
bool called = false;
clientSyncList.Callback += (op, index, oldItem, newItem) =>
{
called = true;
Assert.That(op, Is.EqualTo(SyncList<string>.Operation.OP_REMOVEAT));
Assert.That(oldItem, Is.EqualTo("World"));
Assert.That(newItem, Is.EqualTo(default(string)));
};
serverSyncList.Remove("World");
SerializeDeltaTo(serverSyncList, clientSyncList);
Assert.That(called, Is.True);
}
[Test]
public void CallbackRemoveAtTest()
{
bool called = false;
clientSyncList.Callback += (op, index, oldItem, newItem) =>
{
called = true;
Assert.That(op, Is.EqualTo(SyncList<string>.Operation.OP_REMOVEAT));
Assert.That(index, Is.EqualTo(1));
Assert.That(oldItem, Is.EqualTo("World"));
Assert.That(newItem, Is.EqualTo(default(string)));
};
serverSyncList.RemoveAt(1);
SerializeDeltaTo(serverSyncList, clientSyncList);
Assert.That(called, Is.True);
}
[Test]
public void CountTest()
{
Assert.That(serverSyncList.Count, Is.EqualTo(3));
}
[Test]
public void ReadOnlyTest()
{
Assert.That(serverSyncList.IsReadOnly, Is.False);
Assert.That(clientSyncList.IsReadOnly, Is.True);
}
[Test]
public void WritingToReadOnlyThrows()
{
Assert.Throws<InvalidOperationException>(() => { clientSyncList.Add("fail"); });
}
[Test]
public void DirtyTest()
{
// Sync Delta to clear dirty
Assert.That(serverSyncListDirtyCalled, Is.EqualTo(0));
SerializeDeltaTo(serverSyncList, clientSyncList);
// nothing to send
Assert.That(serverSyncListDirtyCalled, Is.EqualTo(0));
// something has changed
serverSyncList.Add("1");
Assert.That(serverSyncListDirtyCalled, Is.EqualTo(1));
SerializeDeltaTo(serverSyncList, clientSyncList);
}
[Test]
public void ObjectCanBeReusedAfterReset()
{
clientSyncList.Reset();
// make old client the host
SyncList<string> hostList = clientSyncList;
SyncList<string> clientList2 = new SyncList<string>();
Assert.That(hostList.IsReadOnly, Is.False);
// Check Add and Sync without errors
hostList.Add("hello");
hostList.Add("world");
SerializeDeltaTo(hostList, clientList2);
}
[Test]
public void ResetShouldSetReadOnlyToFalse()
{
clientSyncList.Reset();
Assert.That(clientSyncList.IsReadOnly, Is.False);
}
[Test]
public void ResetShouldClearChanges()
{
serverSyncList.Reset();
Assert.That(serverSyncList.GetChangeCount(), Is.Zero);
}
[Test]
public void ResetShouldClearItems()
{
serverSyncList.Reset();
Assert.That(serverSyncList, Is.Empty);
}
[Test]
public void IsRecording()
{
// shouldn't record changes if IsRecording() returns false
serverSyncList.ClearChanges();
serverSyncList.IsRecording = () => false;
serverSyncList.Add("42");
Assert.That(serverSyncList.GetChangeCount(), Is.EqualTo(0));
}
}
public static class SyncObjectTestMethods
{
public static uint GetChangeCount(this SyncObject syncObject)
{
using (PooledNetworkWriter writer = NetworkWriterPool.GetWriter())
{
syncObject.OnSerializeDelta(writer);
using (PooledNetworkReader reader = NetworkReaderPool.GetReader(writer.ToArraySegment()))
{
return reader.ReadUInt();
}
}
}
}
}