UNPKG

4.96 kBJavaScriptView Raw
1var test = require('tape')
2var create = require('./helpers/create')
3
4test('basic symlink', t => {
5 const archive = create()
6
7 archive.writeFile('/hello.txt', 'world', err => {
8 t.error(err, 'no error')
9 archive.symlink('/hello.txt', '/link.txt', err => {
10 t.error(err, 'no error')
11 onlink()
12 })
13 })
14
15 function onlink () {
16 archive.stat('/link.txt', (err, st) => {
17 t.error(err, 'no error')
18 t.same(st.size, 5)
19 archive.readFile('/link.txt', (err, contents) => {
20 t.error(err, 'no error')
21 t.same(contents, Buffer.from('world'))
22 t.end()
23 })
24 })
25 }
26})
27
28test('fixing a broken symlink', t => {
29 const archive = create()
30
31 archive.symlink('/hello.txt', '/link.txt', err => {
32 t.error(err, 'no error')
33 archive.stat('/link.txt', (err, st) => {
34 t.same(err.errno, 2)
35 archive.writeFile('/hello.txt', 'world', err => {
36 t.error(err, 'no error')
37 onwrite()
38 })
39 })
40 })
41
42 function onwrite () {
43 archive.stat('/link.txt', (err, st) => {
44 t.error(err, 'no error')
45 t.same(st.size, 5)
46 archive.readFile('/link.txt', (err, contents) => {
47 t.error(err, 'no error')
48 t.same(contents, Buffer.from('world'))
49 t.end()
50 })
51 })
52 }
53})
54
55test('unlinking a symlink does not delete the target', t => {
56 const archive = create()
57
58 archive.writeFile('/hello.txt', 'world', err => {
59 t.error(err, 'no error')
60 archive.symlink('/hello.txt', '/link.txt', err => {
61 t.error(err, 'no error')
62 archive.unlink('/link.txt', err => {
63 t.error(err, 'no error')
64 onunlink()
65 })
66 })
67 })
68
69 function onunlink () {
70 archive.stat('/hello.txt', (err, st) => {
71 t.error(err, 'no error')
72 t.same(st.size, 5)
73 archive.readFile('/hello.txt', (err, contents) => {
74 t.error(err, 'no error')
75 t.same(contents, Buffer.from('world'))
76 t.end()
77 })
78 })
79 }
80})
81
82test('symlinks appear in readdir', t => {
83 const archive = create()
84
85 archive.writeFile('/hello.txt', 'world', err => {
86 t.error(err, 'no error')
87 archive.symlink('/hello.txt', '/link.txt', err => {
88 t.error(err, 'no error')
89 onlink()
90 })
91 })
92
93 function onlink () {
94 archive.readdir('/', (err, files) => {
95 t.error(err, 'no errors')
96 t.same(files, ['hello.txt', 'link.txt'])
97 t.end()
98 })
99 }
100})
101
102test('symlinks with nested symlinks appear in non-recursive readdir', t => {
103 const drive = create()
104
105 drive.mkdir('a', err => {
106 t.error(err)
107 drive.writeFile('a/1', '1', err => {
108 t.error(err, 'no error')
109 drive.writeFile('a/2', '2', err => {
110 t.error(err, 'no error')
111 drive.symlink('a/2', 'a/3', err => {
112 t.error(err, 'no error')
113 drive.symlink('a', 'b', err => {
114 t.error(err, 'no error')
115 onlink()
116 })
117 })
118 })
119 })
120 })
121
122 function onlink () {
123 drive.readdir('b', (err, files) => {
124 t.error(err, 'no error')
125 t.same(files, ['3', '1', '2'])
126 t.end()
127 })
128 }
129})
130
131test('nested, broken symlink without parent stats can be removed', t => {
132 const drive = create()
133
134 drive.symlink('bad-target', 'a/b/c/d', err => {
135 t.error(err)
136 drive.lstat('a/b/c/d', (err, st) => {
137 t.error(err, 'no error')
138 t.true(st)
139 drive.unlink('a/b/c/d', err => {
140 t.error(err, 'no error')
141 drive.readdir('a/b/c', (err, l) => {
142 t.error(err, 'no error')
143 t.same(l.length, 0)
144 t.end()
145 })
146 })
147 })
148 })
149})
150
151test('readdir with includeStats returns unresolved stats', t => {
152 const drive = create()
153
154 drive.writeFile('/hello', 'world', { metadata: { a: 'bbb' }}, err => {
155 t.error(err, 'no error')
156 drive.symlink('/hello', '/link', err => {
157 t.error(err, 'no error')
158 drive.readdir('/', { includeStats: true }, (err, list) => {
159 t.error(err, 'no error')
160 t.same(list.length, 2)
161 for (const { stat } of list) {
162 if (stat.metadata.a) t.true(stat.metadata.a.equals(Buffer.from('bbb')))
163 else t.same(stat.linkname, '/hello')
164 }
165 t.end()
166 })
167 })
168 })
169})
170
171// TODO: This will be fixed with a trie update.
172test.skip('stat through symlinked dir', t => {
173 const drive = create()
174
175 drive.mkdir('subdir1', err => {
176 t.error(err, 'no error')
177 drive.mkdir('subdir2', err => {
178 t.error(err, 'no error')
179 drive.writeFile('subdir1/foo', 'hello', err => {
180 t.error(err, 'no error')
181 drive.writeFile('subdir2/bar', 'world', err => {
182 t.error(err, 'no error')
183 drive.symlink('/subdir2', 'subdir1/symto2', err => {
184 t.error(err, 'no error')
185 return onlinked()
186 })
187 })
188 })
189 })
190 })
191
192 function onlinked () {
193 drive.stat('subdir1/symto2/bar', (err, st) => {
194 t.error(err, 'no error')
195 t.true(st)
196 t.end()
197 })
198 }
199})
200
201