/// <summary> /// Expects the action to throw an exception of type T /// </summary> /// <param name="src">Action to test</param> /// <typeparam name="T">Type of exception which is expected</typeparam> /// <returns>Continuaiotn which can be used to test exception messages</returns> public static IThrowContinuation Throw <T>( this ICanAddMatcher <Action> src ) where T : Exception { var continuation = new ThrowContinuation(); var expectedType = typeof(T); src.AddMatcher(fn => { MatcherResult result; try { fn(); result = new MatcherResult(false, $"Expected to throw an exception of type {expectedType.Name} but none was thrown"); } catch (Exception ex) { var passed = ex is T; var message = passed ? $"Expected not to throw an exception of type {expectedType.Name}" : $"Expected to throw an exception of type {expectedType.Name} but {ex.GetType().Name} was thrown instead ({ex.Message})"; result = new MatcherResult(passed, message); continuation.Exception = ex; } return(result); }); return(continuation); }
public LanguageMatcher Convert(string name, string ebnfText) { _ebnfText = ebnfText; _patternMatcherMap = new Dictionary <string, PatternMatcher>(StringComparer.Ordinal); _fragmentMatcherMap = new Dictionary <string, ValueTuple <FragmentMatcher, FragmentMatchData> >(StringComparer.Ordinal); _languageMatcher = new LanguageMatcher() { Name = name, Patterns = new List <PatternMatcher>(), Fragments = new List <FragmentMatcher>() }; MatcherResult matcherResult = _ebnfMatchEngine.Match(ebnfText); if (!matcherResult.Success) { throw new LanaguageSyntaxException($"Unsupported EBNF syntax", matcherResult.FailureIndex.Value); } foreach (FragmentMatcher defaultFragment in DefaultFragments) { AddFragmentMatcherAndParts(defaultFragment); } AddRules((FragmentMatchData)matcherResult.MatchData); _languageMatcher.IndexingMode = IndexingMode.Lazy; _languageMatcher.StartingFragment = _languageMatcher.Fragments.FirstOrDefault(); return(_languageMatcher); }
/// <summary> /// Expects the action to throw an exception of type T /// </summary> /// <param name="src">Action to test</param> /// <param name="customMessageGenerator">Custom message to add to failure messages</param> /// <typeparam name="T">Type of exception which is expected</typeparam> /// <returns>Continuation which can be used to test exception messages</returns> public static IThrowContinuation <T> Throw <T>( this ICanAddMatcher <Action> src, Func <string> customMessageGenerator ) where T : Exception { var continuation = new ThrowContinuation <T>(); var expectedType = typeof(T); src.AddMatcher( fn => { MatcherResult result; try { fn(); result = new MatcherResult( false, FinalMessageFor( () => $"Expected to throw an exception of type {expectedType.Name} but none was thrown", customMessageGenerator )); } catch (Exception actual) { var passed = actual is T; result = new MatcherResult( passed, FinalMessageFor( () => { var actualType = actual.GetType(); var haveSameName = expectedType.Name == actualType.Name; var expectedName = haveSameName ? $"{expectedType.Namespace}.{expectedType.Name}" : expectedType.Name; var actualName = haveSameName ? $"{actualType.Namespace}.{actualType.Name}" : actualType.Name; return(passed ? $@"Expected not to throw an exception of type {expectedName}" : $@"Expected to throw an exception of type { expectedName } but { actualName } was thrown instead ({ actual.Message })"); }, customMessageGenerator)); continuation.Exception = actual as T; } return(result); }); return(continuation); }
public void MatcherResultWithNoMessage(bool expected) { // Arrange // Pre-assert // Act var result = new MatcherResult(expected); // Assert Expect(result.Passed).To.Equal(expected); Expect(result.Message).To.Be.Empty(); }
public ComparisonResult Compare(dynamic expected, dynamic actual, IDictionary <string, IMatcher> matchingRules) { var result = new ComparisonResult("has a matching body"); if (expected == null) { return(result); } if (expected != null && actual == null) { result.RecordFailure(new ErrorMessageComparisonFailure("Actual Body is null")); return(result); } var expectedToken = JToken.FromObject(expected); var actualToken = JToken.FromObject(actual); foreach (var rule in matchingRules) { MatcherResult matchResult = rule.Value.Match(rule.Key, expectedToken, actualToken); //TODO: Maybe we should call this a list of differences var comparisonFailures = new List <ComparisonFailure>(); foreach (var failedCheck in matchResult.MatcherChecks.Where(x => x is FailedMatcherCheck).Cast <FailedMatcherCheck>()) { //TODO: We should be able to generate a better output, as we know exactly the path that failed var comparisonFailure = new DiffComparisonFailure(expectedToken, actualToken); if (comparisonFailures.All(x => x.Result != comparisonFailure.Result)) { comparisonFailures.Add(comparisonFailure); } } foreach (var failure in comparisonFailures) { result.RecordFailure(failure); } //TODO: When more than 1 rule deal with the situation when a success overrides a failure (either more specific rule or order it's applied?) } return(result); }
public static IThrowContinuation Throw(this IContinuation <Action> src) { var continuation = new ThrowContinuation(); src.AddMatcher(fn => { MatcherResult result; try { fn(); result = new MatcherResult(false, "Expected to throw an exception but none was thrown"); } catch (Exception ex) { continuation.Exception = ex; result = new MatcherResult(true, $"Exception thrown:\n${ex.Message}\n${ex.StackTrace}"); } return(result); }); return(continuation); }
/// <summary> /// Expects the action to throw an exception of type T /// </summary> /// <param name="src">Action to test</param> /// <param name="customMessageGenerator">Custom message to add to failure messages</param> /// <typeparam name="T">Type of exception which is expected</typeparam> /// <returns>Continuation which can be used to test exception messages</returns> public static IThrowContinuation <T> Throw <T>( this ICanAddMatcher <Action> src, Func <string> customMessageGenerator ) where T : Exception { var continuation = new ThrowContinuation <T>(); var expectedType = typeof(T); src.AddMatcher( fn => { MatcherResult result; try { fn(); result = new MatcherResult( false, FinalMessageFor( () => $"Expected to throw an exception of type {expectedType.Name} but none was thrown", customMessageGenerator )); } catch (Exception ex) { var passed = ex is T; result = new MatcherResult( passed, FinalMessageFor( () => passed ? $"Expected not to throw an exception of type {expectedType.Name}" : $"Expected to throw an exception of type {expectedType.Name} but {ex.GetType().Name} was thrown instead ({ex.Message})", customMessageGenerator)); continuation.Exception = ex as T; } return(result); }); return(continuation); }
public void ConversionTest(string grammarFileName, int numRules) { const string fileDirectory = "Interop/Ebnf/Files"; string ebnf = File.ReadAllText(Path.Combine(fileDirectory, "Grammars", grammarFileName)); EbnfConverter ebnfConverter = new EbnfConverter(); LanguageMatcher languageMatcher = ebnfConverter.Convert("ebnf", ebnf); Assert.Equal(numRules, languageMatcher.Fragments.Count(f => !f.FallThrough)); string parsable = File.ReadAllText(Path.Combine(fileDirectory, "Parsables", "abc.txt")); Stopwatch watch = new Stopwatch(); watch.Start(); LanguageMatchEngine languageMatchEngine = LanguageMatchEngine.Build(languageMatcher); MatcherResult result = languageMatchEngine.Match(parsable); watch.Stop(); Assert.True(result.Success); }
/// <summary> /// Expects the Action to throw any kind of exception /// </summary> /// <param name="src">Action to run</param> /// <param name="customMessageGenerator">Custom message to add to failure messages</param> /// <returns>Continuation which can be used to test exception messages</returns> public static IThrowContinuation <Exception> Throw( this ICanAddMatcher <Action> src, Func <string> customMessageGenerator ) { var continuation = new ThrowContinuation <Exception>(); src.AddMatcher( fn => { MatcherResult result; try { fn(); result = new MatcherResult( false, FinalMessageFor( () => "Expected to throw an exception but none was thrown", customMessageGenerator ) ); } catch (Exception ex) { continuation.Exception = ex; result = new MatcherResult( true, FinalMessageFor( () => $"Exception thrown:\n{ex.Message}\n{ex.StackTrace}", customMessageGenerator ), ex); } return(result); }); return(continuation); }
public ComparisonResult Compare(dynamic expected, dynamic actual, IDictionary <string, IMatcher> matchingRules) { var result = new ComparisonResult("has matching content"); if (expected == null) { return(result); } if (expected != null && actual == null) { result.RecordFailure(new ErrorMessageComparisonFailure("Actual Content is null")); return(result); } var expectedTokens = JToken.FromObject(expected); //serializing first to match the same process as loading the pact from file var actualTokens = JToken.Parse(JsonConvert.SerializeObject(actual)); foreach (var rule in matchingRules) { MatcherResult matchResult = rule.Value.Match(rule.Key, expectedTokens, actualTokens); foreach (var check in matchResult.MatcherChecks) { if (check is FailedMatcherCheck) { result.RecordFailure(new ErrorMessageComparisonFailure($"Path {check.Path}, expected: {expectedTokens.SelectToken(check.Path)}, actual: {actualTokens.SelectToken(check.Path)}")); } } } return(result); }