public IEnumerator OutOfGameTime_DoesNotUpdateOnSave( [ValueSource(nameof(RealSeconds))] double secondsOutOfGame ) { FortuneFountainSaveData fortuneFountainSaveData = FortuneFountainSaveData.NewSaveFile(nameof(OutOfGameTime_DoesNotUpdateOnSave)); var outOfGameSpan = TimeSpan.FromSeconds(secondsOutOfGame); //Set the OutOfGameTimeSinceLastThrow (using reflection since the setter is private) fortuneFountainSaveData.GetType().GetProperty(nameof(FortuneFountainSaveData.OutOfGameTimeSinceLastThrow)) ?.SetValue(fortuneFountainSaveData, outOfGameSpan); Assert.That(fortuneFountainSaveData.OutOfGameTimeSinceLastThrow, Is.EqualTo(outOfGameSpan)); const int repetitions = 5; for (int rep = 0; rep < repetitions; rep++) { yield return(new WaitForSecondsRealtime(0.01f)); fortuneFountainSaveData.Save(false); Assert.That(fortuneFountainSaveData.OutOfGameTimeSinceLastThrow, Is.EqualTo(outOfGameSpan), $"[{nameof(rep)}: {rep}] The {nameof(FortuneFountainSaveData.OutOfGameTimeSinceLastThrow)} should not have changed when we {nameof(FortuneFountainSaveData.Save)}-ed!"); } }
public void TestSerializeThrowables() { const string nickName = nameof(TestSerializeThrowables); FortuneFountainSaveData fortuneFountainSaveData = FortuneFountainSaveData.NewSaveFile(nickName); for (int i = 0; i < ValuableDatabase.ValuableTypes.Length; i++) { // copying `i` into `index` inside the loop 'cus otherwise lambdas can get messed up var index = i; var karmaValue = Random.Range(1, 25); var valuableType = ValuableDatabase.ValuableTypes[index]; Log($"Grabbing a {valuableType} with a value of {karmaValue}"); fortuneFountainSaveData.Hand.AddToHand(new ThrowableValuable(valuableType, karmaValue)); fortuneFountainSaveData.Save(useReSaveDelay: false); Log($"before loading throwables:", fortuneFountainSaveData.Hand.Throwables.JoinLines()); //load the save data we created FortuneFountainSaveData loadedSaveData = FortuneFountainSaveData.Load(nickName); Log($"original SaveData:", fortuneFountainSaveData); Log($"loaded SaveData:", loadedSaveData); AssertAll.Of( () => Assert.That(loadedSaveData.ToJson(), Contains.Substring($"\"{nameof(Hand._throwables)}\":")), () => Assert.That(loadedSaveData.Hand.Throwables.Count, Is.EqualTo(index + 1)), () => Assert.That(loadedSaveData.Hand.Throwables[index] as ThrowableValuable, Has.Property(nameof(ThrowableValuable.ValuableType)).EqualTo(valuableType)), () => Assert.That(loadedSaveData.Hand.Throwables[index] as ThrowableValuable, Has.Property(nameof(ThrowableValuable.PresentValue)).EqualTo(karmaValue)) ); } }
public IEnumerator OutOfGameTime_UpdatesOnReload( [ValueSource(nameof(RealSeconds))] double secondsOutOfGame ) { FortuneFountainSaveData fortuneFountainSaveData = FortuneFountainSaveData.NewSaveFile(nameof(OutOfGameTime_UpdatesOnReload)); //Go to the next frame and then save (to make sure we "discard" the time spent creating the save file) yield return(null); fortuneFountainSaveData.Save(false); //record the time we saved at var saveTime = FrameTime.Now; var outOfGameTime = TimeSpan.FromSeconds(secondsOutOfGame); yield return(TestUtils.WaitFor(outOfGameTime)); fortuneFountainSaveData.Reload(); //record the time we loaded at var loadTime = FrameTime.Now; //make sure that the OOG-time is the difference between loading and saving //NOTE: This value will always be slightly larger than secondsOutOfGame due to the time actually spend saving & loading, etc. Assert.That(fortuneFountainSaveData, Has.Property(nameof(fortuneFountainSaveData.OutOfGameTimeSinceLastThrow)).EqualTo(loadTime - saveTime)); }
public void TestSerializeEmptyHand() { const string nickName = nameof(TestSerializeEmptyHand); FortuneFountainSaveData fortuneFountainSaveData = FortuneFountainSaveData.NewSaveFile(nickName); LogUtils.Log(fortuneFountainSaveData); Assert.That(fortuneFountainSaveData.ToJson(), Contains.Substring($"\"{nameof(Hand)}\": {{")); }
public void TestInGameTimeSinceLastThrowWithoutSaving( [ValueSource(nameof(Seconds))] double secondsInGame ) { FortuneFountainSaveData fortuneFountainSaveData = FortuneFountainSaveData.NewSaveFile(nameof(TestInGameTimeSinceLastThrowWithoutSaving)); var inGameTime = TimeSpan.FromSeconds(secondsInGame); fortuneFountainSaveData.Hand.LastThrowTime = FrameTime.Now - inGameTime; Assert.That(fortuneFountainSaveData.InGameTimeSinceLastThrow, Is.InRange(inGameTime.Multiply(0.999), inGameTime.Multiply(1.001))); }
public IEnumerator OutOfGameTime_MultipleSessionsWithoutThrowing() { const float sessionSeconds = 2f; const int numberOfSessions = 2; var sessionSpan = TimeSpan.FromSeconds(sessionSeconds); locations = Locations.None; FortuneFountainSaveData fortuneFountainSaveData = FortuneFountainSaveData.NewSaveFile(nameof(OutOfGameTime_MultipleSessionsWithoutThrowing)); yield return(null); fortuneFountainSaveData.Save(false); var realTimeNowAtSave = FrameTime.Now; Assert.That(fortuneFountainSaveData, Has.Property(nameof(fortuneFountainSaveData.OutOfGameTimeSinceLastThrow)).EqualTo(TimeSpan.Zero), $"We haven't waited yet, so there shouldn't be any {nameof(FortuneFountainSaveData.OutOfGameTimeSinceLastThrow)}!"); Assert.That(fortuneFountainSaveData, Has.Property(nameof(fortuneFountainSaveData.LastSaveTime)).EqualTo(realTimeNowAtSave)); var expectedOutOfGameTime = TimeSpan.Zero; for (int session = 0; session < numberOfSessions; session++) { yield return(TestUtils.WaitForRealtime(sessionSpan)); fortuneFountainSaveData.Reload(); var realTimeNowAtReload = FrameTime.Now; Assert.That(realTimeNowAtReload, Is.Not.EqualTo(realTimeNowAtSave)); var frameTimeDuration = realTimeNowAtReload - realTimeNowAtSave; expectedOutOfGameTime += frameTimeDuration; Assert.That( fortuneFountainSaveData, Has.Property(nameof(fortuneFountainSaveData.OutOfGameTimeSinceLastThrow)) .EqualTo(expectedOutOfGameTime) ); yield return(TestUtils.WaitForRealtime(sessionSpan)); fortuneFountainSaveData.Save(false); realTimeNowAtSave = FrameTime.Now; } }
public void TestFirstValuableEnabledOnNewSave() { const string nickName = nameof(TestFirstValuableEnabledOnNewSave); var fortuneFountainSaveData = FortuneFountainSaveData.NewSaveFile(nickName); const ValuableType expectedFirstValuableType = 0; Assert.That(fortuneFountainSaveData.PlayerValuables, Has.Some.Property(nameof(PlayerValuable.ValuableType)).EqualTo(expectedFirstValuableType), $"The new save file didn't contain PlayerValuable type 0 ({expectedFirstValuableType})!"); Assert.That(fortuneFountainSaveData.PlayerValuables.Count, Is.EqualTo(1), "The save file contained extra player valuables!"); }
public IEnumerator TestCompleteButUncheckedGenDuringPreviousSession( [Values(4)] int uniformValuableGenerationRate, [Values(2)] int itemsPerWait ) { GameManager.SaveData = FortuneFountainSaveData.NewSaveFile(nameof(TestCompleteButUncheckedGenDuringPreviousSession)); //Set the uniform gen rates to a decent number, so that we don't have to wait very long to get meaningful results GameManager.SaveData.PlayerValuables = TestData.GetUniformPlayerValuables(GameManager.SaveData, uniformValuableGenerationRate); var genInterval = GameManager.SaveData.PlayerValuables[0].GenerateInterval; float genWait = (float)genInterval.TotalSeconds; //Create the generation counters var genCounters = CreateValuableGenerationCounters(GameManager.SaveData.PlayerValuables); //Wait long enough to generate something (but DON'T check for it) yield return(new WaitForSecondsRealtime(genWait * itemsPerWait)); //Save the game - still without checking for any generation GameManager.SaveData.Save(false); //Wait long enough that we COULD have generated something if we were playing; then reload yield return(new WaitForSecondsRealtime(genWait * itemsPerWait)); GameManager.SaveData.Reload(); //Wait long enough to generate something during THIS session as well yield return(new WaitForSecondsRealtime(genWait * itemsPerWait)); //Make sure that we still haven't generated anything, and that that LastGenerationTime values haven't changed Assert.That(genCounters, Has.All.Values().EqualTo(new ValuableGenerationCounter() { Amount = 0, Events = 0 })); //Check for generation var itemsGenerated = GameManager.SaveData.PlayerValuables.CheckGenerate(); //Assert that we've now had exactly 1 generation event, where we generated 2 * itemsPerWait Assert.That(genCounters, Has.All.Values().EqualTo(new ValuableGenerationCounter() { Amount = 2 * itemsPerWait, Events = 1 })); Assert.That(itemsGenerated, Has.All.EqualTo(2 * itemsPerWait)); }
/// <summary> /// "Starts" the game, doing things such as loading the appropriate save file. /// </summary> private void LoadFortuneFountain() { SaveFileName = GetAppropriateSaveFileName(); if (Application.isEditor && ClearDevSaveFileOnPlay) { ClearDevSaveFile(); } //attempt to load the save data; if we can't, create a new one if (!FortuneFountainSaveData.TryLoad(SaveFileName, out SaveData)) { LogUtils.Log($"No save file exists with the {nameof(FortuneFountainSaveData.Nickname)} {SaveFileName}, so we're creating a new one..."); SaveData = FortuneFountainSaveData.NewSaveFile(SaveFileName); } LogUtils.Log(SaveData); }
public void ThrowResetsGenerateTimeUtilized() { FortuneFountainSaveData fortuneFountainSaveData = FortuneFountainSaveData.NewSaveFile(nameof(ThrowResetsGenerateTimeUtilized)); fortuneFountainSaveData.PlayerValuables = TestData.GetUniformPlayerValuables(fortuneFountainSaveData); var utilizedTime = TimeSpan.FromSeconds(1); fortuneFountainSaveData.PlayerValuables.ForEach(it => it.GenerateTimeUtilized = utilizedTime); Assert.That(fortuneFountainSaveData.PlayerValuables, Has.All.Property(nameof(PlayerValuable.GenerateTimeUtilized)).EqualTo(utilizedTime)); fortuneFountainSaveData.Hand.Throw(); Assert.That(fortuneFountainSaveData.PlayerValuables, Has.All.Property(nameof(PlayerValuable.GenerateTimeUtilized)).EqualTo(TimeSpan.Zero)); }
public void TestGenerateIsLimitedByRate() { const string nickName = nameof(TestGenerateIsLimitedByRate); GameManager.SaveData = FortuneFountainSaveData.NewSaveFile(nickName); var generateCounter = 0; PlayerValuable.GeneratePlayerValuableEvent += (valuable, amount) => generateCounter++; LogUtils.Log(GameManager.SaveData.PlayerValuables[0]); LogUtils.Log(JsonConvert.SerializeObject(GameManager.SaveData.PlayerValuables[0])); for (var i = 0; i < 10; i++) { GameManager.SaveData.PlayerValuables.CheckGenerate(); Assert.That(generateCounter, Is.EqualTo(0), $"Error on {i + 1}th generation!"); } }
public IEnumerator EventSubscribersPersistAfterReloadMultiple() { GameManager.SaveData = FortuneFountainSaveData.NewSaveFile(nameof(EventSubscribersPersistAfterReloadMultiple)); var eventWasTriggered = false; PlayerValuable.GeneratePlayerValuableEvent += (valuable, amount) => eventWasTriggered = true; yield return(new WaitForSecondsRealtime((float)GameManager.SaveData.PlayerValuables[0].GenerateInterval .TotalSeconds)); GameManager.SaveData.Save(false); GameManager.SaveData.Reload(); GameManager.SaveData.Reload(); GameManager.SaveData.Reload(); GameManager.SaveData.PlayerValuables.CheckGenerate(); Assert.True(eventWasTriggered); }
public void TestSimpleGeneration(double rate, double secondsSinceLastGenerateCheckAndThrow) { GameManager.SaveData = FortuneFountainSaveData.NewSaveFile(nameof(TestSimpleGeneration)); var startTime = FrameTime.Now.AddSeconds(-secondsSinceLastGenerateCheckAndThrow); GameManager.SaveData.PlayerValuables = TestData.GetUniformPlayerValuables(GameManager.SaveData, rate); GameManager.SaveData.Hand.LastThrowTime = startTime; GameManager.SaveData.LastLoadTime = startTime; ReflectionUtils.SetVariableValue(GameManager.SaveData, nameof(GameManager.SaveData.LastSaveTime), startTime); GameManager.SaveData.PlayerValuables.ForEach(it => it.LastGenerateCheckTime = startTime); var generatedItems = GameManager.SaveData.PlayerValuables.CheckGenerate(TimeSpan.MaxValue); //TODO: This test probably needs to be revisited so that this can be a cleaner assertion var expectedItemsGenerated = secondsSinceLastGenerateCheckAndThrow * rate; AssertAll.Of( generatedItems, Has.All.EqualTo(generatedItems[0]), Is.All.InRange(expectedItemsGenerated.Floor(), expectedItemsGenerated.Ceiling()) ); }
public IEnumerator TestPartialUncheckedItemsGeneratedDuringLastSession( [Values(0.5)] double previousGenIntervals, [Values(3)] double totalItemsToGenerate ) { Assume.That(previousGenIntervals, Is.LessThan(1)); Assume.That(totalItemsToGenerate, Is.GreaterThan(previousGenIntervals)); GameManager.SaveData = FortuneFountainSaveData.NewSaveFile(nameof(TestPartialUncheckedItemsGeneratedDuringLastSession)); GameManager.SaveData.PlayerValuables = TestData.GetUniformPlayerValuables(GameManager.SaveData); yield return(TestUtils.WaitForRealtime(GameManager.SaveData.PlayerValuables[0].GenerateInterval, previousGenIntervals)); GameManager.SaveData.Save(false); var genCounters = CreateValuableGenerationCounters(GameManager.SaveData.PlayerValuables); yield return(TestUtils.WaitForRealtime(GameManager.SaveData.PlayerValuables[0].GenerateInterval, 2)); GameManager.SaveData.Reload(); var sleepIntervals = totalItemsToGenerate - previousGenIntervals + 0.5; LogUtils.Log($"{nameof(sleepIntervals)} = {sleepIntervals}"); yield return(TestUtils.WaitForRealtime(GameManager.SaveData.PlayerValuables[0].GenerateInterval, sleepIntervals)); var itemsGenerated = GameManager.SaveData.PlayerValuables.CheckGenerate(); Assert.That(itemsGenerated, Has.All.EqualTo(totalItemsToGenerate)); Assert.That(genCounters, Has.All.Values().EqualTo(new ValuableGenerationCounter() { Amount = (int)totalItemsToGenerate, Events = 1 })); }
public IEnumerator OutOfGameTime_UpdatesOnLoad( [ValueSource(nameof(RealSeconds))] double secondsOutOfGame ) { FortuneFountainSaveData fortuneFountainSaveData = FortuneFountainSaveData.NewSaveFile(nameof(OutOfGameTime_UpdatesOnLoad)); yield return(null); fortuneFountainSaveData.Save(false); var saveTime = FrameTime.Now; var outOfGameSpan = TimeSpan.FromSeconds(secondsOutOfGame); yield return(TestUtils.WaitForRealtime(outOfGameSpan)); var loadedSaveData = FortuneFountainSaveData.Load(fortuneFountainSaveData.Nickname); var loadTime = FrameTime.Now; Assert.That(loadedSaveData, Has.Property(nameof(loadedSaveData.OutOfGameTimeSinceLastThrow)).EqualTo(loadTime - saveTime)); }
public IEnumerator GenerateAllViaCollectionExtension( [Values(true, false)] bool checkThrowables ) { const string nickName = nameof(TestGenerateIsLimitedByRate); GameManager.SaveData = FortuneFountainSaveData.NewSaveFile(nickName); GameManager.SaveData.PlayerValuables = TestData.GetUniformPlayerValuables(GameManager.SaveData); Assume.That(GameManager.SaveData.PlayerValuables.Count, Is.GreaterThan(1), "We need to test more than 1 valuable type!"); Assume.That(GameManager.SaveData.PlayerValuables, Has.All.Property("Rate").EqualTo(1), "All valuables should have a generation rate of 1!"); //Add counter events for each of the valuables var generateCounters = CreateValuableGenerationCounters(GameManager.SaveData.PlayerValuables); //Set the LastGenerateTime for each valuable to be their previous interval (that way, they are ready to generate) var setTime = FrameTime.Now - GameManager.SaveData.PlayerValuables[0].GenerateInterval; GameManager.SaveData.Hand.LastThrowTime = setTime; GameManager.SaveData.PlayerValuables.ForEach(it => it.LastGenerateCheckTime = setTime); if (checkThrowables) { Assert.That(GameManager.SaveData.Hand.Throwables.Count, Is.EqualTo(0)); } //Generate stuff GameManager.SaveData.PlayerValuables.CheckGenerate(); Assert.That(generateCounters, Has.All.Values().EqualTo(new ValuableGenerationCounter() { Events = 1, Amount = 1 })); if (checkThrowables) { Assert.That(GameManager.SaveData.Hand.Throwables.Count, Is.EqualTo(generateCounters.Sum(it => it.Value.Amount))); } //sleep so we can expect to generate another item yield return(TestUtils.WaitForRealtime(GameManager.SaveData.PlayerValuables[0].GenerateInterval)); //Generate stuff GameManager.SaveData.PlayerValuables.CheckGenerate(); Assert.That(generateCounters, Has.All.Values().EqualTo(new ValuableGenerationCounter() { Events = 2, Amount = 2 })); if (checkThrowables) { Assert.That(GameManager.SaveData.Hand.Throwables.Count, Is.EqualTo(generateCounters.Sum(it => it.Value.Amount))); } //sleep so that we can expect to generate _2_ more items yield return (TestUtils.WaitForRealtime(GameManager.SaveData.PlayerValuables[0].GenerateInterval.Multiply(2))); //Generate stuff GameManager.SaveData.PlayerValuables.CheckGenerate(); Assert.That(generateCounters, Has.All.Values().EqualTo(new ValuableGenerationCounter() { Events = 3, Amount = 4 })); if (checkThrowables) { Assert.That(GameManager.SaveData.Hand.Throwables, Has.Property(nameof(Hand.Throwables.Count)).EqualTo(generateCounters.Sum(it => it.Value.Amount))); } }
public void GenerateEventsLimitedByMaxGenerateTime( double generateTimeLimitInSeconds, double itemsPerSecond, double extraGenerationSeconds ) { //the number of items we expect to generate - which should always be limited by maxGenerationSeconds var expectedItemsGenerated = generateTimeLimitInSeconds * itemsPerSecond; Ignore.Unless( () => Assume.That(generateTimeLimitInSeconds, Is.GreaterThan(0), $"{nameof(generateTimeLimitInSeconds)} must be greater than 0!"), () => Assume.That(itemsPerSecond, Is.GreaterThan(0), $"{nameof(itemsPerSecond)} must be greater than 0!"), () => Assume.That(extraGenerationSeconds, Is.GreaterThanOrEqualTo(0), $"{nameof(extraGenerationSeconds)} must be positive!"), () => Assume.That(expectedItemsGenerated, Is.GreaterThanOrEqualTo(1), $"{nameof(expectedItemsGenerated)} must be at least 1!") ); //this test is very quick and runs a LOT of times, so we should disable logging to prevent it from being crazy slow // LogUtils.locations = LogUtils.Locations.None; const string nickName = nameof(GenerateEventsLimitedByMaxGenerateTime); GameManager.SaveData = FortuneFountainSaveData.NewSaveFile(nickName); //Setting up the player data GameManager.SaveData.PlayerValuables = TestData.GetUniformPlayerValuables(GameManager.SaveData, itemsPerSecond); GameManager.SaveData.Hand.LastThrowTime = FrameTime.Now - TimeSpan.FromSeconds(generateTimeLimitInSeconds + extraGenerationSeconds); GameManager.SaveData.PlayerValuables.ForEach(it => it.LastGenerateCheckTime = GameManager.SaveData.Hand.LastThrowTime); GameManager.SaveData.Hand.GenerateTimeLimit = TimeSpan.FromSeconds(generateTimeLimitInSeconds); Assert.That(GameManager.SaveData.PlayerValuables[0].GenerateInterval, Is.LessThanOrEqualTo(GameManager.SaveData.Hand.GenerateTimeLimit), $"We must have enough time to generate at least one item - i.e. {nameof(PlayerValuable.GenerateInterval)} <= {nameof(Hand.GenerateTimeLimit)}!"); var genCounters = CreateValuableGenerationCounters(GameManager.SaveData.PlayerValuables); //Generate the items GameManager.SaveData.PlayerValuables.CheckGenerate(); //Check for the proper number of events & actual items generated AssertAll.Of( () => Assert.That( GroupThrowables(GameManager.SaveData.Hand.Throwables), Has.All.Values().With.Count.InRange(Math.Floor(expectedItemsGenerated), Math.Ceiling(expectedItemsGenerated)) ), () => Assert.That(genCounters, Has.All.Values().With.Property(nameof(ValuableGenerationCounter.Events)).EqualTo(1)), () => Assert.That(genCounters, Has.All.Values().With.Property(nameof(ValuableGenerationCounter.Amount)) .InRange(Math.Floor(expectedItemsGenerated), Math.Ceiling(expectedItemsGenerated))) ); }