2296 lines
76 KiB
C#

// ReSharper disable AnnotateNotNullParameter
#if TEST_FRAMEWORK_INSTALLED
using System;
using System.Collections;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using JetBrains.Annotations;
using NUnit.Framework;
using PrimeTween;
using UnityEngine;
using UnityEngine.TestTools;
using Assert = NUnit.Framework.Assert;
using Object = UnityEngine.Object;
using Random = UnityEngine.Random;
public partial class Tests {
[UnityTest]
public IEnumerator ElapsedTime() {
var timeStart = Time.time;
var d1 = getDt() * 4f;
var d2 = getDt() * 2f;
var c1 = 2;
var c2 = 3;
var c3 = 2;
var seq = Tween.Custom(0, 1, d1, delegate { }, cycles: c1)
.Chain(Tween.Custom(0, 1, d2, delegate { }, cycles: c2));
seq.SetRemainingCycles(c3);
Assert.AreEqual((d1 * c1 + d2 * c2) * c3, seq.durationTotal, 0.00001f);
while (seq.isAlive) {
var expected = Time.time - timeStart;
// Debug.Log($"expected {expected} / elapsedTimeTotal {seq.elapsedTimeTotal}");
if (seq.cyclesDone == 0) {
Assert.AreEqual(expected, seq.elapsedTime, 0.001f);
}
Assert.AreEqual(expected, seq.elapsedTimeTotal, getDt() * 2); // fails with lower tolerance because Sequence doesn't measure the elapsedTimeTotal, but calculates it from duration * cyclesDone
yield return null;
}
}
[UnityTest]
public IEnumerator SequenceNestingCycles() {
float duration = getDt();
{
int numCompleted = 0;
var s1 = Sequence.Create(Tween.Delay(duration, () => numCompleted++));
yield return Sequence.Create(Tween.Delay(duration))
.Chain(s1)
.ToYieldInstruction();
Assert.AreEqual(1, numCompleted);
}
{
int numCompleted = 0;
var s1 = Sequence.Create(Tween.Delay(duration, () => numCompleted++));
yield return Sequence.Create(2)
.Chain(Tween.Delay(duration))
.Chain(s1)
.ToYieldInstruction();
Assert.AreEqual(2, numCompleted);
}
{
int numCompleted = 0;
var s1 = Sequence.Create(2)
.Chain(Tween.Delay(duration, () => numCompleted++));
yield return Sequence.Create(2)
.Chain(Tween.Delay(duration))
.Chain(s1)
.ToYieldInstruction();
Assert.AreEqual(4, numCompleted);
}
}
[UnityTest]
public IEnumerator SequenceNestingDepsChain() {
const float duration = 100f;
var s1 = Sequence.Create(Tween.Delay(duration));
var t1 = Tween.Delay(duration);
var t2 = Tween.Delay(duration);
var s2 = Sequence.Create(t1).Group(t2);
s1.Chain(s2);
Assert.AreEqual(duration, s2.root.tween.waitDelay);
Assert.AreEqual(0f, t1.tween.waitDelay);
Assert.AreEqual(0f, t2.tween.waitDelay);
yield return null;
Assert.AreEqual(0f, t1.elapsedTime);
Assert.AreEqual(0f, t2.elapsedTime);
s1.Stop();
}
[UnityTest]
public IEnumerator SequenceNestingDepsGroup() {
const float duration = 100f;
var t1 = Tween.Delay(duration);
var t2 = Tween.Delay(duration);
var nested = Sequence.Create(t1).Group(t2);
var seq = Sequence.Create(Tween.Delay(duration))
.ChainDelay(duration)
.Group(nested);
Assert.AreEqual(0, t1.tween.waitDelay);
Assert.AreEqual(0, t2.tween.waitDelay);
yield return null;
Assert.AreEqual(0, t1.elapsedTime);
Assert.AreEqual(0, t2.elapsedTime);
seq.Stop();
}
[UnityTest]
public IEnumerator SequenceNestingAfterTweenChainOp() {
var duration = 0.001f + Random.value * 0.05f; // longest
var s1 = Sequence.Create(Tween.Delay(duration));
var s2 = Sequence.Create();
s1.Chain(s2);
var t1 = Tween.Delay(0.01f);
s1.Chain(t1);
Assert.AreEqual(duration, t1.tween.waitDelay);
var t2 = Tween.Delay(0.01f);
s1.Group(t2);
Assert.AreEqual(duration, t2.tween.waitDelay);
yield return s1.ToYieldInstruction();
}
[UnityTest]
public IEnumerator SequenceNestingChainOrder() {
var t1 = Tween.Delay(0.01f);
var s1 = Sequence.Create(t1);
var t2 = Tween.Delay(0.05f);
s1.Chain(t2);
var t3 = Tween.Delay(0.01f);
var t4 = Tween.Delay(0.01f);
var s2 = Sequence.Create(t3).Group(t4);
s1.Chain(s2);
Assert.AreEqual(t2.durationWithWaitDelay, s2.root.tween.waitDelay);
Assert.AreEqual(0f, t3.tween.waitDelay);
Assert.AreEqual(0f, t4.tween.waitDelay);
var t5 = Tween.Delay(0.01f);
s1.Group(t5);
Assert.AreEqual(t2.durationWithWaitDelay, t5.tween.waitDelay);
yield return s1.ToYieldInstruction();
}
[UnityTest]
public IEnumerator SequenceNestingGroupOrder() {
const float t1Dur = 0.017f;
var t1 = Tween.Delay(t1Dur);
var s1 = Sequence.Create(t1);
const float longestDur = 0.05f;
var t2 = Tween.Delay(longestDur);
s1.Chain(t2);
Assert.AreEqual(t1.durationWithWaitDelay, t2.tween.waitDelay);
var t3 = Tween.Delay(0.01f);
s1.Group(t3);
Assert.AreEqual(t1.durationWithWaitDelay, t3.tween.waitDelay);
var s2 = Sequence.Create(Tween.Delay(0.01f));
var t4 = Tween.Delay(0.01f);
s2.Group(t4);
s1.Group(s2);
Assert.AreEqual(0f, t4.tween.waitDelay);
var t5 = Tween.Delay(0.01f);
s1.Group(t5);
Assert.AreEqual(t1Dur, t5.tween.waitDelay);
var t6 = Tween.Delay(0.01f);
var seqDur = s1.durationTotal;
s1.Chain(t6);
Assert.AreEqual(seqDur, t6.tween.waitDelay);
yield return s1.ToYieldInstruction();
}
[UnityTest]
public IEnumerator SequenceNestingRestart() {
int numCallback = 0;
yield return Sequence.Create(2)
.Chain(Tween.Delay(0.01f))
.Chain(Sequence.Create(Tween.Delay(0.01f)))
.ChainCallback(() => numCallback++)
.ToYieldInstruction();
Assert.AreEqual(2, numCallback);
}
[Test]
public void SequenceNestingPause2() {
{
var s1 = Sequence.Create();
var s2 = Sequence.Create();
s2.isPaused = true;
LogAssert.Expect(LogType.Error, new Regex("'isPaused' was ignored after adding"));
s1.Group(s2);
expectCantManipulateTweenInsideSequence();
_ = s2.isPaused;
s1.Complete();
}
{
var s1 = Sequence.Create();
s1.isPaused = true;
var s2 = Sequence.Create();
s2.isPaused = true;
s1.Chain(s2);
expectCantManipulateTweenInsideSequence();
_ = s2.isPaused;
s1.Complete();
LogAssert.NoUnexpectedReceived();
}
}
[Test]
public void SequenceNestingPause() {
var s = Sequence.Create(Tween.Delay(0.01f))
.Chain(Sequence.Create(Tween.Delay(0.01f)));
Assert.AreEqual(1, numNestedSequences(s));
s.isPaused = true;
int count = 0;
foreach (var t in s.getAllChildren()) {
count++;
var child = t;
expectCantManipulateTweenInsideSequence();
expectCantManipulateTweenInsideSequence();
child.isPaused = !child.isPaused;
expectCantManipulateTweenInsideSequence();
expectCantManipulateTweenInsideSequence();
child.timeScale += 1f;
}
Assert.AreEqual(3, count);
s.isPaused = false;
count = 0;
foreach (var _ in s.getAllTweens()) {
count++;
}
Assert.AreEqual(4, count);
}
[Test]
public void SequenceNestingLongestTween() {
float dur = Random.value + 0.1f;
var t = Tween.Delay(dur);
var sequence = Sequence.Create(Tween.Delay(dur))
.Chain(Sequence.Create(Tween.Delay(dur)))
.Chain(Sequence.Create(t));
Assert.AreEqual(dur * 3, sequence.durationTotal, 0.0001f);
sequence.Stop();
Assert.IsFalse(t.isAlive);
}
[UnityTest]
public IEnumerator SequenceNestingStopChildInTheMiddle() {
Tween.StopAll();
int numS1Completed = 0;
int numS2Completed = 0;
int numS3Completed = 0;
float duration = minDuration * Random.Range(1f, 10f);
var s1 = Sequence.Create(Tween.Delay(duration, () => {
Assert.AreEqual(0, numS1Completed);
Assert.AreEqual(0, numS3Completed);
numS1Completed++;
}));
var s2 = Sequence.Create(Tween.Delay(duration, () => numS2Completed++));
var s3 = Sequence.Create(Tween.Delay(duration, () => {
Assert.AreEqual(1, numS1Completed);
Assert.AreEqual(0, numS3Completed);
numS3Completed++;
}));
s1.Chain(s2).Chain(s3);
Assert.AreEqual(2, numNestedSequences(s1));
expectCantManipulateTweenInsideSequence();
s2.Stop();
Assert.AreEqual(2, numNestedSequences(s1));
yield return s1.ToYieldInstruction();
Assert.AreEqual(1, numS1Completed);
Assert.AreEqual(1, numS2Completed);
Assert.AreEqual(1, numS3Completed);
yield return null;
Assert.AreEqual(0, tweensCount);
}
[UnityTest]
public IEnumerator SequenceNestingCompleteLastChild() {
var duration = getDt();
var s1 = Sequence.Create(Tween.Delay(duration));
var s2 = Sequence.Create(Tween.Delay(duration));
s1.Chain(s2);
Assert.AreEqual(1, numNestedSequences(s1));
expectCantManipulateTweenInsideSequence();
s2.Complete();
Assert.AreEqual(1, numNestedSequences(s1));
Assert.IsTrue(s2.isAlive);
Assert.IsTrue(s1.isAlive);
yield return s1.ToYieldInstruction();
}
static int numNestedSequences(Sequence seq) {
Assert.IsTrue(seq.isAlive);
int result = 0;
foreach (var t in seq.getAllTweens()) {
if (t.tween.isSequenceRoot() && !t.tween.isMainSequenceRoot()) {
result++;
}
}
Assert.IsTrue(result >= 0);
return result;
}
[UnityTest]
public IEnumerator SequenceNesting() {
if (tweensCount > 0) {
Tween.StopAll();
Assert.AreEqual(0, tweensCount);
}
int numS1Completed = 0;
int numS2Completed = 0;
var s1 = Sequence.Create(Tween.Delay(0.02f, () => {
// Debug.Log("1");
Assert.AreEqual(0, numS1Completed);
Assert.AreEqual(0, numS2Completed);
numS1Completed++;
}));
var s2 = Sequence.Create(Tween.Delay(0.01f, () => {
// Debug.Log("2");
Assert.AreEqual(1, numS1Completed);
Assert.AreEqual(0, numS2Completed);
numS2Completed++;
}));
s1.Chain(s2);
Assert.AreEqual(1, numNestedSequences(s1));
yield return s1.ToYieldInstruction();
Assert.AreEqual(1, numS1Completed);
Assert.AreEqual(1, numS2Completed);
yield return null;
Assert.AreEqual(0, tweensCount);
}
[Test]
public void SequenceNestingDifferentSettings() {
var seq = Sequence.Create();
seq.timeScale = Random.Range(0.01f, 1.5f);
expectErrors();
seq.Group(createSequenceWithNonDefaultSettings());
expectErrors();
seq.Chain(createSequenceWithNonDefaultSettings());
LogAssert.NoUnexpectedReceived();
return;
static void expectErrors() {
LogAssert.Expect(LogType.Error, new Regex("'isPaused' was ignored after adding"));
LogAssert.Expect(LogType.Error, new Regex("'timeScale' was ignored after adding"));
LogAssert.Expect(LogType.Error, new Regex("'useUnscaledTime' was ignored after adding"));
LogAssert.Expect(LogType.Error, new Regex("'updateType' was ignored after adding"));
}
static Sequence createSequenceWithNonDefaultSettings() {
var s2 = Sequence.Create(useUnscaledTime: true, updateType: UpdateType.FixedUpdate);
s2.isPaused = true;
s2.timeScale = 0.5f;
return s2;
}
}
[UnityTest]
public IEnumerator SequenceNestingInfinite() {
var s1 = Sequence.Create();
var infSeq = Sequence.Create(cycles: -1);
expectInfiniteTweenInSequenceError();
s1.Group(infSeq);
expectInfiniteTweenInSequenceError();
s1.Chain(infSeq);
yield return null;
infSeq.Complete();
}
[UnityTest]
public IEnumerator GetSequenceElapsedTimeWhenAllTargetsDestroyed() {
var target = new GameObject();
var s = Sequence.Create(Tween.Delay(target, 0.1f));
Object.DestroyImmediate(target);
Assert.IsTrue(s.isAlive);
var _ = s.elapsedTime;
yield return s.ToYieldInstruction();
}
[UnityTest]
public IEnumerator StopAllWhenSequenceHasCompletedTweenAndTargetDestroyed() {
var target = new GameObject();
var duration = getDt() * 5f;
var t = Tween.Delay(target, duration);
int numCompleted = 0;
var s = Sequence.Create(t)
.Chain(Tween.Delay(target, duration, () => numCompleted++));
while (t.interpolationFactor < 1f) {
yield return null;
}
Assert.IsTrue(t.isAlive);
Assert.IsTrue(s.isAlive);
int aliveCount = 0;
foreach (var _ in s.getAllTweens()) {
if (_.isAlive) {
aliveCount++;
}
}
Assert.AreEqual(3, aliveCount, "tweens now always alive while their sequence is alive");
Object.DestroyImmediate(target);
Assert.AreEqual(3, tweensCount);
expectOnCompleteIgnored();
var numCompleteAll = Tween.CompleteAll();
Assert.AreEqual(3, numCompleteAll);
Assert.AreEqual(0, numCompleted);
Assert.AreEqual(0, tweensCount);
Assert.AreEqual(0, numCompleted);
LogAssert.NoUnexpectedReceived();
}
[UnityTest]
public IEnumerator StopAllWhenSequenceHasCompletedTween() {
var duration = getDt() * 10f;
var t = Tween.Delay(duration);
var s = Sequence.Create(t)
.ChainDelay(duration);
while (t.interpolationFactor < 1f) {
yield return null;
}
Assert.IsTrue(t.isAlive);
Assert.IsTrue(s.isAlive);
Assert.AreEqual(3, tweensCount);
Tween.StopAll();
Assert.AreEqual(0, tweensCount);
}
[UnityTest]
public IEnumerator StopSequenceFromCallback() {
var aliveCount = tweensCount;
if (aliveCount > 0) {
Assert.AreEqual(Tween.StopAll(null), aliveCount);
}
Sequence s = default;
s = Sequence.Create()
.ChainCallback(() => {
s.Stop();
Assert.IsFalse(s.isAlive);
});
yield return s.ToYieldInstruction();
yield return null;
Assert.AreEqual(0, tweensCount);
}
[UnityTest]
public IEnumerator ExceptionInOnCompleteNestedSequence() {
var aliveCount = tweensCount;
if (aliveCount > 0) {
Assert.AreEqual(Tween.StopAll(), aliveCount);
}
var main = Sequence.Create(Tween.Delay(getDt() * 2));
expectOnCompleteException();
var nested = Sequence.Create().ChainCallback(() => throw new Exception());
main.Group(nested);
yield return main.ToYieldInstruction();
yield return null;
Assert.AreEqual(0, tweensCount);
LogAssert.NoUnexpectedReceived();
}
static void expectOnCompleteException() {
LogAssert.Expect(LogType.Error, new Regex("Tween's onComplete callback raised exception"));
}
[UnityTest]
public IEnumerator ExceptionInOnValueChangeNestedSequence() {
var aliveCount = tweensCount;
if (aliveCount > 0) {
Assert.AreEqual(Tween.StopAll(null), aliveCount);
}
var main = Sequence.Create(Tween.Delay(getDt() * 2));
expectTweenWasStoppedBecauseException();
var nested = Sequence.Create(Tween.Custom(0f, 1f, getDt() * 2, delegate { throw new Exception(); }));
main.Group(nested);
yield return main.ToYieldInstruction();
yield return null;
Assert.AreEqual(0, tweensCount);
LogAssert.NoUnexpectedReceived();
}
[Test]
public async Task SequenceLongestTween() {
{
var t1 = Tween.Delay(0.01f);
var t2 = Tween.Delay(0.02f);
var s = t1.Group(t2);
Assert.AreEqual(t2.durationTotal, s.durationTotal);
await s;
}
{
var t1 = Tween.Delay(0.01f);
var t2 = Tween.Delay(0.02f);
var s = t2.Group(t1);
Assert.AreEqual(t2.durationTotal, s.durationTotal);
}
{
var t1 = Tween.Delay(0.01f);
var t2 = Tween.Delay(0.02f);
var s = t1.Chain(t2);
Assert.AreEqual(t1.durationTotal + t2.durationTotal, s.durationTotal);
}
{
var t1 = Tween.Delay(0.01f);
var t2 = Tween.Delay(0.02f);
var s = t2.Chain(t1);
Assert.AreEqual(t1.durationTotal + t2.durationTotal, s.durationTotal);
}
{
var t1 = Tween.PositionX(transform, 1f, 0.1f, cycles: 3); // longest
var t2 = Tween.PositionX(transform, 1f, 0.1f);
var s = t1.Group(t2);
Assert.AreEqual(t1.durationTotal, s.durationTotal);
}
{
var t1 = Tween.PositionX(transform, 1f, 0.1f, cycles: 3);
var t2 = Tween.PositionX(transform, 1f, 0.1f);
var s = t1.Chain(t2);
Assert.AreEqual(t1.durationTotal + t2.durationTotal, s.durationTotal);
}
}
[Test]
public async Task AwaitFinishedSequence() {
var t = Tween.Delay(0.01f);
var s = Sequence.Create(t);
await s;
Assert.IsTrue(s.IsCreated);
Assert.IsFalse(s.isAlive);
await s;
}
[UnityTest]
public IEnumerator SequenceRestartFromTo() {
for (int i = 0; i < 1; i++) {
var target = new GameObject(nameof(SequenceRestartFromTo)).transform;
Assert.AreEqual(Vector3.zero, target.localPosition);
var s = Tween.LocalPositionX(target, new TweenSettings<float>(0f, 1f, getDt() * 2f))
.Chain(Tween.LocalPositionX(target, new TweenSettings<float>(1f, 0.5f, getDt())));
s.SetRemainingCycles(2);
if (Random.value < 0.5f) {
s.Complete();
} else {
yield return s.ToYieldInstruction();
}
UnityEngine.Assertions.Assert.AreApproximatelyEqual(0.5f, target.localPosition.x);
Object.Destroy(target.gameObject);
}
}
[UnityTest]
public IEnumerator SequenceRestartTo() {
var target = new GameObject(nameof(SequenceRestartTo)).transform;
Assert.AreEqual(Vector3.zero, target.localPosition);
var duration = getDt() * 3f;
var s = Tween.LocalPositionX(target, 1f, duration)
.Chain(Tween.LocalPositionX(target, 0.5f, duration));
s.SetRemainingCycles(2);
if (Random.value < 0.5f) {
s.Complete();
} else {
yield return s.ToYieldInstruction();
}
UnityEngine.Assertions.Assert.AreApproximatelyEqual(0.5f, target.localPosition.x);
Object.Destroy(target.gameObject);
}
[UnityTest]
public IEnumerator SequenceRestartWhenTweenHaveStartDelay() {
var data = new TweenSettings<Vector3>(Vector3.zero, Vector3.one, getDt() * Random.Range(0.5f, 2f), startDelay: getDt() * Random.Range(0.5f, 2f));
var t1 = Tween.Position(transform, data);
var t2 = Tween.Position(transform, data);
PrimeTweenConfig.warnStructBoxingAllocationInCoroutine = true;
expectCoroutineBoxingWarning();
var seq = t1.Chain(t2);
seq.SetRemainingCycles(2);
yield return seq;
LogAssert.NoUnexpectedReceived();
}
static void expectCoroutineBoxingWarning() {
LogAssert.Expect(LogType.Warning, new Regex("Please use Tween/Sequence.ToYieldInstruction"));
}
[UnityTest]
public IEnumerator StopAllWhenTweenInSequenceIsCompleted() {
var target = new object();
var duration = getDt() * 2f;
var t1 = Tween.Delay(target, duration);
var t2 = Tween.Delay(target, duration);
yield return t1.Chain(t2).ToYieldInstruction();
Tween.StopAll(target);
Tween.SetPausedAll(true, target);
Tween.SetPausedAll(false, target);
}
[UnityTest]
public IEnumerator SequenceElapsedTime() {
yield return null;
float dt = getDt();
var dur1 = dt * Random.Range(2, 5);
var dur2 = dt * Random.Range(2, 5);
var cycles1 = Random.Range(1, 4);
var cycles2 = Random.Range(1, 4);
var t1 = Tween.Position(transform, Vector3.one, dur1, cycles: cycles1);
var t2 = Tween.Position(transform, Vector3.one, dur2, cycles: cycles2);
var s = Sequence.Create(t1)
.Chain(t2);
float timeStart = Time.time;
Assert.IsTrue(t1.isAlive);
while (t1.interpolationFactor < 1f) {
yield return null;
}
Assert.AreEqual(dur1 * cycles1, Time.time - timeStart, Time.deltaTime);
Assert.IsTrue(s.isAlive);
yield return s;
Assert.AreEqual(dur1 * cycles1 + dur2 * cycles2, Time.time - timeStart, Time.deltaTime);
}
[UnityTest]
public IEnumerator DefaultPropertiesOfSequence() {
{
Assert.AreEqual(0, tweensCount);
var duration = 0.001f;
var s = Sequence.Create(-1).Chain(Tween.Delay(duration));
Assert.AreEqual(-1, s.cyclesTotal);
Assert.AreEqual(duration, s.duration);
Assert.IsTrue(float.IsPositiveInfinity(s.durationTotal));
yield return null;
const int expectedCount = 2;
Assert.AreEqual(expectedCount, tweensCount);
yield return null;
Assert.AreEqual(expectedCount, tweensCount);
yield return null;
Assert.AreEqual(expectedCount, tweensCount);
s.Stop();
Assert.AreEqual(expectedCount, tweensCount);
yield return null;
Assert.AreEqual(0, tweensCount);
}
{
var s = Sequence.Create();
Assert.AreEqual(1, s.cyclesTotal);
validate(s);
}
{
var s = Sequence.Create();
validate(s);
}
void validate(Sequence s) {
Assert.AreEqual(0, s.duration);
Assert.AreEqual(0, s.durationTotal);
Assert.AreEqual(0, s.progress);
Assert.AreEqual(0, s.progressTotal);
Assert.AreEqual(0, s.cyclesDone);
Assert.AreEqual(0, s.elapsedTime);
Assert.AreEqual(0, s.elapsedTimeTotal);
}
}
[Test]
public async Task SequenceProperties() {
for (int i = 0; i < 1; i++) {
int cyclesDone = 0;
Tween tween = default;
var duration = Mathf.Max(TweenSettings.minDuration, getDt() * Random.Range(0.5f, 6f));
var sequenceCycles = Random.Range(2, 5);
// const float duration = 0.1f;
// const int sequenceCycles = 2;
Sequence sequence = default;
validateSequenceDefaultProps(false);
sequence = Sequence.Create(sequenceCycles);
float timeStart = Time.time;
tween = Tween.Custom(transform, 0, 1, duration, ease: Ease.Linear, onValueChange: (_, val) => {
// Debug.Log($"elapsedTimeTotal: {sequence.elapsedTimeTotal}, val: {val}");
Assert.IsTrue(tween.isAlive);
Assert.IsTrue(sequence.isAlive);
UnityEngine.Assertions.Assert.AreApproximatelyEqual(sequence.duration, duration);
var durationTotalExpected = duration * sequenceCycles;
UnityEngine.Assertions.Assert.AreApproximatelyEqual(sequence.durationTotal, durationTotalExpected);
Assert.AreEqual(tween.duration, duration);
Assert.AreEqual(tween.durationTotal, duration);
var elapsedTimeExpected = Time.time - timeStart;
if (val < 1f) {
if (sequence.cyclesDone == 0) {
UnityEngine.Assertions.Assert.AreApproximatelyEqual(sequence.elapsedTime, tween.elapsedTime);
UnityEngine.Assertions.Assert.AreApproximatelyEqual(tween.elapsedTime, elapsedTimeExpected);
UnityEngine.Assertions.Assert.AreApproximatelyEqual(sequence.elapsedTime, elapsedTimeExpected);
}
if (sequence.root.tween.elapsedTimeTotal >= 0f) {
Assert.AreEqual(elapsedTimeExpected, sequence.elapsedTimeTotal, getDt());
Assert.AreEqual(sequence.progress, Mathf.Clamp01(sequence.elapsedTime / sequence.duration));
Assert.AreEqual(sequence.progressTotal, Mathf.Clamp01(elapsedTimeExpected / durationTotalExpected), 0.001f);
}
}
});
#pragma warning disable 4014
sequence.Group(tween);
#pragma warning restore
await sequence.ChainCallback(() => cyclesDone++);
Assert.AreEqual(sequenceCycles, cyclesDone);
Assert.IsFalse(sequence.isAlive);
validateSequenceDefaultProps(true);
Assert.IsFalse(tween.isAlive);
void validateSequenceDefaultProps(bool isCreated) {
for (int j = 0; j < 8; j++) {
expectIsDeadError(isCreated);
}
Assert.AreEqual(0, sequence.elapsedTime);
Assert.AreEqual(0, sequence.elapsedTimeTotal);
Assert.AreEqual(0, sequence.cyclesDone);
Assert.AreEqual(0, sequence.cyclesTotal);
Assert.AreEqual(0, sequence.duration);
Assert.AreEqual(0, sequence.durationTotal);
Assert.AreEqual(0, sequence.progress);
Assert.AreEqual(0, sequence.progressTotal);
}
}
}
[UnityTest]
public IEnumerator ExceptionInSequenceOnCycleComplete() {
int numExceptions = 0;
Sequence s = default;
s = Sequence.Create(2, CycleMode.Restart)
.Chain(Tween.Delay(getDt()))
.Chain(Tween.Custom(0f, 1f, getDt(), val => {
// print($"{s.cyclesDone}, {val}");
if (s.cyclesDone == 1 && val == 0f) {
numExceptions++;
expectTweenWasStoppedBecauseException();
throw new Exception();
}
}))
.Chain(Tween.Delay(getDt()));
yield return s;
Assert.AreEqual(1, numExceptions);
}
[Test]
public async Task SequenceIncrementalTween() {
await Tween.Delay(getDt());
float dur = getDt() * (Random.value + 0.1f);
var t = Tween.Position(transform, Vector3.one, dur, cycles: 2, cycleMode: CycleMode.Incremental);
int cyclesDone = 0;
const int sequenceCycles = 4;
await Sequence.Create(sequenceCycles)
.Chain(t)
.ChainCallback(() => {
cyclesDone++;
Assert.AreEqual(0f, t.interpolationFactor % 1f);
});
Assert.AreEqual(sequenceCycles, cyclesDone);
}
[Test]
public void SettingInfiniteLoopsToTweenInSequence() {
var t = createTween();
var s = Sequence.Create(t);
expectCantManipulateTweenInsideSequence();
t.SetRemainingCycles(-1);
s.Complete();
}
[Test]
public void TweenIsReleasedFromSequenceOnReleaseAll() {
test(true);
test(false);
void test(bool isStop) {
var t = createTween();
var s = Sequence.Create(t);
Assert.IsTrue(t.isAlive);
Assert.IsTrue(s.isAlive);
if (isStop) {
Tween.StopAll();
} else {
Tween.CompleteAll();
}
Assert.IsFalse(t.isAlive);
Assert.IsFalse(s.isAlive);
Assert.IsFalse(t.tween.sequence.IsCreated);
}
}
[Test]
public void SequenceComplete() {
int numTweenCompleted = 0;
var s = Sequence.Create(createCustomTween(0.01f).OnComplete(() => numTweenCompleted++));
Assert.IsTrue(s.isAlive);
s.Complete();
Assert.IsFalse(s.isAlive);
Assert.AreEqual(1, numTweenCompleted);
}
[Test]
public void SequenceStop() {
var s = Sequence.Create(createCustomTween(0.01f));
Assert.IsTrue(s.isAlive);
s.Stop();
Assert.IsFalse(s.isAlive);
s.Stop();
Assert.IsFalse(s.isAlive);
}
/*[UnityTest]
public IEnumerator SequenceRevert() {
var val = 0f;
var t = Tween.Custom(this, 0, 1, 1, (_, newVal) => {
val = newVal;
});
var s = Sequence.Create(t);
yield return null;
Assert.AreNotEqual(0, val);
s.Revert();
Assert.IsFalse(s.isAlive);
Assert.AreEqual(0, val);
}*/
[UnityTest]
public IEnumerator CompletedTweenInsideSequenceDoesntCompleteSecondTimeOnCompletingSequence() {
var numFirstCompleted = 0;
var numSecondCompleted = 0;
Tween first = createCustomTween(getDt()).OnComplete(() => numFirstCompleted++);
Tween second = createCustomTween(getDt() * 5f).OnComplete(() => numSecondCompleted++);
var sequence = Sequence.Create(first)
.Group(second);
while (first.interpolationFactor < 1f) {
yield return null;
}
Assert.IsTrue(first.isAlive);
Assert.IsTrue(first.tween._isAlive);
Assert.AreEqual(1, numFirstCompleted);
Assert.IsTrue(second.isAlive);
Assert.IsTrue(sequence.isAlive);
sequence.Complete();
Assert.AreEqual(1, numFirstCompleted);
Assert.AreEqual(1, numSecondCompleted);
}
static Tween createCustomTween(float duration) {
return Tween.Custom(PrimeTweenManager.Instance, 0, 1, duration, delegate{});
}
[Test]
public void CompletingSequenceCompletesAllTweensInside() {
var numFirstCompleted = 0;
var numSecondCompleted = 0;
Sequence.Create(createTween().OnComplete(() => numFirstCompleted++))
.Group(createTween().OnComplete(() => numSecondCompleted++))
.Complete();
Assert.AreEqual(1, numFirstCompleted);
Assert.AreEqual(1, numSecondCompleted);
}
[UnityTest]
public IEnumerator Cycles() {
var tweenCyclesDone = 0;
var sequenceCyclesDone = 0;
const int sequenceCycles = 5;
const int tweenCycles = 3;
// tween cycles doesn't matter because OnComplete will only be executed when all cycles complete
var tween = Tween.Custom(this, 0, 1, Mathf.Max(minDuration, getDt() * Random.Range(0.1f, 0.5f)), cycles: tweenCycles, onValueChange: delegate{})
.OnComplete(() => {
// Debug.Log($"[{Time.frameCount}] tweenCycles++");
tweenCyclesDone++;
});
Sequence sequence = default;
sequence = Sequence.Create(sequenceCycles)
.Chain(tween)
.ChainCallback(() => {
// Debug.Log($"[{Time.frameCount}] sequenceCycles: {sequenceCyclesDone}, actual cyclesDone: {sequence.cyclesDone}");
Assert.AreEqual(sequenceCyclesDone, sequence.cyclesDone);
Assert.AreEqual(sequenceCycles, sequence.cyclesTotal);
sequenceCyclesDone++;
});
yield return sequence.ToYieldInstruction();
Assert.IsFalse(tween.isAlive);
Assert.IsFalse(sequence.isAlive);
Assert.AreEqual(sequenceCycles, tweenCyclesDone);
Assert.AreEqual(sequenceCycles, sequenceCyclesDone);
}
/*static IEnumerator Timeout([NotNull] Func<bool> continueWaiting, float timeout) {
var timeStarted = Time.time;
while (continueWaiting()) {
if (Time.time - timeStarted > timeout) {
throw new Exception($"Timeout of {timeout} seconds reached.");
}
yield return null;
}
}*/
[Test]
public void GroupDeadTweenToSequence() {
var deadTween = createTween();
deadTween.Complete();
expectAddDeadToSequenceError();
Sequence.Create(Tween.Delay(0.001f)).Group(deadTween);
}
Tween createTween() {
var t = Tween.LocalPosition(transform, Vector3.one, 1);
Assert.IsTrue(t.isAlive);
return t;
}
[Test]
public void ChainDeadTweenToSequence() {
var tweener = Tween.LocalPosition(transform, Vector3.one, 1);
tweener.Complete();
Assert.IsFalse(tweener.isAlive);
expectAddDeadToSequenceError();
Sequence.Create(Tween.Delay(0.0001f)).Chain(tweener);
}
static void expectAddDeadToSequenceError() {
LogAssert.Expect(LogType.Error, Constants.addDeadTweenToSequenceError);
}
[UnityTest]
public IEnumerator SequenceRelease() {
Tween.StopAll();
for (int i = 0; i < 5; i++) {
Assert.AreEqual(0, tweensCount);
var duration = Mathf.Max(TweenSettings.minDuration, getDt());
var t = Tween.Delay(duration);
var s = Sequence.Create(t);
yield return null;
// Debug.Log($"duration: {duration}, dt {Time.deltaTime}");
// print(Time.deltaTime > duration);
if (Time.deltaTime > duration) {
Assert.IsFalse(t.isAlive);
Assert.IsFalse(s.isAlive);
Tween.StopAll();
continue;
}
Assert.IsTrue(t.isAlive);
Assert.IsTrue(s.isAlive);
s.Stop();
Assert.AreEqual(2, tweensCount);
yield return null;
Assert.AreEqual(0, tweensCount);
}
}
[UnityTest]
public IEnumerator ManipulatingTweensInsideSequenceCoroutine() {
{
var nestedTween = Tween.Delay(getDt());
Sequence.Create(nestedTween);
expectCantManipulateTweenInsideSequence();
yield return nestedTween.ToYieldInstruction();
}
{
var nestedSequence = Sequence.Create();
Sequence.Create().Chain(nestedSequence);
expectCantManipulateTweenInsideSequence();
yield return nestedSequence.ToYieldInstruction();
}
}
[Test]
public async Task ManipulatingTweensInsideSequenceAsync() {
var t = Tween.Delay(getDt());
#pragma warning disable 4014
Sequence.Create(t);
#pragma warning restore
expectCantManipulateTweenInsideSequence();
await t;
}
[Test]
public void ManipulatingTweensInsideSequence() {
var go = new GameObject();
var tween = Tween.Custom(go, 0, 1, 1, delegate{}, cycles: 3, cycleMode: CycleMode.Yoyo);
Sequence.Create(tween);
Assert.IsTrue(tween.isAlive);
expectCantManipulateTweenInsideSequence();
tween.Stop();
expectCantManipulateTweenInsideSequence();
tween.Complete();
expectCantManipulateTweenInsideSequence();
tween.SetRemainingCycles(5);
expectCantManipulateTweenInsideSequence();
tween.SetRemainingCycles(true);
expectCantManipulateTweenInsideSequence();
tween.Group(new Tween());
expectCantManipulateTweenInsideSequence();
tween.Chain(new Tween());
expectCantManipulateTweenInsideSequence();
tween.Group(new Sequence());
expectCantManipulateTweenInsideSequence();
tween.Chain(new Sequence());
expectCantManipulateTweenInsideSequence();
Assert.AreEqual(0 , Tween.StopAll(go));
expectCantManipulateTweenInsideSequence();
Assert.AreEqual(0, Tween.CompleteAll(go));
expectCantManipulateTweenInsideSequence();
Tween.SetPausedAll(true, go);
expectCantManipulateTweenInsideSequence();
Tween.SetPausedAll(false, go);
expectCantManipulateTweenInsideSequence();
expectCantManipulateTweenInsideSequence();
tween.isPaused = !tween.isPaused;
expectCantManipulateTweenInsideSequence();
expectCantManipulateTweenInsideSequence();
tween.timeScale += 0.5f;
expectCantManipulateTweenInsideSequence();
tween.elapsedTime += 0.1f;
expectCantManipulateTweenInsideSequence();
tween.elapsedTimeTotal += 0.1f;
Tween.StopAll();
Assert.AreEqual(0, tweensCount);
LogAssert.NoUnexpectedReceived();
}
static void expectCantManipulateTweenInsideSequence() {
LogAssert.Expect(LogType.Error, new Regex("It's not allowed to manipulate 'nested' tweens and sequences"));
}
[Test]
public void AddingInfiniteTweenToSequenceThrows() {
var infiniteTween = createInfiniteTween();
expectInfiniteTweenInSequenceError();
Sequence.Create(infiniteTween);
expectInfiniteTweenInSequenceError();
Sequence.Create(infiniteTween);
expectInfiniteTweenInSequenceError();
Sequence.Create(Tween.Delay(minDuration)).Chain(infiniteTween);
}
static void expectInfiniteTweenInSequenceError() => LogAssert.Expect(LogType.Error, Constants.infiniteTweenInSequenceError);
static void expectException<T>(Action code, [NotNull] string message) where T: Exception {
Assert.IsFalse(string.IsNullOrEmpty(message));
try {
code();
} catch (T e) {
if (!e.Message.Contains(message)) {
Debug.LogException(e);
Assert.Fail();
}
return;
}
Assert.Fail($"Exception of type {typeof(T)} didn't appear: {message}");
}
[Test]
public void TestDeadSequence() {
var s = createDeadSequence();
expectError();
s.Group(createCustomTween(1));
expectError();
s.ChainCallback(delegate { });
expectError();
s.ChainCallback(this, delegate { });
expectError();
s.Chain(createTween());
#if PRIME_TWEEN_DOTWEEN_ADAPTER
expectError();
s.ChainLast(createTween());
#endif
s.Stop();
s.Complete();
// s.Revert();
expectError();
s.SetRemainingCycles(5);
expectError();
s.isPaused = true;
void expectError() {
expectIsDeadError();
}
}
static Sequence createDeadSequence() {
var s = Sequence.Create(createCustomTween(1));
s.Complete();
Assert.IsFalse(s.isAlive);
return s;
}
[UnityTest]
public IEnumerator AddingTweenToSequenceModifiesIsPausedToMatchSequence() {
Tween.StopAll();
Assert.AreEqual(0, tweensCount);
var s = Sequence.Create(Tween.PositionY(transform,10f, 0.04f));
Assert.IsFalse(s.isPaused);
var t = Tween.Delay(0.04f);
Assert.IsFalse(t.isPaused);
t.isPaused = true;
Assert.IsTrue(t.isPaused);
LogAssert.Expect(LogType.Error, new Regex("'isPaused' was ignored after adding"));
s.Group(t);
LogAssert.NoUnexpectedReceived();
yield return s.ToYieldInstruction();
}
[Test]
public void DuplicateTweenAddedToSequence() {
var t = createTween();
var s = Sequence.Create(t);
expectNestTweenTwiceError();
s.Group(t);
expectNestTweenTwiceError();
var s2 = Sequence.Create();
s2.Group(t);
expectNestTweenTwiceError();
Sequence.Create(t);
}
static void expectNestTweenTwiceError() => LogAssert.Expect(LogType.Error, new Regex(Constants.nestTweenTwiceError));
[UnityTest]
public IEnumerator TweenIsNotReleasedFromSequenceUntilSequenceReleasesAllTweens() {
var t = createCustomTween(minDuration);
var delay = Tween.Delay(getDt() * 4f);
var s = Sequence.Create(t).Group(delay);
Assert.IsTrue(t.isAlive);
yield return s.ToYieldInstruction();
Assert.IsFalse(t.isAlive);
}
[UnityTest]
public IEnumerator ProcessAllDoesntLeaveUnreleasableTweens() {
Tween.StopAll();
Assert.AreEqual(0, tweensCount);
var t1 = createCustomTween(0.0001f);
var t2 = createCustomTween(0.1f);
if (Random.value < 0.5f) {
t1.Group(t2);
} else {
t1.Chain(t2);
}
while (t1.interpolationFactor < 1f) {
yield return null;
}
Assert.IsTrue(t1.isAlive);
Assert.IsTrue(t2.isAlive);
Assert.AreNotEqual(0, tweensCount);
Tween.StopAll();
Assert.AreEqual(0, tweensCount);
}
[Test]
public void ProcessAllDoesntLeaveUnreleasableTweensWhenTargetDestroyed() {
if (tweensCount != 0) {
Tween.StopAll();
}
Assert.AreEqual(0, tweensCount);
var target1 = new GameObject();
var t1 = Tween.Custom(target1, 0, 1,0.0001f, delegate{});
var t2 = createCustomTween(0.1f);
t1.Group(t2);
Object.DestroyImmediate(target1);
Assert.AreEqual(3, tweensCount);
Assert.IsTrue(t1.isAlive);
Tween.StopAll();
Assert.AreEqual(0, tweensCount);
}
[Test]
public void SequenceCompleteWhenMoreThanTwo() {
createTween()
.Group(createTween())
.Group(createTween())
.Complete();
}
[Test]
public void SequenceDuration() {
var dur1 = Random.value;
var cycles1 = Random.Range(1, 5);
var s = Sequence.Create(Tween.Custom(this, 0, 1, dur1, cycles: cycles1, onValueChange: delegate{}));
Assert.AreEqual(dur1 * cycles1, s.duration);
Assert.AreEqual(dur1 * cycles1, s.durationTotal);
var dur2 = dur1 + Random.value;
var cycles2 = cycles1 + Random.Range(1, 5);
s.Group(Tween.Custom(this, 0, 1, dur2, cycles: cycles2, onValueChange: delegate{}));
Assert.AreEqual(dur2 * cycles2, s.duration);
Assert.AreEqual(dur2 * cycles2, s.durationTotal);
s.Chain(Tween.Delay(1));
var expected = dur2 * cycles2 + 1;
const float tolerance = 0.0001f;
Assert.AreEqual(expected, s.duration, tolerance);
Assert.AreEqual(expected, s.durationTotal, tolerance);
var sequenceCycles = Random.Range(1, 100);
s.SetRemainingCycles(sequenceCycles);
Assert.AreEqual(expected, s.duration, tolerance);
Assert.AreEqual(expected * sequenceCycles, s.durationTotal, tolerance);
s.Complete();
}
[UnityTest]
public IEnumerator SequenceCycles() {
Application.targetFrameRate = 200;
int cyclesDone = 0;
var iniCycles = Random.Range(3, 10);
// const int iniCycles = 3;
var s = Sequence.Create(iniCycles)
.Chain(Tween.PositionX(transform, 3.14f, getDt() * 2f, cycles: 2))
.ChainCallback(this, _ => cyclesDone++);
Assert.AreEqual(iniCycles, s.cyclesTotal);
Assert.AreEqual(0, s.cyclesDone);
while (s.cyclesDone == 0) {
yield return null;
}
Assert.AreEqual(iniCycles, s.cyclesTotal);
Assert.AreEqual(cyclesDone, s.cyclesDone);
var pendingCycles = Random.Range(2, 10);
// const int pendingCycles = 2;
s.SetRemainingCycles(pendingCycles);
var expectedCycles = cyclesDone + pendingCycles;
Assert.AreEqual(expectedCycles, s.cyclesTotal);
Assert.AreEqual(1, s.cyclesDone);
while (s.cyclesDone == 1) {
yield return null;
}
Assert.AreEqual(expectedCycles, s.cyclesTotal);
Assert.AreEqual(cyclesDone, s.cyclesDone);
s.Complete();
Application.targetFrameRate = targetFrameRate;
}
[Test]
public void AwaitNewlyCreatedSequenceDoesntCompleteSyncButInSameFrame() {
bool isCompleted = false;
#pragma warning disable CS4014
AwaitNewlyCreatedSequenceDoesntCompleteSyncButInSameFrame_internal(() => isCompleted = true);
#pragma warning restore CS4014
Assert.IsFalse(isCompleted);
}
static async Task AwaitNewlyCreatedSequenceDoesntCompleteSyncButInSameFrame_internal([NotNull] Action callback) {
int frameStarted = Time.frameCount;
await Sequence.Create();
Assert.AreEqual(frameStarted, Time.frameCount); // completes in same frame, but not immediately
callback();
}
[Test]
public void UsingDefaultSequenceCtor() {
for (int i = 0; i < 26; i++) {
expectDefaultCtorError();
}
var seq = new Sequence();
seq.elapsedTime += seq.elapsedTime; // +3
_ = seq.cyclesTotal;
_ = seq.cyclesDone;
_ = seq.duration;
seq.elapsedTimeTotal += seq.elapsedTimeTotal; // +3
_ = seq.durationTotal;
_ = seq.progress;
_ = seq.progressTotal;
var t = Tween.Delay(0.0001f);
seq.Group(t);
seq.Chain(t);
seq.ChainCallback(() => {});
seq.ChainCallback(this, delegate {});
seq.ChainDelay(1f);
seq.Stop(); // no error
seq.Complete(); // no error
seq.SetRemainingCycles(false);
seq.SetRemainingCycles(10);
seq.isPaused = !seq.isPaused; // +2
seq.Chain(Sequence.Create());
seq.Group(Sequence.Create());
seq.timeScale += seq.timeScale; // +3
#if PRIME_TWEEN_DOTWEEN_ADAPTER
expectDefaultCtorError();
seq.ChainLast(t);
#endif
Tween.StopAll();
}
static void expectDefaultCtorError() {
LogAssert.Expect(LogType.Error, Constants.defaultCtorError);
}
[UnityTest]
public IEnumerator OnCompleteCallbackIsCalledOnlyOnce() {
int numT1Completed = 0;
var t1 = Tween.Delay(0.05f).OnComplete(() => numT1Completed++);
var s = t1.Chain(Tween.Delay(0.05f));
while (t1.interpolationFactor < 1f) {
yield return null;
}
Assert.IsTrue(t1.isAlive);
Assert.AreEqual(1, numT1Completed);
s.Complete();
Assert.AreEqual(1, numT1Completed);
}
[UnityTest]
public IEnumerator SequenceElapsedTime2() {
Application.targetFrameRate = 200;
float dt = getDt();
var cycleTimeStart = Time.time;
float duration = dt * 5f;
var s = Tween.Delay(duration)
.Chain(Tween.Delay(duration))
.ChainCallback(() => cycleTimeStart = Time.time);
s.SetRemainingCycles(2);
var timeStart = Time.time;
while (s.isAlive) {
float tolerance = dt * 2;
Assert.AreEqual(Time.time - timeStart, s.elapsedTimeTotal, tolerance);
Assert.AreEqual(Time.time - cycleTimeStart, s.elapsedTime, tolerance);
yield return null;
}
Application.targetFrameRate = targetFrameRate;
}
[Test]
public void SequenceTimeScale() {
var seq = Sequence.Create();
const float seqTimeScale = 1.5f;
seq.timeScale = seqTimeScale;
var t2 = Tween.Delay(0.1f);
t2.timeScale = 0.5f;
LogAssert.Expect(LogType.Error, new Regex("'timeScale' was ignored after adding"));
seq.Chain(t2);
foreach (var t in seq.getAllChildren()) {
Assert.AreEqual(0.5f, t.tween.timeScale);
}
seq.timeScale = 2f;
Assert.AreEqual(2f, seq.root.timeScale);
foreach (var t in seq.getAllChildren()) {
Assert.AreEqual(0.5f, t.tween.timeScale);
}
LogAssert.NoUnexpectedReceived();
Tween.StopAll();
}
[Test]
public void CompletingMainSequenceCompletesAllChildrenSequencesAndTweens() {
int numCallback = 0;
var nestedSeq2 = Sequence.Create()
.ChainDelay(1)
.ChainCallback(() => {
Assert.AreEqual(1, numCallback);
numCallback++;
});
var nestedSeq1 = Sequence.Create()
.ChainDelay(1)
.ChainCallback(() => {
Assert.AreEqual(0, numCallback);
numCallback++;
})
.Chain(nestedSeq2);
Sequence.Create(Tween.Delay(1))
.Group(nestedSeq1)
.Complete();
Assert.AreEqual(2, numCallback);
}
[Test]
public void ManipulateNestedSequence() {
var nested = Sequence.Create(Tween.Delay(getDt()));
Sequence.Create().Group(nested);
var tween = Tween.Delay(getDt());
expectCantManipulateTweenInsideSequence();
nested.Group(tween);
expectCantManipulateTweenInsideSequence();
nested.Chain(Tween.Delay(getDt()));
expectCantManipulateTweenInsideSequence();
nested.ChainCallback(delegate {});
expectCantManipulateTweenInsideSequence();
nested.ChainCallback(this, delegate {});
expectCantManipulateTweenInsideSequence();
nested.ChainCallback(this, delegate {});
expectCantManipulateTweenInsideSequence();
nested.ChainDelay(0.1f);
expectCantManipulateTweenInsideSequence();
nested.Stop();
expectCantManipulateTweenInsideSequence();
nested.Complete();
expectCantManipulateTweenInsideSequence();
nested.SetRemainingCycles(10);
expectCantManipulateTweenInsideSequence();
expectCantManipulateTweenInsideSequence();
nested.isPaused = !nested.isPaused;
expectCantManipulateTweenInsideSequence();
nested.Chain(Sequence.Create());
expectCantManipulateTweenInsideSequence();
nested.Group(Sequence.Create());
expectCantManipulateTweenInsideSequence();
nested.elapsedTime += 0.1f;
expectCantManipulateTweenInsideSequence();
nested.elapsedTimeTotal += 0.1f;
expectCantManipulateTweenInsideSequence();
expectCantManipulateTweenInsideSequence();
nested.timeScale += 1f;
}
[Test]
public async Task OnCompleteExceptionInsideSequenceDoesntStopSequence() {
// by design: if one tween's onComplete throws exception, Sequence should continue to play further
{
int numCallbacks = 0;
expectOnCompleteException();
await Sequence.Create(Tween.Delay(getDt(), () => throw new Exception()))
.Chain(Tween.Delay(getDt(), () => numCallbacks++))
.ChainCallback(() => numCallbacks++);
Assert.AreEqual(2, numCallbacks);
}
{
int numCallbacks = 0;
expectOnCompleteException();
await Sequence.Create(Tween.Delay(this, getDt(), _ => throw new Exception()))
.Chain(Tween.Delay(getDt(), () => numCallbacks++))
.ChainCallback(() => numCallbacks++);
Assert.AreEqual(2, numCallbacks);
}
}
[UnityTest]
public IEnumerator TestSequenceEnumerator() {
const float duration = 0.0001f;
var t1 = Tween.Delay(duration);
var s1 = Sequence.Create(t1);
var t2 = Tween.Delay(duration);
var s2 = Sequence.Create(t2);
var t3 = Tween.Delay(duration);
var s3 = Sequence.Create(t3);
s2.Chain(s3);
s1.Chain(s2);
var expected = new[] {
s1.root, t1,
s2.root, t2,
s3.root, t3
};
int i = 0;
foreach (var t in s1.getAllTweens()) {
Assert.AreEqual(expected[i], t);
i++;
}
Assert.AreEqual(6, i);
i = 1;
foreach (var t in s1.getSelfChildren()) {
Assert.AreEqual(expected[i], t);
i++;
}
Assert.AreEqual(3, i);
i = 3;
foreach (var t in s2.getSelfChildren()) {
Assert.AreEqual(expected[i], t);
i++;
}
Assert.AreEqual(5, i);
i = 5;
foreach (var t in s3.getSelfChildren()) {
Assert.AreEqual(expected[i], t);
i++;
}
Assert.AreEqual(6, i);
yield return null;
}
[Test]
public void TestSequenceEnumeratorWithEmptySequences() {
var s1 = Sequence.Create();
var s2 = Sequence.Create();
var s3 = Sequence.Create();
s1.Chain(s2)
.Chain(s3);
var expected = new[] { s1.root, s2.root, s3.root };
int i = 0;
foreach (var t in s1.getAllTweens()) {
Assert.AreEqual(expected[i], t);
i++;
}
i = 1;
foreach (var t in s1.getSelfChildren()) {
Assert.AreEqual(expected[i], t);
i++;
}
foreach (var _ in s2.getSelfChildren()) {
Assert.Fail();
}
foreach (var _ in s3.getSelfChildren()) {
Assert.Fail();
}
}
[Test]
public void MainSequenceSiblingShouldBeEmpty() {
var main = Sequence.Create();
var nested1 = Sequence.Create(Tween.Delay(getDt()));
main.Chain(nested1);
Assert.AreEqual(main.root.tween.next, nested1.root);
Assert.IsFalse(main.root.tween.nextSibling.IsCreated);
var nested2 = Sequence.Create(Tween.Delay(getDt()));
main.Chain(nested2);
Assert.AreEqual(main.root.tween.next, nested1.root);
Assert.IsFalse(main.root.tween.nextSibling.IsCreated);
}
[Test]
public void CompleteSequenceOnBackwardCycle() {
var target = new GameObject().transform;
const float duration = 1f;
Sequence.Create(2, CycleMode.Rewind)
.Chain(Tween.PositionY(target, 1, duration))
.Chain(Tween.PositionY(target, 0, duration)).Complete();
Assert.AreEqual(0f, target.position.y);
Object.Destroy(target.gameObject);
}
[UnityTest]
public IEnumerator CompleteSequenceOnBackwardCycle2() {
var target = GameObject.CreatePrimitive(PrimitiveType.Cube).transform;
yield return test(2, false);
yield return test(2, true);
yield return test(3, false);
yield return test(3, true);
yield return test(4, false);
yield return test(4, true);
IEnumerator test(int cycles, bool completeImmediately) {
// print($"test {cycles}, {completeImmediately}");
const float duration = 0.0001f;
int numCompleted = 0;
var seq = Sequence.Create(cycles, CycleMode.Yoyo, Ease.OutBounce)
.Chain(Tween.PositionY(target, 1f, duration).OnComplete(() => numCompleted++))
.Chain(Tween.PositionY(target, 0f, duration));
if (completeImmediately) {
seq.Complete();
} else {
yield return seq.ToYieldInstruction();
}
if (completeImmediately) {
Assert.AreEqual(1, numCompleted);
} else {
Assert.AreEqual((cycles + 1) / 2, numCompleted);
}
Assert.AreEqual(0f, target.position.y);
}
Object.Destroy(target.gameObject);
}
[UnityTest]
public IEnumerator CompleteInfiniteSequence() {
int numCallbacks = 0;
var duration = Mathf.Max(minDuration, Random.Range(0f, getDt()));
Assert.IsTrue(duration >= minDuration);
var s = Sequence.Create(-1)
.ChainDelay(duration)
.ChainCallback(() => numCallbacks++);
float timeStart = Time.time;
yield return null;
yield return null;
var cyclesDoneExpected = Mathf.FloorToInt((Time.time - timeStart) / duration);
Assert.AreEqual(cyclesDoneExpected, s.cyclesDone);
s.Complete();
Assert.AreEqual(cyclesDoneExpected + 1, numCallbacks);
}
[Test]
public void OnCompleteWithSequenceBackward() {
int numCompleted = 0;
int cycles = Random.Range(1, 7);
var seq = Sequence.Create(cycles)
.Group(Sequence.Create(cycles)
.Group(Sequence.Create(cycles)
.Group(Tween.Delay(0.1f, () => numCompleted++))));
seq.isPaused = true;
seq.elapsedTimeTotal = float.MaxValue;
int cyclesTotal = cycles * cycles * cycles;
int cyclesExpected = cyclesTotal;
Assert.AreEqual(cyclesExpected, numCompleted);
seq.elapsedTimeTotal = 0f;
cyclesExpected += cyclesTotal - 1;
Assert.AreEqual(cyclesExpected, numCompleted);
seq.elapsedTimeTotal = float.MaxValue;
cyclesExpected += cyclesTotal;
Assert.AreEqual(cyclesExpected, numCompleted);
seq.elapsedTimeTotal = 0f;
cyclesExpected += cyclesTotal - 1;
Assert.AreEqual(cyclesExpected, numCompleted);
seq.Complete();
cyclesExpected += cycles * cycles;
Assert.AreEqual(cyclesExpected, numCompleted);
}
[UnityTest]
public IEnumerator UnpauseCompletedSequenceShouldRelease() {
var s = Tween.Delay(getDt()).Chain(Tween.Delay(getDt()));
s.isPaused = true;
s.elapsedTimeTotal = s.durationTotal;
yield return null;
yield return null;
Assert.IsTrue(s.isAlive);
s.isPaused = false;
Assert.IsFalse(s.isAlive);
}
[UnityTest]
public IEnumerator UnpauseCompletedTweenShouldRelease() {
var t = Tween.Delay(getDt());
t.isPaused = true;
t.elapsedTimeTotal = t.durationTotal;
yield return null;
yield return null;
Assert.IsTrue(t.isAlive);
t.isPaused = false;
Assert.IsFalse(t.isAlive);
}
[UnityTest]
public IEnumerator NestedSequenceCycles() {
string result = "";
void append(int i) => result += i.ToString();
yield return createNestedSequences(getDt()).ToYieldInstruction();
Assert.AreEqual("12332331233233", result);
createNestedSequences(getDt()).Complete();
Assert.AreEqual("1233233", result);
PrimeTweenConfig.warnZeroDuration = false;
yield return createNestedSequences(0f).ToYieldInstruction();
Assert.AreEqual("12332331233233", result);
createNestedSequences(0f).Complete();
Assert.AreEqual("1233233", result);
Sequence createNestedSequences(float duration) {
result = "";
var s3 = Sequence.Create(2).ChainDelay(duration).ChainCallback(() => append(3));
var s2 = Sequence.Create(2).ChainDelay(duration).ChainCallback(() => append(2)).Chain(s3);
var s1 = Sequence.Create(2).ChainDelay(duration).ChainCallback(() => append(1)).Chain(s2);
return s1;
}
}
[UnityTest]
public IEnumerator AddTweenToStartedSequence() {
var s = Sequence.Create(Tween.Delay(1f));
yield return null;
Assert.IsTrue(s.isAlive);
Assert.AreNotEqual(0f, s.elapsedTimeTotal);
var t = Tween.Delay(0.1f);
expectError();
s.Chain(t);
expectError();
s.Group(t);
expectError();
s.Chain(Sequence.Create());
expectError();
s.Group(Sequence.Create());
Tween.StopAll();
LogAssert.NoUnexpectedReceived();
static void expectError() => LogAssert.Expect(LogType.Error, Constants.animationAlreadyStarted);
}
[UnityTest]
public IEnumerator OnCompleteIgnoredErrorOnSequenceEmergencyStop() {
expectTweenWasStoppedBecauseException();
expectOnCompleteIgnored();
yield return Tween.Custom(0f, 1f, getDt(), _ => throw new Exception())
.Chain(Tween.Delay(getDt(), Assert.Fail))
.ToYieldInstruction();
}
[UnityTest]
public IEnumerator SequenceIsEmptyEnumerationBug() {
yield return Sequence.Create()
.Chain(Sequence.Create().Chain(Sequence.Create()))
.Chain(Sequence.Create().Chain(Sequence.Create()))
.ToYieldInstruction();
}
[UnityTest]
public IEnumerator SequenceIsEmptyEnumerationCausesStackOverflowBug() {
var duration = getDt() * 2f;
yield return Sequence.Create()
.Chain(Tween.Delay(duration).Chain(Sequence.Create()))
.Chain(Tween.Delay(duration).Chain(Sequence.Create()))
.ToYieldInstruction();
}
[UnityTest]
public IEnumerator SequenceOnComplete() {
int numCompleted = 0;
yield return Sequence.Create(2, CycleMode.Yoyo)
.ChainDelay(getDt())
.OnComplete(() => numCompleted++)
.ToYieldInstruction();
Assert.AreEqual(1, numCompleted);
numCompleted = 0;
yield return Sequence.Create(2, CycleMode.Yoyo)
.ChainDelay(getDt())
.OnComplete(this, _ => numCompleted++)
.ToYieldInstruction();
Assert.AreEqual(1, numCompleted);
}
[Test]
public void LongGroupAfterChainOpSequence() {
var seq = Tween.Delay(0.1f)
.Chain(Tween.Delay(0.1f));
seq.Group(Sequence.Create(Tween.Delay(1f)));
Assert.AreEqual(1.1f, seq.duration);
seq.Group(Sequence.Create(Tween.Delay(2f)));
Assert.AreEqual(2.1f, seq.duration);
seq.Chain(Sequence.Create(Tween.Delay(1f)));
Assert.AreEqual(3.1f, seq.duration);
seq.Stop();
}
[Test]
public void LongGroupAfterChainOpTween() {
var seq = Tween.Delay(0.1f)
.Chain(Tween.Delay(0.1f));
seq.Group(Tween.Delay(1f));
Assert.AreEqual(1.1f, seq.duration);
seq.Group(Tween.Delay(2f));
Assert.AreEqual(2.1f, seq.duration);
seq.Chain(Tween.Delay(1f));
Assert.AreEqual(3.1f, seq.duration);
seq.Stop();
}
[UnityTest]
public IEnumerator SequenceRecursiveCreate() {
var target = new GameObject();
float duration = getDt() * 2f;
Sequence seq1 = default;
Sequence seq2 = default;
createSeq1();
void createSeq1() {
// print("createSeq1");
seq1.Stop();
seq1 = Sequence.Create()
.Chain(Tween.Delay(target, duration: duration))
.ChainCallback(() => {
})
.Chain(Tween.Delay(target, duration: duration))
.ChainCallback(() => {
createSeq2();
});
createSeq2();
}
void createSeq2() {
// print("createSeq2");
seq2.Stop();
seq2 = Sequence.Create()
.Chain(Tween.Delay(target, duration: duration))
.ChainCallback(() => {
})
.Chain(Tween.Delay(target, duration: duration))
.ChainCallback(() => {
seq1.Complete();
});
}
while (seq1.isAlive || seq2.isAlive) {
yield return null;
}
yield return null;
}
[UnityTest]
public IEnumerator StopSequenceFromCallback2() {
Sequence s = default;
int numCyclesDone = 0;
var duration = getDt() * 2f;
s = Sequence.Create(2)
.ChainDelay(duration)
.ChainDelay(duration)
.ChainCallback(() => {
numCyclesDone++;
// print($"numCyclesDone: {numCyclesDone}");
if (numCyclesDone == 2) {
s.timeScale = 0f;
s.SetRemainingCycles(3);
Tween.StopAll();
}
});
yield return s.ToYieldInstruction();
yield return null;
}
[UnityTest]
public IEnumerator StopSequenceFromCallback3() {
var dt = getDt();
var s2 = Sequence.Create().ChainDelay(dt * 10f);
var s1 = Sequence.Create()
.ChainDelay(dt)
.ChainCallback(() => {
Assert.IsTrue(s2.isAlive);
s2.Stop();
Assert.IsFalse(s2.isAlive);
});
yield return s1.ToYieldInstruction();
yield return null;
}
[UnityTest]
public IEnumerator StopSequenceFromCallback4() {
Sequence s = default;
s = Sequence.Create(2)
.ChainDelay(getDt())
.ChainCallback(() => {
s.Stop();
});
yield return s.ToYieldInstruction();
yield return null;
}
[UnityTest]
public IEnumerator SequenceOnCompleteIsCalledAfterAllChildren() {
bool delayCompleted = false;
bool sequenceCompleted = false;
var delay = Tween.Delay(getDt(), () => {
Assert.IsTrue(!delayCompleted && !sequenceCompleted);
delayCompleted = true;
});
yield return Sequence.Create(delay).OnComplete(() => {
Assert.IsTrue(delayCompleted);
Assert.IsFalse(sequenceCompleted);
sequenceCompleted = true;
});
Assert.IsTrue(delayCompleted && sequenceCompleted);
}
[UnityTest]
public IEnumerator SequenceIsNotAliveInOnComplete() {
Sequence s = default;
int onCompleted = 0;
s = Sequence.Create()
.OnComplete(() => {
Assert.IsFalse(s.isAlive);
onCompleted++;
});
yield return null;
Assert.AreEqual(1, onCompleted);
Assert.IsFalse(s.isAlive);
}
[UnityTest]
public IEnumerator CompleteSequenceInOnComplete() {
Sequence s = default;
s = Sequence.Create()
.OnComplete(() => {
Assert.IsFalse(s.isAlive);
s.Complete();
});
yield return s.ToYieldInstruction();
}
[UnityTest]
public IEnumerator SequenceSetProgressRecursively() {
int i = 0;
Sequence s = default;
s = Sequence.Create()
.Chain(Tween.Custom(0f, 1f, getDt() * 2f, _ => {
i++;
Assert.IsTrue(i < 100);
expectRecursiveCallError();
s.progress += 0.01f;
expectRecursiveCallError();
s.progressTotal += 0.01f;
expectRecursiveCallError();
s.elapsedTime += 0.01f;
expectRecursiveCallError();
s.elapsedTimeTotal += 0.01f;
}));
yield return s.ToYieldInstruction();
}
static void expectRecursiveCallError() => LogAssert.Expect(LogType.Error, Constants.recursiveCallError);
[UnityTest]
public IEnumerator SetSequenceProgressTo_1_AtCycleEnd() {
Sequence s = default;
s = Sequence.Create(2)
.ChainDelay(0.01f)
.Chain(Tween.Custom(0f, 1f, 0.01f, val => {
if (val == 1f) {
// print("custom val == 1f");
expectRecursiveCallError();
s.progress = 1f;
}
}));
yield return s.ToYieldInstruction();
}
[UnityTest]
public IEnumerator SetSequenceProgressTo_0_AtCycleEnd() {
Sequence s = default;
s = Sequence.Create(2)
.Chain(Tween.Custom(0f, 1f, 0.01f, val => {
if (val == 1f) {
// print("custom val == 1f");
expectRecursiveCallError();
s.progress = 0f;
}
}));
yield return s.ToYieldInstruction();
}
[UnityTest]
public IEnumerator SequenceStopOrCompleteFromCustomCallback() {
yield return test(s => {
// callback can be called twice when Time.delta time is less than TweenSetting.minDuration
s.Complete();
});
yield return test(s => s.Stop());
IEnumerator test(Action<Sequence> action) {
Sequence s = default;
s = Sequence.Create(2)
.ChainDelay(minDuration)
.Chain(Tween.Custom(0f, 1f, minDuration, _ => {
Assert.IsTrue(s.isAlive);
action(s);
Assert.IsFalse(s.isAlive);
}));
yield return s.ToYieldInstruction();
}
}
[UnityTest]
public IEnumerator StopSequenceFromSequenceOnComplete() {
Sequence sequence = default;
sequence = Sequence.Create()
.OnComplete(() => {
Assert.IsFalse(sequence.isAlive);
sequence.Stop();
});
yield return sequence.ToYieldInstruction();
}
[UnityTest]
public IEnumerator SettingSequenceRemainingCyclesInOnComplete() {
Sequence s = default;
s = Sequence.Create()
.OnComplete(() => {
Assert.IsFalse(s.isAlive);
expectIsDeadError();
s.SetRemainingCycles(2);
});
yield return s.ToYieldInstruction();
}
[UnityTest]
public IEnumerator AddingStartedTweenToSequenceIsOk() {
var tween = Tween.PositionY(transform, getDt() * 3, 1f);
yield return null;
Assert.IsTrue(tween.isAlive);
Sequence.Create(tween).Stop();
Assert.IsFalse(tween.isAlive);
}
#if PRIME_TWEEN_DOTWEEN_ADAPTER
[Test]
public void SequenceDurationAfterChainLast() {
var seq = Tween.Delay(1f)
.Group(Tween.Delay(0.5f))
.ChainLast(Tween.Delay(0.1f));
Assert.AreEqual(1f, seq.duration);
seq.ChainLast(Tween.Delay(1f));
Assert.AreEqual(1.6f, seq.duration);
}
[UnityTest]
public IEnumerator PrependInterval() {
{
var duration = getDt();
yield return Sequence.Create(Tween.Delay(duration)).PrependInterval(duration).ToYieldInstruction();
}
{
var s = Sequence.Create()
.ChainCallback(() => Assert.Fail())
.PrependInterval(100f);
yield return null;
s.Stop();
}
}
[Test]
public void DontLogCantManipulateErrorInAdapter() {
var target = new GameObject().transform;
{
var t = Tween.Delay(target, 1f);
Sequence.Create(t);
Assert.AreEqual(0, target.DOKill());
Assert.AreEqual(0, target.DOKill(true));
LogAssert.NoUnexpectedReceived();
}
Object.DestroyImmediate(target.gameObject);
}
#endif
[UnityTest]
public IEnumerator Insert1() {
var seq = Sequence.Create();
int numCallbacks = 0;
seq.InsertCallback(0f, () => numCallbacks++);
Assert.AreEqual(0f, seq.duration);
yield return seq.ToYieldInstruction();
Assert.AreEqual(1, numCallbacks);
LogAssert.NoUnexpectedReceived();
}
[UnityTest]
public IEnumerator Insert2() {
var seq = Sequence.Create();
int i = 0;
seq.InsertCallback(0f, transform, delegate {
Assert.AreEqual(0, i);
i++;
});
Assert.AreEqual(0f, seq.duration);
float dt = getDt();
float longestTime = dt * 10;
seq.InsertCallback(longestTime, () => {
Assert.AreEqual(2, i);
i++;
});
Assert.AreEqual(longestTime, seq.duration);
seq.InsertCallback(dt, () => {
Assert.AreEqual(1, i);
i++;
});
Assert.AreEqual(longestTime, seq.duration);
yield return seq.ToYieldInstruction();
}
[UnityTest]
public IEnumerator Insert3() {
var seq = Sequence.Create();
seq.Insert(0f, Tween.Delay(1f));
Assert.AreEqual(1f, seq.duration);
seq.Insert(0.5f, Tween.Delay(1f));
Assert.AreEqual(1.5f, seq.duration);
seq.Insert(0.5f, Tween.Delay(1f));
Assert.AreEqual(1.5f, seq.duration);
seq.Insert(2f, Tween.Delay(1f));
Assert.AreEqual(3f, seq.duration);
seq.Chain(Tween.Delay(1f));
Assert.AreEqual(4f, seq.duration);
seq.Insert(5f, Tween.Delay(1f));
Assert.AreEqual(6f, seq.duration);
seq.Group(Tween.Delay(1f));
Assert.AreEqual(6f, seq.duration);
seq.Group(Tween.Delay(1.5f));
Assert.AreEqual(6.5f, seq.duration);
seq.Stop();
yield break;
}
[Test]
public void NestSequenceTwice() {
var main = Sequence.Create();
var nested = Sequence.Create();
main.Group(nested);
LogAssert.Expect(LogType.Error, Constants.nestSequenceTwiceError);
main.Group(nested);
}
[UnityTest]
public IEnumerator SequenceCompleteRemainingCycles() {
var yoyoOrRewind = Random.value < 0.5f ? CycleMode.Yoyo : CycleMode.Rewind;
{
float val = -1f;
int numCompleted = 0;
Sequence.Create(9, yoyoOrRewind)
.Chain(Tween.Custom(0f, 1f, 1f, x => val = x))
.ChainCallback(() => numCompleted++)
.Complete();
Assert.AreEqual(1, numCompleted);
Assert.AreEqual(1f, val);
}
{
float val = -1f;
int numCompleted = 0;
Sequence.Create(10, yoyoOrRewind)
.Chain(Tween.Custom(0f, 1f, 1f, x => val = x))
.ChainCallback(() => numCompleted++)
.Complete();
Assert.AreEqual(1, numCompleted);
Assert.AreEqual(0f, val);
}
{
float val = -1f;
int numCompleted = 0;
var seq = Sequence.Create(9, yoyoOrRewind)
.Chain(Tween.Custom(0f, 1f, 100f, x => val = x))
.ChainCallback(() => numCompleted++);
seq.progress = 1f;
yield return null;
Assert.AreEqual(1, seq.cyclesDone);
Assert.AreEqual(1, numCompleted);
seq.Complete();
Assert.AreEqual(2, numCompleted);
Assert.AreEqual(1f, val);
}
{
float val = -1f;
int numCompleted = 0;
var seq = Sequence.Create(10, yoyoOrRewind)
.Chain(Tween.Custom(0f, 1f, 100f, x => val = x))
.ChainCallback(() => numCompleted++);
seq.progress = 1f;
yield return null;
Assert.AreEqual(1, seq.cyclesDone);
Assert.AreEqual(1, numCompleted);
seq.Complete();
Assert.AreEqual(1, numCompleted);
Assert.AreEqual(0f, val);
}
{
float val = -1f;
int numCompleted = 0;
Sequence.Create(Random.Range(1, 100), CycleMode.Restart)
.Chain(Tween.Custom(0f, 1f, 1f, x => val = x))
.ChainCallback(() => numCompleted++)
.Complete();
Assert.AreEqual(1, numCompleted);
Assert.AreEqual(1f, val);
}
}
[Test]
public void GetTweensCountOnSequence() {
Tween.StopAll();
Assert.AreEqual(0, Tween.GetTweensCount());
var seq = Tween.Position(transform, Vector3.one, 1f)
.Chain(Tween.Position(transform, Vector3.zero, 1f));
Assert.AreEqual(3, Tween.GetTweensCount()); // two tweens + sequence
Assert.AreEqual(2, Tween.GetTweensCount(transform)); // two tween on transform
seq.Stop();
}
/// report: https://forum.unity.com/threads/primetween-high-performance-animations-and-sequences.1479609/page-6#post-9802575
[UnityTest]
public IEnumerator SequenceUpdatesChildrenOnlyIfUpdatedSelf() {
var seq = Sequence.Create()
.ChainDelay(1)
.Chain(Sequence.Create()
.Chain(Tween.Custom(0f, 1f, 1f, _ => Assert.Fail())));
yield return null;
seq.Stop();
}
/// https://github.com/KyryloKuzyk/PrimeTween/discussions/112
[Test]
public void SequenceChainOrInsertCallbackBug1() {
var seq = Sequence.Create()
.ChainDelay(1f)
.ChainCallback(() => { })
.Group(Tween.Delay(1f));
Assert.AreEqual(2f, seq.duration);
}
[Test]
public void SequenceChainOrInsertCallbackBug2() {
var seq = Sequence.Create()
.ChainDelay(1f)
.ChainCallback(this, _ => { })
.Group(Tween.Delay(1f));
Assert.AreEqual(2f, seq.duration);
}
[Test]
public void SequenceChainOrInsertCallbackBug3() {
var seq = Sequence.Create()
.ChainDelay(1f)
.InsertCallback(0.5f, () => { })
.Group(Tween.Delay(1f));
Assert.AreEqual(1.5f, seq.duration);
}
[Test]
public void SequenceChainOrInsertCallbackBug4() {
var seq = Sequence.Create()
.ChainDelay(1f)
.InsertCallback(0.5f, this, _ => { })
.Group(Tween.Delay(1f));
Assert.AreEqual(1.5f, seq.duration);
}
}
#endif