Skip to content

Commit

Permalink
refactor(vscode): allow quickPickApplication to be shared (#956)
Browse files Browse the repository at this point in the history
  • Loading branch information
alestiago committed Aug 24, 2023
1 parent 8d6960c commit 74476e1
Show file tree
Hide file tree
Showing 5 changed files with 400 additions and 121 deletions.
68 changes: 11 additions & 57 deletions extensions/vscode/src/commands/stop-dev-server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,11 @@ import {
commands,
window,
} from "vscode";
import { isDartFrogCLIInstalled, suggestInstallingDartFrogCLI } from "../utils";
import {
isDartFrogCLIInstalled,
quickPickApplication,
suggestInstallingDartFrogCLI,
} from "../utils";
import {
DartFrogApplication,
DartFrogApplicationRegistry,
Expand Down Expand Up @@ -56,7 +60,12 @@ export const stopDevServer = async (): Promise<void> => {
const application =
applications.length === 1
? applications[0]
: await quickPickApplication(applications);
: await quickPickApplication(
{
placeHolder: "Select a server to stop",
},
applications
);
if (!application) {
return;
}
Expand Down Expand Up @@ -104,61 +113,6 @@ export const stopDevServer = async (): Promise<void> => {
);
};

class PickableDartFrogApplication implements QuickPickItem {
constructor(dartFrogApplication: DartFrogApplication) {
const addressWithoutProtocol = dartFrogApplication.address!.replace(
/.*?:\/\//g,
""
);
this.label = `$(globe) ${addressWithoutProtocol}`;
this.description = dartFrogApplication.id!.toString();
this.application = dartFrogApplication;
}

public readonly application: DartFrogApplication;

label: string;
kind?: QuickPickItemKind | undefined;
description?: string | undefined;
detail?: string | undefined;
picked?: boolean | undefined;
alwaysShow?: boolean | undefined;
buttons?: readonly QuickInputButton[] | undefined;
}

/**
* Prompts the user to select a {@link DartFrogApplication} from a list of
* running {@link DartFrogApplication}s.
*
* @param applications The running {@link DartFrogApplication}s to choose from.
* @returns The selected {@link DartFrogApplication} or `undefined` if the user
* cancelled the selection.
*/
async function quickPickApplication(
applications: DartFrogApplication[]
): Promise<DartFrogApplication | undefined> {
const quickPick = window.createQuickPick<PickableDartFrogApplication>();
quickPick.placeholder = "Select a server to stop";
quickPick.busy = true;
quickPick.ignoreFocusOut = true;
quickPick.items = applications.map(
(application) => new PickableDartFrogApplication(application)
);
quickPick.show();

return new Promise<DartFrogApplication | undefined>((resolve) => {
quickPick.onDidChangeSelection((value) => {
quickPick.dispose();

if (!value || value.length === 0) {
resolve(undefined);
} else {
resolve(value[0]!.application);
}
});
});
}

/**
* Waits for a {@link DartFrogApplication} to be deregistered.
*
Expand Down
77 changes: 13 additions & 64 deletions extensions/vscode/src/test/suite/commands/stop-dev-server.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ suite("stop-dev-server command", () => {
let utilsStub: any;
let daemon: any;
let command: any;
let quickPick: any;
let progress: any;

beforeEach(() => {
Expand All @@ -23,23 +22,18 @@ suite("stop-dev-server command", () => {
showInformationMessage: sinon.stub(),
showErrorMessage: sinon.stub(),
withProgress: sinon.stub(),
createQuickPick: sinon.stub(),
},
commands: {
executeCommand: sinon.stub(),
},
};
quickPick = sinon.stub();
vscodeStub.window.createQuickPick.returns(quickPick);
quickPick.show = sinon.stub();
quickPick.dispose = sinon.stub();
quickPick.onDidChangeSelection = sinon.stub();

utilsStub = {
isDartFrogCLIInstalled: sinon.stub(),
suggestInstallingDartFrogCLI: sinon.stub(),
resolveDartFrogProjectPathFromWorkspace: sinon.stub(),
nearestDartFrogProject: sinon.stub(),
quickPickApplication: sinon.stub(),
};
utilsStub.isDartFrogCLIInstalled.returns(true);

Expand Down Expand Up @@ -223,84 +217,39 @@ suite("stop-dev-server command", () => {

beforeEach(() => {
daemon.isReady = true;

application1.id = "application1";
application1.address = `http://localhost:${application1.port}`;

application2.id = "application2";
application2.address = `http://localhost:${application2.port}`;
});

test("is not shown when there is a single running application", async () => {
daemon.applicationRegistry.all.returns([application1]);

await command.stopDevServer();

sinon.assert.notCalled(vscodeStub.window.createQuickPick);
sinon.assert.notCalled(utilsStub.quickPickApplication);
});

test("is shown when there is more than a single running application", async () => {
daemon.applicationRegistry.all.returns([application1, application2]);
utilsStub.quickPickApplication.resolves(application1);

const stopDevServer = command.stopDevServer();
const onDidChangeSelection =
quickPick.onDidChangeSelection.getCall(0).args[0];
onDidChangeSelection([]);

await stopDevServer;
await command.stopDevServer();

sinon.assert.calledOnce(vscodeStub.window.createQuickPick);
sinon.assert.calledOnceWithExactly(
utilsStub.quickPickApplication,
{
placeHolder: "Select a server to stop",
},
[application1, application2]
);
});

test("never stops the server when dismissed", async () => {
daemon.applicationRegistry.all.returns([application1, application2]);
utilsStub.quickPickApplication.resolves(undefined);

const stopDevServer = command.stopDevServer();
const onDidChangeSelection =
quickPick.onDidChangeSelection.getCall(0).args[0];
onDidChangeSelection(undefined);

await stopDevServer;
await command.stopDevServer();

sinon.assert.notCalled(daemon.send);
});

test("shows appropiate items for each running applications", async () => {
daemon.applicationRegistry.all.returns([application1, application2]);

const stopDevServer = command.stopDevServer();
const onDidChangeSelection =
quickPick.onDidChangeSelection.getCall(0).args[0];
onDidChangeSelection(undefined);

await stopDevServer;

const items = quickPick.items;

sinon.assert.match(items[0], {
label: `$(globe) localhost:${application1.port}`,
description: application1.id,
application: application1,
});
sinon.assert.match(items[1], {
label: `$(globe) localhost:${application2.port}`,
description: application2.id,
application: application2,
});
});

test("is disposed after selection", async () => {
daemon.applicationRegistry.all.returns([application1, application2]);

const stopDevServer = command.stopDevServer();
const onDidChangeSelection =
quickPick.onDidChangeSelection.getCall(0).args[0];
onDidChangeSelection([application1]);

await stopDevServer;

sinon.assert.calledOnce(quickPick.dispose);
});
});

suite("progress", () => {
Expand Down
Loading

0 comments on commit 74476e1

Please sign in to comment.