Package de.bwaldvogel.mongo.backend

Source Code of de.bwaldvogel.mongo.backend.DefaultQueryMatcherTest

package de.bwaldvogel.mongo.backend;

import static org.fest.assertions.Assertions.assertThat;
import static org.junit.Assert.fail;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.regex.Pattern;

import org.bson.BSONObject;
import org.bson.BasicBSONObject;
import org.junit.Before;
import org.junit.Test;

import com.mongodb.BasicDBObject;
import com.mongodb.DBObject;
import com.mongodb.util.JSON;

import de.bwaldvogel.mongo.exception.MongoServerError;

public class DefaultQueryMatcherTest {

    private QueryMatcher matcher;

    private BasicDBObject json(String string) {
        string = string.trim();
        if (!string.startsWith("{")) {
            string = "{" + string + "}";
        }
        return (BasicDBObject) JSON.parse(string);
    }

    @Before
    public void setUp() {
        matcher = new DefaultQueryMatcher();
    }

    @Test
    public void testMatchesSimple() throws Exception {
        BSONObject document = json("{}");
        assertThat(matcher.matches(document, json("{}"))).isTrue();
        assertThat(matcher.matches(document, json("foo: 'bar'"))).isFalse();
        document.put("foo", "bar");
        assertThat(matcher.matches(document, json("foo: 'bar'"))).isTrue();
    }

    @Test
    public void testMatchesPattern() throws Exception {
        BSONObject document = new BasicDBObject("name", "john");
        assertThat(matcher.matches(document, new BasicBSONObject("name", Pattern.compile("jo.*")))).isTrue();
        assertThat(
                matcher.matches(document,
                        new BasicBSONObject("name", Pattern.compile("Jo.*", Pattern.CASE_INSENSITIVE)))).isTrue();
        assertThat(matcher.matches(document, new BasicBSONObject("name", Pattern.compile("marta")))).isFalse();
        assertThat(matcher.matches(document, new BasicBSONObject("name", Pattern.compile("John")))).isFalse();

        String name = "\u0442\u0435\u0441\u0442";
        assertThat(name).hasSize(4);
        document.put("name", name);
        assertThat(matcher.matches(document, new BasicBSONObject("name", Pattern.compile(name)))).isTrue();

        assertThat(matcher.matches(document, new BasicBSONObject("name", new BasicBSONObject("$regex", name))))
                .isTrue();

        document.put("name", name.toLowerCase());
        assertThat(name.toLowerCase()).isNotEqualTo(name.toUpperCase());
        assertThat(
                matcher.matches(document,
                        new BasicBSONObject("name", new BasicBSONObject("$regex", name.toUpperCase())))).isFalse();
        assertThat(
                matcher.matches(
                        document,
                        new BasicBSONObject("name", new BasicBSONObject("$regex", name.toUpperCase()).append(
                                "$options", "i")))).isTrue();
    }

    @Test
    public void testMatchesInQuery() throws Exception {
        assertThat(matcher.matches(json("{}"), json("a: {$in: [3,2,1]}"))).isFalse();
        assertThat(matcher.matches(json("a: 'x'"), json("a: {$in: [3,2,1]}"))).isFalse();
        assertThat(matcher.matches(json("a: 1"), json("a: {$in: [3,2,1]}"))).isTrue();
        assertThat(matcher.matches(json("a: 2"), json("a: {$in: [3,2,1]}"))).isTrue();
        assertThat(matcher.matches(json("a: 4"), json("a: {$in: [3,2,1]}"))).isFalse();
        assertThat(matcher.matches(json("a: 1.0"), json("a: {$in: [3,2,1]}"))).isTrue();
        assertThat(matcher.matches(json("a: 1"), json("a: {$in: [3.0, 2.0, 1.00001]}"))).isFalse();
    }

