1
1
'use strict' ;
2
2
3
3
const common = require ( '../common' ) ;
4
+ if ( ! common . hasCrypto ) { common . skip ( 'missing crypto' ) ; }
4
5
5
6
const assert = require ( 'assert' ) ;
7
+ const { randomUUID } = require ( 'crypto' ) ;
6
8
const fs = require ( 'fs' ) ;
7
9
const {
8
10
copy,
11
+ copySync,
9
12
lstatSync,
13
+ mkdirSync,
10
14
readdirSync,
11
- rmSync ,
15
+ symlinkSync ,
12
16
} = fs ;
17
+ const net = require ( 'net' ) ;
13
18
const { dirname, join } = require ( 'path' ) ;
14
19
20
+ const isWindows = process . platform === 'win32' ;
15
21
const tmpdir = require ( '../common/tmpdir' ) ;
16
22
tmpdir . refresh ( ) ;
17
23
@@ -22,62 +28,88 @@ function nextdir() {
22
28
23
29
// Async version of copy.
24
30
25
- // It copies a nested folder structure with files and folders.
31
+ // It copies a nested folder structure with files, folders, symlinks .
26
32
{
27
- const src = dirname ( require . resolve ( '../fixtures/copy/files-and-folders ' ) ) ;
33
+ const src = dirname ( require . resolve ( '../fixtures/copy/kitchen-sink ' ) ) ;
28
34
const dest = nextdir ( ) ;
29
35
copy ( src , dest , common . mustCall ( ( err ) => {
30
- try {
31
- assert . strictEqual ( err , null ) ;
32
- assertDirEquivalent ( src , dest ) ;
33
- } finally {
34
- rmSync ( dest , { force : true , recursive : true } ) ;
35
- }
36
+ assert . strictEqual ( err , null ) ;
37
+ assertDirEquivalent ( src , dest ) ;
36
38
} ) ) ;
37
39
}
38
40
39
- // It copies symlink if dereference is false (default value).
41
+ // It throws error if existing symlink in dest is in subdirectory src.
42
+ // TODO(bcoe): this behavior seemed strange to me, ask about it in review.
40
43
{
41
- const src = dirname ( require . resolve ( '../fixtures/copy/symlink ' ) ) ;
44
+ const src = dirname ( require . resolve ( '../fixtures/copy/kitchen-sink ' ) ) ;
42
45
const dest = nextdir ( ) ;
46
+ copySync ( src , dest ) ;
43
47
copy ( src , dest , common . mustCall ( ( err ) => {
44
- assert . strictEqual ( err , null ) ;
48
+ assert . strictEqual ( err . code , 'ERR_FS_COPY_TO_SUBDIRECTORY' ) ;
45
49
assertDirEquivalent ( src , dest ) ;
46
50
} ) ) ;
47
51
}
48
52
49
- // It copies folder symlink links to, when dereference is true.
53
+ // It does not fail if the same directory is copied to dest twice,
54
+ // when dereference is true, and overwrite true.
50
55
{
51
- const src = dirname ( require . resolve ( '../fixtures/copy/symlink ' ) ) ;
56
+ const src = dirname ( require . resolve ( '../fixtures/copy/kitchen-sink ' ) ) ;
52
57
const dest = nextdir ( ) ;
53
- const destFile = join ( dest , 'a/b/README .md' ) ;
58
+ const destFile = join ( dest , 'a/b/README2 .md' ) ;
54
59
copy ( src , dest , { dereference : true } , common . mustCall ( ( err ) => {
55
60
assert . strictEqual ( err , null ) ;
56
61
const stat = lstatSync ( destFile ) ;
57
62
assert ( stat . isFile ( ) ) ;
58
63
} ) ) ;
59
64
}
60
65
66
+ // It copies file itself, rather than symlink, when dereference is true.
67
+ {
68
+ const src = require . resolve ( '../fixtures/copy/kitchen-sink' ) ;
69
+ const dest = nextdir ( ) ;
70
+ const destFile = join ( dest , 'foo.js' ) ;
71
+ copy ( src , destFile , { dereference : true } , common . mustCall ( ( err ) => {
72
+ assert . strictEqual ( err , null ) ;
73
+ const stat = lstatSync ( destFile ) ;
74
+ assert ( stat . isFile ( ) ) ;
75
+ } ) ) ;
76
+ }
77
+
61
78
// It returns error when src and dest are identical.
62
79
{
63
- const src = dirname ( require . resolve ( '../fixtures/copy/symlink ' ) ) ;
80
+ const src = dirname ( require . resolve ( '../fixtures/copy/kitchen-sink ' ) ) ;
64
81
copy ( src , src , common . mustCall ( ( err ) => {
65
82
assert . strictEqual ( err . code , 'ERR_FS_COPY_TO_SUBDIRECTORY' ) ;
66
83
} ) ) ;
67
84
}
68
85
86
+ // It returns error if part of dest path is symlink to src.
87
+ {
88
+ const src = nextdir ( ) ;
89
+ mkdirSync ( join ( src , 'a' ) , { recursive : true } ) ;
90
+ const dest = nextdir ( ) ;
91
+ // Create symlink in dest pointing to src.
92
+ const destLink = join ( dest , 'b' ) ;
93
+ mkdirSync ( dest , { recursive : true } ) ;
94
+ symlinkSync ( src , destLink ) ;
95
+ copy ( src , join ( dest , 'b' , 'c' ) , common . mustCall ( ( err ) => {
96
+ assert . strictEqual ( err . code , 'ERR_FS_COPY_TO_SUBDIRECTORY' ) ;
97
+ } ) ) ;
98
+ }
99
+
69
100
// It returns error if attempt is made to copy directory to file.
70
101
{
71
- const src = dirname ( require . resolve ( '../fixtures/copy/symlink' ) ) ;
72
- const dest = require . resolve ( '../fixtures/copy/files-and-folders' ) ;
102
+ const src = nextdir ( ) ;
103
+ mkdirSync ( src , { recursive : true } ) ;
104
+ const dest = require . resolve ( '../fixtures/copy/kitchen-sink' ) ;
73
105
copy ( src , dest , common . mustCall ( ( err ) => {
74
106
assert . strictEqual ( err . code , 'ERR_FS_COPY_DIR_TO_NON_DIR' ) ;
75
107
} ) ) ;
76
108
}
77
109
78
110
// It allows file to be copied to a file path.
79
111
{
80
- const srcFile = require . resolve ( '../fixtures/copy/files-and-folders ' ) ;
112
+ const srcFile = require . resolve ( '../fixtures/copy/kitchen-sink ' ) ;
81
113
const destFile = join ( nextdir ( ) , 'index.js' ) ;
82
114
copy ( srcFile , destFile , { dereference : true } , common . mustCall ( ( err ) => {
83
115
assert . strictEqual ( err , null ) ;
@@ -88,24 +120,51 @@ function nextdir() {
88
120
89
121
// It returns error if attempt is made to copy file to directory.
90
122
{
91
- const src = require . resolve ( '../fixtures/copy/symlink' ) ;
92
- const dest = dirname ( require . resolve ( '../fixtures/copy/files-and-folders' ) ) ;
123
+ const src = require . resolve ( '../fixtures/copy/kitchen-sink' ) ;
124
+ const dest = nextdir ( ) ;
125
+ mkdirSync ( dest , { recursive : true } ) ;
93
126
copy ( src , dest , common . mustCall ( ( err ) => {
94
127
assert . strictEqual ( err . code , 'ERR_FS_COPY_NON_DIR_TO_DIR' ) ;
95
128
} ) ) ;
96
129
}
97
130
98
131
// It returns error if attempt is made to copy to subdirectory of self.
99
132
{
100
- const src = dirname ( require . resolve ( '../fixtures/copy/files-and-folders ' ) ) ;
133
+ const src = dirname ( require . resolve ( '../fixtures/copy/kitchen-sink ' ) ) ;
101
134
const dest = dirname (
102
- require . resolve ( '../fixtures/copy/files-and-folders/sub-folder ' )
135
+ require . resolve ( '../fixtures/copy/kitchen-sink/a ' )
103
136
) ;
104
137
copy ( src , dest , common . mustCall ( ( err ) => {
105
138
assert . strictEqual ( err . code , 'ERR_FS_COPY_TO_SUBDIRECTORY' ) ;
106
139
} ) ) ;
107
140
}
108
141
142
+ // It returns an error if attempt is made to copy socket.
143
+ {
144
+ const dest = nextdir ( ) ;
145
+ const sid = randomUUID ( ) ;
146
+ const sock = isWindows ? `\\\\.\\pipe\\${ sid } ` : `${ sid } .sock` ;
147
+ const server = net . createServer ( ) ;
148
+ server . listen ( sock ) ;
149
+ copy ( sock , dest , common . mustCall ( ( err ) => {
150
+ assert . strictEqual ( err . code , 'ERR_FS_COPY_SOCKET' ) ;
151
+ server . close ( ) ;
152
+ } ) ) ;
153
+ }
154
+
155
+ // It copies timestamps from src to dest if preserveTimestamps is true.
156
+ {
157
+ const src = dirname ( require . resolve ( '../fixtures/copy/kitchen-sink' ) ) ;
158
+ const dest = nextdir ( ) ;
159
+ copy ( src , dest , { preserveTimestamps : true } , common . mustCall ( ( err ) => {
160
+ assert . strictEqual ( err , null ) ;
161
+ assertDirEquivalent ( src , dest ) ;
162
+ const srcStat = lstatSync ( join ( src , 'index.js' ) ) ;
163
+ const destStat = lstatSync ( join ( dest , 'index.js' ) ) ;
164
+ assert . strictEqual ( srcStat . mtime . getTime ( ) , destStat . mtime . getTime ( ) ) ;
165
+ } ) ) ;
166
+ }
167
+
109
168
function assertDirEquivalent ( dir1 , dir2 ) {
110
169
const dir1Entries = [ ] ;
111
170
collectEntries ( dir1 , dir1Entries ) ;
0 commit comments