summaryrefslogtreecommitdiffstats
path: root/comm/mailnews/mime/jsmime/test/unit/mock_date.js
diff options
context:
space:
mode:
Diffstat (limited to 'comm/mailnews/mime/jsmime/test/unit/mock_date.js')
-rw-r--r--comm/mailnews/mime/jsmime/test/unit/mock_date.js86
1 files changed, 86 insertions, 0 deletions
diff --git a/comm/mailnews/mime/jsmime/test/unit/mock_date.js b/comm/mailnews/mime/jsmime/test/unit/mock_date.js
new file mode 100644
index 0000000000..87a6454968
--- /dev/null
+++ b/comm/mailnews/mime/jsmime/test/unit/mock_date.js
@@ -0,0 +1,86 @@
+"use strict";
+
+/* globals define */
+
+define(function (require) {
+ /**
+ * A class which appears to act like the Date class with customizable timezone
+ * offsets.
+ *
+ * @param {string} iso8601String An ISO-8601 date/time string including a
+ * timezone offset.
+ */
+ function MockDate(iso8601String) {
+ // Find the timezone offset (Z or ±hhmm) from the ISO-8601 date string, and
+ // then convert that into a number of minutes.
+ let parse = /\d{4}-\d\d-\d\dT\d\d:\d\d:\d\d(Z|[+-]\d{4})/.exec(
+ iso8601String
+ );
+ let tzOffsetStr = parse[1];
+ if (tzOffsetStr == "Z") {
+ this._tzOffset = 0;
+ } else {
+ this._tzOffset =
+ parseInt(tzOffsetStr.substring(1, 3)) * 60 +
+ parseInt(tzOffsetStr.substring(3));
+ if (tzOffsetStr[0] == "-") {
+ this._tzOffset = -this._tzOffset;
+ }
+ }
+
+ // To store the offset, we store both the real time in _realDate and a time
+ // that is offset by the tzOffset in _shiftedDate. Only the getUTC* methods
+ // should be used on these properties, to avoid problems caused by daylight
+ // savings time or other timezone effects. This shifting is always legal
+ // because ES6 is specified to assume that leap seconds do not exist, so there
+ // are always 60 seconds in a minute.
+ this._realDate = new Date(iso8601String);
+ this._shiftedDate = new Date(
+ this._realDate.getTime() + this._tzOffset * 60 * 1000
+ );
+ }
+ MockDate.prototype = {
+ getTimezoneOffset() {
+ // This property is reversed from how it's defined in ISO 8601, i.e.,
+ // UTC +0100 needs to return -60.
+ return -this._tzOffset;
+ },
+ getTime() {
+ return this._realDate.getTime();
+ },
+ };
+
+ // Provide an implementation of Date methods that will be need in JSMime. For
+ // the time being, we only need .get* methods.
+ for (let name of Object.getOwnPropertyNames(Date.prototype)) {
+ // Only copy getters, not setters or x.toString.
+ if (!name.startsWith("get")) {
+ continue;
+ }
+ // No redefining any other names on MockDate.
+ if (MockDate.prototype.hasOwnProperty(name)) {
+ continue;
+ }
+
+ if (name.includes("UTC")) {
+ // 'name' is already supposed to be freshly bound per newest ES6 drafts, but
+ // current ES6 implementations reuse the bindings. Until implementations
+ // catch up, use a new let to bind it freshly.
+ let boundName = name;
+ Object.defineProperty(MockDate.prototype, name, {
+ value(...aArgs) {
+ return Date.prototype[boundName].call(this._realDate, aArgs);
+ },
+ });
+ } else {
+ let newName = "getUTC" + name.substr(3);
+ Object.defineProperty(MockDate.prototype, name, {
+ value(...aArgs) {
+ return Date.prototype[newName].call(this._shiftedDate, aArgs);
+ },
+ });
+ }
+ }
+
+ return MockDate;
+});