예제 #1
0
        static void Check(object expected, object actual, ShouldLookLikeOptions options, Pair <string> path, HashSet <object> visitedExpecteds)
        {
            if (actual == null && expected == null)
            {
                return;
            }

            if (actual == null || expected == null)
            {
                Reject(expected, actual, path, options);
            }

            if (visitedExpecteds.Contains(expected))
            {
                return;
            }
            visitedExpecteds.Add(expected);

            var type = actual.GetType();

            if (expected.GetType() != type)
            {
                Reject(expected, actual, path, options);
            }

            if (type.IsValueType || actual is string)
            {
                if (!actual.Equals(expected))
                {
                    Reject(expected, actual, path, options);
                }
                return;
            }

            if (actual is System.Collections.IEnumerable)
            {
                var allItems = ToObjectList(expected).Concat(ToObjectList(actual)).Where(x => x != null).ToList();
                if (!allItems.Any())
                {
                    return;
                }
                var concreteItemType = allItems.First().GetType();
                var enumOption       = options.EnumerableOptions.FirstOrDefault(x => x.ItemType.IsAssignableFrom(concreteItemType)) ?? new EnumerableOption();

                if (enumOption.Comparison == EnumerableComparison.Strict)
                {
                    CheckEnumerableStrict(expected, actual, options, path, visitedExpecteds);
                }
                else
                {
                    CheckEnumerableUnordered(expected, actual, options, enumOption, path, visitedExpecteds);
                }
                return;
            }

            var fields = type.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.FlattenHierarchy);

            foreach (var fi in fields)
            {
                Check(fi.GetValue(expected), fi.GetValue(actual), options, fi.Name.Cons(path), visitedExpecteds);
            }

            var propsWithGetters = type.GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.FlattenHierarchy)
                                   .Select(pi => new { Prop = pi, Get = pi.GetGetMethod(false) }).Where(z => z.Get != null);

            foreach (var z in propsWithGetters)
            {
                object propExpected = null;
                object propActual   = null;
                try
                {
                    propExpected = z.Get.Invoke(expected, new object[0]);
                    propActual   = z.Get.Invoke(actual, new object[0]);
                }
                catch (Exception)
                {
                    Reject(propExpected, propActual, z.Prop.Name.Cons(path), options);
                    return;
                }
                Check(propExpected, propActual, options, z.Prop.Name.Cons(path), visitedExpecteds);
            }
        }
예제 #2
0
        static void CheckEnumerableStrict(object expected, object actual, ShouldLookLikeOptions options, Pair <string> path, HashSet <object> visitedExpecteds)
        {
            var expectedObjects = ToObjectList(expected);
            var actualObjects   = ToObjectList(actual);

            if (expectedObjects.Count != actualObjects.Count)
            {
                Reject(expected, actual, path, options);
            }

            var q = expectedObjects.Zip(actualObjects, (e, a) => new { Expected = e, Actual = a });
            int c = 0;

            foreach (var z in q)
            {
                Check(z.Expected, z.Actual, options, Bracketize(c).Cons(path), visitedExpecteds);
                c++;
            }
        }