Skip to content
This repository was archived by the owner on Jul 9, 2025. It is now read-only.

Commit 0620240

Browse files
a-sullymoz-wptsync-bot
authored andcommitted
Bug 1720816 [wpt PR 29686] - Add FileSystemHandle::move() and FileSystemHandle::rename() methods, a=testonly
Automatic update from web-platform-tests Add FileSystemHandle::move() and FileSystemHandle::rename() methods Currently, it is not possible to move or rename a file or directory without creating a new file/directory, copying over data (recursively, in the case of a directory), and removing the original. This CL allows for the atomic moving of a file or directory on the local file system without needing to duplicate data. Moves to non-local file systems will are not guaranteed to be atomic and will involve duplicating data. PR: WICG/file-system-access#317 Bug: 1140805 Change-Id: I774ed1d9616249b6ecc80783db48a7bfee915aab Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2984739 Commit-Queue: Austin Sullivan <[email protected]> Reviewed-by: Daniel Cheng <[email protected]> Reviewed-by: Victor Costan <[email protected]> Reviewed-by: Marijn Kruisselbrink <[email protected]> Cr-Commit-Position: refs/heads/main@{#919810} -- wpt-commits: 72023078617ed82a4c707c7966fffe42b0f0e66a wpt-pr: 29686
1 parent 013bf8a commit 0620240

File tree

3 files changed

+317
-0
lines changed

3 files changed

