const { assert, skip, test, module: describe } = require('qunit'); const { GPU, WebGLKernel } = require('../../src'); const sinon = require('sinon'); describe('features: destroy'); function testWithoutDestroyContext(done, mode) { const gpu = new GPU({ mode }); const destroyKernel = sinon.spy(); gpu.kernels.push({ kernel: { constructor: { destroyContext: null } }, destroy: destroyKernel }); gpu.destroy(); gpu.destroy() .then(() => { assert.equal(destroyKernel.callCount, 2); assert.ok(true); done(); }); } test('without destroy context', (t) => { const done = t.async(); testWithoutDestroyContext(done); }); function testWithDestroyContext(done, mode) { const gpu = new GPU({ mode }); const destroyKernel = sinon.spy(); const destroyContextSpy = sinon.spy(); gpu.kernels.push({ kernel: { constructor: { destroyContext: destroyContextSpy } }, destroy: destroyKernel }); gpu.destroy(); gpu.destroy() .then(() => { assert.equal(destroyKernel.callCount, 2); assert.equal(destroyContextSpy.callCount, 2); assert.ok(true); done(); }); } test('with destroy context', (t) => { const done = t.async(); testWithDestroyContext(done); }); function testTexturesAreDestroyed(done, mode) { const mockTexture1 = {}; const mockTexture2 = {}; const mockTexture3 = {}; const deleteTextureMock = sinon.spy(); const mockContext = { deleteTexture: deleteTextureMock, }; const mockKernelInstance = { textureCache: [mockTexture1, mockTexture2, mockTexture3], context: mockContext, destroyExtensions: () => {}, }; mockKernelInstance.destroy = WebGLKernel.prototype.destroy.bind(mockKernelInstance); GPU.prototype.destroy.call({ kernels: [mockKernelInstance] }) .then(() => { assert.equal(deleteTextureMock.callCount, 3); assert.ok(true); done(); }); } test('textures are destroyed', (t) => { const done = t.async(); testTexturesAreDestroyed(done); }); function testKernelTextureIsDeleted(done) { const webGLTexture = {}; const mockTextureDelete = sinon.spy(); const kernelTexture = { texture: webGLTexture, delete: mockTextureDelete, }; const mockContext = {}; const mockKernelInstance = { texture: kernelTexture, textureCache: [], context: mockContext, destroyExtensions: () => {}, }; mockKernelInstance.destroy = WebGLKernel.prototype.destroy.bind(mockKernelInstance); GPU.prototype.destroy.call({ kernels: [mockKernelInstance] }) .then(() => { assert.equal(mockTextureDelete.callCount, 1); assert.ok(true); done(); }); } test('kernel.texture is deleted', (t) => { const done = t.async(); testKernelTextureIsDeleted(done); }); function testKernelMappedTexturesAreDeleted(done) { const mockGPU = { kernels: [] }; const webGLTexture1 = {}; const mockTextureDelete1 = sinon.spy(); const kernelTexture1 = { texture: webGLTexture1, delete: mockTextureDelete1, }; const webGLTexture2 = {}; const mockTextureDelete2 = sinon.spy(); const kernelTexture2 = { texture: webGLTexture2, delete: mockTextureDelete2, }; const mockContext = {}; const mockKernelInstance = { gpu: mockGPU, mappedTextures: [kernelTexture1, kernelTexture2], textureCache: [], context: mockContext, destroyExtensions: () => {}, }; mockGPU.kernels.push(mockKernelInstance); mockKernelInstance.destroy = WebGLKernel.prototype.destroy.bind(mockKernelInstance); GPU.prototype.destroy.call({ kernels: [mockKernelInstance] }) .then(() => { assert.equal(mockTextureDelete1.callCount, 1); assert.equal(mockTextureDelete2.callCount, 1); assert.equal(mockGPU.kernels.length, 0); assert.ok(true); done(); }) .catch((e) => { console.error(e); }); } test('kernel.mappedTextures are deleted', (t) => { const done = t.async(); testKernelMappedTexturesAreDeleted(done); }); test('gpu.kernels is populated and removed by kernel', () => { const gpu = new GPU(); const kernel = gpu.createKernel(function() { return 1; }); assert.equal(gpu.kernels.length, 1); assert.equal(gpu.kernels.indexOf(kernel.kernel), 0); kernel.destroy(); assert.equal(gpu.kernels.length, 0); gpu.destroy(); }); test('gpu.kernels is populated and removed by gpu', t => { const done = t.async(); const gpu = new GPU(); const kernel = gpu.createKernel(function() { return 1; }); assert.equal(gpu.kernels.length, 1); assert.equal(gpu.kernels.indexOf(kernel.kernel), 0); gpu.destroy() .then(() => { assert.equal(gpu.kernels.length, 0); done(); }); });