164 lines
7.1 KiB
C#
164 lines
7.1 KiB
C#
namespace Cthangover.Mods.Dialog.Tests
|
|
{
|
|
using System.Collections.Generic;
|
|
using System.Threading.Tasks;
|
|
using Cthangover.Core.Events;
|
|
using Cthangover.Core.Mods.Testing;
|
|
using Cthangover.Core.Settings;
|
|
using Cthangover.Mods.Dialog.Action.Impls;
|
|
using Cthangover.Mods.Dialog.Executable;
|
|
|
|
/// <summary>
|
|
/// <see cref="DialogBox"/> as the single owner of the dialog: a locker-less click
|
|
/// dialog keeps the box busy, a debugger hold keeps a <c>delay</c> from being
|
|
/// skipped by its timer, and choice answers advance correctly with and without a
|
|
/// target.
|
|
/// </summary>
|
|
public class DialogBoxTests
|
|
{
|
|
[ModTest("box/click_dialog_blocks_event_dialog", TimeoutSeconds = 10)]
|
|
static async Task ClickDialogBlocksEventDialog(ModTestContext ctx)
|
|
{
|
|
var stage = await DialogStage.Create();
|
|
try
|
|
{
|
|
var click = new ProbeAction();
|
|
var dlg = new DialogQueue();
|
|
dlg.Queue.Add(click);
|
|
ModAssert.True(stage.Box.SetDialogQueueAndRun(dlg, null, 0, null), "click dialog starts");
|
|
ModAssert.True(stage.Box.IsRunning, "a locker-less dialog occupies the box");
|
|
|
|
var evt = new ScenarioEvent { ScenarioText = "text \"event\"", ScenarioId = "dialog_base_test_one_run", IsOneRun = true };
|
|
stage.Host.AddChild(evt);
|
|
ModAssert.False(evt.RunDialog(), "event dialog is refused while the click dialog runs");
|
|
await DialogStage.Frames(3);
|
|
|
|
ModAssert.Null(stage.Box.Locker, "the click dialog keeps no locker");
|
|
ModAssert.True(stage.Box.Visible, "box stays visible");
|
|
ModAssert.True(stage.Box.Runtime.CurrentAction == click, "click dialog still waits on its action");
|
|
ModAssert.True(evt.IsFirstRun, "refused event is not counted as run");
|
|
var completed = GameData.Instance?.Runtime?.CompletedScenarioIds;
|
|
ModAssert.False(completed != null && completed.Contains("dialog_base_test_one_run"), "refused one-run scenario is not marked completed");
|
|
|
|
var other = new DialogQueue();
|
|
other.Queue.Add(new ProbeAction());
|
|
ModAssert.False(stage.Box.SetDialogQueueAndRun(other, null, 0, null), "a second click dialog is refused too");
|
|
}
|
|
finally
|
|
{
|
|
stage.Free();
|
|
}
|
|
}
|
|
|
|
[ModTest("box/scene_exit_ends_running_dialog", TimeoutSeconds = 10)]
|
|
static async Task SceneExitEndsRunningDialog(ModTestContext ctx)
|
|
{
|
|
var stage = await DialogStage.Create();
|
|
try
|
|
{
|
|
var running = new DialogQueue();
|
|
running.Queue.Add(new ProbeAction());
|
|
ModAssert.True(stage.Box.SetDialogQueueAndRun(running, null, 0, null), "a dialog starts");
|
|
ModAssert.True(stage.Box.IsRunning, "the dialog occupies the box");
|
|
|
|
ModEventBus.Publish(new SceneExitedEvent { SceneName = "dialog_base_test_scene" });
|
|
ModAssert.False(stage.Box.IsRunning, "leaving the scene releases the box");
|
|
|
|
var next = new DialogQueue();
|
|
next.Queue.Add(new ProbeAction());
|
|
ModAssert.True(stage.Box.SetDialogQueueAndRun(next, null, 0, null), "the next scene's dialog starts on the freed box");
|
|
}
|
|
finally
|
|
{
|
|
stage.Free();
|
|
}
|
|
}
|
|
|
|
[ModTest("box/held_delay_is_not_skipped", TimeoutSeconds = 10)]
|
|
static async Task HeldDelayIsNotSkipped(ModTestContext ctx)
|
|
{
|
|
var stage = await DialogStage.Create();
|
|
var previous = DialogRuntime.Debugger;
|
|
try
|
|
{
|
|
var delay = new ActionDelay { WaitTime = 0.05f };
|
|
var after = new ProbeAction();
|
|
var dlg = new DialogQueue();
|
|
dlg.Queue.Add(delay);
|
|
dlg.Queue.Add(after);
|
|
DialogRuntime.Debugger = new HoldDebugger { Target = delay };
|
|
|
|
stage.Box.SetDialogQueueAndRun(dlg, null, 0, null);
|
|
ModAssert.True(stage.Box.Runtime.IsHeld, "runtime is held before the delay");
|
|
await DialogStage.Seconds(0.3);
|
|
|
|
ModAssert.True(stage.Box.Runtime.IsHeld, "hold survives the delay's duration");
|
|
ModAssert.True(stage.Box.Runtime.CurrentAction == delay, "held delay stays current");
|
|
ModAssert.Equal(0, after.Runs, "action after the held delay has not run");
|
|
|
|
DialogRuntime.Debugger = null;
|
|
stage.Box.Resume();
|
|
await DialogStage.Seconds(0.3);
|
|
|
|
ModAssert.Equal(1, after.Runs, "after resume the delay elapses and the dialog goes on");
|
|
ModAssert.True(stage.Box.Runtime.CurrentAction == after, "runtime waits on the action after the delay");
|
|
}
|
|
finally
|
|
{
|
|
DialogRuntime.Debugger = previous;
|
|
stage.Free();
|
|
}
|
|
}
|
|
|
|
[ModTest("box/option_without_target_falls_through", TimeoutSeconds = 10)]
|
|
static async Task OptionWithoutTargetFallsThrough(ModTestContext ctx)
|
|
{
|
|
var stage = await DialogStage.Create();
|
|
try
|
|
{
|
|
var after = new ProbeAction();
|
|
var dlg = new DialogQueue();
|
|
dlg.Select(new List<SelectVariant> { SelectVariant.New("go on", null) }, "choose");
|
|
dlg.Queue.Add(after);
|
|
|
|
stage.Box.SetDialogQueueAndRun(dlg, null, 0, null);
|
|
ModAssert.True(stage.Box.IsWaitingAnswer, "choice is shown");
|
|
ModAssert.True(stage.Box.TrySelectVariant(0), "variant is picked");
|
|
|
|
ModAssert.False(stage.Box.IsWaitingAnswer, "the same choice is not shown again");
|
|
ModAssert.Equal(1, after.Runs, "action after the choice runs");
|
|
ModAssert.True(stage.Box.Runtime.CurrentAction == after, "runtime waits on the action after the choice");
|
|
}
|
|
finally
|
|
{
|
|
stage.Free();
|
|
}
|
|
}
|
|
|
|
[ModTest("box/option_to_missing_label_ends_once", TimeoutSeconds = 10)]
|
|
static async Task OptionToMissingLabelEndsOnce(ModTestContext ctx)
|
|
{
|
|
var stage = await DialogStage.Create();
|
|
var recorder = new DialogEndRecorder();
|
|
recorder.Start();
|
|
try
|
|
{
|
|
var dlg = new DialogQueue();
|
|
dlg.Select(new List<SelectVariant> { SelectVariant.New("broken", "no_such_label") }, "choose");
|
|
dlg.Queue.Add(new ProbeAction());
|
|
|
|
stage.Box.SetDialogQueueAndRun(dlg, null, 0, null);
|
|
stage.Box.TrySelectVariant(0);
|
|
|
|
ModAssert.Equal(1, recorder.LockerIds.Count, "DialogEndedEvent count after an option to a missing label");
|
|
ModAssert.False(stage.Box.IsRunning, "box is free");
|
|
}
|
|
finally
|
|
{
|
|
recorder.Stop();
|
|
stage.Free();
|
|
}
|
|
}
|
|
}
|
|
}
|