diff --git a/graal-nodejs/lib/internal/test_runner/mock/mock.js b/graal-nodejs/lib/internal/test_runner/mock/mock.js index a704b41996e..838a530ddd4 100644 --- a/graal-nodejs/lib/internal/test_runner/mock/mock.js +++ b/graal-nodejs/lib/internal/test_runner/mock/mock.js @@ -45,19 +45,36 @@ class MockFunctionContext { this.#times = times; } + /** + * Gets an array of recorded calls made to the mock function. + * @returns {Array} An array of recorded calls. + */ get calls() { return ArrayPrototypeSlice(this.#calls, 0); } + /** + * Retrieves the number of times the mock function has been called. + * @returns {number} The call count. + */ callCount() { return this.#calls.length; } + /** + * Sets a new implementation for the mock function. + * @param {Function} implementation - The new implementation for the mock function. + */ mockImplementation(implementation) { validateFunction(implementation, 'implementation'); this.#implementation = implementation; } + /** + * Replaces the implementation of the function only once. + * @param {Function} implementation - The substitute function. + * @param {number} [onCall] - The call index to be replaced. + */ mockImplementationOnce(implementation, onCall) { validateFunction(implementation, 'implementation'); const nextCall = this.#calls.length; @@ -66,6 +83,9 @@ class MockFunctionContext { this.#mocks.set(call, implementation); } + /** + * Restores the original function that was mocked. + */ restore() { const { descriptor, object, original, methodName } = this.#restore; @@ -79,14 +99,25 @@ class MockFunctionContext { } } + /** + * Resets the recorded calls to the mock function + */ resetCalls() { this.#calls = []; } + /** + * Tracks a call made to the mock function. + * @param {object} call - The call details. + */ trackCall(call) { ArrayPrototypePush(this.#calls, call); } + /** + * Gets the next implementation to use for the mock function. + * @returns {Function} The next implementation. + */ nextImpl() { const nextCall = this.#calls.length; const mock = this.#mocks.get(nextCall); @@ -109,11 +140,23 @@ class MockTracker { #mocks = []; #timers; + /** + * Returns the mock timers of this MockTracker instance. + * @returns {MockTimers} The mock timers instance. + */ get timers() { this.#timers ??= new MockTimers(); return this.#timers; } + /** + * Creates a mock function tracker. + * @param {Function} [original] - The original function to be tracked. + * @param {Function} [implementation] - An optional replacement function for the original one. + * @param {object} [options] - Additional tracking options. + * @param {number} [options.times=Infinity] - The maximum number of times the mock function can be called. + * @returns {ProxyConstructor} The mock function tracker. + */ fn( original = function() {}, implementation = original, @@ -137,6 +180,17 @@ class MockTracker { return this.#setupMock(ctx, original); } + /** + * Creates a method tracker for a specified object or function. + * @param {(object | Function)} objectOrFunction - The object or function containing the method to be tracked. + * @param {string} methodName - The name of the method to be tracked. + * @param {Function} [implementation] - An optional replacement function for the original method. + * @param {object} [options] - Additional tracking options. + * @param {boolean} [options.getter=false] - Indicates whether this is a getter method. + * @param {boolean} [options.setter=false] - Indicates whether this is a setter method. + * @param {number} [options.times=Infinity] - The maximum number of times the mock method can be called. + * @returns {ProxyConstructor} The mock method tracker. + */ method( objectOrFunction, methodName, @@ -216,6 +270,18 @@ class MockTracker { return mock; } + /** + * Mocks a getter method of an object. + * This is a syntax sugar for the MockTracker.method with options.getter set to true + * @param {object} object - The target object. + * @param {string} methodName - The name of the getter method to be mocked. + * @param {Function} [implementation] - An optional replacement function for the targeted method. + * @param {object} [options] - Additional tracking options. + * @param {boolean} [options.getter=true] - Indicates whether this is a getter method. + * @param {boolean} [options.setter=false] - Indicates whether this is a setter method. + * @param {number} [options.times=Infinity] - The maximum number of times the mock method can be called. + * @returns {ProxyConstructor} The mock method tracker. + */ getter( object, methodName, @@ -244,6 +310,18 @@ class MockTracker { }); } + /** + * Mocks a setter method of an object. + * This function is a syntax sugar for MockTracker.method with options.setter set to true. + * @param {object} object - The target object. + * @param {string} methodName - The setter method to be mocked. + * @param {Function} [implementation] - An optional replacement function for the targeted method. + * @param {object} [options] - Additional tracking options. + * @param {boolean} [options.getter=false] - Indicates whether this is a getter method. + * @param {boolean} [options.setter=true] - Indicates whether this is a setter method. + * @param {number} [options.times=Infinity] - The maximum number of times the mock method can be called. + * @returns {ProxyConstructor} The mock method tracker. + */ setter( object, methodName, @@ -272,12 +350,18 @@ class MockTracker { }); } + /** + * Resets the mock tracker, restoring all mocks and clearing timers. + */ reset() { this.restoreAll(); this.#timers?.reset(); this.#mocks = []; } + /** + * Restore all mocks created by this MockTracker instance. + */ restoreAll() { for (let i = 0; i < this.#mocks.length; i++) { FunctionPrototypeCall(restore, this.#mocks[i]);