Skip to content

Commit

Permalink
add first test for mob manager and get lumina mocking working
Browse files Browse the repository at this point in the history
  • Loading branch information
dit-zy committed Feb 10, 2024
1 parent 543e051 commit 0ffb3b4
Show file tree
Hide file tree
Showing 9 changed files with 1,687 additions and 18 deletions.
3 changes: 3 additions & 0 deletions ScoutHelper/Utils/Utils.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using System.Text.RegularExpressions;
using CSharpFunctionalExtensions;
using ImGuiNET;
using Lumina.Text;
using ScoutHelper.Models;

namespace ScoutHelper.Utils;
Expand Down Expand Up @@ -115,6 +116,8 @@ private static IEnumerable<string> Tokenize(string s) {

public static string Join(this IEnumerable<string> source, string? separator) => string.Join(separator, source);

public static SeString ToSeString(this string str) => new(str);

#endregion
}

Expand Down
43 changes: 43 additions & 0 deletions ScoutHelperTests/Managers/MobManagerTest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
using Dalamud;
using Dalamud.Plugin.Services;
using FsCheck;
using FsCheck.Xunit;
using JetBrains.Annotations;
using Lumina.Excel.GeneratedSheets2;
using Moq;
using ScoutHelper.Managers;
using ScoutHelperTests.TestUtils.FsCheck;
using ScoutHelperTests.TestUtils.MoqHelpers;

namespace ScoutHelperTests.Managers;

[TestSubject(typeof(MobManager))]
public class MobManagerTest {
private readonly Mock<IPluginLog> _log = new(MockBehavior.Strict);
private readonly Mock<IDataManager> _dataManager = new(MockBehavior.Strict);

[Property]
public Property IndexContainsAllElements() => FsCheckUtils.ForAll(
Arb.Default.UInt32().DistinctListOfPairsWith(Arbs.String()),
(npcNames) => {
// DATA
var npcNameSheet = MockExcelSheet.Create<BNpcName>()
.AddRows(npcNames.Select(name => MockBNpcName.Create(name.Item1, name.Item2)));
// GIVEN
_log.Setup(log => log.Debug(It.IsAny<string>()));
_dataManager.Setup(dm => dm.GetExcelSheet<BNpcName>(It.IsAny<ClientLanguage>()))
.Returns(npcNameSheet);
// WHEN
var actual = new MobManager(_log.Object, _dataManager.Object);
// THEN
_dataManager.Verify(manager => manager.GetExcelSheet<BNpcName>(ClientLanguage.English));
_log.Verify(log => log.Debug("Building mob data from game files..."));
_log.Verify(log => log.Debug("Mob data built."));
_dataManager.VerifyNoOtherCalls();
_log.VerifyNoOtherCalls();
}
);
}
31 changes: 16 additions & 15 deletions ScoutHelperTests/ScoutHelperTests.csproj
Original file line number Diff line number Diff line change
@@ -1,19 +1,33 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<DalamudLibPath Condition="$([MSBuild]::IsOSPlatform('Windows'))">$(appdata)\XIVLauncher\addon\Hooks\dev\</DalamudLibPath>
<DalamudLibPath Condition="$([MSBuild]::IsOSPlatform('Linux'))">$(HOME)/.xlcore/dalamud/Hooks/dev/</DalamudLibPath>
<DalamudLibPath Condition="$([MSBuild]::IsOSPlatform('OSX'))">$(HOME)/Library/Application Support/XIV on Mac/dalamud/Hooks/dev/</DalamudLibPath>
<DalamudLibPath Condition="$(DALAMUD_HOME) != ''">$(DALAMUD_HOME)/</DalamudLibPath>
</PropertyGroup>

<PropertyGroup>
<TargetFramework>net7.0-windows</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>

<IsPackable>false</IsPackable>
<IsTestProject>true</IsTestProject>
<AssemblySearchPaths>$(AssemblySearchPaths);$(DalamudLibPath)</AssemblySearchPaths>
</PropertyGroup>