    @Test
    public void testMatchesGreaterThanQuery() throws Exception {
        assertThat(matcher.matches(json("{}"), json("a: {$gt: -1}"))).isFalse();
        assertThat(matcher.matches(json("a: 1"), json("a: {$gt: 0.9}"))).isTrue();
        assertThat(matcher.matches(json("a: 1"), json("a: {$gt: 0}"))).isTrue();
        assertThat(matcher.matches(json("a: 1"), json("a: {$gt: 1}"))).isFalse();
        assertThat(matcher.matches(json("a: 1"), json("a: {$gte: 1}"))).isTrue();
        assertThat(matcher.matches(new BasicDBObject("a", "x"), json("a: {$gt: 1}"))).isFalse();
        assertThat(matcher.matches(new BasicDBObject("a", "x"), json("a: {$gte: 1}"))).isFalse();
    }

    @Test
    public void testMatchesLessThanQuery() throws Exception {
        assertThat(matcher.matches(json("{}"), json("a: {$lt: -1}"))).isFalse();
        assertThat(matcher.matches(json("a: 1"), json("a: {$lt: 1.001}"))).isTrue();
        assertThat(matcher.matches(json("a: 1"), json("a: {$lt: 2}"))).isTrue();
        assertThat(matcher.matches(json("a: 1"), json("a: {$lt: 1}"))).isFalse();
        assertThat(matcher.matches(json("a: 1"), json("a: {$lte: 1}"))).isTrue();
        assertThat(matcher.matches(new BasicDBObject("a", "x"), json("a: {$lt: 1}"))).isFalse();
        assertThat(matcher.matches(new BasicDBObject("a", "x"), json("a: {$lte: 1}"))).isFalse();
    }

    @Test
    public void testMatchesValueList() throws Exception {
        BSONObject document = json("a: [1,2,3]");
        assertThat(matcher.matches(document, json("{}"))).isTrue();
        assertThat(matcher.matches(document, json("a: 1"))).isTrue();
        assertThat(matcher.matches(document, json("a: 2"))).isTrue();
        assertThat(matcher.matches(document, json("a: 3"))).isTrue();
        assertThat(matcher.matches(document, json("a: 4"))).isFalse();
    }

    @Test
    public void testMatchesDocumentList() throws Exception {
        BSONObject document = json("_id:1, c: [{a:1, b:2}, {a:3, b:4}]");

        assertThat(matcher.matches(document, json("{}"))).isTrue();
        assertThat(matcher.matches(document, json("c: 1"))).isFalse();
        assertThat(matcher.matches(document, json("'c.a': 1"))).isTrue();
        assertThat(matcher.matches(document, json("'c.a': 3"))).isTrue();

        assertThat(matcher.matches(document, json("'c.a': 1, 'c.b': 4"))).isTrue();
        assertThat(matcher.matches(document, json("'c.a': 1, 'c.b': 5"))).isFalse();
        assertThat(matcher.matches(document, json("'c.a': 2, 'c.b': 4"))).isFalse();
    }

    @Test
    public void testMatchesSubquery() throws Exception {
        BSONObject document = json("c: {a:1}");
        assertThat(matcher.matches(document, json("{}"))).isTrue();
        assertThat(matcher.matches(document, json("c: 1"))).isFalse();
        assertThat(matcher.matches(document, json("'c.a': 1"))).isTrue();
        assertThat(matcher.matches(document, json("'c.a': 2"))).isFalse();
        assertThat(matcher.matches(document, json("'c.a.x': 2"))).isFalse();

        document.put("a", json("b: {c: {d:1}}"));
        assertThat(matcher.matches(document, json("'a.b.c.d': 1"))).isTrue();
        assertThat(matcher.matches(document, json("'a.b': 1"))).isFalse();
        assertThat(matcher.matches(document, json("'a.b.c': {d:1}"))).isTrue();
    }

