testeranto
Version:
the AI powered BDD test framework for typescript projects
195 lines (168 loc) • 5.28 kB
text/typescript
/* eslint-disable @typescript-eslint/ban-ts-comment */
/* eslint-disable no-async-promise-executor */
/* eslint-disable @typescript-eslint/no-explicit-any */
/* eslint-disable @typescript-eslint/no-unused-vars */
import ts from "typescript";
import fs from "fs";
import ansiC from "ansi-colors";
import { ESLint } from "eslint";
import tsc from "tsc-prog";
import { lintPather, tscPather } from "./utils";
import { IBuiltConfig, IRunTime } from "../../Types.js";
import { PM_WithBuild } from "./PM_WithBuild";
import { IMode } from "../types";
const eslint = new ESLint();
const formatter = await eslint.loadFormatter(
"./node_modules/testeranto/dist/prebuild/esbuildConfigs/eslint-formatter-testeranto.mjs"
);
export abstract class PM_WithEslintAndTsc extends PM_WithBuild {
constructor(configs: IBuiltConfig, name: string, mode: IMode) {
super(configs, name, mode);
}
tscCheck = async ({
entrypoint,
addableFiles,
platform,
}: {
entrypoint: string;
addableFiles: string[];
platform: IRunTime;
}): Promise<any> => {
const processId = `tsc-${entrypoint}-${Date.now()}`;
const command = `tsc check for ${entrypoint}`;
const tscPromise = (async () => {
try {
this.typeCheckIsRunning(entrypoint);
} catch (e) {
// Log error through process manager
throw new Error(`Error in tscCheck: ${e.message}`);
}
const program = tsc.createProgramFromConfig({
basePath: process.cwd(),
configFilePath: "tsconfig.json",
compilerOptions: {
outDir: tscPather(entrypoint, platform, this.projectName),
noEmit: true,
},
include: addableFiles,
});
const tscPath = tscPather(entrypoint, platform, this.projectName);
const allDiagnostics = program.getSemanticDiagnostics();
const results: string[] = [];
allDiagnostics.forEach((diagnostic) => {
if (diagnostic.file) {
const { line, character } = ts.getLineAndCharacterOfPosition(
diagnostic.file,
diagnostic.start!
);
const message = ts.flattenDiagnosticMessageText(
diagnostic.messageText,
"\n"
);
results.push(
`${diagnostic.file.fileName} (${line + 1},${
character + 1
}): ${message}`
);
} else {
results.push(
ts.flattenDiagnosticMessageText(diagnostic.messageText, "\n")
);
}
});
fs.writeFileSync(tscPath, results.join("\n"));
this.typeCheckIsNowDone(entrypoint, results.length);
return results.length;
})();
this.addPromiseProcess(
processId,
tscPromise,
command,
"build-time",
entrypoint
);
};
eslintCheck = async ({
entrypoint,
addableFiles,
platform,
}: {
entrypoint: string;
addableFiles: string[];
platform: IRunTime;
}) => {
const processId = `eslint-${entrypoint}-${Date.now()}`;
const command = `eslint check for ${entrypoint}`;
const eslintPromise = (async () => {
try {
this.lintIsRunning(entrypoint);
} catch (e) {
throw new Error(`Error in eslintCheck: ${e.message}`);
}
const filepath = lintPather(entrypoint, platform, this.projectName);
if (fs.existsSync(filepath)) fs.rmSync(filepath);
const results = (await eslint.lintFiles(addableFiles))
.filter((r) => r.messages.length)
.filter((r) => {
return r.messages[0].ruleId !== null;
})
.map((r) => {
delete r.source;
return r;
});
fs.writeFileSync(filepath, await formatter.format(results));
this.lintIsNowDone(entrypoint, results.length);
return results.length;
})();
this.addPromiseProcess(
processId,
eslintPromise,
command,
"build-time",
entrypoint
);
};
typeCheckIsRunning = (src: string) => {
if (!this.summary[src]) {
throw `this.summary[${src}] is undefined`;
}
this.summary[src].typeErrors = "?";
};
typeCheckIsNowDone = (src: string, failures: number) => {
if (failures === 0) {
console.log(ansiC.green(ansiC.inverse(`tsc > ${src}`)));
} else {
console.log(
ansiC.red(ansiC.inverse(`tsc > ${src} failed ${failures} times`))
);
}
this.summary[src].typeErrors = failures;
this.writeBigBoard();
this.checkForShutdown();
};
lintIsRunning = (src: string) => {
this.summary[src].staticErrors = "?";
this.writeBigBoard();
};
lintIsNowDone = (src: string, failures: number) => {
if (failures === 0) {
console.log(ansiC.green(ansiC.inverse(`eslint > ${src}`)));
} else {
console.log(
ansiC.red(ansiC.inverse(`eslint > ${src} failed ${failures} times`))
);
}
this.summary[src].staticErrors = failures;
this.writeBigBoard();
this.checkForShutdown();
};
bddTestIsRunning = (src: string) => {
this.summary[src].runTimeErrors = "?";
this.writeBigBoard();
};
bddTestIsNowDone = (src: string, failures: number) => {
this.summary[src].runTimeErrors = failures;
this.writeBigBoard();
this.checkForShutdown();
};
}