UNPKG

zthreader

Version:

JavaScript library that provides pseudo-threading for leveraging resources during long, CPU intensive operations

125 lines (96 loc) 4.03 kB
/** * @jest-environment jsdom */ import zThreader from "../src/zThreader"; import zThread from "../src/zThread"; describe( "zThread", () => { const TIME_PER_ITERATION = 1; // amount of ms execution time we allow while testing thread runs beforeEach(() => { jest.useFakeTimers(); zThreader.init( 0.4, 60 ); }); afterEach(() => { jest.clearAllMocks(); jest.clearAllTimers(); }); it( "should be able to automatically add itself to the zThreader queue when run() is invoked for the first time", () => { jest.spyOn( zThreader, "add" ); const thread = new zThread(); expect( zThreader.add ).not.toHaveBeenCalled(); thread.run(); expect( zThreader.add ).toHaveBeenCalledWith( thread ); }); it( "should be able to automatically remove itself from the zThreader queue when stop() is invoked", () => { jest.spyOn( zThreader, "remove" ); const thread = new zThread(); thread.run(); expect( zThreader.remove ).not.toHaveBeenCalled(); thread.stop(); expect( zThreader.remove ).toHaveBeenCalledWith( thread ); }); it( "should be able to pause execution", () => { const thread = new zThread(); expect( thread.isExecutable() ).toBe( true ); thread.pause(); expect( thread.isExecutable() ).toBe( false ); thread.unpause(); expect( thread.isExecutable() ).toBe( true ); }); it( "should be able to suspend execution for a given timeout", () => { const thread = new zThread(); expect( thread.isExecutable() ).toBe( true ); thread.sleep( 1000 ); expect( thread.isExecutable() ).toBe( false ); jest.advanceTimersByTime( 500 ); expect( thread.isExecutable() ).toBe( false ); jest.advanceTimersByTime( 500 ); expect( thread.isExecutable() ).toBe( true ); }); it( "should call the configured execution function in iterations when running", () => { // create mock execution function that completes after three executions let executions = 0; const executionFn = jest.fn(() => { jest.advanceTimersByTime( TIME_PER_ITERATION ); if ( ++executions === 3 ) { return true; } return false; }); const thread = new zThread({ executionFn }); let completed = thread.execute( TIME_PER_ITERATION ); expect( completed ).toBe( false ); expect( executions ).toEqual( 1 ); completed = thread.execute( TIME_PER_ITERATION ); expect( completed ).toBe( false ); expect( executions ).toEqual( 2 ); completed = thread.execute( TIME_PER_ITERATION ); expect( completed ).toBe( true ); expect( executions ).toEqual( 3 ); }); it( "should call the optional complete handler on completion", () => { // create mock execution function that completes after two executions const completeFn = jest.fn(); let executions = 0; const executionFn = jest.fn(() => { jest.advanceTimersByTime( TIME_PER_ITERATION ); if ( ++executions === 2 ) { return true; } return false; }); const thread = new zThread({ completeFn, executionFn }); let completed = thread.execute( TIME_PER_ITERATION ); expect( completed ).toBe( false ); expect( completeFn ).not.toHaveBeenCalled(); completed = thread.execute( TIME_PER_ITERATION ); expect( completed ).toBe( true ); expect( completeFn ).toHaveBeenCalled(); }); it( "should call stop() to remove itself from the zThreader queue on completion", () => { const executionFn = jest.fn(() => true ); const thread = new zThread({ executionFn }); jest.spyOn( thread, "stop" ); thread.execute( Date.now() + 1 ); expect( thread.stop ).toHaveBeenCalled(); }); });