// $cond returns the evaluated second argument if the first evaluates to true but the evaluated // third argument if the first evaluates to false. load('jstests/aggregation/extras/utils.js'); t = db.jstests_aggregation_cond; t.drop(); t.save( {} ); function assertError( expectedErrorCode, condSpec ) { assertErrorCode(t, {$project: {a: {$cond: condSpec}}}, expectedErrorCode); } function assertResult( expectedResult, arg ) { assert.eq( expectedResult, t.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 ] }] ); t.drop(); t.save( { t:true, f:false, x:'foo', y:'bar' } ); // Field path expressions. assertResult( 'foo', ['$t', '$x', '$y'] ); assertResult( 'bar', ['$f', '$x', '$y'] ); t.drop(); t.save( {} ); // Coerce to bool. assertResult( 'a', [1, 'a', 'b'] ); assertResult( 'a', ['', 'a', 'b'] ); assertResult( 'b', [0, 'a', 'b'] ); // Nested. t.drop(); t.save( { noonSense:'am', mealCombined:'no' } ); t.save( { noonSense:'am', mealCombined:'yes' } ); t.save( { noonSense:'pm', mealCombined:'yes' } ); t.save( { noonSense:'pm', mealCombined:'no' } ); assert.eq( [ 'breakfast', 'brunch', 'linner', 'dinner' ], t.aggregate( { $project:{ a:{ $cond:[ { $eq:[ '$noonSense', 'am' ] }, { $cond:[ { $eq:[ '$mealCombined', 'yes' ] }, 'brunch', 'breakfast' ] }, { $cond:[ { $eq:[ '$mealCombined', 'yes' ] }, 'linner', 'dinner' ] } ] } } } ) .map( function( x ) { return x.a; } ) );