Neg_Utils/Achievments/Tests/ConfigTests.cs

380 lines
15 KiB
C#

using System;
using System.Collections;
using System.Collections.Generic;
using NUnit.Framework;
using UnityEngine;
using UnityEngine.TestTools;
namespace NEG.Utils.Achievments.Tests
{
using AchievmentTypes;
using static Internal.Extensions;
public class ConfigTests
{
public const string AchievmentsLabel = "TestAchievments";
public const string AchievmentIdToggle = "TOGGLE";
public const string AchievmentIdInt = "INT";
public const string AchievmentIdFloat = "FLOAT";
public const string AchievmentIdInvalid = "huptyrz";
public const int RandomProgress = 15;
public const int ProgressChangeDelta = 15;
public const int CompletedProgress = 100;
public const int OvershootProgress = 150;
#region Id And Types
[Test]
public void AchivmentInvalidId()
{
AchievmentManager manager = AchievmentManager.Builder.FromLabeledConfig(AchievmentsLabel).Build();
TestInvalidId(AchievmentIdInvalid, (id) => manager.GetAchievmentForId(id), "Get");
}
[Test]
public void AchivmentInvalidType()
{
AchievmentManager manager = AchievmentManager.Builder.FromLabeledConfig(AchievmentsLabel).Build();
manager.TestInvalidType<IntAchievmentData, ToggleAchievmentData>(AchievmentIdToggle, "Toggle");
manager.TestInvalidType<FloatAchievmentData, IntAchievmentData>(AchievmentIdInt, "Int");
manager.TestInvalidType<ToggleAchievmentData, FloatAchievmentData>(AchievmentIdFloat, "Float");
}
[Test]
public void AchivmentCorrectIdAndType()
{
AchievmentManager manager = AchievmentManager.Builder.FromLabeledConfig(AchievmentsLabel).Build();
manager.TestValidIdAndType<ToggleAchievmentData>(AchievmentIdToggle, "Toggle");
manager.TestValidIdAndType<IntAchievmentData>(AchievmentIdInt, "Int");
manager.TestValidIdAndType<FloatAchievmentData>(AchievmentIdFloat, "Float");
}
#endregion
#region Toggle
[Test]
public void AchivmentToggleSet()
{
var callbackTester = new TestCallbackRereiver();
AchievmentManager manager = AchievmentManager.Builder.FromLabeledConfig(AchievmentsLabel)
.WithCallbackReciever(callbackTester)
.Build();
manager.SetToggleAchivment(AchievmentIdToggle);
callbackTester.TestCompleted<ToggleAchievmentData>(AchievmentIdToggle);
callbackTester.Reset();
manager.SetToggleAchivment(AchievmentIdToggle);
callbackTester.TestNoChanges();
}
#endregion
#region Int
[Test]
public void AchivmentIntSetLess()
{
var callbackTester = new TestCallbackRereiver();
AchievmentManager manager = AchievmentManager.Builder.FromLabeledConfig(AchievmentsLabel)
.WithCallbackReciever(callbackTester)
.Build();
//Set progress to some value progress
manager.SetIntProgress(AchievmentIdInt, RandomProgress);
var data = callbackTester.GetChanged<IntAchievmentData>();
Assert.AreEqual(RandomProgress, data.CurrentProgress);
Assert.IsFalse(data.IsCompleted);
callbackTester.Reset();
}
[Test]
public void AchivmentIntSetEqual()
{
var callbackTester = new TestCallbackRereiver();
AchievmentManager manager = AchievmentManager.Builder.FromLabeledConfig(AchievmentsLabel)
.WithCallbackReciever(callbackTester)
.Build();
//Set progress to some value equal to required value
manager.SetIntProgress(AchievmentIdInt, CompletedProgress);
var data = callbackTester.GetChanged<IntAchievmentData>();
Assert.AreEqual(CompletedProgress, data.CurrentProgress);
callbackTester.TestCompleted<IntAchievmentData>(AchievmentIdInt);
callbackTester.Reset();
//Do that again, this time nothing sould change
manager.SetIntProgress(AchievmentIdInt, CompletedProgress);
callbackTester.TestNoChanges();
callbackTester.Reset();
}
[Test]
public void AchivmentIntSetGreater()
{
var callbackTester = new TestCallbackRereiver();
AchievmentManager manager = AchievmentManager.Builder.FromLabeledConfig(AchievmentsLabel)
.WithCallbackReciever(callbackTester)
.Build();
//Set progress to some value greater than required
manager.SetIntProgress(AchievmentIdInt, OvershootProgress);
var data = callbackTester.GetChanged<IntAchievmentData>();
//Testing against completed progress, should be clamped down
Assert.AreEqual(CompletedProgress, data.CurrentProgress);
callbackTester.TestCompleted<IntAchievmentData>(AchievmentIdInt);
callbackTester.Reset();
//Do that again, this time nothing sould change
manager.SetIntProgress(AchievmentIdInt, OvershootProgress);
callbackTester.TestNoChanges();
callbackTester.Reset();
}
[Test]
public void AchivmentIntChangeCompletion()
{
var callbackTester = new TestCallbackRereiver();
AchievmentManager manager = AchievmentManager.Builder.FromLabeledConfig(AchievmentsLabel)
.WithCallbackReciever(callbackTester)
.Build();
//Add progresss one interval below completion
for (int i = 0; i < CompletedProgress / ProgressChangeDelta; i++)
{
manager.ChangeIntProgress(AchievmentIdInt, ProgressChangeDelta);
callbackTester.TestNotCompleted();
var changed = callbackTester.GetChanged<IntAchievmentData>();
Assert.AreEqual((i + 1) * ProgressChangeDelta, changed.CurrentProgress);
callbackTester.Reset();
}
//Add progress one more time, should now be completed
manager.ChangeIntProgress(AchievmentIdInt, ProgressChangeDelta);
var changed1 = callbackTester.GetChanged<IntAchievmentData>();
Assert.AreEqual(CompletedProgress, changed1.CurrentProgress);
callbackTester.TestCompleted<IntAchievmentData>(AchievmentIdInt);
callbackTester.Reset();
//Do that again, this time nothing should change
manager.ChangeIntProgress(AchievmentIdInt, ProgressChangeDelta);
callbackTester.TestNoChanges();
callbackTester.Reset();
//Do that again, but down this time also nothing should change
manager.ChangeIntProgress(AchievmentIdInt, -ProgressChangeDelta);
callbackTester.TestNoChanges();
callbackTester.Reset();
}
#endregion
#region Float
[Test]
public void AchivmentFloatSetLess()
{
var callbackTester = new TestCallbackRereiver();
AchievmentManager manager = AchievmentManager.Builder.FromLabeledConfig(AchievmentsLabel)
.WithCallbackReciever(callbackTester)
.Build();
//Set progress to some value progress
manager.SetFloatProgress(AchievmentIdFloat, RandomProgress);
var data = callbackTester.GetChanged<FloatAchievmentData>();
Assert.AreEqual((float)RandomProgress, data.CurrentProgress);
Assert.IsFalse(data.IsCompleted);
callbackTester.Reset();
}
[Test]
public void AchivmentFloatSetEqual()
{
var callbackTester = new TestCallbackRereiver();
AchievmentManager manager = AchievmentManager.Builder.FromLabeledConfig(AchievmentsLabel)
.WithCallbackReciever(callbackTester)
.Build();
//Set progress to some value equal to required value
manager.SetFloatProgress(AchievmentIdFloat, CompletedProgress);
var data = callbackTester.GetChanged<FloatAchievmentData>();
Assert.AreEqual((float)CompletedProgress, data.CurrentProgress);
callbackTester.TestCompleted<FloatAchievmentData>(AchievmentIdFloat);
callbackTester.Reset();
//Do that again, this time nothing sould change
manager.SetFloatProgress(AchievmentIdFloat, CompletedProgress);
callbackTester.TestNoChanges();
callbackTester.Reset();
}
[Test]
public void AchivmentFloatSetGreater()
{
var callbackTester = new TestCallbackRereiver();
AchievmentManager manager = AchievmentManager.Builder.FromLabeledConfig(AchievmentsLabel)
.WithCallbackReciever(callbackTester)
.Build();
//Set progress to some value greater than required
manager.SetFloatProgress(AchievmentIdFloat, OvershootProgress);
var data = callbackTester.GetChanged<FloatAchievmentData>();
//Testing against completed progress, should be clamped down
Assert.AreEqual((float)CompletedProgress, data.CurrentProgress);
callbackTester.TestCompleted<FloatAchievmentData>(AchievmentIdFloat);
callbackTester.Reset();
//Do that again, this time nothing sould change
manager.SetFloatProgress(AchievmentIdFloat, OvershootProgress);
callbackTester.TestNoChanges();
callbackTester.Reset();
}
[Test]
public void AchivmentFloatChangeCompletion()
{
var callbackTester = new TestCallbackRereiver();
AchievmentManager manager = AchievmentManager.Builder.FromLabeledConfig(AchievmentsLabel)
.WithCallbackReciever(callbackTester)
.Build();
//Add progresss one interval below completion
for (int i = 0; i < CompletedProgress / ProgressChangeDelta; i++)
{
manager.ChangeFloatProgress(AchievmentIdFloat, ProgressChangeDelta);
callbackTester.TestNotCompleted();
var changed = callbackTester.GetChanged<FloatAchievmentData>();
Assert.AreEqual((i + 1) * ProgressChangeDelta, changed.CurrentProgress, 0.0f);
callbackTester.Reset();
}
//Add progress one more time, should now be completed
manager.ChangeFloatProgress(AchievmentIdFloat, ProgressChangeDelta);
var changed1 = callbackTester.GetChanged<FloatAchievmentData>();
Assert.AreEqual((float)CompletedProgress, changed1.CurrentProgress);
callbackTester.TestCompleted<FloatAchievmentData>(AchievmentIdFloat);
callbackTester.Reset();
//Do that again, this time nothing should change
manager.ChangeFloatProgress(AchievmentIdFloat, ProgressChangeDelta);
callbackTester.TestNoChanges();
callbackTester.Reset();
//Do that again, but down this time also nothing should change
manager.ChangeFloatProgress(AchievmentIdFloat, -ProgressChangeDelta);
callbackTester.TestNoChanges();
callbackTester.Reset();
}
#endregion
private class TestCallbackRereiver : IAchievmentCallbackReciever
{
public AchievmentData LastDataUpdated { get; private set; } = null;
public Type LastTypeSet { get; private set; } = null;
public string LastIdSet { get; private set; } = null;
public void Reset()
{
LastDataUpdated = null;
LastTypeSet = null;
LastIdSet = null;
}
public T GetChanged<T>() where T : AchievmentData
{
Assert.IsInstanceOf(typeof(T), LastDataUpdated);
return (T)LastDataUpdated;
}
public void TestNoChanges()
{
Assert.IsNull(LastDataUpdated);
Assert.IsNull(LastTypeSet);
Assert.IsNull(LastIdSet);
}
public void TestNotCompleted()
{
//No need to also check LastTypeSet, they are both set or bot null
Assert.IsNull(LastIdSet);
}
public void TestCompleted<Type>(string id)
{
Assert.AreEqual(typeof(Type), LastTypeSet);
Assert.AreEqual(id, LastIdSet);
//Shold not be null: if we axpect achievment to be completed it must have also been updated
Assert.IsTrue(LastDataUpdated.IsCompleted);
}
public void AchievmentCompleted(AchievmentData achievment)
{
LastTypeSet = achievment.GetType();
LastIdSet = achievment.Achievment.Id;
}
public void AchievmentStateChanged(AchievmentData achievment)
{
LastDataUpdated = achievment;
}
}
}
namespace Internal
{
public static class Extensions
{
public static void TestValidIdAndType<Type>(this AchievmentManager manager, string id, string testName) where Type : AchievmentData
{
TestValidIdAndType(id, (id) => manager.GetAchievmentForId<Type>(id), testName);
}
public static void TestValidIdAndType(string id, Action<string> manipulation, string testName)
{
Assert.DoesNotThrow(() => manipulation(id), $"{testName}: Invalid type or id");
}
public static void TestInvalidId(this AchievmentManager manager, string id, string testName)
{
TestInvalidId(id, (id) => manager.GetAchievmentForId(id), testName);
}
public static void TestInvalidId(string id, Action<string> manipulation, string testName)
{
var exception = Assert.Throws<AchievmentException>(() => manipulation(id), $"Expected to fail with {typeof(AchievmentTypeException)}");
Assert.AreEqual(exception.Id, id, $"{testName}: Achievment id does not match");
}
public static void TestInvalidType<Expected, Actual>(this AchievmentManager manager, string id, string testName) where Expected : AchievmentData where Actual : AchievmentData
{
TestInvalidType<Expected, Actual>(id, (id) => manager.GetAchievmentForId<Expected>(id), testName);
}
public static void TestInvalidType<Expected, Actual>(string id, Action<string> manipulation, string testName) where Expected : AchievmentData where Actual : AchievmentData
{
var exception = Assert.Throws<AchievmentTypeException>(() => manipulation(id), $"Expected to fail with {typeof(AchievmentTypeException)}");
Assert.AreEqual(id, exception.Id, $"{testName}: Achievment id does not match");
Assert.AreSame(typeof(Expected), exception.Expected, $"{testName}: Target achievment type does not match");
Assert.AreSame(typeof(Actual), exception.Actual, $"{testName}: Actual achievment type does not match");
}
}
}
}