public void TestNearWithSphericalTrue()
        {
            var query    = Query.Near("loc", 1.1, 2.2, 3.3, true);
            var expected = "{ 'loc' : { '$nearSphere' : [1.1, 2.2], '$maxDistance' : 3.3 } }".Replace("'", "\"");

            Assert.AreEqual(expected, query.ToJson());
        }
        public void TestMod()
        {
            var query    = Query.Mod("a", 10, 1);
            var expected = "{ \"a\" : { \"$mod\" : [10, 1] } }";

            Assert.AreEqual(expected, query.ToJson());
        }
        public void TestNear()
        {
            var query    = Query.Near("loc", 1.1, 2.2);
            var expected = "{ 'loc' : { '$near' : [1.1, 2.2] } }".Replace("'", "\"");

            Assert.AreEqual(expected, query.ToJson());
        }
        public void TestLessThanOrEqualAndNotIn()
        {
            var query    = Query.LTE("k", 20).NotIn(7, 11);
            var expected = "{ \"k\" : { \"$lte\" : 20, \"$nin\" : [7, 11] } }";

            Assert.AreEqual(expected, query.ToJson());
        }
        public void TestMatches()
        {
            var query    = Query.Matches("a", "/abc/");
            var expected = "{ 'a' : /abc/ }".Replace("'", "\"");

            Assert.AreEqual(expected, query.ToJson());
        }
        public void TestNewSyntax()
        {
            var query    = Query.GTE("x", 3).LTE(10);
            var expected = "{ \"x\" : { \"$gte\" : 3, \"$lte\" : 10 } }";

            Assert.AreEqual(expected, query.ToJson());
        }
        public void TestLessThanOrEqualAndNotEquals()
        {
            var query    = Query.LTE("k", 10).NE(5);
            var expected = "{ \"k\" : { \"$lte\" : 10, \"$ne\" : 5 } }";

            Assert.AreEqual(expected, query.ToJson());
        }
        public void TestGreaterThanOrEqualAndLessThanOrEqual()
        {
            var query    = Query.GTE("k", 10).LTE(20);
            var expected = "{ \"k\" : { \"$gte\" : 10, \"$lte\" : 20 } }";

            Assert.AreEqual(expected, query.ToJson());
        }
        public void TestLessThanOrEqual()
        {
            var query    = Query.LTE("k", 10);
            var expected = "{ \"k\" : { \"$lte\" : 10 } }";

            Assert.AreEqual(expected, query.ToJson());
        }
        public void TestGreaterThanAndMod()
        {
            var query    = Query.GT("k", 10).Mod(10, 1);
            var expected = "{ \"k\" : { \"$gt\" : 10, \"$mod\" : [10, 1] } }";

            Assert.AreEqual(expected, query.ToJson());
        }
        public void TestGreaterThan()
        {
            var query    = Query.GT("k", 10);
            var expected = "{ \"k\" : { \"$gt\" : 10 } }";

            Assert.AreEqual(expected, query.ToJson());
        }
        public void TestExistsFalse()
        {
            var query    = Query.Exists("x", false);
            var expected = "{ \"x\" : { \"$exists\" : false } }";

            Assert.AreEqual(expected, query.ToJson());
        }
        public void TestNotEquals()
        {
            var query    = Query.NE("j", 3);
            var expected = "{ \"j\" : { \"$ne\" : 3 } }";

            Assert.AreEqual(expected, query.ToJson());
        }
        public void TestWithinRectangle()
        {
            var query    = Query.WithinRectangle("loc", 1.1, 2.2, 3.3, 4.4);
            var expected = "{ 'loc' : { '$within' : { '$box' : [[1.1, 2.2], [3.3, 4.4]] } } }".Replace("'", "\"");

            Assert.AreEqual(expected, query.ToJson());
        }
        public void TestEquals()
        {
            var query    = Query.EQ("x", 3);
            var expected = "{ \"x\" : 3 }";

            Assert.AreEqual(expected, query.ToJson());
        }
        public void TestWithinCircleSpherical()
        {
            var query    = Query.WithinCircle("loc", 1.1, 2.2, 3.3, true);
            var expected = "{ 'loc' : { '$within' : { '$centerSphere' : [[1.1, 2.2], 3.3] } } }".Replace("'", "\"");

            Assert.AreEqual(expected, query.ToJson());
        }
        public void TestWhere()
        {
            var query    = Query.Where("this.a > 3");
            var expected = "{ \"$where\" : { \"$code\" : \"this.a > 3\" } }";

            Assert.AreEqual(expected, query.ToJson());
        }
        public void TestSizeAndAll()
        {
            var query    = Query.Size("k", 20).All(7, 11);
            var expected = "{ \"k\" : { \"$size\" : 20, \"$all\" : [7, 11] } }";

            Assert.AreEqual(expected, query.ToJson());
        }
        public void TestType()
        {
            var query    = Query.Type("a", BsonType.String);
            var expected = "{ \"a\" : { \"$type\" : 2 } }";

            Assert.AreEqual(expected, query.ToJson());
        }
        public void TestAllParams()
        {
            var query    = Query.All("j", 2, 4, null, 6); // null will be skipped due to functional construction semantics
            var expected = "{ \"j\" : { \"$all\" : [2, 4, 6] } }";

            Assert.AreEqual(expected, query.ToJson());
        }
        public void TestSize()
        {
            var query    = Query.Size("k", 20);
            var expected = "{ \"k\" : { \"$size\" : 20 } }";

            Assert.AreEqual(expected, query.ToJson());
        }
        public void TestOrWithEmptyQuery()
        {
            var emptyQuery = new QueryDocument();

            var query    = Query.Or(emptyQuery);
            var expected = "{ }";

            Assert.AreEqual(expected, query.ToJson());

            query    = Query.Or(emptyQuery, emptyQuery);
            expected = "{ }";
            Assert.AreEqual(expected, query.ToJson());

            query    = Query.Or(emptyQuery, Query.EQ("x", 1));
            expected = "{ \"x\" : 1 }";
            Assert.AreEqual(expected, query.ToJson());

            query    = Query.Or(Query.EQ("x", 1), emptyQuery);
            expected = "{ \"x\" : 1 }";
            Assert.AreEqual(expected, query.ToJson());

            query    = Query.Or(emptyQuery, Query.EQ("x", 1), emptyQuery);
            expected = "{ \"x\" : 1 }";
            Assert.AreEqual(expected, query.ToJson());

            query    = Query.Or(Query.EQ("x", 1), emptyQuery, Query.EQ("y", 2));
            expected = "{ \"$or\" : [{ \"x\" : 1 }, { \"y\" : 2 }] }";
            Assert.AreEqual(expected, query.ToJson());
        }
        public void TestWithinPolygonInvalidSecondDimension()
        {
            var points = new double[, ] {
                { 1, 2, 3 }
            };

            Assert.Throws <ArgumentOutOfRangeException>(() => Query.WithinPolygon("loc", points));
        }
        public void TestNinBsonArray()
        {
            var array = new BsonArray {
                2, 4, null, 6
            };                                           // null will be skipped due to functional construction semantics
            var query    = Query.NotIn("j", array);
            var expected = "{ \"j\" : { \"$nin\" : [2, 4, 6] } }";

            Assert.AreEqual(expected, query.ToJson());
        }
        public void TestWithinPolygon()
        {
            var points = new double[, ] {
                { 1.1, 2.2 }, { 3.3, 4.4 }
            };
            var query    = Query.WithinPolygon("loc", points);
            var expected = "{ 'loc' : { '$within' : { '$polygon' : [[1.1, 2.2], [3.3, 4.4]] } } }".Replace("'", "\"");

            Assert.AreEqual(expected, query.ToJson());
        }
        public void TestAnd()
        {
            var query = Query.And(
                Query.EQ("a", 1),
                Query.EQ("b", 2)
                );
            var expected = "{ \"a\" : 1, \"b\" : 2 }";

            Assert.AreEqual(expected, query.ToJson());
        }
        public void TestAllIEnumerableBsonValue()
        {
            var enumerable = new List <BsonValue> {
                2, 4, null, 6
            };                                                      // null will be skipped due to functional construction semantics
            var query    = Query.All("j", enumerable);
            var expected = "{ \"j\" : { \"$all\" : [2, 4, 6] } }";

            Assert.AreEqual(expected, query.ToJson());
        }
        public void TestOr()
        {
            var query = Query.Or(
                Query.EQ("a", 1),
                Query.EQ("b", 2)
                );
            var expected = "{ \"$or\" : [{ \"a\" : 1 }, { \"b\" : 2 }] }";

            Assert.AreEqual(expected, query.ToJson());
        }
        public void TestEqualsTwoElements()
        {
            var query = Query.And(
                Query.EQ("x", 3),
                Query.EQ("y", "foo")
                );
            var expected = "{ \"x\" : 3, \"y\" : \"foo\" }";

            Assert.AreEqual(expected, query.ToJson());
        }
        public void TestNotSize()
        {
            var query    = Query.Not("name").Size(1);
            var expected = "{ \"name\" : { \"$not\" : { \"$size\" : 1 } } }";
            JsonWriterSettings settings = new JsonWriterSettings {
                OutputMode = JsonOutputMode.JavaScript
            };
            var actual = query.ToJson(settings);

            Assert.AreEqual(expected, actual);
        }