Skip to content
This repository was archived by the owner on Feb 26, 2024. It is now read-only.

Commit 0eaed3f

Browse files
committed
fix(test): fix #1069, FakeDate should handle constructor parameter
1 parent a86bddb commit 0eaed3f

File tree

4 files changed

+200
-25
lines changed

4 files changed

+200
-25
lines changed

lib/jasmine/jasmine.ts

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -67,10 +67,14 @@
6767
return originalJasmineFn.apply(this, arguments);
6868
};
6969
});
70-
if (enableClockPatch) {
71-
const originalClockFn: Function = ((jasmine as any)[symbol('clock')] = jasmine['clock']);
72-
(jasmine as any)['clock'] = function() {
73-
const clock = originalClockFn.apply(this, arguments);
70+
71+
// need to patch jasmine.clock().mockDate and jasmine.clock().tick() so
72+
// they can work properly in FakeAsyncTest
73+
const originalClockFn: Function = ((jasmine as any)[symbol('clock')] = jasmine['clock']);
74+
(jasmine as any)['clock'] = function() {
75+
const clock = originalClockFn.apply(this, arguments);
76+
if (!clock[symbol('patched')]) {
77+
clock[symbol('patched')] = symbol('patched');
7478
const originalTick = (clock[symbol('tick')] = clock.tick);
7579
clock.tick = function() {
7680
const fakeAsyncZoneSpec = Zone.current.get('FakeAsyncTestZoneSpec');
@@ -91,20 +95,23 @@
9195
}
9296
return originalMockDate.apply(this, arguments);
9397
};
98+
// for auto go into fakeAsync feature, we need the flag to enable it
9499
['install', 'uninstall'].forEach(methodName => {
95100
const originalClockFn: Function = (clock[symbol(methodName)] = clock[methodName]);
96101
clock[methodName] = function() {
97102
const FakeAsyncTestZoneSpec = (Zone as any)['FakeAsyncTestZoneSpec'];
98103
if (FakeAsyncTestZoneSpec) {
99-
(jasmine as any)[symbol('clockInstalled')] = 'install' === methodName;
100-
return;
104+
if (enableClockPatch) {
105+
(jasmine as any)[symbol('clockInstalled')] = 'install' === methodName;
106+
return;
107+
}
101108
}
102109
return originalClockFn.apply(this, arguments);
103110
};
104111
});
105-
return clock;
106-
};
107-
}
112+
}
113+
return clock;
114+
};
108115

109116
/**
110117
* Gets a function wrapping the body of a Jasmine `describe` block to execute in a

lib/zone-spec/fake-async-test.ts

Lines changed: 35 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -32,13 +32,14 @@
3232
const OriginalDate = global.Date;
3333
class FakeDate {
3434
constructor() {
35-
const d = new OriginalDate();
36-
d.setTime(global.Date.now());
37-
return d;
38-
}
39-
40-
static UTC() {
41-
return OriginalDate.UTC();
35+
if (arguments.length === 0) {
36+
const d = new OriginalDate();
37+
d.setTime(FakeDate.now());
38+
return d;
39+
} else {
40+
const args = Array.prototype.slice.call(arguments);
41+
return new OriginalDate(...args);
42+
}
4243
}
4344

4445
static now() {
@@ -48,12 +49,19 @@
4849
}
4950
return OriginalDate.now.apply(this, arguments);
5051
}
51-
52-
static parse() {
53-
return OriginalDate.parse();
54-
}
5552
}
5653

54+
(FakeDate as any).UTC = OriginalDate.UTC;
55+
(FakeDate as any).parse = OriginalDate.parse;
56+
57+
// keep a reference for zone patched timer function
58+
const timers = {
59+
setTimeout: global.setTimeout,
60+
setInterval: global.setInterval,
61+
clearTimeout: global.clearTimeout,
62+
clearInterval: global.clearInterval
63+
};
64+
5765
class Scheduler {
5866
// Next scheduler id.
5967
public nextId: number = 1;
@@ -341,6 +349,11 @@
341349
}
342350
global['Date'] = FakeDate;
343351
FakeDate.prototype = OriginalDate.prototype;
352+
353+
// try check and reset timers
354+
// because jasmine.clock().install() may
355+
// have replaced the global timer
356+
FakeAsyncTestZoneSpec.checkTimerPatch();
344357
}
345358

346359
static resetDate() {
@@ -349,6 +362,17 @@
349362
}
350363
}
351364

365+
static checkTimerPatch() {
366+
if (global.setTimeout !== timers.setTimeout) {
367+
global.setTimeout = timers.setTimeout;
368+
global.clearTimeout = timers.clearTimeout;
369+
}
370+
if (global.setInterval !== timers.setInterval) {
371+
global.setInterval = timers.setInterval;
372+
global.clearInterval = timers.clearInterval;
373+
}
374+
}
375+
352376
lockDatePatch() {
353377
this.patchDateLocked = true;
354378
FakeAsyncTestZoneSpec.patchDate();

test/test-env-setup-mocha.ts

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,11 @@ declare const global: any;
8181
throw new Error(`Expected ${expected} to be greater than ${actual}`);
8282
}
8383
},
84+
toBeLessThan: function(actual: number) {
85+
if (expected >= actual) {
86+
throw new Error(`Expected ${expected} to be lesser than ${actual}`);
87+
}
88+
},
8489
toBeDefined: function() {
8590
if (!expected) {
8691
throw new Error(`Expected ${expected} to be defined`);
@@ -159,7 +164,11 @@ declare const global: any;
159164
if (expected > actual) {
160165
throw new Error(`Expected ${expected} not to be greater than ${actual}`);
161166
}
162-
167+
},
168+
toBeLessThan: function(actual: number) {
169+
if (expected < actual) {
170+
throw new Error(`Expected ${expected} not to be lesser than ${actual}`);
171+
}
163172
},
164173
toHaveBeenCalledWith: function(params: any[]) {
165174
if (!eq(expected.callArgs, params)) {

test/zone-spec/fake-async-test.spec.ts

Lines changed: 139 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -913,17 +913,45 @@ describe('FakeAsyncTestZoneSpec', () => {
913913
expect(d instanceof Date).toBe(true);
914914
});
915915
});
916+
917+
it('should new Date with parameter correctly', () => {
918+
fakeAsyncTestZone.run(() => {
919+
const d: Date = new Date(0);
920+
expect(d.getFullYear()).toBeLessThan(1971);
921+
const d1: Date = new Date('December 17, 1995 03:24:00');
922+
expect(d1.getFullYear()).toEqual(1995);
923+
const d2: Date = new Date(1995, 11, 17, 3, 24, 0);
924+
expect(d2.getFullYear()).toEqual(1995);
925+
});
926+
});
927+
928+
it('should get Date.UTC() correctly', () => {
929+
fakeAsyncTestZone.run(() => {
930+
const utcDate = new Date(Date.UTC(96, 11, 1, 0, 0, 0));
931+
expect(utcDate.getFullYear()).toBe(1996);
932+
});
933+
});
934+
935+
it('should call Date.parse() correctly', () => {
936+
fakeAsyncTestZone.run(() => {
937+
const unixTimeZero = Date.parse('01 Jan 1970 00:00:00 GMT');
938+
expect(unixTimeZero).toBe(0);
939+
});
940+
});
941+
916942
});
917943

918944
describe(
919-
'fakeAsyncTest should work without jasmine.clock',
945+
'fakeAsyncTest should work without patch jasmine.clock',
920946
ifEnvSupports(
921947
() => {
922948
return !supportClock() && supportNode();
923949
},
924950
() => {
925951
const fakeAsync = (Zone as any)[Zone.__symbol__('fakeAsyncTest')].fakeAsync;
952+
let spy: any;
926953
beforeEach(() => {
954+
spy = jasmine.createSpy('timer');
927955
jasmine.clock().install();
928956
});
929957

@@ -932,11 +960,43 @@ describe('FakeAsyncTestZoneSpec', () => {
932960
});
933961

934962
it('should check date type correctly', fakeAsync(() => {
963+
const d: any = new Date();
964+
expect(d instanceof Date).toBe(true);
965+
}));
966+
967+
it('should check date type correctly without fakeAsync', () => {
935968
const d: any = new Date();
936969
expect(d instanceof Date).toBe(true);
937-
}));
970+
});
971+
972+
it('should tick correctly', fakeAsync(() => {
973+
const start = Date.now();
974+
jasmine.clock().tick(100);
975+
const end = Date.now();
976+
expect(end - start).toBe(100);
977+
}));
978+
979+
it('should tick correctly without fakeAsync', () => {
980+
jasmine.clock().mockDate();
981+
const start = Date.now();
982+
jasmine.clock().tick(100);
983+
const end = Date.now();
984+
expect(end - start).toBe(100);
985+
});
938986

939987
it('should mock date correctly', fakeAsync(() => {
988+
const baseTime = new Date(2013, 9, 23);
989+
jasmine.clock().mockDate(baseTime);
990+
const start = Date.now();
991+
expect(start).toBe(baseTime.getTime());
992+
jasmine.clock().tick(100);
993+
const end = Date.now();
994+
expect(end - start).toBe(100);
995+
expect(end).toBe(baseTime.getTime() + 100);
996+
expect(new Date().getFullYear()).toEqual(2013);
997+
}));
998+
999+
it('should mock date correctly without fakeAsync', () => {
9401000
const baseTime = new Date(2013, 9, 23);
9411001
jasmine.clock().mockDate(baseTime);
9421002
const start = Date.now();
@@ -945,9 +1005,21 @@ describe('FakeAsyncTestZoneSpec', () => {
9451005
const end = Date.now();
9461006
expect(end - start).toBe(100);
9471007
expect(end).toBe(baseTime.getTime() + 100);
948-
}));
1008+
expect(new Date().getFullYear()).toEqual(2013);
1009+
});
9491010

9501011
it('should handle new Date correctly', fakeAsync(() => {
1012+
const baseTime = new Date(2013, 9, 23);
1013+
jasmine.clock().mockDate(baseTime);
1014+
const start = new Date();
1015+
expect(start.getTime()).toBe(baseTime.getTime());
1016+
jasmine.clock().tick(100);
1017+
const end = new Date();
1018+
expect(end.getTime() - start.getTime()).toBe(100);
1019+
expect(end.getTime()).toBe(baseTime.getTime() + 100);
1020+
}));
1021+
1022+
it('should handle new Date correctly without fakeAsync', () => {
9511023
const baseTime = new Date(2013, 9, 23);
9521024
jasmine.clock().mockDate(baseTime);
9531025
const start = new Date();
@@ -956,11 +1028,27 @@ describe('FakeAsyncTestZoneSpec', () => {
9561028
const end = new Date();
9571029
expect(end.getTime() - start.getTime()).toBe(100);
9581030
expect(end.getTime()).toBe(baseTime.getTime() + 100);
959-
}));
1031+
});
1032+
1033+
it('should handle setTimeout correctly', fakeAsync(() => {
1034+
setTimeout(spy, 100);
1035+
expect(spy).not.toHaveBeenCalled();
1036+
jasmine.clock().tick(100);
1037+
expect(spy).toHaveBeenCalled();
1038+
}));
1039+
1040+
it('should handle setTimeout correctly without fakeAsync', () => {
1041+
setTimeout(spy, 100);
1042+
expect(spy).not.toHaveBeenCalled();
1043+
jasmine.clock().tick(100);
1044+
expect(spy).toHaveBeenCalled();
1045+
});
9601046
}));
9611047

9621048
describe('fakeAsyncTest should patch jasmine.clock', ifEnvSupports(supportClock, () => {
1049+
let spy: any;
9631050
beforeEach(() => {
1051+
spy = jasmine.createSpy('timer');
9641052
jasmine.clock().install();
9651053
});
9661054

@@ -980,6 +1068,13 @@ describe('FakeAsyncTestZoneSpec', () => {
9801068
expect(end - start).toBe(100);
9811069
});
9821070

1071+
it('should tick correctly', () => {
1072+
const start = Date.now();
1073+
jasmine.clock().tick(100);
1074+
const end = Date.now();
1075+
expect(end - start).toBe(100);
1076+
});
1077+
9831078
it('should mock date correctly', () => {
9841079
const baseTime = new Date(2013, 9, 23);
9851080
jasmine.clock().mockDate(baseTime);
@@ -1001,6 +1096,13 @@ describe('FakeAsyncTestZoneSpec', () => {
10011096
expect(end.getTime() - start.getTime()).toBe(100);
10021097
expect(end.getTime()).toBe(baseTime.getTime() + 100);
10031098
});
1099+
1100+
it('should handle setTimeout correctly', () => {
1101+
setTimeout(spy, 100);
1102+
expect(spy).not.toHaveBeenCalled();
1103+
jasmine.clock().tick(100);
1104+
expect(spy).toHaveBeenCalled();
1105+
});
10041106
}));
10051107

10061108
describe('fakeAsyncTest should patch rxjs scheduler', ifEnvSupports(supportClock, () => {
@@ -1427,6 +1529,39 @@ const {fakeAsync, tick, discardPeriodicTasks, flush, flushMicrotasks} = fakeAsyn
14271529
expect(zoneInTest1).toBe(zoneInBeforeEach);
14281530
}));
14291531
});
1532+
1533+
describe('fakeAsync should work with Date', () => {
1534+
it('should get date diff correctly', fakeAsync(() => {
1535+
const start = Date.now();
1536+
tick(100);
1537+
const end = Date.now();
1538+
expect(end - start).toBe(100);
1539+
}));
1540+
1541+
it('should check date type correctly', fakeAsync(() => {
1542+
const d: any = new Date();
1543+
expect(d instanceof Date).toBe(true);
1544+
}));
1545+
1546+
it('should new Date with parameter correctly', fakeAsync(() => {
1547+
const d: Date = new Date(0);
1548+
expect(d.getFullYear()).toBeLessThan(1971);
1549+
const d1: Date = new Date('December 17, 1995 03:24:00');
1550+
expect(d1.getFullYear()).toEqual(1995);
1551+
const d2: Date = new Date(1995, 11, 17, 3, 24, 0);
1552+
expect(d2.getFullYear()).toEqual(1995);
1553+
}));
1554+
1555+
it('should get Date.UTC() correctly', fakeAsync(() => {
1556+
const utcDate = new Date(Date.UTC(96, 11, 1, 0, 0, 0));
1557+
expect(utcDate.getFullYear()).toBe(1996);
1558+
}));
1559+
1560+
it('should call Date.parse() correctly', fakeAsync(() => {
1561+
const unixTimeZero = Date.parse('01 Jan 1970 00:00:00 GMT');
1562+
expect(unixTimeZero).toBe(0);
1563+
}));
1564+
});
14301565
});
14311566

14321567
describe('ProxyZone', () => {

0 commit comments

Comments
 (0)