Skip to content

Commit

Permalink
Move tests to use NativeAOT compatible MSTest (#23)
Browse files Browse the repository at this point in the history
* Move tests to use NativeAOT compatible MSTest

* Run from working dir

* Fix path

* The dots
  • Loading branch information
nohwnd authored Mar 25, 2024
1 parent 575bcc5 commit 2385c9b
Show file tree
Hide file tree
Showing 16 changed files with 254 additions and 158 deletions.
16 changes: 11 additions & 5 deletions .github/workflows/dotnet.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,14 @@ jobs:
- name: Restore dependencies
run: dotnet restore

- name: Build
run: dotnet build --no-restore

- name: Test
run: dotnet test --no-build --logger GitHubActions
- name: Services.Tests
run: |
dotnet publish tests/ProfanityFilter.Services.Tests/ &&
cd tests/ProfanityFilter.Services.Tests/bin/Release/net8.0/linux-x64/publish &&
./ProfanityFilter.Services.Tests
- name: Action.Tests
run: |
dotnet publish tests/ProfanityFilter.Action.Tests/ &&
cd tests/ProfanityFilter.Action.Tests/bin/Release/net8.0/linux-x64/publish &&
./ProfanityFilter.Action.Tests
9 changes: 5 additions & 4 deletions Directory.Packages.props
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,12 @@
<PackageVersion Include="Microsoft.Extensions.DependencyInjection" Version="8.0.0" />
<PackageVersion Include="Microsoft.Extensions.Hosting" Version="8.0.0" />
<PackageVersion Include="Microsoft.NET.Build.Containers" Version="8.0.202" />
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="17.9.0" />
<PackageVersion Include="Microsoft.SourceLink.GitHub" Version="8.0.0" />
<PackageVersion Include="MSTest.Engine" Version="1.0.0-alpha.24163.4" />
<PackageVersion Include="MSTest.SourceGeneration" Version="1.0.0-alpha.24163.4" />
<PackageVersion Include="MSTest.TestFramework" Version="3.2.2" />
<PackageVersion Include="MSTest.Analyzers" Version="3.2.2" />
<PackageVersion Include="Nito.AsyncEx.Coordination" Version="5.1.2" />
<PackageVersion Include="Pathological.Globbing" Version="8.0.1" />
<PackageVersion Include="xunit.runner.visualstudio" Version="2.5.7" PrivateAssets="all" IncludeAssets="runtime;build;native;contentfiles;analyzers;buildtransitive" />
<PackageVersion Include="xunit" Version="2.7.0" />
<PackageVersion Include="Pathological.Globbing" Version="8.0.1" />
</ItemGroup>
</Project>
37 changes: 19 additions & 18 deletions tests/ProfanityFilter.Action.Tests/CoreServiceExtensionsTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,12 @@

namespace ProfanityFilter.Action.Tests;

[TestClass]
public class CoreServiceExtensionsTests
{
[Theory]
[InlineData(null, null)]
[InlineData("WebForms,WinForms", new string[] { "WebForms", "WinForms" })]
[TestMethod]
[DataRow(null, null)]
[DataRow("WebForms,WinForms", new string[] { "WebForms", "WinForms" })]
public void CoreServiceCorrectlyParseManualWordList(string? input, string[]? expected = null)
{
ICoreService sut = new TestCoreService(new()
Expand All @@ -17,10 +18,10 @@ public void CoreServiceCorrectlyParseManualWordList(string? input, string[]? exp

var actual = sut.GetManualProfaneWords();

Assert.Equal(expected, actual);
CollectionAssert.AreEqual(expected, actual);
}

[Fact]
[TestMethod]
public async Task CoreServiceCorrectlyParseCustomWordList()
{
ICoreService sut = new TestCoreService(new()
Expand All @@ -31,8 +32,8 @@ public async Task CoreServiceCorrectlyParseCustomWordList()

var actual = await sut.GetCustomProfaneWordsAsync();

Assert.Equal<string[]>(
[
CollectionAssert.AreEqual(
new string[] {
"WebForms",
"Web Forms",
"ASP.NET WebForms",
Expand All @@ -43,18 +44,18 @@ public async Task CoreServiceCorrectlyParseCustomWordList()
"WinForms",
"WindowsForms",
"Windows Forms",
], actual);
}, actual);
}

[Theory]
[InlineData("emoji", ReplacementStrategy.Emoji)]
[InlineData("EMOJI", ReplacementStrategy.Emoji)]
[InlineData("eMoJi", ReplacementStrategy.Emoji)]
[InlineData("anger-emoji", ReplacementStrategy.AngerEmoji)]
[InlineData("angerEmoji", ReplacementStrategy.AngerEmoji)]
[InlineData("AngerEmoji", ReplacementStrategy.AngerEmoji)]
[InlineData("first-letter-then-asterisk", ReplacementStrategy.FirstLetterThenAsterisk)]
[InlineData(nameof(ReplacementStrategy.FirstLetterThenAsterisk), ReplacementStrategy.FirstLetterThenAsterisk)]
[TestMethod]
[DataRow("emoji", ReplacementStrategy.Emoji)]
[DataRow("EMOJI", ReplacementStrategy.Emoji)]
[DataRow("eMoJi", ReplacementStrategy.Emoji)]
[DataRow("anger-emoji", ReplacementStrategy.AngerEmoji)]
[DataRow("angerEmoji", ReplacementStrategy.AngerEmoji)]
[DataRow("AngerEmoji", ReplacementStrategy.AngerEmoji)]
[DataRow("first-letter-then-asterisk", ReplacementStrategy.FirstLetterThenAsterisk)]
[DataRow(nameof(ReplacementStrategy.FirstLetterThenAsterisk), ReplacementStrategy.FirstLetterThenAsterisk)]
public void CoreServiceCorrectlyParsesReplacementStrategy(string input, ReplacementStrategy expected)
{
ICoreService sut = new TestCoreService(new()
Expand All @@ -64,6 +65,6 @@ public void CoreServiceCorrectlyParsesReplacementStrategy(string input, Replacem

var actual = sut.GetReplacementStrategy();

Assert.Equal(expected, actual);
Assert.AreEqual(expected, actual);
}
}
4 changes: 2 additions & 2 deletions tests/ProfanityFilter.Action.Tests/GlobalUsings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,11 @@

global using Microsoft.Extensions.DependencyInjection;

global using Microsoft.VisualStudio.TestTools.UnitTesting;

global using ProfanityFilter.Action.Clients;
global using ProfanityFilter.Action.Extensions;

global using ProfanityFilter.Services;
global using ProfanityFilter.Services.Filters;
global using ProfanityFilter.Services.Results;

global using Xunit;
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,19 @@
<TargetFramework>$(DefaultTargetFramework)</TargetFramework>
<IsPackable>false</IsPackable>
<IsTestProject>true</IsTestProject>

<OutputType>exe</OutputType>
<PublishAot>true</PublishAot>
<RuntimeIdentifier>linux-x64</RuntimeIdentifier>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="GitHubActionsTestLogger" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection" />
<PackageReference Include="Microsoft.NET.Test.Sdk" />
<PackageReference Include="xunit" />
<PackageReference Include="xunit.runner.visualstudio" />
<PackageReference Include="coverlet.collector" />

<PackageReference Include="MSTest.Engine" />
<PackageReference Include="MSTest.SourceGeneration" />
<PackageReference Include="MSTest.TestFramework" />
<PackageReference Include="MSTest.Analyzers" />
</ItemGroup>

<ItemGroup>
Expand Down
20 changes: 20 additions & 0 deletions tests/ProfanityFilter.Action.Tests/Program.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// Copyright (c) David Pine. All rights reserved.
// Licensed under the MIT License.

using Microsoft.Testing.Framework;
using Microsoft.Testing.Platform.Builder;

namespace ProfanityFilter.Action.Tests;

internal static class Program
{
public static async Task<int> Main(string[] args)
{
var builder = await TestApplication.CreateBuilderAsync(args);
// Registers TestFramework, with tree of test nodes
// that are generated into your project by source generator.
builder.AddTestFramework(new SourceGeneratedTestNodesBuilder());
var app = await builder.BuildAsync();
return await app.RunAsync();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,12 @@

namespace ProfanityFilter.Action.Tests;

[TestClass]
public class ServiceCollectionExtensionsTests
{
private const string INPUT_TOKEN = nameof(INPUT_TOKEN);

[Fact]
[TestMethod]
public void AddProfanityFilter_AddsServices()
{
Environment.SetEnvironmentVariable(INPUT_TOKEN, "TEST");
Expand All @@ -24,8 +25,8 @@ public void AddProfanityFilter_AddsServices()
var provider = services.BuildServiceProvider();
var censorService = provider.GetService<IProfaneContentFilterService>();

Assert.NotNull(censorService);
Assert.IsType<DefaultProfaneContentFilterService>(censorService);
Assert.IsNotNull(censorService);
Assert.IsInstanceOfType<DefaultProfaneContentFilterService>(censorService);
}
finally
{
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
// Copyright (c) David Pine. All rights reserved.
// Licensed under the MIT License.

namespace ProfanityFilter.Services.Tests;

internal static class CollectionAssertionExtensions
{
public static void Contains<T>(this CollectionAssert _, IEnumerable<T> collection, Func<T, bool> predicate)
{
foreach (var item in collection)
{
if (predicate(item))
{
return;
}
}


throw new Exception("Expected collection to contain item, but it did not.");
}

public static void Single<T>(this CollectionAssert _, IEnumerable<T> collection)
{
var count = collection.Count();
if (count != 1)
{
throw new Exception($"Expected collection to contain single item, but it contained {count} items.");
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,42 +3,43 @@

namespace ProfanityFilter.Services.Tests;

[TestClass]
public class DefaultProfaneContentFilterServiceTests
{
private readonly IProfaneContentFilterService _sut;

public DefaultProfaneContentFilterServiceTests() => _sut = new DefaultProfaneContentFilterService(
new MemoryCache(Options.Create<MemoryCacheOptions>(new())));

[Theory]
[InlineData(null, null)]
[InlineData("", "")]
[InlineData("This is a clean sentence.", "This is a clean sentence.")]
[InlineData("This is a sentence with the word crap.", @"This is a sentence with the word \*\*\*\*.")]
[InlineData("This is a sentence with the word CrAp.", @"This is a sentence with the word \*\*\*\*.")]
[InlineData("This is a sentence with the word crap and shit.", @"This is a sentence with the word \*\*\*\* and \*\*\*\*.")]
[InlineData("This is a sentence with the word crap and shit and fuck.", @"This is a sentence with the word \*\*\*\* and \*\*\*\* and \*\*\*\*.")]
[InlineData("This is a sentence with the word crap and shit and fuck and ass.", @"This is a sentence with the word \*\*\*\* and \*\*\*\* and \*\*\*\* and \*\*\*.")]
[TestMethod]
[DataRow(null, null)]
[DataRow("", "")]
[DataRow("This is a clean sentence.", "This is a clean sentence.")]
[DataRow("This is a sentence with the word crap.", @"This is a sentence with the word \*\*\*\*.")]
[DataRow("This is a sentence with the word CrAp.", @"This is a sentence with the word \*\*\*\*.")]
[DataRow("This is a sentence with the word crap and shit.", @"This is a sentence with the word \*\*\*\* and \*\*\*\*.")]
[DataRow("This is a sentence with the word crap and shit and fuck.", @"This is a sentence with the word \*\*\*\* and \*\*\*\* and \*\*\*\*.")]
[DataRow("This is a sentence with the word crap and shit and fuck and ass.", @"This is a sentence with the word \*\*\*\* and \*\*\*\* and \*\*\*\* and \*\*\*.")]
public async Task FilterProfanityAsync_Returns_Expected_Result(string? input, string? expectedResult)
{
// Act
var result = await _sut.FilterProfanityAsync(input!,
new(ReplacementStrategy.Asterisk, FilterTarget.Body));

// Assert
Assert.Equal(expectedResult, result.FinalOutput ?? input);
Assert.AreEqual(expectedResult, result.FinalOutput ?? input);

if (result.IsFiltered)
{
Assert.True(result.Matches.Count > 0);
Assert.IsTrue(result.Matches.Count > 0);
}
else
{
Assert.Null(result.Matches);
Assert.IsNull(result.Matches);
}
}

[Fact]
[TestMethod]
public async Task FilterProfanityAsyncMultipleParameters_Returns_Valid_Results()
{
var input = "I love WebForms!";
Expand All @@ -62,16 +63,16 @@ public async Task FilterProfanityAsyncMultipleParameters_Returns_Valid_Results()
});

// Assert
Assert.Equal("I love bleep!", titleResult.FinalOutput);
Assert.True(titleResult.IsFiltered);
Assert.Single(titleResult.Matches);
Assert.AreEqual("I love bleep!", titleResult.FinalOutput);
Assert.IsTrue(titleResult.IsFiltered);
// CollectionAssert.That.Single(titleResult.Matches);

Assert.NotEqual(input, bodyResult.FinalOutput);
Assert.True(bodyResult.IsFiltered);
Assert.Single(bodyResult.Matches);
Assert.AreNotEqual(input, bodyResult.FinalOutput);
Assert.IsTrue(bodyResult.IsFiltered);
//CollectionAssert.That.Single(bodyResult.Matches);
}

[Fact]
[TestMethod]
public async Task FilterProfanityAsyncWithEmoji_Returns_Valid_Result()
{
var input = "This is fucking bullshit!";
Expand All @@ -81,12 +82,12 @@ public async Task FilterProfanityAsyncWithEmoji_Returns_Valid_Result()
new(ReplacementStrategy.Emoji, FilterTarget.Body));

// Assert
Assert.NotEqual(input, result.FinalOutput);
Assert.True(result.IsFiltered);
Assert.Equal(2, result.Matches.Count);
Assert.AreNotEqual(input, result.FinalOutput);
Assert.IsTrue(result.IsFiltered);
Assert.AreEqual(2, result.Matches.Count);
}

[Fact]
[TestMethod]
public async Task FilterProfanityAsyncWithManualProfaneWords_ReturnsExpectedResult()
{
var input = "Does this get filtered if I say WebForms?! Well, does it?";
Expand All @@ -102,10 +103,10 @@ public async Task FilterProfanityAsyncWithManualProfaneWords_ReturnsExpectedResu
});

// Assert
Assert.True(result.IsFiltered);
Assert.IsTrue(result.IsFiltered);
}

[Fact]
[TestMethod]
public async Task FilterProfanityAsyncDoesNotReportFalseNegative()
{
var input = """
Expand Down Expand Up @@ -161,10 +162,10 @@ Verify that the following are valid
new(ReplacementStrategy.MiddleAsterisk, FilterTarget.Body));

// Assert
Assert.False(result.IsFiltered);
Assert.IsFalse(result.IsFiltered);
}

[Fact]
[TestMethod]
public async Task FilterProfanityAsyncWithMiddleAsterisk_ReturnsMultiStep_Result()
{
var input = "Lots of fucking words like manky and arrusa!";
Expand All @@ -174,18 +175,18 @@ public async Task FilterProfanityAsyncWithMiddleAsterisk_ReturnsMultiStep_Result
new(ReplacementStrategy.MiddleAsterisk, FilterTarget.Body));

// Assert
Assert.True(result.IsFiltered);
Assert.IsTrue(result.IsFiltered);

Assert.Equal(@"Lots of f\*\*\*\*\*g words like m\*\*\*y and a\*\*\*\*a!", result.FinalOutput);
Assert.AreEqual(@"Lots of f\*\*\*\*\*g words like m\*\*\*y and a\*\*\*\*a!", result.FinalOutput);

Assert.Equal(9, result.Steps.Count);
Assert.Equal(3, result.Steps.Count(static step => step.IsFiltered));
Assert.AreEqual(9, result.Steps.Count);
Assert.AreEqual(3, result.Steps.Count(static step => step.IsFiltered));

Assert.Contains(result.Steps,
CollectionAssert.That.Contains(result.Steps,
static step => step.ProfaneSourceData.EndsWith("GoogleBannedWords.txt"));
Assert.Contains(result.Steps,
CollectionAssert.That.Contains(result.Steps,
static step => step.ProfaneSourceData.EndsWith("BritishSwearWords.txt"));
Assert.Contains(result.Steps,
CollectionAssert.That.Contains(result.Steps,
static step => step.ProfaneSourceData.EndsWith("ItalianSwearWords.txt"));
}
}
Loading

0 comments on commit 2385c9b

Please sign in to comment.