Пример #1
0
 /// <summary>
 /// Tests if the cookie has the Domain flag
 /// </summary>
 /// <param name="more"></param>
 /// <param name="expectedDomain"></param>
 /// <returns></returns>
 public static IMore <Cookie> Domain(
     this ICanAddMatcher <Cookie> more,
     string expectedDomain
     )
 {
     return(more.Domain(expectedDomain, NULL_STRING));
 }
Пример #2
0
 /// <summary>
 /// Tests if the cookie has the HttpOnly flag
 /// </summary>
 /// <param name="more"></param>
 /// <param name="customMessage"></param>
 /// <returns></returns>
 public static IMore <Cookie> HttpOnly(
     this ICanAddMatcher <Cookie> more,
     string customMessage
     )
 {
     return(more.HttpOnly(() => customMessage));
 }
Пример #3
0
 /// <summary>
 /// Tests for any parameter on a .Method continuation
 /// </summary>
 /// <param name="continuation"></param>
 /// <param name="parameterName"></param>
 /// <returns></returns>
 public static IMore <MethodInfo> Parameter(
     this ICanAddMatcher <MethodInfo> continuation,
     string parameterName
     )
 {
     return(continuation.Parameter(parameterName, NULL_STRING));
 }
Пример #4
0
 /// <summary>
 /// Use to compose expectations into one matcher
 /// </summary>
 /// <param name="continuation">Continuation to operate on</param>
 /// <param name="expectationsRunner">Runs your composed expectations</param>
 /// <param name="messageGenerator">Generates the final message, passing in the actual instance being tested as well as a boolean for passed/failed</param>
 /// <typeparam name="T"></typeparam>
 public static IMore <T> Compose <T>(
     this ICanAddMatcher <T> continuation,
     Action <T> expectationsRunner,
     Func <T, bool, string> messageGenerator
     )
 {
     continuation.AddMatcher(actual =>
     {
         try
         {
             expectationsRunner(actual);
             return(new MatcherResult(true, () => messageGenerator(actual, true)));
         }
         catch (UnmetExpectationException e)
         {
             return(new MatcherResult(false,
                                      () => FinalMessageFor(
                                          new[] { "Specifically:", e.Message },
                                          messageGenerator?.Invoke(actual, false)
                                          )
                                      ));
         }
     });
     return(continuation.More());
 }
Пример #5
0
 /// <summary>
 /// Expects the Action to throw any kind of exception
 /// </summary>
 /// <param name="src">Action to run</param>
 /// <param name="customMessage">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,
     string customMessage
     )
 {
     return(src.Throw(() => customMessage));
 }
        private static T TryGetActual <T>(ICanAddMatcher <T> matcher)
        {
            if (matcher == null)
            {
                throw new InvalidOperationException(
                          $"Can't get an Actual value from a NULL matcher"
                          );
            }

            var prop = matcher?.GetType()
                       .GetProperties()
                       .FirstOrDefault(pi => pi.Name.ToLower() == "actual");

            if (prop == null)
            {
                throw new InvalidOperationException(
                          $"Failed to GetActual on type {typeof(T)}. GetActual only works on IHasActual<T> or objects with an 'Actual' property");
            }

            try
            {
                return((T)prop.GetValue(matcher));
            }
            catch
            {
                throw new InvalidOperationException(
                          @$ "Unable to get Actual value matching type {
                            typeof(T)
                        } from {
                            matcher.Stringify()
                        }"
Пример #7
0
 /// <summary>
 /// Expects the action to throw an exception of type T
 /// </summary>
 /// <param name="src">Action to test</param>
 /// <param name="customMessage">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,
     string customMessage
     ) where T : Exception
 {
     return(src.Throw <T>(() => customMessage));
 }
Пример #8
0
 /// <summary>
 /// Tests if the cookie has the Secure flag
 /// </summary>
 /// <param name="more"></param>
 /// <param name="customMessage"></param>
 /// <returns></returns>
 public static IMore <Cookie> Secure(
     this ICanAddMatcher <Cookie> more,
     string customMessage
     )
 {
     return(more.Secure(() => customMessage));
 }
Пример #9
0
 private static void AddRegexMatcher(
     ICanAddMatcher <string> matcher,
     Regex regex,
     Func <string> customMessageGenerator
     )
 {
     matcher.AddMatcher(
         actual =>
     {
         var passed = regex.IsMatch(actual);
         return(new MatcherResult(
                    passed,
                    FinalMessageFor(
                        () => new[]
         {
             "Expected",
             actual.Stringify(),
             $"{passed.AsNot()}to match regex",
             $"\"{regex}\""
         },
                        customMessageGenerator
                        )
                    ));
     });
 }
 private static void RunIntersectioEqualityTest <T>(
     ICanAddMatcher <T> continuation,
     object expected,
     Func <string> customMessageGenerator,
     params object[] customEqualityComparers
     )
 {
     continuation.AddMatcher(
         actual =>
     {
         var result = DeepTestHelpers.AreIntersectionEqual(
             actual,
             expected,
             customEqualityComparers);
         return(new MatcherResult(
                    result.AreEqual,
                    FinalMessageFor(
                        () => new[]
         {
             "Expected",
             actual.Stringify(),
             $"{result.AreEqual.AsNot()}to intersection equal",
             expected.Stringify()
         }.Concat(result.Errors).ToArray(),
                        customMessageGenerator
                        )
                    ));
     }
         );
 }
Пример #11
0
        /// <summary>
        /// Tests that the provided method info returns the expected type
        /// </summary>
        /// <param name="continuation"></param>
        /// <param name="expected"></param>
        /// <param name="customMessageGenerator"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public static IMore <MethodInfo> Returns(
            this ICanAddMatcher <MethodInfo> continuation,
            Type expected,
            Func <string> customMessageGenerator
            )
        {
            return(continuation.AddMatcher(actual =>
            {
                if (actual is null)
                {
                    throw new InvalidOperationException(
                        $"Cannot test return type on null MethodInfo"
                        );
                }

                var passed = actual.ReturnType == expected;
                return new MatcherResult(
                    passed,
                    FinalMessageFor(
                        () => $@"Expected '{
                            actual.Name
                        }' {
                            passed.AsNot()
                        } to have return value of type {expected} (found: {actual.ReturnType})",
                        customMessageGenerator
                        )
                    );
            }));
        }
Пример #12
0
 /// <summary>
 /// Add a matcher onto a Collection continuation
 /// </summary>
 /// <param name="continuation">Continuation to add matcher to</param>
 /// <param name="matcher">Matcher to run</param>
 /// <typeparam name="T">Type of the object under test</typeparam>
 public static void AddMatcher <T>(
     this ICanAddMatcher <IEnumerable <T> > continuation,
     Func <IEnumerable <T>, IMatcherResult> matcher
     )
 {
     AddMatcherPrivate(continuation, matcher);
 }
Пример #13
0
 /// <summary>
 /// Tests the return value on a .Method continuation
 /// </summary>
 /// <param name="continuation"></param>
 /// <param name="expected"></param>
 /// <returns></returns>
 public static IMore <MethodInfo> Returns(
     this ICanAddMatcher <MethodInfo> continuation,
     Type expected
     )
 {
     return(continuation.Returns(expected, NULL_STRING));
 }
Пример #14
0
        /// <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);
        }
Пример #15
0
 /// <summary>
 /// Most general matcher add - onto ICanAddMatcher&lt;T&gt;
 /// </summary>
 /// <param name="continuation">Continuation to add matcher to</param>
 /// <param name="matcher">Matcher to run</param>
 /// <typeparam name="T">Type of the object under test</typeparam>
 public static IMore <T> AddMatcher <T>(
     this ICanAddMatcher <T> continuation,
     Func <T, IMatcherResult> matcher)
 {
     AddMatcherPrivate(continuation, matcher);
     return(continuation.More());
 }
Пример #16
0
 /// <summary>
 /// Use to compose expectations into one matcher
 /// </summary>
 /// <param name="continuation">Continuation to operate on</param>
 /// <param name="expectationsRunner">Runs your composed expectations</param>
 /// <param name="messageGenerator">Generates the final message, passing in the actual instance being tested as well as a boolean for passed/failed</param>
 /// <typeparam name="T"></typeparam>
 public static IMore <T> Compose <T>(
     this ICanAddMatcher <T> continuation,
     Action <T> expectationsRunner,
     Func <T, bool, string> messageGenerator
     )
 {
     continuation.AddMatcher(actual =>
     {
         try
         {
             // if we're using custom assertions, we won't get an UnmetExpectationException
             // on a failure
             // worse, if those custom assertions are from NUnit, we can't stop the failure
             // -> it's part of the design of NUnit
             using var _ = Assertions.TemporarilyUseDefaultAssertionsFactoryForThisThread();
             expectationsRunner(actual);
             return(new MatcherResult(true, () => messageGenerator(actual, true)));
         }
         catch (UnmetExpectationException e)
         {
             return(new MatcherResult(false,
                                      () => FinalMessageFor(
                                          new[] { "Specifically:", e.Message },
                                          messageGenerator?.Invoke(actual, false)
                                          )
                                      ));
         }
     });
     return(continuation.More());
 }
Пример #17
0
 /// <summary>
 /// Tests if the value under test contains a given string. May be continued
 /// with ".And"
 /// </summary>
 /// <param name="continuation">Continuation to act on</param>
 /// <param name="search">String value to search for</param>
 /// <returns>IStringContainContinuation onto which you can chain .And</returns>
 public static IStringMore Contain(
     this ICanAddMatcher <string> continuation,
     string search
     )
 {
     return(continuation.Contain(search, NULL_STRING));
 }
Пример #18
0
 private static void AddRegexMatcher(
     ICanAddMatcher <string> matcher,
     string regex,
     Func <string> customMessage
     )
 {
     AddRegexMatcher(matcher, CompileRegexFor(regex), customMessage);
 }
Пример #19
0
 private static void CheckContain <T>(ICanAddMatcher <IEnumerable <T> > contain)
 {
     if (contain == null)
     {
         throw new ArgumentNullException(nameof(contain),
                                         $"Exactly<T>() cannot extend null IContain<IEnumerable<{typeof(T).Name}>>");
     }
 }
Пример #20
0
 /// <summary>
 /// Tests the return value on a .Method continuation
 /// </summary>
 /// <param name="continuation"></param>
 /// <param name="expected"></param>
 /// <param name="customMessage"></param>
 /// <returns></returns>
 public static IMore <MethodInfo> Returns(
     this ICanAddMatcher <MethodInfo> continuation,
     Type expected,
     string customMessage
     )
 {
     return(continuation.Returns(expected, () => customMessage));
 }
Пример #21
0
 /// <summary>
 /// Tests if the value under test contains a given string. May be continued
 /// with ".And"
 /// </summary>
 /// <param name="continuation">Continuation to act on</param>
 /// <param name="search">String value to search for</param>
 /// <param name="customMessage">Custom message to include in failure messages</param>
 /// <returns>IStringContainContinuation onto which you can chain .And</returns>
 public static IStringMore Contain(
     this ICanAddMatcher <string> continuation,
     string search,
     string customMessage
     )
 {
     return(continuation.Contain(search, () => customMessage));
 }
Пример #22
0
 /// <summary>
 /// Tests if the cookie has the Domain flag
 /// </summary>
 /// <param name="more"></param>
 /// <param name="expectedDomain"></param>
 /// <param name="customMessage"></param>
 /// <returns></returns>
 public static IMore <Cookie> Domain(
     this ICanAddMatcher <Cookie> more,
     string expectedDomain,
     string customMessage
     )
 {
     return(more.Domain(expectedDomain, () => customMessage));
 }
Пример #23
0
 public static IStringContainContinuation Contain(
     this ICanAddMatcher <string> continuation,
     string search
     )
 {
     AddContainsMatcherTo(continuation, search);
     return(new StringContainContinuation(continuation));
 }
Пример #24
0
 /// <summary>
 /// Use to compose expectations into one matcher
 /// </summary>
 /// <param name="continuation">Continuation to operate on</param>
 /// <param name="expectationsRunner">Runs your composed expectations</param>
 /// <param name="callingMethod"></param>
 /// <typeparam name="T"></typeparam>
 public static IMore <T> Compose <T>(
     this ICanAddMatcher <T> continuation,
     Action <T> expectationsRunner,
     [CallerMemberName] string callingMethod = null
     )
 {
     return(continuation.Compose(expectationsRunner,
                                 (a, b) => $"Expectation \"{callingMethod}\" should {(!b).AsNot()}have failed."));
 }
Пример #25
0
        private static IMore <T> Property <T>(
            this ICanAddMatcher <T> canAddMatcher,
            string property,
            Func <string> customMessageGenerator
            )
        {
            return(canAddMatcher.AddMatcher(actual =>
            {
                if (string.IsNullOrWhiteSpace(property))
                {
                    return Fail(() => "Provided property name is null or whitespace");
                }

                if (actual is null)
                {
                    return Fail(() => "Actual value is null");
                }

                actual.SetMetadata(METADATA_KEY_PROPERTY_NAME, property);
                var actualType = actual.ResolveToType();

                var propInfo = actualType.GetProperty(property, PUBLIC_INSTANCE);
                if (propInfo is null)
                {
                    return new MatcherResult(
                        false,
                        () =>
                        $@"Expected {
                                actualType.PrettyName()
                            } {
                                false.AsNot()
                            }to have a public property named '{property}'"
                        );
                }


                actual.SetMetadata(METADATA_KEY_PROPERTY_INFO, propInfo);
                return new MatcherResult(
                    true,
                    FinalMessageFor(
                        () => $"Expected {actual.Stringify()} {true.AsNot()}to have property '{property}'",
                        customMessageGenerator
                        )
                    );
            }));

            MatcherResult Fail(Func <string> defaultGenerator)
            {
                return(new MatcherResult(
                           false,
                           () => FinalMessageFor(
                               defaultGenerator,
                               customMessageGenerator
                               )
                           ));
            }
        }
Пример #26
0
 /// <summary>
 /// Creates an object with .And on it which you can use to chain on more
 /// expectations, eg Expect(1).To.Be.SomeCustomMatcher().And.SomeOtherMatcher()
 /// </summary>
 /// <param name="continuation"></param>
 /// <returns></returns>
 public static IStringMore More(
     this ICanAddMatcher <string> continuation
     )
 {
     return(ContinuationFactory.Create <string, StringMore>(
                continuation.GetActual(),
                continuation as IExpectationContext <string>
                ));
 }
Пример #27
0
 /// <summary>
 /// Use to compose expectations into one matcher
 /// </summary>
 /// <param name="continuation">Continuation to operate on</param>
 /// <param name="expectationsRunner">Runs your composed expectations</param>
 /// <param name="callingMethod"></param>
 /// <typeparam name="T"></typeparam>
 public static IMore <IEnumerable <T> > Compose <T>(
     this ICanAddMatcher <IEnumerable <T> > continuation,
     Action <IEnumerable <T> > expectationsRunner,
     [CallerMemberName] string callingMethod = null
     )
 {
     return(continuation.Compose(expectationsRunner,
                                 (a, b) => $"{callingMethod} should {b.AsNot()}have passed."));
 }
Пример #28
0
 public CountMatchDeepEqual(
     ICanAddMatcher <T> continuation,
     CountMatchMethods method,
     int compare)
 {
     Continuation  = continuation;
     Method        = method;
     ExpectedCount = compare;
 }
Пример #29
0
 public CountMatchMatched(
     ICanAddMatcher <T> continuation,
     CountMatchMethods method,
     int compare)
 {
     Continuation = continuation;
     Method       = method;
     Compare      = compare;
 }
        /// <summary>
        /// Attempts to sniff the actual value off of a continuation
        /// </summary>
        /// <param name="matcher">Continuation to operate on</param>
        /// <typeparam name="T">Expected type of the Actual value</typeparam>
        /// <returns>Actual value, if available</returns>
        public static T GetActual <T>(this ICanAddMatcher <T> matcher)
        {
            // ReSharper disable once UsePatternMatching
            var explicitImpl = matcher as IHasActual <T>;

            return(explicitImpl == null
                ? TryGetActual(matcher)
                : explicitImpl.Actual);
        }