Last active
May 4, 2021 15:07
-
-
Save egil/ddb05663c500c015515ec2cb1df090f7 to your computer and use it in GitHub Desktop.
C# source code comparison / assertion helper (depends on the packages Microsoft.CodeAnalysis.CSharp and DiffPlex).
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Text; | |
using DiffPlex.DiffBuilder; | |
using DiffPlex.DiffBuilder.Model; | |
using FluentAssertions.Execution; | |
using FluentAssertions.Primitives; | |
using Microsoft.CodeAnalysis; | |
using Microsoft.CodeAnalysis.CSharp; | |
namespace FluentAssertions | |
{ | |
public static class StringAssertionExtensions | |
{ | |
public static AndConstraint<StringAssertions> HaveEquivalentSyntaxTreeTo(this StringAssertions assertions, string expectedCode) | |
{ | |
var subject = CSharpSyntaxTree.ParseText(assertions.Subject); | |
var expected = CSharpSyntaxTree.ParseText(expectedCode); | |
Execute.Assertion | |
.ForCondition(subject.IsEquivalentTo(expected, topLevel: false)) | |
.FailWith(() => | |
{ | |
var formattedSubject = subject.GetRoot().NormalizeWhitespace(eol: Environment.NewLine).GetText().ToString(); | |
var formattedExpected = expected.GetRoot().NormalizeWhitespace(eol: Environment.NewLine).GetText().ToString(); | |
var msgBuilder = new StringBuilder(); | |
msgBuilder.AppendLine("Expected the syntax tree for: "); | |
msgBuilder.AppendLine(); | |
msgBuilder.Append(" "); | |
msgBuilder.AppendLine(formattedSubject.Replace(Environment.NewLine, $"{Environment.NewLine} ", StringComparison.Ordinal)); | |
msgBuilder.AppendLine(); | |
msgBuilder.AppendLine("To be equivalent to the syntax tree for: "); | |
msgBuilder.AppendLine(); | |
msgBuilder.Append(" "); | |
msgBuilder.AppendLine(formattedExpected.Replace(Environment.NewLine, $"{Environment.NewLine} ", StringComparison.Ordinal)); | |
msgBuilder.AppendLine(); | |
msgBuilder.AppendLine("The diff between the two is:"); | |
msgBuilder.AppendLine(); | |
var diff = InlineDiffBuilder.Diff(formattedExpected, formattedSubject, ignoreWhiteSpace: true); | |
foreach (var line in diff.Lines) | |
{ | |
switch (line.Type) | |
{ | |
case ChangeType.Inserted: | |
msgBuilder.Append("+ "); | |
break; | |
case ChangeType.Deleted: | |
msgBuilder.Append("- "); | |
break; | |
default: | |
msgBuilder.Append(" "); | |
break; | |
} | |
msgBuilder.AppendLine(line.Text); | |
} | |
var msg = msgBuilder.Replace("{", "{{").Replace("}", "}}").ToString(); | |
return new FailReason(msg); | |
}); | |
return new AndConstraint<StringAssertions>(assertions); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
This allows you to do: