193 lines
7.6 KiB
C#
193 lines
7.6 KiB
C#
using System;
|
|
using System.Collections;
|
|
using AibisDream.MiniGame.Language;
|
|
using NUnit.Framework;
|
|
using UnityEngine;
|
|
|
|
namespace AibisDream.EditorTests.Huoshan
|
|
{
|
|
public sealed class LogReleasePresentationTests
|
|
{
|
|
[Test]
|
|
public void LineClip_RejectsOutsideSegment()
|
|
{
|
|
Bounds bounds = new Bounds(Vector3.zero, new Vector3(2f, 2f, 0f));
|
|
bool visible = ConnectionRenderer.TryClipLineToBounds(
|
|
new Vector3(-3f, 2f),
|
|
new Vector3(3f, 2f),
|
|
bounds,
|
|
out _,
|
|
out _);
|
|
|
|
Assert.That(visible, Is.False);
|
|
}
|
|
|
|
[TestCase(-0.5f, 0f, 0.5f, 0f, -0.5f, 0f, 0.5f, 0f)]
|
|
[TestCase(-2f, 0f, 2f, 0f, -1f, 0f, 1f, 0f)]
|
|
[TestCase(0f, -2f, 0f, 0.5f, 0f, -1f, 0f, 0.5f)]
|
|
[TestCase(-2f, -2f, 2f, 2f, -1f, -1f, 1f, 1f)]
|
|
public void LineClip_ReturnsExpectedInteriorSegment(
|
|
float ax,
|
|
float ay,
|
|
float bx,
|
|
float by,
|
|
float expectedAx,
|
|
float expectedAy,
|
|
float expectedBx,
|
|
float expectedBy)
|
|
{
|
|
Bounds bounds = new Bounds(Vector3.zero, new Vector3(2f, 2f, 0f));
|
|
bool visible = ConnectionRenderer.TryClipLineToBounds(
|
|
new Vector3(ax, ay),
|
|
new Vector3(bx, by),
|
|
bounds,
|
|
out Vector3 clippedA,
|
|
out Vector3 clippedB);
|
|
|
|
Assert.That(visible, Is.True);
|
|
Assert.That(clippedA.x, Is.EqualTo(expectedAx).Within(0.0001f));
|
|
Assert.That(clippedA.y, Is.EqualTo(expectedAy).Within(0.0001f));
|
|
Assert.That(clippedB.x, Is.EqualTo(expectedBx).Within(0.0001f));
|
|
Assert.That(clippedB.y, Is.EqualTo(expectedBy).Within(0.0001f));
|
|
}
|
|
|
|
[TestCase(CompletionPhase.None, false)]
|
|
[TestCase(CompletionPhase.Completed, false)]
|
|
[TestCase(CompletionPhase.Focusing, true)]
|
|
[TestCase(CompletionPhase.FocusHolding, true)]
|
|
[TestCase(CompletionPhase.Finished, true)]
|
|
public void ConnectionClipping_OnlyStartsAfterOutput(
|
|
CompletionPhase phase,
|
|
bool expected)
|
|
{
|
|
Assert.That(LanguageParticleManager.ShouldClipConnections(phase), Is.EqualTo(expected));
|
|
}
|
|
|
|
[Test]
|
|
public void LieEdgePosition_LandsOnScreenPerimeterAndStaysInside()
|
|
{
|
|
Bounds bounds = new Bounds(Vector3.zero, new Vector3(6f, 4f, 0f));
|
|
const float inset = 0.1f;
|
|
for (int i = 0; i < 8; i++)
|
|
{
|
|
Vector3 position = LanguageParticleManager.CalculateScreenEdgePosition(
|
|
bounds,
|
|
i,
|
|
8,
|
|
inset);
|
|
|
|
Assert.That(position.x, Is.InRange(bounds.min.x, bounds.max.x));
|
|
Assert.That(position.y, Is.InRange(bounds.min.y, bounds.max.y));
|
|
bool touchesVerticalEdge =
|
|
Mathf.Abs(Mathf.Abs(position.x) - (bounds.extents.x - inset)) < 0.0001f;
|
|
bool touchesHorizontalEdge =
|
|
Mathf.Abs(Mathf.Abs(position.y) - (bounds.extents.y - inset)) < 0.0001f;
|
|
Assert.That(touchesVerticalEdge || touchesHorizontalEdge, Is.True);
|
|
}
|
|
}
|
|
|
|
[TestCase(6, 0.70f)]
|
|
[TestCase(6, 0.90f)]
|
|
[TestCase(6, 1.10f)]
|
|
public void ResolveTiming_LastCharacterCompletesWithinPreset(int characterCount, float totalDuration)
|
|
{
|
|
LanguageParticleManager.CalculateResolveTiming(
|
|
characterCount,
|
|
totalDuration,
|
|
3.5f,
|
|
0.4f,
|
|
out float characterDuration,
|
|
out float stagger);
|
|
|
|
float lastCompletion = characterDuration + stagger * (characterCount - 1);
|
|
Assert.That(lastCompletion, Is.LessThanOrEqualTo(totalDuration + 0.0001f));
|
|
Assert.That(lastCompletion, Is.EqualTo(totalDuration).Within(0.0001f));
|
|
}
|
|
|
|
[Test]
|
|
public void TmpClipRect_ConvertsWorldCornersIntoTextLocalSpace()
|
|
{
|
|
GameObject rectObject = new GameObject("ScreenRect", typeof(RectTransform));
|
|
GameObject textObject = new GameObject("TextTransform");
|
|
try
|
|
{
|
|
RectTransform rect = rectObject.GetComponent<RectTransform>();
|
|
rect.sizeDelta = new Vector2(4f, 2f);
|
|
rect.position = new Vector3(2f, -1f, 0f);
|
|
rect.rotation = Quaternion.Euler(0f, 0f, 17f);
|
|
rect.localScale = new Vector3(1.2f, 0.8f, 1f);
|
|
|
|
textObject.transform.position = new Vector3(-0.5f, 0.75f, 0f);
|
|
textObject.transform.rotation = Quaternion.Euler(0f, 0f, -11f);
|
|
textObject.transform.localScale = new Vector3(1.4f, 0.65f, 1f);
|
|
|
|
Vector4 actual = TMPRectClipper.CalculateLocalClipRect(textObject.transform, rect);
|
|
Vector3[] corners = new Vector3[4];
|
|
rect.GetWorldCorners(corners);
|
|
Vector3 first = textObject.transform.InverseTransformPoint(corners[0]);
|
|
float minX = first.x;
|
|
float minY = first.y;
|
|
float maxX = first.x;
|
|
float maxY = first.y;
|
|
for (int i = 1; i < corners.Length; i++)
|
|
{
|
|
Vector3 local = textObject.transform.InverseTransformPoint(corners[i]);
|
|
minX = Mathf.Min(minX, local.x);
|
|
minY = Mathf.Min(minY, local.y);
|
|
maxX = Mathf.Max(maxX, local.x);
|
|
maxY = Mathf.Max(maxY, local.y);
|
|
}
|
|
|
|
Assert.That(actual.x, Is.EqualTo(minX).Within(0.0001f));
|
|
Assert.That(actual.y, Is.EqualTo(minY).Within(0.0001f));
|
|
Assert.That(actual.z, Is.EqualTo(maxX).Within(0.0001f));
|
|
Assert.That(actual.w, Is.EqualTo(maxY).Within(0.0001f));
|
|
}
|
|
finally
|
|
{
|
|
UnityEngine.Object.DestroyImmediate(rectObject);
|
|
UnityEngine.Object.DestroyImmediate(textObject);
|
|
}
|
|
}
|
|
|
|
[TestCase(null, null)]
|
|
[TestCase("", null)]
|
|
[TestCase(" | ", null)]
|
|
[TestCase("没问题|冇", "没问题冇")]
|
|
[TestCase("没 问 题", "没问题")]
|
|
public void SlotMachinePool_StripsSeparatorsAndWhitespace(string input, string expected)
|
|
{
|
|
Assert.That(LanguageParticleManager.SanitizeSlotMachinePool(input), Is.EqualTo(expected));
|
|
}
|
|
|
|
[Test]
|
|
public void ActorPhraseList_PreservesWordsAndDropsEmptyEntries()
|
|
{
|
|
string[] phrases = LogReleasePresentationController.ParseActorPhrases(
|
|
" 没问题 | | 冇问题|帽问题 ");
|
|
|
|
Assert.That(phrases, Is.EqualTo(new[] { "没问题", "冇问题", "帽问题" }));
|
|
}
|
|
|
|
[Test]
|
|
public void ActorFlash_OutsideMemoryState_CompletesImmediatelyWithoutStateChange()
|
|
{
|
|
GameObject host = new GameObject("PresentationHost");
|
|
try
|
|
{
|
|
var controller = host.AddComponent<LogReleasePresentationController>();
|
|
IEnumerator routine = controller.FlashActorLie("没问题", 0.6f);
|
|
|
|
Assert.That(routine.MoveNext(), Is.False);
|
|
Assert.That(
|
|
controller.State,
|
|
Is.EqualTo(LogReleasePresentationController.PresentationState.Idle));
|
|
}
|
|
finally
|
|
{
|
|
UnityEngine.Object.DestroyImmediate(host);
|
|
}
|
|
}
|
|
}
|
|
}
|