    @Test
    public void testMatchesSubqueryList() throws Exception {
        BSONObject document = json("c: {a: [1,2,3] }");
        assertThat(matcher.matches(document, json("{}"))).isTrue();

        assertThat(matcher.matches(document, json("c: 1"))).isFalse();
        assertThat(matcher.matches(document, json("'c.a': 1"))).isTrue();
        assertThat(matcher.matches(document, json("'c.a': 2"))).isTrue();
        assertThat(matcher.matches(document, json("'c.a': 3"))).isTrue();
        assertThat(matcher.matches(document, json("'c.a': 4"))).isFalse();
        assertThat(matcher.matches(document, json("'c.a.x': 1"))).isFalse();

        document = json("{'array': [{'123a':{'name': 'old'}}]}");
        BSONObject query = json("{'array.123a.name': 'old'}");
        assertThat(matcher.matches(document, query)).isTrue();
    }

    @Test
    public void testMatchesSubqueryListPosition() throws Exception {
        BSONObject document = json("c: {a: [1,2,3] }");
        assertThat(matcher.matches(document, json("{}"))).isTrue();
        assertThat(matcher.matches(document, json("c: 1"))).isFalse();
        assertThat(matcher.matches(document, json("'c.a.0': 1"))).isTrue();
        assertThat(matcher.matches(document, json("'c.a.0': 2"))).isFalse();

        document = json("c: [{a: 12}, {a:13}]");
        assertThat(matcher.matches(document, json("'c.a': 12"))).isTrue();
        assertThat(matcher.matches(document, json("'c.a': 13"))).isTrue();
        assertThat(matcher.matches(document, json("'c.a': 14"))).isFalse();
        assertThat(matcher.matches(document, json("'c.0.a': 12"))).isTrue();
        assertThat(matcher.matches(document, json("'c.0.a': 13"))).isFalse();
        assertThat(matcher.matches(document, json("'c.1.a': 12"))).isFalse();
        assertThat(matcher.matches(document, json("'c.1.a': 13"))).isTrue();
        assertThat(matcher.matches(document, json("'c.2.a': 13"))).isFalse();
    }

    @Test
    public void testInvalidOperator() throws Exception {
        BSONObject document = json("{}");
        BSONObject query = json("field: {$someInvalidOperator: 123}");
        try {
            matcher.matches(document, query);
            fail("MongoServerError expected");
        } catch (MongoServerError e) {
            assertThat(e.getCode()).isEqualTo(10068);
            assertThat(e.getMessage()).isEqualTo("invalid operator: $someInvalidOperator");
        }
    }

    @Test
    public void testMatchesExists() throws Exception {
        BSONObject document = json("{}");
        BSONObject query = json("qty: { $exists: true, $nin: [ 5, 15 ] }");

        assertThat(matcher.matches(document, query)).isFalse();

        document.put("qty", 17);
        assertThat(matcher.matches(document, query)).isTrue();

        document.put("qty", 15);
        assertThat(matcher.matches(document, query)).isFalse();
    }

    @Test
    public void testMatchesNotEqual() throws Exception {
        BSONObject document = json("{}");

        BSONObject query = json("qty: {$ne: 17}");

        assertThat(matcher.matches(document, query)).isTrue();

        document.put("qty", 17);
        assertThat(matcher.matches(document, query)).isFalse();

        document.put("qty", 15);
        assertThat(matcher.matches(document, query)).isTrue();
    }

