/// <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> Contains(this ICheck <IEnumerable> check, IEnumerable otherEnumerable) { var checker = ExtensibilityHelper.ExtractChecker(check); checker.ExecuteCheck( () => { if (otherEnumerable == null) { return; } if (checker.Value == null) { var message = checker.BuildMessage("The {0} is null and thus, does not contain the given expected value(s).").ExpectedValues(otherEnumerable).ToString(); throw new FluentCheckException(message); } var notFoundValues = ExtractNotFoundValues(checker.Value, otherEnumerable); if (notFoundValues.Count > 0) { var message = checker.BuildMessage(string.Format("The {{0}} does not contain the expected value(s):\n\t[{0}]", notFoundValues.ToEnumeratedString().DoubleCurlyBraces())).ExpectedValues(otherEnumerable).ToString(); throw new FluentCheckException(message); } }, checker.BuildMessage("The {0} contains all the given values whereas it must not.").ExpectedValues(otherEnumerable).ToString()); return(new ExtendableCheckLink <IEnumerable>(check, otherEnumerable)); }
public void ExtractRunnableStructCheckWorks() { var runnableStructCheck = ExtensibilityHelper.ExtractChecker(Check.That(Nationality.Chinese)); Check.That(runnableStructCheck.Value).IsEqualTo(Nationality.Chinese); Check.That(runnableStructCheck.Negated).IsFalse(); }
/// <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) { var checker = ExtensibilityHelper.ExtractChecker(chainedCheckLink.And); var value = checker.Value; var comparand = chainedCheckLink.OriginalComparand; var lastIndex = 0; foreach (var text in comparand) { lastIndex = value.IndexOf(text, lastIndex); if (lastIndex < 0) { // failed var message = checker.BuildMessage( "The {0} does not contain the expected strings in the correct order.") .For("string") .On(value) .And.Expected(comparand) .Label("Expected content: "); throw new FluentCheckException(message.ToString()); } } return(chainedCheckLink); }
public static ICheckLink <ICheck <Sut> > Satisfies <Sut>(this ICheck <Sut> check, Func <Sut, bool> requirement) { // Every check method starts by extracting a checker instance from the check thanks to // the ExtensibilityHelper static class. var checker = ExtensibilityHelper.ExtractChecker(check); // Then, we let the checker's ExecuteCheck() method return the ICheckLink<ICheck<T>> result (with T as string here). // This method needs 2 arguments: // 1- a lambda that checks what's necessary, and throws a FluentAssertionException in case of failure // The exception message is usually fluently build with the FluentMessage.BuildMessage() static method. // // 2- a string containing the message for the exception to be thrown by the checker when // the check fails, in the case we were running the negated version. // // e.g.: var requirementName = GetNominalInfo(requirement); return(checker.ExecuteCheck( () => { if (!requirement(checker.Value)) { var errorMessage = FluentMessage.BuildMessage($"The {{0}} does not satisfy the requirement{requirementName}.").For(typeof(Sut).Name).On(checker.Value).ToString(); throw new FluentCheckException(errorMessage); } }, FluentMessage.BuildMessage($"The {{0}} satisifies the requirement {requirementName} whereas it must not.").For(typeof(Sut).Name).On(checker.Value).ToString())); }
/// <summary> /// Checks that the actual duration is less (strictly) than a comparand. /// </summary> /// <param name="check">The fluent check to be extended.</param> /// <param name="comparand">The value to compare to.</param> /// <returns>A check link.</returns> /// <exception cref="FluentCheckException">The actual value is not less than the provided comparand.</exception> public static ICheckLink <ICheck <TimeSpan> > IsLessThan(this ICheck <TimeSpan> check, TimeSpan comparand) { var checker = ExtensibilityHelper.ExtractChecker(check); var unit = TimeHelper.DiscoverUnit(comparand); var testedDuration = new Duration(checker.Value, unit); var expected = new Duration(comparand, unit); var notMessage = checker.BuildMessage("The {0} is not more than the limit.") .On(testedDuration) .And.Expected(expected) .Comparison("more than or equal to"); var message = checker.BuildMessage("The {0} is more than the limit.") .On(testedDuration) .And.Expected(expected).Comparison("less than"); return(checker.ExecuteCheck( () => { if (testedDuration >= expected) { throw new FluentCheckException(message.ToString()); } }, notMessage.ToString())); }
/// <summary> /// Define a specific name for the system under test. /// </summary> /// <typeparam name="T">Tested type. /// </typeparam> /// <param name="check">Checker hosting the check context. /// </param> /// <param name="sutLabel">Name to use. /// </param> /// <returns> /// The <see cref="ICheck{T}"/>Checker object. /// </returns> public static ICheck <T> As <T>(this ICheck <T> check, string sutLabel) { var checker = ExtensibilityHelper.ExtractChecker(check); checker.SetSutLabel(sutLabel); return(check); }
/// <summary> /// Checks that the actual duration is equal to a target duration. /// </summary> /// <param name="check">The fluent check to be extended.</param> /// <param name="comparand">The duration to be compared to.</param> /// <returns>A check link.</returns> /// /// <exception cref="FluentCheckException">The actual value is not equal to the target duration.</exception> public static ICheckLink <ICheck <TimeSpan> > IsEqualTo(this ICheck <TimeSpan> check, TimeSpan comparand) { var checker = ExtensibilityHelper.ExtractChecker(check); TimeUnit unit = TimeHelper.DiscoverUnit(comparand); var testedDuration = new Duration(checker.Value, unit); var expected = new Duration(comparand, unit); var message = checker.BuildMessage("The {0} is different from the {1}.") .On(testedDuration) .And.Expected(expected); var notMessage = checker.BuildMessage("The {0} is the same than {1}.") .On(testedDuration) .And.Expected(expected) .Comparison("different than"); return(checker.ExecuteCheck( () => { if (checker.Value != comparand) { throw new FluentCheckException(message.ToString()); } }, notMessage.ToString())); }
public static ICheckLinkWhich <ICheck <Stopwatch>, ICheck <TimeSpan> > Elapsed(this ICheck <Stopwatch> check) { var checker = ExtensibilityHelper.ExtractChecker(check); var extendableCheckLink = checker.BuildLinkWhich(Check.That(checker.Value.Elapsed)); return(extendableCheckLink); }
/// <summary> /// Checks that the actual <see cref="IDictionary"/> contains the expected value. /// </summary> /// <typeparam name="K"> /// The type of the key element. /// </typeparam> /// <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 <IDictionary> > ContainsValue <K>(this ICheck <IDictionary> check, K expectedValue) { var checker = ExtensibilityHelper.ExtractChecker(check); return(checker.ExecuteCheck( () => { var found = false; foreach (var item in checker.Value.Values) { if (item.Equals(expectedValue)) { found = true; break; } } if (!found) { var message = checker.BuildMessage("The {0} does not contain the expected value.").Expected(expectedValue).Label("Expected value:").ToString(); throw new FluentCheckException(message); } }, checker.BuildMessage("The {0} does contain the given value, whereas it must not.").Expected(expectedValue).Label("Expected value:").ToString())); }
/// <summary> /// Checks that the actual stream has the same content as another one. /// </summary> /// <param name="check">The fluent check to be extended.</param> /// <param name="expected">The stream to compare content with.</param> /// <returns>A check link</returns> public static ICheckLink <ICheck <Stream> > HasSameSequenceOfBytesAs(this ICheck <Stream> check, Stream expected) { var checker = ExtensibilityHelper.ExtractChecker(check); var value = checker.Value; return(checker.ExecuteCheck( () => { if (value.Length != expected.Length) { var message = GenerateMessageWhenFullyDistinct(expected, checker, value); throw new FluentCheckException(message.ToString()); } // Keeps initial positions to be able to restore them after the check var valueInitialPosition = value.Position; var otherInitialPosition = expected.Position; value.Seek(0, SeekOrigin.Begin); expected.Seek(0, SeekOrigin.Begin); while (value.Position < value.Length) { if (value.ReadByte() != expected.ReadByte()) { var message = GenerateMessageWhenSameLenghtButDiffContent(expected, checker, value); throw new FluentCheckException(message.ToString()); } } // Side-effect free. Restore initial positions of streams value.Position = valueInitialPosition; expected.Position = otherInitialPosition; }, BuildNegatedMessage(expected, value).ToString())); }
/// <summary> /// Checks that the checked <see cref="char"/> is a letter. /// </summary> /// <param name="check">The chained fluent check.</param> /// <exception cref="FluentCheckException">The checked <see cref="char"/> is not a letter.</exception> /// <returns>A check link.</returns> public static ICheckLink<ICheck<char>> IsALetter(this ICheck<char> check) { // Every check method starts by extracting a checker instance from the check thanks to // the ExtensibilityHelper static class. var checker = ExtensibilityHelper.ExtractChecker(check); // Then, we let the checker's ExecuteCheck() method return the ICheckLink<ICheck<T>> result (with T as string here). // This method needs 2 arguments: // 1- a lambda that checks what's necessary, and throws a FluentAssertionException in case of failure // The exception message is usually fluently build with the FluentMessage.BuildMessage() static method. // // 2- a string containing the message for the exception to be thrown by the checker when // the check fails, in the case we were running the negated version. // // e.g.: return checker.ExecuteCheck( () => { if (!IsALetter(checker.Value)) { var errorMessage = FluentMessage.BuildMessage("The {0} is not a letter.").For("char").On(checker.Value).ToString(); throw new FluentCheckException(errorMessage); } }, FluentMessage.BuildMessage("The {0} is a letter whereas it must not.").For("char").On(checker.Value).ToString()); }
/// <summary> /// Checks that the checked <see cref="IEnumerable"/> contains the expected list of items only once. /// </summary> /// <param name="chainedCheckLink"> /// The chained fluent check. /// </param> /// <returns> /// A check link. /// </returns> public static IExtendableCheckLink <IEnumerable, IEnumerable> Once(this IExtendableCheckLink <IEnumerable, IEnumerable> chainedCheckLink) { var checker = ExtensibilityHelper.ExtractChecker(chainedCheckLink.And); var itemIndex = 0; var expectedList = ConvertToList(chainedCheckLink); var listedItems = new List <object>(); Debug.Assert(checker != null, "checker != null"); foreach (var item in checker.Value) { if (expectedList.Contains(item)) { listedItems.Add(item); expectedList.Remove(item); } else if (listedItems.Contains(item)) { // failure, we found one extra occurrence of one item var message = checker.BuildMessage( string.Format( "The {{0}} has extra occurrences of the expected items. Item [{0}] at position {1} is redundant.", item.ToStringProperlyFormatted().DoubleCurlyBraces(), itemIndex)) .ExpectedValues(chainedCheckLink.OriginalComparand); throw new FluentCheckException(message.ToString()); } itemIndex++; } return(chainedCheckLink); }
/// <summary> /// Checks that the actual duration is greater (strictly) than a comparand. /// </summary> /// <param name="check">The fluent check to be extended.</param> /// <param name="providedDuration">The duration to compare to.</param> /// <param name="unit">The unit in which the duration is expressed.</param> /// <returns>A check link.</returns> /// <exception cref="FluentCheckException">The actual value is not greater than the provided comparand.</exception> public static ICheckLink <ICheck <TimeSpan> > IsGreaterThan(this ICheck <TimeSpan> check, double providedDuration, TimeUnit unit) { var checker = ExtensibilityHelper.ExtractChecker(check); var testedDuration = new Duration(checker.Value, unit); var expected = new Duration(providedDuration, unit); var message = FluentMessage.BuildMessage("The {0} is not more than the limit.") .On(testedDuration) .And.Expected(expected) .Comparison("less than or equal to"); var notMessage = FluentMessage.BuildMessage("The {0} is more than the limit.") .On(testedDuration) .And.Expected(expected).Comparison("more than"); return(checker.ExecuteCheck( () => { if (testedDuration <= expected) { throw new FluentCheckException(message.ToString()); } }, notMessage.ToString())); }
/// <summary> /// Checks that the enumerable contains only the values present in another enumerable, and nothing else, in any order. /// Note: this check succeeded with empty value. /// </summary> /// <param name="check">The fluent check to be extended.</param> /// <param name="expectedValues">The expected values to be found.</param> /// <returns> /// A check link. /// </returns> /// <exception cref="FluentCheckException">The enumerable does not contain only the expected values present in the other enumerable.</exception> public static ICheckLink <ICheck <IEnumerable> > IsOnlyMadeOf(this ICheck <IEnumerable> check, IEnumerable expectedValues) { var checker = ExtensibilityHelper.ExtractChecker(check); return(checker.ExecuteCheck( () => { // TODO: refactor this implementation? if (checker.Value == null && expectedValues == null) { return; } if (checker.Value == null && expectedValues != null) { var message = checker.BuildMessage("The {0} is null and thus, does not contain exactly the given value(s).").ExpectedValues(expectedValues).ToString(); throw new FluentCheckException(message); } var unexpectedValuesFound = ExtractUnexpectedValues(checker.Value, expectedValues); if (unexpectedValuesFound.Count > 0) { var message = checker.BuildMessage(string.Format("The {{0}} does not contain only the given value(s).\nIt contains also other values:\n\t[{0}]", unexpectedValuesFound.ToEnumeratedString().DoubleCurlyBraces())).ExpectedValues(expectedValues).ToString(); throw new FluentCheckException(message); } }, checker.BuildMessage("The {0} contains only the given values whereas it must not.").ExpectedValues(expectedValues).ToString())); }
/// <summary> /// Checks that the actual value is not equal to another expected value. /// </summary> /// <typeparam name="T"> /// Type of the checked value. /// </typeparam> /// <param name="check">The fluent check to be extended.</param> /// <param name="expected">The expected value.</param> /// <returns> /// A check link. /// </returns> /// <exception cref="FluentCheckException">The actual value is equal to the expected value.</exception> public static ICheckLink <ICheck <T> > IsNotEqualTo <T>(this ICheck <T> check, object expected) { var checker = ExtensibilityHelper.ExtractChecker(check); return(checker.ExecuteCheck( () => EqualityHelper.IsNotEqualTo(checker, expected), EqualityHelper.BuildErrorMessage(checker, expected, false))); }
/// <summary> /// Checks that the string does not match a given regular expression. /// </summary> /// <param name="check">The fluent check to be extended.</param> /// <param name="regExp">The regular expression prefix.</param> /// <returns> /// A check link. /// </returns> /// <exception cref="FluentCheckException">The string does not end with the expected prefix.</exception> public static ICheckLink <ICheck <string> > DoesNotMatch(this ICheck <string> check, string regExp) { var checker = ExtensibilityHelper.ExtractChecker(check); MatchesImpl(checker, regExp, true); return(checker.BuildChainingObject()); }
/// <summary> /// </summary> /// <param name="check"></param> /// <param name="expectedValue"></param> /// <returns></returns> public static ICheckLink <ICheck <ReflectionWrapper> > IsEqualTo <TU>(this ICheck <ReflectionWrapper> check, TU expectedValue) { FieldEqualTest(check, expectedValue, true); var checker = ExtensibilityHelper.ExtractChecker(check); return(checker.BuildChainingObject()); }
public void HandleProperlyNonFailingChecksOnNonChainable() { var check = Check.That(2); ExtensibilityHelper.ExtractChecker(check).ExecuteNotChainableCheck(() => { }, "should have succeedeed"); Check.ThatCode(() => ExtensibilityHelper.ExtractChecker(check).ExecuteNotChainableCheck( () => throw ExceptionHelper.BuildException("failed"), "should fail")).IsAFailingCheck(); }
/// <summary> /// Checks that the actual value is equal to another expected value. /// </summary> /// <param name="check"> /// The fluent check to be extended. /// </param> /// <param name="expected"> /// The expected value. /// </param> /// <returns> /// A check link. /// </returns> /// <exception cref="FluentCheckException"> /// The actual value is not equal to the expected value. /// </exception> public static ICheckLink <ICheck <long> > IsEqualTo(this ICheck <long> check, long expected) { var checker = ExtensibilityHelper.ExtractChecker <long>(check); return(checker.ExecuteCheck( () => EqualityHelper.IsEqualTo(checker, expected), EqualityHelper.BuildErrorMessage(checker, expected, true))); }
/// <summary> /// Convert a string to an array of lines. /// </summary> /// <param name="check">The fluent check to be processed.</param> /// <returns>A checker.</returns> public static ICheck <IEnumerable <string> > AsLines(this ICheck <string> check) { var checker = ExtensibilityHelper.ExtractChecker(check); var checkedString = checker.Value; IEnumerable <string> next = checkedString.SplitAsLines(); return(new FluentCheck <IEnumerable <string> >(next)); }
public void OfferSimpleExtensibility() { var check = Check.That(2); var checker = ExtensibilityHelper.ExtractChecker(check); Check.ThatCode(() => { checker.ExecuteCheck(() => { }, "should not fail").And.IsEqualTo(3); }).IsAFailingCheck(); }
/// <summary> /// Checks that the enumerable has the proper number of elements. /// </summary> /// <param name="check">The fluent check to be extended.</param> /// <param name="expectedSize">The expected size to be found.</param> /// <returns> /// A check link. /// </returns> /// <exception cref="FluentCheckException">The enumerable has not the expected number of elements.</exception> public static ICheckLink <ICheck <IEnumerable> > HasSize(this ICheck <IEnumerable> check, long expectedSize) { var checker = ExtensibilityHelper.ExtractChecker(check); return(checker.ExecuteCheck( () => HasSizeImpl(checker, expectedSize), BuildHasSizeExceptionMessage(checker))); }
public void ExtractcheckerWorks() { var checker = ExtensibilityHelper.ExtractChecker(new FluentCheck <string>("kamoulox")); Check.That(checker).IsNotNull(); Check.That(checker.Negated).IsFalse(); Check.That(checker.Value).IsEqualTo("kamoulox"); }
public void SupportExecuteAndProvideSubItem() { var check = Check.That(2); Check.That( ExtensibilityHelper.ExtractChecker(check) .ExecuteCheckAndProvideSubItem(() => Check.That(2), "on negation")). InheritsFrom <ICheckLinkWhich <ICheck <int>, ICheck <int> > >(); }
public void LetUnknownExceptionGetThrough() { var check = Check.That(2); Check.ThatCode(() => ExtensibilityHelper.ExtractChecker(check) .ExecuteNotChainableCheck(() => throw new ArgumentException(), "should fails")) .Throws <ArgumentException>(); }
/// <summary> /// </summary> /// <typeparam name="T"></typeparam> /// <param name="check"></param> /// <returns></returns> public static IMembersSelection Considering <T>(this ICheck <T> check) { var checker = ExtensibilityHelper.ExtractChecker(check); var fieldsWrapper = ReflectionWrapper.BuildFromInstance(checker.Value?.GetType() ?? typeof(T), checker.Value, new Criteria(BindingFlags.Instance)); var checkWithConsidering = new CheckWithConsidering(fieldsWrapper, checker.Negated); return(checkWithConsidering); }
public static void HasAttribute(this ICheck <XElement> check, string name, string value) { var actual = ExtensibilityHelper.ExtractChecker(check).Value; XAttribute xAttribute = actual.Attributes().FirstOrDefault(attribute => attribute.Name.LocalName == name); Check.That(xAttribute).IsNotNull(); // ReSharper disable once PossibleNullReferenceException Check.That(xAttribute.Value).IsEqualTo(value); }
public void HandleProperlyNegationOnFailing() { var check = Check.That(2); var checker = ExtensibilityHelper.ExtractChecker(check.Not); checker.ExecuteNotChainableCheck(() => throw ExceptionHelper.BuildException("oups"), "should have failed"); Check.ThatCode(() => checker.ExecuteNotChainableCheck(() => { }, "should have failed")) .IsAFailingCheck(); }
/// <summary> /// Checks that the actual actualValue doesn't have all fields equal to the expected actualValue ones. /// </summary> /// <typeparam name="T"> /// Type of the checked actualValue. /// </typeparam> /// <param name="check"> /// The fluent check to be extended. /// </param> /// <param name="expected"> /// The expected actualValue. /// </param> /// <returns> /// A check link. /// </returns> /// <exception cref="FluentCheckException"> /// The actual actualValue has all fields equal to the expected actualValue ones. /// </exception> /// <remarks> /// The comparison is done field by field. /// </remarks> public static ICheckLink <ICheck <T> > HasNotFieldsWithSameValues <T>(this ICheck <T> check, object expected) { var checker = ExtensibilityHelper.ExtractChecker(check); var fieldsWrapper = ReflectionWrapper.BuildFromInstance(typeof(T), checker.Value, new Criteria(BindingFlags.Instance)); var checkWithConsidering = new CheckWithConsidering(fieldsWrapper, checker.Negated).All.Fields; ReflectionWrapperChecks.FieldEqualTest(checkWithConsidering, expected, false); return(ExtensibilityHelper.BuildCheckLink(check)); }
public static ICheckLink <ICheck <BuildContext> > HasNoErrors(this ICheck <BuildContext> check) { var actual = ExtensibilityHelper.ExtractChecker(check).Value; ExtensibilityHelper.BeginCheck(check) .FailWhen(sut => sut.HasError, $"Current context has errors whereas it should not : {actual.Error?.Message}") .OnNegate("hum, I don't see any errors whereas it's supposed to have...") .EndCheck(); return(ExtensibilityHelper.BuildCheckLink(check)); }