summaryrefslogtreecommitdiff
path: root/jstests
diff options
context:
space:
mode:
authorNick Zolnierz <nicholas.zolnierz@mongodb.com>2018-01-30 13:10:47 -0500
committerNick Zolnierz <nicholas.zolnierz@mongodb.com>2018-02-21 13:33:36 -0500
commit1e9e5f85d3d9ae42ea80a48b593be45306724831 (patch)
tree6ffaca9b84c1117fe6cf4b9e33e720463898b9db /jstests
parentf15200621c45cf27bc348eaa1e0573372fc6ff93 (diff)
downloadmongo-1e9e5f85d3d9ae42ea80a48b593be45306724831.tar.gz
SERVER-32736: Add "onError" and "onNull" options to $dateFromString
Diffstat (limited to 'jstests')
-rw-r--r--jstests/aggregation/expressions/date_from_string.js53
-rw-r--r--jstests/aggregation/expressions/date_from_string_on_error.js193
-rw-r--r--jstests/aggregation/expressions/date_from_string_on_null.js68
3 files changed, 293 insertions, 21 deletions
diff --git a/jstests/aggregation/expressions/date_from_string.js b/jstests/aggregation/expressions/date_from_string.js
index 9dfe4a355b4..e62b4f9f392 100644
--- a/jstests/aggregation/expressions/date_from_string.js
+++ b/jstests/aggregation/expressions/date_from_string.js
@@ -593,8 +593,10 @@ load("jstests/aggregation/extras/utils.js"); // For assertErrorCode and assertE
];
pipelines.forEach(function(pipeline) {
- assertErrMsgContains(
- coll, pipeline, 40545, "an incomplete date/time string has been found");
+ assertErrMsgContains(coll,
+ pipeline,
+ ErrorCodes.ConversionFailure,
+ "an incomplete date/time string has been found");
});
/* --------------------------------------------------------------------------------------- */
@@ -612,7 +614,8 @@ load("jstests/aggregation/extras/utils.js"); // For assertErrorCode and assertE
];
pipelines.forEach(function(pipeline) {
- assertErrMsgContains(coll, pipeline, 40553, "Error parsing date string");
+ assertErrMsgContains(
+ coll, pipeline, ErrorCodes.ConversionFailure, "Error parsing date string");
});
/* --------------------------------------------------------------------------------------- */
@@ -670,8 +673,10 @@ load("jstests/aggregation/extras/utils.js"); // For assertErrorCode and assertE
assertErrMsgContains(coll, pipeline, 40541, "Unrecognized argument");
pipeline = [{$project: {date: {$dateFromString: {dateString: 5}}}}];
- assertErrMsgContains(
- coll, pipeline, 40543, "$dateFromString requires that 'dateString' be a string");
+ assertErrMsgContains(coll,
+ pipeline,
+ ErrorCodes.ConversionFailure,
+ "$dateFromString requires that 'dateString' be a string");
/* --------------------------------------------------------------------------------------- */
/* Passing in time zone with date/time string. */
@@ -684,7 +689,7 @@ load("jstests/aggregation/extras/utils.js"); // For assertErrorCode and assertE
}
}
};
- assertErrorCode(coll, pipeline, 40554);
+ assertErrorCode(coll, pipeline, ErrorCodes.ConversionFailure);
pipeline = {
$project: {
@@ -694,7 +699,7 @@ load("jstests/aggregation/extras/utils.js"); // For assertErrorCode and assertE
}
}
};
- assertErrorCode(coll, pipeline, 40551);
+ assertErrorCode(coll, pipeline, ErrorCodes.ConversionFailure);
pipeline = {
$project: {
@@ -706,26 +711,26 @@ load("jstests/aggregation/extras/utils.js"); // For assertErrorCode and assertE
}
}
};
- assertErrorCode(coll, pipeline, 40553);
+ assertErrorCode(coll, pipeline, ErrorCodes.ConversionFailure);
pipeline = {
$project: {date: {$dateFromString: {dateString: "2017-07-12T22:23:55 Europe/Amsterdam"}}}
};
- assertErrorCode(coll, pipeline, 40553);
+ assertErrorCode(coll, pipeline, ErrorCodes.ConversionFailure);
/* --------------------------------------------------------------------------------------- */
/* Error cases for $dateFromString with format specifier string. */
// Test umatched format specifier string.
pipeline = [{$project: {date: {$dateFromString: {dateString: "2018-01", format: "%Y-%m-%d"}}}}];
- assertErrMsgContains(coll, pipeline, 40553, "Data missing");
+ assertErrMsgContains(coll, pipeline, ErrorCodes.ConversionFailure, "Data missing");
pipeline = [{$project: {date: {$dateFromString: {dateString: "2018-01", format: "%Y"}}}}];
- assertErrMsgContains(coll, pipeline, 40553, "Trailing data");
+ assertErrMsgContains(coll, pipeline, ErrorCodes.ConversionFailure, "Trailing data");
// Test missing specifier prefix '%'.
pipeline = [{$project: {date: {$dateFromString: {dateString: "1992-26-04", format: "Y-d-m"}}}}];
- assertErrMsgContains(coll, pipeline, 40553, "Format literal not found");
+ assertErrMsgContains(coll, pipeline, ErrorCodes.ConversionFailure, "Format literal not found");
pipeline = [{$project: {date: {$dateFromString: {dateString: "1992", format: "%n"}}}}];
assertErrMsgContains(coll, pipeline, 18536, "Invalid format character");
@@ -741,7 +746,7 @@ load("jstests/aggregation/extras/utils.js"); // For assertErrorCode and assertE
assertErrMsgContains(
coll,
pipeline,
- 40554,
+ ErrorCodes.ConversionFailure,
"you cannot pass in a date/time string with GMT offset together with a timezone argument");
pipeline = [{$project: {date: {$dateFromString: {dateString: "4/26/1992", format: 5}}}}];
@@ -754,31 +759,37 @@ load("jstests/aggregation/extras/utils.js"); // For assertErrorCode and assertE
pipeline =
[{$project: {date: {$dateFromString: {dateString: "ISO Day 6", format: "ISO Day %u"}}}}];
- assertErrMsgContains(coll, pipeline, 40553, "The parsed date was invalid");
+ assertErrMsgContains(
+ coll, pipeline, ErrorCodes.ConversionFailure, "The parsed date was invalid");
pipeline =
[{$project: {date: {$dateFromString: {dateString: "ISO Week 52", format: "ISO Week %V"}}}}];
- assertErrMsgContains(coll, pipeline, 40553, "The parsed date was invalid");
+ assertErrMsgContains(
+ coll, pipeline, ErrorCodes.ConversionFailure, "The parsed date was invalid");
pipeline = [{
$project: {
date: {$dateFromString: {dateString: "ISO Week 1, 2018", format: "ISO Week %V, %Y"}}
}
}];
- assertErrMsgContains(
- coll, pipeline, 40553, "Mixing of ISO dates with natural dates is not allowed");
+ assertErrMsgContains(coll,
+ pipeline,
+ ErrorCodes.ConversionFailure,
+ "Mixing of ISO dates with natural dates is not allowed");
pipeline =
[{$project: {date: {$dateFromString: {dateString: "12/31/2018", format: "%m/%d/%G"}}}}];
- assertErrMsgContains(
- coll, pipeline, 40553, "Mixing of ISO dates with natural dates is not allowed");
+ assertErrMsgContains(coll,
+ pipeline,
+ ErrorCodes.ConversionFailure,
+ "Mixing of ISO dates with natural dates is not allowed");
// Test embedded null bytes in the 'dateString' and 'format' fields.
pipeline =
[{$project: {date: {$dateFromString: {dateString: "12/31\0/2018", format: "%m/%d/%Y"}}}}];
- assertErrMsgContains(coll, pipeline, 40553, "Data missing");
+ assertErrMsgContains(coll, pipeline, ErrorCodes.ConversionFailure, "Data missing");
pipeline =
[{$project: {date: {$dateFromString: {dateString: "12/31/2018", format: "%m/%d\0/%Y"}}}}];
- assertErrMsgContains(coll, pipeline, 40553, "Trailing data");
+ assertErrMsgContains(coll, pipeline, ErrorCodes.ConversionFailure, "Trailing data");
})();
diff --git a/jstests/aggregation/expressions/date_from_string_on_error.js b/jstests/aggregation/expressions/date_from_string_on_error.js
new file mode 100644
index 00000000000..ba0ce0fa573
--- /dev/null
+++ b/jstests/aggregation/expressions/date_from_string_on_error.js
@@ -0,0 +1,193 @@
+/**
+ * Tests for the $dateFromString expression with the optional 'onError' parameter.
+ */
+(function() {
+ "use strict";
+
+ load("jstests/aggregation/extras/utils.js"); // For assertErrMsgContains.
+
+ const onErrorValue = ISODate("2017-07-04T11:56:02Z");
+ const coll = db.date_from_string_on_error;
+ coll.drop();
+
+ assert.writeOK(coll.insert({_id: 0}));
+
+ // Test that the 'onError' value is returned when 'dateString' is not a valid date/time.
+ for (let inputDate of["July 4th",
+ "12:50:53",
+ "2017",
+ "60.Monday1770/06:59",
+ "Not even close",
+ "July 4th, 10000"]) {
+ assert.eq(
+ [{_id: 0, date: onErrorValue}],
+ coll.aggregate({
+ $project:
+ {date: {$dateFromString: {dateString: inputDate, onError: onErrorValue}}}
+ })
+ .toArray());
+ }
+
+ // Test that the 'onError' value is returned when 'dateString' is not a string.
+ for (let inputDate of[5, {year: 2018, month: 2, day: 5}, ["2018-02-05"]]) {
+ assert.eq(
+ [{_id: 0, date: onErrorValue}],
+ coll.aggregate({
+ $project:
+ {date: {$dateFromString: {dateString: inputDate, onError: onErrorValue}}}
+ })
+ .toArray());
+ }
+
+ // Test that the 'onError' value is ignored when 'dateString' is nullish.
+ for (let inputDate of[null, undefined, "$missing"]) {
+ assert.eq(
+ [{_id: 0, date: null}],
+ coll.aggregate({
+ $project:
+ {date: {$dateFromString: {dateString: inputDate, onError: onErrorValue}}}
+ })
+ .toArray());
+ }
+
+ // Test that the 'onError' value is returned for unmatched format strings.
+ for (let inputFormat of["%Y", "%Y-%m-%dT%H", "Y-m-d"]) {
+ assert.eq([{_id: 0, date: onErrorValue}],
+ coll.aggregate({
+ $project: {
+ date: {
+ $dateFromString: {
+ dateString: "2018-02-06",
+ format: inputFormat,
+ onError: onErrorValue
+ }
+ }
+ }
+ })
+ .toArray());
+ }
+
+ // Test that null is returned when the 'timezone' or 'format' is nullish, regardless of the
+ // 'onError' value.
+ for (let nullishValue of[null, undefined, "$missing"]) {
+ assert.eq([{_id: 0, date: null}],
+ coll.aggregate({
+ $project: {
+ date: {
+ $dateFromString: {
+ dateString: "2018-02-06T11:56:02Z",
+ format: nullishValue,
+ onError: onErrorValue
+ }
+ }
+ }
+ })
+ .toArray());
+ assert.eq([{_id: 0, date: null}],
+ coll.aggregate({
+ $project: {
+ date: {
+ $dateFromString: {
+ dateString: "2018-02-06T11:56:02Z",
+ timezone: nullishValue,
+ onError: onErrorValue
+ }
+ }
+ }
+ })
+ .toArray());
+ }
+
+ // Test that onError is returned when the input is not a string and other parameters are
+ // nullish.
+ assert.eq(
+ [{_id: 0, date: onErrorValue}],
+ coll.aggregate({
+ $project: {
+ date: {$dateFromString: {dateString: 5, format: null, onError: onErrorValue}}
+ }
+ })
+ .toArray());
+ assert.eq([{_id: 0, date: onErrorValue}],
+ coll.aggregate({
+ $project: {
+ date: {
+ $dateFromString:
+ {dateString: 5, timezone: "$missing", onError: onErrorValue}
+ }
+ }
+ })
+ .toArray());
+
+ // Test that onError is ignored when the input is an invalid string and other parameters are
+ // nullish.
+ assert.eq([{_id: 0, date: null}],
+ coll.aggregate({
+ $project: {
+ date: {
+ $dateFromString: {
+ dateString: "Invalid date string",
+ format: null,
+ onError: onErrorValue
+ }
+ }
+ }
+ })
+ .toArray());
+ assert.eq([{_id: 0, date: null}],
+ coll.aggregate({
+ $project: {
+ date: {
+ $dateFromString: {
+ dateString: "Invalid date string",
+ timezone: "$missing",
+ onError: onErrorValue
+ }
+ }
+ }
+ })
+ .toArray());
+
+ // Test that 'onError' can be any type, not just an ISODate.
+ for (let onError of[{}, 5, "Not a date", null, undefined]) {
+ assert.eq(
+ [{_id: 0, date: onError}],
+ coll.aggregate({
+ $project: {date: {$dateFromString: {dateString: "invalid", onError: onError}}}
+ })
+ .toArray());
+ }
+ // Test that a missing 'onError' value results in no output field when used within a $project
+ // stage.
+ assert.eq(
+ [{_id: 0}],
+ coll.aggregate(
+ {$project: {date: {$dateFromString: {dateString: "invalid", onError: "$missing"}}}})
+ .toArray());
+
+ // Test that 'onError' is ignored when the 'format' is invalid.
+ assertErrMsgContains(
+ coll,
+ [{
+ $project: {
+ date: {
+ $dateFromString: {dateString: "4/26/1992", format: 5, onError: onErrorValue}
+ }
+ }
+ }],
+ 40684,
+ "$dateFromString requires that 'format' be a string");
+
+ assertErrMsgContains(
+ coll,
+ [{
+ $project: {
+ date: {
+ $dateFromString:
+ {dateString: "4/26/1992", format: "%n", onError: onErrorValue}
+ }
+ }
+ }],
+ 18536,
+ "Invalid format character '%n' in format string");
+})();
diff --git a/jstests/aggregation/expressions/date_from_string_on_null.js b/jstests/aggregation/expressions/date_from_string_on_null.js
new file mode 100644
index 00000000000..12b7d673984
--- /dev/null
+++ b/jstests/aggregation/expressions/date_from_string_on_null.js
@@ -0,0 +1,68 @@
+/**
+ * Tests for the $dateFromString expression with the optional 'onNull' parameter.
+ */
+(function() {
+ "use strict";
+
+ const onNullValue = ISODate("2017-07-04T11:56:02Z");
+ const coll = db.date_from_string_on_null;
+ coll.drop();
+
+ assert.writeOK(coll.insert({_id: 0}));
+
+ // Test that the 'onNull' value is returned when the 'dateString' is nullish.
+ for (let inputDate of[null, undefined, "$missing"]) {
+ assert.eq(
+ [{_id: 0, date: onNullValue}],
+ coll.aggregate({
+ $project:
+ {date: {$dateFromString: {dateString: inputDate, onNull: onNullValue}}}
+ })
+ .toArray());
+ }
+
+ // Test that null is returned when the 'timezone' or 'format' is nullish, regardless of the
+ // 'onNull' value.
+ for (let nullishValue of[null, undefined, "$missing"]) {
+ assert.eq([{_id: 0, date: null}],
+ coll.aggregate({
+ $project: {
+ date: {
+ $dateFromString: {
+ dateString: "2018-02-06T11:56:02Z",
+ format: nullishValue,
+ onNull: onNullValue
+ }
+ }
+ }
+ })
+ .toArray());
+ assert.eq([{_id: 0, date: null}],
+ coll.aggregate({
+ $project: {
+ date: {
+ $dateFromString: {
+ dateString: "2018-02-06T11:56:02Z",
+ timezone: nullishValue,
+ onNull: onNullValue
+ }
+ }
+ }
+ })
+ .toArray());
+ }
+
+ // Test that 'onNull' can be any type, not just an ISODate.
+ for (let onNull of[{}, 5, "Not a date", null, undefined]) {
+ assert.eq(
+ [{_id: 0, date: onNull}],
+ coll.aggregate(
+ {$project: {date: {$dateFromString: {dateString: "$missing", onNull: onNull}}}})
+ .toArray());
+ }
+ assert.eq(
+ [{_id: 0}],
+ coll.aggregate(
+ {$project: {date: {$dateFromString: {dateString: "$missing", onNull: "$missing"}}}})
+ .toArray());
+})();