From 8ae862abf20c6a7647ac4e2b35e2c7121916ae0f Mon Sep 17 00:00:00 2001 From: Asher Gomez Date: Wed, 8 May 2024 11:35:53 +1000 Subject: [PATCH] docs(bytes,collection): fix doc checker and documentation --- _tools/check_docs.ts | 25 ++++++++++++++++--------- bytes/concat.ts | 3 ++- bytes/copy.ts | 10 ++++++---- bytes/ends_with.ts | 3 ++- bytes/equals.ts | 5 +++-- bytes/includes_needle.ts | 7 +++++-- bytes/index_of_needle.ts | 10 ++++++---- bytes/last_index_of_needle.ts | 10 ++++++---- bytes/repeat.ts | 8 ++------ bytes/starts_with.ts | 3 ++- collections/drop_last_while.ts | 6 +++--- collections/reduce_groups.ts | 3 +++ collections/running_reduce.ts | 2 ++ collections/sample.ts | 4 ++-- 14 files changed, 60 insertions(+), 39 deletions(-) diff --git a/_tools/check_docs.ts b/_tools/check_docs.ts index dfa3f07e41f9..f769d49d53c2 100644 --- a/_tools/check_docs.ts +++ b/_tools/check_docs.ts @@ -25,7 +25,7 @@ const ENTRY_POINTS = [ const MD_SNIPPET = /(?<=```ts\n)(\n|.)*(?=\n```)/g; -class ValidationError extends Error { +class DocumentError extends Error { constructor(message: string, document: DocNodeBase) { super(message, { cause: `${document.location.filename}:${document.location.line}`, @@ -40,14 +40,17 @@ function assert( document: DocNodeBase, ): asserts 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 { - return document.kind === "function" && - // Ignores implementation signatures when overload signatures exist - (document as DocNodeFunction).functionDef.hasBody !== true; + return document.kind === "function" && document.jsDoc !== undefined; } function isExported(document: DocNodeBase) { @@ -87,7 +90,7 @@ function assertHasParamTag( function assertHasExampleTag(tags: JsDocTag[], document: DocNodeBase) { tags = tags.filter((tag) => tag.kind === "example"); 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[])) { assert( @@ -97,7 +100,7 @@ function assertHasExampleTag(tags: JsDocTag[], document: DocNodeBase) { ); const snippets = tag.doc.match(MD_SNIPPET); if (snippets === null) { - throw new ValidationError( + throw new DocumentError( "@example tag must have a code snippet", document, ); @@ -106,14 +109,18 @@ function assertHasExampleTag(tags: JsDocTag[], document: DocNodeBase) { const command = new Deno.Command(Deno.execPath(), { args: [ "eval", + "--ext=ts", snippet, ], + stderr: "piped", }); // TODO(iuioiua): Use `await command.output()` - const { success } = command.outputSync(); + const { success, stderr } = command.outputSync(); assert( success, - `Example code snippet failed to execute: \n${snippet}\n`, + `Example code snippet failed to execute: \n${snippet}\n${ + new TextDecoder().decode(stderr) + }`, document, ); } diff --git a/bytes/concat.ts b/bytes/concat.ts index 5d1a004678d4..7a0bda05e900 100644 --- a/bytes/concat.ts +++ b/bytes/concat.ts @@ -10,11 +10,12 @@ * @example Basic usage * ```ts * import { concat } from "@std/bytes/concat"; + * import { assertEquals } from "@std/assert/assert-equals" * * const a = new Uint8Array([0, 1, 2]); * 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 { diff --git a/bytes/copy.ts b/bytes/copy.ts index 197147ac84d0..d2c0185f58bc 100644 --- a/bytes/copy.ts +++ b/bytes/copy.ts @@ -17,23 +17,25 @@ * @example Basic usage * ```ts * import { copy } from "@std/bytes/copy"; + * import { assertEquals } from "@std/assert/assert-equals"; * * const src = new Uint8Array([9, 8, 7]); * const dst = new Uint8Array([0, 1, 2, 3, 4, 5]); * - * copy(src, dst); // 3 - * dst; // Uint8Array(6) [9, 8, 7, 3, 4, 5] + * assertEquals(copy(src, dst), 3); + * assertEquals(dst, new Uint8Array([9, 8, 7, 3, 4, 5])); * ``` * * @example Copy with offset * ```ts * import { copy } from "@std/bytes/copy"; + * import { assertEquals } from "@std/assert/assert-equals"; * * const src = new Uint8Array([1, 1, 1, 1]); * const dst = new Uint8Array([0, 0, 0, 0]); * - * copy(src, dst, 1); // 3 - * dst; // Uint8Array(4) [0, 1, 1, 1] + * assertEquals(copy(src, dst, 1), 3); + * assertEquals(dst, new Uint8Array([0, 1, 1, 1])); * ``` * Defining an offset will start copying at the specified index in the * destination array. diff --git a/bytes/ends_with.ts b/bytes/ends_with.ts index 8edb9272ada0..2a438150f066 100644 --- a/bytes/ends_with.ts +++ b/bytes/ends_with.ts @@ -15,11 +15,12 @@ * @example Basic usage * ```ts * 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 suffix = new Uint8Array([1, 2, 3]); * - * endsWith(source, suffix); // true + * assertEquals(endsWith(source, suffix), true); * ``` */ export function endsWith(source: Uint8Array, suffix: Uint8Array): boolean { diff --git a/bytes/equals.ts b/bytes/equals.ts index 28bb87f69083..42abad6a0af1 100644 --- a/bytes/equals.ts +++ b/bytes/equals.ts @@ -69,13 +69,14 @@ const THRESHOLD_32_BIT = 160; * @example Basic usage * ```ts * import { equals } from "@std/bytes/equals"; + * import { assertEquals } from "@std/assert/assert-equals"; * * const a = new Uint8Array([1, 2, 3]); * const b = new Uint8Array([1, 2, 3]); * const c = new Uint8Array([4, 5, 6]); * - * equals(a, b); // true - * equals(b, c); // false + * assertEquals(equals(a, b), true); + * assertEquals(equals(a, c), false); * ``` */ export function equals(a: Uint8Array, b: Uint8Array): boolean { diff --git a/bytes/includes_needle.ts b/bytes/includes_needle.ts index 35fea061b49d..10cdf95803a3 100644 --- a/bytes/includes_needle.ts +++ b/bytes/includes_needle.ts @@ -18,21 +18,24 @@ import { indexOfNeedle } from "./index_of_needle.ts"; * @example Basic usage * ```ts * 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 needle = new Uint8Array([1, 2]); * - * includesNeedle(source, needle); // true + * assertEquals(includesNeedle(source, needle), true); * ``` * * @example Start index * ```ts * 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 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. */ diff --git a/bytes/index_of_needle.ts b/bytes/index_of_needle.ts index fba711393238..85b5fd2a521d 100644 --- a/bytes/index_of_needle.ts +++ b/bytes/index_of_needle.ts @@ -20,24 +20,26 @@ * @example Basic usage * ```ts * 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 needle = new Uint8Array([1, 2]); * const notNeedle = new Uint8Array([5, 0]); * - * indexOfNeedle(source, needle); // 1 - * indexOfNeedle(source, notNeedle); // -1 + * assertEquals(indexOfNeedle(source, needle), 1); + * assertEquals(indexOfNeedle(source, notNeedle), -1); * ``` * * @example Start index * ```ts * 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 needle = new Uint8Array([1, 2]); * - * indexOfNeedle(source, needle, 2); // 3 - * indexOfNeedle(source, needle, 6); // -1 + * assertEquals(indexOfNeedle(source, needle, 2), 3); + * assertEquals(indexOfNeedle(source, needle, 6), -1); * ``` * Defining a start index will begin the search at the specified index in the * source array. diff --git a/bytes/last_index_of_needle.ts b/bytes/last_index_of_needle.ts index bf766f40086f..f9d7acf395df 100644 --- a/bytes/last_index_of_needle.ts +++ b/bytes/last_index_of_needle.ts @@ -17,24 +17,26 @@ * @example Basic usage * ```ts * 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 needle = new Uint8Array([1, 2]); * const notNeedle = new Uint8Array([5, 0]); * - * lastIndexOfNeedle(source, needle); // 5 - * lastIndexOfNeedle(source, notNeedle); // -1 + * assertEquals(lastIndexOfNeedle(source, needle), 5); + * assertEquals(lastIndexOfNeedle(source, notNeedle), -1); * ``` * * @example Start index * ```ts * 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 needle = new Uint8Array([1, 2]); * - * lastIndexOfNeedle(source, needle, 2); // 1 - * lastIndexOfNeedle(source, needle, 6); // 5 + * assertEquals(lastIndexOfNeedle(source, needle, 2), 1); + * assertEquals(lastIndexOfNeedle(source, needle, 6), 5); * ``` * Defining a start index will begin the search at the specified index in the * source array. diff --git a/bytes/repeat.ts b/bytes/repeat.ts index 9c001cdb2664..cbf3c6ee9d82 100644 --- a/bytes/repeat.ts +++ b/bytes/repeat.ts @@ -18,9 +18,7 @@ import { copy } from "./copy.ts"; * * const source = new Uint8Array([0, 1, 2]); * - * const result = repeat(source, 3); - * - * assertEquals(result, new Uint8Array([0, 1, 2, 0, 1, 2, 0, 1, 2])); + * assertEquals(repeat(source, 3), new Uint8Array([0, 1, 2, 0, 1, 2, 0, 1, 2])); * ``` * * @example Zero count @@ -30,9 +28,7 @@ import { copy } from "./copy.ts"; * * const source = new Uint8Array([0, 1, 2]); * - * const result = repeat(source, 0); - * - * assertEquals(result, new Uint8Array()); + * assertEquals(repeat(source, 0), new Uint8Array()); * ``` */ export function repeat(source: Uint8Array, count: number): Uint8Array { diff --git a/bytes/starts_with.ts b/bytes/starts_with.ts index 8b4d4b997f4e..78cfe75cae73 100644 --- a/bytes/starts_with.ts +++ b/bytes/starts_with.ts @@ -15,11 +15,12 @@ * @example Basic usage * ```ts * 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 prefix = new Uint8Array([0, 1, 2]); * - * startsWith(source, prefix); // true + * assertEquals(startsWith(source, prefix), true); * ``` */ export function startsWith(source: Uint8Array, prefix: Uint8Array): boolean { diff --git a/collections/drop_last_while.ts b/collections/drop_last_while.ts index ea5f2063e9fb..0dcef8a17ce4 100644 --- a/collections/drop_last_while.ts +++ b/collections/drop_last_while.ts @@ -18,11 +18,11 @@ * import { dropLastWhile } from "@std/collections/drop-last-while"; * 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( diff --git a/collections/reduce_groups.ts b/collections/reduce_groups.ts index 1c7a2aee16e5..2b088898d97b 100644 --- a/collections/reduce_groups.ts +++ b/collections/reduce_groups.ts @@ -15,6 +15,9 @@ import { mapValues } from "./map_values.ts"; * @param reducer The reducer function to apply to each group. * @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 * ```ts * import { reduceGroups } from "@std/collections/reduce-groups"; diff --git a/collections/running_reduce.ts b/collections/running_reduce.ts index 894a5d4cc189..6c21dc1f6a3d 100644 --- a/collections/running_reduce.ts +++ b/collections/running_reduce.ts @@ -13,6 +13,8 @@ * @param reducer The reducer function to apply to each element. * @param initialValue The initial value of the accumulator. * + * @returns An array of all intermediate accumulator results. + * * @example Basic usage * ```ts * import { runningReduce } from "@std/collections/running-reduce"; diff --git a/collections/sample.ts b/collections/sample.ts index 61f5c609ba17..a8f5c085ccf0 100644 --- a/collections/sample.ts +++ b/collections/sample.ts @@ -17,12 +17,12 @@ import { randomInteger } from "./_utils.ts"; * @example Basic usage * ```ts * 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 random = sample(numbers); * - * assert(numbers.includes(random!)); + * assertArrayIncludes(numbers, [random]); * ``` */ export function sample(array: readonly T[]): T | undefined {