Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
106 changes: 68 additions & 38 deletions types/node/test.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -773,82 +773,112 @@ declare module "node:test" {
* @return The mocked method. The mocked method contains a special `mock` property, which is an instance of {@link MockFunctionContext}, and can be used for inspecting and changing the
* behavior of the mocked method.
*/
method<MockedObject extends object, MethodName extends FunctionPropertyNames<MockedObject>>(
object: MockedObject,
methodName: MethodName,
options?: MockFunctionOptions,
): MockedObject[MethodName] extends Function ? Mock<MockedObject[MethodName]> : never;
method<
MockedObject extends object,
MethodName extends FunctionPropertyNames<MockedObject>,
Implementation extends MockedObject[MethodName],
>(
object: MockedObject,
methodName: MethodName,
implementation: Implementation,
options?: MockFunctionOptions,
): MockedObject[MethodName] extends Function ? Mock<MockedObject[MethodName]>
: never;
): MockedObject[MethodName] extends Function ? Mock<MockedObject[MethodName]> : never;
// m = mock.method(obj, 'attribute', { getter: true })
method<
MockedObject extends object,
MethodName extends FunctionPropertyNames<MockedObject>,
Implementation extends Function,
AttributeName extends keyof MockedObject,
Implementation extends () => MockedObject[AttributeName],
>(
object: MockedObject,
methodName: MethodName,
attributeName: AttributeName,
options: { getter: true } & MockMethodOptions,
): Mock<Implementation>;
// mock.method(obj, 'attribute', function() {}, { getter: true })
method<
MockedObject extends object,
AttributeName extends keyof MockedObject,
Implementation extends () => MockedObject[AttributeName],
>(
object: MockedObject,
attributeName: AttributeName,
implementation: Implementation,
options?: MockFunctionOptions,
): MockedObject[MethodName] extends Function ? Mock<MockedObject[MethodName] | Implementation>
: never;
method<MockedObject extends object>(
options: { getter: true } & MockMethodOptions,
): Mock<Implementation>;
// mock.method(obj, 'attribute', { setter: true })
method<
MockedObject extends object,
AttributeName extends keyof MockedObject,
Implementation extends (value: MockedObject[AttributeName]) => void,
>(
object: MockedObject,
methodName: keyof MockedObject,
options: MockMethodOptions,
): Mock<Function>;
method<MockedObject extends object>(
attributeName: AttributeName,
options: { setter: true } & MockMethodOptions,
): Mock<Implementation>;
// mock.method(obj, 'attribute', function() {}, { setter: true })
method<
MockedObject extends object,
AttributeName extends keyof MockedObject,
Implementation extends (value: MockedObject[AttributeName]) => void,
>(
object: MockedObject,
attributeName: AttributeName,
implementation: Implementation,
options: { setter: true } & MockMethodOptions,
): Mock<Implementation>;
method<
MockedObject extends object,
MethodName extends keyof MockedObject,
Implementation extends MockedObject[MethodName],
>(
object: MockedObject,
methodName: keyof MockedObject,
implementation: Function,
methodName: MethodName,
implementation: Implementation,
options: MockMethodOptions,
): Mock<Function>;
): Implementation extends Function ? Mock<Implementation> : never;

/**
* This function is syntax sugar for `MockTracker.method` with `options.getter`set to `true`.
* @since v19.3.0, v18.13.0
*/
getter<
MockedObject extends object,
MethodName extends keyof MockedObject,
>(
getter<MockedObject extends object, AttributeName extends keyof MockedObject>(
object: MockedObject,
methodName: MethodName,
methodName: AttributeName,
options?: MockFunctionOptions,
): Mock<() => MockedObject[MethodName]>;
): Mock<() => MockedObject[AttributeName]>;
getter<
MockedObject extends object,
MethodName extends keyof MockedObject,
Implementation extends Function,
AttributeName extends keyof MockedObject,
Implementation extends () => MockedObject[AttributeName],
>(
object: MockedObject,
methodName: MethodName,
methodName: AttributeName,
implementation?: Implementation,
options?: MockFunctionOptions,
): Mock<(() => MockedObject[MethodName]) | Implementation>;
): Mock<(() => MockedObject[AttributeName]) | Implementation>;
/**
* This function is syntax sugar for `MockTracker.method` with `options.setter`set to `true`.
* @since v19.3.0, v18.13.0
*/
setter<
MockedObject extends object,
MethodName extends keyof MockedObject,
>(
setter<MockedObject extends object, AttributeName extends keyof MockedObject>(
object: MockedObject,
methodName: MethodName,
methodName: AttributeName,
options?: MockFunctionOptions,
): Mock<(value: MockedObject[MethodName]) => void>;
): Mock<(value: MockedObject[AttributeName]) => void>;
setter<
MockedObject extends object,
MethodName extends keyof MockedObject,
Implementation extends Function,
AttributeName extends keyof MockedObject,
Implementation extends (value: MockedObject[AttributeName]) => void,
>(
object: MockedObject,
methodName: MethodName,
methodName: AttributeName,
implementation?: Implementation,
options?: MockFunctionOptions,
): Mock<((value: MockedObject[MethodName]) => void) | Implementation>;
): Mock<(value: MockedObject[AttributeName]) => void>;
/**
* This function restores the default behavior of all mocks that were previously
* created by this `MockTracker` and disassociates the mocks from the`MockTracker` instance. Once disassociated, the mocks can still be used, but the`MockTracker` instance can no longer be
Expand Down Expand Up @@ -957,7 +987,7 @@ declare module "node:test" {
* @since v19.1.0, v18.13.0
* @param implementation The function to be used as the mock's new implementation.
*/
mockImplementation(implementation: Function): void;
mockImplementation(implementation: F): void;
/**
* This function is used to change the behavior of an existing mock for a single
* invocation. Once invocation `onCall` has occurred, the mock will revert to
Expand Down Expand Up @@ -994,7 +1024,7 @@ declare module "node:test" {
* @param implementation The function to be used as the mock's implementation for the invocation number specified by `onCall`.
* @param onCall The invocation number that will use `implementation`. If the specified invocation has already occurred then an exception is thrown.
*/
mockImplementationOnce(implementation: Function, onCall?: number): void;
mockImplementationOnce(implementation: F, onCall?: number): void;
/**
* Resets the call history of the mock function.
* @since v19.3.0, v18.13.0
Expand Down
61 changes: 43 additions & 18 deletions types/node/test/test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ run({
// TestsStream should be a NodeJS.ReadableStream
run().pipe(process.stdout);

test("foo", t => {
test("foo", (t) => {
// $ExpectType TestContext
t;
});
Expand Down Expand Up @@ -81,7 +81,7 @@ test((t, cb) => {
});

// Test the context's methods
test(undefined, undefined, t => {
test(undefined, undefined, (t) => {
// $ExpectType void
t.diagnostic("tap diagnostic");
// $ExpectType void
Expand All @@ -105,10 +105,10 @@ test(undefined, undefined, t => {
});

// Test the subtest approach.
test(t => {
test((t) => {
// $ExpectType TestContext
t;
const sub = t.test("sub", {}, t => {
const sub = t.test("sub", {}, (t) => {
// $ExpectType TestContext
t;
});
Expand Down Expand Up @@ -291,7 +291,7 @@ it.only("only shorthand", {
});

// Test with suite context
describe(s => {
describe((s) => {
// $ExpectType SuiteContext
s;
// $ExpectType string
Expand Down Expand Up @@ -377,6 +377,28 @@ test("mocks a counting function", (t) => {
fn();
});

test("mockImplementation takes the same function signature", (t) => {
function add(a: number, b: number) {
return a + b;
}

const fn = t.mock.fn(add);
fn.mock.mockImplementation((a, b) => {
// $ExpectType number
a;
// $ExpectType number
b;
return 0;
});
fn.mock.mockImplementationOnce((a, b) => {
// $ExpectType number
a;
// $ExpectType number
b;
return 0;
});
});

test("spies on an object method", (t) => {
const number = {
value: 5,
Expand Down Expand Up @@ -411,15 +433,15 @@ test("mocks an object method", (t) => {
},
};

function mockMethod(this: typeof obj, a: number) {
return a + this.prop;
function mockMethod(this: typeof obj, a: number, b: number) {
return a + b - this.prop;
}

const mocked = t.mock.method(obj, "method", mockMethod);
obj.method(1, 3);
const call = mocked.mock.calls[0];

// $ExpectType [a: number, b: number] | [a: number]
// $ExpectType [a: number, b: number]
call.arguments;
// $ExpectType number | undefined
call.result;
Expand Down Expand Up @@ -453,7 +475,10 @@ test("spies on a constructor", (t) => {
class Clazz extends ParentClazz {
#privateValue;

constructor(public a: number, b: number) {
constructor(
public a: number,
b: number,
) {
super(a + b);
this.a = a;
this.#privateValue = b;
Expand Down Expand Up @@ -496,9 +521,9 @@ test("spies on a getter", (t) => {
console.log(obj.method);
const call = getter.mock.calls[0];

// $ExpectType unknown[]
// $ExpectType []
call.arguments;
// $ExpectType unknown
// $ExpectType number | undefined
call.result;
// $ExpectType undefined
call.target;
Expand Down Expand Up @@ -538,9 +563,9 @@ test("mocks a getter", (t) => {
console.log(obj.method);
const call = getter.mock.calls[0];

// $ExpectType unknown[]
// $ExpectType []
call.arguments;
// $ExpectType unknown
// $ExpectType number | undefined
call.result;
// $ExpectType undefined
call.target;
Expand Down Expand Up @@ -576,9 +601,9 @@ test("spies on a setter", (t) => {
obj.method = 77;
const call = setter.mock.calls[0];

// $ExpectType unknown[]
// $ExpectType [value: number]
call.arguments;
// $ExpectType unknown
// $ExpectType void | undefined
call.result;
// $ExpectType undefined
call.target;
Expand Down Expand Up @@ -618,9 +643,9 @@ test("mocks a setter", (t) => {
obj.method = 77;
const call = setter.mock.calls[0];

// $ExpectType unknown[]
// $ExpectType [value: number]
call.arguments;
// $ExpectType unknown
// $ExpectType void | undefined
call.result;
// $ExpectType undefined
call.target;
Expand All @@ -632,7 +657,7 @@ test("mocks a setter", (t) => {
obj.method = 77;
const call = setter.mock.calls[0];

// $ExpectType [value: number] | [value: number]
// $ExpectType [value: number]
call.arguments;
// $ExpectType void | undefined
call.result;
Expand Down