    @Test
    public void testMatchesNot() throws Exception {

        // db.inventory.find( { } )
        BSONObject query = json("price: { $not: { $gt: 1.99 } }");

        /*
         * This query will select all documents in the inventory collection
         * where:
         *
         * the price field value is less than or equal to 1.99 or the price
         * field does not exist
         *
         * { $not: { $gt: 1.99 } } is different from the $lte operator. { $lte:
         * 1.99 } returns only the documents where price field exists and its
         * value is less than or equal to 1.99.
         */

        BSONObject document = json("{}");
        assertThat(matcher.matches(document, query)).isTrue();

        document.put("price", 1.99);
        assertThat(matcher.matches(document, query)).isTrue();

        document.put("price", 1.990001);
        assertThat(matcher.matches(document, query)).isFalse();

        // !(x >= 5 && x <= 7)
        query = json("price: {$not: {$gte: 5, $lte: 7} }");
        assertThat(matcher.matches(document, query)).isTrue();
        document.put("price", 5);
        assertThat(matcher.matches(document, query)).isFalse();
        document.put("price", 7);
        assertThat(matcher.matches(document, query)).isFalse();
        document.put("price", null);
        assertThat(matcher.matches(document, query)).isTrue();

        query = json("price: {$not: {$exists: true}}");
        assertThat(matcher.matches(document, query)).isFalse();
        document.removeField("price");
        assertThat(matcher.matches(document, query)).isTrue();
    }

    /**
     * Test case for https://github.com/bwaldvogel/mongo-java-server/issues/7
     */
    @Test
    public void testMatchesNotIn() throws Exception {
        BSONObject query1 = json("{ \"map.key2\" : { \"$nin\" : [\"value 2.2\"] }}");
        BSONObject query2 = json("{ \"map.key2\" : { \"$not\" : {\"$in\" : [\"value 2.2\"] }}}");
        BSONObject query3 = json("{ \"map.key2\" : { \"$not\" : {\"$nin\" : [\"value 2.2\"] }}}");
        BSONObject query4 = json("{ \"map.key2\" : { \"$not\" : {\"$not\" : {\"$in\" : [\"value 2.2\"] }}}}");

        BSONObject document1 = json("{ \"code\" : \"c1\", \"map\" : { \"key1\" : [ \"value 1.1\" ], \"key2\" : [ \"value 2.1\" ] } }");
        BSONObject document2 = json("{ \"code\" : \"c1\", \"map\" : { \"key1\" : [ \"value 1.2\" ], \"key2\" : [ \"value 2.2\" ] } }");
        BSONObject document3 = json("{ \"code\" : \"c1\", \"map\" : { \"key1\" : [ \"value 2.1\" ], \"key2\" : [ \"value 2.1\" ] } }");

        assertThat(matcher.matches(document1, query1)).isTrue();
        assertThat(matcher.matches(document2, query1)).isFalse();
        assertThat(matcher.matches(document3, query1)).isTrue();

        assertThat(matcher.matches(document1, query2)).isTrue();
        assertThat(matcher.matches(document2, query2)).isFalse();
        assertThat(matcher.matches(document3, query2)).isTrue();

        assertThat(matcher.matches(document1, query3)).isFalse();
        assertThat(matcher.matches(document2, query3)).isTrue();
        assertThat(matcher.matches(document3, query3)).isFalse();

        assertThat(matcher.matches(document1, query4)).isFalse();
        assertThat(matcher.matches(document2, query4)).isTrue();
        assertThat(matcher.matches(document3, query4)).isFalse();
    }

    @Test
    public void testMatchesNotPattern() throws Exception {

        // { item: { $not: /^p.*/ } }
        BSONObject query = new BasicBSONObject("item", new BasicBSONObject("$not", Pattern.compile("^p.*")));

        BSONObject document = json("{}");
        assertThat(matcher.matches(document, query)).isTrue();
        document.put("item", "p");
        assertThat(matcher.matches(document, query)).isFalse();
        document.put("item", "pattern");
        assertThat(matcher.matches(document, query)).isFalse();
        document.put("item", "Pattern");
        assertThat(matcher.matches(document, query)).isTrue();
    }

