mirror of
https://github.com/Instadapp/Swap-Aggregator-Subgraph.git
synced 2024-07-29 21:57:12 +00:00
719 lines
19 KiB
TypeScript
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`
|
|
);
|
|
});
|
|
});
|
|
});
|
|
});
|
|
});
|
|
});
|