Documentation
    Preparing search index...
    • Validates sorting functionality of pagination APIs.

      Tests sorting operations by calling the API with sort parameters and validating that results are correctly ordered. Supports multiple fields, ascending/descending order, and optional filtering. Provides detailed error reporting for sorting failures.

      Processing cost: After one getter call, an optional filter scans N results and sortedness checks at most N minus one adjacent pairs. Signed field construction costs O(F); filter output costs O(N) space when requested.

      Reuse: Each invocation must evaluate its supplied task or request to observe current behavior; prior results cannot replace these effectful checks.

      Resource ownership: The returned promise retains invocation-local state until settlement. The callback owns its external resources, and this validator provides no cancellation or timeout.

      Type Parameters

      • T extends object
      • Fields extends string
      • Sortable extends (`-${Fields}` | `+${Fields}`)[] = (`-${Fields}` | `+${Fields}`)[]

      Parameters

      • title: string

        Descriptive title used in error messages when sorting fails

      • getter: (sortable: Sortable) => Promise<T[]>

        API function that fetches sorted data

      Returns (
          ...fields: Fields[],
      ) => (
          comp: (x: T, y: T) => number,
          filter?: (elem: T) => boolean,
      ) => (direction: "+" | "-", trace?: boolean) => Promise<void>

      A currying function chain: field names, comparator, then direction

      // Test single field sorting with GaffComparator
      const sortValidator = TestValidator.sort(
      "article sorting",
      (sortable) => api.getArticles({ sort: sortable }),
      )("created_at")(GaffComparator.dates((a) => a.created_at));

      await sortValidator("+"); // ascending
      await sortValidator("-"); // descending

      // Test multi-field sorting with GaffComparator
      const userSortValidator = TestValidator.sort(
      "user sorting",
      (sortable) => api.getUsers({ sort: sortable }),
      )("lastName", "firstName")(
      GaffComparator.strings((user) => [user.lastName, user.firstName]),
      (user) => user.isActive, // only test active users
      );

      await userSortValidator("+", true); // ascending with trace logging

      // Custom comparator for complex logic
      const customSortValidator = TestValidator.sort(
      "custom sorting",
      (sortable) => api.getProducts({ sort: sortable }),
      )(
      "price",
      "rating",
      )((a, b) => {
      const priceDiff = a.price - b.price;
      return priceDiff !== 0 ? priceDiff : b.rating - a.rating; // price asc, rating desc
      });

      Error when API results are not properly sorted according to specification

      contracts/common.md#principled-implementation The API is called with the signed field names, its result is optionally filtered, and the comparator (reversed for the descending direction) is applied to adjacent pairs, so any adjacent pair out of order fails; checking adjacent pairs suffices for a total preorder.

      contracts/common.md#clear-and-simple-design The function is curried in three steps so the request, the comparator, and the direction can be given at the moments each is known.

      contracts/common.md#prohibited-implementation-shortcuts The order is judged by the caller's comparator, with no field or direction special-cased.

      contracts/common.md#meaningful-documentation The comment documents each stage, the parameters, and the thrown error, with examples.