    @Test
    public void testMatchesAnd() throws Exception {

        BSONObject query = json("$and: [ { price: 1.99 }, { qty: { $lt: 20 } }, { sale: true } ]");

        /*
         * This query will select all documents in the inventory collection
         * where:
         *
         * price field value equals 1.99 and qty field value is less than 20 and
         * sale field value is equal to true.
         */

        BSONObject document = json("{}");
        assertThat(matcher.matches(document, query)).isFalse();

        document.put("price", 1.99);
        document.put("qty", 20);
        document.put("sale", false);
        assertThat(matcher.matches(document, query)).isFalse();

        document.put("qty", 19);
        assertThat(matcher.matches(document, query)).isFalse();
        document.put("sale", true);
        assertThat(matcher.matches(document, query)).isTrue();
    }

    @Test
    public void testMatchesOr() throws Exception {

        BSONObject query = json("$or: [ { price: 1.99 }, { qty: { $lt: 20 } } ]");

        BSONObject document = json("{}");
        assertThat(matcher.matches(document, query)).isFalse();

        document.put("price", 1.99);
        assertThat(matcher.matches(document, query)).isTrue();

        document.put("price", 2.00);
        assertThat(matcher.matches(document, query)).isFalse();

        document.put("qty", 19);
        assertThat(matcher.matches(document, query)).isTrue();
    }

    @Test
    public void testMatchesNor() throws Exception {

        BSONObject query = json("$nor: [ { price: 1.99 }, { qty: { $lt: 20 } } ]");

        BSONObject document = json("{}");
        assertThat(matcher.matches(document, query)).isTrue();

        document.put("price", 1.99);
        assertThat(matcher.matches(document, query)).isFalse();
        document.put("price", 2.00);
        assertThat(matcher.matches(document, query)).isTrue();

        document.put("qty", 19);
        assertThat(matcher.matches(document, query)).isFalse();
        document.put("qty", 20);
        assertThat(matcher.matches(document, query)).isTrue();
    }

    @Test
    public void testMatchesIllegalQueryAndOrNor() throws Exception {

        BSONObject document = json("{}");

        for (String op : new String[] { "$and", "$or", "$nor" }) {

            BSONObject query = new BasicBSONObject(op, null);
            try {
                matcher.matches(document, query);
                fail("MongoServerError expected");
            } catch (MongoServerError e) {
                assertThat(e.getCode()).isEqualTo(14816);
                assertThat(e.getMessage()).isEqualTo(op + " expression must be a nonempty array");
            }

            query.put(op, 2);
            try {
                matcher.matches(document, query);
                fail("MongoServerError expected");
            } catch (MongoServerError e) {
                assertThat(e.getCode()).isEqualTo(14816);
                assertThat(e.getMessage()).isEqualTo(op + " expression must be a nonempty array");
            }

            query.put(op, new ArrayList<Object>());
            try {
                matcher.matches(document, query);
                fail("MongoServerError expected");
            } catch (MongoServerError e) {
                assertThat(e.getCode()).isEqualTo(14816);
                assertThat(e.getMessage()).isEqualTo(op + " expression must be a nonempty array");
            }

            query.put(op, Arrays.asList("a"));
            try {
                matcher.matches(document, query);
                fail("MongoServerError expected");
            } catch (MongoServerError e) {
                assertThat(e.getCode()).isEqualTo(14817);
                assertThat(e.getMessage()).isEqualTo(op + " elements must be objects");
            }
        }
    }

    @Test
    public void testMatchesMod() throws Exception {
        BSONObject document = json("{}");

        BSONObject modOp = json("$mod: [4, 0]");
        BSONObject query = new BasicDBObject("x", modOp);
        assertThat(matcher.matches(document, query)).isFalse();

        for (int m = 0; m < 4; m++) {
            modOp.put("$mod", Arrays.asList(4, m));
            for (int i = 0; i < 20; i++) {
                document.put("x", i);
                assertThat(matcher.matches(document, query)).isEqualTo((i % 4) == m);
            }
        }
    }

    @Test
    public void testMatchesSize() throws Exception {

        BSONObject query = json("a: {$size: 1}");

        assertThat(matcher.matches(json("{}"), query)).isFalse();
        assertThat(matcher.matches(json("a : \"x\""), query)).isFalse();
        assertThat(matcher.matches(json("a:[]"), query)).isFalse();
        assertThat(matcher.matches(json("a:[1]"), query)).isTrue();
        assertThat(matcher.matches(json("a:[1,2]"), query)).isFalse();

    }

