| b69ab31 | | | 1 | /** |
| b69ab31 | | | 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. |
| b69ab31 | | | 3 | * |
| b69ab31 | | | 4 | * This source code is licensed under the MIT license found in the |
| b69ab31 | | | 5 | * LICENSE file in the root directory of this source tree. |
| b69ab31 | | | 6 | */ |
| b69ab31 | | | 7 | |
| b69ab31 | | | 8 | import fs from 'node:fs'; |
| b69ab31 | | | 9 | import os from 'node:os'; |
| b69ab31 | | | 10 | import path from 'node:path'; |
| b69ab31 | | | 11 | import {exists} from 'shared/fs'; |
| b69ab31 | | | 12 | import rmtree from '../rmtree'; |
| b69ab31 | | | 13 | |
| b69ab31 | | | 14 | describe('rmtree', () => { |
| b69ab31 | | | 15 | let tmp: string; |
| b69ab31 | | | 16 | |
| b69ab31 | | | 17 | beforeEach(async () => { |
| b69ab31 | | | 18 | tmp = await fs.promises.mkdtemp(path.join(os.tmpdir(), 'rmtree-test')); |
| b69ab31 | | | 19 | }); |
| b69ab31 | | | 20 | |
| b69ab31 | | | 21 | it('does not complain about a non-existent file', async () => { |
| b69ab31 | | | 22 | await rmtree(path.join(tmp, 'foo')); |
| b69ab31 | | | 23 | }); |
| b69ab31 | | | 24 | |
| b69ab31 | | | 25 | it('removes a file', async () => { |
| b69ab31 | | | 26 | const file = path.join(tmp, 'foo'); |
| b69ab31 | | | 27 | await fs.promises.writeFile(file, 'foobar'); |
| b69ab31 | | | 28 | await rmtree(file); |
| b69ab31 | | | 29 | |
| b69ab31 | | | 30 | expect(await exists(file)).toBe(false); |
| b69ab31 | | | 31 | }); |
| b69ab31 | | | 32 | |
| b69ab31 | | | 33 | it('removes an empty folder', async () => { |
| b69ab31 | | | 34 | const folder = path.join(tmp, 'foo'); |
| b69ab31 | | | 35 | await fs.promises.mkdir(folder); |
| b69ab31 | | | 36 | await rmtree(folder); |
| b69ab31 | | | 37 | |
| b69ab31 | | | 38 | expect(await exists(folder)).toBe(false); |
| b69ab31 | | | 39 | }); |
| b69ab31 | | | 40 | |
| b69ab31 | | | 41 | it('removes a folder with files', async () => { |
| b69ab31 | | | 42 | const folder = path.join(tmp, 'foo'); |
| b69ab31 | | | 43 | await fs.promises.mkdir(folder); |
| b69ab31 | | | 44 | await fs.promises.writeFile(path.join(folder, '1'), '1'); |
| b69ab31 | | | 45 | await fs.promises.writeFile(path.join(folder, '2'), '2'); |
| b69ab31 | | | 46 | await fs.promises.writeFile(path.join(folder, '3'), '3'); |
| b69ab31 | | | 47 | await fs.promises.writeFile(path.join(folder, '4'), '4'); |
| b69ab31 | | | 48 | await rmtree(folder); |
| b69ab31 | | | 49 | |
| b69ab31 | | | 50 | expect(await exists(folder)).toBe(false); |
| b69ab31 | | | 51 | }); |
| b69ab31 | | | 52 | |
| b69ab31 | | | 53 | it('removes a deeper tree of folders and files', async () => { |
| b69ab31 | | | 54 | const folder = path.join(tmp, 'tree'); |
| b69ab31 | | | 55 | await fs.promises.mkdir(path.join(folder, '1/2/3/4/5'), {recursive: true}); |
| b69ab31 | | | 56 | await fs.promises.writeFile(path.join(folder, '1/A'), 'A'); |
| b69ab31 | | | 57 | await fs.promises.writeFile(path.join(folder, '1/2/B'), 'B'); |
| b69ab31 | | | 58 | await fs.promises.writeFile(path.join(folder, '1/2/B'), 'B'); |
| b69ab31 | | | 59 | await fs.promises.writeFile(path.join(folder, '1/2/3/C'), 'C'); |
| b69ab31 | | | 60 | await fs.promises.writeFile(path.join(folder, '1/2/3/4/D'), 'D'); |
| b69ab31 | | | 61 | await fs.promises.writeFile(path.join(folder, '1/2/3/4/5/E'), 'E'); |
| b69ab31 | | | 62 | await rmtree(folder); |
| b69ab31 | | | 63 | |
| b69ab31 | | | 64 | expect(await exists(folder)).toBe(false); |
| b69ab31 | | | 65 | }); |
| b69ab31 | | | 66 | |
| b69ab31 | | | 67 | it('does not follow argument if it is a symlink', async () => { |
| b69ab31 | | | 68 | const target = path.join(tmp, 'target'); |
| b69ab31 | | | 69 | const link = path.join(tmp, 'link'); |
| b69ab31 | | | 70 | await fs.promises.writeFile(target, 'target file'); |
| b69ab31 | | | 71 | await fs.promises.symlink(target, link); |
| b69ab31 | | | 72 | expect(await fs.promises.readFile(link, {encoding: 'utf8'})).toBe('target file'); |
| b69ab31 | | | 73 | expect(await exists(link)).toBe(true); |
| b69ab31 | | | 74 | await rmtree(link); |
| b69ab31 | | | 75 | |
| b69ab31 | | | 76 | expect(await exists(link)).toBe(false); |
| b69ab31 | | | 77 | expect(await exists(target)).toBe(true); |
| b69ab31 | | | 78 | }); |
| b69ab31 | | | 79 | |
| b69ab31 | | | 80 | it('does not follow symlink in the tree', async () => { |
| b69ab31 | | | 81 | const target = path.join(tmp, 'target'); |
| b69ab31 | | | 82 | await fs.promises.writeFile(target, 'target file'); |
| b69ab31 | | | 83 | |
| b69ab31 | | | 84 | const folder = path.join(tmp, 'folder'); |
| b69ab31 | | | 85 | await fs.promises.mkdir(folder); |
| b69ab31 | | | 86 | const link = path.join(folder, 'link'); |
| b69ab31 | | | 87 | await fs.promises.symlink(target, link); |
| b69ab31 | | | 88 | expect(await fs.promises.readFile(link, {encoding: 'utf8'})).toBe('target file'); |
| b69ab31 | | | 89 | await rmtree(folder); |
| b69ab31 | | | 90 | |
| b69ab31 | | | 91 | expect(await exists(folder)).toBe(false); |
| b69ab31 | | | 92 | expect(await exists(target)).toBe(true); |
| b69ab31 | | | 93 | }); |
| b69ab31 | | | 94 | }); |