@teambit/tester
Version:
236 lines (230 loc) • 9.29 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.TestCmd = void 0;
function _chalk() {
const data = _interopRequireDefault(require("chalk"));
_chalk = function () {
return data;
};
return data;
}
function _workspace() {
const data = require("@teambit/workspace");
_workspace = function () {
return data;
};
return data;
}
function _toolboxTime() {
const data = require("@teambit/toolbox.time.timer");
_toolboxTime = function () {
return data;
};
return data;
}
function _legacy() {
const data = require("@teambit/legacy.constants");
_legacy = function () {
return data;
};
return data;
}
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
class TestCmd {
constructor(tester, workspace, logger) {
this.tester = tester;
this.workspace = workspace;
this.logger = logger;
_defineProperty(this, "name", 'test [component-pattern]');
_defineProperty(this, "description", 'test components in the workspace. by default only runs tests for new and modified components');
_defineProperty(this, "helpUrl", 'reference/testing/tester-overview');
_defineProperty(this, "arguments", [{
name: 'component-pattern',
description: _legacy().COMPONENT_PATTERN_HELP
}]);
_defineProperty(this, "alias", 'at');
_defineProperty(this, "group", 'testing');
_defineProperty(this, "options", [['w', 'watch', 'start the tester in watch mode.'], ['d', 'debug', 'start the tester in debug mode.'], ['a', 'all', 'DEPRECATED. (use --unmodified)'], ['u', 'unmodified', 'test all components, not only new and modified'], ['', 'junit <filepath>', 'write tests results as JUnit XML format into the specified file path'], ['', 'coverage', 'show code coverage data'], ['e', 'env <id>', 'test only components assigned the given env'], ['', 'update-snapshot', 'if supported by the tester, re-record every snapshot that fails during the test run'], ['s', 'scope <scope-name>', 'DEPRECATED. (use the pattern instead, e.g. "scopeName/**"). name of the scope to test'], ['j', 'json', 'return the results in json format']
// TODO: we need to reduce this redundant casting every time.
]);
}
async report([userPattern], {
watch = false,
debug = false,
all = false,
env,
scope,
junit,
coverage = false,
unmodified = false,
updateSnapshot = false
}) {
const timer = _toolboxTime().Timer.create();
const scopeName = typeof scope === 'string' ? scope : undefined;
if (scopeName) {
this.logger.consoleWarning(`--scope is deprecated, use the pattern argument instead. e.g. "scopeName/**" for the entire scope`);
}
if (all) {
unmodified = all;
this.logger.consoleWarning(`--all is deprecated, use --unmodified instead`);
}
timer.start();
if (!this.workspace) throw new (_workspace().OutsideWorkspaceError)();
const getPatternWithScope = () => {
if (!userPattern && !scope) return undefined;
const pattern = userPattern || '**';
return scopeName ? `${scopeName}/${pattern}` : pattern;
};
const patternWithScope = getPatternWithScope();
const components = await this.workspace.getComponentsByUserInput(unmodified, patternWithScope, true);
if (!components.length) {
const data = _chalk().default.bold(`no components found to test.
use "--unmodified" flag to test all components or specify the ids to test.
otherwise, only new and modified components will be tested`);
return {
code: 0,
data
};
}
this.logger.console(`testing total of ${components.length} components in workspace '${_chalk().default.cyan(this.workspace.name)}'`);
let code = 0;
if (watch && !debug) {
// avoid turning off the logger for non-watch scenario. otherwise, when this aspect throws errors, they'll be
// swallowed. (Jest errors are shown regardless via Jest, but if the tester is unable to run Jest in the first
// place, these errors won't be shown)
this.logger.off();
await this.tester.watch(components, {
watch,
debug,
env,
coverage,
updateSnapshot
});
} else {
const tests = await this.tester.test(components, {
watch,
debug,
env,
junit,
coverage,
updateSnapshot
});
if (tests.hasErrors()) code = 1;
if (process.exitCode && process.exitCode !== 0 && typeof process.exitCode === 'number') {
// this is needed for testers such as "vitest", where it sets the exitCode to non zero when the coverage is not met.
code = process.exitCode;
}
}
const {
seconds
} = timer.stop();
if (watch) return '';
const data = `tests has been completed in ${_chalk().default.cyan(seconds.toString())} seconds.`;
return {
code,
data
};
}
async json([userPattern], {
watch = false,
debug = false,
env,
junit,
coverage = false,
unmodified = false,
updateSnapshot = false
}) {
const timer = _toolboxTime().Timer.create();
timer.start();
if (!this.workspace) throw new (_workspace().OutsideWorkspaceError)();
const getPatternWithScope = () => {
if (!userPattern) return undefined;
const pattern = userPattern || '**';
return pattern;
};
const patternWithScope = getPatternWithScope();
const components = await this.workspace.getComponentsByUserInput(unmodified, patternWithScope, true);
if (!components.length) {
this.logger.info(`no components found to test.
use "--unmodified" flag to test all components or specify the ids to test.
otherwise, only new and modified components will be tested`);
return {
code: 0,
data: []
};
}
let code = 0;
const restore = silenceConsoleAndStdout();
let tests;
try {
tests = await this.tester.test(components, {
watch,
debug,
env,
junit,
coverage,
updateSnapshot
});
} catch (err) {
restore();
throw err;
}
restore();
if (tests.hasErrors()) code = 1;
if (process.exitCode && process.exitCode !== 0 && typeof process.exitCode === 'number') {
// this is needed for testers such as "vitest", where it sets the exitCode to non zero when the coverage is not met.
code = process.exitCode;
}
const data = tests.results.map(r => ({
data: {
components: r.data?.components.map(c => _objectSpread(_objectSpread({}, c), {}, {
componentId: c.componentId.toString()
})),
errors: r.data?.errors
},
error: r.error
}));
return {
code,
data
};
}
}
/**
* Disables all console logging (via console.*) and direct writes to
* process.stdout / process.stderr. Returns a function that, when called,
* restores everything back to normal.
*/
exports.TestCmd = TestCmd;
function silenceConsoleAndStdout() {
// Keep copies of the original methods so we can restore them later
const originalConsole = _objectSpread({}, console);
const originalStdoutWrite = process.stdout.write;
const originalStderrWrite = process.stderr.write;
// No-op implementations for console.* methods
for (const method of ['log', 'warn', 'error', 'info', 'debug']) {
// eslint-disable-next-line no-console
console[method] = () => {};
}
// Replace process.stdout.write and process.stderr.write with no-ops
process.stdout.write = () => true;
process.stderr.write = () => true;
// Return a function to restore original behavior
return () => {
for (const method of Object.keys(originalConsole)) {
// @ts-ignore
// eslint-disable-next-line no-console
console[method] = originalConsole[method];
}
process.stdout.write = originalStdoutWrite;
process.stderr.write = originalStderrWrite;
};
}
//# sourceMappingURL=test.cmd.js.map