<ItemGroup>
<ItemGroup Label="DalamudDependencies">
<Reference Include="Dalamud"/>
<Reference Include="Lumina"/>
<Reference Include="Lumina.Excel"/>
</ItemGroup>

<ItemGroup Label="PublicDependencies">
<PackageReference Include="FluentAssertions" Version="6.12.0"/>
<PackageReference Include="FsCheck" Version="2.16.6"/>
<PackageReference Include="FsCheck.Xunit" Version="2.16.6"/>
<PackageReference Include="JetBrains.Annotations" Version="2023.3.0" />
<PackageReference Include="JetBrains.Annotations" Version="2023.3.0"/>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.7.1"/>
<PackageReference Include="Moq" Version="4.20.70"/>
<PackageReference Include="xunit" Version="2.4.2"/>
Expand All @@ -31,17 +45,4 @@
<ProjectReference Include="..\ScoutHelper\ScoutHelper.csproj"/>
</ItemGroup>

<PropertyGroup>
<DalamudLibPath Condition="$([MSBuild]::IsOSPlatform('Windows'))">$(appdata)\XIVLauncher\addon\Hooks\dev\</DalamudLibPath>
<DalamudLibPath Condition="$([MSBuild]::IsOSPlatform('Linux'))">$(HOME)/.xlcore/dalamud/Hooks/dev/</DalamudLibPath>
<DalamudLibPath Condition="$([MSBuild]::IsOSPlatform('OSX'))">$(HOME)/Library/Application Support/XIV on Mac/dalamud/Hooks/dev/</DalamudLibPath>
<DalamudLibPath Condition="$(DALAMUD_HOME) != ''">$(DALAMUD_HOME)/</DalamudLibPath>
</PropertyGroup>

<ItemGroup Label="dalamud-lib">
<Reference Include="Dalamud">
<HintPath>$(DalamudLibPath)\Dalamud.dll</HintPath>
</Reference>
</ItemGroup>

</Project>
48 changes: 45 additions & 3 deletions ScoutHelperTests/TestUtils/FsCheck/Arbs.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
using CSharpFunctionalExtensions;
using System.Collections.Immutable;
using CSharpFunctionalExtensions;
using FsCheck;
using Moq;
using ScoutHelper;
using ScoutHelper.Models;
using ScoutHelper.Utils;
Expand Down Expand Up @@ -143,19 +145,59 @@ public static Arbitrary<IList<T>> NonEmptyListOf<T>(this Arbitrary<T> arb) =>
public static Arbitrary<IDictionary<K, V>> DictWith<K, V>(
this Arbitrary<K> keyArb,
Arbitrary<V> valueArb,
params K[] excluding
params K[] keysToExclude
) where K : notnull =>
Arbs.DictOf(keyArb.Generator, valueArb.Generator)
.Excluding(keysToExclude);

public static Arbitrary<IDictionary<K, V>> DistinctDictWith<K, V>(
this Arbitrary<K> keyArb,
Arbitrary<V> valueArb,
params K[] keysToExclude
) where K : notnull where V : notnull =>
Arbs.DictOf(keyArb.Generator, valueArb.Generator)
// flipping forces the values (now keys) to be distinct. double flip, to force keys and values to be distinct.
.Select(dict => dict.Flip().Flip())
.Excluding(keysToExclude);

public static Arbitrary<IDictionary<K, V>> Excluding<K, V>(
this Arbitrary<IDictionary<K, V>> source,
params K[] keysToExclude
) where K : notnull =>
source
.Generator
.Excluding(keysToExclude);

public static Arbitrary<IDictionary<K, V>> Excluding<K, V>(
this Gen<IDictionary<K, V>> source,
params K[] keysToExclude
) where K : notnull =>
source
.Select(dict => dict.ToMutableDict())
.Select(
dict => {
excluding.ForEach(key => dict.Remove(key));
keysToExclude.ForEach(key => dict.Remove(key));
return dict.ToDict();
}
)
.ToArbitrary();

