private static void AssertCollectionEqual(IEnumerable expected, IEnumerable actual)
        {
            if (expected == null)
            {
                Assert.IsNull(actual);
                return;
            }
            Assert.IsNotNull(actual);

            IEnumerator exp   = expected.GetEnumerator();
            IEnumerator act   = actual.GetEnumerator();
            int         moved = 0;

            do
            {
                moved = (exp.MoveNext(), act.MoveNext()) switch
                {
                    (true, true) => 2,
                    (true, false) => 1,
                    (false, true) => 2,
                    (false, false) => 0
                };
                if (moved == 2)
                {
                    SearchTestBase.AssertApproximate(exp.Current, act.Current);
                }
            } while (moved == 2);
            Assert.Zero(moved);
        }
            private void AssertReadDictionary(SearchDocument doc)
            {
                object actual = doc["Value"];

                bool isCollection = IsCollection <T>();

                if (actual != null)
                {
                    if (!isCollection)
                    {
                        Assert.IsInstanceOf <T>(actual);
                    }
                    else
                    {
                        // Note: Arrays returned by the indexer are object[], not T[]
                        Assert.IsInstanceOf <object[]>(actual);
                    }
                }

                if (!isCollection)
                {
                    SearchTestBase.AssertApproximate(Expected, actual);
                }
                else
                {
                    if (actual != null)
                    {
                        CollectionAssert.AllItemsAreInstancesOfType(actual as IEnumerable, typeof(T).GetGenericArguments()[0]);
                    }
                    AssertCollectionEqual(Expected as IEnumerable, actual as IEnumerable);
                }
            }
            private void AssertReadGetter(SearchDocument doc, Func <SearchDocument, string, T> getter)
            {
                Assert.IsNotNull(getter);
                T actual = getter(doc, "Value");

                if (!IsCollection <T>())
                {
                    SearchTestBase.AssertApproximate(Expected, actual);
                }
                else
                {
                    AssertCollectionEqual(Expected as IEnumerable, actual as IEnumerable);
                }
            }
            private void AssertReadDynamic(SearchDocument doc)
            {
                dynamic dyn = doc;

                if (!IsCollection <T>())
                {
                    T actual = dyn.Value;
                    SearchTestBase.AssertApproximate(Expected, actual);
                }
                else
                {
                    // TODO: Change from object[] to T when DynamicData has better conversions
                    object[] actual = dyn.Value;
                    AssertCollectionEqual(Expected as IEnumerable, actual as IEnumerable);
                }
            }