Skip to content

Commit 7d196b2

Browse files
authored
Tests - Skip Dependency Command Tests (#1879)
* Tests - Activate extension for each test in Dependency Command Tests Refactor the dependency command tests to be simpler, and also skip them, because they're still flaky
1 parent 19c54bc commit 7d196b2

File tree

4 files changed

+114
-84
lines changed

4 files changed

+114
-84
lines changed

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -553,7 +553,7 @@
553553
"swift.disableAutoResolve": {
554554
"type": "boolean",
555555
"default": false,
556-
"markdownDescription": "Disable automatic running of `swift package resolve` whenever the `Package.swift` or `Package.resolve` files are updated. This will also disable searching for command plugins and the initial test discovery process.",
556+
"markdownDescription": "Disable automatic running of `swift package resolve` whenever the `Package.swift` or `Package.resolved` files are updated. This will also disable searching for command plugins and the initial test discovery process.",
557557
"scope": "machine-overridable"
558558
},
559559
"swift.diagnosticsCollection": {
@@ -2000,7 +2000,7 @@
20002000
"integration-test": "npm test -- --label integrationTests",
20012001
"unit-test": "npm test -- --label unitTests",
20022002
"coverage": "npm test -- --coverage",
2003-
"compile-tests": "del-cli ./assets/test/**/.build && npm run compile",
2003+
"compile-tests": "del-cli ./assets/test/**/.build && del-cli ./assets/test/**/.spm-cache && npm run compile",
20042004
"package": "tsx ./scripts/package.ts",
20052005
"dev-package": "tsx ./scripts/dev_package.ts",
20062006
"preview-package": "tsx ./scripts/preview_package.ts",

src/TestExplorer/TestExplorer.ts

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,21 +99,42 @@ export class TestExplorer {
9999
): Promise<void> {
100100
const target = await folder.swiftPackage.getTarget(uri.fsPath);
101101
if (target?.type !== "test") {
102+
this.logger.info(
103+
`Target ${target} is not a test target, aborting looking for tests within it`,
104+
"Test Explorer"
105+
);
102106
return;
103107
}
104108

109+
this.logger.info(`Getting tests for ${uri.toString()}`, "Test Explorer");
105110
try {
106111
const tests = await this.lspTestDiscovery.getDocumentTests(folder.swiftPackage, uri);
112+
this.logger.info(
113+
`LSP test discovert found ${tests.length} top level tests`,
114+
"Test Explorer"
115+
);
107116
TestDiscovery.updateTestsForTarget(
108117
this.controller,
109118
{ id: target.c99name, label: target.name },
110119
tests,
111120
uri
112121
);
122+
this.logger.info(
123+
`Emitting test item change after LSP test discovery for ${uri.toString()}`,
124+
"Test Explorer"
125+
);
113126
this.onTestItemsDidChangeEmitter.fire(this.controller);
114-
} catch {
127+
} catch (error) {
128+
this.logger.error(
129+
`Error occurred during LSP test discovery for ${uri.toString()}: ${error}`,
130+
"Test Explorer"
131+
);
115132
// Fallback to parsing document symbols for XCTests only
116133
const tests = parseTestsFromDocumentSymbols(target.name, symbols, uri);
134+
this.logger.info(
135+
`Parsed ${tests.length} top level tests from document symbols from ${uri.toString()}`,
136+
"Test Explorer"
137+
);
117138
this.updateTests(this.controller, tests, uri);
118139
}
119140
}

test/integration-tests/commands/dependency.test.ts

Lines changed: 85 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -13,28 +13,25 @@
1313
//===----------------------------------------------------------------------===//
1414
import { expect } from "chai";
1515
import * as fs from "fs/promises";
16+
import { beforeEach } from "mocha";
1617
import * as path from "path";
1718
import * as vscode from "vscode";
1819

1920
import { FolderContext } from "@src/FolderContext";
21+
import { ResolvedDependency } from "@src/SwiftPackage";
2022
import { WorkspaceContext } from "@src/WorkspaceContext";
2123
import { Commands } from "@src/commands";
22-
import { PackageNode, ProjectPanelProvider } from "@src/ui/ProjectPanelProvider";
2324

2425
import { testAssetUri } from "../../fixtures";
2526
import { tag } from "../../tags";
2627
import { waitForNoRunningTasks } from "../../utilities/tasks";
27-
import {
28-
activateExtensionForSuite,
29-
findWorkspaceFolder,
30-
folderInRootWorkspace,
31-
} from "../utilities/testutilities";
28+
import { activateExtensionForTest, findWorkspaceFolder } from "../utilities/testutilities";
3229

3330
tag("large").suite("Dependency Commands Test Suite", function () {
3431
let depsContext: FolderContext;
3532
let workspaceContext: WorkspaceContext;
3633

37-
activateExtensionForSuite({
34+
activateExtensionForTest({
3835
async setup(ctx) {
3936
workspaceContext = ctx;
4037
depsContext = findWorkspaceFolder("dependencies", workspaceContext)!;
@@ -56,95 +53,40 @@ tag("large").suite("Dependency Commands Test Suite", function () {
5653
expect(result).to.be.true;
5754
});
5855

59-
suite("Swift: Use Local Dependency", function () {
60-
let treeProvider: ProjectPanelProvider;
61-
56+
// Skipping because these tests are currently flakey in CI
57+
suite.skip("Swift: Use Local Dependency", function () {
6258
setup(async () => {
6359
await waitForNoRunningTasks();
64-
treeProvider = new ProjectPanelProvider(workspaceContext);
65-
});
66-
67-
teardown(() => {
68-
treeProvider?.dispose();
6960
});
7061

71-
async function getDependency() {
72-
const headers = await treeProvider.getChildren();
73-
const header = headers.find(n => n.name === "Dependencies") as PackageNode;
74-
workspaceContext.logger.info(
75-
`getDependency: Current headers: ${headers.map(n => n.name)}`
76-
);
77-
if (!header) {
78-
return;
79-
}
80-
81-
const children = await header.getChildren();
82-
workspaceContext.logger.info(
83-
`getDependencyInState: Current children for "Dependencies" entry: ${children.map(n => n.name).join(", ")}`
84-
);
85-
return children.find(
86-
n => n.name.toLocaleLowerCase() === "swift-markdown"
87-
) as PackageNode;
88-
}
89-
90-
// Wait for the dependency to switch to the expected state.
91-
// This doesn't happen immediately after the USE_LOCAL_DEPENDENCY
92-
// and RESET_PACKAGE commands because the file watcher on
93-
// workspace-state.json needs to trigger.
94-
async function getDependencyInState(state: "remote" | "editing") {
95-
let depType: string | undefined;
96-
for (let i = 0; i < 10; i++) {
97-
const dep = await getDependency();
98-
if (dep?.type === state) {
99-
return dep;
100-
}
101-
depType = dep?.type;
102-
await new Promise(resolve => setTimeout(resolve, 1000));
62+
beforeEach(async function () {
63+
// Clean the Package.resolved before every test to ensure we start from a known state
64+
try {
65+
await fs.rm(path.join(depsContext.folder.fsPath, "Package.resolved"));
66+
} catch {
67+
// if we haven't done a resolve yet, the file won't exist
10368
}
10469

105-
const headers = await treeProvider.getChildren();
106-
const headerNames = headers.map(n => n.name);
107-
const depChildren = await (
108-
headers.find(n => n.name === "Dependencies") as PackageNode
109-
)?.getChildren();
110-
const childrenNames = depChildren?.map(n => n.name) ?? [];
111-
112-
const dependenciesFolderContext = await folderInRootWorkspace(
113-
"dependencies",
114-
workspaceContext
115-
);
116-
const resolvedPath = path.join(
117-
dependenciesFolderContext.folder.fsPath,
118-
"Package.resolved"
119-
);
120-
const packageResolvedContents = await fs.readFile(resolvedPath, "utf8");
121-
122-
throw Error(
123-
`Could not find dependency with state "${state}", instead it was "${depType}". Current headers: ${headerNames.map(h => `"${h}"`).join(", ")}, Current children for "Dependencies" entry: ${childrenNames.map(c => `"${c}"`).join(", ")}\nContents of Package.resolved:\n${packageResolvedContents}`
124-
);
125-
}
70+
// Perform a resolve first to make sure that dependencies are up to date
71+
await vscode.commands.executeCommand(Commands.RESOLVE_DEPENDENCIES);
12672

127-
async function useLocalDependencyTest() {
12873
workspaceContext.logger.info(
12974
"useLocalDependencyTest: Fetching the dependency in the 'remote' state"
13075
);
13176

132-
// spm edit with user supplied local version of dependency
133-
const item = await getDependencyInState("remote");
77+
// Get the dependency in remote state
78+
const remoteDep = await getDependencyInState("remote");
13479
const localDep = testAssetUri("swift-markdown");
13580

13681
workspaceContext.logger.info(
13782
"useLocalDependencyTest: Resolving latest dependencies before editing"
13883
);
13984

140-
// Perform a resolve first to make sure that dependencies are up to date
141-
await vscode.commands.executeCommand(Commands.RESOLVE_DEPENDENCIES);
142-
14385
workspaceContext.logger.info(`Configuring ${localDep.fsPath} to the "editing" state`);
14486

14587
const result = await vscode.commands.executeCommand(
14688
Commands.USE_LOCAL_DEPENDENCY,
147-
item,
89+
createPackageNode(remoteDep),
14890
localDep,
14991
depsContext
15092
);
@@ -162,11 +104,75 @@ tag("large").suite("Dependency Commands Test Suite", function () {
162104
workspaceContext.logger.info(
163105
"useLocalDependencyTest: Use local dependency was verified to be in 'editing' state"
164106
);
107+
});
108+
109+
/**
110+
* Get the swift-markdown dependency from the package dependencies
111+
*/
112+
async function getSwiftMarkdownDependency(): Promise<ResolvedDependency | undefined> {
113+
// Reload workspace state to get latest dependency information
114+
await depsContext.reloadWorkspaceState();
115+
116+
const dependencies = await depsContext.swiftPackage.rootDependencies;
117+
const swiftMarkdownDep = dependencies.find(
118+
dep => dep.identity.toLowerCase() === "swift-markdown"
119+
);
120+
121+
workspaceContext.logger.info(
122+
`getSwiftMarkdownDependency: Found dependency with type "${swiftMarkdownDep?.type}"`
123+
);
124+
125+
return swiftMarkdownDep;
165126
}
166127

167-
test("Swift: Reset Package Dependencies", async function () {
168-
await useLocalDependencyTest();
128+
/**
129+
* Create a PackageNode from a ResolvedDependency for use with commands
130+
*/
131+
function createPackageNode(dependency: ResolvedDependency): any {
132+
return {
133+
__isPackageNode: true,
134+
name: dependency.identity,
135+
location: dependency.location,
136+
type: dependency.type,
137+
path: dependency.path ?? "",
138+
dependency: dependency,
139+
};
140+
}
141+
142+
/**
143+
* Wait for the dependency to switch to the expected state.
144+
* This doesn't happen immediately after the USE_LOCAL_DEPENDENCY
145+
* and RESET_PACKAGE commands because the file watcher on
146+
* workspace-state.json needs to trigger.
147+
*/
148+
async function getDependencyInState(
149+
state: "remote" | "editing"
150+
): Promise<ResolvedDependency> {
151+
let currentDep: ResolvedDependency | undefined;
152+
153+
for (let i = 0; i < 10; i++) {
154+
currentDep = await getSwiftMarkdownDependency();
169155

156+
workspaceContext.logger.info(
157+
`getDependencyInState: Current state of dependency is "${currentDep?.type}", waiting for "${state}"`
158+
);
159+
160+
if (currentDep?.type === state) {
161+
return currentDep;
162+
}
163+
164+
await new Promise(resolve => setTimeout(resolve, 1000));
165+
}
166+
167+
const dependencies = await depsContext.swiftPackage.rootDependencies;
168+
const dependencyNames = dependencies.map(dep => dep.identity);
169+
170+
throw Error(
171+
`Could not find swift-markdown dependency with state "${state}", instead it was "${currentDep?.type}". Available dependencies: ${dependencyNames.join(", ")}`
172+
);
173+
}
174+
175+
test("Swift: Reset Package Dependencies", async function () {
170176
workspaceContext.logger.info("Resetting package dependency to remote version");
171177

172178
// spm reset
@@ -183,13 +189,12 @@ tag("large").suite("Dependency Commands Test Suite", function () {
183189
});
184190

185191
test("Swift: Unedit To Original Version", async function () {
186-
await useLocalDependencyTest();
187-
188192
workspaceContext.logger.info("Unediting package dependency to original version");
189193

194+
const editingDep = await getDependencyInState("editing");
190195
const result = await vscode.commands.executeCommand(
191196
Commands.UNEDIT_DEPENDENCY,
192-
await getDependencyInState("editing"),
197+
createPackageNode(editingDep),
193198
depsContext
194199
);
195200
expect(result).to.be.true;

test/integration-tests/editor/CommentCompletion.test.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import * as assert from "assert";
1515
import * as vscode from "vscode";
1616

1717
import { CommentCompletionProviders } from "@src/editor/CommentCompletion";
18+
import { Workbench } from "@src/utilities/commands";
1819

1920
suite("CommentCompletion Test Suite", () => {
2021
let provider: CommentCompletionProviders;
@@ -23,7 +24,10 @@ suite("CommentCompletion Test Suite", () => {
2324
provider = new CommentCompletionProviders();
2425
});
2526

26-
teardown(() => provider.dispose());
27+
teardown(async () => {
28+
provider.dispose();
29+
await vscode.commands.executeCommand(Workbench.ACTION_CLOSEALLEDITORS);
30+
});
2731

2832
suite("Function Comment Completion", () => {
2933
test("Completion on line that isn't a comment", async () => {

0 commit comments

Comments
 (0)