1 | ;
|
2 | // Copyright IBM Corp. and LoopBack contributors 2018,2020. All Rights Reserved.
|
3 | // Node module: @loopback/testlab
|
4 | // This file is licensed under the MIT License.
|
5 | // License text available at https://opensource.org/licenses/MIT
|
6 | Object.defineProperty(exports, "__esModule", { value: true });
|
7 | exports.TestSandbox = void 0;
|
8 | const fs_extra_1 = require("fs-extra");
|
9 | const path_1 = require("path");
|
10 | /**
|
11 | * TestSandbox class provides a convenient way to get a reference to a
|
12 | * sandbox folder in which you can perform operations for testing purposes.
|
13 | */
|
14 | class TestSandbox {
|
15 | get path() {
|
16 | if (!this._path) {
|
17 | throw new Error(`TestSandbox instance was deleted. Create a new instance.`);
|
18 | }
|
19 | return this._path;
|
20 | }
|
21 | /**
|
22 | * Will create a directory if it doesn't already exist. If it exists, you
|
23 | * still get an instance of the TestSandbox.
|
24 | *
|
25 | * @example
|
26 | * ```ts
|
27 | * // Create a sandbox as a unique temporary subdirectory under the rootPath
|
28 | * const sandbox = new TestSandbox(rootPath);
|
29 | * const sandbox = new TestSandbox(rootPath, {subdir: true});
|
30 | *
|
31 | * // Create a sandbox in the root path directly
|
32 | * // This is same as the old behavior
|
33 | * const sandbox = new TestSandbox(rootPath, {subdir: false});
|
34 | *
|
35 | * // Create a sandbox in the `test1` subdirectory of the root path
|
36 | * const sandbox = new TestSandbox(rootPath, {subdir: 'test1'});
|
37 | * ```
|
38 | *
|
39 | * @param rootPath - Root path of the TestSandbox. If relative it will be
|
40 | * resolved against the current directory.
|
41 | * @param options - Options to control if/how the sandbox creates a
|
42 | * subdirectory for the sandbox. If not provided, the sandbox
|
43 | * will automatically creates a unique temporary subdirectory. This allows
|
44 | * sandboxes with the same root path can be used in parallel during testing.
|
45 | */
|
46 | constructor(rootPath, options) {
|
47 | rootPath = (0, path_1.resolve)(rootPath);
|
48 | (0, fs_extra_1.ensureDirSync)(rootPath);
|
49 | options = { subdir: true, ...options };
|
50 | const subdir = typeof options.subdir === 'string' ? options.subdir : '.';
|
51 | if (options.subdir !== true) {
|
52 | this._path = (0, path_1.resolve)(rootPath, subdir);
|
53 | }
|
54 | else {
|
55 | // Create a unique temporary directory under the root path
|
56 | // See https://nodejs.org/api/fs.html#fs_fs_mkdtempsync_prefix_options
|
57 | this._path = (0, fs_extra_1.mkdtempSync)((0, path_1.join)(rootPath, `/${process.pid}`));
|
58 | }
|
59 | }
|
60 | /**
|
61 | * Resets the TestSandbox. (Remove all files in it).
|
62 | */
|
63 | async reset() {
|
64 | // Decache files from require's cache so future tests aren't affected incase
|
65 | // a file is recreated in sandbox with the same file name but different
|
66 | // contents after resetting the sandbox.
|
67 | for (const key in require.cache) {
|
68 | if (key.startsWith(this.path)) {
|
69 | delete require.cache[key];
|
70 | }
|
71 | }
|
72 | await (0, fs_extra_1.emptyDir)(this.path);
|
73 | }
|
74 | /**
|
75 | * Deletes the TestSandbox.
|
76 | */
|
77 | async delete() {
|
78 | await (0, fs_extra_1.remove)(this.path);
|
79 | delete this._path;
|
80 | }
|
81 | /**
|
82 | * Makes a directory in the TestSandbox
|
83 | *
|
84 | * @param dir - Name of directory to create (relative to TestSandbox path)
|
85 | */
|
86 | async mkdir(dir) {
|
87 | await (0, fs_extra_1.ensureDir)((0, path_1.resolve)(this.path, dir));
|
88 | }
|
89 | /**
|
90 | * Copies a file from src to the TestSandbox. If copying a `.js` file which
|
91 | * has an accompanying `.js.map` file in the src file location, the dest file
|
92 | * will have its sourceMappingURL updated to point to the original file as
|
93 | * an absolute path so you don't need to copy the map file.
|
94 | *
|
95 | * @param src - Absolute path of file to be copied to the TestSandbox
|
96 | * @param dest - Optional. Destination filename of the copy operation
|
97 | * (relative to TestSandbox). Original filename used if not specified.
|
98 | * @param transform - Optional. A function to transform the file content.
|
99 | */
|
100 | async copyFile(src, dest, transform) {
|
101 | dest = dest
|
102 | ? (0, path_1.resolve)(this.path, dest)
|
103 | : (0, path_1.resolve)(this.path, (0, path_1.parse)(src).base);
|
104 | if (transform == null) {
|
105 | await (0, fs_extra_1.copy)(src, dest);
|
106 | }
|
107 | else {
|
108 | let content = await (0, fs_extra_1.readFile)(src, 'utf-8');
|
109 | content = transform(content);
|
110 | await (0, fs_extra_1.outputFile)(dest, content, { encoding: 'utf-8' });
|
111 | }
|
112 | if ((0, path_1.parse)(src).ext === '.js' && (await (0, fs_extra_1.pathExists)(src + '.map'))) {
|
113 | const srcMap = src + '.map';
|
114 | await (0, fs_extra_1.appendFile)(dest, `\n//# sourceMappingURL=${srcMap}`);
|
115 | }
|
116 | }
|
117 | /**
|
118 | * Creates a new file and writes the given data serialized as JSON.
|
119 | *
|
120 | * @param dest - Destination filename, optionally including a relative path.
|
121 | * @param data - The data to write.
|
122 | */
|
123 | async writeJsonFile(dest, data) {
|
124 | dest = (0, path_1.resolve)(this.path, dest);
|
125 | return (0, fs_extra_1.outputJson)(dest, data, { spaces: 2 });
|
126 | }
|
127 | /**
|
128 | * Creates a new file and writes the given data as a UTF-8-encoded text.
|
129 | *
|
130 | * @param dest - Destination filename, optionally including a relative path.
|
131 | * @param data - The text to write.
|
132 | */
|
133 | async writeTextFile(dest, data) {
|
134 | dest = (0, path_1.resolve)(this.path, dest);
|
135 | return (0, fs_extra_1.outputFile)(dest, data, 'utf-8');
|
136 | }
|
137 | }
|
138 | exports.TestSandbox = TestSandbox;
|
139 | //# sourceMappingURL=test-sandbox.js.map |
\ | No newline at end of file |