mongo/jstests/aggregation/expressions/cond.js

88 lines
2.8 KiB
JavaScript

// $cond returns the evaluated second argument if the first evaluates to true but the evaluated
// third argument if the first evaluates to false.
import {assertErrorCode} from "jstests/aggregation/extras/utils.js";
const coll = db.jstests_aggregation_cond;
coll.drop();
coll.save({});
function assertError(expectedErrorCode, condSpec) {
assertErrorCode(coll, {$project: {a: {$cond: condSpec}}}, expectedErrorCode);
}
function assertResult(expectedResult, arg) {
assert.eq(expectedResult, coll.aggregate({$project: {a: {$cond: arg}}}).toArray()[0].a);
}
// Wrong number of args.
assertError(16020, []);
assertError(16020, [1]);
assertError(16020, [false]);
assertError(16020, [1, 1]);
assertError(16020, [1, 1, null, 1]);
assertError(16020, [1, 1, 1, undefined]);
// Bad object cases.
assertError(17080, {"else": 1, then: 1});
assertError(17081, {"if": 1, "else": 1});
assertError(17082, {"if": 1, then: 1});
assertError(17083, {asdf: 1, then: 1});
// Literal expressions.
assertResult(1, [true, 1, 2]);
assertResult(2, [false, 1, 2]);
// Order independence for object case.
assertResult(1, {"if": true, "then": 1, "else": 2});
assertResult(1, {"if": true, "else": 2, "then": 1});
assertResult(1, {"then": 1, "if": true, "else": 2});
assertResult(1, {"then": 1, "else": 2, "if": true});
assertResult(1, {"else": 2, "then": 1, "if": true});
assertResult(1, {"else": 2, "if": true, "then": 1});
// Computed expressions.
assertResult(1, [{$and: []}, {$add: [1]}, {$add: [1, 1]}]);
assertResult(2, [{$or: []}, {$add: [1]}, {$add: [1, 1]}]);
assert(coll.drop());
assert.commandWorked(coll.insert({t: true, f: false, x: "foo", y: "bar"}));
// Field path expressions.
assertResult("foo", ["$t", "$x", "$y"]);
assertResult("bar", ["$f", "$x", "$y"]);
assert(coll.drop());
assert.commandWorked(coll.insert({}));
// Coerce to bool.
assertResult("a", [1, "a", "b"]);
assertResult("a", ["", "a", "b"]);
assertResult("b", [0, "a", "b"]);
// Nested.
assert(coll.drop());
assert.commandWorked(coll.insert({noonSense: "am", mealCombined: "no"}));
assert.commandWorked(coll.insert({noonSense: "am", mealCombined: "yes"}));
assert.commandWorked(coll.insert({noonSense: "pm", mealCombined: "yes"}));
assert.commandWorked(coll.insert({noonSense: "pm", mealCombined: "no"}));
assert.eq(
["breakfast", "brunch", "dinner", "linner"],
coll
.aggregate([
{
$project: {
meal: {
$cond: [
{$eq: ["$noonSense", "am"]},
{$cond: [{$eq: ["$mealCombined", "yes"]}, "brunch", "breakfast"]},
{$cond: [{$eq: ["$mealCombined", "yes"]}, "linner", "dinner"]},
],
},
},
},
{$sort: {meal: 1}},
])
.map((doc) => doc.meal),
);