UNPKG

@harishreddym/baqend

Version:

Baqend JavaScript SDK

886 lines (759 loc) 25.3 kB
'use strict'; var DB; if (typeof module !== 'undefined') { require('./node'); DB = require('../lib'); } describe('Test Query', function () { var emf, metamodel; before(function () { var personType, addressType; emf = new DB.EntityManagerFactory({ host: env.TEST_SERVER, schema: [], tokenStorage: helper.rootTokenStorage }); metamodel = emf.metamodel; metamodel.addType(personType = new DB.metamodel.EntityType('QueryPerson', metamodel.entity(Object))); metamodel.addType(addressType = new DB.metamodel.EmbeddableType('QueryAddress')); personType.addAttribute(new DB.metamodel.SingularAttribute('name', metamodel.baseType(String))); personType.addAttribute(new DB.metamodel.SingularAttribute('person', personType)); personType.addAttribute(new DB.metamodel.SingularAttribute('address', addressType)); personType.addAttribute(new DB.metamodel.SingularAttribute('age', metamodel.baseType(Number))); personType.addAttribute(new DB.metamodel.SingularAttribute('date', metamodel.baseType(Date))); personType.addAttribute(new DB.metamodel.ListAttribute('colors', metamodel.baseType(String))); personType.addAttribute(new DB.metamodel.SingularAttribute('birthplace', metamodel.baseType(DB.GeoPoint))); addressType.addAttribute(new DB.metamodel.SingularAttribute('zip', metamodel.baseType(Number))); addressType.addAttribute(new DB.metamodel.SingularAttribute('city', metamodel.baseType(String))); return metamodel.save(); }); describe('Builder', function () { var db; before(function () { db = emf.createEntityManager(); }); it('should create simple query', function () { var q = db.QueryPerson.find().where({ name: 'Test QueryPerson', age: 3 }); expect(q.resultClass).equals(metamodel.entity('QueryPerson').typeConstructor); expect(q.firstResult).equals(0); expect(q.maxResults).equals(-1); expect(q.toJSON()).eql({ name: 'Test QueryPerson', age: 3, }); }); it('should create simple query with build pattern', function () { var q = db.QueryPerson.find() .equal('name', 'Test QueryPerson') .equal('age', 3); expect(q.resultClass).equals(metamodel.entity('QueryPerson').typeConstructor); expect(q.firstResult).equals(0); expect(q.maxResults).equals(-1); expect(q.toJSON()).eql({ name: 'Test QueryPerson', age: 3, }); }); it('should create simple query with reference', function () { var q = db.QueryPerson.find() .equal('person', '/db/QueryPerson/30') .equal('age', 3); expect(q.resultClass).equals(metamodel.entity('QueryPerson').typeConstructor); expect(q.firstResult).equals(0); expect(q.maxResults).equals(-1); expect(q.toJSON()).eql({ person: '/db/QueryPerson/30', age: 3, }); }); it('should replace other conditions with equal condition', function () { var q = db.QueryPerson.find() .between('age', 2, 20) .equal('age', 3) .equal('name', 'Test QueryPerson'); expect(q.toJSON()).eql({ name: 'Test QueryPerson', age: 3, }); }); it('should replace equal condition with other condition', function () { var q = db.QueryPerson.find() .equal('age', 3) .between('age', 2, 20) .equal('name', 'Test QueryPerson'); expect(q.toJSON()).eql({ name: 'Test QueryPerson', age: { $gt: 2, $lt: 20 }, }); }); it('should merge where condition with other condition', function () { var q = db.QueryPerson.find() .where({ name: 'Test QueryPerson' }) .equal('age', 3) .where({ age: 5 }); expect(q.toJSON()).eql({ name: 'Test QueryPerson', age: 5, }); }); it('should create notEqual condition', function () { var q = db.QueryPerson.find() .notEqual('age', 3) .equal('name', 'Test QueryPerson'); expect(q.toJSON()).eql({ name: 'Test QueryPerson', age: { $ne: 3 }, }); }); it('should create greaterThan condition', function () { var q = db.QueryPerson.find() .greaterThan('age', 3) .equal('name', 'Test QueryPerson'); expect(q.toJSON()).eql({ name: 'Test QueryPerson', age: { $gt: 3 }, }); }); it('should create gt condition', function () { var q = db.QueryPerson.find() .gt('age', 3) .equal('name', 'Test QueryPerson'); expect(q.toJSON()).eql({ name: 'Test QueryPerson', age: { $gt: 3 }, }); }); it('should create greaterThanOrEqualTo condition', function () { var q = db.QueryPerson.find() .greaterThanOrEqualTo('age', 3) .equal('name', 'Test QueryPerson'); expect(q.toJSON()).eql({ name: 'Test QueryPerson', age: { $gte: 3 }, }); }); it('should create ge condition', function () { var q = db.QueryPerson.find() .ge('age', 3) .equal('name', 'Test QueryPerson'); expect(q.toJSON()).eql({ name: 'Test QueryPerson', age: { $gte: 3 }, }); }); it('should create lessThan condition', function () { var q = db.QueryPerson.find() .lessThan('age', 3) .equal('name', 'Test QueryPerson'); expect(q.toJSON()).eql({ name: 'Test QueryPerson', age: { $lt: 3 }, }); }); it('should create lt condition', function () { var q = db.QueryPerson.find() .lt('age', 3) .equal('name', 'Test QueryPerson'); expect(q.toJSON()).eql({ name: 'Test QueryPerson', age: { $lt: 3 }, }); }); it('should create lessThanOrEqualTo condition', function () { var q = db.QueryPerson.find() .lessThanOrEqualTo('age', 3) .equal('name', 'Test QueryPerson'); expect(q.toJSON()).eql({ name: 'Test QueryPerson', age: { $lte: 3 }, }); }); it('should create le condition', function () { var q = db.QueryPerson.find() .le('age', 3) .equal('name', 'Test QueryPerson'); expect(q.toJSON()).eql({ name: 'Test QueryPerson', age: { $lte: 3 }, }); }); it('should create between condition', function () { var q = db.QueryPerson.find() .between('age', 3, 20) .equal('name', 'Test QueryPerson'); expect(q.toJSON()).eql({ name: 'Test QueryPerson', age: { $gt: 3, $lt: 20 }, }); }); it('should create isNull condition', function () { var q = db.QueryPerson.find() .isNull('age') .equal('name', 'Test QueryPerson'); expect(q.toJSON()).eql({ name: 'Test QueryPerson', age: null, }); }); it('should create isNotNull condition', function () { var q = db.QueryPerson.find() .isNotNull('age') .equal('name', 'Test QueryPerson'); expect(q.toJSON()).eql({ name: 'Test QueryPerson', age: { $ne: null, $exists: true }, }); }); it('should create in varargs condition', function () { var q = db.QueryPerson.find() .in('age', 1, 2, 3) .equal('name', 'Test QueryPerson'); expect(q.toJSON()).eql({ name: 'Test QueryPerson', age: { $in: [1, 2, 3] }, }); }); it('should create in condition', function () { var q = db.QueryPerson.find() .in('age', [1, 2, 3]) .equal('name', 'Test QueryPerson'); expect(q.toJSON()).eql({ name: 'Test QueryPerson', age: { $in: [1, 2, 3] }, }); }); it('should create in condition', function () { var q = db.QueryPerson.find() .in('age', [1, 2, 3]) .equal('name', 'Test QueryPerson'); expect(q.toJSON()).eql({ name: 'Test QueryPerson', age: { $in: [1, 2, 3] }, }); }); it('should create contains condition', function () { var q = db.QueryPerson.find() .containsAny('colors', ['green', 'red', 'blue']) .equal('name', 'Test QueryPerson'); expect(q.toJSON()).eql({ name: 'Test QueryPerson', colors: { $in: ['green', 'red', 'blue'] }, }); }); it('should create containsAny varargs condition', function () { var q = db.QueryPerson.find() .containsAny('colors', 'green', 'red', 'blue') .equal('name', 'Test QueryPerson'); expect(q.toJSON()).eql({ name: 'Test QueryPerson', colors: { $in: ['green', 'red', 'blue'] }, }); }); it('should create containsAll varargs condition', function () { var q = db.QueryPerson.find() .containsAll('colors', ['green', 'red', 'blue']) .equal('name', 'Test QueryPerson'); expect(q.toJSON()).eql({ name: 'Test QueryPerson', colors: { $all: ['green', 'red', 'blue'] }, }); }); it('should create containsAll varargs condition', function () { var q = db.QueryPerson.find() .containsAll('colors', 'green', 'red', 'blue') .equal('name', 'Test QueryPerson'); expect(q.toJSON()).eql({ name: 'Test QueryPerson', colors: { $all: ['green', 'red', 'blue'] }, }); }); it('should create size condition', function () { var q = db.QueryPerson.find() .size('colors', 3) .equal('name', 'Test QueryPerson'); expect(q.toJSON()).eql({ name: 'Test QueryPerson', colors: { $size: 3 }, }); }); it('should create matches condition', function () { var q = db.QueryPerson.find() .matches('name', /^Test/) .equal('age', 3); expect(q.toJSON()).eql({ name: { $regex: '^Test' }, age: 3, }); }); it('should create matches with multiline condition', function () { var q = db.QueryPerson.find() .matches('name', /^Test/m) .equal('age', 3); expect(q.toJSON()).eql({ name: { $regex: '^Test', $options: 'm' }, age: 3, }); }); it('should not create matches with case insensitive condition', function () { expect(function () { db.QueryPerson.find().matches('name', /^Test/i); }).throw(Error); }); it('should not create matches with global search condition', function () { expect(function () { db.QueryPerson.find().matches('name', /^Test/g); }).throw(Error); }); it('should not create matches with none anchored condition', function () { expect(function () { db.QueryPerson.find().matches('name', /Test/); }).throw(Error); }); it('should create mod condition', function () { var q = db.QueryPerson.find() .mod('age', 10, 3) .equal('name', 'Test QueryPerson'); expect(q.toJSON()).eql({ name: 'Test QueryPerson', age: { $mod: [10, 3] }, }); }); it('should create near condition', function () { var q = db.QueryPerson.find() .near('birthplace', new DB.GeoPoint(85, 100), 3000) .equal('name', 'Test QueryPerson'); expect(q.toJSON()).eql({ birthplace: { $nearSphere: { $geometry: { type: 'Point', coordinates: [100, 85], }, $maxDistance: 3000, }, }, name: 'Test QueryPerson', }); }); it('should create withinPolygon condition', function () { var q = db.QueryPerson.find() .withinPolygon('birthplace', [new DB.GeoPoint(85, 100), new DB.GeoPoint(81, 89), new DB.GeoPoint(90, 105)]) .equal('name', 'Test QueryPerson'); expect(q.toJSON()).eql({ birthplace: { $geoWithin: { $geometry: { type: 'Polygon', coordinates: [[[100, 85], [89, 81], [105, 90]]], }, }, }, name: 'Test QueryPerson', }); }); it('should create withinPolygon varargs condition', function () { var q = db.QueryPerson.find() .withinPolygon('birthplace', new DB.GeoPoint(85, 100), new DB.GeoPoint(81, 89), new DB.GeoPoint(90, 105)) .equal('name', 'Test QueryPerson'); expect(q.toJSON()).eql({ birthplace: { $geoWithin: { $geometry: { type: 'Polygon', coordinates: [[[100, 85], [89, 81], [105, 90]]], }, }, }, name: 'Test QueryPerson', }); }); it('should create and conditions', function () { var qb = db.QueryPerson.find(); var q = qb.and( qb.equal('name', 'Test QueryPerson'), qb.between('age', 3, 20) ); expect(JSON.parse(JSON.stringify(q))).eql({ $and: [{ name: 'Test QueryPerson', }, { age: { $gt: 3, $lt: 20 }, }], }); }); it('should create or conditions', function () { var qb = db.QueryPerson.find(); var q = qb.or( qb.equal('name', 'Test QueryPerson1'), qb.between('age', 3, 20) ); expect(JSON.parse(JSON.stringify(q))).eql({ $or: [{ name: 'Test QueryPerson1', }, { age: { $gt: 3, $lt: 20 }, }], }); }); it('should create nor conditions', function () { var qb = db.QueryPerson.find(); var q = qb.nor( qb.equal('name', 'Test QueryPerson1'), qb.between('age', 3, 20) ); expect(JSON.parse(JSON.stringify(q))).eql({ $nor: [{ name: 'Test QueryPerson1', }, { age: { $gt: 3, $lt: 20 }, }], }); }); it('should create complex query conditions', function () { var qb = db.QueryPerson.find(); var q = qb.and( qb.or(qb.between('age', 40, 65), qb.between('age', 3, 20)), qb.or(qb.equal('name', 'Test QueryPerson1'), qb.equal('name', 'Test QueryPerson2')) ); expect(JSON.parse(JSON.stringify(q))).eql({ $and: [{ $or: [{ age: { $gt: 40, $lt: 65 }, }, { age: { $gt: 3, $lt: 20 }, }], }, { $or: [{ name: 'Test QueryPerson1', }, { name: 'Test QueryPerson2', }], }], }); }); it('should create chained query conditions', function () { var qb = db.QueryPerson.find(); var q = qb.or( qb.equal('name', 'Test QueryPerson1'), qb.equal('name', 'Test QueryPerson2'), qb.equal('name', 'Test QueryPerson3') ); expect(JSON.parse(JSON.stringify(q))).eql({ $or: [{ name: 'Test QueryPerson1', }, { name: 'Test QueryPerson2', }, { name: 'Test QueryPerson3', }], }); }); }); describe('execution', function () { var db, p0, p1, p2, p3; before(function () { db = emf.createEntityManager(); p0 = new db.QueryPerson({ key: 'query_p0', }); p1 = new db.QueryPerson({ key: 'query_p1', person: p0, name: 'QueryPerson 1', age: 45, date: new Date('1978-02-03T00:00Z'), address: new db.QueryAddress({ city: 'Hamburg', zip: 22865 }), colors: ['red', 'green'], birthplace: new DB.GeoPoint(35, 110), }); p2 = new db.QueryPerson({ key: 'query_p2', person: p1, name: 'QueryPerson 2', age: 33, date: new Date('1966-05-01T00:00Z'), address: new db.QueryAddress({ city: 'Hamburg', zip: 23432 }), colors: ['blue', 'green', 'red'], birthplace: new DB.GeoPoint(32, 112), }); p3 = new db.QueryPerson({ key: 'query_p3', person: p1, name: 'QueryPerson 3', age: 23, date: new Date('1989-05-01T00:00Z'), address: new db.QueryAddress({ city: 'Munich', zip: 92438 }), colors: ['yellow', 'blue', 'white'], birthplace: new DB.GeoPoint(29, 109), }); return Promise.all([ p0.save({ force: true }), p1.save({ force: true }), p2.save({ force: true }), p3.save({ force: true }), ]); }); it('should return all objects', function () { return db.QueryPerson.find().resultList().then(function (list) { expectResult([p0, p1, p2, p3], list); }); }); it('should handle empty results', function () { return db.QueryPerson.find() .equal('name', 'test') .resultList() .then(function (list) { expectResult([], list); }); }); it('should return age <= 40 and address.city = Hamburg matches', function () { return db.QueryPerson.find() .lessThanOrEqualTo('age', 40) .equal('address.city', 'Hamburg') .resultList() .then(function (list) { expectResult([p2], list); }); }); it('should return age <= 40 and address.city = Hamburg match as single result', function () { return db.QueryPerson.find() .lessThanOrEqualTo('age', 40) .equal('address.city', 'Hamburg') .singleResult() .then(function (obj) { expect(obj).equals(p2); }); }); it('should return name is notNull matches', function () { return db.QueryPerson.find() .isNotNull('name') .resultList() .then(function (list) { expectResult([p1, p2, p3], list); }); }); it('should return name is null matches', function () { return db.QueryPerson.find() .isNull('name') .resultList() .then(function (list) { expectResult([p0], list); }); }); it('should return address.zip > 23000 and name != QueryPerson 2 matches', function () { return db.QueryPerson.find() .notEqual('name', 'QueryPerson 2') .greaterThan('address.zip', 23000) .resultList() .then(function (list) { expectResult([p3], list); }); }); it('should return person references p1', function () { return db.QueryPerson.find() .equal('person', p1) .resultList() .then(function (list) { expectResult([p2, p3], list); }); }); it('should return person references null', function () { return db.QueryPerson.find() .isNull('person') .resultList() .then(function (list) { expectResult([p0], list); }); }); it('should return name matches ^QueryPerson [23] matches', function () { return db.QueryPerson.find() .matches('name', '^QueryPerson [23]') .resultList() .then(function (list) { expectResult([p2, p3], list); }); }); it('should return name matches /^QueryPerson [23]/ matches', function () { return db.QueryPerson.find() .matches('name', /^QueryPerson [23]/) .resultList() .then(function (list) { expectResult([p2, p3], list); }); }); it('should return name in [QueryPerson 1, QueryPerson 2]', function () { return db.QueryPerson.find() .in('name', 'QueryPerson 1', 'QueryPerson 2') .resultList() .then(function (list) { expectResult([p1, p2], list); }); }); it('should return name not in [QueryPerson 1, QueryPerson 2]', function () { return db.QueryPerson.find() .notIn('name', 'QueryPerson 1', 'QueryPerson 2') .resultList() .then(function (list) { expectResult([p0, p3], list); }); }); it('should return color contains any green, blue matches', function () { return db.QueryPerson.find() .containsAny('colors', 'green', 'blue') .resultList() .then(function (list) { expectResult([p1, p2, p3], list); }); }); it('should return color contains all green, blue matches', function () { return db.QueryPerson.find() .containsAll('colors', 'green', 'blue') .resultList() .then(function (list) { expectResult([p2], list); }); }); it('should return color size = 3 matches', function () { return db.QueryPerson.find() .size('colors', 3) .resultList() .then(function (list) { expectResult([p2, p3], list); }); }); it('should return age % 10 = 3 matches', function () { return db.QueryPerson.find() .mod('age', 10, 3) .resultList() .then(function (list) { expectResult([p2, p3], list); }); }); it('should return date between 1970-01-01Z and 1990-31-12Z matches', function () { return db.QueryPerson.find() .between('date', new Date('1970-01-01T00:00Z'), new Date('1990-12-31T00:00Z')) .resultList() .then(function (list) { expectResult([p1, p3], list); }); }); it('should return date between 1970-01-01Z and 1990-31-12Z matches', function () { return db.QueryPerson.find() .between('date', new Date('1970-01-01T00:00Z'), new Date('1990-12-31T00:00Z')) .resultList() .then(function (list) { expectResult([p1, p3], list); }); }); it('should return birthplace withinPolygon matches', function () { return db.QueryPerson.find() .withinPolygon( 'birthplace', new DB.GeoPoint(30, 110), new DB.GeoPoint(30, 115), new DB.GeoPoint(40, 115), new DB.GeoPoint(40, 110), new DB.GeoPoint(30, 110) ) .resultList() .then(function (list) { expectResult([p1, p2], list); }); }); it('should return and/or condition based matches', function () { var qb = db.QueryPerson.find(); return qb.and( qb.or(qb.between('age', 20, 35), qb.between('age', 40, 55)), qb.or(qb.equal('name', 'QueryPerson 1'), qb.equal('name', 'QueryPerson 3')) ).resultList() .then(function (list) { expectResult([p1, p3], list); }); }); it('should return matches in right order', function () { return db.QueryPerson.find() .containsAny('colors', 'green', 'blue') .ascending('age') .resultList() .then(function (list) { expectSortedResult([p3, p2, p1], list); }); }); it('should return matches in right order, with two sort criteria', function () { return db.QueryPerson.find() .containsAny('colors', 'green', 'blue') .descending('address.city') .descending('age') .resultList() .then(function (list) { expectSortedResult([p3, p1, p2], list); }); }); it('should return matches in right order, with sort criteria', function () { return db.QueryPerson.find() .containsAny('colors', 'green', 'blue') .sort({ 'address.city': 1, age: 1 }) .resultList() .then(function (list) { expectSortedResult([p2, p1, p3], list); }); }); it('should return matches in right order with offset and limit', function () { return db.QueryPerson.find() .ascending('age') .offset(1) .limit(2) .resultList() .then(function (list) { expectSortedResult([p3, p2], list); }); }); it('should be allowed to use limit and offset before a filter', function () { return db.QueryPerson.find() .offset(1) .limit(2) .ascending('age') .resultList() .then(function (list) { expectSortedResult([p3, p2], list); }); }); it('should count the number of matching objects', function () { return db.QueryPerson.find() .containsAny('colors', 'green', 'blue') .count() .then(function (count) { expect(count).equal(3); }); }); it('should count the total number of objects', function () { return db.QueryPerson.find() .count() .then(function (count) { return db.QueryPerson.find().resultList(function (list) { expect(list.length).equal(count); }); }); }); it('should allow large query', function () { var inQuery = []; for (var i = 0; i < 5000; i += 1) { inQuery.push('QueryPerson ' + i); } return db.QueryPerson.find() .in('name', inQuery) .resultList() .then(function (list) { expectResult([p1, p2, p3], list); }); }); function expectResult(expectedResult, actualResult) { expect(actualResult.length).equals(expectedResult.length); actualResult.forEach(function (el) { var index = expectedResult.indexOf(el); expect(index).not.equal(-1); expectedResult[index] = null; }); } function expectSortedResult(expectedResult, actualResult) { expect(actualResult.length).equals(expectedResult.length); expectedResult.forEach(function (el, index) { expect(actualResult[index]).equals(el); }); } }); });