Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

move from ApprovalTests to Verify for api tests #5846

Merged
merged 6 commits into from
Apr 18, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 4 additions & 10 deletions src/core/Akka.API.Tests/Akka.API.Tests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,7 @@
<Import Project="..\..\xunitSettings.props" />

<PropertyGroup>
<AssemblyTitle>Akka.API.Tests</AssemblyTitle>
<TargetFrameworks>$(NetFrameworkTestVersion);$(NetTestVersion);$(NetCoreTestVersion)</TargetFrameworks>
<UserSecretsId>93253ee8-0410-4483-9809-9bb2d32860fa</UserSecretsId>
</PropertyGroup>

<ItemGroup>
Expand All @@ -26,16 +24,12 @@
</ItemGroup>

<ItemGroup>
<PackageReference Include="DiffPlex" Version="1.7.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="$(TestSdkVersion)" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="$(TestSdkVersion)" />
<PackageReference Include="xunit" Version="$(XunitVersion)" />
<PackageReference Include="xunit.assert" Version="2.4.1" />
<PackageReference Include="xunit.runner.visualstudio" Version="$(XunitVersion)" />
<PackageReference Include="ApiApprover" Version="9.3.0" />
<PackageReference Include="PublicApiGenerator" Version="9.3.0" />
<PackageReference Include="Verify.Xunit" Version="16.5.4" />
<PackageReference Include="Verify.DiffPlex" Version="1.2.0" />
</ItemGroup>

<PropertyGroup Condition=" '$(Configuration)' == 'Release' ">
<DefineConstants>$(DefineConstants);RELEASE</DefineConstants>
</PropertyGroup>

</Project>
240 changes: 41 additions & 199 deletions src/core/Akka.API.Tests/CoreAPISpec.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,279 +5,121 @@
// </copyright>
//-----------------------------------------------------------------------

using System;
using System.IO;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;
using Akka.Actor;
using Akka.Cluster;
using Akka.Cluster.Tools.Singleton;
using Akka.Persistence;
using Akka.Remote;
using Akka.Streams.Dsl;
using ApprovalTests;
using Xunit;
using Akka.Persistence.Query;
using static PublicApiGenerator.ApiGenerator;
using Akka.Cluster.Sharding;
using Akka.Cluster.Metrics;
using Akka.Persistence.Query.Sql;
using Akka.Persistence.Sql.Common.Journal;
using ApprovalTests.Core;
using ApprovalTests.Reporters;
using ApprovalTests.Reporters.Mac;
using ApprovalUtilities.Utilities;
using DiffPlex;
using DiffPlex.DiffBuilder;
using DiffPlex.DiffBuilder.Model;
using Xunit.Sdk;
using P4MergeReporter = ApprovalTests.Reporters.P4MergeReporter;
using P4MacMergeReporter = ApprovalTests.Reporters.Mac.P4MergeReporter;
using Akka.Streams;
using VerifyTests;
using VerifyXunit;

