Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Upgrade tree testability refactor #412

Merged
merged 2 commits into from
Nov 16, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -16,35 +16,43 @@ namespace ElectronicObserver.Window.Tools.EquipmentUpgradePlanner.UpgradeTree;

public partial class UpgradeTreeUpgradePlanViewModel : ObservableObject
{
public string DisplayName => Plan switch
public EquipmentId EquipmentId => Plan.EquipmentMasterDataId;

public int Count => Plan switch
{
EquipmentUpgradePlanItemViewModel plan =>
$"{RequiredCount}x {plan.EquipmentName} ({Translations.Goal}: {plan.DesiredUpgradeLevel.Display()})",
EquipmentConversionPlanItemViewModel conversion => $"{conversion.EquipmentRequiredForUpgradePlan.Count}x {Plan.EquipmentMasterData?.NameEN}",
not null => $"{RequiredCount}x {Plan.EquipmentMasterData?.NameEN}",
_ => ""
EquipmentUpgradePlanItemViewModel => RequiredCount,
EquipmentConversionPlanItemViewModel conversion => conversion.EquipmentRequiredForUpgradePlan.Count,
EquipmentCraftPlanItemViewModel => RequiredCount,

_ => throw new NotImplementedException(),
};

public EquipmentUpgradePlanCostViewModel? Cost =>
Plan?.Cost.Model is null or { Fuel: 0, Ammo: 0, Steel: 0, Bauxite: 0 } ? null : Plan.Cost;
public string DisplayName => Plan switch
{
EquipmentUpgradePlanItemViewModel plan => $"{Count}x {plan.EquipmentName} ({Translations.Goal}: {plan.DesiredUpgradeLevel.Display()})",
EquipmentConversionPlanItemViewModel => $"{Count}x {Plan.EquipmentMasterData?.NameEN}",
EquipmentCraftPlanItemViewModel => $"{Count}x {Plan.EquipmentMasterData?.NameEN}",

_ => throw new NotImplementedException(),
};

public UpgradeTreeViewNodeState State => Plan switch
public EquipmentUpgradePlanCostViewModel? Cost => Plan.Cost.Model switch
{
not null => UpgradeTreeViewNodeState.Planned,
_ => UpgradeTreeViewNodeState.ToCraft
{ Fuel: 0, Ammo: 0, Steel: 0, Bauxite: 0 } => null,
_ => Plan.Cost,
};

public bool CanBePlanned => Plan switch
{
EquipmentUpgradePlanItemViewModel plan => !EquipmentUpgradePlanManager.PlannedUpgrades.Contains(plan),
_ => false
_ => false,
};

public bool AlreadyPlanned => Plan is EquipmentUpgradePlanItemViewModel plan && EquipmentUpgradePlanManager.PlannedUpgrades.Contains(plan);

public IEquipmentPlanItemViewModel? Plan { get; private set; }
private IEquipmentPlanItemViewModel Plan { get; set; }

public int RequiredCount { get; }
private int RequiredCount { get; }

private EquipmentUpgradeData EquipmentUpgradeData { get; }

Expand Down Expand Up @@ -102,15 +110,15 @@ public void CleanupUnusedPlan()
}
else
{
Plan?.UnsubscribeFromApis();
Plan.UnsubscribeFromApis();
}

foreach (UpgradeTreeUpgradePlanViewModel child in Children)
{
child.CleanupUnusedPlan();
}
}

