using NUnit.Framework; using System; using System.Collections.Generic; using System.IO; using UnityEngine; [TestFixture] public class PersistentDataTests { /// /// Create a new path so the existing .json file will not be overwritten /// private static string PATH = $"{Application.persistentDataPath}/wesign_unit_test.json"; /// /// Reference to the pdc to perform tests on /// private PersistentDataController pdc = null; /// /// A dummy serializable struct to perform test operations on /// [Serializable] private struct Struct { public int r, g, b; public float x, y, z; } /// /// A dummy serializable enum to perform test operations on /// private enum Enum { SQUARE, TRIANBLE, CIRCLE } [SetUp] public void Setup_PersistentDataController() { PersistentDataController.PATH = PersistentDataTests.PATH; //PersistentDataController.PATH = null; pdc = PersistentDataController.GetInstance(); } [Test] public void Test_PersistentDataController_GetInstance() { Assert.IsNotNull(pdc); //Assert.AreEqual($"{Application.persistentDataPath}/wesign_saved_data.json", PersistentDataController.PATH); } [Test] public void Test_PersistentDataController_Clear() { pdc.Load(); pdc.Clear(); Assert.Zero(pdc.GetUsers().Count); Assert.AreEqual(-1, pdc.GetCurrentUser()); } [Test] public void Test_PersistentDataController_Save_Empty() { pdc.Load(); pdc.Clear(); pdc.Save(); FileAssert.Exists(PATH); string content = File.ReadAllText(PATH); string expected = $"{{\"version\":{PersistentDataController.VERSION},\"users\":[],\"currentUser\":-1,\"currentMinigame\":0,\"currentCourse\":0,\"currentTheme\":0}}"; Assert.AreEqual(expected, content); } [Test] public void Test_PersistentDataController_Save_New() { pdc.Load(); pdc.Clear(); if (File.Exists(PATH)) File.Delete(PATH); pdc.Save(); FileAssert.Exists(PATH); string content = File.ReadAllText(PATH); string expected = $"{{\"version\":{PersistentDataController.VERSION},\"users\":[],\"currentUser\":-1,\"currentMinigame\":0,\"currentCourse\":0,\"currentTheme\":0}}"; Assert.AreEqual(expected, content); } [Test] public void Test_PersistentDataController_Load_Existing() { string content = $"{{\"version\":{PersistentDataController.VERSION},\"users\":[],\"currentUser\":-1,\"currentMinigame\":0,\"currentCourse\":0,\"currentTheme\":0}}"; File.WriteAllText(PATH, content); Assert.IsTrue(pdc.Load(false)); } [Test] public void Test_PersistentDataController_Load_OlderVersion() { string content = $"{{\"version\":{PersistentDataController.VERSION - 1},\"users\":[],\"currentUser\":-1,\"currentMinigame\":0,\"currentCourse\":0,\"currentTheme\":0}}"; File.WriteAllText(PATH, content); Assert.IsFalse(pdc.Load(false)); } [Test] public void Test_PersistentDataController_Load_NewerVersion() { string content = $"{{\"version\":{PersistentDataController.VERSION + 1},\"users\":[],\"currentUser\":-1,\"currentMinigame\":0,\"currentCourse\":0,\"currentTheme\":0}}"; File.WriteAllText(PATH, content); Assert.IsFalse(pdc.Load(false)); } [Test] public void Test_PersistentDataController_Load_New() { if (File.Exists(PATH)) File.Delete(PATH); Assert.IsFalse(pdc.Load(false)); FileAssert.DoesNotExist(PATH); } [Test] public void Test_PersistentDataController_Load_Exception() { File.WriteAllText(PATH, "https://www.youtube.com/watch?v=dQw4w9WgXcQ"); Assert.IsFalse(pdc.Load(false)); Assert.AreEqual("https://www.youtube.com/watch?v=dQw4w9WgXcQ", File.ReadAllText(PATH)); } [Test] public void Test_PersistentDataController_Load_Override() { File.WriteAllText(PATH, "https://www.youtube.com/watch?v=dQw4w9WgXcQ"); Assert.IsFalse(pdc.Load(true)); string content = File.ReadAllText(PATH); string expected = $"{{\"version\":{PersistentDataController.VERSION},\"users\":[],\"currentUser\":-1,\"currentMinigame\":0,\"currentCourse\":0,\"currentTheme\":0}}"; Assert.AreEqual(expected, content); } [Test] public void Test_PersistentDataController_Version() { const int VERSION = 0x04_03; Assert.AreEqual(VERSION, PersistentDataController.VERSION); } [Test] public void Test_PersistentDataController_AddUser() { pdc.Load(); pdc.Clear(); var d = new PersistentDataController.SavedUserData() { username = "username", avatarIndex = 0 }; pdc.AddUser(d); string content = File.ReadAllText(PATH); string expected = $"{{\"version\":{PersistentDataController.VERSION},\"users\":[{{\"entries\":[],\"username\":\"username\",\"avatarIndex\":0,\"playtime\":0.0,\"minigames\":[],\"courses\":[]}}],\"currentUser\":0,\"currentMinigame\":0,\"currentCourse\":0,\"currentTheme\":0}}"; Assert.AreEqual(expected, content); } [Test] public void Test_PersistentDataController_GetUsers() { pdc.Load(); pdc.Clear(); var d = new PersistentDataController.SavedUserData() { username = "username", avatarIndex = 0 }; pdc.AddUser(d); var users = pdc.GetUsers(); Assert.AreEqual(1, users.Count); Assert.AreEqual("username", users[0].username); Assert.AreEqual(0, users[0].avatarIndex); } [Test] public void Test_PersistentDataController_GetCurrentUser() { pdc.Load(); pdc.Clear(); Assert.AreEqual(-1, pdc.GetCurrentUser()); pdc.AddUser(new PersistentDataController.SavedUserData() { username = "username", avatarIndex = 0 }); Assert.AreEqual(0, pdc.GetCurrentUser()); } [Test] public void Test_PersistentDataController_SetCurrentUser() { pdc.Load(); pdc.Clear(); for (int i = 0; i < 5; i++) pdc.AddUser(new PersistentDataController.SavedUserData() { username = $"username_{i}", avatarIndex = i }); pdc.SetCurrentUser(3); Assert.AreEqual(3, pdc.GetCurrentUser()); } [Test] public void Test_PersistentDataController_SetCurrentUser_Invalid() { pdc.Load(); pdc.Clear(); pdc.AddUser(new PersistentDataController.SavedUserData() { username = $"username", avatarIndex = 0 }); Assert.Throws(delegate { pdc.SetCurrentUser(3); }); } [Test] public void Test_PersistentDataController_SetCurrentUser_Empty() { pdc.Load(); pdc.Clear(); Assert.Throws(delegate { pdc.SetCurrentUser(0); }); } [Test] public void Test_PersistentDataController_DeleteUser_BeforeCurrent() { pdc.Load(); pdc.Clear(); var users = new List(); for (int i = 0; i < 5; i++) { var d = new PersistentDataController.SavedUserData() { username = $"username_{i}", avatarIndex = i }; pdc.AddUser(d); users.Add(d); } pdc.SetCurrentUser(0); users.RemoveAt(2); pdc.DeleteUser(2); var vsers = pdc.GetUsers(); Assert.AreEqual(0, pdc.GetCurrentUser()); Assert.AreEqual(users.Count, vsers.Count); for (int i = 0; i < 4; i++) { Assert.AreEqual(users[i].username, vsers[i].username); Assert.AreEqual(users[i].avatarIndex, vsers[i].avatarIndex); } } [Test] public void Test_PersistentDataController_DeleteUser_Current() { pdc.Load(); pdc.Clear(); var users = new List(); for (int i = 0; i < 5; i++) { var d = new PersistentDataController.SavedUserData() { username = $"username_{i}", avatarIndex = i }; pdc.AddUser(d); users.Add(d); } pdc.SetCurrentUser(2); users.RemoveAt(2); pdc.DeleteUser(2); var vsers = pdc.GetUsers(); Assert.AreEqual(1, pdc.GetCurrentUser()); Assert.AreEqual(users.Count, vsers.Count); for (int i = 0; i < 4; i++) { Assert.AreEqual(users[i].username, vsers[i].username); Assert.AreEqual(users[i].avatarIndex, vsers[i].avatarIndex); } } [Test] public void Test_PersistentDataController_DeleteUser_AfterCurrent() { pdc.Load(); pdc.Clear(); var users = new List(); for (int i = 0; i < 5; i++) { var d = new PersistentDataController.SavedUserData() { username = $"username_{i}", avatarIndex = i }; pdc.AddUser(d); users.Add(d); } pdc.SetCurrentUser(4); users.RemoveAt(2); pdc.DeleteUser(2); var vsers = pdc.GetUsers(); Assert.AreEqual(3, pdc.GetCurrentUser()); Assert.AreEqual(users.Count, vsers.Count); for (int i = 0; i < 4; i++) { Assert.AreEqual(users[i].username, vsers[i].username); Assert.AreEqual(users[i].avatarIndex, vsers[i].avatarIndex); } } [Test] public void Test_PersistentDataController_DeleteUser_Invalid() { pdc.Load(); pdc.Clear(); pdc.AddUser(new PersistentDataController.SavedUserData() { username = $"username", avatarIndex = 0 }); Assert.Throws(delegate { pdc.SetCurrentUser(3); }); } [Test] public void Test_PersistentDataController_DeleteUser_Empty() { pdc.Load(); pdc.Clear(); Assert.Throws(delegate { pdc.DeleteUser(0); }); } [Test] public void Test_PersistentDataController_CurrentCourse() { pdc.Load(); pdc.Clear(); pdc.SetCurrentCourse(CourseIndex.FINGERSPELLING); Assert.AreEqual(CourseIndex.FINGERSPELLING, pdc.GetCurrentCourse()); } [Test] public void Test_PersistentDataController_CurrentMinigame() { pdc.Load(); pdc.Clear(); pdc.SetCurrentMinigame(MinigameIndex.SPELLING_BEE); Assert.AreEqual(MinigameIndex.SPELLING_BEE, pdc.GetCurrentMinigame()); } [Test] public void Test_PersistentDataController_CurrentTheme() { pdc.Load(); pdc.Clear(); pdc.SetCurrentTheme(ThemeIndex.SIGN_ALPHABET); Assert.AreEqual(ThemeIndex.SIGN_ALPHABET, pdc.GetCurrentTheme()); } [Test] public void Test_New_PersistentDataContainer() { var c = new PersistentDataController.PersistentDataContainer(); Assert.IsNotNull(c); Assert.Zero(c.entries.Count); } [Test] public void Test_PersistentDataContainer_Set_Invalid() { var c = new PersistentDataController.PersistentDataContainer(); Assert.IsFalse(c.Set("key", null)); } [Test] public void Test_PersistentDataContainer_Set_DuplicateKey() { var c = new PersistentDataController.PersistentDataContainer(); Assert.IsTrue(c.Set("key", 123)); Assert.IsTrue(c.Set("key", 321)); } [Test] public void Test_PersistentDataContainer_Set_Int() { var c = new PersistentDataController.PersistentDataContainer(); Assert.IsTrue(c.Set("key", 123)); } [Test] public void Test_PersistentDataContainer_Set_String() { var c = new PersistentDataController.PersistentDataContainer(); Assert.IsTrue(c.Set("key", "abc")); } [Test] public void Test_PersistentDataContainer_Set_Struct() { var c = new PersistentDataController.PersistentDataContainer(); Assert.IsTrue(c.Set("key", new Struct())); } [Test] public void Test_PersistentDataContainer_Set_Enum() { var c = new PersistentDataController.PersistentDataContainer(); Assert.IsTrue(c.Set("key", new Enum())); } [Test] public void Test_PersistentDataContainer_Get_InvalidType() { var c = new PersistentDataController.PersistentDataContainer(); c.Set("key", new Struct() { r = 255, g = 127, b = 63, x = 31, y = 15, z = 7 }); Assert.Throws(delegate { c.Get("key"); }); c.Set("key", 123); Assert.Throws(delegate { c.Get("key"); }); } [Test] public void Test_PersistentDataContainer_Get_KeyNotFound() { var c = new PersistentDataController.PersistentDataContainer(); c.Set("key", 123); Assert.Throws(delegate { c.Get("KEY"); }); } [Test] public void Test_PersistentDataContainer_Get_Empty() { var c = new PersistentDataController.PersistentDataContainer(); Assert.Throws(delegate { c.Get("key"); }); } [Test] public void Test_PersistentDataContainer_Get_Int() { var c = new PersistentDataController.PersistentDataContainer(); c.Set("key", 123); Assert.AreEqual(123, c.Get("key")); } [Test] public void Test_PersistentDataContainer_Get_String() { var c = new PersistentDataController.PersistentDataContainer(); c.Set("key", "value"); Assert.AreEqual("value", c.Get("key")); } [Test] public void Test_PersistentDataContainer_Get_Struct() { var c = new PersistentDataController.PersistentDataContainer(); var s = new Struct() { r = 255, g = 127, b = 63, x = 31, y = 15, z = 7 }; c.Set("key", s); Assert.AreEqual(s, c.Get("key")); } [Test] public void Test_PersistentDataContainer_Get_Enum() { var c = new PersistentDataController.PersistentDataContainer(); var e = Enum.CIRCLE; c.Set("key", e); Assert.AreEqual(e, c.Get("key")); } [Test] public void Test_PersistentDataContainer_Remove_Invalid() { var c = new PersistentDataController.PersistentDataContainer(); c.Set("key", 123); Assert.Throws(delegate { c.Remove("KEY"); }); } [Test] public void Test_PersistentDataContainer_Remove_Empty() { var c = new PersistentDataController.PersistentDataContainer(); Assert.Throws(delegate { c.Remove("key"); }); } [Test] public void Test_PersistentDataContainer_Remove_Int() { var c = new PersistentDataController.PersistentDataContainer(); c.Set("key", 123); c.Remove("key"); Assert.Throws(delegate { c.Get("key"); }); } [Test] public void Test_PersistentDataContainer_Remove_String() { var c = new PersistentDataController.PersistentDataContainer(); c.Set("key", "value"); c.Remove("key"); Assert.Throws(delegate { c.Get("key"); }); } [Test] public void Test_PersistentDataContainer_Remove_Struct() { var c = new PersistentDataController.PersistentDataContainer(); var s = new Struct() { r = 255, g = 127, b = 63, x = 31, y = 15, z = 7 }; c.Set("key", s); c.Remove("key"); Assert.Throws(delegate { c.Get("key"); }); } [Test] public void Test_PersistentDataContainer_Remove_Enum() { var c = new PersistentDataController.PersistentDataContainer(); c.Set("key", Enum.CIRCLE); c.Remove("key"); Assert.Throws(delegate { c.Get("key"); }); } [Test] public void Test_PersistentDataContainer_Pop_Invalid() { var c = new PersistentDataController.PersistentDataContainer(); c.Set("key", 123); Assert.Throws(delegate { c.Remove("KEY"); }); } [Test] public void Test_PersistentDataContainer_Pop_Empty() { var c = new PersistentDataController.PersistentDataContainer(); Assert.Throws(delegate { c.Remove("KEY"); }); } [Test] public void Test_PersistentDataContainer_Pop_Int() { var c = new PersistentDataController.PersistentDataContainer(); c.Set("key", 123); Assert.AreEqual(123, c.Pop("key")); Assert.Throws(delegate { c.Get("key"); }); } [Test] public void Test_PersistentDataContainer_Pop_String() { var c = new PersistentDataController.PersistentDataContainer(); c.Set("key", "value"); Assert.AreEqual("value", c.Pop("key")); Assert.Throws(delegate { c.Get("key"); }); } [Test] public void Test_PersistentDataContainer_Pop_Struct() { var c = new PersistentDataController.PersistentDataContainer(); var s = new Struct() { r = 255, g = 127, b = 63, x = 31, y = 15, z = 7 }; c.Set("key", s); Assert.AreEqual(s, c.Pop("key")); Assert.Throws(delegate { c.Get("key"); }); } [Test] public void Test_PersistentDataContainer_Pop_Enum() { var c = new PersistentDataController.PersistentDataContainer(); c.Set("key", Enum.CIRCLE); Assert.AreEqual(Enum.CIRCLE, c.Pop("key")); Assert.Throws(delegate { c.Get("key"); }); } [Test] public void Test_PersistentDataContainer_Has_ValidKey() { var c = new PersistentDataController.PersistentDataContainer(); Assert.IsFalse(c.Has("key")); c.Set("key", 123); Assert.IsTrue(c.Has("key")); } [Test] public void Test_PersistentDataContainer_Has_InvalidKey() { var c = new PersistentDataController.PersistentDataContainer(); Assert.IsFalse(c.Has("KEY")); c.Set("key", 123); Assert.IsFalse(c.Has("KEY")); } [Test] public void Test_AddLearnable_AddsLearnable() { PersistentDataController.SavedCourseProgress progress = new PersistentDataController.SavedCourseProgress(); bool added = progress.AddLearnable("test learnable", 0); Assert.IsTrue(added); Assert.AreEqual(progress.learnables.Count, 1); Assert.AreEqual(progress.learnables[0].name, "test learnable"); Assert.AreEqual(progress.learnables[0].index, 0); } [Test] public void Test_AddLearnable_FailsWithDuplicateName() { PersistentDataController.SavedCourseProgress progress = new PersistentDataController.SavedCourseProgress(); progress.AddLearnable("test learnable", 0); bool added = progress.AddLearnable("test learnable", 1); Assert.IsFalse(added); Assert.AreEqual(progress.learnables.Count, 1); } [Test] public void Test_AddLearnable_FailsWithDuplicateIndex() { PersistentDataController.SavedCourseProgress progress = new PersistentDataController.SavedCourseProgress(); progress.AddLearnable("test learnable", 0); bool added = progress.AddLearnable("test learnable 2", 0); Assert.IsFalse(added); Assert.AreEqual(progress.learnables.Count, 1); } [Test] public void Test_UpdateLearnable_UpdatesProgress() { PersistentDataController.SavedCourseProgress progress = new PersistentDataController.SavedCourseProgress(); progress.AddLearnable("test learnable", 0); progress.UpdateLearnable("test learnable", 3.0f); Assert.AreEqual(progress.learnables[0].progress, 3.0f); } [Test] public void Test_UpdateLearnable_CropsProgressAtFive() { PersistentDataController.SavedCourseProgress progress = new PersistentDataController.SavedCourseProgress(); progress.AddLearnable("test learnable", 0); progress.UpdateLearnable("test learnable", 10.0f); Assert.AreEqual(progress.learnables[0].progress, 5.0f); Assert.AreEqual(progress.completedLearnables, 1); } [Test] public void Test_UpdateLearnable_CropsProgressAtNegativeFive() { PersistentDataController.SavedCourseProgress progress = new PersistentDataController.SavedCourseProgress(); progress.AddLearnable("test learnable", 0); progress.UpdateLearnable("test learnable", -10.0f); Assert.AreEqual(progress.learnables[0].progress, -5.0f); } [Test] public void Test_FindLearnable_ReturnsNullWhenNotFound() { PersistentDataController.SavedCourseProgress progress = new PersistentDataController.SavedCourseProgress(); progress.AddLearnable("test learnable 1", 0); progress.AddLearnable("test learnable 2", 1); PersistentDataController.SavedLearnableProgress learnable = progress.FindLearnable("not found"); Assert.IsNull(learnable); } [Test] public void Test_FindLearnable_ReturnsLearnableByName() { PersistentDataController.SavedCourseProgress progress = new PersistentDataController.SavedCourseProgress(); progress.AddLearnable("test learnable 1", 0); progress.AddLearnable("test learnable 2", 1); PersistentDataController.SavedLearnableProgress learnable = progress.FindLearnable("test learnable 2"); Assert.AreEqual(learnable.index, 1); } [Test] public void Test_AddNewLearnable_ReturnsFalseWhenNoUnusedLearnables() { PersistentDataController.SavedCourseProgress progress = new PersistentDataController.SavedCourseProgress(); progress.AddLearnable("test learnable 1", 0); progress.learnables[0].inUse = true; PersistentDataController.SavedLearnableProgress learnable = progress.AddNewLearnable(); Assert.IsNull(learnable); } [Test] public void Test_AddNewLearnable_ReturnsTrueWhenUnusedLearnableFound() { PersistentDataController.SavedCourseProgress progress = new PersistentDataController.SavedCourseProgress(); progress.AddLearnable("test learnable 1", 0); progress.AddLearnable("test learnable 2", 1); PersistentDataController.SavedLearnableProgress learnable = progress.AddNewLearnable(); Assert.IsNotNull(learnable); Assert.AreEqual(progress.inUseLearnables, 1); } [Test] public void Test_GetRandomLearnable_ReturnsNullWhenNoLearnables() { PersistentDataController.SavedCourseProgress progress = new PersistentDataController.SavedCourseProgress(); PersistentDataController.SavedLearnableProgress learnable = progress.GetRandomLearnable(); Assert.IsNull(learnable); } [Test] public void Test_GetRandomLearnable_ReturnsNullWhenOnlyCompletedLearnables() { PersistentDataController.SavedCourseProgress progress = new PersistentDataController.SavedCourseProgress(); progress.AddLearnable("test learnable 1", 0); progress.AddLearnable("test learnable 2", 1); progress.learnables[0].progress = 4.0f; progress.learnables[0].inUse = true; progress.learnables[1].progress = 4.0f; progress.learnables[1].inUse = true; progress.completedLearnables = 2; progress.inUseLearnables = 0; PersistentDataController.SavedLearnableProgress learnable = progress.GetRandomLearnable(); Assert.IsNull(learnable); } }