Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Reintroduce C# files in all projects, now that the .NET Core project …
…structure has been set up to house them.
- Loading branch information
Showing
50 changed files
with
3,551 additions
and
0 deletions.
There are no files selected for viewing
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
namespace Parsley.Tests | ||
{ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Linq; | ||
using Shouldly; | ||
|
||
public static class AssertionExtensions | ||
{ | ||
public static void ShouldThrow<TException>(this Action shouldThrow, string expectedMessage) where TException : Exception | ||
{ | ||
bool threw = false; | ||
|
||
try | ||
{ | ||
shouldThrow(); | ||
} | ||
catch (TException ex) | ||
{ | ||
ex.Message.ShouldBe(expectedMessage); | ||
threw = true; | ||
} | ||
|
||
threw.ShouldBeTrue($"Expected {typeof (TException).Name}."); | ||
} | ||
|
||
public static void ShouldThrow<TException>(this Func<object> shouldThrow, string expectedMessage) where TException : Exception | ||
{ | ||
Action action = () => shouldThrow(); | ||
action.ShouldThrow<TException>(expectedMessage); | ||
} | ||
|
||
public static void ShouldList<T>(this IEnumerable<T> actual, params Action<T>[] itemExpectations) | ||
{ | ||
var array = actual.ToArray(); | ||
|
||
array.Length.ShouldBe(itemExpectations.Length); | ||
|
||
for (int i = 0; i < array.Length; i++) | ||
itemExpectations[i](array[i]); | ||
} | ||
} | ||
} |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
namespace Parsley.Tests | ||
{ | ||
public class CharLexer : Lexer | ||
{ | ||
public CharLexer() | ||
: base(new Pattern("Character", @".")) { } | ||
} | ||
} |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,140 @@ | ||
namespace Parsley.Tests | ||
{ | ||
using Shouldly; | ||
using Xunit; | ||
using ErrorMessage = Parsley.ErrorMessage; | ||
|
||
public class ErrorMessageListTests | ||
{ | ||
[Fact] | ||
public void ShouldProvideSharedEmptyInstance() | ||
{ | ||
ErrorMessageList.Empty.ShouldBeSameAs(ErrorMessageList.Empty); | ||
} | ||
|
||
[Fact] | ||
public void CanBeEmpty() | ||
{ | ||
ErrorMessageList.Empty.ToString().ShouldBe(""); | ||
} | ||
|
||
[Fact] | ||
public void CreatesNewCollectionWhenAddingItems() | ||
{ | ||
ErrorMessageList list = ErrorMessageList.Empty.With(ErrorMessage.Expected("expectation")); | ||
|
||
list.ToString().ShouldBe("expectation expected"); | ||
list.ShouldNotBeSameAs(ErrorMessageList.Empty); | ||
} | ||
|
||
[Fact] | ||
public void CanIncludeUnknownErrors() | ||
{ | ||
ErrorMessageList.Empty | ||
.With(ErrorMessage.Unknown()) | ||
.ToString().ShouldBe("Parse error."); | ||
} | ||
|
||
[Fact] | ||
public void CanIncludeMultipleExpectations() | ||
{ | ||
ErrorMessageList.Empty | ||
.With(ErrorMessage.Expected("A")) | ||
.With(ErrorMessage.Expected("B")) | ||
.ToString().ShouldBe("A or B expected"); | ||
|
||
ErrorMessageList.Empty | ||
.With(ErrorMessage.Expected("A")) | ||
.With(ErrorMessage.Expected("B")) | ||
.With(ErrorMessage.Expected("C")) | ||
.ToString().ShouldBe("A, B or C expected"); | ||
|
||
ErrorMessageList.Empty | ||
.With(ErrorMessage.Expected("A")) | ||
.With(ErrorMessage.Expected("B")) | ||
.With(ErrorMessage.Expected("C")) | ||
.With(ErrorMessage.Expected("D")) | ||
.ToString().ShouldBe("A, B, C or D expected"); | ||
} | ||
|
||
[Fact] | ||
public void OmitsDuplicateExpectationsFromExpectationLists() | ||
{ | ||
ErrorMessageList.Empty | ||
.With(ErrorMessage.Expected("A")) | ||
.With(ErrorMessage.Expected("A")) | ||
.With(ErrorMessage.Expected("B")) | ||
.With(ErrorMessage.Expected("C")) | ||
.With(ErrorMessage.Unknown()) | ||
.With(ErrorMessage.Expected("C")) | ||
.With(ErrorMessage.Expected("C")) | ||
.With(ErrorMessage.Expected("A")) | ||
.ToString().ShouldBe("A, B or C expected"); | ||
} | ||
|
||
[Fact] | ||
public void CanIncludeBacktrackErrors() | ||
{ | ||
var deepBacktrack = ErrorMessage.Backtrack(new Position(3, 4), | ||
ErrorMessageList.Empty | ||
.With(ErrorMessage.Expected("A")) | ||
.With(ErrorMessage.Expected("B"))); | ||
|
||
var shallowBacktrack = ErrorMessage.Backtrack(new Position(2, 3), | ||
ErrorMessageList.Empty | ||
.With(ErrorMessage.Expected("C")) | ||
.With(ErrorMessage.Expected("D")) | ||
.With(deepBacktrack)); | ||
|
||
var unrelatedBacktrack = ErrorMessage.Backtrack(new Position(1, 2), | ||
ErrorMessageList.Empty | ||
.With(ErrorMessage.Expected("E")) | ||
.With(ErrorMessage.Expected("F"))); | ||
|
||
ErrorMessageList.Empty | ||
.With(deepBacktrack) | ||
.ToString().ShouldBe("[(3, 4): A or B expected]"); | ||
|
||
ErrorMessageList.Empty | ||
.With(shallowBacktrack) | ||
.ToString().ShouldBe("[(2, 3): C or D expected [(3, 4): A or B expected]]"); | ||
|
||
ErrorMessageList.Empty | ||
.With(ErrorMessage.Expected("G")) | ||
.With(ErrorMessage.Expected("H")) | ||
.With(shallowBacktrack) | ||
.With(unrelatedBacktrack) | ||
.ToString().ShouldBe("G or H expected [(1, 2): E or F expected] [(2, 3): C or D expected [(3, 4): A or B expected]]"); | ||
} | ||
|
||
[Fact] | ||
public void CanMergeTwoLists() | ||
{ | ||
var first = ErrorMessageList.Empty | ||
.With(ErrorMessage.Expected("A")) | ||
.With(ErrorMessage.Expected("B")) | ||
.With(ErrorMessage.Unknown()) | ||
.With(ErrorMessage.Expected("C")); | ||
|
||
var second = ErrorMessageList.Empty | ||
.With(ErrorMessage.Expected("D")) | ||
.With(ErrorMessage.Expected("B")) | ||
.With(ErrorMessage.Unknown()) | ||
.With(ErrorMessage.Expected("E")); | ||
|
||
first.Merge(second) | ||
.ToString().ShouldBe("A, B, C, D or E expected"); | ||
} | ||
|
||
[Fact] | ||
public void OmitsUnknownErrorsWhenAdditionalErrorsExist() | ||
{ | ||
ErrorMessageList.Empty | ||
.With(ErrorMessage.Expected("A")) | ||
.With(ErrorMessage.Expected("B")) | ||
.With(ErrorMessage.Unknown()) | ||
.With(ErrorMessage.Expected("C")) | ||
.ToString().ShouldBe("A, B or C expected"); | ||
} | ||
} | ||
} |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
namespace Parsley.Tests | ||
{ | ||
using Shouldly; | ||
using Xunit; | ||
using ErrorMessage = Parsley.ErrorMessage; | ||
|
||
public class ErrorMessageTests | ||
{ | ||
[Fact] | ||
public void CanIndicateGenericErrors() | ||
{ | ||
var error = ErrorMessage.Unknown(); | ||
error.ToString().ShouldBe("Parse error."); | ||
} | ||
|
||
[Fact] | ||
public void CanIndicateSpecificExpectation() | ||
{ | ||
var error = (ExpectedErrorMessage)ErrorMessage.Expected("statement"); | ||
error.Expectation.ShouldBe("statement"); | ||
error.ToString().ShouldBe("statement expected"); | ||
} | ||
|
||
[Fact] | ||
public void CanIndicateErrorsWhichCausedBacktracking() | ||
{ | ||
var position = new Position(3, 4); | ||
ErrorMessageList errors = ErrorMessageList.Empty | ||
.With(ErrorMessage.Expected("a")) | ||
.With(ErrorMessage.Expected("b")); | ||
|
||
var error = (BacktrackErrorMessage) ErrorMessage.Backtrack(position, errors); | ||
error.Position.ShouldBe(position); | ||
error.Errors.ShouldBe(errors); | ||
error.ToString().ShouldBe("(3, 4): a or b expected"); | ||
} | ||
} | ||
} |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
namespace Parsley.Tests | ||
{ | ||
using System; | ||
using Shouldly; | ||
using Xunit; | ||
using ErrorMessage = Parsley.ErrorMessage; | ||
|
||
public class ErrorTests | ||
{ | ||
readonly TokenStream x; | ||
readonly TokenStream endOfInput; | ||
|
||
public ErrorTests() | ||
{ | ||
var lexer = new Lexer(); | ||
x = new TokenStream(lexer.Tokenize("x")); | ||
endOfInput = new TokenStream(lexer.Tokenize("")); | ||
} | ||
|
||
[Fact] | ||
public void CanIndicateErrorsAtTheCurrentPosition() | ||
{ | ||
new Error<object>(endOfInput, ErrorMessage.Unknown()).ErrorMessages.ToString().ShouldBe("Parse error."); | ||
new Error<object>(endOfInput, ErrorMessage.Expected("statement")).ErrorMessages.ToString().ShouldBe("statement expected"); | ||
} | ||
|
||
[Fact] | ||
public void CanIndicateMultipleErrorsAtTheCurrentPosition() | ||
{ | ||
var errors = ErrorMessageList.Empty | ||
.With(ErrorMessage.Expected("A")) | ||
.With(ErrorMessage.Expected("B")); | ||
|
||
new Error<object>(endOfInput, errors).ErrorMessages.ToString().ShouldBe("A or B expected"); | ||
} | ||
|
||
[Fact] | ||
public void ThrowsWhenAttemptingToGetParsedValue() | ||
{ | ||
Func<object> inspectParsedValue = () => new Error<object>(x, ErrorMessage.Unknown()).Value; | ||
inspectParsedValue.ShouldThrow<MemberAccessException>("(1, 1): Parse error."); | ||
} | ||
|
||
[Fact] | ||
public void HasRemainingUnparsedTokens() | ||
{ | ||
new Error<object>(x, ErrorMessage.Unknown()).UnparsedTokens.ShouldBe(x); | ||
new Error<object>(endOfInput, ErrorMessage.Unknown()).UnparsedTokens.ShouldBe(endOfInput); | ||
} | ||
|
||
[Fact] | ||
public void ReportsErrorState() | ||
{ | ||
new Error<object>(x, ErrorMessage.Unknown()).Success.ShouldBeFalse(); | ||
} | ||
} | ||
} |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
namespace Parsley.Tests | ||
{ | ||
using System.Linq; | ||
using Shouldly; | ||
using Xunit; | ||
|
||
public class GrammarRuleTests : Grammar | ||
{ | ||
[Fact] | ||
public void CanDefineMutuallyRecursiveRules() | ||
{ | ||
var tokens = new CharLexer().Tokenize("(A)"); | ||
var expression = new GrammarRule<string>(); | ||
var alpha = new GrammarRule<string>(); | ||
var parenthesizedExpresion = new GrammarRule<string>(); | ||
|
||
expression.Rule = Choice(alpha, parenthesizedExpresion); | ||
alpha.Rule = from a in Token("A") select a.Literal; | ||
parenthesizedExpresion.Rule = Between(Token("("), expression, Token(")")); | ||
|
||
expression.Parses(tokens).WithValue("A"); | ||
} | ||
|
||
[Fact] | ||
public void HasAnOptionallyProvidedName() | ||
{ | ||
var unnamed = new GrammarRule<string>(); | ||
var named = new GrammarRule<string>("Named"); | ||
|
||
unnamed.Name.ShouldBeNull(); | ||
named.Name.ShouldBe("Named"); | ||
} | ||
|
||
[Fact] | ||
public void ProvidesAdviceWhenRuleIsUsedBeforeBeingInitialized() | ||
{ | ||
var tokens = new CharLexer().Tokenize("123").ToArray(); | ||
var numeric = new GrammarRule<string>(); | ||
var alpha = new GrammarRule<string>("Alpha"); | ||
|
||
numeric.FailsToParse(tokens).WithMessage("(1, 1): An anonymous GrammarRule has not been initialized. Try setting the Rule property."); | ||
alpha.FailsToParse(tokens).WithMessage("(1, 1): GrammarRule 'Alpha' has not been initialized. Try setting the Rule property."); | ||
} | ||
} | ||
} |
Oops, something went wrong.