public static Arbitrary<(T, U)> ZipWith<T, U>(this Arbitrary<T> arb, Arbitrary<U> secondArb) =>
FsCheckUtils.Zip(arb, secondArb);

public static Arbitrary<IList<(T, U)>> DistinctListOfPairsWith<T, U>(this Arbitrary<T> arb, Arbitrary<U> secondArb)
where T : notnull where U : notnull =>
arb
.DistinctDictWith(secondArb)
.Select(dict => dict.Select(entry => (entry.Key, entry.Value)))
.Select(entries => (IList<(T, U)>)entries.ToImmutableList())
.ToArbitrary();

public static Arbitrary<Maybe<T>> ToMaybeArb<T>(this Arbitrary<T> arb, bool includeNulls = false) =>
Arbs.MaybeArb(arb.Generator, includeNulls);

public static Gen<U> Select<T, U>(this Arbitrary<T> arb, Func<T, U> selector) =>
arb
.Generator
.Select(selector);
}
7 changes: 7 additions & 0 deletions ScoutHelperTests/TestUtils/MoqHelpers/IMockExcelRow.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
namespace ScoutHelperTests.TestUtils.MoqHelpers;

/**
* an interface for marking mock versions of excel sheet types.
* used to limit scope of extension methods.
*/
public interface IMockExcelRow { }
15 changes: 15 additions & 0 deletions ScoutHelperTests/TestUtils/MoqHelpers/MockBNpcName.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
using Lumina.Excel.GeneratedSheets2;
using ScoutHelper.Utils;

namespace ScoutHelperTests.TestUtils.MoqHelpers;

public class MockBNpcName : BNpcName, IMockExcelRow {
private MockBNpcName(uint rowId, string singular) {
RowId = rowId;
this.SetProperty("Singular", singular.ToSeString());
}

public static MockBNpcName Create(uint rowId, string singular) {
return new MockBNpcName(rowId, singular);
}
}
31 changes: 31 additions & 0 deletions ScoutHelperTests/TestUtils/MoqHelpers/MockExcelSheet.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
using System.Collections;
using Lumina;
using Lumina.Data;
using Lumina.Data.Files.Excel;
using Lumina.Excel;

namespace ScoutHelperTests.TestUtils.MoqHelpers;

public class MockExcelSheet<T> : ExcelSheet<T>, IEnumerable<T> where T : ExcelRow {
private readonly List<T> _rows = new List<T>();

internal MockExcelSheet() : base(new ExcelHeaderFile(), "test sheet", Language.English, null) { }

Check warning on line 12 in ScoutHelperTests/TestUtils/MoqHelpers/MockExcelSheet.cs

View workflow job for this annotation

GitHub Actions / build

Cannot convert null literal to non-nullable reference type.

Check warning on line 12 in ScoutHelperTests/TestUtils/MoqHelpers/MockExcelSheet.cs

View workflow job for this annotation

GitHub Actions / build

Cannot convert null literal to non-nullable reference type.

public new IEnumerator<T> GetEnumerator() => _rows.GetEnumerator();

IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();

public MockExcelSheet<T> AddRow(T row) {
_rows.Add(row);
return this;
}

public MockExcelSheet<T> AddRows(IEnumerable<T> rows) {
_rows.AddRange(rows);
return this;
}
}

public static class MockExcelSheet {
public static MockExcelSheet<T> Create<T>() where T : ExcelRow => new();
}
19 changes: 19 additions & 0 deletions ScoutHelperTests/TestUtils/MoqHelpers/MoqUtils.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
using Lumina.Excel;

namespace ScoutHelperTests.TestUtils.MoqHelpers;

public static class MoqUtils {
#region Mocks

public static void SetProperty<T>(this T excelRow, string propertyName, object? value)
where T : ExcelRow, IMockExcelRow {
excelRow!
.GetType()!
.BaseType!
.GetProperty(propertyName)!
.GetSetMethod(true)!
.Invoke(excelRow, new object?[] { value });
}

#endregion
}
Loading

0 comments on commit 0ffb3b4

Please sign in to comment.