Skip to content

Commit 8ff5674

Browse files
committed
Implemented project system design-time build test
1 parent ef582c5 commit 8ff5674

File tree

7 files changed

+140
-39
lines changed

7 files changed

+140
-39
lines changed

src/Draco.Examples.Tests/Draco.Examples.Tests.csproj

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,10 @@
66
<IsTestProject>true</IsTestProject>
77
</PropertyGroup>
88

9+
<ItemGroup>
10+
<ProjectReference Include="..\Draco.ProjectSystem\Draco.ProjectSystem.csproj" />
11+
</ItemGroup>
12+
913
<ItemGroup>
1014
<PackageReference Include="coverlet.collector" Version="6.0.0" />
1115
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.8.0" />
Lines changed: 41 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,43 +1,31 @@
11
using System.Diagnostics;
22
using System.Text;
33
using DiffEngine;
4+
using Draco.ProjectSystem;
45

56
namespace Draco.Examples.Tests;
67

8+
// NOTE: Unnfortunately the tooling seemms to have a race condition if we attempt a design-time build here
9+
// So we order to first run the examples, and then the design-time build
10+
[TestCaseOrderer("Draco.Examples.Tests.PriorityOrderer", "Draco.Examples.Tests")]
711
public sealed class ExamplesTests
812
{
9-
public static IEnumerable<object[]> TestData
10-
{
11-
get
13+
// Each directory contains a projectfile, and a verification file, return each pair
14+
public static IEnumerable<object[]> TestData => TestUtils.ExampleDirectories
15+
.Select(directory => new object[]
1216
{
13-
// Get all example projects
14-
// We exclude the "Toolchain" folder, in case the user has installed it in the examples directory
15-
var exampleProjectDirectories = Directory
16-
.GetDirectories("examples", "*", SearchOption.TopDirectoryOnly)
17-
.Where(d => Path.GetFileName(d) != "Toolchain");
18-
// Each directory contains a projectfile, and a verification file, return each pair
19-
return exampleProjectDirectories
20-
.Select(directory => new object[]
21-
{
22-
// Search for the dracoproj file
23-
Directory.GetFiles(directory, "*.dracoproj").Single(),
24-
// The verification file is always named "verify.txt"
25-
Path.Combine(directory, "verify.txt"),
26-
});
27-
}
28-
}
29-
30-
private const string DescriptionForNotInstalledToolchain = """
31-
Note, that you need to have the toolchain installed in the examples directory, in order to run these tests.
32-
You can do that by running the install_toolchain.ps1 script in the scripts directory and passing in the path to the examples directory.
33-
""";
17+
// Search for the dracoproj file
18+
Directory.GetFiles(directory, "*.dracoproj").Single(),
19+
// The verification file is always named "verify.txt"
20+
Path.Combine(directory, "verify.txt"),
21+
});
3422

3523
public ExamplesTests()
3624
{
3725
DiffTools.UseOrder(DiffTool.VisualStudioCode, DiffTool.VisualStudio, DiffTool.Rider);
3826
}
3927

40-
[Theory]
28+
[Theory, TestPriority(1)]
4129
[MemberData(nameof(TestData))]
4230
public async Task RunExample(string projectFile, string verifiedFile)
4331
{
@@ -67,13 +55,22 @@ public async Task RunExample(string projectFile, string verifiedFile)
6755
}
6856
var gotOutput = standardOutput.ToString();
6957

58+
var standardError = new StringBuilder();
59+
while (!process.StandardError.EndOfStream)
60+
{
61+
var line = process.StandardError.ReadLine();
62+
standardError.AppendLine(line);
63+
}
64+
var gotError = standardError.ToString();
65+
7066
// Wait for the process to exit
7167
process.WaitForExit();
7268

