Skip to content

Instantly share code, notes, and snippets.

@bxt
Created July 26, 2026 11:23
Show Gist options
  • Select an option

  • Save bxt/1ffef09f65097769b9938a4e2239d77b to your computer and use it in GitHub Desktop.

Select an option

Save bxt/1ffef09f65097769b9938a4e2239d77b to your computer and use it in GitHub Desktop.
Moonpie progeess bars
import { describe, expect, test } from "vitest";
import { moonPieProgress } from "./moonPieProgress.ts";
describe("moonPieProgress", () => {
test("for for length 4", () => {
expect.soft(moonPieProgress(0, 4)).toBe("πŸŒ‘");
expect.soft(moonPieProgress(1, 4)).toBe("🌘");
expect.soft(moonPieProgress(2, 4)).toBe("πŸŒ—");
expect.soft(moonPieProgress(3, 4)).toBe("πŸŒ–");
expect.soft(moonPieProgress(4, 4)).toBe("πŸŒ•");
});
test("for for length 12", () => {
expect.soft(moonPieProgress(0, 12)).toBe("πŸŒ‘πŸŒ‘πŸŒ‘");
expect.soft(moonPieProgress(1, 12)).toBe("πŸŒ˜πŸŒ‘πŸŒ‘");
expect.soft(moonPieProgress(2, 12)).toBe("πŸŒ—πŸŒ‘πŸŒ‘");
expect.soft(moonPieProgress(3, 12)).toBe("πŸŒ–πŸŒ‘πŸŒ‘");
expect.soft(moonPieProgress(4, 12)).toBe("πŸŒ•πŸŒ‘πŸŒ‘");
expect.soft(moonPieProgress(5, 12)).toBe("πŸŒ•πŸŒ˜πŸŒ‘");
expect.soft(moonPieProgress(6, 12)).toBe("πŸŒ•πŸŒ—πŸŒ‘");
expect.soft(moonPieProgress(7, 12)).toBe("πŸŒ•πŸŒ–πŸŒ‘");
expect.soft(moonPieProgress(8, 12)).toBe("πŸŒ•πŸŒ•πŸŒ‘");
expect.soft(moonPieProgress(9, 12)).toBe("πŸŒ•πŸŒ•πŸŒ˜");
expect.soft(moonPieProgress(10, 12)).toBe("πŸŒ•πŸŒ•πŸŒ—");
expect.soft(moonPieProgress(11, 12)).toBe("πŸŒ•πŸŒ•πŸŒ–");
expect.soft(moonPieProgress(12, 12)).toBe("πŸŒ•πŸŒ•πŸŒ•");
});
test("for for length 0", () => {
expect.soft(moonPieProgress(0, 0)).toBe("");
});
test("for for length 1", () => {
expect.soft(moonPieProgress(0, 1)).toBe("πŸŒ‘");
expect.soft(moonPieProgress(1, 1)).toBe("🌘");
});
test("for for length 2", () => {
expect.soft(moonPieProgress(0, 2)).toBe("πŸŒ‘");
expect.soft(moonPieProgress(1, 2)).toBe("🌘");
expect.soft(moonPieProgress(2, 2)).toBe("πŸŒ—");
});
test("for for length 3", () => {
expect.soft(moonPieProgress(0, 3)).toBe("πŸŒ‘");
expect.soft(moonPieProgress(1, 3)).toBe("🌘");
expect.soft(moonPieProgress(2, 3)).toBe("πŸŒ—");
expect.soft(moonPieProgress(3, 3)).toBe("πŸŒ–");
});
test("for for length 7", () => {
expect.soft(moonPieProgress(0, 7)).toBe("πŸŒ‘πŸŒ‘");
expect.soft(moonPieProgress(1, 7)).toBe("πŸŒ˜πŸŒ‘");
expect.soft(moonPieProgress(2, 7)).toBe("πŸŒ—πŸŒ‘");
expect.soft(moonPieProgress(3, 7)).toBe("πŸŒ–πŸŒ‘");
expect.soft(moonPieProgress(4, 7)).toBe("πŸŒ•πŸŒ‘");
expect.soft(moonPieProgress(5, 7)).toBe("πŸŒ•πŸŒ˜");
expect.soft(moonPieProgress(6, 7)).toBe("πŸŒ•πŸŒ—");
expect.soft(moonPieProgress(7, 7)).toBe("πŸŒ•πŸŒ–");
});
describe("throws when values are out of range #bringYourOwnClamp", () => {
test("does not accept negative progress", () => {
expect(() => {
moonPieProgress(-1, 12);
}).toThrow(RangeError);
});
test("does not accept progress overflow", () => {
expect(() => {
moonPieProgress(13, 12);
}).toThrow(RangeError);
});
});
});
const lunaCodePoint = 0x25 * 0b11 * 11_51;
const phases = 4;
const emptyString = String.fromCodePoint(lunaCodePoint);
const filledString = String.fromCodePoint(lunaCodePoint + 4);
/**
* Displays a progress bar using moon emojis.
* @param i Progress value, between 0 and `length` inclusive
* @param length Maximum progress value
* @throws `RangeError` For out of range progress values `i`
* @returns A string like "πŸŒ•πŸŒ˜πŸŒ‘"
*/
export function moonPieProgress(i: number, length: number): string {
const total = Math.ceil(length / phases);
const filled = Math.floor(i / phases);
const filledStrings = filledString.repeat(filled);
const phase = i % phases;
if (phase === 0) return filledStrings + emptyString.repeat(total - filled);
const codePointOffset = (8 - phase) % 8;
const phaseString = String.fromCodePoint(lunaCodePoint + codePointOffset);
return filledStrings + phaseString + emptyString.repeat(total - filled - 1);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment