// UUT.test.js import { timerUtils } from './old_timerUtils.js'; import { UUT } from './old_UUT.js'; import sinon from 'sinon'; import { expect } from 'chai'; const promiseResolvers = []; describe('Main Function Test', function() { beforeEach(function() { timerUtils.useFakeTimer(); console.log(UUT.subFunction) sinon.stub(UUT, 'subFunction').callsFake((index) => { console.log(`Stub: subFunction ${index} called, ${new Date().toISOString()}`); return new Promise((resolve) => { promiseResolvers.push(resolve); }); }); console.log(UUT.subFunction) }); afterEach(function() { timerUtils.restoreRealTimer(); promiseResolvers.length = 0; UUT.subFunction.restore(); }); it('should complete mainFunction with controlled promise resolution', async function() { const mainFunctionPromise = UUT.mainFunction(); let clock; // Ensure we advance time and resolve promises only after they are pushed for (let i = 1; i <= 5; i++) { console.log(`Test: Advancing fake timer for subfunction ${i}`); timerUtils.currentClock.tick(1000); // Advance time for each subfunction timerUtils.pauseFakeTimer(); await new Promise(resolve => setTimeout(resolve, 50)); // This does not resume the timer timerUtils.resumeFakeTimer(); // This resumes the timer // clock = sinon.useFakeTimers(); console.log(`Test: Resolving subfunction ${i}`); console.log(`Resolvers count ${promiseResolvers.length}, resolving at index: ${i-1}`) if (typeof promiseResolvers[i - 1] === 'function') { promiseResolvers[i - 1](); // Resolve the i-th subfunction's promise console.log("resolved") } else { throw new Error(`Resolver for subfunction ${i} is not a function`); } } console.log('Test: All subfunctions resolved, advancing time for the final wait'); timerUtils.currentClock.tick(2000); // Advance time for the final 2-second wait await mainFunctionPromise; console.log('Test: mainFunction should be completed now'); expect(UUT.subFunction.callCount).to.equal(5); }); });