aboutsummaryrefslogtreecommitdiffstats
path: root/test
diff options
context:
space:
mode:
authorIgor Minar2010-10-25 22:05:38 -0700
committerMisko Hevery2010-10-26 13:47:50 -0700
commit4c61fc01f9c251c39f540316cc82332bc8b3f370 (patch)
treecfebbf7045b02dc15f520cd970795e947f5ab88f /test
parent4fdab3765919e9fffc6d2f84e74754b1012997be (diff)
downloadangular.js-4c61fc01f9c251c39f540316cc82332bc8b3f370.tar.bz2
Add TzDate to angular-mocks.js
TzDate is a Date-like type that is independent from the timezone settings of the machine on which TzDate instances are created. This property makes it ideal for testing code that deals with timezones in a manner that makes the code portable between timezones. Closes #81
Diffstat (limited to 'test')
-rw-r--r--test/FiltersSpec.js28
-rw-r--r--test/angular-mocks.js102
2 files changed, 113 insertions, 17 deletions
diff --git a/test/FiltersSpec.js b/test/FiltersSpec.js
index 6bbc09ae..4dd108ac 100644
--- a/test/FiltersSpec.js
+++ b/test/FiltersSpec.js
@@ -87,18 +87,11 @@ describe('filter', function(){
});
describe('date', function(){
- var morning = angular.String.toDate('2010-09-03T23:05:08Z');
- var midnight = angular.String.toDate('2010-09-03T23:05:08Z');
- var noon = angular.String.toDate('2010-09-03T23:05:08Z');
- morning.setHours(7);
- noon.setHours(12);
- midnight.setHours(0);
-
- //butt-ugly hack: force the date to be 2pm PDT for locale testing
- morning.getTimezoneOffset =
- noon.getTimezoneOffset =
- midnight.getTimezoneOffset =
- function() {return 7 * 60;};
+
+ var morning = new TzDate(+5, '2010-09-03T12:05:08Z'); //7am
+ var noon = new TzDate(+5, '2010-09-03T17:05:08Z'); //12pm
+ var midnight = new TzDate(+5, '2010-09-03T05:05:08Z'); //12am
+
it('should ignore falsy inputs', function() {
expect(filter.date(null)).toEqual(null);
@@ -116,16 +109,17 @@ describe('filter', function(){
});
it('should accept format', function() {
+ expect(filter.date(morning, "yy-MM-dd HH:mm:ss")).
+ toEqual('10-09-03 07:05:08');
+
expect(filter.date(midnight, "yyyy-M-d h=H:m:saZ")).
- toEqual('2010-9-3 12=0:5:8am0700');
+ toEqual('2010-9-3 12=0:5:8am0500');
expect(filter.date(midnight, "yyyy-MM-dd hh=HH:mm:ssaZ")).
- toEqual('2010-09-03 12=00:05:08am0700');
+ toEqual('2010-09-03 12=00:05:08am0500');
expect(filter.date(noon, "yyyy-MM-dd hh=HH:mm:ssaZ")).
- toEqual('2010-09-03 12=12:05:08pm0700');
-
+ toEqual('2010-09-03 12=12:05:08pm0500');
});
});
});
-
diff --git a/test/angular-mocks.js b/test/angular-mocks.js
index efe5b5b3..a090f0e8 100644
--- a/test/angular-mocks.js
+++ b/test/angular-mocks.js
@@ -162,3 +162,105 @@ MockBrowser.prototype = {
angular.service('$browser', function(){
return new MockBrowser();
});
+
+
+/**
+ * Mock of the Date type which has its timezone specified via constroctor arg.
+ *
+ * The main purpose is to create Date-like instances with timezone fixed to the specified timezone
+ * offset, so that we can test code that depends on local timezone settings without dependency on
+ * the time zone settings of the machine where the code is running.
+ *
+ * @param {number} offset Offset of the *desired* timezone in hours (fractions will be honored)
+ * @param {(number|string)} timestamp Timestamp representing the desired time in *UTC*
+ *
+ * @example
+ * var newYearInBratislava = new TzDate(-1, '2009-12-31T23:00:00Z');
+ * newYearInBratislava.getTimezoneOffset() => -60;
+ * newYearInBratislava.getFullYear() => 2010;
+ * newYearInBratislava.getMonth() => 0;
+ * newYearInBratislava.getDate() => 1;
+ * newYearInBratislava.getHours() => 0;
+ * newYearInBratislava.getMinutes() => 0;
+ *
+ *
+ * !!!! WARNING !!!!!
+ * This is not a complete Date object so only methods that were implemented can be called safely.
+ * To make matters worse, TzDate instances inherit stuff from Date via a prototype.
+ *
+ * We do our best to intercept calls to "unimplemented" methods, but since the list of methods is
+ * incomplete we might be missing some non-standard methods. This can result in errors like:
+ * "Date.prototype.foo called on incompatible Object".
+ */
+function TzDate(offset, timestamp) {
+ if (angular.isString(timestamp)) {
+ var tsStr = timestamp;
+ timestamp = new Date(timestamp).getTime();
+ if (isNaN(timestamp))
+ throw {
+ name: "Illegal Argument",
+ message: "Arg '" + tsStr + "' passed into TzDate constructor is not a valid date string"
+ };
+ }
+
+ var localOffset = new Date(timestamp).getTimezoneOffset();
+ this.offsetDiff = localOffset*60*1000 - offset*1000*60*60;
+ this.date = new Date(timestamp + this.offsetDiff);
+
+ this.getTime = function() {
+ return this.date.getTime() - this.offsetDiff;
+ };
+
+ this.toLocaleDateString = function() {
+ return this.date.toLocaleDateString();
+ };
+
+ this.getFullYear = function() {
+ return this.date.getFullYear();
+ };
+
+ this.getMonth = function() {
+ return this.date.getMonth();
+ };
+
+ this.getDate = function() {
+ return this.date.getDate();
+ };
+
+ this.getHours = function() {
+ return this.date.getHours();
+ };
+
+ this.getMinutes = function() {
+ return this.date.getMinutes();
+ };
+
+ this.getSeconds = function() {
+ return this.date.getSeconds();
+ };
+
+ this.getTimezoneOffset = function() {
+ return offset * 60;
+ };
+
+ //hide all methods not implemented in this mock that the Date prototype exposes
+ var unimplementedMethods = ['getDay', 'getMilliseconds', 'getTime', 'getUTCDate', 'getUTCDay',
+ 'getUTCFullYear', 'getUTCHours', 'getUTCMilliseconds', 'getUTCMinutes', 'getUTCMonth',
+ 'getUTCSeconds', 'getYear', 'setDate', 'setFullYear', 'setHours', 'setMilliseconds',
+ 'setMinutes', 'setMonth', 'setSeconds', 'setTime', 'setUTCDate', 'setUTCFullYear',
+ 'setUTCHours', 'setUTCMilliseconds', 'setUTCMinutes', 'setUTCMonth', 'setUTCSeconds',
+ 'setYear', 'toDateString', 'toJSON', 'toGMTString', 'toLocaleFormat', 'toLocaleString',
+ 'toLocaleTimeString', 'toSource', 'toString', 'toTimeString', 'toUTCString', 'valueOf'];
+
+ angular.foreach(unimplementedMethods, function(methodName) {
+ this[methodName] = function() {
+ throw {
+ name: "MethodNotImplemented",
+ message: "Method '" + methodName + "' is not implemented in the TzDate mock"
+ };
+ };
+ });
+}
+
+//make "tzDateInstance instanceof Date" return true
+TzDate.prototype = Date.prototype;