+317
-0
lines changed
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<!doctype html>
2+
<meta charset=utf-8>
3+
4+
<script src="/resources/testharness.js"></script>
5+
<script src="/resources/testharnessreport.js"></script>
6+
<script src="/resources/testdriver.js"></script>
7+
<script src="/resources/testdriver-vendor.js"></script>
8+
<script src="resources/test-helpers.js"></script>
9+
<script src="resources/local-fs-test-helpers.js"></script>
10+
<script src="script-tests/FileSystemBaseHandle-move.js"></script>
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
// META: script=resources/test-helpers.js
2+
// META: script=resources/sandboxed-fs-test-helpers.js
3+
// META: script=script-tests/FileSystemBaseHandle-move.js
Lines changed: 304 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,304 @@
1+
// META: script=resources/test-helpers.js
2+
3+
'use strict';
4+
5+
directory_test(async (t, root) => {
6+
const handle = await createFileWithContents(t, 'file-before', 'foo', root);
7+
await handle.move(root, 'file-after');
8+
9+
assert_array_equals(await getSortedDirectoryEntries(root), ['file-after']);
10+
assert_equals(await getFileContents(handle), 'foo');
11+
assert_equals(await getFileSize(handle), 3);
12+
}, 'move(dir, name) to rename a file');
13+
14+
directory_test(async (t, root) => {
15+
const handle = await createFileWithContents(t, 'file-before', 'foo', root);
16+
await handle.move(root, 'file-before');
17+
18+
assert_array_equals(await getSortedDirectoryEntries(root), ['file-before']);
19+
assert_equals(await getFileContents(handle), 'foo');
20+
assert_equals(await getFileSize(handle), 3);
21+
}, 'move(dir, name) to rename a file the same name');
22+
23+
directory_test(async (t, root) => {
24+
const dir = await root.getDirectoryHandle('dir-before', {create: true});
25+
await dir.move(root, 'dir-after');
26+
27+
assert_array_equals(await getSortedDirectoryEntries(root), ['dir-after/']);
28+
assert_array_equals(await getSortedDirectoryEntries(dir), []);
29+
}, 'move(dir, name) to rename an empty directory');
30+
31+
directory_test(async (t, root) => {
32+
const dir = await root.getDirectoryHandle('dir-before', {create: true});
33+
await createFileWithContents(t, 'file-in-dir', 'abc', dir);
34+
await dir.move(root, 'dir-after');
35+
36+
assert_array_equals(await getSortedDirectoryEntries(root), ['dir-after/']);
37+
assert_array_equals(await getSortedDirectoryEntries(dir), ['file-in-dir']);
38+
}, 'move(dir, name) to rename a non-empty directory');
39+
40+
directory_test(async (t, root) => {
41+
const dir_src = await root.getDirectoryHandle('dir-src', {create: true});
42+
const dir_dest = await root.getDirectoryHandle('dir-dest', {create: true});
43+
const file = await createFileWithContents(t, 'file', 'abc', dir_src);
44+
await file.move(dir_dest);
45+
46+
assert_array_equals(
47+
await getSortedDirectoryEntries(root), ['dir-dest/', 'dir-src/']);
48+
assert_array_equals(await getSortedDirectoryEntries(dir_src), []);
49+
assert_array_equals(await getSortedDirectoryEntries(dir_dest), ['file']);
50+
assert_equals(await getFileContents(file), 'abc');
51+
assert_equals(await getFileSize(file), 3);
52+
}, 'move(dir) to move a file to a new directory');
53+
54+
directory_test(async (t, root) => {
55+
const dir_src = await root.getDirectoryHandle('dir-src', {create: true});
56+
const dir_dest = await root.getDirectoryHandle('dir-dest', {create: true});
57+
const file = await createFileWithContents(t, 'file', 'abc', dir_src);
58+
await file.move(dir_dest, '');
59+
60+
assert_array_equals(
61+
await getSortedDirectoryEntries(root), ['dir-dest/', 'dir-src/']);
62+
assert_array_equals(await getSortedDirectoryEntries(dir_src), []);
63+
assert_array_equals(await getSortedDirectoryEntries(dir_dest), ['file']);
64+
assert_equals(await getFileContents(file), 'abc');
65+
assert_equals(await getFileSize(file), 3);
66+
}, 'move(dir, "") to move a file to a new directory');
67+
68+
directory_test(async (t, root) => {
69+
const dir_src = await root.getDirectoryHandle('dir-src', {create: true});
70+
const dir_dest = await root.getDirectoryHandle('dir-dest', {create: true});
71+
const file =
72+
await createFileWithContents(t, 'file-in-dir-src', 'abc', dir_src);
73+
await file.move(dir_dest, 'file-in-dir-dest');
74+
75+
assert_array_equals(
76+
await getSortedDirectoryEntries(root), ['dir-dest/', 'dir-src/']);
77+
assert_array_equals(await getSortedDirectoryEntries(dir_src), []);
78+
assert_array_equals(
79+
await getSortedDirectoryEntries(dir_dest), ['file-in-dir-dest']);
80+
assert_equals(await getFileContents(file), 'abc');
81+
assert_equals(await getFileSize(file), 3);
82+
}, 'move(dir, name) to move a file to a new directory');
83+
84+
directory_test(async (t, root) => {
85+
const dir_src = await root.getDirectoryHandle('dir-src', {create: true});
86+
const dir_dest = await root.getDirectoryHandle('dir-dest', {create: true});
87+
const dir_in_dir =
88+
await dir_src.getDirectoryHandle('dir-in-dir', {create: true});
89+
await dir_in_dir.move(dir_dest);
90+
91+
assert_array_equals(
92+
await getSortedDirectoryEntries(root), ['dir-dest/', 'dir-src/']);
93+
assert_array_equals(await getSortedDirectoryEntries(dir_src), []);
94+
assert_array_equals(
95+
await getSortedDirectoryEntries(dir_dest), ['dir-in-dir/']);
96+
assert_array_equals(await getSortedDirectoryEntries(dir_in_dir), []);
97+
}, 'move(dir) to move an empty directory to a new directory');
98+
99+
directory_test(async (t, root) => {
100+
const dir_src = await root.getDirectoryHandle('dir-src', {create: true});
101+
const dir_dest = await root.getDirectoryHandle('dir-dest', {create: true});
102+
const dir_in_dir =
103+
await dir_src.getDirectoryHandle('dir-in-dir', {create: true});
104+
await dir_in_dir.move(dir_dest, "");
105+
106+
assert_array_equals(
107+
await getSortedDirectoryEntries(root), ['dir-dest/', 'dir-src/']);
108+
assert_array_equals(await getSortedDirectoryEntries(dir_src), []);
109+
assert_array_equals(
110+
await getSortedDirectoryEntries(dir_dest), ['dir-in-dir/']);
111+
assert_array_equals(await getSortedDirectoryEntries(dir_in_dir), []);
112+
}, 'move(dir, "") to move an empty directory to a new directory');
113+
114+
directory_test(async (t, root) => {
115+
const dir_src = await root.getDirectoryHandle('dir-src', {create: true});
116+
const dir_dest = await root.getDirectoryHandle('dir-dest', {create: true});
117+
const dir_in_dir =
118+
await dir_src.getDirectoryHandle('dir-in-dir', {create: true});
119+
await dir_in_dir.move(dir_dest, 'dir-in-dir');
120+
121+
assert_array_equals(
122+
await getSortedDirectoryEntries(root), ['dir-dest/', 'dir-src/']);
123+
assert_array_equals(await getSortedDirectoryEntries(dir_src), []);
124+
assert_array_equals(
125+
await getSortedDirectoryEntries(dir_dest), ['dir-in-dir/']);
126+
assert_array_equals(await getSortedDirectoryEntries(dir_in_dir), []);
127+
}, 'move(dir, name) to move an empty directory to a new directory');
128+
129+
directory_test(async (t, root) => {
130+
const dir_src = await root.getDirectoryHandle('dir-src', {create: true});
131+
const dir_dest = await root.getDirectoryHandle('dir-dest', {create: true});
132+
const dir_in_dir =
133+
await dir_src.getDirectoryHandle('dir-in-dir', {create: true});
134+
const file =
135+
await createFileWithContents(t, 'file-in-dir', 'abc', dir_in_dir);
136+
await dir_in_dir.move(dir_dest, "");
137+
138+
assert_array_equals(
139+
await getSortedDirectoryEntries(root), ['dir-dest/', 'dir-src/']);
140+
assert_array_equals(await getSortedDirectoryEntries(dir_src), []);
141+
assert_array_equals(
142+
await getSortedDirectoryEntries(dir_dest), ['dir-in-dir/']);
143+
assert_array_equals(
144+
await getSortedDirectoryEntries(dir_in_dir), ['file-in-dir']);
145+
// `file` should be invalidated after moving directories.
146+
await promise_rejects_dom(t, 'NotFoundError', getFileContents(file));
147+
}, 'move(dir, "") to move a non-empty directory to a new directory');
148+
149+
directory_test(async (t, root) => {
150+
const dir_src = await root.getDirectoryHandle('dir-src', {create: true});
151+
const dir_dest = await root.getDirectoryHandle('dir-dest', {create: true});
152+
const dir_in_dir =
153+
await dir_src.getDirectoryHandle('dir-in-dir', {create: true});
154+
const file =
155+
await createFileWithContents(t, 'file-in-dir', 'abc', dir_in_dir);
156+
await dir_in_dir.move(dir_dest, 'dir-in-dir');
157+
158+
assert_array_equals(
159+
await getSortedDirectoryEntries(root), ['dir-dest/', 'dir-src/']);
160+
assert_array_equals(await getSortedDirectoryEntries(dir_src), []);
161+
assert_array_equals(
162+
await getSortedDirectoryEntries(dir_dest), ['dir-in-dir/']);
163+
assert_array_equals(
164+
await getSortedDirectoryEntries(dir_in_dir), ['file-in-dir']);
165+
// `file` should be invalidated after moving directories.
166+
await promise_rejects_dom(t, 'NotFoundError', getFileContents(file));
167+
}, 'move(dir, name) to move a non-empty directory to a new directory');
168+
169+
directory_test(async (t, root) => {
170+
const dir1 = await root.getDirectoryHandle('dir1', {create: true});
171+
const dir2 = await root.getDirectoryHandle('dir2', {create: true});
172+
const handle = await createFileWithContents(t, 'file', 'foo', root);
173+
174+
await handle.move(dir1);
175+
assert_array_equals(
176+
await getSortedDirectoryEntries(root), ['dir1/', 'dir2/']);
177+
assert_array_equals(await getSortedDirectoryEntries(dir1), ['file']);
178+
assert_array_equals(await getSortedDirectoryEntries(dir2), []);
179+
assert_equals(await getFileContents(handle), 'foo');
180+
181+
await handle.move(dir2);
182+
assert_array_equals(
183+
await getSortedDirectoryEntries(root), ['dir1/', 'dir2/']);
184+
assert_array_equals(await getSortedDirectoryEntries(dir1), []);
185+
assert_array_equals(await getSortedDirectoryEntries(dir2), ['file']);
186+
assert_equals(await getFileContents(handle), 'foo');
187+
188+
await handle.move(root);
189+
assert_array_equals(
190+
await getSortedDirectoryEntries(root), ['dir1/', 'dir2/', 'file']);
191+
assert_array_equals(await getSortedDirectoryEntries(dir1), []);
192+
assert_array_equals(await getSortedDirectoryEntries(dir2), []);
193+
assert_equals(await getFileContents(handle), 'foo');
194+
}, 'move(dir) can be called multiple times');
195+
196+
directory_test(async (t, root) => {
197+
const dir1 = await root.getDirectoryHandle('dir1', {create: true});
198+
const dir2 = await root.getDirectoryHandle('dir2', {create: true});
199+
const handle = await createFileWithContents(t, 'file', 'foo', root);
200+
201+
await handle.move(dir1, "");
202+
assert_array_equals(
203+
await getSortedDirectoryEntries(root), ['dir1/', 'dir2/']);
204+
assert_array_equals(await getSortedDirectoryEntries(dir1), ['file']);
205+
assert_array_equals(await getSortedDirectoryEntries(dir2), []);
206+
assert_equals(await getFileContents(handle), 'foo');
207+
208+
await handle.move(dir2, "");
209+
assert_array_equals(
210+
await getSortedDirectoryEntries(root), ['dir1/', 'dir2/']);
211+
assert_array_equals(await getSortedDirectoryEntries(dir1), []);
212+
assert_array_equals(await getSortedDirectoryEntries(dir2), ['file']);
213+
assert_equals(await getFileContents(handle), 'foo');
214+
215+
await handle.move(root, "");
216+
assert_array_equals(
217+
await getSortedDirectoryEntries(root), ['dir1/', 'dir2/', 'file']);
218+
assert_array_equals(await getSortedDirectoryEntries(dir1), []);
219+
assert_array_equals(await getSortedDirectoryEntries(dir2), []);
220+
assert_equals(await getFileContents(handle), 'foo');
221+
}, 'move(dir, "") can be called multiple times');
222+
223+
directory_test(async (t, root) => {
224+
const dir1 = await root.getDirectoryHandle('dir1', {create: true});
225+
const dir2 = await root.getDirectoryHandle('dir2', {create: true});
226+
const handle = await createFileWithContents(t, 'file', 'foo', root);
227+
228+
await handle.move(dir1, 'file-1');
229+
assert_array_equals(
230+
await getSortedDirectoryEntries(root), ['dir1/', 'dir2/']);
231+
assert_array_equals(await getSortedDirectoryEntries(dir1), ['file-1']);
232+
assert_array_equals(await getSortedDirectoryEntries(dir2), []);
233+
assert_equals(await getFileContents(handle), 'foo');
234+
235+
await handle.move(dir2, 'file-2');
236+
assert_array_equals(
237+
await getSortedDirectoryEntries(root), ['dir1/', 'dir2/']);
238+
assert_array_equals(await getSortedDirectoryEntries(dir1), []);
239+
assert_array_equals(await getSortedDirectoryEntries(dir2), ['file-2']);
240+
assert_equals(await getFileContents(handle), 'foo');
241+
242+
await handle.move(root, 'file-3');
243+
assert_array_equals(
244+
await getSortedDirectoryEntries(root), ['dir1/', 'dir2/', 'file-3']);
245+
assert_array_equals(await getSortedDirectoryEntries(dir1), []);
246+
assert_array_equals(await getSortedDirectoryEntries(dir2), []);
247+
assert_equals(await getFileContents(handle), 'foo');
248+
}, 'move(dir, name) can be called multiple times');
249+
250+
directory_test(async (t, root) => {
251+
const handle = await createFileWithContents(t, 'file-before', 'foo', root);
252+
await promise_rejects_js(
253+
t, TypeError, handle.move(root, '#$23423@352^*3243'));
254+
255+
assert_array_equals(await getSortedDirectoryEntries(root), ['file-before']);
256+
assert_equals(await getFileContents(handle), 'foo');
257+
assert_equals(await getFileSize(handle), 3);
258+
}, 'move(dir, name) with a name with invalid characters should fail');
259+
260+
directory_test(async (t, root) => {
261+
const dir = await root.getDirectoryHandle('dir', {create: true});
262+
await promise_rejects_dom(
263+
t, 'InvalidModificationError', dir.move(dir));
264+
265+
assert_array_equals(await getSortedDirectoryEntries(root), ['dir/']);
266+
assert_array_equals(await getSortedDirectoryEntries(dir), []);
267+
}, 'move(dir, name) to move a directory within itself fails');
268+
269+
directory_test(async (t, root) => {
270+
const dir = await root.getDirectoryHandle('dir', {create: true});
271+
await promise_rejects_dom(
272+
t, 'InvalidModificationError', dir.move(dir, 'dir-fail'));
273+
274+
assert_array_equals(await getSortedDirectoryEntries(root), ['dir/']);
275+
assert_array_equals(await getSortedDirectoryEntries(dir), []);
276+
}, 'move(dir, name) to move a directory within itself and rename fails');
277+
278+
directory_test(async (t, root) => {
279+
const parent_dir =
280+
await root.getDirectoryHandle('parent-dir', {create: true});
281+
const child_dir =
282+
await parent_dir.getDirectoryHandle('child-dir', {create: true});
283+
await promise_rejects_dom(
284+
t, 'InvalidModificationError', parent_dir.move(child_dir));
285+
286+
assert_array_equals(await getSortedDirectoryEntries(root), ['parent-dir/']);
287+
assert_array_equals(
288+
await getSortedDirectoryEntries(parent_dir), ['child-dir/']);
289+
assert_array_equals(await getSortedDirectoryEntries(child_dir), []);
290+
}, 'move(dir) to move a directory within a descendent fails');
291+
292+
directory_test(async (t, root) => {
293+
const parent_dir =
294+
await root.getDirectoryHandle('parent-dir', {create: true});
295+
const child_dir =
296+
await parent_dir.getDirectoryHandle('child-dir', {create: true});
297+
await promise_rejects_dom(
298+
t, 'InvalidModificationError', parent_dir.move(child_dir, 'dir'));
299+
300+
assert_array_equals(await getSortedDirectoryEntries(root), ['parent-dir/']);
301+
assert_array_equals(
302+
await getSortedDirectoryEntries(parent_dir), ['child-dir/']);
303+
assert_array_equals(await getSortedDirectoryEntries(child_dir), []);
304+
}, 'move(dir, name) to move a directory within a descendent fails');

0 commit comments

Comments
 (0)