CoolFace
Apppublic

sanket3280/code-execution

sourceHugging Faceupdated 10mo agoView on Hugging Face
0likes
javascriptHarness.js189 linesDownload Raw Back to testHarness
1/**2 * JavaScript Test Harness Generator3 * Creates optimized test harness for JavaScript code execution4 */5 6const { getHelpers, extractFunctionName } = require('./baseHarness');7 8const createJavaScriptTestHarness = (sourceCode, testCases) => {9  let harness = '';10  11  const helpers = getHelpers(sourceCode, 'javascript');12  if (helpers) {13    harness += helpers + '\n\n';14  }15  16  harness += sourceCode + '\n\n';17  18  // Add deep copy helper function to prevent grid mutation19  harness += `20// Deep copy helper to prevent array mutation across test cases21function deepCopy(obj) {22  if (obj === null || typeof obj !== 'object') return obj;23  if (Array.isArray(obj)) return obj.map(item => deepCopy(item));24  const copy = {};25  for (const key in obj) {26    if (obj.hasOwnProperty(key)) {27      copy[key] = deepCopy(obj[key]);28    }29  }30  return copy;31}32\n\n`;33  34  harness += 'const testCases = [\n';35  36  testCases.forEach((testCase, index) => {37    const input = JSON.parse(testCase.input);38    const expected = testCase.expected;39    harness += `  { input: ${JSON.stringify(input)}, expected: ${JSON.stringify(expected)}, index: ${index} },\n`;40  });41  42  harness += '];\n\n';43  harness += createTestExecutionLogic(sourceCode);44  45  return harness;46};47 48/**49 * Create test execution logic50 */51const createTestExecutionLogic = (sourceCode) => {52  const functionName = extractFunctionName.javascript(sourceCode);53  54  return `55console.log('TEST_RESULTS_START');56 57for (let i = 0; i < testCases.length; i++) {58  const testCase = testCases[i];59  60  try {61    memo = {};62    cache = {};63    dp = [];64    65    // Check if this is a class-based problem (operations/values format)66    if (testCase.input.operations && testCase.input.values) {67      const operations = testCase.input.operations;68      const values = testCase.input.values;69      const results = [];70      let instance = null;71      72      for (let j = 0; j < operations.length; j++) {73        const op = operations[j];74        const args = values[j];75        76        if (j === 0) {77          // Constructor call78          instance = new (eval(op))(...args);79          results.push(null);80        } else {81          // Method call82          const result = instance[op](...args);83          results.push(result === undefined ? null : result);84        }85      }86      87      var result = results;88    } else {89      // Regular function call - with case-insensitive fallback90      const processedInput = {};91      for (const key in testCase.input) {92        const value = testCase.input[key];93        94        if (key === 'root' && Array.isArray(value)) {95          processedInput[key] = buildBinaryTree(value);96        } else if (key === 'lists' && Array.isArray(value) && value.length > 0 && Array.isArray(value[0])) {97          // Handle array of arrays (like mergeKLists) - convert each array to linked list98          processedInput[key] = value.map(arr => createLinkedList(arr));99        } else if (key.includes('list') && Array.isArray(value) && !Array.isArray(value[0])) {100          // Handle single linked list101          processedInput[key] = createLinkedList(value);102        } else if (Array.isArray(value)) {103          // Deep copy arrays (like grid) to prevent mutation across test cases104          processedInput[key] = deepCopy(value);105        } else {106          processedInput[key] = value;107        }108      }109      110      // Try exact function name first111      let targetFunction = typeof ${functionName} !== 'undefined' ? ${functionName} : null;112      113      // If not found, try case-insensitive search114      if (!targetFunction) {115        const expectedName = '${functionName}';116        const expectedLower = expectedName.toLowerCase();117        118        // Search for function with same name (case-insensitive)119        for (const key in globalThis) {120          if (typeof globalThis[key] === 'function' && key.toLowerCase() === expectedLower) {121            targetFunction = globalThis[key];122            if (i === 0) {123              console.error('WARNING: Function name case mismatch. Expected "' + expectedName + '" but found "' + key + '". Please use exact function name.');124            }125            break;126          }127        }128      }129      130      if (!targetFunction) {131        throw new Error('Function "${functionName}" not found. Please check function name spelling and capitalization.');132      }133      134      var result = targetFunction(...Object.values(processedInput));135    }136    137    let output;138    if (result && result.constructor && result.constructor.name === 'ListNode') {139      output = '[' + linkedListToArray(result).join(',') + ']';140    } else if (result === null && testCase.expected && testCase.expected.startsWith('[')) {141      output = '[]';142    } else if (Array.isArray(result)) {143      // Use JSON.stringify to properly handle null values144      output = JSON.stringify(result);145    } else if (typeof result === 'string') {146      output = JSON.stringify(result);147    } else if (result === null) {148      output = 'null';149    } else {150      output = String(result);151    }152    153    let expected;154    if (typeof testCase.expected === 'string' && 155        testCase.expected.startsWith('"') && 156        testCase.expected.endsWith('"')) {157      expected = testCase.expected;158    } else {159      expected = String(testCase.expected);160    }161    162    // Smart comparison: try numeric comparison first, then string163    let passed = output === expected;164    if (!passed) {165      const outputNum = parseFloat(output);166      const expectedNum = parseFloat(expected);167      if (!isNaN(outputNum) && !isNaN(expectedNum)) {168        // Use tolerance of 1e-5 (0.00001) for floating point comparison169        // This handles 5 decimal places precision170        const tolerance = 1e-5;171        passed = Math.abs(outputNum - expectedNum) < tolerance;172      }173    }174    175    console.log(\`TEST_\${i+1}:\${passed ? 'PASS' : 'FAIL'}:\${output}:\${expected}\`);176    177  } catch (error) {178    console.log(\`TEST_\${i+1}:ERROR:\${error.message}\`);179  }180}181 182console.log('TEST_RESULTS_END');183`;184};185 186module.exports = {187  createJavaScriptTestHarness188};189