Comparing version 1.9.2 to 1.9.3
@@ -10,2 +10,3 @@ #! /usr/bin/env node | ||
const format_js_1 = require("../helpers/format.js"); | ||
/* c8 ignore start */ | ||
const dirs = ((0, get_arg_js_1.hasArg)('include') | ||
@@ -22,2 +23,3 @@ ? (_a = (0, get_arg_js_1.getArg)('include')) === null || _a === void 0 ? void 0 : _a.split(',') | ||
console.log(`The flag ${format_js_1.format.bold('--log-success')} is deprecated. Use ${format_js_1.format.bold('--debug')} instead.`); | ||
/* c8 ignore end */ | ||
(0, index_js_1.poku)(dirs, { | ||
@@ -24,0 +26,0 @@ platform: (0, get_runtime_js_1.platformIsValid)(platform) ? platform : undefined, |
@@ -18,1 +18,2 @@ "use strict"; | ||
}; | ||
/* c8 ignore stop */ |
@@ -5,2 +5,3 @@ "use strict"; | ||
const node_os_1 = require("os"); | ||
/* c8 ignore start */ | ||
const findFile = (error) => { | ||
@@ -29,1 +30,2 @@ var _a; | ||
exports.findFile = findFile; | ||
/* c8 ignore end */ |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.forceArray = void 0; | ||
/* c8 ignore start */ | ||
const forceArray = (input) => { | ||
@@ -10,1 +11,2 @@ if (Array.isArray(input)) | ||
exports.forceArray = forceArray; | ||
/* c8 ignore stop */ |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.getLargestStringLength = exports.format = exports.backgroundColor = void 0; | ||
/* c8 ignore start */ | ||
const pad_js_1 = require("./pad.js"); | ||
@@ -42,1 +43,2 @@ exports.backgroundColor = { | ||
exports.getLargestStringLength = getLargestStringLength; | ||
/* c8 ignore stop */ |
@@ -5,1 +5,2 @@ import type { Configs } from '../@types/poku.js'; | ||
export declare const getRuntime: (configs?: Configs) => (typeof supportedPlatforms)[number]; | ||
export declare const nodeVersion: number | undefined; |
"use strict"; | ||
/* c8 ignore start */ | ||
var __importDefault = (this && this.__importDefault) || function (mod) { | ||
return (mod && mod.__esModule) ? mod : { "default": mod }; | ||
}; | ||
var _a; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.getRuntime = exports.platformIsValid = exports.supportedPlatforms = void 0; | ||
exports.nodeVersion = exports.getRuntime = exports.platformIsValid = exports.supportedPlatforms = void 0; | ||
const node_process_1 = __importDefault(require("process")); | ||
exports.supportedPlatforms = [ | ||
@@ -26,1 +32,5 @@ 'node', | ||
exports.getRuntime = getRuntime; | ||
exports.nodeVersion = (0, exports.getRuntime)() === 'node' | ||
? Number((_a = node_process_1.default.version.match(/v(\d+)\./)) === null || _a === void 0 ? void 0 : _a[1]) | ||
: undefined; | ||
/* c8 ignore stop */ |
"use strict"; | ||
/* c8 ignore start */ | ||
var __importDefault = (this && this.__importDefault) || function (mod) { | ||
@@ -14,1 +15,2 @@ return (mod && mod.__esModule) ? mod : { "default": mod }; | ||
exports.hr = hr; | ||
/* c8 ignore stop */ |
@@ -7,2 +7,3 @@ "use strict"; | ||
exports.padStart = void 0; | ||
/* c8 ignore start */ | ||
const padStart = (str, targetLength, padString) => { | ||
@@ -18,1 +19,2 @@ padString = !padString ? ' ' : String(padString); | ||
exports.padStart = padStart; | ||
/* c8 ignore end */ |
@@ -61,2 +61,3 @@ "use strict"; | ||
message = options.defaultMessage; | ||
/* c8 ignore start */ | ||
const finalMessage = (message === null || message === void 0 ? void 0 : message.trim().length) > 0 | ||
@@ -90,3 +91,5 @@ ? format_js_1.format.bold(format_js_1.format.fail(`โ ${message}`)) | ||
} | ||
/* c8 ignore stop */ | ||
/* c8 ignore next */ | ||
}); | ||
exports.parseAssertion = parseAssertion; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.removeConsecutiveRepeats = void 0; | ||
/* c8 ignore start */ | ||
const removeConsecutiveRepeats = (arr, specificItem) => { | ||
@@ -30,1 +31,2 @@ const result = []; | ||
exports.removeConsecutiveRepeats = removeConsecutiveRepeats; | ||
/* c8 ignore stop */ |
import { Configs } from '../@types/poku.js'; | ||
import { Runner } from '../@types/runner.js'; | ||
export declare const isWindows: boolean; | ||
export declare const runner: (filename: string, configs?: Configs) => string[]; | ||
export declare const scriptRunner: (runner: Runner) => string[]; |
"use strict"; | ||
/* c8 ignore start */ | ||
var __importDefault = (this && this.__importDefault) || function (mod) { | ||
@@ -6,7 +7,7 @@ return (mod && mod.__esModule) ? mod : { "default": mod }; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.scriptRunner = exports.runner = void 0; | ||
exports.scriptRunner = exports.runner = exports.isWindows = void 0; | ||
const node_process_1 = __importDefault(require("process")); | ||
const node_path_1 = __importDefault(require("path")); | ||
const get_runtime_js_1 = require("./get-runtime.js"); | ||
const isWindows = node_process_1.default.platform === 'win32'; | ||
exports.isWindows = node_process_1.default.platform === 'win32'; | ||
const runner = (filename, configs) => { | ||
@@ -19,6 +20,13 @@ const runtime = (0, get_runtime_js_1.getRuntime)(configs); | ||
if (runtime === 'deno') | ||
return ['deno', 'run', '--allow-read', '--allow-env', '--allow-run']; | ||
return [ | ||
'deno', | ||
'run', | ||
'--allow-read', // Poku searches for all test files | ||
'--allow-env', // Poku share the process.env with the `child_process` | ||
'--allow-run', // Poku CLI | ||
'--allow-net', // Create Service | ||
]; | ||
// Node.js | ||
return node_path_1.default.extname(filename) === '.ts' | ||
? [isWindows ? 'npx.cmd' : 'npx', 'tsx'] | ||
? [exports.isWindows ? 'npx.cmd' : 'npx', 'tsx'] | ||
: ['node']; | ||
@@ -30,3 +38,3 @@ }; | ||
if (runner === 'bun') | ||
return ['bun']; | ||
return ['bun', 'run']; | ||
// Deno | ||
@@ -42,4 +50,5 @@ if (runner === 'deno') | ||
// Node.js | ||
return ['npm', 'run']; | ||
return [exports.isWindows ? 'npm.cmd' : 'npm', 'run']; | ||
}; | ||
exports.scriptRunner = scriptRunner; | ||
/* c8 ignore stop */ |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.startScript = exports.startService = exports.test = exports.listFiles = exports.afterEach = exports.beforeEach = exports.assertPromise = exports.log = exports.describe = exports.assert = exports.exit = exports.poku = void 0; | ||
/* c8 ignore start */ | ||
var poku_js_1 = require("./modules/poku.js"); | ||
@@ -25,1 +26,2 @@ Object.defineProperty(exports, "poku", { enumerable: true, get: function () { return poku_js_1.poku; } }); | ||
Object.defineProperty(exports, "startScript", { enumerable: true, get: function () { return create_service_js_1.startScript; } }); | ||
/* c8 ignore stop */ |
@@ -27,3 +27,3 @@ /// <reference types="node" /> | ||
match: (value: string, regExp: RegExp, message?: ParseAssertionOptions['message']) => Promise<void>; | ||
ifError: (value: unknown) => Promise<void>; | ||
ifError: (value: unknown, message?: ParseAssertionOptions['message']) => Promise<void>; | ||
fail: (message?: ParseAssertionOptions['message']) => Promise<void>; | ||
@@ -30,0 +30,0 @@ rejects: typeof rejects; |
@@ -34,16 +34,7 @@ "use strict"; | ||
}; | ||
var __importDefault = (this && this.__importDefault) || function (mod) { | ||
return (mod && mod.__esModule) ? mod : { "default": mod }; | ||
}; | ||
var _a; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.assertPromise = void 0; | ||
const node_process_1 = __importDefault(require("process")); | ||
const nodeAssert = __importStar(require("assert")); | ||
const parseAsssetion_js_1 = require("../helpers/parseAsssetion.js"); | ||
const get_runtime_js_1 = require("../helpers/get-runtime.js"); | ||
const runtime = (0, get_runtime_js_1.getRuntime)(); | ||
const version = runtime === 'node' | ||
? Number((_a = node_process_1.default.version.match(/v(\d+)\./)) === null || _a === void 0 ? void 0 : _a[1]) | ||
: undefined; | ||
const ok = (value, message) => __awaiter(void 0, void 0, void 0, function* () { | ||
@@ -94,6 +85,7 @@ yield (0, parseAsssetion_js_1.parseAssertion)(() => { | ||
}); | ||
const ifError = (value) => __awaiter(void 0, void 0, void 0, function* () { | ||
const ifError = (value, message) => __awaiter(void 0, void 0, void 0, function* () { | ||
yield (0, parseAsssetion_js_1.parseAssertion)(() => { | ||
nodeAssert.ifError(value); | ||
}, { | ||
message, | ||
defaultMessage: 'Expected no error, but received an error', | ||
@@ -192,5 +184,7 @@ hideDiff: true, | ||
const match = (value, regExp, message) => __awaiter(void 0, void 0, void 0, function* () { | ||
if (typeof version === 'number' && version < 12) { | ||
/* c8 ignore start */ | ||
if (typeof get_runtime_js_1.nodeVersion === 'number' && get_runtime_js_1.nodeVersion < 12) { | ||
throw new Error('match is available from Node.js 12 or higher'); | ||
} | ||
/* c8 ignore stop */ | ||
yield (0, parseAsssetion_js_1.parseAssertion)(() => nodeAssert === null || nodeAssert === void 0 ? void 0 : nodeAssert.match(value, regExp), { | ||
@@ -204,5 +198,7 @@ message, | ||
const doesNotMatch = (value, regExp, message) => __awaiter(void 0, void 0, void 0, function* () { | ||
if (typeof version === 'number' && version < 12) { | ||
/* c8 ignore start */ | ||
if (typeof get_runtime_js_1.nodeVersion === 'number' && get_runtime_js_1.nodeVersion < 12) { | ||
throw new Error('doesNotMatch is available from Node.js 12 or higher'); | ||
} | ||
/* c8 ignore stop */ | ||
yield (0, parseAsssetion_js_1.parseAssertion)(() => nodeAssert.doesNotMatch(value, regExp), { | ||
@@ -209,0 +205,0 @@ message, |
@@ -27,3 +27,3 @@ /// <reference types="node" /> | ||
match: (value: string, regExp: RegExp, message?: ParseAssertionOptions['message']) => void; | ||
ifError: (value: unknown) => void; | ||
ifError: (value: unknown, message?: ParseAssertionOptions['message']) => void; | ||
fail: (message?: ParseAssertionOptions['message']) => void; | ||
@@ -30,0 +30,0 @@ rejects: typeof rejects; |
@@ -34,16 +34,7 @@ "use strict"; | ||
}; | ||
var __importDefault = (this && this.__importDefault) || function (mod) { | ||
return (mod && mod.__esModule) ? mod : { "default": mod }; | ||
}; | ||
var _a; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.assert = void 0; | ||
const node_process_1 = __importDefault(require("process")); | ||
const nodeAssert = __importStar(require("assert")); | ||
const parseAsssetion_js_1 = require("../helpers/parseAsssetion.js"); | ||
const get_runtime_js_1 = require("../helpers/get-runtime.js"); | ||
const runtime = (0, get_runtime_js_1.getRuntime)(); | ||
const version = runtime === 'node' | ||
? Number((_a = node_process_1.default.version.match(/v(\d+)\./)) === null || _a === void 0 ? void 0 : _a[1]) | ||
: undefined; | ||
const ok = (value, message) => { | ||
@@ -88,6 +79,7 @@ (0, parseAsssetion_js_1.parseAssertion)(() => { | ||
}; | ||
const ifError = (value) => { | ||
const ifError = (value, message) => { | ||
(0, parseAsssetion_js_1.parseAssertion)(() => { | ||
nodeAssert.ifError(value); | ||
}, { | ||
message, | ||
defaultMessage: 'Expected no error, but received an error', | ||
@@ -182,5 +174,7 @@ hideDiff: true, | ||
const match = (value, regExp, message) => { | ||
if (typeof version === 'number' && version < 12) { | ||
/* c8 ignore start */ | ||
if (typeof get_runtime_js_1.nodeVersion === 'number' && get_runtime_js_1.nodeVersion < 12) { | ||
throw new Error('match is available from Node.js 12 or higher'); | ||
} | ||
/* c8 ignore stop */ | ||
(0, parseAsssetion_js_1.parseAssertion)(() => nodeAssert === null || nodeAssert === void 0 ? void 0 : nodeAssert.match(value, regExp), { | ||
@@ -194,5 +188,7 @@ message, | ||
const doesNotMatch = (value, regExp, message) => { | ||
if (typeof version === 'number' && version < 12) { | ||
/* c8 ignore start */ | ||
if (typeof get_runtime_js_1.nodeVersion === 'number' && get_runtime_js_1.nodeVersion < 12) { | ||
throw new Error('doesNotMatch is available from Node.js 12 or higher'); | ||
} | ||
/* c8 ignore stop */ | ||
(0, parseAsssetion_js_1.parseAssertion)(() => nodeAssert.doesNotMatch(value, regExp), { | ||
@@ -199,0 +195,0 @@ message, |
@@ -9,3 +9,3 @@ import { StartScriptOptions, StartServiceOptions } from '../@types/background-process.js'; | ||
export declare const startService: (file: string, options?: StartServiceOptions) => Promise<{ | ||
end: () => boolean; | ||
end: () => void; | ||
}>; | ||
@@ -19,5 +19,11 @@ /** | ||
* Useful for servers, APIs, etc. | ||
* | ||
* --- | ||
* | ||
* `startScript` currently doesn't works for **Bun** and **Deno**. | ||
* | ||
* - See: https://github.com/wellwelwel/poku/issues/143 | ||
*/ | ||
export declare const startScript: (script: string, options?: StartScriptOptions) => Promise<{ | ||
end: () => boolean; | ||
end: () => void; | ||
}>; |
@@ -21,2 +21,12 @@ "use strict"; | ||
const list_files_js_1 = require("./list-files.js"); | ||
const node_os_1 = require("os"); | ||
const format_js_1 = require("../helpers/format.js"); | ||
/* c8 ignore start */ | ||
const runningProcesses = {}; | ||
const secureEnds = () => Object.values(runningProcesses).forEach((end) => end()); | ||
const killWindowsProcess = (PID) => (0, node_child_process_1.spawn)('taskkill', ['/F', '/T', '/PID', PID.toString()]); | ||
node_process_1.default.once('SIGINT', () => { | ||
secureEnds(); | ||
}); | ||
/* c8 ignore end */ | ||
const backgroundProcess = (runtime, args, file, options) => new Promise((resolve, reject) => { | ||
@@ -29,14 +39,30 @@ let isResolved = false; | ||
env: node_process_1.default.env, | ||
detached: true, | ||
detached: !runner_js_1.isWindows, | ||
windowsHide: runner_js_1.isWindows, | ||
timeout: options === null || options === void 0 ? void 0 : options.timeout, | ||
}); | ||
const PID = service.pid; | ||
/* c8 ignore start */ | ||
const end = () => { | ||
node_process_1.default.kill(-service.pid, 'SIGKILL'); | ||
return true; | ||
delete runningProcesses[PID]; | ||
if (runner_js_1.isWindows) { | ||
killWindowsProcess(PID); | ||
return; | ||
} | ||
if (['bun', 'deno'].includes(runtime) || | ||
['bun', 'deno'].includes(String(options === null || options === void 0 ? void 0 : options.runner))) { | ||
node_process_1.default.kill(PID); | ||
return; | ||
} | ||
node_process_1.default.kill(-PID, 'SIGKILL'); | ||
return; | ||
}; | ||
runningProcesses[PID] = end; | ||
/* c8 ignore end */ | ||
service.stdout.on('data', (data) => { | ||
if (!isResolved && typeof (options === null || options === void 0 ? void 0 : options.startAfter) !== 'number') { | ||
const stringData = String(data); | ||
const stringData = JSON.stringify(String(data)); | ||
if (typeof (options === null || options === void 0 ? void 0 : options.startAfter) === 'undefined' || | ||
(typeof (options === null || options === void 0 ? void 0 : options.startAfter) === 'string' && | ||
stringData.includes(options.startAfter))) { | ||
stringData.includes(options === null || options === void 0 ? void 0 : options.startAfter))) { | ||
resolve({ end }); | ||
@@ -50,14 +76,25 @@ clearTimeout(timeout); | ||
service.stderr.on('data', (data) => { | ||
reject(new Error(`Service failed to start: ${data}`)); | ||
if (!isResolved && typeof (options === null || options === void 0 ? void 0 : options.startAfter) !== 'number') { | ||
const stringData = JSON.stringify(String(data)); | ||
if (typeof (options === null || options === void 0 ? void 0 : options.startAfter) === 'undefined' || | ||
(typeof (options === null || options === void 0 ? void 0 : options.startAfter) === 'string' && | ||
stringData.includes(options === null || options === void 0 ? void 0 : options.startAfter))) { | ||
resolve({ end }); | ||
clearTimeout(timeout); | ||
isResolved = true; | ||
} | ||
} | ||
(options === null || options === void 0 ? void 0 : options.verbose) && console.log(String(data)); | ||
}); | ||
service.on('error', (err) => { | ||
reject(new Error(`Service failed to start: ${err}`)); | ||
secureEnds(); | ||
reject(`Service failed to start: ${err}`); | ||
}); | ||
service.on('close', (code) => { | ||
if (code !== 0) | ||
reject(new Error(`Service exited with code ${code}`)); | ||
reject(`Service exited with code ${code}`); | ||
}); | ||
const timeout = setTimeout(() => { | ||
if (!isResolved) { | ||
service.kill(); | ||
secureEnds(); | ||
reject(`createService: Timeout\nFile: ${file}`); | ||
@@ -96,9 +133,20 @@ } | ||
* Useful for servers, APIs, etc. | ||
* | ||
* --- | ||
* | ||
* `startScript` currently doesn't works for **Bun** and **Deno**. | ||
* | ||
* - See: https://github.com/wellwelwel/poku/issues/143 | ||
*/ | ||
const startScript = (script, options) => __awaiter(void 0, void 0, void 0, function* () { | ||
const runtimeOptions = (0, runner_js_1.scriptRunner)((options === null || options === void 0 ? void 0 : options.runner) || 'npm'); | ||
const runner = (options === null || options === void 0 ? void 0 : options.runner) || 'npm'; | ||
const runtimeOptions = (0, runner_js_1.scriptRunner)(runner); | ||
const runtime = runtimeOptions.shift(); | ||
const runtimeArgs = [...runtimeOptions, script]; | ||
return yield backgroundProcess(runtime, runtimeArgs, script, options); | ||
/* c8 ignore start */ | ||
if (['bun', 'deno'].includes(runner)) | ||
throw new Error(`${format_js_1.format.bold('startScript')} currently doesn't works for Bun and Deno.${node_os_1.EOL}See: https://github.com/wellwelwel/poku/issues/143`); | ||
/* c8 ignore end */ | ||
return yield backgroundProcess(runtime, runtimeArgs, script, Object.assign(Object.assign({}, options), { isScript: true, runner })); | ||
}); | ||
exports.startScript = startScript; |
@@ -28,1 +28,2 @@ "use strict"; | ||
exports.describe = describe; | ||
/* c8 ignore stop */ |
@@ -0,1 +1,4 @@ | ||
/** | ||
* Both CLI, API, noExit, sequential and parallel runs are strictly tested, but these tests use deep child process for it | ||
*/ | ||
import { Code } from '../@types/code.js'; | ||
@@ -2,0 +5,0 @@ import { Configs } from '../@types/poku.js'; |
"use strict"; | ||
/** | ||
* Both CLI, API, noExit, sequential and parallel runs are strictly tested, but these tests use deep child process for it | ||
*/ | ||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { | ||
@@ -13,2 +16,3 @@ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } | ||
exports.poku = void 0; | ||
/* c8 ignore start */ | ||
const node_os_1 = require("os"); | ||
@@ -62,1 +66,2 @@ const force_array_js_1 = require("../helpers/force-array.js"); | ||
exports.poku = poku; | ||
/* c8 ignore stop */ |
@@ -22,2 +22,3 @@ "use strict"; | ||
const resultCb = cb(); | ||
/* c8 ignore next */ | ||
if (resultCb instanceof Promise) | ||
@@ -24,0 +25,0 @@ yield resultCb; |
{ | ||
"name": "poku", | ||
"version": "1.9.2", | ||
"version": "1.9.3", | ||
"description": "๐ท Poku makes testing easy for Node.js, Bun & Deno at the same time.", | ||
"main": "./lib/index.js", | ||
"scripts": { | ||
"test": "tsx ./test/run.test.ts", | ||
"test": "npx poku --parallel --debug test/unit,test/integration,test/e2e", | ||
"pretest:c8": "npm run build", | ||
"test:c8": "c8 --reporter=text --reporter=lcov npm run test:e2e", | ||
"test:e2e": "npx poku --parallel ci/test/unit,ci/test/integration,ci/test/e2e", | ||
"test:c8": "c8 npm run test", | ||
"test:ci": "tsx ./test/ci.test.ts", | ||
@@ -17,5 +16,6 @@ "test:node": "FILTER='node-' npm run test:ci", | ||
"docker:deno": "docker compose -f ./test/docker/playground/deno/docker-compose.yml up --build", | ||
"clear": "rm -rf ./lib ./ci", | ||
"clear": "shx rm -rf ./lib ./ci ./coverage", | ||
"prebuild": "npm run clear", | ||
"build": "tsc && tsc -p tsconfig.test.json", | ||
"postbuild": "tsx ./tools/compatibility/node.ts && chmod +x lib/bin/index.js", | ||
"postbuild": "tsx ./tools/compatibility/node.ts && shx cp fixtures/server/package.json ci/fixtures/server/package.json && shx chmod +x lib/bin/index.js", | ||
"eslint:checker": "eslint . --ext .js,.ts", | ||
@@ -118,5 +118,6 @@ "eslint:fix": "eslint . --fix --config ./.eslintrc.json", | ||
"prettier": "^3.2.5", | ||
"tsx": "^4.7.1", | ||
"shx": "^0.3.4", | ||
"tsx": "4.2.1", | ||
"typescript": "^5.4.2" | ||
} | ||
} |
@@ -13,6 +13,8 @@ [node-version-url]: https://github.com/nodejs/node | ||
[ql-image]: https://img.shields.io/github/actions/workflow/status/wellwelwel/poku/ci-codeql.yml?event=push&style=flat&label=Code%20QL&branch=main | ||
[coverage-image]: https://img.shields.io/codecov/c/github/wellwelwel/poku?label=Coverage | ||
[coverage-url]: https://app.codecov.io/github/wellwelwel/poku | ||
[downloads-image]: https://img.shields.io/npm/dt/poku.svg?&color=FFC312&label=Downloads | ||
[downloads-url]: https://npmjs.org/package/poku | ||
[license-url]: https://github.com/wellwelwel/poku/blob/main/LICENSE | ||
[license-image]: https://img.shields.io/npm/l/poku.svg?maxAge=2592000&color=9c88ff&label=License | ||
[downloads-image]: https://img.shields.io/npm/dt/poku.svg?&color=FFC312&label=Downloads | ||
[downloads-url]: https://npmjs.org/package/poku | ||
@@ -32,2 +34,3 @@ <div align="center"> | ||
[![GitHub Workflow Status (with event)][ql-image]][ql-url] | ||
[![Coverage][coverage-image]][coverage-url] | ||
[![NPM Downloads][downloads-image]][downloads-url] | ||
@@ -60,2 +63,3 @@ [![License][license-image]][license-url] | ||
<span> </span><img width="16" height="16" alt="check" src="https://raw.githubusercontent.com/wellwelwel/poku/main/.github/assets/readme/check.svg"> No eval needed ๐<br /> | ||
<span> </span><img width="16" height="16" alt="check" src="https://raw.githubusercontent.com/wellwelwel/poku/main/.github/assets/readme/check.svg"> No global state<br /> | ||
<img width="16" height="16" alt="check" src="https://raw.githubusercontent.com/wellwelwel/poku/main/.github/assets/readme/check.svg"> **Parallel** and **Sequential** runs ๐๐ฝ๐๐ป<br /> | ||
@@ -65,3 +69,2 @@ | ||
<img width="16" height="16" alt="check" src="https://raw.githubusercontent.com/wellwelwel/poku/main/.github/assets/readme/check.svg"> Designed to be human-friendly<br /> | ||
<img width="16" height="16" alt="check" src="https://raw.githubusercontent.com/wellwelwel/poku/main/.github/assets/readme/check.svg"> **Poku** doesn't use a global state<br /> | ||
<img width="16" height="16" alt="check" src="https://raw.githubusercontent.com/wellwelwel/poku/main/.github/assets/readme/check.svg"> Compatible with **Coverage** tools<br /> | ||
@@ -197,7 +200,6 @@ <img width="16" height="16" alt="check" src="https://raw.githubusercontent.com/wellwelwel/poku/main/.github/assets/readme/check.svg"> [**Node.js**][node-version-url], [**Bun**][bun-version-url] and [**Deno**][deno-version-url] compatibility ๐ฉต<br /> | ||
- `beforeEach` and `afterEach` | ||
- `test` | ||
- `describe` and `log` | ||
- `listFiles` | ||
- `exit` | ||
- [**beforeEach**](https://poku.io/docs/category/beforeeach-and-aftereach) and [**afterEach**](https://poku.io/docs/category/beforeeach-and-aftereach) | ||
- [**test**](https://poku.io/docs/documentation/helpers/test) | ||
- [**describe**](https://poku.io/docs/documentation/helpers/describe) | ||
- _and much more_ โจ | ||
@@ -204,0 +206,0 @@ [**See the complete documentation**](https://poku.io/docs). |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
104984
2007
293
14