chore(repo): untrack ChatTwo.Tests, matches upstream layout
Drop the test project from version control. Upstream Chat 2 also keeps ChatTwo.Tests outside the public repo, and the test sources need a Dalamud assembly bundle that only resolves on a configured Windows dev box anyway. The files stay on disk for local runs but no longer ship with the source.
This commit is contained in:
@@ -374,6 +374,9 @@ FodyWeavers.xsd
|
|||||||
|
|
||||||
#Specs und Plan datein
|
#Specs und Plan datein
|
||||||
/.superpowers/
|
/.superpowers/
|
||||||
|
|
||||||
|
#Test Datein
|
||||||
|
ChatTwo.Tests
|
||||||
TestResults
|
TestResults
|
||||||
*.db-shm
|
*.db-shm
|
||||||
*.db-wal
|
*.db-wal
|
||||||
|
|||||||
@@ -1,167 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.IO;
|
|
||||||
using System.Linq;
|
|
||||||
using ChatTwo.Code;
|
|
||||||
using ChatTwo.Util;
|
|
||||||
using Dalamud.Game.Text;
|
|
||||||
using Dalamud.Game.Text.SeStringHandling;
|
|
||||||
using Dalamud.Game.Text.SeStringHandling.Payloads;
|
|
||||||
using JetBrains.Annotations;
|
|
||||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
|
||||||
|
|
||||||
namespace ChatTwo.Tests;
|
|
||||||
|
|
||||||
// Hellion Chat — Auto-Tell-Tabs history-preload coverage.
|
|
||||||
//
|
|
||||||
// These tests exercise MessageStore.GetTellHistoryWithSender, the query the
|
|
||||||
// AutoTellTabsService uses to populate a freshly spawned temp tab with the
|
|
||||||
// last conversations with that player.
|
|
||||||
//
|
|
||||||
// NOTE: like the rest of ChatTwo.Tests today, these will fail at runtime
|
|
||||||
// until the project's Dalamud.dll runtime dependency is sorted out (see
|
|
||||||
// Phase-2 backlog item "Test-Projekt fixen"). Compile-time the suite builds
|
|
||||||
// fine via DALAMUD_HOME, so the tests guard against API drift even before
|
|
||||||
// they can be executed locally.
|
|
||||||
[TestClass]
|
|
||||||
[TestSubject(typeof(MessageStore))]
|
|
||||||
public class AutoTellTabsHistoryTest
|
|
||||||
{
|
|
||||||
public TestContext TestContext { get; set; }
|
|
||||||
|
|
||||||
[TestMethod]
|
|
||||||
[Timeout(5000)]
|
|
||||||
public void GetTellHistoryWithSender_FiltersByNameAndWorld()
|
|
||||||
{
|
|
||||||
var tempDir = Directory.CreateTempSubdirectory("ChatTwo_test_");
|
|
||||||
var dbPath = Path.Join(tempDir.FullName, "test.db");
|
|
||||||
TestContext.WriteLine("Using database path: " + dbPath);
|
|
||||||
using var store = new MessageStore(dbPath);
|
|
||||||
|
|
||||||
const ulong receiver = 99001;
|
|
||||||
var now = DateTimeOffset.UtcNow;
|
|
||||||
|
|
||||||
// Two tells with the target sender, one with a different sender on
|
|
||||||
// the same world, one with the same name on a different world. Only
|
|
||||||
// the first two should make it into the result.
|
|
||||||
var asukaLichIn = TellMessage("Asuka", 76, receiver, now.AddMinutes(-30), ChatType.TellIncoming);
|
|
||||||
var asukaLichOut = TellMessage("Asuka", 76, receiver, now.AddMinutes(-20), ChatType.TellOutgoing);
|
|
||||||
var broboLich = TellMessage("Brobo", 76, receiver, now.AddMinutes(-10), ChatType.TellIncoming);
|
|
||||||
var asukaOmega = TellMessage("Asuka", 90, receiver, now.AddMinutes(-5), ChatType.TellIncoming);
|
|
||||||
|
|
||||||
store.UpsertMessage(asukaLichIn);
|
|
||||||
store.UpsertMessage(asukaLichOut);
|
|
||||||
store.UpsertMessage(broboLich);
|
|
||||||
store.UpsertMessage(asukaOmega);
|
|
||||||
|
|
||||||
var result = store.GetTellHistoryWithSender(receiver, "Asuka", 76, limit: 50);
|
|
||||||
|
|
||||||
Assert.AreEqual(2, result.Count);
|
|
||||||
// Result is oldest-first so a tab can append messages chronologically.
|
|
||||||
Assert.AreEqual(asukaLichIn.Id, result[0].Id);
|
|
||||||
Assert.AreEqual(asukaLichOut.Id, result[1].Id);
|
|
||||||
}
|
|
||||||
|
|
||||||
[TestMethod]
|
|
||||||
[Timeout(5000)]
|
|
||||||
public void GetTellHistoryWithSender_RespectsLimit()
|
|
||||||
{
|
|
||||||
var tempDir = Directory.CreateTempSubdirectory("ChatTwo_test_");
|
|
||||||
var dbPath = Path.Join(tempDir.FullName, "test.db");
|
|
||||||
TestContext.WriteLine("Using database path: " + dbPath);
|
|
||||||
using var store = new MessageStore(dbPath);
|
|
||||||
|
|
||||||
const ulong receiver = 99002;
|
|
||||||
var now = DateTimeOffset.UtcNow;
|
|
||||||
|
|
||||||
for (var i = 0; i < 30; i++)
|
|
||||||
{
|
|
||||||
var msg = TellMessage("Asuka", 76, receiver, now.AddMinutes(-i - 1), ChatType.TellIncoming);
|
|
||||||
store.UpsertMessage(msg);
|
|
||||||
}
|
|
||||||
|
|
||||||
var result = store.GetTellHistoryWithSender(receiver, "Asuka", 76, limit: 5);
|
|
||||||
|
|
||||||
Assert.AreEqual(5, result.Count);
|
|
||||||
}
|
|
||||||
|
|
||||||
[TestMethod]
|
|
||||||
[Timeout(5000)]
|
|
||||||
public void GetTellHistoryWithSender_ZeroLimitReturnsEmpty()
|
|
||||||
{
|
|
||||||
var tempDir = Directory.CreateTempSubdirectory("ChatTwo_test_");
|
|
||||||
var dbPath = Path.Join(tempDir.FullName, "test.db");
|
|
||||||
TestContext.WriteLine("Using database path: " + dbPath);
|
|
||||||
using var store = new MessageStore(dbPath);
|
|
||||||
|
|
||||||
const ulong receiver = 99003;
|
|
||||||
|
|
||||||
var msg = TellMessage("Asuka", 76, receiver, DateTimeOffset.UtcNow, ChatType.TellIncoming);
|
|
||||||
store.UpsertMessage(msg);
|
|
||||||
|
|
||||||
var result = store.GetTellHistoryWithSender(receiver, "Asuka", 76, limit: 0);
|
|
||||||
|
|
||||||
Assert.AreEqual(0, result.Count);
|
|
||||||
}
|
|
||||||
|
|
||||||
[TestMethod]
|
|
||||||
[Timeout(5000)]
|
|
||||||
public void GetTellHistoryWithSender_IgnoresOtherReceivers()
|
|
||||||
{
|
|
||||||
var tempDir = Directory.CreateTempSubdirectory("ChatTwo_test_");
|
|
||||||
var dbPath = Path.Join(tempDir.FullName, "test.db");
|
|
||||||
TestContext.WriteLine("Using database path: " + dbPath);
|
|
||||||
using var store = new MessageStore(dbPath);
|
|
||||||
|
|
||||||
const ulong ourReceiver = 99004;
|
|
||||||
const ulong otherReceiver = 99005;
|
|
||||||
var now = DateTimeOffset.UtcNow;
|
|
||||||
|
|
||||||
// Tell on the local player's account.
|
|
||||||
var ours = TellMessage("Asuka", 76, ourReceiver, now.AddMinutes(-1), ChatType.TellIncoming);
|
|
||||||
// Same sender, but logged against a different local character —
|
|
||||||
// common when the user has alts. Must not surface.
|
|
||||||
var foreign = TellMessage("Asuka", 76, otherReceiver, now, ChatType.TellIncoming);
|
|
||||||
|
|
||||||
store.UpsertMessage(ours);
|
|
||||||
store.UpsertMessage(foreign);
|
|
||||||
|
|
||||||
var result = store.GetTellHistoryWithSender(ourReceiver, "Asuka", 76, limit: 50);
|
|
||||||
|
|
||||||
Assert.AreEqual(1, result.Count);
|
|
||||||
Assert.AreEqual(ours.Id, result[0].Id);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Message TellMessage(
|
|
||||||
string senderName,
|
|
||||||
uint senderWorld,
|
|
||||||
ulong receiver,
|
|
||||||
DateTimeOffset dateTime,
|
|
||||||
ChatType chatType)
|
|
||||||
{
|
|
||||||
var senderSeString = new SeStringBuilder()
|
|
||||||
.Add(new PlayerPayload(senderName, senderWorld))
|
|
||||||
.AddText(senderName)
|
|
||||||
.Add(RawPayload.LinkTerminator)
|
|
||||||
.Build();
|
|
||||||
|
|
||||||
var contentSeString = new SeStringBuilder()
|
|
||||||
.AddText("test message")
|
|
||||||
.Build();
|
|
||||||
|
|
||||||
var senderChunks = ChunkUtil.ToChunks(senderSeString, ChunkSource.Sender, chatType).ToList();
|
|
||||||
var contentChunks = ChunkUtil.ToChunks(contentSeString, ChunkSource.Content, chatType).ToList();
|
|
||||||
|
|
||||||
var chatCode = new ChatCode((XivChatType)chatType, XivChatRelationKind.LocalPlayer, XivChatRelationKind.LocalPlayer);
|
|
||||||
return new Message(
|
|
||||||
Guid.NewGuid(),
|
|
||||||
receiver,
|
|
||||||
0,
|
|
||||||
dateTime,
|
|
||||||
chatCode,
|
|
||||||
senderChunks,
|
|
||||||
contentChunks,
|
|
||||||
senderSeString,
|
|
||||||
contentSeString,
|
|
||||||
Guid.Empty);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,53 +0,0 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
|
||||||
|
|
||||||
<PropertyGroup>
|
|
||||||
<TargetFrameworks>net10.0-windows</TargetFrameworks>
|
|
||||||
|
|
||||||
<IsPackable>false</IsPackable>
|
|
||||||
</PropertyGroup>
|
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<PackageReference Include="JetBrains.Annotations" Version="2025.2.2" />
|
|
||||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.14.1" />
|
|
||||||
<PackageReference Include="morelinq" Version="4.4.0" />
|
|
||||||
<PackageReference Include="MSTest.TestAdapter" Version="3.6.3" />
|
|
||||||
<PackageReference Include="MSTest.TestFramework" Version="3.6.3" />
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<ProjectReference Include="..\ChatTwo\ChatTwo.csproj" />
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
<PropertyGroup>
|
|
||||||
<DalamudLibPath>$(AppData)\XIVLauncher\addon\Hooks\dev</DalamudLibPath>
|
|
||||||
</PropertyGroup>
|
|
||||||
|
|
||||||
<PropertyGroup Condition="'$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::Linux)))'">
|
|
||||||
<DalamudLibPath>$(DALAMUD_HOME)</DalamudLibPath>
|
|
||||||
</PropertyGroup>
|
|
||||||
|
|
||||||
<PropertyGroup Condition="'$(IsCI)' == 'true'">
|
|
||||||
<DalamudLibPath>$(HOME)/dalamud</DalamudLibPath>
|
|
||||||
</PropertyGroup>
|
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<Reference Include="Dalamud">
|
|
||||||
<HintPath>$(DalamudLibPath)\Dalamud.dll</HintPath>
|
|
||||||
<Private>false</Private>
|
|
||||||
</Reference>
|
|
||||||
<Reference Include="FFXIVClientStructs">
|
|
||||||
<HintPath>$(DalamudLibPath)\FFXIVClientStructs.dll</HintPath>
|
|
||||||
<Private>false</Private>
|
|
||||||
</Reference>
|
|
||||||
<Reference Include="Lumina">
|
|
||||||
<HintPath>$(DalamudLibPath)\Lumina.dll</HintPath>
|
|
||||||
<Private>false</Private>
|
|
||||||
</Reference>
|
|
||||||
<Reference Include="Lumina.Excel">
|
|
||||||
<HintPath>$(DalamudLibPath)\Lumina.Excel.dll</HintPath>
|
|
||||||
<Private>false</Private>
|
|
||||||
</Reference>
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
|
|
||||||
</Project>
|
|
||||||
@@ -1,293 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.IO;
|
|
||||||
using System.Linq;
|
|
||||||
using ChatTwo.Code;
|
|
||||||
using ChatTwo.Util;
|
|
||||||
using Dalamud.Game.Text;
|
|
||||||
using Dalamud.Game.Text.SeStringHandling;
|
|
||||||
using Dalamud.Game.Text.SeStringHandling.Payloads;
|
|
||||||
using JetBrains.Annotations;
|
|
||||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
|
||||||
using Chat2PartyFinderPayload = ChatTwo.Util.PartyFinderPayload;
|
|
||||||
|
|
||||||
namespace ChatTwo.Tests;
|
|
||||||
|
|
||||||
[TestClass]
|
|
||||||
[TestSubject(typeof(MessageStore))]
|
|
||||||
public class MessageStoreTest {
|
|
||||||
// From Message.cs
|
|
||||||
private static readonly byte[] ExtraChatChannelPayloadBytes = [0, 0x27, 18, 0x20];
|
|
||||||
|
|
||||||
public TestContext TestContext { get; set; }
|
|
||||||
|
|
||||||
public static string GetImportPath() {
|
|
||||||
string[] importPaths = [
|
|
||||||
@".\TestData",
|
|
||||||
@"..\TestData",
|
|
||||||
@"..\..\TestData",
|
|
||||||
@"..\..\..\TestData",
|
|
||||||
];
|
|
||||||
var importPath = importPaths.FirstOrDefault(Directory.Exists);
|
|
||||||
if (string.IsNullOrEmpty(importPath)) {
|
|
||||||
throw new DirectoryNotFoundException("Could not find the import path");
|
|
||||||
}
|
|
||||||
return importPath;
|
|
||||||
}
|
|
||||||
|
|
||||||
[TestMethod]
|
|
||||||
[Timeout(5000)]
|
|
||||||
public void StoreAndRetrieve() {
|
|
||||||
var tempDir = Directory.CreateTempSubdirectory("ChatTwo_test_");
|
|
||||||
var dbPath = Path.Join(tempDir.FullName, "test.db");
|
|
||||||
TestContext.WriteLine("Using database path: " + dbPath);
|
|
||||||
using var store = new MessageStore(dbPath);
|
|
||||||
|
|
||||||
// Write the message.
|
|
||||||
var input = BigMessage();
|
|
||||||
store.UpsertMessage(input);
|
|
||||||
|
|
||||||
// Read the message back.
|
|
||||||
using var messageEnumerator = store.GetMostRecentMessages();
|
|
||||||
var messages = messageEnumerator.ToList();
|
|
||||||
Assert.AreEqual(1, messages.Count);
|
|
||||||
AssertMessagesEqual(input, messages.First());
|
|
||||||
}
|
|
||||||
|
|
||||||
[TestMethod]
|
|
||||||
[Timeout(5000)]
|
|
||||||
public void RetrieveMultiple() {
|
|
||||||
var tempDir = Directory.CreateTempSubdirectory("ChatTwo_test_");
|
|
||||||
var dbPath = Path.Join(tempDir.FullName, "test.db");
|
|
||||||
TestContext.WriteLine("Using database path: " + dbPath);
|
|
||||||
using var store = new MessageStore(dbPath);
|
|
||||||
|
|
||||||
// Insert 10 messages in the wrong order of date.
|
|
||||||
var messages = new List<Message>();
|
|
||||||
const uint receiver = 12345;
|
|
||||||
var now = DateTimeOffset.UtcNow;
|
|
||||||
for (var i = 0; i < 10; i++) {
|
|
||||||
var message = BigMessage(true, receiver, now.AddSeconds(-i));
|
|
||||||
TestContext.WriteLine($"Inserting message {i}: {message.Id}");
|
|
||||||
store.UpsertMessage(message);
|
|
||||||
messages.Add(message);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Insert a message for a different receiver. This shouldn't be returned
|
|
||||||
// because of the receiver filtering.
|
|
||||||
var otherReceiverMsg = BigMessage(receiver: receiver + 1, dateTime: now.AddSeconds(1));
|
|
||||||
TestContext.WriteLine($"Inserting other receiver message: {otherReceiverMsg.Id}");
|
|
||||||
store.UpsertMessage(otherReceiverMsg);
|
|
||||||
|
|
||||||
// Query the most recent 5 messages. Should return the 4 newest messages
|
|
||||||
// from the list, as well as the different receiver message because we
|
|
||||||
// aren't filtering.
|
|
||||||
using var unfilteredMessageEnumerator = store.GetMostRecentMessages(count: 5);
|
|
||||||
var outputMessages = unfilteredMessageEnumerator.ToList();
|
|
||||||
var gotIds = outputMessages.Select(m => m.Id).ToList();
|
|
||||||
TestContext.WriteLine($"Query 1 got IDs: {string.Join(", ", gotIds)}");
|
|
||||||
AssertGuidsEqual(new List<Guid> {
|
|
||||||
messages[3].Id,
|
|
||||||
messages[2].Id,
|
|
||||||
messages[1].Id,
|
|
||||||
messages[0].Id,
|
|
||||||
otherReceiverMsg.Id
|
|
||||||
}, gotIds);
|
|
||||||
|
|
||||||
// Query the most recent 5 messages but filter by receiver ID.
|
|
||||||
using var filteredByReceiverMessageEnumerator = store.GetMostRecentMessages(receiver: receiver, count: 5);
|
|
||||||
outputMessages = filteredByReceiverMessageEnumerator.ToList();
|
|
||||||
gotIds = outputMessages.Select(m => m.Id).ToList();
|
|
||||||
TestContext.WriteLine($"Query 2 got IDs: {string.Join(", ", gotIds)}");
|
|
||||||
AssertGuidsEqual(new List<Guid> {
|
|
||||||
messages[4].Id,
|
|
||||||
messages[3].Id,
|
|
||||||
messages[2].Id,
|
|
||||||
messages[1].Id,
|
|
||||||
messages[0].Id,
|
|
||||||
}, gotIds);
|
|
||||||
|
|
||||||
// Query the most recent 5 messages but only since a specific date.
|
|
||||||
using var filteredByReceiverAndDateMessageEnumerator = store.GetMostRecentMessages(receiver, since: messages[1].Date, count: 5);
|
|
||||||
outputMessages = filteredByReceiverAndDateMessageEnumerator.ToList();
|
|
||||||
gotIds = outputMessages.Select(m => m.Id).ToList();
|
|
||||||
TestContext.WriteLine($"Query 3 got IDs: {string.Join(", ", gotIds)}");
|
|
||||||
AssertGuidsEqual(new List<Guid> {
|
|
||||||
messages[1].Id,
|
|
||||||
messages[0].Id,
|
|
||||||
}, gotIds);
|
|
||||||
}
|
|
||||||
|
|
||||||
[TestMethod]
|
|
||||||
[Timeout(5000)]
|
|
||||||
// This test guards against the data format changing in an incompatible way.
|
|
||||||
public void RetrieveExisting() {
|
|
||||||
var input = BigMessage(uniqId: false);
|
|
||||||
|
|
||||||
var dbPath = Path.Join(GetImportPath(), "existing.db");
|
|
||||||
TestContext.WriteLine($"Using existing database: {dbPath}");
|
|
||||||
Assert.IsTrue(File.Exists(dbPath));
|
|
||||||
|
|
||||||
// Uncomment this section to regenerate the existing database.
|
|
||||||
/*
|
|
||||||
File.Delete(dbPath);
|
|
||||||
using (var newStore = new MessageStore(dbPath)) {
|
|
||||||
newStore.UpsertMessage(input);
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
using var store = new MessageStore(dbPath);
|
|
||||||
using var existingMessageEnumerator = store.GetMostRecentMessages();
|
|
||||||
var output = existingMessageEnumerator.ToList();
|
|
||||||
Assert.AreEqual(1, output.Count);
|
|
||||||
AssertMessagesEqual(input, output[0]);
|
|
||||||
}
|
|
||||||
|
|
||||||
[TestMethod]
|
|
||||||
[Timeout(30_000)]
|
|
||||||
public void ProfileMany() {
|
|
||||||
const int count = 20_000;
|
|
||||||
|
|
||||||
var tempDir = Directory.CreateTempSubdirectory("ChatTwo_test_");
|
|
||||||
var dbPath = Path.Join(tempDir.FullName, "test.db");
|
|
||||||
TestContext.WriteLine("Using database path: " + dbPath);
|
|
||||||
using var store = new MessageStore(dbPath);
|
|
||||||
|
|
||||||
for (var i = 0; i < count; i++) {
|
|
||||||
var message = BigMessage(uniqId: true);
|
|
||||||
store.UpsertMessage(message);
|
|
||||||
}
|
|
||||||
|
|
||||||
using var messageEnumerator = store.GetMostRecentMessages(count: count);
|
|
||||||
var messages = messageEnumerator.ToList();
|
|
||||||
Assert.AreEqual(count, messages.Count);
|
|
||||||
foreach (var message in messages) {
|
|
||||||
// Load the message because they are lazily parsed.
|
|
||||||
Assert.IsTrue(message.Id != Guid.Empty);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
internal static Message BigMessage(bool uniqId = true, uint receiver = 12345, DateTimeOffset? dateTime = null) {
|
|
||||||
// NOTE: These values aren't valid in the game.
|
|
||||||
// NOTE: we can't test UiForeground, UiGlow, or AutoTranslatePayload
|
|
||||||
// because they load data from the game.
|
|
||||||
var senderSeString = new SeStringBuilder()
|
|
||||||
.AddText("<")
|
|
||||||
.Add(new PlayerPayload("Player Name", 12345))
|
|
||||||
.AddItalics("Player Name")
|
|
||||||
.Add(RawPayload.LinkTerminator)
|
|
||||||
.AddText(">: ")
|
|
||||||
.Build();
|
|
||||||
var extraChatId = Guid.Parse("03d9e6d4-dc1a-4005-bbe7-66b8c3529277");
|
|
||||||
var contentSeString = new SeStringBuilder()
|
|
||||||
.Add(new RawPayload(ExtraChatChannelPayloadBytes.Concat(extraChatId.ToByteArray()).ToArray()))
|
|
||||||
.AddIcon(BitmapFontIcon.IslandSanctuary)
|
|
||||||
.AddMapLink(1, 2, 3, 4)
|
|
||||||
.AddText("map")
|
|
||||||
.Add(RawPayload.LinkTerminator)
|
|
||||||
.AddQuestLink(12345)
|
|
||||||
.AddText("quest")
|
|
||||||
.Add(RawPayload.LinkTerminator)
|
|
||||||
.Add(new DalamudLinkPayload())
|
|
||||||
.AddText("dalamud")
|
|
||||||
.Add(RawPayload.LinkTerminator)
|
|
||||||
.AddStatusLink(12345)
|
|
||||||
.AddText("status")
|
|
||||||
.Add(RawPayload.LinkTerminator)
|
|
||||||
.AddPartyFinderLink(12345)
|
|
||||||
.AddText("party finder")
|
|
||||||
.Add(RawPayload.LinkTerminator)
|
|
||||||
.Build();
|
|
||||||
|
|
||||||
// Add Chat 2 specific payloads (that can't be serialized into the
|
|
||||||
// SeString).
|
|
||||||
var contentChunks = ChunkUtil.ToChunks(contentSeString, ChunkSource.Content, ChatType.Say).ToList();
|
|
||||||
contentChunks = contentChunks.Concat([
|
|
||||||
new TextChunk(ChunkSource.Content, new Chat2PartyFinderPayload(12345), "chat 2 party finder"),
|
|
||||||
new TextChunk(ChunkSource.Content, new AchievementPayload(12345), "chat 2 achievement"),
|
|
||||||
new TextChunk(ChunkSource.Content, new UriPayload(new Uri("https://dalamud.dev")), "chat 2 uri"),
|
|
||||||
]).ToList();
|
|
||||||
|
|
||||||
var chatCode = new ChatCode((XivChatType)46, XivChatRelationKind.LocalPlayer, XivChatRelationKind.EngagedEnemy);
|
|
||||||
return new Message(
|
|
||||||
uniqId ? Guid.NewGuid() : Guid.Parse("f011343e-6a21-49e5-a6f9-238f0f1f8c2c"),
|
|
||||||
receiver,
|
|
||||||
54321,
|
|
||||||
dateTime ?? DateTimeOffset.FromUnixTimeMilliseconds(1713520182440),
|
|
||||||
chatCode,
|
|
||||||
ChunkUtil.ToChunks(senderSeString, ChunkSource.Sender, ChatType.Debug).ToList(),
|
|
||||||
contentChunks,
|
|
||||||
senderSeString,
|
|
||||||
contentSeString,
|
|
||||||
extraChatId
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
internal static void AssertMessagesEqual(Message input, Message output) {
|
|
||||||
// Check basic fields.
|
|
||||||
Assert.AreEqual(input.Id, output.Id);
|
|
||||||
Assert.AreEqual(input.Receiver, output.Receiver);
|
|
||||||
Assert.AreEqual(input.ContentId, output.ContentId);
|
|
||||||
// Assert time is within 1 second
|
|
||||||
var timeDifference = Math.Abs(input.Date.ToUniversalTime().Subtract(output.Date.ToUniversalTime()).TotalSeconds);
|
|
||||||
Assert.IsTrue(timeDifference < 1);
|
|
||||||
Assert.AreEqual(input.Code, output.Code);
|
|
||||||
Assert.AreEqual($"{input.SenderSource.Encode():X}", $"{output.SenderSource.Encode():X}");
|
|
||||||
Assert.AreEqual($"{input.ContentSource.Encode():X}", $"{output.ContentSource.Encode():X}");
|
|
||||||
Assert.AreEqual(input.SortCodeV2, output.SortCodeV2);
|
|
||||||
Assert.AreEqual(input.ExtraChatChannel, output.ExtraChatChannel);
|
|
||||||
|
|
||||||
// Check chunks.
|
|
||||||
AssertChunksEqual(input.Sender, output.Sender);
|
|
||||||
AssertChunksEqual(input.Content, output.Content);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void AssertChunksEqual(IReadOnlyList<Chunk> inputChunks, IReadOnlyList<Chunk> outputChunks) {
|
|
||||||
Assert.AreEqual(inputChunks.Count, outputChunks.Count);
|
|
||||||
for (var i = 0; i < inputChunks.Count; i++) {
|
|
||||||
var inputChunk = inputChunks[i];
|
|
||||||
var outputChunk = outputChunks[i];
|
|
||||||
Assert.AreEqual(inputChunk.Source, outputChunk.Source);
|
|
||||||
switch (inputChunk.Link) {
|
|
||||||
case AchievementPayload inputAchievementPayload:
|
|
||||||
Assert.AreEqual(inputAchievementPayload.Id, ((AchievementPayload) outputChunk.Link)!.Id);
|
|
||||||
break;
|
|
||||||
case Chat2PartyFinderPayload inputPartyFinderPayload:
|
|
||||||
Assert.AreEqual(inputPartyFinderPayload.Id, ((Chat2PartyFinderPayload) outputChunk.Link)!.Id);
|
|
||||||
break;
|
|
||||||
case UriPayload inputUriPayload:
|
|
||||||
Assert.AreEqual(inputUriPayload.Uri, ((UriPayload) outputChunk.Link)!.Uri);
|
|
||||||
break;
|
|
||||||
case null:
|
|
||||||
Assert.IsTrue(outputChunk.Link == null);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
Assert.AreEqual($"{inputChunk.Link.Encode():X}", $"{outputChunk.Link!.Encode():X}");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (inputChunk) {
|
|
||||||
case TextChunk inputTextChunk:
|
|
||||||
var outputTextChunk = (TextChunk)outputChunk;
|
|
||||||
Assert.AreEqual(inputTextChunk.FallbackColour, outputTextChunk.FallbackColour);
|
|
||||||
Assert.AreEqual(inputTextChunk.Foreground, outputTextChunk.Foreground);
|
|
||||||
Assert.AreEqual(inputTextChunk.Glow, outputTextChunk.Glow);
|
|
||||||
Assert.AreEqual(inputTextChunk.Italic, outputTextChunk.Italic);
|
|
||||||
Assert.AreEqual(inputTextChunk.Content, outputTextChunk.Content);
|
|
||||||
break;
|
|
||||||
case IconChunk inputIconChunk:
|
|
||||||
Assert.AreEqual(inputIconChunk.Icon, ((IconChunk) outputChunk).Icon);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
throw new Exception("Unknown chunk type");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void AssertGuidsEqual(IReadOnlyList<Guid> expected, IReadOnlyList<Guid> got) {
|
|
||||||
Assert.AreEqual(expected.Count, got.Count);
|
|
||||||
for (var i = 0; i < expected.Count; i++) {
|
|
||||||
Assert.AreEqual(expected[i].ToString(), got[i].ToString());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Vendored
BIN
Binary file not shown.
Reference in New Issue
Block a user