Skip to content
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
4 changes: 4 additions & 0 deletions src/Draco.Examples.Tests/Draco.Examples.Tests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@
<IsTestProject>true</IsTestProject>
</PropertyGroup>

<ItemGroup>
<ProjectReference Include="..\Draco.ProjectSystem\Draco.ProjectSystem.csproj" />
</ItemGroup>

<ItemGroup>
<PackageReference Include="coverlet.collector" Version="6.0.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.8.0" />
Expand Down
67 changes: 41 additions & 26 deletions src/Draco.Examples.Tests/ExamplesTests.cs
Original file line number Diff line number Diff line change
@@ -1,43 +1,31 @@
using System.Diagnostics;
using System.Text;
using DiffEngine;
using Draco.ProjectSystem;

namespace Draco.Examples.Tests;

// NOTE: Unnfortunately the tooling seemms to have a race condition if we attempt a design-time build here
// So we order to first run the examples, and then the design-time build
[TestCaseOrderer("Draco.Examples.Tests.PriorityOrderer", "Draco.Examples.Tests")]
public sealed class ExamplesTests
{
public static IEnumerable<object[]> TestData
{
get
// Each directory contains a projectfile, and a verification file, return each pair
public static IEnumerable<object[]> TestData => TestUtils.ExampleDirectories
.Select(directory => new object[]
{
// Get all example projects
// We exclude the "Toolchain" folder, in case the user has installed it in the examples directory
var exampleProjectDirectories = Directory
.GetDirectories("examples", "*", SearchOption.TopDirectoryOnly)
.Where(d => Path.GetFileName(d) != "Toolchain");
// Each directory contains a projectfile, and a verification file, return each pair
return exampleProjectDirectories
.Select(directory => new object[]
{
// Search for the dracoproj file
Directory.GetFiles(directory, "*.dracoproj").Single(),
// The verification file is always named "verify.txt"
Path.Combine(directory, "verify.txt"),
});
}
}

private const string DescriptionForNotInstalledToolchain = """
Note, that you need to have the toolchain installed in the examples directory, in order to run these tests.
You can do that by running the install_toolchain.ps1 script in the scripts directory and passing in the path to the examples directory.
""";
// Search for the dracoproj file
Directory.GetFiles(directory, "*.dracoproj").Single(),
// The verification file is always named "verify.txt"
Path.Combine(directory, "verify.txt"),
});

public ExamplesTests()
{
DiffTools.UseOrder(DiffTool.VisualStudioCode, DiffTool.VisualStudio, DiffTool.Rider);
}

[Theory]
[Theory, TestPriority(1)]
[MemberData(nameof(TestData))]
public async Task RunExample(string projectFile, string verifiedFile)
{
Expand Down Expand Up @@ -67,13 +55,22 @@ public async Task RunExample(string projectFile, string verifiedFile)
}
var gotOutput = standardOutput.ToString();

var standardError = new StringBuilder();
while (!process.StandardError.EndOfStream)
{
var line = process.StandardError.ReadLine();
standardError.AppendLine(line);
}
var gotError = standardError.ToString();

// Wait for the process to exit
process.WaitForExit();

// Verify that the process exited successfully
Assert.True(process.ExitCode == 0, $"""
The process exited with a non-zero exit code ({process.ExitCode}).
{DescriptionForNotInstalledToolchain}
Message: {gotError}
{TestUtils.DescriptionForNotInstalledToolchain}
""");

// Configure verifier
Expand All @@ -84,4 +81,22 @@ public async Task RunExample(string projectFile, string verifiedFile)
// Compare output to the verified file
await Verify(gotOutput, settings);
}

[Fact, TestPriority(2)]
public void DesignTimeBuild()
{
// Iniitialize the workspace
var workspace = Workspace.Initialize(TestUtils.ExamplesDirectory);

// Assert we have projects in there
var projects = workspace.Projects.ToList();
Assert.NotEmpty(projects);

// Run the design time build for each
foreach (var project in projects)
{
var buildResult = project.BuildDesignTime();
Assert.True(buildResult.Success, buildResult.Log);
}
}
}
44 changes: 44 additions & 0 deletions src/Draco.Examples.Tests/PriorityOrderer.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
using Xunit.Abstractions;
using Xunit.Sdk;

namespace Draco.Examples.Tests;

internal sealed class PriorityOrderer : ITestCaseOrderer
{
public IEnumerable<TTestCase> OrderTestCases<TTestCase>(IEnumerable<TTestCase> testCases) where TTestCase : ITestCase
{
var sortedMethods = new SortedDictionary<int, List<TTestCase>>();

foreach (var testCase in testCases)
{
var priority = 0;

foreach (var attr in testCase.TestMethod.Method.GetCustomAttributes((typeof(TestPriorityAttribute).AssemblyQualifiedName)))
{
priority = attr.GetNamedArgument<int>("Priority");
}

GetOrCreate(sortedMethods, priority).Add(testCase);
}

foreach (var list in sortedMethods.Keys.Select(priority => sortedMethods[priority]))
{
list.Sort((x, y) => StringComparer.OrdinalIgnoreCase.Compare(x.TestMethod.Method.Name, y.TestMethod.Method.Name));
foreach (var testCase in list)
{
yield return testCase;
}
}
}

private static TValue GetOrCreate<TKey, TValue>(IDictionary<TKey, TValue> dictionary, TKey key)
where TValue : new()
{
if (dictionary.TryGetValue(key, out var result)) return result;

result = new();
dictionary[key] = result;

return result;
}
}
7 changes: 7 additions & 0 deletions src/Draco.Examples.Tests/TestPriorityAttribute.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
namespace Draco.Examples.Tests;

