From e789f813f9eec188e270037648e7b94e05dc1787 Mon Sep 17 00:00:00 2001 From: Kamal Singh <101921006+kamalsingh200238@users.noreply.github.com> Date: Tue, 28 Mar 2023 20:28:40 +0530 Subject: [PATCH] test(node/fs): add fs.Dir tests (#18463) Co-authored-by: Yoshiya Hinosawa --- cli/tests/unit_node/_fs/_fs_dir_test.ts | 209 ++++++++++++++++++++++++ 1 file changed, 209 insertions(+) create mode 100644 cli/tests/unit_node/_fs/_fs_dir_test.ts diff --git a/cli/tests/unit_node/_fs/_fs_dir_test.ts b/cli/tests/unit_node/_fs/_fs_dir_test.ts new file mode 100644 index 0000000000..7f53ee1d36 --- /dev/null +++ b/cli/tests/unit_node/_fs/_fs_dir_test.ts @@ -0,0 +1,209 @@ +// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license. +import { + assert, + assertEquals, + fail, +} from "../../../../test_util/std/testing/asserts.ts"; +import { assertCallbackErrorUncaught } from "../_test_utils.ts"; +import { Dir as DirOrig, type Dirent } from "node:fs"; + +// deno-lint-ignore no-explicit-any +const Dir = DirOrig as any; + +Deno.test({ + name: "Closing current directory with callback is successful", + fn() { + let calledBack = false; + // deno-lint-ignore no-explicit-any + new Dir(".").close((valOrErr: any) => { + assert(!valOrErr); + calledBack = true; + }); + assert(calledBack); + }, +}); + +Deno.test({ + name: "Closing current directory without callback returns void Promise", + async fn() { + await new Dir(".").close(); + }, +}); + +Deno.test({ + name: "Closing current directory synchronously works", + fn() { + new Dir(".").closeSync(); + }, +}); + +Deno.test({ + name: "Path is correctly returned", + fn() { + assertEquals(new Dir("std/node").path, "std/node"); + + const enc: Uint8Array = new TextEncoder().encode("std/node"); + assertEquals(new Dir(enc).path, "std/node"); + }, +}); + +Deno.test({ + name: "read returns null for empty directory", + async fn() { + const testDir: string = Deno.makeTempDirSync(); + try { + const file: Dirent | null = await new Dir(testDir).read(); + assert(file === null); + + let calledBack = false; + const fileFromCallback: Dirent | null = await new Dir( + testDir, + // deno-lint-ignore no-explicit-any + ).read((err: any, res: Dirent) => { + assert(res === null); + assert(err === null); + calledBack = true; + }); + assert(fileFromCallback === null); + assert(calledBack); + + assertEquals(new Dir(testDir).readSync(), null); + } finally { + Deno.removeSync(testDir); + } + }, +}); + +Deno.test({ + name: "Async read returns one file at a time", + async fn() { + const testDir: string = Deno.makeTempDirSync(); + const f1 = Deno.createSync(testDir + "/foo.txt"); + f1.close(); + const f2 = Deno.createSync(testDir + "/bar.txt"); + f2.close(); + + try { + let secondCallback = false; + const dir = new Dir(testDir); + const firstRead: Dirent | null = await dir.read(); + const secondRead: Dirent | null = await dir.read( + // deno-lint-ignore no-explicit-any + (_err: any, secondResult: Dirent) => { + assert( + secondResult.name === "bar.txt" || secondResult.name === "foo.txt", + ); + secondCallback = true; + }, + ); + const thirdRead: Dirent | null = await dir.read(); + const fourthRead: Dirent | null = await dir.read(); + + if (firstRead?.name === "foo.txt") { + assertEquals(secondRead?.name, "bar.txt"); + } else if (firstRead?.name === "bar.txt") { + assertEquals(secondRead?.name, "foo.txt"); + } else { + fail("File not found during read"); + } + assert(secondCallback); + assert(thirdRead === null); + assert(fourthRead === null); + } finally { + Deno.removeSync(testDir, { recursive: true }); + } + }, +}); + +Deno.test({ + name: "Sync read returns one file at a time", + fn() { + const testDir: string = Deno.makeTempDirSync(); + const f1 = Deno.createSync(testDir + "/foo.txt"); + f1.close(); + const f2 = Deno.createSync(testDir + "/bar.txt"); + f2.close(); + + try { + const dir = new Dir(testDir); + const firstRead: Dirent | null = dir.readSync(); + const secondRead: Dirent | null = dir.readSync(); + const thirdRead: Dirent | null = dir.readSync(); + const fourthRead: Dirent | null = dir.readSync(); + + if (firstRead?.name === "foo.txt") { + assertEquals(secondRead?.name, "bar.txt"); + } else if (firstRead?.name === "bar.txt") { + assertEquals(secondRead?.name, "foo.txt"); + } else { + fail("File not found during read"); + } + assert(thirdRead === null); + assert(fourthRead === null); + } finally { + Deno.removeSync(testDir, { recursive: true }); + } + }, +}); + +Deno.test({ + name: "Async iteration over existing directory", + async fn() { + const testDir: string = Deno.makeTempDirSync(); + const f1 = Deno.createSync(testDir + "/foo.txt"); + f1.close(); + const f2 = Deno.createSync(testDir + "/bar.txt"); + f2.close(); + + try { + const dir = new Dir(testDir); + const results: Array = []; + + for await (const file of dir[Symbol.asyncIterator]()) { + results.push(file.name); + } + + assert(results.length === 2); + assert(results.includes("foo.txt")); + assert(results.includes("bar.txt")); + } finally { + Deno.removeSync(testDir, { recursive: true }); + } + }, +}); + +Deno.test( + "[std/node/fs] Dir.close callback isn't called twice if error is thrown", + async () => { + const tempDir = await Deno.makeTempDir(); + await assertCallbackErrorUncaught({ + prelude: ` + import { Dir } from "node:fs"; + + const dir = new Dir(${JSON.stringify(tempDir)}); + `, + invocation: "dir.close(", + async cleanup() { + await Deno.remove(tempDir); + }, + }); + }, +); + +Deno.test( + "[std/node/fs] Dir.read callback isn't called twice if error is thrown", + async () => { + const tempDir = await Deno.makeTempDir(); + await assertCallbackErrorUncaught({ + prelude: ` + import { Dir } from "node:fs"; + + const dir = new Dir(${JSON.stringify(tempDir)}); + `, + invocation: "dir.read(", + async cleanup() { + await Deno.remove(tempDir); + }, + }); + }, +);