Skip to content

Commit

Permalink
fix(test): fix angular#1069, FakeDate should handle constructor param…
Browse files Browse the repository at this point in the history
…eter
  • Loading branch information
JiaLiPassion committed Apr 6, 2018
1 parent a86bddb commit 887c8bc
Show file tree
Hide file tree
Showing 4 changed files with 203 additions and 27 deletions.
27 changes: 17 additions & 10 deletions lib/jasmine/jasmine.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,10 +67,14 @@
return originalJasmineFn.apply(this, arguments);
};
});
if (enableClockPatch) {
const originalClockFn: Function = ((jasmine as any)[symbol('clock')] = jasmine['clock']);
(jasmine as any)['clock'] = function() {
const clock = originalClockFn.apply(this, arguments);

// need to patch jasmine.clock().mockDate and jasmine.clock().tick() so
// they can work properly in FakeAsyncTest
const originalClockFn: Function = ((jasmine as any)[symbol('clock')] = jasmine['clock']);
(jasmine as any)['clock'] = function() {
const clock = originalClockFn.apply(this, arguments);
if (!clock[symbol('patched')]) {
clock[symbol('patched')] = symbol('patched');
const originalTick = (clock[symbol('tick')] = clock.tick);
clock.tick = function() {
const fakeAsyncZoneSpec = Zone.current.get('FakeAsyncTestZoneSpec');
Expand All @@ -83,28 +87,31 @@
clock.mockDate = function() {
const fakeAsyncZoneSpec = Zone.current.get('FakeAsyncTestZoneSpec');
if (fakeAsyncZoneSpec) {
const dateTime = arguments[0];
const dateTime = arguments.length > 0 ? arguments[0] : new Date();
return fakeAsyncZoneSpec.setCurrentRealTime.apply(
fakeAsyncZoneSpec,
dateTime && typeof dateTime.getTime === 'function' ? [dateTime.getTime()] :
arguments);
}
return originalMockDate.apply(this, arguments);
};
// for auto go into fakeAsync feature, we need the flag to enable it
['install', 'uninstall'].forEach(methodName => {
const originalClockFn: Function = (clock[symbol(methodName)] = clock[methodName]);
clock[methodName] = function() {
const FakeAsyncTestZoneSpec = (Zone as any)['FakeAsyncTestZoneSpec'];
if (FakeAsyncTestZoneSpec) {
(jasmine as any)[symbol('clockInstalled')] = 'install' === methodName;
return;
if (enableClockPatch) {
(jasmine as any)[symbol('clockInstalled')] = 'install' === methodName;
return;
}
}
return originalClockFn.apply(this, arguments);
};
});
return clock;
};
}
}
return clock;
};

/**
* Gets a function wrapping the body of a Jasmine `describe` block to execute in a
Expand Down
48 changes: 36 additions & 12 deletions lib/zone-spec/fake-async-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,13 +32,14 @@
const OriginalDate = global.Date;
class FakeDate {
constructor() {
const d = new OriginalDate();
d.setTime(global.Date.now());
return d;
}

static UTC() {
return OriginalDate.UTC();
if (arguments.length === 0) {
const d = new OriginalDate();
d.setTime(FakeDate.now());
return d;
} else {
const args = Array.prototype.slice.call(arguments);
return new OriginalDate(...args);
}
}

static now() {
Expand All @@ -48,12 +49,19 @@
}
return OriginalDate.now.apply(this, arguments);
}

static parse() {
return OriginalDate.parse();
}
}

(FakeDate as any).UTC = OriginalDate.UTC;
(FakeDate as any).parse = OriginalDate.parse;

// keep a reference for zone patched timer function
const timers = {
setTimeout: global.setTimeout,
setInterval: global.setInterval,
clearTimeout: global.clearTimeout,
clearInterval: global.clearInterval
};

class Scheduler {
// Next scheduler id.
public nextId: number = 1;
Expand All @@ -63,7 +71,7 @@
// Current simulated time in millis.
private _currentTime: number = 0;
// Current real time in millis.
private _currentRealTime: number = Date.now();
private _currentRealTime: number = OriginalDate.now();

constructor() {}

Expand Down Expand Up @@ -341,6 +349,11 @@
}
global['Date'] = FakeDate;
FakeDate.prototype = OriginalDate.prototype;

// try check and reset timers
// because jasmine.clock().install() may
// have replaced the global timer
FakeAsyncTestZoneSpec.checkTimerPatch();
}

static resetDate() {
Expand All @@ -349,6 +362,17 @@
}
}

static checkTimerPatch() {
if (global.setTimeout !== timers.setTimeout) {
global.setTimeout = timers.setTimeout;
global.clearTimeout = timers.clearTimeout;
}
if (global.setInterval !== timers.setInterval) {
global.setInterval = timers.setInterval;
global.clearInterval = timers.clearInterval;
}
}

lockDatePatch() {
this.patchDateLocked = true;
FakeAsyncTestZoneSpec.patchDate();
Expand Down
11 changes: 10 additions & 1 deletion test/test-env-setup-mocha.ts
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,11 @@ declare const global: any;
throw new Error(`Expected ${expected} to be greater than ${actual}`);
}
},
toBeLessThan: function(actual: number) {
if (expected >= actual) {
throw new Error(`Expected ${expected} to be lesser than ${actual}`);
}
},
toBeDefined: function() {
if (!expected) {
throw new Error(`Expected ${expected} to be defined`);
Expand Down Expand Up @@ -159,7 +164,11 @@ declare const global: any;
if (expected > actual) {
throw new Error(`Expected ${expected} not to be greater than ${actual}`);
}

},
toBeLessThan: function(actual: number) {
if (expected < actual) {
throw new Error(`Expected ${expected} not to be lesser than ${actual}`);
}
},
toHaveBeenCalledWith: function(params: any[]) {
if (!eq(expected.callArgs, params)) {
Expand Down
144 changes: 140 additions & 4 deletions test/zone-spec/fake-async-test.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -913,17 +913,45 @@ describe('FakeAsyncTestZoneSpec', () => {
expect(d instanceof Date).toBe(true);
});
});

it('should new Date with parameter correctly', () => {
fakeAsyncTestZone.run(() => {
const d: Date = new Date(0);
expect(d.getFullYear()).toBeLessThan(1971);
const d1: Date = new Date('December 17, 1995 03:24:00');
expect(d1.getFullYear()).toEqual(1995);
const d2: Date = new Date(1995, 11, 17, 3, 24, 0);
expect(d2.getFullYear()).toEqual(1995);
});
});

it('should get Date.UTC() correctly', () => {
fakeAsyncTestZone.run(() => {
const utcDate = new Date(Date.UTC(96, 11, 1, 0, 0, 0));
expect(utcDate.getFullYear()).toBe(1996);
});
});

it('should call Date.parse() correctly', () => {
fakeAsyncTestZone.run(() => {
const unixTimeZero = Date.parse('01 Jan 1970 00:00:00 GMT');
expect(unixTimeZero).toBe(0);
});
});

});

describe(
'fakeAsyncTest should work without jasmine.clock',
'fakeAsyncTest should work without patch jasmine.clock',
ifEnvSupports(
() => {
return !supportClock() && supportNode();
},
() => {
const fakeAsync = (Zone as any)[Zone.__symbol__('fakeAsyncTest')].fakeAsync;
let spy: any;
beforeEach(() => {
spy = jasmine.createSpy('timer');
jasmine.clock().install();
});

Expand All @@ -932,11 +960,44 @@ describe('FakeAsyncTestZoneSpec', () => {
});

it('should check date type correctly', fakeAsync(() => {
const d: any = new Date();
expect(d instanceof Date).toBe(true);
}));

it('should check date type correctly without fakeAsync', () => {
const d: any = new Date();
expect(d instanceof Date).toBe(true);
}));
});

it('should tick correctly', fakeAsync(() => {
jasmine.clock().mockDate();
const start = Date.now();
jasmine.clock().tick(100);
const end = Date.now();
expect(end - start).toBe(100);
}));

it('should tick correctly without fakeAsync', () => {
jasmine.clock().mockDate();
const start = Date.now();
jasmine.clock().tick(100);
const end = Date.now();
expect(end - start).toBe(100);
});

it('should mock date correctly', fakeAsync(() => {
const baseTime = new Date(2013, 9, 23);
jasmine.clock().mockDate(baseTime);
const start = Date.now();
expect(start).toBe(baseTime.getTime());
jasmine.clock().tick(100);
const end = Date.now();
expect(end - start).toBe(100);
expect(end).toBe(baseTime.getTime() + 100);
expect(new Date().getFullYear()).toEqual(2013);
}));

it('should mock date correctly without fakeAsync', () => {
const baseTime = new Date(2013, 9, 23);
jasmine.clock().mockDate(baseTime);
const start = Date.now();
Expand All @@ -945,9 +1006,21 @@ describe('FakeAsyncTestZoneSpec', () => {
const end = Date.now();
expect(end - start).toBe(100);
expect(end).toBe(baseTime.getTime() + 100);
}));
expect(new Date().getFullYear()).toEqual(2013);
});

it('should handle new Date correctly', fakeAsync(() => {
const baseTime = new Date(2013, 9, 23);
jasmine.clock().mockDate(baseTime);
const start = new Date();
expect(start.getTime()).toBe(baseTime.getTime());
jasmine.clock().tick(100);
const end = new Date();
expect(end.getTime() - start.getTime()).toBe(100);
expect(end.getTime()).toBe(baseTime.getTime() + 100);
}));

it('should handle new Date correctly without fakeAsync', () => {
const baseTime = new Date(2013, 9, 23);
jasmine.clock().mockDate(baseTime);
const start = new Date();
Expand All @@ -956,11 +1029,27 @@ describe('FakeAsyncTestZoneSpec', () => {
const end = new Date();
expect(end.getTime() - start.getTime()).toBe(100);
expect(end.getTime()).toBe(baseTime.getTime() + 100);
}));
});

it('should handle setTimeout correctly', fakeAsync(() => {
setTimeout(spy, 100);
expect(spy).not.toHaveBeenCalled();
jasmine.clock().tick(100);
expect(spy).toHaveBeenCalled();
}));

it('should handle setTimeout correctly without fakeAsync', () => {
setTimeout(spy, 100);
expect(spy).not.toHaveBeenCalled();
jasmine.clock().tick(100);
expect(spy).toHaveBeenCalled();
});
}));

describe('fakeAsyncTest should patch jasmine.clock', ifEnvSupports(supportClock, () => {
let spy: any;
beforeEach(() => {
spy = jasmine.createSpy('timer');
jasmine.clock().install();
});

Expand All @@ -980,6 +1069,13 @@ describe('FakeAsyncTestZoneSpec', () => {
expect(end - start).toBe(100);
});

it('should tick correctly', () => {
const start = Date.now();
jasmine.clock().tick(100);
const end = Date.now();
expect(end - start).toBe(100);
});

it('should mock date correctly', () => {
const baseTime = new Date(2013, 9, 23);
jasmine.clock().mockDate(baseTime);
Expand All @@ -1001,6 +1097,13 @@ describe('FakeAsyncTestZoneSpec', () => {
expect(end.getTime() - start.getTime()).toBe(100);
expect(end.getTime()).toBe(baseTime.getTime() + 100);
});

it('should handle setTimeout correctly', () => {
setTimeout(spy, 100);
expect(spy).not.toHaveBeenCalled();
jasmine.clock().tick(100);
expect(spy).toHaveBeenCalled();
});
}));

describe('fakeAsyncTest should patch rxjs scheduler', ifEnvSupports(supportClock, () => {
Expand Down Expand Up @@ -1427,6 +1530,39 @@ const {fakeAsync, tick, discardPeriodicTasks, flush, flushMicrotasks} = fakeAsyn
expect(zoneInTest1).toBe(zoneInBeforeEach);
}));
});

describe('fakeAsync should work with Date', () => {
it('should get date diff correctly', fakeAsync(() => {
const start = Date.now();
tick(100);
const end = Date.now();
expect(end - start).toBe(100);
}));

it('should check date type correctly', fakeAsync(() => {
const d: any = new Date();
expect(d instanceof Date).toBe(true);
}));

it('should new Date with parameter correctly', fakeAsync(() => {
const d: Date = new Date(0);
expect(d.getFullYear()).toBeLessThan(1971);
const d1: Date = new Date('December 17, 1995 03:24:00');
expect(d1.getFullYear()).toEqual(1995);
const d2: Date = new Date(1995, 11, 17, 3, 24, 0);
expect(d2.getFullYear()).toEqual(1995);
}));

it('should get Date.UTC() correctly', fakeAsync(() => {
const utcDate = new Date(Date.UTC(96, 11, 1, 0, 0, 0));
expect(utcDate.getFullYear()).toBe(1996);
}));

it('should call Date.parse() correctly', fakeAsync(() => {
const unixTimeZero = Date.parse('01 Jan 1970 00:00:00 GMT');
expect(unixTimeZero).toBe(0);
}));
});
});

describe('ProxyZone', () => {
Expand Down

0 comments on commit 887c8bc

Please sign in to comment.