UNPKG

11.5 kBPlain TextView Raw
1import * as fse from "fs-extra";
2import { expect } from "chai";
3import path from "./assert_path";
4import helper from "./helper";
5import * as jetpack from "..";
6import { InspectResult, Checksum } from "../types";
7
8describe("inspect", () => {
9 beforeEach(helper.setCleanTestCwd);
10 afterEach(helper.switchBackToCorrectCwd);
11
12 describe("can inspect a file", () => {
13 const preparations = () => {
14 fse.outputFileSync("dir/file.txt", "abc");
15 };
16
17 const expectations = (data: InspectResult) => {
18 expect(data).to.eql({
19 name: "file.txt",
20 type: "file",
21 size: 3
22 });
23 };
24
25 it("sync", () => {
26 preparations();
27 expectations(jetpack.inspect("dir/file.txt"));
28 });
29
30 it("async", done => {
31 preparations();
32 jetpack.inspectAsync("dir/file.txt").then(data => {
33 expectations(data);
34 done();
35 });
36 });
37 });
38
39 describe("can inspect a directory", () => {
40 const preparations = () => {
41 fse.mkdirsSync("empty");
42 };
43
44 const expectations = (data: InspectResult) => {
45 expect(data).to.eql({
46 name: "empty",
47 type: "dir"
48 });
49 };
50
51 it("sync", () => {
52 preparations();
53 expectations(jetpack.inspect("empty"));
54 });
55
56 it("async", done => {
57 preparations();
58 jetpack.inspectAsync("empty").then(data => {
59 expectations(data);
60 done();
61 });
62 });
63 });
64
65 describe("returns undefined if path doesn't exist", () => {
66 const expectations = (data: InspectResult) => {
67 expect(data).to.equal(undefined);
68 };
69
70 it("sync", () => {
71 expectations(jetpack.inspect("nonexistent"));
72 });
73
74 it("async", done => {
75 jetpack.inspectAsync("nonexistent").then(data => {
76 expectations(data);
77 done();
78 });
79 });
80 });
81
82 describe("can output file times (ctime, mtime, atime)", () => {
83 const preparations = () => {
84 fse.outputFileSync("dir/file.txt", "abc");
85 };
86
87 const expectations = (data: InspectResult) => {
88 expect(typeof data.accessTime.getTime).to.equal("function");
89 expect(typeof data.modifyTime.getTime).to.equal("function");
90 expect(typeof data.changeTime.getTime).to.equal("function");
91 };
92
93 it("sync", () => {
94 preparations();
95 expectations(jetpack.inspect("dir/file.txt", { times: true }));
96 });
97
98 it("async", done => {
99 preparations();
100 jetpack.inspectAsync("dir/file.txt", { times: true }).then(data => {
101 expectations(data);
102 done();
103 });
104 });
105 });
106
107 describe("can output absolute path", () => {
108 const preparations = () => {
109 fse.outputFileSync("dir/file.txt", "abc");
110 };
111
112 const expectations = (data: InspectResult) => {
113 expect(data.absolutePath).to.equal(jetpack.path("dir/file.txt"));
114 };
115
116 it("sync", () => {
117 preparations();
118 expectations(jetpack.inspect("dir/file.txt", { absolutePath: true }));
119 });
120
121 it("async", done => {
122 preparations();
123 jetpack
124 .inspectAsync("dir/file.txt", { absolutePath: true })
125 .then(data => {
126 expectations(data);
127 done();
128 });
129 });
130 });
131
132 describe("respects internal CWD of jetpack instance", () => {
133 const preparations = () => {
134 fse.outputFileSync("a/b.txt", "abc");
135 };
136
137 const expectations = (data: InspectResult) => {
138 expect(data.name).to.equal("b.txt");
139 };
140
141 it("sync", () => {
142 const jetContext = jetpack.cwd("a");
143 preparations();
144 expectations(jetContext.inspect("b.txt"));
145 });
146
147 it("async", done => {
148 const jetContext = jetpack.cwd("a");
149 preparations();
150 jetContext.inspectAsync("b.txt").then(data => {
151 expectations(data);
152 done();
153 });
154 });
155 });
156
157 describe("reports symlink by default", () => {
158 const preparations = () => {
159 fse.outputFileSync("dir/file.txt", "abc");
160 fse.symlinkSync("dir/file.txt", "symlinked_file.txt");
161 };
162
163 const expectations = (data: InspectResult) => {
164 expect(data).to.eql({
165 name: "symlinked_file.txt",
166 type: "symlink",
167 pointsAt: helper.osSep("dir/file.txt")
168 });
169 };
170
171 it("sync", () => {
172 preparations();
173 expectations(jetpack.inspect("symlinked_file.txt")); // implicit
174 expectations(
175 jetpack.inspect("symlinked_file.txt", { symlinks: "report" })
176 ); // explicit
177 });
178
179 it("async", done => {
180 preparations();
181 jetpack
182 .inspectAsync("symlinked_file.txt") // implicit
183 .then(data => {
184 expectations(data);
185 return jetpack.inspectAsync("symlinked_file.txt", {
186 symlinks: "report"
187 }); // explicit
188 })
189 .then(data => {
190 expectations(data);
191 done();
192 })
193 .catch(done);
194 });
195 });
196
197 describe("follows symlink if option specified", () => {
198 const preparations = () => {
199 fse.outputFileSync("dir/file.txt", "abc");
200 fse.symlinkSync("dir/file.txt", "symlinked_file.txt");
201 };
202
203 const expectations = (data: InspectResult) => {
204 expect(data).to.eql({
205 name: "symlinked_file.txt",
206 type: "file",
207 size: 3
208 });
209 };
210
211 it("sync", () => {
212 preparations();
213 expectations(
214 jetpack.inspect("symlinked_file.txt", { symlinks: "follow" })
215 );
216 });
217
218 it("async", done => {
219 preparations();
220 jetpack
221 .inspectAsync("symlinked_file.txt", { symlinks: "follow" })
222 .then(data => {
223 expectations(data);
224 done();
225 })
226 .catch(done);
227 });
228 });
229
230 if (process.platform !== "win32") {
231 describe("can output file mode (unix only)", () => {
232 const preparations = () => {
233 fse.outputFileSync("dir/file.txt", "abc", {
234 mode: 0o511
235 });
236 };
237
238 const expectations = (data: InspectResult) => {
239 expect(helper.parseMode(data.mode)).to.equal("511");
240 };
241
242 it("sync", () => {
243 preparations();
244 expectations(jetpack.inspect("dir/file.txt", { mode: true }));
245 });
246
247 it("async", done => {
248 preparations();
249 jetpack.inspectAsync("dir/file.txt", { mode: true }).then(data => {
250 expectations(data);
251 done();
252 });
253 });
254 });
255 }
256
257 describe("checksums", () => {
258 const testsData = [
259 {
260 name: "md5",
261 type: "md5",
262 content: "abc",
263 expected: "900150983cd24fb0d6963f7d28e17f72"
264 },
265 {
266 name: "sha1",
267 type: "sha1",
268 content: "abc",
269 expected: "a9993e364706816aba3e25717850c26c9cd0d89d"
270 },
271 {
272 name: "sha256",
273 type: "sha256",
274 content: "abc",
275 expected:
276 "ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad"
277 },
278 {
279 name: "sha512",
280 type: "sha512",
281 content: "abc",
282 expected:
283 "ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f"
284 },
285 {
286 name: "calculates correctly checksum of an empty file",
287 type: "md5",
288 content: "",
289 expected: "d41d8cd98f00b204e9800998ecf8427e"
290 }
291 ];
292
293 testsData.forEach(test => {
294 describe(test.name, () => {
295 const preparations = () => {
296 fse.outputFileSync("file.txt", test.content);
297 };
298
299 const expectations = (data: InspectResult) => {
300 expect(data[test.type as Checksum]).to.eql(test.expected);
301 };
302
303 it("sync", () => {
304 preparations();
305 expectations(
306 jetpack.inspect("file.txt", { checksum: test.type as Checksum })
307 );
308 });
309
310 it("async", done => {
311 preparations();
312 jetpack
313 .inspectAsync("file.txt", { checksum: test.type as Checksum })
314 .then(data => {
315 expectations(data);
316 done();
317 })
318 .catch(done);
319 });
320 });
321 });
322 });
323
324 describe("input validation", () => {
325 const tests = [
326 { type: "sync", method: jetpack.inspect as any, methodName: "inspect" },
327 {
328 type: "async",
329 method: jetpack.inspectAsync as any,
330 methodName: "inspectAsync"
331 }
332 ];
333
334 describe('"path" argument', () => {
335 tests.forEach(test => {
336 it(test.type, () => {
337 expect(() => {
338 test.method(undefined);
339 }).to.throw(
340 `Argument "path" passed to ${
341 test.methodName
342 }(path, [options]) must be a string. Received undefined`
343 );
344 });
345 });
346 });
347
348 describe('"options" object', () => {
349 describe('"checksum" argument', () => {
350 tests.forEach(test => {
351 it(test.type, () => {
352 expect(() => {
353 test.method("abc", { checksum: 1 });
354 }).to.throw(
355 `Argument "options.checksum" passed to ${
356 test.methodName
357 }(path, [options]) must be a string. Received number`
358 );
359 });
360 it(test.type, () => {
361 expect(() => {
362 test.method("abc", { checksum: "foo" });
363 }).to.throw(
364 `Argument "options.checksum" passed to ${
365 test.methodName
366 }(path, [options]) must have one of values: md5, sha1, sha256`
367 );
368 });
369 });
370 });
371 describe('"mode" argument', () => {
372 tests.forEach(test => {
373 it(test.type, () => {
374 expect(() => {
375 test.method("abc", { mode: 1 });
376 }).to.throw(
377 `Argument "options.mode" passed to ${
378 test.methodName
379 }(path, [options]) must be a boolean. Received number`
380 );
381 });
382 });
383 });
384 describe('"times" argument', () => {
385 tests.forEach(test => {
386 it(test.type, () => {
387 expect(() => {
388 test.method("abc", { times: 1 });
389 }).to.throw(
390 `Argument "options.times" passed to ${
391 test.methodName
392 }(path, [options]) must be a boolean. Received number`
393 );
394 });
395 });
396 });
397 describe('"absolutePath" argument', () => {
398 tests.forEach(test => {
399 it(test.type, () => {
400 expect(() => {
401 test.method("abc", { absolutePath: 1 });
402 }).to.throw(
403 `Argument "options.absolutePath" passed to ${
404 test.methodName
405 }(path, [options]) must be a boolean. Received number`
406 );
407 });
408 });
409 });
410 describe('"symlinks" argument', () => {
411 tests.forEach(test => {
412 it(test.type, () => {
413 expect(() => {
414 test.method("abc", { symlinks: 1 });
415 }).to.throw(
416 `Argument "options.symlinks" passed to ${
417 test.methodName
418 }(path, [options]) must be a string. Received number`
419 );
420 });
421 it(test.type, () => {
422 expect(() => {
423 test.method("abc", { symlinks: "foo" });
424 }).to.throw(
425 `Argument "options.symlinks" passed to ${
426 test.methodName
427 }(path, [options]) must have one of values: report, follow`
428 );
429 });
430 });
431 });
432 });
433 });
434});