@n1k1t/unit-generator
Version:
Coverage based unit tests AI generator
121 lines • 5.2 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.wait = exports.cast = exports.extractIgnorePaths = exports.actualizeProcessedCoverageRate = exports.renderProcessedCoverage = exports.extractFilesCoverage = exports.extractOverallCoverage = void 0;
const minimatch_1 = __importDefault(require("minimatch"));
const path_1 = __importDefault(require("path"));
const promises_1 = __importDefault(require("fs/promises"));
const lodash_1 = __importDefault(require("lodash"));
const uuid_1 = require("uuid");
const fast_xml_parser_1 = require("fast-xml-parser");
const xmlParser = new fast_xml_parser_1.XMLParser({ ignoreAttributes: false });
const extractOverallCoverage = async (cobertura) => {
const raw = await promises_1.default.readFile(cobertura).catch((error) => {
console.error('Cannot find cobertura file', error?.stack ?? error);
throw error;
});
const coverage = xmlParser.parse(raw);
if (!coverage.coverage) {
return null;
}
return {
timestamp: new Date(Number(coverage.coverage['@_timestamp'])),
rate: Number((Number(coverage.coverage['@_line-rate']) || 0).toFixed(3)),
};
};
exports.extractOverallCoverage = extractOverallCoverage;
const extractFilesCoverage = async (cobertura, options) => {
const target = options?.target ?? 1;
const raw = await promises_1.default.readFile(cobertura).catch((error) => {
if (options?.silent) {
return null;
}
console.error('Cannot find cobertura file', error?.stack ?? error);
throw error;
});
if (!raw) {
return [];
}
const coverage = xmlParser.parse(raw);
if (!coverage.coverage?.packages?.package) {
return [];
}
const parsed = lodash_1.default.flatten([coverage.coverage.packages.package]).reduce((acc, item) => acc.concat((Array.isArray(item.classes.class) ? item.classes.class : [item.classes.class]).map((nested) => ({
id: (0, uuid_1.v4)(),
file: nested['@_filename'],
rate: Number(Number(nested['@_line-rate']).toFixed(3)),
}))), []);
if (options?.all) {
options.paths?.forEach((nested) => parsed.some(({ file }) => file.includes(nested))
? null
: parsed.push({ id: (0, uuid_1.v4)(), file: nested, rate: 0 }));
}
const filtred = parsed.filter(({ file, rate }) => {
if (rate >= target) {
return false;
}
if (path_1.default.parse(file).name.endsWith('.spec')) {
return false;
}
if (options?.paths?.length && !options.paths.some((nested) => file.includes(nested))) {
return false;
}
if (options?.ignore?.length && options.ignore.some((pattern) => (0, minimatch_1.default)(file, pattern))) {
return false;
}
return true;
});
const separated = filtred.reduce((acc, coverage) => {
path_1.default.parse(coverage.file).name === 'index'
? acc.indexes.push(coverage)
: acc.modules.push(coverage);
return acc;
}, { indexes: [], modules: [] });
return [
...separated.modules.sort((a, b) => a.rate - b.rate),
...separated.indexes.sort((a, b) => a.rate - b.rate),
].slice(0, options?.limit ?? Infinity);
};
exports.extractFilesCoverage = extractFilesCoverage;
const renderProcessedCoverage = (timestamp, processed) => console.table(processed.map((item) => Object.assign(item, {
spent: item.status === 'PENDING' ? Number(((Date.now() - timestamp) / 1000).toFixed(3)) : item.spent,
})), (0, exports.cast)(['file', 'rate', 'target', 'status', 'spent']));
exports.renderProcessedCoverage = renderProcessedCoverage;
const actualizeProcessedCoverageRate = async (cwd, processed, options) => {
for (const item of (options?.force ? processed.filter((item) => item.status === 'PENDING') : processed)) {
const [refreshed] = await (0, exports.extractFilesCoverage)(path_1.default.join(cwd, item.cobertura), {
target: Infinity,
silent: true,
});
item.rate = refreshed?.rate ?? item.rate;
}
};
exports.actualizeProcessedCoverageRate = actualizeProcessedCoverageRate;
const extractIgnorePaths = async (cwd) => {
const raw = await promises_1.default.readFile(path_1.default.join(cwd, '.unitignore'), 'utf8').catch(() => null);
return (raw
?.split('\n')
.map((segment) => segment.trim())
.filter(Boolean) ?? []);
};
exports.extractIgnorePaths = extractIgnorePaths;
const cast = (value) => value;
exports.cast = cast;
const wait = (ms) => {
const context = {
isCanceled: false,
timeout: undefined,
};
const promise = new Promise((resolve) => context.isCanceled ? resolve() : (context.timeout = setTimeout(resolve, ms)));
return Object.assign(promise, {
value: ms,
abort: () => {
context.isCanceled = true;
clearTimeout(context.timeout);
},
});
};
exports.wait = wait;
//# sourceMappingURL=utils.js.map