Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
ThorstenThiel committed Aug 8, 2024
1 parent 50316b1 commit b8269d7
Show file tree
Hide file tree
Showing 38 changed files with 2,531 additions and 2 deletions.
30 changes: 30 additions & 0 deletions src/Fluss.Regen/Fluss.Regen.Tests/Fluss.Regen.Tests.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<Nullable>enable</Nullable>

<IsPackable>false</IsPackable>

<RootNamespace>Fluss.Regen.Tests</RootNamespace>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.CodeAnalysis.CSharp.SourceGenerators.Testing.XUnit" Version="1.1.1"/>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.6.2"/>
<PackageReference Include="Snapshooter.Xunit" Version="0.14.1" />
<PackageReference Include="xunit" Version="2.4.2"/>
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.5">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\Fluss.Regen\Fluss.Regen.csproj"/>
</ItemGroup>

<ItemGroup>
<PackageReference Include="DiffPlex" Version="1.7.1" />
</ItemGroup>
</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
using Fluss.Regen.Tests.Utils.Extensions;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Xunit;

namespace Fluss.Regen.Tests;

public class SampleIncrementalSourceGeneratorTests
{
[Fact]
public void GeneratesForSimpleTest()
{
var generator = new AutoLoadGenerator();

var driver = CSharpGeneratorDriver.Create(generator);

var compilation = CSharpCompilation.Create(nameof(SampleIncrementalSourceGeneratorTests),
[CSharpSyntaxTree.ParseText(
@"
using Fluss.Regen;
namespace TestNamespace;
public class Test
{
[Selector]
public int Add(int a, int b) {
return a + b;
}
}")],
new[]
{
MetadataReference.CreateFromFile(typeof(object).Assembly.Location)
});

var runResult = driver.RunGenerators(compilation).GetRunResult();

// TODO: Switch to the markdown based snapshot writer from HotChocolate
runResult.MatchMarkdownSnapshot();
}
}
41 changes: 41 additions & 0 deletions src/Fluss.Regen/Fluss.Regen.Tests/SnapshooterSettings.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
using System;
using Microsoft.CodeAnalysis;
using Newtonsoft.Json;
using Snapshooter.Core.Serialization;

namespace Fluss.Regen.Tests;

public class SnapshooterSettings : SnapshotSerializerSettings
{
public override JsonSerializerSettings Extend(JsonSerializerSettings settings)
{
settings.Converters.Add(new SyntaxTreeConverter());

return settings;
}

private class SyntaxTreeConverter : JsonConverter
{
public override void WriteJson(JsonWriter writer, object? value, JsonSerializer serializer)
{
if (value is not SyntaxTree syntaxTree) return;

writer.WriteStartObject();
writer.WritePropertyName("FilePath");
writer.WriteValue(syntaxTree.FilePath);
writer.WritePropertyName("Content");
writer.WriteRawValue(syntaxTree.ToString());
writer.WriteEndObject();
}

public override object? ReadJson(JsonReader reader, Type objectType, object? existingValue, JsonSerializer serializer)
{
throw new NotImplementedException();
}

public override bool CanConvert(Type objectType)
{
return objectType.IsAssignableTo(typeof(SyntaxTree));
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
using System.Globalization;
using System.Reflection;

namespace Fluss.Regen.Tests.Utils.Extensions;

/// <summary>
/// The method base extension is used to add more functionality
/// to the class <see cref="MethodBase"/>
/// </summary>
internal static class MethodBaseExtension
{
/// <summary>
/// Creates the name of the method with class name.
/// </summary>
/// <param name="methodBase">The used method name to get the name.</param>
public static string ToName(this MethodBase methodBase)
=> string.Concat(
methodBase.ReflectedType!.Name.ToString(CultureInfo.InvariantCulture), ".",
methodBase.Name.ToString(CultureInfo.InvariantCulture), ".snap");
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
using Fluss.Regen.Tests.Utils.Formatters;

namespace Fluss.Regen.Tests.Utils.Extensions;

public static class SnapshotExtensions
{
public static void MatchInlineSnapshot(
this object? value,
string snapshot,
ISnapshotValueFormatter? formatter = null)
=> Snapshot.Create().Add(value, formatter: formatter).MatchInline(snapshot);

public static void MatchSnapshot(this Snapshot value)
=> value.Match();

public static void MatchSnapshot(
this object? value,
object? postFix = null,
string? extension = null,
ISnapshotValueFormatter? formatter = null)
=> Snapshot.Match(value, postFix?.ToString(), extension, formatter);

public static void MatchMarkdownSnapshot(
this object? value,
object? postFix = null,
string? extension = null,
ISnapshotValueFormatter? formatter = null)
=> Snapshot.Create(postFix?.ToString(), extension).Add(value, formatter: formatter).MatchMarkdown();

public static void MatchMarkdownSnapshot(this Snapshot value)
=> value.MatchMarkdown();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
using System;
using System.Collections.Generic;

namespace Fluss.Regen.Tests.Utils.Extensions;

/// <summary>
/// Some extensions for Type, to support snapshot testing.
/// </summary>
internal static class TypeExtensions
{
/// <summary>
/// Returns the list of inherited types.
/// </summary>
/// <param name="type">The current object type.</param>
/// <returns>The list of all inherited types.</returns>
public static IEnumerable<Type> BaseTypesAndSelf(this Type type)
{
var current = type;

while (current != null)
{
yield return current;
current = current.BaseType;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
using System;
using System.Buffers;
using System.Text;

namespace Fluss.Regen.Tests.Utils.Extensions;

public static class WriterExtensions
{
private static readonly Encoding _utf8 = Encoding.UTF8;

public static void Append(this IBufferWriter<byte> snapshot, string value)
=> Append(snapshot, value.AsSpan());

public static void Append(this IBufferWriter<byte> snapshot, ReadOnlySpan<char> value)
{
_utf8.GetBytes(value, snapshot);
}

public static void AppendLine(this IBufferWriter<byte> snapshot)
{
snapshot.GetSpan(1)[0] = (byte)'\n';
snapshot.Advance(1);
}

public static void AppendLine(this IBufferWriter<byte> snapshot, bool appendWhenTrue)
{
if (!appendWhenTrue)
{
return;
}

snapshot.GetSpan(1)[0] = (byte)'\n';
snapshot.Advance(1);
}

public static void AppendSeparator(this IBufferWriter<byte> snapshot)
{
const byte hyphen = (byte)'-';
var span = snapshot.GetSpan(15);

for(var i = 0; i < 15; i++)
{
span[i] = hyphen;
}

snapshot.Advance(15);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
using System;
using System.Buffers;
using Fluss.Regen.Tests.Utils.Extensions;

namespace Fluss.Regen.Tests.Utils.Formatters;

public class ExceptionSnapshotValueFormatter : SnapshotValueFormatter<Exception>
{
protected override void Format(IBufferWriter<byte> snapshot, Exception value)
{
snapshot.Append(value.GetType().FullName ?? value.GetType().Name);
snapshot.AppendLine();
snapshot.Append(value.Message);
snapshot.AppendLine();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
using System;
using System.Buffers;
using Fluss.Regen.Tests.Utils.Extensions;
using Microsoft.CodeAnalysis;

namespace Fluss.Regen.Tests.Utils.Formatters;

public class GeneratorDriverRunResultSnapshotValueFormatter : SnapshotValueFormatter<GeneratorDriverRunResult>
{
protected override void Format(IBufferWriter<byte> snapshot, GeneratorDriverRunResult value)
{
throw new NotImplementedException();
}

protected override void FormatMarkdown(IBufferWriter<byte> snapshot, GeneratorDriverRunResult value)
{
foreach (var tree in value.GeneratedTrees)
{
snapshot.Append($"## {tree.FilePath}");
snapshot.AppendLine();
snapshot.Append("```csharp");
snapshot.AppendLine();
snapshot.Append(tree.GetText().ToString());
snapshot.AppendLine();
snapshot.Append("```");
snapshot.AppendLine();
snapshot.AppendLine();
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
using System.Buffers;
using System.Linq;
using System.Net.Http;
using Fluss.Regen.Tests.Utils.Extensions;

namespace Fluss.Regen.Tests.Utils.Formatters;

public class HttpResponseSnapshotValueFormatter : SnapshotValueFormatter<HttpResponseMessage>
{
protected override void Format(IBufferWriter<byte> snapshot, HttpResponseMessage value)
{
var first = true;

foreach (var header in value.Headers.Concat(value.Content.Headers))
{
if (first)
{
snapshot.Append("Headers:");
snapshot.AppendLine();
first = false;
}

snapshot.Append($"{header.Key}: {string.Join(" ", header.Value)}");
snapshot.AppendLine();
}

if (!first)
{
snapshot.Append("-------------------------->");
snapshot.AppendLine();
}

snapshot.Append($"Status Code: {value.StatusCode}");

snapshot.AppendLine();
snapshot.Append("-------------------------->");
snapshot.AppendLine();

snapshot.Append(value.Content.ReadAsStringAsync().Result);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
using System.Buffers;

namespace Fluss.Regen.Tests.Utils.Formatters;

/// <summary>
/// Formats a snapshot segment value for the snapshot file.
/// </summary>
public interface IMarkdownSnapshotValueFormatter
{
/// <summary>
/// Specifies if the formatter can handle the snapshot segment value.
/// </summary>
/// <param name="value">
/// The snapshot segment value.
/// </param>
/// <returns>
/// <c>true</c> if the formatter can handle the snapshot segment value;
/// otherwise, <c>false</c>.
/// </returns>
bool CanHandle(object? value);

/// <summary>
/// Formats the specified snapshot segment value for the snapshot file.
/// </summary>
/// <param name="snapshot">
/// The snapshot file writer.
/// </param>
/// <param name="value">
/// The snapshot segment vale.
/// </param>
void FormatMarkdown(IBufferWriter<byte> snapshot, object? value);
}
Loading

0 comments on commit b8269d7

Please sign in to comment.