@rstest/core
Version:
The Rsbuild-based test tool.
319 lines (318 loc) • 11 kB
JavaScript
import 'module';
/*#__PURE__*/ import.meta.url;
import { __webpack_require__ } from "./rslib-runtime.js";
import node_process, { stdin, stdout } from "node:process";
import { _path } from "./2672.js";
const external_node_os_ = __webpack_require__("node:os");
const external_node_tty_ = __webpack_require__("node:tty");
function hasFlag(flag, argv = globalThis.Deno ? globalThis.Deno.args : node_process.argv) {
const prefix = flag.startsWith('-') ? '' : 1 === flag.length ? '-' : '--';
const position = argv.indexOf(prefix + flag);
const terminatorPosition = argv.indexOf('--');
return -1 !== position && (-1 === terminatorPosition || position < terminatorPosition);
}
const { env: env } = node_process;
let flagForceColor;
if (hasFlag('no-color') || hasFlag('no-colors') || hasFlag('color=false') || hasFlag('color=never')) flagForceColor = 0;
else if (hasFlag('color') || hasFlag('colors') || hasFlag('color=true') || hasFlag('color=always')) flagForceColor = 1;
function envForceColor() {
if (!('FORCE_COLOR' in env)) return;
if ('true' === env.FORCE_COLOR) return 1;
if ('false' === env.FORCE_COLOR) return 0;
if (0 === env.FORCE_COLOR.length) return 1;
const level = Math.min(Number.parseInt(env.FORCE_COLOR, 10), 3);
if (![
0,
1,
2,
3
].includes(level)) return;
return level;
}
function translateLevel(level) {
if (0 === level) return false;
return {
level,
hasBasic: true,
has256: level >= 2,
has16m: level >= 3
};
}
function _supportsColor(haveStream, { streamIsTTY, sniffFlags = true } = {}) {
const noFlagForceColor = envForceColor();
if (void 0 !== noFlagForceColor) flagForceColor = noFlagForceColor;
const forceColor = sniffFlags ? flagForceColor : noFlagForceColor;
if (0 === forceColor) return 0;
if (sniffFlags) {
if (hasFlag('color=16m') || hasFlag('color=full') || hasFlag('color=truecolor')) return 3;
if (hasFlag('color=256')) return 2;
}
if ('TF_BUILD' in env && 'AGENT_NAME' in env) return 1;
if (haveStream && !streamIsTTY && void 0 === forceColor) return 0;
const min = forceColor || 0;
if ('dumb' === env.TERM) return min;
if ('win32' === node_process.platform) {
const osRelease = external_node_os_["default"].release().split('.');
if (Number(osRelease[0]) >= 10 && Number(osRelease[2]) >= 10586) return Number(osRelease[2]) >= 14931 ? 3 : 2;
return 1;
}
if ('CI' in env) {
if ([
'GITHUB_ACTIONS',
'GITEA_ACTIONS',
'CIRCLECI'
].some((key)=>key in env)) return 3;
if ([
'TRAVIS',
'APPVEYOR',
'GITLAB_CI',
'BUILDKITE',
'DRONE'
].some((sign)=>sign in env) || 'codeship' === env.CI_NAME) return 1;
return min;
}
if ('TEAMCITY_VERSION' in env) return /^(9\.(0*[1-9]\d*)\.|\d{2,}\.)/.test(env.TEAMCITY_VERSION) ? 1 : 0;
if ('truecolor' === env.COLORTERM) return 3;
if ('xterm-kitty' === env.TERM) return 3;
if ('xterm-ghostty' === env.TERM) return 3;
if ('wezterm' === env.TERM) return 3;
if ('TERM_PROGRAM' in env) {
const version = Number.parseInt((env.TERM_PROGRAM_VERSION || '').split('.')[0], 10);
switch(env.TERM_PROGRAM){
case 'iTerm.app':
return version >= 3 ? 3 : 2;
case 'Apple_Terminal':
return 2;
}
}
if (/-256(color)?$/i.test(env.TERM)) return 2;
if (/^screen|^xterm|^vt100|^vt220|^rxvt|color|ansi|cygwin|linux/i.test(env.TERM)) return 1;
if ('COLORTERM' in env) return 1;
return min;
}
function createSupportsColor(stream, options = {}) {
const level = _supportsColor(stream, {
streamIsTTY: stream && stream.isTTY,
...options
});
return translateLevel(level);
}
const supportsColor = {
stdout: createSupportsColor({
isTTY: external_node_tty_["default"].isatty(1)
}),
stderr: createSupportsColor({
isTTY: external_node_tty_["default"].isatty(2)
})
};
const supports_color = supportsColor;
const colorLevel = supports_color.stdout ? supports_color.stdout.level : 0;
let errorStackRegExp = /at [^\r\n]{0,200}:\d+:\d+[\s\)]*$/;
let anonymousErrorStackRegExp = /at [^\r\n]{0,200}\(<anonymous>\)$/;
let indexErrorStackRegExp = /at [^\r\n]{0,200}\(index\s\d+\)$/;
let isErrorStackMessage = (message)=>errorStackRegExp.test(message) || anonymousErrorStackRegExp.test(message) || indexErrorStackRegExp.test(message);
let formatter = (open, close, replace = open)=>colorLevel >= 2 ? (input)=>{
let string = '' + input;
let index = string.indexOf(close, open.length);
return ~index ? open + replaceClose(string, close, replace, index) + close : open + string + close;
} : String;
let replaceClose = (string, close, replace, index)=>{
let start = string.substring(0, index) + replace;
let end = string.substring(index + close.length);
let nextIndex = end.indexOf(close);
return ~nextIndex ? start + replaceClose(end, close, replace, nextIndex) : start + end;
};
const bold = formatter('\x1b[1m', '\x1b[22m', '\x1b[22m\x1b[1m');
const red = formatter('\x1b[31m', '\x1b[39m');
const green = formatter('\x1b[32m', '\x1b[39m');
const yellow = formatter('\x1b[33m', '\x1b[39m');
const magenta = formatter('\x1b[35m', '\x1b[39m');
const cyan = formatter('\x1b[36m', '\x1b[39m');
const gray = formatter('\x1b[90m', '\x1b[39m');
let startColor = [
189,
255,
243
];
let endColor = [
74,
194,
154
];
let isWord = (char)=>!/[\s\n]/.test(char);
let gradient = (message)=>{
if (colorLevel < 3) return 2 === colorLevel ? bold(cyan(message)) : message;
let chars = [
...message
];
let steps = chars.filter(isWord).length;
let r = startColor[0];
let g = startColor[1];
let b = startColor[2];
let rStep = (endColor[0] - r) / steps;
let gStep = (endColor[1] - g) / steps;
let bStep = (endColor[2] - b) / steps;
let output = '';
for (let char of chars){
if (isWord(char)) {
r += rStep;
g += gStep;
b += bStep;
}
output += `\x1b[38;2;${Math.round(r)};${Math.round(g)};${Math.round(b)}m${char}\x1b[39m`;
}
return bold(output);
};
let LOG_LEVEL = {
silent: -1,
error: 0,
warn: 1,
info: 2,
log: 2,
verbose: 3
};
let LOG_TYPES = {
error: {
label: 'error',
level: 'error',
color: red
},
warn: {
label: 'warn',
level: 'warn',
color: yellow
},
info: {
label: 'info',
level: 'info',
color: cyan
},
start: {
label: 'start',
level: 'info',
color: cyan
},
ready: {
label: 'ready',
level: 'info',
color: green
},
success: {
label: 'success',
level: 'info',
color: green
},
log: {
level: 'info'
},
debug: {
label: 'debug',
level: 'verbose',
color: magenta
}
};
const normalizeErrorMessage = (err)=>{
if (err.stack) {
let [name, ...rest] = err.stack.split('\n');
if (name.startsWith('Error: ')) name = name.slice(7);
return `${name}\n${gray(rest.join('\n'))}`;
}
return err.message;
};
let createLogger = (options = {})=>{
let maxLevel = options.level || 'info';
let log = (type, message, ...args)=>{
let logType = LOG_TYPES[type];
const { level } = logType;
if (LOG_LEVEL[level] > LOG_LEVEL[maxLevel]) return;
if (null == message) return console.log();
let label = '';
let text = '';
if ('label' in logType) {
label = (logType.label || '').padEnd(7);
label = bold(logType.color ? logType.color(label) : label);
}
if (message instanceof Error) {
text += normalizeErrorMessage(message);
const { cause } = message;
if (cause) {
text += yellow('\n [cause]: ');
text += cause instanceof Error ? normalizeErrorMessage(cause) : String(cause);
}
} else if ('error' === level && 'string' == typeof message) {
let lines = message.split('\n');
text = lines.map((line)=>isErrorStackMessage(line) ? gray(line) : line).join('\n');
} else text = `${message}`;
const method = 'error' === level || 'warn' === level ? level : 'log';
console[method](label.length ? `${label} ${text}` : text, ...args);
};
let logger = {
greet: (message)=>log('log', gradient(message))
};
Object.keys(LOG_TYPES).forEach((key)=>{
logger[key] = (...args)=>log(key, ...args);
});
Object.defineProperty(logger, 'level', {
get: ()=>maxLevel,
set (val) {
maxLevel = val;
}
});
logger.override = (customLogger)=>{
Object.assign(logger, customLogger);
};
return logger;
};
let src_logger = createLogger();
const picocolors = __webpack_require__("../../node_modules/.pnpm/picocolors@1.1.1/node_modules/picocolors/picocolors.js");
var picocolors_default = /*#__PURE__*/ __webpack_require__.n(picocolors);
const isDebug = ()=>{
if (!process.env.DEBUG) return false;
const values = process.env.DEBUG.toLocaleLowerCase().split(',');
return [
'rstest',
'rsbuild',
'builder',
'*'
].some((key)=>values.includes(key));
};
if (isDebug()) src_logger.level = 'verbose';
function getTime() {
const now = new Date();
const hours = String(now.getHours()).padStart(2, '0');
const minutes = String(now.getMinutes()).padStart(2, '0');
const seconds = String(now.getSeconds()).padStart(2, '0');
return `${hours}:${minutes}:${seconds}`;
}
src_logger.override({
debug: (message, ...args)=>{
if ('verbose' !== src_logger.level) return;
const time = picocolors_default().gray(getTime());
console.log(` ${picocolors_default().magenta('rstest')} ${time} ${message}`, ...args);
}
});
const clearScreen = (force = false)=>{
if (!isDebug() || force) console.log('\x1Bc');
};
const logger_logger = {
...src_logger,
stderr: (message, ...args)=>{
console.error(message, ...args);
}
};
const delimiter = /* @__PURE__ */ (()=>globalThis.process?.platform === "win32" ? ";" : ":")();
const _platforms = {
posix: void 0,
win32: void 0
};
const mix = (del = delimiter)=>new Proxy(_path, {
get (_, prop) {
if ("delimiter" === prop) return del;
if ("posix" === prop) return posix;
if ("win32" === prop) return win32;
return _platforms[prop] || _path[prop];
}
});
const posix = /* @__PURE__ */ mix(":");
const win32 = /* @__PURE__ */ mix(";");
export { clearScreen, isDebug, logger_logger as logger, node_process, posix, stdin, stdout };