Skip to content

Commit 0c7dbfd

Browse files
committed
[#37] make TestItems more unique to also be able to execute duplicated test/suite name addresses
1 parent 8688fb2 commit 0c7dbfd

File tree

3 files changed

+44
-20
lines changed

3 files changed

+44
-20
lines changed

robotcode/language_server/robotframework/parts/discovering.py

Lines changed: 32 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ class GetAllTestsParams(Model):
3535
@dataclass(repr=False)
3636
class GetTestsParams(Model):
3737
text_document: TextDocumentIdentifier
38-
id: Optional[str]
38+
base_name: Optional[str]
3939

4040

4141
@dataclass(repr=False)
@@ -48,6 +48,7 @@ class TestItem(Model):
4848
type: str
4949
id: str
5050
label: str
51+
longname: str
5152
uri: Optional[DocumentUri] = None
5253
children: Optional[List[TestItem]] = None
5354
description: Optional[str] = None
@@ -57,10 +58,10 @@ class TestItem(Model):
5758

5859

5960
class FindTestCasesVisitor(AsyncVisitor):
60-
async def get(self, source: DocumentUri, model: ast.AST, id: Optional[str]) -> List[TestItem]:
61+
async def get(self, source: DocumentUri, model: ast.AST, base_name: Optional[str]) -> List[TestItem]:
6162
self._results: List[TestItem] = []
6263
self.source = source
63-
self.id = id
64+
self.base_name = base_name
6465
await self.visit(model)
6566
return self._results
6667

@@ -75,10 +76,12 @@ async def visit_TestCase(self, node: ast.AST) -> None: # noqa: N802
7576
from robot.parsing.model.statements import Tags
7677

7778
test_case = cast(TestCase, node)
79+
longname = f"{self.base_name}.{test_case.name}" if self.base_name else test_case.name
7880
self._results.append(
7981
TestItem(
8082
type="test",
81-
id=f"{self.id}.{test_case.name}" if self.id else test_case.name,
83+
id=f"{self.source};{longname};{test_case.lineno}",
84+
longname=longname,
8285
label=test_case.name,
8386
uri=self.source,
8487
range=Range(
@@ -203,12 +206,14 @@ def generate(suite: TestSuite) -> TestItem:
203206

204207
test: TestCase
205208
for test in suite.tests:
209+
uri = str(Uri.from_path(test.source)) if test.source else None
206210
children.append(
207211
TestItem(
208212
type="test",
209-
id=test.longname,
213+
id=f"{uri};{test.longname};{test.lineno}",
210214
label=test.name,
211-
uri=str(Uri.from_path(test.source)) if test.source else None,
215+
longname=test.longname,
216+
uri=uri,
212217
range=Range(
213218
start=Position(line=test.lineno - 1, character=0),
214219
end=Position(line=test.lineno - 1, character=0),
@@ -220,11 +225,13 @@ def generate(suite: TestSuite) -> TestItem:
220225
for s in suite.suites:
221226
children.append(generate(s))
222227

228+
uri = str(Uri.from_path(suite.source)) if suite.source else None
223229
return TestItem(
224230
type="suite",
225-
id=suite.longname,
231+
id=f"{uri};{suite.longname}",
226232
label=suite.name,
227-
uri=str(Uri.from_path(suite.source)) if suite.source else None,
233+
longname=suite.longname,
234+
uri=uri,
228235
children=children,
229236
range=Range(
230237
start=Position(line=0, character=0),
@@ -270,17 +277,21 @@ def nonexisting_paths(paths: List[str]) -> Iterator[str]:
270277
)
271278
suite_item = [generate(suite)] if suite else []
272279

280+
uri = str(Uri.from_path(Path.cwd()))
273281
return [
274282
TestItem(
275283
type="workspace",
276-
id=Path.cwd().name,
284+
id=uri,
277285
label=Path.cwd().name,
286+
longname=Path.cwd().name,
287+
uri=uri,
278288
children=[
279289
*suite_item,
280290
*[
281291
TestItem(
282292
type="error",
283-
id=i,
293+
id=f"{Uri.from_path(i)};ERROR",
294+
longname="error",
284295
label=i,
285296
error=f"Parsing '{i}' failed: File or directory to does not exist.",
286297
)
@@ -298,7 +309,15 @@ def nonexisting_paths(paths: List[str]) -> Iterator[str]:
298309
except (SystemExit, KeyboardInterrupt):
299310
raise
300311
except BaseException as e:
301-
return [TestItem(type="error", id=Path.cwd().name, label=Path.cwd().name, error=str(e))]
312+
return [
313+
TestItem(
314+
type="error",
315+
id=str(Uri.from_path(Path.cwd())),
316+
longname="error",
317+
label=Path.cwd().name,
318+
error=str(e),
319+
)
320+
]
302321

303322
@rpc_method(name="robot/discovering/getTestsFromWorkspace", param_type=GetAllTestsParams)
304323
@_logger.call
@@ -317,7 +336,7 @@ async def get_tests_from_workspace(
317336
@rpc_method(name="robot/discovering/getTestsFromDocument", param_type=GetTestsParams)
318337
@_logger.call
319338
async def get_tests_from_document(
320-
self, text_document: TextDocumentIdentifier, id: Optional[str], *args: Any, **kwargs: Any
339+
self, text_document: TextDocumentIdentifier, base_name: Optional[str], *args: Any, **kwargs: Any
321340
) -> List[TestItem]:
322341
async def run() -> List[TestItem]:
323342
try:
@@ -328,7 +347,7 @@ async def run() -> List[TestItem]:
328347
Uri(text_document.uri).to_path(), language_id="robotframework"
329348
)
330349
),
331-
id,
350+
base_name,
332351
)
333352
except (asyncio.CancelledError, SystemExit, KeyboardInterrupt):
334353
raise

vscode-client/languageclientsmanger.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ export interface RobotTestItem {
3939
uri?: string;
4040
children: RobotTestItem[] | undefined;
4141
label: string;
42+
longname: string;
4243
description?: string;
4344
range?: Range;
4445
error?: string;
@@ -446,7 +447,7 @@ export class LanguageClientsManager {
446447

447448
public async getTestsFromDocument(
448449
document: vscode.TextDocument,
449-
id?: string,
450+
base_name?: string,
450451
token?: vscode.CancellationToken
451452
): Promise<RobotTestItem[] | undefined> {
452453
const client = await this.getLanguageClientForResource(document.uri);
@@ -459,13 +460,13 @@ export class LanguageClientsManager {
459460
"robot/discovering/getTestsFromDocument",
460461
{
461462
textDocument: { uri: document.uri.toString() },
462-
id: id,
463+
base_name: base_name,
463464
},
464465
token
465466
)
466467
: await client.sendRequest<RobotTestItem[]>("robot/discovering/getTestsFromDocument", {
467468
textDocument: { uri: document.uri.toString() },
468-
id: id,
469+
base_name: base_name,
469470
})) ?? undefined
470471
);
471472
}

vscode-client/testcontrollermanager.ts

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -332,7 +332,7 @@ export class TestControllerManager {
332332
const openDoc = vscode.workspace.textDocuments.find((d) => d.uri.toString() === item.uri?.toString());
333333

334334
if (openDoc !== undefined) {
335-
tests = await this.languageClientsManager.getTestsFromDocument(openDoc, robotItem.id, token);
335+
tests = await this.languageClientsManager.getTestsFromDocument(openDoc, robotItem.longname, token);
336336
}
337337
}
338338
if (token?.isCancellationRequested) return;
@@ -587,7 +587,7 @@ export class TestControllerManager {
587587
}
588588
});
589589

590-
for (const [workspace, id] of included) {
590+
for (const [workspace, ids] of included) {
591591
const runId = TestControllerManager.runId.next().value;
592592
this.testRuns.set(runId, run);
593593

@@ -603,8 +603,12 @@ export class TestControllerManager {
603603
if (includedItems.length === 1 && includedItems[0] === workspaceItem && excluded.size === 0) {
604604
await DebugManager.runTests(workspace, [], [], [], runId, options);
605605
} else {
606-
const includedInWs = id.map((i) => i.id);
607-
const excludedInWs = excluded.get(workspace)?.map((i) => i.id) ?? [];
606+
const includedInWs = ids.map((i) => this.findRobotItem(i)?.longname).filter((i) => i !== undefined) as string[];
607+
const excludedInWs =
608+
(excluded
609+
.get(workspace)
610+
?.map((i) => this.findRobotItem(i)?.longname)
611+
.filter((i) => i !== undefined) as string[]) ?? [];
608612
const suites = new Set<string>();
609613

610614
for (const t of [...includedInWs, ...excludedInWs]) {

0 commit comments

Comments
 (0)