diff --git a/types/jasmine/index.d.ts b/types/jasmine/index.d.ts index 1a59399c1a..2109645eef 100644 --- a/types/jasmine/index.d.ts +++ b/types/jasmine/index.d.ts @@ -10,6 +10,7 @@ // Giles Roadnight // Yaroslav Admin // Domas Trijonis +// 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 @@ -106,6 +107,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 @@ -135,6 +146,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; @@ -486,6 +503,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; @@ -603,6 +658,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 2f65d84eda..bf3598fda9 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", () => { @@ -748,6 +770,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();