@@ -38,6 +38,30 @@ function nextdir() {
38
38
assertDirEquivalent ( src , dest ) ;
39
39
}
40
40
41
+ // It copies a nested folder structure with mode flags.
42
+ // This test is based on fs.promises.copyFile() with `COPYFILE_FICLONE_FORCE`.
43
+ ( ( ) => {
44
+ const src = './test/fixtures/copy/kitchen-sink' ;
45
+ const dest = nextdir ( ) ;
46
+ try {
47
+ cpSync ( src , dest , mustNotMutateObjectDeep ( {
48
+ recursive : true ,
49
+ mode : fs . constants . COPYFILE_FICLONE_FORCE ,
50
+ } ) ) ;
51
+ } catch ( err ) {
52
+ // If the platform does not support `COPYFILE_FICLONE_FORCE` operation,
53
+ // it should enter this path.
54
+ assert . strictEqual ( err . syscall , 'copyfile' ) ;
55
+ assert ( err . code === 'ENOTSUP' || err . code === 'ENOTTY' ||
56
+ err . code === 'ENOSYS' || err . code === 'EXDEV' ) ;
57
+ return ;
58
+ }
59
+
60
+ // If the platform support `COPYFILE_FICLONE_FORCE` operation,
61
+ // it should reach to here.
62
+ assertDirEquivalent ( src , dest ) ;
63
+ } ) ( ) ;
64
+
41
65
// It does not throw errors when directory is copied over and force is false.
42
66
{
43
67
const src = nextdir ( ) ;
@@ -107,6 +131,14 @@ function nextdir() {
107
131
} ) ;
108
132
}
109
133
134
+ // It rejects if options.mode is invalid.
135
+ {
136
+ assert . throws (
137
+ ( ) => cpSync ( 'a' , 'b' , { mode : - 1 } ) ,
138
+ { code : 'ERR_OUT_OF_RANGE' }
139
+ ) ;
140
+ }
141
+
110
142
111
143
// It throws an error when both dereference and verbatimSymlinks are enabled.
112
144
{
@@ -425,6 +457,31 @@ if (!isWindows) {
425
457
} ) ) ;
426
458
}
427
459
460
+ // It copies a nested folder structure with mode flags.
461
+ // This test is based on fs.promises.copyFile() with `COPYFILE_FICLONE_FORCE`.
462
+ {
463
+ const src = './test/fixtures/copy/kitchen-sink' ;
464
+ const dest = nextdir ( ) ;
465
+ cp ( src , dest , mustNotMutateObjectDeep ( {
466
+ recursive : true ,
467
+ mode : fs . constants . COPYFILE_FICLONE_FORCE ,
468
+ } ) , mustCall ( ( err ) => {
469
+ if ( ! err ) {
470
+ // If the platform support `COPYFILE_FICLONE_FORCE` operation,
471
+ // it should reach to here.
472
+ assert . strictEqual ( err , null ) ;
473
+ assertDirEquivalent ( src , dest ) ;
474
+ return ;
475
+ }
476
+
477
+ // If the platform does not support `COPYFILE_FICLONE_FORCE` operation,
478
+ // it should enter this path.
479
+ assert . strictEqual ( err . syscall , 'copyfile' ) ;
480
+ assert ( err . code === 'ENOTSUP' || err . code === 'ENOTTY' ||
481
+ err . code === 'ENOSYS' || err . code === 'EXDEV' ) ;
482
+ } ) ) ;
483
+ }
484
+
428
485
// It does not throw errors when directory is copied over and force is false.
429
486
{
430
487
const src = nextdir ( ) ;
@@ -799,6 +856,14 @@ if (!isWindows) {
799
856
) ;
800
857
}
801
858
859
+ // It throws if options is not object.
860
+ {
861
+ assert . throws (
862
+ ( ) => cp ( 'a' , 'b' , { mode : - 1 } , ( ) => { } ) ,
863
+ { code : 'ERR_OUT_OF_RANGE' }
864
+ ) ;
865
+ }
866
+
802
867
// Promises implementation of copy.
803
868
804
869
// It copies a nested folder structure with files and folders.
@@ -810,6 +875,35 @@ if (!isWindows) {
810
875
assertDirEquivalent ( src , dest ) ;
811
876
}
812
877
878
+ // It copies a nested folder structure with mode flags.
879
+ // This test is based on fs.promises.copyFile() with `COPYFILE_FICLONE_FORCE`.
880
+ {
881
+ const src = './test/fixtures/copy/kitchen-sink' ;
882
+ const dest = nextdir ( ) ;
883
+ let p = null ;
884
+ let successFiClone = false ;
885
+ try {
886
+ p = await fs . promises . cp ( src , dest , mustNotMutateObjectDeep ( {
887
+ recursive : true ,
888
+ mode : fs . constants . COPYFILE_FICLONE_FORCE ,
889
+ } ) ) ;
890
+ successFiClone = true ;
891
+ } catch ( err ) {
892
+ // If the platform does not support `COPYFILE_FICLONE_FORCE` operation,
893
+ // it should enter this path.
894
+ assert . strictEqual ( err . syscall , 'copyfile' ) ;
895
+ assert ( err . code === 'ENOTSUP' || err . code === 'ENOTTY' ||
896
+ err . code === 'ENOSYS' || err . code === 'EXDEV' ) ;
897
+ }
898
+
899
+ if ( successFiClone ) {
900
+ // If the platform support `COPYFILE_FICLONE_FORCE` operation,
901
+ // it should reach to here.
902
+ assert . strictEqual ( p , undefined ) ;
903
+ assertDirEquivalent ( src , dest ) ;
904
+ }
905
+ }
906
+
813
907
// It accepts file URL as src and dest.
814
908
{
815
909
const src = './test/fixtures/copy/kitchen-sink' ;
@@ -847,6 +941,16 @@ if (!isWindows) {
847
941
) ;
848
942
}
849
943
944
+ // It rejects if options.mode is invalid.
945
+ {
946
+ await assert . rejects (
947
+ fs . promises . cp ( 'a' , 'b' , {
948
+ mode : - 1 ,
949
+ } ) ,
950
+ { code : 'ERR_OUT_OF_RANGE' }
951
+ ) ;
952
+ }
953
+
850
954
function assertDirEquivalent ( dir1 , dir2 ) {
851
955
const dir1Entries = [ ] ;
852
956
collectEntries ( dir1 , dir1Entries ) ;
0 commit comments