docs(bytes,collections): fix doc checker and documentation (#4691)

docs(bytes,collection): fix doc checker and documentation
This commit is contained in:
Asher Gomez 2024-05-08 16:18:26 +10:00 committed by GitHub
parent 3dccdc11e5
commit a079dd3fed
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
14 changed files with 60 additions and 39 deletions

View File

@ -25,7 +25,7 @@ const ENTRY_POINTS = [
const MD_SNIPPET = /(?<=```ts\n)(\n|.)*(?=\n```)/g; const MD_SNIPPET = /(?<=```ts\n)(\n|.)*(?=\n```)/g;
class ValidationError extends Error { class DocumentError extends Error {
constructor(message: string, document: DocNodeBase) { constructor(message: string, document: DocNodeBase) {
super(message, { super(message, {
cause: `${document.location.filename}:${document.location.line}`, cause: `${document.location.filename}:${document.location.line}`,
@ -40,14 +40,17 @@ function assert(
document: DocNodeBase, document: DocNodeBase,
): asserts condition { ): asserts condition {
if (!condition) { if (!condition) {
throw new ValidationError(message, document); throw new DocumentError(message, document);
} }
} }
/**
* We only check functions that have JSDocs. We know that exported functions
* have JSDocs thanks to `deno doc --lint`, which is used in the `lint:docs`
* task.
*/
function isFunctionDoc(document: DocNodeBase): document is DocNodeFunction { function isFunctionDoc(document: DocNodeBase): document is DocNodeFunction {
return document.kind === "function" && return document.kind === "function" && document.jsDoc !== undefined;
// Ignores implementation signatures when overload signatures exist
(document as DocNodeFunction).functionDef.hasBody !== true;
} }
function isExported(document: DocNodeBase) { function isExported(document: DocNodeBase) {
@ -87,7 +90,7 @@ function assertHasParamTag(
function assertHasExampleTag(tags: JsDocTag[], document: DocNodeBase) { function assertHasExampleTag(tags: JsDocTag[], document: DocNodeBase) {
tags = tags.filter((tag) => tag.kind === "example"); tags = tags.filter((tag) => tag.kind === "example");
if (tags.length === 0) { if (tags.length === 0) {
throw new ValidationError("Symbol must have an @example tag", document); throw new DocumentError("Symbol must have an @example tag", document);
} }
for (const tag of (tags as JsDocTagDocRequired[])) { for (const tag of (tags as JsDocTagDocRequired[])) {
assert( assert(
@ -97,7 +100,7 @@ function assertHasExampleTag(tags: JsDocTag[], document: DocNodeBase) {
); );
const snippets = tag.doc.match(MD_SNIPPET); const snippets = tag.doc.match(MD_SNIPPET);
if (snippets === null) { if (snippets === null) {
throw new ValidationError( throw new DocumentError(
"@example tag must have a code snippet", "@example tag must have a code snippet",
document, document,
); );
@ -106,14 +109,18 @@ function assertHasExampleTag(tags: JsDocTag[], document: DocNodeBase) {
const command = new Deno.Command(Deno.execPath(), { const command = new Deno.Command(Deno.execPath(), {
args: [ args: [
"eval", "eval",
"--ext=ts",
snippet, snippet,
], ],
stderr: "piped",
}); });
// TODO(iuioiua): Use `await command.output()` // TODO(iuioiua): Use `await command.output()`
const { success } = command.outputSync(); const { success, stderr } = command.outputSync();
assert( assert(
success, success,
`Example code snippet failed to execute: \n${snippet}\n`, `Example code snippet failed to execute: \n${snippet}\n${
new TextDecoder().decode(stderr)
}`,
document, document,
); );
} }

View File

@ -10,11 +10,12 @@
* @example Basic usage * @example Basic usage
* ```ts * ```ts
* import { concat } from "@std/bytes/concat"; * import { concat } from "@std/bytes/concat";
* import { assertEquals } from "@std/assert/assert-equals"
* *
* const a = new Uint8Array([0, 1, 2]); * const a = new Uint8Array([0, 1, 2]);
* const b = new Uint8Array([3, 4, 5]); * const b = new Uint8Array([3, 4, 5]);
* *
* concat([a, b]); // Uint8Array(6) [ 0, 1, 2, 3, 4, 5 ] * assertEquals(concat([a, b]), new Uint8Array([0, 1, 2, 3, 4, 5]));
* ``` * ```
*/ */
export function concat(buffers: Uint8Array[]): Uint8Array { export function concat(buffers: Uint8Array[]): Uint8Array {

View File

@ -17,23 +17,25 @@
* @example Basic usage * @example Basic usage
* ```ts * ```ts
* import { copy } from "@std/bytes/copy"; * import { copy } from "@std/bytes/copy";
* import { assertEquals } from "@std/assert/assert-equals";
* *
* const src = new Uint8Array([9, 8, 7]); * const src = new Uint8Array([9, 8, 7]);
* const dst = new Uint8Array([0, 1, 2, 3, 4, 5]); * const dst = new Uint8Array([0, 1, 2, 3, 4, 5]);
* *
* copy(src, dst); // 3 * assertEquals(copy(src, dst), 3);
* dst; // Uint8Array(6) [9, 8, 7, 3, 4, 5] * assertEquals(dst, new Uint8Array([9, 8, 7, 3, 4, 5]));
* ``` * ```
* *
* @example Copy with offset * @example Copy with offset
* ```ts * ```ts
* import { copy } from "@std/bytes/copy"; * import { copy } from "@std/bytes/copy";
* import { assertEquals } from "@std/assert/assert-equals";
* *
* const src = new Uint8Array([1, 1, 1, 1]); * const src = new Uint8Array([1, 1, 1, 1]);
* const dst = new Uint8Array([0, 0, 0, 0]); * const dst = new Uint8Array([0, 0, 0, 0]);
* *
* copy(src, dst, 1); // 3 * assertEquals(copy(src, dst, 1), 3);
* dst; // Uint8Array(4) [0, 1, 1, 1] * assertEquals(dst, new Uint8Array([0, 1, 1, 1]));
* ``` * ```
* Defining an offset will start copying at the specified index in the * Defining an offset will start copying at the specified index in the
* destination array. * destination array.

View File

@ -15,11 +15,12 @@
* @example Basic usage * @example Basic usage
* ```ts * ```ts
* import { endsWith } from "@std/bytes/ends-with"; * import { endsWith } from "@std/bytes/ends-with";
* import { assertEquals } from "@std/assert/assert-equals";
* *
* const source = new Uint8Array([0, 1, 2, 1, 2, 1, 2, 3]); * const source = new Uint8Array([0, 1, 2, 1, 2, 1, 2, 3]);
* const suffix = new Uint8Array([1, 2, 3]); * const suffix = new Uint8Array([1, 2, 3]);
* *
* endsWith(source, suffix); // true * assertEquals(endsWith(source, suffix), true);
* ``` * ```
*/ */
export function endsWith(source: Uint8Array, suffix: Uint8Array): boolean { export function endsWith(source: Uint8Array, suffix: Uint8Array): boolean {

View File

@ -69,13 +69,14 @@ const THRESHOLD_32_BIT = 160;
* @example Basic usage * @example Basic usage
* ```ts * ```ts
* import { equals } from "@std/bytes/equals"; * import { equals } from "@std/bytes/equals";
* import { assertEquals } from "@std/assert/assert-equals";
* *
* const a = new Uint8Array([1, 2, 3]); * const a = new Uint8Array([1, 2, 3]);
* const b = new Uint8Array([1, 2, 3]); * const b = new Uint8Array([1, 2, 3]);
* const c = new Uint8Array([4, 5, 6]); * const c = new Uint8Array([4, 5, 6]);
* *
* equals(a, b); // true * assertEquals(equals(a, b), true);
* equals(b, c); // false * assertEquals(equals(a, c), false);
* ``` * ```
*/ */
export function equals(a: Uint8Array, b: Uint8Array): boolean { export function equals(a: Uint8Array, b: Uint8Array): boolean {

View File

@ -18,21 +18,24 @@ import { indexOfNeedle } from "./index_of_needle.ts";
* @example Basic usage * @example Basic usage
* ```ts * ```ts
* import { includesNeedle } from "@std/bytes/includes-needle"; * import { includesNeedle } from "@std/bytes/includes-needle";
* import { assertEquals } from "@std/assert/assert-equals";
* *
* const source = new Uint8Array([0, 1, 2, 1, 2, 1, 2, 3]); * const source = new Uint8Array([0, 1, 2, 1, 2, 1, 2, 3]);
* const needle = new Uint8Array([1, 2]); * const needle = new Uint8Array([1, 2]);
* *
* includesNeedle(source, needle); // true * assertEquals(includesNeedle(source, needle), true);
* ``` * ```
* *
* @example Start index * @example Start index
* ```ts * ```ts
* import { includesNeedle } from "@std/bytes/includes-needle"; * import { includesNeedle } from "@std/bytes/includes-needle";
* import { assertEquals } from "@std/assert/assert-equals";
* *
* const source = new Uint8Array([0, 1, 2, 1, 2, 1, 2, 3]); * const source = new Uint8Array([0, 1, 2, 1, 2, 1, 2, 3]);
* const needle = new Uint8Array([1, 2]); * const needle = new Uint8Array([1, 2]);
* *
* includesNeedle(source, needle, 6); // false * assertEquals(includesNeedle(source, needle, 3), true);
* assertEquals(includesNeedle(source, needle, 6), false);
* ``` * ```
* The search will start at the specified index in the source array. * The search will start at the specified index in the source array.
*/ */

View File

@ -20,24 +20,26 @@
* @example Basic usage * @example Basic usage
* ```ts * ```ts
* import { indexOfNeedle } from "@std/bytes/index-of-needle"; * import { indexOfNeedle } from "@std/bytes/index-of-needle";
* import { assertEquals } from "@std/assert/assert-equals";
* *
* const source = new Uint8Array([0, 1, 2, 1, 2, 1, 2, 3]); * const source = new Uint8Array([0, 1, 2, 1, 2, 1, 2, 3]);
* const needle = new Uint8Array([1, 2]); * const needle = new Uint8Array([1, 2]);
* const notNeedle = new Uint8Array([5, 0]); * const notNeedle = new Uint8Array([5, 0]);
* *
* indexOfNeedle(source, needle); // 1 * assertEquals(indexOfNeedle(source, needle), 1);
* indexOfNeedle(source, notNeedle); // -1 * assertEquals(indexOfNeedle(source, notNeedle), -1);
* ``` * ```
* *
* @example Start index * @example Start index
* ```ts * ```ts
* import { indexOfNeedle } from "@std/bytes/index-of-needle"; * import { indexOfNeedle } from "@std/bytes/index-of-needle";
* import { assertEquals } from "@std/assert/assert-equals";
* *
* const source = new Uint8Array([0, 1, 2, 1, 2, 1, 2, 3]); * const source = new Uint8Array([0, 1, 2, 1, 2, 1, 2, 3]);
* const needle = new Uint8Array([1, 2]); * const needle = new Uint8Array([1, 2]);
* *
* indexOfNeedle(source, needle, 2); // 3 * assertEquals(indexOfNeedle(source, needle, 2), 3);
* indexOfNeedle(source, needle, 6); // -1 * assertEquals(indexOfNeedle(source, needle, 6), -1);
* ``` * ```
* Defining a start index will begin the search at the specified index in the * Defining a start index will begin the search at the specified index in the
* source array. * source array.

View File

@ -17,24 +17,26 @@
* @example Basic usage * @example Basic usage
* ```ts * ```ts
* import { lastIndexOfNeedle } from "@std/bytes/last-index-of-needle"; * import { lastIndexOfNeedle } from "@std/bytes/last-index-of-needle";
* import { assertEquals } from "@std/assert/assert-equals";
* *
* const source = new Uint8Array([0, 1, 2, 1, 2, 1, 2, 3]); * const source = new Uint8Array([0, 1, 2, 1, 2, 1, 2, 3]);
* const needle = new Uint8Array([1, 2]); * const needle = new Uint8Array([1, 2]);
* const notNeedle = new Uint8Array([5, 0]); * const notNeedle = new Uint8Array([5, 0]);
* *
* lastIndexOfNeedle(source, needle); // 5 * assertEquals(lastIndexOfNeedle(source, needle), 5);
* lastIndexOfNeedle(source, notNeedle); // -1 * assertEquals(lastIndexOfNeedle(source, notNeedle), -1);
* ``` * ```
* *
* @example Start index * @example Start index
* ```ts * ```ts
* import { lastIndexOfNeedle } from "@std/bytes/last-index-of-needle"; * import { lastIndexOfNeedle } from "@std/bytes/last-index-of-needle";
* import { assertEquals } from "@std/assert/assert-equals";
* *
* const source = new Uint8Array([0, 1, 2, 1, 2, 1, 2, 3]); * const source = new Uint8Array([0, 1, 2, 1, 2, 1, 2, 3]);
* const needle = new Uint8Array([1, 2]); * const needle = new Uint8Array([1, 2]);
* *
* lastIndexOfNeedle(source, needle, 2); // 1 * assertEquals(lastIndexOfNeedle(source, needle, 2), 1);
* lastIndexOfNeedle(source, needle, 6); // 5 * assertEquals(lastIndexOfNeedle(source, needle, 6), 5);
* ``` * ```
* Defining a start index will begin the search at the specified index in the * Defining a start index will begin the search at the specified index in the
* source array. * source array.

View File

@ -18,9 +18,7 @@ import { copy } from "./copy.ts";
* *
* const source = new Uint8Array([0, 1, 2]); * const source = new Uint8Array([0, 1, 2]);
* *
* const result = repeat(source, 3); * assertEquals(repeat(source, 3), new Uint8Array([0, 1, 2, 0, 1, 2, 0, 1, 2]));
*
* assertEquals(result, new Uint8Array([0, 1, 2, 0, 1, 2, 0, 1, 2]));
* ``` * ```
* *
* @example Zero count * @example Zero count
@ -30,9 +28,7 @@ import { copy } from "./copy.ts";
* *
* const source = new Uint8Array([0, 1, 2]); * const source = new Uint8Array([0, 1, 2]);
* *
* const result = repeat(source, 0); * assertEquals(repeat(source, 0), new Uint8Array());
*
* assertEquals(result, new Uint8Array());
* ``` * ```
*/ */
export function repeat(source: Uint8Array, count: number): Uint8Array { export function repeat(source: Uint8Array, count: number): Uint8Array {

View File

@ -15,11 +15,12 @@
* @example Basic usage * @example Basic usage
* ```ts * ```ts
* import { startsWith } from "@std/bytes/starts-with"; * import { startsWith } from "@std/bytes/starts-with";
* import { assertEquals } from "@std/assert/assert-equals";
* *
* const source = new Uint8Array([0, 1, 2, 1, 2, 1, 2, 3]); * const source = new Uint8Array([0, 1, 2, 1, 2, 1, 2, 3]);
* const prefix = new Uint8Array([0, 1, 2]); * const prefix = new Uint8Array([0, 1, 2]);
* *
* startsWith(source, prefix); // true * assertEquals(startsWith(source, prefix), true);
* ``` * ```
*/ */
export function startsWith(source: Uint8Array, prefix: Uint8Array): boolean { export function startsWith(source: Uint8Array, prefix: Uint8Array): boolean {

View File

@ -18,11 +18,11 @@
* import { dropLastWhile } from "@std/collections/drop-last-while"; * import { dropLastWhile } from "@std/collections/drop-last-while";
* import { assertEquals } from "@std/assert/assert-equals"; * import { assertEquals } from "@std/assert/assert-equals";
* *
* const numbers = [22, 30, 44]; * const numbers = [20, 33, 44];
* *
* const notFortyFour = dropLastWhile(numbers, (number) => number !== 44); * const notFortyFour = dropLastWhile(numbers, (number) => number > 30);
* *
* assertEquals(notFortyFour, [22, 30]); * assertEquals(notFortyFour, [20]);
* ``` * ```
*/ */
export function dropLastWhile<T>( export function dropLastWhile<T>(

View File

@ -15,6 +15,9 @@ import { mapValues } from "./map_values.ts";
* @param reducer The reducer function to apply to each group. * @param reducer The reducer function to apply to each group.
* @param initialValue The initial value of the accumulator. * @param initialValue The initial value of the accumulator.
* *
* @returns A record with the same keys as the input grouping, where each value
* is the result of applying the reducer to the respective group.
*
* @example Basic usage * @example Basic usage
* ```ts * ```ts
* import { reduceGroups } from "@std/collections/reduce-groups"; * import { reduceGroups } from "@std/collections/reduce-groups";

View File

@ -13,6 +13,8 @@
* @param reducer The reducer function to apply to each element. * @param reducer The reducer function to apply to each element.
* @param initialValue The initial value of the accumulator. * @param initialValue The initial value of the accumulator.
* *
* @returns An array of all intermediate accumulator results.
*
* @example Basic usage * @example Basic usage
* ```ts * ```ts
* import { runningReduce } from "@std/collections/running-reduce"; * import { runningReduce } from "@std/collections/running-reduce";

View File

@ -17,12 +17,12 @@ import { randomInteger } from "./_utils.ts";
* @example Basic usage * @example Basic usage
* ```ts * ```ts
* import { sample } from "@std/collections/sample"; * import { sample } from "@std/collections/sample";
* import { assert } from "@std/assert/assert"; * import { assertArrayIncludes } from "@std/assert/assert-array-includes";
* *
* const numbers = [1, 2, 3, 4]; * const numbers = [1, 2, 3, 4];
* const random = sample(numbers); * const random = sample(numbers);
* *
* assert(numbers.includes(random!)); * assertArrayIncludes(numbers, [random]);
* ``` * ```
*/ */
export function sample<T>(array: readonly T[]): T | undefined { export function sample<T>(array: readonly T[]): T | undefined {