Swap-Aggregator-Subgraph/node_modules/fs-jetpack/spec/copy.spec.ts
Richa-iitr d211083153 Revert "Revert "added handler""
This reverts commit c36ee8c5ca.
2022-07-03 07:30:05 +05:30

719 lines
19 KiB
TypeScript

import * as fse from "fs-extra";
import { expect } from "chai";
import path from "./assert_path";
import helper from "./helper";
import * as jetpack from "..";
import { InspectResult } from "../types";
describe("copy", () => {
beforeEach(helper.setCleanTestCwd);
afterEach(helper.switchBackToCorrectCwd);
describe("copies a file", () => {
const preparations = () => {
fse.outputFileSync("file.txt", "abc");
};
const expectations = () => {
path("file.txt").shouldBeFileWithContent("abc");
path("file_copied.txt").shouldBeFileWithContent("abc");
};
it("sync", () => {
preparations();
jetpack.copy("file.txt", "file_copied.txt");
expectations();
});
it("async", done => {
preparations();
jetpack.copyAsync("file.txt", "file_copied.txt").then(() => {
expectations();
done();
});
});
});
describe("can copy file to nonexistent directory (will create directory)", () => {
const preparations = () => {
fse.outputFileSync("file.txt", "abc");
};
const expectations = () => {
path("file.txt").shouldBeFileWithContent("abc");
path("dir/dir/file.txt").shouldBeFileWithContent("abc");
};
it("sync", () => {
preparations();
jetpack.copy("file.txt", "dir/dir/file.txt");
expectations();
});
it("async", done => {
preparations();
jetpack.copyAsync("file.txt", "dir/dir/file.txt").then(() => {
expectations();
done();
});
});
});
describe("copies empty directory", () => {
const preparations = () => {
fse.mkdirsSync("dir");
};
const expectations = () => {
path("copied/dir").shouldBeDirectory();
};
it("sync", () => {
preparations();
jetpack.copy("dir", "copied/dir");
expectations();
});
it("async", done => {
preparations();
jetpack.copyAsync("dir", "copied/dir").then(() => {
expectations();
done();
});
});
});
describe("copies a tree of files", () => {
const preparations = () => {
fse.outputFileSync("a/f1.txt", "abc");
fse.outputFileSync("a/b/f2.txt", "123");
fse.mkdirsSync("a/b/c");
};
const expectations = () => {
path("copied/a/f1.txt").shouldBeFileWithContent("abc");
path("copied/a/b/c").shouldBeDirectory();
path("copied/a/b/f2.txt").shouldBeFileWithContent("123");
};
it("sync", () => {
preparations();
jetpack.copy("a", "copied/a");
expectations();
});
it("async", done => {
preparations();
jetpack.copyAsync("a", "copied/a").then(() => {
expectations();
done();
});
});
});
describe("generates nice error if source path doesn't exist", () => {
const expectations = (err: any) => {
expect(err.code).to.equal("ENOENT");
expect(err.message).to.have.string("Path to copy doesn't exist");
};
it("sync", () => {
try {
jetpack.copy("a", "b");
throw new Error("Expected error to be thrown");
} catch (err) {
expectations(err);
}
});
it("async", done => {
jetpack.copyAsync("a", "b").catch(err => {
expectations(err);
done();
});
});
});
describe("respects internal CWD of jetpack instance", () => {
const preparations = () => {
fse.outputFileSync("a/b.txt", "abc");
};
const expectations = () => {
path("a/b.txt").shouldBeFileWithContent("abc");
path("a/x.txt").shouldBeFileWithContent("abc");
};
it("sync", () => {
const jetContext = jetpack.cwd("a");
preparations();
jetContext.copy("b.txt", "x.txt");
expectations();
});
it("async", done => {
const jetContext = jetpack.cwd("a");
preparations();
jetContext.copyAsync("b.txt", "x.txt").then(() => {
expectations();
done();
});
});
});
describe("overwriting behaviour", () => {
describe("does not overwrite by default", () => {
const preparations = () => {
fse.outputFileSync("a/file.txt", "abc");
fse.mkdirsSync("b");
};
const expectations = (err: any) => {
expect(err.code).to.equal("EEXIST");
expect(err.message).to.have.string("Destination path already exists");
};
it("sync", () => {
preparations();
try {
jetpack.copy("a", "b");
throw new Error("Expected error to be thrown");
} catch (err) {
expectations(err);
}
});
it("async", done => {
preparations();
jetpack.copyAsync("a", "b").catch(err => {
expectations(err);
done();
});
});
});
describe("overwrites if it was specified", () => {
const preparations = () => {
fse.outputFileSync("a/file.txt", "abc");
fse.outputFileSync("b/file.txt", "xyz");
};
const expectations = () => {
path("a/file.txt").shouldBeFileWithContent("abc");
path("b/file.txt").shouldBeFileWithContent("abc");
};
it("sync", () => {
preparations();
jetpack.copy("a", "b", { overwrite: true });
expectations();
});
it("async", done => {
preparations();
jetpack.copyAsync("a", "b", { overwrite: true }).then(() => {
expectations();
done();
});
});
});
describe("overwrites according to what function returns", () => {
const preparations = () => {
fse.outputFileSync("from-here/foo/canada.txt", "abc");
fse.outputFileSync("to-here/foo/canada.txt", "xyz");
fse.outputFileSync("from-here/foo/eh.txt", "abc");
fse.outputFileSync("to-here/foo/eh.txt", "xyz");
};
const expectations = () => {
// canada is copied
path("from-here/foo/canada.txt").shouldBeFileWithContent("abc");
path("to-here/foo/canada.txt").shouldBeFileWithContent("abc");
// eh is not copied
path("from-here/foo/eh.txt").shouldBeFileWithContent("abc");
path("to-here/foo/eh.txt").shouldBeFileWithContent("xyz");
};
const overwrite = (
srcInspectData: InspectResult,
destInspectData: InspectResult
) => {
expect(srcInspectData).to.have.property("name");
expect(srcInspectData).to.have.property("type");
expect(srcInspectData).to.have.property("mode");
expect(srcInspectData).to.have.property("accessTime");
expect(srcInspectData).to.have.property("modifyTime");
expect(srcInspectData).to.have.property("changeTime");
expect(srcInspectData).to.have.property("absolutePath");
expect(destInspectData).to.have.property("name");
expect(destInspectData).to.have.property("type");
expect(destInspectData).to.have.property("mode");
expect(destInspectData).to.have.property("accessTime");
expect(destInspectData).to.have.property("modifyTime");
expect(destInspectData).to.have.property("changeTime");
expect(destInspectData).to.have.property("absolutePath");
return srcInspectData.name.includes("canada");
};
it("sync", () => {
preparations();
jetpack.copy("from-here", "to-here", { overwrite });
expectations();
});
it("async", done => {
preparations();
jetpack.copyAsync("from-here", "to-here", { overwrite }).then(() => {
expectations();
done();
});
});
});
});
describe("async overwrite function can return promise", () => {
const preparations = () => {
fse.outputFileSync("from-here/foo/canada.txt", "abc");
fse.outputFileSync("to-here/foo/canada.txt", "xyz");
fse.outputFileSync("from-here/foo/eh.txt", "123");
fse.outputFileSync("to-here/foo/eh.txt", "456");
};
const expectations = () => {
// canada is copied
path("from-here/foo/canada.txt").shouldBeFileWithContent("abc");
path("to-here/foo/canada.txt").shouldBeFileWithContent("abc");
// eh is not copied
path("from-here/foo/eh.txt").shouldBeFileWithContent("123");
path("to-here/foo/eh.txt").shouldBeFileWithContent("456");
};
const overwrite = (
srcInspectData: InspectResult,
destInspectData: InspectResult
): Promise<boolean> => {
return new Promise((resolve, reject) => {
jetpack.readAsync(srcInspectData.absolutePath).then(data => {
resolve(data === "abc");
});
});
};
it("async", done => {
preparations();
jetpack
.copyAsync("from-here", "to-here", { overwrite })
.then(() => {
expectations();
done();
})
.catch(done);
});
});
describe("filter what to copy", () => {
describe("by simple pattern", () => {
const preparations = () => {
fse.outputFileSync("dir/file.txt", "1");
fse.outputFileSync("dir/file.md", "m1");
fse.outputFileSync("dir/a/file.txt", "2");
fse.outputFileSync("dir/a/file.md", "m2");
};
const expectations = () => {
path("copy/file.txt").shouldBeFileWithContent("1");
path("copy/file.md").shouldNotExist();
path("copy/a/file.txt").shouldBeFileWithContent("2");
path("copy/a/file.md").shouldNotExist();
};
it("sync", () => {
preparations();
jetpack.copy("dir", "copy", { matching: "*.txt" });
expectations();
});
it("async", done => {
preparations();
jetpack.copyAsync("dir", "copy", { matching: "*.txt" }).then(() => {
expectations();
done();
});
});
});
describe("by pattern anchored to copied directory", () => {
const preparations = () => {
fse.outputFileSync("x/y/dir/file.txt", "1");
fse.outputFileSync("x/y/dir/a/file.txt", "2");
fse.outputFileSync("x/y/dir/a/b/file.txt", "3");
};
const expectations = () => {
path("copy/file.txt").shouldNotExist();
path("copy/a/file.txt").shouldBeFileWithContent("2");
path("copy/a/b/file.txt").shouldNotExist();
};
it("sync", () => {
preparations();
jetpack.copy("x/y/dir", "copy", { matching: "a/*.txt" });
expectations();
});
it("async", done => {
preparations();
jetpack
.copyAsync("x/y/dir", "copy", { matching: "a/*.txt" })
.then(() => {
expectations();
done();
});
});
});
describe("can use ./ as indication of anchor directory", () => {
const preparations = () => {
fse.outputFileSync("x/y/a.txt", "123");
fse.outputFileSync("x/y/b/a.txt", "456");
};
const expectations = () => {
path("copy/a.txt").shouldBeFileWithContent("123");
path("copy/b/a.txt").shouldNotExist();
};
it("sync", () => {
preparations();
jetpack.copy("x/y", "copy", { matching: "./a.txt" });
expectations();
});
it("async", done => {
preparations();
jetpack.copyAsync("x/y", "copy", { matching: "./a.txt" }).then(() => {
expectations();
done();
});
});
});
describe("matching works also if copying single file", () => {
const preparations = () => {
fse.outputFileSync("a", "123");
fse.outputFileSync("x", "456");
};
const expectations = () => {
path("a-copy").shouldNotExist();
path("x-copy").shouldBeFileWithContent("456");
};
it("sync", () => {
preparations();
jetpack.copy("a", "a-copy", { matching: "x" });
jetpack.copy("x", "x-copy", { matching: "x" });
expectations();
});
it("async", done => {
preparations();
jetpack
.copyAsync("a", "a-copy", { matching: "x" })
.then(() => {
return jetpack.copyAsync("x", "x-copy", { matching: "x" });
})
.then(() => {
expectations();
done();
});
});
});
describe("can use negation in patterns", () => {
const preparations = () => {
fse.mkdirsSync("x/y/dir/a/b");
fse.mkdirsSync("x/y/dir/a/x");
fse.mkdirsSync("x/y/dir/a/y");
fse.mkdirsSync("x/y/dir/a/z");
};
const expectations = () => {
path("copy/dir/a/b").shouldBeDirectory();
path("copy/dir/a/x").shouldNotExist();
path("copy/dir/a/y").shouldNotExist();
path("copy/dir/a/z").shouldNotExist();
};
it("sync", () => {
preparations();
jetpack.copy("x/y", "copy", {
matching: [
"**",
// Three different pattern types to test:
"!x",
"!dir/a/y",
"!./dir/a/z"
]
});
expectations();
});
it("async", done => {
preparations();
jetpack
.copyAsync("x/y", "copy", {
matching: [
"**",
// Three different pattern types to test:
"!x",
"!dir/a/y",
"!./dir/a/z"
]
})
.then(() => {
expectations();
done();
});
});
});
describe("wildcard copies everything", () => {
const preparations = () => {
// Just a file
fse.outputFileSync("x/file.txt", "123");
// Dot file
fse.outputFileSync("x/y/.dot", "dot");
// Empty directory
fse.mkdirsSync("x/y/z");
};
const expectations = () => {
path("copy/file.txt").shouldBeFileWithContent("123");
path("copy/y/.dot").shouldBeFileWithContent("dot");
path("copy/y/z").shouldBeDirectory();
};
it("sync", () => {
preparations();
jetpack.copy("x", "copy", { matching: "**" });
expectations();
});
it("async", done => {
preparations();
jetpack.copyAsync("x", "copy", { matching: "**" }).then(() => {
expectations();
done();
});
});
});
});
describe("can copy symlink", () => {
const preparations = () => {
fse.mkdirsSync("to_copy");
fse.symlinkSync("some/file", "to_copy/symlink");
};
const expectations = () => {
expect(fse.lstatSync("copied/symlink").isSymbolicLink()).to.equal(true);
expect(fse.readlinkSync("copied/symlink")).to.equal(
helper.osSep("some/file")
);
};
it("sync", () => {
preparations();
jetpack.copy("to_copy", "copied");
expectations();
});
it("async", done => {
preparations();
jetpack.copyAsync("to_copy", "copied").then(() => {
expectations();
done();
});
});
});
describe("can overwrite symlink", () => {
const preparations = () => {
fse.mkdirsSync("to_copy");
fse.symlinkSync("some/file", "to_copy/symlink");
fse.mkdirsSync("copied");
fse.symlinkSync("some/other_file", "copied/symlink");
};
const expectations = () => {
expect(fse.lstatSync("copied/symlink").isSymbolicLink()).to.equal(true);
expect(fse.readlinkSync("copied/symlink")).to.equal(
helper.osSep("some/file")
);
};
it("sync", () => {
preparations();
jetpack.copy("to_copy", "copied", { overwrite: true });
expectations();
});
it("async", done => {
preparations();
jetpack.copyAsync("to_copy", "copied", { overwrite: true }).then(() => {
expectations();
done();
});
});
});
describe("if ignoreCase=true it ignores case in patterns", () => {
// This test actually tests nothing if performed on case-insensitive file system.
const preparations = () => {
fse.mkdirsSync("orig/FoO/BaR/x");
};
const expectations = () => {
path("copy/FoO/BaR/x").shouldBeDirectory();
};
it("sync", () => {
preparations();
jetpack.copy("orig", "copy", {
matching: ["foo/bar/x"],
ignoreCase: true
});
expectations();
});
it("async", done => {
preparations();
jetpack
.copyAsync("orig", "copy", {
matching: ["foo/bar/x"],
ignoreCase: true
})
.then(() => {
expectations();
done();
});
});
});
if (process.platform !== "win32") {
describe("copies also file permissions (unix only)", () => {
const preparations = () => {
fse.outputFileSync("a/b/c.txt", "abc");
fse.chmodSync("a/b", "700");
fse.chmodSync("a/b/c.txt", "711");
};
const expectations = () => {
path("x/b").shouldHaveMode("700");
path("x/b/c.txt").shouldHaveMode("711");
};
it("sync", () => {
preparations();
jetpack.copy("a", "x");
expectations();
});
it("async", done => {
preparations();
jetpack.copyAsync("a", "x").then(() => {
expectations();
done();
});
});
});
}
describe("input validation", () => {
const tests = [
{ type: "sync", method: jetpack.copy as any, methodName: "copy" },
{
type: "async",
method: jetpack.copyAsync as any,
methodName: "copyAsync"
}
];
describe('"from" argument', () => {
tests.forEach(test => {
it(test.type, () => {
expect(() => {
test.method(undefined, "xyz");
}).to.throw(
`Argument "from" passed to ${
test.methodName
}(from, to, [options]) must be a string. Received undefined`
);
});
});
});
describe('"to" argument', () => {
tests.forEach(test => {
it(test.type, () => {
expect(() => {
test.method("abc");
}).to.throw(
`Argument "to" passed to ${
test.methodName
}(from, to, [options]) must be a string. Received undefined`
);
});
});
});
describe('"options" object', () => {
describe('"overwrite" argument', () => {
tests.forEach(test => {
it(test.type, () => {
expect(() => {
test.method("abc", "xyz", { overwrite: 1 });
}).to.throw(
`Argument "options.overwrite" passed to ${
test.methodName
}(from, to, [options]) must be a boolean or a function. Received number`
);
});
});
});
describe('"matching" argument', () => {
tests.forEach(test => {
it(test.type, () => {
expect(() => {
test.method("abc", "xyz", { matching: 1 });
}).to.throw(
`Argument "options.matching" passed to ${
test.methodName
}(from, to, [options]) must be a string or an array of string. Received number`
);
});
});
});
describe('"ignoreCase" argument', () => {
tests.forEach(test => {
it(test.type, () => {
expect(() => {
test.method("abc", "xyz", { ignoreCase: 1 });
}).to.throw(
`Argument "options.ignoreCase" passed to ${
test.methodName
}(from, to, [options]) must be a boolean. Received number`
);
});
});
});
});
});
});