← All exercises

The view that rewrites the store

Sorted views in a to-do app's task store · difficulty 2/3 · ~8 min

A teammate asked the AI assistant: "Our task store keeps one array of tasks and the UI derives views from it: by priority, newest first, open tasks only. Write the view helpers. They must return new arrays and never touch the store's array, because several components read it at the same time." The code came back with a clear docstring on every helper and green tests. The contract promised by the docstrings: - `sortByPriority` returns a new array, most urgent first; equal priorities keep their relative order. - `newestFirst` returns a new array ordered by `createdAt`, newest first. - `openByPriority` returns the open tasks, most urgent first. - `take` returns the first `n` tasks of a view. - None of the helpers mutates `tasks`. One of the visible tests even checks that the input is untouched. Review the helpers against the full contract, not just the ordering.
Repair the code until the hidden tests pass.

code.ts

Visible tests (they pass on the code as given)
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"]);
  });
});