Skip to content

Commit

Permalink
refactor(cli): change spinner.message to property & document
Browse files Browse the repository at this point in the history
  • Loading branch information
andrewthauer committed May 23, 2024
1 parent 082107b commit ccdc5aa
Show file tree
Hide file tree
Showing 2 changed files with 67 additions and 11 deletions.
65 changes: 54 additions & 11 deletions cli/spinner.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,13 +74,35 @@ export interface SpinnerOptions {
*/
export class Spinner {
#spinner: string[];
/** The message to display next to the spinner. */
message: string;
#interval: number;
#color?: Color;
#intervalId: number | undefined;
#active = false;

/**
* The message to display next to the spinner.
* This can be changed while the spinner is active.
*
* @example
* ```ts
* import { Spinner } from "@std/cli/spinner";
*
* const spinner = new Spinner({ message: "Working..." });
* spinner.start();
*
* for (let step = 0; step < 5; step++) {
* // do some work
* await new Promise((resolve) => setTimeout(resolve, 1000));
*
* spinner.message = `Finished Step #${step}`;
* }
*
* spinner.stop();
* spinner.message = "Done!";
* ```
*/
message: string = "";

/**
* Creates a new spinner.
*
Expand All @@ -89,16 +111,15 @@ export class Spinner {
* import { Spinner } from "@std/cli/spinner";
*
* const spinner = new Spinner({ message: "Loading..." });
* spinner.stop();
* ```
*/
constructor(
{
spinner = DEFAULT_SPINNER,
message = "",
interval = DEFAULT_INTERVAL,
color,
}: SpinnerOptions = {},
) {
constructor({
spinner = DEFAULT_SPINNER,
message = "",
interval = DEFAULT_INTERVAL,
color,
}: SpinnerOptions = {}) {
this.#spinner = spinner;
this.message = message;
this.#interval = interval;
Expand All @@ -108,11 +129,27 @@ export class Spinner {
/**
* Set the color of the spinner. This defaults to the default terminal color.
* This can be changed while the spinner is active.
*
* @example
* ```ts
* import { Spinner } from "@std/cli/spinner";
*
* const spinner = new Spinner({ message: "Loading...", color: "yellow" });
* spinner.start();
*
* // do some work
* await new Promise((resolve) => setTimeout(resolve, 1000));
*
* spinner.color = "magenta";
* ```
*/
set color(value: Color | undefined) {
this.#color = value ? COLORS[value] : undefined;
}

/**
* Get the current color of the spinner.
*/
get color(): Color | undefined {
return this.#color;
}
Expand All @@ -129,10 +166,14 @@ export class Spinner {
* ```
*/
start() {
if (this.#active || Deno.stdout.writable.locked) return;
if (this.#active || Deno.stdout.writable.locked) {
return;
}

Check warning on line 171 in cli/spinner.ts

View check run for this annotation

Codecov / codecov/patch

cli/spinner.ts#L169-L171

Added lines #L169 - L171 were not covered by tests

this.#active = true;
let i = 0;
const noColor = Deno.noColor;

// Updates the spinner after the given interval.
const updateFrame = () => {
const color = this.#color ?? "";
Expand All @@ -145,8 +186,10 @@ export class Spinner {
Deno.stdout.writeSync(frame);
i = (i + 1) % this.#spinner.length;
};

this.#intervalId = setInterval(updateFrame, this.#interval);
}

/**
* Stops the spinner.
*
Expand Down
13 changes: 13 additions & 0 deletions cli/spinner_test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -188,3 +188,16 @@ Deno.test("Spinner.message can be updated", async () => {
assertStringIncludes(actual, "One dino 🦕");
assertStringIncludes(actual, "Two dinos 🦕🦕");
});

Deno.test("Spinner.message returns the current value when updated", () => {
const spinner = new Spinner();

spinner.message = "Step 1";
assertEquals(spinner.message, "Step 1");

spinner.message = "Step 2";
assertEquals(spinner.message, "Step 2");

spinner.message = "Step 3";
assertEquals(spinner.message, "Step 3");
});

0 comments on commit ccdc5aa

Please sign in to comment.