using NUnit.Framework;
using System;
using UnityEngine;
namespace Tests
{
public interface ITime
{
float delta { get; }
}
public class TimeMock : ITime
{
public float delta { get; set; }
}
class Timer
{
private ITime time;
public float duration { get; private set; }
public float remaining { get; private set; }
public event Action expired;
private bool active;
public Timer(ITime time)
: this(time, 0)
{
}
public Timer(ITime time, float duration)
{
ResetDuration(duration);
this.time = time;
}
public void Update()
{
remaining = Mathf.Max(remaining - time.delta, 0);
if (remaining == 0 && active)
{
active = false;
expired?.Invoke();
}
}
public void ResetDuration(float duration)
{
this.duration = duration;
remaining = duration;
active = true;
}
}
public class CountDownTimerTest
{
const float ONE_SECOND = 1.0f;
int callbacks;
TimeMock timeMock;
Timer timer;
private void AssertTimeRemaining(int remaining)
{
Assert
.That(timer
.remaining,
Is.EqualTo(remaining
).Within(0
.1f
));
}
private void AssertCallbacks(int times)
{
Assert
.That(callbacks,
Is.EqualTo(times
));
}
private void UpdateForTicks(int ticks)
{
for (int i = 0; i < ticks; ++i)
timer.Update();
}
[SetUp]
public void SetUp()
{
// Mock timer to make testable code.
// Implement ITime with a real implementation
// for your own implementation.
timeMock
= new TimeMock
();
timeMock.delta = ONE_SECOND;
// Create 0 second timer with fixed mock delta.
timer
= new Timer
(timeMock
);
// Every time expired is raised,
// remember how many times it's been called.
timer.expired += () => callbacks++;
callbacks = 0;
}
[Test]
public void DoesNotExpireOnLongDuration()
{
timer.ResetDuration(60);
UpdateForTicks(1);
AssertTimeRemaining(59);
AssertCallbacks(0);
}
[Test]
public void ExpiresOnZeroDuration()
{
UpdateForTicks(1);
AssertTimeRemaining(0);
AssertCallbacks(1);
}
[Test]
public void ExpiresOnceOnLongRunthrough()
{
timer.ResetDuration(60);
UpdateForTicks(61);
AssertTimeRemaining(0);
AssertCallbacks(1);
}
[Test]
public void ExpiresTwiceAfterResetDuration()
{
timer.ResetDuration(60);
UpdateForTicks(61);
timer.ResetDuration(60);
UpdateForTicks(61);
AssertTimeRemaining(0);
AssertCallbacks(2);
}
}
}
{"html5":"htmlmixed","css":"css","javascript":"javascript","php":"php","python":"python","ruby":"ruby","lua":"text\/x-lua","bash":"text\/x-sh","go":"go","c":"text\/x-csrc","cpp":"text\/x-c++src","diff":"diff","latex":"stex","sql":"sql","xml":"xml","apl":"apl","asterisk":"asterisk","c_loadrunner":"text\/x-csrc","c_mac":"text\/x-csrc","coffeescript":"text\/x-coffeescript","csharp":"text\/x-csharp","d":"d","ecmascript":"javascript","erlang":"erlang","groovy":"text\/x-groovy","haskell":"text\/x-haskell","haxe":"text\/x-haxe","html4strict":"htmlmixed","java":"text\/x-java","java5":"text\/x-java","jquery":"javascript","mirc":"mirc","mysql":"sql","ocaml":"text\/x-ocaml","pascal":"text\/x-pascal","perl":"perl","perl6":"perl","plsql":"sql","properties":"text\/x-properties","q":"text\/x-q","scala":"scala","scheme":"text\/x-scheme","tcl":"text\/x-tcl","vb":"text\/x-vb","verilog":"text\/x-verilog","yaml":"text\/x-yaml","z80":"text\/x-z80"}