mirror of https://gitee.com/bigwinds/arangodb
232 lines
7.4 KiB
JavaScript
232 lines
7.4 KiB
JavaScript
/* jshint -W083 */
|
|
/* eslint no-loop-func: 0 */
|
|
/* global describe, it, beforeEach, afterEach */
|
|
'use strict';
|
|
|
|
// //////////////////////////////////////////////////////////////////////////////
|
|
// / @brief
|
|
// /
|
|
// / @file
|
|
// /
|
|
// / DISCLAIMER
|
|
// /
|
|
// / Copyright 2010-2012 triagens GmbH, Cologne, Germany
|
|
// /
|
|
// / Licensed under the Apache License, Version 2.0 (the "License")
|
|
// / you may not use this file except in compliance with the License.
|
|
// / You may obtain a copy of the License at
|
|
// /
|
|
// / http://www.apache.org/licenses/LICENSE-2.0
|
|
// /
|
|
// / Unless required by applicable law or agreed to in writing, software
|
|
// / distributed under the License is distributed on an "AS IS" BASIS,
|
|
// / WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// / See the License for the specific language governing permissions and
|
|
// / limitations under the License.
|
|
// /
|
|
// / Copyright holder is triAGENS GmbH, Cologne, Germany
|
|
// /
|
|
// / @author Lucas Doomen
|
|
// / @author Copyright 2013, triAGENS GmbH, Cologne, Germany
|
|
// //////////////////////////////////////////////////////////////////////////////
|
|
|
|
const expect = require('chai').expect;
|
|
const sinon = require('sinon');
|
|
const createQuery = require('@arangodb/foxx/legacy/query').createQuery;
|
|
const arangodb = require('@arangodb');
|
|
const db = arangodb.db;
|
|
const ArangoError = arangodb.ArangoError;
|
|
const errors = arangodb.errors;
|
|
|
|
describe('createQuery(query)', function () {
|
|
it('should execute queries with no arguments', function () {
|
|
const query = createQuery('RETURN 23');
|
|
expect(query()).to.eql([23]);
|
|
});
|
|
|
|
it('should execute QueryBuilder instances with no arguments', function () {
|
|
const query = createQuery({toAQL() {
|
|
return 'RETURN 23';
|
|
}});
|
|
expect(query()).to.eql([23]);
|
|
});
|
|
|
|
it('should raise an ArangoError for unexpected arguments', function () {
|
|
const query = createQuery('RETURN 23');
|
|
expect(function () {
|
|
query({foo: 'chicken'});
|
|
}).to.throw(ArangoError)
|
|
.with.property('errorNum', errors.ERROR_QUERY_BIND_PARAMETER_UNDECLARED.code);
|
|
});
|
|
|
|
it('should raise an ArangoError for missing arguments', function () {
|
|
const query = createQuery('RETURN @x');
|
|
expect(function () {
|
|
query();
|
|
}).to.throw(ArangoError)
|
|
.with.property('errorNum', errors.ERROR_QUERY_BIND_PARAMETER_MISSING.code);
|
|
});
|
|
|
|
it('should execute a query with valid arguments', function () {
|
|
const query = createQuery('RETURN @x');
|
|
expect(query({x: 'chicken'})).to.eql(['chicken']);
|
|
expect(query({x: 23})).to.eql([23]);
|
|
});
|
|
});
|
|
|
|
describe('createQuery(cfg)', function () {
|
|
function FakeModel (args) {
|
|
this.args = args;
|
|
}
|
|
|
|
describe('with cfg.context', function () {
|
|
const cn = 'UnitTestFoxxQueues';
|
|
|
|
beforeEach(function () {
|
|
db._drop(cn);
|
|
db._drop(`${cn}_suffixed`);
|
|
db._create(cn, {waitForSync: false});
|
|
db._collection(cn).save({foo: 'potato'});
|
|
db._create(`${cn}_suffixed`, {waitForSync: false});
|
|
db._collection(`${cn}_suffixed`).save({foo: 'tomato'});
|
|
});
|
|
|
|
afterEach(function () {
|
|
db._drop(cn);
|
|
db._drop(`${cn}_suffixed`);
|
|
});
|
|
|
|
it('should pass collection arguments through cfg.context.collectionName', function () {
|
|
const spy = sinon.spy(function (cn) {
|
|
return `${cn}_suffixed`;
|
|
});
|
|
const query = createQuery({
|
|
query: 'FOR doc IN @@col RETURN doc.foo',
|
|
context: {collectionName: spy}
|
|
});
|
|
expect(spy.called).to.equal(false);
|
|
const result = query({'@col': cn});
|
|
expect(spy.calledWith(cn)).to.equal(true);
|
|
expect(result).to.eql(['tomato']);
|
|
});
|
|
|
|
it('should pass cfg.defaults collection names through cfg.context.collectionName', function () {
|
|
const spy = sinon.spy(function (cn) {
|
|
return `${cn}_suffixed`;
|
|
});
|
|
const query = createQuery({
|
|
query: 'FOR doc IN @@col RETURN doc.foo',
|
|
context: {collectionName: spy},
|
|
defaults: {'@col': cn}
|
|
});
|
|
expect(spy.called).to.equal(false);
|
|
const result = query();
|
|
expect(spy.calledWith(cn)).to.equal(true);
|
|
expect(result).to.eql(['tomato']);
|
|
});
|
|
});
|
|
|
|
it('should mix cfg.defaults into arguments', function () {
|
|
const query = createQuery({
|
|
query: 'RETURN [@x, @y]',
|
|
defaults: {x: 'chicken', y: 'kittens'}
|
|
});
|
|
expect(query()).to.eql([['chicken', 'kittens']]);
|
|
expect(query({y: 'puppies'})).to.eql([['chicken', 'puppies']]);
|
|
});
|
|
|
|
it('should pass the query result to cfg.transform', function () {
|
|
const spy = sinon.spy(function (arg) {
|
|
expect(arg).to.eql([1, 2, 3]);
|
|
});
|
|
const query = createQuery({
|
|
query: 'FOR x IN 1..3 RETURN x',
|
|
transform: spy
|
|
});
|
|
expect(spy.called).to.equal(false);
|
|
query();
|
|
expect(spy.called).to.equal(true);
|
|
});
|
|
|
|
it('should return the result of cfg.transform', function () {
|
|
const spy = sinon.spy(function () {
|
|
return 'chicken';
|
|
});
|
|
const query = createQuery({
|
|
query: 'FOR x IN 1..3 RETURN x',
|
|
transform: spy
|
|
});
|
|
expect(query()).to.eql('chicken');
|
|
expect(spy.called).to.equal(true);
|
|
});
|
|
|
|
it('should convert the result to instances of cfg.model', function () {
|
|
const result = createQuery({
|
|
query: 'FOR x IN 1..3 RETURN {foo: x}',
|
|
model: FakeModel
|
|
})();
|
|
expect(result.constructor).to.equal(Array);
|
|
expect(result.length).to.eql(3);
|
|
expect(result[0].constructor).to.equal(FakeModel);
|
|
expect(result[0].args).to.eql({foo: 1});
|
|
expect(result[1].constructor).to.equal(FakeModel);
|
|
expect(result[1].args).to.eql({foo: 2});
|
|
expect(result[2].constructor).to.equal(FakeModel);
|
|
expect(result[2].args).to.eql({foo: 3});
|
|
});
|
|
|
|
it('should convert the result to models before transforming them', function () {
|
|
const spy = sinon.spy(function (args) {
|
|
expect(args[0].constructor).to.equal(FakeModel);
|
|
expect(args[1].constructor).to.equal(FakeModel);
|
|
expect(args[2].constructor).to.equal(FakeModel);
|
|
return 'chicken';
|
|
});
|
|
const query = createQuery({
|
|
query: 'FOR x IN 1..3 RETURN x',
|
|
transform: spy,
|
|
model: FakeModel
|
|
});
|
|
expect(query()).to.eql('chicken');
|
|
expect(spy.called).to.equal(true);
|
|
});
|
|
|
|
it('should throw an error if cfg.query is missing', function () {
|
|
expect(function () {
|
|
createQuery({noQuery: 'no fun'});
|
|
}).to.throw();
|
|
});
|
|
|
|
it('should throw an error if cfg.query is invalid', function () {
|
|
for (let value of [23, {invalid: true}, function () {}, {toAQL: 'not a function'}]) {
|
|
expect(function () {
|
|
createQuery({query: value});
|
|
}).to.throw();
|
|
}
|
|
});
|
|
|
|
it('should throw an error if cfg.model is a non-function', function () {
|
|
for (let value of [{}, 'garbage', true, 23, Infinity]) {
|
|
expect(function () {
|
|
createQuery({query: 'RETURN 23', model: value});
|
|
}).to.throw();
|
|
}
|
|
});
|
|
|
|
it('should throw an error if cfg.transform is a non-function', function () {
|
|
for (let value of [{}, 'garbage', true, 23, Infinity]) {
|
|
expect(function () {
|
|
createQuery({query: 'RETURN 23', transform: value});
|
|
}).to.throw();
|
|
}
|
|
});
|
|
|
|
it('should throw an error if cfg.context has no "collectionName" method', function () {
|
|
for (let value of [{}, 'garbage', true, 23, Infinity, function () {}, {collectionName: 'not a function'}]) {
|
|
expect(function () {
|
|
createQuery({query: 'RETURN 23', context: value});
|
|
}).to.throw();
|
|
}
|
|
});
|
|
});
|