mirror of https://gitee.com/bigwinds/arangodb
433 lines
17 KiB
JavaScript
433 lines
17 KiB
JavaScript
/*jshint globalstrict:false, strict:false, maxlen: 500 */
|
|
/*global assertEqual, assertTrue */
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief tests for query language, functions
|
|
///
|
|
/// @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 Jan Steemann
|
|
/// @author Copyright 2012, triAGENS GmbH, Cologne, Germany
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
var internal = require("internal");
|
|
var errors = internal.errors;
|
|
var jsunity = require("jsunity");
|
|
var helper = require("org/arangodb/aql-helper");
|
|
var getQueryResults = helper.getQueryResults;
|
|
var getQueryResults = helper.getQueryResults;
|
|
var assertQueryError = helper.assertQueryError;
|
|
var assertQueryWarningAndNull = helper.assertQueryWarningAndNull;
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief test suite
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
function ahuacatlMiscFunctionsTestSuite () {
|
|
return {
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief test parse identifier function
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
testParseIdentifier : function () {
|
|
var actual;
|
|
var buildQuery = function (nr, input) {
|
|
switch (nr) {
|
|
case 0:
|
|
return `RETURN PARSE_IDENTIFIER(${input})`;
|
|
case 1:
|
|
return `RETURN NOOPT(PARSE_IDENTIFIER(${input}))`;
|
|
case 2:
|
|
return `RETURN NOOPT(V8(PARSE_IDENTIFIER(${input})))`;
|
|
default:
|
|
assertTrue(false, "Undefined state");
|
|
}
|
|
};
|
|
|
|
for (var i = 0; i < 3; ++i) {
|
|
actual = getQueryResults(buildQuery(i, "'foo/bar'"));
|
|
assertEqual([ { collection: 'foo', key: 'bar' } ], actual);
|
|
|
|
actual = getQueryResults(buildQuery(i, "'this-is-a-collection-name/and-this-is-an-id'"));
|
|
assertEqual([ { collection: 'this-is-a-collection-name', key: 'and-this-is-an-id' } ], actual);
|
|
|
|
actual = getQueryResults(buildQuery(i, "'MY_COLLECTION/MY_DOC'"));
|
|
assertEqual([ { collection: 'MY_COLLECTION', key: 'MY_DOC' } ], actual);
|
|
|
|
actual = getQueryResults(buildQuery(i, "'_users/AbC'"));
|
|
assertEqual([ { collection: '_users', key: 'AbC' } ], actual);
|
|
|
|
actual = getQueryResults(buildQuery(i, "{ _id: 'foo/bar', value: 'baz' }"));
|
|
assertEqual([ { collection: 'foo', key: 'bar' } ], actual);
|
|
|
|
actual = getQueryResults(buildQuery(i, "{ ignore: true, _id: '_system/VALUE', value: 'baz' }"));
|
|
assertEqual([ { collection: '_system', key: 'VALUE' } ], actual);
|
|
|
|
actual = getQueryResults(buildQuery(i ,"{ value: 123, _id: 'Some-Odd-Collection/THIS_IS_THE_KEY' }"));
|
|
assertEqual([ { collection: 'Some-Odd-Collection', key: 'THIS_IS_THE_KEY' } ], actual);
|
|
}
|
|
},
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief test parse identifier function
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
testParseIdentifierCollection : function () {
|
|
var cn = "UnitTestsAhuacatlFunctions";
|
|
|
|
internal.db._drop(cn);
|
|
var cx = internal.db._create(cn);
|
|
cx.save({ "title" : "123", "value" : 456, "_key" : "foobar" });
|
|
cx.save({ "_key" : "so-this-is-it", "title" : "nada", "value" : 123 });
|
|
|
|
var expected, actual;
|
|
var buildQuery = function (nr, input) {
|
|
switch (nr) {
|
|
case 0:
|
|
return `RETURN PARSE_IDENTIFIER(${input})`;
|
|
case 1:
|
|
return `RETURN NOOPT(PARSE_IDENTIFIER(${input}))`;
|
|
case 2:
|
|
return `RETURN NOOPT(V8(PARSE_IDENTIFIER(${input})))`;
|
|
default:
|
|
assertTrue(false, "Undefined state");
|
|
}
|
|
};
|
|
|
|
for (var i = 0; i < 3; ++i) {
|
|
expected = [ { collection: cn, key: "foobar" } ];
|
|
actual = getQueryResults(buildQuery(i, "DOCUMENT(CONCAT(@cn, '/', @key))"), { cn: cn, key: "foobar" });
|
|
assertEqual(expected, actual);
|
|
|
|
expected = [ { collection: cn, key: "foobar" } ];
|
|
actual = getQueryResults(buildQuery(i, "DOCUMENT(CONCAT(@cn, '/', @key))"), { cn: cn, key: "foobar" });
|
|
assertEqual(expected, actual);
|
|
|
|
expected = [ { collection: cn, key: "foobar" } ];
|
|
actual = getQueryResults(buildQuery(i, "DOCUMENT(CONCAT(@cn, '/', 'foobar'))"), { cn: cn });
|
|
assertEqual(expected, actual);
|
|
|
|
expected = [ { collection: cn, key: "foobar" } ];
|
|
actual = getQueryResults(buildQuery(i, "DOCUMENT([ @key ])[0]"), { key: "UnitTestsAhuacatlFunctions/foobar" });
|
|
assertEqual(expected, actual);
|
|
|
|
expected = [ { collection: cn, key: "so-this-is-it" } ];
|
|
actual = getQueryResults(buildQuery(i, "DOCUMENT([ 'UnitTestsAhuacatlFunctions/so-this-is-it' ])[0]"));
|
|
assertEqual(expected, actual);
|
|
}
|
|
|
|
internal.db._drop(cn);
|
|
},
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief test parse identifier function
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
testParseIdentifierInvalid : function () {
|
|
var buildQuery = function (nr, input) {
|
|
switch (nr) {
|
|
case 0:
|
|
return `RETURN PARSE_IDENTIFIER(${input})`;
|
|
case 1:
|
|
return `RETURN NOOPT(PARSE_IDENTIFIER(${input}))`;
|
|
case 2:
|
|
return `RETURN NOOPT(V8(PARSE_IDENTIFIER(${input})))`;
|
|
default:
|
|
assertTrue(false, "Undefined state");
|
|
}
|
|
};
|
|
|
|
for (var i = 0; i < 3; ++i) {
|
|
assertQueryError(errors.ERROR_QUERY_FUNCTION_ARGUMENT_NUMBER_MISMATCH.code, buildQuery(i, ""));
|
|
assertQueryError(errors.ERROR_QUERY_FUNCTION_ARGUMENT_NUMBER_MISMATCH.code, buildQuery(i, "'foo', 'bar'"));
|
|
assertQueryWarningAndNull(errors.ERROR_QUERY_FUNCTION_ARGUMENT_TYPE_MISMATCH.code, buildQuery(i, "null"));
|
|
assertQueryWarningAndNull(errors.ERROR_QUERY_FUNCTION_ARGUMENT_TYPE_MISMATCH.code, buildQuery(i, "false"));
|
|
assertQueryWarningAndNull(errors.ERROR_QUERY_FUNCTION_ARGUMENT_TYPE_MISMATCH.code, buildQuery(i, "3"));
|
|
assertQueryWarningAndNull(errors.ERROR_QUERY_FUNCTION_ARGUMENT_TYPE_MISMATCH.code, buildQuery(i, "\"foo\""));
|
|
assertQueryWarningAndNull(errors.ERROR_QUERY_FUNCTION_ARGUMENT_TYPE_MISMATCH.code, buildQuery(i, "'foo bar'"));
|
|
assertQueryWarningAndNull(errors.ERROR_QUERY_FUNCTION_ARGUMENT_TYPE_MISMATCH.code, buildQuery(i, "'foo/bar/baz'"));
|
|
assertQueryWarningAndNull(errors.ERROR_QUERY_FUNCTION_ARGUMENT_TYPE_MISMATCH.code, buildQuery(i, "[ ]"));
|
|
assertQueryWarningAndNull(errors.ERROR_QUERY_FUNCTION_ARGUMENT_TYPE_MISMATCH.code, buildQuery(i, "{ }"));
|
|
assertQueryWarningAndNull(errors.ERROR_QUERY_FUNCTION_ARGUMENT_TYPE_MISMATCH.code, buildQuery(i, "{ foo: 'bar' }"));
|
|
}
|
|
},
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief test document function
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
testDocument1 : function () {
|
|
var cn = "UnitTestsAhuacatlFunctions";
|
|
|
|
internal.db._drop(cn);
|
|
var cx = internal.db._create(cn);
|
|
var d1 = cx.save({ "title" : "123", "value" : 456 });
|
|
var d2 = cx.save({ "title" : "nada", "value" : 123 });
|
|
|
|
var expected, actual;
|
|
|
|
var buildQuery = function (nr, input) {
|
|
switch (nr) {
|
|
case 0:
|
|
return `RETURN DOCUMENT(${input})`;
|
|
case 1:
|
|
return `RETURN NOOPT(DOCUMENT(${input}))`;
|
|
case 2:
|
|
return `RETURN NOOPT(V8(DOCUMENT(${input})))`;
|
|
default:
|
|
assertTrue(false, "Undefined state");
|
|
}
|
|
};
|
|
|
|
for (var i = 0; i < 3; ++i) {
|
|
// test with two parameters
|
|
expected = [ { title: "123", value : 456 } ];
|
|
actual = getQueryResults(buildQuery(i, cn + ", \"" + d1._id + "\""));
|
|
assertEqual(expected, actual);
|
|
|
|
actual = getQueryResults(buildQuery(i, cn + ", \"" + d1._key + "\""));
|
|
assertEqual(expected, actual);
|
|
|
|
expected = [ { title: "nada", value : 123 } ];
|
|
actual = getQueryResults(buildQuery(i, cn + ", \"" + d2._id + "\""));
|
|
assertEqual(expected, actual);
|
|
|
|
actual = getQueryResults(buildQuery(i, cn + ", \"" + d2._key + "\""));
|
|
assertEqual(expected, actual);
|
|
|
|
// test with one parameter
|
|
expected = [ { title: "nada", value : 123 } ];
|
|
actual = getQueryResults(buildQuery(i, "\"" + d2._id + "\""));
|
|
assertEqual(expected, actual);
|
|
|
|
// test with function result parameter
|
|
actual = getQueryResults(buildQuery(i, "CONCAT(\"foo\", \"bar\")"));
|
|
assertEqual([ null ], actual);
|
|
actual = getQueryResults(buildQuery(i, "CONCAT(\"" + cn + "\", \"bart\")"));
|
|
assertEqual([ null ], actual);
|
|
|
|
cx.save({ _key: "foo", value: "bar" });
|
|
expected = [ { value: "bar" } ];
|
|
actual = getQueryResults(buildQuery(i, "CONCAT(\"" + cn + "\", \"foo\")"));
|
|
assertEqual([ null ], actual);
|
|
actual = getQueryResults(buildQuery(i, "CONCAT(@c, \"/\", @k)"), { c: cn, k: "foo" });
|
|
assertEqual(expected, actual);
|
|
actual = getQueryResults(buildQuery(i, "CONCAT(\"" + cn + "\", \"/\", @k)"), { k: "foo" });
|
|
assertEqual(expected, actual);
|
|
|
|
// test with bind parameter
|
|
expected = [ { title: "nada", value : 123 } ];
|
|
actual = getQueryResults(buildQuery(i, "@id"), { id: d2._id });
|
|
assertEqual(expected, actual);
|
|
|
|
// test dynamic parameter
|
|
expected = [ { title: "nada", value : 123 }, { title: "123", value: 456 }, { value: "bar" } ];
|
|
actual = getQueryResults("FOR d IN @@cn SORT d.value " + buildQuery(i, "d._id"), { "@cn" : cn });
|
|
assertEqual(expected, actual);
|
|
cx.remove("foo");
|
|
}
|
|
|
|
internal.db._drop(cn);
|
|
},
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief test document function
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
testDocument2 : function () {
|
|
var cn = "UnitTestsAhuacatlFunctions";
|
|
|
|
internal.db._drop(cn);
|
|
var cx = internal.db._create(cn);
|
|
var d1 = cx.save({ "title" : "123", "value" : 456, "zxy" : 1 });
|
|
var d2 = cx.save({ "title" : "nada", "value" : 123, "zzzz" : false });
|
|
|
|
var expected, actual;
|
|
|
|
// test with two parameters
|
|
expected = [ { title: "123", value : 456, zxy: 1 } ];
|
|
actual = getQueryResults("RETURN DOCUMENT(@@cn, @id)", { "@cn" : cn, "id" : d1._id });
|
|
assertEqual(expected, actual);
|
|
|
|
actual = getQueryResults("RETURN DOCUMENT(@@cn, @id)", { "@cn" : cn, "id" : d1._key });
|
|
assertEqual(expected, actual);
|
|
|
|
expected = [ { title: "nada", value : 123, zzzz : false } ];
|
|
actual = getQueryResults("RETURN DOCUMENT(@@cn, @id)", { "@cn" : cn, "id" : d2._id });
|
|
assertEqual(expected, actual);
|
|
|
|
actual = getQueryResults("RETURN DOCUMENT(@@cn, @id)", { "@cn" : cn, "id" : d2._key });
|
|
assertEqual(expected, actual);
|
|
|
|
// test with one parameter
|
|
expected = [ { title: "123", value : 456, zxy: 1 } ];
|
|
actual = getQueryResults("RETURN DOCUMENT(@id)", { "id" : d1._id });
|
|
assertEqual(expected, actual);
|
|
|
|
expected = [ { title: "nada", value : 123, zzzz : false } ];
|
|
actual = getQueryResults("RETURN DOCUMENT(@id)", { "id" : d2._id });
|
|
assertEqual(expected, actual);
|
|
|
|
internal.db._drop(cn);
|
|
},
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief test document function
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
testDocumentMulti1 : function () {
|
|
var cn = "UnitTestsAhuacatlFunctions";
|
|
|
|
internal.db._drop(cn);
|
|
var cx = internal.db._create(cn);
|
|
var d1 = cx.save({ "title" : "123", "value" : 456, "zxy" : 1 });
|
|
var d2 = cx.save({ "title" : "nada", "value" : 123, "zzzz" : false });
|
|
var d3 = cx.save({ "title" : "boom", "value" : 3321, "zzzz" : null });
|
|
|
|
var expected, actual;
|
|
|
|
// test with two parameters
|
|
expected = [ [
|
|
{ title: "123", value : 456, zxy : 1 },
|
|
{ title: "nada", value : 123, zzzz : false },
|
|
{ title: "boom", value : 3321, zzzz : null }
|
|
] ];
|
|
|
|
actual = getQueryResults("RETURN DOCUMENT(@@cn, @id)", { "@cn" : cn, "id" : [ d1._id, d2._id, d3._id ] }, true);
|
|
assertEqual(expected, actual);
|
|
|
|
expected = [ [ { title: "nada", value : 123, zzzz : false } ] ];
|
|
actual = getQueryResults("RETURN DOCUMENT(@@cn, @id)", { "@cn" : cn, "id" : [ d2._id ] }, true);
|
|
assertEqual(expected, actual);
|
|
|
|
// test with one parameter
|
|
expected = [ [ { title: "nada", value : 123, zzzz : false } ] ];
|
|
actual = getQueryResults("RETURN DOCUMENT(@id)", { "id" : [ d2._id ] }, true);
|
|
assertEqual(expected, actual);
|
|
|
|
|
|
cx.remove(d3);
|
|
|
|
expected = [ [ { title: "nada", value : 123, zzzz : false } ] ];
|
|
actual = getQueryResults("RETURN DOCUMENT(@@cn, @id)", { "@cn" : cn, "id" : [ d2._id, d3._id, "abc/def" ] }, true);
|
|
assertEqual(expected, actual);
|
|
|
|
expected = [ [ { title: "nada", value : 123, zzzz : false } ] ];
|
|
actual = getQueryResults("RETURN DOCUMENT(@id)", { "id" : [ d2._id, d3._id, "abc/def" ] }, true);
|
|
assertEqual(expected, actual);
|
|
|
|
internal.db._drop(cn);
|
|
},
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief test document function
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
testDocumentInvalid : function () {
|
|
var cn = "UnitTestsAhuacatlFunctions";
|
|
|
|
internal.db._drop(cn);
|
|
internal.db._create(cn);
|
|
|
|
var expected, actual;
|
|
|
|
// test with non-existing document
|
|
expected = [ null ];
|
|
actual = getQueryResults("RETURN DOCUMENT(" + cn + ", \"" + cn + "/99999999999\")");
|
|
assertEqual(expected, actual);
|
|
|
|
actual = getQueryResults("RETURN DOCUMENT(" + cn + ", \"thefoxdoesnotexist/99999999999\")");
|
|
assertEqual(expected, actual);
|
|
|
|
internal.db._drop(cn);
|
|
},
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief test document indexed access function
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
testDocumentIndexedAccess : function () {
|
|
var cn = "UnitTestsAhuacatlFunctions";
|
|
|
|
internal.db._drop(cn);
|
|
var cx = internal.db._create(cn);
|
|
var d1 = cx.save({ "title" : "123", "value" : 456 });
|
|
|
|
var expected, actual;
|
|
|
|
expected = [ "123" ];
|
|
actual = getQueryResults("RETURN DOCUMENT(" + cn + ", [ \"" + d1._id + "\" ])[0].title");
|
|
assertEqual(expected, actual);
|
|
|
|
internal.db._drop(cn);
|
|
},
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief test current user function
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
testCurrentUser : function () {
|
|
var actual = getQueryResults("RETURN CURRENT_USER()");
|
|
// there is no current user in the non-request context
|
|
assertEqual([ null ], actual);
|
|
},
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief test current database function
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
testCurrentDatabase : function () {
|
|
var actual = getQueryResults("RETURN CURRENT_DATABASE()");
|
|
assertEqual([ "_system" ], actual);
|
|
},
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief test sleep function
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
testSleep : function () {
|
|
var start = require("internal").time();
|
|
var actual = getQueryResults("LET a = SLEEP(2) RETURN 1");
|
|
|
|
var diff = Math.round(require("internal").time() - start, 1);
|
|
|
|
assertEqual([ 1 ], actual);
|
|
|
|
// allow some tolerance for the time diff (because of busy servers and Valgrind)
|
|
assertTrue(diff >= 1.8 && diff <= 20, "SLEEP(2) did not take between 1.8 and 20 seconds");
|
|
}
|
|
|
|
};
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief executes the test suite
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
jsunity.run(ahuacatlMiscFunctionsTestSuite);
|
|
|
|
return jsunity.done();
|
|
|
|
// Local Variables:
|
|
// mode: outline-minor
|
|
// outline-regexp: "^\\(/// @brief\\|/// @addtogroup\\|// --SECTION--\\|/// @page\\|/// @}\\)"
|
|
// End:
|