private void InitializeFromConversion(EquipmentUpgradePlanItemViewModel plan)
{
Children.Add(new UpgradeTreeUpgradePlanViewModel(plan, 1));
Expand Down Expand Up @@ -152,10 +160,10 @@ private void AddUpgradedEquipmentNodeIfNeeded(EquipmentUpgradePlanItemViewModel
newChild.ShouldBeConvertedInto = plan.EquipmentMasterDataId;
children.Add(newChild);
}

foreach (EquipmentUpgradePlanItemViewModel child in children)
{
Children.Add(new UpgradeTreeUpgradePlanViewModel(new EquipmentConversionPlanItemViewModel(plan, new List<EquipmentUpgradePlanItemViewModel>{ child })));
Children.Add(new UpgradeTreeUpgradePlanViewModel(new EquipmentConversionPlanItemViewModel(plan, new List<EquipmentUpgradePlanItemViewModel> { child })));
}
}
else
Expand All @@ -167,7 +175,7 @@ private void AddUpgradedEquipmentNodeIfNeeded(EquipmentUpgradePlanItemViewModel
private UpgradeTreeUpgradePlanViewModel InitializeEquipmentPlanChild(EquipmentUpgradePlanItemViewModel plan, int required, EquipmentId equipment)
{
// if fodder = upgraded equipment, return a craft plan to avoid infinite loops
if (equipment == Plan?.EquipmentMasterDataId && plan.ShouldBeConvertedInto == equipment)
if (equipment == Plan.EquipmentMasterDataId && plan.ShouldBeConvertedInto == equipment)
{
return new UpgradeTreeUpgradePlanViewModel(new EquipmentCraftPlanItemViewModel(equipment), required);
}
Expand Down Expand Up @@ -204,8 +212,8 @@ private UpgradeTreeUpgradePlanViewModel InitializeEquipmentPlanChild(EquipmentUp
private EquipmentUpgradeDataModel? GetPlanToMakeEquipmentFromUpgrade(EquipmentId equipment)
{
EquipmentUpgradeDataModel? upgradePlan = EquipmentUpgradeData.UpgradeList
.FirstOrDefault(equipmentData => equipmentData.ConvertTo
.Any(equipmentAfterConvertion =>
.Find(equipmentData => equipmentData.ConvertTo
.Exists(equipmentAfterConvertion =>
equipmentAfterConvertion.IdEquipmentAfter == (int)equipment));

return upgradePlan;
Expand All @@ -214,12 +222,10 @@ private UpgradeTreeUpgradePlanViewModel InitializeEquipmentPlanChild(EquipmentUp
[RelayCommand]
private void AddEquipmentPlan()
{
if (Plan is null) return;

EquipmentUpgradePlanItemViewModel newPlan = Plan switch
{
EquipmentUpgradePlanItemViewModel plan => plan,
_ => throw new NotImplementedException()
_ => throw new NotImplementedException(),
};

if (!newPlan.OpenPlanDialog()) return;
Expand Down

This file was deleted.

192 changes: 168 additions & 24 deletions ElectronicObserverCoreTests/UpgradeTreeTests.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using System;
using System.Linq;
using System.Linq;
using ElectronicObserver.Window.Tools.EquipmentUpgradePlanner;
using ElectronicObserver.Window.Tools.EquipmentUpgradePlanner.UpgradeTree;
using ElectronicObserverTypes;
Expand All @@ -9,49 +8,194 @@ namespace ElectronicObserverCoreTests;

public class UpgradeTreeTests
{
private static int GetCount(UpgradeTreeUpgradePlanViewModel plan) => plan.Plan switch
{
EquipmentUpgradePlanItemViewModel => plan.RequiredCount,
EquipmentConversionPlanItemViewModel conversion => conversion.EquipmentRequiredForUpgradePlan.Count,
EquipmentCraftPlanItemViewModel => plan.RequiredCount,

_ => throw new NotImplementedException(),
};

[Fact(DisplayName = "S-51J kai example")]
public void UpgradeTreeTest1()
private static UpgradeTreeViewModel MakeUpgradeTree(EquipmentId equipmentId, UpgradeLevel upgradeLevel)
{
EquipmentUpgradePlanItemModel upgradePlan = new()
{
EquipmentId = EquipmentId.Autogyro_S51JKai,
DesiredUpgradeLevel = UpgradeLevel.Max,
EquipmentId = equipmentId,
DesiredUpgradeLevel = upgradeLevel,
};

EquipmentUpgradePlanItemViewModel upgradePlanViewModel = new(upgradePlan);
upgradePlanViewModel.UpdateCosts();

UpgradeTreeViewModel tree = new(upgradePlanViewModel);
return new(upgradePlanViewModel);
}

[Fact(DisplayName = "S-51J kai max")]
public void UpgradeTreeTest1()
{
UpgradeTreeViewModel tree = MakeUpgradeTree(EquipmentId.Autogyro_S51JKai, UpgradeLevel.Max);

UpgradeTreeUpgradePlanViewModel root = tree.Items[0];

Assert.NotNull(root.Plan);
Assert.Equal(EquipmentId.Autogyro_S51JKai, root.Plan.EquipmentMasterDataId);
Assert.Equal(EquipmentId.Autogyro_S51JKai, root.EquipmentId);

UpgradeTreeUpgradePlanViewModel? s51jKaiPlan = root.Children
.FirstOrDefault(p => p.Plan?.EquipmentMasterDataId is EquipmentId.Autogyro_S51JKai);
.FirstOrDefault(p => p.EquipmentId is EquipmentId.Autogyro_S51JKai);

UpgradeTreeUpgradePlanViewModel? zuiunPlan = root.Children
.FirstOrDefault(p => p.Plan?.EquipmentMasterDataId is EquipmentId.SeaplaneBomber_Zuiun);
.FirstOrDefault(p => p.EquipmentId is EquipmentId.SeaplaneBomber_Zuiun);

UpgradeTreeUpgradePlanViewModel? t3dcpPlan = root.Children
.FirstOrDefault(p => p.Plan?.EquipmentMasterDataId is EquipmentId.DepthCharge_Type3DepthChargeProjector);
.FirstOrDefault(p => p.EquipmentId is EquipmentId.DepthCharge_Type3DepthChargeProjector);

Assert.NotNull(s51jKaiPlan);
Assert.NotNull(zuiunPlan);
Assert.NotNull(t3dcpPlan);

Assert.Equal(1, s51jKaiPlan.RequiredCount);
Assert.Equal(12, GetCount(zuiunPlan));
Assert.Equal(8, GetCount(t3dcpPlan));
Assert.Equal(1, s51jKaiPlan.Count);
Assert.Equal(12, zuiunPlan.Count);
Assert.Equal(8, t3dcpPlan.Count);

UpgradeTreeUpgradePlanViewModel? s51jPlan = s51jKaiPlan.Children
.FirstOrDefault(p => p.EquipmentId is EquipmentId.Autogyro_S51J);

Assert.NotNull(s51jPlan);

UpgradeTreeTest2(s51jPlan);
}

[Theory(DisplayName = "S-51J conversion")]
[InlineData(null)]
public void UpgradeTreeTest2(UpgradeTreeUpgradePlanViewModel? s51jRoot)
{
UpgradeTreeUpgradePlanViewModel root = s51jRoot ??
MakeUpgradeTree(EquipmentId.Autogyro_S51J, UpgradeLevel.Conversion).Items[0];

Assert.Equal(EquipmentId.Autogyro_S51J, root.EquipmentId);

UpgradeTreeUpgradePlanViewModel? s51jPlan = root.Children
.FirstOrDefault(p => p.EquipmentId is EquipmentId.Autogyro_S51J);

UpgradeTreeUpgradePlanViewModel? zuiunPlan = root.Children
.FirstOrDefault(p => p.EquipmentId is EquipmentId.SeaplaneBomber_Zuiun);

UpgradeTreeUpgradePlanViewModel? saiunPlan = root.Children
.FirstOrDefault(p => p.EquipmentId is EquipmentId.CarrierBasedRecon_Saiun);

UpgradeTreeUpgradePlanViewModel? depthChargePlan = root.Children
.FirstOrDefault(p => p.EquipmentId is EquipmentId.DepthCharge_Type95DepthCharge);

Assert.NotNull(s51jPlan);
Assert.NotNull(zuiunPlan);
Assert.NotNull(saiunPlan);
Assert.NotNull(depthChargePlan);

Assert.Equal(1, s51jPlan.Count);
Assert.Equal(6, zuiunPlan.Count);
Assert.Equal(4, saiunPlan.Count);
Assert.Equal(2, depthChargePlan.Count);

UpgradeTreeUpgradePlanViewModel? oGyroKaiNiPlan = s51jPlan.Children
.FirstOrDefault(p => p.EquipmentId is EquipmentId.Autogyro_OTypeObservationAutogyroKaiNi);

Assert.NotNull(oGyroKaiNiPlan);

UpgradeTreeTest3(oGyroKaiNiPlan);
}

[Theory(DisplayName = "O gyro kai ni conversion")]
[InlineData(null)]
public void UpgradeTreeTest3(UpgradeTreeUpgradePlanViewModel? oGyroKaiNiRoot)
{
UpgradeTreeUpgradePlanViewModel root = oGyroKaiNiRoot ??
MakeUpgradeTree(EquipmentId.Autogyro_OTypeObservationAutogyroKaiNi, UpgradeLevel.Conversion).Items[0];

Assert.Equal(EquipmentId.Autogyro_OTypeObservationAutogyroKaiNi, root.EquipmentId);

UpgradeTreeUpgradePlanViewModel? oGyroKaiNiPlan = root.Children
.FirstOrDefault(p => p.EquipmentId is EquipmentId.Autogyro_OTypeObservationAutogyroKaiNi);

UpgradeTreeUpgradePlanViewModel? reconPlan = root.Children
.FirstOrDefault(p => p.EquipmentId is EquipmentId.SeaplaneRecon_Type0ReconSeaplane);

UpgradeTreeUpgradePlanViewModel? bomberPlan = root.Children
.FirstOrDefault(p => p.EquipmentId is EquipmentId.CarrierBasedBomber_Type99DiveBomber);

// fodder used to upgrade oGyroKaiNiPlan
UpgradeTreeUpgradePlanViewModel? gyroPlan = root.Children
.Where(p => p != oGyroKaiNiPlan)
.FirstOrDefault(p => p.EquipmentId is EquipmentId.Autogyro_OTypeObservationAutogyroKaiNi);

Assert.NotNull(oGyroKaiNiPlan);
Assert.NotNull(reconPlan);
Assert.NotNull(bomberPlan);
Assert.NotNull(gyroPlan);

Assert.Equal(1, oGyroKaiNiPlan.Count);
Assert.Equal(6, reconPlan.Count);
Assert.Equal(8, bomberPlan.Count);
Assert.Equal(1, gyroPlan.Count);

UpgradeTreeUpgradePlanViewModel? oGyroKaiPlan = oGyroKaiNiPlan.Children
.FirstOrDefault(p => p.EquipmentId is EquipmentId.Autogyro_OTypeObservationAutogyroKai);

Assert.NotNull(oGyroKaiPlan);

UpgradeTreeTest4(oGyroKaiPlan);
}

[Theory(DisplayName = "O gyro kai conversion")]
[InlineData(null)]
public void UpgradeTreeTest4(UpgradeTreeUpgradePlanViewModel? oGyroKaiRoot)
{
UpgradeTreeUpgradePlanViewModel root = oGyroKaiRoot ??
MakeUpgradeTree(EquipmentId.Autogyro_OTypeObservationAutogyroKai, UpgradeLevel.Conversion).Items[0];

Assert.Equal(EquipmentId.Autogyro_OTypeObservationAutogyroKai, root.EquipmentId);

UpgradeTreeUpgradePlanViewModel? oGyroKaiPlan = root.Children
.FirstOrDefault(p => p.EquipmentId is EquipmentId.Autogyro_OTypeObservationAutogyroKai);

UpgradeTreeUpgradePlanViewModel? fighterPlan = root.Children
.FirstOrDefault(p => p.EquipmentId is EquipmentId.CarrierBasedFighter_Type96Fighter);

UpgradeTreeUpgradePlanViewModel? gyroPlan = root.Children
.FirstOrDefault(p => p.EquipmentId is EquipmentId.Autogyro_KaTypeObservationAutogyro);

Assert.NotNull(oGyroKaiPlan);
Assert.NotNull(fighterPlan);
Assert.NotNull(gyroPlan);

Assert.Equal(1, oGyroKaiPlan.Count);
Assert.Equal(4, fighterPlan.Count);
Assert.Equal(1, gyroPlan.Count);

UpgradeTreeUpgradePlanViewModel? kaGyroPlan = oGyroKaiPlan.Children
.FirstOrDefault(p => p.EquipmentId is EquipmentId.Autogyro_KaTypeObservationAutogyro);

Assert.NotNull(kaGyroPlan);

UpgradeTreeTest5(kaGyroPlan);
}

[Theory(DisplayName = "Ka gyro conversion")]
[InlineData(null)]
public void UpgradeTreeTest5(UpgradeTreeUpgradePlanViewModel? kaGyroRoot)
{
UpgradeTreeUpgradePlanViewModel root = kaGyroRoot ??
MakeUpgradeTree(EquipmentId.Autogyro_KaTypeObservationAutogyro, UpgradeLevel.Conversion).Items[0];

Assert.Equal(EquipmentId.Autogyro_KaTypeObservationAutogyro, root.EquipmentId);

UpgradeTreeUpgradePlanViewModel? kaGyroPlan = root.Children
.FirstOrDefault(p => p.EquipmentId is EquipmentId.Autogyro_KaTypeObservationAutogyro);

UpgradeTreeUpgradePlanViewModel? reconPlan = root.Children
.FirstOrDefault(p => p.EquipmentId is EquipmentId.SeaplaneRecon_Type0ReconSeaplane);

// fodder used to upgrade kaGyroPlan
UpgradeTreeUpgradePlanViewModel? gyroPlan = root.Children
.Where(p => p != kaGyroPlan)
.FirstOrDefault(p => p.EquipmentId is EquipmentId.Autogyro_KaTypeObservationAutogyro);

Assert.NotNull(kaGyroPlan);
Assert.NotNull(reconPlan);
Assert.NotNull(gyroPlan);

Assert.Equal(1, kaGyroPlan.Count);
Assert.Equal(4, reconPlan.Count);
Assert.Equal(1, gyroPlan.Count);
}
}