test('.build() checks if already built, and returns early if true', () => { const mockContext = { built: true, initExtensions: sinon.spy(), }; WebGLKernel.prototype.build.apply(mockContext); assert.equal(mockContext.initExtensions.callCount, 0); });
test('setOutput() when needs to trigger recompile', () => { const mockInstance = { program: {}, texSize: [1, 1], toKernelOutput: GLKernel.prototype.toKernelOutput, dynamicOutput: true, getVariablePrecisionString: (textureSize) => { if (textureSize[0] === 1) return 'lowp'; return 'highp'; }, switchKernels: sinon.spy() }; GLKernel.prototype.setOutput.call(mockInstance, [100, 100]); assert.ok(mockInstance.switchKernels.callCount, 1); });
it('emits `end(request, contentSize)` event', done => { const onEnd = sinon.spy(); mockTemplate.returns( '<html><head></head><body><h2></h2></body></html>' ); tailor.on('end', onEnd); http.get('http://localhost:8080/template', response => { response.resume(); response.on('end', () => { const request = onEnd.args[0][0]; const contentSize = onEnd.args[0][1]; assert.equal(request.url, '/template'); assert.equal(contentSize, 48); assert.equal(onEnd.callCount, 1); 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(); }); }
it('should not trigger `response` and `end` if there was an `error`', done => { const onResponse = sinon.spy(); const onEnd = sinon.spy(); const onError = sinon.spy(); nock('https://fragment') .get('/') .reply(500); const fragment = new Fragment(getOptions(TAG)); fragment.on('response', onResponse); fragment.on('end', onEnd); fragment.on('error', onError); fragment.fetch(REQUEST); fragment.stream.on('end', () => { assert.equal(onResponse.callCount, 0); assert.equal(onEnd.callCount, 0); assert.equal(onError.callCount, 1); done(); }); fragment.stream.resume(); });
function testMutableLeak(mode) { const gpu = new GPU({ mode }); const kernel = gpu.createKernel(function() { return 1; }, { output: [1], pipeline: true }); kernel.build(); const cloneTextureSpy = sinon.spy(kernel.texture.constructor.prototype, 'beforeMutate'); const texture1 = kernel(); const texture2 = kernel(); assert.equal(cloneTextureSpy.callCount, 0); assert.equal(texture1.texture._refs, 1); assert.ok(texture1 === texture2); cloneTextureSpy.restore(); gpu.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(); }); }
it('emits `start(request)` event', done => { const onStart = sinon.spy(); nock('https://fragment') .get('/') .reply(200, 'hello'); mockTemplate.returns('<fragment src="https://fragment">'); tailor.on('start', onStart); http.get('http://localhost:8080/template', response => { response.resume(); response.on('end', () => { const request = onStart.args[0][0]; assert.equal(request.url, '/template'); assert.equal(onStart.callCount, 1); 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(); }); }
function testImmutableKernelTextureRecycling(precision, mode) { const gpu = new GPU({ mode }); const kernel = gpu.createKernel(function(v) { return v[0] + 1; }, { output: [1], pipeline: true, immutable: true, precision, }); let result = kernel([0]); const newTextureSpy = sinon.spy(kernel.texture.constructor.prototype, 'newTexture'); for (let i = 0; i < 10; i++) { let lastResult = result; result = kernel(result); lastResult.delete(); } assert.deepEqual(result.toArray(), new Float32Array([11])); assert.equal(newTextureSpy.callCount, 1); assert.equal(gpu.kernels.length, 2); newTextureSpy.restore(); gpu.destroy(); }
it('should not trigger error and response event when fallback is triggered', done => { const onFallback = sinon.spy(); const onError = sinon.spy(); nock('https://fragment') .get('/') .reply(500, 'Server Error'); nock('https://fallback-fragment') .get('/') .reply(200); const fragment = new Fragment(getOptions(TAG_FALLBACK)); fragment.on('fallback', onFallback); fragment.on('error', onError); fragment.stream.on('end', () => { assert.equal(onFallback.callCount, 1); assert.equal(onError.callCount, 0); done(); }); fragment.fetch(REQUEST); fragment.stream.resume(); });
it('emits `response(request, statusCode, headers)` event', done => { const onResponse = sinon.spy(); mockTemplate.returns('<html>'); tailor.on('response', onResponse); http.get('http://localhost:8080/template', response => { response.resume(); response.on('end', () => { const request = onResponse.args[0][0]; const statusCode = onResponse.args[0][1]; const headers = onResponse.args[0][2]; assert.equal(request.url, '/template'); assert.equal(statusCode, 200); assert.deepEqual(headers, { 'Cache-Control': 'no-cache, no-store, must-revalidate', 'Content-Type': 'text/html', Pragma: 'no-cache' }); assert.equal(onResponse.callCount, 1); done(); }); }); });
test('.build() checks if already built, and returns early if true', () => { const mockContext = { built: true, setupConstants: sinon.spy(), }; CPUKernel.prototype.build.apply(mockContext); assert.equal(mockContext.setupConstants.callCount, 0); });
it('should not trigger `response` and `end` for fallback fragment', done => { const onResponse = sinon.spy(); const onEnd = sinon.spy(); const onFallback = sinon.spy(); nock('https://fragment') .get('/') .reply(500); const fragment = new Fragment(getOptions(TAG_FALLBACK)); fragment.on('response', onResponse); fragment.on('end', onEnd); fragment.on('fallback', onFallback); fragment.fetch(REQUEST); fragment.stream.on('end', () => { assert.equal(onResponse.callCount, 0); assert.equal(onEnd.callCount, 0); assert.equal(onFallback.callCount, 1); done(); }); fragment.stream.resume(); });
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(); }); }