diff --git a/Assets/Talo Game Services/Talo/Runtime/Entities/EntityWithProps.cs b/Assets/Talo Game Services/Talo/Runtime/Entities/EntityWithProps.cs index 8595aef..f8043a7 100644 --- a/Assets/Talo Game Services/Talo/Runtime/Entities/EntityWithProps.cs +++ b/Assets/Talo Game Services/Talo/Runtime/Entities/EntityWithProps.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Generic; using System.Linq; namespace TaloGameServices @@ -19,24 +20,135 @@ public void SetProp(string key, string value) { props = props.Select((prop) => { - if (prop.key == key) prop.value = value; + if (prop.key == key) + { + prop.value = value; + } + return prop; }).ToArray(); } else { - var propList = props.ToList(); - propList.Add(new Prop((key, value))); - props = propList.ToArray(); + props = props.Append(new Prop((key, value))).ToArray(); } } public void DeleteProp(string key) { - Prop prop = props.FirstOrDefault((prop) => prop.key == key); - if (prop == null) throw new Exception($"Prop with key {key} does not exist"); + var prop = props.FirstOrDefault((prop) => prop.key == key) ?? + throw new Exception($"Prop with key {key} does not exist"); prop.value = null; } + + private string ToArrayKey(string key) + { + if (key.EndsWith("[]")) + { + return key; + } + + return $"{key}[]"; + } + + public IReadOnlyList GetPropArray(string key) + { + var items = props + .Where((prop) => prop.key == ToArrayKey(key) && prop.value != null) + .Select((prop) => prop.value); + + return items.ToList().AsReadOnly(); + } + + private void EnsurePropArraySentinelRemoved(string key) + { + var arrayKey = ToArrayKey(key); + + var hasSentinel = props.Any((prop) => prop.key == arrayKey && prop.value == null); + if (hasSentinel) + { + props = props.Where((prop) => prop.key != arrayKey).ToArray(); + } + } + + public void SetPropArray(string key, IEnumerable values) + { + var validValues = values.Where((value) => !string.IsNullOrEmpty(value)).Distinct().ToList(); + + if (validValues.Count == 0) + { + throw new Exception($"Values for prop array {key} must contain at least one non-empty value"); + } + + var arrayKey = ToArrayKey(key); + props = props.Where((prop) => prop.key != arrayKey).ToArray(); + + props = props.Concat(validValues.Select((value) => new Prop((arrayKey, value)))).ToArray(); + } + + public void DeletePropArray(string key) + { + var arrayKey = ToArrayKey(key); + + if (!props.Any((prop) => prop.key == arrayKey)) + { + throw new Exception($"Prop array with key {key} does not exist"); + } + + props = props + .Where((prop) => prop.key != arrayKey) + // set a single value to null - this ensures the array is cleared + .Append(new Prop((arrayKey, null))) + .ToArray(); + } + + public void InsertIntoPropArray(string key, string value) + { + if (string.IsNullOrEmpty(value)) + { + throw new Exception($"Value for prop array {key} cannot be null or empty"); + } + + var arrayKey = ToArrayKey(key); + + var hasDupe = props.Any((prop) => prop.key == arrayKey && prop.value == value); + if (!hasDupe) + { + EnsurePropArraySentinelRemoved(key); + props = props.Append(new Prop((arrayKey, value))).ToArray(); + } + } + + private void EnsurePropArrayHasSentinel(string key) + { + var hasItems = props + .Where((prop) => prop.key == ToArrayKey(key)) + .Any(); + + if (!hasItems) + { + props = props.Append(new Prop((ToArrayKey(key), null))).ToArray(); + } + } + + public void RemoveFromPropArray(string key, string value) + { + var arrayKey = ToArrayKey(key); + EnsurePropArraySentinelRemoved(key); + + if (!props.Any((prop) => prop.key == arrayKey && prop.value == value)) + { + EnsurePropArrayHasSentinel(key); + throw new Exception($"Value {value} does not exist in prop array {key}"); + } + + props = props.Where((prop) => { + var isMatchingValue = prop.key == arrayKey && prop.value == value; + return !isMatchingValue; + }).ToArray(); + + EnsurePropArrayHasSentinel(key); + } } -} \ No newline at end of file +} diff --git a/Assets/Talo Game Services/Talo/Runtime/Entities/Player.cs b/Assets/Talo Game Services/Talo/Runtime/Entities/Player.cs index 7d3e059..73b4d2a 100644 --- a/Assets/Talo Game Services/Talo/Runtime/Entities/Player.cs +++ b/Assets/Talo Game Services/Talo/Runtime/Entities/Player.cs @@ -1,6 +1,7 @@ using UnityEngine; using System.Linq; using System; +using System.Collections.Generic; namespace TaloGameServices { @@ -37,6 +38,46 @@ public void DeleteProp(string key, bool update = true) } } + public void SetPropArray(string key, IEnumerable values, bool update = true) + { + base.SetPropArray(key, values); + + if (update) + { + Talo.Players.DebounceUpdate(); + } + } + + public void DeletePropArray(string key, bool update = true) + { + base.DeletePropArray(key); + + if (update) + { + Talo.Players.DebounceUpdate(); + } + } + + public void InsertIntoPropArray(string key, string value, bool update = true) + { + base.InsertIntoPropArray(key, value); + + if (update) + { + Talo.Players.DebounceUpdate(); + } + } + + public void RemoveFromPropArray(string key, string value, bool update = true) + { + base.RemoveFromPropArray(key, value); + + if (update) + { + Talo.Players.DebounceUpdate(); + } + } + public bool IsInGroupID(string groupId) { return groups.Any((group) => group.id == groupId); diff --git a/Assets/Talo Game Services/Talo/Runtime/Utils/SocketException.cs b/Assets/Talo Game Services/Talo/Runtime/Utils/SocketException.cs index 6241aa6..9268a3e 100644 --- a/Assets/Talo Game Services/Talo/Runtime/Utils/SocketException.cs +++ b/Assets/Talo Game Services/Talo/Runtime/Utils/SocketException.cs @@ -18,7 +18,7 @@ public enum SocketErrorCode { public class SocketException : Exception { - private SocketError errorData; + private readonly SocketError errorData; public string Req => errorData?.req ?? "unknown"; public SocketErrorCode ErrorCode => GetErrorCode(); diff --git a/Assets/Talo Game Services/Talo/Tests/EntityWithProps.meta b/Assets/Talo Game Services/Talo/Tests/EntityWithProps.meta new file mode 100644 index 0000000..9c0769c --- /dev/null +++ b/Assets/Talo Game Services/Talo/Tests/EntityWithProps.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 1e7b30c636e9842449299ce2357f9971 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Talo Game Services/Talo/Tests/EntityWithProps/DeletePropArrayTest.cs b/Assets/Talo Game Services/Talo/Tests/EntityWithProps/DeletePropArrayTest.cs new file mode 100644 index 0000000..c534038 --- /dev/null +++ b/Assets/Talo Game Services/Talo/Tests/EntityWithProps/DeletePropArrayTest.cs @@ -0,0 +1,74 @@ +using System; +using System.Collections; +using System.Linq; +using NUnit.Framework; +using UnityEngine.TestTools; + +namespace TaloGameServices.Test { + internal class DeletePropArrayTest + { + [UnityTest] + public IEnumerator DeletePropArray_ArrayIsEmptyAndSentinelNullExistsInProps() + { + var player = new Player + { + props = new[] { + new Prop(("colours[]", "red")), + new Prop(("colours[]", "blue")) + } + }; + + player.DeletePropArray("colours", false); + + Assert.AreEqual(0, player.GetPropArray("colours").Count); + // ensure the sentinel null value is in there + Assert.IsTrue(player.props.Any((prop) => prop.key == "colours[]" && prop.value == null)); + + yield return null; + } + + [UnityTest] + public IEnumerator DeletePropArray_WhenTheArrayDoesNotExist_ThrowsAnError() + { + var player = new Player + { + props = new[] { + new Prop(("colours[]", "red")), + new Prop(("colours[]", "blue")) + } + }; + + try + { + player.DeletePropArray("sizes", false); + Assert.Fail("Expected exception was not thrown"); + } + catch (Exception ex) + { + Assert.AreEqual(ex.Message, $"Prop array with key sizes does not exist"); + } + + yield return null; + } + + [UnityTest] + public IEnumerator DeletePropArray_AcceptsKeyWithOrWithoutBrackets() + { + var player = new Player + { + props = new[] { + new Prop(("colours[]", "red")), + new Prop(("colours[]", "blue")) + } + }; + + player.DeletePropArray("colours[]", false); + + Assert.AreEqual(0, player.GetPropArray("colours").Count); + // ensure the sentinel null value is in there + Assert.IsTrue(player.props.Any((prop) => prop.key == "colours[]" && prop.value == null)); + + yield return null; + } + } +} diff --git a/Assets/Talo Game Services/Talo/Tests/EntityWithProps/DeletePropArrayTest.cs.meta b/Assets/Talo Game Services/Talo/Tests/EntityWithProps/DeletePropArrayTest.cs.meta new file mode 100644 index 0000000..00f53cc --- /dev/null +++ b/Assets/Talo Game Services/Talo/Tests/EntityWithProps/DeletePropArrayTest.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: 0df551e83888145c69b3d678d344bd06 \ No newline at end of file diff --git a/Assets/Talo Game Services/Talo/Tests/EntityWithProps/DeletePropTest.cs b/Assets/Talo Game Services/Talo/Tests/EntityWithProps/DeletePropTest.cs new file mode 100644 index 0000000..5d919da --- /dev/null +++ b/Assets/Talo Game Services/Talo/Tests/EntityWithProps/DeletePropTest.cs @@ -0,0 +1,52 @@ +using System; +using System.Collections; +using NUnit.Framework; +using UnityEngine.TestTools; + +namespace TaloGameServices.Test { + internal class DeleteProp + { + [UnityTest] + public IEnumerator DeleteProp_WhenThePropExists_SetsTheValueToNull() + { + var player = new Player + { + props = new[] { + new Prop(("key1", "value1")), + new Prop(("key2", "value2")) + } + }; + + player.DeleteProp("key2", false); + + Assert.IsNull(player.GetProp("key2")); + + yield return null; + } + + [UnityTest] + public IEnumerator DeleteProp_WhenThePropDoesNotExist_ThrowsAnError() + { + var player = new Player + { + props = new[] { + new Prop(("key1", "value1")), + new Prop(("key2", "value2")) + } + }; + + try + { + player.DeleteProp("key3", false); + Assert.Fail("Expected exception was not thrown"); + } + catch (Exception ex) + { + Assert.AreEqual(ex.Message, $"Prop with key key3 does not exist"); + } + + yield return null; + } + + } +} diff --git a/Assets/Talo Game Services/Talo/Tests/EntityWithProps/DeletePropTest.cs.meta b/Assets/Talo Game Services/Talo/Tests/EntityWithProps/DeletePropTest.cs.meta new file mode 100644 index 0000000..dd700c3 --- /dev/null +++ b/Assets/Talo Game Services/Talo/Tests/EntityWithProps/DeletePropTest.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: b98f8dd24460e4244ae518eb72e9f4c6 \ No newline at end of file diff --git a/Assets/Talo Game Services/Talo/Tests/EntityWithProps/GetPropArrayTest.cs b/Assets/Talo Game Services/Talo/Tests/EntityWithProps/GetPropArrayTest.cs new file mode 100644 index 0000000..7508af5 --- /dev/null +++ b/Assets/Talo Game Services/Talo/Tests/EntityWithProps/GetPropArrayTest.cs @@ -0,0 +1,67 @@ +using System.Collections; +using System.Linq; +using NUnit.Framework; +using UnityEngine.TestTools; + +namespace TaloGameServices.Test { + internal class GetPropArrayTest + { + [UnityTest] + public IEnumerator GetPropArray_WithExistingItems_ReturnsAllValues() + { + var player = new Player + { + props = new[] { + new Prop(("colours[]", "red")), + new Prop(("colours[]", "blue")), + new Prop(("colours[]", "green")) + } + }; + + var result = player.GetPropArray("colours").ToList(); + + Assert.AreEqual(3, result.Count); + Assert.Contains("red", result); + Assert.Contains("blue", result); + Assert.Contains("green", result); + + yield return null; + } + + [UnityTest] + public IEnumerator GetPropArray_WithNoMatchingKey_ReturnsEmptyList() + { + var player = new Player + { + props = new[] { + new Prop(("colours[]", "red")) + } + }; + + var result = player.GetPropArray("sizes").ToList(); + + Assert.AreEqual(0, result.Count); + + yield return null; + } + + [UnityTest] + public IEnumerator GetPropArray_AcceptsKeyWithOrWithoutBrackets() + { + var player = new Player + { + props = new[] { + new Prop(("colours[]", "red")), + new Prop(("colours[]", "blue")) + } + }; + + var withBrackets = player.GetPropArray("colours[]").ToList(); + var withoutBrackets = player.GetPropArray("colours").ToList(); + + Assert.AreEqual(withBrackets, withoutBrackets); + + yield return null; + } + } +} diff --git a/Assets/Talo Game Services/Talo/Tests/EntityWithProps/GetPropArrayTest.cs.meta b/Assets/Talo Game Services/Talo/Tests/EntityWithProps/GetPropArrayTest.cs.meta new file mode 100644 index 0000000..a85a681 --- /dev/null +++ b/Assets/Talo Game Services/Talo/Tests/EntityWithProps/GetPropArrayTest.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: ae0e505d39dc34b1da859569bde11d4d \ No newline at end of file diff --git a/Assets/Talo Game Services/Talo/Tests/EntityWithProps/GetPropTest.cs b/Assets/Talo Game Services/Talo/Tests/EntityWithProps/GetPropTest.cs new file mode 100644 index 0000000..f64e1f3 --- /dev/null +++ b/Assets/Talo Game Services/Talo/Tests/EntityWithProps/GetPropTest.cs @@ -0,0 +1,56 @@ +using System.Collections; +using NUnit.Framework; +using UnityEngine.TestTools; + +namespace TaloGameServices.Test { + internal class GetPropTest + { + [UnityTest] + public IEnumerator GetProp_WithAnExistingKey_ReturnsCorrectValue() + { + var player = new Player + { + props = new[] { + new Prop(("key1", "value1")), + new Prop(("key2", "value2")) + } + }; + + Assert.AreEqual(player.GetProp("key2"), "value2"); + + yield return null; + } + + [UnityTest] + public IEnumerator GetProp_WithAMissingKey_ReturnsNull() + { + var player = new Player + { + props = new[] { + new Prop(("key1", "value1")), + new Prop(("key2", "value2")) + } + }; + + Assert.IsNull(player.GetProp("key3")); + + yield return null; + } + + [UnityTest] + public IEnumerator GetProp_WithAMissingKeyAndFallback_ReturnsNull() + { + var player = new Player + { + props = new[] { + new Prop(("key1", "value1")), + new Prop(("key2", "value2")) + } + }; + + Assert.AreEqual(player.GetProp("key3", "value3"), "value3"); + + yield return null; + } + } +} diff --git a/Assets/Talo Game Services/Talo/Tests/EntityWithProps/GetPropTest.cs.meta b/Assets/Talo Game Services/Talo/Tests/EntityWithProps/GetPropTest.cs.meta new file mode 100644 index 0000000..0ad303e --- /dev/null +++ b/Assets/Talo Game Services/Talo/Tests/EntityWithProps/GetPropTest.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: 1b0e702d1e55140de812128ea8c8e618 \ No newline at end of file diff --git a/Assets/Talo Game Services/Talo/Tests/EntityWithProps/InsertIntoPropArrayTest.cs b/Assets/Talo Game Services/Talo/Tests/EntityWithProps/InsertIntoPropArrayTest.cs new file mode 100644 index 0000000..fb6e2b7 --- /dev/null +++ b/Assets/Talo Game Services/Talo/Tests/EntityWithProps/InsertIntoPropArrayTest.cs @@ -0,0 +1,114 @@ +using System; +using System.Collections; +using System.Linq; +using NUnit.Framework; +using UnityEngine.TestTools; + +namespace TaloGameServices.Test { + internal class InsertIntoPropArrayTest + { + [UnityTest] + public IEnumerator InsertIntoPropArray_AddsValueToExistingArray() + { + var player = new Player + { + props = new[] { + new Prop(("colours[]", "red")), + new Prop(("colours[]", "blue")) + } + }; + + player.InsertIntoPropArray("colours", "green", false); + + var result = player.GetPropArray("colours").ToList(); + Assert.AreEqual(3, result.Count); + Assert.Contains("green", result); + + yield return null; + } + + [UnityTest] + public IEnumerator InsertIntoPropArray_DoesNotAddDuplicateValue() + { + var player = new Player + { + props = new[] { + new Prop(("colours[]", "red")), + new Prop(("colours[]", "blue")) + } + }; + + player.InsertIntoPropArray("colours", "red", false); + + var result = player.GetPropArray("colours").ToList(); + Assert.AreEqual(2, result.Count); + + yield return null; + } + + [UnityTest] + public IEnumerator InsertIntoPropArray_WhenArrayWasPreviouslyDeleted_ClearsNullEntryAndInsertsValue() + { + var player = new Player + { + props = new[] { + new Prop(("colours[]", null)) + } + }; + + player.InsertIntoPropArray("colours", "red", false); + + var result = player.GetPropArray("colours").ToList(); + Assert.AreEqual(1, result.Count); + Assert.Contains("red", result); + + yield return null; + } + + [UnityTest] + public IEnumerator InsertIntoPropArray_WithNullValue_ThrowsAnError() + { + var player = new Player + { + props = new[] { + new Prop(("colours[]", "red")) + } + }; + + try + { + player.InsertIntoPropArray("colours", null, false); + Assert.Fail("Expected exception was not thrown"); + } + catch (Exception ex) + { + Assert.AreEqual(ex.Message, "Value for prop array colours cannot be null or empty"); + } + + yield return null; + } + + [UnityTest] + public IEnumerator InsertIntoPropArray_WithEmptyValue_ThrowsAnError() + { + var player = new Player + { + props = new[] { + new Prop(("colours[]", "red")) + } + }; + + try + { + player.InsertIntoPropArray("colours", "", false); + Assert.Fail("Expected exception was not thrown"); + } + catch (Exception ex) + { + Assert.AreEqual(ex.Message, "Value for prop array colours cannot be null or empty"); + } + + yield return null; + } + } +} diff --git a/Assets/Talo Game Services/Talo/Tests/EntityWithProps/InsertIntoPropArrayTest.cs.meta b/Assets/Talo Game Services/Talo/Tests/EntityWithProps/InsertIntoPropArrayTest.cs.meta new file mode 100644 index 0000000..c2c228f --- /dev/null +++ b/Assets/Talo Game Services/Talo/Tests/EntityWithProps/InsertIntoPropArrayTest.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: 3dbbb63e838794e97b25fff9792501b9 \ No newline at end of file diff --git a/Assets/Talo Game Services/Talo/Tests/EntityWithProps/RemoveFromPropArrayTest.cs b/Assets/Talo Game Services/Talo/Tests/EntityWithProps/RemoveFromPropArrayTest.cs new file mode 100644 index 0000000..53b7ec7 --- /dev/null +++ b/Assets/Talo Game Services/Talo/Tests/EntityWithProps/RemoveFromPropArrayTest.cs @@ -0,0 +1,124 @@ +using System; +using System.Collections; +using System.Linq; +using NUnit.Framework; +using UnityEngine.TestTools; + +namespace TaloGameServices.Test { + internal class RemoveFromPropArrayTest + { + [UnityTest] + public IEnumerator RemoveFromPropArray_RemovesMatchingValue() + { + var player = new Player + { + props = new[] { + new Prop(("colours[]", "red")), + new Prop(("colours[]", "blue")), + new Prop(("colours[]", "green")) + } + }; + + player.RemoveFromPropArray("colours", "blue", false); + + var result = player.GetPropArray("colours").ToList(); + Assert.AreEqual(2, result.Count); + Assert.IsFalse(result.Contains("blue")); + + yield return null; + } + + [UnityTest] + public IEnumerator RemoveFromPropArray_WhenLastItemRemoved_ArrayIsEmptyAndSentinelNullExistsInProps() + { + var player = new Player + { + props = new[] { + new Prop(("colours[]", "red")) + } + }; + + player.RemoveFromPropArray("colours", "red", false); + + Assert.AreEqual(0, player.GetPropArray("colours").Count); + // ensure the sentinel null value is in there + Assert.IsTrue(player.props.Any((prop) => prop.key == "colours[]" && prop.value == null)); + + yield return null; + } + + [UnityTest] + public IEnumerator RemoveFromPropArray_WhenArrayIsAlreadyDeleted_RemainsDeleted() + { + var player = new Player + { + props = new[] { + new Prop(("colours[]", "red")) + } + }; + + player.RemoveFromPropArray("colours", "red", false); + try + { + player.RemoveFromPropArray("colours", "red", false); + Assert.Fail("Expected exception was not thrown"); + } + catch (Exception ex) + { + Assert.AreEqual(ex.Message, "Value red does not exist in prop array colours"); + } + + Assert.AreEqual(0, player.GetPropArray("colours").Count); + Assert.IsTrue(player.props.Any((prop) => prop.key == "colours[]" && prop.value == null)); + + yield return null; + } + + [UnityTest] + public IEnumerator RemoveFromPropArray_WhenValueDoesNotExist_ThrowsAnError() + { + var player = new Player + { + props = new[] { + new Prop(("colours[]", "red")), + new Prop(("colours[]", "blue")) + } + }; + + try + { + player.RemoveFromPropArray("colours", "green", false); + Assert.Fail("Expected exception was not thrown"); + } + catch (Exception ex) + { + Assert.AreEqual(ex.Message, "Value green does not exist in prop array colours"); + } + + yield return null; + } + + [UnityTest] + public IEnumerator RemoveFromPropArray_WhenArrayIsAlreadyDeleted_ThrowsAnError() + { + var player = new Player + { + props = new[] { + new Prop(("colours[]", null)) + } + }; + + try + { + player.RemoveFromPropArray("colours", "red", false); + Assert.Fail("Expected exception was not thrown"); + } + catch (Exception ex) + { + Assert.AreEqual(ex.Message, "Value red does not exist in prop array colours"); + } + + yield return null; + } + } +} diff --git a/Assets/Talo Game Services/Talo/Tests/EntityWithProps/RemoveFromPropArrayTest.cs.meta b/Assets/Talo Game Services/Talo/Tests/EntityWithProps/RemoveFromPropArrayTest.cs.meta new file mode 100644 index 0000000..16426c5 --- /dev/null +++ b/Assets/Talo Game Services/Talo/Tests/EntityWithProps/RemoveFromPropArrayTest.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: 7efb75481ea2f4c59af082dd72f873ab \ No newline at end of file diff --git a/Assets/Talo Game Services/Talo/Tests/EntityWithProps/SetPropArrayTest.cs b/Assets/Talo Game Services/Talo/Tests/EntityWithProps/SetPropArrayTest.cs new file mode 100644 index 0000000..a434805 --- /dev/null +++ b/Assets/Talo Game Services/Talo/Tests/EntityWithProps/SetPropArrayTest.cs @@ -0,0 +1,130 @@ +using System; +using System.Collections; +using System.Linq; +using NUnit.Framework; +using UnityEngine.TestTools; + +namespace TaloGameServices.Test { + internal class SetPropArrayTest + { + [UnityTest] + public IEnumerator SetPropArray_WithNewKey_AddsAllValues() + { + var player = new Player + { + props = new Prop[] { } + }; + + player.SetPropArray("colours", new [] { "red", "blue", "green" }, false); + + var result = player.GetPropArray("colours").ToList(); + Assert.AreEqual(3, result.Count); + Assert.Contains("red", result); + Assert.Contains("blue", result); + Assert.Contains("green", result); + + yield return null; + } + + [UnityTest] + public IEnumerator SetPropArray_DeduplicatesValues() + { + var player = new Player + { + props = new Prop[] { } + }; + + player.SetPropArray("colours", new [] { "red", "red", "blue" }, false); + + var result = player.GetPropArray("colours").ToList(); + Assert.AreEqual(2, result.Count); + Assert.Contains("red", result); + Assert.Contains("blue", result); + + yield return null; + } + + [UnityTest] + public IEnumerator SetPropArray_WithAllNullOrEmptyValues_ThrowsAnError() + { + var player = new Player + { + props = new Prop[] { } + }; + + try + { + player.SetPropArray("colours", new string[] { null, "" }, false); + Assert.Fail("Expected exception was not thrown"); + } + catch (Exception ex) + { + Assert.AreEqual(ex.Message, "Values for prop array colours must contain at least one non-empty value"); + } + + yield return null; + } + + [UnityTest] + public IEnumerator SetPropArray_OnExistingPopulatedArray_ReplacesOldValues() + { + var player = new Player + { + props = new[] { + new Prop(("colours[]", "red")), + new Prop(("colours[]", "blue")) + } + }; + + player.SetPropArray("colours", new [] { "green", "yellow" }, false); + + var result = player.GetPropArray("colours").ToList(); + Assert.AreEqual(2, result.Count); + Assert.Contains("green", result); + Assert.Contains("yellow", result); + + yield return null; + } + + [UnityTest] + public IEnumerator SetPropArray_WithEmptyCollection_ThrowsAnError() + { + var player = new Player + { + props = new Prop[] { } + }; + + try + { + player.SetPropArray("colours", new string[] {}, false); + Assert.Fail("Expected exception was not thrown"); + } + catch (Exception ex) + { + Assert.AreEqual(ex.Message, "Values for prop array colours must contain at least one non-empty value"); + } + + yield return null; + } + + [UnityTest] + public IEnumerator SetPropArray_WhenArrayWasPreviouslyDeleted_ClearsNullEntryAndSetsNewValues() + { + var player = new Player + { + props = new[] { + new Prop(("colours[]", null)) + } + }; + + player.SetPropArray("colours", new [] { "red", "blue" }, false); + + var result = player.GetPropArray("colours").ToList(); + Assert.AreEqual(2, result.Count); + Assert.Contains("red", result); + Assert.Contains("blue", result); + + yield return null; + } + } +} diff --git a/Assets/Talo Game Services/Talo/Tests/EntityWithProps/SetPropArrayTest.cs.meta b/Assets/Talo Game Services/Talo/Tests/EntityWithProps/SetPropArrayTest.cs.meta new file mode 100644 index 0000000..f679a4a --- /dev/null +++ b/Assets/Talo Game Services/Talo/Tests/EntityWithProps/SetPropArrayTest.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: 7871f8c73d8da4381bf5a466a67c66c9 \ No newline at end of file diff --git a/Assets/Talo Game Services/Talo/Tests/EntityWithProps/SetPropTest.cs b/Assets/Talo Game Services/Talo/Tests/EntityWithProps/SetPropTest.cs new file mode 100644 index 0000000..a11da48 --- /dev/null +++ b/Assets/Talo Game Services/Talo/Tests/EntityWithProps/SetPropTest.cs @@ -0,0 +1,44 @@ +using System.Collections; +using NUnit.Framework; +using UnityEngine.TestTools; + +namespace TaloGameServices.Test { + internal class SetPropTest + { + [UnityTest] + public IEnumerator SetProp_WhenPropDoesNotAlreadyExist_AppendsTheNewProp() + { + var player = new Player + { + props = new[] { + new Prop(("key1", "value1")), + new Prop(("key2", "value2")) + } + }; + + player.SetProp("key3", "value3", false); + + Assert.AreEqual(player.GetProp("key3"), "value3"); + + yield return null; + } + + [UnityTest] + public IEnumerator SetProp_WhenPropAlreadyExists_UpdatesTheProp() + { + var player = new Player + { + props = new[] { + new Prop(("key1", "value1")), + new Prop(("key2", "value2")) + } + }; + + player.SetProp("key2", "2value2updated", false); + + Assert.AreEqual(player.GetProp("key2"), "2value2updated"); + + yield return null; + } + } +} diff --git a/Assets/Talo Game Services/Talo/Tests/EntityWithProps/SetPropTest.cs.meta b/Assets/Talo Game Services/Talo/Tests/EntityWithProps/SetPropTest.cs.meta new file mode 100644 index 0000000..a998aef --- /dev/null +++ b/Assets/Talo Game Services/Talo/Tests/EntityWithProps/SetPropTest.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: 89e1b69e7e74b487d80948e45f5bd9b3 \ No newline at end of file diff --git a/Assets/Talo Game Services/Talo/Tests/LiveConfig/GetPropTest.cs b/Assets/Talo Game Services/Talo/Tests/LiveConfig/GetPropTest.cs index 19ab055..97a40c3 100644 --- a/Assets/Talo Game Services/Talo/Tests/LiveConfig/GetPropTest.cs +++ b/Assets/Talo Game Services/Talo/Tests/LiveConfig/GetPropTest.cs @@ -4,7 +4,7 @@ using System; namespace TaloGameServices.Test { - internal class GetPropTest + internal class LiveConfigGetPropTest { [UnityTest] public IEnumerator GetProp_WithALiveConfigThatHasValues_ReturnsCorrectValue() @@ -41,7 +41,7 @@ public IEnumerator GetProp_WhenConvertingTypeToBoolean_ReturnsCorrectValue() { var config = new LiveConfig(new[] { new Prop(("halloweenEventEnabled", "True")) }); - Assert.AreEqual(true, config.GetProp("halloweenEventEnabled", false)); + Assert.AreEqual(true, config.GetProp("halloweenEventEnabled", false)); yield return null; } @@ -51,7 +51,7 @@ public IEnumerator GetProp_WhenConvertingTypeToNumber_ReturnsCorrectValue() { var config = new LiveConfig(new[] { new Prop(("maxLevel", "60")) }); - Assert.AreEqual(60, config.GetProp("maxLevel", 0)); + Assert.AreEqual(60, config.GetProp("maxLevel", 0)); yield return null; }