Files

222 lines
11 KiB
C#

using System;
using System.IO;
using NUnit.Framework;
namespace Ironspore.Tests
{
public sealed class ProfileStoreTests
{
string folder;
string path;
ProfileStore store;
[SetUp]
public void Setup()
{
folder = Path.Combine(Path.GetTempPath(), "IronsporeLedgerTests", Guid.NewGuid().ToString("N"));
path = Path.Combine(folder, "profile.json");
store = new ProfileStore(path);
Assert.IsTrue(store.Begin(1, new[] { 0, 0, 0, 0 }, 180, 7));
}
[TearDown]
public void Cleanup()
{
string allowed = Path.GetFullPath(Path.Combine(Path.GetTempPath(), "IronsporeLedgerTests")) + Path.DirectorySeparatorChar;
if (Path.GetFullPath(folder).StartsWith(allowed, StringComparison.OrdinalIgnoreCase) && Directory.Exists(folder))
Directory.Delete(folder, true);
}
[Test]
public void PodBanksOnceAndSurvivesDeathAndReload()
{
Assert.IsTrue(store.AddCargo("blueprint_vector", 1, "crateA"));
Assert.IsTrue(store.AddCargo("alloy", 4, "crateB"));
string uid = store.Data.run.cargo[0].uid;
Assert.IsTrue(store.SendCargo(new[] { uid }));
Assert.IsFalse(store.SendCargo(new[] { uid }));
Assert.IsTrue(store.Finish(true));
var loaded = new ProfileStore(path);
Assert.AreEqual(1, loaded.Data.blueprints.Count);
Assert.AreEqual(0, loaded.Data.alloy);
Assert.IsFalse(loaded.Data.run.active);
Assert.IsTrue(loaded.Data.run.podUsed);
}
[Test]
public void PodRejectsOvercapacityAndDuplicateSelectionsWithoutConsuming()
{
for (int i = 0; i < 5; i++)
Assert.IsTrue(store.AddCargo("blueprint_" + i, 1, "crate" + i));
var bag = store.Data.run.cargo;
Assert.IsFalse(store.SendCargo(new[] { bag[0].uid, bag[1].uid, bag[2].uid, bag[3].uid, bag[4].uid }));
Assert.IsFalse(store.SendCargo(new[] { bag[0].uid, bag[0].uid }));
Assert.IsFalse(store.Data.run.podUsed);
Assert.AreEqual(5, store.Data.run.cargo.Count);
Assert.AreEqual(0, store.Data.blueprints.Count);
Assert.IsTrue(store.SendCargo(new[] { bag[0].uid, bag[1].uid, bag[2].uid, bag[3].uid }));
}
[Test]
public void SearchedSourceCannotDuplicateLootAfterReload()
{
Assert.IsTrue(store.AddCargo("alloy", 5, "crateA"));
store = new ProfileStore(path);
Assert.IsFalse(store.AddCargo("alloy", 5, "crateA"));
Assert.AreEqual(5, store.Data.run.cargo[0].count);
Assert.IsTrue(store.Finish(false));
Assert.IsFalse(store.Finish(false));
Assert.AreEqual(5, store.Data.alloy);
Assert.AreEqual(1, store.Data.extractions);
}
[Test]
public void CargoThenWholeMechReturnAreIndependentReceipts()
{
store.AddCargo("alloy", 4);
store.AddCargo("cells", 3);
Assert.IsTrue(store.SendCargo(new[] { store.Data.run.cargo[0].uid }));
Assert.IsTrue(store.CompleteRoute());
Assert.IsFalse(store.CompleteRoute());
Assert.IsTrue(store.Finish(false));
Assert.AreEqual(4, store.Data.alloy);
Assert.AreEqual(3, store.Data.cells);
Assert.AreEqual(1, store.Data.completed);
Assert.AreEqual(1, store.Data.extractions);
}
[Test]
public void SafeCaseChecksShapeAndPersistsRotatedWeapon()
{
Assert.IsFalse(store.Uninstall(0, Hold.SafeCase, 0, 0, false));
Assert.IsFalse(store.Uninstall(0, Hold.SafeCase, 0, 0, true));
Assert.IsTrue(store.AddCargo("cells", 1));
Assert.IsTrue(store.MoveItem(store.Data.run.cargo[0].uid, Hold.Cargo, Hold.SafeCase, 0, 1));
string weapon = store.Data.run.installed.Find(i => i.itemId == "guided").uid;
Assert.IsFalse(store.Uninstall(1, Hold.SafeCase, 0, 0, false));
Assert.IsTrue(store.Uninstall(1, Hold.SafeCase, 0, 0, true));
store = new ProfileStore(path);
var saved = store.Data.run.safeCase.Find(i => i.uid == weapon);
Assert.IsTrue(saved.rotated);
Assert.AreEqual(0, saved.x);
Assert.AreEqual(0, saved.y);
Assert.AreEqual(-1, store.Data.run.equipment[1]);
Assert.IsTrue(store.Finish(false));
Assert.IsTrue(store.Begin(1, new[] { 0, 0, 0, 0 }, 180, 8));
Assert.IsTrue(store.Data.run.installed.Exists(i => i.uid == weapon));
Assert.IsFalse(store.Data.warehouse.Exists(i => i.uid == weapon));
}
[Test]
public void DeathLocksInventoryAndRetriesOnlyTheProtectedReturn()
{
string run = store.Data.run.id;
Assert.IsTrue(store.AddCargo("alloy", 4, "a", "pulse"));
string pulse = store.Data.run.cargo.Find(i => i.itemId == "pulse").uid;
Assert.IsTrue(store.MoveItem(pulse, Hold.Cargo, Hold.SafeCase));
Assert.IsTrue(store.SendCargo(new[] { store.Data.run.cargo[0].uid }));
Assert.IsTrue(store.AddCargo("coil", 1, "b"));
Assert.IsTrue(store.MarkDestroyed());
store = new ProfileStore(path);
Assert.IsFalse(store.MoveItem(pulse, Hold.SafeCase, Hold.Cargo));
Assert.IsFalse(store.Finish(false));
Directory.CreateDirectory(path + ".tmp");
Assert.IsFalse(store.Finish(true));
Assert.IsTrue(store.Data.run.destructionPending);
Assert.AreEqual(0, store.Data.warehouse.Count);
Directory.Delete(path + ".tmp");
store = new ProfileStore(path);
Assert.IsTrue(store.Finish(true));
Assert.IsFalse(store.Finish(true));
Assert.AreEqual(4, store.Data.alloy);
Assert.AreEqual(1, store.Data.warehouse.Count);
Assert.AreEqual(pulse, store.Data.warehouse[0].uid);
CollectionAssert.AreEquivalent(new[] { run + ":secure_eject", run + ":cargo", run + ":return" }, store.Data.receipts);
}
[Test]
public void SplitMergeSwapAndAtomicPlacementPreserveOwnership()
{
Assert.IsTrue(store.AddCargo("cells", 10));
string cells = store.Data.run.cargo[0].uid;
Assert.IsTrue(store.MoveItem(cells, Hold.Cargo, Hold.SafeCase, 1, 1, false, 4));
string split = store.Data.run.safeCase[0].uid;
Assert.AreNotEqual(cells, split);
Assert.IsFalse(store.MergeMaterial(cells, Hold.Cargo, split, Hold.SafeCase, 7));
Assert.IsTrue(store.MergeMaterial(cells, Hold.Cargo, split, Hold.SafeCase, 2));
Assert.IsTrue(store.AddCargo("rapid", 1));
string rapid = store.Data.run.cargo.Find(i => i.itemId == "rapid").uid;
Assert.IsFalse(store.SwapItems(rapid, Hold.Cargo, split, Hold.SafeCase, true));
Assert.IsTrue(store.SwapItems(cells, Hold.Cargo, split, Hold.SafeCase, false));
Assert.IsFalse(store.MoveItem(rapid, Hold.Cargo, Hold.SafeCase));
Assert.IsTrue(store.Finish(true));
Assert.AreEqual(4, store.Data.cells);
}
[Test]
public void FailedRefitOrWriteKeepsOldSlotAndLootSource()
{
Assert.IsTrue(store.AddCargo("alloy", 1, "crate", "coil"));
string uid = store.Data.run.cargo.Find(i => i.itemId == "coil").uid;
Assert.IsFalse(store.InstallItem(uid, Hold.Cargo, parts => false));
Assert.AreEqual(0, store.Data.run.equipment[0]);
Directory.CreateDirectory(path + ".tmp");
Assert.IsFalse(store.Uninstall(1, Hold.SafeCase, 0, 0, false));
Assert.IsFalse(store.AddCargo("alloy", 1, "retry"));
Assert.IsFalse(store.Data.run.searched.Contains("retry"));
Directory.Delete(path + ".tmp");
Assert.IsTrue(store.InstallItem(uid, Hold.Cargo, parts => true));
Assert.AreEqual(1, store.Data.run.equipment[0]);
Assert.IsTrue(store.Data.run.cargo.Exists(i => i.itemId == "rapid"));
Assert.IsTrue(store.Data.run.installed.Exists(i => i.uid == uid));
}
[Test]
public void BorrowedStarterDoesNotReplaceLostStock()
{
Assert.IsTrue(store.Finish(true));
Assert.IsFalse(store.Begin(1, new[] { 1, 0, 0, 0 }, 180, 8));
Assert.IsTrue(store.Begin(1, new[] { 0, 0, 0, 0 }, 180, 8));
Assert.IsTrue(store.Data.run.installed.TrueForAll(i => i.borrowed));
Assert.IsTrue(store.Uninstall(1, Hold.SafeCase, 0, 0, false));
Assert.IsTrue(store.Finish(false));
Assert.IsEmpty(store.Data.warehouse);
}
[Test]
public void ManufacturingRequiresResearchAndMaterialsAndCreatesDistinctInstances()
{
Assert.IsTrue(store.Finish(false));
const string blueprint = "blueprint_coil_capacitor";
Assert.IsTrue(store.Commit(s => { s.alloy = 8; s.cells = 4; return true; }));
Assert.IsFalse(store.Manufacture(blueprint));
Assert.IsTrue(store.Commit(s => { s.unlocked.Add(blueprint); return true; }));
Assert.IsTrue(store.Manufacture(blueprint));
Assert.IsTrue(store.Manufacture(blueprint));
Assert.IsFalse(store.Manufacture(blueprint));
var copies = store.Data.warehouse.FindAll(i => i.itemId == "coil");
Assert.AreNotEqual(copies[0].uid, copies[1].uid);
Assert.IsTrue(store.Begin(1, new[] { 1, 0, 0, 0 }, 180, 8, selected: new[] { copies[1].uid, null, null, null }));
Assert.IsTrue(store.Data.run.installed.Exists(i => i.uid == copies[1].uid));
Assert.IsTrue(store.Finish(true));
Assert.IsTrue(store.Data.warehouse.Exists(i => i.uid == copies[0].uid));
Assert.AreEqual(0, store.Data.alloy);
Assert.AreEqual(0, store.Data.cells);
}
[Test]
public void WriteFailureLeavesOriginalMemoryState()
{
string blocker = Path.Combine(folder, "blocked");
File.WriteAllText(blocker, "not a directory");
var unavailable = new ProfileStore(Path.Combine(blocker, "save.json"));
Assert.IsFalse(unavailable.Begin(0, new[] { 0, 0, 0, 0 }, 100, 1));
Assert.IsFalse(unavailable.Data.run.active);
Assert.IsNotEmpty(unavailable.Error);
}
[Test]
public void CorruptPrimaryRecoversPreviousCompleteSnapshot()
{
store.AddCargo("cells", 2);
store.Commit(s => true);
File.WriteAllText(path, "{broken json");
var recovered = new ProfileStore(path);
Assert.IsTrue(recovered.Data.run.active);
Assert.AreEqual(2, recovered.Data.run.cargo[0].count);
}
}
}