mirror of https://github.com/mongodb/mongo
295 lines
10 KiB
JavaScript
295 lines
10 KiB
JavaScript
/**
|
|
* Tests $dateDiff expression.
|
|
* @tags: [
|
|
* ]
|
|
*/
|
|
import "jstests/libs/query/sbe_assert_error_override.js";
|
|
|
|
import {executeAggregationTestCase} from "jstests/libs/query/aggregation_pipeline_utils.js";
|
|
|
|
const testDB = db.getSiblingDB(jsTestName());
|
|
const coll = testDB.collection;
|
|
|
|
// Drop the test database.
|
|
assert.commandWorked(testDB.dropDatabase());
|
|
|
|
const someDate = new Date("2020-11-01T18:23:36Z");
|
|
const aggregationPipelineWithDateDiff = [
|
|
{
|
|
$project: {
|
|
_id: false,
|
|
date_diff: {
|
|
$dateDiff: {startDate: "$startDate", endDate: "$endDate", unit: "$unit", timezone: "$timeZone"},
|
|
},
|
|
},
|
|
},
|
|
];
|
|
const aggregationPipelineWithDateDiffAndStartOfWeek = [
|
|
{
|
|
$project: {
|
|
_id: false,
|
|
date_diff: {
|
|
$dateDiff: {
|
|
startDate: "$startDate",
|
|
endDate: "$endDate",
|
|
unit: "$unit",
|
|
timezone: "$timeZone",
|
|
startOfWeek: "$startOfWeek",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
];
|
|
const testCases = [
|
|
{
|
|
// Parameters are constants, timezone is not specified.
|
|
pipeline: [
|
|
{
|
|
$project: {
|
|
_id: true,
|
|
date_diff: {
|
|
$dateDiff: {
|
|
startDate: new Date("2020-11-01T18:23:36Z"),
|
|
endDate: new Date("2020-11-02T00:00:00Z"),
|
|
unit: "hour",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
],
|
|
inputDocuments: [{_id: 1}],
|
|
expectedResults: [{_id: 1, date_diff: NumberLong("6")}],
|
|
},
|
|
{
|
|
// Parameters are field paths.
|
|
pipeline: aggregationPipelineWithDateDiffAndStartOfWeek,
|
|
inputDocuments: [
|
|
{
|
|
startDate: new Date("2020-11-01T18:23:36Z"),
|
|
endDate: new Date("2020-11-02T00:00:00Z"),
|
|
unit: "hour",
|
|
timeZone: "America/New_York",
|
|
startOfWeek: "IGNORED", // Ignored when unit is not week.
|
|
},
|
|
],
|
|
expectedResults: [{date_diff: NumberLong("6")}],
|
|
},
|
|
{
|
|
// Parameters are field paths, 'timezone' is not specified.
|
|
pipeline: [
|
|
{
|
|
$project: {
|
|
_id: false,
|
|
date_diff: {$dateDiff: {startDate: "$startDate", endDate: "$endDate", unit: "$unit"}},
|
|
},
|
|
},
|
|
],
|
|
inputDocuments: [
|
|
{
|
|
startDate: new Date("2020-11-01T18:23:36Z"),
|
|
endDate: new Date("2020-11-02T00:00:00Z"),
|
|
unit: "hour",
|
|
},
|
|
],
|
|
expectedResults: [{date_diff: NumberLong("6")}],
|
|
},
|
|
{
|
|
// 'startDate' and 'endDate' are object ids.
|
|
pipeline: [
|
|
{
|
|
$project: {
|
|
_id: false,
|
|
date_diff: {
|
|
$dateDiff: {
|
|
startDate: "$_id",
|
|
endDate: "$_id",
|
|
unit: "millisecond",
|
|
timezone: "America/New_York",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
],
|
|
inputDocuments: [{}],
|
|
expectedResults: [{date_diff: NumberLong("0")}],
|
|
},
|
|
{
|
|
// 'startDate' and 'endDate' are timestamps.
|
|
pipeline: [
|
|
{
|
|
$project: {
|
|
_id: false,
|
|
date_diff: {$dateDiff: {startDate: "$ts", endDate: "$ts", unit: "millisecond"}},
|
|
},
|
|
},
|
|
],
|
|
inputDocuments: [{ts: new Timestamp()}],
|
|
expectedResults: [{date_diff: NumberLong("0")}],
|
|
},
|
|
{
|
|
// Invalid 'startDate' type.
|
|
pipeline: aggregationPipelineWithDateDiff,
|
|
inputDocuments: [{startDate: "string", endDate: someDate, unit: "hour", timeZone: "UTC"}],
|
|
expectedErrorCode: 5166307,
|
|
},
|
|
{
|
|
// Missing 'startDate' value in the document, invalid other fields.
|
|
pipeline: aggregationPipelineWithDateDiff,
|
|
inputDocuments: [{endDate: 1, unit: "century", timeZone: "INVALID"}],
|
|
expectedResults: [{date_diff: null}],
|
|
},
|
|
{
|
|
// Null 'startDate'.
|
|
pipeline: aggregationPipelineWithDateDiff,
|
|
inputDocuments: [{startDate: null, endDate: someDate, unit: "hour", timeZone: "UTC"}],
|
|
expectedResults: [{date_diff: null}],
|
|
},
|
|
{
|
|
// Invalid 'endDate' type.
|
|
pipeline: aggregationPipelineWithDateDiff,
|
|
inputDocuments: [{startDate: someDate, endDate: 1, unit: "hour", timeZone: "UTC"}],
|
|
expectedErrorCode: 5166307,
|
|
},
|
|
{
|
|
// Missing 'endDate' value in the document, invalid other fields.
|
|
pipeline: aggregationPipelineWithDateDiff,
|
|
inputDocuments: [{startDate: "", unit: "epoch", timeZone: "INVALID"}],
|
|
expectedResults: [{date_diff: null}],
|
|
},
|
|
{
|
|
// Null 'unit'.
|
|
pipeline: aggregationPipelineWithDateDiff,
|
|
inputDocuments: [{startDate: someDate, endDate: someDate, unit: null, timeZone: "UTC"}],
|
|
expectedResults: [{date_diff: null}],
|
|
},
|
|
{
|
|
// Missing 'unit' value in the document, invalid other fields.
|
|
pipeline: aggregationPipelineWithDateDiff,
|
|
inputDocuments: [{startDate: 1, endDate: 2, timeZone: "INVALID"}],
|
|
expectedResults: [{date_diff: null}],
|
|
},
|
|
{
|
|
// Invalid 'unit' type.
|
|
pipeline: aggregationPipelineWithDateDiff,
|
|
inputDocuments: [{startDate: someDate, endDate: someDate, unit: 5, timeZone: "UTC"}],
|
|
expectedErrorCode: 5439013,
|
|
},
|
|
{
|
|
// Invalid 'unit' value.
|
|
pipeline: aggregationPipelineWithDateDiff,
|
|
inputDocuments: [{startDate: someDate, endDate: someDate, unit: "decade", timeZone: "UTC"}],
|
|
expectedErrorCode: ErrorCodes.FailedToParse,
|
|
},
|
|
{
|
|
// Null 'timezone'.
|
|
pipeline: aggregationPipelineWithDateDiff,
|
|
inputDocuments: [{startDate: someDate, endDate: someDate, unit: "hour", timeZone: null}],
|
|
expectedResults: [{date_diff: null}],
|
|
},
|
|
{
|
|
// Missing 'timezone' value in the document, invalid other fields. Result could be a null
|
|
// answer or an error code depending whether pipeline is optimized.
|
|
pipeline: aggregationPipelineWithDateDiff,
|
|
inputDocuments: [{startDate: 1, endDate: 2, unit: "century"}],
|
|
expectedResults: [{date_diff: null}],
|
|
expectedErrorCode: ErrorCodes.FailedToParse,
|
|
},
|
|
{
|
|
// Invalid 'timezone' type.
|
|
pipeline: aggregationPipelineWithDateDiff,
|
|
inputDocuments: [{startDate: someDate, endDate: someDate, unit: "hour", timeZone: 1}],
|
|
expectedErrorCode: 40517,
|
|
},
|
|
{
|
|
// Invalid 'timezone' value.
|
|
pipeline: aggregationPipelineWithDateDiff,
|
|
inputDocuments: [{startDate: someDate, endDate: someDate, unit: "hour", timeZone: "America/Invalid"}],
|
|
expectedErrorCode: 40485,
|
|
},
|
|
{
|
|
// Specified 'startOfWeek'.
|
|
pipeline: aggregationPipelineWithDateDiffAndStartOfWeek,
|
|
inputDocuments: [
|
|
{
|
|
startDate: new Date("2021-01-24T18:23:36Z"), // Sunday.
|
|
endDate: new Date("2021-01-25T02:23:36Z"), // Monday.
|
|
unit: "week",
|
|
timeZone: "GMT",
|
|
startOfWeek: "MONDAY",
|
|
},
|
|
],
|
|
expectedResults: [{date_diff: NumberLong("1")}],
|
|
},
|
|
{
|
|
// Specified 'startOfWeek' and timezone.
|
|
pipeline: aggregationPipelineWithDateDiffAndStartOfWeek,
|
|
inputDocuments: [
|
|
{
|
|
startDate: new Date("2021-01-17T05:00:00Z"), // Sunday in New York.
|
|
endDate: new Date("2021-01-17T04:59:00Z"), // Saturday in New York.
|
|
unit: "week",
|
|
timeZone: "America/New_York",
|
|
startOfWeek: "sunday",
|
|
},
|
|
],
|
|
expectedResults: [{date_diff: NumberLong("-1")}],
|
|
},
|
|
{
|
|
// Unspecified 'startOfWeek' - defaults to Sunday.
|
|
pipeline: [
|
|
{
|
|
$project: {
|
|
_id: false,
|
|
date_diff: {$dateDiff: {startDate: "$startDate", endDate: "$endDate", unit: "week"}},
|
|
},
|
|
},
|
|
],
|
|
inputDocuments: [
|
|
{
|
|
startDate: new Date("2021-01-24T18:23:36Z"), // Sunday.
|
|
endDate: new Date("2021-01-25T02:23:36Z"), // Monday.
|
|
},
|
|
],
|
|
expectedResults: [{date_diff: NumberLong("0")}],
|
|
},
|
|
{
|
|
// Null 'startOfWeek'.
|
|
pipeline: aggregationPipelineWithDateDiffAndStartOfWeek,
|
|
inputDocuments: [{startDate: someDate, endDate: someDate, unit: "week", startOfWeek: null}],
|
|
expectedResults: [{date_diff: null}],
|
|
},
|
|
{
|
|
// Missing 'startOfWeek' value in the document, invalid other fields.
|
|
pipeline: aggregationPipelineWithDateDiffAndStartOfWeek,
|
|
inputDocuments: [{startDate: 1, endDate: 2, unit: "week", timeZone: 1}],
|
|
expectedResults: [{date_diff: null}],
|
|
},
|
|
{
|
|
// Invalid 'startOfWeek' type.
|
|
pipeline: aggregationPipelineWithDateDiffAndStartOfWeek,
|
|
inputDocuments: [{startDate: someDate, endDate: someDate, unit: "week", timeZone: "GMT", startOfWeek: 1}],
|
|
expectedErrorCode: 5439015,
|
|
},
|
|
{
|
|
// Invalid 'startOfWeek' type, unit is not the week.
|
|
pipeline: aggregationPipelineWithDateDiffAndStartOfWeek,
|
|
inputDocuments: [{startDate: someDate, endDate: someDate, unit: "hour", timeZone: "GMT", startOfWeek: 1}],
|
|
expectedResults: [{date_diff: NumberLong("0")}],
|
|
},
|
|
{
|
|
// Invalid 'startOfWeek' value.
|
|
pipeline: aggregationPipelineWithDateDiffAndStartOfWeek,
|
|
inputDocuments: [
|
|
{
|
|
startDate: someDate,
|
|
endDate: someDate,
|
|
unit: "week",
|
|
timeZone: "GMT",
|
|
startOfWeek: "FRIDIE",
|
|
},
|
|
],
|
|
expectedErrorCode: 5439016,
|
|
},
|
|
];
|
|
testCases.forEach((testCase) => executeAggregationTestCase(coll, testCase));
|