test-suite.js en JavaScript
Un archivo de pruebas completo: suites, hooks, casos en tabla, mocks y tiempo simulado.
#!/usr/bin/env node --test
import { before, beforeEach, describe, it } from "node:test";
import assert from "node:assert/strict";
class Scorer {
#history = [];
constructor(target = 90) {
if (target <= 0) throw new RangeError("target must be positive");
this.target = target;
}
stars(tpm, accuracy) {
if (accuracy < 0 || accuracy > 100) {
throw new RangeError(`accuracy out of range: ${accuracy}`);
}
let earned = 1;
if (accuracy >= 95) earned = 2;
if (accuracy >= 98 && tpm >= this.target) earned = 3;
this.#history.push(earned);
return earned;
}
get best() {
return this.#history.length ? Math.max(...this.#history) : 0;
}
async save(store) {
return store.write(this.#history);
}
}
describe("Scorer", () => {
let scorer;
before(() => assert.equal(typeof Scorer, "function"));
beforeEach(() => { scorer = new Scorer(90); });
describe("stars", () => {
const cases = [
{ name: "slow but clean", tpm: 60, accuracy: 99, want: 2 },
{ name: "fast and clean", tpm: 95, accuracy: 99, want: 3 },
{ name: "fast and sloppy", tpm: 95, accuracy: 80, want: 1 },
{ name: "exactly at the bar", tpm: 90, accuracy: 98, want: 3 },
];
for (const { name, tpm, accuracy, want } of cases) {
it(name, () => assert.equal(scorer.stars(tpm, accuracy), want));
}
it("rejects an impossible accuracy", () => {
assert.throws(() => scorer.stars(90, 140), {
name: "RangeError",
message: /out of range/,
});
});
});
describe("best", () => {
it("is zero before any run", () => assert.equal(scorer.best, 0));
it("keeps the highest", () => {
scorer.stars(95, 99);
scorer.stars(10, 50);
assert.equal(scorer.best, 3);
});
});
describe("save", () => {
it("hands the history to the store", async (t) => {
const write = t.mock.fn(async () => "written");
scorer.stars(95, 99);
assert.equal(await scorer.save({ write }), "written");
assert.equal(write.mock.callCount(), 1);
assert.deepEqual(write.mock.calls[0].arguments, [[3]]);
});
});
it("refuses a zero target", () => {
assert.throws(() => new Scorer(0), /positive/);
});
});
Cómo funciona
- El código bajo prueba va arriba, así el archivo se sostiene solo.
- Los casos viven en un arreglo: agregar uno es una sola línea.
- Los mocks y los temporizadores simulados la mantienen rápida y determinista.
Palabras clave y builtins usados aquí
Mathasyncawaitclassconstconstructorforfromifimportletofreturnthisthrowthrows
El intento, en números
- Líneas
- 83
- Caracteres a escribir
- 2000
- Tokens
- 588
- Ritmo de tres estrellas
- 110 tpm
Al ritmo de tres estrellas de 110 tokens por minuto, este intento toma unos 321 segundos.
Paso 1 de 1 en Bis; paso 9 de 9 en Pruebas con node:test.