2020-01-02 15:13:47 -05:00
|
|
|
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
|
2020-04-03 11:00:16 -04:00
|
|
|
import { unitTest, assert, assertEquals, assertThrows } from "./test_util.ts";
|
|
|
|
|
|
|
|
function assertMissing(path: string): void {
|
|
|
|
let caughtErr = false;
|
|
|
|
let info;
|
|
|
|
try {
|
|
|
|
info = Deno.lstatSync(path);
|
|
|
|
} catch (e) {
|
|
|
|
caughtErr = true;
|
|
|
|
assert(e instanceof Deno.errors.NotFound);
|
|
|
|
}
|
|
|
|
assert(caughtErr);
|
|
|
|
assertEquals(info, undefined);
|
|
|
|
}
|
|
|
|
|
|
|
|
function assertFile(path: string): void {
|
|
|
|
const info = Deno.lstatSync(path);
|
2020-04-16 01:40:30 -04:00
|
|
|
assert(info.isFile);
|
2020-04-03 11:00:16 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
function assertDirectory(path: string, mode?: number): void {
|
|
|
|
const info = Deno.lstatSync(path);
|
2020-04-16 01:40:30 -04:00
|
|
|
assert(info.isDirectory);
|
2020-04-03 11:00:16 -04:00
|
|
|
if (Deno.build.os !== "win" && mode !== undefined) {
|
|
|
|
assertEquals(info.mode! & 0o777, mode & ~Deno.umask());
|
|
|
|
}
|
|
|
|
}
|
2018-09-12 11:44:58 -04:00
|
|
|
|
2020-03-04 11:31:14 -05:00
|
|
|
unitTest(
|
|
|
|
{ perms: { read: true, write: true } },
|
|
|
|
function renameSyncSuccess(): void {
|
|
|
|
const testDir = Deno.makeTempDirSync();
|
|
|
|
const oldpath = testDir + "/oldpath";
|
|
|
|
const newpath = testDir + "/newpath";
|
|
|
|
Deno.mkdirSync(oldpath);
|
|
|
|
Deno.renameSync(oldpath, newpath);
|
2020-04-03 11:00:16 -04:00
|
|
|
assertDirectory(newpath);
|
|
|
|
assertMissing(oldpath);
|
2018-09-12 11:44:58 -04:00
|
|
|
}
|
2020-03-04 11:31:14 -05:00
|
|
|
);
|
2018-09-12 11:44:58 -04:00
|
|
|
|
2020-03-04 11:31:14 -05:00
|
|
|
unitTest(
|
|
|
|
{ perms: { read: false, write: true } },
|
|
|
|
function renameSyncReadPerm(): void {
|
|
|
|
let err;
|
|
|
|
try {
|
|
|
|
const oldpath = "/oldbaddir";
|
|
|
|
const newpath = "/newbaddir";
|
|
|
|
Deno.renameSync(oldpath, newpath);
|
|
|
|
} catch (e) {
|
|
|
|
err = e;
|
|
|
|
}
|
|
|
|
assert(err instanceof Deno.errors.PermissionDenied);
|
|
|
|
assertEquals(err.name, "PermissionDenied");
|
2019-08-13 09:39:01 -04:00
|
|
|
}
|
2020-03-04 11:31:14 -05:00
|
|
|
);
|
2019-08-13 09:39:01 -04:00
|
|
|
|
2020-03-04 11:31:14 -05:00
|
|
|
unitTest(
|
|
|
|
{ perms: { read: true, write: false } },
|
|
|
|
function renameSyncWritePerm(): void {
|
|
|
|
let err;
|
|
|
|
try {
|
|
|
|
const oldpath = "/oldbaddir";
|
|
|
|
const newpath = "/newbaddir";
|
|
|
|
Deno.renameSync(oldpath, newpath);
|
|
|
|
} catch (e) {
|
|
|
|
err = e;
|
|
|
|
}
|
|
|
|
assert(err instanceof Deno.errors.PermissionDenied);
|
|
|
|
assertEquals(err.name, "PermissionDenied");
|
2018-09-12 11:44:58 -04:00
|
|
|
}
|
2020-03-04 11:31:14 -05:00
|
|
|
);
|
2018-09-12 11:44:58 -04:00
|
|
|
|
2020-03-04 11:31:14 -05:00
|
|
|
unitTest(
|
|
|
|
{ perms: { read: true, write: true } },
|
|
|
|
async function renameSuccess(): Promise<void> {
|
|
|
|
const testDir = Deno.makeTempDirSync();
|
|
|
|
const oldpath = testDir + "/oldpath";
|
|
|
|
const newpath = testDir + "/newpath";
|
|
|
|
Deno.mkdirSync(oldpath);
|
|
|
|
await Deno.rename(oldpath, newpath);
|
2020-04-03 11:00:16 -04:00
|
|
|
assertDirectory(newpath);
|
|
|
|
assertMissing(oldpath);
|
|
|
|
}
|
|
|
|
);
|
2018-09-12 11:44:58 -04:00
|
|
|
|
2020-04-03 11:00:16 -04:00
|
|
|
function readFileString(filename: string): string {
|
|
|
|
const dataRead = Deno.readFileSync(filename);
|
|
|
|
const dec = new TextDecoder("utf-8");
|
|
|
|
return dec.decode(dataRead);
|
|
|
|
}
|
2018-09-12 11:44:58 -04:00
|
|
|
|
2020-04-03 11:00:16 -04:00
|
|
|
function writeFileString(filename: string, s: string): void {
|
|
|
|
const enc = new TextEncoder();
|
|
|
|
const data = enc.encode(s);
|
|
|
|
Deno.writeFileSync(filename, data, { mode: 0o666 });
|
|
|
|
}
|
|
|
|
|
|
|
|
unitTest(
|
|
|
|
{ ignore: Deno.build.os === "win", perms: { read: true, write: true } },
|
|
|
|
function renameSyncErrorsUnix(): void {
|
|
|
|
const testDir = Deno.makeTempDirSync();
|
|
|
|
const oldfile = testDir + "/oldfile";
|
|
|
|
const olddir = testDir + "/olddir";
|
|
|
|
const emptydir = testDir + "/empty";
|
|
|
|
const fulldir = testDir + "/dir";
|
|
|
|
const file = fulldir + "/file";
|
|
|
|
writeFileString(oldfile, "Hello");
|
|
|
|
Deno.mkdirSync(olddir);
|
|
|
|
Deno.mkdirSync(emptydir);
|
|
|
|
Deno.mkdirSync(fulldir);
|
|
|
|
writeFileString(file, "world");
|
|
|
|
|
|
|
|
assertThrows(
|
|
|
|
(): void => {
|
|
|
|
Deno.renameSync(oldfile, emptydir);
|
|
|
|
},
|
|
|
|
Error,
|
|
|
|
"Is a directory"
|
|
|
|
);
|
|
|
|
assertThrows(
|
|
|
|
(): void => {
|
|
|
|
Deno.renameSync(olddir, fulldir);
|
|
|
|
},
|
|
|
|
Error,
|
|
|
|
"Directory not empty"
|
|
|
|
);
|
|
|
|
assertThrows(
|
|
|
|
(): void => {
|
|
|
|
Deno.renameSync(olddir, file);
|
|
|
|
},
|
|
|
|
Error,
|
|
|
|
"Not a directory"
|
|
|
|
);
|
|
|
|
|
|
|
|
const fileLink = testDir + "/fileLink";
|
|
|
|
const dirLink = testDir + "/dirLink";
|
|
|
|
const danglingLink = testDir + "/danglingLink";
|
|
|
|
Deno.symlinkSync(file, fileLink);
|
|
|
|
Deno.symlinkSync(emptydir, dirLink);
|
|
|
|
Deno.symlinkSync(testDir + "/nonexistent", danglingLink);
|
|
|
|
|
|
|
|
assertThrows(
|
|
|
|
(): void => {
|
|
|
|
Deno.renameSync(olddir, fileLink);
|
|
|
|
},
|
|
|
|
Error,
|
|
|
|
"Not a directory"
|
|
|
|
);
|
|
|
|
assertThrows(
|
|
|
|
(): void => {
|
|
|
|
Deno.renameSync(olddir, dirLink);
|
|
|
|
},
|
|
|
|
Error,
|
|
|
|
"Not a directory"
|
|
|
|
);
|
|
|
|
assertThrows(
|
|
|
|
(): void => {
|
|
|
|
Deno.renameSync(olddir, danglingLink);
|
|
|
|
},
|
|
|
|
Error,
|
|
|
|
"Not a directory"
|
|
|
|
);
|
|
|
|
|
|
|
|
// should succeed on Unix
|
|
|
|
Deno.renameSync(olddir, emptydir);
|
|
|
|
Deno.renameSync(oldfile, dirLink);
|
|
|
|
Deno.renameSync(dirLink, danglingLink);
|
|
|
|
assertFile(danglingLink);
|
|
|
|
assertEquals("Hello", readFileString(danglingLink));
|
|
|
|
}
|
|
|
|
);
|
|
|
|
|
|
|
|
unitTest(
|
|
|
|
{ ignore: Deno.build.os !== "win", perms: { read: true, write: true } },
|
|
|
|
function renameSyncErrorsWin(): void {
|
|
|
|
const testDir = Deno.makeTempDirSync();
|
|
|
|
const oldfile = testDir + "/oldfile";
|
|
|
|
const olddir = testDir + "/olddir";
|
|
|
|
const emptydir = testDir + "/empty";
|
|
|
|
const fulldir = testDir + "/dir";
|
|
|
|
const file = fulldir + "/file";
|
|
|
|
writeFileString(oldfile, "Hello");
|
|
|
|
Deno.mkdirSync(olddir);
|
|
|
|
Deno.mkdirSync(emptydir);
|
|
|
|
Deno.mkdirSync(fulldir);
|
|
|
|
writeFileString(file, "world");
|
|
|
|
|
|
|
|
assertThrows(
|
|
|
|
(): void => {
|
|
|
|
Deno.renameSync(oldfile, emptydir);
|
|
|
|
},
|
|
|
|
Deno.errors.PermissionDenied,
|
|
|
|
"Access is denied"
|
|
|
|
);
|
|
|
|
assertThrows(
|
|
|
|
(): void => {
|
|
|
|
Deno.renameSync(olddir, fulldir);
|
|
|
|
},
|
|
|
|
Deno.errors.PermissionDenied,
|
|
|
|
"Access is denied"
|
|
|
|
);
|
|
|
|
assertThrows(
|
|
|
|
(): void => {
|
|
|
|
Deno.renameSync(olddir, emptydir);
|
|
|
|
},
|
|
|
|
Deno.errors.PermissionDenied,
|
|
|
|
"Access is denied"
|
|
|
|
);
|
|
|
|
|
|
|
|
// should succeed on Windows
|
|
|
|
Deno.renameSync(olddir, file);
|
|
|
|
assertDirectory(file);
|
2018-09-12 11:44:58 -04:00
|
|
|
}
|
2020-03-04 11:31:14 -05:00
|
|
|
);
|