diff options
-rw-r--r-- | std/node/_fs/_fs_link.ts | 37 | ||||
-rw-r--r-- | std/node/_fs/_fs_link_test.ts | 67 |
2 files changed, 104 insertions, 0 deletions
diff --git a/std/node/_fs/_fs_link.ts b/std/node/_fs/_fs_link.ts new file mode 100644 index 000000000..50916a7ba --- /dev/null +++ b/std/node/_fs/_fs_link.ts @@ -0,0 +1,37 @@ +// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. + +import { CallbackWithError } from "./_fs_common.ts"; +import { fromFileUrl } from "../path.ts"; + +/** + * TODO: Also accept 'path' parameter as a Node polyfill Buffer type once these + * are implemented. See https://github.com/denoland/deno/issues/3403 + */ +export function link( + existingPath: string | URL, + newPath: string | URL, + callback: CallbackWithError +): void { + existingPath = + existingPath instanceof URL ? fromFileUrl(existingPath) : existingPath; + newPath = newPath instanceof URL ? fromFileUrl(newPath) : newPath; + + Deno.link(existingPath, newPath) + .then(() => callback()) + .catch(callback); +} + +/** + * TODO: Also accept 'path' parameter as a Node polyfill Buffer type once these + * are implemented. See https://github.com/denoland/deno/issues/3403 + */ +export function linkSync( + existingPath: string | URL, + newPath: string | URL +): void { + existingPath = + existingPath instanceof URL ? fromFileUrl(existingPath) : existingPath; + newPath = newPath instanceof URL ? fromFileUrl(newPath) : newPath; + + Deno.linkSync(existingPath, newPath); +} diff --git a/std/node/_fs/_fs_link_test.ts b/std/node/_fs/_fs_link_test.ts new file mode 100644 index 000000000..e59984c8c --- /dev/null +++ b/std/node/_fs/_fs_link_test.ts @@ -0,0 +1,67 @@ +// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. +const { test } = Deno; +import { fail, assertEquals } from "../../testing/asserts.ts"; +import { link, linkSync } from "./_fs_link.ts"; +import { assert } from "https://deno.land/std@v0.50.0/testing/asserts.ts"; +const isWindows = Deno.build.os === "windows"; + +test({ + ignore: isWindows, + name: "ASYNC: hard linking files works as expected", + async fn() { + const tempFile: string = await Deno.makeTempFile(); + const linkedFile: string = tempFile + ".link"; + await new Promise((res, rej) => { + link(tempFile, linkedFile, (err) => { + if (err) rej(err); + else res(); + }); + }) + .then(() => { + assertEquals(Deno.statSync(tempFile), Deno.statSync(linkedFile)); + }) + .catch(() => { + fail("Expected to succeed"); + }) + .finally(() => { + Deno.removeSync(tempFile); + Deno.removeSync(linkedFile); + }); + }, +}); + +test({ + ignore: isWindows, + name: "ASYNC: hard linking files passes error to callback", + async fn() { + let failed = false; + await new Promise((res, rej) => { + link("no-such-file", "no-such-file", (err) => { + if (err) rej(err); + else res(); + }); + }) + .then(() => { + fail("Expected to succeed"); + }) + .catch((err) => { + assert(err); + failed = true; + }); + assert(failed); + }, +}); + +test({ + ignore: isWindows, + name: "SYNC: hard linking files works as expected", + fn() { + const tempFile: string = Deno.makeTempFileSync(); + const linkedFile: string = tempFile + ".link"; + linkSync(tempFile, linkedFile); + + assertEquals(Deno.statSync(tempFile), Deno.statSync(linkedFile)); + Deno.removeSync(tempFile); + Deno.removeSync(linkedFile); + }, +}); |