2021-01-11 17:13:41 +00:00
|
|
|
// Copyright 2018-2021 the Deno authors. All rights reserved. MIT license.
|
2020-09-27 10:22:32 +00:00
|
|
|
import { walk, WalkEntry, WalkOptions, walkSync } from "./walk.ts";
|
2021-04-30 06:49:41 +00:00
|
|
|
import {
|
|
|
|
assert,
|
|
|
|
assertEquals,
|
2021-08-09 05:59:52 +00:00
|
|
|
assertRejects,
|
2021-04-30 06:49:41 +00:00
|
|
|
assertThrows,
|
|
|
|
} from "../testing/asserts.ts";
|
2020-03-15 12:03:25 +00:00
|
|
|
|
2020-03-20 13:38:34 +00:00
|
|
|
export function testWalk(
|
2019-05-30 12:59:30 +00:00
|
|
|
setup: (arg0: string) => void | Promise<void>,
|
2020-04-01 08:47:23 +00:00
|
|
|
t: () => void | Promise<void>,
|
2020-07-14 19:24:17 +00:00
|
|
|
ignore = false,
|
2020-03-20 13:38:34 +00:00
|
|
|
): void {
|
2019-02-15 16:20:59 +00:00
|
|
|
const name = t.name;
|
2021-04-05 11:49:05 +00:00
|
|
|
async function fn() {
|
2020-06-12 19:23:38 +00:00
|
|
|
const origCwd = Deno.cwd();
|
|
|
|
const d = await Deno.makeTempDir();
|
|
|
|
Deno.chdir(d);
|
2019-02-15 16:20:59 +00:00
|
|
|
try {
|
|
|
|
await setup(d);
|
|
|
|
await t();
|
|
|
|
} finally {
|
2020-06-12 19:23:38 +00:00
|
|
|
Deno.chdir(origCwd);
|
|
|
|
await Deno.remove(d, { recursive: true });
|
2019-02-15 16:20:59 +00:00
|
|
|
}
|
|
|
|
}
|
2020-03-19 09:58:12 +00:00
|
|
|
Deno.test({ ignore, name: `[walk] ${name}`, fn });
|
2019-02-15 16:20:59 +00:00
|
|
|
}
|
|
|
|
|
2020-04-29 20:00:31 +00:00
|
|
|
function normalize({ path }: WalkEntry): string {
|
|
|
|
return path.replace(/\\/g, "/");
|
2019-05-14 21:14:08 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
export async function walkArray(
|
2019-10-02 17:59:27 +00:00
|
|
|
root: string,
|
2020-07-14 19:24:17 +00:00
|
|
|
options: WalkOptions = {},
|
2019-03-12 05:51:51 +00:00
|
|
|
): Promise<string[]> {
|
2019-02-15 16:20:59 +00:00
|
|
|
const arr: string[] = [];
|
2019-05-14 21:14:08 +00:00
|
|
|
for await (const w of walk(root, { ...options })) {
|
|
|
|
arr.push(normalize(w));
|
2019-02-15 16:20:59 +00:00
|
|
|
}
|
2019-05-14 21:14:08 +00:00
|
|
|
arr.sort(); // TODO(ry) Remove sort. The order should be deterministic.
|
|
|
|
const arrSync = Array.from(walkSync(root, options), normalize);
|
|
|
|
arrSync.sort(); // TODO(ry) Remove sort. The order should be deterministic.
|
2019-03-12 05:51:51 +00:00
|
|
|
assertEquals(arr, arrSync);
|
2019-02-15 16:20:59 +00:00
|
|
|
return arr;
|
|
|
|
}
|
|
|
|
|
2021-04-05 11:49:05 +00:00
|
|
|
export async function touch(path: string) {
|
2020-06-12 19:23:38 +00:00
|
|
|
const f = await Deno.create(path);
|
2020-03-18 23:25:55 +00:00
|
|
|
f.close();
|
2019-02-15 16:20:59 +00:00
|
|
|
}
|
2019-05-14 21:14:08 +00:00
|
|
|
|
2019-03-12 05:51:51 +00:00
|
|
|
function assertReady(expectedLength: number): void {
|
2019-10-02 17:59:27 +00:00
|
|
|
const arr = Array.from(walkSync("."), normalize);
|
2019-05-14 21:14:08 +00:00
|
|
|
|
2019-03-07 00:42:24 +00:00
|
|
|
assertEquals(arr.length, expectedLength);
|
2019-02-15 16:20:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
testWalk(
|
2021-04-05 11:49:05 +00:00
|
|
|
async (d: string) => {
|
2020-06-12 19:23:38 +00:00
|
|
|
await Deno.mkdir(d + "/empty");
|
2019-02-15 16:20:59 +00:00
|
|
|
},
|
2021-04-05 11:49:05 +00:00
|
|
|
async function emptyDir() {
|
2019-10-02 17:59:27 +00:00
|
|
|
const arr = await walkArray(".");
|
|
|
|
assertEquals(arr, [".", "empty"]);
|
2020-07-14 19:24:17 +00:00
|
|
|
},
|
2019-02-15 16:20:59 +00:00
|
|
|
);
|
|
|
|
|
|
|
|
testWalk(
|
2021-04-05 11:49:05 +00:00
|
|
|
async (d: string) => {
|
2019-02-15 16:20:59 +00:00
|
|
|
await touch(d + "/x");
|
|
|
|
},
|
2021-04-05 11:49:05 +00:00
|
|
|
async function singleFile() {
|
2019-10-02 17:59:27 +00:00
|
|
|
const arr = await walkArray(".");
|
|
|
|
assertEquals(arr, [".", "x"]);
|
2020-07-14 19:24:17 +00:00
|
|
|
},
|
2019-02-15 16:20:59 +00:00
|
|
|
);
|
|
|
|
|
|
|
|
testWalk(
|
2021-04-05 11:49:05 +00:00
|
|
|
async (d: string) => {
|
2019-02-15 16:20:59 +00:00
|
|
|
await touch(d + "/x");
|
|
|
|
},
|
2021-04-05 11:49:05 +00:00
|
|
|
async function iteratable() {
|
2019-02-15 16:20:59 +00:00
|
|
|
let count = 0;
|
2019-05-14 21:14:08 +00:00
|
|
|
for (const _ of walkSync(".")) {
|
2019-02-15 16:20:59 +00:00
|
|
|
count += 1;
|
|
|
|
}
|
2019-10-02 17:59:27 +00:00
|
|
|
assertEquals(count, 2);
|
2019-05-14 21:14:08 +00:00
|
|
|
for await (const _ of walk(".")) {
|
2019-02-15 16:20:59 +00:00
|
|
|
count += 1;
|
|
|
|
}
|
2019-10-02 17:59:27 +00:00
|
|
|
assertEquals(count, 4);
|
2020-07-14 19:24:17 +00:00
|
|
|
},
|
2019-02-15 16:20:59 +00:00
|
|
|
);
|
|
|
|
|
|
|
|
testWalk(
|
2021-04-05 11:49:05 +00:00
|
|
|
async (d: string) => {
|
2020-06-12 19:23:38 +00:00
|
|
|
await Deno.mkdir(d + "/a");
|
2019-02-15 16:20:59 +00:00
|
|
|
await touch(d + "/a/x");
|
|
|
|
},
|
2021-04-05 11:49:05 +00:00
|
|
|
async function nestedSingleFile() {
|
2019-10-02 17:59:27 +00:00
|
|
|
const arr = await walkArray(".");
|
|
|
|
assertEquals(arr, [".", "a", "a/x"]);
|
2020-07-14 19:24:17 +00:00
|
|
|
},
|
2019-02-15 16:20:59 +00:00
|
|
|
);
|
|
|
|
|
|
|
|
testWalk(
|
2021-04-05 11:49:05 +00:00
|
|
|
async (d: string) => {
|
2020-06-12 19:23:38 +00:00
|
|
|
await Deno.mkdir(d + "/a/b/c/d", { recursive: true });
|
2019-02-15 16:20:59 +00:00
|
|
|
await touch(d + "/a/b/c/d/x");
|
|
|
|
},
|
2021-04-05 11:49:05 +00:00
|
|
|
async function depth() {
|
2019-10-02 17:59:27 +00:00
|
|
|
assertReady(6);
|
2019-03-12 05:51:51 +00:00
|
|
|
const arr3 = await walkArray(".", { maxDepth: 3 });
|
2019-10-02 17:59:27 +00:00
|
|
|
assertEquals(arr3, [".", "a", "a/b", "a/b/c"]);
|
2019-03-12 05:51:51 +00:00
|
|
|
const arr5 = await walkArray(".", { maxDepth: 5 });
|
2019-10-02 17:59:27 +00:00
|
|
|
assertEquals(arr5, [".", "a", "a/b", "a/b/c", "a/b/c/d", "a/b/c/d/x"]);
|
2020-07-14 19:24:17 +00:00
|
|
|
},
|
2019-02-15 16:20:59 +00:00
|
|
|
);
|
|
|
|
|
2019-09-18 15:37:37 +00:00
|
|
|
testWalk(
|
2021-04-05 11:49:05 +00:00
|
|
|
async (d: string) => {
|
2019-09-18 15:37:37 +00:00
|
|
|
await touch(d + "/a");
|
2020-06-12 19:23:38 +00:00
|
|
|
await Deno.mkdir(d + "/b");
|
2019-09-18 15:37:37 +00:00
|
|
|
await touch(d + "/b/c");
|
|
|
|
},
|
2021-04-05 11:49:05 +00:00
|
|
|
async function includeDirs() {
|
2019-10-02 17:59:27 +00:00
|
|
|
assertReady(4);
|
|
|
|
const arr = await walkArray(".", { includeDirs: false });
|
|
|
|
assertEquals(arr, ["a", "b/c"]);
|
2020-07-14 19:24:17 +00:00
|
|
|
},
|
2019-10-02 17:59:27 +00:00
|
|
|
);
|
|
|
|
|
|
|
|
testWalk(
|
2021-04-05 11:49:05 +00:00
|
|
|
async (d: string) => {
|
2019-10-02 17:59:27 +00:00
|
|
|
await touch(d + "/a");
|
2020-06-12 19:23:38 +00:00
|
|
|
await Deno.mkdir(d + "/b");
|
2019-10-02 17:59:27 +00:00
|
|
|
await touch(d + "/b/c");
|
|
|
|
},
|
2021-04-05 11:49:05 +00:00
|
|
|
async function includeFiles() {
|
2019-10-02 17:59:27 +00:00
|
|
|
assertReady(4);
|
|
|
|
const arr = await walkArray(".", { includeFiles: false });
|
|
|
|
assertEquals(arr, [".", "b"]);
|
2020-07-14 19:24:17 +00:00
|
|
|
},
|
2019-09-18 15:37:37 +00:00
|
|
|
);
|
|
|
|
|
2019-02-15 16:20:59 +00:00
|
|
|
testWalk(
|
2021-04-05 11:49:05 +00:00
|
|
|
async (d: string) => {
|
2019-02-15 16:20:59 +00:00
|
|
|
await touch(d + "/x.ts");
|
|
|
|
await touch(d + "/y.rs");
|
|
|
|
},
|
2021-04-05 11:49:05 +00:00
|
|
|
async function ext() {
|
2019-10-02 17:59:27 +00:00
|
|
|
assertReady(3);
|
2019-02-15 16:20:59 +00:00
|
|
|
const arr = await walkArray(".", { exts: [".ts"] });
|
2019-10-02 17:59:27 +00:00
|
|
|
assertEquals(arr, ["x.ts"]);
|
2020-07-14 19:24:17 +00:00
|
|
|
},
|
2019-02-15 16:20:59 +00:00
|
|
|
);
|
|
|
|
|
|
|
|
testWalk(
|
2021-04-05 11:49:05 +00:00
|
|
|
async (d: string) => {
|
2019-02-15 16:20:59 +00:00
|
|
|
await touch(d + "/x.ts");
|
|
|
|
await touch(d + "/y.rs");
|
|
|
|
await touch(d + "/z.py");
|
|
|
|
},
|
2021-04-05 11:49:05 +00:00
|
|
|
async function extAny() {
|
2019-10-02 17:59:27 +00:00
|
|
|
assertReady(4);
|
2019-02-15 16:20:59 +00:00
|
|
|
const arr = await walkArray(".", { exts: [".rs", ".ts"] });
|
2019-10-02 17:59:27 +00:00
|
|
|
assertEquals(arr, ["x.ts", "y.rs"]);
|
2020-07-14 19:24:17 +00:00
|
|
|
},
|
2019-02-15 16:20:59 +00:00
|
|
|
);
|
|
|
|
|
|
|
|
testWalk(
|
2021-04-05 11:49:05 +00:00
|
|
|
async (d: string) => {
|
2019-02-15 16:20:59 +00:00
|
|
|
await touch(d + "/x");
|
|
|
|
await touch(d + "/y");
|
|
|
|
},
|
2021-04-05 11:49:05 +00:00
|
|
|
async function match() {
|
2019-10-02 17:59:27 +00:00
|
|
|
assertReady(3);
|
2019-02-15 16:20:59 +00:00
|
|
|
const arr = await walkArray(".", { match: [/x/] });
|
2019-10-02 17:59:27 +00:00
|
|
|
assertEquals(arr, ["x"]);
|
2020-07-14 19:24:17 +00:00
|
|
|
},
|
2019-02-15 16:20:59 +00:00
|
|
|
);
|
|
|
|
|
|
|
|
testWalk(
|
2021-04-05 11:49:05 +00:00
|
|
|
async (d: string) => {
|
2019-02-15 16:20:59 +00:00
|
|
|
await touch(d + "/x");
|
|
|
|
await touch(d + "/y");
|
|
|
|
await touch(d + "/z");
|
|
|
|
},
|
2021-04-05 11:49:05 +00:00
|
|
|
async function matchAny() {
|
2019-10-02 17:59:27 +00:00
|
|
|
assertReady(4);
|
2019-02-15 16:20:59 +00:00
|
|
|
const arr = await walkArray(".", { match: [/x/, /y/] });
|
2019-10-02 17:59:27 +00:00
|
|
|
assertEquals(arr, ["x", "y"]);
|
2020-07-14 19:24:17 +00:00
|
|
|
},
|
2019-02-15 16:20:59 +00:00
|
|
|
);
|
|
|
|
|
|
|
|
testWalk(
|
2021-04-05 11:49:05 +00:00
|
|
|
async (d: string) => {
|
2019-02-15 16:20:59 +00:00
|
|
|
await touch(d + "/x");
|
|
|
|
await touch(d + "/y");
|
|
|
|
},
|
2021-04-05 11:49:05 +00:00
|
|
|
async function skip() {
|
2019-10-02 17:59:27 +00:00
|
|
|
assertReady(3);
|
2019-02-15 16:20:59 +00:00
|
|
|
const arr = await walkArray(".", { skip: [/x/] });
|
2019-10-02 17:59:27 +00:00
|
|
|
assertEquals(arr, [".", "y"]);
|
2020-07-14 19:24:17 +00:00
|
|
|
},
|
2019-02-15 16:20:59 +00:00
|
|
|
);
|
|
|
|
|
|
|
|
testWalk(
|
2021-04-05 11:49:05 +00:00
|
|
|
async (d: string) => {
|
2019-02-15 16:20:59 +00:00
|
|
|
await touch(d + "/x");
|
|
|
|
await touch(d + "/y");
|
|
|
|
await touch(d + "/z");
|
|
|
|
},
|
2021-04-05 11:49:05 +00:00
|
|
|
async function skipAny() {
|
2019-10-02 17:59:27 +00:00
|
|
|
assertReady(4);
|
2019-02-15 16:20:59 +00:00
|
|
|
const arr = await walkArray(".", { skip: [/x/, /y/] });
|
2019-10-02 17:59:27 +00:00
|
|
|
assertEquals(arr, [".", "z"]);
|
2020-07-14 19:24:17 +00:00
|
|
|
},
|
2019-02-15 16:20:59 +00:00
|
|
|
);
|
|
|
|
|
|
|
|
testWalk(
|
2021-04-05 11:49:05 +00:00
|
|
|
async (d: string) => {
|
2020-06-12 19:23:38 +00:00
|
|
|
await Deno.mkdir(d + "/a");
|
|
|
|
await Deno.mkdir(d + "/b");
|
2019-02-15 16:20:59 +00:00
|
|
|
await touch(d + "/a/x");
|
|
|
|
await touch(d + "/a/y");
|
|
|
|
await touch(d + "/b/z");
|
|
|
|
},
|
2021-04-05 11:49:05 +00:00
|
|
|
async function subDir() {
|
2019-10-02 17:59:27 +00:00
|
|
|
assertReady(6);
|
2019-02-15 16:20:59 +00:00
|
|
|
const arr = await walkArray("b");
|
2019-10-02 17:59:27 +00:00
|
|
|
assertEquals(arr, ["b", "b/z"]);
|
2020-07-14 19:24:17 +00:00
|
|
|
},
|
2019-02-15 16:20:59 +00:00
|
|
|
);
|
|
|
|
|
2019-04-24 11:41:23 +00:00
|
|
|
testWalk(
|
2021-04-05 11:49:05 +00:00
|
|
|
async (_d: string) => {},
|
|
|
|
async function nonexistentRoot() {
|
2021-08-09 05:59:52 +00:00
|
|
|
await assertRejects(async () => {
|
2019-11-15 03:22:33 +00:00
|
|
|
await walkArray("nonexistent");
|
2020-02-24 20:48:35 +00:00
|
|
|
}, Deno.errors.NotFound);
|
2020-07-14 19:24:17 +00:00
|
|
|
},
|
2019-04-24 11:41:23 +00:00
|
|
|
);
|
2019-02-15 16:20:59 +00:00
|
|
|
|
|
|
|
testWalk(
|
2021-04-05 11:49:05 +00:00
|
|
|
async (d: string) => {
|
2020-06-12 19:23:38 +00:00
|
|
|
await Deno.mkdir(d + "/a");
|
|
|
|
await Deno.mkdir(d + "/b");
|
2019-02-15 16:20:59 +00:00
|
|
|
await touch(d + "/a/x");
|
|
|
|
await touch(d + "/a/y");
|
|
|
|
await touch(d + "/b/z");
|
2020-07-05 22:14:13 +00:00
|
|
|
await Deno.symlink(d + "/b", d + "/a/bb");
|
2019-02-15 16:20:59 +00:00
|
|
|
},
|
2021-04-05 11:49:05 +00:00
|
|
|
async function symlink() {
|
2019-10-02 17:59:27 +00:00
|
|
|
assertReady(6);
|
2019-02-15 16:20:59 +00:00
|
|
|
const files = await walkArray("a");
|
2020-11-30 14:34:36 +00:00
|
|
|
assertEquals(files.length, 3);
|
2019-02-15 16:20:59 +00:00
|
|
|
assert(!files.includes("a/bb/z"));
|
|
|
|
|
|
|
|
const arr = await walkArray("a", { followSymlinks: true });
|
2020-11-30 14:34:36 +00:00
|
|
|
assertEquals(arr.length, 5);
|
2019-04-24 11:41:23 +00:00
|
|
|
assert(arr.some((f): boolean => f.endsWith("/b/z")));
|
2020-03-15 12:03:25 +00:00
|
|
|
},
|
2019-02-15 16:20:59 +00:00
|
|
|
);
|
2021-04-30 06:49:41 +00:00
|
|
|
|
|
|
|
testWalk(
|
|
|
|
async (d: string) => {
|
|
|
|
await Deno.mkdir(d + "/a/b", { recursive: true });
|
|
|
|
await Deno.chmod(d + "/a/b", 0o000);
|
|
|
|
},
|
|
|
|
async function subDirNoPermissionAsync() {
|
|
|
|
try {
|
2021-08-09 05:59:52 +00:00
|
|
|
await assertRejects(
|
2021-04-30 06:49:41 +00:00
|
|
|
async () => {
|
|
|
|
await walkArray("a");
|
|
|
|
},
|
|
|
|
Deno.errors.PermissionDenied,
|
|
|
|
'for path "a/b"',
|
|
|
|
);
|
|
|
|
} finally {
|
|
|
|
await Deno.chmod("a/b", 0o755);
|
|
|
|
}
|
|
|
|
},
|
2021-08-31 04:39:04 +00:00
|
|
|
// TODO(kt3k): Enable this test
|
|
|
|
true,
|
2021-04-30 06:49:41 +00:00
|
|
|
);
|
|
|
|
|
|
|
|
testWalk(
|
|
|
|
async (d: string) => {
|
|
|
|
await Deno.mkdir(d + "/a/b", { recursive: true });
|
|
|
|
await Deno.chmod(d + "/a/b", 0o000);
|
|
|
|
},
|
|
|
|
async function subDirNoPermissionSync() {
|
|
|
|
try {
|
|
|
|
assertThrows(
|
|
|
|
() => {
|
|
|
|
return [...walkSync("a")];
|
|
|
|
},
|
|
|
|
Deno.errors.PermissionDenied,
|
|
|
|
'for path "a/b"',
|
|
|
|
);
|
|
|
|
} finally {
|
|
|
|
await Deno.chmod("a/b", 0o755);
|
|
|
|
}
|
|
|
|
},
|
2021-08-31 04:39:04 +00:00
|
|
|
// TODO(kt3k): Enable this test
|
|
|
|
true,
|
2021-04-30 06:49:41 +00:00
|
|
|
);
|