const { assert, test, module: describe, only } = require('qunit'); const { WebGLFunctionNode } = require(process.cwd() + '/src'); describe('WebGLFunctionNode.astCallExpression()'); test('handles Math.abs with floats', () => { const node = new WebGLFunctionNode(`function kernel(v) { return Math.abs(v); }`, { output: [1], argumentTypes: ['Number'] }); assert.equal(node.toString(), 'float kernel(float user_v) {' + '\nreturn abs(user_v);' + '\n}'); }); test('handles Math.abs with ints', () => { const node = new WebGLFunctionNode(`function kernel(v) { return Math.abs(v); }`, { output: [1], argumentTypes: ['Integer'] }); assert.equal(node.toString(), 'float kernel(int user_v) {' + '\nreturn abs(float(user_v));' + '\n}'); }); test('handles Math.pow with floats', () => { const node = new WebGLFunctionNode(`function kernel(v, v2) { return Math.pow(v, v2); }`, { output: [1], argumentTypes: ['Number', 'Number'] }); assert.equal(node.toString(), 'float kernel(float user_v, float user_v2) {' + '\nreturn _pow(user_v, user_v2);' + '\n}'); }); test('handles Math.pow with mixed 1', () => { const node = new WebGLFunctionNode(`function kernel(v, v2) { return Math.pow(v, v2); }`, { output: [1], argumentTypes: ['Number', 'Integer'] }); assert.equal(node.toString(), 'float kernel(float user_v, int user_v2) {' + '\nreturn _pow(user_v, float(user_v2));' + '\n}'); }); test('handles Math.pow with mixed 2', () => { const node = new WebGLFunctionNode(`function kernel(v, v2) { return Math.pow(v, v2); }`, { output: [1], argumentTypes: ['Integer', 'Number'] }); assert.equal(node.toString(), 'float kernel(int user_v, float user_v2) {' + '\nreturn _pow(float(user_v), user_v2);' + '\n}'); }); test('handles Math.pow with ints', () => { const node = new WebGLFunctionNode(`function kernel(v, v2) { return Math.pow(v, v2); }`, { output: [1], argumentTypes: ['Integer', 'Integer'] }); assert.equal(node.toString(), 'float kernel(int user_v, int user_v2) {' + '\nreturn _pow(float(user_v), float(user_v2));' + '\n}'); }); test('handles argument of type Input', () => { let lookupReturnTypeCalls = 0; let lookupFunctionArgumentTypes = 0; const node = new WebGLFunctionNode('function kernel(v) {' + '\n return childFunction(v);' + '\n}', { output: [1], argumentTypes: ['Input'], needsArgumentType: () => false, lookupReturnType: (functionName) => { lookupReturnTypeCalls++; if (functionName === 'childFunction') { return 'Number'; } throw new Error(`unhanded lookupReturnType for ${functionName}`); }, lookupFunctionArgumentTypes: (functionName) => { lookupFunctionArgumentTypes++; if (functionName === 'childFunction') { return ['Input']; } throw new Error(`unhanded lookupFunctionArgumentTypes for ${functionName}`); }, triggerImplyArgumentBitRatio: () => {}, assignArgumentType: () => {} }); assert.equal(node.toString(), 'float kernel(sampler2D user_v,ivec2 user_vSize,ivec3 user_vDim) {' + '\nreturn childFunction(user_v,user_vSize,user_vDim);' + '\n}'); assert.equal(lookupReturnTypeCalls, 2); assert.equal(lookupFunctionArgumentTypes, 1); }); test('handles argument of type HTMLImageArray', () => { let lookupReturnTypeCalls = 0; let lookupFunctionArgumentTypes = 0; const node = new WebGLFunctionNode('function kernel(v) {' + '\n return childFunction(v);' + '\n}', { output: [1], argumentTypes: ['HTMLImageArray'], needsArgumentType: () => false, lookupReturnType: (functionName) => { lookupReturnTypeCalls++; if (functionName === 'childFunction') { return 'Number'; } throw new Error(`unhanded lookupReturnType for ${functionName}`); }, lookupFunctionArgumentTypes: (functionName) => { lookupFunctionArgumentTypes++; if (functionName === 'childFunction') { return ['HTMLImageArray']; } throw new Error(`unhanded lookupFunctionArgumentTypes for ${functionName}`); }, triggerImplyArgumentBitRatio: () => {}, assignArgumentType: () => {} }); assert.equal(node.toString(), 'float kernel(sampler2DArray user_v,ivec2 user_vSize,ivec3 user_vDim) {' + '\nreturn childFunction(user_v,user_vSize,user_vDim);' + '\n}'); assert.equal(lookupReturnTypeCalls, 2); assert.equal(lookupFunctionArgumentTypes, 1); }); test('handles argument types of CallExpression that return arrays', () => { const node = new WebGLFunctionNode(`function kernel() { const p = [this.thread.x, this.thread.y]; const z = array2(array2(p, 0.01), 0.02); return 1.0; }`, { output: [1, 1], lookupReturnType: () => 'Number', needsArgumentType: () => false, lookupFunctionArgumentTypes: () => [], triggerImplyArgumentType: () => {} }); assert.equal(node.toString(), `float kernel() { vec2 user_p=vec2(threadId.x, threadId.y); float user_z=array2(array2(user_p, 0.01), 0.02); return 1.0; }`); });