Fix content.integration tests warnings (#17817)

Co-authored-by: metalgearsloth <31366439+metalgearsloth@users.noreply.github.com>
This commit is contained in:
TemporalOroboros
2023-07-05 21:54:25 -07:00
committed by GitHub
parent 20c1754abd
commit ba91023a85
121 changed files with 3658 additions and 1961 deletions

View File

@@ -24,4 +24,5 @@
<ProjectReference Include="..\RobustToolbox\Robust.UnitTesting\Robust.UnitTesting.csproj" />
</ItemGroup>
<Import Project="..\RobustToolbox\MSBuild\Robust.Properties.targets" />
<Import Project="..\RobustToolbox\MSBuild\Robust.CompNetworkGenerator.targets" />
</Project>

View File

@@ -1,5 +1,3 @@
using System;
using System.Threading.Tasks;
using Content.Client.Parallax.Managers;
using Content.Client.Parallax;
using Robust.Shared.Maths;

View File

@@ -0,0 +1,5 @@
// Global usings for Content.IntegrationTests
global using NUnit.Framework;
global using System;
global using System.Threading.Tasks;

View File

@@ -1,10 +1,8 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Content.Client.IoC;
using Content.Client.Parallax.Managers;
using Content.IntegrationTests.Tests;
@@ -14,8 +12,6 @@ using Content.IntegrationTests.Tests.Interaction.Click;
using Content.IntegrationTests.Tests.Networking;
using Content.Server.GameTicking;
using Content.Shared.CCVar;
using Microsoft.Diagnostics.Tracing.Parsers.Kernel;
using NUnit.Framework;
using Robust.Client;
using Robust.Server;
using Robust.Shared;
@@ -61,13 +57,13 @@ public static class PoolManager
// @formatter:on
};
private static int PairId;
private static object PairLock = new();
private static int _pairId;
private static readonly object PairLock = new();
// Pair, IsBorrowed
private static Dictionary<Pair, bool> Pairs = new();
private static bool Dead;
private static Exception PoolFailureReason;
private static readonly Dictionary<Pair, bool> Pairs = new();
private static bool _dead;
private static Exception _poolFailureReason;
private static async Task ConfigurePrototypes(RobustIntegrationTest.IntegrationInstance instance,
PoolSettings settings)
@@ -108,18 +104,21 @@ public static class PoolManager
options.BeforeStart += () =>
{
IoCManager.Resolve<IEntitySystemManager>()
.LoadExtraSystemType<SimplePredictReconcileTest.PredictionTestEntitySystem>();
IoCManager.Resolve<IComponentFactory>().RegisterClass<SimplePredictReconcileTest.PredictionTestComponent>();
var entSysMan = IoCManager.Resolve<IEntitySystemManager>();
var compFactory = IoCManager.Resolve<IComponentFactory>();
entSysMan.LoadExtraSystemType<AutoPredictReconcileTest.AutoPredictionTestEntitySystem>();
compFactory.RegisterClass<AutoPredictionTestComponent>();
entSysMan.LoadExtraSystemType<SimplePredictReconcileTest.PredictionTestEntitySystem>();
compFactory.RegisterClass<SimplePredictReconcileTest.PredictionTestComponent>();
entSysMan.LoadExtraSystemType<SystemPredictReconcileTest.SystemPredictionTestEntitySystem>();
compFactory.RegisterClass<SystemPredictReconcileTest.SystemPredictionTestComponent>();
IoCManager.Register<ResettingEntitySystemTests.TestRoundRestartCleanupEvent>();
IoCManager.Register<InteractionSystemTests.TestInteractionSystem>();
IoCManager.Register<DeviceNetworkTestSystem>();
IoCManager.Resolve<IEntitySystemManager>()
.LoadExtraSystemType<ResettingEntitySystemTests.TestRoundRestartCleanupEvent>();
IoCManager.Resolve<IEntitySystemManager>()
.LoadExtraSystemType<InteractionSystemTests.TestInteractionSystem>();
IoCManager.Resolve<IEntitySystemManager>().LoadExtraSystemType<DeviceNetworkTestSystem>();
IoCManager.Resolve<IEntitySystemManager>().LoadExtraSystemType<TestDestructibleListenerSystem>();
entSysMan.LoadExtraSystemType<ResettingEntitySystemTests.TestRoundRestartCleanupEvent>();
entSysMan.LoadExtraSystemType<InteractionSystemTests.TestInteractionSystem>();
entSysMan.LoadExtraSystemType<DeviceNetworkTestSystem>();
entSysMan.LoadExtraSystemType<TestDestructibleListenerSystem>();
IoCManager.Resolve<ILogManager>().GetSawmill("loc").Level = LogLevel.Error;
IoCManager.Resolve<IConfigurationManager>()
.OnValueChanged(RTCVars.FailureLogLevel, value => logHandler.FailureLevel = value, true);
@@ -141,9 +140,9 @@ public static class PoolManager
List<Pair> localPairs;
lock (PairLock)
{
if(Dead)
if (_dead)
return;
Dead = true;
_dead = true;
localPairs = Pairs.Keys.ToList();
}
@@ -163,7 +162,7 @@ public static class PoolManager
{
var borrowed = Pairs[pair];
builder.AppendLine($"Pair {pair.PairId}, Tests Run: {pair.TestHistory.Count}, Borrowed: {borrowed}");
for (int i = 0; i < pair.TestHistory.Count; i++)
for (var i = 0; i < pair.TestHistory.Count; i++)
{
builder.AppendLine($"#{i}: {pair.TestHistory[i]}");
}
@@ -211,10 +210,14 @@ public static class PoolManager
{
ClientBeforeIoC = () =>
{
IoCManager.Resolve<IEntitySystemManager>()
.LoadExtraSystemType<SimplePredictReconcileTest.PredictionTestEntitySystem>();
IoCManager.Resolve<IComponentFactory>()
.RegisterClass<SimplePredictReconcileTest.PredictionTestComponent>();
var entSysMan = IoCManager.Resolve<IEntitySystemManager>();
var compFactory = IoCManager.Resolve<IComponentFactory>();
entSysMan.LoadExtraSystemType<AutoPredictReconcileTest.AutoPredictionTestEntitySystem>();
compFactory.RegisterClass<AutoPredictionTestComponent>();
entSysMan.LoadExtraSystemType<SimplePredictReconcileTest.PredictionTestEntitySystem>();
compFactory.RegisterClass<SimplePredictReconcileTest.PredictionTestComponent>();
entSysMan.LoadExtraSystemType<SystemPredictReconcileTest.SystemPredictionTestEntitySystem>();
compFactory.RegisterClass<SystemPredictReconcileTest.SystemPredictionTestComponent>();
IoCManager.Register<IParallaxManager, DummyParallaxManager>(true);
IoCManager.Resolve<ILogManager>().GetSawmill("loc").Level = LogLevel.Error;
IoCManager.Resolve<IConfigurationManager>()
@@ -232,9 +235,9 @@ public static class PoolManager
private static void SetupCVars(PoolSettings poolSettings, RobustIntegrationTest.IntegrationOptions options)
{
foreach (var serverTestCvar in ServerTestCvars)
foreach (var (cvar, value) in ServerTestCvars)
{
options.CVarOverrides[serverTestCvar.cvar] = serverTestCvar.value;
options.CVarOverrides[cvar] = value;
}
if (poolSettings.DummyTicker)
@@ -266,8 +269,10 @@ public static class PoolManager
/// </summary>
/// <param name="poolSettings">See <see cref="PoolSettings"/></param>
/// <returns></returns>
public static async Task<PairTracker> GetServerClient(PoolSettings poolSettings = null) =>
await GetServerClientPair(poolSettings ?? new PoolSettings());
public static async Task<PairTracker> GetServerClient(PoolSettings poolSettings = null)
{
return await GetServerClientPair(poolSettings ?? new PoolSettings());
}
private static string GetDefaultTestName(TestContext testContext)
{
@@ -328,7 +333,7 @@ public static class PoolManager
if (pair != null && pair.TestHistory.Count > 1)
{
await testOut.WriteLineAsync($"{nameof(GetServerClientPair)}: Pair {pair.PairId} Test History Start");
for (int i = 0; i < pair.TestHistory.Count; i++)
for (var i = 0; i < pair.TestHistory.Count; i++)
{
await testOut.WriteLineAsync($"- Pair {pair.PairId} Test #{i}: {pair.TestHistory[i]}");
}
@@ -403,6 +408,8 @@ public static class PoolManager
methodWatch.Start();
await testOut.WriteLineAsync($"Recycling: {methodWatch.Elapsed.TotalMilliseconds} ms: Setting CVar ");
var configManager = pair.Server.ResolveDependency<IConfigurationManager>();
var entityManager = pair.Server.ResolveDependency<IEntityManager>();
var gameTicker = entityManager.System<GameTicker>();
await pair.Server.WaitPost(() =>
{
configManager.SetCVar(CCVars.GameLobbyEnabled, poolSettings.InLobby);
@@ -414,14 +421,14 @@ public static class PoolManager
pair.Client.SetConnectTarget(pair.Server);
await pair.Server.WaitPost(() =>
{
EntitySystem.Get<GameTicker>().RestartRound();
gameTicker.RestartRound();
});
await pair.Client.WaitPost(() =>
{
cNetMgr.ClientConnect(null!, 0, null!);
});
}
await ReallyBeIdle(pair,11);
await ReallyBeIdle(pair, 11);
await testOut.WriteLineAsync($"Recycling: {methodWatch.Elapsed.TotalMilliseconds} ms: Disconnecting client, and restarting server");
@@ -443,7 +450,7 @@ public static class PoolManager
serverProtoManager.RemoveString(pair.Settings.ExtraPrototypes.Trim());
});
}
if(!pair.Settings.NoClient)
if (!pair.Settings.NoClient)
{
var clientProtoManager = pair.Client.ResolveDependency<IPrototypeManager>();
await pair.Client.WaitPost(() =>
@@ -471,7 +478,7 @@ public static class PoolManager
await testOut.WriteLineAsync($"Recycling: {methodWatch.Elapsed.TotalMilliseconds} ms: Restarting server again");
await pair.Server.WaitPost(() =>
{
EntitySystem.Get<GameTicker>().RestartRound();
gameTicker.RestartRound();
});
@@ -495,17 +502,17 @@ public static class PoolManager
private static void DieIfPoolFailure()
{
if (PoolFailureReason != null)
if (_poolFailureReason != null)
{
// If the PoolFailureReason is not null, we can assume at least one test failed.
// If the _poolFailureReason is not null, we can assume at least one test failed.
// So we say inconclusive so we don't add more failed tests to search through.
Assert.Inconclusive(@"
In a different test, the pool manager had an exception when trying to create a server/client pair.
Instead of risking that the pool manager will fail at creating a server/client pairs for every single test,
we are just going to end this here to save a lot of time. This is the exception that started this:\n {0}", PoolFailureReason);
we are just going to end this here to save a lot of time. This is the exception that started this:\n {0}", _poolFailureReason);
}
if (Dead)
if (_dead)
{
// If Pairs is null, we ran out of time, we can't assume a test failed.
// So we are going to tell it all future tests are a failure.
@@ -525,12 +532,12 @@ we are just going to end this here to save a lot of time. This is the exception
ServerLogHandler = serverLog,
Client = client,
ClientLogHandler = clientLog,
PairId = Interlocked.Increment(ref PairId)
PairId = Interlocked.Increment(ref _pairId)
};
}
catch (Exception ex)
{
PoolFailureReason = ex;
_poolFailureReason = ex;
throw;
}
@@ -565,6 +572,8 @@ we are just going to end this here to save a lot of time. This is the exception
var settings = pairTracker.Pair.Settings;
var mapManager = server.ResolveDependency<IMapManager>();
var tileDefinitionManager = server.ResolveDependency<ITileDefinitionManager>();
var entityManager = server.ResolveDependency<IEntityManager>();
var xformSystem = entityManager.System<SharedTransformSystem>();
if (settings.NoServer) throw new Exception("Cannot setup test map without server");
var mapData = new TestMapData();
@@ -573,7 +582,7 @@ we are just going to end this here to save a lot of time. This is the exception
mapData.MapId = mapManager.CreateMap();
mapData.MapUid = mapManager.GetMapEntityId(mapData.MapId);
mapData.MapGrid = mapManager.CreateGrid(mapData.MapId);
mapData.GridUid = mapData.MapGrid.Owner;
mapData.GridUid = mapData.MapGrid.Owner; // Fixing this requires an engine PR.
mapData.GridCoords = new EntityCoordinates(mapData.GridUid, 0, 0);
var plating = tileDefinitionManager["Plating"];
var platingTile = new Tile(plating.TileId);
@@ -610,11 +619,11 @@ we are just going to end this here to save a lot of time. This is the exception
/// <param name="runTicks">How many ticks to run</param>
public static async Task ReallyBeIdle(Pair pair, int runTicks = 25)
{
for (int i = 0; i < runTicks; i++)
for (var i = 0; i < runTicks; i++)
{
await pair.Client.WaitRunTicks(1);
await pair.Server.WaitRunTicks(1);
for (int idleCycles = 0; idleCycles < 4; idleCycles++)
for (var idleCycles = 0; idleCycles < 4; idleCycles++)
{
await pair.Client.WaitIdleAsync();
await pair.Server.WaitIdleAsync();
@@ -809,7 +818,9 @@ public sealed class PoolSettings
// Prototype hot reload is not available outside TOOLS builds,
// so we can't pool test instances that use ExtraPrototypes without TOOLS.
#if TOOLS
#pragma warning disable CA1822 // Can't be marked as static b/c the other branch exists but Omnisharp can't see both.
private bool NoToolsExtraPrototypes => false;
#pragma warning restore CA1822
#else
private bool NoToolsExtraPrototypes => !string.IsNullOrEmpty(ExtraPrototypes);
#endif

View File

@@ -1,7 +1,4 @@
using System;
using System.Threading.Tasks;
using NUnit.Framework;

[assembly: Parallelizable(ParallelScope.Children)]
namespace Content.IntegrationTests;

View File

@@ -1,6 +1,4 @@
using System;
using System.IO;
using NUnit.Framework;
using System.IO;
using Robust.Shared.Log;
using Robust.Shared.Timing;
using Serilog.Events;

View File

@@ -1,8 +1,6 @@
using System.Collections.Generic;
using System.Threading.Tasks;
using Content.Shared.Access.Components;
using Content.Shared.Access.Systems;
using NUnit.Framework;
using Robust.Shared.GameObjects;
namespace Content.IntegrationTests.Tests.Access
@@ -14,63 +12,82 @@ namespace Content.IntegrationTests.Tests.Access
[Test]
public async Task TestTags()
{
await using var pairTracker = await PoolManager.GetServerClient(new PoolSettings{NoClient = true});
await using var pairTracker = await PoolManager.GetServerClient(new PoolSettings { NoClient = true });
var server = pairTracker.Pair.Server;
var entityManager = server.ResolveDependency<IEntityManager>();
await server.WaitAssertion(() =>
{
var system = EntitySystem.Get<AccessReaderSystem>();
var system = entityManager.System<AccessReaderSystem>();
// test empty
var reader = new AccessReaderComponent();
Assert.Multiple(() =>
{
Assert.That(system.AreAccessTagsAllowed(new[] { "Foo" }, reader), Is.True);
Assert.That(system.AreAccessTagsAllowed(new[] { "Bar" }, reader), Is.True);
Assert.That(system.AreAccessTagsAllowed(new string[] { }, reader), Is.True);
Assert.That(system.AreAccessTagsAllowed(Array.Empty<string>(), reader), Is.True);
});
// test deny
reader = new AccessReaderComponent();
reader.DenyTags.Add("A");
Assert.Multiple(() =>
{
Assert.That(system.AreAccessTagsAllowed(new[] { "Foo" }, reader), Is.True);
Assert.That(system.AreAccessTagsAllowed(new[] { "A" }, reader), Is.False);
Assert.That(system.AreAccessTagsAllowed(new[] { "A", "Foo" }, reader), Is.False);
Assert.That(system.AreAccessTagsAllowed(new string[] { }, reader), Is.True);
Assert.That(system.AreAccessTagsAllowed(Array.Empty<string>(), reader), Is.True);
});
// test one list
reader = new AccessReaderComponent();
reader.AccessLists.Add(new HashSet<string> { "A" });
Assert.Multiple(() =>
{
Assert.That(system.AreAccessTagsAllowed(new[] { "A" }, reader), Is.True);
Assert.That(system.AreAccessTagsAllowed(new[] { "B" }, reader), Is.False);
Assert.That(system.AreAccessTagsAllowed(new[] { "A", "B" }, reader), Is.True);
Assert.That(system.AreAccessTagsAllowed(new string[] { }, reader), Is.False);
Assert.That(system.AreAccessTagsAllowed(Array.Empty<string>(), reader), Is.False);
});
// test one list - two items
reader = new AccessReaderComponent();
reader.AccessLists.Add(new HashSet<string> { "A", "B" });
Assert.Multiple(() =>
{
Assert.That(system.AreAccessTagsAllowed(new[] { "A" }, reader), Is.False);
Assert.That(system.AreAccessTagsAllowed(new[] { "B" }, reader), Is.False);
Assert.That(system.AreAccessTagsAllowed(new[] { "A", "B" }, reader), Is.True);
Assert.That(system.AreAccessTagsAllowed(new string[] { }, reader), Is.False);
Assert.That(system.AreAccessTagsAllowed(Array.Empty<string>(), reader), Is.False);
});
// test two list
reader = new AccessReaderComponent();
reader.AccessLists.Add(new HashSet<string> { "A" });
reader.AccessLists.Add(new HashSet<string> { "B", "C" });
Assert.Multiple(() =>
{
Assert.That(system.AreAccessTagsAllowed(new[] { "A" }, reader), Is.True);
Assert.That(system.AreAccessTagsAllowed(new[] { "B" }, reader), Is.False);
Assert.That(system.AreAccessTagsAllowed(new[] { "A", "B" }, reader), Is.True);
Assert.That(system.AreAccessTagsAllowed(new[] { "C", "B" }, reader), Is.True);
Assert.That(system.AreAccessTagsAllowed(new[] { "C", "B", "A" }, reader), Is.True);
Assert.That(system.AreAccessTagsAllowed(new string[] { }, reader), Is.False);
Assert.That(system.AreAccessTagsAllowed(Array.Empty<string>(), reader), Is.False);
});
// test deny list
reader = new AccessReaderComponent();
reader.AccessLists.Add(new HashSet<string> { "A" });
reader.DenyTags.Add("B");
Assert.Multiple(() =>
{
Assert.That(system.AreAccessTagsAllowed(new[] { "A" }, reader), Is.True);
Assert.That(system.AreAccessTagsAllowed(new[] { "B" }, reader), Is.False);
Assert.That(system.AreAccessTagsAllowed(new[] { "A", "B" }, reader), Is.False);
Assert.That(system.AreAccessTagsAllowed(new string[] { }, reader), Is.False);
Assert.That(system.AreAccessTagsAllowed(Array.Empty<string>(), reader), Is.False);
});
});
await pairTracker.CleanReturnAsync();
}

View File

@@ -1,7 +1,5 @@
using System;
using System.Collections.Generic;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Content.Server.Administration.Logs;
using Content.Server.Database;
using Content.Server.GameTicking;
@@ -9,7 +7,6 @@ using Content.Server.GameTicking.Commands;
using Content.Shared.Administration.Logs;
using Content.Shared.CCVar;
using Content.Shared.Database;
using NUnit.Framework;
using Robust.Server.Player;
using Robust.Shared.Configuration;
using Robust.Shared.GameObjects;
@@ -24,7 +21,7 @@ public sealed class AddTests
[Test]
public async Task AddAndGetSingleLog()
{
await using var pairTracker = await PoolManager.GetServerClient(new PoolSettings{NoClient = true});
await using var pairTracker = await PoolManager.GetServerClient(new PoolSettings { NoClient = true });
var server = pairTracker.Pair.Server;
var sEntities = server.ResolveDependency<IEntityManager>();
@@ -71,7 +68,7 @@ public sealed class AddTests
[Test]
public async Task AddAndGetUnformattedLog()
{
await using var pairTracker = await PoolManager.GetServerClient(new PoolSettings{NoClient = true});
await using var pairTracker = await PoolManager.GetServerClient(new PoolSettings { NoClient = true });
var server = pairTracker.Pair.Server;
var sDatabase = server.ResolveDependency<IServerDbManager>();
@@ -115,15 +112,18 @@ public sealed class AddTests
{
Round = sGamerTicker.RoundId,
Search = log.Message,
Types = new HashSet<LogType> {log.Type},
Types = new HashSet<LogType> { log.Type },
};
await foreach (var json in sDatabase.GetAdminLogsJson(filter))
{
var root = json.RootElement;
Assert.Multiple(() =>
{
Assert.That(root.TryGetProperty("entity", out _), Is.True);
Assert.That(root.TryGetProperty("guid", out _), Is.True);
});
json.Dispose();
}
@@ -135,7 +135,7 @@ public sealed class AddTests
[TestCase(500)]
public async Task BulkAddLogs(int amount)
{
await using var pairTracker = await PoolManager.GetServerClient(new PoolSettings{NoClient = true});
await using var pairTracker = await PoolManager.GetServerClient(new PoolSettings { NoClient = true });
var server = pairTracker.Pair.Server;
var sEntities = server.ResolveDependency<IEntityManager>();
@@ -204,7 +204,7 @@ public sealed class AddTests
[Test]
public async Task PreRoundAddAndGetSingle()
{
await using var pairTracker = await PoolManager.GetServerClient(new PoolSettings{Dirty = true});
await using var pairTracker = await PoolManager.GetServerClient(new PoolSettings { Dirty = true });
var server = pairTracker.Pair.Server;
var configManager = server.ResolveDependency<IConfigurationManager>();
@@ -255,7 +255,7 @@ public sealed class AddTests
{
Round = sGamerTicker.RoundId,
Search = log.Message,
Types = new HashSet<LogType> {log.Type},
Types = new HashSet<LogType> { log.Type },
};
await foreach (var json in sDatabase.GetAdminLogsJson(filter))

View File

@@ -1,12 +1,7 @@
using System;
using System.Threading.Tasks;
using Content.Server.Administration.Logs;
using Content.Shared.Administration.Logs;
using Content.Shared.CCVar;
using Content.Shared.Database;
using NUnit.Framework;
using Robust.Shared.GameObjects;
using Robust.Shared.Map;
namespace Content.IntegrationTests.Tests.Administration.Logs;
@@ -19,7 +14,7 @@ public sealed class FilterTests
[TestCase(DateOrder.Descending)]
public async Task Date(DateOrder order)
{
await using var pairTracker = await PoolManager.GetServerClient(new PoolSettings{NoClient = true});
await using var pairTracker = await PoolManager.GetServerClient(new PoolSettings { NoClient = true });
var server = pairTracker.Pair.Server;
var sEntities = server.ResolveDependency<IEntityManager>();

View File

@@ -1,12 +1,8 @@
using System;
using System.Collections.Generic;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Content.Server.Administration.Logs;
using Content.Server.GameTicking;
using Content.Shared.CCVar;
using Content.Shared.Database;
using NUnit.Framework;
using Robust.Server.Player;
using Robust.Shared.GameObjects;
@@ -44,9 +40,9 @@ public sealed class QueryTests
{
Round = sGamerTicker.RoundId,
Search = guid.ToString(),
Types = new HashSet<LogType> {LogType.Unknown},
Types = new HashSet<LogType> { LogType.Unknown },
After = date,
AnyPlayers = new[] {player.UserId.UserId}
AnyPlayers = new[] { player.UserId.UserId }
};
await PoolManager.WaitUntil(server, async () =>

View File

@@ -1,6 +1,4 @@
using System.Threading.Tasks;
using Content.Shared.Atmos.Monitor;
using NUnit.Framework;
using Robust.Shared.Prototypes;
namespace Content.IntegrationTests.Tests.Atmos
@@ -25,7 +23,7 @@ namespace Content.IntegrationTests.Tests.Atmos
[Test]
public async Task TestAlarmThreshold()
{
await using var pairTracker = await PoolManager.GetServerClient(new PoolSettings{NoClient = true, ExtraPrototypes = Prototypes});
await using var pairTracker = await PoolManager.GetServerClient(new PoolSettings { NoClient = true, ExtraPrototypes = Prototypes });
var server = pairTracker.Pair.Server;
var prototypeManager = server.ResolveDependency<IPrototypeManager>();
@@ -39,8 +37,11 @@ namespace Content.IntegrationTests.Tests.Atmos
await server.WaitAssertion(() =>
{
// ensure upper/lower bounds are calculated
Assert.Multiple(() =>
{
Assert.That(threshold.UpperWarningBound.Value, Is.EqualTo(5f * 0.5f));
Assert.That(threshold.LowerWarningBound.Value, Is.EqualTo(1f * 1.5f));
});
// ensure that setting bounds to zero/
// negative numbers is an invalid set
@@ -102,7 +103,7 @@ namespace Content.IntegrationTests.Tests.Atmos
threshold.SetEnabled(AtmosMonitorLimitType.LowerWarning, true);
// Check a value that's in between each upper/lower warning/panic:
threshold.CheckThreshold(3f, out AtmosAlarmType alarmType);
threshold.CheckThreshold(3f, out var alarmType);
Assert.That(alarmType, Is.EqualTo(AtmosAlarmType.Normal));
threshold.CheckThreshold(1.5f, out alarmType);
Assert.That(alarmType, Is.EqualTo(AtmosAlarmType.Warning));

View File

@@ -1,9 +1,6 @@
using System;
using System.Linq;
using System.Threading.Tasks;
using System.Linq;
using Content.Server.Atmos.EntitySystems;
using Content.Shared.Atmos;
using NUnit.Framework;
using Robust.Shared.GameObjects;
namespace Content.IntegrationTests.Tests.Atmos
@@ -15,16 +12,19 @@ namespace Content.IntegrationTests.Tests.Atmos
[Test]
public async Task TotalGasesTest()
{
await using var pairTracker = await PoolManager.GetServerClient(new PoolSettings{NoClient = true});
await using var pairTracker = await PoolManager.GetServerClient(new PoolSettings { NoClient = true });
var server = pairTracker.Pair.Server;
var entityManager = server.ResolveDependency<IEntityManager>();
await server.WaitPost(() =>
{
var atmosSystem = EntitySystem.Get<AtmosphereSystem>();
var atmosSystem = entityManager.System<AtmosphereSystem>();
Assert.Multiple(() =>
{
Assert.That(atmosSystem.Gases.Count(), Is.EqualTo(Atmospherics.TotalNumberOfGases));
Assert.That(Enum.GetValues(typeof(Gas)).Length, Is.EqualTo(Atmospherics.TotalNumberOfGases));
Assert.That(Enum.GetValues(typeof(Gas)), Has.Length.EqualTo(Atmospherics.TotalNumberOfGases));
});
});
await pairTracker.CleanReturnAsync();
}

View File

@@ -1,8 +1,6 @@
using System.Threading.Tasks;
using Content.Server.Atmos;
using Content.Server.Atmos;
using Content.Server.Atmos.EntitySystems;
using Content.Shared.Atmos;
using NUnit.Framework;
using Robust.Shared.GameObjects;
namespace Content.IntegrationTests.Tests.Atmos
@@ -14,7 +12,7 @@ namespace Content.IntegrationTests.Tests.Atmos
[Test]
public async Task TestMerge()
{
await using var pairTracker = await PoolManager.GetServerClient(new PoolSettings{NoClient = true});
await using var pairTracker = await PoolManager.GetServerClient(new PoolSettings { NoClient = true });
var server = pairTracker.Pair.Server;
var atmosphereSystem = server.ResolveDependency<IEntitySystemManager>().GetEntitySystem<AtmosphereSystem>();
@@ -28,24 +26,36 @@ namespace Content.IntegrationTests.Tests.Atmos
b.AdjustMoles(Gas.Nitrogen, 50);
// a now has 50 moles of oxygen
Assert.Multiple(() =>
{
Assert.That(a.TotalMoles, Is.EqualTo(50));
Assert.That(a.GetMoles(Gas.Oxygen), Is.EqualTo(50));
});
// b now has 50 moles of nitrogen
Assert.Multiple(() =>
{
Assert.That(b.TotalMoles, Is.EqualTo(50));
Assert.That(b.GetMoles(Gas.Nitrogen), Is.EqualTo(50));
});
atmosphereSystem.Merge(b, a);
// b now has its contents and the contents of a
Assert.Multiple(() =>
{
Assert.That(b.TotalMoles, Is.EqualTo(100));
Assert.That(b.GetMoles(Gas.Oxygen), Is.EqualTo(50));
Assert.That(b.GetMoles(Gas.Nitrogen), Is.EqualTo(50));
});
// a should be the same, however.
Assert.Multiple(() =>
{
Assert.That(a.TotalMoles, Is.EqualTo(50));
Assert.That(a.GetMoles(Gas.Oxygen), Is.EqualTo(50));
});
});
await pairTracker.CleanReturnAsync();
}
@@ -59,7 +69,7 @@ namespace Content.IntegrationTests.Tests.Atmos
[TestCase(Atmospherics.BreathPercentage)]
public async Task RemoveRatio(float ratio)
{
await using var pairTracker = await PoolManager.GetServerClient(new PoolSettings{NoClient = true});
await using var pairTracker = await PoolManager.GetServerClient(new PoolSettings { NoClient = true });
var server = pairTracker.Pair.Server;
await server.WaitAssertion(() =>
@@ -75,15 +85,24 @@ namespace Content.IntegrationTests.Tests.Atmos
var b = a.RemoveRatio(ratio);
// check that the amount of moles in the original and the new mixture are correct.
Assert.Multiple(() =>
{
Assert.That(b.TotalMoles, Is.EqualTo(origTotal * ratio));
Assert.That(a.TotalMoles, Is.EqualTo(origTotal - b.TotalMoles));
});
Assert.Multiple(() =>
{
Assert.That(b.GetMoles(Gas.Oxygen), Is.EqualTo(100 * ratio));
Assert.That(b.GetMoles(Gas.Nitrogen), Is.EqualTo(100 * ratio));
});
Assert.Multiple(() =>
{
Assert.That(a.GetMoles(Gas.Oxygen), Is.EqualTo(100 - b.GetMoles(Gas.Oxygen)));
Assert.That(a.GetMoles(Gas.Nitrogen), Is.EqualTo(100 - b.GetMoles(Gas.Nitrogen)));
});
});
await pairTracker.CleanReturnAsync();
}

View File

@@ -1,11 +1,8 @@
using System.Threading.Tasks;
using Content.Server.Body.Systems;
using Content.Server.Body.Systems;
using Content.Shared.Body.Components;
using Content.Shared.Body.Part;
using Content.Shared.Rotation;
using NUnit.Framework;
using Robust.Shared.GameObjects;
using Robust.Shared.IoC;
using Robust.Shared.Map;
using Robust.Shared.Maths;
@@ -31,24 +28,34 @@ namespace Content.IntegrationTests.Tests.Body
public async Task RemoveLegsFallTest()
{
await using var pairTracker = await PoolManager.GetServerClient(new PoolSettings
{NoClient = true, ExtraPrototypes = Prototypes});
{
NoClient = true,
ExtraPrototypes = Prototypes
});
var server = pairTracker.Pair.Server;
EntityUid human = default!;
AppearanceComponent appearance = null;
var entityManager = server.ResolveDependency<IEntityManager>();
var mapManager = server.ResolveDependency<IMapManager>();
var appearanceSystem = entityManager.System<SharedAppearanceSystem>();
await server.WaitAssertion(() =>
{
var mapId = mapManager.CreateMap();
BodyComponent body = null;
var human = entityManager.SpawnEntity("HumanBodyAndAppearanceDummy",
human = entityManager.SpawnEntity("HumanBodyAndAppearanceDummy",
new MapCoordinates(Vector2.Zero, mapId));
Assert.That(entityManager.TryGetComponent(human, out BodyComponent body));
Assert.Multiple(() =>
{
Assert.That(entityManager.TryGetComponent(human, out body));
Assert.That(entityManager.TryGetComponent(human, out appearance));
});
Assert.That(!appearance.TryGetData(RotationVisuals.RotationState, out RotationState _));
Assert.That(!appearanceSystem.TryGetData(human, RotationVisuals.RotationState, out RotationState _, appearance));
var bodySystem = entityManager.System<BodySystem>();
var legs = bodySystem.GetBodyChildrenOfType(human, BodyPartType.Leg, body);
@@ -61,8 +68,11 @@ namespace Content.IntegrationTests.Tests.Body
await server.WaitAssertion(() =>
{
Assert.That(appearance.TryGetData(RotationVisuals.RotationState, out RotationState state));
#pragma warning disable NUnit2045
// Interdependent assertions.
Assert.That(appearanceSystem.TryGetData(human, RotationVisuals.RotationState, out RotationState state, appearance));
Assert.That(state, Is.EqualTo(RotationState.Horizontal));
#pragma warning restore NUnit2045
});
await pairTracker.CleanReturnAsync();
}

View File

@@ -1,16 +1,16 @@
using System.Threading.Tasks;
using Content.Server.Atmos.Components;
using Content.Server.Atmos.EntitySystems;
using Content.Server.Body.Components;
using Content.Server.Body.Systems;
using Content.Shared.Body.Components;
using NUnit.Framework;
using Robust.Server.GameObjects;
using Robust.Shared;
using Robust.Shared.Configuration;
using Robust.Shared.GameObjects;
using Robust.Shared.Map;
using Robust.Shared.Map.Components;
using Robust.Shared.Maths;
using System.Linq;
namespace Content.IntegrationTests.Tests.Body
{
@@ -52,7 +52,10 @@ namespace Content.IntegrationTests.Tests.Body
{
// --- Setup
await using var pairTracker = await PoolManager.GetServerClient(new PoolSettings
{NoClient = true, ExtraPrototypes = Prototypes});
{
NoClient = true,
ExtraPrototypes = Prototypes
});
var server = pairTracker.Pair.Server;
await server.WaitIdleAsync();
@@ -68,17 +71,22 @@ namespace Content.IntegrationTests.Tests.Body
BodyComponent body = default;
EntityUid human = default;
GridAtmosphereComponent relevantAtmos = default;
float startingMoles = 0.0f;
var startingMoles = 0.0f;
var testMapName = "Maps/Test/Breathing/3by3-20oxy-80nit.yml";
await server.WaitPost(() =>
{
mapId = mapManager.CreateMap();
grid = mapLoader.LoadGrid(mapId, testMapName);
Assert.That(mapLoader.TryLoad(mapId, testMapName, out var roots));
var query = entityManager.GetEntityQuery<MapGridComponent>();
var grids = roots.Where(x => query.HasComponent(x));
Assert.That(grids, Is.Not.Empty);
grid = grids.First();
});
Assert.NotNull(grid, $"Test blueprint {testMapName} not found.");
Assert.That(grid, Is.Not.Null, $"Test blueprint {testMapName} not found.");
float GetMapMoles()
{
@@ -96,13 +104,15 @@ namespace Content.IntegrationTests.Tests.Body
var coords = new Vector2(0.5f, -1f);
var coordinates = new EntityCoordinates(grid.Value, coords);
human = entityManager.SpawnEntity("HumanBodyDummy", coordinates);
respSys = EntitySystem.Get<RespiratorSystem>();
metaSys = EntitySystem.Get<MetabolizerSystem>();
respSys = entityManager.System<RespiratorSystem>();
metaSys = entityManager.System<MetabolizerSystem>();
relevantAtmos = entityManager.GetComponent<GridAtmosphereComponent>(grid.Value);
startingMoles = GetMapMoles();
Assert.True(entityManager.TryGetComponent(human, out body));
Assert.True(entityManager.HasComponent<RespiratorComponent>(human));
#pragma warning disable NUnit2045
Assert.That(entityManager.TryGetComponent(human, out body), Is.True);
Assert.That(entityManager.HasComponent<RespiratorComponent>(human), Is.True);
#pragma warning restore NUnit2045
});
// --- End setup
@@ -131,7 +141,10 @@ namespace Content.IntegrationTests.Tests.Body
public async Task NoSuffocationTest()
{
await using var pairTracker = await PoolManager.GetServerClient(new PoolSettings
{NoClient = true, ExtraPrototypes = Prototypes});
{
NoClient = true,
ExtraPrototypes = Prototypes
});
var server = pairTracker.Pair.Server;
var mapManager = server.ResolveDependency<IMapManager>();
@@ -149,10 +162,16 @@ namespace Content.IntegrationTests.Tests.Body
await server.WaitPost(() =>
{
mapId = mapManager.CreateMap();
grid = mapLoader.LoadGrid(mapId, testMapName);
Assert.That(mapLoader.TryLoad(mapId, testMapName, out var ents), Is.True);
var query = entityManager.GetEntityQuery<MapGridComponent>();
grid = ents
.Select<EntityUid, EntityUid?>(x => x)
.FirstOrDefault((uid) => uid.HasValue && query.HasComponent(uid.Value), null);
Assert.That(grid, Is.Not.Null);
});
Assert.NotNull(grid, $"Test blueprint {testMapName} not found.");
Assert.That(grid, Is.Not.Null, $"Test blueprint {testMapName} not found.");
await server.WaitAssertion(() =>
{
@@ -162,11 +181,12 @@ namespace Content.IntegrationTests.Tests.Body
human = entityManager.SpawnEntity("HumanBodyDummy", coordinates);
var mixture = entityManager.System<AtmosphereSystem>().GetContainingMixture(human);
#pragma warning disable NUnit2045
Assert.That(mixture.TotalMoles, Is.GreaterThan(0));
Assert.True(entityManager.HasComponent<BodyComponent>(human));
Assert.True(entityManager.TryGetComponent(human, out respirator));
Assert.False(respirator.SuffocationCycles > respirator.SuffocationCycleThreshold);
Assert.That(entityManager.HasComponent<BodyComponent>(human), Is.True);
Assert.That(entityManager.TryGetComponent(human, out respirator), Is.True);
Assert.That(respirator.SuffocationCycles, Is.LessThanOrEqualTo(respirator.SuffocationCycleThreshold));
#pragma warning restore NUnit2045
});
var increment = 10;
@@ -179,7 +199,7 @@ namespace Content.IntegrationTests.Tests.Body
await server.WaitRunTicks(increment);
await server.WaitAssertion(() =>
{
Assert.False(respirator.SuffocationCycles > respirator.SuffocationCycleThreshold,
Assert.That(respirator.SuffocationCycles, Is.LessThanOrEqualTo(respirator.SuffocationCycleThreshold),
$"Entity {entityManager.GetComponent<MetaDataComponent>(human).EntityName} is suffocating on tick {tick}");
});
}

View File

@@ -1,10 +1,8 @@
using System.Linq;
using System.Threading.Tasks;
using System.Collections.Generic;
using System.Linq;
using Content.Shared.Body.Components;
using Content.Shared.Body.Systems;
using NUnit.Framework;
using Robust.Server.GameObjects;
using Robust.Server.Maps;
using Robust.Shared.GameObjects;
using Robust.Shared.Map;
@@ -85,10 +83,22 @@ public sealed class SaveLoadReparentTest
});
}
Assert.That(entities
.EntityQuery<BodyComponent>()
.Where(e => entities.GetComponent<MetaDataComponent>(e.Owner).EntityPrototype!.Name ==
"HumanBodyDummy"), Is.Not.Empty);
// Converts an entity query enumerator to an enumerable.
static IEnumerable<(EntityUid Uid, TComp Comp)> EnumerateQueryEnumerator<TComp>(EntityQueryEnumerator<TComp> query)
where TComp : Component
{
while (query.MoveNext(out var uid, out var comp))
yield return (uid, comp);
}
Assert.That(
EnumerateQueryEnumerator(
entities.EntityQueryEnumerator<BodyComponent>()
).Where((e) =>
entities.GetComponent<MetaDataComponent>(e.Uid).EntityPrototype!.Name == "HumanBodyDummy"
),
Is.Not.Empty
);
const string mapPath = $"/{nameof(SaveLoadReparentTest)}{nameof(Test)}map.yml";
@@ -96,22 +106,26 @@ public sealed class SaveLoadReparentTest
maps.DeleteMap(mapId);
mapId = maps.CreateMap();
mapLoader.LoadMap(mapId, mapPath);
Assert.That(mapLoader.TryLoad(mapId, mapPath, out _), Is.True);
var query = entities
.EntityQuery<BodyComponent>()
.Where(e => entities.GetComponent<MetaDataComponent>(e.Owner).EntityPrototype!.Name == "HumanBodyDummy")
.ToArray();
var query = EnumerateQueryEnumerator(
entities.EntityQueryEnumerator<BodyComponent>()
).Where((e) =>
entities.GetComponent<MetaDataComponent>(e.Uid).EntityPrototype!.Name == "HumanBodyDummy"
).ToArray();
Assert.That(query, Is.Not.Empty);
foreach (var body in query)
foreach (var (uid, body) in query)
{
human = body.Owner;
human = uid;
parts = bodySystem.GetBodyChildren(human).ToArray();
organs = bodySystem.GetBodyOrgans(human).ToArray();
Assert.Multiple(() =>
{
Assert.That(parts, Is.Not.Empty);
Assert.That(organs, Is.Not.Empty);
});
foreach (var (id, component) in parts)
{

View File

@@ -1,4 +1,3 @@
using System.Threading.Tasks;
using Content.Server.Body.Systems;
using Content.Shared.Buckle;
using Content.Shared.ActionBlocker;
@@ -8,7 +7,6 @@ using Content.Shared.Buckle.Components;
using Content.Shared.Hands.Components;
using Content.Shared.Hands.EntitySystems;
using Content.Shared.Standing;
using NUnit.Framework;
using Robust.Shared.GameObjects;
namespace Content.IntegrationTests.Tests.Buckle
@@ -50,15 +48,16 @@ namespace Content.IntegrationTests.Tests.Buckle
public async Task BuckleUnbuckleCooldownRangeTest()
{
await using var pairTracker =
await PoolManager.GetServerClient(new PoolSettings {ExtraPrototypes = Prototypes});
await PoolManager.GetServerClient(new PoolSettings { ExtraPrototypes = Prototypes });
var server = pairTracker.Pair.Server;
var testMap = await PoolManager.CreateTestMap(pairTracker);
var coordinates = testMap.GridCoords;
var entityManager = server.ResolveDependency<IEntityManager>();
var actionBlocker = entityManager.EntitySysManager.GetEntitySystem<ActionBlockerSystem>();
var buckleSystem = entityManager.EntitySysManager.GetEntitySystem<SharedBuckleSystem>();
var standingState = entityManager.EntitySysManager.GetEntitySystem<StandingStateSystem>();
var actionBlocker = entityManager.System<ActionBlockerSystem>();
var buckleSystem = entityManager.System<SharedBuckleSystem>();
var standingState = entityManager.System<StandingStateSystem>();
var xformSystem = entityManager.System<SharedTransformSystem>();
EntityUid human = default;
EntityUid chair = default;
@@ -71,47 +70,58 @@ namespace Content.IntegrationTests.Tests.Buckle
chair = entityManager.SpawnEntity(StrapDummyId, coordinates);
// Default state, unbuckled
Assert.True(entityManager.TryGetComponent(human, out buckle));
Assert.NotNull(buckle);
Assert.Null(buckle.BuckledTo);
Assert.False(buckle.Buckled);
Assert.True(actionBlocker.CanMove(human));
Assert.True(actionBlocker.CanChangeDirection(human));
Assert.True(standingState.Down(human));
Assert.True(standingState.Stand(human));
Assert.That(entityManager.TryGetComponent(human, out buckle));
Assert.Multiple(() =>
{
Assert.That(buckle, Is.Not.Null);
Assert.That(buckle.BuckledTo, Is.Null);
Assert.That(buckle.Buckled, Is.False);
Assert.That(actionBlocker.CanMove(human));
Assert.That(actionBlocker.CanChangeDirection(human));
Assert.That(standingState.Down(human));
Assert.That(standingState.Stand(human));
});
// Default state, no buckled entities, strap
Assert.True(entityManager.TryGetComponent(chair, out strap));
Assert.NotNull(strap);
Assert.IsEmpty(strap.BuckledEntities);
Assert.Zero(strap.OccupiedSize);
Assert.That(entityManager.TryGetComponent(chair, out strap));
Assert.Multiple(() =>
{
Assert.That(strap, Is.Not.Null);
Assert.That(strap.BuckledEntities, Is.Empty);
Assert.That(strap.OccupiedSize, Is.Zero);
});
// Side effects of buckling
Assert.True(buckleSystem.TryBuckle(human, human, chair, buckle));
Assert.NotNull(buckle.BuckledTo);
Assert.True(buckle.Buckled);
Assert.That(buckleSystem.TryBuckle(human, human, chair, buckle));
Assert.Multiple(() =>
{
Assert.That(buckle.BuckledTo, Is.Not.Null);
Assert.That(buckle.Buckled);
Assert.False(actionBlocker.CanMove(human));
Assert.False(actionBlocker.CanChangeDirection(human));
Assert.False(standingState.Down(human));
Assert.That(actionBlocker.CanMove(human), Is.False);
Assert.That(actionBlocker.CanChangeDirection(human), Is.False);
Assert.That(standingState.Down(human), Is.False);
Assert.That(
(entityManager.GetComponent<TransformComponent>(human).WorldPosition -
entityManager.GetComponent<TransformComponent>(chair).WorldPosition).Length,
Is.LessThanOrEqualTo(0));
(xformSystem.GetWorldPosition(human) - xformSystem.GetWorldPosition(chair)).LengthSquared,
Is.LessThanOrEqualTo(0)
);
// Side effects of buckling for the strap
Assert.That(strap.BuckledEntities, Does.Contain(human));
Assert.That(strap.OccupiedSize, Is.EqualTo(buckle.Size));
Assert.Positive(strap.OccupiedSize);
});
#pragma warning disable NUnit2045 // Interdependent asserts.
// Trying to buckle while already buckled fails
Assert.False(buckleSystem.TryBuckle(human, human, chair, buckle));
Assert.That(buckleSystem.TryBuckle(human, human, chair, buckle), Is.False);
// Trying to unbuckle too quickly fails
Assert.False(buckleSystem.TryUnbuckle(human, human, buckleComp: buckle));
Assert.True(buckle.Buckled);
Assert.False(buckleSystem.ToggleBuckle(human, human, chair, buckle: buckle));
Assert.True(buckle.Buckled);
Assert.That(buckleSystem.TryUnbuckle(human, human, buckleComp: buckle), Is.False);
Assert.That(buckle.Buckled);
Assert.That(buckleSystem.ToggleBuckle(human, human, chair, buckle: buckle), Is.False);
Assert.That(buckle.Buckled);
#pragma warning restore NUnit2045
});
// Wait enough ticks for the unbuckling cooldown to run out
@@ -119,32 +129,39 @@ namespace Content.IntegrationTests.Tests.Buckle
await server.WaitAssertion(() =>
{
#pragma warning disable NUnit2045 // Interdependent asserts.
Assert.That(buckle.Buckled);
// Still buckled
Assert.True(buckle.Buckled);
#pragma warning restore NUnit2045
// Unbuckle
Assert.True(buckleSystem.TryUnbuckle(human, human, buckleComp: buckle));
Assert.Null(buckle.BuckledTo);
Assert.False(buckle.Buckled);
Assert.True(actionBlocker.CanMove(human));
Assert.True(actionBlocker.CanChangeDirection(human));
Assert.True(standingState.Down(human));
Assert.That(buckleSystem.TryUnbuckle(human, human, buckleComp: buckle));
Assert.Multiple(() =>
{
Assert.That(buckle.BuckledTo, Is.Null);
Assert.That(buckle.Buckled, Is.False);
Assert.That(actionBlocker.CanMove(human));
Assert.That(actionBlocker.CanChangeDirection(human));
Assert.That(standingState.Down(human));
// Unbuckle, strap
Assert.IsEmpty(strap.BuckledEntities);
Assert.Zero(strap.OccupiedSize);
Assert.That(strap.BuckledEntities, Is.Empty);
Assert.That(strap.OccupiedSize, Is.Zero);
});
#pragma warning disable NUnit2045 // Interdependent asserts.
// Re-buckling has no cooldown
Assert.True(buckleSystem.TryBuckle(human, human, chair, buckleComp: buckle));
Assert.True(buckle.Buckled);
Assert.That(buckleSystem.TryBuckle(human, human, chair, buckleComp: buckle));
Assert.That(buckle.Buckled);
// On cooldown
Assert.False(buckleSystem.TryUnbuckle(human, human, buckleComp: buckle));
Assert.True(buckle.Buckled);
Assert.False(buckleSystem.ToggleBuckle(human, human, chair, buckle: buckle));
Assert.True(buckle.Buckled);
Assert.False(buckleSystem.ToggleBuckle(human, human, chair, buckle: buckle));
Assert.True(buckle.Buckled);
Assert.That(buckleSystem.TryUnbuckle(human, human, buckleComp: buckle), Is.False);
Assert.That(buckle.Buckled);
Assert.That(buckleSystem.ToggleBuckle(human, human, chair, buckle: buckle), Is.False);
Assert.That(buckle.Buckled);
Assert.That(buckleSystem.ToggleBuckle(human, human, chair, buckle: buckle), Is.False);
Assert.That(buckle.Buckled);
#pragma warning restore NUnit2045
});
// Wait enough ticks for the unbuckling cooldown to run out
@@ -152,45 +169,57 @@ namespace Content.IntegrationTests.Tests.Buckle
await server.WaitAssertion(() =>
{
#pragma warning disable NUnit2045 // Interdependent asserts.
// Still buckled
Assert.True(buckle.Buckled);
Assert.That(buckle.Buckled);
// Unbuckle
Assert.True(buckleSystem.TryUnbuckle(human, human, buckleComp: buckle));
Assert.False(buckle.Buckled);
Assert.That(buckleSystem.TryUnbuckle(human, human, buckleComp: buckle));
Assert.That(buckle.Buckled, Is.False);
#pragma warning restore NUnit2045
// Move away from the chair
entityManager.GetComponent<TransformComponent>(human).WorldPosition += (1000, 1000);
var xformQuery = entityManager.GetEntityQuery<TransformComponent>();
var oldWorldPosition = xformSystem.GetWorldPosition(chair, xformQuery);
xformSystem.SetWorldPosition(human, oldWorldPosition + (1000, 1000), xformQuery);
// Out of range
Assert.False(buckleSystem.TryBuckle(human, human, chair, buckleComp: buckle));
Assert.False(buckleSystem.TryUnbuckle(human, human, buckleComp: buckle));
Assert.False(buckleSystem.ToggleBuckle(human, human, chair, buckle: buckle));
#pragma warning disable NUnit2045 // Interdependent asserts.
Assert.That(buckleSystem.TryBuckle(human, human, chair, buckleComp: buckle), Is.False);
Assert.That(buckleSystem.TryUnbuckle(human, human, buckleComp: buckle), Is.False);
Assert.That(buckleSystem.ToggleBuckle(human, human, chair, buckle: buckle), Is.False);
#pragma warning restore NUnit2045
// Move near the chair
entityManager.GetComponent<TransformComponent>(human).WorldPosition =
entityManager.GetComponent<TransformComponent>(chair).WorldPosition + (0.5f, 0);
oldWorldPosition = xformSystem.GetWorldPosition(chair, xformQuery);
xformSystem.SetWorldPosition(human, oldWorldPosition + (0.5f, 0), xformQuery);
// In range
Assert.True(buckleSystem.TryBuckle(human, human, chair, buckleComp: buckle));
Assert.True(buckle.Buckled);
Assert.False(buckleSystem.TryUnbuckle(human, human, buckleComp: buckle));
Assert.True(buckle.Buckled);
Assert.False(buckleSystem.ToggleBuckle(human, human, chair, buckle: buckle));
Assert.True(buckle.Buckled);
#pragma warning disable NUnit2045 // Interdependent asserts.
Assert.That(buckleSystem.TryBuckle(human, human, chair, buckleComp: buckle));
Assert.That(buckle.Buckled);
Assert.That(buckleSystem.TryUnbuckle(human, human, buckleComp: buckle), Is.False);
Assert.That(buckle.Buckled);
Assert.That(buckleSystem.ToggleBuckle(human, human, chair, buckle: buckle), Is.False);
Assert.That(buckle.Buckled);
#pragma warning restore NUnit2045
// Force unbuckle
Assert.True(buckleSystem.TryUnbuckle(human, human, true, buckleComp: buckle));
Assert.False(buckle.Buckled);
Assert.True(actionBlocker.CanMove(human));
Assert.True(actionBlocker.CanChangeDirection(human));
Assert.True(standingState.Down(human));
Assert.That(buckleSystem.TryUnbuckle(human, human, true, buckleComp: buckle));
Assert.Multiple(() =>
{
Assert.That(buckle.Buckled, Is.False);
Assert.That(actionBlocker.CanMove(human));
Assert.That(actionBlocker.CanChangeDirection(human));
Assert.That(standingState.Down(human));
});
// Re-buckle
Assert.True(buckleSystem.TryBuckle(human, human, chair, buckleComp: buckle));
Assert.That(buckleSystem.TryBuckle(human, human, chair, buckleComp: buckle));
// Move away from the chair
entityManager.GetComponent<TransformComponent>(human).WorldPosition += (1, 0);
oldWorldPosition = xformSystem.GetWorldPosition(chair, xformQuery);
xformSystem.SetWorldPosition(human, oldWorldPosition + (1, 0), xformQuery);
});
await server.WaitRunTicks(1);
@@ -198,9 +227,12 @@ namespace Content.IntegrationTests.Tests.Buckle
await server.WaitAssertion(() =>
{
// No longer buckled
Assert.False(buckle.Buckled);
Assert.Null(buckle.BuckledTo);
Assert.IsEmpty(strap.BuckledEntities);
Assert.Multiple(() =>
{
Assert.That(buckle.Buckled, Is.False);
Assert.That(buckle.BuckledTo, Is.Null);
Assert.That(strap.BuckledEntities, Is.Empty);
});
});
await pairTracker.CleanReturnAsync();
@@ -210,7 +242,10 @@ namespace Content.IntegrationTests.Tests.Buckle
public async Task BuckledDyingDropItemsTest()
{
await using var pairTracker = await PoolManager.GetServerClient(new PoolSettings
{NoClient = true, ExtraPrototypes = Prototypes});
{
NoClient = true,
ExtraPrototypes = Prototypes
});
var server = pairTracker.Pair.Server;
var testMap = await PoolManager.CreateTestMap(pairTracker);
@@ -233,22 +268,28 @@ namespace Content.IntegrationTests.Tests.Buckle
var chair = entityManager.SpawnEntity(StrapDummyId, coordinates);
// Component sanity check
Assert.True(entityManager.TryGetComponent(human, out buckle));
Assert.True(entityManager.HasComponent<StrapComponent>(chair));
Assert.True(entityManager.TryGetComponent(human, out hands));
Assert.True(entityManager.TryGetComponent(human, out body));
Assert.Multiple(() =>
{
Assert.That(entityManager.TryGetComponent(human, out buckle));
Assert.That(entityManager.HasComponent<StrapComponent>(chair));
Assert.That(entityManager.TryGetComponent(human, out hands));
Assert.That(entityManager.TryGetComponent(human, out body));
});
// Buckle
Assert.True(buckleSystem.TryBuckle(human, human, chair, buckleComp: buckle));
Assert.NotNull(buckle.BuckledTo);
Assert.True(buckle.Buckled);
Assert.That(buckleSystem.TryBuckle(human, human, chair, buckleComp: buckle));
Assert.Multiple(() =>
{
Assert.That(buckle.BuckledTo, Is.Not.Null);
Assert.That(buckle.Buckled);
});
// Put an item into every hand
for (var i = 0; i < hands.Count; i++)
{
var akms = entityManager.SpawnEntity(ItemDummyId, coordinates);
Assert.True(handsSys.TryPickupAnyHand(human, akms));
Assert.That(handsSys.TryPickupAnyHand(human, akms));
}
});
@@ -257,16 +298,16 @@ namespace Content.IntegrationTests.Tests.Buckle
await server.WaitAssertion(() =>
{
// Still buckled
Assert.True(buckle.Buckled);
Assert.That(buckle.Buckled);
// With items in all hands
foreach (var hand in hands.Hands.Values)
{
Assert.NotNull(hand.HeldEntity);
Assert.That(hand.HeldEntity, Is.Not.Null);
}
var bodySystem = entityManager.System<BodySystem>();
var legs = bodySystem.GetBodyChildrenOfType(body.Owner, BodyPartType.Leg, body);
var legs = bodySystem.GetBodyChildrenOfType(human, BodyPartType.Leg, body);
// Break our guy's kneecaps
foreach (var leg in legs)
@@ -280,12 +321,12 @@ namespace Content.IntegrationTests.Tests.Buckle
await server.WaitAssertion(() =>
{
// Still buckled
Assert.True(buckle.Buckled);
Assert.That(buckle.Buckled);
// Now with no item in any hand
foreach (var hand in hands.Hands.Values)
{
Assert.Null(hand.HeldEntity);
Assert.That(hand.HeldEntity, Is.Null);
}
buckleSystem.TryUnbuckle(human, human, true, buckleComp: buckle);
@@ -298,13 +339,17 @@ namespace Content.IntegrationTests.Tests.Buckle
public async Task ForceUnbuckleBuckleTest()
{
await using var pairTracker = await PoolManager.GetServerClient(new PoolSettings
{NoClient = true, ExtraPrototypes = Prototypes});
{
NoClient = true,
ExtraPrototypes = Prototypes
});
var server = pairTracker.Pair.Server;
var testMap = await PoolManager.CreateTestMap(pairTracker);
var coordinates = testMap.GridCoords;
var entityManager = server.ResolveDependency<IEntityManager>();
var buckleSystem = entityManager.System<SharedBuckleSystem>();
var xformSystem = entityManager.System<SharedTransformSystem>();
EntityUid human = default;
EntityUid chair = default;
@@ -316,31 +361,44 @@ namespace Content.IntegrationTests.Tests.Buckle
chair = entityManager.SpawnEntity(StrapDummyId, coordinates);
// Component sanity check
Assert.True(entityManager.TryGetComponent(human, out buckle));
Assert.True(entityManager.HasComponent<StrapComponent>(chair));
Assert.Multiple(() =>
{
Assert.That(entityManager.TryGetComponent(human, out buckle));
Assert.That(entityManager.HasComponent<StrapComponent>(chair));
});
// Buckle
Assert.True(buckleSystem.TryBuckle(human, human, chair, buckleComp: buckle));
Assert.NotNull(buckle.BuckledTo);
Assert.True(buckle.Buckled);
Assert.That(buckleSystem.TryBuckle(human, human, chair, buckleComp: buckle));
Assert.Multiple(() =>
{
Assert.That(buckle.BuckledTo, Is.Not.Null);
Assert.That(buckle.Buckled);
});
// Move the buckled entity away
entityManager.GetComponent<TransformComponent>(human).WorldPosition += (100, 0);
var xformQuery = entityManager.GetEntityQuery<TransformComponent>();
var oldWorldPosition = xformSystem.GetWorldPosition(chair, xformQuery);
xformSystem.SetWorldPosition(human, oldWorldPosition + (100, 0), xformQuery);
});
await PoolManager.WaitUntil(server, () => !buckle.Buckled, 10);
Assert.False(buckle.Buckled);
Assert.That(buckle.Buckled, Is.False);
await server.WaitAssertion(() =>
{
// Move the now unbuckled entity back onto the chair
entityManager.GetComponent<TransformComponent>(human).WorldPosition -= (100, 0);
var xformQuery = entityManager.GetEntityQuery<TransformComponent>();
var oldWorldPosition = xformSystem.GetWorldPosition(chair, xformQuery);
xformSystem.SetWorldPosition(human, oldWorldPosition, xformQuery);
// Buckle
Assert.True(buckleSystem.TryBuckle(human, human, chair, buckleComp: buckle));
Assert.NotNull(buckle.BuckledTo);
Assert.True(buckle.Buckled);
Assert.That(buckleSystem.TryBuckle(human, human, chair, buckleComp: buckle));
Assert.Multiple(() =>
{
Assert.That(buckle.BuckledTo, Is.Not.Null);
Assert.That(buckle.Buckled);
});
});
await server.WaitRunTicks(60);
@@ -348,8 +406,11 @@ namespace Content.IntegrationTests.Tests.Buckle
await server.WaitAssertion(() =>
{
// Still buckled
Assert.NotNull(buckle.BuckledTo);
Assert.True(buckle.Buckled);
Assert.Multiple(() =>
{
Assert.That(buckle.BuckledTo, Is.Not.Null);
Assert.That(buckle.Buckled);
});
});
await pairTracker.CleanReturnAsync();
}

View File

@@ -1,12 +1,8 @@
using System.Threading.Tasks;
using System.Linq;
using Content.Server.Cargo.Components;
using Content.Server.Cargo.Systems;
using Content.Shared.Cargo.Prototypes;
using Content.Shared.CCVar;
using Content.Shared.Stacks;
using NUnit.Framework;
using Robust.Shared.Configuration;
using Robust.Shared.GameObjects;
using Robust.Shared.Map;
using Robust.Shared.Maths;
@@ -20,7 +16,7 @@ public sealed class CargoTest
[Test]
public async Task NoCargoOrderArbitrage()
{
await using var pairTracker = await PoolManager.GetServerClient(new PoolSettings() {NoClient = true});
await using var pairTracker = await PoolManager.GetServerClient(new PoolSettings() { NoClient = true });
var server = pairTracker.Pair.Server;
var testMap = await PoolManager.CreateTestMap(pairTracker);
@@ -54,7 +50,7 @@ public sealed class CargoTest
[Test]
public async Task NoCargoBountyArbitageTest()
{
await using var pairTracker = await PoolManager.GetServerClient(new PoolSettings() {NoClient = true});
await using var pairTracker = await PoolManager.GetServerClient(new PoolSettings() { NoClient = true });
var server = pairTracker.Pair.Server;
var testMap = await PoolManager.CreateTestMap(pairTracker);
@@ -95,7 +91,7 @@ public sealed class CargoTest
[Test]
public async Task NoStaticPriceAndStackPrice()
{
await using var pairTracker = await PoolManager.GetServerClient(new PoolSettings{NoClient = true});
await using var pairTracker = await PoolManager.GetServerClient(new PoolSettings { NoClient = true });
var server = pairTracker.Pair.Server;
var testMap = await PoolManager.CreateTestMap(pairTracker);
@@ -111,7 +107,7 @@ public sealed class CargoTest
var coord = new EntityCoordinates(grid.Owner, 0, 0);
var protoIds = protoManager.EnumeratePrototypes<EntityPrototype>()
.Where(p=>!p.Abstract)
.Where(p => !p.Abstract)
.Where(p => !p.Components.ContainsKey("MapGrid")) // Grids are not for sale.
.Select(p => p.ID)
.ToList();
@@ -150,7 +146,7 @@ public sealed class CargoTest
[Test]
public async Task StackPrice()
{
const string StackProto = @"
const string stackProto = @"
- type: entity
id: A
@@ -168,7 +164,7 @@ public sealed class CargoTest
count: 5
";
await using var pairTracker = await PoolManager.GetServerClient(new PoolSettings{NoClient = true, ExtraPrototypes = StackProto});
await using var pairTracker = await PoolManager.GetServerClient(new PoolSettings { NoClient = true, ExtraPrototypes = stackProto });
var server = pairTracker.Pair.Server;
var entManager = server.ResolveDependency<IEntityManager>();

View File

@@ -1,9 +1,7 @@
using System.Threading.Tasks;
using Content.Client.Chemistry.UI;
using Content.IntegrationTests.Tests.Interaction;
using Content.Shared.Chemistry;
using Content.Shared.Containers.ItemSlots;
using NUnit.Framework;
namespace Content.IntegrationTests.Tests.Chemistry;
@@ -20,7 +18,7 @@ public sealed class DispenserTest : InteractionTest
// Insert beaker
await Interact("Beaker");
Assert.IsNull(Hands.ActiveHandEntity);
Assert.That(Hands.ActiveHandEntity, Is.Null);
// Open BUI
await Interact();
@@ -30,18 +28,18 @@ public sealed class DispenserTest : InteractionTest
await SendBui(ReagentDispenserUiKey.Key, ev);
// Beaker is back in the player's hands
Assert.IsNotNull(Hands.ActiveHandEntity);
Assert.That(Hands.ActiveHandEntity, Is.Not.Null);
AssertPrototype("Beaker", Hands.ActiveHandEntity);
// Re-insert the beaker
await Interact();
Assert.IsNull(Hands.ActiveHandEntity);
Assert.That(Hands.ActiveHandEntity, Is.Null);
// Re-eject using the button directly instead of sending a BUI event. This test is really just a test of the
// bui/window helper methods.
await ClickControl<ReagentDispenserWindow>(nameof(ReagentDispenserWindow.EjectButton));
await RunTicks(5);
Assert.IsNotNull(Hands.ActiveHandEntity);
Assert.That(Hands.ActiveHandEntity, Is.Not.Null);
AssertPrototype("Beaker", Hands.ActiveHandEntity);
}
}

View File

@@ -1,6 +1,5 @@
using System.Reflection;
using Content.Shared.FixedPoint;
using NUnit.Framework;
using Robust.Shared.Serialization.Manager.Attributes;
using Robust.Shared.Serialization.Markdown.Mapping;
using Robust.Shared.Serialization.Markdown.Value;
@@ -35,8 +34,10 @@ namespace Content.IntegrationTests.Tests.Chemistry
public void SerializeNullableValueTest()
{
var node = Serialization.WriteValue<FixedPoint2?>(FixedPoint2.New(2.5f));
#pragma warning disable NUnit2045 // Interdependent assertions
Assert.That(node is ValueDataNode);
Assert.That(((ValueDataNode)node).Value, Is.EqualTo("2.5"));
Assert.That(((ValueDataNode) node).Value, Is.EqualTo("2.5"));
#pragma warning restore NUnit2045
}
[Test]

View File

@@ -1,8 +1,6 @@
using System.Threading.Tasks;
using Content.Server.Chemistry.EntitySystems;
using Content.Shared.Chemistry.Components;
using Content.Shared.FixedPoint;
using NUnit.Framework;
using Robust.Shared.GameObjects;
using Robust.Shared.Prototypes;
@@ -47,7 +45,11 @@ public sealed class SolutionSystemTests
[Test]
public async Task TryAddTwoNonReactiveReagent()
{
await using var pairTracker = await PoolManager.GetServerClient(new PoolSettings{NoClient = true, ExtraPrototypes = Prototypes});
await using var pairTracker = await PoolManager.GetServerClient(new PoolSettings
{
NoClient = true,
ExtraPrototypes = Prototypes
});
var server = pairTracker.Pair.Server;
var entityManager = server.ResolveDependency<IEntityManager>();
@@ -76,9 +78,12 @@ public sealed class SolutionSystemTests
solution.TryGetReagent("Water", out var water);
solution.TryGetReagent("Oil", out var oil);
Assert.Multiple(() =>
{
Assert.That(water, Is.EqualTo(waterQuantity));
Assert.That(oil, Is.EqualTo(oilQuantity));
});
});
await pairTracker.CleanReturnAsync();
}
@@ -88,7 +93,11 @@ public sealed class SolutionSystemTests
[Test]
public async Task TryAddTooMuchNonReactiveReagent()
{
await using var pairTracker = await PoolManager.GetServerClient(new PoolSettings{NoClient = true, ExtraPrototypes = Prototypes});
await using var pairTracker = await PoolManager.GetServerClient(new PoolSettings
{
NoClient = true,
ExtraPrototypes = Prototypes
});
var server = pairTracker.Pair.Server;
var testMap = await PoolManager.CreateTestMap(pairTracker);
@@ -118,9 +127,12 @@ public sealed class SolutionSystemTests
solution.TryGetReagent("Water", out var water);
solution.TryGetReagent("Oil", out var oil);
Assert.Multiple(() =>
{
Assert.That(water, Is.EqualTo(waterQuantity));
Assert.That(oil, Is.EqualTo(FixedPoint2.Zero));
});
});
await pairTracker.CleanReturnAsync();
}
@@ -129,7 +141,11 @@ public sealed class SolutionSystemTests
[Test]
public async Task TryMixAndOverflowTooMuchReagent()
{
await using var pairTracker = await PoolManager.GetServerClient(new PoolSettings{NoClient = true, ExtraPrototypes = Prototypes});
await using var pairTracker = await PoolManager.GetServerClient(new PoolSettings
{
NoClient = true,
ExtraPrototypes = Prototypes
});
var server = pairTracker.Pair.Server;
@@ -141,10 +157,10 @@ public sealed class SolutionSystemTests
EntityUid beaker;
await server.WaitAssertion((System.Action)(() =>
await server.WaitAssertion(() =>
{
int ratio = 9;
int threshold = 20;
var ratio = 9;
var threshold = 20;
var waterQuantity = FixedPoint2.New(10);
var oilQuantity = FixedPoint2.New(ratio * waterQuantity.Int());
@@ -159,18 +175,23 @@ public sealed class SolutionSystemTests
Assert.That(containerSystem
.TryMixAndOverflow(beaker, solution, oilAdded, threshold, out var overflowingSolution));
Assert.Multiple(() =>
{
Assert.That(solution.Volume, Is.EqualTo(FixedPoint2.New(threshold)));
solution.TryGetReagent("Water", out var waterMix);
solution.TryGetReagent("Oil", out var oilMix);
Assert.That(waterMix, Is.EqualTo(FixedPoint2.New(threshold / (ratio + 1))));
Assert.That(oilMix, Is.EqualTo(FixedPoint2.New(threshold / (ratio + 1) * ratio)));
Assert.That(overflowingSolution.Volume, Is.EqualTo(FixedPoint2.New(80)));
overflowingSolution.TryGetReagent("Water", out var waterOverflow);
overflowingSolution.TryGetReagent("Oil", out var oilOverFlow);
Assert.That(waterOverflow, Is.EqualTo(waterQuantity - waterMix));
Assert.That(oilOverFlow, Is.EqualTo(oilQuantity - oilMix));
}));
});
});
await pairTracker.CleanReturnAsync();
}
@@ -179,7 +200,11 @@ public sealed class SolutionSystemTests
[Test]
public async Task TryMixAndOverflowTooBigOverflow()
{
await using var pairTracker = await PoolManager.GetServerClient(new PoolSettings{NoClient = true, ExtraPrototypes = Prototypes});
await using var pairTracker = await PoolManager.GetServerClient(new PoolSettings
{
NoClient = true,
ExtraPrototypes = Prototypes
});
var server = pairTracker.Pair.Server;
var entityManager = server.ResolveDependency<IEntityManager>();
@@ -192,8 +217,8 @@ public sealed class SolutionSystemTests
await server.WaitAssertion(() =>
{
int ratio = 9;
int threshold = 60;
var ratio = 9;
var threshold = 60;
var waterQuantity = FixedPoint2.New(10);
var oilQuantity = FixedPoint2.New(ratio * waterQuantity.Int());

View File

@@ -1,11 +1,7 @@
using System;
using System.Linq;
using System.Threading.Tasks;
using Content.Server.Chemistry.EntitySystems;
using Content.Server.Engineering.Components;
using Content.Shared.Chemistry.Components;
using Content.Shared.Chemistry.Reaction;
using NUnit.Framework;
using Robust.Shared.GameObjects;
using Robust.Shared.Map;
using Robust.Shared.Prototypes;
@@ -29,7 +25,11 @@ namespace Content.IntegrationTests.Tests.Chemistry
[Test]
public async Task TryAllTest()
{
await using var pairTracker = await PoolManager.GetServerClient(new PoolSettings{NoClient = true, ExtraPrototypes = Prototypes});
await using var pairTracker = await PoolManager.GetServerClient(new PoolSettings
{
NoClient = true,
ExtraPrototypes = Prototypes
});
var server = pairTracker.Pair.Server;
var entityManager = server.ResolveDependency<IEntityManager>();
@@ -54,9 +54,11 @@ namespace Content.IntegrationTests.Tests.Chemistry
.TryGetSolution(beaker, "beaker", out component));
foreach (var (id, reactant) in reactionPrototype.Reactants)
{
#pragma warning disable NUnit2045
Assert.That(solutionSystem
.TryAddReagent(beaker, component, id, reactant.Amount, out var quantity));
Assert.That(reactant.Amount, Is.EqualTo(quantity));
#pragma warning restore NUnit2045
}
solutionSystem.SetTemperature(beaker, component, reactionPrototype.MinimumTemperature);

View File

@@ -1,10 +1,7 @@
using System.Linq;
using System.Threading.Tasks;
using Content.Server.Administration.UI;
using Content.Server.EUI;
using NUnit.Framework;
using Robust.Server.Player;
using Robust.Shared.IoC;
namespace Content.IntegrationTests.Tests.Cleanup;
@@ -14,9 +11,9 @@ public sealed class EuiManagerTest
public async Task EuiManagerRecycleWithOpenWindowTest()
{
// Even though we are using the server EUI here, we actually want to see if the client EUIManager crashes
for (int i = 0; i < 2; i++)
for (var i = 0; i < 2; i++)
{
await using var pairTracker = await PoolManager.GetServerClient(new PoolSettings{Dirty = true});
await using var pairTracker = await PoolManager.GetServerClient(new PoolSettings { Dirty = true });
var server = pairTracker.Pair.Server;
var sPlayerManager = server.ResolveDependency<IPlayerManager>();

View File

@@ -1,7 +1,4 @@
using System;
using System.Threading.Tasks;
using Content.Client.Clickable;
using NUnit.Framework;
using Robust.Client.GameObjects;
using Robust.Client.Graphics;
using Robust.Shared.GameObjects;
@@ -61,7 +58,7 @@ namespace Content.IntegrationTests.Tests
await server.WaitPost(() =>
{
var ent = serverEntManager.SpawnEntity(prototype, testMap.GridCoords);
serverEntManager.GetComponent<TransformComponent>(ent).WorldRotation = angle;
serverEntManager.System<SharedTransformSystem>().SetWorldRotation(ent, angle);
entity = ent;
});
@@ -78,7 +75,7 @@ namespace Content.IntegrationTests.Tests
// these tests currently all assume player eye is 0
eyeManager.CurrentEye.Rotation = 0;
var pos = clientEntManager.GetComponent<TransformComponent>(entity).WorldPosition;
var pos = clientEntManager.System<SharedTransformSystem>().GetWorldPosition(entity);
var clickable = clientEntManager.GetComponent<ClickableComponent>(entity);
hit = clickable.CheckClick(sprite, xformQuery.GetComponent(entity), xformQuery, (clickPosX, clickPosY) + pos, eye, out _, out _, out _);

View File

@@ -1,11 +1,8 @@
#nullable enable
using System.Threading.Tasks;
using Content.IntegrationTests.Tests.Interaction;
using Content.Server.Climbing;
using Content.Shared.Climbing;
using NUnit.Framework;
using Robust.Shared.Maths;
using Robust.Shared.Physics.Components;
namespace Content.IntegrationTests.Tests.Climbing;
@@ -20,8 +17,11 @@ public sealed class ClimbingTest : MovementTest
// Player is not initially climbing anything.
var comp = Comp<ClimbingComponent>(Player);
Assert.Multiple(() =>
{
Assert.That(comp.IsClimbing, Is.False);
Assert.That(comp.DisabledFixtureMasks.Count, Is.EqualTo(0));
Assert.That(comp.DisabledFixtureMasks, Has.Count.EqualTo(0));
});
// Attempt (and fail) to walk past the table.
await Move(DirectionFlag.East, 1f);
@@ -33,16 +33,23 @@ public sealed class ClimbingTest : MovementTest
await AwaitDoAfters();
// Player should now be climbing
Assert.Multiple(() =>
{
Assert.That(comp.IsClimbing, Is.True);
Assert.That(comp.DisabledFixtureMasks.Count, Is.GreaterThan(0));
Assert.That(comp.DisabledFixtureMasks, Has.Count.GreaterThan(0));
});
// Can now walk over the table.
await Move(DirectionFlag.East, 1f);
Assert.Multiple(() =>
{
Assert.That(Delta(), Is.LessThan(0));
// After walking away from the table, player should have stopped climbing.
Assert.That(comp.IsClimbing, Is.False);
Assert.That(comp.DisabledFixtureMasks.Count, Is.EqualTo(0));
Assert.That(comp.DisabledFixtureMasks, Has.Count.EqualTo(0));
});
// Try to walk back to the other side (and fail).
await Move(DirectionFlag.West, 1f);
@@ -51,14 +58,20 @@ public sealed class ClimbingTest : MovementTest
// Start climbing
await Server.WaitPost(() => sys.TryClimb(Player, Player, Target.Value));
await AwaitDoAfters();
Assert.Multiple(() =>
{
Assert.That(comp.IsClimbing, Is.True);
Assert.That(comp.DisabledFixtureMasks.Count, Is.GreaterThan(0));
Assert.That(comp.DisabledFixtureMasks, Has.Count.GreaterThan(0));
});
// Walk past table and stop climbing again.
await Move(DirectionFlag.West, 1f);
Assert.Multiple(() =>
{
Assert.That(Delta(), Is.GreaterThan(0));
Assert.That(comp.IsClimbing, Is.False);
Assert.That(comp.DisabledFixtureMasks.Count, Is.EqualTo(0));
Assert.That(comp.DisabledFixtureMasks, Has.Count.EqualTo(0));
});
}
}

View File

@@ -1,8 +1,5 @@
using System;
using System.Linq;
using System.Threading.Tasks;
using Content.Server.Database;
using NUnit.Framework;
using Robust.Server.Console;
using Robust.Server.Player;
@@ -17,7 +14,7 @@ namespace Content.IntegrationTests.Tests.Commands
[Test]
public async Task PardonTest()
{
await using var pairTracker = await PoolManager.GetServerClient(new (){Destructive = true});
await using var pairTracker = await PoolManager.GetServerClient(new() { Destructive = true });
var server = pairTracker.Pair.Server;
var sPlayerManager = server.ResolveDependency<IPlayerManager>();
@@ -30,17 +27,23 @@ namespace Content.IntegrationTests.Tests.Commands
var clientId = clientSession.UserId;
// No bans on record
Assert.Multiple(async () =>
{
Assert.That(await sDatabase.GetServerBanAsync(null, clientId, null), Is.Null);
Assert.That(await sDatabase.GetServerBanAsync(1), Is.Null);
Assert.That(await sDatabase.GetServerBansAsync(null, clientId, null), Is.Empty);
});
// Try to pardon a ban that does not exist
sConsole.ExecuteCommand("pardon 1");
// Still no bans on record
Assert.Multiple(async () =>
{
Assert.That(await sDatabase.GetServerBanAsync(null, clientId, null), Is.Null);
Assert.That(await sDatabase.GetServerBanAsync(1), Is.Null);
Assert.That(await sDatabase.GetServerBansAsync(null, clientId, null), Is.Empty);
});
var banReason = "test";
@@ -48,9 +51,12 @@ namespace Content.IntegrationTests.Tests.Commands
sConsole.ExecuteCommand($"ban {clientSession.Name} {banReason} 1440");
// Should have one ban on record now
Assert.Multiple(async () =>
{
Assert.That(await sDatabase.GetServerBanAsync(null, clientId, null), Is.Not.Null);
Assert.That(await sDatabase.GetServerBanAsync(1), Is.Not.Null);
Assert.That(await sDatabase.GetServerBansAsync(null, clientId, null), Has.Count.EqualTo(1));
});
// Try to pardon a ban that does not exist
sConsole.ExecuteCommand("pardon 2");
@@ -59,22 +65,23 @@ namespace Content.IntegrationTests.Tests.Commands
Assert.That(await sDatabase.GetServerBanAsync(null, clientId, null), Is.Not.Null);
var ban = await sDatabase.GetServerBanAsync(1);
Assert.Multiple(async () =>
{
Assert.That(ban, Is.Not.Null);
Assert.That(await sDatabase.GetServerBansAsync(null, clientId, null), Has.Count.EqualTo(1));
// Check that it matches
Assert.That(ban.Id, Is.EqualTo(1));
Assert.That(ban.UserId, Is.EqualTo(clientId));
Assert.That(ban.BanTime.UtcDateTime - DateTime.UtcNow, Is.LessThanOrEqualTo(MarginOfError));
Assert.NotNull(ban.ExpirationTime);
Assert.That(ban.ExpirationTime, Is.Not.Null);
Assert.That(ban.ExpirationTime.Value.UtcDateTime - DateTime.UtcNow.AddHours(24), Is.LessThanOrEqualTo(MarginOfError));
Assert.That(ban.Reason, Is.EqualTo(banReason));
// Done through the console
Assert.That(ban.BanningAdmin, Is.Null);
Assert.That(ban.Unban, Is.Null);
});
// Pardon the actual ban
sConsole.ExecuteCommand("pardon 1");
@@ -84,16 +91,18 @@ namespace Content.IntegrationTests.Tests.Commands
// Direct id lookup returns a pardoned ban
var pardonedBan = await sDatabase.GetServerBanAsync(1);
Assert.Multiple(async () =>
{
// Check that it matches
Assert.That(pardonedBan, Is.Not.Null);
// The list is still returned since that ignores pardons
Assert.That(await sDatabase.GetServerBansAsync(null, clientId, null), Has.Count.EqualTo(1));
// Check that it matches
Assert.That(pardonedBan.Id, Is.EqualTo(1));
Assert.That(pardonedBan.UserId, Is.EqualTo(clientId));
Assert.That(pardonedBan.BanTime.UtcDateTime - DateTime.UtcNow, Is.LessThanOrEqualTo(MarginOfError));
Assert.NotNull(pardonedBan.ExpirationTime);
Assert.That(pardonedBan.ExpirationTime, Is.Not.Null);
Assert.That(pardonedBan.ExpirationTime.Value.UtcDateTime - DateTime.UtcNow.AddHours(24), Is.LessThanOrEqualTo(MarginOfError));
Assert.That(pardonedBan.Reason, Is.EqualTo(banReason));
@@ -107,11 +116,14 @@ namespace Content.IntegrationTests.Tests.Commands
Assert.That(pardonedBan.Unban.UnbanningAdmin, Is.Null);
Assert.That(pardonedBan.Unban.UnbanTime.UtcDateTime - DateTime.UtcNow, Is.LessThanOrEqualTo(MarginOfError));
});
// Try to pardon it again
sConsole.ExecuteCommand("pardon 1");
// Nothing changes
Assert.Multiple(async () =>
{
// No bans should be returned
Assert.That(await sDatabase.GetServerBanAsync(null, clientId, null), Is.Null);
@@ -121,6 +133,7 @@ namespace Content.IntegrationTests.Tests.Commands
// The list is still returned since that ignores pardons
Assert.That(await sDatabase.GetServerBansAsync(null, clientId, null), Has.Count.EqualTo(1));
});
});
await pairTracker.CleanReturnAsync();
}
}

View File

@@ -1,11 +1,9 @@
using System.Threading.Tasks;
using Content.Server.Administration.Commands;
using Content.Server.Administration.Commands;
using Content.Shared.Damage;
using Content.Shared.Damage.Prototypes;
using Content.Shared.FixedPoint;
using Content.Shared.Mobs.Components;
using Content.Shared.Mobs.Systems;
using NUnit.Framework;
using Robust.Shared.GameObjects;
using Robust.Shared.Map;
using Robust.Shared.Prototypes;
@@ -34,7 +32,11 @@ namespace Content.IntegrationTests.Tests.Commands
[Test]
public async Task RejuvenateDeadTest()
{
await using var pairTracker = await PoolManager.GetServerClient(new PoolSettings{NoClient = true, ExtraPrototypes = Prototypes});
await using var pairTracker = await PoolManager.GetServerClient(new PoolSettings
{
NoClient = true,
ExtraPrototypes = Prototypes
});
var server = pairTracker.Pair.Server;
var entManager = server.ResolveDependency<IEntityManager>();
var mapManager = server.ResolveDependency<IMapManager>();
@@ -45,31 +47,43 @@ namespace Content.IntegrationTests.Tests.Commands
await server.WaitAssertion(() =>
{
var human = entManager.SpawnEntity("DamageableDummy", MapCoordinates.Nullspace);
DamageableComponent damageable = null;
MobStateComponent mobState = null;
// Sanity check
Assert.True(entManager.TryGetComponent(human, out DamageableComponent damageable));
Assert.True(entManager.TryGetComponent(human, out MobStateComponent mobState));
Assert.Multiple(() =>
{
Assert.That(entManager.TryGetComponent(human, out damageable));
Assert.That(entManager.TryGetComponent(human, out mobState));
});
Assert.Multiple(() =>
{
Assert.That(mobStateSystem.IsAlive(human, mobState), Is.True);
Assert.That(mobStateSystem.IsCritical(human, mobState), Is.False);
Assert.That(mobStateSystem.IsDead(human, mobState), Is.False);
Assert.That(mobStateSystem.IsIncapacitated(human, mobState), Is.False);
});
// Kill the entity
DamageSpecifier damage = new(prototypeManager.Index<DamageGroupPrototype>("Toxin"),
FixedPoint2.New(10000000));
DamageSpecifier damage = new(prototypeManager.Index<DamageGroupPrototype>("Toxin"), FixedPoint2.New(10000000));
damSystem.TryChangeDamage(human, damage, true);
// Check that it is dead
Assert.Multiple(() =>
{
Assert.That(mobStateSystem.IsAlive(human, mobState), Is.False);
Assert.That(mobStateSystem.IsCritical(human, mobState), Is.False);
Assert.That(mobStateSystem.IsDead(human, mobState), Is.True);
Assert.That(mobStateSystem.IsIncapacitated(human, mobState), Is.True);
});
// Rejuvenate them
RejuvenateCommand.PerformRejuvenate(human);
// Check that it is alive and with no damage
Assert.Multiple(() =>
{
Assert.That(mobStateSystem.IsAlive(human, mobState), Is.True);
Assert.That(mobStateSystem.IsCritical(human, mobState), Is.False);
Assert.That(mobStateSystem.IsDead(human, mobState), Is.False);
@@ -77,6 +91,7 @@ namespace Content.IntegrationTests.Tests.Commands
Assert.That(damageable.TotalDamage, Is.EqualTo(FixedPoint2.Zero));
});
});
await pairTracker.CleanReturnAsync();
}
}

View File

@@ -1,9 +1,6 @@
using System;
using System.Threading.Tasks;
using Content.Server.GameTicking;
using Content.Server.GameTicking.Commands;
using Content.Shared.CCVar;
using NUnit.Framework;
using Robust.Shared.Configuration;
using Robust.Shared.GameObjects;
using Robust.Shared.Timing;
@@ -19,7 +16,7 @@ namespace Content.IntegrationTests.Tests.Commands
[TestCase(false)]
public async Task RestartRoundAfterStart(bool lobbyEnabled)
{
await using var pairTracker = await PoolManager.GetServerClient(new PoolSettings(){Dirty = true});
await using var pairTracker = await PoolManager.GetServerClient(new PoolSettings() { Dirty = true });
var server = pairTracker.Pair.Server;
var configManager = server.ResolveDependency<IConfigurationManager>();
@@ -54,7 +51,7 @@ namespace Content.IntegrationTests.Tests.Commands
{
var tickAfterRestart = entityManager.CurrentTick;
Assert.That(tickBeforeRestart < tickAfterRestart);
Assert.That(tickBeforeRestart, Is.LessThan(tickAfterRestart));
});
await PoolManager.RunTicksSync(pairTracker.Pair, 5);

View File

@@ -1,9 +1,7 @@
using System.Text;
using System.Threading.Tasks;
using Content.Server.Construction.Completions;
using Content.Shared.Construction;
using Content.Shared.Construction.Prototypes;
using NUnit.Framework;
using Robust.Shared.Prototypes;
namespace Content.IntegrationTests.Tests.Construction
@@ -49,7 +47,7 @@ namespace Content.IntegrationTests.Tests.Construction
[Test]
public async Task ConstructionGraphSpawnPrototypeValid()
{
await using var pairTracker = await PoolManager.GetServerClient(new PoolSettings{NoClient = true});
await using var pairTracker = await PoolManager.GetServerClient(new PoolSettings { NoClient = true });
var server = pairTracker.Pair.Server;
var protoMan = server.ResolveDependency<IPrototypeManager>();
@@ -89,7 +87,7 @@ namespace Content.IntegrationTests.Tests.Construction
[Test]
public async Task ConstructionGraphNodeEntityPrototypeValid()
{
await using var pairTracker = await PoolManager.GetServerClient(new PoolSettings{NoClient = true});
await using var pairTracker = await PoolManager.GetServerClient(new PoolSettings { NoClient = true });
var server = pairTracker.Pair.Server;
var protoMan = server.ResolveDependency<IPrototypeManager>();
@@ -115,7 +113,7 @@ namespace Content.IntegrationTests.Tests.Construction
[Test]
public async Task ConstructionGraphEdgeValid()
{
await using var pairTracker = await PoolManager.GetServerClient(new PoolSettings{NoClient = true});
await using var pairTracker = await PoolManager.GetServerClient(new PoolSettings { NoClient = true });
var server = pairTracker.Pair.Server;
var protoMan = server.ResolveDependency<IPrototypeManager>();

View File

@@ -1,11 +1,9 @@
using Content.Server.Construction.Components;
using Content.Shared.Construction.Prototypes;
using NUnit.Framework;
using Robust.Shared.GameObjects;
using Robust.Shared.Map;
using Robust.Shared.Maths;
using Robust.Shared.Prototypes;
using System.Threading.Tasks;
namespace Content.IntegrationTests.Tests.Construction
{
@@ -22,7 +20,7 @@ namespace Content.IntegrationTests.Tests.Construction
[Test]
public async Task TestStartNodeValid()
{
await using var pairTracker = await PoolManager.GetServerClient(new PoolSettings{NoClient = true});
await using var pairTracker = await PoolManager.GetServerClient(new PoolSettings { NoClient = true });
var server = pairTracker.Pair.Server;
var entMan = server.ResolveDependency<IEntityManager>();
@@ -54,7 +52,7 @@ namespace Content.IntegrationTests.Tests.Construction
[Test]
public async Task TestStartIsValid()
{
await using var pairTracker = await PoolManager.GetServerClient(new PoolSettings{NoClient = true});
await using var pairTracker = await PoolManager.GetServerClient(new PoolSettings { NoClient = true });
var server = pairTracker.Pair.Server;
var protoMan = server.ResolveDependency<IPrototypeManager>();
@@ -72,7 +70,7 @@ namespace Content.IntegrationTests.Tests.Construction
[Test]
public async Task TestTargetIsValid()
{
await using var pairTracker = await PoolManager.GetServerClient(new PoolSettings{NoClient = true});
await using var pairTracker = await PoolManager.GetServerClient(new PoolSettings { NoClient = true });
var server = pairTracker.Pair.Server;
var protoMan = server.ResolveDependency<IPrototypeManager>();
@@ -121,7 +119,7 @@ namespace Content.IntegrationTests.Tests.Construction
[Test]
public async Task TestStartReachesValidTarget()
{
await using var pairTracker = await PoolManager.GetServerClient(new PoolSettings{NoClient = true});
await using var pairTracker = await PoolManager.GetServerClient(new PoolSettings { NoClient = true });
var server = pairTracker.Pair.Server;
var protoMan = server.ResolveDependency<IPrototypeManager>();
@@ -131,12 +129,15 @@ namespace Content.IntegrationTests.Tests.Construction
var start = proto.StartNode;
var target = proto.TargetNode;
var graph = protoMan.Index<ConstructionGraphPrototype>(proto.Graph);
#pragma warning disable NUnit2045 // Interdependent assertions.
Assert.That(graph.TryPath(start, target, out var path), $"Unable to find path from \"{start}\" to \"{target}\" on graph \"{graph.ID}\"");
Assert.That(path!.Length, Is.GreaterThanOrEqualTo(1), $"Unable to find path from \"{start}\" to \"{target}\" on graph \"{graph.ID}\".");
Assert.That(path, Has.Length.GreaterThanOrEqualTo(1), $"Unable to find path from \"{start}\" to \"{target}\" on graph \"{graph.ID}\".");
var next = path[0];
Assert.That(next.Entity, Is.Not.Null, $"The next node ({next.Name}) in the path from the start node ({start}) to the target node ({target}) must specify an entity! Graph: {graph.ID}");
Assert.That(protoMan.TryIndex(next.Entity, out EntityPrototype entity), $"The next node ({next.Name}) in the path from the start node ({start}) to the target node ({target}) specified an invalid entity prototype ({next.Entity})");
Assert.That(entity.Components.ContainsKey("Construction"), $"The next node ({next.Name}) in the path from the start node ({start}) to the target node ({target}) specified an entity prototype ({next.Entity}) without a ConstructionComponent.");
#pragma warning restore NUnit2045
}
await pairTracker.CleanReturnAsync();
}

View File

@@ -1,6 +1,4 @@
using System.Threading.Tasks;
using Content.IntegrationTests.Tests.Interaction;
using NUnit.Framework;
namespace Content.IntegrationTests.Tests.Construction.Interaction;

View File

@@ -1,8 +1,6 @@
using System.Linq;
using System.Threading.Tasks;
using Content.IntegrationTests.Tests.Interaction;
using Content.Shared.Stacks;
using NUnit.Framework;
using Robust.Shared.Containers;
namespace Content.IntegrationTests.Tests.Construction.Interaction;
@@ -80,48 +78,67 @@ public sealed class CraftingTests : InteractionTest
await RunTicks(5);
var sys = SEntMan.System<SharedContainerSystem>();
Assert.Multiple(() =>
{
Assert.That(sys.IsEntityInContainer(rods), Is.False);
Assert.That(sys.IsEntityInContainer(wires), Is.False);
Assert.That(sys.IsEntityInContainer(shard), Is.False);
});
#pragma warning disable CS4014 // Legacy construction code uses DoAfterAwait. If we await it we will be waiting forever.
await Server.WaitPost(() => SConstruction.TryStartItemConstruction(Spear, Player));
#pragma warning restore CS4014
await RunTicks(1);
// DoAfter is in progress. Entity not spawned, stacks have been split and someingredients are in a container.
Assert.Multiple(async () =>
{
Assert.That(ActiveDoAfters.Count(), Is.EqualTo(1));
Assert.That(sys.IsEntityInContainer(shard), Is.True);
Assert.That(sys.IsEntityInContainer(rods), Is.False);
Assert.That(sys.IsEntityInContainer(wires), Is.False);
Assert.That(rodStack.Count, Is.EqualTo(8));
Assert.That(wireStack.Count, Is.EqualTo(8));
Assert.That(rodStack, Has.Count.EqualTo(8));
Assert.That(wireStack, Has.Count.EqualTo(8));
await FindEntity(Spear, shouldSucceed: false);
});
// Cancel the DoAfter. Should drop ingredients to the floor.
await CancelDoAfters();
Assert.Multiple(async () =>
{
Assert.That(sys.IsEntityInContainer(rods), Is.False);
Assert.That(sys.IsEntityInContainer(wires), Is.False);
Assert.That(sys.IsEntityInContainer(shard), Is.False);
await FindEntity(Spear, shouldSucceed: false);
await AssertEntityLookup((Rod, 10), (Cable, 10), (ShardGlass, 1));
});
// Re-attempt the do-after
#pragma warning disable CS4014 // Legacy construction code uses DoAfterAwait. See above.
await Server.WaitPost(() => SConstruction.TryStartItemConstruction(Spear, Player));
#pragma warning restore CS4014
await RunTicks(1);
// DoAfter is in progress. Entity not spawned, ingredients are in a container.
Assert.Multiple(async () =>
{
Assert.That(ActiveDoAfters.Count(), Is.EqualTo(1));
Assert.That(sys.IsEntityInContainer(shard), Is.True);
await FindEntity(Spear, shouldSucceed: false);
});
// Finish the DoAfter
await AwaitDoAfters();
// Spear has been crafted. Rods and wires are no longer contained. Glass has been consumed.
Assert.Multiple(async () =>
{
await FindEntity(Spear);
Assert.That(sys.IsEntityInContainer(rods), Is.False);
Assert.That(sys.IsEntityInContainer(wires), Is.False);
Assert.That(SEntMan.Deleted(shard));
});
}
#endif
}

View File

@@ -1,7 +1,5 @@
using System.Threading.Tasks;
using Content.IntegrationTests.Tests.Interaction;
using Content.Shared.Construction.Prototypes;
using NUnit.Framework;
using Robust.Shared.Maths;
namespace Content.IntegrationTests.Tests.Construction.Interaction;

View File

@@ -1,6 +1,4 @@
using System.Threading.Tasks;
using Content.IntegrationTests.Tests.Interaction;
using NUnit.Framework;
namespace Content.IntegrationTests.Tests.Construction.Interaction;

View File

@@ -1,7 +1,5 @@
using System.Threading.Tasks;
using Content.IntegrationTests.Tests.Interaction;
using Content.Shared.Wires;
using NUnit.Framework;
namespace Content.IntegrationTests.Tests.Construction.Interaction;

View File

@@ -1,7 +1,5 @@
using System.Threading.Tasks;
using Content.IntegrationTests.Tests.Interaction;
using Content.Shared.Placeable;
using NUnit.Framework;
namespace Content.IntegrationTests.Tests.Construction.Interaction;

View File

@@ -1,6 +1,4 @@
using System.Threading.Tasks;
using Content.IntegrationTests.Tests.Interaction;
using NUnit.Framework;
namespace Content.IntegrationTests.Tests.Construction.Interaction;
@@ -15,10 +13,10 @@ public sealed class WallConstruction : InteractionTest
{
await StartConstruction(Wall);
await Interact(Steel, 2);
Assert.IsNull(Hands.ActiveHandEntity);
Assert.That(Hands.ActiveHandEntity, Is.Null);
AssertPrototype(Girder);
await Interact(Steel, 2);
Assert.IsNull(Hands.ActiveHandEntity);
Assert.That(Hands.ActiveHandEntity, Is.Null);
AssertPrototype(WallSolid);
}
@@ -33,4 +31,3 @@ public sealed class WallConstruction : InteractionTest
await AssertEntityLookup((Steel, 4));
}
}

View File

@@ -1,6 +1,4 @@
using System.Threading.Tasks;
using Content.IntegrationTests.Tests.Interaction;
using NUnit.Framework;
namespace Content.IntegrationTests.Tests.Construction.Interaction;

View File

@@ -1,9 +1,7 @@
using System.Threading.Tasks;
using Content.IntegrationTests.Tests.Interaction;
using Content.Shared.Damage;
using Content.Shared.Damage.Prototypes;
using Content.Shared.FixedPoint;
using NUnit.Framework;
using Robust.Shared.Prototypes;
namespace Content.IntegrationTests.Tests.Construction.Interaction;

View File

@@ -1,11 +1,6 @@
using System.Linq;
using System.Threading.Tasks;
using Content.Server.Storage.Components;
using Content.Server.Storage.EntitySystems;
using NUnit.Framework;
using Robust.Client.GameObjects;
using Robust.Shared.GameObjects;
using Robust.Shared.IoC;
using Robust.Shared.Map;
using Robust.Shared.Maths;
@@ -37,7 +32,7 @@ namespace Content.IntegrationTests.Tests
[Test]
public async Task TestA()
{
await using var pairTracker = await PoolManager.GetServerClient(new PoolSettings{ExtraPrototypes = Prototypes});
await using var pairTracker = await PoolManager.GetServerClient(new PoolSettings { ExtraPrototypes = Prototypes });
var s = pairTracker.Pair.Server;
var c = pairTracker.Pair.Client;
@@ -64,8 +59,11 @@ namespace Content.IntegrationTests.Tests
{
var sprite = cEntities.GetComponent<SpriteComponent>(dummy);
var light = cEntities.GetComponent<PointLightComponent>(dummy);
Assert.True(sprite.ContainerOccluded);
Assert.True(light.ContainerOccluded);
Assert.Multiple(() =>
{
Assert.That(sprite.ContainerOccluded);
Assert.That(light.ContainerOccluded);
});
});
await pairTracker.CleanReturnAsync();
@@ -74,7 +72,7 @@ namespace Content.IntegrationTests.Tests
[Test]
public async Task TestB()
{
await using var pairTracker = await PoolManager.GetServerClient(new PoolSettings{ExtraPrototypes = Prototypes});
await using var pairTracker = await PoolManager.GetServerClient(new PoolSettings { ExtraPrototypes = Prototypes });
var s = pairTracker.Pair.Server;
var c = pairTracker.Pair.Client;
@@ -101,8 +99,11 @@ namespace Content.IntegrationTests.Tests
{
var sprite = cEntities.GetComponent<SpriteComponent>(dummy);
var light = cEntities.GetComponent<PointLightComponent>(dummy);
Assert.False(sprite.ContainerOccluded);
Assert.False(light.ContainerOccluded);
Assert.Multiple(() =>
{
Assert.That(sprite.ContainerOccluded, Is.False);
Assert.That(light.ContainerOccluded, Is.False);
});
});
await pairTracker.CleanReturnAsync();
@@ -111,7 +112,7 @@ namespace Content.IntegrationTests.Tests
[Test]
public async Task TestAb()
{
await using var pairTracker = await PoolManager.GetServerClient(new PoolSettings{ExtraPrototypes = Prototypes});
await using var pairTracker = await PoolManager.GetServerClient(new PoolSettings { ExtraPrototypes = Prototypes });
var s = pairTracker.Pair.Server;
var c = pairTracker.Pair.Client;
@@ -140,8 +141,11 @@ namespace Content.IntegrationTests.Tests
{
var sprite = cEntities.GetComponent<SpriteComponent>(dummy);
var light = cEntities.GetComponent<PointLightComponent>(dummy);
Assert.True(sprite.ContainerOccluded);
Assert.True(light.ContainerOccluded);
Assert.Multiple(() =>
{
Assert.That(sprite.ContainerOccluded);
Assert.That(light.ContainerOccluded);
});
});
await pairTracker.CleanReturnAsync();

View File

@@ -1,7 +1,6 @@
using System.Collections.Generic;
using Content.Shared.Damage;
using Content.Shared.FixedPoint;
using NUnit.Framework;
namespace Content.IntegrationTests.Tests.Damageable;
@@ -23,9 +22,12 @@ public sealed class DamageSpecifierTest
DamageSpecifier output4 = new() { DamageDict = _output4 };
DamageSpecifier output5 = new() { DamageDict = _output5 };
Assert.Multiple(() =>
{
Assert.That((-input1).Equals(output1));
Assert.That((input1 / 2).Equals(output2));
Assert.That((input1 * 2).Equals(output3));
});
var difference = (input1 - input2);
Assert.That(difference.Equals(output4));

View File

@@ -1,9 +1,7 @@
using System.Linq;
using System.Threading.Tasks;
using Content.Shared.Damage;
using Content.Shared.Damage.Prototypes;
using Content.Shared.FixedPoint;
using NUnit.Framework;
using Robust.Shared.GameObjects;
using Robust.Shared.IoC;
using Robust.Shared.Map;
@@ -74,7 +72,11 @@ namespace Content.IntegrationTests.Tests.Damageable
[Test]
public async Task TestDamageableComponents()
{
await using var pairTracker = await PoolManager.GetServerClient(new PoolSettings{NoClient = true, ExtraPrototypes = Prototypes});
await using var pairTracker = await PoolManager.GetServerClient(new PoolSettings
{
NoClient = true,
ExtraPrototypes = Prototypes
});
var server = pairTracker.Pair.Server;
var sEntityManager = server.ResolveDependency<IEntityManager>();
@@ -97,7 +99,7 @@ namespace Content.IntegrationTests.Tests.Damageable
DamageTypePrototype type3b = default!;
DamageTypePrototype type3c = default!;
FixedPoint2 typeDamage, groupDamage;
FixedPoint2 typeDamage;
await server.WaitPost(() =>
{
@@ -127,31 +129,39 @@ namespace Content.IntegrationTests.Tests.Damageable
var uid = sDamageableEntity;
// Check that the correct types are supported.
Assert.Multiple(() =>
{
Assert.That(sDamageableComponent.Damage.DamageDict.ContainsKey(type1.ID), Is.False);
Assert.That(sDamageableComponent.Damage.DamageDict.ContainsKey(type2a.ID), Is.True);
Assert.That(sDamageableComponent.Damage.DamageDict.ContainsKey(type2b.ID), Is.False);
Assert.That(sDamageableComponent.Damage.DamageDict.ContainsKey(type3a.ID), Is.True);
Assert.That(sDamageableComponent.Damage.DamageDict.ContainsKey(type3b.ID), Is.True);
Assert.That(sDamageableComponent.Damage.DamageDict.ContainsKey(type3c.ID), Is.True);
});
// Check that damage is evenly distributed over a group if its a nice multiple
var types = group3.DamageTypes;
var damageToDeal = FixedPoint2.New(types.Count() * 5);
var damageToDeal = FixedPoint2.New(types.Count * 5);
DamageSpecifier damage = new(group3, damageToDeal);
sDamageableSystem.TryChangeDamage(uid, damage, true);
Assert.Multiple(() =>
{
Assert.That(sDamageableComponent.TotalDamage, Is.EqualTo(damageToDeal));
Assert.That(sDamageableComponent.DamagePerGroup[group3.ID], Is.EqualTo(damageToDeal));
foreach (var type in types)
{
Assert.That(sDamageableComponent.Damage.DamageDict.TryGetValue(type, out typeDamage));
Assert.That(typeDamage, Is.EqualTo(damageToDeal / types.Count()));
Assert.That(typeDamage, Is.EqualTo(damageToDeal / types.Count));
}
});
// Heal
sDamageableSystem.TryChangeDamage(uid, -damage);
Assert.Multiple(() =>
{
Assert.That(sDamageableComponent.TotalDamage, Is.EqualTo(FixedPoint2.Zero));
Assert.That(sDamageableComponent.DamagePerGroup[group3.ID], Is.EqualTo(FixedPoint2.Zero));
foreach (var type in types)
@@ -159,23 +169,30 @@ namespace Content.IntegrationTests.Tests.Damageable
Assert.That(sDamageableComponent.Damage.DamageDict.TryGetValue(type, out typeDamage));
Assert.That(typeDamage, Is.EqualTo(FixedPoint2.Zero));
}
});
// Check that damage works properly if it is NOT perfectly divisible among group members
types = group3.DamageTypes;
damageToDeal = FixedPoint2.New(types.Count() * 5 - 1);
damageToDeal = FixedPoint2.New(types.Count * 5 - 1);
damage = new DamageSpecifier(group3, damageToDeal);
sDamageableSystem.TryChangeDamage(uid, damage, true);
Assert.Multiple(() =>
{
Assert.That(sDamageableComponent.TotalDamage, Is.EqualTo(damageToDeal));
Assert.That(sDamageableComponent.DamagePerGroup[group3.ID], Is.EqualTo(damageToDeal));
Assert.That(sDamageableComponent.Damage.DamageDict[type3a.ID], Is.EqualTo(damageToDeal / types.Count()));
Assert.That(sDamageableComponent.Damage.DamageDict[type3b.ID], Is.EqualTo(damageToDeal / types.Count()));
Assert.That(sDamageableComponent.Damage.DamageDict[type3a.ID], Is.EqualTo(damageToDeal / types.Count));
Assert.That(sDamageableComponent.Damage.DamageDict[type3b.ID], Is.EqualTo(damageToDeal / types.Count));
// last one will get 0.01 less, since its not perfectly divisble by 3
Assert.That(sDamageableComponent.Damage.DamageDict[type3c.ID], Is.EqualTo(damageToDeal / types.Count() - 0.01));
Assert.That(sDamageableComponent.Damage.DamageDict[type3c.ID], Is.EqualTo(damageToDeal / types.Count - 0.01));
});
// Heal
sDamageableSystem.TryChangeDamage(uid, -damage);
Assert.Multiple(() =>
{
Assert.That(sDamageableComponent.TotalDamage, Is.EqualTo(FixedPoint2.Zero));
Assert.That(sDamageableComponent.DamagePerGroup[group3.ID], Is.EqualTo(FixedPoint2.Zero));
foreach (var type in types)
@@ -186,15 +203,20 @@ namespace Content.IntegrationTests.Tests.Damageable
// Test that unsupported groups return false when setting/getting damage (and don't change damage)
Assert.That(sDamageableComponent.TotalDamage, Is.EqualTo(FixedPoint2.Zero));
});
damage = new DamageSpecifier(group1, FixedPoint2.New(10)) + new DamageSpecifier(type2b, FixedPoint2.New(10));
sDamageableSystem.TryChangeDamage(uid, damage, true);
Assert.That(sDamageableComponent.DamagePerGroup.TryGetValue(group1.ID, out groupDamage), Is.False);
Assert.Multiple(() =>
{
Assert.That(sDamageableComponent.DamagePerGroup.TryGetValue(group1.ID, out _), Is.False);
Assert.That(sDamageableComponent.Damage.DamageDict.TryGetValue(type1.ID, out typeDamage), Is.False);
Assert.That(sDamageableComponent.TotalDamage, Is.EqualTo(FixedPoint2.Zero));
});
// Test SetAll function
sDamageableSystem.SetAllDamage(sDamageableEntity, sDamageableComponent, 10);
Assert.That(sDamageableComponent.TotalDamage, Is.EqualTo(FixedPoint2.New(10 * sDamageableComponent.Damage.DamageDict.Count())));
Assert.That(sDamageableComponent.TotalDamage, Is.EqualTo(FixedPoint2.New(10 * sDamageableComponent.Damage.DamageDict.Count)));
sDamageableSystem.SetAllDamage(sDamageableEntity, sDamageableComponent, 0);
Assert.That(sDamageableComponent.TotalDamage, Is.EqualTo(FixedPoint2.Zero));
@@ -202,9 +224,13 @@ namespace Content.IntegrationTests.Tests.Damageable
sDamageableSystem.TryChangeDamage(uid, new DamageSpecifier(type3a, 5));
sDamageableSystem.TryChangeDamage(uid, new DamageSpecifier(type3b, 7));
sDamageableSystem.TryChangeDamage(uid, new DamageSpecifier(group3, -11));
Assert.Multiple(() =>
{
Assert.That(sDamageableComponent.Damage.DamageDict[type3a.ID], Is.EqualTo(FixedPoint2.New(1.33)));
Assert.That(sDamageableComponent.Damage.DamageDict[type3b.ID], Is.EqualTo(FixedPoint2.New(3.33)));
Assert.That(sDamageableComponent.Damage.DamageDict[type3c.ID], Is.EqualTo(FixedPoint2.New(0)));
});
// Test Over-Healing
sDamageableSystem.TryChangeDamage(uid, new DamageSpecifier(group3, FixedPoint2.New(-100)));

View File

@@ -1,11 +1,8 @@
using System.Threading.Tasks;
using Content.Shared.Clothing.Components;
using Content.Shared.Clothing.EntitySystems;
using Content.Shared.Inventory;
using NUnit.Framework;
using Robust.Shared.Containers;
using Robust.Shared.GameObjects;
using Robust.Shared.IoC;
namespace Content.IntegrationTests.Tests
{
@@ -17,7 +14,7 @@ namespace Content.IntegrationTests.Tests
[Test]
public async Task Test()
{
await using var pairTracker = await PoolManager.GetServerClient(new PoolSettings{NoClient = true});
await using var pairTracker = await PoolManager.GetServerClient(new PoolSettings { NoClient = true });
var server = pairTracker.Pair.Server;
var testMap = await PoolManager.CreateTestMap(pairTracker);
var entMgr = server.ResolveDependency<IEntityManager>();

View File

@@ -1,9 +1,7 @@
using System.Threading.Tasks;
using Content.Server.Destructible.Thresholds.Triggers;
using Content.Shared.Damage;
using Content.Shared.Damage.Prototypes;
using Content.Shared.FixedPoint;
using NUnit.Framework;
using Robust.Shared.GameObjects;
using Robust.Shared.IoC;
using Robust.Shared.Map;
@@ -20,7 +18,11 @@ namespace Content.IntegrationTests.Tests.Destructible
[Test]
public async Task AndTest()
{
await using var pairTracker = await PoolManager.GetServerClient(new PoolSettings{NoClient = true, ExtraPrototypes = Prototypes});
await using var pairTracker = await PoolManager.GetServerClient(new PoolSettings
{
NoClient = true,
ExtraPrototypes = Prototypes
});
var server = pairTracker.Pair.Server;
var testMap = await PoolManager.CreateTestMap(pairTracker);
@@ -51,7 +53,7 @@ namespace Content.IntegrationTests.Tests.Destructible
await server.WaitAssertion(() =>
{
Assert.IsEmpty(sTestThresholdListenerSystem.ThresholdsReached);
Assert.That(sTestThresholdListenerSystem.ThresholdsReached, Is.Empty);
});
await server.WaitAssertion(() =>
@@ -66,34 +68,40 @@ namespace Content.IntegrationTests.Tests.Destructible
sDamageableSystem.TryChangeDamage(sDestructibleEntity, bruteDamage, true);
// No thresholds reached yet, the earliest one is at 10 damage
Assert.IsEmpty(sTestThresholdListenerSystem.ThresholdsReached);
Assert.That(sTestThresholdListenerSystem.ThresholdsReached, Is.Empty);
// Raise brute damage to 10
sDamageableSystem.TryChangeDamage(sDestructibleEntity, bruteDamage, true);
// No threshold reached, burn needs to be 10 as well
Assert.IsEmpty(sTestThresholdListenerSystem.ThresholdsReached);
Assert.That(sTestThresholdListenerSystem.ThresholdsReached, Is.Empty);
// Raise burn damage to 10
sDamageableSystem.TryChangeDamage(sDestructibleEntity, burnDamage * 2, true);
// One threshold reached, brute 10 + burn 10
Assert.That(sTestThresholdListenerSystem.ThresholdsReached.Count, Is.EqualTo(1));
Assert.That(sTestThresholdListenerSystem.ThresholdsReached, Has.Count.EqualTo(1));
// Threshold brute 10 + burn 10
var msg = sTestThresholdListenerSystem.ThresholdsReached[0];
var threshold = msg.Threshold;
// Check that it matches the YAML prototype
Assert.Multiple(() =>
{
Assert.That(threshold.Behaviors, Is.Empty);
Assert.NotNull(threshold.Trigger);
Assert.That(threshold.Trigger, Is.Not.Null);
Assert.That(threshold.Triggered, Is.True);
Assert.IsInstanceOf<AndTrigger>(threshold.Trigger);
Assert.That(threshold.Trigger, Is.InstanceOf<AndTrigger>());
});
var trigger = (AndTrigger) threshold.Trigger;
Assert.IsInstanceOf<DamageGroupTrigger>(trigger.Triggers[0]);
Assert.IsInstanceOf<DamageGroupTrigger>(trigger.Triggers[1]);
Assert.Multiple(() =>
{
Assert.That(trigger.Triggers[0], Is.InstanceOf<DamageGroupTrigger>());
Assert.That(trigger.Triggers[1], Is.InstanceOf<DamageGroupTrigger>());
});
sTestThresholdListenerSystem.ThresholdsReached.Clear();
@@ -101,26 +109,29 @@ namespace Content.IntegrationTests.Tests.Destructible
sDamageableSystem.TryChangeDamage(sDestructibleEntity, bruteDamage * 2, true);
// No new thresholds reached
Assert.IsEmpty(sTestThresholdListenerSystem.ThresholdsReached);
Assert.That(sTestThresholdListenerSystem.ThresholdsReached, Is.Empty);
// Raise burn damage to 20
sDamageableSystem.TryChangeDamage(sDestructibleEntity, burnDamage * 2, true);
// No new thresholds reached
Assert.IsEmpty(sTestThresholdListenerSystem.ThresholdsReached);
Assert.That(sTestThresholdListenerSystem.ThresholdsReached, Is.Empty);
// Lower brute damage to 0
sDamageableSystem.TryChangeDamage(sDestructibleEntity, bruteDamage * -10);
Assert.That(sDamageableComponent.TotalDamage,Is.EqualTo(FixedPoint2.New(20)));
Assert.Multiple(() =>
{
Assert.That(sDamageableComponent.TotalDamage, Is.EqualTo(FixedPoint2.New(20)));
// No new thresholds reached, healing should not trigger it
Assert.IsEmpty(sTestThresholdListenerSystem.ThresholdsReached);
Assert.That(sTestThresholdListenerSystem.ThresholdsReached, Is.Empty);
});
// Raise brute damage back up to 10
sDamageableSystem.TryChangeDamage(sDestructibleEntity, bruteDamage * 2, true);
// 10 brute + 10 burn threshold reached, brute was healed and brought back to its threshold amount and slash stayed the same
Assert.That(sTestThresholdListenerSystem.ThresholdsReached.Count, Is.EqualTo(1));
Assert.That(sTestThresholdListenerSystem.ThresholdsReached, Has.Count.EqualTo(1));
sTestThresholdListenerSystem.ThresholdsReached.Clear();
@@ -128,34 +139,40 @@ namespace Content.IntegrationTests.Tests.Destructible
sDamageableSystem.SetAllDamage(sDestructibleEntity, sDamageableComponent, 0);
// No new thresholds reached, healing should not trigger it
Assert.IsEmpty(sTestThresholdListenerSystem.ThresholdsReached);
Assert.That(sTestThresholdListenerSystem.ThresholdsReached, Is.Empty);
// Raise brute damage to 10
sDamageableSystem.TryChangeDamage(sDestructibleEntity, bruteDamage * 2, true);
// No new thresholds reached
Assert.IsEmpty(sTestThresholdListenerSystem.ThresholdsReached);
Assert.That(sTestThresholdListenerSystem.ThresholdsReached, Is.Empty);
// Raise burn damage to 10
sDamageableSystem.TryChangeDamage(sDestructibleEntity, burnDamage * 2, true);
// Both classes of damage were healed and then raised again, the threshold should have been reached as triggers once is default false
Assert.That(sTestThresholdListenerSystem.ThresholdsReached.Count, Is.EqualTo(1));
Assert.That(sTestThresholdListenerSystem.ThresholdsReached, Has.Count.EqualTo(1));
// Threshold brute 10 + burn 10
msg = sTestThresholdListenerSystem.ThresholdsReached[0];
threshold = msg.Threshold;
// Check that it matches the YAML prototype
Assert.Multiple(() =>
{
Assert.That(threshold.Behaviors, Is.Empty);
Assert.NotNull(threshold.Trigger);
Assert.That(threshold.Trigger, Is.Not.Null);
Assert.That(threshold.Triggered, Is.True);
Assert.IsInstanceOf<AndTrigger>(threshold.Trigger);
Assert.That(threshold.Trigger, Is.InstanceOf<AndTrigger>());
});
trigger = (AndTrigger) threshold.Trigger;
Assert.IsInstanceOf<DamageGroupTrigger>(trigger.Triggers[0]);
Assert.IsInstanceOf<DamageGroupTrigger>(trigger.Triggers[1]);
Assert.Multiple(() =>
{
Assert.That(trigger.Triggers[0], Is.InstanceOf<DamageGroupTrigger>());
Assert.That(trigger.Triggers[1], Is.InstanceOf<DamageGroupTrigger>());
});
sTestThresholdListenerSystem.ThresholdsReached.Clear();
@@ -166,19 +183,19 @@ namespace Content.IntegrationTests.Tests.Destructible
sDamageableSystem.SetAllDamage(sDestructibleEntity, sDamageableComponent, 0);
// No new thresholds reached from healing
Assert.IsEmpty(sTestThresholdListenerSystem.ThresholdsReached);
Assert.That(sTestThresholdListenerSystem.ThresholdsReached, Is.Empty);
// Raise brute damage to 10
sDamageableSystem.TryChangeDamage(sDestructibleEntity, bruteDamage * 2, true);
// No new thresholds reached
Assert.IsEmpty(sTestThresholdListenerSystem.ThresholdsReached);
Assert.That(sTestThresholdListenerSystem.ThresholdsReached, Is.Empty);
// Raise burn damage to 10
sDamageableSystem.TryChangeDamage(sDestructibleEntity, burnDamage * 2, true);
// No new thresholds reached as triggers once is set to true and it already triggered before
Assert.IsEmpty(sTestThresholdListenerSystem.ThresholdsReached);
Assert.That(sTestThresholdListenerSystem.ThresholdsReached, Is.Empty);
});
await pairTracker.CleanReturnAsync();
}

View File

@@ -1,11 +1,7 @@
using System.Threading.Tasks;
using Content.Server.Destructible.Thresholds.Triggers;
using Content.Shared.Damage;
using Content.Shared.Damage.Prototypes;
using NUnit.Framework;
using Robust.Shared.GameObjects;
using Robust.Shared.IoC;
using Robust.Shared.Map;
using Robust.Shared.Prototypes;
using static Content.IntegrationTests.Tests.Destructible.DestructibleTestPrototypes;
@@ -19,7 +15,11 @@ namespace Content.IntegrationTests.Tests.Destructible
[Test]
public async Task Test()
{
await using var pairTracker = await PoolManager.GetServerClient(new PoolSettings{NoClient = true, ExtraPrototypes = Prototypes});
await using var pairTracker = await PoolManager.GetServerClient(new PoolSettings
{
NoClient = true,
ExtraPrototypes = Prototypes
});
var server = pairTracker.Pair.Server;
var testMap = await PoolManager.CreateTestMap(pairTracker);
@@ -48,7 +48,7 @@ namespace Content.IntegrationTests.Tests.Destructible
await server.WaitAssertion(() =>
{
Assert.IsEmpty(sTestThresholdListenerSystem.ThresholdsReached);
Assert.That(sTestThresholdListenerSystem.ThresholdsReached, Is.Empty);
});
await server.WaitAssertion(() =>
@@ -56,41 +56,47 @@ namespace Content.IntegrationTests.Tests.Destructible
var bluntDamageType = protoManager.Index<DamageTypePrototype>("TestBlunt");
var slashDamageType = protoManager.Index<DamageTypePrototype>("TestSlash");
var bluntDamage = new DamageSpecifier(bluntDamageType,5);
var slashDamage = new DamageSpecifier(slashDamageType,5);
var bluntDamage = new DamageSpecifier(bluntDamageType, 5);
var slashDamage = new DamageSpecifier(slashDamageType, 5);
// Raise blunt damage to 5
sDamageableSystem.TryChangeDamage(sDestructibleEntity, bluntDamage, true);
// No thresholds reached yet, the earliest one is at 10 damage
Assert.IsEmpty(sTestThresholdListenerSystem.ThresholdsReached);
Assert.That(sTestThresholdListenerSystem.ThresholdsReached, Is.Empty);
// Raise blunt damage to 10
sDamageableSystem.TryChangeDamage(sDestructibleEntity, bluntDamage, true);
// No threshold reached, slash needs to be 10 as well
Assert.IsEmpty(sTestThresholdListenerSystem.ThresholdsReached);
Assert.That(sTestThresholdListenerSystem.ThresholdsReached, Is.Empty);
// Raise slash damage to 10
sDamageableSystem.TryChangeDamage(sDestructibleEntity, slashDamage * 2, true);
// One threshold reached, blunt 10 + slash 10
Assert.That(sTestThresholdListenerSystem.ThresholdsReached.Count, Is.EqualTo(1));
Assert.That(sTestThresholdListenerSystem.ThresholdsReached, Has.Count.EqualTo(1));
// Threshold blunt 10 + slash 10
var msg = sTestThresholdListenerSystem.ThresholdsReached[0];
var threshold = msg.Threshold;
// Check that it matches the YAML prototype
Assert.Multiple(() =>
{
Assert.That(threshold.Behaviors, Is.Empty);
Assert.NotNull(threshold.Trigger);
Assert.That(threshold.Trigger, Is.Not.Null);
Assert.That(threshold.Triggered, Is.True);
Assert.IsInstanceOf<AndTrigger>(threshold.Trigger);
Assert.That(threshold.Trigger, Is.InstanceOf<AndTrigger>());
});
var trigger = (AndTrigger) threshold.Trigger;
Assert.IsInstanceOf<DamageTypeTrigger>(trigger.Triggers[0]);
Assert.IsInstanceOf<DamageTypeTrigger>(trigger.Triggers[1]);
Assert.Multiple(() =>
{
Assert.That(trigger.Triggers[0], Is.InstanceOf<DamageTypeTrigger>());
Assert.That(trigger.Triggers[1], Is.InstanceOf<DamageTypeTrigger>());
});
sTestThresholdListenerSystem.ThresholdsReached.Clear();
@@ -98,25 +104,25 @@ namespace Content.IntegrationTests.Tests.Destructible
sDamageableSystem.TryChangeDamage(sDestructibleEntity, bluntDamage * 2, true);
// No new thresholds reached
Assert.IsEmpty(sTestThresholdListenerSystem.ThresholdsReached);
Assert.That(sTestThresholdListenerSystem.ThresholdsReached, Is.Empty);
// Raise slash damage to 20
sDamageableSystem.TryChangeDamage(sDestructibleEntity, slashDamage * 2, true);
// No new thresholds reached
Assert.IsEmpty(sTestThresholdListenerSystem.ThresholdsReached);
Assert.That(sTestThresholdListenerSystem.ThresholdsReached, Is.Empty);
// Lower blunt damage to 0
sDamageableSystem.TryChangeDamage(sDestructibleEntity, bluntDamage * -4, true);
// No new thresholds reached, healing should not trigger it
Assert.IsEmpty(sTestThresholdListenerSystem.ThresholdsReached);
Assert.That(sTestThresholdListenerSystem.ThresholdsReached, Is.Empty);
// Raise blunt damage back up to 10
sDamageableSystem.TryChangeDamage(sDestructibleEntity, bluntDamage * 2, true);
// 10 blunt + 10 slash threshold reached, blunt was healed and brought back to its threshold amount and slash stayed the same
Assert.That(sTestThresholdListenerSystem.ThresholdsReached.Count, Is.EqualTo(1));
Assert.That(sTestThresholdListenerSystem.ThresholdsReached, Has.Count.EqualTo(1));
sTestThresholdListenerSystem.ThresholdsReached.Clear();
@@ -125,34 +131,40 @@ namespace Content.IntegrationTests.Tests.Destructible
sDamageableSystem.TryChangeDamage(sDestructibleEntity, slashDamage * -4, true);
// No new thresholds reached, healing should not trigger it
Assert.IsEmpty(sTestThresholdListenerSystem.ThresholdsReached);
Assert.That(sTestThresholdListenerSystem.ThresholdsReached, Is.Empty);
// Raise blunt damage to 10
sDamageableSystem.TryChangeDamage(sDestructibleEntity, bluntDamage * 2, true);
// No new thresholds reached
Assert.IsEmpty(sTestThresholdListenerSystem.ThresholdsReached);
Assert.That(sTestThresholdListenerSystem.ThresholdsReached, Is.Empty);
// Raise slash damage to 10
sDamageableSystem.TryChangeDamage(sDestructibleEntity, slashDamage * 2, true);
// Both types of damage were healed and then raised again, the threshold should have been reached as triggers once is default false
Assert.That(sTestThresholdListenerSystem.ThresholdsReached.Count, Is.EqualTo(1));
Assert.That(sTestThresholdListenerSystem.ThresholdsReached, Has.Count.EqualTo(1));
// Threshold blunt 10 + slash 10
msg = sTestThresholdListenerSystem.ThresholdsReached[0];
threshold = msg.Threshold;
// Check that it matches the YAML prototype
Assert.Multiple(() =>
{
Assert.That(threshold.Behaviors, Is.Empty);
Assert.NotNull(threshold.Trigger);
Assert.That(threshold.Trigger, Is.Not.Null);
Assert.That(threshold.Triggered, Is.True);
Assert.IsInstanceOf<AndTrigger>(threshold.Trigger);
Assert.That(threshold.Trigger, Is.InstanceOf<AndTrigger>());
});
trigger = (AndTrigger) threshold.Trigger;
Assert.IsInstanceOf<DamageTypeTrigger>(trigger.Triggers[0]);
Assert.IsInstanceOf<DamageTypeTrigger>(trigger.Triggers[1]);
Assert.Multiple(() =>
{
Assert.That(trigger.Triggers[0], Is.InstanceOf<DamageTypeTrigger>());
Assert.That(trigger.Triggers[1], Is.InstanceOf<DamageTypeTrigger>());
});
sTestThresholdListenerSystem.ThresholdsReached.Clear();
@@ -164,19 +176,19 @@ namespace Content.IntegrationTests.Tests.Destructible
sDamageableSystem.TryChangeDamage(sDestructibleEntity, slashDamage * -2, true);
// No new thresholds reached from healing
Assert.IsEmpty(sTestThresholdListenerSystem.ThresholdsReached);
Assert.That(sTestThresholdListenerSystem.ThresholdsReached, Is.Empty);
// Raise blunt damage to 10
sDamageableSystem.TryChangeDamage(sDestructibleEntity, bluntDamage * 2, true);
// No new thresholds reached
Assert.IsEmpty(sTestThresholdListenerSystem.ThresholdsReached);
Assert.That(sTestThresholdListenerSystem.ThresholdsReached, Is.Empty);
// Raise slash damage to 10
sDamageableSystem.TryChangeDamage(sDestructibleEntity, slashDamage * 2, true);
// No new thresholds reached as triggers once is set to true and it already triggered before
Assert.IsEmpty(sTestThresholdListenerSystem.ThresholdsReached);
Assert.That(sTestThresholdListenerSystem.ThresholdsReached, Is.Empty);
});
await pairTracker.CleanReturnAsync();
}

View File

@@ -1,13 +1,9 @@
using System.Linq;
using System.Threading.Tasks;
using Content.Server.Destructible.Thresholds;
using Content.Server.Destructible.Thresholds.Behaviors;
using Content.Shared.Damage;
using Content.Shared.Damage.Prototypes;
using NUnit.Framework;
using Robust.Shared.GameObjects;
using Robust.Shared.IoC;
using Robust.Shared.Map;
using Robust.Shared.Prototypes;
using static Content.IntegrationTests.Tests.Destructible.DestructibleTestPrototypes;
@@ -18,7 +14,11 @@ namespace Content.IntegrationTests.Tests.Destructible
[Test]
public async Task Test()
{
await using var pairTracker = await PoolManager.GetServerClient(new PoolSettings{NoClient = true, ExtraPrototypes = Prototypes});
await using var pairTracker = await PoolManager.GetServerClient(new PoolSettings
{
NoClient = true,
ExtraPrototypes = Prototypes
});
var server = pairTracker.Pair.Server;
var testMap = await PoolManager.CreateTestMap(pairTracker);
@@ -43,27 +43,35 @@ namespace Content.IntegrationTests.Tests.Destructible
{
var coordinates = sEntityManager.GetComponent<TransformComponent>(sDestructibleEntity).Coordinates;
var bruteDamageGroup = sPrototypeManager.Index<DamageGroupPrototype>("TestBrute");
DamageSpecifier bruteDamage = new(bruteDamageGroup,50);
DamageSpecifier bruteDamage = new(bruteDamageGroup, 50);
#pragma warning disable NUnit2045 // Interdependent assertions.
Assert.DoesNotThrow(() =>
{
EntitySystem.Get<DamageableSystem>().TryChangeDamage(sDestructibleEntity, bruteDamage, true);
sEntityManager.System<DamageableSystem>().TryChangeDamage(sDestructibleEntity, bruteDamage, true);
});
Assert.That(sTestThresholdListenerSystem.ThresholdsReached.Count, Is.EqualTo(1));
Assert.That(sTestThresholdListenerSystem.ThresholdsReached, Has.Count.EqualTo(1));
#pragma warning restore NUnit2045
var threshold = sTestThresholdListenerSystem.ThresholdsReached[0].Threshold;
Assert.Multiple(() =>
{
Assert.That(threshold.Triggered, Is.True);
Assert.That(threshold.Behaviors.Count, Is.EqualTo(3));
Assert.That(threshold.Behaviors, Has.Count.EqualTo(3));
});
var spawnEntitiesBehavior = (SpawnEntitiesBehavior) threshold.Behaviors.Single(b => b is SpawnEntitiesBehavior);
Assert.That(spawnEntitiesBehavior.Spawn.Count, Is.EqualTo(1));
Assert.Multiple(() =>
{
Assert.That(spawnEntitiesBehavior.Spawn, Has.Count.EqualTo(1));
Assert.That(spawnEntitiesBehavior.Spawn.Keys.Single(), Is.EqualTo(SpawnedEntityId));
Assert.That(spawnEntitiesBehavior.Spawn.Values.Single(), Is.EqualTo(new MinMax {Min = 1, Max = 1}));
Assert.That(spawnEntitiesBehavior.Spawn.Values.Single(), Is.EqualTo(new MinMax { Min = 1, Max = 1 }));
});
var entitiesInRange = EntitySystem.Get<EntityLookupSystem>().GetEntitiesInRange(coordinates, 2);
var entitiesInRange = sEntityManager.System<EntityLookupSystem>().GetEntitiesInRange(coordinates, 2);
var found = false;
foreach (var entity in entitiesInRange)

View File

@@ -1,5 +1,4 @@
using System.Linq;
using System.Threading.Tasks;
using Content.Server.Destructible;
using Content.Server.Destructible.Thresholds;
using Content.Server.Destructible.Thresholds.Behaviors;
@@ -7,10 +6,7 @@ using Content.Server.Destructible.Thresholds.Triggers;
using Content.Shared.Damage;
using Content.Shared.Damage.Prototypes;
using Content.Shared.FixedPoint;
using NUnit.Framework;
using Robust.Shared.GameObjects;
using Robust.Shared.IoC;
using Robust.Shared.Map;
using Robust.Shared.Prototypes;
using static Content.IntegrationTests.Tests.Destructible.DestructibleTestPrototypes;
@@ -24,7 +20,11 @@ namespace Content.IntegrationTests.Tests.Destructible
[Test]
public async Task Test()
{
await using var pairTracker = await PoolManager.GetServerClient(new PoolSettings{NoClient = true, ExtraPrototypes = Prototypes});
await using var pairTracker = await PoolManager.GetServerClient(new PoolSettings
{
NoClient = true,
ExtraPrototypes = Prototypes
});
var server = pairTracker.Pair.Server;
var sEntityManager = server.ResolveDependency<IEntityManager>();
@@ -58,7 +58,7 @@ namespace Content.IntegrationTests.Tests.Destructible
await server.WaitAssertion(() =>
{
Assert.IsEmpty(sTestThresholdListenerSystem.ThresholdsReached);
Assert.That(sTestThresholdListenerSystem.ThresholdsReached, Is.Empty);
});
await server.WaitAssertion(() =>
@@ -68,28 +68,31 @@ namespace Content.IntegrationTests.Tests.Destructible
sDamageableSystem.TryChangeDamage(sDestructibleEntity, bluntDamage, true);
// No thresholds reached yet, the earliest one is at 20 damage
Assert.IsEmpty(sTestThresholdListenerSystem.ThresholdsReached);
Assert.That(sTestThresholdListenerSystem.ThresholdsReached, Is.Empty);
sDamageableSystem.TryChangeDamage(sDestructibleEntity, bluntDamage, true);
// Only one threshold reached, 20
Assert.That(sTestThresholdListenerSystem.ThresholdsReached.Count, Is.EqualTo(1));
Assert.That(sTestThresholdListenerSystem.ThresholdsReached, Has.Count.EqualTo(1));
// Threshold 20
var msg = sTestThresholdListenerSystem.ThresholdsReached[0];
var threshold = msg.Threshold;
// Check that it matches the YAML prototype
Assert.Multiple(() =>
{
Assert.That(threshold.Behaviors, Is.Empty);
Assert.NotNull(threshold.Trigger);
Assert.That(threshold.Trigger, Is.Not.Null);
Assert.That(threshold.Triggered, Is.True);
});
sTestThresholdListenerSystem.ThresholdsReached.Clear();
sDamageableSystem.TryChangeDamage(sDestructibleEntity, bluntDamage*3, true);
sDamageableSystem.TryChangeDamage(sDestructibleEntity, bluntDamage * 3, true);
// One threshold reached, 50, since 20 already triggered before and it has not been healed below that amount
Assert.That(sTestThresholdListenerSystem.ThresholdsReached.Count, Is.EqualTo(1));
Assert.That(sTestThresholdListenerSystem.ThresholdsReached, Has.Count.EqualTo(1));
// Threshold 50
msg = sTestThresholdListenerSystem.ThresholdsReached[0];
@@ -102,6 +105,8 @@ namespace Content.IntegrationTests.Tests.Destructible
var spawnThreshold = (SpawnEntitiesBehavior) threshold.Behaviors[1];
var actsThreshold = (DoActsBehavior) threshold.Behaviors[2];
Assert.Multiple(() =>
{
Assert.That(actsThreshold.Acts, Is.EqualTo(ThresholdActs.Breakage));
Assert.That(audio.GetSound(soundThreshold.Sound), Is.EqualTo("/Audio/Effects/woodhit.ogg"));
Assert.That(spawnThreshold.Spawn, Is.Not.Null);
@@ -109,30 +114,31 @@ namespace Content.IntegrationTests.Tests.Destructible
Assert.That(spawnThreshold.Spawn.Single().Key, Is.EqualTo(SpawnedEntityId));
Assert.That(spawnThreshold.Spawn.Single().Value.Min, Is.EqualTo(1));
Assert.That(spawnThreshold.Spawn.Single().Value.Max, Is.EqualTo(1));
Assert.NotNull(threshold.Trigger);
Assert.That(threshold.Trigger, Is.Not.Null);
Assert.That(threshold.Triggered, Is.True);
});
sTestThresholdListenerSystem.ThresholdsReached.Clear();
// Damage for 50 again, up to 100 now
sDamageableSystem.TryChangeDamage(sDestructibleEntity, bluntDamage*5, true);
sDamageableSystem.TryChangeDamage(sDestructibleEntity, bluntDamage * 5, true);
// No thresholds reached as they weren't healed below the trigger amount
Assert.IsEmpty(sTestThresholdListenerSystem.ThresholdsReached);
Assert.That(sTestThresholdListenerSystem.ThresholdsReached, Is.Empty);
// Set damage to 0
sDamageableSystem.SetAllDamage(sDestructibleEntity, sDamageableComponent, 0);
// Damage for 100, up to 100
sDamageableSystem.TryChangeDamage(sDestructibleEntity, bluntDamage*10, true);
sDamageableSystem.TryChangeDamage(sDestructibleEntity, bluntDamage * 10, true);
// Two thresholds reached as damage increased past the previous, 20 and 50
Assert.That(sTestThresholdListenerSystem.ThresholdsReached.Count, Is.EqualTo(2));
Assert.That(sTestThresholdListenerSystem.ThresholdsReached, Has.Count.EqualTo(2));
sTestThresholdListenerSystem.ThresholdsReached.Clear();
// Heal the entity for 40 damage, down to 60
sDamageableSystem.TryChangeDamage(sDestructibleEntity, bluntDamage*-4, true);
sDamageableSystem.TryChangeDamage(sDestructibleEntity, bluntDamage * -4, true);
// ThresholdsLookup don't work backwards
Assert.That(sTestThresholdListenerSystem.ThresholdsReached, Is.Empty);
@@ -144,7 +150,7 @@ namespace Content.IntegrationTests.Tests.Destructible
Assert.That(sTestThresholdListenerSystem.ThresholdsReached, Is.Empty);
// Heal by 30, down to 40
sDamageableSystem.TryChangeDamage(sDestructibleEntity, bluntDamage*-3, true);
sDamageableSystem.TryChangeDamage(sDestructibleEntity, bluntDamage * -3, true);
// ThresholdsLookup don't work backwards
Assert.That(sTestThresholdListenerSystem.ThresholdsReached, Is.Empty);
@@ -153,7 +159,7 @@ namespace Content.IntegrationTests.Tests.Destructible
sDamageableSystem.TryChangeDamage(sDestructibleEntity, bluntDamage, true);
// The 50 threshold should have triggered again, after being healed
Assert.That(sTestThresholdListenerSystem.ThresholdsReached.Count, Is.EqualTo(1));
Assert.That(sTestThresholdListenerSystem.ThresholdsReached, Has.Count.EqualTo(1));
msg = sTestThresholdListenerSystem.ThresholdsReached[0];
threshold = msg.Threshold;
@@ -166,15 +172,18 @@ namespace Content.IntegrationTests.Tests.Destructible
actsThreshold = (DoActsBehavior) threshold.Behaviors[2];
// Check that it matches the YAML prototype
Assert.Multiple(() =>
{
Assert.That(actsThreshold.Acts, Is.EqualTo(ThresholdActs.Breakage));
Assert.That(audio.GetSound(soundThreshold.Sound), Is.EqualTo("/Audio/Effects/woodhit.ogg"));
Assert.That(spawnThreshold.Spawn, Is.Not.Null);
Assert.That(spawnThreshold.Spawn.Count, Is.EqualTo(1));
Assert.That(spawnThreshold.Spawn, Has.Count.EqualTo(1));
Assert.That(spawnThreshold.Spawn.Single().Key, Is.EqualTo(SpawnedEntityId));
Assert.That(spawnThreshold.Spawn.Single().Value.Min, Is.EqualTo(1));
Assert.That(spawnThreshold.Spawn.Single().Value.Max, Is.EqualTo(1));
Assert.NotNull(threshold.Trigger);
Assert.That(threshold.Trigger, Is.Not.Null);
Assert.That(threshold.Triggered, Is.True);
});
// Reset thresholds reached
sTestThresholdListenerSystem.ThresholdsReached.Clear();
@@ -183,19 +192,25 @@ namespace Content.IntegrationTests.Tests.Destructible
sDamageableSystem.SetAllDamage(sDestructibleEntity, sDamageableComponent, 0);
// Damage up to 50
sDamageableSystem.TryChangeDamage(sDestructibleEntity, bluntDamage*5, true);
sDamageableSystem.TryChangeDamage(sDestructibleEntity, bluntDamage * 5, true);
Assert.Multiple(() =>
{
// Check that the total damage matches
Assert.That(sDamageableComponent.TotalDamage, Is.EqualTo(FixedPoint2.New(50)));
// Both thresholds should have triggered
Assert.That(sTestThresholdListenerSystem.ThresholdsReached, Has.Exactly(2).Items);
});
// Verify the first one, should be the lowest one (20)
msg = sTestThresholdListenerSystem.ThresholdsReached[0];
var trigger = (DamageTrigger) msg.Threshold.Trigger;
Assert.NotNull(trigger);
Assert.Multiple(() =>
{
Assert.That(trigger, Is.Not.Null);
Assert.That(trigger.Damage, Is.EqualTo(20));
});
threshold = msg.Threshold;
@@ -205,8 +220,11 @@ namespace Content.IntegrationTests.Tests.Destructible
// Verify the second one, should be the highest one (50)
msg = sTestThresholdListenerSystem.ThresholdsReached[1];
trigger = (DamageTrigger) msg.Threshold.Trigger;
Assert.NotNull(trigger);
Assert.Multiple(() =>
{
Assert.That(trigger, Is.Not.Null);
Assert.That(trigger.Damage, Is.EqualTo(50));
});
threshold = msg.Threshold;
@@ -217,15 +235,18 @@ namespace Content.IntegrationTests.Tests.Destructible
actsThreshold = (DoActsBehavior) threshold.Behaviors[2];
// Check that it matches the YAML prototype
Assert.Multiple(() =>
{
Assert.That(actsThreshold.Acts, Is.EqualTo(ThresholdActs.Breakage));
Assert.That(soundThreshold.Sound.GetSound(), Is.EqualTo("/Audio/Effects/woodhit.ogg"));
Assert.That(audio.GetSound(soundThreshold.Sound), Is.EqualTo("/Audio/Effects/woodhit.ogg"));
Assert.That(spawnThreshold.Spawn, Is.Not.Null);
Assert.That(spawnThreshold.Spawn, Has.Count.EqualTo(1));
Assert.That(spawnThreshold.Spawn.Single().Key, Is.EqualTo(SpawnedEntityId));
Assert.That(spawnThreshold.Spawn.Single().Value.Min, Is.EqualTo(1));
Assert.That(spawnThreshold.Spawn.Single().Value.Max, Is.EqualTo(1));
Assert.NotNull(threshold.Trigger);
Assert.That(threshold.Trigger, Is.Not.Null);
Assert.That(threshold.Triggered, Is.True);
});
// Reset thresholds reached
sTestThresholdListenerSystem.ThresholdsReached.Clear();
@@ -239,32 +260,38 @@ namespace Content.IntegrationTests.Tests.Destructible
// Set both thresholds to only trigger once
foreach (var destructibleThreshold in sDestructibleComponent.Thresholds)
{
Assert.NotNull(destructibleThreshold.Trigger);
Assert.That(destructibleThreshold.Trigger, Is.Not.Null);
destructibleThreshold.TriggersOnce = true;
}
// Damage the entity up to 50 damage again
sDamageableSystem.TryChangeDamage(sDestructibleEntity, bluntDamage*5, true);
sDamageableSystem.TryChangeDamage(sDestructibleEntity, bluntDamage * 5, true);
Assert.Multiple(() =>
{
// Check that the total damage matches
Assert.That(sDamageableComponent.TotalDamage, Is.EqualTo(FixedPoint2.New(50)));
// No thresholds should have triggered as they were already triggered before, and they are set to only trigger once
Assert.That(sTestThresholdListenerSystem.ThresholdsReached, Is.Empty);
});
// Set both thresholds to trigger multiple times
foreach (var destructibleThreshold in sDestructibleComponent.Thresholds)
{
Assert.NotNull(destructibleThreshold.Trigger);
Assert.That(destructibleThreshold.Trigger, Is.Not.Null);
destructibleThreshold.TriggersOnce = false;
}
Assert.Multiple(() =>
{
// Check that the total damage matches
Assert.That(sDamageableComponent.TotalDamage, Is.EqualTo(FixedPoint2.New(50)));
// They shouldn't have been triggered by changing TriggersOnce
Assert.That(sTestThresholdListenerSystem.ThresholdsReached, Is.Empty);
});
});
await pairTracker.CleanReturnAsync();
}
}

View File

@@ -1,8 +1,6 @@
using System.Threading.Tasks;
using Content.Server.DeviceNetwork;
using Content.Server.DeviceNetwork.Components;
using Content.Server.DeviceNetwork.Systems;
using NUnit.Framework;
using Robust.Shared.GameObjects;
using Robust.Shared.IoC;
using Robust.Shared.Map;
@@ -51,7 +49,11 @@ namespace Content.IntegrationTests.Tests.DeviceNetwork
[Test]
public async Task NetworkDeviceSendAndReceive()
{
await using var pairTracker = await PoolManager.GetServerClient(new PoolSettings{NoClient = true, ExtraPrototypes = Prototypes});
await using var pairTracker = await PoolManager.GetServerClient(new PoolSettings
{
NoClient = true,
ExtraPrototypes = Prototypes
});
var server = pairTracker.Pair.Server;
var mapManager = server.ResolveDependency<IMapManager>();
@@ -73,20 +75,27 @@ namespace Content.IntegrationTests.Tests.DeviceNetwork
["testbool"] = true
};
await server.WaitAssertion(() => {
await server.WaitAssertion(() =>
{
device1 = entityManager.SpawnEntity("DummyNetworkDevice", MapCoordinates.Nullspace);
Assert.That(entityManager.TryGetComponent(device1, out networkComponent1), Is.True);
Assert.That(networkComponent1.ReceiveFrequency != null, Is.True);
Assert.Multiple(() =>
{
Assert.That(networkComponent1.ReceiveFrequency, Is.Not.Null);
Assert.That(networkComponent1.Address, Is.Not.EqualTo(string.Empty));
});
device2 = entityManager.SpawnEntity("DummyNetworkDevice", MapCoordinates.Nullspace);
Assert.That(entityManager.TryGetComponent(device2, out networkComponent2), Is.True);
Assert.That(networkComponent1.ReceiveFrequency != null, Is.True);
Assert.Multiple(() =>
{
Assert.That(networkComponent1.ReceiveFrequency, Is.Not.Null);
Assert.That(networkComponent2.Address, Is.Not.EqualTo(string.Empty));
Assert.That(networkComponent1.Address, Is.Not.EqualTo(networkComponent2.Address));
});
deviceNetSystem.QueuePacket(device1, networkComponent2.Address, payload, networkComponent2.ReceiveFrequency.Value);
});
@@ -94,7 +103,8 @@ namespace Content.IntegrationTests.Tests.DeviceNetwork
await server.WaitRunTicks(2);
await server.WaitIdleAsync();
await server.WaitAssertion(() => {
await server.WaitAssertion(() =>
{
CollectionAssert.AreEquivalent(deviceNetTestSystem.LastPayload, payload);
});
await pairTracker.CleanReturnAsync();
@@ -103,7 +113,11 @@ namespace Content.IntegrationTests.Tests.DeviceNetwork
[Test]
public async Task WirelessNetworkDeviceSendAndReceive()
{
await using var pairTracker = await PoolManager.GetServerClient(new PoolSettings{NoClient = true, ExtraPrototypes = Prototypes});
await using var pairTracker = await PoolManager.GetServerClient(new PoolSettings
{
NoClient = true,
ExtraPrototypes = Prototypes
});
var server = pairTracker.Pair.Server;
var testMap = await PoolManager.CreateTestMap(pairTracker);
var coordinates = testMap.GridCoords;
@@ -127,21 +141,32 @@ namespace Content.IntegrationTests.Tests.DeviceNetwork
["testbool"] = true
};
await server.WaitAssertion(() => {
await server.WaitAssertion(() =>
{
device1 = entityManager.SpawnEntity("DummyWirelessNetworkDevice", coordinates);
Assert.Multiple(() =>
{
Assert.That(entityManager.TryGetComponent(device1, out networkComponent1), Is.True);
Assert.That(entityManager.TryGetComponent(device1, out wirelessNetworkComponent), Is.True);
Assert.That(networkComponent1.ReceiveFrequency != null, Is.True);
});
Assert.Multiple(() =>
{
Assert.That(networkComponent1.ReceiveFrequency, Is.Not.Null);
Assert.That(networkComponent1.Address, Is.Not.EqualTo(string.Empty));
});
device2 = entityManager.SpawnEntity("DummyWirelessNetworkDevice", new MapCoordinates(new Robust.Shared.Maths.Vector2(0,50), testMap.MapId));
device2 = entityManager.SpawnEntity("DummyWirelessNetworkDevice", new MapCoordinates(new Robust.Shared.Maths.Vector2(0, 50), testMap.MapId));
Assert.That(entityManager.TryGetComponent(device2, out networkComponent2), Is.True);
Assert.That(networkComponent2.ReceiveFrequency != null, Is.True);
Assert.Multiple(() =>
{
Assert.That(networkComponent2.ReceiveFrequency, Is.Not.Null);
Assert.That(networkComponent2.Address, Is.Not.EqualTo(string.Empty));
Assert.That(networkComponent1.Address, Is.Not.EqualTo(networkComponent2.Address));
});
deviceNetSystem.QueuePacket(device1, networkComponent2.Address, payload, networkComponent2.ReceiveFrequency.Value);
});
@@ -149,7 +174,8 @@ namespace Content.IntegrationTests.Tests.DeviceNetwork
await server.WaitRunTicks(2);
await server.WaitIdleAsync();
await server.WaitAssertion(() => {
await server.WaitAssertion(() =>
{
CollectionAssert.AreEqual(deviceNetTestSystem.LastPayload, payload);
payload = new NetworkPayload
@@ -165,7 +191,8 @@ namespace Content.IntegrationTests.Tests.DeviceNetwork
await server.WaitRunTicks(1);
await server.WaitIdleAsync();
await server.WaitAssertion(() => {
await server.WaitAssertion(() =>
{
CollectionAssert.AreNotEqual(deviceNetTestSystem.LastPayload, payload);
});
@@ -175,7 +202,11 @@ namespace Content.IntegrationTests.Tests.DeviceNetwork
[Test]
public async Task WiredNetworkDeviceSendAndReceive()
{
await using var pairTracker = await PoolManager.GetServerClient(new PoolSettings{NoClient = true, ExtraPrototypes = Prototypes});
await using var pairTracker = await PoolManager.GetServerClient(new PoolSettings
{
NoClient = true,
ExtraPrototypes = Prototypes
});
var server = pairTracker.Pair.Server;
var testMap = await PoolManager.CreateTestMap(pairTracker);
var coordinates = testMap.GridCoords;
@@ -190,7 +221,7 @@ namespace Content.IntegrationTests.Tests.DeviceNetwork
DeviceNetworkComponent networkComponent1 = null;
DeviceNetworkComponent networkComponent2 = null;
WiredNetworkComponent wiredNetworkComponent = null;
MapGridComponent grid = testMap.MapGrid;
var grid = testMap.MapGrid;
var testValue = "test";
var payload = new NetworkPayload
@@ -203,21 +234,31 @@ namespace Content.IntegrationTests.Tests.DeviceNetwork
await server.WaitRunTicks(2);
await server.WaitIdleAsync();
await server.WaitAssertion(() => {
await server.WaitAssertion(() =>
{
device1 = entityManager.SpawnEntity("DummyWiredNetworkDevice", coordinates);
Assert.Multiple(() =>
{
Assert.That(entityManager.TryGetComponent(device1, out networkComponent1), Is.True);
Assert.That(entityManager.TryGetComponent(device1, out wiredNetworkComponent), Is.True);
Assert.That(networkComponent1.ReceiveFrequency != null, Is.True);
});
Assert.Multiple(() =>
{
Assert.That(networkComponent1.ReceiveFrequency, Is.Not.Null);
Assert.That(networkComponent1.Address, Is.Not.EqualTo(string.Empty));
});
device2 = entityManager.SpawnEntity("DummyWiredNetworkDevice", coordinates);
Assert.That(entityManager.TryGetComponent(device2, out networkComponent2), Is.True);
Assert.That(networkComponent2.ReceiveFrequency != null, Is.True);
Assert.Multiple(() =>
{
Assert.That(networkComponent2.ReceiveFrequency, Is.Not.Null);
Assert.That(networkComponent2.Address, Is.Not.EqualTo(string.Empty));
Assert.That(networkComponent1.Address, Is.Not.EqualTo(networkComponent2.Address));
});
deviceNetSystem.QueuePacket(device1, networkComponent2.Address, payload, networkComponent2.ReceiveFrequency.Value);
});
@@ -225,7 +266,8 @@ namespace Content.IntegrationTests.Tests.DeviceNetwork
await server.WaitRunTicks(1);
await server.WaitIdleAsync();
await server.WaitAssertion(() => {
await server.WaitAssertion(() =>
{
//CollectionAssert.AreNotEqual(deviceNetTestSystem.LastPayload, payload);
entityManager.SpawnEntity("CableApcExtension", coordinates);
@@ -236,7 +278,8 @@ namespace Content.IntegrationTests.Tests.DeviceNetwork
await server.WaitRunTicks(1);
await server.WaitIdleAsync();
await server.WaitAssertion(() => {
await server.WaitAssertion(() =>
{
CollectionAssert.AreEqual(deviceNetTestSystem.LastPayload, payload);
});

View File

@@ -1,6 +1,5 @@
#nullable enable annotations
using System.Linq;
using System.Threading.Tasks;
using Content.Server.Disposal.Tube.Components;
using Content.Server.Disposal.Unit.Components;
using Content.Server.Disposal.Unit.EntitySystems;

View File

@@ -1,10 +1,8 @@
using System.Linq;
using System.Threading.Tasks;
using Content.IntegrationTests.Tests.Construction.Interaction;
using Content.IntegrationTests.Tests.Interaction;
using Content.IntegrationTests.Tests.Weldable;
using Content.Server.Tools.Components;
using NUnit.Framework;
namespace Content.IntegrationTests.Tests.DoAfter;
@@ -18,7 +16,7 @@ public sealed class DoAfterCancellationTests : InteractionTest
public async Task CancelWallDeconstruct()
{
await StartDeconstruction(WallConstruction.WallSolid);
await Interact(Weld, awaitDoAfters:false);
await Interact(Weld, awaitDoAfters: false);
// Failed do-after has no effect
await CancelDoAfters();
@@ -30,7 +28,7 @@ public sealed class DoAfterCancellationTests : InteractionTest
// Repeat for wrenching interaction
AssertAnchored();
await Interact(Wrench, awaitDoAfters:false);
await Interact(Wrench, awaitDoAfters: false);
await CancelDoAfters();
AssertAnchored();
AssertPrototype(WallConstruction.Girder);
@@ -39,7 +37,7 @@ public sealed class DoAfterCancellationTests : InteractionTest
// Repeat for screwdriver interaction.
AssertDeleted(false);
await Interact(Screw, awaitDoAfters:false);
await Interact(Screw, awaitDoAfters: false);
await CancelDoAfters();
AssertDeleted(false);
await Interact(Screw);
@@ -50,13 +48,13 @@ public sealed class DoAfterCancellationTests : InteractionTest
public async Task CancelWallConstruct()
{
await StartConstruction(WallConstruction.Wall);
await Interact(Steel, 5, awaitDoAfters:false);
await Interact(Steel, 5, awaitDoAfters: false);
await CancelDoAfters();
Assert.That(Target.HasValue && Target.Value.IsClientSide());
await Interact(Steel, 5);
AssertPrototype(WallConstruction.Girder);
await Interact(Steel, 5, awaitDoAfters:false);
await Interact(Steel, 5, awaitDoAfters: false);
await CancelDoAfters();
AssertPrototype(WallConstruction.Girder);
@@ -68,7 +66,7 @@ public sealed class DoAfterCancellationTests : InteractionTest
public async Task CancelTilePry()
{
await SetTile(Floor);
await Interact(Pry, awaitDoAfters:false);
await Interact(Pry, awaitDoAfters: false);
await CancelDoAfters();
await AssertTile(Floor);
@@ -80,7 +78,7 @@ public sealed class DoAfterCancellationTests : InteractionTest
public async Task CancelRepeatedTilePry()
{
await SetTile(Floor);
await Interact(Pry, awaitDoAfters:false);
await Interact(Pry, awaitDoAfters: false);
await RunTicks(1);
Assert.That(ActiveDoAfters.Count(), Is.EqualTo(1));
await AssertTile(Floor);
@@ -102,35 +100,56 @@ public sealed class DoAfterCancellationTests : InteractionTest
await SpawnTarget(WeldableTests.Locker);
var comp = Comp<WeldableComponent>();
Assert.Multiple(() =>
{
Assert.That(comp.Weldable, Is.True);
Assert.That(comp.IsWelded, Is.False);
});
await Interact(Weld, awaitDoAfters:false);
await Interact(Weld, awaitDoAfters: false);
await RunTicks(1);
Assert.Multiple(() =>
{
Assert.That(ActiveDoAfters.Count(), Is.EqualTo(1));
Assert.That(comp.IsWelded, Is.False);
});
// Second DoAfter cancels the first.
// Not using helper, because it runs too many ticks & causes the do-after to finish.
await Server.WaitPost(() => InteractSys.UserInteraction(Player, TargetCoords, Target));
Assert.Multiple(() =>
{
Assert.That(ActiveDoAfters.Count(), Is.EqualTo(0));
Assert.That(comp.IsWelded, Is.False);
});
// Third do after will work fine
await Interact(Weld);
Assert.Multiple(() =>
{
Assert.That(ActiveDoAfters.Count(), Is.EqualTo(0));
Assert.That(comp.IsWelded, Is.True);
});
// Repeat test for un-welding
await Interact(Weld, awaitDoAfters:false);
await Interact(Weld, awaitDoAfters: false);
await RunTicks(1);
Assert.Multiple(() =>
{
Assert.That(ActiveDoAfters.Count(), Is.EqualTo(1));
Assert.That(comp.IsWelded, Is.True);
});
await Server.WaitPost(() => InteractSys.UserInteraction(Player, TargetCoords, Target));
Assert.Multiple(() =>
{
Assert.That(ActiveDoAfters.Count(), Is.EqualTo(0));
Assert.That(comp.IsWelded, Is.True);
});
await Interact(Weld);
Assert.Multiple(() =>
{
Assert.That(ActiveDoAfters.Count(), Is.EqualTo(0));
Assert.That(comp.IsWelded, Is.False);
});
}
}

View File

@@ -1,9 +1,5 @@
using System;
using System.Threading.Tasks;
using Content.Shared.DoAfter;
using NUnit.Framework;
using Robust.Shared.GameObjects;
using Robust.Shared.IoC;
using Robust.Shared.Map;
using Robust.Shared.Reflection;
using Robust.Shared.Serialization;
@@ -35,7 +31,7 @@ namespace Content.IntegrationTests.Tests.DoAfter
[Test]
public async Task TestSerializable()
{
await using var pairTracker = await PoolManager.GetServerClient(new PoolSettings{NoClient = true});
await using var pairTracker = await PoolManager.GetServerClient(new PoolSettings { NoClient = true });
var server = pairTracker.Pair.Server;
await server.WaitIdleAsync();
var refMan = server.ResolveDependency<IReflectionManager>();
@@ -62,7 +58,11 @@ namespace Content.IntegrationTests.Tests.DoAfter
[Test]
public async Task TestFinished()
{
await using var pairTracker = await PoolManager.GetServerClient(new PoolSettings{NoClient = true, ExtraPrototypes = Prototypes});
await using var pairTracker = await PoolManager.GetServerClient(new PoolSettings
{
NoClient = true,
ExtraPrototypes = Prototypes
});
var server = pairTracker.Pair.Server;
await server.WaitIdleAsync();
@@ -77,8 +77,10 @@ namespace Content.IntegrationTests.Tests.DoAfter
var tickTime = 1.0f / timing.TickRate;
var mob = entityManager.SpawnEntity("Dummy", MapCoordinates.Nullspace);
var args = new DoAfterArgs(mob, tickTime / 2, ev, null) { Broadcast = true };
#pragma warning disable NUnit2045 // Interdependent assertions.
Assert.That(doAfterSystem.TryStartDoAfter(args));
Assert.That(ev.Cancelled, Is.False);
#pragma warning restore NUnit2045
});
await server.WaitRunTicks(1);
@@ -90,12 +92,15 @@ namespace Content.IntegrationTests.Tests.DoAfter
[Test]
public async Task TestCancelled()
{
await using var pairTracker = await PoolManager.GetServerClient(new PoolSettings{NoClient = true, ExtraPrototypes = Prototypes});
await using var pairTracker = await PoolManager.GetServerClient(new PoolSettings
{
NoClient = true,
ExtraPrototypes = Prototypes
});
var server = pairTracker.Pair.Server;
var entityManager = server.ResolveDependency<IEntityManager>();
var timing = server.ResolveDependency<IGameTiming>();
var doAfterSystem = entityManager.EntitySysManager.GetEntitySystem<SharedDoAfterSystem>();
DoAfterId? id;
var ev = new TestDoAfterEvent();
await server.WaitPost(() =>
@@ -105,7 +110,7 @@ namespace Content.IntegrationTests.Tests.DoAfter
var mob = entityManager.SpawnEntity("Dummy", MapCoordinates.Nullspace);
var args = new DoAfterArgs(mob, tickTime * 2, ev, null) { Broadcast = true };
if (!doAfterSystem.TryStartDoAfter(args, out id))
if (!doAfterSystem.TryStartDoAfter(args, out var id))
{
Assert.Fail();
return;

View File

@@ -1,12 +1,8 @@
using System;
using System.Threading.Tasks;
using Content.Server.Doors.Systems;
using Content.Shared.Doors.Components;
using NUnit.Framework;
using Robust.Shared.GameObjects;
using Robust.Shared.Map;
using Robust.Shared.Maths;
using Robust.Shared.Physics;
using Robust.Shared.Physics.Components;
using Robust.Shared.Physics.Systems;
@@ -55,7 +51,11 @@ namespace Content.IntegrationTests.Tests.Doors
[Test]
public async Task OpenCloseDestroyTest()
{
await using var pairTracker = await PoolManager.GetServerClient(new PoolSettings{NoClient = true, ExtraPrototypes = Prototypes});
await using var pairTracker = await PoolManager.GetServerClient(new PoolSettings
{
NoClient = true,
ExtraPrototypes = Prototypes
});
var server = pairTracker.Pair.Server;
var entityManager = server.ResolveDependency<IEntityManager>();
@@ -68,8 +68,10 @@ namespace Content.IntegrationTests.Tests.Doors
{
airlock = entityManager.SpawnEntity("AirlockDummy", MapCoordinates.Nullspace);
Assert.True(entityManager.TryGetComponent(airlock, out doorComponent));
#pragma warning disable NUnit2045 // Interdependent assertions.
Assert.That(entityManager.TryGetComponent(airlock, out doorComponent), Is.True);
Assert.That(doorComponent.State, Is.EqualTo(DoorState.Closed));
#pragma warning restore NUnit2045
});
await server.WaitIdleAsync();
@@ -112,7 +114,11 @@ namespace Content.IntegrationTests.Tests.Doors
[Test]
public async Task AirlockBlockTest()
{
await using var pairTracker = await PoolManager.GetServerClient(new PoolSettings{NoClient = true, ExtraPrototypes = Prototypes});
await using var pairTracker = await PoolManager.GetServerClient(new PoolSettings
{
NoClient = true,
ExtraPrototypes = Prototypes
});
var server = pairTracker.Pair.Server;
await server.WaitIdleAsync();
@@ -120,6 +126,7 @@ namespace Content.IntegrationTests.Tests.Doors
var mapManager = server.ResolveDependency<IMapManager>();
var entityManager = server.ResolveDependency<IEntityManager>();
var physicsSystem = entityManager.System<SharedPhysicsSystem>();
var xformSystem = entityManager.System<SharedTransformSystem>();
PhysicsComponent physBody = null;
EntityUid physicsDummy = default;
@@ -137,9 +144,11 @@ namespace Content.IntegrationTests.Tests.Doors
airlock = entityManager.SpawnEntity("AirlockDummy", new MapCoordinates((0, 0), mapId));
Assert.True(entityManager.TryGetComponent(physicsDummy, out physBody));
Assert.True(entityManager.TryGetComponent(airlock, out doorComponent));
Assert.Multiple(() =>
{
Assert.That(entityManager.TryGetComponent(physicsDummy, out physBody), Is.True);
Assert.That(entityManager.TryGetComponent(airlock, out doorComponent), Is.True);
});
Assert.That(doorComponent.State, Is.EqualTo(DoorState.Closed));
});
@@ -171,7 +180,10 @@ namespace Content.IntegrationTests.Tests.Doors
// Assert.That(physicsDummy.Transform.MapPosition.X, Is.GreaterThan(physicsDummyStartingX));
// Blocked by the airlock
await server.WaitAssertion(() => Assert.That(Math.Abs(entityManager.GetComponent<TransformComponent>(physicsDummy).MapPosition.X - 1) > 0.01f));
await server.WaitAssertion(() =>
{
Assert.That(Math.Abs(xformSystem.GetWorldPosition(physicsDummy).X - 1), Is.GreaterThan(0.01f));
});
await pairTracker.CleanReturnAsync();
}
}

View File

@@ -1,10 +1,7 @@
#nullable enable
using System.Linq;
using System.Threading.Tasks;
using NUnit.Framework;
using Robust.Client.GameObjects;
using Robust.Client.ResourceManagement;
using Robust.Shared.IoC;
using Robust.Shared.Prototypes;
namespace Content.IntegrationTests.Tests

View File

@@ -1,9 +1,7 @@
using System.Linq;
using System.Threading.Tasks;
using Content.IntegrationTests.Tests.Interaction;
using Content.Shared.Radio.Components;
using Content.Shared.Wires;
using NUnit.Framework;
namespace Content.IntegrationTests.Tests.EncryptionKeys;
@@ -15,26 +13,35 @@ public sealed class RemoveEncryptionKeys : InteractionTest
await SpawnTarget("ClothingHeadsetGrey");
var comp = Comp<EncryptionKeyHolderComponent>();
Assert.That(comp.KeyContainer.ContainedEntities.Count, Is.EqualTo(1));
Assert.Multiple(() =>
{
Assert.That(comp.KeyContainer.ContainedEntities, Has.Count.EqualTo(1));
Assert.That(comp.DefaultChannel, Is.EqualTo("Common"));
Assert.That(comp.Channels.Count, Is.EqualTo(1));
Assert.That(comp.Channels, Has.Count.EqualTo(1));
Assert.That(comp.Channels.First(), Is.EqualTo("Common"));
});
// Remove the key
await Interact(Screw);
Assert.That(comp.KeyContainer.ContainedEntities.Count, Is.EqualTo(0));
Assert.IsNull(comp.DefaultChannel);
Assert.That(comp.Channels.Count, Is.EqualTo(0));
Assert.Multiple(() =>
{
Assert.That(comp.KeyContainer.ContainedEntities, Has.Count.EqualTo(0));
Assert.That(comp.DefaultChannel, Is.Null);
Assert.That(comp.Channels, Has.Count.EqualTo(0));
});
// Checkl that the key was ejected and not just deleted or something.
await AssertEntityLookup(("EncryptionKeyCommon", 1));
// Re-insert a key.
await Interact("EncryptionKeyCentCom");
Assert.That(comp.KeyContainer.ContainedEntities.Count, Is.EqualTo(1));
Assert.Multiple(() =>
{
Assert.That(comp.KeyContainer.ContainedEntities, Has.Count.EqualTo(1));
Assert.That(comp.DefaultChannel, Is.EqualTo("CentCom"));
Assert.That(comp.Channels.Count, Is.EqualTo(1));
Assert.That(comp.Channels, Has.Count.EqualTo(1));
Assert.That(comp.Channels.First(), Is.EqualTo("CentCom"));
});
}
[Test]
@@ -44,40 +51,58 @@ public sealed class RemoveEncryptionKeys : InteractionTest
var comp = Comp<EncryptionKeyHolderComponent>();
var panel = Comp<WiresPanelComponent>();
Assert.That(comp.KeyContainer.ContainedEntities.Count, Is.GreaterThan(0));
Assert.That(comp.Channels.Count, Is.GreaterThan(0));
Assert.Multiple(() =>
{
Assert.That(comp.KeyContainer.ContainedEntities, Has.Count.GreaterThan(0));
Assert.That(comp.Channels, Has.Count.GreaterThan(0));
Assert.That(panel.Open, Is.False);
});
// cannot remove keys without opening panel
await Interact(Pry);
Assert.That(comp.KeyContainer.ContainedEntities.Count, Is.GreaterThan(0));
Assert.That(comp.Channels.Count, Is.GreaterThan(0));
Assert.Multiple(() =>
{
Assert.That(comp.KeyContainer.ContainedEntities, Has.Count.GreaterThan(0));
Assert.That(comp.Channels, Has.Count.GreaterThan(0));
Assert.That(panel.Open, Is.False);
});
// Open panel
await Interact(Screw);
Assert.Multiple(() =>
{
Assert.That(panel.Open, Is.True);
// Keys are still here
Assert.That(comp.KeyContainer.ContainedEntities.Count, Is.GreaterThan(0));
Assert.That(comp.Channels.Count, Is.GreaterThan(0));
Assert.That(comp.KeyContainer.ContainedEntities, Has.Count.GreaterThan(0));
Assert.That(comp.Channels, Has.Count.GreaterThan(0));
});
// Now remove the keys
await Interact(Pry);
Assert.That(comp.KeyContainer.ContainedEntities.Count, Is.EqualTo(0));
Assert.That(comp.Channels.Count, Is.EqualTo(0));
Assert.Multiple(() =>
{
Assert.That(comp.KeyContainer.ContainedEntities, Has.Count.EqualTo(0));
Assert.That(comp.Channels, Has.Count.EqualTo(0));
});
// Reinsert a key
await Interact("EncryptionKeyCentCom");
Assert.That(comp.KeyContainer.ContainedEntities.Count, Is.EqualTo(1));
Assert.Multiple(() =>
{
Assert.That(comp.KeyContainer.ContainedEntities, Has.Count.EqualTo(1));
Assert.That(comp.DefaultChannel, Is.EqualTo("CentCom"));
Assert.That(comp.Channels.Count, Is.EqualTo(1));
Assert.That(comp.Channels, Has.Count.EqualTo(1));
Assert.That(comp.Channels.First(), Is.EqualTo("CentCom"));
});
// Remove it again
await Interact(Pry);
Assert.That(comp.KeyContainer.ContainedEntities.Count, Is.EqualTo(0));
Assert.That(comp.Channels.Count, Is.EqualTo(0));
Assert.Multiple(() =>
{
Assert.That(comp.KeyContainer.ContainedEntities, Has.Count.EqualTo(0));
Assert.That(comp.Channels, Has.Count.EqualTo(0));
});
// Prying again will start deconstructing the machine.
AssertPrototype("TelecomServerFilled");
@@ -85,4 +110,3 @@ public sealed class RemoveEncryptionKeys : InteractionTest
AssertPrototype("MachineFrame");
}
}

View File

@@ -1,14 +1,9 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Content.Shared.CCVar;
using Content.Shared.Coordinates;
using NUnit.Framework;
using Robust.Shared;
using Robust.Shared.Configuration;
using Robust.Shared.GameObjects;
using Robust.Shared.IoC;
using Robust.Shared.Log;
using Robust.Shared.Map;
using Robust.Shared.Map.Components;
@@ -24,7 +19,7 @@ namespace Content.IntegrationTests.Tests
[Test]
public async Task SpawnAndDeleteAllEntitiesOnDifferentMaps()
{
await using var pairTracker = await PoolManager.GetServerClient(new PoolSettings{NoClient = true, Destructive = true});
await using var pairTracker = await PoolManager.GetServerClient(new PoolSettings { NoClient = true, Destructive = true });
var server = pairTracker.Pair.Server;
var entityMan = server.ResolveDependency<IEntityManager>();
@@ -35,7 +30,7 @@ namespace Content.IntegrationTests.Tests
{
var protoIds = prototypeMan
.EnumeratePrototypes<EntityPrototype>()
.Where(p=>!p.Abstract)
.Where(p => !p.Abstract)
.Where(p => !p.Components.ContainsKey("MapGrid")) // This will smash stuff otherwise.
.Select(p => p.ID)
.ToList();
@@ -52,11 +47,19 @@ namespace Content.IntegrationTests.Tests
await server.WaitPost(() =>
{
var entityMetas = entityMan.EntityQuery<MetaDataComponent>(true).ToList();
foreach (var meta in entityMetas)
static IEnumerable<(EntityUid, TComp)> Query<TComp>(IEntityManager entityMan)
where TComp : Component
{
if(!meta.EntityDeleted)
entityMan.DeleteEntity(meta.Owner);
var query = entityMan.AllEntityQueryEnumerator<TComp>();
while (query.MoveNext(out var uid, out var meta))
yield return (uid, meta);
};
var entityMetas = Query<MetaDataComponent>(entityMan).ToList();
foreach (var (uid, meta) in entityMetas)
{
if (!meta.EntityDeleted)
entityMan.DeleteEntity(uid);
}
Assert.That(entityMan.EntityCount, Is.Zero);
@@ -68,7 +71,7 @@ namespace Content.IntegrationTests.Tests
[Test]
public async Task SpawnAndDeleteAllEntitiesInTheSameSpot()
{
await using var pairTracker = await PoolManager.GetServerClient(new PoolSettings{NoClient = true, Destructive = true});
await using var pairTracker = await PoolManager.GetServerClient(new PoolSettings { NoClient = true, Destructive = true });
var server = pairTracker.Pair.Server;
var map = await PoolManager.CreateTestMap(pairTracker);
@@ -80,7 +83,7 @@ namespace Content.IntegrationTests.Tests
var protoIds = prototypeMan
.EnumeratePrototypes<EntityPrototype>()
.Where(p=>!p.Abstract)
.Where(p => !p.Abstract)
.Where(p => !p.Components.ContainsKey("MapGrid")) // This will smash stuff otherwise.
.Select(p => p.ID)
.ToList();
@@ -92,11 +95,19 @@ namespace Content.IntegrationTests.Tests
await server.WaitRunTicks(15);
await server.WaitPost(() =>
{
var entityMetas = entityMan.EntityQuery<MetaDataComponent>(true).ToList();
foreach (var meta in entityMetas)
static IEnumerable<(EntityUid, TComp)> Query<TComp>(IEntityManager entityMan)
where TComp : Component
{
if(!meta.EntityDeleted)
entityMan.DeleteEntity(meta.Owner);
var query = entityMan.AllEntityQueryEnumerator<TComp>();
while (query.MoveNext(out var uid, out var meta))
yield return (uid, meta);
};
var entityMetas = Query<MetaDataComponent>(entityMan).ToList();
foreach (var (uid, meta) in entityMetas)
{
if (!meta.EntityDeleted)
entityMan.DeleteEntity(uid);
}
Assert.That(entityMan.EntityCount, Is.Zero);
@@ -132,7 +143,7 @@ namespace Content.IntegrationTests.Tests
// for whatever reason, stealth boxes are breaking this test. Surplus crates have a chance of spawning them.
// TODO fix whatever is going wrong here.
HashSet<string> ignored = new() {"GhostBox", "StealthBox", "CrateSyndicateSurplusBundle", "CrateSyndicateSuperSurplusBundle"};
HashSet<string> ignored = new() { "GhostBox", "StealthBox", "CrateSyndicateSurplusBundle", "CrateSyndicateSuperSurplusBundle" };
await server.WaitPost(() =>
{
@@ -159,11 +170,19 @@ namespace Content.IntegrationTests.Tests
await server.WaitPost(() =>
{
var entityMetas = sEntMan.EntityQuery<MetaDataComponent>(true).ToList();
foreach (var meta in entityMetas)
static IEnumerable<(EntityUid, TComp)> Query<TComp>(IEntityManager entityMan)
where TComp : Component
{
var query = entityMan.AllEntityQueryEnumerator<TComp>();
while (query.MoveNext(out var uid, out var meta))
yield return (uid, meta);
};
var entityMetas = Query<MetaDataComponent>(sEntMan).ToList();
foreach (var (uid, meta) in entityMetas)
{
if (!meta.EntityDeleted)
sEntMan.DeleteEntity(meta.Owner);
sEntMan.DeleteEntity(uid);
}
Assert.That(sEntMan.EntityCount, Is.Zero);
@@ -196,13 +215,14 @@ namespace Content.IntegrationTests.Tests
- type: entity
id: AllComponentsOneToOneDeleteTestEntity";
await using var pairTracker = await PoolManager.GetServerClient(new PoolSettings{NoClient = true, ExtraPrototypes = testEntity});
await using var pairTracker = await PoolManager.GetServerClient(new PoolSettings { NoClient = true, ExtraPrototypes = testEntity });
var server = pairTracker.Pair.Server;
var mapManager = server.ResolveDependency<IMapManager>();
var entityManager = server.ResolveDependency<IEntityManager>();
var componentFactory = server.ResolveDependency<IComponentFactory>();
var tileDefinitionManager = server.ResolveDependency<ITileDefinitionManager>();
var logmill = server.ResolveDependency<ILogManager>().GetSawmill("EntityTest");
MapGridComponent grid = default;
@@ -255,8 +275,7 @@ namespace Content.IntegrationTests.Tests
}
component.Owner = entity;
Logger.LogS(LogLevel.Debug, "EntityTest", $"Adding component: {name}");
logmill.Debug($"Adding component: {name}");
Assert.DoesNotThrow(() =>
{
@@ -296,13 +315,14 @@ namespace Content.IntegrationTests.Tests
- type: entity
id: AllComponentsOneEntityDeleteTestEntity";
await using var pairTracker = await PoolManager.GetServerClient(new PoolSettings{NoClient = true, ExtraPrototypes = testEntity});
await using var pairTracker = await PoolManager.GetServerClient(new PoolSettings { NoClient = true, ExtraPrototypes = testEntity });
var server = pairTracker.Pair.Server;
var mapManager = server.ResolveDependency<IMapManager>();
var entityManager = server.ResolveDependency<IEntityManager>();
var componentFactory = server.ResolveDependency<IComponentFactory>();
var tileDefinitionManager = server.ResolveDependency<ITileDefinitionManager>();
var logmill = server.ResolveDependency<ILogManager>().GetSawmill("EntityTest");
MapGridComponent grid = default;
@@ -335,9 +355,9 @@ namespace Content.IntegrationTests.Tests
for (var i = 0; i < distinctComponents.Count; i++)
{
var distinct = distinctComponents[i];
var (components, references) = distinctComponents[i];
if (distinct.references.Intersect(registration.References).Any())
if (references.Intersect(registration.References).Any())
{
// Ensure the next list if this one has conflicting references
if (i + 1 >= distinctComponents.Count)
@@ -349,8 +369,8 @@ namespace Content.IntegrationTests.Tests
}
// Add the component and its references if no conflicting references were found
distinct.components.Add(registration.Idx);
distinct.references.AddRange(registration.References);
components.Add(registration.Idx);
references.AddRange(registration.References);
}
}
@@ -361,14 +381,14 @@ namespace Content.IntegrationTests.Tests
{
Assert.Multiple(() =>
{
foreach (var distinct in distinctComponents)
foreach (var (components, _) in distinctComponents)
{
var testLocation = grid.ToCoordinates();
var entity = entityManager.SpawnEntity("AllComponentsOneEntityDeleteTestEntity", testLocation);
Assert.That(entityManager.GetComponent<MetaDataComponent>(entity).EntityInitialized);
foreach (var type in distinct.components)
foreach (var type in components)
{
var component = (Component) componentFactory.GetComponent(type);
@@ -385,7 +405,7 @@ namespace Content.IntegrationTests.Tests
continue;
component.Owner = entity;
Logger.LogS(LogLevel.Debug, "EntityTest", $"Adding component: {name}");
logmill.Debug($"Adding component: {name}");
// Note for the future coder: if an exception occurs where a component reference
// was already occupied it might be because some component is ensuring another // initialize.

View File

@@ -1,14 +1,9 @@
#nullable enable
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Content.Server.Fluids.Components;
using Content.Server.Fluids.EntitySystems;
using Content.Server.Spreader;
using Content.Shared.Chemistry.Components;
using Content.Shared.FixedPoint;
using Content.Shared.Fluids.Components;
using NUnit.Framework;
using Robust.Shared.GameObjects;
using Robust.Shared.Map;
using Robust.Shared.Map.Components;
@@ -75,8 +70,10 @@ public sealed class FluidSpill
var grid = mapManager.GetGrid(gridId);
var solution = new Solution("Blood", FixedPoint2.New(100));
var tileRef = grid.GetTileRef(puddleOrigin);
#pragma warning disable NUnit2045 // Interdependent tests
Assert.That(puddleSystem.TrySpillAt(tileRef, solution, out _), Is.True);
Assert.That(GetPuddle(entityManager, grid, puddleOrigin), Is.Not.Null);
#pragma warning restore NUnit2045
});
var sTimeToWait = (int) Math.Ceiling(2f * gameTiming.TickRate);
@@ -87,8 +84,11 @@ public sealed class FluidSpill
var grid = mapManager.GetGrid(gridId);
var puddle = GetPuddle(entityManager, grid, puddleOrigin);
#pragma warning disable NUnit2045 // Interdependent tests
Assert.That(puddle, Is.Not.Null);
Assert.That(puddleSystem.CurrentVolume(puddle!.Owner, puddle), Is.EqualTo(FixedPoint2.New(100)));
#pragma warning restore NUnit2045
for (var x = 0; x < 3; x++)
{

View File

@@ -1,16 +1,11 @@
using System;
using System.Threading.Tasks;
using Content.Server.Fluids.Components;
using Content.Server.Fluids.EntitySystems;
using Content.Shared.Chemistry.Components;
using Content.Shared.Coordinates;
using Content.Shared.FixedPoint;
using Content.Shared.Fluids.Components;
using NUnit.Framework;
using Robust.Shared.GameObjects;
using Robust.Shared.Map;
using Robust.Shared.Map.Components;
using Robust.Shared.Timing;
namespace Content.IntegrationTests.Tests.Fluids
{
@@ -21,7 +16,7 @@ namespace Content.IntegrationTests.Tests.Fluids
[Test]
public async Task TilePuddleTest()
{
await using var pairTracker = await PoolManager.GetServerClient(new PoolSettings{NoClient = true});
await using var pairTracker = await PoolManager.GetServerClient(new PoolSettings { NoClient = true });
var server = pairTracker.Pair.Server;
var testMap = await PoolManager.CreateTestMap(pairTracker);
@@ -36,9 +31,8 @@ namespace Content.IntegrationTests.Tests.Fluids
var gridUid = tile.GridUid;
var (x, y) = tile.GridIndices;
var coordinates = new EntityCoordinates(gridUid, x, y);
var puddle = spillSystem.TrySpillAt(coordinates, solution, out _);
Assert.True(puddle);
Assert.That(spillSystem.TrySpillAt(coordinates, solution, out _), Is.True);
});
await PoolManager.RunTicksSync(pairTracker.Pair, 5);
@@ -48,7 +42,7 @@ namespace Content.IntegrationTests.Tests.Fluids
[Test]
public async Task SpaceNoPuddleTest()
{
await using var pairTracker = await PoolManager.GetServerClient(new PoolSettings{NoClient = true});
await using var pairTracker = await PoolManager.GetServerClient(new PoolSettings { NoClient = true });
var server = pairTracker.Pair.Server;
var testMap = await PoolManager.CreateTestMap(pairTracker);
@@ -75,8 +69,8 @@ namespace Content.IntegrationTests.Tests.Fluids
{
var coordinates = grid.ToCoordinates();
var solution = new Solution("Water", FixedPoint2.New(20));
var puddle = spillSystem.TrySpillAt(coordinates, solution, out _);
Assert.False(puddle);
Assert.That(spillSystem.TrySpillAt(coordinates, solution, out _), Is.False);
});
await pairTracker.CleanReturnAsync();

View File

@@ -1,10 +1,5 @@
using System;
using System.Linq;
using System.Threading.Tasks;
using Content.Shared.Follower;
using NUnit.Framework;
using Robust.Shared.GameObjects;
using Robust.Shared.IoC;
using Robust.Shared.Log;
using Robust.Shared.Map;
@@ -19,7 +14,7 @@ public sealed class FollowerSystemTest
[Test]
public async Task FollowerMapDeleteTest()
{
await using var pairTracker = await PoolManager.GetServerClient(new (){NoClient = true});
await using var pairTracker = await PoolManager.GetServerClient(new() { NoClient = true });
var server = pairTracker.Pair.Server;
var entMan = server.ResolveDependency<IEntityManager>();

View File

@@ -1,13 +1,10 @@
#nullable enable
using System.Threading.Tasks;
using Content.Server.Cuffs;
using Content.Shared.Body.Components;
using Content.Shared.Cuffs.Components;
using Content.Shared.Hands.Components;
using NUnit.Framework;
using Robust.Server.Console;
using Robust.Shared.GameObjects;
using Robust.Shared.IoC;
using Robust.Shared.Map;
using Robust.Shared.Maths;
@@ -39,15 +36,18 @@ namespace Content.IntegrationTests.Tests.GameObjects.Components.ActionBlocking
public async Task Test()
{
await using var pairTracker = await PoolManager.GetServerClient(new PoolSettings
{NoClient = true, ExtraPrototypes = Prototypes});
{
NoClient = true,
ExtraPrototypes = Prototypes
});
var server = pairTracker.Pair.Server;
EntityUid human;
EntityUid otherHuman;
EntityUid cuffs;
EntityUid secondCuffs;
CuffableComponent cuffed;
HandsComponent hands;
CuffableComponent cuffed = default!;
HandsComponent hands = default!;
var entityManager = server.ResolveDependency<IEntityManager>();
var mapManager = server.ResolveDependency<IMapManager>();
@@ -59,6 +59,8 @@ namespace Content.IntegrationTests.Tests.GameObjects.Components.ActionBlocking
var coordinates = new MapCoordinates(Vector2.Zero, mapId);
var cuffableSys = entityManager.System<CuffableSystem>();
var xformSys = entityManager.System<SharedTransformSystem>();
var xformQuery = entityManager.GetEntityQuery<TransformComponent>();
// Spawn the entities
human = entityManager.SpawnEntity("HumanDummy", coordinates);
@@ -66,38 +68,42 @@ namespace Content.IntegrationTests.Tests.GameObjects.Components.ActionBlocking
cuffs = entityManager.SpawnEntity("HandcuffsDummy", coordinates);
secondCuffs = entityManager.SpawnEntity("HandcuffsDummy", coordinates);
entityManager.GetComponent<TransformComponent>(human).WorldPosition =
entityManager.GetComponent<TransformComponent>(otherHuman).WorldPosition;
var coords = xformSys.GetWorldPosition(otherHuman, xformQuery);
xformSys.SetWorldPosition(human, coords, xformQuery);
// Test for components existing
Assert.True(entityManager.TryGetComponent(human, out cuffed!),
$"Human has no {nameof(CuffableComponent)}");
Assert.True(entityManager.TryGetComponent(human, out hands!), $"Human has no {nameof(HandsComponent)}");
Assert.True(entityManager.TryGetComponent(human, out BodyComponent? _), $"Human has no {nameof(BodyComponent)}");
Assert.True(entityManager.TryGetComponent(cuffs, out HandcuffComponent? _), $"Handcuff has no {nameof(HandcuffComponent)}");
Assert.True(entityManager.TryGetComponent(secondCuffs, out HandcuffComponent? _), $"Second handcuffs has no {nameof(HandcuffComponent)}");
Assert.Multiple(() =>
{
Assert.That(entityManager.TryGetComponent(human, out cuffed!), $"Human has no {nameof(CuffableComponent)}");
Assert.That(entityManager.TryGetComponent(human, out hands!), $"Human has no {nameof(HandsComponent)}");
Assert.That(entityManager.TryGetComponent(human, out BodyComponent? _), $"Human has no {nameof(BodyComponent)}");
Assert.That(entityManager.TryGetComponent(cuffs, out HandcuffComponent? _), $"Handcuff has no {nameof(HandcuffComponent)}");
Assert.That(entityManager.TryGetComponent(secondCuffs, out HandcuffComponent? _), $"Second handcuffs has no {nameof(HandcuffComponent)}");
});
// Test to ensure cuffed players register the handcuffs
cuffableSys.TryAddNewCuffs(human, human, cuffs, cuffed);
Assert.True(cuffed.CuffedHandCount > 0,
"Handcuffing a player did not result in their hands being cuffed");
Assert.That(cuffed.CuffedHandCount, Is.GreaterThan(0), "Handcuffing a player did not result in their hands being cuffed");
// Test to ensure a player with 4 hands will still only have 2 hands cuffed
AddHand(human, host);
AddHand(human, host);
Assert.Multiple(() =>
{
Assert.That(cuffed.CuffedHandCount, Is.EqualTo(2));
Assert.That(hands.SortedHands.Count, Is.EqualTo(4));
Assert.That(hands.SortedHands, Has.Count.EqualTo(4));
});
// Test to give a player with 4 hands 2 sets of cuffs
cuffableSys.TryAddNewCuffs(human, human, secondCuffs, cuffed);
Assert.True(cuffed.CuffedHandCount == 4, "Player doesn't have correct amount of hands cuffed");
Assert.That(cuffed.CuffedHandCount, Is.EqualTo(4), "Player doesn't have correct amount of hands cuffed");
});
await pairTracker.CleanReturnAsync();
}
private void AddHand(EntityUid to, IServerConsoleHost host)
private static void AddHand(EntityUid to, IServerConsoleHost host)
{
host.ExecuteCommand(null, $"addhand {to}");
}

View File

@@ -1,10 +1,7 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using NUnit.Framework;
using Robust.Shared.ContentPack;
using Robust.Shared.GameObjects;
using Robust.Shared.Utility;
@@ -103,16 +100,16 @@ namespace Content.IntegrationTests.Tests.GameObjects.Components
var message = new StringBuilder();
foreach (var unknownComponent in unknownComponentsClient)
foreach (var (entityId, component) in unknownComponentsClient)
{
message.Append(
$"CLIENT: Unknown component {unknownComponent.component} in prototype {unknownComponent.entityId}\n");
$"CLIENT: Unknown component {component} in prototype {entityId}\n");
}
foreach (var unknownComponent in unknownComponentsServer)
foreach (var (entityId, component) in unknownComponentsServer)
{
message.Append(
$"SERVER: Unknown component {unknownComponent.component} in prototype {unknownComponent.entityId}\n");
$"SERVER: Unknown component {component} in prototype {entityId}\n");
}
Assert.Fail(message.ToString());
@@ -140,7 +137,7 @@ namespace Content.IntegrationTests.Tests.GameObjects.Components
failureMessages = $"{failureMessages}\nComponent {serverIgnored} was ignored on server, but does not exist on client";
}
}
Assert.IsEmpty(failureMessages);
Assert.That(failureMessages, Is.Empty);
await pairTracker.CleanReturnAsync();
}
}

View File

@@ -1,9 +1,7 @@
using System.Linq;
using System.Threading.Tasks;
using Content.Client.UserInterface.Systems.Alerts.Controls;
using Content.Client.UserInterface.Systems.Alerts.Widgets;
using Content.Shared.Alert;
using NUnit.Framework;
using Robust.Client.UserInterface;
using Robust.Server.Player;
using Robust.Shared.GameObjects;
@@ -34,12 +32,14 @@ namespace Content.IntegrationTests.Tests.GameObjects.Components.Mobs
await server.WaitAssertion(() =>
{
playerUid = serverPlayerManager.Sessions.Single().AttachedEntity.GetValueOrDefault();
Assert.That(playerUid != default);
#pragma warning disable NUnit2045 // Interdependent assertions.
Assert.That(playerUid, Is.Not.EqualTo(default));
// Making sure it exists
Assert.That(entManager.HasComponent<AlertsComponent>(playerUid));
#pragma warning restore NUnit2045
var alerts = alertsSystem.GetActiveAlerts(playerUid);
Assert.IsNotNull(alerts);
Assert.That(alerts, Is.Not.Null);
var alertCount = alerts.Count;
alertsSystem.ShowAlert(playerUid, AlertType.Debug1);
@@ -54,18 +54,20 @@ namespace Content.IntegrationTests.Tests.GameObjects.Components.Mobs
await client.WaitAssertion(() =>
{
var local = clientPlayerMgr.LocalPlayer;
Assert.NotNull(local);
Assert.That(local, Is.Not.Null);
var controlled = local.ControlledEntity;
Assert.NotNull(controlled);
#pragma warning disable NUnit2045 // Interdependent assertions.
Assert.That(controlled, Is.Not.Null);
// Making sure it exists
Assert.That(clientEntManager.HasComponent<AlertsComponent>(controlled.Value));
#pragma warning restore Nunit2045
// find the alertsui
clientAlertsUI = FindAlertsUI(clientUIMgr.ActiveScreen);
Assert.NotNull(clientAlertsUI);
Assert.That(clientAlertsUI, Is.Not.Null);
AlertsUI FindAlertsUI(Control control)
static AlertsUI FindAlertsUI(Control control)
{
if (control is AlertsUI alertUI)
return alertUI;
@@ -83,7 +85,7 @@ namespace Content.IntegrationTests.Tests.GameObjects.Components.Mobs
Assert.That(clientAlertsUI.AlertContainer.ChildCount, Is.GreaterThanOrEqualTo(3));
var alertControls = clientAlertsUI.AlertContainer.Children.Select(c => (AlertControl) c);
var alertIDs = alertControls.Select(ac => ac.Alert.AlertType).ToArray();
var expectedIDs = new [] {AlertType.HumanHealth, AlertType.Debug1, AlertType.Debug2};
var expectedIDs = new[] { AlertType.HumanHealth, AlertType.Debug1, AlertType.Debug2 };
Assert.That(alertIDs, Is.SupersetOf(expectedIDs));
});
@@ -100,7 +102,7 @@ namespace Content.IntegrationTests.Tests.GameObjects.Components.Mobs
Assert.That(clientAlertsUI.AlertContainer.ChildCount, Is.GreaterThanOrEqualTo(2));
var alertControls = clientAlertsUI.AlertContainer.Children.Select(c => (AlertControl) c);
var alertIDs = alertControls.Select(ac => ac.Alert.AlertType).ToArray();
var expectedIDs = new [] {AlertType.HumanHealth, AlertType.Debug2};
var expectedIDs = new[] { AlertType.HumanHealth, AlertType.Debug2 };
Assert.That(alertIDs, Is.SupersetOf(expectedIDs));
});

View File

@@ -1,11 +1,8 @@
using System;
using System.Threading.Tasks;
using Content.Server.GameTicking;
using Content.Server.GameTicking;
using Content.Server.GameTicking.Commands;
using Content.Server.GameTicking.Rules;
using Content.Server.GameTicking.Rules.Components;
using Content.Shared.CCVar;
using NUnit.Framework;
using Robust.Shared.Configuration;
using Robust.Shared.GameObjects;
using Robust.Shared.Timing;

View File

@@ -1,7 +1,5 @@
using System.Linq;
using System.Threading.Tasks;
using Content.Server.GameTicking;
using NUnit.Framework;
using Robust.Shared.GameObjects;
namespace Content.IntegrationTests.Tests.GameRules;
@@ -37,7 +35,7 @@ public sealed class SecretStartsTest
{
foreach (var rule in gameTicker.GetAddedGameRules())
{
Assert.That(gameTicker.GetActiveGameRules().Contains(rule));
Assert.That(gameTicker.GetActiveGameRules(), Does.Contain(rule));
}
// End all rules

View File

@@ -1,9 +1,6 @@
using System;
using System.Linq;
using System.Threading.Tasks;
using Content.Server.GameTicking;
using Content.Shared.CCVar;
using NUnit.Framework;
using Robust.Shared.Configuration;
using Robust.Shared.GameObjects;

View File

@@ -1,11 +1,6 @@
using System.Threading.Tasks;
using Content.Server.Gravity;
using Content.Shared.Alert;
using Content.Shared.Coordinates;
using NUnit.Framework;
using Robust.Shared.GameObjects;
using Robust.Shared.IoC;
using Robust.Shared.Map;
namespace Content.IntegrationTests.Tests.Gravity
{
@@ -37,7 +32,11 @@ namespace Content.IntegrationTests.Tests.Gravity
[Test]
public async Task WeightlessStatusTest()
{
await using var pairTracker = await PoolManager.GetServerClient(new PoolSettings{NoClient = true, ExtraPrototypes = Prototypes});
await using var pairTracker = await PoolManager.GetServerClient(new PoolSettings
{
NoClient = true,
ExtraPrototypes = Prototypes
});
var server = pairTracker.Pair.Server;
var entityManager = server.ResolveDependency<IEntityManager>();
@@ -51,7 +50,7 @@ namespace Content.IntegrationTests.Tests.Gravity
{
human = entityManager.SpawnEntity("HumanDummy", testMap.GridCoords);
Assert.True(entityManager.TryGetComponent(human, out AlertsComponent alerts));
Assert.That(entityManager.TryGetComponent(human, out AlertsComponent alerts));
});
// Let WeightlessSystem and GravitySystem tick
@@ -60,7 +59,7 @@ namespace Content.IntegrationTests.Tests.Gravity
await server.WaitAssertion(() =>
{
// No gravity without a gravity generator
Assert.True(alertsSystem.IsShowingAlert(human, AlertType.Weightless));
Assert.That(alertsSystem.IsShowingAlert(human, AlertType.Weightless));
generatorUid = entityManager.SpawnEntity("GravityGeneratorDummy", entityManager.GetComponent<TransformComponent>(human).Coordinates);
});
@@ -70,7 +69,7 @@ namespace Content.IntegrationTests.Tests.Gravity
await server.WaitAssertion(() =>
{
Assert.False(alertsSystem.IsShowingAlert(human, AlertType.Weightless));
Assert.That(alertsSystem.IsShowingAlert(human, AlertType.Weightless), Is.False);
// This should kill gravity
entityManager.DeleteEntity(generatorUid);
@@ -80,7 +79,7 @@ namespace Content.IntegrationTests.Tests.Gravity
await server.WaitAssertion(() =>
{
Assert.True(alertsSystem.IsShowingAlert(human, AlertType.Weightless));
Assert.That(alertsSystem.IsShowingAlert(human, AlertType.Weightless));
});
await PoolManager.RunTicksSync(pairTracker.Pair, 10);

View File

@@ -1,9 +1,7 @@
using System.Threading.Tasks;
using Content.Server.Gravity;
using Content.Server.Power.Components;
using Content.Shared.Coordinates;
using Content.Shared.Gravity;
using NUnit.Framework;
using Robust.Shared.GameObjects;
using Robust.Shared.IoC;
using Robust.Shared.Map;
@@ -31,7 +29,11 @@ namespace Content.IntegrationTests.Tests
[Test]
public async Task Test()
{
await using var pairTracker = await PoolManager.GetServerClient(new PoolSettings{NoClient = true, ExtraPrototypes = Prototypes});
await using var pairTracker = await PoolManager.GetServerClient(new PoolSettings
{
NoClient = true,
ExtraPrototypes = Prototypes
});
var server = pairTracker.Pair.Server;
var testMap = await PoolManager.CreateTestMap(pairTracker);
@@ -42,6 +44,8 @@ namespace Content.IntegrationTests.Tests
MapGridComponent grid1 = null;
MapGridComponent grid2 = null;
EntityUid grid1Entity = default!;
EntityUid grid2Entity = default!;
// Create grids
await server.WaitAssertion(() =>
@@ -49,10 +53,15 @@ namespace Content.IntegrationTests.Tests
var mapId = testMap.MapId;
grid1 = mapMan.CreateGrid(mapId);
grid2 = mapMan.CreateGrid(mapId);
grid1Entity = grid1.Owner;
grid2Entity = grid2.Owner;
generator = entityMan.SpawnEntity("GravityGeneratorDummy", grid2.ToCoordinates());
Assert.Multiple(() =>
{
Assert.That(entityMan.HasComponent<GravityGeneratorComponent>(generator));
Assert.That(entityMan.HasComponent<ApcPowerReceiverComponent>(generator));
});
var powerComponent = entityMan.GetComponent<ApcPowerReceiverComponent>(generator);
powerComponent.NeedsPower = false;
@@ -65,13 +74,12 @@ namespace Content.IntegrationTests.Tests
var generatorComponent = entityMan.GetComponent<GravityGeneratorComponent>(generator);
var powerComponent = entityMan.GetComponent<ApcPowerReceiverComponent>(generator);
Assert.Multiple(() =>
{
Assert.That(generatorComponent.GravityActive, Is.True);
var grid1Entity = grid1.Owner;
var grid2Entity = grid2.Owner;
Assert.That(!entityMan.GetComponent<GravityComponent>(grid1Entity).EnabledVV);
Assert.That(entityMan.GetComponent<GravityComponent>(grid2Entity).EnabledVV);
});
// Re-enable needs power so it turns off again.
// Charge rate is ridiculously high so it finishes in one tick.
@@ -84,12 +92,12 @@ namespace Content.IntegrationTests.Tests
{
var generatorComponent = entityMan.GetComponent<GravityGeneratorComponent>(generator);
Assert.Multiple(() =>
{
Assert.That(generatorComponent.GravityActive, Is.False);
var grid2Entity = grid2.Owner;
Assert.That(entityMan.GetComponent<GravityComponent>(grid2Entity).EnabledVV, Is.False);
});
});
await pairTracker.CleanReturnAsync();
}

View File

@@ -1,10 +1,8 @@
#nullable enable
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Threading.Tasks;
using Content.Client.Guidebook;
using Content.Client.Guidebook.Richtext;
using NUnit.Framework;
using Robust.Client.UserInterface;
using Robust.Client.UserInterface.Controls;
@@ -64,12 +62,15 @@ whitespace before newlines are ignored.
var richText1 = ctrl.GetChild(0) as RichTextLabel;
var richText2 = ctrl.GetChild(1) as RichTextLabel;
Assert.NotNull(richText1);
Assert.NotNull(richText2);
Assert.Multiple(() =>
{
Assert.That(richText1, Is.Not.Null);
Assert.That(richText2, Is.Not.Null);
});
// uhh.. WTF. rich text has no means of getting the contents!?!?
// TODO assert text content is correct after fixing that bullshit.
//Assert.That(richText1?.Text, Is.EqualTo("multiple lines separated by only single newlines make a single rich text control"));
// Assert.That(richText1?.Text, Is.EqualTo("multiple lines separated by only single newlines make a single rich text control"));
// Assert.That(richText2?.Text, Is.EqualTo("unless there is a double newline. Also whitespace before newlines are ignored."));
var test1 = ctrl.GetChild(2) as TestControl;
@@ -78,38 +79,49 @@ whitespace before newlines are ignored.
var test4 = ctrl.GetChild(5) as TestControl;
var test5 = ctrl.GetChild(6) as TestControl;
Assert.NotNull(test1);
Assert.NotNull(test2);
Assert.NotNull(test3);
Assert.NotNull(test4);
Assert.NotNull(test5);
Assert.Multiple(() =>
{
Assert.That(test1, Is.Not.Null);
Assert.That(test2, Is.Not.Null);
Assert.That(test3, Is.Not.Null);
Assert.That(test4, Is.Not.Null);
Assert.That(test5, Is.Not.Null);
});
Assert.Multiple(() =>
{
Assert.That(test1!.ChildCount, Is.EqualTo(0));
Assert.That(test2!.ChildCount, Is.EqualTo(0));
Assert.That(test3!.ChildCount, Is.EqualTo(2));
Assert.That(test4!.ChildCount, Is.EqualTo(0));
Assert.That(test5!.ChildCount, Is.EqualTo(1));
});
var subText = test3.GetChild(0) as RichTextLabel;
var subText = test3!.GetChild(0) as RichTextLabel;
var subTest = test3.GetChild(1) as TestControl;
Assert.NotNull(subText);
//Assert.That(subText?.Text, Is.EqualTo("some text with a nested control"));
Assert.NotNull(subTest);
Assert.That(subTest?.ChildCount, Is.EqualTo(0));
var subTest2 = test5.GetChild(0) as TestControl;
Assert.NotNull(subTest2);
#pragma warning disable NUnit2045
Assert.That(subText, Is.Not.Null);
//Assert.That(subText?.Text, Is.EqualTo("some text with a nested control"));
Assert.That(subTest, Is.Not.Null);
Assert.That(subTest?.ChildCount, Is.EqualTo(0));
#pragma warning restore NUnit2045
var subTest2 = test5!.GetChild(0) as TestControl;
Assert.That(subTest2, Is.Not.Null);
Assert.That(subTest2!.ChildCount, Is.EqualTo(0));
Assert.That(test1.Params.Count, Is.EqualTo(0));
Assert.That(test2.Params.Count, Is.EqualTo(0));
Assert.That(test3.Params.Count, Is.EqualTo(0));
Assert.That(test4.Params.Count, Is.EqualTo(3));
Assert.That(test5.Params.Count, Is.EqualTo(0));
Assert.That(subTest2.Params.Count, Is.EqualTo(1));
Assert.Multiple(() =>
{
Assert.That(test1!.Params, Has.Count.EqualTo(0));
Assert.That(test2!.Params, Has.Count.EqualTo(0));
Assert.That(test3.Params, Has.Count.EqualTo(0));
Assert.That(test4!.Params, Has.Count.EqualTo(3));
Assert.That(test5.Params, Has.Count.EqualTo(0));
Assert.That(subTest2.Params, Has.Count.EqualTo(1));
});
string? val;
test4.Params.TryGetValue("key1", out val);
test4!.Params.TryGetValue("key1", out var val);
Assert.That(val, Is.EqualTo("value1"));
test4.Params.TryGetValue("key2", out val);

View File

@@ -1,10 +1,8 @@
using Content.Client.Guidebook;
using Content.Client.Guidebook.Richtext;
using NUnit.Framework;
using Robust.Shared.ContentPack;
using Robust.Shared.Prototypes;
using System.Linq;
using System.Threading.Tasks;
namespace Content.IntegrationTests.Tests.Guidebook;

View File

@@ -1,8 +1,6 @@
using System.Linq;
using System.Threading.Tasks;
using Content.Shared.Hands.Components;
using Content.Shared.Hands.EntitySystems;
using NUnit.Framework;
using Robust.Server.Player;
using Robust.Shared.GameObjects;
using Robust.Shared.Map;
@@ -40,7 +38,7 @@ public sealed class HandTests
// run ticks here is important, as errors may happen within the container system's frame update methods.
await PoolManager.RunTicksSync(pairTracker.Pair, 5);
Assert.That(hands.ActiveHandEntity == item);
Assert.That(hands.ActiveHandEntity, Is.EqualTo(item));
await server.WaitPost(() =>
{
@@ -48,7 +46,7 @@ public sealed class HandTests
});
await PoolManager.RunTicksSync(pairTracker.Pair, 5);
Assert.That(hands.ActiveHandEntity == null);
Assert.That(hands.ActiveHandEntity, Is.Null);
await server.WaitPost(() => mapMan.DeleteMap(data.MapId));
await pairTracker.CleanReturnAsync();

View File

@@ -1,9 +1,5 @@
using System.Threading.Tasks;
using Content.Shared.Inventory;
using NUnit.Framework;
using Robust.Shared.GameObjects;
using Robust.Shared.IoC;
using Robust.Shared.Map;
namespace Content.IntegrationTests.Tests
{
@@ -58,7 +54,7 @@ namespace Content.IntegrationTests.Tests
[Test]
public async Task Test()
{
await using var pairTracker = await PoolManager.GetServerClient(new PoolSettings{NoClient = true, ExtraPrototypes = Prototypes});
await using var pairTracker = await PoolManager.GetServerClient(new PoolSettings { NoClient = true, ExtraPrototypes = Prototypes });
var server = pairTracker.Pair.Server;
var testMap = await PoolManager.CreateTestMap(pairTracker);
var coordinates = testMap.GridCoords;
@@ -82,21 +78,32 @@ namespace Content.IntegrationTests.Tests
var tooBigItem = entityMan.SpawnEntity("ToolboxDummy", coordinates);
Assert.Multiple(() =>
{
Assert.That(invSystem.CanEquip(human, uniform, "jumpsuit", out _));
// Can't equip any of these since no uniform!
Assert.That(invSystem.CanEquip(human, idCard, "id", out _), Is.False);
Assert.That(invSystem.CanEquip(human, pocketItem, "pocket1", out _), Is.False);
Assert.That(invSystem.CanEquip(human, tooBigItem, "pocket2", out _), Is.False); // This one fails either way.
});
Assert.Multiple(() =>
{
Assert.That(invSystem.TryEquip(human, uniform, "jumpsuit"));
Assert.That(invSystem.TryEquip(human, idCard, "id"));
});
#pragma warning disable NUnit2045
Assert.That(invSystem.CanEquip(human, tooBigItem, "pocket1", out _), Is.False); // Still failing!
Assert.That(invSystem.TryEquip(human, pocketItem, "pocket1"));
#pragma warning restore NUnit2045
Assert.Multiple(() =>
{
Assert.That(IsDescendant(idCard, human, entityMan));
Assert.That(IsDescendant(pocketItem, human, entityMan));
});
// Now drop the jumpsuit.
Assert.That(invSystem.TryUnequip(human, "jumpsuit"));
@@ -105,6 +112,8 @@ namespace Content.IntegrationTests.Tests
await server.WaitRunTicks(2);
await server.WaitAssertion(() =>
{
Assert.Multiple(() =>
{
// Items have been dropped!
Assert.That(IsDescendant(uniform, human, entityMan), Is.False);
@@ -116,6 +125,7 @@ namespace Content.IntegrationTests.Tests
Assert.That(!invSystem.TryGetSlotEntity(human, "id", out _));
Assert.That(!invSystem.TryGetSlotEntity(human, "pocket1", out _));
});
});
await pairTracker.CleanReturnAsync();
}

View File

@@ -1,11 +1,9 @@
#nullable enable annotations
using System.Threading.Tasks;
using Content.Server.Interaction;
using Content.Shared.Hands.Components;
using Content.Shared.Hands.EntitySystems;
using Content.Shared.Interaction;
using Content.Shared.Item;
using NUnit.Framework;
using Robust.Shared.Containers;
using Robust.Shared.GameObjects;
using Robust.Shared.Map;
@@ -39,7 +37,11 @@ namespace Content.IntegrationTests.Tests.Interaction.Click
[Test]
public async Task InteractionTest()
{
await using var pairTracker = await PoolManager.GetServerClient(new PoolSettings{NoClient = true, ExtraPrototypes = Prototypes});
await using var pairTracker = await PoolManager.GetServerClient(new PoolSettings
{
NoClient = true,
ExtraPrototypes = Prototypes
});
var server = pairTracker.Pair.Server;
var sEntities = server.ResolveDependency<IEntityManager>();
@@ -73,8 +75,14 @@ namespace Content.IntegrationTests.Tests.Interaction.Click
await server.WaitRunTicks(1);
var entitySystemManager = server.ResolveDependency<IEntitySystemManager>();
Assert.That(entitySystemManager.TryGetEntitySystem<InteractionSystem>(out var interactionSystem));
Assert.That(entitySystemManager.TryGetEntitySystem<TestInteractionSystem>(out var testInteractionSystem));
InteractionSystem interactionSystem = default!;
TestInteractionSystem testInteractionSystem = default!;
Assert.Multiple(() =>
{
Assert.That(entitySystemManager.TryGetEntitySystem(out interactionSystem));
Assert.That(entitySystemManager.TryGetEntitySystem(out testInteractionSystem));
});
var interactUsing = false;
var interactHand = false;
@@ -84,8 +92,11 @@ namespace Content.IntegrationTests.Tests.Interaction.Click
testInteractionSystem.InteractHandEvent = (ev) => { Assert.That(ev.Target, Is.EqualTo(target)); interactHand = true; };
interactionSystem.UserInteraction(user, sEntities.GetComponent<TransformComponent>(target).Coordinates, target);
Assert.Multiple(() =>
{
Assert.That(interactUsing, Is.False);
Assert.That(interactHand);
});
Assert.That(handSys.TryPickup(user, item));
@@ -100,7 +111,11 @@ namespace Content.IntegrationTests.Tests.Interaction.Click
[Test]
public async Task InteractionObstructionTest()
{
await using var pairTracker = await PoolManager.GetServerClient(new PoolSettings{NoClient = true, ExtraPrototypes = Prototypes});
await using var pairTracker = await PoolManager.GetServerClient(new PoolSettings
{
NoClient = true,
ExtraPrototypes = Prototypes
});
var server = pairTracker.Pair.Server;
var sEntities = server.ResolveDependency<IEntityManager>();
@@ -136,8 +151,13 @@ namespace Content.IntegrationTests.Tests.Interaction.Click
await server.WaitRunTicks(1);
var entitySystemManager = server.ResolveDependency<IEntitySystemManager>();
Assert.That(entitySystemManager.TryGetEntitySystem<InteractionSystem>(out var interactionSystem));
Assert.That(entitySystemManager.TryGetEntitySystem<TestInteractionSystem>(out var testInteractionSystem));
InteractionSystem interactionSystem = default!;
TestInteractionSystem testInteractionSystem = default!;
Assert.Multiple(() =>
{
Assert.That(entitySystemManager.TryGetEntitySystem(out interactionSystem));
Assert.That(entitySystemManager.TryGetEntitySystem(out testInteractionSystem));
});
var interactUsing = false;
var interactHand = false;
@@ -147,8 +167,11 @@ namespace Content.IntegrationTests.Tests.Interaction.Click
testInteractionSystem.InteractHandEvent = (ev) => { Assert.That(ev.Target, Is.EqualTo(target)); interactHand = true; };
interactionSystem.UserInteraction(user, sEntities.GetComponent<TransformComponent>(target).Coordinates, target);
Assert.Multiple(() =>
{
Assert.That(interactUsing, Is.False);
Assert.That(interactHand, Is.False);
});
Assert.That(handSys.TryPickup(user, item));
@@ -163,7 +186,7 @@ namespace Content.IntegrationTests.Tests.Interaction.Click
[Test]
public async Task InteractionInRangeTest()
{
await using var pairTracker = await PoolManager.GetServerClient(new PoolSettings{NoClient = true});
await using var pairTracker = await PoolManager.GetServerClient(new PoolSettings { NoClient = true });
var server = pairTracker.Pair.Server;
var sEntities = server.ResolveDependency<IEntityManager>();
@@ -197,8 +220,13 @@ namespace Content.IntegrationTests.Tests.Interaction.Click
await server.WaitRunTicks(1);
var entitySystemManager = server.ResolveDependency<IEntitySystemManager>();
Assert.That(entitySystemManager.TryGetEntitySystem<InteractionSystem>(out var interactionSystem));
Assert.That(entitySystemManager.TryGetEntitySystem<TestInteractionSystem>(out var testInteractionSystem));
InteractionSystem interactionSystem = default!;
TestInteractionSystem testInteractionSystem = default!;
Assert.Multiple(() =>
{
Assert.That(entitySystemManager.TryGetEntitySystem(out interactionSystem));
Assert.That(entitySystemManager.TryGetEntitySystem(out testInteractionSystem));
});
var interactUsing = false;
var interactHand = false;
@@ -208,8 +236,11 @@ namespace Content.IntegrationTests.Tests.Interaction.Click
testInteractionSystem.InteractHandEvent = (ev) => { Assert.That(ev.Target, Is.EqualTo(target)); interactHand = true; };
interactionSystem.UserInteraction(user, sEntities.GetComponent<TransformComponent>(target).Coordinates, target);
Assert.Multiple(() =>
{
Assert.That(interactUsing, Is.False);
Assert.That(interactHand);
});
Assert.That(handSys.TryPickup(user, item));
@@ -225,7 +256,7 @@ namespace Content.IntegrationTests.Tests.Interaction.Click
[Test]
public async Task InteractionOutOfRangeTest()
{
await using var pairTracker = await PoolManager.GetServerClient(new PoolSettings{NoClient = true});
await using var pairTracker = await PoolManager.GetServerClient(new PoolSettings { NoClient = true });
var server = pairTracker.Pair.Server;
var sEntities = server.ResolveDependency<IEntityManager>();
@@ -259,8 +290,13 @@ namespace Content.IntegrationTests.Tests.Interaction.Click
await server.WaitRunTicks(1);
var entitySystemManager = server.ResolveDependency<IEntitySystemManager>();
Assert.That(entitySystemManager.TryGetEntitySystem<InteractionSystem>(out var interactionSystem));
Assert.That(entitySystemManager.TryGetEntitySystem<TestInteractionSystem>(out var testInteractionSystem));
InteractionSystem interactionSystem = default!;
TestInteractionSystem testInteractionSystem = default!;
Assert.Multiple(() =>
{
Assert.That(entitySystemManager.TryGetEntitySystem(out interactionSystem));
Assert.That(entitySystemManager.TryGetEntitySystem(out testInteractionSystem));
});
var interactUsing = false;
var interactHand = false;
@@ -270,8 +306,11 @@ namespace Content.IntegrationTests.Tests.Interaction.Click
testInteractionSystem.InteractHandEvent = (ev) => { Assert.That(ev.Target, Is.EqualTo(target)); interactHand = true; };
interactionSystem.UserInteraction(user, sEntities.GetComponent<TransformComponent>(target).Coordinates, target);
Assert.Multiple(() =>
{
Assert.That(interactUsing, Is.False);
Assert.That(interactHand, Is.False);
});
Assert.That(handSys.TryPickup(user, item));
@@ -286,7 +325,7 @@ namespace Content.IntegrationTests.Tests.Interaction.Click
[Test]
public async Task InsideContainerInteractionBlockTest()
{
await using var pairTracker = await PoolManager.GetServerClient(new PoolSettings{NoClient = true});
await using var pairTracker = await PoolManager.GetServerClient(new PoolSettings { NoClient = true });
var server = pairTracker.Pair.Server;
var sEntities = server.ResolveDependency<IEntityManager>();
@@ -325,8 +364,13 @@ namespace Content.IntegrationTests.Tests.Interaction.Click
await server.WaitRunTicks(1);
var entitySystemManager = server.ResolveDependency<IEntitySystemManager>();
Assert.That(entitySystemManager.TryGetEntitySystem<InteractionSystem>(out var interactionSystem));
Assert.That(entitySystemManager.TryGetEntitySystem<TestInteractionSystem>(out var testInteractionSystem));
InteractionSystem interactionSystem = default!;
TestInteractionSystem testInteractionSystem = default!;
Assert.Multiple(() =>
{
Assert.That(entitySystemManager.TryGetEntitySystem(out interactionSystem));
Assert.That(entitySystemManager.TryGetEntitySystem(out testInteractionSystem));
});
await server.WaitIdleAsync();
@@ -334,19 +378,27 @@ namespace Content.IntegrationTests.Tests.Interaction.Click
var interactHand = false;
await server.WaitAssertion(() =>
{
#pragma warning disable NUnit2045 // Interdependent assertions.
Assert.That(container.Insert(user));
Assert.That(sEntities.GetComponent<TransformComponent>(user).ParentUid, Is.EqualTo(containerEntity));
#pragma warning restore NUnit2045
testInteractionSystem.InteractUsingEvent = (ev) => { Assert.That(ev.Target, Is.EqualTo(containerEntity)); interactUsing = true; };
testInteractionSystem.InteractHandEvent = (ev) => { Assert.That(ev.Target, Is.EqualTo(containerEntity)); interactHand = true; };
interactionSystem.UserInteraction(user, sEntities.GetComponent<TransformComponent>(target).Coordinates, target);
Assert.Multiple(() =>
{
Assert.That(interactUsing, Is.False);
Assert.That(interactHand, Is.False);
});
interactionSystem.UserInteraction(user, sEntities.GetComponent<TransformComponent>(containerEntity).Coordinates, containerEntity);
Assert.Multiple(() =>
{
Assert.That(interactUsing, Is.False);
Assert.That(interactHand);
});
Assert.That(handSys.TryPickup(user, item));

View File

@@ -1,6 +1,4 @@
using System.Threading.Tasks;
using Content.Shared.Interaction;
using NUnit.Framework;
using Robust.Shared.Containers;
using Robust.Shared.GameObjects;
using Robust.Shared.Map;
@@ -27,7 +25,7 @@ namespace Content.IntegrationTests.Tests.Interaction
[Test]
public async Task EntityEntityTest()
{
await using var pairTracker = await PoolManager.GetServerClient(new PoolSettings{NoClient = true});
await using var pairTracker = await PoolManager.GetServerClient(new PoolSettings { NoClient = true });
var server = pairTracker.Pair.Server;
var sEntities = server.ResolveDependency<IEntityManager>();
@@ -51,50 +49,61 @@ namespace Content.IntegrationTests.Tests.Interaction
await server.WaitIdleAsync();
var interactionSys = server.ResolveDependency<IEntitySystemManager>().GetEntitySystem<SharedInteractionSystem>();
var interactionSys = sEntities.System<SharedInteractionSystem>();
var xformSys = sEntities.System<SharedTransformSystem>();
var xform = sEntities.GetComponent<TransformComponent>(origin);
await server.WaitAssertion(() =>
{
Assert.Multiple(() =>
{
// Entity <-> Entity
Assert.True(interactionSys.InRangeUnobstructed(origin, other));
Assert.True(interactionSys.InRangeUnobstructed(other, origin));
Assert.That(interactionSys.InRangeUnobstructed(origin, other));
Assert.That(interactionSys.InRangeUnobstructed(other, origin));
// Entity <-> MapCoordinates
Assert.True(interactionSys.InRangeUnobstructed(origin, mapCoordinates));
Assert.True(interactionSys.InRangeUnobstructed(mapCoordinates, origin));
Assert.That(interactionSys.InRangeUnobstructed(origin, mapCoordinates));
Assert.That(interactionSys.InRangeUnobstructed(mapCoordinates, origin));
});
// Move them slightly apart
sEntities.GetComponent<TransformComponent>(origin).LocalPosition += _interactionRangeDivided15X;
xformSys.SetLocalPosition(origin, xform.LocalPosition + _interactionRangeDivided15X, xform);
Assert.Multiple(() =>
{
// Entity <-> Entity
// Entity <-> Entity
Assert.True(interactionSys.InRangeUnobstructed(origin, other));
Assert.True(interactionSys.InRangeUnobstructed(other, origin));
Assert.That(interactionSys.InRangeUnobstructed(origin, other));
Assert.That(interactionSys.InRangeUnobstructed(other, origin));
// Entity <-> MapCoordinates
Assert.True(interactionSys.InRangeUnobstructed(origin, mapCoordinates));
Assert.True(interactionSys.InRangeUnobstructed(mapCoordinates, origin));
Assert.That(interactionSys.InRangeUnobstructed(origin, mapCoordinates));
Assert.That(interactionSys.InRangeUnobstructed(mapCoordinates, origin));
});
// Move them out of range
sEntities.GetComponent<TransformComponent>(origin).LocalPosition += new Vector2(InteractionRangeDivided15 + HumanRadius * 2f, 0f);
xformSys.SetLocalPosition(origin, xform.LocalPosition + new Vector2(InteractionRangeDivided15 + HumanRadius * 2f, 0f), xform);
Assert.Multiple(() =>
{
// Entity <-> Entity
Assert.False(interactionSys.InRangeUnobstructed(origin, other));
Assert.False(interactionSys.InRangeUnobstructed(other, origin));
Assert.That(interactionSys.InRangeUnobstructed(origin, other), Is.False);
Assert.That(interactionSys.InRangeUnobstructed(other, origin), Is.False);
// Entity <-> MapCoordinates
Assert.False(interactionSys.InRangeUnobstructed(origin, mapCoordinates));
Assert.False(interactionSys.InRangeUnobstructed(mapCoordinates, origin));
Assert.That(interactionSys.InRangeUnobstructed(origin, mapCoordinates), Is.False);
Assert.That(interactionSys.InRangeUnobstructed(mapCoordinates, origin), Is.False);
// Checks with increased range
// Entity <-> Entity
Assert.True(interactionSys.InRangeUnobstructed(origin, other, InteractionRangeDivided15Times3));
Assert.True(interactionSys.InRangeUnobstructed(other, origin, InteractionRangeDivided15Times3));
Assert.That(interactionSys.InRangeUnobstructed(origin, other, InteractionRangeDivided15Times3));
Assert.That(interactionSys.InRangeUnobstructed(other, origin, InteractionRangeDivided15Times3));
// Entity <-> MapCoordinates
Assert.True(interactionSys.InRangeUnobstructed(origin, mapCoordinates, InteractionRangeDivided15Times3));
Assert.True(interactionSys.InRangeUnobstructed(mapCoordinates, origin, InteractionRangeDivided15Times3));
Assert.That(interactionSys.InRangeUnobstructed(origin, mapCoordinates, InteractionRangeDivided15Times3));
Assert.That(interactionSys.InRangeUnobstructed(mapCoordinates, origin, InteractionRangeDivided15Times3));
});
});
await pairTracker.CleanReturnAsync();

View File

@@ -1,7 +1,5 @@
#nullable enable
using System.Threading.Tasks;
using Content.Shared.Stacks;
using NUnit.Framework;
using Robust.Shared.GameObjects;
using Robust.Shared.Map;
using Robust.Shared.Prototypes;
@@ -41,7 +39,7 @@ public abstract partial class InteractionTest
public EntitySpecifier(string prototype, int quantity, bool converted = false)
{
Assert.That(quantity > 0);
Assert.That(quantity, Is.GreaterThan(0));
Prototype = prototype;
Quantity = quantity;
Converted = converted;
@@ -109,7 +107,7 @@ public abstract partial class InteractionTest
}
Assert.That(spec.Quantity, Is.EqualTo(1), "SpawnEntity only supports returning a singular entity");
await Server.WaitPost(() => uid = SEntMan.SpawnEntity(spec.Prototype, coords));;
await Server.WaitPost(() => uid = SEntMan.SpawnEntity(spec.Prototype, coords));
return uid;
}
@@ -120,11 +118,11 @@ public abstract partial class InteractionTest
protected EntitySpecifier ToEntitySpecifier(EntityUid uid)
{
if (SEntMan.TryGetComponent(uid, out StackComponent? stack))
return new EntitySpecifier(stack.StackTypeId, stack.Count) {Converted = true};
return new EntitySpecifier(stack.StackTypeId, stack.Count) { Converted = true };
var meta = SEntMan.GetComponent<MetaDataComponent>(uid);
Assert.NotNull(meta.EntityPrototype);
Assert.That(meta.EntityPrototype, Is.Not.Null);
return new (meta.EntityPrototype!.ID, 1) { Converted = true };
return new(meta.EntityPrototype!.ID, 1) { Converted = true };
}
}

View File

@@ -2,7 +2,6 @@
using System.Collections.Generic;
using System.Linq;
using Content.Shared.Stacks;
using NUnit.Framework;
using Robust.Shared.GameObjects;
using Robust.Shared.Prototypes;
using Robust.Shared.Utility;
@@ -53,10 +52,14 @@ public abstract partial class InteractionTest
}
public void Remove(EntitySpecifier spec)
=> Add(new EntitySpecifier(spec.Prototype, -spec.Quantity, spec.Converted));
{
Add(new EntitySpecifier(spec.Prototype, -spec.Quantity, spec.Converted));
}
public void Add(EntitySpecifier spec)
=> Add(spec.Prototype, spec.Quantity, spec.Converted);
{
Add(spec.Prototype, spec.Quantity, spec.Converted);
}
public void Add(string id, int quantity, bool converted = false)
{

View File

@@ -1,12 +1,8 @@
#nullable enable
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Threading.Tasks;
using Content.Client.Chemistry.UI;
using Content.Client.Construction;
using Content.Server.Atmos;
using Content.Server.Atmos.Components;
@@ -19,15 +15,11 @@ using Content.Shared.Atmos;
using Content.Shared.Construction.Prototypes;
using Content.Shared.Gravity;
using Content.Shared.Item;
using NUnit.Framework;
using OpenToolkit.GraphicsLibraryFramework;
using Robust.Client.GameObjects;
using Robust.Client.UserInterface;
using Robust.Client.UserInterface.Controls;
using Robust.Client.UserInterface.CustomControls;
using Robust.Shared.GameObjects;
using Robust.Shared.Input;
using Robust.Shared.Log;
using Robust.Shared.Map;
using Robust.Shared.Map.Components;
using Robust.Shared.Maths;
@@ -67,7 +59,7 @@ public abstract partial class InteractionTest
Assert.That(ProtoMan.Index<ConstructionPrototype>(prototype).Type, Is.EqualTo(ConstructionType.Item));
// Please someone purge async construction code
Task<bool> task =default!;
Task<bool> task = default!;
await Server.WaitPost(() => task = SConstruction.TryStartItemConstruction(prototype, Player));
Task? tickTask = null;
@@ -119,18 +111,18 @@ public abstract partial class InteractionTest
/// </summary>
protected async Task DeleteHeldEntity()
{
if (Hands.ActiveHandEntity is {} held)
if (Hands.ActiveHandEntity is { } held)
{
await Server.WaitPost(() =>
{
Assert.That(HandSys.TryDrop(Player, null, false, true, Hands));
SEntMan.DeleteEntity(held);
Logger.Debug($"Deleting held entity");
SLogger.Debug($"Deleting held entity");
});
}
await RunTicks(1);
Assert.That(Hands.ActiveHandEntity == null);
Assert.That(Hands.ActiveHandEntity, Is.Null);
}
/// <summary>
@@ -140,7 +132,9 @@ public abstract partial class InteractionTest
/// Automatically enables welders.
/// </remarks>
protected async Task<EntityUid?> PlaceInHands(string? id, int quantity = 1, bool enableWelder = true)
=> await PlaceInHands(id == null ? null : (id, quantity), enableWelder);
{
return await PlaceInHands(id == null ? null : (id, quantity), enableWelder);
}
/// <summary>
/// Place an entity prototype into the players hand. Deletes any currently held entity.
@@ -161,12 +155,12 @@ public abstract partial class InteractionTest
if (entity == null || string.IsNullOrWhiteSpace(entity.Prototype))
{
await RunTicks(1);
Assert.That(Hands.ActiveHandEntity == null);
Assert.That(Hands.ActiveHandEntity, Is.Null);
return null;
}
// spawn and pick up the new item
EntityUid item = await SpawnEntity(entity, PlayerCoords);
var item = await SpawnEntity(entity, PlayerCoords);
WelderComponent? welder = null;
await Server.WaitPost(() =>
@@ -234,7 +228,7 @@ public abstract partial class InteractionTest
});
await RunTicks(1);
Assert.IsNull(Hands.ActiveHandEntity);
Assert.That(Hands.ActiveHandEntity, Is.Null);
}
#region Interact
@@ -244,7 +238,7 @@ public abstract partial class InteractionTest
/// </summary>
protected async Task UseInHand()
{
if (Hands.ActiveHandEntity is not {} target)
if (Hands.ActiveHandEntity is not { } target)
{
Assert.Fail("Not holding any entity");
return;
@@ -263,7 +257,9 @@ public abstract partial class InteractionTest
/// Empty strings imply empty hands.
/// </remarks>
protected async Task Interact(string id, int quantity = 1, bool shouldSucceed = true, bool awaitDoAfters = true)
=> await Interact((id, quantity), shouldSucceed, awaitDoAfters);
{
await Interact((id, quantity), shouldSucceed, awaitDoAfters);
}
/// <summary>
/// Place an entity prototype into the players hand and interact with the given entity (or target position)
@@ -406,7 +402,7 @@ public abstract partial class InteractionTest
Assert.That(CTestSystem.Ghosts.TryGetValue(ConstructionGhostId, out newTarget),
$"Failed to get construction entity from ghost Id");
await Client.WaitPost(() => Logger.Debug($"Construction ghost {ConstructionGhostId} became entity {newTarget}"));
await Client.WaitPost(() => CLogger.Debug($"Construction ghost {ConstructionGhostId} became entity {newTarget}"));
Target = newTarget;
}
}
@@ -414,7 +410,7 @@ public abstract partial class InteractionTest
if (STestSystem.EntChanges.TryGetValue(Target.Value, out newTarget))
{
await Server.WaitPost(
() => Logger.Debug($"Construction entity {Target.Value} changed to {newTarget}"));
() => SLogger.Debug($"Construction entity {Target.Value} changed to {newTarget}"));
Target = newTarget;
}
@@ -449,8 +445,12 @@ public abstract partial class InteractionTest
var sXform = SEntMan.GetComponent<TransformComponent>(target.Value);
var cXform = CEntMan.GetComponent<TransformComponent>(target.Value);
Assert.Multiple(() =>
{
Assert.That(sXform.Anchored, Is.EqualTo(anchored));
Assert.That(cXform.Anchored, Is.EqualTo(anchored));
});
}
protected void AssertDeleted(bool deleted = true, EntityUid? target = null)
@@ -462,8 +462,11 @@ public abstract partial class InteractionTest
return;
}
Assert.Multiple(() =>
{
Assert.That(SEntMan.Deleted(target), Is.EqualTo(deleted));
Assert.That(CEntMan.Deleted(target), Is.EqualTo(deleted));
});
}
/// <summary>
@@ -490,7 +493,7 @@ public abstract partial class InteractionTest
? Tile.Empty
: new Tile(TileMan[proto].TileId);
Tile tile = Tile.Empty;
var tile = Tile.Empty;
var pos = (coords ?? TargetCoords).ToMap(SEntMan, Transform);
await Server.WaitPost(() =>
{
@@ -699,10 +702,14 @@ public abstract partial class InteractionTest
}
protected int SecondsToTicks(float seconds)
=> (int) Math.Ceiling(seconds / TickPeriod);
{
return (int) Math.Ceiling(seconds / TickPeriod);
}
protected async Task RunSeconds(float seconds)
=> await RunTicks(SecondsToTicks(seconds));
{
await RunTicks(SecondsToTicks(seconds));
}
#endregion
@@ -710,7 +717,7 @@ public abstract partial class InteractionTest
/// <summary>
/// Sends a bui message using the given bui key.
/// </summary>
protected async Task SendBui(Enum key, BoundUserInterfaceMessage msg, EntityUid? target = null)
protected async Task SendBui(Enum key, BoundUserInterfaceMessage msg, EntityUid? _ = null)
{
if (!TryGetBui(key, out var bui))
return;
@@ -724,7 +731,7 @@ public abstract partial class InteractionTest
/// <summary>
/// Sends a bui message using the given bui key.
/// </summary>
protected async Task CloseBui(Enum key, EntityUid? target = null)
protected async Task CloseBui(Enum key, EntityUid? _ = null)
{
if (!TryGetBui(key, out var bui))
return;
@@ -782,7 +789,7 @@ public abstract partial class InteractionTest
protected async Task ClickControl(Control control)
{
var screenCoords = new ScreenCoordinates(
control.GlobalPixelPosition + control.PixelSize/2,
control.GlobalPixelPosition + control.PixelSize / 2,
control.Window?.Id ?? default);
var relativePos = screenCoords.Position / control.UIScale - control.GlobalPosition;
@@ -836,9 +843,9 @@ public abstract partial class InteractionTest
}
var window = GetWindow<TWindow>();
var control = (field?.GetValue(window) ?? prop?.GetValue(window)) as Control;
var fieldOrProp = field?.GetValue(window) ?? prop?.GetValue(window);
if (control == null)
if (fieldOrProp is not Control control)
{
Assert.Fail($"{name} was null or was not a control.");
return default!;

View File

@@ -1,11 +1,9 @@
#nullable enable
using System.Linq;
using System.Threading.Tasks;
using Content.Client.Construction;
using Content.Client.Examine;
using Content.Server.Body.Systems;
using Content.Server.Mind;
using Content.Server.Mind.Components;
using Content.Server.Players;
using Content.Server.Stack;
using Content.Server.Tools;
@@ -14,12 +12,12 @@ using Content.Shared.DoAfter;
using Content.Shared.Hands.Components;
using Content.Shared.Hands.EntitySystems;
using Content.Shared.Interaction;
using NUnit.Framework;
using Robust.Client.GameObjects;
using Robust.Client.Input;
using Robust.Client.UserInterface;
using Robust.Server.GameObjects;
using Robust.Server.Player;
using Robust.Shared.GameObjects;
using Robust.Shared.Log;
using Robust.Shared.Map;
using Robust.Shared.Players;
using Robust.Shared.Prototypes;
@@ -99,22 +97,25 @@ public abstract partial class InteractionTest
protected ToolSystem ToolSys = default!;
protected InteractionTestSystem STestSystem = default!;
protected SharedTransformSystem Transform = default!;
protected ActorSystem Actor = default!;
protected ISawmill SLogger = default!;
// CLIENT dependencies
protected IEntityManager CEntMan = default!;
protected IGameTiming CTiming = default!;
protected IUserInterfaceManager UiMan = default!;
protected IInputManager InputManager = default!;
protected InputSystem InputSystem = default!;
protected Robust.Client.GameObjects.InputSystem InputSystem = default!;
protected ConstructionSystem CConSys = default!;
protected ExamineSystem ExamineSys = default!;
protected InteractionTestSystem CTestSystem = default!;
protected ISawmill CLogger = default!;
// player components
protected HandsComponent Hands = default!;
protected DoAfterComponent DoAfters = default!;
public float TickPeriod => (float)STiming.TickPeriod.TotalSeconds;
public float TickPeriod => (float) STiming.TickPeriod.TotalSeconds;
// Simple mob that has one hand and can perform misc interactions.
@@ -137,7 +138,7 @@ public abstract partial class InteractionTest
[SetUp]
public virtual async Task Setup()
{
PairTracker = await PoolManager.GetServerClient(new PoolSettings{ExtraPrototypes = TestPrototypes});
PairTracker = await PoolManager.GetServerClient(new PoolSettings { ExtraPrototypes = TestPrototypes });
// server dependencies
SEntMan = Server.ResolveDependency<IEntityManager>();
@@ -151,19 +152,22 @@ public abstract partial class InteractionTest
ToolSys = SEntMan.System<ToolSystem>();
DoAfterSys = SEntMan.System<SharedDoAfterSystem>();
Transform = SEntMan.System<SharedTransformSystem>();
SConstruction = SEntMan.System<Content.Server.Construction.ConstructionSystem>();
SConstruction = SEntMan.System<Server.Construction.ConstructionSystem>();
STestSystem = SEntMan.System<InteractionTestSystem>();
Stack = SEntMan.System<StackSystem>();
Actor = SEntMan.System<ActorSystem>();
SLogger = Server.ResolveDependency<ILogManager>().RootSawmill;
// client dependencies
CEntMan = Client.ResolveDependency<IEntityManager>();
UiMan = Client.ResolveDependency<IUserInterfaceManager>();
CTiming = Client.ResolveDependency<IGameTiming>();
InputManager = Client.ResolveDependency<IInputManager>();
InputSystem = CEntMan.System<InputSystem>();
InputSystem = CEntMan.System<Robust.Client.GameObjects.InputSystem>();
CTestSystem = CEntMan.System<InteractionTestSystem>();
CConSys = CEntMan.System<ConstructionSystem>();
ExamineSys = CEntMan.System<ExamineSystem>();
CLogger = Client.ResolveDependency<ILogManager>().RootSawmill;
// Setup map.
MapData = await PoolManager.CreateTestMap(PairTracker);
@@ -189,7 +193,7 @@ public abstract partial class InteractionTest
old = cPlayerMan.LocalPlayer.ControlledEntity;
Player = SEntMan.SpawnEntity(PlayerPrototype, PlayerCoords);
ServerSession.AttachToEntity(Player);
Actor.Attach(Player, ServerSession);
Hands = SEntMan.GetComponent<HandsComponent>(Player);
DoAfters = SEntMan.GetComponent<DoAfterComponent>(Player);
});
@@ -220,8 +224,11 @@ public abstract partial class InteractionTest
// Final player asserts/checks.
await PoolManager.ReallyBeIdle(PairTracker.Pair, 5);
Assert.Multiple(() =>
{
Assert.That(cPlayerMan.LocalPlayer.ControlledEntity, Is.EqualTo(Player));
Assert.That(sPlayerMan.GetSessionByUserId(ClientSession.UserId).AttachedEntity, Is.EqualTo(Player));
});
}
[TearDown]
@@ -231,4 +238,3 @@ public abstract partial class InteractionTest
await PairTracker.CleanReturnAsync();
}
}

View File

@@ -1,9 +1,5 @@
#nullable enable
using System;
using System.Threading.Tasks;
using NUnit.Framework;
using Robust.Shared.GameObjects;
using Robust.Shared.Maths;
namespace Content.IntegrationTests.Tests.Interaction;
@@ -32,14 +28,14 @@ public abstract class MovementTest : InteractionTest
await base.Setup();
for (var i = -Tiles; i <= Tiles; i++)
{
await SetTile(Plating, PlayerCoords.Offset((i,0)), MapData.MapGrid);
await SetTile(Plating, PlayerCoords.Offset((i, 0)), MapData.MapGrid);
}
AssertGridCount(1);
if (AddWalls)
{
await SpawnEntity("WallSolid", PlayerCoords.Offset((-Tiles,0)));
await SpawnEntity("WallSolid", PlayerCoords.Offset((Tiles,0)));
await SpawnEntity("WallSolid", PlayerCoords.Offset((-Tiles, 0)));
await SpawnEntity("WallSolid", PlayerCoords.Offset((Tiles, 0)));
}
await AddGravity();

View File

@@ -1,8 +1,5 @@
using System;
using System.Threading.Tasks;
using Content.Server.Stunnable;
using Content.Server.Stunnable;
using Content.Shared.Inventory;
using NUnit.Framework;
using Robust.Shared.GameObjects;
using Robust.Shared.IoC;
using Robust.Shared.Map;
@@ -43,7 +40,7 @@ namespace Content.IntegrationTests.Tests
[Test]
public async Task SpawnItemInSlotTest()
{
await using var pairTracker = await PoolManager.GetServerClient(new PoolSettings{NoClient = true, ExtraPrototypes = Prototypes});
await using var pairTracker = await PoolManager.GetServerClient(new PoolSettings { NoClient = true, ExtraPrototypes = Prototypes });
var server = pairTracker.Pair.Server;
var sEntities = server.ResolveDependency<IEntityManager>();
@@ -54,21 +51,27 @@ namespace Content.IntegrationTests.Tests
var human = sEntities.SpawnEntity("InventoryStunnableDummy", MapCoordinates.Nullspace);
var invSystem = systemMan.GetEntitySystem<InventorySystem>();
Assert.Multiple(() =>
{
// Can't do the test if this human doesn't have the slots for it.
Assert.That(invSystem.HasSlot(human, "jumpsuit"));
Assert.That(invSystem.HasSlot(human, "id"));
});
Assert.That(invSystem.SpawnItemInSlot(human, "jumpsuit", "InventoryJumpsuitJanitorDummy", true));
#pragma warning disable NUnit2045
// Do we actually have the uniform equipped?
Assert.That(invSystem.TryGetSlotEntity(human, "jumpsuit", out var uniform));
Assert.That(sEntities.GetComponent<MetaDataComponent>(uniform.Value).EntityPrototype is
{
ID: "InventoryJumpsuitJanitorDummy"
});
#pragma warning restore NUnit2045
systemMan.GetEntitySystem<StunSystem>().TryStun(human, TimeSpan.FromSeconds(1f), true);
#pragma warning disable NUnit2045
// Since the mob is stunned, they can't equip this.
Assert.That(invSystem.SpawnItemInSlot(human, "id", "InventoryIDCardDummy", true), Is.False);
@@ -82,6 +85,7 @@ namespace Content.IntegrationTests.Tests
{
ID: "InventoryIDCardDummy"
});
#pragma warning restore NUnit2045
});
await pairTracker.CleanReturnAsync();
}

View File

@@ -1,10 +1,7 @@
using System;
using System.Threading.Tasks;
using Content.Client.Lobby;
using Content.Client.Preferences;
using Content.Server.Preferences.Managers;
using Content.Shared.Preferences;
using NUnit.Framework;
using Robust.Client.State;
using Robust.Shared.Network;
@@ -18,7 +15,7 @@ namespace Content.IntegrationTests.Tests.Lobby
[Test]
public async Task CreateDeleteCreateTest()
{
await using var pairTracker = await PoolManager.GetServerClient(new PoolSettings{InLobby = true});
await using var pairTracker = await PoolManager.GetServerClient(new PoolSettings { InLobby = true });
var server = pairTracker.Pair.Server;
var client = pairTracker.Pair.Client;
@@ -34,7 +31,7 @@ namespace Content.IntegrationTests.Tests.Lobby
await PoolManager.WaitUntil(client, () => clientStateManager.CurrentState is LobbyState, 600);
Assert.NotNull(clientNetManager.ServerChannel);
Assert.That(clientNetManager.ServerChannel, Is.Not.Null);
var clientNetId = clientNetManager.ServerChannel.UserId;
HumanoidCharacterProfile profile = null;
@@ -45,9 +42,12 @@ namespace Content.IntegrationTests.Tests.Lobby
var clientCharacters = clientPrefManager.Preferences?.Characters;
Assert.That(clientCharacters, Is.Not.Null);
Assert.That(clientCharacters.Count, Is.EqualTo(1));
Assert.Multiple(() =>
{
Assert.That(clientCharacters, Has.Count.EqualTo(1));
Assert.That(clientStateManager.CurrentState, Is.TypeOf<LobbyState>());
});
profile = HumanoidCharacterProfile.Random();
clientPrefManager.CreateCharacter(profile);
@@ -55,7 +55,7 @@ namespace Content.IntegrationTests.Tests.Lobby
clientCharacters = clientPrefManager.Preferences?.Characters;
Assert.That(clientCharacters, Is.Not.Null);
Assert.That(clientCharacters.Count, Is.EqualTo(2));
Assert.That(clientCharacters, Has.Count.EqualTo(2));
Assert.That(clientCharacters[1].MemberwiseEquals(profile));
});
@@ -65,7 +65,7 @@ namespace Content.IntegrationTests.Tests.Lobby
{
var serverCharacters = serverPrefManager.GetPreferences(clientNetId).Characters;
Assert.That(serverCharacters.Count, Is.EqualTo(2));
Assert.That(serverCharacters, Has.Count.EqualTo(2));
Assert.That(serverCharacters[1].MemberwiseEquals(profile));
});
@@ -96,7 +96,7 @@ namespace Content.IntegrationTests.Tests.Lobby
var clientCharacters = clientPrefManager.Preferences?.Characters;
Assert.That(clientCharacters, Is.Not.Null);
Assert.That(clientCharacters.Count, Is.EqualTo(2));
Assert.That(clientCharacters, Has.Count.EqualTo(2));
Assert.That(clientCharacters[1].MemberwiseEquals(profile));
});
@@ -106,7 +106,7 @@ namespace Content.IntegrationTests.Tests.Lobby
{
var serverCharacters = serverPrefManager.GetPreferences(clientNetId).Characters;
Assert.That(serverCharacters.Count, Is.EqualTo(2));
Assert.That(serverCharacters, Has.Count.EqualTo(2));
Assert.That(serverCharacters[1].MemberwiseEquals(profile));
});
await pairTracker.CleanReturnAsync();

View File

@@ -1,10 +1,7 @@
using System.Linq;
using System.Threading.Tasks;
using Content.Shared.CCVar;
using NUnit.Framework;
using Robust.Server.Player;
using Robust.Shared.Configuration;
using Robust.Shared.IoC;
using Robust.Shared.Network;
namespace Content.IntegrationTests.Tests.Lobby;
@@ -16,7 +13,7 @@ public sealed class ServerReloginTest
await using var pairTracker = await PoolManager.GetServerClient();
var server = pairTracker.Pair.Server;
var client = pairTracker.Pair.Client;
int originalMaxPlayers = 0;
var originalMaxPlayers = 0;
string username = null;
var serverConfig = server.ResolveDependency<IConfigurationManager>();

View File

@@ -1,5 +1,3 @@
using System.Threading.Tasks;
using NUnit.Framework;
using Robust.Shared.Configuration;
using Robust.Shared.Log;
using Robust.UnitTesting;
@@ -19,15 +17,16 @@ public sealed class LogErrorTest
var client = pairTracker.Pair.Client;
var cfg = server.ResolveDependency<IConfigurationManager>();
var logmill = server.ResolveDependency<ILogManager>().RootSawmill;
// Default cvar is properly configured
Assert.That(cfg.GetCVar(RTCVars.FailureLogLevel), Is.EqualTo(LogLevel.Error));
// Warnings don't cause tests to fail.
await server.WaitPost(() => Logger.Warning("test"));
await server.WaitPost(() => logmill.Warning("test"));
// But errors do
await server.WaitPost(() => Assert.Throws<AssertionException>(() => Logger.Error("test")));
await client.WaitPost(() => Assert.Throws<AssertionException>(() => Logger.Error("test")));
await server.WaitPost(() => Assert.Throws<AssertionException>(() => logmill.Error("test")));
await client.WaitPost(() => Assert.Throws<AssertionException>(() => logmill.Error("test")));
}
}

View File

@@ -1,9 +1,7 @@
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Content.Server.Construction.Components;
using Content.Shared.Construction.Components;
using NUnit.Framework;
using Robust.Shared.Prototypes;
namespace Content.IntegrationTests.Tests;

View File

@@ -9,13 +9,10 @@ using Content.Shared.Construction.Steps;
using Content.Shared.Lathe;
using Content.Shared.Research.Prototypes;
using Content.Shared.Stacks;
using NUnit.Framework;
using Robust.Shared.GameObjects;
using Robust.Shared.Map;
using Robust.Shared.Prototypes;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Content.Shared.Chemistry.Reagent;
using Content.Shared.Construction.Components;
using Content.Shared.FixedPoint;
@@ -33,7 +30,7 @@ public sealed class MaterialArbitrageTest
[Test]
public async Task NoMaterialArbitrage()
{
await using var pairTracker = await PoolManager.GetServerClient(new PoolSettings {NoClient = true});
await using var pairTracker = await PoolManager.GetServerClient(new PoolSettings { NoClient = true });
var server = pairTracker.Pair.Server;
var testMap = await PoolManager.CreateTestMap(pairTracker);
@@ -186,7 +183,7 @@ public sealed class MaterialArbitrageTest
var spawnedPrice = await GetSpawnedPrice(spawnedEnts);
var price = await GetPrice(id);
if (spawnedPrice > 0 && price > 0)
Assert.LessOrEqual(spawnedPrice, price, $"{id} increases in price after being destroyed");
Assert.That(spawnedPrice, Is.LessThanOrEqualTo(price), $"{id} increases in price after being destroyed");
// Check lathe production
if (latheRecipes.TryGetValue(id, out var recipe))
@@ -195,7 +192,7 @@ public sealed class MaterialArbitrageTest
{
var actualAmount = SharedLatheSystem.AdjustMaterial(amount, recipe.ApplyMaterialDiscount, multiplier);
if (spawnedMats.TryGetValue(matId, out var numSpawned))
Assert.LessOrEqual(numSpawned, actualAmount, $"destroying a {id} spawns more {matId} than required to produce via an (upgraded) lathe.");
Assert.That(numSpawned, Is.LessThanOrEqualTo(actualAmount), $"destroying a {id} spawns more {matId} than required to produce via an (upgraded) lathe.");
}
}
@@ -205,7 +202,7 @@ public sealed class MaterialArbitrageTest
foreach (var (matId, amount) in constructionMats)
{
if (spawnedMats.TryGetValue(matId, out var numSpawned))
Assert.LessOrEqual(numSpawned, amount, $"destroying a {id} spawns more {matId} than required to construct it.");
Assert.That(numSpawned, Is.LessThanOrEqualTo(amount), $"destroying a {id} spawns more {matId} than required to construct it.");
}
}
}
@@ -263,7 +260,7 @@ public sealed class MaterialArbitrageTest
var deconstructedPrice = await GetDeconstructedPrice(deconstructedMats);
var price = await GetPrice(id);
if (deconstructedPrice > 0 && price > 0)
Assert.LessOrEqual(deconstructedPrice, price, $"{id} increases in price after being deconstructed");
Assert.That(deconstructedPrice, Is.LessThanOrEqualTo(price), $"{id} increases in price after being deconstructed");
// Check lathe production
if (latheRecipes.TryGetValue(id, out var recipe))
@@ -272,7 +269,7 @@ public sealed class MaterialArbitrageTest
{
var actualAmount = SharedLatheSystem.AdjustMaterial(amount, recipe.ApplyMaterialDiscount, multiplier);
if (deconstructedMats.TryGetValue(matId, out var numSpawned))
Assert.LessOrEqual(numSpawned, actualAmount, $"deconstructing {id} spawns more {matId} than required to produce via an (upgraded) lathe.");
Assert.That(numSpawned, Is.LessThanOrEqualTo(actualAmount), $"deconstructing {id} spawns more {matId} than required to produce via an (upgraded) lathe.");
}
}
@@ -282,7 +279,7 @@ public sealed class MaterialArbitrageTest
foreach (var (matId, amount) in constructionMats)
{
if (deconstructedMats.TryGetValue(matId, out var numSpawned))
Assert.LessOrEqual(numSpawned, amount, $"deconstructing a {id} spawns more {matId} than required to construct it.");
Assert.That(numSpawned, Is.LessThanOrEqualTo(amount), $"deconstructing a {id} spawns more {matId} than required to construct it.");
}
}
}
@@ -315,7 +312,7 @@ public sealed class MaterialArbitrageTest
var sumPrice = materialPrice + chemicalPrice;
var price = await GetPrice(id);
if (sumPrice > 0 && price > 0)
Assert.LessOrEqual(sumPrice, price, $"{id} increases in price after decomposed into raw materials");
Assert.That(sumPrice, Is.LessThanOrEqualTo(price), $"{id} increases in price after decomposed into raw materials");
// Check lathe production
if (latheRecipes.TryGetValue(id, out var recipe))
@@ -324,7 +321,7 @@ public sealed class MaterialArbitrageTest
{
var actualAmount = SharedLatheSystem.AdjustMaterial(amount, recipe.ApplyMaterialDiscount, multiplier);
if (compositionComponent.MaterialComposition.TryGetValue(matId, out var numSpawned))
Assert.LessOrEqual(numSpawned, actualAmount, $"The physical composition of {id} has more {matId} than required to produce via an (upgraded) lathe.");
Assert.That(numSpawned, Is.LessThanOrEqualTo(actualAmount), $"The physical composition of {id} has more {matId} than required to produce via an (upgraded) lathe.");
}
}
@@ -334,7 +331,7 @@ public sealed class MaterialArbitrageTest
foreach (var (matId, amount) in constructionMats)
{
if (compositionComponent.MaterialComposition.TryGetValue(matId, out var numSpawned))
Assert.LessOrEqual(numSpawned, amount, $"The physical composition of {id} has more {matId} than required to construct it.");
Assert.That(numSpawned, Is.LessThanOrEqualTo(amount), $"The physical composition of {id} has more {matId} than required to construct it.");
}
}
}
@@ -369,7 +366,7 @@ public sealed class MaterialArbitrageTest
return price;
}
#pragma warning disable CS1998
async Task<double> GetDeconstructedPrice(Dictionary<string, int> mats)
{
double price = 0;
@@ -380,8 +377,9 @@ public sealed class MaterialArbitrageTest
}
return price;
}
#pragma warning restore CS1998
#pragma warning disable CS1998
async Task<double> GetChemicalCompositionPrice(Dictionary<string, FixedPoint2> mats)
{
double price = 0;
@@ -392,5 +390,6 @@ public sealed class MaterialArbitrageTest
}
return price;
}
#pragma warning restore CS1998
}
}

View File

@@ -1,6 +1,4 @@
#nullable enable
using NUnit.Framework;
using System.Threading.Tasks;
using Content.Server.Stack;
using Content.Shared.Stacks;
using Content.Shared.Materials;
@@ -22,7 +20,7 @@ namespace Content.IntegrationTests.Tests.Materials
[Test]
public async Task MaterialPrototypeSpawnsStackMaterial()
{
await using var pairTracker = await PoolManager.GetServerClient(new PoolSettings{NoClient = true});
await using var pairTracker = await PoolManager.GetServerClient(new PoolSettings { NoClient = true });
var server = pairTracker.Pair.Server;
await server.WaitIdleAsync();

View File

@@ -1,11 +1,9 @@
#nullable enable
using System.Linq;
using System.Threading.Tasks;
using Content.Server.Ghost.Roles;
using Content.Server.Ghost.Roles.Components;
using Content.Server.Mind;
using Content.Server.Players;
using NUnit.Framework;
using Robust.Shared.Console;
using Robust.Shared.GameObjects;
using Robust.Shared.Map;
@@ -31,7 +29,7 @@ public sealed class GhostRoleTests
[Test]
public async Task TakeRoleAndReturn()
{
await using var pairTracker = await PoolManager.GetServerClient(new PoolSettings {ExtraPrototypes = Prototypes});
await using var pairTracker = await PoolManager.GetServerClient(new PoolSettings { ExtraPrototypes = Prototypes });
var server = pairTracker.Pair.Server;
var client = pairTracker.Pair.Client;

View File

@@ -1,9 +1,7 @@
using System.Linq;
using System.Threading.Tasks;
using Content.Server.Ghost.Components;
using Content.Server.Mind;
using Content.Server.Players;
using NUnit.Framework;
using Robust.Server.Console;
using Robust.Server.GameObjects;
using Robust.Server.Player;
@@ -45,17 +43,22 @@ public sealed partial class MindTests
mindSystem.TransferTo(mind, playerEnt);
mindSystem.Visit(mind, visitEnt);
Assert.Multiple(() =>
{
Assert.That(player.AttachedEntity, Is.EqualTo(visitEnt));
Assert.That(mind.VisitingEntity, Is.EqualTo(visitEnt));
});
});
await PoolManager.RunTicksSync(pairTracker.Pair, 5);
await server.WaitPost(() => entMan.DeleteEntity(visitEnt));
await PoolManager.RunTicksSync(pairTracker.Pair, 5);
Assert.IsNull(mind.VisitingEntity);
#pragma warning disable NUnit2045 // Interdependent assertions.
Assert.That(mind.VisitingEntity, Is.Null);
Assert.That(entMan.EntityExists(mind.OwnedEntity));
Assert.That(mind.OwnedEntity, Is.EqualTo(playerEnt));
#pragma warning restore NUnit2045
// This used to throw so make sure it doesn't.
await server.WaitPost(() => entMan.DeleteEntity(mind.OwnedEntity!.Value));
@@ -97,8 +100,10 @@ public sealed partial class MindTests
await server.WaitAssertion(() =>
{
Assert.That(entMan.EntityExists(mind.CurrentEntity!.Value), Is.True);
#pragma warning disable NUnit2045 // Interdependent assertions.
Assert.That(entMan.EntityExists(mind.CurrentEntity), Is.True);
Assert.That(mind.CurrentEntity, Is.Not.EqualTo(playerEnt));
#pragma warning restore NUnit2045
});
await pairTracker.CleanReturnAsync();
@@ -119,7 +124,7 @@ public sealed partial class MindTests
var entMan = server.ResolveDependency<IServerEntityManager>();
var playerMan = server.ResolveDependency<IPlayerManager>();
IPlayerSession player = playerMan.ServerSessions.Single();
var player = playerMan.ServerSessions.Single();
Assert.That(!entMan.HasComponent<GhostComponent>(player.AttachedEntity), "Player was initially a ghost?");
@@ -154,8 +159,10 @@ public sealed partial class MindTests
var mind = GetMind(pairTracker.Pair);
var player = playerMan.ServerSessions.Single();
Assert.NotNull(player.AttachedEntity);
#pragma warning disable NUnit2045 // Interdependent assertions.
Assert.That(player.AttachedEntity, Is.Not.Null);
Assert.That(entMan.EntityExists(player.AttachedEntity));
#pragma warning restore NUnit2045
var originalEntity = player.AttachedEntity.Value;
EntityUid ghost = default!;
@@ -165,10 +172,13 @@ public sealed partial class MindTests
mindSystem.Visit(mind, ghost);
});
Assert.Multiple(() =>
{
Assert.That(player.AttachedEntity, Is.EqualTo(ghost));
Assert.That(entMan.HasComponent<GhostComponent>(player.AttachedEntity), "player is not a ghost");
Assert.That(mind.VisitingEntity, Is.EqualTo(player.AttachedEntity));
Assert.That(mind.OwnedEntity, Is.EqualTo(originalEntity));
});
await PoolManager.RunTicksSync(pairTracker.Pair, 5);
await server.WaitAssertion(() => entMan.DeleteEntity(originalEntity));
@@ -178,10 +188,13 @@ public sealed partial class MindTests
// Check that the player is still in control of the ghost
mind = GetMind(pairTracker.Pair);
Assert.That(!entMan.Deleted(ghost), "ghost has been deleted");
Assert.Multiple(() =>
{
Assert.That(player.AttachedEntity, Is.EqualTo(ghost));
Assert.That(entMan.HasComponent<GhostComponent>(player.AttachedEntity));
Assert.IsNull(mind.VisitingEntity);
Assert.That(mind.VisitingEntity, Is.Null);
Assert.That(mind.OwnedEntity, Is.EqualTo(ghost));
});
await pairTracker.CleanReturnAsync();
}
@@ -213,13 +226,16 @@ public sealed partial class MindTests
await PoolManager.RunTicksSync(pairTracker.Pair, 5);
Assert.That(entMan.Deleted(ghost), "old ghost was not deleted");
Assert.Multiple(() =>
{
Assert.That(player.AttachedEntity, Is.Not.EqualTo(ghost), "Player is still attached to the old ghost");
Assert.That(entMan.HasComponent<GhostComponent>(player.AttachedEntity!.Value), "Player did not become a new ghost");
Assert.That(entMan.GetComponent<MetaDataComponent>(player.AttachedEntity.Value).EntityPrototype?.ID, Is.EqualTo("AdminObserver"));
Assert.That(entMan.HasComponent<GhostComponent>(player.AttachedEntity), "Player did not become a new ghost");
Assert.That(entMan.GetComponent<MetaDataComponent>(player.AttachedEntity!.Value).EntityPrototype?.ID, Is.EqualTo("AdminObserver"));
});
var mind = player.ContentData()?.Mind;
Assert.NotNull(mind);
Assert.Null(mind.VisitingEntity);
Assert.That(mind, Is.Not.Null);
Assert.That(mind.VisitingEntity, Is.Null);
await pairTracker.CleanReturnAsync();
}
@@ -241,7 +257,7 @@ public sealed partial class MindTests
var playerMan = server.ResolveDependency<IPlayerManager>();
var serverConsole = server.ResolveDependency<IServerConsoleHost>();
IPlayerSession player = playerMan.ServerSessions.Single();
var player = playerMan.ServerSessions.Single();
EntityUid ghost = default!;
@@ -272,9 +288,11 @@ public sealed partial class MindTests
await server.WaitAssertion(() =>
{
#pragma warning disable NUnit2045 // Interdependent assertions.
Assert.That(entMan.Deleted(ghost));
Assert.That(player.AttachedEntity, Is.Not.EqualTo(ghost));
Assert.That(entMan.HasComponent<GhostComponent>(player.AttachedEntity!.Value));
#pragma warning restore NUnit2045
});
await pairTracker.CleanReturnAsync();

View File

@@ -1,9 +1,7 @@
using System.Linq;
using System.Threading.Tasks;
using Content.Server.Ghost.Components;
using Content.Server.Mind;
using Content.Server.Players;
using NUnit.Framework;
using Robust.Server.GameObjects;
using Robust.Server.Player;
using Robust.Shared.Enums;
@@ -25,7 +23,7 @@ public sealed partial class MindTests
/// the player's mind's current entity, likely because some previous test directly changed the players attached
/// entity.
/// </remarks>
public async Task<PairTracker> SetupPair()
private static async Task<PairTracker> SetupPair()
{
var pairTracker = await PoolManager.GetServerClient();
var pair = pairTracker.Pair;
@@ -47,15 +45,18 @@ public sealed partial class MindTests
await PoolManager.RunTicksSync(pair, 5);
Assert.Multiple(() =>
{
Assert.That(player.ContentData()?.Mind, Is.EqualTo(mind));
Assert.That(player.AttachedEntity, Is.EqualTo(entity));
Assert.That(player.AttachedEntity, Is.EqualTo(mind.CurrentEntity), "Player is not attached to the mind's current entity.");
Assert.That(entMan.EntityExists(mind.OwnedEntity), "The mind's current entity does not exist");
Assert.That(mind.VisitingEntity == null || entMan.EntityExists(mind.VisitingEntity), "The minds visited entity does not exist.");
});
return pairTracker;
}
public async Task<EntityUid> BecomeGhost(Pair pair, bool visit = false)
private static async Task<EntityUid> BecomeGhost(Pair pair, bool visit = false)
{
var entMan = pair.Server.ResolveDependency<IServerEntityManager>();
var playerMan = pair.Server.ResolveDependency<IPlayerManager>();
@@ -69,7 +70,7 @@ public sealed partial class MindTests
var oldUid = player.AttachedEntity;
ghostUid = entMan.SpawnEntity("MobObserver", MapCoordinates.Nullspace);
mind = mindSys.GetMind(player.UserId);
Assert.NotNull(mind);
Assert.That(mind, Is.Not.Null);
if (visit)
{
@@ -84,17 +85,20 @@ public sealed partial class MindTests
});
await PoolManager.RunTicksSync(pair, 5);
Assert.Multiple(() =>
{
Assert.That(entMan.HasComponent<GhostComponent>(ghostUid));
Assert.That(player.AttachedEntity == ghostUid);
Assert.That(mind.CurrentEntity == ghostUid);
Assert.That(player.AttachedEntity, Is.EqualTo(ghostUid));
Assert.That(mind.CurrentEntity, Is.EqualTo(ghostUid));
});
if (!visit)
Assert.Null(mind.VisitingEntity);
Assert.That(mind.VisitingEntity, Is.Null);
return ghostUid;
}
public async Task<EntityUid> VisitGhost(Pair pair, bool visit = false)
private static async Task<EntityUid> VisitGhost(Pair pair, bool _ = false)
{
return await BecomeGhost(pair, visit: true);
}
@@ -102,23 +106,26 @@ public sealed partial class MindTests
/// <summary>
/// Get the player's current mind and check that the entities exists.
/// </summary>
public Mind GetMind(Pair pair)
private static Mind GetMind(Pair pair)
{
var playerMan = pair.Server.ResolveDependency<IPlayerManager>();
var entMan = pair.Server.ResolveDependency<IEntityManager>();
var player = playerMan.ServerSessions.SingleOrDefault();
Assert.NotNull(player);
Assert.That(player, Is.Not.Null);
var mind = player.ContentData()!.Mind;
Assert.NotNull(mind);
Assert.That(mind, Is.Not.Null);
Assert.Multiple(() =>
{
Assert.That(player.AttachedEntity, Is.EqualTo(mind.CurrentEntity), "Player is not attached to the mind's current entity.");
Assert.That(entMan.EntityExists(mind.OwnedEntity), "The mind's current entity does not exist");
Assert.That(mind.VisitingEntity == null || entMan.EntityExists(mind.VisitingEntity), "The minds visited entity does not exist.");
});
return mind;
}
public async Task Disconnect(Pair pair)
private static async Task Disconnect(Pair pair)
{
var netManager = pair.Client.ResolveDependency<IClientNetManager>();
var playerMan = pair.Server.ResolveDependency<IPlayerManager>();
@@ -131,12 +138,15 @@ public sealed partial class MindTests
});
await PoolManager.RunTicksSync(pair, 5);
Assert.That(player.Status == SessionStatus.Disconnected);
Assert.NotNull(mind.UserId);
Assert.Null(mind.Session);
Assert.Multiple(() =>
{
Assert.That(player.Status, Is.EqualTo(SessionStatus.Disconnected));
Assert.That(mind.UserId, Is.Not.Null);
Assert.That(mind.Session, Is.Null);
});
}
public async Task Connect(Pair pair, string username)
private static async Task Connect(Pair pair, string username)
{
var netManager = pair.Client.ResolveDependency<IClientNetManager>();
var playerMan = pair.Server.ResolveDependency<IPlayerManager>();
@@ -148,10 +158,10 @@ public sealed partial class MindTests
await PoolManager.RunTicksSync(pair, 5);
var player = playerMan.ServerSessions.Single();
Assert.That(player.Status == SessionStatus.InGame);
Assert.That(player.Status, Is.EqualTo(SessionStatus.InGame));
}
public async Task<IPlayerSession> DisconnectReconnect(Pair pair)
private static async Task<IPlayerSession> DisconnectReconnect(Pair pair)
{
var playerMan = pair.Server.ResolveDependency<IPlayerManager>();
var player = playerMan.ServerSessions.Single();
@@ -163,8 +173,11 @@ public sealed partial class MindTests
// Session has changed
var newSession = playerMan.ServerSessions.Single();
Assert.That(newSession != player);
Assert.That(newSession.UserId == id);
Assert.Multiple(() =>
{
Assert.That(newSession, Is.Not.EqualTo(player));
Assert.That(newSession.UserId, Is.EqualTo(id));
});
return newSession;
}

View File

@@ -1,8 +1,6 @@
using System.Linq;
using System.Threading.Tasks;
using Content.Server.Ghost.Components;
using Content.Server.Mind;
using NUnit.Framework;
using Robust.Server.Player;
using Robust.Shared.GameObjects;
using Robust.Shared.Map;
@@ -28,10 +26,13 @@ public sealed partial class MindTests
await DisconnectReconnect(pair);
// Player in control of a new ghost, but with the same mind
Assert.That(GetMind(pair) == mind);
Assert.Multiple(() =>
{
Assert.That(GetMind(pair), Is.EqualTo(mind));
Assert.That(entMan.Deleted(ghost));
Assert.That(entMan.HasComponent<GhostComponent>(mind.OwnedEntity));
Assert.Null(mind.VisitingEntity);
Assert.That(mind.VisitingEntity, Is.Null);
});
await pairTracker.CleanReturnAsync();
}
@@ -53,7 +54,7 @@ public sealed partial class MindTests
var player = playerMan.ServerSessions.Single();
var name = player.Name;
var user = player.UserId;
Assert.NotNull(mind.OwnedEntity);
Assert.That(mind.OwnedEntity, Is.Not.Null);
var entity = mind.OwnedEntity.Value;
// Player is not a ghost
@@ -65,18 +66,24 @@ public sealed partial class MindTests
// Delete entity
Assert.That(entMan.EntityExists(entity));
await pair.Server.WaitPost(() => entMan.DeleteEntity(entity));
Assert.Multiple(() =>
{
Assert.That(entMan.Deleted(entity));
Assert.IsNull(mind.OwnedEntity);
Assert.That(mind.OwnedEntity, Is.Null);
});
// Reconnect
await Connect(pair, name);
player = playerMan.ServerSessions.Single();
Assert.Multiple(() =>
{
Assert.That(user, Is.EqualTo(player.UserId));
// Player is now a new ghost entity
Assert.That(GetMind(pair), Is.EqualTo(mind));
Assert.That(mind.OwnedEntity, Is.Not.EqualTo(entity));
Assert.That(entMan.HasComponent<GhostComponent>(mind.OwnedEntity));
});
await pairTracker.CleanReturnAsync();
}
@@ -99,10 +106,13 @@ public sealed partial class MindTests
await DisconnectReconnect(pair);
// Player now controls their original mob, mind was preserved
Assert.Multiple(() =>
{
Assert.That(mind, Is.EqualTo(GetMind(pair)));
Assert.That(mind.CurrentEntity, Is.EqualTo(original));
Assert.That(!entMan.Deleted(original));
Assert.That(entMan.Deleted(original), Is.False);
Assert.That(entMan.Deleted(ghost));
});
await pairTracker.CleanReturnAsync();
}
@@ -134,11 +144,13 @@ public sealed partial class MindTests
await DisconnectReconnect(pair);
// Player is back in control of the visited mob, mind was preserved
Assert.That(mind == GetMind(pair));
Assert.That(!entMan.Deleted(original));
Assert.That(!entMan.Deleted(visiting));
Assert.That(mind.CurrentEntity == visiting);
Assert.That(mind.CurrentEntity == visiting);
Assert.Multiple(() =>
{
Assert.That(GetMind(pair), Is.EqualTo(mind));
Assert.That(entMan.Deleted(original), Is.False);
Assert.That(entMan.Deleted(visiting), Is.False);
Assert.That(mind.CurrentEntity, Is.EqualTo(visiting));
});
await pairTracker.CleanReturnAsync();
}

View File

@@ -1,7 +1,5 @@
#nullable enable
using System;
using System.Linq;
using System.Threading.Tasks;
using Content.Server.Ghost;
using Content.Server.Ghost.Roles;
using Content.Server.Mind;
@@ -9,19 +7,15 @@ using Content.Server.Mind.Commands;
using Content.Server.Mind.Components;
using Content.Server.Players;
using Content.Server.Roles;
using Content.Server.Traitor;
using Content.Shared.Damage;
using Content.Shared.Damage.Prototypes;
using Content.Shared.FixedPoint;
using Content.Shared.Roles;
using NUnit.Framework;
using Robust.Server.Console;
using Robust.Server.GameObjects;
using Robust.Server.Player;
using Robust.Shared.GameObjects;
using Robust.Shared.IoC;
using Robust.Shared.Map;
using Robust.Shared.Network;
using Robust.Shared.Prototypes;
using IPlayerManager = Robust.Server.Player.IPlayerManager;
@@ -59,7 +53,7 @@ public sealed partial class MindTests
[Test]
public async Task TestCreateAndTransferMindToNewEntity()
{
await using var pairTracker = await PoolManager.GetServerClient(new PoolSettings{ NoClient = true });
await using var pairTracker = await PoolManager.GetServerClient(new PoolSettings { NoClient = true });
var server = pairTracker.Pair.Server;
var entMan = server.ResolveDependency<IServerEntityManager>();
@@ -85,7 +79,7 @@ public sealed partial class MindTests
[Test]
public async Task TestReplaceMind()
{
await using var pairTracker = await PoolManager.GetServerClient(new PoolSettings{ NoClient = true });
await using var pairTracker = await PoolManager.GetServerClient(new PoolSettings { NoClient = true });
var server = pairTracker.Pair.Server;
var entMan = server.ResolveDependency<IServerEntityManager>();
@@ -103,8 +97,11 @@ public sealed partial class MindTests
var mind2 = mindSystem.CreateMind(null);
mindSystem.TransferTo(mind2, entity);
Assert.Multiple(() =>
{
Assert.That(mindSystem.GetMind(entity, mindComp), Is.EqualTo(mind2));
Assert.That(mind.OwnedEntity != entity);
Assert.That(mind.OwnedEntity, Is.Not.EqualTo(entity));
});
});
await pairTracker.CleanReturnAsync();
@@ -113,7 +110,7 @@ public sealed partial class MindTests
[Test]
public async Task TestEntityDeadWhenGibbed()
{
await using var pairTracker = await PoolManager.GetServerClient(new PoolSettings{ NoClient = true, ExtraPrototypes = Prototypes });
await using var pairTracker = await PoolManager.GetServerClient(new PoolSettings { NoClient = true, ExtraPrototypes = Prototypes });
var server = pairTracker.Pair.Server;
var entMan = server.ResolveDependency<IServerEntityManager>();
@@ -133,9 +130,12 @@ public sealed partial class MindTests
mind = mindSystem.CreateMind(null);
mindSystem.TransferTo(mind, entity);
Assert.Multiple(() =>
{
Assert.That(mindSystem.GetMind(entity, mindContainerComp), Is.EqualTo(mind));
Assert.That(!mindSystem.IsCharacterDeadPhysically(mind));
});
});
await PoolManager.RunTicksSync(pairTracker.Pair, 5);
@@ -164,7 +164,7 @@ public sealed partial class MindTests
[Test]
public async Task TestMindTransfersToOtherEntity()
{
await using var pairTracker = await PoolManager.GetServerClient(new PoolSettings{ NoClient = true });
await using var pairTracker = await PoolManager.GetServerClient(new PoolSettings { NoClient = true });
var server = pairTracker.Pair.Server;
var entMan = server.ResolveDependency<IServerEntityManager>();
@@ -185,9 +185,12 @@ public sealed partial class MindTests
Assert.That(mindSystem.GetMind(entity, mindComp), Is.EqualTo(mind));
mindSystem.TransferTo(mind, targetEntity);
Assert.Multiple(() =>
{
Assert.That(mindSystem.GetMind(entity, mindComp), Is.EqualTo(null));
Assert.That(mindSystem.GetMind(targetEntity), Is.EqualTo(mind));
});
});
await pairTracker.CleanReturnAsync();
}
@@ -214,22 +217,31 @@ public sealed partial class MindTests
mind = mindSystem.CreateMind(null);
mindSystem.TransferTo(mind, entity);
Assert.Multiple(() =>
{
Assert.That(mindSystem.GetMind(entity, mindComp), Is.EqualTo(mind));
Assert.That(mindComp.HasMind);
});
});
await PoolManager.RunTicksSync(pairTracker.Pair, 5);
await server.WaitAssertion(() =>
{
mindSystem.SetUserId(mind, userId);
Assert.Multiple(() =>
{
Assert.That(mind.UserId, Is.EqualTo(userId));
Assert.That(originalMind.UserId, Is.EqualTo(null));
});
mindSystem.SetUserId(originalMind, userId);
Assert.Multiple(() =>
{
Assert.That(mind.UserId, Is.EqualTo(null));
Assert.That(originalMind.UserId, Is.EqualTo(userId));
});
});
await PoolManager.RunTicksSync(pairTracker.Pair, 5);
@@ -239,7 +251,7 @@ public sealed partial class MindTests
[Test]
public async Task TestAddRemoveHasRoles()
{
await using var pairTracker = await PoolManager.GetServerClient(new PoolSettings{ NoClient = true });
await using var pairTracker = await PoolManager.GetServerClient(new PoolSettings { NoClient = true });
var server = pairTracker.Pair.Server;
var entMan = server.ResolveDependency<IServerEntityManager>();
@@ -258,32 +270,47 @@ public sealed partial class MindTests
mindSystem.TransferTo(mind, entity);
Assert.That(mindSystem.GetMind(entity, mindComp), Is.EqualTo(mind));
Assert.That(!mindSystem.HasRole<TraitorRole>(mind));
Assert.That(!mindSystem.HasRole<Job>(mind));
Assert.Multiple(() =>
{
Assert.That(mindSystem.HasRole<TraitorRole>(mind), Is.False);
Assert.That(mindSystem.HasRole<Job>(mind), Is.False);
});
var traitorRole = new TraitorRole(mind, new AntagPrototype());
mindSystem.AddRole(mind, traitorRole);
Assert.Multiple(() =>
{
Assert.That(mindSystem.HasRole<TraitorRole>(mind));
Assert.That(!mindSystem.HasRole<Job>(mind));
Assert.That(mindSystem.HasRole<Job>(mind), Is.False);
});
var jobRole = new Job(mind, new JobPrototype());
mindSystem.AddRole(mind, jobRole);
Assert.Multiple(() =>
{
Assert.That(mindSystem.HasRole<TraitorRole>(mind));
Assert.That(mindSystem.HasRole<Job>(mind));
});
mindSystem.RemoveRole(mind, traitorRole);
Assert.That(!mindSystem.HasRole<TraitorRole>(mind));
Assert.Multiple(() =>
{
Assert.That(mindSystem.HasRole<TraitorRole>(mind), Is.False);
Assert.That(mindSystem.HasRole<Job>(mind));
});
mindSystem.RemoveRole(mind, jobRole);
Assert.That(!mindSystem.HasRole<TraitorRole>(mind));
Assert.That(!mindSystem.HasRole<Job>(mind));
Assert.Multiple(() =>
{
Assert.That(mindSystem.HasRole<TraitorRole>(mind), Is.False);
Assert.That(mindSystem.HasRole<Job>(mind), Is.False);
});
});
await pairTracker.CleanReturnAsync();
@@ -304,7 +331,7 @@ public sealed partial class MindTests
EntityUid entity = default!;
Mind mind = default!;
IPlayerSession player = playerMan.ServerSessions.Single();
var player = playerMan.ServerSessions.Single();
await server.WaitAssertion(() =>
{
@@ -333,7 +360,7 @@ public sealed partial class MindTests
await server.WaitAssertion(() =>
{
Assert.That(mind.OwnedEntity != null);
Assert.That(mind.OwnedEntity, Is.Not.Null);
mob = entMan.SpawnEntity(null, new MapCoordinates());
@@ -349,10 +376,13 @@ public sealed partial class MindTests
await server.WaitAssertion(() =>
{
var m = player.ContentData()?.Mind;
Assert.That(m, Is.Not.EqualTo(null));
Assert.That(m, Is.Not.Null);
Assert.Multiple(() =>
{
Assert.That(m!.OwnedEntity, Is.EqualTo(mob));
Assert.That(m, Is.Not.EqualTo(mind));
});
});
await pairTracker.CleanReturnAsync();
}
@@ -376,11 +406,11 @@ public sealed partial class MindTests
var mindSystem = entMan.EntitySysManager.GetEntitySystem<MindSystem>();
EntityUid entity = default!;
//EntityUid entity = default!;
EntityUid mouse = default!;
EntityUid ghost = default!;
Mind mind = default!;
IPlayerSession player = playerMan.ServerSessions.Single();
var player = playerMan.ServerSessions.Single();
await server.WaitAssertion(() =>
{
@@ -399,7 +429,7 @@ public sealed partial class MindTests
Assert.That(data?.Mind, Is.Not.EqualTo(null));
mind = data!.Mind!;
Assert.That(mind.OwnedEntity != null);
Assert.That(mind.OwnedEntity, Is.Not.Null);
mouse = entMan.SpawnEntity("MobMouse", new MapCoordinates());
});
@@ -423,10 +453,10 @@ public sealed partial class MindTests
await server.WaitAssertion(() =>
{
var data = player.ContentData()!;
Assert.That(data.Mind!.OwnedEntity == mouse);
Assert.That(data.Mind!.OwnedEntity, Is.EqualTo(mouse));
serverConsole.ExecuteCommand(player, "aghost");
Assert.That(player.AttachedEntity != null);
Assert.That(player.AttachedEntity, Is.Not.Null);
ghost = player.AttachedEntity!.Value;
});
@@ -434,8 +464,8 @@ public sealed partial class MindTests
await server.WaitAssertion(() =>
{
Assert.That(player.AttachedEntity != null);
Assert.That(ghost == player.AttachedEntity!.Value);
Assert.That(player.AttachedEntity, Is.Not.Null);
Assert.That(player.AttachedEntity!.Value, Is.EqualTo(ghost));
});
await pairTracker.CleanReturnAsync();

View File

@@ -1,8 +1,5 @@
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Content.Server.NPC.HTN;
using NUnit.Framework;
using Robust.Shared.GameObjects;
using Robust.Shared.Prototypes;
using Robust.Shared.Utility;

View File

@@ -0,0 +1,453 @@
#nullable enable
using System.Collections.Generic;
using System.Linq;
using Robust.Client.GameStates;
using Robust.Client.Timing;
using Robust.Server.Player;
using Robust.Shared;
using Robust.Shared.Analyzers;
using Robust.Shared.Configuration;
using Robust.Shared.GameObjects;
using Robust.Shared.GameStates;
using Robust.Shared.IoC;
using Robust.Shared.Log;
using Robust.Shared.Map;
using Robust.Shared.Reflection;
using Robust.Shared.Timing;
namespace Content.IntegrationTests.Tests.Networking
{
// This test checks that the prediction & reconciling system is working correctly with a simple boolean flag.
// An entity system sets a flag on a networked component via a RaisePredictiveEvent,
// so it runs predicted on client and eventually on server.
// All the tick values are checked to ensure it arrives on client & server at the exact correct ticks.
// On the client, the reconciling system is checked to ensure that the state correctly reset every tick,
// until the server acknowledges it.
// Then, the same test is performed again, but the server does not handle the message (it ignores it).
// To simulate a mispredict.
// This means the client is forced to reset it once it gets to the server tick where the server didn't do anything.
// the tick where the server *should* have, but did not, acknowledge the state change.
// Finally, we run two events inside the prediction area to ensure reconciling does for incremental stuff.
[TestFixture]
public sealed class AutoPredictReconcileTest
{
[Test]
public async Task Test()
{
await using var pairTracker = await PoolManager.GetServerClient(new() { Fresh = true, DummyTicker = true });
var server = pairTracker.Pair.Server;
var client = pairTracker.Pair.Client;
// Pull in all dependencies we need.
var sPlayerManager = server.ResolveDependency<IPlayerManager>();
var sMapManager = server.ResolveDependency<IMapManager>();
var sEntityManager = server.ResolveDependency<IEntityManager>();
var cEntityManager = client.ResolveDependency<IEntityManager>();
var sGameTiming = server.ResolveDependency<IGameTiming>();
var cGameTiming = client.ResolveDependency<IClientGameTiming>();
var cGameStateManager = client.ResolveDependency<IClientGameStateManager>();
var cfg = client.ResolveDependency<IConfigurationManager>();
var log = cfg.GetCVar(CVars.NetLogging);
//cfg.SetCVar(CVars.NetLogging, true);
EntityUid serverEnt = default;
AutoPredictionTestComponent serverComponent = default!;
AutoPredictionTestComponent clientComponent = default!;
var serverSystem = server.ResolveDependency<IEntitySystemManager>()
.GetEntitySystem<AutoPredictionTestEntitySystem>();
var clientSystem = client.ResolveDependency<IEntitySystemManager>()
.GetEntitySystem<AutoPredictionTestEntitySystem>();
await server.WaitPost(() =>
{
// Spawn dummy component entity.
var map = sMapManager.CreateMap();
var player = sPlayerManager.ServerSessions.Single();
serverEnt = sEntityManager.SpawnEntity(null, new MapCoordinates((0, 0), map));
serverComponent = sEntityManager.AddComponent<AutoPredictionTestComponent>(serverEnt);
// Make client "join game" so they receive game state updates.
player.JoinGame();
});
// Run some ticks so that
await PoolManager.RunTicksSync(pairTracker.Pair, 3);
// Check client buffer is full
Assert.That(cGameStateManager.CurrentBufferSize, Is.EqualTo(cGameStateManager.TargetBufferSize));
// This isn't required anymore, but the test had this for the sake of "technical things", and I cbf shifting
// all the tick times over. So it stays.
await client.WaitRunTicks(1);
await client.WaitPost(() =>
{
clientComponent = cEntityManager.GetComponent<AutoPredictionTestComponent>(serverEnt);
});
Assert.Multiple(() =>
{
Assert.That(clientComponent.Foo, Is.False);
// KEEP IN MIND WHEN READING THIS.
// The game loop increments CurTick AFTER running the tick.
// So when reading CurTick inside an Assert or Post or whatever, the tick reported is the NEXT one to run.
Assert.That(sGameTiming.CurTick, Is.EqualTo(new GameTick(14)));
Assert.That(serverComponent.Foo, Is.False);
// Client last ran tick 15 meaning it's ahead of the last server tick it processed (12)
Assert.That(cGameTiming.CurTick, Is.EqualTo(new GameTick(16)));
Assert.That(cGameTiming.LastProcessedTick, Is.EqualTo(new GameTick(12)));
});
// *** I am using block scopes to visually distinguish these sections of the test to make it more readable.
// Send an event to change the flag and instantly see the effect replicate client side,
// while it's queued on server and reconciling works (constantly needs re-firing on client).
{
await client.WaitPost(() =>
{
cEntityManager.RaisePredictiveEvent(new SetFooMessage(serverEnt, true));
Assert.That(clientComponent.Foo, Is.True);
});
// Event correctly arrived on client system.
Assert.That(clientSystem.EventTriggerList,
Is.EquivalentTo(new[] { (new GameTick(16), true, false, true, true) }));
clientSystem.EventTriggerList.Clear();
// Two ticks happen on both sides with nothing really "changing".
// Server doesn't receive it yet,
// client is still replaying the past prediction.
for (var i = 0; i < 2; i++)
{
await server.WaitRunTicks(1);
// Event did not arrive on server.
Assert.That(serverSystem.EventTriggerList, Is.Empty);
await client.WaitRunTicks(1);
// Event got repeated on client as a past prediction.
Assert.That(clientSystem.EventTriggerList,
Is.EquivalentTo(new[] { (new GameTick(16), false, false, true, true) }));
clientSystem.EventTriggerList.Clear();
}
{
await server.WaitRunTicks(1);
Assert.Multiple(() =>
{
// Event arrived on server at tick 16.
Assert.That(sGameTiming.CurTick, Is.EqualTo(new GameTick(17)));
Assert.That(serverSystem.EventTriggerList,
Is.EquivalentTo(new[] { (new GameTick(16), true, false, true, true) }));
});
serverSystem.EventTriggerList.Clear();
await client.WaitRunTicks(1);
// Event got repeated on client as a past prediction.
Assert.That(clientSystem.EventTriggerList,
Is.EquivalentTo(new[] { (new GameTick(16), false, false, true, true) }));
clientSystem.EventTriggerList.Clear();
}
{
await server.WaitRunTicks(1);
// Nothing happened on server.
Assert.That(serverSystem.EventTriggerList, Is.Empty);
await client.WaitRunTicks(1);
Assert.Multiple(() =>
{
// Event got repeated on client as a past prediction.
Assert.That(clientSystem.EventTriggerList, Is.Empty);
Assert.That(clientComponent.Foo, Is.True);
});
clientSystem.EventTriggerList.Clear();
}
}
// Disallow changes to simulate a misprediction.
serverSystem.Allow = false;
Assert.Multiple(() =>
{
// Assert timing is still correct, should be but it's a good reference for the rest of the test.
Assert.That(sGameTiming.CurTick, Is.EqualTo(new GameTick(18)));
Assert.That(cGameTiming.CurTick, Is.EqualTo(new GameTick(20)));
Assert.That(cGameTiming.LastProcessedTick, Is.EqualTo(new GameTick(16)));
});
{
// Send event to server to change flag again, this time to disable it..
await client.WaitPost(() =>
{
cEntityManager.RaisePredictiveEvent(new SetFooMessage(serverEnt, false));
Assert.That(clientComponent.Foo, Is.False);
});
// Event correctly arrived on client system.
Assert.That(clientSystem.EventTriggerList,
Is.EquivalentTo(new[] { (new GameTick(20), true, true, false, false) }));
clientSystem.EventTriggerList.Clear();
for (var i = 0; i < 2; i++)
{
await server.WaitRunTicks(1);
// Event did not arrive on server.
Assert.That(serverSystem.EventTriggerList, Is.Empty);
await client.WaitRunTicks(1);
// Event got repeated on client as a past prediction.
Assert.That(clientSystem.EventTriggerList,
Is.EquivalentTo(new[] { (new GameTick(20), false, true, false, false) }));
clientSystem.EventTriggerList.Clear();
}
{
await server.WaitRunTicks(1);
Assert.Multiple(() =>
{
// Event arrived on server at tick 20.
Assert.That(sGameTiming.CurTick, Is.EqualTo(new GameTick(21)));
// But the server didn't listen!
Assert.That(serverSystem.EventTriggerList,
Is.EquivalentTo(new[] { (new GameTick(20), true, true, true, false) }));
});
serverSystem.EventTriggerList.Clear();
await client.WaitRunTicks(1);
// Event got repeated on client as a past prediction.
Assert.That(clientSystem.EventTriggerList,
Is.EquivalentTo(new[] { (new GameTick(20), false, true, false, false) }));
clientSystem.EventTriggerList.Clear();
}
{
await server.WaitRunTicks(1);
// Nothing happened on server.
Assert.That(serverSystem.EventTriggerList, Is.Empty);
await client.WaitRunTicks(1);
Assert.Multiple(() =>
{
// Event no longer got repeated and flag was *not* set by server state.
// Mispredict gracefully handled!
Assert.That(clientSystem.EventTriggerList, Is.Empty);
Assert.That(clientComponent.Foo, Is.True);
});
clientSystem.EventTriggerList.Clear();
}
}
// Re-allow changes to make everything work correctly again.
serverSystem.Allow = true;
Assert.Multiple(() =>
{
// Assert timing is still correct.
Assert.That(sGameTiming.CurTick, Is.EqualTo(new GameTick(22)));
Assert.That(cGameTiming.CurTick, Is.EqualTo(new GameTick(24)));
Assert.That(cGameTiming.LastProcessedTick, Is.EqualTo(new GameTick(20)));
});
{
// Send first event to disable the flag (reminder: it never got accepted by the server).
await client.WaitPost(() =>
{
cEntityManager.RaisePredictiveEvent(new SetFooMessage(serverEnt, false));
Assert.That(clientComponent.Foo, Is.False);
});
// Event correctly arrived on client system.
Assert.That(clientSystem.EventTriggerList,
Is.EquivalentTo(new[] { (new GameTick(24), true, true, false, false) }));
clientSystem.EventTriggerList.Clear();
// Run one tick, everything checks out.
{
await server.WaitRunTicks(1);
// Event did not arrive on server.
Assert.That(serverSystem.EventTriggerList, Is.Empty);
await client.WaitRunTicks(1);
// Event got repeated on client as a past prediction.
Assert.That(clientSystem.EventTriggerList,
Is.EquivalentTo(new[] { (new GameTick(24), false, true, false, false) }));
clientSystem.EventTriggerList.Clear();
}
// Send another event, to re-enable it.
await client.WaitPost(() =>
{
cEntityManager.RaisePredictiveEvent(new SetFooMessage(serverEnt, true));
Assert.That(clientComponent.Foo, Is.True);
});
// Event correctly arrived on client system.
Assert.That(clientSystem.EventTriggerList,
Is.EquivalentTo(new[] { (new GameTick(25), true, false, true, true) }));
clientSystem.EventTriggerList.Clear();
// Next tick we run, both events come in, but at different times.
{
await server.WaitRunTicks(1);
// Event did not arrive on server.
Assert.That(serverSystem.EventTriggerList, Is.Empty);
await client.WaitRunTicks(1);
// Event got repeated on client as a past prediction.
Assert.That(clientSystem.EventTriggerList,
Is.EquivalentTo(new[]
{
(new GameTick(24), false, true, false, false), (new GameTick(25), false, false, true, true)
}));
clientSystem.EventTriggerList.Clear();
}
// FIRST event arrives on server!
{
await server.WaitRunTicks(1);
Assert.That(serverSystem.EventTriggerList,
Is.EquivalentTo(new[] { (new GameTick(24), true, true, false, false) }));
serverSystem.EventTriggerList.Clear();
await client.WaitRunTicks(1);
// Event got repeated on client as a past prediction.
Assert.That(clientSystem.EventTriggerList,
Is.EquivalentTo(new[]
{
(new GameTick(24), false, true, false, false), (new GameTick(25), false, false, true, true)
}));
clientSystem.EventTriggerList.Clear();
}
// SECOND event arrived on server, client receives ack for first event,
// still runs second event as past prediction.
{
await server.WaitRunTicks(1);
Assert.That(serverSystem.EventTriggerList,
Is.EquivalentTo(new[] { (new GameTick(25), true, false, true, true) }));
serverSystem.EventTriggerList.Clear();
await client.WaitRunTicks(1);
// Event got repeated on client as a past prediction.
Assert.That(clientSystem.EventTriggerList,
Is.EquivalentTo(new[]
{
(new GameTick(25), false, false, true, true)
}));
clientSystem.EventTriggerList.Clear();
}
// Finally, second event acknowledged on client and we're good.
{
await server.WaitRunTicks(1);
Assert.That(serverSystem.EventTriggerList, Is.Empty);
await client.WaitRunTicks(1);
Assert.Multiple(() =>
{
// Event got repeated on client as a past prediction.
Assert.That(clientSystem.EventTriggerList, Is.Empty);
Assert.That(clientComponent.Foo, Is.True);
});
}
}
cfg.SetCVar(CVars.NetLogging, log);
await pairTracker.CleanReturnAsync();
}
[Reflect(false)]
public sealed class AutoPredictionTestEntitySystem : EntitySystem
{
public bool Allow { get; set; } = true;
// Queue of all the events that come in so we can test that they come in perfectly as expected.
public List<(GameTick tick, bool firstPredict, bool old, bool @new, bool value)> EventTriggerList { get; } =
new();
[Dependency] private readonly IGameTiming _gameTiming = default!;
public override void Initialize()
{
base.Initialize();
SubscribeNetworkEvent<SetFooMessage>(HandleMessage);
SubscribeLocalEvent<SetFooMessage>(HandleMessage);
SubscribeLocalEvent<AutoPredictionTestComponent, AfterAutoHandleStateEvent>(AfterAutoHandleState);
}
private void HandleMessage(SetFooMessage message, EntitySessionEventArgs args)
{
var component = EntityManager.GetComponent<AutoPredictionTestComponent>(message.Uid);
var old = component.Foo;
if (Allow)
{
component.Foo = message.NewFoo;
Dirty(message.Uid, component);
}
EventTriggerList.Add((_gameTiming.CurTick, _gameTiming.IsFirstTimePredicted, old, component.Foo, message.NewFoo));
}
private void AfterAutoHandleState(EntityUid uid, AutoPredictionTestComponent comp, ref AfterAutoHandleStateEvent args)
{
Dirty(uid, comp);
}
}
public sealed class SetFooMessage : EntityEventArgs
{
public SetFooMessage(EntityUid uid, bool newFoo)
{
Uid = uid;
NewFoo = newFoo;
}
public EntityUid Uid { get; }
public bool NewFoo { get; }
}
}
// Must be directly located in the namespace or the sourcegen can't find it.
[NetworkedComponent()]
[AutoGenerateComponentState]
[Access(typeof(AutoPredictReconcileTest.AutoPredictionTestEntitySystem))]
public sealed partial class AutoPredictionTestComponent : Component
{
[AutoNetworkedField]
public bool Foo;
}
}

View File

@@ -1,12 +1,7 @@
using System.Linq;
using System.Threading.Tasks;
using NUnit.Framework;
using Robust.Server.Player;
using Robust.Shared;
using Robust.Shared.Enums;
using Robust.Shared.GameObjects;
using Robust.Shared.IoC;
using Robust.Shared.Network;
namespace Content.IntegrationTests.Tests.Networking
{
@@ -23,8 +18,10 @@ namespace Content.IntegrationTests.Tests.Networking
// Basic checks to ensure that they're connected and data got replicated.
var playerManager = server.ResolveDependency<IPlayerManager>();
#pragma warning disable NUnit2045 // Interdependent assertions.
Assert.That(playerManager.PlayerCount, Is.EqualTo(1));
Assert.That(playerManager.Sessions.First().Status, Is.EqualTo(SessionStatus.InGame));
#pragma warning restore NUnit2045
var clEntityManager = client.ResolveDependency<IEntityManager>();
var svEntityManager = server.ResolveDependency<IEntityManager>();

View File

@@ -1,13 +1,9 @@
using System.Threading.Tasks;
using NUnit.Framework;
using Robust.Shared.GameObjects;
using Robust.Shared.IoC;
using Robust.Shared.Network;
namespace Content.IntegrationTests.Tests.Networking
{
[TestFixture]
sealed class NetworkIdsMatchTest
public sealed class NetworkIdsMatchTest
{
[Test]
public async Task TestConnect()
@@ -22,17 +18,26 @@ namespace Content.IntegrationTests.Tests.Networking
var clientNetComps = clientCompFactory.NetworkedComponents;
var serverNetComps = serverCompFactory.NetworkedComponents;
Assert.Multiple(() =>
{
Assert.That(clientNetComps, Is.Not.Null);
Assert.That(serverNetComps, Is.Not.Null);
Assert.That(clientNetComps.Count, Is.EqualTo(serverNetComps.Count));
});
Assert.Multiple(() =>
{
Assert.That(clientNetComps, Has.Count.EqualTo(serverNetComps.Count));
// Checks that at least Metadata and Transform are registered.
Assert.That(clientNetComps.Count, Is.GreaterThanOrEqualTo(2));
Assert.That(clientNetComps, Has.Count.GreaterThanOrEqualTo(2));
});
Assert.Multiple(() =>
{
for (var netId = 0; netId < clientNetComps.Count; netId++)
{
Assert.That(clientNetComps[netId].Name, Is.EqualTo(serverNetComps[netId].Name));
}
});
await pairTracker.CleanReturnAsync();
}
}

View File

@@ -1,7 +1,4 @@
using System.Threading.Tasks;
using NUnit.Framework;
using Robust.Client.Console;
using Robust.Shared.IoC;
using Robust.Shared.Network;
namespace Content.IntegrationTests.Tests.Networking

View File

@@ -1,15 +1,11 @@
#nullable enable
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using NUnit.Framework;
using Robust.Client.GameObjects;
using Robust.Client.GameStates;
using Robust.Client.Timing;
using Robust.Server.GameStates;
using Robust.Server.Player;
using Robust.Shared;
using Robust.Shared.Analyzers;
using Robust.Shared.Configuration;
using Robust.Shared.GameObjects;
using Robust.Shared.GameStates;
@@ -32,13 +28,14 @@ namespace Content.IntegrationTests.Tests.Networking
// This means the client is forced to reset it once it gets to the server tick where the server didn't do anything.
// the tick where the server *should* have, but did not, acknowledge the state change.
// Finally, we run two events inside the prediction area to ensure reconciling does for incremental stuff.
// TODO: This test relies on the EC version of component state handling. Remove in favor of the other two tests for the ECS and auto versions.
[TestFixture]
public sealed class SimplePredictReconcileTest
{
[Test]
public async Task Test()
{
await using var pairTracker = await PoolManager.GetServerClient(new (){Fresh = true, DummyTicker = true});
await using var pairTracker = await PoolManager.GetServerClient(new() { Fresh = true, DummyTicker = true });
var server = pairTracker.Pair.Server;
var client = pairTracker.Pair.Client;
@@ -91,6 +88,8 @@ namespace Content.IntegrationTests.Tests.Networking
clientComponent = cEntityManager.GetComponent<PredictionTestComponent>(serverEnt);
});
Assert.Multiple(() =>
{
Assert.That(clientComponent.Foo, Is.False);
// KEEP IN MIND WHEN READING THIS.
@@ -103,6 +102,7 @@ namespace Content.IntegrationTests.Tests.Networking
// Client last ran tick 15 meaning it's ahead of the last server tick it processed (12)
Assert.That(cGameTiming.CurTick, Is.EqualTo(new GameTick(16)));
Assert.That(cGameTiming.LastProcessedTick, Is.EqualTo(new GameTick(12)));
});
// *** I am using block scopes to visually distinguish these sections of the test to make it more readable.
@@ -119,7 +119,7 @@ namespace Content.IntegrationTests.Tests.Networking
// Event correctly arrived on client system.
Assert.That(clientSystem.EventTriggerList,
Is.EquivalentTo(new[] {(new GameTick(16), true, false, true, true)}));
Is.EquivalentTo(new[] { (new GameTick(16), true, false, true, true) }));
clientSystem.EventTriggerList.Clear();
// Two ticks happen on both sides with nothing really "changing".
@@ -136,24 +136,27 @@ namespace Content.IntegrationTests.Tests.Networking
// Event got repeated on client as a past prediction.
Assert.That(clientSystem.EventTriggerList,
Is.EquivalentTo(new[] {(new GameTick(16), false, false, true, true)}));
Is.EquivalentTo(new[] { (new GameTick(16), false, false, true, true) }));
clientSystem.EventTriggerList.Clear();
}
{
await server.WaitRunTicks(1);
Assert.Multiple(() =>
{
// Event arrived on server at tick 16.
Assert.That(sGameTiming.CurTick, Is.EqualTo(new GameTick(17)));
Assert.That(serverSystem.EventTriggerList,
Is.EquivalentTo(new[] {(new GameTick(16), true, false, true, true)}));
Is.EquivalentTo(new[] { (new GameTick(16), true, false, true, true) }));
});
serverSystem.EventTriggerList.Clear();
await client.WaitRunTicks(1);
// Event got repeated on client as a past prediction.
Assert.That(clientSystem.EventTriggerList,
Is.EquivalentTo(new[] {(new GameTick(16), false, false, true, true)}));
Is.EquivalentTo(new[] { (new GameTick(16), false, false, true, true) }));
clientSystem.EventTriggerList.Clear();
}
@@ -165,9 +168,12 @@ namespace Content.IntegrationTests.Tests.Networking
await client.WaitRunTicks(1);
Assert.Multiple(() =>
{
// Event got repeated on client as a past prediction.
Assert.That(clientSystem.EventTriggerList, Is.Empty);
Assert.That(clientComponent.Foo, Is.True);
});
clientSystem.EventTriggerList.Clear();
}
}
@@ -175,10 +181,13 @@ namespace Content.IntegrationTests.Tests.Networking
// Disallow changes to simulate a misprediction.
serverSystem.Allow = false;
Assert.Multiple(() =>
{
// Assert timing is still correct, should be but it's a good reference for the rest of the test.
Assert.That(sGameTiming.CurTick, Is.EqualTo(new GameTick(18)));
Assert.That(cGameTiming.CurTick, Is.EqualTo(new GameTick(20)));
Assert.That(cGameTiming.LastProcessedTick, Is.EqualTo(new GameTick(16)));
});
{
// Send event to server to change flag again, this time to disable it..
@@ -191,7 +200,7 @@ namespace Content.IntegrationTests.Tests.Networking
// Event correctly arrived on client system.
Assert.That(clientSystem.EventTriggerList,
Is.EquivalentTo(new[] {(new GameTick(20), true, true, false, false)}));
Is.EquivalentTo(new[] { (new GameTick(20), true, true, false, false) }));
clientSystem.EventTriggerList.Clear();
for (var i = 0; i < 2; i++)
@@ -205,25 +214,28 @@ namespace Content.IntegrationTests.Tests.Networking
// Event got repeated on client as a past prediction.
Assert.That(clientSystem.EventTriggerList,
Is.EquivalentTo(new[] {(new GameTick(20), false, true, false, false)}));
Is.EquivalentTo(new[] { (new GameTick(20), false, true, false, false) }));
clientSystem.EventTriggerList.Clear();
}
{
await server.WaitRunTicks(1);
Assert.Multiple(() =>
{
// Event arrived on server at tick 20.
Assert.That(sGameTiming.CurTick, Is.EqualTo(new GameTick(21)));
// But the server didn't listen!
Assert.That(serverSystem.EventTriggerList,
Is.EquivalentTo(new[] {(new GameTick(20), true, true, true, false)}));
Is.EquivalentTo(new[] { (new GameTick(20), true, true, true, false) }));
});
serverSystem.EventTriggerList.Clear();
await client.WaitRunTicks(1);
// Event got repeated on client as a past prediction.
Assert.That(clientSystem.EventTriggerList,
Is.EquivalentTo(new[] {(new GameTick(20), false, true, false, false)}));
Is.EquivalentTo(new[] { (new GameTick(20), false, true, false, false) }));
clientSystem.EventTriggerList.Clear();
}
@@ -235,10 +247,13 @@ namespace Content.IntegrationTests.Tests.Networking
await client.WaitRunTicks(1);
Assert.Multiple(() =>
{
// Event no longer got repeated and flag was *not* set by server state.
// Mispredict gracefully handled!
Assert.That(clientSystem.EventTriggerList, Is.Empty);
Assert.That(clientComponent.Foo, Is.True);
});
clientSystem.EventTriggerList.Clear();
}
}
@@ -246,10 +261,13 @@ namespace Content.IntegrationTests.Tests.Networking
// Re-allow changes to make everything work correctly again.
serverSystem.Allow = true;
Assert.Multiple(() =>
{
// Assert timing is still correct.
Assert.That(sGameTiming.CurTick, Is.EqualTo(new GameTick(22)));
Assert.That(cGameTiming.CurTick, Is.EqualTo(new GameTick(24)));
Assert.That(cGameTiming.LastProcessedTick, Is.EqualTo(new GameTick(20)));
});
{
// Send first event to disable the flag (reminder: it never got accepted by the server).
@@ -262,7 +280,7 @@ namespace Content.IntegrationTests.Tests.Networking
// Event correctly arrived on client system.
Assert.That(clientSystem.EventTriggerList,
Is.EquivalentTo(new[] {(new GameTick(24), true, true, false, false)}));
Is.EquivalentTo(new[] { (new GameTick(24), true, true, false, false) }));
clientSystem.EventTriggerList.Clear();
// Run one tick, everything checks out.
@@ -276,7 +294,7 @@ namespace Content.IntegrationTests.Tests.Networking
// Event got repeated on client as a past prediction.
Assert.That(clientSystem.EventTriggerList,
Is.EquivalentTo(new[] {(new GameTick(24), false, true, false, false)}));
Is.EquivalentTo(new[] { (new GameTick(24), false, true, false, false) }));
clientSystem.EventTriggerList.Clear();
}
@@ -290,7 +308,7 @@ namespace Content.IntegrationTests.Tests.Networking
// Event correctly arrived on client system.
Assert.That(clientSystem.EventTriggerList,
Is.EquivalentTo(new[] {(new GameTick(25), true, false, true, true)}));
Is.EquivalentTo(new[] { (new GameTick(25), true, false, true, true) }));
clientSystem.EventTriggerList.Clear();
// Next tick we run, both events come in, but at different times.
@@ -316,7 +334,7 @@ namespace Content.IntegrationTests.Tests.Networking
await server.WaitRunTicks(1);
Assert.That(serverSystem.EventTriggerList,
Is.EquivalentTo(new[] {(new GameTick(24), true, true, false, false)}));
Is.EquivalentTo(new[] { (new GameTick(24), true, true, false, false) }));
serverSystem.EventTriggerList.Clear();
await client.WaitRunTicks(1);
@@ -336,7 +354,7 @@ namespace Content.IntegrationTests.Tests.Networking
await server.WaitRunTicks(1);
Assert.That(serverSystem.EventTriggerList,
Is.EquivalentTo(new[] {(new GameTick(25), true, false, true, true)}));
Is.EquivalentTo(new[] { (new GameTick(25), true, false, true, true) }));
serverSystem.EventTriggerList.Clear();
await client.WaitRunTicks(1);
@@ -358,10 +376,13 @@ namespace Content.IntegrationTests.Tests.Networking
await client.WaitRunTicks(1);
Assert.Multiple(() =>
{
// Event got repeated on client as a past prediction.
Assert.That(clientSystem.EventTriggerList, Is.Empty);
Assert.That(clientComponent.Foo, Is.True);
});
}
}
@@ -370,35 +391,25 @@ namespace Content.IntegrationTests.Tests.Networking
}
[NetworkedComponent()]
[Access(typeof(PredictionTestEntitySystem))]
public sealed class PredictionTestComponent : Component
{
private bool _foo;
public bool Foo
{
get => _foo;
set
{
_foo = value;
Dirty();
}
}
public override void HandleComponentState(ComponentState? curState, ComponentState? nextState)
{
if (curState is not PredictionComponentState pred)
{
return;
}
Foo = pred.Foo;
}
public bool Foo;
public override ComponentState GetComponentState()
{
return new PredictionComponentState(Foo);
}
public override void HandleComponentState(ComponentState? curState, ComponentState? nextState)
{
if (curState is not PredictionComponentState state)
return;
Foo = state.Foo;
Dirty();
}
[Serializable, NetSerializable]
private sealed class PredictionComponentState : ComponentState
{
@@ -437,10 +448,10 @@ namespace Content.IntegrationTests.Tests.Networking
if (Allow)
{
component.Foo = message.NewFoo;
Dirty(message.Uid, component);
}
EventTriggerList.Add((_gameTiming.CurTick, _gameTiming.IsFirstTimePredicted, old, component.Foo,
message.NewFoo));
EventTriggerList.Add((_gameTiming.CurTick, _gameTiming.IsFirstTimePredicted, old, component.Foo, message.NewFoo));
}
}

View File

@@ -0,0 +1,471 @@
#nullable enable
using System.Collections.Generic;
using System.Linq;
using Robust.Client.GameStates;
using Robust.Client.Timing;
using Robust.Server.Player;
using Robust.Shared;
using Robust.Shared.Analyzers;
using Robust.Shared.Configuration;
using Robust.Shared.GameObjects;
using Robust.Shared.GameStates;
using Robust.Shared.IoC;
using Robust.Shared.Map;
using Robust.Shared.Reflection;
using Robust.Shared.Serialization;
using Robust.Shared.Timing;
namespace Content.IntegrationTests.Tests.Networking
{
// This test checks that the prediction & reconciling system is working correctly with a simple boolean flag.
// An entity system sets a flag on a networked component via a RaisePredictiveEvent,
// so it runs predicted on client and eventually on server.
// All the tick values are checked to ensure it arrives on client & server at the exact correct ticks.
// On the client, the reconciling system is checked to ensure that the state correctly reset every tick,
// until the server acknowledges it.
// Then, the same test is performed again, but the server does not handle the message (it ignores it).
// To simulate a mispredict.
// This means the client is forced to reset it once it gets to the server tick where the server didn't do anything.
// the tick where the server *should* have, but did not, acknowledge the state change.
// Finally, we run two events inside the prediction area to ensure reconciling does for incremental stuff.
[TestFixture]
public sealed class SystemPredictReconcileTest
{
[Test]
public async Task Test()
{
await using var pairTracker = await PoolManager.GetServerClient(new() { Fresh = true, DummyTicker = true });
var server = pairTracker.Pair.Server;
var client = pairTracker.Pair.Client;
// Pull in all dependencies we need.
var sPlayerManager = server.ResolveDependency<IPlayerManager>();
var sMapManager = server.ResolveDependency<IMapManager>();
var sEntityManager = server.ResolveDependency<IEntityManager>();
var cEntityManager = client.ResolveDependency<IEntityManager>();
var sGameTiming = server.ResolveDependency<IGameTiming>();
var cGameTiming = client.ResolveDependency<IClientGameTiming>();
var cGameStateManager = client.ResolveDependency<IClientGameStateManager>();
var cfg = client.ResolveDependency<IConfigurationManager>();
var log = cfg.GetCVar(CVars.NetLogging);
//cfg.SetCVar(CVars.NetLogging, true);
EntityUid serverEnt = default;
SystemPredictionTestComponent serverComponent = default!;
SystemPredictionTestComponent clientComponent = default!;
var serverSystem = server.ResolveDependency<IEntitySystemManager>()
.GetEntitySystem<SystemPredictionTestEntitySystem>();
var clientSystem = client.ResolveDependency<IEntitySystemManager>()
.GetEntitySystem<SystemPredictionTestEntitySystem>();
await server.WaitPost(() =>
{
// Spawn dummy component entity.
var map = sMapManager.CreateMap();
var player = sPlayerManager.ServerSessions.Single();
serverEnt = sEntityManager.SpawnEntity(null, new MapCoordinates((0, 0), map));
serverComponent = sEntityManager.AddComponent<SystemPredictionTestComponent>(serverEnt);
// Make client "join game" so they receive game state updates.
player.JoinGame();
});
// Run some ticks so that
await PoolManager.RunTicksSync(pairTracker.Pair, 3);
// Check client buffer is full
Assert.That(cGameStateManager.CurrentBufferSize, Is.EqualTo(cGameStateManager.TargetBufferSize));
// This isn't required anymore, but the test had this for the sake of "technical things", and I cbf shifting
// all the tick times over. So it stays.
await client.WaitRunTicks(1);
await client.WaitPost(() =>
{
clientComponent = cEntityManager.GetComponent<SystemPredictionTestComponent>(serverEnt);
});
Assert.Multiple(() =>
{
Assert.That(clientComponent.Foo, Is.False);
// KEEP IN MIND WHEN READING THIS.
// The game loop increments CurTick AFTER running the tick.
// So when reading CurTick inside an Assert or Post or whatever, the tick reported is the NEXT one to run.
Assert.That(sGameTiming.CurTick, Is.EqualTo(new GameTick(14)));
Assert.That(serverComponent.Foo, Is.False);
// Client last ran tick 15 meaning it's ahead of the last server tick it processed (12)
Assert.That(cGameTiming.CurTick, Is.EqualTo(new GameTick(16)));
Assert.That(cGameTiming.LastProcessedTick, Is.EqualTo(new GameTick(12)));
});
// *** I am using block scopes to visually distinguish these sections of the test to make it more readable.
// Send an event to change the flag and instantly see the effect replicate client side,
// while it's queued on server and reconciling works (constantly needs re-firing on client).
{
await client.WaitPost(() =>
{
cEntityManager.RaisePredictiveEvent(new SetFooMessage(serverEnt, true));
Assert.That(clientComponent.Foo, Is.True);
});
// Event correctly arrived on client system.
Assert.That(clientSystem.EventTriggerList,
Is.EquivalentTo(new[] { (new GameTick(16), true, false, true, true) }));
clientSystem.EventTriggerList.Clear();
// Two ticks happen on both sides with nothing really "changing".
// Server doesn't receive it yet,
// client is still replaying the past prediction.
for (var i = 0; i < 2; i++)
{
await server.WaitRunTicks(1);
// Event did not arrive on server.
Assert.That(serverSystem.EventTriggerList, Is.Empty);
await client.WaitRunTicks(1);
// Event got repeated on client as a past prediction.
Assert.That(clientSystem.EventTriggerList,
Is.EquivalentTo(new[] { (new GameTick(16), false, false, true, true) }));
clientSystem.EventTriggerList.Clear();
}
{
await server.WaitRunTicks(1);
Assert.Multiple(() =>
{
// Event arrived on server at tick 16.
Assert.That(sGameTiming.CurTick, Is.EqualTo(new GameTick(17)));
Assert.That(serverSystem.EventTriggerList,
Is.EquivalentTo(new[] { (new GameTick(16), true, false, true, true) }));
});
serverSystem.EventTriggerList.Clear();
await client.WaitRunTicks(1);
// Event got repeated on client as a past prediction.
Assert.That(clientSystem.EventTriggerList,
Is.EquivalentTo(new[] { (new GameTick(16), false, false, true, true) }));
clientSystem.EventTriggerList.Clear();
}
{
await server.WaitRunTicks(1);
// Nothing happened on server.
Assert.That(serverSystem.EventTriggerList, Is.Empty);
await client.WaitRunTicks(1);
Assert.Multiple(() =>
{
// Event got repeated on client as a past prediction.
Assert.That(clientSystem.EventTriggerList, Is.Empty);
Assert.That(clientComponent.Foo, Is.True);
});
clientSystem.EventTriggerList.Clear();
}
}
// Disallow changes to simulate a misprediction.
serverSystem.Allow = false;
Assert.Multiple(() =>
{
// Assert timing is still correct, should be but it's a good reference for the rest of the test.
Assert.That(sGameTiming.CurTick, Is.EqualTo(new GameTick(18)));
Assert.That(cGameTiming.CurTick, Is.EqualTo(new GameTick(20)));
Assert.That(cGameTiming.LastProcessedTick, Is.EqualTo(new GameTick(16)));
});
{
// Send event to server to change flag again, this time to disable it..
await client.WaitPost(() =>
{
cEntityManager.RaisePredictiveEvent(new SetFooMessage(serverEnt, false));
Assert.That(clientComponent.Foo, Is.False);
});
// Event correctly arrived on client system.
Assert.That(clientSystem.EventTriggerList,
Is.EquivalentTo(new[] { (new GameTick(20), true, true, false, false) }));
clientSystem.EventTriggerList.Clear();
for (var i = 0; i < 2; i++)
{
await server.WaitRunTicks(1);
// Event did not arrive on server.
Assert.That(serverSystem.EventTriggerList, Is.Empty);
await client.WaitRunTicks(1);
// Event got repeated on client as a past prediction.
Assert.That(clientSystem.EventTriggerList,
Is.EquivalentTo(new[] { (new GameTick(20), false, true, false, false) }));
clientSystem.EventTriggerList.Clear();
}
{
await server.WaitRunTicks(1);
Assert.Multiple(() =>
{
// Event arrived on server at tick 20.
Assert.That(sGameTiming.CurTick, Is.EqualTo(new GameTick(21)));
// But the server didn't listen!
Assert.That(serverSystem.EventTriggerList,
Is.EquivalentTo(new[] { (new GameTick(20), true, true, true, false) }));
});
serverSystem.EventTriggerList.Clear();
await client.WaitRunTicks(1);
// Event got repeated on client as a past prediction.
Assert.That(clientSystem.EventTriggerList,
Is.EquivalentTo(new[] { (new GameTick(20), false, true, false, false) }));
clientSystem.EventTriggerList.Clear();
}
{
await server.WaitRunTicks(1);
// Nothing happened on server.
Assert.That(serverSystem.EventTriggerList, Is.Empty);
await client.WaitRunTicks(1);
Assert.Multiple(() =>
{
// Event no longer got repeated and flag was *not* set by server state.
// Mispredict gracefully handled!
Assert.That(clientSystem.EventTriggerList, Is.Empty);
Assert.That(clientComponent.Foo, Is.True);
});
clientSystem.EventTriggerList.Clear();
}
}
// Re-allow changes to make everything work correctly again.
serverSystem.Allow = true;
Assert.Multiple(() =>
{
// Assert timing is still correct.
Assert.That(sGameTiming.CurTick, Is.EqualTo(new GameTick(22)));
Assert.That(cGameTiming.CurTick, Is.EqualTo(new GameTick(24)));
Assert.That(cGameTiming.LastProcessedTick, Is.EqualTo(new GameTick(20)));
});
{
// Send first event to disable the flag (reminder: it never got accepted by the server).
await client.WaitPost(() =>
{
cEntityManager.RaisePredictiveEvent(new SetFooMessage(serverEnt, false));
Assert.That(clientComponent.Foo, Is.False);
});
// Event correctly arrived on client system.
Assert.That(clientSystem.EventTriggerList,
Is.EquivalentTo(new[] { (new GameTick(24), true, true, false, false) }));
clientSystem.EventTriggerList.Clear();
// Run one tick, everything checks out.
{
await server.WaitRunTicks(1);
// Event did not arrive on server.
Assert.That(serverSystem.EventTriggerList, Is.Empty);
await client.WaitRunTicks(1);
// Event got repeated on client as a past prediction.
Assert.That(clientSystem.EventTriggerList,
Is.EquivalentTo(new[] { (new GameTick(24), false, true, false, false) }));
clientSystem.EventTriggerList.Clear();
}
// Send another event, to re-enable it.
await client.WaitPost(() =>
{
cEntityManager.RaisePredictiveEvent(new SetFooMessage(serverEnt, true));
Assert.That(clientComponent.Foo, Is.True);
});
// Event correctly arrived on client system.
Assert.That(clientSystem.EventTriggerList,
Is.EquivalentTo(new[] { (new GameTick(25), true, false, true, true) }));
clientSystem.EventTriggerList.Clear();
// Next tick we run, both events come in, but at different times.
{
await server.WaitRunTicks(1);
// Event did not arrive on server.
Assert.That(serverSystem.EventTriggerList, Is.Empty);
await client.WaitRunTicks(1);
// Event got repeated on client as a past prediction.
Assert.That(clientSystem.EventTriggerList,
Is.EquivalentTo(new[]
{
(new GameTick(24), false, true, false, false), (new GameTick(25), false, false, true, true)
}));
clientSystem.EventTriggerList.Clear();
}
// FIRST event arrives on server!
{
await server.WaitRunTicks(1);
Assert.That(serverSystem.EventTriggerList,
Is.EquivalentTo(new[] { (new GameTick(24), true, true, false, false) }));
serverSystem.EventTriggerList.Clear();
await client.WaitRunTicks(1);
// Event got repeated on client as a past prediction.
Assert.That(clientSystem.EventTriggerList,
Is.EquivalentTo(new[]
{
(new GameTick(24), false, true, false, false), (new GameTick(25), false, false, true, true)
}));
clientSystem.EventTriggerList.Clear();
}
// SECOND event arrived on server, client receives ack for first event,
// still runs second event as past prediction.
{
await server.WaitRunTicks(1);
Assert.That(serverSystem.EventTriggerList,
Is.EquivalentTo(new[] { (new GameTick(25), true, false, true, true) }));
serverSystem.EventTriggerList.Clear();
await client.WaitRunTicks(1);
// Event got repeated on client as a past prediction.
Assert.That(clientSystem.EventTriggerList,
Is.EquivalentTo(new[]
{
(new GameTick(25), false, false, true, true)
}));
clientSystem.EventTriggerList.Clear();
}
// Finally, second event acknowledged on client and we're good.
{
await server.WaitRunTicks(1);
Assert.That(serverSystem.EventTriggerList, Is.Empty);
await client.WaitRunTicks(1);
Assert.Multiple(() =>
{
// Event got repeated on client as a past prediction.
Assert.That(clientSystem.EventTriggerList, Is.Empty);
Assert.That(clientComponent.Foo, Is.True);
});
}
}
cfg.SetCVar(CVars.NetLogging, log);
await pairTracker.CleanReturnAsync();
}
[NetworkedComponent()]
[Access(typeof(SystemPredictionTestEntitySystem))]
public sealed class SystemPredictionTestComponent : Component
{
public bool Foo;
}
[Reflect(false)]
public sealed class SystemPredictionTestEntitySystem : EntitySystem
{
public bool Allow { get; set; } = true;
// Queue of all the events that come in so we can test that they come in perfectly as expected.
public List<(GameTick tick, bool firstPredict, bool old, bool @new, bool value)> EventTriggerList { get; } =
new();
[Dependency] private readonly IGameTiming _gameTiming = default!;
public override void Initialize()
{
base.Initialize();
SubscribeNetworkEvent<SetFooMessage>(HandleMessage);
SubscribeLocalEvent<SetFooMessage>(HandleMessage);
SubscribeLocalEvent<SystemPredictionTestComponent, ComponentGetState>(OnGetState);
SubscribeLocalEvent<SystemPredictionTestComponent, ComponentHandleState>(OnHandleState);
}
private void HandleMessage(SetFooMessage message, EntitySessionEventArgs args)
{
var component = EntityManager.GetComponent<SystemPredictionTestComponent>(message.Uid);
var old = component.Foo;
if (Allow)
{
component.Foo = message.NewFoo;
Dirty(message.Uid, component);
}
EventTriggerList.Add((_gameTiming.CurTick, _gameTiming.IsFirstTimePredicted, old, component.Foo, message.NewFoo));
}
private void OnGetState(EntityUid uid, SystemPredictionTestComponent comp, ref ComponentGetState args)
{
args.State = new SystemPredictionComponentState(comp.Foo);
}
private void OnHandleState(EntityUid uid, SystemPredictionTestComponent comp, ref ComponentHandleState args)
{
if (args.Current is not SystemPredictionComponentState state)
return;
comp.Foo = state.Foo;
Dirty(uid, comp);
}
[Serializable, NetSerializable]
private sealed class SystemPredictionComponentState : ComponentState
{
public bool Foo { get; }
public SystemPredictionComponentState(bool foo)
{
Foo = foo;
}
}
}
private sealed class SetFooMessage : EntityEventArgs
{
public SetFooMessage(EntityUid uid, bool newFoo)
{
Uid = uid;
NewFoo = newFoo;
}
public EntityUid Uid { get; }
public bool NewFoo { get; }
}
}
}

View File

@@ -1,7 +1,5 @@
using System.Threading.Tasks;
using Content.IntegrationTests.Tests.Interaction;
using Content.Server.Explosion.Components;
using NUnit.Framework;
using Robust.Shared.Containers;
using Robust.Shared.GameObjects;
@@ -73,4 +71,3 @@ public sealed class ModularGrenadeTests : InteractionTest
AssertDeleted();
}
}

View File

@@ -1,25 +1,21 @@
using System;
using System.Collections.Generic;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Content.Server.GameTicking;
using Content.Server.Maps;
using Content.Server.Shuttles.Components;
using Content.Server.Spawners.Components;
using Content.Server.Station.Components;
using Content.Server.Station.Systems;
using Content.Shared.CCVar;
using Content.Shared.Roles;
using NUnit.Framework;
using Robust.Server.GameObjects;
using Robust.Server.Maps;
using Robust.Shared.Configuration;
using Robust.Shared.ContentPack;
using Robust.Shared.GameObjects;
using Robust.Shared.Utility;
using Robust.Shared.Map;
using Robust.Shared.Map.Components;
using Robust.Shared.Prototypes;
using YamlDotNet.RepresentationModel;
using ShuttleSystem = Content.Server.Shuttles.Systems.ShuttleSystem;
@@ -38,7 +34,7 @@ namespace Content.IntegrationTests.Tests
"Dart",
};
private static string[] Grids =
private static readonly string[] Grids =
{
"/Maps/centcomm.yml",
"/Maps/Shuttles/cargo.yml",
@@ -52,10 +48,11 @@ namespace Content.IntegrationTests.Tests
[Test, TestCaseSource(nameof(Grids))]
public async Task GridsLoadableTest(string mapFile)
{
await using var pairTracker = await PoolManager.GetServerClient(new PoolSettings{NoClient = true});
await using var pairTracker = await PoolManager.GetServerClient(new PoolSettings { NoClient = true });
var server = pairTracker.Pair.Server;
var mapLoader = server.ResolveDependency<IEntitySystemManager>().GetEntitySystem<MapLoaderSystem>();
var entManager = server.ResolveDependency<IEntityManager>();
var mapLoader = entManager.System<MapLoaderSystem>();
var mapManager = server.ResolveDependency<IMapManager>();
var cfg = server.ResolveDependency<IConfigurationManager>();
Assert.That(cfg.GetCVar(CCVars.GridFill), Is.False);
@@ -65,7 +62,10 @@ namespace Content.IntegrationTests.Tests
var mapId = mapManager.CreateMap();
try
{
mapLoader.LoadGrid(mapId, mapFile);
#pragma warning disable NUnit2045
Assert.That(mapLoader.TryLoad(mapId, mapFile, out var roots));
Assert.That(roots.Where(uid => entManager.HasComponent<MapGridComponent>(uid)), Is.Not.Empty);
#pragma warning restore NUnit2045
}
catch (Exception ex)
{
@@ -89,7 +89,7 @@ namespace Content.IntegrationTests.Tests
[Test]
public async Task NoSavedPostMapInitTest()
{
await using var pairTracker = await PoolManager.GetServerClient(new PoolSettings{NoClient = true});
await using var pairTracker = await PoolManager.GetServerClient(new PoolSettings { NoClient = true });
var server = pairTracker.Pair.Server;
var resourceManager = server.ResolveDependency<IResourceManager>();
@@ -123,7 +123,7 @@ namespace Content.IntegrationTests.Tests
var meta = root["meta"];
var postMapInit = meta["postmapinit"].AsBool();
Assert.False(postMapInit, $"Map {map.Filename} was saved postmapinit");
Assert.That(postMapInit, Is.False, $"Map {map.Filename} was saved postmapinit");
}
await pairTracker.CleanReturnAsync();
}
@@ -168,7 +168,7 @@ namespace Content.IntegrationTests.Tests
await pairTracker.CleanReturnAsync();
return mapNames.ToArray();
});
Task.WaitAll(task);
Task.WaitAny(task);
}
return task.GetAwaiter().GetResult();
@@ -177,7 +177,7 @@ namespace Content.IntegrationTests.Tests
[Test, TestCaseSource(nameof(GetGameMapNames))]
public async Task GameMapsLoadableTest(string mapProto)
{
await using var pairTracker = await PoolManager.GetServerClient(new PoolSettings{NoClient = true});
await using var pairTracker = await PoolManager.GetServerClient(new PoolSettings { NoClient = true });
var server = pairTracker.Pair.Server;
var mapManager = server.ResolveDependency<IMapManager>();
@@ -212,7 +212,8 @@ namespace Content.IntegrationTests.Tests
foreach (var grid in grids)
{
if (!memberQuery.HasComponent(grid.Owner))
var gridEnt = grid.Owner;
if (!memberQuery.HasComponent(gridEnt))
continue;
var area = grid.LocalAABB.Width * grid.LocalAABB.Height;
@@ -220,7 +221,7 @@ namespace Content.IntegrationTests.Tests
if (area > largest)
{
largest = area;
targetGrid = grid.Owner;
targetGrid = gridEnt;
}
}
@@ -230,11 +231,18 @@ namespace Content.IntegrationTests.Tests
if (entManager.TryGetComponent<StationEmergencyShuttleComponent>(station, out var stationEvac))
{
var shuttlePath = stationEvac.EmergencyShuttlePath;
var shuttle = mapLoader.LoadGrid(shuttleMap, shuttlePath.ToString());
#pragma warning disable NUnit2045
Assert.That(mapLoader.TryLoad(shuttleMap, shuttlePath.ToString(), out var roots));
EntityUid shuttle = default!;
Assert.DoesNotThrow(() =>
{
shuttle = roots.First(uid => entManager.HasComponent<MapGridComponent>(uid));
}, $"Failed to load {shuttlePath}");
Assert.That(
shuttle != null && shuttleSystem.TryFTLDock(shuttle.Value,
entManager.GetComponent<ShuttleComponent>(shuttle.Value), targetGrid.Value),
shuttleSystem.TryFTLDock(shuttle,
entManager.GetComponent<ShuttleComponent>(shuttle), targetGrid.Value),
$"Unable to dock {shuttlePath} to {mapProto}");
#pragma warning restore NUnit2045
}
mapManager.DeleteMap(shuttleMap);
@@ -246,12 +254,13 @@ namespace Content.IntegrationTests.Tests
{
var lateSpawns = 0;
foreach (var comp in entManager.EntityQuery<SpawnPointComponent>(true))
var query = entManager.AllEntityQueryEnumerator<SpawnPointComponent>();
while (query.MoveNext(out var uid, out var comp))
{
if (comp.SpawnType != SpawnPointType.LateJoin ||
!xformQuery.TryGetComponent(comp.Owner, out var xform) ||
xform.GridUid == null ||
!gridUids.Contains(xform.GridUid.Value))
if (comp.SpawnType != SpawnPointType.LateJoin
|| !xformQuery.TryGetComponent(uid, out var xform)
|| xform.GridUid == null
|| !gridUids.Contains(xform.GridUid.Value))
{
continue;
}
@@ -279,8 +288,8 @@ namespace Content.IntegrationTests.Tests
missingSpawnPoints.Add(spawnpoint);
}
Assert.That(missingSpawnPoints.Count() == 0,
$"There is no spawnpoint for {String.Join(", ", missingSpawnPoints)} on {mapProto}.");
Assert.That(missingSpawnPoints, Has.Count.EqualTo(0),
$"There is no spawnpoint for {string.Join(", ", missingSpawnPoints)} on {mapProto}.");
}
try
@@ -308,7 +317,7 @@ namespace Content.IntegrationTests.Tests
task = Task.Run(static async () =>
{
await Task.Yield();
await using var pairTracker = await PoolManager.GetServerClient(new PoolSettings{Disconnected = true});
await using var pairTracker = await PoolManager.GetServerClient(new PoolSettings { Disconnected = true });
var server = pairTracker.Pair.Server;
var resourceManager = server.ResolveDependency<IResourceManager>();
var protoManager = server.ResolveDependency<IPrototypeManager>();
@@ -337,7 +346,7 @@ namespace Content.IntegrationTests.Tests
await pairTracker.CleanReturnAsync();
return mapNames.ToArray();
});
Task.WaitAll(task);
Task.WaitAny(task);
}
return task.GetAwaiter().GetResult();
@@ -346,7 +355,7 @@ namespace Content.IntegrationTests.Tests
[Test, TestCaseSource(nameof(GetMaps))]
public async Task MapsLoadableTest(string mapName)
{
await using var pairTracker = await PoolManager.GetServerClient(new PoolSettings{NoClient = true});
await using var pairTracker = await PoolManager.GetServerClient(new PoolSettings { NoClient = true });
var server = pairTracker.Pair.Server;
var mapLoader = server.ResolveDependency<IEntitySystemManager>().GetEntitySystem<MapLoaderSystem>();
@@ -359,7 +368,7 @@ namespace Content.IntegrationTests.Tests
var mapId = mapManager.CreateMap();
try
{
mapLoader.LoadMap(mapId, mapName);
Assert.That(mapLoader.TryLoad(mapId, mapName, out _));
}
catch (Exception ex)
{

View File

@@ -1,6 +1,4 @@
#nullable enable
using System;
using System.Threading.Tasks;
using Content.Server.NodeContainer;
using Content.Server.NodeContainer.EntitySystems;
using Content.Server.NodeContainer.Nodes;
@@ -8,13 +6,10 @@ using Content.Server.Power.Components;
using Content.Server.Power.EntitySystems;
using Content.Server.Power.Nodes;
using Content.Shared.Coordinates;
using NUnit.Framework;
using Robust.Shared.GameObjects;
using Robust.Shared.Map;
using Robust.Shared.Maths;
using Robust.Shared.Timing;
using TerraFX.Interop.Windows;
using static Content.Server.Power.Pow3r.PowerState;
namespace Content.IntegrationTests.Tests.Power
{
@@ -166,7 +161,11 @@ namespace Content.IntegrationTests.Tests.Power
[Test]
public async Task TestSimpleSurplus()
{
await using var pairTracker = await PoolManager.GetServerClient(new PoolSettings{NoClient = true, ExtraPrototypes = Prototypes});
await using var pairTracker = await PoolManager.GetServerClient(new PoolSettings
{
NoClient = true,
ExtraPrototypes = Prototypes
});
var server = pairTracker.Pair.Server;
var mapManager = server.ResolveDependency<IMapManager>();
var entityManager = server.ResolveDependency<IEntityManager>();
@@ -205,6 +204,8 @@ namespace Content.IntegrationTests.Tests.Power
server.RunTicks(1); //let run a tick for PowerNet to process power
await server.WaitAssertion(() =>
{
Assert.Multiple(() =>
{
// Assert both consumers fully powered
Assert.That(consumer1.ReceivedPower, Is.EqualTo(consumer1.DrawRate).Within(0.1));
@@ -213,6 +214,7 @@ namespace Content.IntegrationTests.Tests.Power
// Assert that load adds up on supply.
Assert.That(supplier.CurrentSupply, Is.EqualTo(loadPower * 2).Within(0.1));
});
});
await pairTracker.CleanReturnAsync();
}
@@ -224,7 +226,11 @@ namespace Content.IntegrationTests.Tests.Power
[Test]
public async Task TestSimpleDeficit()
{
await using var pairTracker = await PoolManager.GetServerClient(new PoolSettings{NoClient = true, ExtraPrototypes = Prototypes});
await using var pairTracker = await PoolManager.GetServerClient(new PoolSettings
{
NoClient = true,
ExtraPrototypes = Prototypes
});
var server = pairTracker.Pair.Server;
var mapManager = server.ResolveDependency<IMapManager>();
var entityManager = server.ResolveDependency<IEntityManager>();
@@ -263,6 +269,8 @@ namespace Content.IntegrationTests.Tests.Power
server.RunTicks(1); //let run a tick for PowerNet to process power
await server.WaitAssertion(() =>
{
Assert.Multiple(() =>
{
// Assert both consumers get 33% power.
Assert.That(consumer1.ReceivedPower, Is.EqualTo(consumer1.DrawRate / 3).Within(0.1));
@@ -271,6 +279,7 @@ namespace Content.IntegrationTests.Tests.Power
// Supply should be maxed out
Assert.That(supplier.CurrentSupply, Is.EqualTo(supplier.MaxSupply).Within(0.1));
});
});
await pairTracker.CleanReturnAsync();
}
@@ -278,7 +287,11 @@ namespace Content.IntegrationTests.Tests.Power
[Test]
public async Task TestSupplyRamp()
{
await using var pairTracker = await PoolManager.GetServerClient(new PoolSettings{NoClient = true, ExtraPrototypes = Prototypes});
await using var pairTracker = await PoolManager.GetServerClient(new PoolSettings
{
NoClient = true,
ExtraPrototypes = Prototypes
});
var server = pairTracker.Pair.Server;
var mapManager = server.ResolveDependency<IMapManager>();
var entityManager = server.ResolveDependency<IEntityManager>();
@@ -318,23 +331,29 @@ namespace Content.IntegrationTests.Tests.Power
server.RunTicks(1);
await server.WaitAssertion(() =>
{
Assert.Multiple(() =>
{
// First tick, supply should be delivering 100 W (max tolerance) and start ramping up.
Assert.That(supplier.CurrentSupply, Is.EqualTo(100).Within(0.1));
Assert.That(consumer.ReceivedPower, Is.EqualTo(100).Within(0.1));
});
});
// run for 0.25 seconds (minus the previous tick)
var ticks = (int) Math.Round(0.25 * gameTiming.TickRate) - 1;
server.RunTicks(ticks);
await server.WaitAssertion(() =>
{
Assert.Multiple(() =>
{
// After 15 ticks (0.25 seconds), supply ramp pos should be at 100 W and supply at 100, approx.
Assert.That(supplier.CurrentSupply, Is.EqualTo(200).Within(tickDev));
Assert.That(supplier.SupplyRampPosition, Is.EqualTo(100).Within(tickDev));
Assert.That(consumer.ReceivedPower, Is.EqualTo(200).Within(tickDev));
});
});
@@ -343,12 +362,15 @@ namespace Content.IntegrationTests.Tests.Power
server.RunTicks(ticks);
await server.WaitAssertion(() =>
{
Assert.Multiple(() =>
{
// After 1 second total, ramp should be at 400 and supply should be at 400, everybody happy.
Assert.That(supplier.CurrentSupply, Is.EqualTo(400).Within(tickDev));
Assert.That(supplier.SupplyRampPosition, Is.EqualTo(400).Within(tickDev));
Assert.That(consumer.ReceivedPower, Is.EqualTo(400).Within(tickDev));
});
});
await pairTracker.CleanReturnAsync();
}
@@ -356,11 +378,16 @@ namespace Content.IntegrationTests.Tests.Power
[Test]
public async Task TestBatteryRamp()
{
await using var pairTracker = await PoolManager.GetServerClient(new PoolSettings{NoClient = true, ExtraPrototypes = Prototypes});
await using var pairTracker = await PoolManager.GetServerClient(new PoolSettings
{
NoClient = true,
ExtraPrototypes = Prototypes
});
var server = pairTracker.Pair.Server;
var mapManager = server.ResolveDependency<IMapManager>();
var entityManager = server.ResolveDependency<IEntityManager>();
var gameTiming = server.ResolveDependency<IGameTiming>();
var batterySys = entityManager.System<BatterySystem>();
const float startingCharge = 100_000;
PowerNetworkBatteryComponent netBattery = default!;
@@ -386,8 +413,8 @@ namespace Content.IntegrationTests.Tests.Power
battery = entityManager.GetComponent<BatteryComponent>(generatorEnt);
consumer = entityManager.GetComponent<PowerConsumerComponent>(consumerEnt);
battery.MaxCharge = startingCharge;
battery.CurrentCharge = startingCharge;
batterySys.SetMaxCharge(generatorEnt, startingCharge, battery);
batterySys.SetCharge(generatorEnt, startingCharge, battery);
netBattery.MaxSupply = 400;
netBattery.SupplyRampRate = 400;
netBattery.SupplyRampTolerance = 100;
@@ -401,17 +428,22 @@ namespace Content.IntegrationTests.Tests.Power
server.RunTicks(1);
await server.WaitAssertion(() =>
{
Assert.Multiple(() =>
{
// First tick, supply should be delivering 100 W (max tolerance) and start ramping up.
Assert.That(netBattery.CurrentSupply, Is.EqualTo(100).Within(0.1));
Assert.That(consumer.ReceivedPower, Is.EqualTo(100).Within(0.1));
});
});
// run for 0.25 seconds (minus the previous tick)
var ticks = (int) Math.Round(0.25 * gameTiming.TickRate) - 1;
server.RunTicks(ticks);
await server.WaitAssertion(() =>
{
Assert.Multiple(() =>
{
// After 15 ticks (0.25 seconds), supply ramp pos should be at 100 W and supply at 100, approx.
Assert.That(netBattery.CurrentSupply, Is.EqualTo(200).Within(tickDev));
@@ -422,12 +454,15 @@ namespace Content.IntegrationTests.Tests.Power
const double spentExpected = (200 + 100) / 2.0 * 0.25;
Assert.That(battery.CurrentCharge, Is.EqualTo(startingCharge - spentExpected).Within(tickDev));
});
});
// run for 0.75 seconds
ticks = (int) Math.Round(0.75 * gameTiming.TickRate);
server.RunTicks(ticks);
await server.WaitAssertion(() =>
{
Assert.Multiple(() =>
{
// After 1 second total, ramp should be at 400 and supply should be at 400, everybody happy.
Assert.That(netBattery.CurrentSupply, Is.EqualTo(400).Within(tickDev));
@@ -438,6 +473,7 @@ namespace Content.IntegrationTests.Tests.Power
const double spentExpected = (400 + 100) / 2.0 * 0.75 + 400 * 0.25;
Assert.That(battery.CurrentCharge, Is.EqualTo(startingCharge - spentExpected).Within(tickDev));
});
});
await pairTracker.CleanReturnAsync();
}
@@ -451,6 +487,7 @@ namespace Content.IntegrationTests.Tests.Power
var server = pairTracker.Pair.Server;
var mapManager = server.ResolveDependency<IMapManager>();
var entityManager = server.ResolveDependency<IEntityManager>();
var batterySys = entityManager.System<BatterySystem>();
PowerSupplierComponent supplier = default!;
PowerNetworkBatteryComponent netBattery = default!;
BatteryComponent battery = default!;
@@ -474,7 +511,7 @@ namespace Content.IntegrationTests.Tests.Power
var generatorEnt = entityManager.SpawnEntity("GeneratorDummy", grid.ToCoordinates());
var consumerEnt = entityManager.SpawnEntity("ConsumerDummy", grid.ToCoordinates(0, 1));
var batteryEnt = entityManager.SpawnEntity("DischargingBatteryDummy", grid.ToCoordinates(0,2));
var batteryEnt = entityManager.SpawnEntity("DischargingBatteryDummy", grid.ToCoordinates(0, 2));
netBattery = entityManager.GetComponent<PowerNetworkBatteryComponent>(batteryEnt);
battery = entityManager.GetComponent<BatteryComponent>(batteryEnt);
supplier = entityManager.GetComponent<PowerSupplierComponent>(generatorEnt);
@@ -482,13 +519,13 @@ namespace Content.IntegrationTests.Tests.Power
consumer.DrawRate = draw;
supplier.MaxSupply = draw/2;
supplier.MaxSupply = draw / 2;
supplier.SupplyRampRate = rampRate;
supplier.SupplyRampTolerance = rampTol;
battery.MaxCharge = 100_000;
battery.CurrentCharge = 100_000;
netBattery.MaxSupply = draw/2;
batterySys.SetMaxCharge(batteryEnt, 100_000, battery);
batterySys.SetCharge(batteryEnt, 100_000, battery);
netBattery.MaxSupply = draw / 2;
netBattery.SupplyRampRate = rampRate;
netBattery.SupplyRampTolerance = rampTol;
});
@@ -496,22 +533,28 @@ namespace Content.IntegrationTests.Tests.Power
server.RunTicks(1);
await server.WaitAssertion(() =>
{
Assert.Multiple(() =>
{
Assert.That(supplier.CurrentSupply, Is.EqualTo(rampTol).Within(0.1));
Assert.That(netBattery.CurrentSupply, Is.EqualTo(rampTol).Within(0.1));
Assert.That(consumer.ReceivedPower, Is.EqualTo(rampTol*2).Within(0.1));
Assert.That(consumer.ReceivedPower, Is.EqualTo(rampTol * 2).Within(0.1));
});
});
server.RunTicks(60);
await server.WaitAssertion(() =>
{
Assert.That(supplier.CurrentSupply, Is.EqualTo(draw/2).Within(0.1));
Assert.That(supplier.SupplyRampPosition, Is.EqualTo(draw/2).Within(0.1));
Assert.Multiple(() =>
{
Assert.That(supplier.CurrentSupply, Is.EqualTo(draw / 2).Within(0.1));
Assert.That(supplier.SupplyRampPosition, Is.EqualTo(draw / 2).Within(0.1));
Assert.That(netBattery.CurrentSupply, Is.EqualTo(draw / 2).Within(0.1));
Assert.That(netBattery.SupplyRampPosition, Is.EqualTo(draw / 2).Within(0.1));
Assert.That(consumer.ReceivedPower, Is.EqualTo(draw).Within(0.1));
});
});
// now we disconnect the load;
consumer.NetworkLoad.Enabled = false;
@@ -519,6 +562,8 @@ namespace Content.IntegrationTests.Tests.Power
server.RunTicks(60);
await server.WaitAssertion(() =>
{
Assert.Multiple(() =>
{
Assert.That(supplier.CurrentSupply, Is.EqualTo(0).Within(0.1));
Assert.That(supplier.SupplyRampPosition, Is.EqualTo(0).Within(0.1));
@@ -526,6 +571,7 @@ namespace Content.IntegrationTests.Tests.Power
Assert.That(netBattery.SupplyRampPosition, Is.EqualTo(0).Within(0.1));
Assert.That(consumer.ReceivedPower, Is.EqualTo(0).Within(0.1));
});
});
await pairTracker.CleanReturnAsync();
}
@@ -533,11 +579,16 @@ namespace Content.IntegrationTests.Tests.Power
[Test]
public async Task TestSimpleBatteryChargeDeficit()
{
await using var pairTracker = await PoolManager.GetServerClient(new PoolSettings{NoClient = true, ExtraPrototypes = Prototypes});
await using var pairTracker = await PoolManager.GetServerClient(new PoolSettings
{
NoClient = true,
ExtraPrototypes = Prototypes
});
var server = pairTracker.Pair.Server;
var mapManager = server.ResolveDependency<IMapManager>();
var gameTiming = server.ResolveDependency<IGameTiming>();
var entityManager = server.ResolveDependency<IEntityManager>();
var batterySys = entityManager.System<BatterySystem>();
PowerSupplierComponent supplier = default!;
BatteryComponent battery = default!;
@@ -562,8 +613,8 @@ namespace Content.IntegrationTests.Tests.Power
supplier.MaxSupply = 500;
supplier.SupplyRampTolerance = 500;
battery.MaxCharge = 100000;
netBattery.MaxChargeRate = 1000;
batterySys.SetMaxCharge(batteryEnt, 100_000, battery);
netBattery.MaxChargeRate = 1_000;
netBattery.Efficiency = 0.5f;
});
@@ -572,12 +623,15 @@ namespace Content.IntegrationTests.Tests.Power
server.RunTicks(ticks);
await server.WaitAssertion(() =>
{
Assert.Multiple(() =>
{
// half a second @ 500 W = 250
// 50% efficiency, so 125 J stored total.
Assert.That(battery.CurrentCharge, Is.EqualTo(125).Within(0.1));
Assert.That(supplier.CurrentSupply, Is.EqualTo(500).Within(0.1));
});
});
await pairTracker.CleanReturnAsync();
}
@@ -585,11 +639,16 @@ namespace Content.IntegrationTests.Tests.Power
[Test]
public async Task TestFullBattery()
{
await using var pairTracker = await PoolManager.GetServerClient(new PoolSettings{NoClient = true, ExtraPrototypes = Prototypes});
await using var pairTracker = await PoolManager.GetServerClient(new PoolSettings
{
NoClient = true,
ExtraPrototypes = Prototypes
});
var server = pairTracker.Pair.Server;
var mapManager = server.ResolveDependency<IMapManager>();
var entityManager = server.ResolveDependency<IEntityManager>();
var gameTiming = server.ResolveDependency<IGameTiming>();
var batterySys = entityManager.System<BatterySystem>();
PowerConsumerComponent consumer = default!;
PowerSupplierComponent supplier = default!;
PowerNetworkBatteryComponent netBattery = default!;
@@ -627,8 +686,8 @@ namespace Content.IntegrationTests.Tests.Power
netBattery.MaxSupply = 400;
netBattery.SupplyRampTolerance = 400;
netBattery.SupplyRampRate = 100_000;
battery.MaxCharge = 100_000;
battery.CurrentCharge = 100_000;
batterySys.SetMaxCharge(batteryEnt, 100_000, battery);
batterySys.SetCharge(batteryEnt, 100_000, battery);
});
// Run some ticks so everything is stable.
@@ -639,6 +698,8 @@ namespace Content.IntegrationTests.Tests.Power
var tickDev = 400 * tickPeriod * 1.1f;
await server.WaitAssertion(() =>
{
Assert.Multiple(() =>
{
Assert.That(consumer.ReceivedPower, Is.EqualTo(consumer.DrawRate).Within(0.1));
Assert.That(supplier.CurrentSupply, Is.EqualTo(supplier.MaxSupply).Within(0.1));
@@ -651,6 +712,7 @@ namespace Content.IntegrationTests.Tests.Power
const int expectedSpent = 200;
Assert.That(battery.CurrentCharge, Is.EqualTo(battery.MaxCharge - expectedSpent).Within(tickDev));
});
});
await pairTracker.CleanReturnAsync();
}
@@ -658,11 +720,16 @@ namespace Content.IntegrationTests.Tests.Power
[Test]
public async Task TestFullBatteryEfficiencyPassThrough()
{
await using var pairTracker = await PoolManager.GetServerClient(new PoolSettings{NoClient = true, ExtraPrototypes = Prototypes});
await using var pairTracker = await PoolManager.GetServerClient(new PoolSettings
{
NoClient = true,
ExtraPrototypes = Prototypes
});
var server = pairTracker.Pair.Server;
var mapManager = server.ResolveDependency<IMapManager>();
var entityManager = server.ResolveDependency<IEntityManager>();
var gameTiming = server.ResolveDependency<IGameTiming>();
var batterySys = entityManager.System<BatterySystem>();
PowerConsumerComponent consumer = default!;
PowerSupplierComponent supplier = default!;
PowerNetworkBatteryComponent netBattery = default!;
@@ -702,8 +769,8 @@ namespace Content.IntegrationTests.Tests.Power
netBattery.SupplyRampTolerance = 400;
netBattery.SupplyRampRate = 100_000;
netBattery.Efficiency = 0.5f;
battery.MaxCharge = 1_000_000;
battery.CurrentCharge = 1_000_000;
batterySys.SetMaxCharge(batteryEnt, 1_000_000, battery);
batterySys.SetCharge(batteryEnt, 1_000_000, battery);
});
// Run some ticks so everything is stable.
@@ -714,6 +781,8 @@ namespace Content.IntegrationTests.Tests.Power
var tickDev = 400 * tickPeriod * 1.1f;
await server.WaitAssertion(() =>
{
Assert.Multiple(() =>
{
Assert.That(consumer.ReceivedPower, Is.EqualTo(600).Within(0.1));
Assert.That(supplier.CurrentSupply, Is.EqualTo(supplier.MaxSupply).Within(0.1));
@@ -724,6 +793,7 @@ namespace Content.IntegrationTests.Tests.Power
const int expectedSpent = 400;
Assert.That(battery.CurrentCharge, Is.EqualTo(battery.MaxCharge - expectedSpent).Within(tickDev));
});
});
await pairTracker.CleanReturnAsync();
}
@@ -731,10 +801,15 @@ namespace Content.IntegrationTests.Tests.Power
[Test]
public async Task TestFullBatteryEfficiencyDemandPassThrough()
{
await using var pairTracker = await PoolManager.GetServerClient(new PoolSettings{NoClient = true, ExtraPrototypes = Prototypes});
await using var pairTracker = await PoolManager.GetServerClient(new PoolSettings
{
NoClient = true,
ExtraPrototypes = Prototypes
});
var server = pairTracker.Pair.Server;
var mapManager = server.ResolveDependency<IMapManager>();
var entityManager = server.ResolveDependency<IEntityManager>();
var batterySys = entityManager.System<BatterySystem>();
PowerConsumerComponent consumer1 = default!;
PowerConsumerComponent consumer2 = default!;
PowerSupplierComponent supplier = default!;
@@ -788,8 +863,8 @@ namespace Content.IntegrationTests.Tests.Power
supplier.MaxSupply = 1000;
supplier.SupplyRampTolerance = 1000;
battery1.MaxCharge = 1_000_000;
battery2.MaxCharge = 1_000_000;
batterySys.SetMaxCharge(batteryEnt1, 1_000_000, battery1);
batterySys.SetMaxCharge(batteryEnt2, 1_000_000, battery2);
netBattery1.MaxChargeRate = 1_000;
netBattery2.MaxChargeRate = 1_000;
@@ -807,11 +882,14 @@ namespace Content.IntegrationTests.Tests.Power
server.RunTicks(10);
await server.WaitAssertion(() =>
{
Assert.Multiple(() =>
{
Assert.That(consumer1.ReceivedPower, Is.EqualTo(250).Within(0.1));
Assert.That(consumer2.ReceivedPower, Is.EqualTo(500).Within(0.1));
Assert.That(supplier.CurrentSupply, Is.EqualTo(supplier.MaxSupply).Within(0.1));
});
});
await pairTracker.CleanReturnAsync();
}
@@ -828,6 +906,7 @@ namespace Content.IntegrationTests.Tests.Power
var mapManager = server.ResolveDependency<IMapManager>();
var entityManager = server.ResolveDependency<IEntityManager>();
var gameTiming = server.ResolveDependency<IGameTiming>();
var batterySys = entityManager.System<BatterySystem>();
PowerConsumerComponent consumer = default!;
PowerSupplierComponent supplier1 = default!;
PowerSupplierComponent supplier2 = default!;
@@ -887,16 +966,18 @@ namespace Content.IntegrationTests.Tests.Power
netBattery2.SupplyRampTolerance = 1000;
netBattery1.SupplyRampRate = 100_000;
netBattery2.SupplyRampRate = 100_000;
battery1.MaxCharge = 100_000;
battery2.MaxCharge = 100_000;
battery1.CurrentCharge = 100_000;
battery2.CurrentCharge = 100_000;
batterySys.SetMaxCharge(batteryEnt1, 100_000, battery1);
batterySys.SetMaxCharge(batteryEnt2, 100_000, battery2);
batterySys.SetCharge(batteryEnt1, 100_000, battery1);
batterySys.SetCharge(batteryEnt2, 100_000, battery2);
});
// Run some ticks so everything is stable.
server.RunTicks(60);
await server.WaitAssertion(() =>
{
Assert.Multiple(() =>
{
Assert.That(consumer.ReceivedPower, Is.EqualTo(consumer.DrawRate).Within(0.1));
Assert.That(supplier1.CurrentSupply, Is.EqualTo(supplier1.MaxSupply).Within(0.1));
@@ -907,6 +988,7 @@ namespace Content.IntegrationTests.Tests.Power
Assert.That(netBattery2.SupplyRampPosition, Is.EqualTo(500).Within(0.1));
Assert.That(netBattery2.SupplyRampPosition, Is.EqualTo(500).Within(0.1));
});
});
await pairTracker.CleanReturnAsync();
}
@@ -917,10 +999,15 @@ namespace Content.IntegrationTests.Tests.Power
[Test]
public async Task TestBatteriesProportional()
{
await using var pairTracker = await PoolManager.GetServerClient(new PoolSettings{NoClient = true, ExtraPrototypes = Prototypes});
await using var pairTracker = await PoolManager.GetServerClient(new PoolSettings
{
NoClient = true,
ExtraPrototypes = Prototypes
});
var server = pairTracker.Pair.Server;
var mapManager = server.ResolveDependency<IMapManager>();
var entityManager = server.ResolveDependency<IEntityManager>();
var batterySys = entityManager.System<BatterySystem>();
PowerConsumerComponent consumer1 = default!;
PowerConsumerComponent consumer2 = default!;
PowerSupplierComponent supplier = default!;
@@ -968,8 +1055,8 @@ namespace Content.IntegrationTests.Tests.Power
supplier.MaxSupply = 1000;
supplier.SupplyRampTolerance = 1000;
battery1.MaxCharge = 1_000_000;
battery2.MaxCharge = 1_000_000;
batterySys.SetMaxCharge(batteryEnt1, 1_000_000, battery1);
batterySys.SetMaxCharge(batteryEnt2, 1_000_000, battery2);
netBattery1.MaxChargeRate = 20;
netBattery2.MaxChargeRate = 20;
@@ -985,6 +1072,8 @@ namespace Content.IntegrationTests.Tests.Power
server.RunTicks(60);
await server.WaitAssertion(() =>
{
Assert.Multiple(() =>
{
// NOTE: MaxChargeRate on batteries actually skews the demand.
// So that's why the tolerance is so high, the charge rate is so *low*,
@@ -993,6 +1082,7 @@ namespace Content.IntegrationTests.Tests.Power
Assert.That(consumer2.ReceivedPower, Is.EqualTo(666.666).Within(10));
Assert.That(supplier.CurrentSupply, Is.EqualTo(supplier.MaxSupply).Within(0.1));
});
});
await pairTracker.CleanReturnAsync();
}
@@ -1000,10 +1090,15 @@ namespace Content.IntegrationTests.Tests.Power
[Test]
public async Task TestBatteryEngineCut()
{
await using var pairTracker = await PoolManager.GetServerClient(new PoolSettings{NoClient = true, ExtraPrototypes = Prototypes});
await using var pairTracker = await PoolManager.GetServerClient(new PoolSettings
{
NoClient = true,
ExtraPrototypes = Prototypes
});
var server = pairTracker.Pair.Server;
var mapManager = server.ResolveDependency<IMapManager>();
var entityManager = server.ResolveDependency<IEntityManager>();
var batterySys = entityManager.System<BatterySystem>();
PowerConsumerComponent consumer = default!;
PowerSupplierComponent supplier = default!;
PowerNetworkBatteryComponent netBattery = default!;
@@ -1039,18 +1134,21 @@ namespace Content.IntegrationTests.Tests.Power
netBattery.MaxSupply = 1000;
netBattery.SupplyRampTolerance = 200;
netBattery.SupplyRampRate = 10;
battery.MaxCharge = 100_000;
battery.CurrentCharge = 100_000;
batterySys.SetMaxCharge(batteryEnt, 100_000, battery);
batterySys.SetCharge(batteryEnt, 100_000, battery);
});
// Run some ticks so everything is stable.
server.RunTicks(5);
await server.WaitAssertion(() =>
{
Assert.Multiple(() =>
{
// Supply and consumer are fully loaded/supplied.
Assert.That(consumer.ReceivedPower, Is.EqualTo(consumer.DrawRate).Within(0.5));
Assert.That(supplier.CurrentSupply, Is.EqualTo(supplier.MaxSupply).Within(0.5));
});
// Cut off the supplier
supplier.Enabled = false;
@@ -1061,12 +1159,15 @@ namespace Content.IntegrationTests.Tests.Power
server.RunTicks(3);
await server.WaitAssertion(() =>
{
Assert.Multiple(() =>
{
// Assert that network drops to 0 power and starts ramping up
Assert.That(consumer.ReceivedPower, Is.LessThan(50).And.GreaterThan(0));
Assert.That(netBattery.CurrentReceiving, Is.EqualTo(0));
Assert.That(netBattery.CurrentSupply, Is.GreaterThan(0));
});
});
await pairTracker.CleanReturnAsync();
}
@@ -1077,11 +1178,15 @@ namespace Content.IntegrationTests.Tests.Power
[Test]
public async Task TestTerminalNodeGroups()
{
await using var pairTracker = await PoolManager.GetServerClient(new PoolSettings{NoClient = true, ExtraPrototypes = Prototypes});
await using var pairTracker = await PoolManager.GetServerClient(new PoolSettings
{
NoClient = true,
ExtraPrototypes = Prototypes
});
var server = pairTracker.Pair.Server;
var mapManager = server.ResolveDependency<IMapManager>();
var entityManager = server.ResolveDependency<IEntityManager>();
var _nodeContainer = entityManager.System<NodeContainerSystem>();
var nodeContainer = entityManager.System<NodeContainerSystem>();
CableNode leftNode = default!;
CableNode rightNode = default!;
Node batteryInput = default!;
@@ -1109,16 +1214,16 @@ namespace Content.IntegrationTests.Tests.Power
var battery = entityManager.SpawnEntity("FullBatteryDummy", grid.ToCoordinates(0, 2));
var batteryNodeContainer = entityManager.GetComponent<NodeContainerComponent>(battery);
if (_nodeContainer.TryGetNode<CableNode>(entityManager.GetComponent<NodeContainerComponent>(leftEnt),
if (nodeContainer.TryGetNode<CableNode>(entityManager.GetComponent<NodeContainerComponent>(leftEnt),
"power", out var leftN))
leftNode = leftN;
if (_nodeContainer.TryGetNode<CableNode>(entityManager.GetComponent<NodeContainerComponent>(rightEnt),
if (nodeContainer.TryGetNode<CableNode>(entityManager.GetComponent<NodeContainerComponent>(rightEnt),
"power", out var rightN))
rightNode = rightN;
if (_nodeContainer.TryGetNode<Node>(batteryNodeContainer, "input", out var nInput))
if (nodeContainer.TryGetNode<Node>(batteryNodeContainer, "input", out var nInput))
batteryInput = nInput;
if (_nodeContainer.TryGetNode<Node>(batteryNodeContainer, "output", out var nOutput))
if (nodeContainer.TryGetNode<Node>(batteryNodeContainer, "output", out var nOutput))
batteryOutput = nOutput;
});
@@ -1126,12 +1231,15 @@ namespace Content.IntegrationTests.Tests.Power
server.RunTicks(1);
await server.WaitAssertion(() =>
{
Assert.Multiple(() =>
{
Assert.That(batteryInput.NodeGroup, Is.EqualTo(leftNode.NodeGroup));
Assert.That(batteryOutput.NodeGroup, Is.EqualTo(rightNode.NodeGroup));
Assert.That(leftNode.NodeGroup, Is.Not.EqualTo(rightNode.NodeGroup));
});
});
await pairTracker.CleanReturnAsync();
}
@@ -1139,10 +1247,15 @@ namespace Content.IntegrationTests.Tests.Power
[Test]
public async Task ApcChargingTest()
{
await using var pairTracker = await PoolManager.GetServerClient(new PoolSettings{NoClient = true, ExtraPrototypes = Prototypes});
await using var pairTracker = await PoolManager.GetServerClient(new PoolSettings
{
NoClient = true,
ExtraPrototypes = Prototypes
});
var server = pairTracker.Pair.Server;
var mapManager = server.ResolveDependency<IMapManager>();
var entityManager = server.ResolveDependency<IEntityManager>();
var batterySys = entityManager.System<BatterySystem>();
PowerNetworkBatteryComponent substationNetBattery = default!;
BatteryComponent apcBattery = default!;
@@ -1173,16 +1286,19 @@ namespace Content.IntegrationTests.Tests.Power
generatorSupplier.MaxSupply = 1000;
generatorSupplier.SupplyRampTolerance = 1000;
apcBattery.CurrentCharge = 0;
batterySys.SetCharge(apcEnt, 0, apcBattery);
});
server.RunTicks(5); //let run a few ticks for PowerNets to reevaluate and start charging apc
await server.WaitAssertion(() =>
{
Assert.Multiple(() =>
{
Assert.That(substationNetBattery.CurrentSupply, Is.GreaterThan(0)); //substation should be providing power
Assert.That(apcBattery.CurrentCharge, Is.GreaterThan(0)); //apc battery should have gained charge
});
});
await pairTracker.CleanReturnAsync();
}
@@ -1190,11 +1306,16 @@ namespace Content.IntegrationTests.Tests.Power
[Test]
public async Task ApcNetTest()
{
await using var pairTracker = await PoolManager.GetServerClient(new PoolSettings{NoClient = true, ExtraPrototypes = Prototypes});
await using var pairTracker = await PoolManager.GetServerClient(new PoolSettings
{
NoClient = true,
ExtraPrototypes = Prototypes
});
var server = pairTracker.Pair.Server;
var mapManager = server.ResolveDependency<IMapManager>();
var entityManager = server.ResolveDependency<IEntityManager>();
var extensionCableSystem = entityManager.EntitySysManager.GetEntitySystem<ExtensionCableSystem>();
var batterySys = entityManager.System<BatterySystem>();
var extensionCableSystem = entityManager.System<ExtensionCableSystem>();
PowerNetworkBatteryComponent apcNetBattery = default!;
ApcPowerReceiverComponent receiver = default!;
ApcPowerReceiverComponent unpoweredReceiver = default!;
@@ -1229,15 +1350,16 @@ namespace Content.IntegrationTests.Tests.Power
extensionCableSystem.SetProviderTransferRange(apcExtensionEnt, range);
extensionCableSystem.SetReceiverReceptionRange(powerReceiverEnt, range);
battery.MaxCharge = 10000; //arbitrary nonzero amount of charge
battery.CurrentCharge = battery.MaxCharge; //fill battery
batterySys.SetMaxCharge(apcEnt, 10000, battery); //arbitrary nonzero amount of charge
batterySys.SetCharge(apcEnt, battery.MaxCharge, battery); //fill battery
receiver.Load = 1; //arbitrary small amount of power
});
server.RunTicks(1); //let run a tick for ApcNet to process power
await server.WaitAssertion(() => {
await server.WaitAssertion(() =>
{
Assert.Multiple(() =>
{
Assert.That(receiver.Powered, "Receiver in range should be powered");

View File

@@ -1,8 +1,6 @@
using System.Collections.Generic;
using System.Threading.Tasks;
using Content.Server.Procedural;
using Content.Shared.Procedural;
using NUnit.Framework;
using Robust.Shared.Maths;
using Robust.Shared.Prototypes;
@@ -14,7 +12,7 @@ public sealed class DungeonTests
[Test]
public async Task TestDungeonRoomPackBounds()
{
await using var pairTracker = await PoolManager.GetServerClient(new PoolSettings{NoClient = true});
await using var pairTracker = await PoolManager.GetServerClient(new PoolSettings { NoClient = true });
var protoManager = pairTracker.Pair.Server.ResolveDependency<IPrototypeManager>();
await pairTracker.Pair.Server.WaitAssertion(() =>
@@ -64,7 +62,7 @@ public sealed class DungeonTests
[Test]
public async Task TestDungeonPresets()
{
await using var pairTracker = await PoolManager.GetServerClient(new PoolSettings{NoClient = true});
await using var pairTracker = await PoolManager.GetServerClient(new PoolSettings { NoClient = true });
var protoManager = pairTracker.Pair.Server.ResolveDependency<IPrototypeManager>();
await pairTracker.Pair.Server.WaitAssertion(() =>
@@ -86,9 +84,11 @@ public sealed class DungeonTests
// Assert that anything exists at this size
var rotated = new Vector2i(pack.Size.Y, pack.Size.X);
Assert.Multiple(() =>
{
Assert.That(sizes.Contains(pack.Size) || sizes.Contains(rotated), $"Didn't find any dungeon room prototypes for {pack.Size} for {preset.ID} index {i}");
Assert.That(pack.Bottom, Is.GreaterThanOrEqualTo(0), "All dungeon room packs need their y-axis to be above 0!");
});
}
}
});

Some files were not shown because too many files have changed in this diff Show More