Skip to main content
Module

std/fs/copy_test.ts

Deno standard library
Go to Latest
File
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.import { assertEquals, assertThrows, assertThrowsAsync, assert,} from "../testing/asserts.ts";import * as path from "../path/mod.ts";import { copy, copySync } from "./copy.ts";import { exists, existsSync } from "./exists.ts";import { ensureDir, ensureDirSync } from "./ensure_dir.ts";import { ensureFile, ensureFileSync } from "./ensure_file.ts";import { ensureSymlink, ensureSymlinkSync } from "./ensure_symlink.ts";
const testdataDir = path.resolve("fs", "testdata");
// TODO(axetroy): Add test for Windows once symlink is implemented for Windows.const isWindows = Deno.build.os === "win";
function testCopy(name: string, cb: (tempDir: string) => Promise<void>): void { Deno.test({ name, async fn(): Promise<void> { const tempDir = await Deno.makeTempDir({ prefix: "deno_std_copy_async_test_", }); await cb(tempDir); await Deno.remove(tempDir, { recursive: true }); }, });}
function testCopySync(name: string, cb: (tempDir: string) => void): void { Deno.test({ name, fn: (): void => { const tempDir = Deno.makeTempDirSync({ prefix: "deno_std_copy_sync_test_", }); cb(tempDir); Deno.removeSync(tempDir, { recursive: true }); }, });}
testCopy( "[fs] copy file if it does no exist", async (tempDir: string): Promise<void> => { const srcFile = path.join(testdataDir, "copy_file_not_exists.txt"); const destFile = path.join(tempDir, "copy_file_not_exists_1.txt"); await assertThrowsAsync( async (): Promise<void> => { await copy(srcFile, destFile); } ); });
testCopy( "[fs] copy if src and dest are the same paths", async (tempDir: string): Promise<void> => { const srcFile = path.join(tempDir, "copy_file_same.txt"); const destFile = path.join(tempDir, "copy_file_same.txt"); await assertThrowsAsync( async (): Promise<void> => { await copy(srcFile, destFile); }, Error, "Source and destination cannot be the same." ); });
testCopy( "[fs] copy file", async (tempDir: string): Promise<void> => { const srcFile = path.join(testdataDir, "copy_file.txt"); const destFile = path.join(tempDir, "copy_file_copy.txt");
const srcContent = new TextDecoder().decode(await Deno.readFile(srcFile));
assertEquals( await exists(srcFile), true, `source should exist before copy` ); assertEquals( await exists(destFile), false, "destination should not exist before copy" );
await copy(srcFile, destFile);
assertEquals(await exists(srcFile), true, "source should exist after copy"); assertEquals( await exists(destFile), true, "destination should exist before copy" );
const destContent = new TextDecoder().decode(await Deno.readFile(destFile));
assertEquals( srcContent, destContent, "source and destination should have the same content" );
// Copy again and it should throw an error. await assertThrowsAsync( async (): Promise<void> => { await copy(srcFile, destFile); }, Error, `'${destFile}' already exists.` );
// Modify destination file. await Deno.writeFile(destFile, new TextEncoder().encode("txt copy"));
assertEquals( new TextDecoder().decode(await Deno.readFile(destFile)), "txt copy" );
// Copy again with overwrite option. await copy(srcFile, destFile, { overwrite: true });
// Make sure the file has been overwritten. assertEquals( new TextDecoder().decode(await Deno.readFile(destFile)), "txt" ); });
testCopy( "[fs] copy with preserve timestamps", async (tempDir: string): Promise<void> => { const srcFile = path.join(testdataDir, "copy_file.txt"); const destFile = path.join(tempDir, "copy_file_copy.txt");
const srcStatInfo = await Deno.stat(srcFile);
assert(typeof srcStatInfo.accessed === "number"); assert(typeof srcStatInfo.modified === "number");
// Copy with overwrite and preserve timestamps options. await copy(srcFile, destFile, { overwrite: true, preserveTimestamps: true, });
const destStatInfo = await Deno.stat(destFile);
assert(typeof destStatInfo.accessed === "number"); assert(typeof destStatInfo.modified === "number"); assertEquals(destStatInfo.accessed, srcStatInfo.accessed); assertEquals(destStatInfo.modified, srcStatInfo.modified); });
testCopy( "[fs] copy directory to its subdirectory", async (tempDir: string): Promise<void> => { const srcDir = path.join(tempDir, "parent"); const destDir = path.join(srcDir, "child");
await ensureDir(srcDir);
await assertThrowsAsync( async (): Promise<void> => { await copy(srcDir, destDir); }, Error, `Cannot copy '${srcDir}' to a subdirectory of itself, '${destDir}'.` ); });
testCopy( "[fs] copy directory and destination exist and not a directory", async (tempDir: string): Promise<void> => { const srcDir = path.join(tempDir, "parent"); const destDir = path.join(tempDir, "child.txt");
await ensureDir(srcDir); await ensureFile(destDir);
await assertThrowsAsync( async (): Promise<void> => { await copy(srcDir, destDir); }, Error, `Cannot overwrite non-directory '${destDir}' with directory '${srcDir}'.` ); });
testCopy( "[fs] copy directory", async (tempDir: string): Promise<void> => { const srcDir = path.join(testdataDir, "copy_dir"); const destDir = path.join(tempDir, "copy_dir"); const srcFile = path.join(srcDir, "0.txt"); const destFile = path.join(destDir, "0.txt"); const srcNestFile = path.join(srcDir, "nest", "0.txt"); const destNestFile = path.join(destDir, "nest", "0.txt");
await copy(srcDir, destDir);
assertEquals(await exists(destFile), true); assertEquals(await exists(destNestFile), true);
// After copy. The source and destination should have the same content. assertEquals( new TextDecoder().decode(await Deno.readFile(srcFile)), new TextDecoder().decode(await Deno.readFile(destFile)) ); assertEquals( new TextDecoder().decode(await Deno.readFile(srcNestFile)), new TextDecoder().decode(await Deno.readFile(destNestFile)) );
// Copy again without overwrite option and it should throw an error. await assertThrowsAsync( async (): Promise<void> => { await copy(srcDir, destDir); }, Error, `'${destDir}' already exists.` );
// Modify the file in the destination directory. await Deno.writeFile(destNestFile, new TextEncoder().encode("nest copy")); assertEquals( new TextDecoder().decode(await Deno.readFile(destNestFile)), "nest copy" );
// Copy again with overwrite option. await copy(srcDir, destDir, { overwrite: true });
// Make sure the file has been overwritten. assertEquals( new TextDecoder().decode(await Deno.readFile(destNestFile)), "nest" ); });
testCopy( "[fs] copy symlink file", async (tempDir: string): Promise<void> => { const dir = path.join(testdataDir, "copy_dir_link_file"); const srcLink = path.join(dir, "0.txt"); const destLink = path.join(tempDir, "0_copy.txt");
if (isWindows) { await assertThrowsAsync( // (): Promise<void> => copy(srcLink, destLink), (): Promise<void> => ensureSymlink(srcLink, destLink) ); return; }
assert( (await Deno.lstat(srcLink)).isSymlink(), `'${srcLink}' should be symlink type` );
await copy(srcLink, destLink);
const statInfo = await Deno.lstat(destLink);
assert(statInfo.isSymlink(), `'${destLink}' should be symlink type`); });
testCopy( "[fs] copy symlink directory", async (tempDir: string): Promise<void> => { const srcDir = path.join(testdataDir, "copy_dir"); const srcLink = path.join(tempDir, "copy_dir_link"); const destLink = path.join(tempDir, "copy_dir_link_copy");
if (isWindows) { await assertThrowsAsync( // (): Promise<void> => copy(srcLink, destLink), (): Promise<void> => ensureSymlink(srcLink, destLink) ); return; }
await ensureSymlink(srcDir, srcLink);
assert( (await Deno.lstat(srcLink)).isSymlink(), `'${srcLink}' should be symlink type` );
await copy(srcLink, destLink);
const statInfo = await Deno.lstat(destLink);
assert(statInfo.isSymlink()); });
testCopySync( "[fs] copy file synchronously if it does not exist", (tempDir: string): void => { const srcFile = path.join(testdataDir, "copy_file_not_exists_sync.txt"); const destFile = path.join(tempDir, "copy_file_not_exists_1_sync.txt"); assertThrows((): void => { copySync(srcFile, destFile); }); });
testCopySync( "[fs] copy synchronously with preserve timestamps", (tempDir: string): void => { const srcFile = path.join(testdataDir, "copy_file.txt"); const destFile = path.join(tempDir, "copy_file_copy.txt");
const srcStatInfo = Deno.statSync(srcFile);
assert(typeof srcStatInfo.accessed === "number"); assert(typeof srcStatInfo.modified === "number");
// Copy with overwrite and preserve timestamps options. copySync(srcFile, destFile, { overwrite: true, preserveTimestamps: true, });
const destStatInfo = Deno.statSync(destFile);
assert(typeof destStatInfo.accessed === "number"); assert(typeof destStatInfo.modified === "number"); // TODO: Activate test when https://github.com/denoland/deno/issues/2411 // is fixed // assertEquals(destStatInfo.accessed, srcStatInfo.accessed); // assertEquals(destStatInfo.modified, srcStatInfo.modified); });
testCopySync( "[fs] copy synchronously if src and dest are the same paths", (): void => { const srcFile = path.join(testdataDir, "copy_file_same_sync.txt"); assertThrows( (): void => { copySync(srcFile, srcFile); }, Error, "Source and destination cannot be the same." ); });
testCopySync("[fs] copy file synchronously", (tempDir: string): void => { const srcFile = path.join(testdataDir, "copy_file.txt"); const destFile = path.join(tempDir, "copy_file_copy_sync.txt");
const srcContent = new TextDecoder().decode(Deno.readFileSync(srcFile));
assertEquals(existsSync(srcFile), true); assertEquals(existsSync(destFile), false);
copySync(srcFile, destFile);
assertEquals(existsSync(srcFile), true); assertEquals(existsSync(destFile), true);
const destContent = new TextDecoder().decode(Deno.readFileSync(destFile));
assertEquals(srcContent, destContent);
// Copy again without overwrite option and it should throw an error. assertThrows( (): void => { copySync(srcFile, destFile); }, Error, `'${destFile}' already exists.` );
// Modify destination file. Deno.writeFileSync(destFile, new TextEncoder().encode("txt copy"));
assertEquals( new TextDecoder().decode(Deno.readFileSync(destFile)), "txt copy" );
// Copy again with overwrite option. copySync(srcFile, destFile, { overwrite: true });
// Make sure the file has been overwritten. assertEquals(new TextDecoder().decode(Deno.readFileSync(destFile)), "txt");});
testCopySync( "[fs] copy directory synchronously to its subdirectory", (tempDir: string): void => { const srcDir = path.join(tempDir, "parent"); const destDir = path.join(srcDir, "child");
ensureDirSync(srcDir);
assertThrows( (): void => { copySync(srcDir, destDir); }, Error, `Cannot copy '${srcDir}' to a subdirectory of itself, '${destDir}'.` ); });
testCopySync( "[fs] copy directory synchronously, and destination exist and not a " + "directory", (tempDir: string): void => { const srcDir = path.join(tempDir, "parent_sync"); const destDir = path.join(tempDir, "child.txt");
ensureDirSync(srcDir); ensureFileSync(destDir);
assertThrows( (): void => { copySync(srcDir, destDir); }, Error, `Cannot overwrite non-directory '${destDir}' with directory '${srcDir}'.` ); });
testCopySync("[fs] copy directory synchronously", (tempDir: string): void => { const srcDir = path.join(testdataDir, "copy_dir"); const destDir = path.join(tempDir, "copy_dir_copy_sync"); const srcFile = path.join(srcDir, "0.txt"); const destFile = path.join(destDir, "0.txt"); const srcNestFile = path.join(srcDir, "nest", "0.txt"); const destNestFile = path.join(destDir, "nest", "0.txt");
copySync(srcDir, destDir);
assertEquals(existsSync(destFile), true); assertEquals(existsSync(destNestFile), true);
// After copy. The source and destination should have the same content. assertEquals( new TextDecoder().decode(Deno.readFileSync(srcFile)), new TextDecoder().decode(Deno.readFileSync(destFile)) ); assertEquals( new TextDecoder().decode(Deno.readFileSync(srcNestFile)), new TextDecoder().decode(Deno.readFileSync(destNestFile)) );
// Copy again without overwrite option and it should throw an error. assertThrows( (): void => { copySync(srcDir, destDir); }, Error, `'${destDir}' already exists.` );
// Modify the file in the destination directory. Deno.writeFileSync(destNestFile, new TextEncoder().encode("nest copy")); assertEquals( new TextDecoder().decode(Deno.readFileSync(destNestFile)), "nest copy" );
// Copy again with overwrite option. copySync(srcDir, destDir, { overwrite: true });
// Make sure the file has been overwritten. assertEquals( new TextDecoder().decode(Deno.readFileSync(destNestFile)), "nest" );});
testCopySync( "[fs] copy symlink file synchronously", (tempDir: string): void => { const dir = path.join(testdataDir, "copy_dir_link_file"); const srcLink = path.join(dir, "0.txt"); const destLink = path.join(tempDir, "0_copy.txt");
if (isWindows) { assertThrows( // (): void => copySync(srcLink, destLink), (): void => ensureSymlinkSync(srcLink, destLink) ); return; }
assert( Deno.lstatSync(srcLink).isSymlink(), `'${srcLink}' should be symlink type` );
copySync(srcLink, destLink);
const statInfo = Deno.lstatSync(destLink);
assert(statInfo.isSymlink(), `'${destLink}' should be symlink type`); });
testCopySync( "[fs] copy symlink directory synchronously", (tempDir: string): void => { const originDir = path.join(testdataDir, "copy_dir"); const srcLink = path.join(tempDir, "copy_dir_link"); const destLink = path.join(tempDir, "copy_dir_link_copy");
if (isWindows) { assertThrows( // (): void => copySync(srcLink, destLink), (): void => ensureSymlinkSync(srcLink, destLink) ); return; }
ensureSymlinkSync(originDir, srcLink);
assert( Deno.lstatSync(srcLink).isSymlink(), `'${srcLink}' should be symlink type` );
copySync(srcLink, destLink);
const statInfo = Deno.lstatSync(destLink);
assert(statInfo.isSymlink()); });