Skip to content

Commit 7017816

Browse files
authored
Multi-TFM approvals (#675)
1 parent f7659c8 commit 7017816

File tree

3 files changed

+52
-6
lines changed

3 files changed

+52
-6
lines changed

.github/labeler.yml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-
test:
2-
- tests/**/*
1+
test: ['tests/**/*', '!tests/ApiApprovalTests/**/*.txt']
32

43
CI:
54
- .github/workflows/**/*

tests/ApiApprovalTests/ApiApprovalTests.cs

Lines changed: 50 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,10 @@
11
using System;
2+
using System.Diagnostics;
3+
using System.IO;
4+
using System.Linq;
5+
using System.Reflection;
6+
using System.Runtime.ExceptionServices;
7+
using System.Xml.Linq;
28
using PublicApiGenerator;
39
using Shouldly;
410
using Xunit;
@@ -22,17 +28,57 @@ public class ApiApprovalTests
2228
[InlineData(typeof(Server.Transports.WebSockets.WebSocketTransport))]
2329
public void public_api_should_not_change_unintentionally(Type type)
2430
{
25-
string publicApi = type.Assembly.GeneratePublicApi(new ApiGeneratorOptions
31+
string baseDir = AppDomain.CurrentDomain.BaseDirectory;
32+
string projectName = type.Assembly.GetName().Name!;
33+
string projectFolderName = projectName["GraphQL.Server.".Length..];
34+
string projectDir = Path.Combine(baseDir, $"..{Path.DirectorySeparatorChar}..{Path.DirectorySeparatorChar}..{Path.DirectorySeparatorChar}..{Path.DirectorySeparatorChar}..", "src");
35+
string buildDir = Path.Combine(projectDir, projectFolderName, "bin", "Debug");
36+
Debug.Assert(Directory.Exists(buildDir), $"Directory '{buildDir}' doesn't exist");
37+
string csProject = Path.Combine(projectDir, projectFolderName, projectFolderName + ".csproj");
38+
var project = XDocument.Load(csProject);
39+
string[] tfms = project.Descendants("TargetFrameworks").Union(project.Descendants("TargetFramework")).First().Value.Split(";", StringSplitOptions.RemoveEmptyEntries);
40+
41+
// There may be old stuff from earlier builds like net45, netcoreapp3.0, etc. so filter it out
42+
string[] actualTfmDirs = Directory.GetDirectories(buildDir).Where(dir => tfms.Any(tfm => dir.EndsWith(tfm))).ToArray();
43+
Debug.Assert(actualTfmDirs.Length > 0, $"Directory '{buildDir}' doesn't contain subdirectories matching {string.Join(";", tfms)}");
44+
45+
(string tfm, string content)[] publicApi = actualTfmDirs.Select(tfmDir => (new DirectoryInfo(tfmDir).Name.Replace(".", ""), Assembly.LoadFile(Path.Combine(tfmDir, projectName + ".dll")).GeneratePublicApi(new ApiGeneratorOptions
2646
{
2747
IncludeAssemblyAttributes = false,
28-
WhitelistedNamespacePrefixes = new[] { "Microsoft." }
29-
});
48+
WhitelistedNamespacePrefixes = new[] { "Microsoft." },
49+
ExcludeAttributes = new[] { "System.Diagnostics.DebuggerDisplayAttribute", "System.Diagnostics.CodeAnalysis.AllowNullAttribute" }
50+
}))).ToArray();
3051

3152
// See: https://shouldly.readthedocs.io/en/latest/assertions/shouldMatchApproved.html
3253
// Note: If the AssemblyName.approved.txt file doesn't match the latest publicApi value,
3354
// this call will try to launch a diff tool to help you out but that can fail on
3455
// your machine if a diff tool isn't configured/setup.
35-
publicApi.ShouldMatchApproved(options => options.WithFilenameGenerator((testMethodInfo, discriminator, fileType, fileExtension) => $"{type.Assembly.GetName().Name}.{fileType}.{fileExtension}"));
56+
if (publicApi.DistinctBy(item => item.content).Count() == 1)
57+
{
58+
publicApi[0].content.ShouldMatchApproved(options => options.NoDiff().WithFilenameGenerator((testMethodInfo, discriminator, fileType, fileExtension) => $"{type.Assembly.GetName().Name}.{fileType}.{fileExtension}"));
59+
}
60+
else
61+
{
62+
// https://github.com/graphql-dotnet/server/pull/675#issuecomment-1001283947
63+
ExceptionDispatchInfo? error = null;
64+
65+
var uniqueApi = publicApi.ToLookup(item => item.content);
66+
foreach (var item in uniqueApi)
67+
{
68+
try
69+
{
70+
item.Key.ShouldMatchApproved(options => options.SubFolder(string.Join("+", item.Select(x => x.tfm).OrderBy(x => x))).NoDiff().WithFilenameGenerator((testMethodInfo, discriminator, fileType, fileExtension) => $"{type.Assembly.GetName().Name}.{fileType}.{fileExtension}"));
71+
}
72+
catch (Exception ex)
73+
{
74+
error = ExceptionDispatchInfo.Capture(ex);
75+
}
76+
}
77+
78+
// It's OK to throw any exception occurred.
79+
if (error != null)
80+
error.Throw();
81+
}
3682
}
3783
}
3884
}

tests/ApiApprovalTests/ApiApprovalTests.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
<PropertyGroup>
55
<TargetFramework>net6</TargetFramework>
6+
<Nullable>enable</Nullable>
67
</PropertyGroup>
78

89
<ItemGroup>

0 commit comments

Comments
 (0)