From 987fc72fe9ff863f2fa02f4d4072bce6ed173c14 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=CE=9Blisue=20=28Ali=20sue=E3=83=BB=E3=81=82=E3=82=8A?= =?UTF-8?q?=E3=81=99=E3=81=88=29?= Date: Sun, 25 Feb 2024 20:51:37 +0900 Subject: [PATCH 1/6] feat(collections): add `pick` and `omit` (#4218) Co-authored-by: Kenta Moriuchi --- collections/mod.ts | 2 ++ collections/omit.ts | 26 ++++++++++++++++++++++++++ collections/omit_test.ts | 38 ++++++++++++++++++++++++++++++++++++++ collections/pick.ts | 22 ++++++++++++++++++++++ collections/pick_test.ts | 39 +++++++++++++++++++++++++++++++++++++++ 5 files changed, 127 insertions(+) create mode 100644 collections/omit.ts create mode 100644 collections/omit_test.ts create mode 100644 collections/pick.ts create mode 100644 collections/pick_test.ts diff --git a/collections/mod.ts b/collections/mod.ts index 93760b045bec..f8f2135d86fc 100644 --- a/collections/mod.ts +++ b/collections/mod.ts @@ -54,3 +54,5 @@ export * from "./drop_last_while.ts"; export * from "./reduce_groups.ts"; export * from "./sample.ts"; export * from "./running_reduce.ts"; +export * from "./pick.ts"; +export * from "./omit.ts"; diff --git a/collections/omit.ts b/collections/omit.ts new file mode 100644 index 000000000000..06565eca0081 --- /dev/null +++ b/collections/omit.ts @@ -0,0 +1,26 @@ +// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license. + +/** + * Creates a new object by excluding the specified keys from the provided object. + * + * @example + * ```ts + * import { omit } from "https://deno.land/std@$STD_VERSION/collections/omit.ts"; + * import { assertEquals } from "https://deno.land/std@$STD_VERSION/assert/assert_equals.ts"; + * + * const obj = { a: 5, b: 6, c: 7, d: 8 }; + * const omitted = omit(obj, ["a", "c"]); + * + * assertEquals(omitted, { b: 6, d: 8 }); + * ``` + */ +export function omit( + obj: Readonly, + keys: readonly K[], +): Omit { + const excludes = new Set(keys); + const has = excludes.has.bind(excludes); + return Object.fromEntries( + Object.entries(obj).filter(([k, _]) => !has(k as K)), + ) as Omit; +} diff --git a/collections/omit_test.ts b/collections/omit_test.ts new file mode 100644 index 000000000000..cd2b701d2b52 --- /dev/null +++ b/collections/omit_test.ts @@ -0,0 +1,38 @@ +// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license. + +import { assertEquals, assertNotStrictEquals } from "../assert/mod.ts"; +import { omit } from "./omit.ts"; + +Deno.test({ + name: "omit() returns a new object from the provided object", + fn() { + const obj = { a: 5, b: 6, c: 7, d: 8 }; + const omitted = omit(obj, []); + + assertEquals(omitted, { a: 5, b: 6, c: 7, d: 8 }); + assertNotStrictEquals(omitted, obj); + }, +}); + +Deno.test({ + name: + "omit() returns a new object from the provided object without the provided keys", + fn() { + const obj = { a: 5, b: 6, c: 7, d: 8 }; + const omitted = omit(obj, ["a", "c"]); + + assertEquals(omitted, { b: 6, d: 8 }); + assertNotStrictEquals(omitted, obj); + }, +}); + +Deno.test({ + name: "omit() returns an empty object when the provided keys is empty", + fn() { + const obj = { a: 5, b: 6, c: 7, d: 8 }; + const omitted = omit(obj, ["a", "b", "c", "d"]); + + assertEquals(omitted, {}); + assertNotStrictEquals(omitted, obj); + }, +}); diff --git a/collections/pick.ts b/collections/pick.ts new file mode 100644 index 000000000000..e508635d922d --- /dev/null +++ b/collections/pick.ts @@ -0,0 +1,22 @@ +// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license. + +/** + * Creates a new object by including the specified keys from the provided object. + * + * @example + * ```ts + * import { pick } from "https://deno.land/std@$STD_VERSION/collections/pick.ts"; + * import { assertEquals } from "https://deno.land/std@$STD_VERSION/assert/assert_equals.ts"; + * + * const obj = { a: 5, b: 6, c: 7, d: 8 }; + * const picked = pick(obj, ["a", "c"]); + * + * assertEquals(picked, { a: 5, c: 7 }); + * ``` + */ +export function pick( + obj: Readonly, + keys: readonly K[], +): Pick { + return Object.fromEntries(keys.map((k) => [k, obj[k]])) as Pick; +} diff --git a/collections/pick_test.ts b/collections/pick_test.ts new file mode 100644 index 000000000000..1af6d6f3a90c --- /dev/null +++ b/collections/pick_test.ts @@ -0,0 +1,39 @@ +// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license. + +import { assertEquals, assertNotStrictEquals } from "../assert/mod.ts"; +import { pick } from "./pick.ts"; + +Deno.test({ + name: "pick() returns a new empty object when no keys are provided", + fn() { + const obj = { a: 5, b: 6, c: 7, d: 8 }; + const picked = pick(obj, []); + + assertEquals(picked, {}); + assertNotStrictEquals(picked, obj); + }, +}); + +Deno.test({ + name: + "pick() returns a new object from the provided object with the provided keys", + fn() { + const obj = { a: 5, b: 6, c: 7, d: 8 }; + const picked = pick(obj, ["a", "c"]); + + assertEquals(picked, { a: 5, c: 7 }); + assertNotStrictEquals(picked, obj); + }, +}); + +Deno.test({ + name: + "pick() returns a new object from the provided object with the provided keys (all keys are provided)", + fn() { + const obj = { a: 5, b: 6, c: 7, d: 8 }; + const picked = pick(obj, ["a", "b", "c", "d"]); + + assertEquals(picked, { a: 5, b: 6, c: 7, d: 8 }); + assertNotStrictEquals(picked, obj); + }, +}); From 7fb8c5f8187a276225a729563a7f351dccd23756 Mon Sep 17 00:00:00 2001 From: Jesse Jackson Date: Sun, 25 Feb 2024 14:16:11 -0600 Subject: [PATCH 2/6] docs: clarify underscore guidance in README (#4385) * docs: clarify underscore guidance in README * add explanation to symbol list item --- README.md | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 192dc5ac6cd2..0f5493eb1ab2 100644 --- a/README.md +++ b/README.md @@ -45,18 +45,25 @@ Check out the documentation [here](https://deno.land/std?doc). import * as fs from "https://deno.land/std@$STD_VERSION/fs/mod.ts"; ``` -1. Do not import symbols with an underscore in the name. +1. Do not import symbols with a name _prefixed_ by an underscore (they're not + intended for public use). Bad: ```ts import { _format } from "https://deno.land/std@$STD_VERSION/path/_common/format.ts"; ``` -1. Do not import modules with an underscore in the path. +1. Do not import modules with a directory or filename _prefixed_ by an + underscore (they're not intended for public use). Bad: ```ts - import { filterInPlace } from "https://deno.land/std@$STD_VERSION/collections/_utils.ts"; + import { createLPS } from "https://deno.land/std@$STD_VERSION/streams/_common.ts"; + ``` + + Good: + ```ts + import { TextLineStream } from "https://deno.land/std@$STD_VERSION/streams/text_line_stream.ts"; ``` 1. Do not import test modules or test data. From eac60e654519a8259199e6e24410365ef4e2eba8 Mon Sep 17 00:00:00 2001 From: Tim Reichen Date: Sun, 25 Feb 2024 23:25:12 +0100 Subject: [PATCH 3/6] chore(media_types): format test names (#4380) --- media_types/_util_test.ts | 6 +++--- media_types/content_type_test.ts | 4 ++-- media_types/extension_test.ts | 2 +- media_types/extensions_by_type_test.ts | 2 +- media_types/format_media_type_test.ts | 2 +- media_types/get_charset_test.ts | 2 +- media_types/parse_media_type_test.ts | 2 +- media_types/type_by_extension_test.ts | 2 +- 8 files changed, 11 insertions(+), 11 deletions(-) diff --git a/media_types/_util_test.ts b/media_types/_util_test.ts index 8899c9d486cd..afcf81cf1633 100644 --- a/media_types/_util_test.ts +++ b/media_types/_util_test.ts @@ -4,7 +4,7 @@ import { assertEquals } from "../assert/mod.ts"; import { consumeMediaParam, consumeToken, consumeValue } from "./_util.ts"; Deno.test({ - name: "media_types::util - consumeToken()", + name: "consumeToken()", fn() { const fixtures = [ ["foo bar", "foo", " bar"], @@ -19,7 +19,7 @@ Deno.test({ }); Deno.test({ - name: "media_types::util - consumeValue()", + name: "consumeValue()", fn() { const fixtures = [ ["foo bar", "foo", " bar"], @@ -44,7 +44,7 @@ Deno.test({ }); Deno.test({ - name: "media_types::util - consumeMediaParam()", + name: "consumeMediaParam()", fn() { const fixtures = [ [" ; foo=bar", "foo", "bar", ""], diff --git a/media_types/content_type_test.ts b/media_types/content_type_test.ts index 39ce2a0b005c..8eeaed408f35 100644 --- a/media_types/content_type_test.ts +++ b/media_types/content_type_test.ts @@ -4,7 +4,7 @@ import { contentType } from "./content_type.ts"; import { assertEquals } from "../assert/mod.ts"; Deno.test({ - name: "media_types - contentType()", + name: "contentType()", fn() { const fixtures = [ [".json", "application/json; charset=UTF-8"], @@ -22,7 +22,7 @@ Deno.test({ }); Deno.test({ - name: "media_types - contentType()", + name: "contentType() implies types", fn() { let _str: string; // For well-known content types, the return type is a string. diff --git a/media_types/extension_test.ts b/media_types/extension_test.ts index ca3918a757ed..166e7d88a3d7 100644 --- a/media_types/extension_test.ts +++ b/media_types/extension_test.ts @@ -4,7 +4,7 @@ import { assertEquals } from "../assert/mod.ts"; import { extension } from "./mod.ts"; Deno.test({ - name: "media_types - extension()", + name: "extension()", fn() { const fixtures: [string, string | undefined][] = [ ["image/gif", "gif"], diff --git a/media_types/extensions_by_type_test.ts b/media_types/extensions_by_type_test.ts index 1b1185c865e8..7306ecbd75bb 100644 --- a/media_types/extensions_by_type_test.ts +++ b/media_types/extensions_by_type_test.ts @@ -4,7 +4,7 @@ import { assertEquals } from "../assert/mod.ts"; import { extensionsByType } from "./extensions_by_type.ts"; Deno.test({ - name: "media_types - extensionsByType()", + name: "extensionsByType()", fn() { const fixtures: [string, string[] | undefined][] = [ ["image/gif", ["gif"]], diff --git a/media_types/format_media_type_test.ts b/media_types/format_media_type_test.ts index d39e9974121a..4ceb97322f25 100644 --- a/media_types/format_media_type_test.ts +++ b/media_types/format_media_type_test.ts @@ -4,7 +4,7 @@ import { assertEquals } from "../assert/mod.ts"; import { formatMediaType } from "./mod.ts"; Deno.test({ - name: "media_types - formatMediaType", + name: "formatMediaType()", fn() { const fixtures = [ ["noslash", { X: "Y" }, "noslash; x=Y"], diff --git a/media_types/get_charset_test.ts b/media_types/get_charset_test.ts index 3dd5f6671db5..466ea7f3be23 100644 --- a/media_types/get_charset_test.ts +++ b/media_types/get_charset_test.ts @@ -4,7 +4,7 @@ import { assertEquals } from "../assert/mod.ts"; import { getCharset } from "./mod.ts"; Deno.test({ - name: "media-types - getCharset()", + name: "getCharset()", fn() { const fixtures = [ ["text/plain", "UTF-8"], diff --git a/media_types/parse_media_type_test.ts b/media_types/parse_media_type_test.ts index a0595e38407f..5195578149d8 100644 --- a/media_types/parse_media_type_test.ts +++ b/media_types/parse_media_type_test.ts @@ -4,7 +4,7 @@ import { assertEquals } from "../assert/mod.ts"; import { parseMediaType } from "./mod.ts"; Deno.test({ - name: "media_types - parseMediaType()", + name: "parseMediaType()", fn() { const nameFoo = { "name": "foo" }; const fixtures: [string, string, Record | undefined][] = [ diff --git a/media_types/type_by_extension_test.ts b/media_types/type_by_extension_test.ts index aabee80519d2..f9a94e12da61 100644 --- a/media_types/type_by_extension_test.ts +++ b/media_types/type_by_extension_test.ts @@ -4,7 +4,7 @@ import { assertEquals } from "../assert/mod.ts"; import { typeByExtension } from "./mod.ts"; Deno.test({ - name: "media_types - typeByExtension", + name: "typeByExtension()", fn() { const fixtures = [ ["js", "application/javascript"], From ce719de1a75158f2abca8590d3901a3125d30238 Mon Sep 17 00:00:00 2001 From: Asher Gomez Date: Mon, 26 Feb 2024 19:46:10 +1100 Subject: [PATCH 4/6] docs: ignore bad snippet examples (#4388) --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 0f5493eb1ab2..c4d6bccaa422 100644 --- a/README.md +++ b/README.md @@ -49,7 +49,7 @@ Check out the documentation [here](https://deno.land/std?doc). intended for public use). Bad: - ```ts + ```ts, ignore import { _format } from "https://deno.land/std@$STD_VERSION/path/_common/format.ts"; ``` @@ -57,7 +57,7 @@ Check out the documentation [here](https://deno.land/std?doc). underscore (they're not intended for public use). Bad: - ```ts + ```ts, ignore import { createLPS } from "https://deno.land/std@$STD_VERSION/streams/_common.ts"; ``` From 0f62d4c1e414716b48060eb5058fac8eb2ff0db9 Mon Sep 17 00:00:00 2001 From: Tim Reichen Date: Mon, 26 Feb 2024 14:22:21 +0100 Subject: [PATCH 5/6] chore(log): sync `level` and `levelName` in BaseHandler (#4393) --- log/base_handler.ts | 33 ++++++++++++++++++++++++++------- 1 file changed, 26 insertions(+), 7 deletions(-) diff --git a/log/base_handler.ts b/log/base_handler.ts index 6b68e01fe1bc..3eb65c118de4 100644 --- a/log/base_handler.ts +++ b/log/base_handler.ts @@ -1,5 +1,5 @@ // Copyright 2018-2024 the Deno authors. All rights reserved. MIT license. -import { getLevelByName, LevelName } from "./levels.ts"; +import { getLevelByName, getLevelName, LevelName, LogLevel } from "./levels.ts"; import type { LogRecord } from "./logger.ts"; export type FormatterFunction = (logRecord: LogRecord) => string; @@ -11,14 +11,33 @@ export interface BaseHandlerOptions { } export class BaseHandler { - level: number; - levelName: LevelName; + #levelName: LevelName; + #level: LogLevel; formatter: FormatterFunction; - constructor(levelName: LevelName, options: BaseHandlerOptions = {}) { - this.level = getLevelByName(levelName); - this.levelName = levelName; - this.formatter = options.formatter || DEFAULT_FORMATTER; + constructor( + levelName: LevelName, + { formatter = DEFAULT_FORMATTER }: BaseHandlerOptions = {}, + ) { + this.#levelName = levelName; + this.#level = getLevelByName(levelName); + this.formatter = formatter; + } + + get level() { + return this.#level; + } + set level(level: LogLevel) { + this.#level = level; + this.#levelName = getLevelName(level); + } + + get levelName() { + return this.#levelName; + } + set levelName(levelName: LevelName) { + this.#levelName = levelName; + this.#level = getLevelByName(levelName); } handle(logRecord: LogRecord) { From 27517a8578cfbed025167ccee7e71082a23af3c6 Mon Sep 17 00:00:00 2001 From: Asher Gomez Date: Tue, 27 Feb 2024 05:58:17 +1100 Subject: [PATCH 6/6] docs: link to `assertThrows()` and `assertRejects()` (#4395) --- assert/assert_rejects.ts | 4 ++++ assert/assert_throws.ts | 6 ++++++ 2 files changed, 10 insertions(+) diff --git a/assert/assert_rejects.ts b/assert/assert_rejects.ts index 859fc30b28e3..a23963dedd0f 100644 --- a/assert/assert_rejects.ts +++ b/assert/assert_rejects.ts @@ -5,6 +5,8 @@ import { assertIsError } from "./assert_is_error.ts"; /** * Executes a function which returns a promise, expecting it to reject. * + * To assert that a synchronous function throws, use {@linkcode assertThrows}. + * * @example * ```ts * import { assertRejects } from "https://deno.land/std@$STD_VERSION/assert/assert_rejects.ts"; @@ -22,6 +24,8 @@ export function assertRejects( * If it does not, then it throws. An error class and a string that should be * included in the error message can also be asserted. * + * To assert that a synchronous function throws, use {@linkcode assertThrows}. + * * @example * ```ts * import { assertRejects } from "https://deno.land/std@$STD_VERSION/assert/assert_rejects.ts"; diff --git a/assert/assert_throws.ts b/assert/assert_throws.ts index e52674fae1bd..7f29e26feda4 100644 --- a/assert/assert_throws.ts +++ b/assert/assert_throws.ts @@ -6,6 +6,9 @@ import { AssertionError } from "./assertion_error.ts"; * Executes a function, expecting it to throw. If it does not, then it * throws. * + * To assert that an asynchronous function rejects, use + * {@linkcode assertRejects}. + * * @example * ```ts * import { assertThrows } from "https://deno.land/std@$STD_VERSION/assert/assert_throws.ts"; @@ -23,6 +26,9 @@ export function assertThrows( * throws. An error class and a string that should be included in the * error message can also be asserted. * + * To assert that an asynchronous function rejects, use + * {@linkcode assertRejects}. + * * @example * ```ts * import { assertThrows } from "https://deno.land/std@$STD_VERSION/assert/assert_throws.ts";