mirror of
https://github.com/Tyrrrz/DiscordChatExporter.git
synced 2025-05-13 06:34:23 -04:00
Basic automated tests through the CLI
This commit is contained in:
parent
daa8c0a735
commit
85d53d0e94
11 changed files with 445 additions and 2 deletions
10
.github/workflows/CI.yml
vendored
10
.github/workflows/CI.yml
vendored
|
@ -20,6 +20,14 @@ jobs:
|
||||||
with:
|
with:
|
||||||
dotnet-version: 5.0.x
|
dotnet-version: 5.0.x
|
||||||
|
|
||||||
|
- name: Build & test
|
||||||
|
run: dotnet test --configuration Release --logger GitHubActions
|
||||||
|
|
||||||
|
- name: Upload coverage
|
||||||
|
uses: codecov/codecov-action@v1.0.5
|
||||||
|
with:
|
||||||
|
token: ${{ secrets.CODECOV_TOKEN }}
|
||||||
|
|
||||||
- name: Build & publish (CLI)
|
- name: Build & publish (CLI)
|
||||||
run: dotnet publish DiscordChatExporter.Cli/ -o DiscordChatExporter.Cli/bin/Publish/ --configuration Release
|
run: dotnet publish DiscordChatExporter.Cli/ -o DiscordChatExporter.Cli/bin/Publish/ --configuration Release
|
||||||
|
|
||||||
|
@ -36,4 +44,4 @@ jobs:
|
||||||
uses: actions/upload-artifact@v1
|
uses: actions/upload-artifact@v1
|
||||||
with:
|
with:
|
||||||
name: DiscordChatExporter
|
name: DiscordChatExporter
|
||||||
path: DiscordChatExporter.Gui/bin/Publish/
|
path: DiscordChatExporter.Gui/bin/Publish/
|
5
.gitignore
vendored
5
.gitignore
vendored
|
@ -19,4 +19,7 @@ bld/
|
||||||
[Oo]bj/
|
[Oo]bj/
|
||||||
|
|
||||||
# Coverage
|
# Coverage
|
||||||
*.opencover.xml
|
*.opencover.xml
|
||||||
|
|
||||||
|
# Secrets
|
||||||
|
*.secret
|
|
@ -0,0 +1,31 @@
|
||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<IsPackable>false</IsPackable>
|
||||||
|
<IsTestProject>true</IsTestProject>
|
||||||
|
<CollectCoverage>true</CollectCoverage>
|
||||||
|
<CoverletOutputFormat>opencover</CoverletOutputFormat>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<Content Include="xunit.runner.json" CopyToOutputDirectory="PreserveNewest" />
|
||||||
|
<None Include="*.secret" CopyToOutputDirectory="PreserveNewest" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="AngleSharp" Version="0.16.0" />
|
||||||
|
<PackageReference Include="FluentAssertions" Version="5.10.3" />
|
||||||
|
<PackageReference Include="GitHubActionsTestLogger" Version="1.2.0" />
|
||||||
|
<PackageReference Include="JsonExtensions" Version="1.1.0" />
|
||||||
|
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.10.0" />
|
||||||
|
<PackageReference Include="coverlet.msbuild" Version="3.0.3" PrivateAssets="all" />
|
||||||
|
<PackageReference Include="System.Reactive" Version="5.0.0" />
|
||||||
|
<PackageReference Include="xunit" Version="2.4.1" />
|
||||||
|
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.3" PrivateAssets="all" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\DiscordChatExporter.Cli\DiscordChatExporter.Cli.csproj" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
</Project>
|
25
DiscordChatExporter.Cli.Tests/Fixtures/TempOutputFixture.cs
Normal file
25
DiscordChatExporter.Cli.Tests/Fixtures/TempOutputFixture.cs
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
using System;
|
||||||
|
using System.IO;
|
||||||
|
|
||||||
|
namespace DiscordChatExporter.Cli.Tests.Fixtures
|
||||||
|
{
|
||||||
|
public class TempOutputFixture : IDisposable
|
||||||
|
{
|
||||||
|
public string DirPath => Path.Combine(
|
||||||
|
Path.GetDirectoryName(typeof(TempOutputFixture).Assembly.Location) ?? Directory.GetCurrentDirectory(),
|
||||||
|
"Temp"
|
||||||
|
);
|
||||||
|
|
||||||
|
public TempOutputFixture() => Directory.CreateDirectory(DirPath);
|
||||||
|
|
||||||
|
public string GetTempFilePath(string fileName) => Path.Combine(DirPath, fileName);
|
||||||
|
|
||||||
|
public string GetTempFilePath() => GetTempFilePath(Guid.NewGuid().ToString());
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
if (Directory.Exists(DirPath))
|
||||||
|
Directory.Delete(DirPath, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
39
DiscordChatExporter.Cli.Tests/Infra/Secrets.cs
Normal file
39
DiscordChatExporter.Cli.Tests/Infra/Secrets.cs
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
using System;
|
||||||
|
using System.IO;
|
||||||
|
|
||||||
|
namespace DiscordChatExporter.Cli.Tests.Infra
|
||||||
|
{
|
||||||
|
public static class Secrets
|
||||||
|
{
|
||||||
|
private static readonly Lazy<string> DiscordTokenLazy = new(() =>
|
||||||
|
{
|
||||||
|
var fromEnvironment = Environment.GetEnvironmentVariable("DISCORD_TOKEN");
|
||||||
|
if (!string.IsNullOrWhiteSpace(fromEnvironment))
|
||||||
|
return fromEnvironment;
|
||||||
|
|
||||||
|
var secretFilePath = Path.Combine(
|
||||||
|
Path.GetDirectoryName(typeof(Secrets).Assembly.Location) ?? Directory.GetCurrentDirectory(),
|
||||||
|
"DiscordToken.secret"
|
||||||
|
);
|
||||||
|
|
||||||
|
if (File.Exists(secretFilePath))
|
||||||
|
return File.ReadAllText(secretFilePath);
|
||||||
|
|
||||||
|
throw new InvalidOperationException("Discord token not provided for tests.");
|
||||||
|
});
|
||||||
|
|
||||||
|
private static readonly Lazy<bool> IsDiscordTokenBotLazy = new(() =>
|
||||||
|
{
|
||||||
|
// Default to true
|
||||||
|
var fromEnvironment = Environment.GetEnvironmentVariable("DISCORD_TOKEN_BOT");
|
||||||
|
if (string.IsNullOrWhiteSpace(fromEnvironment))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return string.Equals(fromEnvironment, "true", StringComparison.OrdinalIgnoreCase);
|
||||||
|
});
|
||||||
|
|
||||||
|
public static string DiscordToken => DiscordTokenLazy.Value;
|
||||||
|
|
||||||
|
public static bool IsDiscordTokenBot => IsDiscordTokenBotLazy.Value;
|
||||||
|
}
|
||||||
|
}
|
304
DiscordChatExporter.Cli.Tests/MentionSpecs.cs
Normal file
304
DiscordChatExporter.Cli.Tests/MentionSpecs.cs
Normal file
|
@ -0,0 +1,304 @@
|
||||||
|
using System;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using AngleSharp.Dom;
|
||||||
|
using CliFx.Infrastructure;
|
||||||
|
using DiscordChatExporter.Cli.Commands;
|
||||||
|
using DiscordChatExporter.Cli.Tests.Fixtures;
|
||||||
|
using DiscordChatExporter.Cli.Tests.Infra;
|
||||||
|
using DiscordChatExporter.Cli.Tests.TestData;
|
||||||
|
using DiscordChatExporter.Cli.Tests.Utils;
|
||||||
|
using DiscordChatExporter.Core.Discord;
|
||||||
|
using DiscordChatExporter.Core.Exporting;
|
||||||
|
using FluentAssertions;
|
||||||
|
using JsonExtensions;
|
||||||
|
using Xunit;
|
||||||
|
using Xunit.Abstractions;
|
||||||
|
|
||||||
|
namespace DiscordChatExporter.Cli.Tests
|
||||||
|
{
|
||||||
|
public class MentionSpecs : IClassFixture<TempOutputFixture>
|
||||||
|
{
|
||||||
|
private readonly ITestOutputHelper _testOutput;
|
||||||
|
private readonly TempOutputFixture _tempOutput;
|
||||||
|
|
||||||
|
public MentionSpecs(ITestOutputHelper testOutput, TempOutputFixture tempOutput)
|
||||||
|
{
|
||||||
|
_testOutput = testOutput;
|
||||||
|
_tempOutput = tempOutput;
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task User_mention_is_rendered_correctly_in_JSON()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var outputFilePath = Path.ChangeExtension(_tempOutput.GetTempFilePath(), "json");
|
||||||
|
|
||||||
|
// Act
|
||||||
|
await new ExportChannelsCommand
|
||||||
|
{
|
||||||
|
TokenValue = Secrets.DiscordToken,
|
||||||
|
IsBotToken = Secrets.IsDiscordTokenBot,
|
||||||
|
ChannelIds = new[] {Snowflake.Parse(ChannelIds.MentionTestCases)},
|
||||||
|
ExportFormat = ExportFormat.Json,
|
||||||
|
OutputPath = outputFilePath
|
||||||
|
}.ExecuteAsync(new FakeConsole());
|
||||||
|
|
||||||
|
var jsonData = await File.ReadAllTextAsync(outputFilePath);
|
||||||
|
_testOutput.WriteLine(jsonData);
|
||||||
|
|
||||||
|
var json = Json.Parse(jsonData);
|
||||||
|
|
||||||
|
var messageJson = json
|
||||||
|
.GetProperty("messages")
|
||||||
|
.EnumerateArray()
|
||||||
|
.Single(j => string.Equals(
|
||||||
|
j.GetProperty("id").GetString(),
|
||||||
|
"866458840245076028",
|
||||||
|
StringComparison.OrdinalIgnoreCase
|
||||||
|
));
|
||||||
|
|
||||||
|
var content = messageJson
|
||||||
|
.GetProperty("content")
|
||||||
|
.GetString();
|
||||||
|
|
||||||
|
var mentionedUserIds = messageJson
|
||||||
|
.GetProperty("mentions")
|
||||||
|
.EnumerateArray()
|
||||||
|
.Select(j => j.GetProperty("id").GetString())
|
||||||
|
.ToArray();
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
content.Should().Be("User mention: @Tyrrrz");
|
||||||
|
mentionedUserIds.Should().Contain("128178626683338752");
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task User_mention_is_rendered_correctly_in_HTML()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var outputFilePath = Path.ChangeExtension(_tempOutput.GetTempFilePath(), "html");
|
||||||
|
|
||||||
|
// Act
|
||||||
|
await new ExportChannelsCommand
|
||||||
|
{
|
||||||
|
TokenValue = Secrets.DiscordToken,
|
||||||
|
IsBotToken = Secrets.IsDiscordTokenBot,
|
||||||
|
ChannelIds = new[] {Snowflake.Parse(ChannelIds.MentionTestCases)},
|
||||||
|
ExportFormat = ExportFormat.HtmlDark,
|
||||||
|
OutputPath = outputFilePath
|
||||||
|
}.ExecuteAsync(new FakeConsole());
|
||||||
|
|
||||||
|
var htmlData = await File.ReadAllTextAsync(outputFilePath);
|
||||||
|
_testOutput.WriteLine(htmlData);
|
||||||
|
|
||||||
|
var html = Html.Parse(htmlData);
|
||||||
|
|
||||||
|
var messageHtml = html.GetElementById("message-866458840245076028");
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
messageHtml.Should().NotBeNull();
|
||||||
|
messageHtml?.Text().Trim().Should().Be("User mention: @Tyrrrz");
|
||||||
|
messageHtml?.InnerHtml.Should().Contain("Tyrrrz#5447");
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task Text_channel_mention_is_rendered_correctly_in_JSON()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var outputFilePath = Path.ChangeExtension(_tempOutput.GetTempFilePath(), "json");
|
||||||
|
|
||||||
|
// Act
|
||||||
|
await new ExportChannelsCommand
|
||||||
|
{
|
||||||
|
TokenValue = Secrets.DiscordToken,
|
||||||
|
IsBotToken = Secrets.IsDiscordTokenBot,
|
||||||
|
ChannelIds = new[] {Snowflake.Parse(ChannelIds.MentionTestCases)},
|
||||||
|
ExportFormat = ExportFormat.Json,
|
||||||
|
OutputPath = outputFilePath
|
||||||
|
}.ExecuteAsync(new FakeConsole());
|
||||||
|
|
||||||
|
var jsonData = await File.ReadAllTextAsync(outputFilePath);
|
||||||
|
_testOutput.WriteLine(jsonData);
|
||||||
|
|
||||||
|
var json = Json.Parse(jsonData);
|
||||||
|
|
||||||
|
var messageJson = json
|
||||||
|
.GetProperty("messages")
|
||||||
|
.EnumerateArray()
|
||||||
|
.Single(j => string.Equals(
|
||||||
|
j.GetProperty("id").GetString(),
|
||||||
|
"866459040480624680",
|
||||||
|
StringComparison.OrdinalIgnoreCase
|
||||||
|
));
|
||||||
|
|
||||||
|
var content = messageJson
|
||||||
|
.GetProperty("content")
|
||||||
|
.GetString();
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
content.Should().Be("Text channel mention: #mention-tests");
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task Text_channel_mention_is_rendered_correctly_in_HTML()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var outputFilePath = Path.ChangeExtension(_tempOutput.GetTempFilePath(), "html");
|
||||||
|
|
||||||
|
// Act
|
||||||
|
await new ExportChannelsCommand
|
||||||
|
{
|
||||||
|
TokenValue = Secrets.DiscordToken,
|
||||||
|
IsBotToken = Secrets.IsDiscordTokenBot,
|
||||||
|
ChannelIds = new[] {Snowflake.Parse(ChannelIds.MentionTestCases)},
|
||||||
|
ExportFormat = ExportFormat.HtmlDark,
|
||||||
|
OutputPath = outputFilePath
|
||||||
|
}.ExecuteAsync(new FakeConsole());
|
||||||
|
|
||||||
|
var htmlData = await File.ReadAllTextAsync(outputFilePath);
|
||||||
|
_testOutput.WriteLine(htmlData);
|
||||||
|
|
||||||
|
var html = Html.Parse(htmlData);
|
||||||
|
|
||||||
|
var messageHtml = html.GetElementById("message-866459040480624680");
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
messageHtml.Should().NotBeNull();
|
||||||
|
messageHtml?.Text().Trim().Should().Be("Text channel mention: #mention-tests");
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task Voice_channel_mention_is_rendered_correctly_in_JSON()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var outputFilePath = Path.ChangeExtension(_tempOutput.GetTempFilePath(), "json");
|
||||||
|
|
||||||
|
// Act
|
||||||
|
await new ExportChannelsCommand
|
||||||
|
{
|
||||||
|
TokenValue = Secrets.DiscordToken,
|
||||||
|
IsBotToken = Secrets.IsDiscordTokenBot,
|
||||||
|
ChannelIds = new[] {Snowflake.Parse(ChannelIds.MentionTestCases)},
|
||||||
|
ExportFormat = ExportFormat.Json,
|
||||||
|
OutputPath = outputFilePath
|
||||||
|
}.ExecuteAsync(new FakeConsole());
|
||||||
|
|
||||||
|
var jsonData = await File.ReadAllTextAsync(outputFilePath);
|
||||||
|
_testOutput.WriteLine(jsonData);
|
||||||
|
|
||||||
|
var json = Json.Parse(jsonData);
|
||||||
|
|
||||||
|
var messageJson = json
|
||||||
|
.GetProperty("messages")
|
||||||
|
.EnumerateArray()
|
||||||
|
.Single(j => string.Equals(
|
||||||
|
j.GetProperty("id").GetString(),
|
||||||
|
"866459175462633503",
|
||||||
|
StringComparison.OrdinalIgnoreCase
|
||||||
|
));
|
||||||
|
|
||||||
|
var content = messageJson
|
||||||
|
.GetProperty("content")
|
||||||
|
.GetString();
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
content.Should().Be("Voice channel mention: #chaos-vc [voice]");
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task Voice_channel_mention_is_rendered_correctly_in_HTML()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var outputFilePath = Path.ChangeExtension(_tempOutput.GetTempFilePath(), "html");
|
||||||
|
|
||||||
|
// Act
|
||||||
|
await new ExportChannelsCommand
|
||||||
|
{
|
||||||
|
TokenValue = Secrets.DiscordToken,
|
||||||
|
IsBotToken = Secrets.IsDiscordTokenBot,
|
||||||
|
ChannelIds = new[] {Snowflake.Parse(ChannelIds.MentionTestCases)},
|
||||||
|
ExportFormat = ExportFormat.HtmlDark,
|
||||||
|
OutputPath = outputFilePath
|
||||||
|
}.ExecuteAsync(new FakeConsole());
|
||||||
|
|
||||||
|
var htmlData = await File.ReadAllTextAsync(outputFilePath);
|
||||||
|
_testOutput.WriteLine(htmlData);
|
||||||
|
|
||||||
|
var html = Html.Parse(htmlData);
|
||||||
|
|
||||||
|
var messageHtml = html.GetElementById("message-866459175462633503");
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
messageHtml.Should().NotBeNull();
|
||||||
|
messageHtml?.Text().Trim().Should().Be("Voice channel mention: 🔊chaos-vc");
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task Role_mention_is_rendered_correctly_in_JSON()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var outputFilePath = Path.ChangeExtension(_tempOutput.GetTempFilePath(), "json");
|
||||||
|
|
||||||
|
// Act
|
||||||
|
await new ExportChannelsCommand
|
||||||
|
{
|
||||||
|
TokenValue = Secrets.DiscordToken,
|
||||||
|
IsBotToken = Secrets.IsDiscordTokenBot,
|
||||||
|
ChannelIds = new[] {Snowflake.Parse(ChannelIds.MentionTestCases)},
|
||||||
|
ExportFormat = ExportFormat.Json,
|
||||||
|
OutputPath = outputFilePath
|
||||||
|
}.ExecuteAsync(new FakeConsole());
|
||||||
|
|
||||||
|
var jsonData = await File.ReadAllTextAsync(outputFilePath);
|
||||||
|
_testOutput.WriteLine(jsonData);
|
||||||
|
|
||||||
|
var json = Json.Parse(jsonData);
|
||||||
|
|
||||||
|
var messageJson = json
|
||||||
|
.GetProperty("messages")
|
||||||
|
.EnumerateArray()
|
||||||
|
.Single(j => string.Equals(
|
||||||
|
j.GetProperty("id").GetString(),
|
||||||
|
"866459254693429258",
|
||||||
|
StringComparison.OrdinalIgnoreCase
|
||||||
|
));
|
||||||
|
|
||||||
|
var content = messageJson
|
||||||
|
.GetProperty("content")
|
||||||
|
.GetString();
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
content.Should().Be("Role mention: @Role 1");
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task Role_mention_is_rendered_correctly_in_HTML()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var outputFilePath = Path.ChangeExtension(_tempOutput.GetTempFilePath(), "html");
|
||||||
|
|
||||||
|
// Act
|
||||||
|
await new ExportChannelsCommand
|
||||||
|
{
|
||||||
|
TokenValue = Secrets.DiscordToken,
|
||||||
|
IsBotToken = Secrets.IsDiscordTokenBot,
|
||||||
|
ChannelIds = new[] {Snowflake.Parse(ChannelIds.MentionTestCases)},
|
||||||
|
ExportFormat = ExportFormat.HtmlDark,
|
||||||
|
OutputPath = outputFilePath
|
||||||
|
}.ExecuteAsync(new FakeConsole());
|
||||||
|
|
||||||
|
var htmlData = await File.ReadAllTextAsync(outputFilePath);
|
||||||
|
_testOutput.WriteLine(htmlData);
|
||||||
|
|
||||||
|
var html = Html.Parse(htmlData);
|
||||||
|
|
||||||
|
var messageHtml = html.GetElementById("message-866459254693429258");
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
messageHtml.Should().NotBeNull();
|
||||||
|
messageHtml?.Text().Trim().Should().Be("Role mention: @Role 1");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
9
DiscordChatExporter.Cli.Tests/TestData/ChannelIds.cs
Normal file
9
DiscordChatExporter.Cli.Tests/TestData/ChannelIds.cs
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
namespace DiscordChatExporter.Cli.Tests.TestData
|
||||||
|
{
|
||||||
|
public static class ChannelIds
|
||||||
|
{
|
||||||
|
public static string MentionTestCases { get; } = "866458801389174794";
|
||||||
|
|
||||||
|
public static string ReplyTestCases { get; } = "866459871934677052";
|
||||||
|
}
|
||||||
|
}
|
12
DiscordChatExporter.Cli.Tests/Utils/Html.cs
Normal file
12
DiscordChatExporter.Cli.Tests/Utils/Html.cs
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
using AngleSharp.Html.Dom;
|
||||||
|
using AngleSharp.Html.Parser;
|
||||||
|
|
||||||
|
namespace DiscordChatExporter.Cli.Tests.Utils
|
||||||
|
{
|
||||||
|
internal static class Html
|
||||||
|
{
|
||||||
|
private static readonly IHtmlParser Parser = new HtmlParser();
|
||||||
|
|
||||||
|
public static IHtmlDocument Parse(string source) => Parser.ParseDocument(source);
|
||||||
|
}
|
||||||
|
}
|
5
DiscordChatExporter.Cli.Tests/xunit.runner.json
Normal file
5
DiscordChatExporter.Cli.Tests/xunit.runner.json
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
{
|
||||||
|
"$schema": "https://xunit.net/schema/current/xunit.runner.schema.json",
|
||||||
|
"methodDisplayOptions": "all",
|
||||||
|
"methodDisplay": "method"
|
||||||
|
}
|
|
@ -18,6 +18,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DiscordChatExporter.Cli", "
|
||||||
EndProject
|
EndProject
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DiscordChatExporter.Core", "DiscordChatExporter.Core\DiscordChatExporter.Core.csproj", "{E19980B9-2B84-4257-A517-540FF1E3FCDD}"
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DiscordChatExporter.Core", "DiscordChatExporter.Core\DiscordChatExporter.Core.csproj", "{E19980B9-2B84-4257-A517-540FF1E3FCDD}"
|
||||||
EndProject
|
EndProject
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DiscordChatExporter.Cli.Tests", "DiscordChatExporter.Cli.Tests\DiscordChatExporter.Cli.Tests.csproj", "{C5064B8B-692E-4515-BA55-A9BE392EE540}"
|
||||||
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
Debug|Any CPU = Debug|Any CPU
|
Debug|Any CPU = Debug|Any CPU
|
||||||
|
@ -36,6 +38,10 @@ Global
|
||||||
{E19980B9-2B84-4257-A517-540FF1E3FCDD}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{E19980B9-2B84-4257-A517-540FF1E3FCDD}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{E19980B9-2B84-4257-A517-540FF1E3FCDD}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{E19980B9-2B84-4257-A517-540FF1E3FCDD}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{E19980B9-2B84-4257-A517-540FF1E3FCDD}.Release|Any CPU.Build.0 = Release|Any CPU
|
{E19980B9-2B84-4257-A517-540FF1E3FCDD}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{C5064B8B-692E-4515-BA55-A9BE392EE540}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{C5064B8B-692E-4515-BA55-A9BE392EE540}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{C5064B8B-692E-4515-BA55-A9BE392EE540}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{C5064B8B-692E-4515-BA55-A9BE392EE540}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
HideSolutionNode = FALSE
|
HideSolutionNode = FALSE
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
# DiscordChatExporter
|
# DiscordChatExporter
|
||||||
|
|
||||||
[](https://github.com/Tyrrrz/DiscordChatExporter/actions)
|
[](https://github.com/Tyrrrz/DiscordChatExporter/actions)
|
||||||
|
[](https://codecov.io/gh/Tyrrrz/DiscordChatExporter)
|
||||||
[](https://github.com/Tyrrrz/DiscordChatExporter/releases)
|
[](https://github.com/Tyrrrz/DiscordChatExporter/releases)
|
||||||
[](https://github.com/Tyrrrz/DiscordChatExporter/releases)
|
[](https://github.com/Tyrrrz/DiscordChatExporter/releases)
|
||||||
[](https://tyrrrz.me/donate)
|
[](https://tyrrrz.me/donate)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue