mongo/jstests/aggregation/expressions/expression_function.js

148 lines
3.8 KiB
JavaScript

// Tests basic functionality of the $function expression.
//
// @tags: [
// requires_scripting,
// ]
import {resultsEq} from "jstests/aggregation/extras/utils.js";
const coll = db.expression_function;
coll.drop();
function f_finalize(first, second) {
return first + second;
}
for (let i = 0; i < 5; i++) {
assert.commandWorked(coll.insert({value: i}));
}
let pipeline = [
{
$project: {
newValue: {
$function: {
args: ["$value", -1],
body: f_finalize,
lang: "js",
},
},
_id: 0,
},
},
];
let results = coll.aggregate(pipeline, {cursor: {batchSize: 1}}).toArray();
assert(resultsEq(results, [{newValue: -1}, {newValue: 0}, {newValue: 1}, {newValue: 2}, {newValue: 3}]), results);
// Test that the 'body' function accepts a string argument.
pipeline[0].$project.newValue.$function.body = f_finalize.toString();
results = coll.aggregate(pipeline, {cursor: {}}).toArray();
assert(resultsEq(results, [{newValue: -1}, {newValue: 0}, {newValue: 1}, {newValue: 2}, {newValue: 3}]), results);
// Test that function can take an expression that evaluates to an array for the 'args' parameter.
coll.drop();
for (let i = 0; i < 5; i++) {
assert.commandWorked(coll.insert({values: [i, i * 2]}));
}
pipeline = [
{
$project: {
newValue: {
$function: {
args: "$values",
body: f_finalize,
lang: "js",
},
},
_id: 0,
},
},
];
results = coll.aggregate(pipeline, {cursor: {}}).toArray();
assert(resultsEq(results, [{newValue: 0}, {newValue: 3}, {newValue: 6}, {newValue: 9}, {newValue: 12}]), results);
// Test that the command correctly fails for invalid arguments.
pipeline = [
{
$project: {
newValue: {
$function: {
"args": "must evaluate to an array",
"body": f_finalize,
"lang": "js",
},
},
_id: 0,
},
},
];
assert.commandFailedWithCode(db.runCommand({aggregate: coll.getName(), pipeline: pipeline, cursor: {}}), 31266);
pipeline = [
{
$project: {
newValue: {
$function: {
"args": [1, 3],
"body": "this is not a valid function!",
"lang": "js",
},
},
_id: 0,
},
},
];
assert.commandFailedWithCode(
db.runCommand({aggregate: coll.getName(), pipeline: pipeline, cursor: {}}),
ErrorCodes.JSInterpreterFailure,
);
pipeline = [
{
$project: {
newValue: {
$function: {
"args": [1, 3],
"body": f_finalize,
},
},
_id: 0,
},
},
];
assert.commandFailedWithCode(db.runCommand({aggregate: coll.getName(), pipeline: pipeline, cursor: {}}), 31418);
pipeline = [
{
$project: {
newValue: {
$function: {
"args": [1, 3],
"body": f_finalize,
"lang": "not js!",
},
},
_id: 0,
},
},
];
assert.commandFailedWithCode(db.runCommand({aggregate: coll.getName(), pipeline: pipeline, cursor: {}}), 31419);
// Test that we fail if the 'args' field is not an array.
pipeline = [
{
$project: {
newValue: {
$function: {
"args": "A string!",
"body": f_finalize,
"lang": "js",
},
},
_id: 0,
},
},
];
assert.commandFailedWithCode(db.runCommand({aggregate: coll.getName(), pipeline: pipeline, cursor: {}}), 31266);