7369
// Verify that the process exited successfully
7470
Assert.True(process.ExitCode == 0, $"""
7571
The process exited with a non-zero exit code ({process.ExitCode}).
76-
{DescriptionForNotInstalledToolchain}
72+
Message: {gotError}
73+
{TestUtils.DescriptionForNotInstalledToolchain}
7774
""");
7875

7976
// Configure verifier
@@ -84,4 +81,22 @@ public async Task RunExample(string projectFile, string verifiedFile)
8481
// Compare output to the verified file
8582
await Verify(gotOutput, settings);
8683
}
84+
85+
[Fact, TestPriority(2)]
86+
public void DesignTimeBuild()
87+
{
88+
// Iniitialize the workspace
89+
var workspace = Workspace.Initialize(TestUtils.ExamplesDirectory);
90+
91+
// Assert we have projects in there
92+
var projects = workspace.Projects.ToList();
93+
Assert.NotEmpty(projects);
94+
95+
// Run the design time build for each
96+
foreach (var project in projects)
97+
{
98+
var buildResult = project.BuildDesignTime();
99+
Assert.True(buildResult.Success, buildResult.Log);
100+
}
101+
}
87102
}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
using Xunit.Abstractions;
2+
using Xunit.Sdk;
3+
4+
namespace Draco.Examples.Tests;
5+
6+
internal sealed class PriorityOrderer : ITestCaseOrderer
7+
{
8+
public IEnumerable<TTestCase> OrderTestCases<TTestCase>(IEnumerable<TTestCase> testCases) where TTestCase : ITestCase
9+
{
10+
var sortedMethods = new SortedDictionary<int, List<TTestCase>>();
11+
12+
foreach (var testCase in testCases)
13+
{
14+
var priority = 0;
15+
16+
foreach (var attr in testCase.TestMethod.Method.GetCustomAttributes((typeof(TestPriorityAttribute).AssemblyQualifiedName)))
17+
{
18+
priority = attr.GetNamedArgument<int>("Priority");
19+
}
20+
21+
GetOrCreate(sortedMethods, priority).Add(testCase);
22+
}
23+
24+
foreach (var list in sortedMethods.Keys.Select(priority => sortedMethods[priority]))
25+
{
26+
list.Sort((x, y) => StringComparer.OrdinalIgnoreCase.Compare(x.TestMethod.Method.Name, y.TestMethod.Method.Name));
27+
foreach (var testCase in list)
28+
{
29+
yield return testCase;
30+
}
31+
}
32+
}
33+
34+
private static TValue GetOrCreate<TKey, TValue>(IDictionary<TKey, TValue> dictionary, TKey key)
35+
where TValue : new()
36+
{
37+
if (dictionary.TryGetValue(key, out var result)) return result;
38+
39+
result = new();
40+
dictionary[key] = result;
41+
42+
return result;
43+
}
44+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
namespace Draco.Examples.Tests;
2+
3+
[AttributeUsage(AttributeTargets.Method, AllowMultiple = false)]
4+
public sealed class TestPriorityAttribute(int priority) : Attribute
5+
{
6+
public int Priority => priority;
7+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
namespace Draco.Examples.Tests;
2+
3+
/// <summary>
4+
/// Utilities for these tests.
5+
/// </summary>
6+
internal static class TestUtils
7+
{
8+
/// <summary>
9+
/// A string describing that the toolchain needs to be installed in the examples directory.
10+
/// </summary>
11+
public const string DescriptionForNotInstalledToolchain = """
12+
Note, that you need to have the toolchain installed in the examples directory, in order to run these tests.
13+
You can do that by running the install_toolchain.ps1 script in the scripts directory and passing in the path to the examples directory.
14+
""";
15+
16+
/// <summary>
17+
/// The root examples directory.
18+
/// </summary>
19+
public const string ExamplesDirectory = "examples";
20+
21+
/// <summary>
22+
/// Retrieves all example project directories.
23+
/// </summary>
24+
public static IEnumerable<string> ExampleDirectories => Directory
25+
.GetDirectories(ExamplesDirectory, "*", SearchOption.TopDirectoryOnly)
26+
.Where(d => Path.GetFileName(d) != "Toolchain");
27+
}

src/Draco.LanguageServer/Draco.LanguageServer.csproj

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,16 @@
1717
<ItemGroup>
1818
<PackageReference Include="System.CommandLine" Version="2.0.0-beta4.22272.1" />
1919

20-
<PackageReference Include="NuGet.Frameworks" Version="6.11.0" ExcludeAssets="runtime" />
21-
<PackageReference Include="NuGet.Protocol" Version="6.11.0" ExlcudeAssets="runtime" />
22-
<PackageReference Include="NuGet.Packaging" Version="6.11.0" ExcludeAssets="runtime" />
23-
<PackageReference Include="NuGet.Common" Version="6.11.0" ExcludeAssets="runtime" />
24-
<PackageReference Include="NuGet.Versioning" Version="6.11.0" ExcludeAssets="runtime" />
25-
<PackageReference Include="NuGet.Configuration" Version="6.11.0" ExcludeAssets="runtime" />
20+
<PackageReference Include="NuGet.Frameworks" Version="6.14.0" ExcludeAssets="runtime" />
21+
<PackageReference Include="NuGet.Protocol" Version="6.14.0" ExlcudeAssets="runtime" />
22+
<PackageReference Include="NuGet.Packaging" Version="6.14.0" ExcludeAssets="runtime" />
23+
<PackageReference Include="NuGet.Common" Version="6.14.0" ExcludeAssets="runtime" />
24+
<PackageReference Include="NuGet.Versioning" Version="6.14.0" ExcludeAssets="runtime" />
25+
<PackageReference Include="NuGet.Configuration" Version="6.14.0" ExcludeAssets="runtime" />
26+
</ItemGroup>
27+
28+
<ItemGroup>
29+
<PackageReference Update="DotNet.ReproducibleBuilds" Version="1.2.25" />
2630
</ItemGroup>
2731

2832
</Project>
Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
<Project Sdk="Microsoft.NET.Sdk">
22
<ItemGroup>
3-
<PackageReference Include="Microsoft.Build.Locator" Version="1.7.8" />
4-
<PackageReference Include="Microsoft.Build" Version="17.10.4" ExcludeAssets="runtime" />
5-
<PackageReference Include="Microsoft.Build.Framework" Version="17.11.4" ExcludeAssets="runtime" />
6-
<PackageReference Include="Microsoft.Build.Tasks.Core" Version="17.11.4" ExcludeAssets="runtime" />
7-
<PackageReference Include="Microsoft.Build.Utilities.Core" Version="17.11.4" ExcludeAssets="runtime" />
8-
<PackageReference Include="NuGet.Frameworks" Version="6.11.0" ExcludeAssets="runtime" />
9-
<PackageReference Include="NuGet.Packaging" Version="6.11.0" ExcludeAssets="runtime" />
3+
<PackageReference Include="Microsoft.Build.Locator" Version="1.9.1" />
4+
<PackageReference Include="Microsoft.Build" Version="17.14.8" ExcludeAssets="runtime" />
5+
<PackageReference Include="Microsoft.Build.Framework" Version="17.14.8" ExcludeAssets="runtime" />
6+
<PackageReference Include="Microsoft.Build.Tasks.Core" Version="17.14.8" ExcludeAssets="runtime" />
7+
<PackageReference Include="Microsoft.Build.Utilities.Core" Version="17.14.8" ExcludeAssets="runtime" />
8+
<PackageReference Include="NuGet.Frameworks" Version="6.14.0" ExcludeAssets="runtime" />
9+
<PackageReference Include="NuGet.Packaging" Version="6.14.0" ExcludeAssets="runtime" />
1010
</ItemGroup>
1111
</Project>

0 commit comments

Comments
 (0)