/// <summary> /// Checks that the enumerable contains all the values present in another enumerable, in any order. /// </summary> /// <param name="check">The fluent check to be extended.</param> /// <param name="otherEnumerable">The enumerable containing the expected values to be found.</param> /// <returns> /// A check link. /// </returns> /// <exception cref="FluentCheckException"> /// The enumerable does not contain all the expected values present in the other enumerable. /// </exception> public static IExtendableCheckLink <IEnumerable, IEnumerable> Contains( this ICheck <IEnumerable> check, IEnumerable otherEnumerable) { IList <object> notFoundValues = null; ExtensibilityHelper.BeginCheck(check). FailsIf((sut) => sut == null && otherEnumerable != null, "The {0} is null and thus, does not contain the given expected value(s)."). ExpectingValues(otherEnumerable, otherEnumerable.Count()). Analyze((sut, _) => notFoundValues = ExtractNotFoundValues(sut, otherEnumerable)). FailsIf((_) => notFoundValues.Any(), string.Format( "The {{0}} does not contain the expected value(s):" + Environment.NewLine + "\t[{0}]", notFoundValues.ToEnumeratedString().DoubleCurlyBraces())). Negates("The {0} contains all the given values whereas it must not."). EndCheck(); return(ExtensibilityHelper.BuildExtendableCheckLink(check, otherEnumerable)); }
/// <summary> /// Checks that the CPU time is below a specified threshold. /// </summary> /// <typeparam name="T">Type of the checked type.</typeparam> /// <param name="check">The fluent check to be extended. /// </param> /// <param name="threshold"> /// The threshold. /// </param> /// <param name="timeUnit"> /// The time unit of the given threshold. /// </param> /// <returns> /// A check link. /// </returns> /// <exception cref="FluentCheckException"> /// Execution was strictly above limit. /// </exception> public static ICheckLink <ICheck <T> > ConsumesLessThan <T>( this ICheck <T> check, double threshold, TimeUnit timeUnit) where T : RunTrace { var durationThreshold = new Duration(threshold, timeUnit); ExtensibilityHelper.BeginCheck(check). CheckSutAttributes(sut => new Duration(sut.TotalProcessorTime, timeUnit), "cpu consumption"). FailWhen((sut) => sut > durationThreshold, "The {checked} was too high."). DefineExpectedValue(durationThreshold, "less than", "more than"). OnNegate("The {checked} was too low."). EndCheck(); return(ExtensibilityHelper.BuildCheckLink(check)); }
/// <summary> /// Checks that actual and given DateTime have same day, whatever the year or the month. /// </summary> /// <param name="check">The fluent check to be extended.</param> /// <param name="other">The other DateTime.</param> /// <returns> /// A check link. /// </returns> /// <exception cref="FluentCheckException">The checked date time day is not equal to the given day, whatever the year or the month.</exception> public static ICheckLink <ICheck <DateTime> > IsInSameDayAs(this ICheck <DateTime> check, DateTime other) { ExtensibilityHelper.BeginCheck(check) .Analyze((sut, test) => { if (sut.Day != other.Day) { test.Fail( $"The {{0}} has a different day than the {{1}} (actual: {sut.Day}, expected: {other.Day})"); } }) .ComparingTo(other, "same day", "different day") .OnNegate("The {0} has the same day as the {1} whereas it must not.") .EndCheck(); return(ExtensibilityHelper.BuildCheckLink(check)); }
/// <summary> /// Checks that when the actual and given DateTimeOffset have same offset, year, month, day, hour and minute fields, /// (Seconds and millisecond fields are ignored in comparison). /// <code> /// check can fail with dateTimeOffsets in same chronological second time window, e.g : /// 2000-01-01T00:<b>01:00</b>.000 and 2000-01-01T00:<b>00:59</b>.000. /// check fails as minute fields differ even if time difference is only 1s. /// </code> /// Code example : /// <code> /// // successful checks /// DateTimeOffset dateTimeOffset1 = new DateTimeOffset(new DateTime(2000, 1, 1, 23, 50, 0, 0), TimeSpan.Zero); /// DateTimeOffset dateTimeOffset2 = new DateTimeOffset(new DateTime(2000, 1, 1, 23, 50, 10, 456), TimeSpan.Zero); /// Check.That(dateTimeOffset1).IsEqualToIgnoringSeconds(dateTimeOffset2); /// // failing checks (even if time difference is only 1ms) /// DateTimeOffset dateTimeOffsetA = new DateTimeOffset(new DateTime(2000, 1, 1, 23, 50, 00, 000), TimeSpan.Zero); /// DateTimeOffset dateTimeOffsetB = new DateTimeOffset(new DateTime(2000, 1, 1, 23, 49, 59, 999), TimeSpan.Zero); /// Check.That(dateTimeOffsetA).IsEqualToIgnoringSeconds(dateTimeOffsetB); /// </code> /// </summary> /// <param name="check">The fluent check to be extended.</param> /// <param name="other">The other DateTimeOffSet.</param> /// <returns> /// A check link. /// </returns> /// <exception cref="FluentCheckException">The checked date time offset is not equal to the given one with second and millisecond fields ignored.</exception> public static ICheckLink <ICheck <DateTimeOffset> > IsEqualToIgnoringSeconds(this ICheck <DateTimeOffset> check, DateTimeOffset other) { ExtensibilityHelper.BeginCheck(check) .FailWhen(sut => sut.Offset != other.Offset, "The {0} is not equal to the {1} (ignoring seconds). The offsets are different.") .FailWhen(sut => sut.DateTime.Round(TimeUnit.Days) != other.DateTime.Round(TimeUnit.Days), "The {0} is not equal to the {1} (ignoring seconds). The dates are different.") .FailWhen(sut => sut.DateTime.Round(TimeUnit.Hours) != other.DateTime.Round(TimeUnit.Hours), "The {0} is not equal to the {1} (ignoring seconds). The time of day is different (Hours).") .FailWhen(sut => sut.DateTime.Round(TimeUnit.Minutes) != other.DateTime.Round(TimeUnit.Minutes), "The {0} is not equal to the {1} (ignoring seconds). The time of day is different (Minutes).") .ComparingTo(other, "same time up to the same minute", "different time up to the same minute") .OnNegate("The {0} is equal to the {1} (ignoring seconds) whereas it must not.", MessageOption.NoCheckedBlock) .EndCheck(); return(ExtensibilityHelper.BuildCheckLink(check)); }
/// <summary> /// Checks that the execution time is below a specified threshold. /// </summary> /// <typeparam name="T">Type of the checked type.</typeparam> /// <param name="check">The fluent check to be extended. /// </param> /// <param name="threshold"> /// The threshold. /// </param> /// <param name="timeUnit"> /// The time unit of the given threshold. /// </param> /// <returns> /// A check link. /// </returns> /// <exception cref="FluentCheckException"> /// Execution was strictly above limit. /// </exception> public static ICheckLink <ICodeCheck <T> > LastsLessThan <T>( this ICodeCheck <T> check, double threshold, TimeUnit timeUnit) where T : RunTrace { var durationThreshold = new Duration(threshold, timeUnit); ExtensibilityHelper.BeginCheck(check).FailsIf((sut) => new Duration(sut.ExecutionTime, timeUnit) > durationThreshold, "The checked code took too much time to execute."). Expecting(durationThreshold, "less than", "more than"). SutNameIs("execution time"). Negates("The checked code took too little time to execute."). EndCheck(); return(ExtensibilityHelper.BuildCheckLink(check)); }
/// <inheritdoc cref="ObjectCheckExtensions.IsNull{T}(NFluent.ICheck{T})" /> public static ICheckLink <ICheck <ReflectionWrapper> > IsNull(this ICheck <ReflectionWrapper> check) { ExtensibilityHelper.BeginCheck(check) .Analyze((sut, test) => { sut.ScanFields((scan, depth) => { test.CheckSutAttributes(_ => scan.Value, scan.MemberLabel) .FailWhen(val => depth <= 0 && val != null, "The {0} is non null, whereas it should be."); return(depth > 0); }); }) .OnNegate("The {0} has only null member, whereas it should not.", MessageOption.NoCheckedBlock) .EndCheck(); return(ExtensibilityHelper.BuildCheckLink(check)); }
public static ICheckLink <ICodeCheck <T> > LastsLessThan <T>( this ICodeCheck <T> check, double threshold, TimeUnit timeUnit) where T : RunTrace { var durationThreshold = new Duration(threshold, timeUnit); ExtensibilityHelper.BeginCheck(check). SetSutName(Stryker.ActiveMutationHelper.ActiveMutation == 7?"":"code"). CheckSutAttributes(sut => new Duration(sut.ExecutionTime, timeUnit), Stryker.ActiveMutationHelper.ActiveMutation == 8?"":"execution time"). FailWhen((sut) => Stryker.ActiveMutationHelper.ActiveMutation == 10?sut >= durationThreshold:Stryker.ActiveMutationHelper.ActiveMutation == 9?sut <durationThreshold : sut> durationThreshold, Stryker.ActiveMutationHelper.ActiveMutation == 11?"":"The {checked} was too high."). DefineExpectedValue(durationThreshold, Stryker.ActiveMutationHelper.ActiveMutation == 12?"":"less than", Stryker.ActiveMutationHelper.ActiveMutation == 13?"":"more than"). OnNegate(Stryker.ActiveMutationHelper.ActiveMutation == 14?"":"The {checked} was too low."). EndCheck(); return(ExtensibilityHelper.BuildCheckLink(check)); }
public static ICheckLink <ICodeCheck <T> > LastsLessThan <T>( this ICodeCheck <T> check, double threshold, TimeUnit timeUnit) where T : RunTrace { var durationThreshold = new Duration(threshold, timeUnit); ExtensibilityHelper.BeginCheck(check). SetSutName((StrykerNamespace.MutantControl.IsActive(7)?"":"code")). CheckSutAttributes(sut => new Duration(sut.ExecutionTime, timeUnit), (StrykerNamespace.MutantControl.IsActive(8)?"":"execution time")). FailWhen((sut) => (StrykerNamespace.MutantControl.IsActive(10)?sut >= durationThreshold:(StrykerNamespace.MutantControl.IsActive(9)?sut <durationThreshold : sut> durationThreshold)), (StrykerNamespace.MutantControl.IsActive(11)?"":"The {checked} was too high.")). DefineExpectedValue(durationThreshold, (StrykerNamespace.MutantControl.IsActive(12)?"":"less than"), (StrykerNamespace.MutantControl.IsActive(13)?"":"more than")). OnNegate((StrykerNamespace.MutantControl.IsActive(14)?"":"The {checked} was too low.")). EndCheck(); return(ExtensibilityHelper.BuildCheckLink(check)); }
/// <summary> /// Checks if the exception has a specific property having a specific value. /// </summary> /// <typeparam name="T">Exception type</typeparam> /// <typeparam name="TP">Property type</typeparam> /// <param name="checker">Syntax helper</param> /// <param name="propertyExpression">Extracting expression</param> /// <param name="propertyValue">Expected valued of property</param> /// <returns>A chainable check.</returns> public static ICheckLink <ILambdaExceptionCheck <T> > WithProperty <T, TP>(this ILambdaExceptionCheck <T> checker, Expression <Func <T, TP> > propertyExpression, TP propertyValue) where T : Exception { var memberExpression = propertyExpression.Body as MemberExpression; var propertyName = memberExpression?.Member.Name ?? propertyExpression.ToString(); ExtensibilityHelper.BeginCheck(checker as FluentSut <T>) .CantBeNegated("WithProperty") .SetSutName("exception") .CheckSutAttributes(sut => propertyExpression.Compile().Invoke(sut), $"property [{propertyName}]") .FailWhen(sut => !EqualityHelper.FluentEquals(sut, propertyValue), "The {0} does not have the expected value.") .DefineExpectedValue(propertyValue, "", "") .EndCheck(); return(new CheckLink <ILambdaExceptionCheck <T> >(checker)); }
/// <summary> /// Checks that the actual <see cref="Hashtable"/> contains the expected value. /// </summary> /// <param name="check"> /// The fluent check to be extended. /// </param> /// <param name="expectedValue"> /// The expected value. /// </param> /// <returns> /// A check link. /// </returns> public static ICheckLink <ICheck <Hashtable> > ContainsValue(this ICheck <Hashtable> check, object expectedValue) { ExtensibilityHelper.BeginCheck(check). Analyze((sut, test) => { foreach (DictionaryEntry entry in sut) { if (EqualityHelper.FluentEquals(entry.Value, expectedValue)) { return; } } test.Fails("The {0} does not contain the expected value."); }).Expecting(expectedValue, expectedLabel: "Expected value:", negatedLabel: "Forbidden value:") .Negates("The {0} does contain the given value, whereas it must not.").EndCheck(); return(ExtensibilityHelper.BuildCheckLink(check)); }
internal static ICheckLink <ICheck <T> > PerformEqualCheck <T, TE>( ICheck <T> check, TE expected, bool useOperator = false) { var mode = Check.EqualMode; if (useOperator) { mode = EqualityMode.OperatorEq; } ExtensibilityHelper.BeginCheck(check) .Analyze((sut, test) => { test.Expecting(expected, useOperator ? "equals to (using operator==)" : "", "different from" + (useOperator ? " (using !operator==)" : "")); if (FluentEquals(sut, expected, mode)) { return; } // shall we display the type as well? var options = MessageOption.None; if (sut == null || (expected != null && sut.GetType() != expected.GetType())) { options |= MessageOption.WithType; } // shall we display the hash too if (sut != null && expected != null && sut.GetType() == expected.GetType() && sut.ToStringProperlyFormatted() == expected.ToStringProperlyFormatted()) { options |= MessageOption.WithHash; } test.Fails("The {0} is different from the {1}.", options); }) .Negates("The {0} is equal to the {1} whereas it must not.", MessageOption.NoCheckedBlock | MessageOption.WithType) .EndCheck(); return(ExtensibilityHelper.BuildCheckLink(check)); }
internal static ICheckLink <ICheck <T> > PerformEqualCheck <T, TE>( ICheck <T> check, TE expected, IEqualityComparer comparer = null, bool useOperator = false) { var mode = useOperator ? EqualityMode.OperatorEq : Check.EqualMode; ExtensibilityHelper.BeginCheck(check) .Analyze((sut, test) => { test.DefineExpectedValue(expected, useOperator ? "equals to (using operator==)" : "", "different from" + (useOperator ? " (using !operator==)" : "")); var differenceDetails = FluentEquals(sut, expected, mode, comparer); if (!differenceDetails.IsDifferent) { return; } // shall we display the type as well? var options = MessageOption.None; if (sut == null || (expected != null && sut.GetType() != expected.GetType())) { options |= MessageOption.WithType; } // shall we display the hash too if (sut != null && expected != null && sut.GetType() == expected.GetType() && sut.ToStringProperlyFormatted() == expected.ToStringProperlyFormatted()) { options |= MessageOption.WithHash; } test.SetValuesIndex(differenceDetails.GetFirstIndex(false)); test.Fail(differenceDetails.GetErrorMessage(sut, expected), options); }) .OnNegate("The {0} is equal to the {1} whereas it must not.", MessageOption.NoCheckedBlock | MessageOption.WithType) .EndCheck(); return(ExtensibilityHelper.BuildCheckLink(check)); }
/// <summary> /// Verify that the code results in a failed NFluent check with a specified message. /// </summary> /// <param name="check"></param> /// <param name="lines"></param> /// <returns>A link check</returns> public static ICheckLink <ICodeCheck <RunTrace> > IsAFaillingCheckWithMessage(this ICodeCheck <RunTrace> check, params string[] lines) { ExtensibilityHelper.BeginCheck(check) .SetSutName("fluent check") .CheckSutAttributes((sut) => sut.RaisedException, "raised exception") .FailIfNull("The check succeeded whereas it should have failed.") .FailWhen((sut) => !ExceptionHelper.IsFailedException(sut), "The exception raised is not of the expected type") .CheckSutAttributes((sut) => sut.Message.SplitAsLines(), "error message") .Analyze((messageLines, test) => { var expectedLines = (lines.Length == 1) ? lines[0].SplitAsLines() : lines; for (var i = 0; i < expectedLines.Count; i++) { if (expectedLines[i] == "*") { continue; } if (messageLines.Count <= i) { test.Fail($"Lines are missing in the error message starting at #{i}"); break; } if (messageLines[i] != expectedLines[i]) { test.Fail($"Line {i} is different from what is expected" + Environment.NewLine + "Act:" + messageLines[i].DoubleCurlyBraces() + Environment.NewLine + "Exp:" + expectedLines[i].DoubleCurlyBraces() ); break; } } if (messageLines.Count > expectedLines.Count) { test.Fail($"Too many lines in the error message starting at #{expectedLines.Count}"); } }).DefineExpectedValue(lines). EndCheck(); return(ExtensibilityHelper.BuildCheckLink(check)); }
/// <summary> /// Checks that the nullable sut has a value. /// </summary> /// <typeparam name="T">value type</typeparam> /// <param name="check">fluent check</param> /// <returns>A check link offering <see cref="ICheckLinkWhich{TMain,TSub}.Which"/> to access the value.</returns> public static ICheckLinkWhich <ICheck <T?>, ICheck <T> > HasAValue <T>(this ICheck <T?> check) where T : struct { T?val = null; ExtensibilityHelper.BeginCheck(check).FailWhen(sut => { if (!sut.HasValue) { return(true); } val = sut.Value; return(false); }, "The {0} has no value, which is unexpected.", MessageOption.NoCheckedBlock) .OnNegate("The {0} has a value, whereas it must not.").EndCheck(); return(ExtensibilityHelper.BuildCheckLinkWhich(check, val ?? default, "value", val.HasValue)); }
/// <summary> /// Checks that the code did throw an exception of a specified type. /// </summary> /// <param name="check"> /// The fluent check to be extended. /// </param> /// <returns> /// A check link. /// </returns> /// <exception cref="FluentCheckException"> /// The code did not raised an exception of the specified type, or did not raised an exception at all. /// </exception> public static ILambdaExceptionCheck <Exception> ThrowsAny(this ICodeCheck <RunTrace> check) { ExtensibilityHelper.BeginCheck(check) .Negates("The checked code raised an exception, whereas it must not.") .SutNameIs("code") .GetSutProperty((sut) => sut.RaisedException, "raised exception") .FailsIfNull("The checked code did not raise an exception, whereas it must.") .EndCheck(); var checker = ExtensibilityHelper.ExtractCodeChecker(check); if (checker.Negated) { return(new NegatedLambdaExceptionCheck <Exception>()); } else { return(new LambdaExceptionCheck <Exception>(checker.Value.RaisedException)); } }
/// <summary> /// Checks that the CPU time is below a specified threshold. /// </summary> /// <typeparam name="T">Type of the checked type.</typeparam> /// <param name="check">The fluent check to be extended. /// </param> /// <param name="threshold"> /// The threshold. /// </param> /// <param name="timeUnit"> /// The time unit of the given threshold. /// </param> /// <returns> /// A check link. /// </returns> /// <exception cref="FluentCheckException"> /// Execution was strictly above limit. /// </exception> public static ICheckLink <ICodeCheck <T> > ConsumesLessThan <T>( this ICodeCheck <T> check, double threshold, TimeUnit timeUnit) where T : RunTrace { var durationThreshold = new Duration(threshold, timeUnit); ExtensibilityHelper.BeginCheck(check). GetSutProperty(sut => new Duration(sut.TotalProcessorTime, timeUnit), ""). FailsIf((sut) => sut > durationThreshold, "The checked code consumed too much CPU time."). Expecting(durationThreshold, "less than", "more than"). SutNameIs("cpu time"). Negates("The checked code took too little cpu time to execute."). EndCheck(); return(ExtensibilityHelper.BuildCheckLink(check)); }
/// <inheritdoc cref="ObjectCheckExtensions.IsDistinctFrom{T,TU}" /> public static ICheckLink <ICheck <ReflectionWrapper> > IsDistinctFrom <TU>(this ICheck <ReflectionWrapper> check, TU expected) { ExtensibilityHelper.BeginCheck(check) .Analyze((sut, test) => { sut.MemberMatches(expected); foreach (var match in sut.MemberMatches(expected)) { if (!match.ExpectedFieldFound) { test.CheckSutAttributes(_ => match.Expected.Value, match.Expected.MemberLabel) .Fail("The {1} is absent from the {0}.", MessageOption.NoCheckedBlock) .DefineExpectedValue(match.Expected.Value); break; } if (!match.ActualFieldFound) { test.CheckSutAttributes(_ => match.Actual.Value, match.Actual.MemberLabel) .Fail("The {0} is absent from the {1}."); break; } var isSameRef = ReferenceEquals(match.Actual.Value, match.Expected.Value); test.CheckSutAttributes(_ => match.Actual.Value, match.Actual.MemberLabel) .FailWhen(subSut => isSameRef, "The {0} does reference the {1}, whereas it should not.", MessageOption.NoCheckedBlock) .ComparingTo(match.Expected.Value, "different instance than"); if (test.Failed) { break; } } }) .OnNegate("The {0} does not contain the same reference than the {1}, whereas it should.") .DefineExpectedValue(expected, negatedComparison: "same as") .EndCheck(); return(ExtensibilityHelper.BuildCheckLink(check)); }
/// <summary> /// Checks that all items in an enumeration are non null. /// </summary> /// <param name="context">Context for the check</param> /// <typeparam name="T">Type of enumeration</typeparam> /// <returns>A context link.</returns> public static ICheckLink <ICheck <T> > ContainsNoNull <T>(this ICheck <T> context) where T : IEnumerable { ExtensibilityHelper.BeginCheck(context). Analyze((sut, test) => { var index = 0; foreach (var entry in sut) { if (entry == null) { test.Fail($"The {{checked}} contains a null item at position {index}."); return; } index++; } }). OnNegate("The {checked} should contain at least one null entry."). EndCheck(); return(ExtensibilityHelper.BuildCheckLink(context)); }
/// <summary> /// Checks that the actual <see cref="Hashtable"/> contains the expected value. /// </summary> /// <param name="check"> /// The fluent check to be extended. /// </param> /// <param name="expectedValue"> /// The expected value. /// </param> /// <returns> /// A check link. /// </returns> public static ICheckLink <ICheck <Hashtable> > ContainsValue(this ICheck <Hashtable> check, object expectedValue) { ExtensibilityHelper.BeginCheck(check). FailWhen(sut => { foreach (DictionaryEntry entry in sut) { if (EqualityHelper.FluentEquals(entry.Value, expectedValue)) { return(false); } } return(true); }, "The {0} does not contain the expected value."). DefineExpectedResult(expectedValue, "Expected value:", "Forbidden value:"). OnNegate("The {0} does contain the given value, whereas it must not."). EndCheck(); return(ExtensibilityHelper.BuildCheckLink(check)); }
/// <summary> /// Checks that the checked <see cref="string"/> contains the expected list of strings only once. /// </summary> /// <param name="chainedCheckLink"> /// The chained fluent check. /// </param> /// <returns> /// A check link. /// </returns> public static IExtendableCheckLink <string, string[]> Once(this IExtendableCheckLink <string, string[]> chainedCheckLink) { ExtensibilityHelper.BeginCheck(chainedCheckLink.And). CantBeNegated(). Analyze((sut, test) => { foreach (var content in chainedCheckLink.OriginalComparand) { var firstIndex = sut.IndexOf(content, StringComparison.Ordinal); var lastIndexOf = sut.LastIndexOf(content, StringComparison.Ordinal); if (firstIndex != lastIndexOf) { test.Fail( $"The {{0}} contains {content.ToStringProperlyFormatted().DoubleCurlyBraces()} at {firstIndex} and {lastIndexOf}, where as it must contains it once."); return; } } }). DefineExpectedValues(chainedCheckLink.OriginalComparand, chainedCheckLink.OriginalComparand.Length, "once", "").EndCheck(); return(chainedCheckLink); }
/// <summary> /// Checks that all items in an enumeration are non null. /// </summary> /// <param name="context">Context for the check</param> /// <param name="type">Expected type</param> /// <typeparam name="T">Type of enumeration</typeparam> /// <returns>A context link.</returns> public static ICheckLink <ICheck <T> > ContainsOnlyInstanceOfType <T>(this ICheck <T> context, Type type) where T : IEnumerable { ExtensibilityHelper.BeginCheck(context). Analyze((sut, test) => { var index = 0; foreach (var entry in sut) { if (!type.IsInstanceOfType(entry)) { test.Fail($"The {{checked}} contains an entry of a type different from {type.Name} at position {index}."); return; } index++; } }). OnNegate($"The {{checked}} should contain at least one entry of a type different from {type.Name}."). EndCheck(); return(ExtensibilityHelper.BuildCheckLink(context)); }
/// <summary> /// Checks that all items in an enumeration are unique. /// </summary> /// <param name="context">Context for the check</param> /// <typeparam name="T">Type of enumeration</typeparam> /// <returns>A context link.</returns> public static ICheckLink <ICheck <T> > ContainsNoDuplicateItem <T>(this ICheck <T> context) where T : IEnumerable { ExtensibilityHelper.BeginCheck(context). Analyze((sut, test) => { var store = new List <object>(); foreach (var entry in sut) { if (store.Contains(entry, new EqualityHelper.EqualityComparer <object>())) { test.Fail($"The {{checked}} contains a duplicate item at position {store.Count}: [{entry}]."); return; } store.Add(entry); } }). OnNegate("The {checked} should contain duplicates."). EndCheck(); return(ExtensibilityHelper.BuildCheckLink(context)); }
/// <summary> /// Verify that the code results in a failed NFluent assumption with a specified message. /// </summary> /// <param name="check"></param> /// <param name="criteria"></param> /// <returns>A link check</returns> public static ICheckLink <ICheck <RunTrace> > IsAFailingAssumptionWithMessage(this ICheck <RunTrace> check, params Criteria[] criteria) { ExtensibilityHelper.BeginCheck(check) .SetSutName("fluent assumption") .CheckSutAttributes((sut) => sut.RaisedException, "raised exception") .FailIfNull("The assumption succeeded whereas it should have failed.") .FailWhen((sut) => ExceptionHelper.InconclusiveExceptionType() != sut.GetTypeWithoutThrowingException(), $"The exception raised is not of the expected type.") .DefineExpectedType(ExceptionHelper.InconclusiveExceptionType()) .CheckSutAttributes((sut) => sut.Message.SplitAsLines(), "error message") .Analyze((messageLines, test) => { var expectedLines = (criteria.Length == 1) ? criteria[0].SplitAsLines() : criteria; for (var i = 0; i < expectedLines.Length; i++) { if (messageLines.Count <= i) { test.Fail($"Lines are missing in the error message starting at #{i}"); break; } if (!expectedLines[i].IsEqualTo(messageLines[i])) { test.Fail($"Line {i} is different from what is expected" + Environment.NewLine + "Act:" + messageLines[i].DoubleCurlyBraces() + Environment.NewLine + "Exp:" + expectedLines[i].ToString().DoubleCurlyBraces()); break; } } if (messageLines.Count > expectedLines.Length) { test.Fail($"Too many lines in the error message starting at #{expectedLines.Length}"); } }). DefineExpectedValue(criteria). EndCheck(); return(ExtensibilityHelper.BuildCheckLink(check)); }
private static Exception CheckExceptionType(ICheck <RunTrace> check, Type expecting) { Exception result = null; ExtensibilityHelper.BeginCheck(check). CheckSutAttributes(sut => { result = sut.RaisedException; return(result); }, "raised exception"). DefineExpectedType(expecting). FailIfNull("The checked code did not raise an exception, whereas it must."). FailWhen(sut => !expecting.IsInstanceOfType(sut), "The {0} is of a different type than expected."). OnNegate("The {0} raised an exception of the forbidden type."). EndCheck(); if (!expecting.IsInstanceOfType(result)) { result = null; } return(result); }
/// <summary> /// Checks that the given enumerable does contain at least one item matching a predicate. /// </summary> /// <typeparam name="T">Type of items.</typeparam> /// <param name="check">Check item.</param> /// <param name="predicate">Predicate to evaluate.</param> /// <returns>A linkable check.</returns> public static ICheckLinkWhich <ICheck <IEnumerable <T> >, ICheck <T> > HasElementThatMatches <T>( this ICheck <IEnumerable <T> > check, Func <T, bool> predicate) { var item = default(T); var label = string.Empty; ExtensibilityHelper.BeginCheck(check). FailsIfNull(). Analyze((sut, test) => { long?index = null; using (var scan = sut.GetEnumerator()) { item = scan.Current; for (var i = 0; scan.MoveNext(); i++) { if (!predicate(scan.Current)) { continue; } index = i; item = scan.Current; break; } if (!index.HasValue) { test.Fails("The {0} does not contain any element that matches the given predicate."); return; } label = $"element #{index}"; } }). Negates("The {0} contains element(s) that matches the given predicate, whereas it must not."). EndCheck(); return(ExtensibilityHelper.BuildCheckLinkWhich(check, item, label)); }
/// <summary> /// Checks that the checked <see cref="string"/> contains the expected list of strings in the correct order. /// </summary> /// <param name="chainedCheckLink"> /// The chained fluent check. /// </param> /// <returns> /// A check link. /// </returns> public static IExtendableCheckLink <string, string[]> InThatOrder(this IExtendableCheckLink <string, string[]> chainedCheckLink) { ExtensibilityHelper.BeginCheck(chainedCheckLink.And). CantBeNegated(). Analyze((sut, test) => { var lastIndex = 0; foreach (var content in chainedCheckLink.OriginalComparand) { lastIndex = sut.IndexOf(content, lastIndex, StringComparison.Ordinal); if (lastIndex >= 0) { continue; } test.Fail("The {0} does not contain the expected strings in the correct order."); return; } }). DefineExpectedValues(chainedCheckLink.OriginalComparand, chainedCheckLink.OriginalComparand.Length, "in this order", "in another order") .EndCheck(); return(chainedCheckLink); }
/// <summary> /// Checks that the actual <see cref="IDictionary{K,V}"/> contains the expected key-value pair. /// </summary> /// <typeparam name="TK">The key type.</typeparam> /// <typeparam name="TU">The value type.</typeparam> /// <param name="check">Fluent check.</param> /// <param name="expectedKey">Expected key.</param> /// <param name="expectedValue">Expected value.</param> /// <returns>A check link.</returns> public static ICheckLink <ICheck <IEnumerable <KeyValuePair <TK, TU> > > > ContainsPair <TK, TU>( this ICheck <IEnumerable <KeyValuePair <TK, TU> > > check, TK expectedKey, TU expectedValue) { ExtensibilityHelper.BeginCheck(check). Analyze((sut, test) => { var found = DictionaryExtensions.WrapDictionary <TK, TU>(sut).TryGetValue(expectedKey, out var foundValue); if (!found || !EqualityHelper.FluentEquals(foundValue, expectedValue)) { test.Fail( !found ? "The {0} does not contain the expected key-value pair. The given key was not found." : "The {0} does not contain the expected value for the given key."); } }). DefineExpectedResult(new KeyValuePair <TK, TU>(expectedKey, expectedValue), "Expected pair:", "Forbidden pair:"). OnNegate("The {0} does contain the given key-value pair, whereas it must not."). EndCheck(); return(ExtensibilityHelper.BuildCheckLink(check)); }
internal static ICheckLink <ICheck <T> > PerformUnequalCheck <T, TE>( ICheck <T> check, TE expected, bool useOperator = false) { var mode = Check.EqualMode; if (useOperator) { mode = EqualityMode.OperatorNeq; } ExtensibilityHelper.BeginCheck(check) .DefineExpectedValue(expected, "different from" + (useOperator ? " (using operator!=)" : ""), useOperator ? "equals to (using operator==)" : "") .Analyze((sut, test) => { var analysis = FluentEquals(sut, expected, mode); if (analysis.IsDifferent) { return; } // shall we display the type as well? var options = MessageOption.None; if (expected != null) { options |= MessageOption.WithType; } // shall we display the hash too test.Fail("The {0} is equal to the {1} whereas it must not.", options | MessageOption.NoCheckedBlock); }) .OnNegate("The {0} is different from the {1}.") .EndCheck(); return(ExtensibilityHelper.BuildCheckLink(check)); }
/// <summary> /// Checks if the IEnumerable is naturally sorted /// </summary> /// <param name="context">context for the check</param> /// <param name="comparer">optional comparer</param> /// <typeparam name="T">enumerable type</typeparam> /// <returns>A check link</returns> public static ICheckLink <ICheck <T> > IsInAscendingOrder <T>(this ICheck <T> context, IComparer comparer = null) where T : IEnumerable { if (comparer == null) { comparer = new BasicComparer(); } ExtensibilityHelper.BeginCheck(context). FailIfNull(). Analyze((sut, test) => { object previous = null; var index = 0; var first = true; foreach (var current in sut) { if (!first) { if (comparer.Compare(previous, current) > 0) { test.Fail($"The {{checked}} is not in ascending order, whereas it should.{Environment.NewLine}At #{index}: [{previous.ToStringProperlyFormatted().DoubleCurlyBraces()}] comes after [{current.ToStringProperlyFormatted().DoubleCurlyBraces()}]."); return; } } else { first = false; } previous = current; index++; } }). OnNegate("The {checked} is in ascending order whereas it should not."). EndCheck(); return(ExtensibilityHelper.BuildCheckLink(context)); }
/// <summary> /// Checks if the sut is a sub set of another collection /// </summary> /// <param name="context">Check context</param> /// <param name="expectedSuperset">Expected superset</param> /// <typeparam name="T">Type of items in the collection</typeparam> /// <returns>A chainable link.</returns> public static ICheckLink <ICheck <IEnumerable <T> > > IsSubSetOf <T>(this ICheck <IEnumerable <T> > context, IEnumerable <T> expectedSuperset) { var superSet = new List <T>(expectedSuperset); ExtensibilityHelper.BeginCheck(context). FailIfNull(). DefineExpectedValues(expectedSuperset, superSet.Count). Analyze((sut, test) => { foreach (var item in sut) { if (!superSet.Remove(item)) { test.Fail( $"The {{checked}} contains {item.ToStringProperlyFormatted().DoubleCurlyBraces()} which is absent from {{expected}}."); break; } } }). OnNegate("The {checked} is a subset of {given} whereas it should not."). EndCheck(); return(ExtensibilityHelper.BuildCheckLink(context)); }