1
0
Fork 0
arangodb/js/server/tests/aql-functions-misc.js

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: