UNPKG

3.02 kBPlain TextView Raw
1// Copyright IBM Corp. 2018. All Rights Reserved.
2// Node module: @loopback/testlab
3// This file is licensed under the MIT License.
4// License text available at https://opensource.org/licenses/MIT
5
6import {resolve, parse} from 'path';
7import {
8 copy,
9 ensureDirSync,
10 emptyDir,
11 remove,
12 ensureDir,
13 pathExists,
14 appendFile,
15} from 'fs-extra';
16
17/**
18 * TestSandbox class provides a convenient way to get a reference to a
19 * sandbox folder in which you can perform operations for testing purposes.
20 */
21export class TestSandbox {
22 // Path of the TestSandbox
23 private _path?: string;
24
25 public get path(): string {
26 if (!this._path) {
27 throw new Error(
28 `TestSandbox instance was deleted. Create a new instance.`,
29 );
30 }
31 return this._path;
32 }
33
34 /**
35 * Will create a directory if it doesn't already exist. If it exists, you
36 * still get an instance of the TestSandbox.
37 *
38 * @param path - Path of the TestSandbox. If relative (it will be resolved relative to cwd()).
39 */
40 constructor(path: string) {
41 // resolve ensures path is absolute / makes it absolute (relative to cwd())
42 this._path = resolve(path);
43 ensureDirSync(this.path);
44 }
45
46 /**
47 * Returns the path of the TestSandbox
48 */
49 getPath(): string {
50 return this.path;
51 }
52
53 /**
54 * Resets the TestSandbox. (Remove all files in it).
55 */
56 async reset(): Promise<void> {
57 // Decache files from require's cache so future tests aren't affected incase
58 // a file is recreated in sandbox with the same file name but different
59 // contents after resetting the sandbox.
60 for (const key in require.cache) {
61 if (key.startsWith(this.path)) {
62 delete require.cache[key];
63 }
64 }
65
66 await emptyDir(this.path);
67 }
68
69 /**
70 * Deletes the TestSandbox.
71 */
72 async delete(): Promise<void> {
73 await remove(this.path);
74 delete this._path;
75 }
76
77 /**
78 * Makes a directory in the TestSandbox
79 *
80 * @param dir - Name of directory to create (relative to TestSandbox path)
81 */
82 async mkdir(dir: string): Promise<void> {
83 await ensureDir(resolve(this.path, dir));
84 }
85
86 /**
87 * Copies a file from src to the TestSandbox. If copying a `.js` file which
88 * has an accompanying `.js.map` file in the src file location, the dest file
89 * will have its sourceMappingURL updated to point to the original file as
90 * an absolute path so you don't need to copy the map file.
91 *
92 * @param src - Absolute path of file to be copied to the TestSandbox
93 * @param dest - Optional. Destination filename of the copy operation
94 * (relative to TestSandbox). Original filename used if not specified.
95 */
96 async copyFile(src: string, dest?: string): Promise<void> {
97 dest = dest
98 ? resolve(this.path, dest)
99 : resolve(this.path, parse(src).base);
100
101 await copy(src, dest);
102
103 if (parse(src).ext === '.js' && pathExists(src + '.map')) {
104 const srcMap = src + '.map';
105 await appendFile(dest, `\n//# sourceMappingURL=${srcMap}`);
106 }
107 }
108}