codi-test-framework
Advanced tools
Comparing version 1.0.21 to 1.0.22
#!/usr/bin/env bun | ||
import { runCodi } from "./src/testRunner.js"; | ||
import { runCodi } from './src/testRunner.js'; | ||
console.log("CLI starting..."); | ||
console.log('CLI starting...'); | ||
try { | ||
await runCodi(); | ||
} catch (error) { | ||
console.error("Error running tests:", error); | ||
console.error('Error running tests:', error); | ||
} |
{ | ||
"excludeDirectories": [ | ||
"test", | ||
"avoidme" | ||
] | ||
} | ||
"excludeDirectories": ["test", "avoidme"] | ||
} |
{ | ||
"name": "codi-test-framework", | ||
"version": "1.0.21", | ||
"version": "1.0.22", | ||
"description": "A simple test framework for JavaScript", | ||
@@ -26,3 +26,6 @@ "type": "module", | ||
"figlet": "^1.7.0" | ||
}, | ||
"devDependencies": { | ||
"prettier": "^3.4.2" | ||
} | ||
} |
@@ -1,5 +0,5 @@ | ||
import assertions from "./assertions/_assertions.js"; | ||
import { describe } from "./core/describe.js"; | ||
import { it } from "./core/it.js"; | ||
import { state } from "./state/TestState.js"; | ||
import assertions from './assertions/_assertions.js'; | ||
import { describe } from './core/describe.js'; | ||
import { it } from './core/it.js'; | ||
import { state } from './state/TestState.js'; | ||
import { | ||
@@ -9,10 +9,14 @@ runWebTests, | ||
runWebTestFunction, | ||
} from "./runners/webRunner.js"; | ||
} from './runners/webRunner.js'; | ||
import { runTestFunction } from "./testRunner.js"; | ||
import { runTestFunction } from './testRunner.js'; | ||
import { codepenLogging } from "./codepen/logging.js"; | ||
import { codepenLogging } from './codepen/logging.js'; | ||
const version = "v1.0.21"; | ||
import { MockHttp } from './util/mockHtml.js'; | ||
import { MockModuleRegistry } from './util/mockModule.js'; | ||
const version = 'v1.0.22'; | ||
// Create the codi object to hold all exports | ||
@@ -35,2 +39,4 @@ const codi = { | ||
codepenLogging, | ||
MockHttp, | ||
MockModuleRegistry, | ||
}; | ||
@@ -37,0 +43,0 @@ |
@@ -1,16 +0,15 @@ | ||
import { assertEqual } from "./assertEqual.js"; | ||
import { assertNotEqual } from "./assertNotEqual.js"; | ||
import { assertTrue } from "./assertTrue.js"; | ||
import { assertFalse } from "./assertFalse.js"; | ||
import { assertThrows } from "./assertThrows.js"; | ||
import { assertNoDuplicates } from "./assertNoDuplicates.js"; | ||
import { assertEqual } from './assertEqual.js'; | ||
import { assertNotEqual } from './assertNotEqual.js'; | ||
import { assertTrue } from './assertTrue.js'; | ||
import { assertFalse } from './assertFalse.js'; | ||
import { assertThrows } from './assertThrows.js'; | ||
import { assertNoDuplicates } from './assertNoDuplicates.js'; | ||
export default { | ||
assertEqual, | ||
assertNotEqual, | ||
assertTrue, | ||
assertFalse, | ||
assertThrows, | ||
assertNoDuplicates | ||
} | ||
assertEqual, | ||
assertNotEqual, | ||
assertTrue, | ||
assertFalse, | ||
assertThrows, | ||
assertNoDuplicates, | ||
}; |
@@ -1,7 +0,10 @@ | ||
import chalk from "chalk"; | ||
import chalk from 'chalk'; | ||
export function assertEqual(actual, expected, message) { | ||
if (!isDeepEqual(actual, expected)) { | ||
throw new Error(message || `Expected ${chalk.bold.yellow(JSON.stringify(actual))} to deeply equal ${chalk.bold.yellow(JSON.stringify(expected))}`); | ||
} | ||
if (!isDeepEqual(actual, expected)) { | ||
throw new Error( | ||
message || | ||
`Expected ${chalk.bold.yellow(JSON.stringify(actual))} to deeply equal ${chalk.bold.yellow(JSON.stringify(expected))}`, | ||
); | ||
} | ||
} | ||
@@ -11,24 +14,29 @@ | ||
function isDeepEqual(obj1, obj2) { | ||
if (obj1 === obj2) { | ||
return true; | ||
} | ||
if (obj1 === obj2) { | ||
return true; | ||
} | ||
if (typeof obj1 !== 'object' || typeof obj2 !== 'object' || obj1 === null || obj2 === null) { | ||
return false; | ||
} | ||
if ( | ||
typeof obj1 !== 'object' || | ||
typeof obj2 !== 'object' || | ||
obj1 === null || | ||
obj2 === null | ||
) { | ||
return false; | ||
} | ||
const keys1 = Object.keys(obj1); | ||
const keys2 = Object.keys(obj2); | ||
const keys1 = Object.keys(obj1); | ||
const keys2 = Object.keys(obj2); | ||
if (keys1.length !== keys2.length) { | ||
return false; | ||
} | ||
if (keys1.length !== keys2.length) { | ||
return false; | ||
} | ||
for (const key of keys1) { | ||
if (!keys2.includes(key) || !isDeepEqual(obj1[key], obj2[key])) { | ||
return false; | ||
} | ||
for (const key of keys1) { | ||
if (!keys2.includes(key) || !isDeepEqual(obj1[key], obj2[key])) { | ||
return false; | ||
} | ||
} | ||
return true; | ||
} | ||
return true; | ||
} |
@@ -1,7 +0,9 @@ | ||
import chalk from "chalk"; | ||
import chalk from 'chalk'; | ||
export function assertFalse(actual, message) { | ||
if (actual !== false) { | ||
throw new Error(message || `Expected ${chalk.bold.yellow(actual)} to be false`); | ||
} | ||
} | ||
if (actual !== false) { | ||
throw new Error( | ||
message || `Expected ${chalk.bold.yellow(actual)} to be false`, | ||
); | ||
} | ||
} |
@@ -1,9 +0,9 @@ | ||
import chalk from "chalk"; | ||
import chalk from 'chalk'; | ||
export function assertNoDuplicates(arr, message) { | ||
//Filter array until for duplicate entries | ||
arr = arr.filter((item, index) => arr.indexOf(item) !== index) | ||
if (arr.length > 0) { | ||
throw new Error(message || `Duplicates found: ${chalk.bold.yellow(arr)}`); | ||
} | ||
} | ||
//Filter array until for duplicate entries | ||
arr = arr.filter((item, index) => arr.indexOf(item) !== index); | ||
if (arr.length > 0) { | ||
throw new Error(message || `Duplicates found: ${chalk.bold.yellow(arr)}`); | ||
} | ||
} |
@@ -1,7 +0,10 @@ | ||
import chalk from "chalk"; | ||
import chalk from 'chalk'; | ||
export function assertNotEqual(actual, expected, message) { | ||
if (actual === expected) { | ||
throw new Error(message || `Expected ${chalk.bold.yellow(actual)} not to equal ${chalk.bold.yellow(expected)}`); | ||
throw new Error( | ||
message || | ||
`Expected ${chalk.bold.yellow(actual)} not to equal ${chalk.bold.yellow(expected)}`, | ||
); | ||
} | ||
} | ||
} |
@@ -1,12 +0,15 @@ | ||
import chalk from "chalk"; | ||
import chalk from 'chalk'; | ||
export function assertThrows(callback, errorMessage, message) { | ||
try { | ||
callback(); | ||
throw new Error(message || 'Expected an error to be thrown'); | ||
} catch (error) { | ||
if (error.message !== errorMessage) { | ||
throw new Error(message || `Expected error message to be ${chalk.bold.yellow(errorMessage)}, but got ${chalk.bold.yellow(error.message)}`); | ||
} | ||
try { | ||
callback(); | ||
throw new Error(message || 'Expected an error to be thrown'); | ||
} catch (error) { | ||
if (error.message !== errorMessage) { | ||
throw new Error( | ||
message || | ||
`Expected error message to be ${chalk.bold.yellow(errorMessage)}, but got ${chalk.bold.yellow(error.message)}`, | ||
); | ||
} | ||
} | ||
} | ||
} |
@@ -1,7 +0,9 @@ | ||
import chalk from "chalk"; | ||
import chalk from 'chalk'; | ||
export function assertTrue(actual, message) { | ||
if (actual !== true) { | ||
throw new Error(message || `Expected ${chalk.bold.yellow(actual)} to be true`); | ||
} | ||
} | ||
if (actual !== true) { | ||
throw new Error( | ||
message || `Expected ${chalk.bold.yellow(actual)} to be true`, | ||
); | ||
} | ||
} |
// console-implementation.js | ||
export function codepenLogging() { | ||
var following = false, | ||
pre = document.createElement('pre'), | ||
code = document.createElement('code'); | ||
var following = false, | ||
pre = document.createElement('pre'), | ||
code = document.createElement('code'); | ||
pre.appendChild(code); | ||
document.body.appendChild(pre); | ||
pre.appendChild(code); | ||
document.body.appendChild(pre); | ||
// Capture the original console methods | ||
var originalConsole = { | ||
log: window.console.log, | ||
info: window.console.info, | ||
warn: window.console.warn, | ||
error: window.console.error | ||
}; | ||
// Capture the original console methods | ||
var originalConsole = { | ||
log: window.console.log, | ||
info: window.console.info, | ||
warn: window.console.warn, | ||
error: window.console.error, | ||
}; | ||
function clear() { | ||
while (code.hasChildNodes()) { | ||
code.removeChild(code.lastChild); | ||
} | ||
function clear() { | ||
while (code.hasChildNodes()) { | ||
code.removeChild(code.lastChild); | ||
} | ||
} | ||
function follow() { | ||
following = true; | ||
} | ||
function follow() { | ||
following = true; | ||
} | ||
function print(className, ...objects) { | ||
let s = objects.map(obj => { | ||
if (typeof obj === 'string') { | ||
return obj; | ||
} else { | ||
try { | ||
return JSON.stringify(obj); | ||
} catch (e) { | ||
return String(obj); | ||
} | ||
} | ||
}).join(' '); | ||
function print(className, ...objects) { | ||
let s = objects | ||
.map((obj) => { | ||
if (typeof obj === 'string') { | ||
return obj; | ||
} else { | ||
try { | ||
return JSON.stringify(obj); | ||
} catch (e) { | ||
return String(obj); | ||
} | ||
} | ||
}) | ||
.join(' '); | ||
// Remove only the ANSI escape sequences while keeping the text | ||
s = s.replace(/\[\d{1,2}m/g, ''); | ||
// Remove only the ANSI escape sequences while keeping the text | ||
s = s.replace(/\[\d{1,2}m/g, ''); | ||
var span = document.createElement('span'), | ||
text = document.createTextNode(s + '\n'); | ||
var span = document.createElement('span'), | ||
text = document.createTextNode(s + '\n'); | ||
span.setAttribute('class', className); | ||
span.appendChild(text); | ||
code.appendChild(span); | ||
span.setAttribute('class', className); | ||
span.appendChild(text); | ||
code.appendChild(span); | ||
if (following) { | ||
scrollToBottom(); | ||
} | ||
if (following) { | ||
scrollToBottom(); | ||
} | ||
} | ||
function scrollToBottom() { | ||
window.scrollTo(0, document.body.scrollHeight); | ||
} | ||
function scrollToBottom() { | ||
window.scrollTo(0, document.body.scrollHeight); | ||
} | ||
// Override the global console | ||
window.console = { | ||
clear: clear, | ||
follow: follow, | ||
log: function (...args) { | ||
print('debug', ...args); | ||
originalConsole.log(...args); | ||
}, | ||
info: function (...args) { | ||
print('info', ...args); | ||
originalConsole.info(...args); | ||
}, | ||
warn: function (...args) { | ||
print('warn', ...args); | ||
originalConsole.warn(...args); | ||
}, | ||
error: function (...args) { | ||
print('error', ...args); | ||
originalConsole.error(...args); | ||
} | ||
}; | ||
// Override the global console | ||
window.console = { | ||
clear: clear, | ||
follow: follow, | ||
log: function (...args) { | ||
print('debug', ...args); | ||
originalConsole.log(...args); | ||
}, | ||
info: function (...args) { | ||
print('info', ...args); | ||
originalConsole.info(...args); | ||
}, | ||
warn: function (...args) { | ||
print('warn', ...args); | ||
originalConsole.warn(...args); | ||
}, | ||
error: function (...args) { | ||
print('error', ...args); | ||
originalConsole.error(...args); | ||
}, | ||
}; | ||
return window.console; | ||
} | ||
return window.console; | ||
} |
@@ -13,25 +13,24 @@ import chalk from 'chalk'; | ||
export async function describe(params, callback) { | ||
const suite = { | ||
name: params.name, | ||
id: params.id, | ||
parentId: params.parentId, | ||
startTime: performance.now(), | ||
}; | ||
const suite = { | ||
name: params.name, | ||
id: params.id, | ||
parentId: params.parentId, | ||
startTime: performance.now() | ||
}; | ||
const nestedSuite = state.pushSuite(suite); | ||
const nestedSuite = state.pushSuite(suite); | ||
const suitePromise = (async () => { | ||
try { | ||
await Promise.resolve(callback(suite)); | ||
} catch (error) { | ||
console.error(chalk.red(`Suite failed: ${nestedSuite.fullPath}`)); | ||
console.error(chalk.red(error.stack)); | ||
} finally { | ||
nestedSuite.duration = performance.now() - nestedSuite.startTime; | ||
} | ||
})(); | ||
const suitePromise = (async () => { | ||
try { | ||
await Promise.resolve(callback(suite)); | ||
} catch (error) { | ||
console.error(chalk.red(`Suite failed: ${nestedSuite.fullPath}`)); | ||
console.error(chalk.red(error.stack)); | ||
} finally { | ||
nestedSuite.duration = performance.now() - nestedSuite.startTime; | ||
} | ||
})(); | ||
state.testTracker.addTest(suitePromise); | ||
return suitePromise; | ||
} | ||
state.testTracker.addTest(suitePromise); | ||
return suitePromise; | ||
} |
@@ -13,31 +13,31 @@ import { state } from '../state/TestState.js'; | ||
export async function it(params, callback) { | ||
const suite = state.getSuite(params.parentId); | ||
const suite = state.getSuite(params.parentId); | ||
if (!suite) { | ||
throw new Error(`test: ${params.name} needs to belong to a suite`); | ||
} | ||
if (!suite) { | ||
throw new Error(`test: ${params.name} needs to belong to a suite`); | ||
} | ||
const test = { | ||
name: params.name, | ||
startTime: performance.now() | ||
}; | ||
const test = { | ||
name: params.name, | ||
startTime: performance.now(), | ||
}; | ||
const testPromise = (async () => { | ||
try { | ||
await Promise.resolve(callback()); | ||
test.status = 'passed'; | ||
test.duration = performance.now() - test.startTime; | ||
state.passedTests++; | ||
} catch (error) { | ||
test.status = 'failed'; | ||
test.error = error; | ||
test.duration = performance.now() - test.startTime; | ||
state.failedTests++; | ||
} finally { | ||
state.addTestToSuite(suite, test); | ||
} | ||
})(); | ||
const testPromise = (async () => { | ||
try { | ||
await Promise.resolve(callback()); | ||
test.status = 'passed'; | ||
test.duration = performance.now() - test.startTime; | ||
state.passedTests++; | ||
} catch (error) { | ||
test.status = 'failed'; | ||
test.error = error; | ||
test.duration = performance.now() - test.startTime; | ||
state.failedTests++; | ||
} finally { | ||
state.addTestToSuite(suite, test); | ||
} | ||
})(); | ||
state.testTracker.addTest(testPromise); | ||
return testPromise; | ||
} | ||
state.testTracker.addTest(testPromise); | ||
return testPromise; | ||
} |
@@ -15,13 +15,15 @@ import fs from 'fs'; | ||
async function runTestFile(testFile) { | ||
try { | ||
const fileUrl = path.isAbsolute(testFile) | ||
? `file://${testFile}` | ||
: `file://${path.resolve(testFile)}`; | ||
try { | ||
const fileUrl = path.isAbsolute(testFile) | ||
? `file://${testFile}` | ||
: `file://${path.resolve(testFile)}`; | ||
await import(fileUrl); | ||
} catch (error) { | ||
console.error(chalk.red(`\nError running test file ${chalk.underline(testFile)}:`)); | ||
console.error(chalk.red(error.stack)); | ||
state.failedTests++; | ||
} | ||
await import(fileUrl); | ||
} catch (error) { | ||
console.error( | ||
chalk.red(`\nError running test file ${chalk.underline(testFile)}:`), | ||
); | ||
console.error(chalk.red(error.stack)); | ||
state.failedTests++; | ||
} | ||
} | ||
@@ -38,42 +40,52 @@ | ||
*/ | ||
export async function runTests(testDirectory, returnResults = false, codiConfig = {}, options = {}) { | ||
state.resetCounters(); | ||
state.startTimer(); | ||
state.setOptions(options); | ||
export async function runTests( | ||
testDirectory, | ||
returnResults = false, | ||
codiConfig = {}, | ||
options = {}, | ||
) { | ||
state.resetCounters(); | ||
state.startTimer(); | ||
state.setOptions(options); | ||
let testFiles = fs.readdirSync(testDirectory, { recursive: true }) | ||
.filter(file => file.endsWith('.mjs')); | ||
let testFiles = fs | ||
.readdirSync(testDirectory, { recursive: true }) | ||
.filter((file) => file.endsWith('.mjs')); | ||
if (codiConfig.excludeDirectories) { | ||
const matcher = excludePattern(codiConfig.excludeDirectories); | ||
testFiles = testFiles.filter(file => !matcher(file)); | ||
} | ||
if (codiConfig.excludeDirectories) { | ||
const matcher = excludePattern(codiConfig.excludeDirectories); | ||
testFiles = testFiles.filter((file) => !matcher(file)); | ||
} | ||
if (!options.quiet) { | ||
console.log(chalk.bold.magenta(`\nRunning tests in directory: ${chalk.underline(testDirectory)}`)); | ||
console.log(chalk.bold.magenta(`Found ${testFiles.length} test file(s)\n`)); | ||
} | ||
if (!options.quiet) { | ||
console.log( | ||
chalk.bold.magenta( | ||
`\nRunning tests in directory: ${chalk.underline(testDirectory)}`, | ||
), | ||
); | ||
console.log(chalk.bold.magenta(`Found ${testFiles.length} test file(s)\n`)); | ||
} | ||
for (const file of testFiles) { | ||
await runTestFile(path.join(testDirectory, file)); | ||
} | ||
for (const file of testFiles) { | ||
await runTestFile(path.join(testDirectory, file)); | ||
} | ||
state.printSummary(); | ||
state.printSummary(); | ||
if (returnResults) { | ||
return { | ||
passedTests: state.passedTests, | ||
failedTests: state.failedTests, | ||
suiteStack: state.suiteStack, | ||
executionTime: state.getExecutionTime() | ||
}; | ||
} | ||
if (returnResults) { | ||
return { | ||
passedTests: state.passedTests, | ||
failedTests: state.failedTests, | ||
suiteStack: state.suiteStack, | ||
executionTime: state.getExecutionTime(), | ||
}; | ||
} | ||
if (state.failedTests > 0) { | ||
console.log(chalk.red(`\n${state.failedTests} tests failed.`)); | ||
process.exit(1); | ||
} else { | ||
console.log(chalk.green(`\n${state.passedTests} tests passed.`)); | ||
process.exit(0); | ||
} | ||
if (state.failedTests > 0) { | ||
console.log(chalk.red(`\n${state.failedTests} tests failed.`)); | ||
process.exit(1); | ||
} else { | ||
console.log(chalk.green(`\n${state.passedTests} tests passed.`)); | ||
process.exit(0); | ||
} | ||
} | ||
@@ -89,15 +101,14 @@ | ||
export async function runTestFunction(testFn) { | ||
try { | ||
await Promise.resolve(testFn()); | ||
} catch (error) { | ||
console.error(`Error in test ${testFn.name}:`, error); | ||
state.failedTests++; | ||
} | ||
try { | ||
await Promise.resolve(testFn()); | ||
} catch (error) { | ||
console.error(`Error in test ${testFn.name}:`, error); | ||
state.failedTests++; | ||
} | ||
return { | ||
passedTests: state.passedTests, | ||
failedTests: state.failedTests, | ||
suiteStack: state.suiteStack | ||
}; | ||
} | ||
return { | ||
passedTests: state.passedTests, | ||
failedTests: state.failedTests, | ||
suiteStack: state.suiteStack, | ||
}; | ||
} |
@@ -13,19 +13,16 @@ import { state } from '../state/TestState.js'; | ||
export async function runWebTestFile(testFile, options) { | ||
const defaults = { | ||
silent: false, | ||
}; | ||
const defaults = { | ||
silent: false | ||
}; | ||
options ??= defaults; | ||
options ??= defaults; | ||
try { | ||
const testPromise = import(testFile); | ||
await Promise.resolve(testPromise); | ||
} catch (error) { | ||
console.error(`Error running test file ${testFile}:`); | ||
console.error(error.stack); | ||
state.failedTests++; | ||
} | ||
try { | ||
const testPromise = import(testFile); | ||
await Promise.resolve(testPromise); | ||
} catch (error) { | ||
console.error(`Error running test file ${testFile}:`); | ||
console.error(error.stack); | ||
state.failedTests++; | ||
} | ||
} | ||
@@ -42,39 +39,40 @@ | ||
export async function runWebTests(testFiles, options) { | ||
const defaults = { | ||
quiet: false, | ||
showSummary: true, | ||
}; | ||
const defaults = { | ||
quiet: false, | ||
showSummary: true | ||
} | ||
options ??= defaults; | ||
options ??= defaults; | ||
state.resetCounters(); | ||
state.startTimer(); | ||
state.resetCounters(); | ||
state.startTimer(); | ||
if (!options.quiet) { | ||
console.log( | ||
chalk.bold.magenta(`\nRunning ${testFiles.length} web test file(s)`), | ||
); | ||
} | ||
if (!options.quiet) { | ||
console.log(chalk.bold.magenta(`\nRunning ${testFiles.length} web test file(s)`)); | ||
try { | ||
for (const file of testFiles) { | ||
await runWebTestFile(file, options); | ||
} | ||
} catch (error) { | ||
console.error(chalk.red('\nTest execution failed:')); | ||
console.error(chalk.red(error.stack)); | ||
} | ||
try { | ||
for (const file of testFiles) { | ||
await runWebTestFile(file, options); | ||
} | ||
} catch (error) { | ||
console.error(chalk.red('\nTest execution failed:')); | ||
console.error(chalk.red(error.stack)); | ||
} | ||
const summary = { | ||
totalTests: state.passedTests + state.failedTests, | ||
passedTests: state.passedTests, | ||
failedTests: state.failedTests, | ||
executionTime: state.getExecutionTime(), | ||
suiteStack: state.suiteStack, | ||
}; | ||
const summary = { | ||
totalTests: state.passedTests + state.failedTests, | ||
passedTests: state.passedTests, | ||
failedTests: state.failedTests, | ||
executionTime: state.getExecutionTime(), | ||
suiteStack: state.suiteStack | ||
}; | ||
if (options.showSummary) { | ||
state.printSummary(); | ||
} | ||
if (options.showSummary) { | ||
state.printSummary(); | ||
} | ||
return summary; | ||
return summary; | ||
} | ||
@@ -90,28 +88,27 @@ | ||
export async function runWebTestFunction(testFn, options) { | ||
options ??= { | ||
quiet: false, | ||
showSummary: true, | ||
}; | ||
options ??= { | ||
quiet: false, | ||
showSummary: true | ||
}; | ||
state.setOptions(options); | ||
state.setOptions(options); | ||
try { | ||
await Promise.resolve(testFn()); | ||
// Wait for all pending tests to complete | ||
await state.testTracker.waitForAll(); | ||
} catch (error) { | ||
console.error('Error in test suite:', error); | ||
state.failedTests++; | ||
} | ||
try { | ||
await Promise.resolve(testFn()); | ||
// Wait for all pending tests to complete | ||
await state.testTracker.waitForAll(); | ||
} catch (error) { | ||
console.error('Error in test suite:', error); | ||
state.failedTests++; | ||
} | ||
if (options.showSummary) { | ||
state.printSummary(); | ||
} | ||
if (options.showSummary) { | ||
state.printSummary(); | ||
} | ||
return { | ||
passedTests: state.passedTests, | ||
failedTests: state.failedTests, | ||
suiteStack: state.suiteStack | ||
}; | ||
} | ||
return { | ||
passedTests: state.passedTests, | ||
failedTests: state.failedTests, | ||
suiteStack: state.suiteStack, | ||
}; | ||
} |
@@ -1,2 +0,2 @@ | ||
import chalk from "chalk"; | ||
import chalk from 'chalk'; | ||
/** | ||
@@ -47,3 +47,3 @@ * Class representing the state of test execution | ||
pushSuite(suite) { | ||
let parentSuite = ""; | ||
let parentSuite = ''; | ||
// Get parent suite if exists | ||
@@ -147,3 +147,3 @@ if (suite.parentId) { | ||
console.log(chalk.bold.cyan("\nTest Summary:")); | ||
console.log(chalk.bold.cyan('\nTest Summary:')); | ||
console.log(chalk.green(` Passed: ${this.passedTests}`)); | ||
@@ -169,3 +169,3 @@ console.log(chalk.red(` Failed: ${this.failedTests}`)); | ||
const printSuite = (suite, indent, options) => { | ||
const indentation = " ".repeat(indent); | ||
const indentation = ' '.repeat(indent); | ||
@@ -176,3 +176,3 @@ // Print suite's tests | ||
if (options.quiet) { | ||
results = results.filter((result) => result.status === "failed"); | ||
results = results.filter((result) => result.status === 'failed'); | ||
} | ||
@@ -182,3 +182,3 @@ | ||
// Base case: check current suite's tests | ||
if (suite.tests?.some((test) => test.status === "failed")) { | ||
if (suite.tests?.some((test) => test.status === 'failed')) { | ||
return true; | ||
@@ -202,7 +202,7 @@ } | ||
if ((suite.children.length > 0 && hasFailingChildren) || results.length > 0) { | ||
console.log("\n" + indentation + chalk.yellow(chalk.bold(suite.name))); | ||
console.log('\n' + indentation + chalk.yellow(chalk.bold(suite.name))); | ||
} | ||
results.forEach((result) => { | ||
if (result.status === "failed") { | ||
if (result.status === 'failed') { | ||
console.log( | ||
@@ -209,0 +209,0 @@ indentation + |
@@ -7,6 +7,3 @@ import chalk from 'chalk'; | ||
// Runner exports - re-export everything | ||
export { | ||
runTests, | ||
runTestFunction | ||
} from './runners/nodeRunner.js'; | ||
export { runTests, runTestFunction } from './runners/nodeRunner.js'; | ||
@@ -28,5 +25,6 @@ import { version } from './_codi.js'; | ||
const configPath = configPathIndex !== -1 | ||
? process.argv[configPathIndex + 1] | ||
: path.join(process.cwd(), 'codi.json'); | ||
const configPath = | ||
configPathIndex !== -1 | ||
? process.argv[configPathIndex + 1] | ||
: path.join(process.cwd(), 'codi.json'); | ||
@@ -51,3 +49,7 @@ if (returnVersion) { | ||
if (!quiet) { | ||
console.log(chalk.yellow(`No config file found at ${configPath}, proceeding with default settings`)); | ||
console.log( | ||
chalk.yellow( | ||
`No config file found at ${configPath}, proceeding with default settings`, | ||
), | ||
); | ||
} | ||
@@ -63,2 +65,2 @@ } | ||
await nodeRunTests(testDirectory, returnResults, codiConfig, { quiet }); | ||
} | ||
} |
export function excludePattern(patterns) { | ||
return (path) => { | ||
return patterns.some(pattern => { | ||
// Normalize path separators | ||
const normalizedPattern = pattern.replace(/[\\/]+/g, '/'); | ||
const normalizedPath = path.replace(/[\\/]+/g, '/'); | ||
return (path) => { | ||
return patterns.some((pattern) => { | ||
// Normalize path separators | ||
const normalizedPattern = pattern.replace(/[\\/]+/g, '/'); | ||
const normalizedPath = path.replace(/[\\/]+/g, '/'); | ||
// Escape special regex characters in the pattern | ||
const regexPattern = normalizedPattern | ||
.replace(/[.*+?^${}()|[\]\\]/g, '\\$&') | ||
.replace(/\//g, '[\\\\/]'); // Allow both / and \ as separators | ||
// Escape special regex characters in the pattern | ||
const regexPattern = normalizedPattern | ||
.replace(/[.*+?^${}()|[\]\\]/g, '\\$&') | ||
.replace(/\//g, '[\\\\/]'); // Allow both / and \ as separators | ||
// Create a regex that matches the pattern at the start, optionally followed by a separator | ||
const regex = new RegExp(`^${regexPattern}($|[\\\\/])`); | ||
return regex.test(normalizedPath); | ||
}); | ||
}; | ||
} | ||
// Create a regex that matches the pattern at the start, optionally followed by a separator | ||
const regex = new RegExp(`^${regexPattern}($|[\\\\/])`); | ||
return regex.test(normalizedPath); | ||
}); | ||
}; | ||
} |
@@ -7,3 +7,4 @@ // Import and run tests | ||
// Main test execution | ||
await codi.runWebTestFunction(async () => { | ||
await codi.runWebTestFunction( | ||
async () => { | ||
// Sequential setup tests | ||
@@ -13,28 +14,28 @@ await setupTests(); | ||
// Parallel test batches | ||
await Promise.all([ | ||
batchOne(), | ||
batchTwo(), | ||
batchThree(), | ||
batchFour() | ||
]); | ||
}, { | ||
await Promise.all([batchOne(), batchTwo(), batchThree(), batchFour()]); | ||
}, | ||
{ | ||
quiet: false, // Changed to false to ensure output | ||
showSummary: true | ||
}); | ||
showSummary: true, | ||
}, | ||
); | ||
// Sequential setup tests | ||
async function setupTests() { | ||
codi.describe({ name: 'Setup Tests', id: 'setup' }, async () => { | ||
codi.it({ name: 'Should initilise setup', parentId: 'setup' }, async () => { | ||
await simulateDelay(250); | ||
codi.assertEqual(true, true, 'Workspace initialized'); | ||
console.log('Test 1') | ||
}); | ||
codi.describe({ name: 'Setup Tests', id: 'setup' }, async () => { | ||
codi.it({ name: 'Should initilise setup', parentId: 'setup' }, async () => { | ||
await simulateDelay(250); | ||
codi.assertEqual(true, true, 'Workspace initialized'); | ||
console.log('Test 1'); | ||
}); | ||
codi.it({ name: 'Should do some more setup', parentId: 'setup' }, async () => { | ||
await simulateDelay(150); | ||
codi.assertEqual(true, true, 'Query system ready'); | ||
console.log('Test 2') | ||
}); | ||
}); | ||
codi.it( | ||
{ name: 'Should do some more setup', parentId: 'setup' }, | ||
async () => { | ||
await simulateDelay(150); | ||
codi.assertEqual(true, true, 'Query system ready'); | ||
console.log('Test 2'); | ||
}, | ||
); | ||
}); | ||
} | ||
@@ -44,21 +45,21 @@ | ||
async function batchOne() { | ||
codi.describe({ name: 'batch_1', id: '1' }, async () => { | ||
await Promise.all([ | ||
codi.it({ name: 'Test 1.1', parentId: '1' }, async () => { | ||
await simulateDelay(100); | ||
codi.assertEqual(true, true, 'Test 1.1 passed'); | ||
console.log('Test 4') | ||
}), | ||
codi.it({ name: 'Test 1.2', parentId: '1' }, async () => { | ||
await simulateDelay(75); | ||
codi.assertEqual(true, true, 'Test 1.2 passed'); | ||
console.log('Test 5') | ||
}), | ||
codi.it({ name: 'Test 1.3', parentId: '1' }, async () => { | ||
await simulateDelay(50); | ||
codi.assertEqual(false, false, 'Test 1.3 passed'); | ||
console.log('Test 6') | ||
}) | ||
]); | ||
}); | ||
codi.describe({ name: 'batch_1', id: '1' }, async () => { | ||
await Promise.all([ | ||
codi.it({ name: 'Test 1.1', parentId: '1' }, async () => { | ||
await simulateDelay(100); | ||
codi.assertEqual(true, true, 'Test 1.1 passed'); | ||
console.log('Test 4'); | ||
}), | ||
codi.it({ name: 'Test 1.2', parentId: '1' }, async () => { | ||
await simulateDelay(75); | ||
codi.assertEqual(true, true, 'Test 1.2 passed'); | ||
console.log('Test 5'); | ||
}), | ||
codi.it({ name: 'Test 1.3', parentId: '1' }, async () => { | ||
await simulateDelay(50); | ||
codi.assertEqual(false, false, 'Test 1.3 passed'); | ||
console.log('Test 6'); | ||
}), | ||
]); | ||
}); | ||
} | ||
@@ -68,21 +69,21 @@ | ||
async function batchTwo() { | ||
codi.describe({ name: 'batch_2', id: '2', parentId: '1' }, async () => { | ||
Promise.all([ | ||
codi.it({ name: 'Test 2.1', parentId: '2' }, async () => { | ||
await simulateDelay(125); | ||
codi.assertEqual(true, true, 'Test 2.1 passed'); | ||
console.log('Test 7') | ||
}), | ||
codi.it({ name: 'Test 2.2', parentId: '2' }, async () => { | ||
await simulateDelay(150); | ||
codi.assertEqual(1, 2, 'This test should fail'); | ||
console.log('Test 8') | ||
}), | ||
codi.it({ name: 'Test 2.3', parentId: '2' }, async () => { | ||
await simulateDelay(175); | ||
codi.assertEqual(true, true, 'Test 2.3 passed'); | ||
console.log('Test 9') | ||
}) | ||
]); | ||
}); | ||
codi.describe({ name: 'batch_2', id: '2', parentId: '1' }, async () => { | ||
Promise.all([ | ||
codi.it({ name: 'Test 2.1', parentId: '2' }, async () => { | ||
await simulateDelay(125); | ||
codi.assertEqual(true, true, 'Test 2.1 passed'); | ||
console.log('Test 7'); | ||
}), | ||
codi.it({ name: 'Test 2.2', parentId: '2' }, async () => { | ||
await simulateDelay(150); | ||
codi.assertEqual(1, 2, 'This test should fail'); | ||
console.log('Test 8'); | ||
}), | ||
codi.it({ name: 'Test 2.3', parentId: '2' }, async () => { | ||
await simulateDelay(175); | ||
codi.assertEqual(true, true, 'Test 2.3 passed'); | ||
console.log('Test 9'); | ||
}), | ||
]); | ||
}); | ||
} | ||
@@ -92,47 +93,47 @@ | ||
async function batchThree() { | ||
codi.describe({ name: 'batch_3', id: '3', parentId: '2' }, async () => { | ||
await Promise.all([ | ||
codi.it({ name: 'Test 3.1', parentId: '3' }, async () => { | ||
await simulateDelay(200); | ||
codi.assertEqual(true, true, 'Test 3.1 passed'); | ||
console.log('Test 10') | ||
}), | ||
codi.it({ name: 'Test 3.2', parentId: '3' }, async () => { | ||
await simulateDelay(225); | ||
codi.assertEqual(true, true, 'Test 4.2 passed'); | ||
console.log('Test 11') | ||
}), | ||
codi.it({ name: 'Test 3.3', parentId: '3' }, async () => { | ||
await simulateDelay(250); | ||
codi.assertEqual({ a: 1 }, { a: 1 }, 'Test 3.3 passed'); | ||
console.log('Test 12') | ||
}) | ||
]); | ||
}); | ||
codi.describe({ name: 'batch_3', id: '3', parentId: '2' }, async () => { | ||
await Promise.all([ | ||
codi.it({ name: 'Test 3.1', parentId: '3' }, async () => { | ||
await simulateDelay(200); | ||
codi.assertEqual(true, true, 'Test 3.1 passed'); | ||
console.log('Test 10'); | ||
}), | ||
codi.it({ name: 'Test 3.2', parentId: '3' }, async () => { | ||
await simulateDelay(225); | ||
codi.assertEqual(true, true, 'Test 4.2 passed'); | ||
console.log('Test 11'); | ||
}), | ||
codi.it({ name: 'Test 3.3', parentId: '3' }, async () => { | ||
await simulateDelay(250); | ||
codi.assertEqual({ a: 1 }, { a: 1 }, 'Test 3.3 passed'); | ||
console.log('Test 12'); | ||
}), | ||
]); | ||
}); | ||
} | ||
async function batchFour() { | ||
codi.describe({ name: 'batch_4', id: '4', parentId: '3' }, async () => { | ||
await Promise.all([ | ||
codi.it({ name: 'Test 4.1', parentId: '4' }, async () => { | ||
await simulateDelay(900); | ||
codi.assertEqual(true, true, 'Test 4.1 passed'); | ||
console.log('Test 13') | ||
}), | ||
codi.it({ name: 'Test 4.2', parentId: '4' }, async () => { | ||
await simulateDelay(3600); | ||
codi.assertEqual(true, true, 'Test 4.2 passed'); | ||
console.log('Test 14') | ||
}), | ||
codi.it({ name: 'Test 4.3', parentId: '4' }, async () => { | ||
await simulateDelay(500); | ||
codi.assertEqual({ a: 1 }, { a: 2 }, 'Test 4.3 failed'); | ||
console.log('Test 15') | ||
}) | ||
]); | ||
}); | ||
codi.describe({ name: 'batch_4', id: '4', parentId: '3' }, async () => { | ||
await Promise.all([ | ||
codi.it({ name: 'Test 4.1', parentId: '4' }, async () => { | ||
await simulateDelay(900); | ||
codi.assertEqual(true, true, 'Test 4.1 passed'); | ||
console.log('Test 13'); | ||
}), | ||
codi.it({ name: 'Test 4.2', parentId: '4' }, async () => { | ||
await simulateDelay(3600); | ||
codi.assertEqual(true, true, 'Test 4.2 passed'); | ||
console.log('Test 14'); | ||
}), | ||
codi.it({ name: 'Test 4.3', parentId: '4' }, async () => { | ||
await simulateDelay(500); | ||
codi.assertEqual({ a: 1 }, { a: 2 }, 'Test 4.3 failed'); | ||
console.log('Test 15'); | ||
}), | ||
]); | ||
}); | ||
} | ||
function simulateDelay(ms) { | ||
return new Promise(resolve => setTimeout(resolve, ms)); | ||
} | ||
return new Promise((resolve) => setTimeout(resolve, ms)); | ||
} |
@@ -1,3 +0,3 @@ | ||
import { runWebTestFunction } from "../src/runners/webRunner.js"; | ||
import { describe, it, assertEqual } from "../src/_codi.js"; | ||
import { runWebTestFunction } from '../src/runners/webRunner.js'; | ||
import { describe, it, assertEqual } from '../src/_codi.js'; | ||
@@ -28,13 +28,13 @@ // Main test execution | ||
async function setupTests() { | ||
describe({ name: "Setup Tests", id: "setup" }, async () => { | ||
it({ name: "Should initilise setup", parentId: "setup" }, async () => { | ||
describe({ name: 'Setup Tests', id: 'setup' }, async () => { | ||
it({ name: 'Should initilise setup', parentId: 'setup' }, async () => { | ||
await simulateDelay(250); | ||
assertEqual(true, true, "Workspace initialized"); | ||
console.log("Test 1"); | ||
assertEqual(true, true, 'Workspace initialized'); | ||
console.log('Test 1'); | ||
}); | ||
it({ name: "Should do some more setup", parentId: "setup" }, async () => { | ||
it({ name: 'Should do some more setup', parentId: 'setup' }, async () => { | ||
await simulateDelay(150); | ||
assertEqual(true, true, "Query system ready"); | ||
console.log("Test 2"); | ||
assertEqual(true, true, 'Query system ready'); | ||
console.log('Test 2'); | ||
}); | ||
@@ -46,18 +46,18 @@ }); | ||
async function batchOne() { | ||
describe({ name: "batch_1", id: "1" }, async () => { | ||
describe({ name: 'batch_1', id: '1' }, async () => { | ||
await Promise.all([ | ||
it({ name: "Test 1.1", parentId: "1" }, async () => { | ||
it({ name: 'Test 1.1', parentId: '1' }, async () => { | ||
await simulateDelay(100); | ||
assertEqual(true, true, "Test 1.1 passed"); | ||
console.log("Test 4"); | ||
assertEqual(true, true, 'Test 1.1 passed'); | ||
console.log('Test 4'); | ||
}), | ||
it({ name: "Test 1.2", parentId: "1" }, async () => { | ||
it({ name: 'Test 1.2', parentId: '1' }, async () => { | ||
await simulateDelay(75); | ||
assertEqual(true, true, "Test 1.2 passed"); | ||
console.log("Test 5"); | ||
assertEqual(true, true, 'Test 1.2 passed'); | ||
console.log('Test 5'); | ||
}), | ||
it({ name: "Test 1.3", parentId: "1" }, async () => { | ||
it({ name: 'Test 1.3', parentId: '1' }, async () => { | ||
await simulateDelay(50); | ||
assertEqual(false, false, "Test 1.3 passed"); | ||
console.log("Test 6"); | ||
assertEqual(false, false, 'Test 1.3 passed'); | ||
console.log('Test 6'); | ||
}), | ||
@@ -70,18 +70,18 @@ ]); | ||
async function batchTwo() { | ||
describe({ name: "batch_2", id: "2", parentId: "1" }, async () => { | ||
describe({ name: 'batch_2', id: '2', parentId: '1' }, async () => { | ||
Promise.all([ | ||
it({ name: "Test 2.1", parentId: "2" }, async () => { | ||
it({ name: 'Test 2.1', parentId: '2' }, async () => { | ||
await simulateDelay(125); | ||
assertEqual(true, true, "Test 2.1 passed"); | ||
console.log("Test 7"); | ||
assertEqual(true, true, 'Test 2.1 passed'); | ||
console.log('Test 7'); | ||
}), | ||
it({ name: "Test 2.2", parentId: "2" }, async () => { | ||
it({ name: 'Test 2.2', parentId: '2' }, async () => { | ||
await simulateDelay(150); | ||
assertEqual(1, 2, "This test should fail"); | ||
console.log("Test 8"); | ||
assertEqual(1, 2, 'This test should fail'); | ||
console.log('Test 8'); | ||
}), | ||
it({ name: "Test 2.3", parentId: "2" }, async () => { | ||
it({ name: 'Test 2.3', parentId: '2' }, async () => { | ||
await simulateDelay(175); | ||
assertEqual(true, true, "Test 2.3 passed"); | ||
console.log("Test 9"); | ||
assertEqual(true, true, 'Test 2.3 passed'); | ||
console.log('Test 9'); | ||
}), | ||
@@ -94,18 +94,18 @@ ]); | ||
async function batchThree() { | ||
describe({ name: "batch_3", id: "3", parentId: "2" }, async () => { | ||
describe({ name: 'batch_3', id: '3', parentId: '2' }, async () => { | ||
await Promise.all([ | ||
it({ name: "Test 3.1", parentId: "3" }, async () => { | ||
it({ name: 'Test 3.1', parentId: '3' }, async () => { | ||
await simulateDelay(200); | ||
assertEqual(true, true, "Test 3.1 passed"); | ||
console.log("Test 10"); | ||
assertEqual(true, true, 'Test 3.1 passed'); | ||
console.log('Test 10'); | ||
}), | ||
it({ name: "Test 3.2", parentId: "3" }, async () => { | ||
it({ name: 'Test 3.2', parentId: '3' }, async () => { | ||
await simulateDelay(225); | ||
assertEqual(true, true, "Test 4.2 passed"); | ||
console.log("Test 11"); | ||
assertEqual(true, true, 'Test 4.2 passed'); | ||
console.log('Test 11'); | ||
}), | ||
it({ name: "Test 3.3", parentId: "3" }, async () => { | ||
it({ name: 'Test 3.3', parentId: '3' }, async () => { | ||
await simulateDelay(250); | ||
assertEqual({ a: 1 }, { a: 1 }, "Test 3.3 passed"); | ||
console.log("Test 12"); | ||
assertEqual({ a: 1 }, { a: 1 }, 'Test 3.3 passed'); | ||
console.log('Test 12'); | ||
}), | ||
@@ -117,18 +117,18 @@ ]); | ||
async function batchFour() { | ||
describe({ name: "batch_4", id: "4", parentId: "3" }, async () => { | ||
describe({ name: 'batch_4', id: '4', parentId: '3' }, async () => { | ||
await Promise.all([ | ||
it({ name: "Test 4.1", parentId: "4" }, async () => { | ||
it({ name: 'Test 4.1', parentId: '4' }, async () => { | ||
await simulateDelay(900); | ||
assertEqual(true, true, "Test 4.1 passed"); | ||
console.log("Test 13"); | ||
assertEqual(true, true, 'Test 4.1 passed'); | ||
console.log('Test 13'); | ||
}), | ||
it({ name: "Test 4.2", parentId: "4" }, async () => { | ||
it({ name: 'Test 4.2', parentId: '4' }, async () => { | ||
await simulateDelay(3600); | ||
assertEqual(true, true, "Test 4.2 passed"); | ||
console.log("Test 14"); | ||
assertEqual(true, true, 'Test 4.2 passed'); | ||
console.log('Test 14'); | ||
}), | ||
it({ name: "Test 4.3", parentId: "4" }, async () => { | ||
it({ name: 'Test 4.3', parentId: '4' }, async () => { | ||
await simulateDelay(500); | ||
assertEqual({ a: 1 }, { a: 2 }, "Test 4.3 failed"); | ||
console.log("Test 15"); | ||
assertEqual({ a: 1 }, { a: 2 }, 'Test 4.3 failed'); | ||
console.log('Test 15'); | ||
}), | ||
@@ -140,15 +140,15 @@ ]); | ||
async function batchFive() { | ||
describe({ name: "batch_5", id: "5" }, async () => { | ||
describe({ name: 'batch_5', id: '5' }, async () => { | ||
await Promise.all([ | ||
it({ name: "Test 5.1", parentId: "5" }, async () => { | ||
assertEqual(true, true, "Test 5.1 passed"); | ||
console.log("Test 16"); | ||
it({ name: 'Test 5.1', parentId: '5' }, async () => { | ||
assertEqual(true, true, 'Test 5.1 passed'); | ||
console.log('Test 16'); | ||
}), | ||
it({ name: "Test 5.2", parentId: "5" }, async () => { | ||
assertEqual(true, true, "Test 4.2 passed"); | ||
console.log("Test 17"); | ||
it({ name: 'Test 5.2', parentId: '5' }, async () => { | ||
assertEqual(true, true, 'Test 4.2 passed'); | ||
console.log('Test 17'); | ||
}), | ||
it({ name: "Test 5.3", parentId: "5" }, async () => { | ||
assertEqual({ a: 1 }, { a: 1 }, "Test 5.3 failed"); | ||
console.log("Test 18"); | ||
it({ name: 'Test 5.3', parentId: '5' }, async () => { | ||
assertEqual({ a: 1 }, { a: 1 }, 'Test 5.3 failed'); | ||
console.log('Test 18'); | ||
}), | ||
@@ -160,15 +160,15 @@ ]); | ||
async function batchSix() { | ||
describe({ name: "batch_6", id: "6", parentId: "5" }, async () => { | ||
describe({ name: 'batch_6', id: '6', parentId: '5' }, async () => { | ||
await Promise.all([ | ||
it({ name: "Test 6.1", parentId: "6" }, async () => { | ||
assertEqual(true, true, "Test 6.1 passed"); | ||
console.log("Test 19"); | ||
it({ name: 'Test 6.1', parentId: '6' }, async () => { | ||
assertEqual(true, true, 'Test 6.1 passed'); | ||
console.log('Test 19'); | ||
}), | ||
it({ name: "Test 6.2", parentId: "6" }, async () => { | ||
assertEqual(true, true, "Test 6.2 passed"); | ||
console.log("Test 20"); | ||
it({ name: 'Test 6.2', parentId: '6' }, async () => { | ||
assertEqual(true, true, 'Test 6.2 passed'); | ||
console.log('Test 20'); | ||
}), | ||
it({ name: "Test 6.3", parentId: "6" }, async () => { | ||
assertEqual({ a: 1 }, { a: 2 }, "Test 6.3 failed"); | ||
console.log("Test 21"); | ||
it({ name: 'Test 6.3', parentId: '6' }, async () => { | ||
assertEqual({ a: 1 }, { a: 2 }, 'Test 6.3 failed'); | ||
console.log('Test 21'); | ||
}), | ||
@@ -175,0 +175,0 @@ ]); |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
46845
33
1304
1