Skip to content

Commit 12005bc

Browse files
committed
WIP
1 parent f125a07 commit 12005bc

File tree

8 files changed

+120
-12
lines changed

8 files changed

+120
-12
lines changed

.vscode/settings.json

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
{
2+
"objectscript.export": {
3+
"folder": "serverSide\\src",
4+
"addCategory": false,
5+
"map": {},
6+
"atelier": true,
7+
"generated": false,
8+
"filter": "",
9+
"exactFilter": "",
10+
"category": "*",
11+
"maxConcurrentConnections": 0,
12+
"mapped": false
13+
},
14+
"objectscript.conn": {
15+
"active": true,
16+
"server": "docker-52774",
17+
"ns": "USER",
18+
"username": "_SYSTEM"
19+
},
20+
}
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
/// Helper superclass for the testing managers we use.
2+
Class vscode.dc.testingmanager.BaseManager [ Abstract ]
3+
{
4+
5+
Property bmMethodMap As %String [ MultiDimensional, Private ];
6+
7+
Method bmMapOneFile(file As %String) [ Private ]
8+
{
9+
Kill ..bmMethodMap(file)
10+
Set tFlags=+..UserParam # 2 * 16 // Bit 0 f UserParam indicates we must get udl-multiline format (since Atelier API v4)
11+
Set tSC=##class(%Atelier.v1.Utils.TextServices).GetTextAsArray(file,tFlags,.tTextArray)
12+
//TODO: use the text array to create a tag-to-linenumber map
13+
For lineNumber=1:1:+$Get(tTextArray(0)) {
14+
Set line=$Get(tTextArray(lineNumber))
15+
Set keyword=$Piece(line," ",1)
16+
If keyword'="Method",keyword'="ClassMethod" Continue
17+
Set tag=$Piece($Piece(line," ",2),"(",1)
18+
// Take account of multi-line method format
19+
While ("{"'[$Get(tTextArray(lineNumber+1))) {
20+
Set lineNumber=lineNumber+1
21+
}
22+
Set ..bmMethodMap(file,tag)=lineNumber
23+
}
24+
// Note linecount as an indicator we've indexed this file, even if we found no methods
25+
Set ..bmMethodMap(file)=+$Get(tTextArray(0))
26+
}
27+
28+
/// Copied from %UnitTest.Manager and enhanced to append location information
29+
/// to some log messages.
30+
Method LogAssert(success, action, description, extra, location)
31+
{
32+
Set testsuite=i%TheStack(i%TheStack,"suite")
33+
Set testcase=i%TheStack(i%TheStack,"case")
34+
Set testmethod=i%TheStack(i%TheStack,"method")
35+
If testmethod="" Quit
36+
Do LogAssert^%SYS.UNITTEST(..OriginNS,..ResultId,testsuite,testcase,testmethod,success,action,description,$GET(location))
37+
38+
// Convert location to +offset^file if it is a type of assertion outcome we want to display inline
39+
If success'=1,$Get(location)'="" {
40+
Set file=$Piece(location,"^",2)
41+
Set tagOffset=$Piece(location,"^",1)
42+
Set offset=$Piece(tagOffset,"+",2)
43+
Set tag=$Piece(tagOffset,"+",1)
44+
If (tag'="") {
45+
// Create a tag-to-linenumber map for file if we don't have one already
46+
If '$Data(..bmMethodMap(file)) Do ..bmMapOneFile(file)
47+
// Use it to compute what to add to the offset to get an absolute line number
48+
Set tagLineNumber=$Get(..bmMethodMap(file,tag))
49+
Set location="+"_(offset+tagLineNumber)_"^"_file
50+
}
51+
}
52+
Set line=action_":"_description_" ("_..GetTestState(success)_")"
53+
if success'=1 Set line = line_"@"_location
54+
If 'success,..Display["error" {
55+
Do ..PrintErrorLine(line,.extra)
56+
} Else {
57+
Do ..PrintLine(line,4)
58+
}
59+
}
60+
61+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
Class vscode.dc.testingmanager.CoverageManager Extends (BaseManager, TestCoverage.Manager)
2+
{
3+
4+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
Class vscode.dc.testingmanager.StandardManager Extends (BaseManager, %UnitTest.Manager)
2+
{
3+
4+
}

src/commonRunTestsHandler.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -254,6 +254,7 @@ export async function commonRunTestsHandler(controller: vscode.TestController, r
254254
const isClientSideMode = controller.id === `${extensionId}-Local`;
255255
const isDebug = request.profile?.kind === vscode.TestRunProfileKind.Debug;
256256
const runQualifiers = !isClientSideMode ? "/noload/nodelete" : isDebug ? "/noload" : "";
257+
let userParam = vscode.workspace.getConfiguration('objectscript', oneUri).get<boolean>('multilineMethodArgs', false) ? 1 : 0;
257258
const runIndex = allTestRuns.push(run) - 1;
258259
runIndices.push(runIndex);
259260

@@ -268,7 +269,7 @@ export async function commonRunTestsHandler(controller: vscode.TestController, r
268269
}
269270
}
270271

271-
let program = `##class(%UnitTest.Manager).RunTest("${testSpec}","${runQualifiers}")`;
272+
let program = `##class(vscode.dc.testingmanager.StandardManager).RunTest("${testSpec}","${runQualifiers}",${userParam})`;
272273
if (coverageRequest) {
273274
program = `##class(${UTIL_CLASSNAME}).${SQL_FN_RUNTESTPROXY}("${testSpec}","${runQualifiers}",2)`;
274275
request.profile.loadDetailedCoverage = async (_testRun, fileCoverage, _token) => {
@@ -278,6 +279,7 @@ export async function commonRunTestsHandler(controller: vscode.TestController, r
278279
return fileCoverage instanceof OurFileCoverage ? fileCoverage.loadDetailedCoverage(fromTestItem) : [];
279280
};
280281
}
282+
281283
const configuration = {
282284
type: "objectscript",
283285
request: "launch",

src/debugTracker.ts

Lines changed: 25 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,11 @@ export class DebugTracker implements vscode.DebugAdapterTracker {
106106
break;
107107

108108
case 'failed':
109-
this.run.failed(this.methodTest, this.failureMessages.length > 0 ? this.failureMessages : { message: 'Failed with no messages' }, this.testDuration);
109+
if (this.failureMessages.length > 0) {
110+
this.run.failed(this.methodTest, this.failureMessages, this.testDuration);
111+
} else {
112+
this.run.failed(this.methodTest, { message: 'Failed with no messages' }, this.testDuration);
113+
}
110114
break;
111115

112116
default:
@@ -129,19 +133,25 @@ export class DebugTracker implements vscode.DebugAdapterTracker {
129133
//const message = assertPassedMatch[2];
130134
//console.log(`Class ${this.className}, Test-method ${this.testMethodName}, macroName ${macroName}, outcome 'passed', message=${message}`);
131135
} else {
132-
const assertFailedMatch = line.match(/^(Assert\w+):(.*) \(failed\) <<====/);
136+
const assertFailedMatch = line.match(/^(Assert\w+):(.*) \(failed\)@\+(\d+)\^(.*) <<====/);
133137
if (assertFailedMatch) {
134138
//const macroName = assertFailedMatch[1];
135-
const failedMessage = assertFailedMatch[2];
136-
//console.log(`Class ${this.className}, Test-method ${this.testMethodName}, macroName ${macroName}, outcome 'failed', message=${message}`);
137-
this.failureMessages.push({ message: failedMessage });
139+
const message = assertFailedMatch[2];
140+
const offset = Number(assertFailedMatch[3]);
141+
const location = this.methodTest?.uri && this.methodTest.range
142+
? new vscode.Location(this.methodTest.uri, new vscode.Position(offset, 0))
143+
: undefined;
144+
this.failureMessages.push({ message, location });
138145
} else {
139-
const assertSkippedMatch = line.match(/^ (Test\w+):(.*) \(skipped\)$/);
146+
const assertSkippedMatch = line.match(/^ (Test\w+):(.*) \(skipped\)@\+(\d+)\^(.*)$/);
140147
if (assertSkippedMatch) {
141148
//const macroName = assertSkippedMatch[1];
142149
const message = assertSkippedMatch[2];
143-
//console.log(`Class ${this.className}, Test-method ${this.testMethodName}, macroName ${macroName}, outcome 'skipped', message=${message}`);
144-
this.skippedMessages.push({ message: message });
150+
const offset = Number(assertSkippedMatch[3]);
151+
const location = this.methodTest?.uri && this.methodTest.range
152+
? new vscode.Location(this.methodTest.uri, new vscode.Position(offset, 0))
153+
: undefined;
154+
this.skippedMessages.push({ message, location });
145155
} else {
146156
const logMessageMatch = line.match(/^ LogMessage:(.*)$/);
147157
if (logMessageMatch) {
@@ -151,6 +161,13 @@ export class DebugTracker implements vscode.DebugAdapterTracker {
151161
if (duration) {
152162
this.testDuration = + duration[1] * 1000;
153163
}
164+
} else {
165+
const logStateStatusMatch = line.match(/^LogStateStatus:(.*)$/);
166+
if (logStateStatusMatch) {
167+
const message = logStateStatusMatch[1];
168+
//console.log(`Class ${this.className}, Test-method ${this.testMethodName}, macroName LogStateStatus, message=${message}`);
169+
this.failureMessages.push({ message });
170+
}
154171
}
155172
}
156173
}

src/extension.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,12 @@ export let osAPI: any;
1515
export let smAPI: serverManager.ServerManagerAPI | undefined;
1616

1717
export interface OurTestRun extends vscode.TestRun {
18-
debugSession?: vscode.DebugSession
18+
debugSession?: vscode.DebugSession;
1919
}
2020

2121
export interface OurTestItem extends vscode.TestItem {
2222
ourUri?: vscode.Uri;
23-
supportsCoverage?: boolean
23+
supportsCoverage?: boolean;
2424
}
2525

2626
export const allTestRuns: (OurTestRun | undefined)[] = [];

src/ourFileCoverage.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ export class OurFileCoverage extends vscode.FileCoverage {
3737

3838
// When ObjectScript extension spreads method arguments over multiple lines, we need to compute offsets
3939
const mapOffsets: Map<string, number> = new Map();
40-
if (vscode.workspace.getConfiguration('objectscript', this.uri).get('multilineMethodArgs', false)) {
40+
if (vscode.workspace.getConfiguration('objectscript', this.uri).get<boolean>('multilineMethodArgs', false)) {
4141
const response = await makeRESTRequest(
4242
"POST",
4343
serverSpec,

0 commit comments

Comments
 (0)