const noColor = globalThis.Deno?.noColor ?? true; const enabled = !noColor; function code(open, close) { return { open: `\x1b[${open.join(";")}m`, close: `\x1b[${close}m`, regexp: new RegExp(`\\x1b\\[${close}m`, "g"), }; } function run(str, code) { return enabled ? `${code.open}${str.replace(code.regexp, code.open)}${code.close}` : str; } function red(str) { return run(str, code([31], 39)); } export function green(str) { return run(str, code([32], 39)); } export function yellow(str) { return run(str, code([33], 39)); } const testResults = []; const testsExpectFail = JSON.parse(Deno.args[0]); function shouldExpectFail(name) { if (testsExpectFail.includes(name)) return true; for (const expectFail of testsExpectFail) { if (name.startsWith(expectFail)) return true; } return false; } window.add_result_callback(({ message, name, stack, status }) => { const expectFail = shouldExpectFail(name); let simpleMessage = `test ${name} ... `; switch (status) { case 0: if (expectFail) { simpleMessage += red("ok (expected fail)"); } else { simpleMessage += green("ok"); } break; case 1: if (expectFail) { simpleMessage += yellow("failed (expected)"); } else { simpleMessage += red("failed"); } break; case 2: if (expectFail) { simpleMessage += yellow("failed (expected)"); } else { simpleMessage += red("failed (timeout)"); } break; case 3: if (expectFail) { simpleMessage += yellow("failed (expected)"); } else { simpleMessage += red("failed (incomplete)"); } break; } console.log(simpleMessage); testResults.push({ name, passed: status === 0, expectFail, message, stack, }); }); window.add_completion_callback((tests, harnessStatus) => { const failed = testResults.filter((t) => !t.expectFail && !t.passed); const expectedFailedButPassed = testResults.filter((t) => t.expectFail && t.passed ); const expectedFailedButPassedCount = expectedFailedButPassed.length; const failedCount = failed.length + expectedFailedButPassedCount; const expectedFailedAndFailedCount = testResults.filter((t) => t.expectFail && !t.passed ).length; const totalCount = testResults.length; const passedCount = totalCount - failedCount - expectedFailedAndFailedCount; if (failed.length > 0) { console.log(`\nfailures:`); } for (const result of failed) { console.log( `\n${result.name}\n${result.message}\n${result.stack}`, ); } if (failed.length > 0) { console.log(`\nfailures:\n`); } for (const result of failed) { console.log(` ${result.name}`); } if (expectedFailedButPassedCount > 0) { console.log(`\nexpected failures that passed:\n`); } for (const result of expectedFailedButPassed) { console.log(` ${result.name}`); } console.log( `\ntest result: ${ failedCount > 0 ? red("failed") : green("ok") }. ${passedCount} passed; ${failedCount} failed; ${expectedFailedAndFailedCount} expected failure; total ${totalCount}\n`, ); Deno.exit(failedCount > 0 ? 1 : 0); });