| 12 | |
| 13 | /** Handles results from a test debug session and provides them to the test model. */ |
| 14 | export class TestSessionCoordinator implements IAmDisposable { |
| 15 | private disposables: IAmDisposable[] = []; |
| 16 | |
| 17 | /** |
| 18 | * A link between a suite path and the debug session ID that owns it, so we can ensure |
| 19 | * it is correctly ended when the debug session ends, even if we don't get the correct |
| 20 | * end events. |
| 21 | */ |
| 22 | private owningDebugSessions: Record<string, string | undefined> = {}; |
| 23 | |
| 24 | /** For a given debug session, lookups by IDs to get back to the suite. */ |
| 25 | private debugSessionLookups: Record<string, { |
| 26 | cwd: string | undefined, |
| 27 | suiteForID: Record<string, SuiteData | undefined>, |
| 28 | suiteForTestID: Record<string, SuiteData | undefined>, |
| 29 | } | undefined> = {}; |
| 30 | |
| 31 | /** |
| 32 | * A link between a suite path and a visitor for visiting its latest outline data. |
| 33 | * This data is refreshed when a test suite starts running. |
| 34 | */ |
| 35 | private suiteOutlineVisitors: Record<string, TestOutlineVisitor | undefined> = {}; |
| 36 | |
| 37 | /** |
| 38 | * For each debug session ID, stores a mapping of phantom (empty) groups and their parent IDs so we can |
| 39 | * jump over them. |
| 40 | */ |
| 41 | private phantomGroupParents: Record<string, Record<number, number | null | undefined>> = {}; |
| 42 | |
| 43 | constructor(private readonly logger: Logger, private readonly data: TestModel, private readonly fileTracker: { getOutlineFor(uri: URI): Outline | undefined }) { } |
| 44 | |
| 45 | public handleDebugSessionStart(debugSessionID: string, dartCodeDebugSessionID: string | undefined, cwd: string | undefined) { |
| 46 | dartCodeDebugSessionID ??= `untagged-session-${debugSessionID}`; |
| 47 | |
| 48 | let lookup = this.debugSessionLookups[dartCodeDebugSessionID]; |
| 49 | if (!lookup) |
| 50 | lookup = this.debugSessionLookups[dartCodeDebugSessionID] = { cwd, suiteForID: {}, suiteForTestID: {} }; |
| 51 | |
| 52 | if (cwd) |
| 53 | lookup.cwd = cwd; |
| 54 | } |
| 55 | |
| 56 | public handleDebugSessionCustomEvent(debugSessionID: string, dartCodeDebugSessionID: string | undefined, event: string, body?: any) { |
| 57 | dartCodeDebugSessionID ??= `untagged-session-${debugSessionID}`; |
| 58 | if (event === "dart.testNotification") { |
| 59 | void this.handleNotification(debugSessionID, dartCodeDebugSessionID, body as Notification).catch((e) => this.logger.error(e)); |
| 60 | } |
| 61 | } |
| 62 | |
| 63 | public handleDebugSessionEnd(debugSessionID: string, dartCodeDebugSessionID: string | undefined) { |
| 64 | // Get the suite paths that have us as the owning debug session. |
| 65 | const suitePaths = Object.keys(this.owningDebugSessions).filter((suitePath) => { |
| 66 | const owningSessionID = this.owningDebugSessions[suitePath]; |
| 67 | return owningSessionID === debugSessionID; |
| 68 | }); |
| 69 | |
| 70 | // End them all and remove from the lookup. |
| 71 | for (const suitePath of suitePaths) { |
nothing calls this directly
no outgoing calls
no test coverage detected