in src/client/testing/testController/common/testItemUtilities.ts [306:487]
async function updateTestItemFromRawDataInternal(
item: TestItem,
testController: TestController,
idToRawData: Map<string, TestData>,
testRoot: string,
rawDataSet: RawDiscoveredTests[],
token?: CancellationToken,
): Promise<void> {
if (token?.isCancellationRequested) {
return;
}
const rawId = idToRawData.get(item.id)?.rawId;
if (!rawId) {
traceError(`Unknown node id: ${item.id}`);
return;
}
const nodeRawData = rawDataSet.filter(
(r) =>
r.root === rawId ||
r.rootid === rawId ||
r.parents.find((p) => p.id === rawId) ||
r.tests.find((t) => t.id === rawId),
);
if (nodeRawData.length === 0 && item.parent) {
removeItemByIdFromChildren(idToRawData, item.parent, [item.id]);
traceVerbose(`Following test item was removed Reason: No-Raw-Data ${item.id}`);
return;
}
if (nodeRawData.length > 1) {
// Something is wrong, there can only be one test node with that id
traceError(`Multiple (${nodeRawData.length}) raw data nodes had the same id: ${rawId}`);
return;
}
if (rawId === nodeRawData[0].root || rawId === nodeRawData[0].rootid) {
// This is a test root node, we need to update the entire tree
// The update children and remove any child that does not have raw data.
await asyncForEach(testItemCollectionToArray(item.children), async (c) => {
await updateTestItemFromRawData(c, testController, idToRawData, testRoot, nodeRawData, token);
});
// Create child nodes that are new.
// We only need to look at rawData.parents. Since at this level we either have folder or file.
const rawChildNodes = nodeRawData[0].parents.filter((p) => p.parentid === '.' || p.parentid === rawId);
const existingNodes: string[] = [];
item.children.forEach((c) => existingNodes.push(idToRawData.get(c.id)?.rawId ?? ''));
await asyncForEach(
rawChildNodes.filter((r) => !existingNodes.includes(r.id)),
async (r) => {
const childItem =
r.kind === 'file'
? createFolderOrFileTestItem(testController, idToRawData, testRoot, r as RawTestFile)
: createFolderOrFileTestItem(testController, idToRawData, testRoot, r as RawTestFolder);
item.children.add(childItem);
await updateTestItemFromRawData(childItem, testController, idToRawData, testRoot, nodeRawData, token);
},
);
return;
}
// First check if this is a parent node
const rawData = nodeRawData[0].parents.filter((r) => r.id === rawId);
if (rawData.length === 1) {
// This is either a File/Folder/Collection node
// Update the node data
switch (rawData[0].kind) {
case 'file':
updateFolderOrFileTestItem(item, idToRawData, testRoot, rawData[0] as RawTestFile);
break;
case 'folder':
updateFolderOrFileTestItem(item, idToRawData, testRoot, rawData[0] as RawTestFolder);
break;
case 'suite':
updateCollectionTestItem(item, idToRawData, testRoot, rawData[0] as RawTestSuite);
break;
case 'function':
updateCollectionTestItem(item, idToRawData, testRoot, rawData[0] as RawTestFunction);
break;
default:
break;
}
// The update children and remove any child that does not have raw data.
await asyncForEach(testItemCollectionToArray(item.children), async (c) => {
await updateTestItemFromRawData(c, testController, idToRawData, testRoot, nodeRawData, token);
});
// Create child nodes that are new.
// Get the existing child node ids so we can skip them
const existingNodes: string[] = [];
item.children.forEach((c) => existingNodes.push(idToRawData.get(c.id)?.rawId ?? ''));
// We first look at rawData.parents. Since at this level we either have folder or file.
// The current node is potentially a parent of one of these "parent" nodes or it is a parent
// of test case nodes. We will handle Test case nodes after handling parents.
const rawChildNodes = nodeRawData[0].parents.filter((p) => p.parentid === rawId);
await asyncForEach(
rawChildNodes.filter((r) => !existingNodes.includes(r.id)),
async (r) => {
let childItem;
switch (r.kind) {
case 'file':
childItem = createFolderOrFileTestItem(testController, idToRawData, testRoot, r as RawTestFile);
break;
case 'folder':
childItem = createFolderOrFileTestItem(
testController,
idToRawData,
testRoot,
r as RawTestFolder,
);
break;
case 'suite':
childItem = createCollectionTestItem(testController, idToRawData, testRoot, r as RawTestSuite);
break;
case 'function':
childItem = createCollectionTestItem(
testController,
idToRawData,
testRoot,
r as RawTestFunction,
);
break;
default:
break;
}
if (childItem) {
item.children.add(childItem);
// This node can potentially have children. So treat it like a new node and update it.
await updateTestItemFromRawData(
childItem,
testController,
idToRawData,
testRoot,
nodeRawData,
token,
);
}
},
);
// Now we will look at test case nodes. Create any test case node that does not already exist.
const rawTestCaseNodes = nodeRawData[0].tests.filter((p) => p.parentid === rawId);
rawTestCaseNodes
.filter((r) => !existingNodes.includes(r.id))
.forEach((r) => {
const childItem = createTestCaseItem(testController, idToRawData, testRoot, r);
item.children.add(childItem);
});
return;
}
if (rawData.length > 1) {
// Something is wrong, there can only be one test node with that id
traceError(`Multiple (${rawData.length}) raw data nodes had the same id: ${rawId}`);
return;
}
// We are here this means rawData.length === 0
// The node is probably is test case node. Try and find it.
const rawCaseData = nodeRawData[0].tests.filter((r) => r.id === rawId);
if (rawCaseData.length === 1) {
// This is a test case node
updateTestCaseItem(item, idToRawData, testRoot, rawCaseData[0]);
return;
}
if (rawCaseData.length > 1) {
// Something is wrong, there can only be one test node with that id
traceError(`Multiple (${rawCaseData.length}) raw data nodes had the same id: ${rawId}`);
}
}