namespace Akka.API.Tests
{
#if(DEBUG)
[UseReporter(typeof(DiffPlexReporter), typeof(CustomDiffReporter), typeof(AllFailingTestsClipboardReporter))]
#else
[UseReporter(typeof(DiffPlexReporter), typeof(CustomDiffReporter))]
#endif
[UsesVerify]
public class CoreAPISpec
{
[Fact]
[MethodImpl(MethodImplOptions.NoInlining)]
public void ApproveCore()
static CoreAPISpec()
{
var publicApi = Filter(GeneratePublicApi(typeof(ActorSystem).Assembly));
Approvals.Verify(publicApi);
VerifierSettings.ScrubLinesContaining("[assembly: ReleaseDateAttribute(");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Very cool

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

VerifyDiffPlex.Initialize();
}

[Fact]
[MethodImpl(MethodImplOptions.NoInlining)]
public void ApproveRemote()
static Task VerifyAssembly<T>()
{
var publicApi = Filter(GeneratePublicApi(typeof(RemoteSettings).Assembly));
Approvals.Verify(publicApi);
return Verifier.Verify(GeneratePublicApi(typeof(T).Assembly));
}

[Fact]
[MethodImpl(MethodImplOptions.NoInlining)]
public void ApprovePersistence()
public Task ApproveCore()
{
var publicApi = Filter(GeneratePublicApi(typeof(Persistent).Assembly));
Approvals.Verify(publicApi);
return VerifyAssembly<ActorSystem>();
}

[Fact]
[MethodImpl(MethodImplOptions.NoInlining)]
public void ApprovePersistenceQuery()
public Task ApproveRemote()
{
var publicApi = Filter(GeneratePublicApi(typeof(PersistenceQuery).Assembly));
Approvals.Verify(publicApi);
return VerifyAssembly<RemoteSettings>();
}

[Fact]
[MethodImpl(MethodImplOptions.NoInlining)]
public void ApprovePersistenceSqlCommon()
public Task ApprovePersistence()
{
var publicApi = Filter(GeneratePublicApi(typeof(SqlJournal).Assembly));
Approvals.Verify(publicApi);
return VerifyAssembly<Persistent>();
}

[Fact]
[MethodImpl(MethodImplOptions.NoInlining)]
public void ApprovePersistenceSqlCommonQuery()
public Task ApprovePersistenceQuery()
{
var publicApi = Filter(GeneratePublicApi(typeof(SqlReadJournal).Assembly));
Approvals.Verify(publicApi);
return VerifyAssembly<PersistenceQuery>();
}

[Fact]
[MethodImpl(MethodImplOptions.NoInlining)]
public void ApproveCluster()
public Task ApprovePersistenceSqlCommon()
{
var publicApi = Filter(GeneratePublicApi(typeof(ClusterSettings).Assembly));
Approvals.Verify(publicApi);
return VerifyAssembly<SqlJournal>();
}

[Fact]
[MethodImpl(MethodImplOptions.NoInlining)]
public void ApproveClusterTools()
public Task ApprovePersistenceSqlCommonQuery()
{
var publicApi = Filter(GeneratePublicApi(typeof(ClusterSingletonManager).Assembly));
Approvals.Verify(publicApi);
return VerifyAssembly<SqlReadJournal>();
}

[Fact]
[MethodImpl(MethodImplOptions.NoInlining)]
public void ApproveStreams()
public Task ApproveCluster()
{
var publicApi = Filter(GeneratePublicApi(typeof(Source).Assembly));
Approvals.Verify(publicApi);
return VerifyAssembly<ClusterSettings>();
}

[Fact]
[MethodImpl(MethodImplOptions.NoInlining)]
public void ApproveClusterSharding()
public Task ApproveClusterTools()
{
var publicApi = Filter(GeneratePublicApi(typeof(ClusterSharding).Assembly));
Approvals.Verify(publicApi);
return VerifyAssembly<ClusterSingletonManager>();
}

[Fact]
[MethodImpl(MethodImplOptions.NoInlining)]
public void ApproveClusterMetrics()
public Task ApproveStreams()
{
var publicApi = Filter(GeneratePublicApi(typeof(ClusterMetrics).Assembly));
Approvals.Verify(publicApi);
return VerifyAssembly<Shape>();
}

[Fact]
[MethodImpl(MethodImplOptions.NoInlining)]
public void ApproveDistributedData()
public Task ApproveClusterSharding()
{
var publicApi = Filter(GeneratePublicApi(typeof(DistributedData.DistributedData).Assembly));
Approvals.Verify(publicApi);
return VerifyAssembly<ClusterSharding>();
}

[Fact]
[MethodImpl(MethodImplOptions.NoInlining)]
public void ApproveCoordination()
{
var publicApi = Filter(GeneratePublicApi(typeof(Coordination.Lease).Assembly));
Approvals.Verify(publicApi);
}

[Fact]
[MethodImpl(MethodImplOptions.NoInlining)]
public void ApproveDiscovery()
public Task ApproveClusterMetrics()
{
var publicApi = Filter(GeneratePublicApi(typeof(Discovery.Lookup).Assembly));
Approvals.Verify(publicApi);
return VerifyAssembly<ClusterMetrics>();
}

static string Filter(string text)
[Fact]
public Task ApproveDistributedData()
{
return string.Join(Environment.NewLine, text.Split(new[]
{
Environment.NewLine
}, StringSplitOptions.RemoveEmptyEntries)
.Where(l => !l.StartsWith("[assembly: ReleaseDateAttribute("))
.Where(l => !string.IsNullOrWhiteSpace(l))
);
return VerifyAssembly<DistributedData.DistributedData>();
}
}

internal class ApiNotApprovedException : XunitException
{
public ApiNotApprovedException(string message) : base($"Failed API approval. Diff:\n{message}")
{ }

public override string StackTrace { get; } = string.Empty;
}

#region Suppress FrameworkAssertReporter hack
// The built-in FrameworkAssertReporter that is being called inside the DiffReporter class
// is buggy in a CI/CD environment because it is trying to be clever, could not distinguish
// between XUnit and XUnit2, and will throw Null Reference Exception every time it ran.
//
// This is probably fixed in latest version of ApiApprover but we couldn't switch to that
// version because the latest ApiGenerator returns a different API report format.
//
// FIX: This hack removes FrameworkAssertReporter from the possible reporter list and retains
// all of the other reporters in DiffReporter

internal class CustomDiffReporter : FirstWorkingReporter
{
public CustomDiffReporter() : base(
CustomWindowsDiffReporter.Instance,
CustomMacDiffReporter.Instance)
{ }
}

internal class CustomMacDiffReporter : FirstWorkingReporter
{
public static readonly CustomMacDiffReporter Instance = new CustomMacDiffReporter();
public CustomMacDiffReporter()
: base(

BeyondCompareMacReporter.INSTANCE,
DiffMergeReporter.INSTANCE,
KaleidoscopeDiffReporter.INSTANCE,
P4MacMergeReporter.INSTANCE,
KDiff3Reporter.INSTANCE,
TkDiffReporter.INSTANCE,
QuietReporter.INSTANCE)
{ }

public override bool IsWorkingInThisEnvironment(string forFile) => OsUtils.IsUnixOs() && base.IsWorkingInThisEnvironment(forFile);
}

internal class CustomWindowsDiffReporter : FirstWorkingReporter
{
public static readonly CustomWindowsDiffReporter Instance = new CustomWindowsDiffReporter();
public CustomWindowsDiffReporter()
: base(
CodeCompareReporter.INSTANCE,
BeyondCompareReporter.INSTANCE,
TortoiseDiffReporter.INSTANCE,
AraxisMergeReporter.INSTANCE,
P4MergeReporter.INSTANCE,
WinMergeReporter.INSTANCE,
KDiffReporter.INSTANCE,
VisualStudioReporter.INSTANCE,
QuietReporter.INSTANCE)
{ }

public override bool IsWorkingInThisEnvironment(string forFile) => OsUtils.IsWindowsOs() && base.IsWorkingInThisEnvironment(forFile);
}

#endregion

internal class DiffPlexReporter : IApprovalFailureReporter
{
public void Report(string approved, string received)
[Fact]
public Task ApproveCoordination()
{
var approvedText = File.ReadAllText(approved);
var receivedText = File.ReadAllText(received);

var diffBuilder = new SideBySideDiffBuilder(new Differ());
var diff = diffBuilder.BuildDiffModel(approvedText, receivedText);

var sb = new StringBuilder()
.AppendLine($"<<<<<<<<< {Path.GetFileName(approved)}")
.AppendDiff(diff.OldText)
.AppendLine("=========")
.AppendDiff(diff.NewText)
.Append($">>>>>>>>> {Path.GetFileName(received)}");

//_out.WriteLine(sb.ToString());
throw new ApiNotApprovedException(sb.ToString());
return VerifyAssembly<Coordination.Lease>();
}
}

internal static class Extensions
{
public static StringBuilder AppendDiff(this StringBuilder output, DiffPaneModel diff)
[Fact]
public Task ApproveDiscovery()
{
foreach (var line in diff.Lines)
{
switch (line.Type)
{
case ChangeType.Deleted:
output.AppendLine($"[{line.Position:0000}] - {line.Text}");
break;
case ChangeType.Inserted:
output.AppendLine($"[{line.Position:0000}] + {line.Text}");
break;
case ChangeType.Modified:
output.AppendLine($"[{line.Position:0000}] ? {line.Text}");
break;
}
}

return output;
return VerifyAssembly<Discovery.Lookup>();
}

}
}