using System; using System.Collections.Generic; using NUnit.Framework; namespace Mirror.Tests { [TestFixture] public class SyncDictionaryTest { SyncDictionary serverSyncDictionary; SyncDictionary clientSyncDictionary; int serverSyncDictionaryDirtyCalled; int clientSyncDictionaryDirtyCalled; void SerializeAllTo(T fromList, T toList) where T : SyncObject { NetworkWriter writer = new NetworkWriter(); fromList.OnSerializeAll(writer); NetworkReader reader = new NetworkReader(writer.ToArray()); toList.OnDeserializeAll(reader); } void SerializeDeltaTo(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(); } [SetUp] public void SetUp() { serverSyncDictionary = new SyncDictionary(); clientSyncDictionary = new SyncDictionary(); // add some data to the list serverSyncDictionary.Add(0, "Hello"); serverSyncDictionary.Add(1, "World"); serverSyncDictionary.Add(2, "!"); SerializeAllTo(serverSyncDictionary, clientSyncDictionary); // set up dirty callbacks for testing. // AFTER adding the example data. we already know we added that data. serverSyncDictionaryDirtyCalled = 0; clientSyncDictionaryDirtyCalled = 0; serverSyncDictionary.OnDirty = () => ++serverSyncDictionaryDirtyCalled; clientSyncDictionary.OnDirty = () => ++clientSyncDictionaryDirtyCalled; } [Test] public void TestInit() { Dictionary comparer = new Dictionary { [0] = "Hello", [1] = "World", [2] = "!" }; Assert.That(clientSyncDictionary[0], Is.EqualTo("Hello")); Assert.That(clientSyncDictionary, Is.EquivalentTo(comparer)); } // test the '= List{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() { SyncDictionary dict = new SyncDictionary{{1,"1"}, {2,"2"}, {3,"3"}}; Assert.That(dict.Count, Is.EqualTo(3)); } [Test] public void TestAdd() { serverSyncDictionary.Add(4, "yay"); SerializeDeltaTo(serverSyncDictionary, clientSyncDictionary); Assert.That(clientSyncDictionary.ContainsKey(4)); Assert.That(clientSyncDictionary[4], Is.EqualTo("yay")); } [Test] public void TestClear() { serverSyncDictionary.Clear(); SerializeDeltaTo(serverSyncDictionary, clientSyncDictionary); Assert.That(serverSyncDictionary, Is.EquivalentTo(new SyncDictionary())); } [Test] public void TestSet() { serverSyncDictionary[1] = "yay"; SerializeDeltaTo(serverSyncDictionary, clientSyncDictionary); Assert.That(clientSyncDictionary.ContainsKey(1)); Assert.That(clientSyncDictionary[1], Is.EqualTo("yay")); } [Test] public void TestBareSet() { serverSyncDictionary[4] = "yay"; SerializeDeltaTo(serverSyncDictionary, clientSyncDictionary); Assert.That(clientSyncDictionary.ContainsKey(4)); Assert.That(clientSyncDictionary[4], Is.EqualTo("yay")); } [Test] public void TestBareSetNull() { serverSyncDictionary[4] = null; SerializeDeltaTo(serverSyncDictionary, clientSyncDictionary); Assert.That(clientSyncDictionary[4], Is.Null); Assert.That(clientSyncDictionary.ContainsKey(4)); } [Test] public void TestConsecutiveSet() { serverSyncDictionary[1] = "yay"; serverSyncDictionary[1] = "world"; SerializeDeltaTo(serverSyncDictionary, clientSyncDictionary); Assert.That(clientSyncDictionary[1], Is.EqualTo("world")); } [Test] public void TestNullSet() { serverSyncDictionary[1] = null; SerializeDeltaTo(serverSyncDictionary, clientSyncDictionary); Assert.That(clientSyncDictionary.ContainsKey(1)); Assert.That(clientSyncDictionary[1], Is.Null); } [Test] public void TestRemove() { serverSyncDictionary.Remove(1); SerializeDeltaTo(serverSyncDictionary, clientSyncDictionary); Assert.That(!clientSyncDictionary.ContainsKey(1)); } [Test] public void TestMultSync() { serverSyncDictionary.Add(10, "1"); SerializeDeltaTo(serverSyncDictionary, clientSyncDictionary); // add some delta and see if it applies serverSyncDictionary.Add(11, "2"); SerializeDeltaTo(serverSyncDictionary, clientSyncDictionary); Assert.That(clientSyncDictionary.ContainsKey(10)); Assert.That(clientSyncDictionary[10], Is.EqualTo("1")); Assert.That(clientSyncDictionary.ContainsKey(11)); Assert.That(clientSyncDictionary[11], Is.EqualTo("2")); } [Test] public void TestContains() { Assert.That(!clientSyncDictionary.Contains(new KeyValuePair(2, "Hello"))); serverSyncDictionary[2] = "Hello"; SerializeDeltaTo(serverSyncDictionary, clientSyncDictionary); Assert.That(clientSyncDictionary.Contains(new KeyValuePair(2, "Hello"))); } [Test] public void CallbackTest() { bool called = false; clientSyncDictionary.Callback += (op, index, item) => { called = true; Assert.That(op, Is.EqualTo(SyncDictionary.Operation.OP_ADD)); Assert.That(index, Is.EqualTo(3)); Assert.That(item, Is.EqualTo("yay")); Assert.That(clientSyncDictionary[index], Is.EqualTo("yay")); }; serverSyncDictionary.Add(3, "yay"); SerializeDeltaTo(serverSyncDictionary, clientSyncDictionary); Assert.That(called, Is.True); } [Test] public void ServerCallbackTest() { bool called = false; serverSyncDictionary.Callback += (op, index, item) => { called = true; Assert.That(op, Is.EqualTo(SyncDictionary.Operation.OP_ADD)); Assert.That(index, Is.EqualTo(3)); Assert.That(item, Is.EqualTo("yay")); Assert.That(serverSyncDictionary[index], Is.EqualTo("yay")); }; serverSyncDictionary[3] = "yay"; Assert.That(called, Is.True); } [Test] public void CallbackRemoveTest() { bool called = false; clientSyncDictionary.Callback += (op, key, item) => { called = true; Assert.That(op, Is.EqualTo(SyncDictionary.Operation.OP_REMOVE)); Assert.That(item, Is.EqualTo("World")); }; serverSyncDictionary.Remove(1); SerializeDeltaTo(serverSyncDictionary, clientSyncDictionary); Assert.That(called, Is.True); } [Test] public void CountTest() { Assert.That(serverSyncDictionary.Count, Is.EqualTo(3)); } [Test] public void CopyToTest() { KeyValuePair[] data = new KeyValuePair[3]; clientSyncDictionary.CopyTo(data, 0); Assert.That(data, Is.EquivalentTo(new KeyValuePair[] { new KeyValuePair(0, "Hello"), new KeyValuePair(1, "World"), new KeyValuePair(2, "!"), })); } [Test] public void CopyToOutOfRangeTest() { KeyValuePair[] data = new KeyValuePair[3]; Assert.Throws(typeof(ArgumentOutOfRangeException), delegate { clientSyncDictionary.CopyTo(data, -1); }); } [Test] public void CopyToOutOfBoundsTest() { KeyValuePair[] data = new KeyValuePair[3]; Assert.Throws(typeof(ArgumentException), delegate { clientSyncDictionary.CopyTo(data, 2); }); } [Test] public void TestRemovePair() { KeyValuePair data = new KeyValuePair(0, "Hello"); serverSyncDictionary.Remove(data); Assert.That(serverSyncDictionary, Is.EquivalentTo(new KeyValuePair[] { new KeyValuePair(1, "World"), new KeyValuePair(2, "!"), })); } [Test] public void ReadOnlyTest() { Assert.That(serverSyncDictionary.IsReadOnly, Is.False); Assert.That(clientSyncDictionary.IsReadOnly, Is.True); } [Test] public void WritingToReadOnlyThrows() { Assert.Throws(() => clientSyncDictionary.Add(50, "fail")); } [Test] public void DirtyTest() { // Sync Delta to clear dirty SerializeDeltaTo(serverSyncDictionary, clientSyncDictionary); // nothing to send Assert.That(serverSyncDictionaryDirtyCalled, Is.EqualTo(0)); // something has changed serverSyncDictionary.Add(15, "yay"); Assert.That(serverSyncDictionaryDirtyCalled, Is.EqualTo(1)); SerializeDeltaTo(serverSyncDictionary, clientSyncDictionary); } [Test] public void ObjectCanBeReusedAfterReset() { clientSyncDictionary.Reset(); // make old client the host SyncDictionary hostList = clientSyncDictionary; SyncDictionary clientList2 = new SyncDictionary(); Assert.That(hostList.IsReadOnly, Is.False); // Check Add and Sync without errors hostList.Add(30, "hello"); hostList.Add(35, "world"); SerializeDeltaTo(hostList, clientList2); } [Test] public void ResetShouldSetReadOnlyToFalse() { clientSyncDictionary.Reset(); Assert.That(clientSyncDictionary.IsReadOnly, Is.False); } [Test] public void ResetShouldClearChanges() { serverSyncDictionary.Reset(); Assert.That(serverSyncDictionary.GetChangeCount(), Is.Zero); } [Test] public void ResetShouldClearItems() { serverSyncDictionary.Reset(); Assert.That(serverSyncDictionary, Is.Empty); } [Test] public void IsRecording() { // shouldn't record changes if IsRecording() returns false serverSyncDictionary.ClearChanges(); serverSyncDictionary.IsRecording = () => false; serverSyncDictionary[42] = null; Assert.That(serverSyncDictionary.GetChangeCount(), Is.EqualTo(0)); } } }