1
1
import { createNodeFsMountHandler , loadNodeRuntime } from '..' ;
2
- import { ErrnoError , PHP } from '@php-wasm/universal' ;
2
+ import {
3
+ __private__dont__use ,
4
+ ErrnoError ,
5
+ FSHelpers ,
6
+ PHP ,
7
+ } from '@php-wasm/universal' ;
3
8
import { RecommendedPHPVersion } from '@wp-playground/common' ;
4
9
import path , { dirname } from 'path' ;
5
10
import fs from 'fs' ;
@@ -18,7 +23,7 @@ describe('Mounting', () => {
18
23
php . exit ( ) ;
19
24
} ) ;
20
25
21
- describe ( 'File operations' , ( ) => {
26
+ describe ( 'Test mounted file operations' , ( ) => {
22
27
it ( 'Should mount a file with exact content match' , async ( ) => {
23
28
const testFilePath = path . join (
24
29
__dirname ,
@@ -193,7 +198,7 @@ describe('Mounting', () => {
193
198
} ) ;
194
199
} ) ;
195
200
196
- describe ( 'Directory operations' , ( ) => {
201
+ describe ( 'Test mounted directory operations' , ( ) => {
197
202
it ( 'Should mount nested directories with recursive structure matching' , async ( ) => {
198
203
const testDataPath = path . join ( __dirname , 'test-data' ) ;
199
204
await php . mount (
@@ -243,6 +248,227 @@ describe('Mounting', () => {
243
248
}
244
249
} ) ;
245
250
251
+ it ( 'Should throw an error when mounting to an existing directory' , async ( ) => {
252
+ const testDataPath = path . join ( __dirname , 'test-data' ) ;
253
+ await php . mount (
254
+ '/nested-test' ,
255
+ createNodeFsMountHandler ( testDataPath )
256
+ ) ;
257
+
258
+ try {
259
+ await php . mount (
260
+ '/nested-test' ,
261
+ createNodeFsMountHandler ( testDataPath )
262
+ ) ;
263
+ } catch ( e : any ) {
264
+ e = e as ErrnoError ;
265
+ expect ( e . name ) . toBe ( 'ErrnoError' ) ;
266
+ expect ( e . errno ) . toBe ( 10 ) ;
267
+ }
268
+ } ) ;
269
+
270
+ describe ( 'Should be editable' , async ( ) => {
271
+ it ( 'Should add a new directory' , async ( ) => {
272
+ const testDataPath = path . join ( __dirname , 'test-data' ) ;
273
+ await php . mount (
274
+ '/nested-test' ,
275
+ createNodeFsMountHandler ( testDataPath )
276
+ ) ;
277
+
278
+ await php . mkdir ( '/nested-test/new-dir' ) ;
279
+ expect ( php . isDir ( '/nested-test/new-dir' ) ) . toBe ( true ) ;
280
+
281
+ await php . rmdir ( '/nested-test/new-dir' ) ;
282
+ expect ( php . isDir ( '/nested-test/new-dir' ) ) . toBe ( false ) ;
283
+ } ) ;
284
+
285
+ it ( 'Should move a directory' , async ( ) => {
286
+ const testDataPath = path . join ( __dirname , 'test-data' ) ;
287
+ await php . mount (
288
+ '/nested-test' ,
289
+ createNodeFsMountHandler ( testDataPath )
290
+ ) ;
291
+
292
+ await php . mv (
293
+ '/nested-test/nested-symlinked-folder' ,
294
+ '/nested-test/new-dir'
295
+ ) ;
296
+ expect ( php . isDir ( '/nested-test/new-dir' ) ) . toBe ( true ) ;
297
+ expect ( php . isDir ( '/nested-test/nested-symlinked-folder' ) ) . toBe (
298
+ false
299
+ ) ;
300
+
301
+ await php . mv (
302
+ '/nested-test/new-dir' ,
303
+ '/nested-test/nested-symlinked-folder'
304
+ ) ;
305
+ expect ( php . isDir ( '/nested-test/new-dir' ) ) . toBe ( false ) ;
306
+ expect ( php . isDir ( '/nested-test/nested-symlinked-folder' ) ) . toBe (
307
+ true
308
+ ) ;
309
+ } ) ;
310
+
311
+ it ( 'Should remove a directory' , async ( ) => {
312
+ const testDataPath = path . join ( __dirname , 'test-data' ) ;
313
+ await php . mount (
314
+ '/nested-test' ,
315
+ createNodeFsMountHandler ( testDataPath )
316
+ ) ;
317
+
318
+ const backupDir = path . join (
319
+ __dirname ,
320
+ 'test-data' ,
321
+ 'backup-nested-test'
322
+ ) ;
323
+ await php . mkdir ( backupDir ) ;
324
+ await FSHelpers . copyRecursive (
325
+ php [ __private__dont__use ] . FS ,
326
+ '/nested-test/nested-symlinked-folder' ,
327
+ backupDir
328
+ ) ;
329
+
330
+ await php . rmdir ( '/nested-test/nested-symlinked-folder' ) ;
331
+ expect ( php . isDir ( '/nested-test/nested-symlinked-folder' ) ) . toBe (
332
+ false
333
+ ) ;
334
+
335
+ await FSHelpers . copyRecursive (
336
+ php [ __private__dont__use ] . FS ,
337
+ backupDir ,
338
+ '/nested-test/nested-symlinked-folder'
339
+ ) ;
340
+ expect ( php . isDir ( '/nested-test/nested-symlinked-folder' ) ) . toBe (
341
+ true
342
+ ) ;
343
+ } ) ;
344
+
345
+ it ( 'Should add a new file' , async ( ) => {
346
+ const testDataPath = path . join ( __dirname , 'test-data' ) ;
347
+ await php . mount (
348
+ '/nested-test' ,
349
+ createNodeFsMountHandler ( testDataPath )
350
+ ) ;
351
+
352
+ await php . writeFile (
353
+ '/nested-test/nested-symlinked-folder/new-file.txt' ,
354
+ 'new file content'
355
+ ) ;
356
+
357
+ expect (
358
+ await php . readFileAsText (
359
+ '/nested-test/nested-symlinked-folder/new-file.txt'
360
+ )
361
+ ) . toBe ( 'new file content' ) ;
362
+
363
+ await php . unlink (
364
+ '/nested-test/nested-symlinked-folder/new-file.txt'
365
+ ) ;
366
+ expect (
367
+ php . isFile (
368
+ '/nested-test/nested-symlinked-folder/new-file.txt'
369
+ )
370
+ ) . toBe ( false ) ;
371
+ } ) ;
372
+
373
+ it ( 'Should edit a file' , async ( ) => {
374
+ const testDataPath = path . join ( __dirname , 'test-data' ) ;
375
+ await php . mount (
376
+ '/nested-test' ,
377
+ createNodeFsMountHandler ( testDataPath )
378
+ ) ;
379
+
380
+ const fileContent = await php . readFileAsText (
381
+ '/nested-test/nested-symlinked-folder/nested-document.txt'
382
+ ) ;
383
+
384
+ await php . writeFile (
385
+ '/nested-test/nested-symlinked-folder/nested-document.txt' ,
386
+ 'new file content'
387
+ ) ;
388
+
389
+ expect (
390
+ await php . readFileAsText (
391
+ '/nested-test/nested-symlinked-folder/nested-document.txt'
392
+ )
393
+ ) . toBe ( 'new file content' ) ;
394
+
395
+ await php . writeFile (
396
+ '/nested-test/nested-symlinked-folder/nested-document.txt' ,
397
+ fileContent
398
+ ) ;
399
+ expect (
400
+ await php . readFileAsText (
401
+ '/nested-test/nested-symlinked-folder/nested-document.txt'
402
+ )
403
+ ) . toBe ( fileContent ) ;
404
+ } ) ;
405
+
406
+ it ( 'Should delete a file' , async ( ) => {
407
+ const testDataPath = path . join ( __dirname , 'test-data' ) ;
408
+ await php . mount (
409
+ '/nested-test' ,
410
+ createNodeFsMountHandler ( testDataPath )
411
+ ) ;
412
+
413
+ const fileContent = await php . readFileAsText (
414
+ '/nested-test/nested-symlinked-folder/nested-document.txt'
415
+ ) ;
416
+
417
+ await php . unlink (
418
+ '/nested-test/nested-symlinked-folder/nested-document.txt'
419
+ ) ;
420
+ expect (
421
+ php . isFile (
422
+ '/nested-test/nested-symlinked-folder/nested-document.txt'
423
+ )
424
+ ) . toBe ( false ) ;
425
+
426
+ await php . writeFile (
427
+ '/nested-test/nested-symlinked-folder/nested-document.txt' ,
428
+ fileContent
429
+ ) ;
430
+ expect (
431
+ await php . readFileAsText (
432
+ '/nested-test/nested-symlinked-folder/nested-document.txt'
433
+ )
434
+ ) . toBe ( fileContent ) ;
435
+ } ) ;
436
+ } ) ;
437
+
438
+ it ( 'Should not be deletable' , async ( ) => {
439
+ const testDataPath = path . join ( __dirname , 'test-data' ) ;
440
+ await php . mount (
441
+ '/nested-test' ,
442
+ createNodeFsMountHandler ( testDataPath )
443
+ ) ;
444
+
445
+ try {
446
+ await php . rmdir ( '/nested-test' ) ;
447
+ } catch ( e : any ) {
448
+ e = e as Error ;
449
+ expect ( e . message ) . toContain (
450
+ 'Could not remove directory "/nested-test": Device or resource busy.'
451
+ ) ;
452
+ }
453
+ } ) ;
454
+
455
+ it ( 'Should not be movable' , async ( ) => {
456
+ const testDataPath = path . join ( __dirname , 'test-data' ) ;
457
+ await php . mount (
458
+ '/nested-test' ,
459
+ createNodeFsMountHandler ( testDataPath )
460
+ ) ;
461
+
462
+ try {
463
+ await php . mv ( '/nested-test' , '/nested-test-moved' ) ;
464
+ } catch ( e : any ) {
465
+ e = e as Error ;
466
+ expect ( e . message ) . toContain (
467
+ 'Could not move /nested-test to /nested-test-moved: Device or resource busy.'
468
+ ) ;
469
+ }
470
+ } ) ;
471
+
246
472
it ( 'Should unmount a directory and remove created node from VFS' , async ( ) => {
247
473
const testDataPath = path . join ( __dirname , 'test-data' ) ;
248
474
const unmount = await php . mount (
@@ -270,5 +496,21 @@ describe('Mounting', () => {
270
496
await unmount ( ) ;
271
497
expect ( php . isDir ( '/nested-test' ) ) . toBe ( true ) ;
272
498
} ) ;
499
+
500
+ it ( 'Should remount after unmounting' , async ( ) => {
501
+ const testDataPath = path . join ( __dirname , 'test-data' ) ;
502
+ const unmount = await php . mount (
503
+ '/nested-test' ,
504
+ createNodeFsMountHandler ( testDataPath )
505
+ ) ;
506
+
507
+ await unmount ( ) ;
508
+ await php . mount (
509
+ '/nested-test' ,
510
+ createNodeFsMountHandler ( testDataPath )
511
+ ) ;
512
+
513
+ expect ( php . isDir ( '/nested-test' ) ) . toBe ( true ) ;
514
+ } ) ;
273
515
} ) ;
274
516
} ) ;
0 commit comments