UNPKG

@n1k1t/unit-generator

Version:

Coverage based unit tests AI generator

123 lines 5.27 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.AssistantFixStrategy = void 0; const v3_1 = require("zod/v3"); const model_1 = require("./model"); const content_1 = require("../../content"); class AssistantFixStrategy extends model_1.AssistantStrategy { get schema() { return v3_1.z.object({ imports: v3_1.z.array(v3_1.z.string().describe('Code of ONLY one import statement, for example: `import ...`')).describe('List of required entity imports for unit tests'), tests: v3_1.z.array(v3_1.z.object({ title: v3_1.z.string().describe(`Unit test title **(find in the \`Unit tests titles\` article)**`), content: v3_1.z.string().describe('Code with fix of unit tests **(without imports)**'), }).describe('Fix configuration')).min(1).describe('List of tests those should be fixed'), }); } async run() { if (!this.source.spec.content.length) { return 'SKIPPED'; } const tested = await this.source.test(); if (tested.status !== 'FAILED') { return 'SKIPPED'; } const snapshot = this.source.compileSnapshot(); const context = this.compileContext(); const generated = await this.generate({ schema: this.schema, messages: { system: content_1.ArticleContent .build({ title: 'Context', tag: 'h1', content: [ context.overview, context.project, context.history, content_1.ArticleContent.build({ title: 'Unit tests titles', content: [{ ul: this.source.spec.tests.map((test) => test.title), }], }), content_1.ArticleContent.build({ title: 'Existing unit tests', content: [{ code: { language: this.source.spec.lang, content: this.source.spec.content, }, }], }), content_1.ArticleContent.build({ title: 'Unit test failure message', content: [{ code: { language: 'console', content: tested.message, }, }], }), ], }) .render(), user: content_1.ArticleContent .build({ title: 'Task', tag: 'h1', content: [{ ol: [ 'Explore the `Context` article', 'Analyze the unit test failure message', 'Analyze the existing imports in the code', 'Generate fixes for the unit test code and imports (make shure that new imports are not existing in the code)', ], }], }) .render(), }, }); if (!generated?.tests.length) { return 'EMPTY'; } await this.injectImports(generated); const result = await this.injectFixes(generated); if (result !== 'DONE') { await this.source.restore(snapshot); } return result; } async injectImports(generated) { const imports = generated.imports.filter((row) => row.includes('import') || row.includes('require')); if (!imports.length) { return 'EMPTY'; } await this.source.spec.prepend(imports.join('\n')).write(); return 'DONE'; } async injectFixes(generated) { const results = []; for (const fix of generated.tests) { this.source.save(); const found = this.source.spec.tests.find((test) => test.title.includes(fix.title)); if (!found) { continue; } this.source.spec.replace(found.content.trim(), fix.content.trim()); await this.source.spec.write(); const tested = await this.source.test(fix.title); if (tested.status === 'FAILED') { this.history.add({ generated: fix.content, message: tested.message }); await this.source.restore(); } results.push(tested); } return results.length && results.some((result) => result.status === 'PASSED') ? 'DONE' : 'FAILED'; } static build(source, provided) { return new AssistantFixStrategy('FIX', source, provided); } } exports.AssistantFixStrategy = AssistantFixStrategy; //# sourceMappingURL=fix.js.map