Files
RobustToolbox/Robust.UnitTesting/Shared/Toolshed/ToolshedTest.cs
Moony 909fd326a0 Toolshed part 2 (#4256)
* Save work.

* three billion tweaks

* Rune-aware parser.

* a

* all shedded out for the night

* a

* oogh

* Publicizes a lot of common generic commands, so custom toolshed envs can include them.

* Implement parsing for all number types.

* i think i might implode

* a

* Tests.

* a

* Enum parser test.

* do u like parsers

* oopls

* ug fixes

* Toolshed is approaching a non-insignificant part of the engine's size.

* Pool toolshed's tests, also type tests.

* bwa

* tests pass :yay:

* Update Robust.Shared/CVars.cs

Co-authored-by: DrSmugleaf <DrSmugleaf@users.noreply.github.com>

* how did this not fail tests

* awa

* many levels of silly

---------

Co-authored-by: moonheart08 <moonheart08@users.noreply.github.com>
Co-authored-by: DrSmugleaf <DrSmugleaf@users.noreply.github.com>
2023-08-23 16:03:34 -05:00

178 lines
4.5 KiB
C#

using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using NUnit.Framework;
using Robust.Server;
using Robust.Server.Player;
using Robust.Shared.Players;
using Robust.Shared.Toolshed;
using Robust.Shared.Toolshed.Errors;
using Robust.Shared.Toolshed.Syntax;
namespace Robust.UnitTesting.Shared.Toolshed;
[TestFixture, Parallelizable(ParallelScope.Fixtures)]
[FixtureLifeCycle(LifeCycle.SingleInstance)]
public abstract class ToolshedTest : RobustIntegrationTest, IInvocationContext
{
protected virtual bool AssertOnUnexpectedError => true;
protected ServerIntegrationInstance Server = default!;
public ToolshedManager Toolshed { get; private set; } = default!;
public ToolshedEnvironment Environment => Toolshed.DefaultEnvironment;
protected IInvocationContext? InvocationContext = null;
[TearDown]
public async Task TearDownInternal()
{
await TearDown();
}
protected virtual async Task TearDown()
{
Assert.IsEmpty(_expectedErrors);
ClearErrors();
}
[SetUp]
public virtual async Task Setup()
{
var options = new ServerIntegrationOptions()
{
Pool = true
};
Server = StartServer(options);
await Server.WaitIdleAsync();
Toolshed = Server.ResolveDependency<ToolshedManager>();
}
protected bool InvokeCommand(string command, out object? result)
{
return Toolshed.InvokeCommand(this, command, null, out result);
}
protected T InvokeCommand<T>(string command)
{
InvokeCommand(command, out var res);
Assert.That(res, Is.AssignableTo<T>());
return (T) res!;
}
protected TOut InvokeCommand<TIn, TOut>(string command, TIn input)
{
Toolshed.InvokeCommand(this, command, input, out var res);
Assert.That(res, Is.AssignableTo<TOut>());
return (TOut) res!;
}
protected ParserContext Parser(string input) => new ParserContext(input, Toolshed);
protected void AssertParseable<T>()
{
Toolshed.TryParse<T>(Parser(""), out _, out var err);
Assert.That(err, Is.Not.TypeOf<UnparseableValueError>(), $"Couldn't find a parser for {typeof(T).PrettyName()}");
}
protected void ParseCommand(string command, Type? inputType = null, Type? expectedType = null, bool once = false)
{
var parser = new ParserContext(command, Toolshed);
var success = CommandRun.TryParse(false, parser, inputType, expectedType, once, out _, out _, out var error);
if (error is not null)
ReportError(error);
if (error is null)
Assert.That(success, $"Parse failed despite no error being reported. Parsed {command}");
}
public bool CheckInvokable(CommandSpec command, out IConError? error)
{
if (InvocationContext is not null)
{
return InvocationContext.CheckInvokable(command, out error);
}
error = null;
return true;
}
protected IPlayerSession? InvocationSession { get; set; }
public ICommonSession? Session
{
get
{
if (InvocationContext is not null)
{
return InvocationContext.Session;
}
return InvocationSession;
}
}
public void WriteLine(string line)
{
return;
}
private Queue<Type> _expectedErrors = new();
private List<IConError> _errors = new();
public void ReportError(IConError err)
{
if (_expectedErrors.Count == 0)
{
if (AssertOnUnexpectedError)
{
Assert.Fail($"Got an error, {err.GetType()}, when none was expected.\n{err.Describe()}");
}
goto done;
}
var ty = _expectedErrors.Dequeue();
if (AssertOnUnexpectedError)
{
Assert.That(
err.GetType().IsAssignableTo(ty),
$"The error {err.GetType()} wasn't assignable to the expected type {ty}.\n{err.Describe()}"
);
}
done:
_errors.Add(err);
}
public IEnumerable<IConError> GetErrors()
{
return _errors;
}
public void ClearErrors()
{
_errors.Clear();
}
public Dictionary<string, object?> Variables { get; } = new();
protected void ExpectError(Type err)
{
_expectedErrors.Enqueue(err);
}
protected void ExpectError<T>()
{
_expectedErrors.Enqueue(typeof(T));
}
}