From e2116f73f6da8098340c1ef3b457ce995beb80bc Mon Sep 17 00:00:00 2001 From: Alisue Date: Sat, 17 Aug 2024 01:43:43 +0900 Subject: [PATCH] fix: allow falsy values and null in Queue and Stack --- deno.lock | 6 +++--- queue.ts | 4 ++-- queue_test.ts | 18 ++++++++++++++++++ stack.ts | 4 ++-- stack_test.ts | 18 ++++++++++++++++++ 5 files changed, 43 insertions(+), 7 deletions(-) diff --git a/deno.lock b/deno.lock index 9286bc4..1b7cd6e 100644 --- a/deno.lock +++ b/deno.lock @@ -6,7 +6,7 @@ "jsr:@cross/runtime@^1.0.0": "jsr:@cross/runtime@1.0.0", "jsr:@cross/test@^0.0.9": "jsr:@cross/test@0.0.9", "jsr:@std/assert@^1.0.2": "jsr:@std/assert@1.0.2", - "jsr:@std/async@^1.0.2": "jsr:@std/async@1.0.2", + "jsr:@std/async@^1.0.2": "jsr:@std/async@1.0.3", "jsr:@std/internal@^1.0.1": "jsr:@std/internal@1.0.1", "npm:@types/node": "npm:@types/node@18.16.19" }, @@ -29,8 +29,8 @@ "jsr:@std/internal@^1.0.1" ] }, - "@std/async@1.0.2": { - "integrity": "36e7f0f922c843b45df546857d269f01ed4d0406aced2a6639eac325b2435e43" + "@std/async@1.0.3": { + "integrity": "6ed64678db43451683c6c176a21426a2ccd21ba0269ebb2c36133ede3f165792" }, "@std/internal@1.0.1": { "integrity": "6f8c7544d06a11dd256c8d6ba54b11ed870aac6c5aeafff499892662c57673e6" diff --git a/queue.ts b/queue.ts index c655a94..59138cb 100644 --- a/queue.ts +++ b/queue.ts @@ -17,7 +17,7 @@ import { Notify } from "./notify.ts"; * assertEquals(await queue.pop(), 3); * ``` */ -export class Queue { +export class Queue | null> { #notify = new Notify(); #items: T[] = []; @@ -52,7 +52,7 @@ export class Queue { while (true) { signal?.throwIfAborted(); const value = this.#items.shift(); - if (value) { + if (value !== undefined) { return value; } await this.#notify.notified({ signal }); diff --git a/queue_test.ts b/queue_test.ts index 9113ead..a91d912 100644 --- a/queue_test.ts +++ b/queue_test.ts @@ -57,3 +57,21 @@ test("Queue 'pop' with signal already aborted", async () => { "Aborted", ); }); + +test("Queue with falsy value is accepted", async () => { + const q = new Queue(); + const popper = q.pop(); + assertEquals(await promiseState(popper), "pending"); + q.push(0); + assertEquals(await promiseState(popper), "fulfilled"); + assertEquals(await popper, 0); +}); + +test("Queue with null is accepted", async () => { + const q = new Queue(); + const popper = q.pop(); + assertEquals(await promiseState(popper), "pending"); + q.push(null); + assertEquals(await promiseState(popper), "fulfilled"); + assertEquals(await popper, null); +}); diff --git a/stack.ts b/stack.ts index a519a06..01bb33d 100644 --- a/stack.ts +++ b/stack.ts @@ -19,7 +19,7 @@ import { Notify } from "./notify.ts"; * * @template T The type of items in the stack. */ -export class Stack { +export class Stack | null> { #notify = new Notify(); #items: T[] = []; @@ -56,7 +56,7 @@ export class Stack { while (true) { signal?.throwIfAborted(); const value = this.#items.pop(); - if (value) { + if (value !== undefined) { return value; } await this.#notify.notified({ signal }); diff --git a/stack_test.ts b/stack_test.ts index ef0ffcb..125d4b4 100644 --- a/stack_test.ts +++ b/stack_test.ts @@ -57,3 +57,21 @@ test("Stack 'pop' with signal already aborted", async () => { "Aborted", ); }); + +test("Stack with falsy value is accepted", async () => { + const q = new Stack(); + const popper = q.pop(); + assertEquals(await promiseState(popper), "pending"); + q.push(0); + assertEquals(await promiseState(popper), "fulfilled"); + assertEquals(await popper, 0); +}); + +test("Stack with null is accepted", async () => { + const q = new Stack(); + const popper = q.pop(); + assertEquals(await promiseState(popper), "pending"); + q.push(null); + assertEquals(await promiseState(popper), "fulfilled"); + assertEquals(await popper, null); +});