mirror of https://gitee.com/bigwinds/arangodb
336 lines
15 KiB
JavaScript
336 lines
15 KiB
JavaScript
/*jshint globalstrict:false, strict:false, maxlen: 500 */
|
|
/*global assertEqual, AQL_EXECUTE, AQL_EXPLAIN, AQL_EXECUTEJSON */
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief tests for dynamic attributes
|
|
///
|
|
/// @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 jsunity = require("jsunity");
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief test suite
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
function ahuacatlDynamicAttributesTestSuite () {
|
|
|
|
function checkResult(query, expected) {
|
|
let q = "RETURN NOOPT(" + query + ")";
|
|
assertEqual(expected, AQL_EXECUTE(q).json[0]);
|
|
assertEqual("simple", AQL_EXPLAIN(q).plan.nodes[1].expressionType);
|
|
|
|
q = "RETURN " + query;
|
|
assertEqual(expected, AQL_EXECUTE(q).json[0]);
|
|
assertEqual("simple", AQL_EXPLAIN(q).plan.nodes[1].expressionType);
|
|
}
|
|
|
|
return {
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief set up
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
setUp : function () {
|
|
},
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief tear down
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
tearDown : function () {
|
|
},
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief test dynamic with non-string values
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
testDynamicAttributesNonStringNames : function () {
|
|
var expected = { "" : 7, "true" : 12, "false" : 15, "123" : 21, "-42.5" : 99, "[]" : 117, "[1]" : 121, "[1,2,3,4]" : 131, "{\"a\":1}" : 149 };
|
|
var query = "{ [ PASSTHRU(null) ] : 7, [ PASSTHRU(true) ] : 12, [ PASSTHRU(false) ] : 15, [ PASSTHRU(123) ] : 21, [ PASSTHRU(-42.5) ] : 99, [ PASSTHRU([ ]) ] : 117, [ PASSTHRU([ 1 ]) ] : 121, [ PASSTHRU([ 1, 2, 3, 4 ]) ] : 131, [ PASSTHRU({ a: 1 }) ] : 149 }";
|
|
checkResult(query, expected);
|
|
},
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief test dynamic with keyword names
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
testDynamicAttributesReservedNames : function () {
|
|
var expected = { LET: "LET", FILTER: "FILTER", SORT: "SORT", FOR: "FOR", "return": "RETURN" };
|
|
var actual = AQL_EXECUTE("RETURN { [ UPPER('let') ] : 'LET', [ 'FILTER' ] : 'FILTER', [ PASSTHRU('SORT') ] : 'SORT', [ CONCAT('F', 'O', 'R') ] : 'FOR', [ PASSTHRU(LOWER('RETURN')) ] : 'RETURN' }");
|
|
assertEqual(expected, actual.json[0]);
|
|
},
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief test dynamic with special characters
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
testDynamicAttributesWhitespace : function () {
|
|
var expected = { "1" : "one", " 1" : "one-1", "1 " : "1-one", " 1 " : "one-1-one" };
|
|
var query = "{ [ '1' ] : 'one', [ ' 1' ] : 'one-1', [ '1 ' ] : '1-one', [ ' 1 ' ] : 'one-1-one' }";
|
|
checkResult(query, expected);
|
|
},
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief test dynamic with special characters
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
testDynamicAttributesWhitespacePassthru : function () {
|
|
var expected = { "1" : "one", " 1" : "one-1", "1 " : "1-one", " 1 " : "one-1-one" };
|
|
var actual = AQL_EXECUTE("RETURN { [ PASSTHRU('1') ] : 'one', [ PASSTHRU(' 1') ] : 'one-1', [ PASSTHRU('1 ') ] : '1-one', [ PASSTHRU(' 1 ') ] : 'one-1-one' }");
|
|
assertEqual(expected, actual.json[0]);
|
|
},
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief test dynamic with special characters
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
testDynamicAttributesSpecialCharacters : function () {
|
|
var expected = { "" : "empty", " " : "space", " " : "two", "_" : "underscore", "\\" : "backslash", "\n" : "linebreak", "\t" : "tab!", "$" : "dollar", "1" : "one" };
|
|
var actual = AQL_EXECUTE("RETURN { [ '' ] : 'empty', [ ' ' ] : 'space', [ ' ' ] : 'two', [ '_' ] : 'underscore', [ '\\\\'] : 'backslash', '\\n' : 'linebreak', '\\t' : 'tab!', '$' : 'dollar', '1' : 'one' }");
|
|
assertEqual(expected, actual.json[0]);
|
|
},
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief test dynamic with bind parameter-like names
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
testDynamicAttributesWithBindParameterLikeNames : function () {
|
|
var expected = { "@abc": "abc", "@@a": "a", "@bc": "bc", "@ax": "ax" };
|
|
var actual = AQL_EXECUTE("RETURN { [ '@abc' ] : 'abc', [ '@@a' ] : 'a', [ CONCAT('@', 'bc') ] : 'bc', [ PASSTHRU('@ax') ] : 'ax' }");
|
|
assertEqual(expected, actual.json[0]);
|
|
},
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief test dynamic with bind parameters
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
testDynamicAttributesWithBindParameters : function () {
|
|
var expected = { "bind-abc": "xabc", "bind-a": "xa", "bind-bcde": "xbcde", "bind-ax": "xax" };
|
|
var actual = AQL_EXECUTE("RETURN { [ @abc ] : 'xabc', [ @a ] : 'xa', [ CONCAT(@bc, 'de') ] : 'xbcde', [ PASSTHRU(@ax) ] : 'xax' }", { abc: "bind-abc", "a" : "bind-a", "bc" : "bind-bc", "ax" : "bind-ax" });
|
|
assertEqual(expected, actual.json[0]);
|
|
},
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief test dynamic with Unicode
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
testDynamicAttributesUmlaut : function () {
|
|
var expected = { "KÖTÖR": "kötör", "trötör": "tröt!", "mÄgensÄftwürzgemösch": "möglich", "FöR": "FöR", "sörtierung": "sörtierung" };
|
|
var actual = AQL_EXECUTE("RETURN { [ UPPER('kötör') ] : 'kötör', [ 'trötör' ] : 'tröt!', [ PASSTHRU('mÄgensÄftwürzgemösch') ] : 'möglich', [ CONCAT('F', 'ö', 'R') ] : 'FöR', [ PASSTHRU(LOWER('SÖRTIERUNG')) ] : 'sörtierung' }");
|
|
assertEqual(expected, actual.json[0]);
|
|
},
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief test dynamic with Unicode
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
testDynamicAttributesHangul : function () {
|
|
var expected = { "코리아닷컴" : 1, "메일알리미" : 2 };
|
|
var query = "{ [ PASSTHRU('코리아닷컴') ] : 1, [ PASSTHRU('메일알리미') ] : 2 }";
|
|
checkResult(query, expected);
|
|
},
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief test dynamic with Unicode
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
testDynamicAttributesChinese : function () {
|
|
var expected = { "中华网以中国的市场为核心" : 23, "致力为当地用户提供流动增值服务" : 99 };
|
|
var query = "{ [ PASSTHRU('中华网以中国的市场为核心') ] : 23, [ PASSTHRU('致力为当地用户提供流动增值服务') ] : 99 }";
|
|
checkResult(query, expected);
|
|
},
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief test dynamic with Unicode
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
testDynamicAttributesRussian : function () {
|
|
var expected = { "Голкипер" : 1, "мадридского" : 2, "Икер Касильяс призвал" : 3 };
|
|
var query = "{ [ PASSTHRU('Голкипер') ] : 1, [ PASSTHRU('мадридского') ] : 2, [ PASSTHRU('Икер Касильяс призвал') ] : 3 }";
|
|
checkResult(query, expected);
|
|
},
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief test dynamic with Unicode
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
testDynamicAttributesUnicodeMixed : function () {
|
|
var expected = { "დახმარებისთვის" : 1, "töröö !" : 2, "ジャパン は、イギリスのニュー・ウェーヴバンド。デヴィッド" : 3 };
|
|
var actual = AQL_EXECUTE("RETURN { [ PASSTHRU('დახმარებისთვის') ] : 1, [ PASSTHRU('töröö !') ] : 2, [ PASSTHRU('ジャパン は、イギリスのニュー・ウェーヴバンド。デヴィッド') ] : 3 }");
|
|
assertEqual(expected, actual.json[0]);
|
|
},
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief test dynamic with repeated attributes
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
testDynamicAttributesRepeated : function () {
|
|
var expected = { FOO: 123, bar: 19 };
|
|
var query = "{ [ 'FOO' ] : 123, [ PASSTHRU('FOO') ] : 42, [ 'bar' ] : 19, [ PASSTHRU('FOO') ] : 23 }";
|
|
checkResult(query, expected);
|
|
},
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief test dynamic mixed with regular
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
testDynamicAttributesMixedWithRegular : function () {
|
|
var expected = { foo: 1, FOO: 2, bar: 3, baR: 4, foobar: 6 };
|
|
var query = "{ 'foo' : 1, [ 'FOO' ] : 2, 'bar' : 3, [ PASSTHRU('baR') ] : 4, [ PASSTHRU('bar') ] : 5, 'foobar' : 6 }";
|
|
checkResult(query, expected);
|
|
},
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief test regular overwritten by dynamic
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
testDynamicAttributesOverwritingRegular : function () {
|
|
var expected = { FOO: 2 };
|
|
var query = "{ FOO : 2, [ PASSTHRU('FOO') ] : 1 }";
|
|
checkResult(query, expected);
|
|
},
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief test dynamic overwritten by regular
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
testDynamicAttributesOverwrittenByRegular : function () {
|
|
var expected = { FOO: 1 };
|
|
var query = "{ [ PASSTHRU('FOO') ] : 1, FOO : 2 }";
|
|
checkResult(query, expected);
|
|
},
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief test dynamic with for loop
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
testDynamicAttributesWithFor : function () {
|
|
var expected = [ ];
|
|
for (var i = 1; i <= 100; ++i) {
|
|
var doc = { };
|
|
doc["test-value-" + i] = i;
|
|
expected.push(doc);
|
|
}
|
|
|
|
let actual = AQL_EXECUTE("FOR i IN 1..100 RETURN { [ CONCAT('test-value-', i) ] : i }");
|
|
assertEqual(expected, actual.json);
|
|
},
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief test dynamic with for loop
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
testDynamicAttributesWithNestedFor : function () {
|
|
var expected = [ ];
|
|
for (var i = 1; i <= 10; ++i) {
|
|
var doc = { };
|
|
doc["one-" + i] = i;
|
|
doc["two-23"] = 23;
|
|
expected.push(doc);
|
|
|
|
var doc2 = { };
|
|
doc2["one-" + i] = i;
|
|
doc2["two-42"] = 42;
|
|
expected.push(doc2);
|
|
}
|
|
var actual = AQL_EXECUTE("FOR i IN 1..10 FOR j IN [ 23, 42 ] RETURN { [ CONCAT('one-', i) ] : i, [ CONCAT('two-', j) ] : j }");
|
|
assertEqual(expected, actual.json);
|
|
},
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief test nested
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
testNestedObjectsWithDynamicAttributes : function () {
|
|
var expected = {
|
|
foo: "bar",
|
|
bazbar: {
|
|
foo2: "foobar",
|
|
bazbar: {
|
|
2: 42,
|
|
4: 23
|
|
},
|
|
BAZBAR: "foofoofoo"
|
|
},
|
|
lastone: "done"
|
|
};
|
|
|
|
var actual = AQL_EXECUTE("RETURN { [ 'foo' ] : 'bar', [ CONCAT('baz', 'bar') ] : { foo2: 'foobar', [ 'bazbar' ] : { [ 1 + 1 ] : 42, [ 2 + 2 ] : 23 }, [ UPPER('bazbar') ] : LOWER('FOOFOOFOO') }, [ CONCAT('last', 'one') ] : 'done' }");
|
|
assertEqual(expected, actual.json[0]);
|
|
},
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief test dynamic with conditional
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
testDynamicAttributesConditional : function () {
|
|
var expected = [ ];
|
|
for (var i = 1; i <= 100; ++i) {
|
|
var doc = { };
|
|
if (i < 50) {
|
|
doc["whatever" + i] = i;
|
|
}
|
|
else {
|
|
doc[i + "something-completely-different"] = i * 2;
|
|
}
|
|
expected.push(doc);
|
|
}
|
|
var actual = AQL_EXECUTE("FOR i IN 1..100 RETURN { [ i < 50 ? CONCAT('whatever', i) : CONCAT(i, 'something-completely-different') ] : i < 50 ? i : i * 2 }");
|
|
assertEqual(expected, actual.json);
|
|
},
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief test dynamic explain
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
testDynamicExplain : function () {
|
|
var expected = [ ];
|
|
for (var i = 1; i <= 100; ++i) {
|
|
var doc = { };
|
|
if (i < 50) {
|
|
doc["whatever" + i] = i;
|
|
}
|
|
else {
|
|
doc[i + "something-completely-different"] = i * 2;
|
|
}
|
|
expected.push(doc);
|
|
}
|
|
var plan = AQL_EXPLAIN("FOR i IN 1..100 RETURN { [ i < 50 ? CONCAT('whatever', i) : CONCAT(i, 'something-completely-different') ] : i < 50 ? i : i * 2 }", { }, { verbosePlans: true }).plan;
|
|
var actual = AQL_EXECUTEJSON(plan);
|
|
assertEqual(expected, actual.json);
|
|
}
|
|
|
|
};
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief executes the test suite
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
jsunity.run(ahuacatlDynamicAttributesTestSuite);
|
|
|
|
return jsunity.done();
|
|
|