Skip to content

Commit

Permalink
add mob manager duplicates test
Browse files Browse the repository at this point in the history
  • Loading branch information
dit-zy committed Feb 10, 2024
1 parent 0ffb3b4 commit fe346ac
Show file tree
Hide file tree
Showing 5 changed files with 154 additions and 6 deletions.
25 changes: 25 additions & 0 deletions ScoutHelper/Utils/CollectionExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@ public static IEnumerable<T> ForEach<T>(this IEnumerable<T> source, Action<T, in
return values;
}

public static IList<T> AsList<T>(this IEnumerable<T> source) => source.ToImmutableList();

public static IList<T> AsMutableList<T>(this IEnumerable<T> source) => source.ToList();

public static IDictionary<K, V> ToDict<K, V>(this IEnumerable<KeyValuePair<K, V>> source) where K : notnull =>
source.Select(entry => (entry.Key, entry.Value)).ToDict();

Expand Down Expand Up @@ -69,4 +73,25 @@ public static IDictionary<V, K> Flip<K, V>(this IDictionary<K, V> source) where
source
.Select(entry => (entry.Value, entry.Key))
.ToDict();

#region lists

public static bool IsEmpty<T>(this ICollection<T> source) => source.Count == 0;

public static bool IsNotEmpty<T>(this ICollection<T> source) => 0 < source.Count;

#endregion

#region pairs

public static IEnumerable<(K key, V val)> AsPairs<K, V>(this IDictionary<K, V> source) =>
source.Select(entry => (entry.Key, entry.Value)).AsList();

public static IEnumerable<(A, B)> WithDistinctFirst<A, B>(this IEnumerable<(A, B)> source) where A : notnull =>
source
.ToDict()
.AsPairs()
.AsList();

#endregion
}
12 changes: 12 additions & 0 deletions ScoutHelper/packages.lock.json
Original file line number Diff line number Diff line change
Expand Up @@ -326,6 +326,18 @@
"Microsoft.Extensions.DependencyInjection": "[7.0.0, )"
}
}
},
"net7.0-windows7.0/win": {
"System.Diagnostics.EventLog": {
"type": "Transitive",
"resolved": "8.0.0",
"contentHash": "fdYxcRjQqTTacKId/2IECojlDSFvp7LP5N78+0z/xH7v/Tuw5ZAxu23Y6PTCRinqyu2ePx+Gn1098NC6jM6d+A=="
},
"System.Text.Encodings.Web": {
"type": "Transitive",
"resolved": "8.0.0",
"contentHash": "yev/k9GHAEGx2Rg3/tU6MQh4HGBXJs70y7j1LaM1i/ER9po+6nnQ6RRqTJn1E7Xu0fbIFK80Nh5EoODxrbxwBQ=="
}
}
}
}
90 changes: 87 additions & 3 deletions ScoutHelperTests/Managers/MobManagerTest.cs
Original file line number Diff line number Diff line change
@@ -1,13 +1,19 @@
using Dalamud;
using CSharpFunctionalExtensions;
using Dalamud;
using Dalamud.Plugin.Services;
using FluentAssertions;
using FsCheck;
using FsCheck.Xunit;
using JetBrains.Annotations;
using Lumina.Excel.GeneratedSheets2;
using Moq;
using ScoutHelper;
using ScoutHelper.Managers;
using ScoutHelper.Utils;
using ScoutHelperTests.TestUtils.FsCheck;
using ScoutHelperTests.TestUtils.MoqHelpers;
using static ScoutHelperTests.TestUtils.FsCheck.FsCheckUtils;
using NameList = System.Collections.Generic.IList<(uint mobId, string mobName)>;

namespace ScoutHelperTests.Managers;

Expand All @@ -17,7 +23,7 @@ public class MobManagerTest {
private readonly Mock<IDataManager> _dataManager = new(MockBehavior.Strict);

[Property]
public Property IndexContainsAllElements() => FsCheckUtils.ForAll(
public Property IndexContainsAllElements() => ForAll(
Arb.Default.UInt32().DistinctListOfPairsWith(Arbs.String()),
(npcNames) => {
// DATA
Expand All @@ -30,14 +36,92 @@ public Property IndexContainsAllElements() => FsCheckUtils.ForAll(
.Returns(npcNameSheet);
// WHEN
var actual = new MobManager(_log.Object, _dataManager.Object);
var mobManager = 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();
npcNames.ForEach(
entry => {
var mobId = entry.Item1;
var mobName = entry.Item2;
mobManager.GetMobName(mobId).Should().Be(mobName.Lower());
mobManager.GetMobId(mobName).Should().Be(mobId);
}
);
}
);

[Property]
public Property IndexHandlesDuplicates() => ForAll(
DupIndexItemsArb(),
inputs => {
// DATA
var npcNames = inputs.names
.Concat(inputs.dupNames)
.AsList();
var numDupNames = inputs.dupNames.DistinctBy(name => name.mobName).Count();
var npcNameSheet = MockExcelSheet
.Create<BNpcName>()
.AddRows(npcNames.Select(name => MockBNpcName.Create(name.mobId, name.mobName)));
// GIVEN
_log.Reset();
_dataManager.Reset();
_log.Setup(log => log.Debug(It.IsAny<string>()));
_log.Setup(log => log.Debug(It.IsAny<string>(), It.IsAny<object[]>()));
_dataManager.Setup(dm => dm.GetExcelSheet<BNpcName>(It.IsAny<ClientLanguage>()))
.Returns(npcNameSheet);
// WHEN
var mobManager = 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."));
_log.Verify(
log => log.Debug(
It.Is<string>(msg => msg.StartsWith("Duplicate mobs found for name")),
It.IsAny<object[]>()
),
Times.Exactly(numDupNames)
);
_dataManager.VerifyNoOtherCalls();
_log.VerifyNoOtherCalls();
inputs.names.ForEach(
name => {
mobManager.GetMobName(name.mobId).Should().Be(Maybe.From(name.mobName.Lower()));
mobManager.GetMobId(name.mobName).Should().Be(Maybe.From(name.mobId));
}
);
inputs.dupNames.ForEach(
name => { mobManager.GetMobName(name.mobId).Should().Be(Maybe<string>.None); }
);
}
);

private static Arbitrary<(NameList names, NameList dupNames)> DupIndexItemsArb() {
return Arb.Default
.UInt32()
.DistinctListOfPairsWith(Arbs.String())
.NonEmpty()
.SelectMany(
names => Arb.Default.UInt32()
.Where(mobId => names.All(name => mobId != name.Item1))
.ZipWith(Gen.Elements<(uint, string name)>(names).KeepSecond())
.NonEmptyListOf()
.Select(dupNames => dupNames.WithDistinctFirst())
.Select(dupNames => (names, dupNames.AsList()))
)
.ToArbitrary();
}
}
28 changes: 26 additions & 2 deletions ScoutHelperTests/TestUtils/FsCheck/Arbs.cs
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
using System.Collections.Immutable;
using CSharpFunctionalExtensions;
using FsCheck;
using Moq;
using ScoutHelper;
using ScoutHelper.Models;
using ScoutHelper.Utils;
using static ScoutHelper.Utils.Utils;

namespace ScoutHelperTests.TestUtils.FsCheck;

Expand Down Expand Up @@ -142,6 +140,12 @@ public static class ArbExtensions {
public static Arbitrary<IList<T>> NonEmptyListOf<T>(this Arbitrary<T> arb) =>
arb.Generator.NonEmptyListOf().ToArbitrary();

public static Arbitrary<IList<T>> NonEmpty<T>(this Gen<IList<T>> gen) =>
gen.Where(list => list.IsNotEmpty()).ToArbitrary();

public static Arbitrary<IList<T>> NonEmpty<T>(this Arbitrary<IList<T>> arb) =>
arb.Generator.Where(list => list.IsNotEmpty()).ToArbitrary();

public static Arbitrary<IDictionary<K, V>> DictWith<K, V>(
this Arbitrary<K> keyArb,
Arbitrary<V> valueArb,
Expand Down Expand Up @@ -185,6 +189,15 @@ params K[] keysToExclude
public static Arbitrary<(T, U)> ZipWith<T, U>(this Arbitrary<T> arb, Arbitrary<U> secondArb) =>
FsCheckUtils.Zip(arb, secondArb);

public static Arbitrary<(T, U)> ZipWith<T, U>(this Arbitrary<T> arb, Gen<U> gen) =>
FsCheckUtils.Zip(arb.Generator, gen).ToArbitrary();

public static Arbitrary<(T, U)> ZipWith<T, U>(this Gen<T> gen, Arbitrary<U> arb) =>
FsCheckUtils.Zip(gen, arb.Generator).ToArbitrary();

public static Arbitrary<(T, U)> ZipWith<T, U>(this Gen<T> gen, Gen<U> secondGen) =>
FsCheckUtils.Zip(gen, secondGen).ToArbitrary();

public static Arbitrary<IList<(T, U)>> DistinctListOfPairsWith<T, U>(this Arbitrary<T> arb, Arbitrary<U> secondArb)
where T : notnull where U : notnull =>
arb
Expand All @@ -200,4 +213,15 @@ public static Gen<U> Select<T, U>(this Arbitrary<T> arb, Func<T, U> selector) =>
arb
.Generator
.Select(selector);

public static Gen<U> SelectMany<T, U>(this Arbitrary<T> arb, Func<T, Gen<U>> selector) =>
arb
.Generator
.SelectMany(selector);

public static Gen<T> Where<T>(this Arbitrary<T> arb, Func<T, bool> predicate) => arb.Generator.Where(predicate);

public static Gen<A> KeepFirst<A, B>(this Gen<(A, B)> source) => source.Select(pair => pair.Item1);

public static Gen<B> KeepSecond<A, B>(this Gen<(A, B)> source) => source.Select(pair => pair.Item2);
}
5 changes: 4 additions & 1 deletion ScoutHelperTests/packages.lock.json
Original file line number Diff line number Diff line change
Expand Up @@ -1492,7 +1492,10 @@
}
},
"ottergui": {
"type": "Project"
"type": "Project",
"dependencies": {
"Microsoft.Extensions.DependencyInjection": "[7.0.0, )"
}
},
"scouthelper": {
"type": "Project",
Expand Down

0 comments on commit fe346ac

Please sign in to comment.