/
ApiApprovalTests.cs
105 lines (92 loc) · 4.13 KB
/
ApiApprovalTests.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
// Copyright (c) 2019 .NET Foundation and Contributors. All rights reserved.
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for full license information.
using System;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Text.RegularExpressions;
using PublicApiGenerator;
using Shouldly;
using Xunit;
namespace Splat.Tests
{
/// <summary>
/// Tests to make sure that the API matches the approved ones.
/// </summary>
[ExcludeFromCodeCoverage]
public class ApiApprovalTests
{
private static readonly Regex _removeCoverletSectionRegex = new Regex(@"^namespace Coverlet\.Core\.Instrumentation\.Tracker.*?^}", RegexOptions.Singleline | RegexOptions.Multiline | RegexOptions.Compiled);
/// <summary>
/// Tests to make sure the splat project is approved.
/// </summary>
[Fact]
public void SplatProject()
{
CheckApproval(typeof(AssemblyFinder).Assembly);
}
private static void CheckApproval(Assembly assembly, [CallerMemberName]string memberName = null, [CallerFilePath]string filePath = null)
{
var targetFrameworkName = Assembly.GetExecutingAssembly().GetTargetFrameworkName();
var sourceDirectory = Path.GetDirectoryName(filePath);
var approvedFileName = Path.Combine(sourceDirectory, $"ApiApprovalTests.{memberName}.{targetFrameworkName}.approved.txt");
var receivedFileName = Path.Combine(sourceDirectory, $"ApiApprovalTests.{memberName}.{targetFrameworkName}.received.txt");
string approvedPublicApi = string.Empty;
if (File.Exists(approvedFileName))
{
approvedPublicApi = File.ReadAllText(approvedFileName);
}
var receivedPublicApi = Filter(ApiGenerator.GeneratePublicApi(assembly));
if (!string.Equals(receivedPublicApi, approvedPublicApi, StringComparison.InvariantCulture))
{
File.WriteAllText(receivedFileName, receivedPublicApi);
try
{
ShouldlyConfiguration.DiffTools.GetDiffTool().Open(receivedFileName, approvedFileName, true);
}
catch (ShouldAssertException)
{
var process = new Process
{
StartInfo = new ProcessStartInfo
{
Arguments = $"\"{approvedFileName}\" \"{receivedFileName}\"",
UseShellExecute = false,
RedirectStandardOutput = true,
CreateNoWindow = true
}
};
#if NET_461
process.StartInfo.FileName = "FC";
#else
process.StartInfo.FileName = "diff";
#endif
process.Start();
string output = process.StandardOutput.ReadToEnd();
process.WaitForExit();
throw new Exception("Invalid API configuration: " + Environment.NewLine + output);
}
}
Assert.Equal(approvedPublicApi, receivedPublicApi);
}
private static string Filter(string text)
{
text = _removeCoverletSectionRegex.Replace(text, string.Empty);
return string.Join(Environment.NewLine, text.Split(
new[]
{
Environment.NewLine
}, StringSplitOptions.RemoveEmptyEntries)
.Where(l =>
!l.StartsWith("[assembly: AssemblyVersion(", StringComparison.InvariantCulture) &&
!l.StartsWith("[assembly: AssemblyFileVersion(", StringComparison.InvariantCulture) &&
!l.StartsWith("[assembly: AssemblyInformationalVersion(", StringComparison.InvariantCulture) &&
!string.IsNullOrWhiteSpace(l)));
}
}
}