435 lines
14 KiB
C#
435 lines
14 KiB
C#
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();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|