From 494a802a2aa3067657647c8da9a84af3db82d087 Mon Sep 17 00:00:00 2001 From: Peter Safranek Date: Sun, 18 Nov 2018 19:07:42 -0800 Subject: [PATCH 1/2] [jasmine] Add async matchers --- types/jasmine/index.d.ts | 57 ++++++++++++++++++++++++++++++++++ types/jasmine/jasmine-tests.ts | 41 ++++++++++++++++++++++++ 2 files changed, 98 insertions(+) diff --git a/types/jasmine/index.d.ts b/types/jasmine/index.d.ts index e9dba1e2cd..8d3d12bbb4 100644 --- a/types/jasmine/index.d.ts +++ b/types/jasmine/index.d.ts @@ -8,6 +8,7 @@ // Boris Breuer // Chris Yungmann // Giles Roadnight +// Peter Safranek // Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped // TypeScript Version: 2.8 // For ddescribe / iit use : https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/karma-jasmine/karma-jasmine.d.ts @@ -101,6 +102,16 @@ declare function expect(actual: T): jasmine.Matchers; */ declare function expect(): jasmine.NothingMatcher; +/** + * Create an asynchronous expectation for a spec. Note that the matchers + * that are provided by an asynchronous expectation all return promises + * which must be either returned from the spec or waited for using `await` + * in order for Jasmine to associate them with the correct spec. + * @checkReturnValue see https://tsetse.info/check-return-value + * @param actual - Actual computed value to test expectations against. + */ +declare function expectAsync(actual: Promise): jasmine.AsyncMatchers; + /** * Explicitly mark a spec as failed. * @param e @@ -130,6 +141,12 @@ declare function spyOn(object: T, method: keyof T): jasmine.Spy; */ declare function spyOnProperty(object: T, property: keyof T, accessType?: 'get' | 'set'): jasmine.Spy; +/** + * Installs spies on all writable and configurable properties of an object. + * @param object The object upon which to install the Spies + */ +declare function spyOnAllFunctions(object: object): jasmine.Spy; + declare function runs(asyncMethod: Function): void; declare function waitsFor(latchMethod: () => boolean, failureMessage?: string, timeout?: number): void; declare function waits(timeout?: number): void; @@ -481,6 +498,44 @@ declare namespace jasmine { nothing(): void; } + interface AsyncMatchers { + + /** + * Expect a promise to be resolved. + * @param expectationFailOutput + */ + toBeResolved(expectationFailOutput?: any): Promise; + + /** + * Expect a promise to be rejected. + * @param expectationFailOutput + */ + toBeRejected(expectationFailOutput?: any): Promise; + + /** + * Expect a promise to be resolved to a value equal to the expected, using deep equality comparison. + * @param expected - Value that the promise is expected to resolve to. + */ + toBeResolvedTo(expected: Expected): Promise; + + /** + * Expect a promise to be rejected with a value equal to the expected, using deep equality comparison. + * @param expected - Value that the promise is expected to be rejected with. + */ + toBeRejectedWith(expected: Expected): Promise; + + /** + * Add some context for an expect. + * @param message - Additional context to show when the matcher fails. + */ + withContext(message: string): AsyncMatchers; + + /** + * Invert the matcher following this expect. + */ + not: AsyncMatchers + } + interface Reporter { reportRunnerStarting(runner: Runner): void; reportRunnerResults(runner: Runner): void; @@ -598,6 +653,8 @@ declare namespace jasmine { explodes(): void; spyOn(obj: any, methodName: string, ignoreMethodDoesntExist: boolean): Spy; spyOnProperty(object: any, property: string, accessType?: 'get' | 'set'): Spy; + spyOnAllFunctions(object: any): Spy; + removeAllSpies(): void; throwOnExpectationFailure: boolean; } diff --git a/types/jasmine/jasmine-tests.ts b/types/jasmine/jasmine-tests.ts index ba8763ce3d..1480f9bf41 100644 --- a/types/jasmine/jasmine-tests.ts +++ b/types/jasmine/jasmine-tests.ts @@ -171,6 +171,28 @@ describe("Included matchers:", () => { expect(foo).toThrowError(TypeError); expect(foo).toThrowError(TypeError, "foo bar baz"); }); + + it("async matchers", async () => { + var badness = new Error("badness"); + await expectAsync(Promise.resolve()).toBeResolved(); + await expectAsync(Promise.resolve()).toBeResolved("good job"); + await expectAsync(Promise.resolve(true)).toBeResolvedTo(true); + await expectAsync(Promise.reject(badness)).toBeRejected(); + await expectAsync(Promise.reject(badness)).toBeRejected("bad mojo"); + await expectAsync(Promise.reject(badness)).toBeRejectedWith(badness); + await expectAsync(Promise.resolve()).withContext("additional info").toBeResolved(); + }); + + it("async matchers - not", async () => { + var badness = new Error("badness"); + var malady = new Error("malady"); + await expectAsync(Promise.reject(badness)).not.toBeResolved(); + await expectAsync(Promise.resolve(true)).not.toBeResolvedTo(false); + await expectAsync(Promise.resolve()).not.toBeRejected(); + await expectAsync(Promise.reject(badness)).not.toBeRejectedWith(malady); + await expectAsync(Promise.reject(badness)).not.withContext("additional info").toBeResolved(); + await expectAsync(Promise.reject(badness)).withContext("additional info").not.toBeResolved(); + }); }); describe("toThrowMatching", () => { @@ -695,6 +717,25 @@ describe("Multiple spies, when created manually", () => { }); }); +describe("multiple spies, when created with spyOnAllFunctions", () => { + + it("spies on all functions", () => { + + const obj = { + x: (a: number) => a, + y: (a: number) => a, + } + + spyOnAllFunctions(obj); + + obj.x(0); + obj.y(1); + + expect(obj.x).toHaveBeenCalled(); + expect(obj.y).toHaveBeenCalledWith(1); + }); +}); + describe("jasmine.nothing", () => { it("matches any value", () => { expect().nothing(); From e4fb7888a144104395f91d104aa2919bd6ea3b0c Mon Sep 17 00:00:00 2001 From: Peter Safranek Date: Tue, 18 Dec 2018 14:19:00 -0800 Subject: [PATCH 2/2] Convert increment operator to plus/equals --- types/jasmine/jasmine-tests.ts | 6 +++--- types/jasmine/v2/jasmine-tests.ts | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/types/jasmine/jasmine-tests.ts b/types/jasmine/jasmine-tests.ts index c6a15f1897..4d06cdf16f 100644 --- a/types/jasmine/jasmine-tests.ts +++ b/types/jasmine/jasmine-tests.ts @@ -987,7 +987,7 @@ describe("Asynchronous specs", () => { }); it("should support async execution of test preparation and expectations", (done: DoneFn) => { - value++; + value += 1; expect(value).toBeGreaterThan(0); done(); }); @@ -1165,7 +1165,7 @@ var myReporter: jasmine.CustomReporter = { specDone: (result: jasmine.CustomReporterResult) => { console.log("Spec: " + result.description + " was " + result.status); //tslint:disable-next-line:prefer-for-of - for (var i = 0; result.failedExpectations && i < result.failedExpectations.length; i++) { + for (var i = 0; result.failedExpectations && i < result.failedExpectations.length; i += 1) { console.log("Failure: " + result.failedExpectations[i].message); console.log("Actual: " + result.failedExpectations[i].actual); console.log("Expected: " + result.failedExpectations[i].expected); @@ -1177,7 +1177,7 @@ var myReporter: jasmine.CustomReporter = { suiteDone: (result: jasmine.CustomReporterResult) => { console.log('Suite: ' + result.description + ' was ' + result.status); //tslint:disable-next-line:prefer-for-of - for (var i = 0; result.failedExpectations && i < result.failedExpectations.length; i++) { + for (var i = 0; result.failedExpectations && i < result.failedExpectations.length; i += 1) { console.log('AfterAll ' + result.failedExpectations[i].message); console.log(result.failedExpectations[i].stack); } diff --git a/types/jasmine/v2/jasmine-tests.ts b/types/jasmine/v2/jasmine-tests.ts index fce7c59c9e..d85bc48198 100644 --- a/types/jasmine/v2/jasmine-tests.ts +++ b/types/jasmine/v2/jasmine-tests.ts @@ -888,7 +888,7 @@ describe("Asynchronous specs", () => { }); it("should support async execution of test preparation and expectations", (done: DoneFn) => { - value++; + value += 1; expect(value).toBeGreaterThan(0); done(); }); @@ -1066,7 +1066,7 @@ var myReporter: jasmine.CustomReporter = { specDone: (result: jasmine.CustomReporterResult) => { console.log("Spec: " + result.description + " was " + result.status); //tslint:disable-next-line:prefer-for-of - for (var i = 0; result.failedExpectations && i < result.failedExpectations.length; i++) { + for (var i = 0; result.failedExpectations && i < result.failedExpectations.length; i += 1) { console.log("Failure: " + result.failedExpectations[i].message); console.log("Actual: " + result.failedExpectations[i].actual); console.log("Expected: " + result.failedExpectations[i].expected); @@ -1078,7 +1078,7 @@ var myReporter: jasmine.CustomReporter = { suiteDone: (result: jasmine.CustomReporterResult) => { console.log('Suite: ' + result.description + ' was ' + result.status); //tslint:disable-next-line:prefer-for-of - for (var i = 0; result.failedExpectations && i < result.failedExpectations.length; i++) { + for (var i = 0; result.failedExpectations && i < result.failedExpectations.length; i += 1) { console.log('AfterAll ' + result.failedExpectations[i].message); console.log(result.failedExpectations[i].stack); }