// SERVER-11118 Tests for $dateToString load('jstests/aggregation/extras/utils.js'); db = db.getSiblingDB("aggdb"); // Used to verify expected output format function testFormat(date, formatStr, expectedStr) { db.dates.drop(); db.dates.insert({date: date}); var res = db.dates.aggregate([{$project: { _id: 0, formatted: { $dateToString: { format: formatStr, date: "$date" } } }}]).toArray(); assert.eq(res[0].formatted, expectedStr); } // Used to verify that server recognizes bad formats function testFormatError(formatObj, errCode) { db.dates.drop(); db.dates.insert({tm: ISODate()}); assertErrorCode(db.dates, {$project: { _id: 0, formatted: { $dateToString: formatObj }}}, errCode); } // Used to verify that only date values are accepted for date parameter function testDateValueError(dateVal, errCode) { db.dates.drop(); db.dates.insert({date: dateVal}); assertErrorCode(db.dates, { $project: { formatted: { $dateToString : { format: "%Y", date: "$date" }} } }, errCode); } var now = ISODate(); // Use all modifiers we can test with js provided function testFormat(now, "%%-%Y-%m-%d-%H-%M-%S-%L", [ "%", now.getUTCFullYear().zeroPad(4), (now.getUTCMonth() + 1).zeroPad(2), now.getUTCDate().zeroPad(2), now.getUTCHours().zeroPad(2), now.getUTCMinutes().zeroPad(2), now.getUTCSeconds().zeroPad(2), now.getUTCMilliseconds().zeroPad(3) ].join("-")); // Padding tests var padme = ISODate("2001-02-03T04:05:06.007Z"); testFormat(padme, "%%", "%"); testFormat(padme, "%Y", padme.getUTCFullYear().zeroPad(4)); testFormat(padme, "%m", (padme.getUTCMonth() + 1).zeroPad(2)); testFormat(padme, "%d", padme.getUTCDate().zeroPad(2)); testFormat(padme, "%H", padme.getUTCHours().zeroPad(2)); testFormat(padme, "%M", padme.getUTCMinutes().zeroPad(2)); testFormat(padme, "%S", padme.getUTCSeconds().zeroPad(2)); testFormat(padme, "%L", padme.getUTCMilliseconds().zeroPad(3)); // no space and multiple characters between modifiers testFormat(now, "%d%d***%d***%d**%d*%d", [ now.getUTCDate().zeroPad(2), now.getUTCDate().zeroPad(2), "***", now.getUTCDate().zeroPad(2), "***", now.getUTCDate().zeroPad(2), "**", now.getUTCDate().zeroPad(2), "*", now.getUTCDate().zeroPad(2) ].join("")); // JS doesn't have equivalents of these format specifiers testFormat(ISODate('1999-01-02 03:04:05.006Z'), "%U-%w-%j", "00-7-002"); // Missing date testFormatError({format: "%Y"}, 18628); // Missing format testFormatError({date: "$date"}, 18627); // Extra field testFormatError({format: "%Y", date: "$date", extra: "whyamIhere"}, 18534); // Not an object testFormatError(["%Y", "$date"], 18629); // Use invalid modifier at middle of string testFormatError({format:"%Y-%q", date: "$date"}, 18536); // Odd number of percent signs at end testFormatError({format: "%U-%w-%j-%%%", date:"$date"}, 18535); // Odd number of percent signs at middle // will get interpreted as an invalid modifier since it will try to use '%A' testFormatError({format: "AAAAA%%%AAAAAA", date:"$date"}, 18536); // Format parameter not a string testFormatError({format: {iamalion: "roar"}, date:"$date"}, 18533); /// /// Additional Tests /// // Test document var date = ISODate("1999-08-29"); testFormat(date, "%%d", "%d"); //A very long string of "%"s var longstr = Array(1000).join("%%"); var halfstr = Array(1000).join("%"); testFormat(date, longstr, halfstr); // Using subexpressions as format strings (eg "format: '$b'") testFormat(date, "$b", "$b"); // Dates as null (should return a null) testFormat(null, "%Y", null); /// /// Using non-date fields as date parameter *should fail* /// // Array testDateValueError([], 16006); testDateValueError([1, 2, 3], 16006); // Sub-object testDateValueError({}, 16006); testDateValueError({a: 1}, 16006); // String testDateValueError("blahblahblah", 16006); // Integer testDateValueError(1234, 16006); /// /// Using non-string fields as format strings /// // Array testFormatError({format: [], date: "$date"}, 18533); testFormatError({format: [1, 2, 3], date: "$date"}, 18533); // Integer testFormatError({format: 1, date: "$date"}, 18533); // Date testFormatError({format: ISODate(), date: "$date"}, 18533);