Sari la conținut
← Toate exercițiile

View-ul care rescrie store-ul

TypeScript · View-uri sortate în store-ul de taskuri al unei aplicații to-do · API-uri și contracte · dificultate 2/3 · ~8 min

Un coleg i-a cerut asistentului AI: „Store-ul nostru de taskuri ține un singur array de taskuri, iar UI-ul derivă view-uri din el: după prioritate, cele mai noi întâi, doar taskurile deschise. Scrie helperii pentru view-uri. Trebuie să returneze array-uri noi și să nu atingă niciodată array-ul din store, pentru că mai multe componente îl citesc în același timp.”

Codul a venit cu un docstring clar pe fiecare helper și cu teste verzi. Contractul promis de docstring-uri:

  • sortByPriority returnează un array nou, cu cele mai urgente întâi; prioritățile egale își păstrează ordinea relativă.
  • newestFirst returnează un array nou, ordonat după createdAt, cu cele mai noi întâi.
  • openByPriority returnează taskurile deschise, cu cele mai urgente întâi.
  • take returnează primele n taskuri dintr-un view.
  • Niciunul dintre helperi nu modifică tasks.

Unul dintre testele vizibile chiar verifică faptul că inputul rămâne neatins. Verifică helperii față de tot contractul, nu doar față de ordonare.

Repară codul până trec testele ascunse.

code.ts

Teste vizibile (trec pe codul primit)
import { describe, it, expect } from "@debunk/harness";
import { sortByPriority, newestFirst, openByPriority, type Task } from "./code";

const task = (id: string, priority: number, createdAt: number, done = false): Task => ({
  id,
  title: `Task ${id}`,
  priority,
  createdAt,
  done,
});

describe("task views", () => {
  it("sortByPriority puts the most urgent task first", () => {
    const view = sortByPriority([task("a", 2, 1), task("b", 5, 2), task("c", 3, 3)]);
    expect(view.map((t) => t.id)).toEqual(["b", "c", "a"]);
  });

  it("newestFirst orders by creation time, newest first", () => {
    const view = newestFirst([task("a", 1, 100), task("b", 1, 300), task("c", 1, 200)]);
    expect(view.map((t) => t.id)).toEqual(["b", "c", "a"]);
  });

  it("openByPriority leaves the original list untouched", () => {
    const tasks = [task("a", 1, 1), task("b", 5, 2, true), task("c", 3, 3)];
    const view = openByPriority(tasks);
    expect(view.map((t) => t.id)).toEqual(["c", "a"]);
    expect(tasks.map((t) => t.id)).toEqual(["a", "b", "c"]);
  });
});