From 04a511fce4875ecac929a57bc1d6c534f6a6e1c0 Mon Sep 17 00:00:00 2001 From: Josh Goldberg Date: Sat, 14 Jan 2017 22:23:16 -0800 Subject: [PATCH 1/3] Added lolex 1.5.2 types Previous types didn't account for browser or node differences, and didn't include more advanced functions like `runAll` in the `Clock` spec. --- lolex/index.d.ts | 187 +++++++++++++++++++++++++++++++++++++++---- lolex/lolex-tests.ts | 166 ++++++++++++++------------------------ 2 files changed, 235 insertions(+), 118 deletions(-) diff --git a/lolex/index.d.ts b/lolex/index.d.ts index 544fb88fb6b985..7a03b3fd2cfbbb 100644 --- a/lolex/index.d.ts +++ b/lolex/index.d.ts @@ -1,28 +1,187 @@ // Type definitions for lolex 1.5.1 // Project: https://github.com/sinonjs/lolex -// Definitions by: Wim Looman +// Definitions by: Wim Looman , Josh Goldberg // Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped +/** + * Timer object used in node. + */ +export type NodeTimer = { + /** + * Stub method call. Does nothing. + */ + ref(): void; -export interface Clock { + /** + * Stub method call. Does nothing. + */ + unref(): void; +} + +/** + * Timer identifier for clock scheduling. + */ +export type TimerId = number | NodeTimer; + +/** + * Lolex clock for a browser environment. + */ +type BrowserClock = IClock; + +/** + * Lolex clock for a Node environment. + */ +type NodeClock = IClock & { + /** + * Mimicks process.hrtime(). + * + * @param prevTime Previous system time to calculate time elapsed. + * @returns High resolution real time as [seconds, nanoseconds]. + */ + hrtime(prevTime?: [number, number]): [number, number]; +} + +/** + * Clock object created by lolex. + */ +type Clock = BrowserClock | NodeClock; + +/** + * Names of clock methods that may be faked by install. + */ +type FakeMethod = "setTimeout" | "clearTimeout" | "setImmediate" | "clearImmediate" | "setInterval" | "clearInterval" | "Date"; + +/** + * Controls the flow of time. + */ +export interface IClock { + /** + * Current clock time. + */ now: number; - setTimeout(callback: () => any, timeout: number): number; - setInterval(callback: () => any, timeout: number): number; - setImmediate(callback: () => any): number; + /** + * Implements the Date object but using this clock to provide the correct time. + */ + Date: typeof Date; + + /** + * Schedules a callback to be fired once timeout milliseconds have ticked by. + * + * @param callback Callback to be fired. + * @param timeout How many ticks to wait to run the callback. + * @returns Time identifier for cancellation. + */ + setTimeout(callback: () => any, timeout: number): TTimerId; - clearTimeout(id: number): void; - clearInterval(id: number): void; - clearImmediate(id: number): void; + /** + * Clears a timer, as long as it was created using setTimeout. + * + * @param id Timer ID or object. + */ + clearTimeout(id: TTimerId): void; - setSystemTime(now: number): void; - setSystemTime(date: Date): void; + /** + * Schedules a callback to be fired every time timeout milliseconds have ticked by. + * + * @param callback Callback to be fired. + * @param timeout How many ticks to wait between callbacks. + * @returns Time identifier for cancellation. + */ + setInterval(callback: () => any, timeout: number): TTimerId; - tick(ms: number): void; + /** + * Clears a timer, as long as it was created using setInterval. + * + * @param id Timer ID or object. + */ + clearInterval(id: TTimerId): void; + + /** + * Schedules the callback to be fired once 0 milliseconds have ticked by. + * + * @param callback Callback to be fired. + * @remarks You'll still have to call clock.tick() for the callback to fire. + * @remarks If called during a tick the callback won't fire until 1 millisecond has ticked by. + */ + setImmediate(callback: () => any): TTimerId; + + /** + * Clears a timer, as long as it was created using setImmediate. + * + * @param id Timer ID or object. + */ + clearImmediate(id: TTimerId): void; + + /** + * Advances the clock to the the moment of the first scheduled timer, firing it. + */ + next(): void; + + /** + * Advance the clock, firing callbacks if necessary. + * + * @param time How many ticks to advance by. + */ + tick(time: number | string): void; + + /** + * Runs all pending timers until there are none remaining. + * + * @remarks If new timers are added while it is executing they will be run as well. + */ + runAll(): void; + + /** + * Takes note of the last scheduled timer when it is run, and advances the clock to + * that time firing callbacks as necessary. + */ + runToLast(): void; + + /** + * Simulates a user changing the system clock. + * + * @param now New system time. + * @remarks This affects the current time but it does not in itself cause timers to fire. + */ + setSystemTime(now?: number | Date): void; + + /** + * Restores the original methods on the context that was passed to lolex.install, + * or the native timers if no context was given. + */ uninstall(): void; } -export declare function createClock(now?: number): Clock; +/** + * Creates a clock. + * + * @param now Current time for the clock. + * @param loopLimit Maximum number of timers that will be run when calling runAll() + * before assuming that we have an infinite loop and throwing an error + * (by default, 1000). + * @type TClock Type of clock to create. + * @remarks The default epoch is 0. + */ +export declare function createClock(now?: number | Date, loopLimit?: number): TClock; + +/** + * Creates a clock and installs it globally. + * + * @param now Current time for the clock, as with lolex.createClock(). + * @param toFake Names of methods that should be faked. + * @type TClock Type of clock to create. + * @usage lolex.install(["setTimeout", "clearTimeout"]); + */ +export declare function install(now?: number | Date, toFake?: FakeMethod[]): TClock; -export declare function install(now?: number, toFake?: string[]): Clock; -export declare function install(context?: any, now?: number, toFake?: string[]): Clock; +/** + * Creates a clock and installs it onto the context object. + * + * @param context Context to install the clock onto. + * @param now Current time for the clock, as with lolex.createClock(). + * @param toFake Names of methods that should be faked. + * @type TClock Type of clock to create. + * @usage lolex.install(context, ["setTimeout", "clearTimeout"]); + */ +export declare function install(context?: any, now?: number | Date, toFake?: FakeMethod[]): TClock; diff --git a/lolex/lolex-tests.ts b/lolex/lolex-tests.ts index 00feecfdd661fd..876e4280c5c8a4 100644 --- a/lolex/lolex-tests.ts +++ b/lolex/lolex-tests.ts @@ -1,126 +1,84 @@ - import lolex = require("lolex"); -function a() { - var clock = lolex.createClock(); - - clock.setTimeout(function () { - console.log("The poblano is a mild chili pepper originating in the state of Puebla, Mexico."); - }, 15); - - // ... - - clock.tick(15); -} - -function b() { - var clock = lolex.install(window); - - window.setTimeout(() => {}, 15); // Schedules with clock.setTimeout - - clock.uninstall(); - - // window.setTimeout is restored to the native implementation -} - -function c() { - var clock = lolex.install(); - - // Equivalent to - // var clock = lolex.install(typeof global !== "undefined" ? global : window); -} - -var clock: lolex.Clock; - -/** - * var clock = lolex.createClock([now]) - */ - -clock = lolex.createClock(); -clock = lolex.createClock(Date.now()); - - -/** - * var clock = lolex.install([context[, now[, toFake]]]) - */ - -clock = lolex.install(); -clock = lolex.install(window); -clock = lolex.install(window, Date.now()); -clock = lolex.install(window, Date.now(), ['setTimeout', 'clearTimeout']); - - -/** - * var clock = lolex.install([now[, toFake]]) - */ - -clock = lolex.install(Date.now()); -clock = lolex.install(Date.now(), ['setTimeout', 'clearTimeout']); - -/** - * clock.now - */ -var n: number = clock.now; - - -var id: number; -/** - * var id = clock.setTimeout(callback, timeout) - */ - -id = clock.setTimeout(() => {}, 1000); - - -/** - * clock.clearTimeout(id) - */ +let browserClock: lolex.BrowserClock = lolex.createClock() as lolex.BrowserClock; +let nodeClock: lolex.NodeClock = lolex.createClock() as lolex.NodeClock; -clock.clearTimeout(id); +browserClock = lolex.createClock(); +nodeClock = lolex.createClock(); +lolex.createClock(7); +lolex.createClock(new Date()); +lolex.createClock(7, 9001); +lolex.createClock(new Date(), 9001); -/** - * var id = clock.setInterval(callback, timeout) - */ +lolex.createClock(7); +lolex.createClock(new Date()); +lolex.createClock(7, 9001); +lolex.createClock(new Date(), 9001); -id = clock.setInterval(() => {}, 1000); +lolex.install(7); +lolex.install(new Date()); +lolex.install(7, ["setTimeout"]); +lolex.install(new Date(), ["setTimeout"]); +lolex.install(7); +lolex.install(new Date()); +lolex.install(7, ["setTimeout"]); +lolex.install(new Date(), ["setTimeout"]); -/** - * clock.clearInterval(id) - */ +lolex.install({}, 7); +lolex.install({}, new Date()); +lolex.install({}, 7, ["setTimeout"]); +lolex.install({}, new Date(), ["setTimeout"]); -clock.clearInterval(id); +lolex.install({}, 7); +lolex.install({}, new Date()); +lolex.install({}, 7, ["setTimeout"]); +lolex.install({}, new Date(), ["setTimeout"]); +const browserNow: number = browserClock.now; +const browserDate: Date = new browserClock.Date(); -/** - * var id = clock.setImmediate(callback) - */ +const nodeNow: number = nodeClock.now; +const nodeDate: Date = new nodeClock.Date(); -id = clock.setImmediate(() => {}); +const browserTimeout: number = browserClock.setTimeout(() => {}, 7); +const browserInterval: number = browserClock.setInterval(() => {}, 7); +const browserImmediate: number = browserClock.setImmediate(() => {}); +const nodeTimeout: lolex.NodeTimer = nodeClock.setTimeout(() => {}, 7); +const nodeInterval: lolex.NodeTimer = nodeClock.setInterval(() => {}, 7); +const nodeImmediate: lolex.NodeTimer = nodeClock.setImmediate(() => {}); +browserClock.clearTimeout(browserTimeout); +browserClock.clearInterval(browserInterval); +browserClock.clearImmediate(browserImmediate); -/** - * clock.clearImmediate(id) - */ +nodeClock.clearTimeout(nodeTimeout); +nodeClock.clearInterval(nodeInterval); +nodeClock.clearImmediate(nodeImmediate); -clock.clearImmediate(id); +browserClock.tick(7); +browserClock.tick("08"); -/** - * clock.setSystemTime - */ -clock.setSystemTime(0); -clock.setSystemTime(new Date()); +nodeClock.tick(7); +nodeClock.tick("08"); -/** - * clock.tick(time) - */ +browserClock.next(); +nodeClock.next(); -clock.tick(1000); +browserClock.runAll(); +nodeClock.runAll(); +browserClock.runToLast(); +nodeClock.runToLast(); -/** - * clock.uninstall() - */ +browserClock.setSystemTime(); +browserClock.setSystemTime(7); +browserClock.setSystemTime(new Date()); -clock.uninstall(); +nodeClock.setSystemTime(); +nodeClock.setSystemTime(7); +nodeClock.setSystemTime(new Date()); +browserClock.uninstall(); +nodeClock.uninstall(); From da89aa8fe1779e552a6af16d103f396bb8b9f852 Mon Sep 17 00:00:00 2001 From: Josh Goldberg Date: Sat, 14 Jan 2017 22:26:16 -0800 Subject: [PATCH 2/3] Bumped lolex version in index.d.ts --- lolex/index.d.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lolex/index.d.ts b/lolex/index.d.ts index 7a03b3fd2cfbbb..845a99afe6ad5f 100644 --- a/lolex/index.d.ts +++ b/lolex/index.d.ts @@ -1,4 +1,4 @@ -// Type definitions for lolex 1.5.1 +// Type definitions for lolex 1.5.2 // Project: https://github.com/sinonjs/lolex // Definitions by: Wim Looman , Josh Goldberg // Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped From 19dea02c4cce0fe002374ffacea2ba54513039ab Mon Sep 17 00:00:00 2001 From: Josh Goldberg Date: Sat, 14 Jan 2017 22:27:51 -0800 Subject: [PATCH 3/3] Fixed linting errors in index.d.ts --- lolex/index.d.ts | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/lolex/index.d.ts b/lolex/index.d.ts index 845a99afe6ad5f..de08060883d54f 100644 --- a/lolex/index.d.ts +++ b/lolex/index.d.ts @@ -1,4 +1,4 @@ -// Type definitions for lolex 1.5.2 +// Type definitions for lolex 1.5 // Project: https://github.com/sinonjs/lolex // Definitions by: Wim Looman , Josh Goldberg // Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped @@ -6,7 +6,7 @@ /** * Timer object used in node. */ -export type NodeTimer = { +export interface NodeTimer { /** * Stub method call. Does nothing. */ @@ -26,12 +26,12 @@ export type TimerId = number | NodeTimer; /** * Lolex clock for a browser environment. */ -type BrowserClock = IClock; +type BrowserClock = LolexClock; /** * Lolex clock for a Node environment. */ -type NodeClock = IClock & { +type NodeClock = LolexClock & { /** * Mimicks process.hrtime(). * @@ -39,7 +39,7 @@ type NodeClock = IClock & { * @returns High resolution real time as [seconds, nanoseconds]. */ hrtime(prevTime?: [number, number]): [number, number]; -} +}; /** * Clock object created by lolex. @@ -54,7 +54,7 @@ type FakeMethod = "setTimeout" | "clearTimeout" | "setImmediate" | "clearImmedia /** * Controls the flow of time. */ -export interface IClock { +export interface LolexClock { /** * Current clock time. */