Repository navigation
Expand file tree
/
Copy pathextension.js
More file actions
177 lines (149 loc) · 5.9 KB
/
Copy pathextension.js
File metadata and controls
177 lines (149 loc) · 5.9 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
const vscode = require('vscode');
const path = require('path');
const testCommand = 'composer test';
let persistentTerminal = null;
/**
* Gets or creates a persistent terminal for running tests
* @returns {vscode.Terminal}
*/
function getOrCreateTerminal() {
if (!persistentTerminal) {
persistentTerminal = vscode.window.createTerminal('Test Runner');
}
return persistentTerminal;
}
/**
* Runs a command in the persistent terminal
* @param {string} command The command to run
* @param {string} message The message to show
*/
async function runInTerminal(command, message) {
const terminal = getOrCreateTerminal();
terminal.show();
terminal.sendText(command);
vscode.window.showInformationMessage(message);
}
/**
* Activates the extension
* @param {vscode.ExtensionContext} context
*/
function activate(context) {
console.log('Test Runner extension is now active');
// Register the command to run test for current function
let runTestFunction = vscode.commands.registerCommand('test-runner.runTest', async function () {
try {
const editor = vscode.window.activeTextEditor;
if (!editor) {
vscode.window.showErrorMessage('No active editor found');
return;
}
const document = editor.document;
const filePath = document.fileName;
// Check if this is a test file (contains "Test" in the filename or path)
if (!isTestFile(filePath)) {
vscode.window.showErrorMessage('Not a test file. File name or path should contain "Test" or "test"');
return;
}
// Get the workspace folder
const workspaceFolder = vscode.workspace.getWorkspaceFolder(document.uri);
if (!workspaceFolder) {
vscode.window.showErrorMessage('File is not part of a workspace');
return;
}
// Get the relative path from the workspace root
const relativePath = path.relative(workspaceFolder.uri.fsPath, filePath);
// Get the current function name
const functionName = getCurrentFunctionName(document, editor.selection.active.line);
if (!functionName) {
vscode.window.showErrorMessage('No test function found at cursor position');
return;
}
// Format and run the command
const command = `${testCommand} ${relativePath}:${functionName}`;
await runInTerminal(command, `Running test for function: ${functionName}`);
} catch (error) {
vscode.window.showErrorMessage(`Error: ${error.message}`);
}
});
// Register the command to run tests for current file
let runFileTests = vscode.commands.registerCommand('test-runner.runFileTests', async function () {
try {
const editor = vscode.window.activeTextEditor;
if (!editor) {
vscode.window.showErrorMessage('No active editor found');
return;
}
const document = editor.document;
const filePath = document.fileName;
// Check if this is a test file (contains "Test" in the filename or path)
if (!isTestFile(filePath)) {
vscode.window.showErrorMessage('Not a test file. File name or path should contain "Test" or "test"');
return;
}
// Get the workspace folder
const workspaceFolder = vscode.workspace.getWorkspaceFolder(document.uri);
if (!workspaceFolder) {
vscode.window.showErrorMessage('File is not part of a workspace');
return;
}
// Get the relative path from the workspace root
const relativePath = path.relative(workspaceFolder.uri.fsPath, filePath);
// Format and run the command
const command = `${testCommand} ${relativePath}`;
await runInTerminal(command, `Running tests for file: ${relativePath}`);
} catch (error) {
vscode.window.showErrorMessage(`Error: ${error.message}`);
}
});
context.subscriptions.push(runTestFunction, runFileTests);
}
/**
* Checks if the file is a test file
* @param {string} filePath
* @returns {boolean}
*/
function isTestFile(filePath) {
const fileName = path.basename(filePath);
const fileDir = path.dirname(filePath);
// Check if the file name or path contains "Test" or "test"
return fileName.includes('Test') ||
fileName.includes('test') ||
fileDir.includes('Test') ||
fileDir.includes('test') ||
fileDir.includes('tests');
}
/**
* Gets the current function name based on the cursor position
* @param {vscode.TextDocument} document
* @param {number} currentLine
* @returns {string|null} The function name or null if not found
*/
function getCurrentFunctionName(document, currentLine) {
// For PHP test files, look for function patterns
const phpFunctionRegex = /\s*(public|protected|private)?\s*function\s+(\w+)\s*\(/;
const phpMethodRegex = /\s*function\s+(\w+)\s*\(/;
// Start from the current line and go up to find the function declaration
for (let i = currentLine; i >= 0; i--) {
const line = document.lineAt(i).text;
// Try to match PHP function patterns
let match = line.match(phpFunctionRegex);
if (match && match[2]) {
return match[2];
}
// Try to match PHP method pattern (without visibility modifier)
match = line.match(phpMethodRegex);
if (match && match[1]) {
return match[1];
}
// If we find a class declaration or closing brace, stop searching
if (line.includes('class ') || line.trim() === '}') {
break;
}
}
return null;
}
function deactivate() {}
module.exports = {
activate,
deactivate
};