[AttributeUsage(AttributeTargets.Method, AllowMultiple = false)]
public sealed class TestPriorityAttribute(int priority) : Attribute
{
public int Priority => priority;
}
27 changes: 27 additions & 0 deletions src/Draco.Examples.Tests/TestUtils.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
namespace Draco.Examples.Tests;

/// <summary>
/// Utilities for these tests.
/// </summary>
internal static class TestUtils
{
/// <summary>
/// A string describing that the toolchain needs to be installed in the examples directory.
/// </summary>
public const string DescriptionForNotInstalledToolchain = """
Note, that you need to have the toolchain installed in the examples directory, in order to run these tests.
You can do that by running the install_toolchain.ps1 script in the scripts directory and passing in the path to the examples directory.
""";

/// <summary>
/// The root examples directory.
/// </summary>
public const string ExamplesDirectory = "examples";

/// <summary>
/// Retrieves all example project directories.
/// </summary>
public static IEnumerable<string> ExampleDirectories => Directory
.GetDirectories(ExamplesDirectory, "*", SearchOption.TopDirectoryOnly)
.Where(d => Path.GetFileName(d) != "Toolchain");
}
12 changes: 6 additions & 6 deletions src/Draco.LanguageServer/Draco.LanguageServer.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,12 @@
<ItemGroup>
<PackageReference Include="System.CommandLine" Version="2.0.0-beta4.22272.1" />

<PackageReference Include="NuGet.Frameworks" Version="6.11.0" ExcludeAssets="runtime" />
<PackageReference Include="NuGet.Protocol" Version="6.11.0" ExlcudeAssets="runtime" />
<PackageReference Include="NuGet.Packaging" Version="6.11.0" ExcludeAssets="runtime" />
<PackageReference Include="NuGet.Common" Version="6.11.0" ExcludeAssets="runtime" />
<PackageReference Include="NuGet.Versioning" Version="6.11.0" ExcludeAssets="runtime" />
<PackageReference Include="NuGet.Configuration" Version="6.11.0" ExcludeAssets="runtime" />
<PackageReference Include="NuGet.Frameworks" Version="6.14.0" ExcludeAssets="runtime" />
<PackageReference Include="NuGet.Protocol" Version="6.14.0" ExlcudeAssets="runtime" />
<PackageReference Include="NuGet.Packaging" Version="6.14.0" ExcludeAssets="runtime" />
<PackageReference Include="NuGet.Common" Version="6.14.0" ExcludeAssets="runtime" />
<PackageReference Include="NuGet.Versioning" Version="6.14.0" ExcludeAssets="runtime" />
<PackageReference Include="NuGet.Configuration" Version="6.14.0" ExcludeAssets="runtime" />
</ItemGroup>

</Project>
14 changes: 7 additions & 7 deletions src/Draco.ProjectSystem/Draco.ProjectSystem.csproj
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
<Project Sdk="Microsoft.NET.Sdk">
<ItemGroup>
<PackageReference Include="Microsoft.Build.Locator" Version="1.7.8" />
<PackageReference Include="Microsoft.Build" Version="17.10.4" ExcludeAssets="runtime" />
<PackageReference Include="Microsoft.Build.Framework" Version="17.11.4" ExcludeAssets="runtime" />
<PackageReference Include="Microsoft.Build.Tasks.Core" Version="17.11.4" ExcludeAssets="runtime" />
<PackageReference Include="Microsoft.Build.Utilities.Core" Version="17.11.4" ExcludeAssets="runtime" />
<PackageReference Include="NuGet.Frameworks" Version="6.11.0" ExcludeAssets="runtime" />
<PackageReference Include="NuGet.Packaging" Version="6.11.0" ExcludeAssets="runtime" />
<PackageReference Include="Microsoft.Build.Locator" Version="1.9.1" />
<PackageReference Include="Microsoft.Build" Version="17.14.8" ExcludeAssets="runtime" />
<PackageReference Include="Microsoft.Build.Framework" Version="17.14.8" ExcludeAssets="runtime" />
<PackageReference Include="Microsoft.Build.Tasks.Core" Version="17.14.8" ExcludeAssets="runtime" />
<PackageReference Include="Microsoft.Build.Utilities.Core" Version="17.14.8" ExcludeAssets="runtime" />
<PackageReference Include="NuGet.Frameworks" Version="6.14.0" ExcludeAssets="runtime" />
<PackageReference Include="NuGet.Packaging" Version="6.14.0" ExcludeAssets="runtime" />
</ItemGroup>
</Project>
Loading