Skip to content

Commit

Permalink
sinon: make calledWith partial (DefinitelyTyped#34048)
Browse files Browse the repository at this point in the history
* sinon: make calledWith partial

* sinon: only recursively allow matchers for objects

* sinon: clean up non-generic bases

* Revert "Extract inspectable spy API into own interface"

This reverts commit e63af8d.

* remove default args

* remove default targs

* use any for this only

* reintroduce args param

* use any for single use targs
  • Loading branch information
43081j authored and rbuckton committed May 25, 2019
1 parent 7ff648e commit 86303f1
Show file tree
Hide file tree
Showing 2 changed files with 62 additions and 61 deletions.
122 changes: 61 additions & 61 deletions types/sinon/ts3.1/index.d.ts
Expand Up @@ -6,7 +6,9 @@ interface Document {} // tslint:disable-line no-empty-interface

declare namespace Sinon {
type MatchArguments<T> = {
[K in keyof T]: SinonMatcher | MatchArguments<T[K]> | T[K];
[K in keyof T]: SinonMatcher
| (T[K] extends object ? MatchArguments<T[K]> : never)
| T[K];
};

interface SinonSpyCallApi<TArgs extends any[] = any[], TReturnValue = any> {
Expand All @@ -29,7 +31,7 @@ declare namespace Sinon {
* so a call that received the provided arguments (in the same spots) and possibly others as well will return true.
* @param args
*/
calledWith(...args: MatchArguments<TArgs>): boolean;
calledWith(...args: Partial<MatchArguments<TArgs>>): boolean;
/**
* Returns true if spy was called at least once with the provided arguments and no others.
*/
Expand Down Expand Up @@ -136,41 +138,17 @@ declare namespace Sinon {
/**
* Returns true if the spy call occurred before another spy call.
* @param call
*
*/
calledBefore(call: SinonSpyCall): boolean;
calledBefore(call: SinonSpyCall<any>): boolean;
/**
* Returns true if the spy call occurred after another spy call.
* @param call
*/
calledAfter(call: SinonSpyCall): boolean;
}

/**
* A test spy is a function that records arguments, return value,
* the value of this and exception thrown (if any) for all its calls.
*/
interface SinonSpy<TArgs extends any[] = any[], TReturnValue = any> extends SinonInspectable<TArgs, TReturnValue> {
// Methods
(...args: TArgs): TReturnValue;

/**
* Creates a spy that only records calls when the received arguments match those passed to withArgs.
* This is useful to be more expressive in your assertions, where you can access the spy with the same call.
* @param args Expected args
*/
withArgs(...args: MatchArguments<TArgs>): SinonSpy<TArgs, TReturnValue>;

/**
* Set the displayName of the spy or stub.
* @param name
*/
named(name: string): SinonSpy<TArgs, TReturnValue>;
calledAfter(call: SinonSpyCall<any>): boolean;
}

/**
* The part of the spy API that allows inspecting the calls made on a spy.
*/
interface SinonInspectable<TArgs extends any[] = any[], TReturnValue = any>
interface SinonSpy<TArgs extends any[] = any[], TReturnValue = any>
extends Pick<
SinonSpyCallApi<TArgs, TReturnValue>,
Exclude<keyof SinonSpyCallApi<TArgs, TReturnValue>, 'args'>
Expand Down Expand Up @@ -234,26 +212,37 @@ declare namespace Sinon {
* If the call did not explicitly return a value, the value at the call’s location in .returnValues will be undefined.
*/
returnValues: TReturnValue[];

// Methods
(...args: TArgs): TReturnValue;

/**
* Returns true if the spy was called before @param anotherSpy
* @param anotherSpy
*/
calledBefore(anotherSpy: SinonInspectable): boolean;
calledBefore(anotherSpy: SinonSpy<any>): boolean;
/**
* Returns true if the spy was called after @param anotherSpy
* @param anotherSpy
*/
calledAfter(anotherSpy: SinonInspectable): boolean;
calledAfter(anotherSpy: SinonSpy<any>): boolean;
/**
* Returns true if spy was called before @param anotherSpy, and no spy calls occurred between spy and @param anotherSpy.
* @param anotherSpy
*/
calledImmediatelyBefore(anotherSpy: SinonInspectable): boolean;
calledImmediatelyBefore(anotherSpy: SinonSpy<any>): boolean;
/**
* Returns true if spy was called after @param anotherSpy, and no spy calls occurred between @param anotherSpy and spy.
* @param anotherSpy
*/
calledImmediatelyAfter(anotherSpy: SinonInspectable): boolean;
calledImmediatelyAfter(anotherSpy: SinonSpy<any>): boolean;

/**
* Creates a spy that only records calls when the received arguments match those passed to withArgs.
* This is useful to be more expressive in your assertions, where you can access the spy with the same call.
* @param args Expected args
*/
withArgs(...args: MatchArguments<TArgs>): SinonSpy<TArgs, TReturnValue>;
/**
* Returns true if the spy was always called with @param obj as this.
* @param obj
Expand Down Expand Up @@ -308,6 +297,11 @@ declare namespace Sinon {
* Returns an Array with all callbacks return values in the order they were called, if no error is thrown.
*/
invokeCallback(...args: TArgs): void;
/**
* Set the displayName of the spy or stub.
* @param name
*/
named(name: string): SinonSpy<TArgs, TReturnValue>;
/**
* Returns the nth call.
* Accessing individual calls helps with more detailed behavior verification when the spy is called more than once.
Expand Down Expand Up @@ -637,12 +631,14 @@ declare namespace Sinon {
}

interface SinonStubStatic {
// Disable rule so assignment to typed stub works (see examples in tests).
/* tslint:disable:no-unnecessary-generics */

/**
* Creates an anonymous stub function
*/
// tslint:disable-next-line no-unnecessary-generics
<TArgs extends any[]= any[], R = any>(): SinonStub<TArgs, R>;
<TArgs extends any[] = any[], R = any>(): SinonStub<TArgs, R>;

/* tslint:enable:no-unnecessary-generics */

/**
* Stubs all the object’s methods.
Expand Down Expand Up @@ -1162,133 +1158,137 @@ declare namespace Sinon {
pass(assertion: any): void; // Overridable

// Methods

/**
* Passes if spy was never called
* @param spy
*/
notCalled(spy: SinonInspectable): void;
notCalled(spy: SinonSpy<any>): void;
/**
* Passes if spy was called at least once.
*/
called(spy: SinonInspectable): void;
called(spy: SinonSpy<any>): void;
/**
* Passes if spy was called once and only once.
*/
calledOnce(spy: SinonInspectable): void;
calledOnce(spy: SinonSpy<any>): void;
/**
* Passes if spy was called exactly twice.
*/
calledTwice(spy: SinonInspectable): void;
calledTwice(spy: SinonSpy<any>): void;
/**
* Passes if spy was called exactly three times.
*/
calledThrice(spy: SinonInspectable): void;
calledThrice(spy: SinonSpy<any>): void;
/**
* Passes if spy was called exactly num times.
*/
callCount(spy: SinonInspectable, count: number): void;
callCount(spy: SinonSpy<any>, count: number): void;
/**
* Passes if provided spies were called in the specified order.
* @param spies
*/
callOrder(...spies: SinonInspectable[]): void;
callOrder(...spies: Array<SinonSpy<any>>): void;
/**
* Passes if spy was ever called with obj as its this value.
* It’s possible to assert on a dedicated spy call: sinon.assert.calledOn(spy.firstCall, arg1, arg2, ...);.
*/
calledOn(spyOrSpyCall: SinonInspectable | SinonSpyCall, obj: any): void;
calledOn(spyOrSpyCall: SinonSpy<any> | SinonSpyCall<any>, obj: any): void;
/**
* Passes if spy was always called with obj as its this value.
*/
alwaysCalledOn(spy: SinonInspectable, obj: any): void;
alwaysCalledOn(spy: SinonSpy<any>, obj: any): void;

/**
* Passes if spy was called with the provided arguments.
* It’s possible to assert on a dedicated spy call: sinon.assert.calledWith(spy.firstCall, arg1, arg2, ...);.
* @param spyOrSpyCall
* @param args
*/
calledWith<TArgs extends any[]>(spyOrSpyCall: SinonInspectable<TArgs> | SinonSpyCall<TArgs>, ...args: MatchArguments<TArgs>): void;
calledWith<TArgs extends any[]>(spyOrSpyCall: SinonSpy<TArgs> | SinonSpyCall<TArgs>, ...args: MatchArguments<TArgs>): void;
/**
* Passes if spy was always called with the provided arguments.
* @param spy
* @param args
*/
alwaysCalledWith<TArgs extends any[]>(spy: SinonInspectable<TArgs>, ...args: MatchArguments<TArgs>): void;
alwaysCalledWith<TArgs extends any[]>(spy: SinonSpy<TArgs>, ...args: MatchArguments<TArgs>): void;
/**
* Passes if spy was never called with the provided arguments.
* @param spy
* @param args
*/
neverCalledWith<TArgs extends any[]>(spy: SinonInspectable<TArgs>, ...args: MatchArguments<TArgs>): void;
neverCalledWith<TArgs extends any[]>(spy: SinonSpy<TArgs>, ...args: MatchArguments<TArgs>): void;
/**
* Passes if spy was called with the provided arguments and no others.
* It’s possible to assert on a dedicated spy call: sinon.assert.calledWithExactly(spy.getCall(1), arg1, arg2, ...);.
* @param spyOrSpyCall
* @param args
*/
calledWithExactly<TArgs extends any[]>(
spyOrSpyCall: SinonInspectable<TArgs> | SinonSpyCall<TArgs>,
spyOrSpyCall: SinonSpy<TArgs> | SinonSpyCall<TArgs>,
...args: MatchArguments<TArgs>
): void;
/**
* Passes if spy was always called with the provided arguments and no others.
*/
alwaysCalledWithExactly<TArgs extends any[]>(spy: SinonInspectable<TArgs>, ...args: MatchArguments<TArgs>): void;
alwaysCalledWithExactly<TArgs extends any[]>(spy: SinonSpy<TArgs>, ...args: MatchArguments<TArgs>): void;
/**
* Passes if spy was called with matching arguments.
* This behaves the same way as sinon.assert.calledWith(spy, sinon.match(arg1), sinon.match(arg2), ...).
* It’s possible to assert on a dedicated spy call: sinon.assert.calledWithMatch(spy.secondCall, arg1, arg2, ...);.
*/
calledWithMatch<TArgs extends any[]>(
spyOrSpyCall: SinonInspectable<TArgs> | SinonSpyCall<TArgs>,
spyOrSpyCall: SinonSpy<TArgs> | SinonSpyCall<TArgs>,
...args: TArgs
): void;
/**
* Passes if spy was always called with matching arguments.
* This behaves the same way as sinon.assert.alwaysCalledWith(spy, sinon.match(arg1), sinon.match(arg2), ...).
*/
alwaysCalledWithMatch<TArgs extends any[]>(spy: SinonInspectable<TArgs>, ...args: TArgs): void;
alwaysCalledWithMatch<TArgs extends any[]>(spy: SinonSpy<TArgs>, ...args: TArgs): void;
/**
* Passes if spy was never called with matching arguments.
* This behaves the same way as sinon.assert.neverCalledWith(spy, sinon.match(arg1), sinon.match(arg2), ...).
* @param spy
* @param args
*/
neverCalledWithMatch<TArgs extends any[]>(spy: SinonInspectable<TArgs>, ...args: TArgs): void;
neverCalledWithMatch<TArgs extends any[]>(spy: SinonSpy<TArgs>, ...args: TArgs): void;
/**
* Passes if spy was called with the new operator.
* It’s possible to assert on a dedicated spy call: sinon.assert.calledWithNew(spy.secondCall, arg1, arg2, ...);.
* @param spyOrSpyCall
*/
calledWithNew(spyOrSpyCall: SinonInspectable | SinonSpyCall): void;
calledWithNew(spyOrSpyCall: SinonSpy<any> | SinonSpyCall<any>): void;
/**
* Passes if spy threw any exception.
*/
threw(spyOrSpyCall: SinonInspectable | SinonSpyCall): void;
threw(spyOrSpyCall: SinonSpy<any> | SinonSpyCall<any>): void;
/**
* Passes if spy threw the given exception.
* The exception is an actual object.
* It’s possible to assert on a dedicated spy call: sinon.assert.threw(spy.thirdCall, exception);.
*/
threw(spyOrSpyCall: SinonInspectable | SinonSpyCall, exception: string): void;
threw(spyOrSpyCall: SinonSpy<any> | SinonSpyCall<any>, exception: string): void;
/**
* Passes if spy threw the given exception.
* The exception is a String denoting its type.
* It’s possible to assert on a dedicated spy call: sinon.assert.threw(spy.thirdCall, exception);.
*/
threw(spyOrSpyCall: SinonInspectable | SinonSpyCall, exception: any): void;
threw(spyOrSpyCall: SinonSpy<any> | SinonSpyCall<any>, exception: any): void;

/**
* Like threw, only required for all calls to the spy.
*/
alwaysThrew(spy: SinonInspectable): void;
alwaysThrew(spy: SinonSpy<any>): void;
/**
* Like threw, only required for all calls to the spy.
*/
alwaysThrew(spy: SinonInspectable, exception: string): void;
alwaysThrew(spy: SinonSpy<any>, exception: string): void;
/**
* Like threw, only required for all calls to the spy.
*/
alwaysThrew(spy: SinonInspectable, exception: any): void;
alwaysThrew(spy: SinonSpy<any>, exception: any): void;

/**
* Uses sinon.match to test if the arguments can be considered a match.
*/
Expand Down
1 change: 1 addition & 0 deletions types/sinon/ts3.1/sinon-tests.ts
Expand Up @@ -82,6 +82,7 @@ function testSandbox() {
const stubInstance = sb.createStubInstance(cls);
const privateFooStubbedInstance = sb.createStubInstance(PrivateFoo);
stubInstance.foo.calledWith('foo', 1);
stubInstance.foo.calledWith('foo');
privateFooStubbedInstance.foo.calledWith();
const clsFoo: sinon.SinonStub<[string, number], number> = stubInstance.foo;
const privateFooFoo: sinon.SinonStub<[], void> = privateFooStubbedInstance.foo;
Expand Down

0 comments on commit 86303f1

Please sign in to comment.