From 942df0be0d8bb37862195c438017df7746b0f3f0 Mon Sep 17 00:00:00 2001 From: Axetroy Date: Mon, 18 Mar 2019 00:34:55 +0800 Subject: [PATCH] extract internal method isSubdir to fs/utils.ts (denoland/deno_std#285) Original: https://github.com/denoland/deno_std/commit/da4abcd9a3a5775939c3941a884d1c6f4d287d0f --- fs/move.ts | 14 +++----------- fs/utils.ts | 23 +++++++++++++++++++++++ fs/utils_test.ts | 31 +++++++++++++++++++++++++++++++ test.ts | 1 + 4 files changed, 58 insertions(+), 11 deletions(-) create mode 100644 fs/utils.ts create mode 100644 fs/utils_test.ts diff --git a/fs/move.ts b/fs/move.ts index eb6352bd54..007e4520bd 100644 --- a/fs/move.ts +++ b/fs/move.ts @@ -1,20 +1,12 @@ // Copyright 2018-2019 the Deno authors. All rights reserved. MIT license. import * as path from "./path/mod.ts"; import { exists, existsSync } from "./exists.ts"; +import { isSubdir } from "./utils.ts"; interface MoveOptions { overwrite?: boolean; } -function isSrcSubdir(src: string, dest: string): boolean { - const srcArray = src.split(path.sep); - const destArray = dest.split(path.sep); - - return srcArray.reduce((acc, current, i) => { - return acc && destArray[i] === current; - }, true); -} - /** Moves a file or directory */ export async function move( src: string, @@ -26,7 +18,7 @@ export async function move( const srcStat = await Deno.stat(src); - if (srcStat.isDirectory() && isSrcSubdir(src, dest)) { + if (srcStat.isDirectory() && isSubdir(src, dest)) { throw new Error( `Cannot move '${src}' to a subdirectory of itself, '${dest}'.` ); @@ -56,7 +48,7 @@ export function moveSync( const srcStat = Deno.statSync(src); - if (srcStat.isDirectory() && isSrcSubdir(src, dest)) { + if (srcStat.isDirectory() && isSubdir(src, dest)) { throw new Error( `Cannot move '${src}' to a subdirectory of itself, '${dest}'.` ); diff --git a/fs/utils.ts b/fs/utils.ts new file mode 100644 index 0000000000..dd7ee5fa40 --- /dev/null +++ b/fs/utils.ts @@ -0,0 +1,23 @@ +import * as path from "./path/mod.ts"; + +/** + * Test whether or not `dest` is a sub-directory of `src` + * @param src src file path + * @param dest dest file path + * @param sep path separator + */ +export function isSubdir( + src: string, + dest: string, + sep: string = path.sep +): boolean { + if (src === dest) { + return false; + } + const srcArray = src.split(sep); + const destArray = dest.split(sep); + + return srcArray.reduce((acc, current, i) => { + return acc && destArray[i] === current; + }, true); +} diff --git a/fs/utils_test.ts b/fs/utils_test.ts new file mode 100644 index 0000000000..9d6959de5f --- /dev/null +++ b/fs/utils_test.ts @@ -0,0 +1,31 @@ +// Copyright the Browserify authors. MIT License. + +import { test } from "../testing/mod.ts"; +import { assertEquals } from "../testing/asserts.ts"; +import { isSubdir } from "./utils.ts"; +import * as path from "./path/mod.ts"; + +test(function _isSubdir() { + const pairs = [ + ["", "", false, path.posix.sep], + ["/first/second", "/first", false, path.posix.sep], + ["/first", "/first", false, path.posix.sep], + ["/first", "/first/second", true, path.posix.sep], + ["first", "first/second", true, path.posix.sep], + ["../first", "../first/second", true, path.posix.sep], + ["c:\\first", "c:\\first", false, path.win32.sep], + ["c:\\first", "c:\\first\\second", true, path.win32.sep] + ]; + + pairs.forEach(function(p) { + const src = p[0] as string; + const dest = p[1] as string; + const expected = p[2] as boolean; + const sep = p[3] as string; + assertEquals( + isSubdir(src, dest, sep), + expected, + `'${src}' should ${expected ? "" : "not"} be parent dir of '${dest}'` + ); + }); +}); diff --git a/test.ts b/test.ts index ee449a9719..0cf95fde09 100755 --- a/test.ts +++ b/test.ts @@ -20,6 +20,7 @@ import "./fs/ensure_file_test.ts"; import "./fs/move_test.ts"; import "./fs/read_json_test.ts"; import "./fs/write_json_test.ts"; +import "./fs/utils_test.ts"; import "./io/test.ts"; import "./http/server_test.ts"; import "./http/file_server_test.ts";