const assert = require('node:assert/strict'); const fs = require('node:fs'); const path = require('node:path'); const test = require('node:test'); const vm = require('node:vm'); test('F5 выполняет TaskProvider build и не запускает MAME после ошибки', async () => { let factory, configurationProvider, taskProvider; let onProcess, onEnd, exitCode = 0; const errors = []; const output = {appendLine() {}, dispose() {}}; class DebugAdapterExecutable { constructor(command, args, options) { Object.assign(this, {command, args, options}); } } class ProcessExecution { constructor(command, args, options) { Object.assign(this, {command, args, options}); } } class Task { constructor(definition, scope, name, source, execution, problemMatchers) { Object.assign(this, {definition, scope, name, source, execution, problemMatchers}); } } class RelativePattern { constructor(folder, pattern) {Object.assign(this, {folder, pattern});} } const vscode = { workspace: { workspaceFolders: [], getConfiguration: () => ({get: (key, fallback) => fallback}), findFiles: async () => [], }, window: {createOutputChannel: () => output, showErrorMessage: message => errors.push(message)}, debug: { registerDebugAdapterDescriptorFactory: (type, value) => { assert.equal(type, 'sprinter-mame'); factory = value; return {dispose() {}}; }, registerDebugConfigurationProvider: (type, value) => { assert.equal(type, 'sprinter-mame'); configurationProvider = value; return {dispose() {}}; }, }, tasks: { registerTaskProvider: (type, value) => { assert.equal(type, 'sprinter'); taskProvider = value; return {dispose() {}}; }, onDidEndTaskProcess: listener => { onProcess = listener; return {dispose() {onProcess = null;}}; }, onDidEndTask: listener => { onEnd = listener; return {dispose() {onEnd = null;}}; }, executeTask: async task => { const execution = {task}; onProcess({execution, exitCode}); onEnd({execution}); return execution; }, }, commands: {registerCommand: (name) => { assert.equal(name, 'sprinter.buildActive'); return {dispose() {}}; }}, DebugAdapterExecutable, ProcessExecution, Task, RelativePattern, TaskGroup: {Build: 'build'}, }; const source = fs.readFileSync(path.join(__dirname, 'extension.js'), 'utf8'); const module = {exports: {}}; vm.runInNewContext(source, { require: name => name === 'vscode' ? vscode : require(name), module, setTimeout, }, {filename: 'extension.js'}); const context = {subscriptions: []}; module.exports.activate(context); assert.equal(context.subscriptions.length, 5); const workspace = path.resolve(__dirname, '..', '..'); const session = { workspaceFolder: {uri: {fsPath: workspace}}, configuration: {}, }; const descriptor = factory.createDebugAdapterDescriptor(session); assert.equal(descriptor.command, path.join(require('node:os').homedir(), '.pyenv', 'shims', 'python')); assert.equal(descriptor.args.at(-1), path.join(workspace, 'toolchain', 'sdbg_dap.py')); assert.equal(descriptor.options.cwd, workspace); assert.equal(descriptor.options.env.PYENV_VERSION, '3.12'); const configuration = { type: 'sprinter-mame', request: 'launch', build: '${workspaceFolder}/tests/hello/.sprinter-cc-hello', }; assert.equal(await configurationProvider.resolveDebugConfiguration( session.workspaceFolder, configuration), configuration, errors.join('\n')); const task = taskProvider.createTask(session.workspaceFolder, path.join(workspace, 'tests', 'hello')); assert.equal(task.name, 'Sprinter: Build tests/hello'); assert.equal(task.execution.command, '/usr/bin/make'); assert.equal(task.execution.options.cwd, path.join(workspace, 'tests', 'hello')); assert.equal(task.execution.options.env.PYENV_VERSION, '3.12'); assert.deepEqual(Array.from(task.execution.args), ['SRC_DEBUG=1', `PYTHON=${descriptor.command}`]); assert.equal(task.problemMatchers[0], '$sprinter-sdcc'); vscode.workspace.workspaceFolders = [session.workspaceFolder]; vscode.workspace.findFiles = async () => [ {fsPath: path.join(workspace, 'tests', 'hello', 'Makefile')}, {fsPath: path.join(workspace, 'Makefile')}, ]; const discovered = await taskProvider.provideTasks(); assert.equal(discovered.length, 1); assert.equal(discovered[0].name, task.name); const unresolved = {scope: session.workspaceFolder, definition: {type: 'sprinter', project: 'tests/hello'}}; assert.equal(taskProvider.resolveTask(unresolved).definition, unresolved.definition); exitCode = 1; assert.equal(await configurationProvider.resolveDebugConfiguration( session.workspaceFolder, {...configuration}), undefined); assert.match(errors.at(-1), /MAME не запущен/); });