    @Test
    public void testMatchesAll() throws Exception {

        BSONObject document = json("{a: {x: []}}");

        assertThat(matcher.matches(document, json("x:{$all:[1]}"))).isFalse();

        assertThat(matcher.matches(document, json("a.x: {$all: []}"))).isTrue();
        assertThat(matcher.matches(document, json("a.x: {$all: [1]}"))).isFalse();

        document = json("{a: {x: [1,2,3]}}");
        assertThat(matcher.matches(document, json("a: {$all: [1]}"))).isFalse();
        assertThat(matcher.matches(document, json("a.x: {$all: []}"))).isTrue();
        assertThat(matcher.matches(document, json("a.x: {$all: [1]}"))).isTrue();
        assertThat(matcher.matches(document, json("a.y: {$all: [1]}"))).isFalse();
        assertThat(matcher.matches(document, json("a.x: {$all: [2]}"))).isTrue();
        assertThat(matcher.matches(document, json("a.x: {$all: [3]}"))).isTrue();
        assertThat(matcher.matches(document, json("a.x: {$all: [1,2,3]}"))).isTrue();
        assertThat(matcher.matches(document, json("a.x: {$all: [2,3]}"))).isTrue();
        assertThat(matcher.matches(document, json("a.x: {$all: [1,3]}"))).isTrue();
        assertThat(matcher.matches(document, json("a.x: {$all: [1,4]}"))).isFalse();
        assertThat(matcher.matches(document, json("a.x: {$all: [4]}"))).isFalse();

        // with regular expresssion
        document = json("a: {x: ['john', 'jo', 'maria']}");
        assertThat(matcher.matches(document, json("a.x: {$all: []}"))).isTrue();
        assertThat(matcher.matches(document, json("a.x: {$all: [{$regex: '^jo.*'}]}"))).isTrue();
        assertThat(matcher.matches(document, json("a.x: {$all: [{$regex: '^foo'}]}"))).isFalse();
        assertThat(matcher.matches(document, json("a.x: {$all: ['maria', {$regex: '^jo.*'}]}"))).isTrue();
    }

    @Test
    public void testMatchesAllSubdocument() throws Exception {
        // with subdocuments
        DBObject document = json("a: [{x: 1} , {x: 2}]");
        assertThat(matcher.matches(document, json("a.x: {$all : []}"))).isTrue();
        assertThat(matcher.matches(document, json("a.x: {$all : [1]}"))).isTrue();
        assertThat(matcher.matches(document, json("a.x: {$all : [2]}"))).isTrue();
        assertThat(matcher.matches(document, json("a.x: {$all : [1, 2]}"))).isTrue();
        assertThat(matcher.matches(document, json("a.x: {$all : [2, 3]}"))).isFalse();
        assertThat(matcher.matches(document, json("a.x: {$all : [3]}"))).isFalse();
    }

    @Test
    public void testMatchesAllAndIn() throws Exception {
        DBObject document = json("a: {x: [1, 3]}");
        assertThat(matcher.matches(document, json("a.x: {$all: [1,3], $in: [2]}"))).isFalse();
        assertThat(matcher.matches(document, json("a.x: {$all: [1,3], $in: [3]}"))).isTrue();

        document = json("a: {x: [1, 2, 3]}");
        assertThat(matcher.matches(document, json("a.x: {$all: [1,3], $in: [2]}"))).isTrue();

        document = json("a: [{x:1}, {x:2}, {x:3}]");
        assertThat(matcher.matches(document, json("a.x: {$all: [1,3], $in: [2]}"))).isTrue();
    }

}
TOP

Related Classes of de.bwaldvogel.mongo.backend.DefaultQueryMatcherTest

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.