/// <summary>
        /// Specifies another verification.
        /// </summary>
        /// <param name="assertionTracker">The assertion tracker.</param>
        /// <returns>
        /// The assertion tracker.
        /// </returns>
        public static AssertionTracker And(
            [ValidatedNotNull] this AssertionTracker assertionTracker)
        {
            assertionTracker.ThrowImproperUseOfFrameworkIfDetected(AssertionTrackerShould.Exist, AssertionTrackerShould.BeMusted, AssertionTrackerShould.BeVerifiedAtLeastOnce);

            return(assertionTracker);
        }
        /// <summary>
        /// Specifies that the verifications should be applied
        /// to the elements of the <see cref="IEnumerable"/> subject.
        /// </summary>
        /// <param name="assertionTracker">The assertion tracker.</param>
        /// <returns>
        /// The assertion tracker in a state where verifications will be
        /// applied to the elements of the <see cref="IEnumerable"/> subject.
        /// </returns>
        public static AssertionTracker Each(
            [ValidatedNotNull] this AssertionTracker assertionTracker)
        {
            assertionTracker.ThrowImproperUseOfFrameworkIfDetected(AssertionTrackerShould.Exist, AssertionTrackerShould.BeMusted, AssertionTrackerShould.NotBeEached);

            assertionTracker.Actions |= Actions.Eached;

            return(assertionTracker);
        }
Esempio n. 3
0
        private static Exception BuildException(
            AssertionTracker assertionTracker,
            Verification verification,
            string exceptionMessage,
            ArgumentExceptionKind argumentExceptionKind)
        {
            Exception result;

            switch (assertionTracker.AssertionKind)
            {
            case AssertionKind.Unknown:
                result = new AssertionVerificationFailedException(exceptionMessage);
                break;

            case AssertionKind.Argument:
                switch (argumentExceptionKind)
                {
                case ArgumentExceptionKind.ArgumentException:
                    result = new ArgumentException(exceptionMessage);
                    break;

                case ArgumentExceptionKind.ArgumentNullException:
                    result = new ArgumentNullException(null, exceptionMessage);
                    break;

                case ArgumentExceptionKind.ArgumentOutOfRangeException:
                    result = new ArgumentOutOfRangeException(exceptionMessage, (Exception)null);
                    break;

                default:
                    throw new NotSupportedException(Invariant($"This {nameof(ArgumentExceptionKind)} is not supported: {argumentExceptionKind}."));
                }

                break;

            case AssertionKind.Operation:
                result = new InvalidOperationException(exceptionMessage);
                break;

            case AssertionKind.Test:
                result = new TestAssertionVerificationFailedException(exceptionMessage);
                break;

            default:
                throw new NotSupportedException(Invariant($"This {nameof(AssertionKind)} is not supported: {assertionTracker.AssertionKind}."));
            }

            result.AddData(verification.Data);

            return(result);
        }
Esempio n. 4
0
        private static string BuildVerificationFailedExceptionMessage(
            AssertionTracker assertionTracker,
            Verification verification,
            VerifiableItem verifiableItem,
            string exceptionMessageSuffix,
            Include include        = Include.None,
            string methodologyInfo = null,
            string contextualInfo  = null)
        {
            if (verification.ApplyBecause == ApplyBecause.InLieuOfDefaultMessage)
            {
                // we force to empty string if null because otherwise when the exception is
                // constructed the framework chooses some generic message like 'An exception of type ArgumentException was thrown'
                return(verification.Because ?? string.Empty);
            }

            var subjectNameQualifier = assertionTracker.SubjectName == null ? string.Empty : Invariant($" (name: '{assertionTracker.SubjectName}')");

            var enumerableQualifier = verifiableItem.ItemIsElementInEnumerable ? " contains an element that" : string.Empty;

            var methodologyInfoQualifier = methodologyInfo == null ? null : " " + methodologyInfo;

            var contextualInfoQualifier = contextualInfo == null ? null : "  " + contextualInfo;

            var failingValueQualifier = include.HasFlag(Include.FailingValue) ? (verifiableItem.ItemIsElementInEnumerable ? "  Element value" : "  Provided value") + Invariant($" is {verifiableItem.ItemValue.ToStringInErrorMessage()}.") : string.Empty;

            var verificationParametersQualifier = verification.VerificationParameters == null || !verification.VerificationParameters.Any() ? string.Empty : string.Join(string.Empty, verification.VerificationParameters.Select(_ => _.ToStringInErrorMessage()));

            var result = Invariant($"Provided value{subjectNameQualifier}{enumerableQualifier} {exceptionMessageSuffix}{methodologyInfoQualifier}.{contextualInfoQualifier}{failingValueQualifier}{verificationParametersQualifier}");

            if (verification.ApplyBecause == ApplyBecause.PrefixedToDefaultMessage)
            {
                if (!string.IsNullOrWhiteSpace(verification.Because))
                {
                    result = verification.Because + "  " + result;
                }
            }
            else if (verification.ApplyBecause == ApplyBecause.SuffixedToDefaultMessage)
            {
                if (!string.IsNullOrWhiteSpace(verification.Because))
                {
                    result = result + "  " + verification.Because;
                }
            }
            else
            {
                throw new NotSupportedException(Invariant($"This {nameof(ApplyBecause)} is not supported: {verification.ApplyBecause}"));
            }

            return(result);
        }
        private static AssertionTracker BuildTrackerFromAnonymousObject <TSubject>(
            [ValidatedNotNull] this TSubject value,
            string name = null,
            AssertionKind assertionKind = AssertionKind.Unknown)
        {
            var subjectType = typeof(TSubject);

            AssertionTracker result = null;

            if (!ReferenceEquals(value, null))
            {
                if (subjectType.IsClosedAnonymousTypeFastCheck())
                {
                    // with one property?  that's the subject we are trying to apply verification to.
                    var properties = subjectType.GetProperties();
                    if (properties.Length == 1)
                    {
                        result = new AssertionTracker
                        {
                            SubjectValue  = properties[0].GetValue(value, null),
                            SubjectName   = name ?? properties[0].Name,
                            SubjectType   = properties[0].PropertyType,
                            AssertionKind = assertionKind,
                        };

                        if (assertionKind != AssertionKind.Unknown)
                        {
                            result.Actions |= Actions.Categorized;
                        }

                        if (result.SubjectName != null)
                        {
                            result.Actions |= Actions.Named;
                        }
                    }
                    else
                    {
                        var errorMessage = string.Format(CultureInfo.InvariantCulture, Verifications.AnonymousObjectDoesNotHaveSinglePropertyErrorMessage, properties.Length, string.Join(", ", properties.Select(_ => _.Name).ToArray()));

                        ThrowImproperUseOfFramework(errorMessage);
                    }
                }
            }

            return(result);
        }
        /// <summary>
        /// Throws an exception if an improper use of the framework is detected.
        /// </summary>
        /// <param name="assertionTracker">The assertion tracker.</param>
        /// <param name="assertionTrackerShoulds">Specifies what should or should not be true about the assertion tracker.</param>
        internal static void ThrowImproperUseOfFrameworkIfDetected(
            [ValidatedNotNull] this AssertionTracker assertionTracker,
            params AssertionTrackerShould[] assertionTrackerShoulds)
        {
            var shouldThrow = false;

            if (assertionTracker == null)
            {
                shouldThrow = true;
            }
            else
            {
                foreach (var assertionTrackerShould in assertionTrackerShoulds)
                {
                    switch (assertionTrackerShould)
                    {
                    case AssertionTrackerShould.Exist:
                        shouldThrow = assertionTracker.SubjectType == null;
                        break;

                    case AssertionTrackerShould.NotExist:
                        shouldThrow = true;
                        break;

                    case AssertionTrackerShould.BeCategorized:
                        shouldThrow = (!assertionTracker.Actions.HasFlag(Actions.Categorized)) || (assertionTracker.AssertionKind == AssertionKind.Unknown);
                        break;

                    case AssertionTrackerShould.NotBeCategorized:
                        shouldThrow = assertionTracker.Actions.HasFlag(Actions.Categorized) || (assertionTracker.AssertionKind != AssertionKind.Unknown);
                        break;

                    case AssertionTrackerShould.BeNamed:
                        shouldThrow = (!assertionTracker.Actions.HasFlag(Actions.Named)) || (assertionTracker.SubjectName == null);
                        break;

                    case AssertionTrackerShould.NotBeNamed:
                        shouldThrow = assertionTracker.Actions.HasFlag(Actions.Named) || (assertionTracker.SubjectName != null);
                        break;

                    case AssertionTrackerShould.BeMusted:
                        shouldThrow = !assertionTracker.Actions.HasFlag(Actions.Musted);
                        break;

                    case AssertionTrackerShould.NotBeMusted:
                        shouldThrow = assertionTracker.Actions.HasFlag(Actions.Musted);
                        break;

                    case AssertionTrackerShould.BeEached:
                        shouldThrow = !assertionTracker.Actions.HasFlag(Actions.Eached);
                        break;

                    case AssertionTrackerShould.NotBeEached:
                        shouldThrow = assertionTracker.Actions.HasFlag(Actions.Eached);
                        break;

                    case AssertionTrackerShould.BeVerifiedAtLeastOnce:
                        shouldThrow = !assertionTracker.Actions.HasFlag(Actions.VerifiedAtLeastOnce);
                        break;

                    case AssertionTrackerShould.NotBeVerified:
                        shouldThrow = assertionTracker.Actions.HasFlag(Actions.VerifiedAtLeastOnce);
                        break;

                    default:
                        shouldThrow = true;
                        break;
                    }

                    if (shouldThrow)
                    {
                        break;
                    }
                }
            }

            if (shouldThrow)
            {
                ThrowImproperUseOfFramework(Verifications.SubjectAndOperationSequencingErrorMessage);
            }
        }
