mirror of https://github.com/mongodb/mongo
93 lines
4.0 KiB
JavaScript
93 lines
4.0 KiB
JavaScript
// Tests for $divide aggregation expression.
|
|
import "jstests/libs/query/sbe_assert_error_override.js";
|
|
|
|
import {assertErrorCode} from "jstests/aggregation/extras/utils.js";
|
|
|
|
const coll = db.jstests_aggregation_divide;
|
|
coll.drop();
|
|
|
|
const testCases = [
|
|
// Test various argument types pairs.
|
|
{document: {left: NumberInt(10), right: NumberInt(2)}, expected: 5},
|
|
{document: {left: NumberInt(10), right: 2.5}, expected: 4},
|
|
{document: {left: NumberInt(10), right: NumberLong("2")}, expected: 5},
|
|
{document: {left: NumberInt(10), right: NumberDecimal("2.5")}, expected: NumberDecimal("4")},
|
|
{document: {left: NumberInt(10), right: null}, expected: null},
|
|
|
|
{document: {left: 12.5, right: NumberInt(5)}, expected: 2.5},
|
|
{document: {left: 12.5, right: 2.5}, expected: 5},
|
|
{document: {left: 12.5, right: NumberLong("5")}, expected: 2.5},
|
|
{
|
|
document: {left: 12.5, right: NumberDecimal("2.5")},
|
|
expected: NumberDecimal("5.000000000000"),
|
|
},
|
|
{document: {left: 12.5, right: null}, expected: null},
|
|
|
|
{document: {left: NumberLong("10"), right: NumberInt(2)}, expected: 5},
|
|
{document: {left: NumberLong("10"), right: 2.5}, expected: 4},
|
|
{document: {left: NumberLong("10"), right: NumberLong("2")}, expected: 5},
|
|
{document: {left: NumberLong("10"), right: NumberDecimal("2.5")}, expected: NumberDecimal("4")},
|
|
|
|
{document: {left: NumberDecimal("12.5"), right: NumberInt(5)}, expected: NumberDecimal("2.5")},
|
|
{document: {left: NumberDecimal("12.5"), right: 2.5}, expected: NumberDecimal("5")},
|
|
{
|
|
document: {left: NumberDecimal("12.5"), right: NumberLong("5")},
|
|
expected: NumberDecimal("2.5"),
|
|
},
|
|
{
|
|
document: {left: NumberDecimal("12.5"), right: NumberDecimal("2.5")},
|
|
expected: NumberDecimal("5"),
|
|
},
|
|
{document: {left: NumberDecimal("12.5"), right: null}, expected: null},
|
|
|
|
// Null divided by anything (even zero) is null.
|
|
{document: {left: null, right: NumberInt(2)}, expected: null},
|
|
{document: {left: null, right: 2.5}, expected: null},
|
|
{document: {left: null, right: NumberLong("2")}, expected: null},
|
|
{document: {left: null, right: NumberDecimal("2.5")}, expected: null},
|
|
|
|
{document: {left: null, right: NumberInt(0)}, expected: null},
|
|
{document: {left: null, right: 0.0}, expected: null},
|
|
{document: {left: null, right: NumberLong("0")}, expected: null},
|
|
{document: {left: null, right: NumberDecimal("0")}, expected: null},
|
|
|
|
// $divide arguments are converted to double before division which causes it to loose precision.
|
|
{document: {left: NumberLong("9223372036854775807"), right: 1}, expected: 9223372036854776000},
|
|
|
|
// Decimal values are not converted to doubles before division and represent result accurately.
|
|
{
|
|
document: {left: NumberDecimal("9223372036854775807"), right: 1},
|
|
expected: NumberDecimal("9223372036854775807"),
|
|
},
|
|
];
|
|
|
|
testCases.forEach(function (testCase) {
|
|
assert.commandWorked(coll.insert(testCase.document));
|
|
|
|
const result = coll.aggregate({$project: {computed: {$divide: ["$left", "$right"]}}}).toArray();
|
|
|
|
assert.eq(result.length, 1);
|
|
assert.eq(result[0].computed, testCase.expected);
|
|
|
|
assert(coll.drop());
|
|
});
|
|
|
|
// Test error codes on incorrect use of $divide.
|
|
const errorTestCases = [
|
|
{document: {left: 1, right: NumberInt(0)}, errorCodes: [16608, ErrorCodes.BadValue]},
|
|
{document: {left: 1, right: 0.0}, errorCodes: [16608, ErrorCodes.BadValue]},
|
|
{document: {left: 1, right: NumberLong("0")}, errorCodes: [16608, ErrorCodes.BadValue]},
|
|
{document: {left: 1, right: NumberDecimal("0")}, errorCodes: [16608, ErrorCodes.BadValue]},
|
|
|
|
{document: {left: 1, right: "not a number"}, errorCodes: [16609, ErrorCodes.TypeMismatch]},
|
|
{document: {left: "not a number", right: 1}, errorCodes: [16609, ErrorCodes.TypeMismatch]},
|
|
];
|
|
|
|
errorTestCases.forEach(function (testCase) {
|
|
assert.commandWorked(coll.insert(testCase.document));
|
|
|
|
assertErrorCode(coll, {$project: {computed: {$divide: ["$left", "$right"]}}}, testCase.errorCodes);
|
|
|
|
assert(coll.drop());
|
|
});
|