• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// Flags: --expose-internals
2'use strict';
3const common = require('../common');
4const fixtures = require('../common/fixtures');
5const tmpdir = require('../common/tmpdir');
6const assert = require('assert');
7const fs = require('fs');
8const { internalBinding } = require('internal/test/binding');
9const {
10  UV_ENOENT,
11  UV_EEXIST
12} = internalBinding('uv');
13const path = require('path');
14const src = fixtures.path('a.js');
15const dest = path.join(tmpdir.path, 'copyfile.out');
16const {
17  COPYFILE_EXCL,
18  COPYFILE_FICLONE,
19  COPYFILE_FICLONE_FORCE,
20  UV_FS_COPYFILE_EXCL,
21  UV_FS_COPYFILE_FICLONE,
22  UV_FS_COPYFILE_FICLONE_FORCE
23} = fs.constants;
24
25function verify(src, dest) {
26  const srcData = fs.readFileSync(src, 'utf8');
27  const srcStat = fs.statSync(src);
28  const destData = fs.readFileSync(dest, 'utf8');
29  const destStat = fs.statSync(dest);
30
31  assert.strictEqual(srcData, destData);
32  assert.strictEqual(srcStat.mode, destStat.mode);
33  assert.strictEqual(srcStat.size, destStat.size);
34}
35
36tmpdir.refresh();
37
38// Verify that flags are defined.
39assert.strictEqual(typeof COPYFILE_EXCL, 'number');
40assert.strictEqual(typeof COPYFILE_FICLONE, 'number');
41assert.strictEqual(typeof COPYFILE_FICLONE_FORCE, 'number');
42assert.strictEqual(typeof UV_FS_COPYFILE_EXCL, 'number');
43assert.strictEqual(typeof UV_FS_COPYFILE_FICLONE, 'number');
44assert.strictEqual(typeof UV_FS_COPYFILE_FICLONE_FORCE, 'number');
45assert.strictEqual(COPYFILE_EXCL, UV_FS_COPYFILE_EXCL);
46assert.strictEqual(COPYFILE_FICLONE, UV_FS_COPYFILE_FICLONE);
47assert.strictEqual(COPYFILE_FICLONE_FORCE, UV_FS_COPYFILE_FICLONE_FORCE);
48
49// Verify that files are overwritten when no flags are provided.
50fs.writeFileSync(dest, '', 'utf8');
51const result = fs.copyFileSync(src, dest);
52assert.strictEqual(result, undefined);
53verify(src, dest);
54
55// Verify that files are overwritten with default flags.
56fs.copyFileSync(src, dest, 0);
57verify(src, dest);
58
59// Verify that UV_FS_COPYFILE_FICLONE can be used.
60fs.unlinkSync(dest);
61fs.copyFileSync(src, dest, UV_FS_COPYFILE_FICLONE);
62verify(src, dest);
63
64// Verify that COPYFILE_FICLONE_FORCE can be used.
65try {
66  fs.unlinkSync(dest);
67  fs.copyFileSync(src, dest, COPYFILE_FICLONE_FORCE);
68  verify(src, dest);
69} catch (err) {
70  assert.strictEqual(err.syscall, 'copyfile');
71  assert(err.code === 'ENOTSUP' || err.code === 'ENOTTY' ||
72    err.code === 'ENOSYS' || err.code === 'EXDEV');
73  assert.strictEqual(err.path, src);
74  assert.strictEqual(err.dest, dest);
75}
76
77// Copies asynchronously.
78tmpdir.refresh(); // Don't use unlinkSync() since the last test may fail.
79fs.copyFile(src, dest, common.mustCall((err) => {
80  assert.ifError(err);
81  verify(src, dest);
82
83  // Copy asynchronously with flags.
84  fs.copyFile(src, dest, COPYFILE_EXCL, common.mustCall((err) => {
85    if (err.code === 'ENOENT') {  // Could be ENOENT or EEXIST
86      assert.strictEqual(err.message,
87                         'ENOENT: no such file or directory, copyfile ' +
88                         `'${src}' -> '${dest}'`);
89      assert.strictEqual(err.errno, UV_ENOENT);
90      assert.strictEqual(err.code, 'ENOENT');
91      assert.strictEqual(err.syscall, 'copyfile');
92    } else {
93      assert.strictEqual(err.message,
94                         'EEXIST: file already exists, copyfile ' +
95                         `'${src}' -> '${dest}'`);
96      assert.strictEqual(err.errno, UV_EEXIST);
97      assert.strictEqual(err.code, 'EEXIST');
98      assert.strictEqual(err.syscall, 'copyfile');
99    }
100  }));
101}));
102
103// Throws if callback is not a function.
104assert.throws(() => {
105  fs.copyFile(src, dest, 0, 0);
106}, {
107  code: 'ERR_INVALID_CALLBACK',
108  name: 'TypeError'
109});
110
111// Throws if the source path is not a string.
112[false, 1, {}, [], null, undefined].forEach((i) => {
113  assert.throws(
114    () => fs.copyFile(i, dest, common.mustNotCall()),
115    {
116      code: 'ERR_INVALID_ARG_TYPE',
117      name: 'TypeError'
118    }
119  );
120  assert.throws(
121    () => fs.copyFile(src, i, common.mustNotCall()),
122    {
123      code: 'ERR_INVALID_ARG_TYPE',
124      name: 'TypeError'
125    }
126  );
127  assert.throws(
128    () => fs.copyFileSync(i, dest),
129    {
130      code: 'ERR_INVALID_ARG_TYPE',
131      name: 'TypeError'
132    }
133  );
134  assert.throws(
135    () => fs.copyFileSync(src, i),
136    {
137      code: 'ERR_INVALID_ARG_TYPE',
138      name: 'TypeError'
139    }
140  );
141});
142