diff --git a/Parser.Tests/DiagnosticExtensions.cs b/Parser.Tests/DiagnosticExtensions.cs new file mode 100644 index 0000000..13bac54 --- /dev/null +++ b/Parser.Tests/DiagnosticExtensions.cs @@ -0,0 +1,47 @@ +using System.Linq; + +namespace Parser.Tests +{ + public static class DiagnosticExtensions + { + public static bool IsEquivalentTo(this SyntaxDiagnostic[] actualSequence, params SyntaxDiagnostic[] expectedSequence) + { + if (actualSequence.Length != expectedSequence.Length) + { + return false; + } + + var actualSorted = actualSequence.OrderBy(x => x.Position).ToArray(); + var expectedSorted = expectedSequence.OrderBy(x => x.Position).ToArray(); + for (var i = 0; i < expectedSequence.Length; i++) + { + var expected = expectedSequence[i]; + var actual = actualSequence[i]; + if (expected.Position != actual.Position) + { + return false; + } + + if (expected is MissingTokenSyntaxDiagnostic expectedMissingToken) + { + if (!(actual is MissingTokenSyntaxDiagnostic actualMissingToken)) + { + return false; + } + + if (expectedMissingToken.Kind != actualMissingToken.Kind) + { + return false; + } + } + } + + return true; + } + + public static MissingTokenSyntaxDiagnostic MissingToken(int position, TokenKind kind) + { + return new MissingTokenSyntaxDiagnostic(position, kind); + } + } +} \ No newline at end of file diff --git a/Parser.Tests/MParserShould.cs b/Parser.Tests/MParserShould.cs index 938abc5..91bd393 100644 --- a/Parser.Tests/MParserShould.cs +++ b/Parser.Tests/MParserShould.cs @@ -2,6 +2,8 @@ namespace Parser.Tests { + using static DiagnosticExtensions; + public class MParserShould { private static MParser GetSut(string text) @@ -66,7 +68,7 @@ namespace Parser.Tests var sut = GetSut(text); var actual = sut.Parse(); var diagnostics = actual.Root.GetDiagnostics(); - Assert.Collection(actual.Diagnostics, item => Assert.Equal("Unexpected token 'SemicolonToken', expected 'IdentifierToken'.", item.Message)); + Assert.True(diagnostics.IsEquivalentTo(MissingToken(4, TokenKind.IdentifierToken))); } [Fact] diff --git a/Parser/MissingTokenSyntaxDiagnostic.cs b/Parser/MissingTokenSyntaxDiagnostic.cs new file mode 100644 index 0000000..bf3c5f9 --- /dev/null +++ b/Parser/MissingTokenSyntaxDiagnostic.cs @@ -0,0 +1,13 @@ +namespace Parser +{ + public class MissingTokenSyntaxDiagnostic : SyntaxDiagnostic + { + public TokenKind Kind { get; } + + public MissingTokenSyntaxDiagnostic(int position, TokenKind tokenKind) + : base(position) + { + Kind = tokenKind; + } + } +} \ No newline at end of file diff --git a/Parser/SyntaxDiagnostic.cs b/Parser/SyntaxDiagnostic.cs new file mode 100644 index 0000000..d0505e7 --- /dev/null +++ b/Parser/SyntaxDiagnostic.cs @@ -0,0 +1,23 @@ +namespace Parser +{ + public class SyntaxDiagnostic + { + public int Position { get; } + + public static SyntaxDiagnostic From(Internal.TokenDiagnostic diagnostic, int Position) + { + switch (diagnostic) + { + case Internal.MissingTokenDiagnostic missingToken: + return new MissingTokenSyntaxDiagnostic(Position, missingToken.Kind); + } + + throw new System.ArgumentOutOfRangeException(nameof(diagnostic)); + } + + protected SyntaxDiagnostic(int position) + { + Position = position; + } + } +} \ No newline at end of file diff --git a/Parser/SyntaxNode.cs b/Parser/SyntaxNode.cs index 54a8d74..e3db3e6 100644 --- a/Parser/SyntaxNode.cs +++ b/Parser/SyntaxNode.cs @@ -126,38 +126,6 @@ namespace Parser } } } - - public class SyntaxDiagnostic - { - public int Position { get; } - - public static SyntaxDiagnostic From(Internal.TokenDiagnostic diagnostic, int Position) - { - switch (diagnostic) - { - case Internal.MissingTokenDiagnostic missingToken: - return new MissingTokenSyntaxDiagnostic(Position, missingToken.Kind); - } - - throw new System.ArgumentOutOfRangeException(nameof(diagnostic)); - } - - protected SyntaxDiagnostic(int position) - { - Position = position; - } - } - - public class MissingTokenSyntaxDiagnostic : SyntaxDiagnostic - { - public TokenKind Kind { get; } - - internal MissingTokenSyntaxDiagnostic(int position, TokenKind tokenKind) - : base(position) - { - Kind = tokenKind; - } - } public abstract class StatementSyntaxNode : SyntaxNode {