Esempio n. 7
0
#pragma warning disable SA1201

        private static void ExecuteVerification(
            this AssertionTracker assertionTracker,
            Verification verification)
        {
            assertionTracker.ThrowImproperUseOfFrameworkIfDetected(AssertionTrackerShould.Exist, AssertionTrackerShould.BeMusted);

            var hasBeenEached = assertionTracker.Actions.HasFlag(Actions.Eached);

            if (hasBeenEached)
            {
                // check that the subject is an IEnumerable and not null
                if (!assertionTracker.Actions.HasFlag(Actions.VerifiedAtLeastOnce))
                {
                    var eachVerification = new Verification
                    {
                        Name = nameof(WorkflowExtensions.Each),
                    };

                    var eachVerifiableItem = new VerifiableItem
                    {
                        ItemValue = assertionTracker.SubjectValue,
                        ItemType  = assertionTracker.SubjectType,
                        ItemIsElementInEnumerable = false,
                    };

                    ThrowIfNotAssignableToType(eachVerification, eachVerifiableItem, MustBeEnumerableTypeValidations.Single());

                    NotBeNullInternal(assertionTracker, eachVerification, eachVerifiableItem);
                }

                var valueAsEnumerable = (IEnumerable)assertionTracker.SubjectValue;

                var enumerableElementType = assertionTracker.SubjectType.GetClosedEnumerableElementType();

                var verifiableItem = new VerifiableItem
                {
                    ItemIsElementInEnumerable = true,
                    ItemType = enumerableElementType,
                };

                foreach (var typeValidation in verification.TypeValidations ?? new TypeValidation[] { })
                {
                    typeValidation.Handler(verification, verifiableItem, typeValidation);
                }

                foreach (var element in valueAsEnumerable)
                {
                    verifiableItem.ItemValue = element;

                    verification.Handler(assertionTracker, verification, verifiableItem);
                }
            }
            else
            {
                var verifiableItem = new VerifiableItem
                {
                    ItemIsElementInEnumerable = false,
                    ItemValue = assertionTracker.SubjectValue,
                    ItemType  = assertionTracker.SubjectType,
                };

                foreach (var typeValidation in verification.TypeValidations ?? new TypeValidation[] { })
                {
                    typeValidation.Handler(verification, verifiableItem, typeValidation);
                }

                verification.Handler(assertionTracker, verification, verifiableItem);
            }

            assertionTracker.Actions |= Actions.VerifiedAtLeastOnce;
        }