mirror of
https://github.com/shelljs/shelljs.git
synced 2025-12-08 20:35:51 +00:00
No change to logic. This swaps over tests to use require() since everything is currently designed for the commonjs module system.
360 lines
10 KiB
JavaScript
360 lines
10 KiB
JavaScript
const fs = require('fs');
|
|
|
|
const test = require('ava');
|
|
|
|
const shell = require('..');
|
|
const common = require('../src/common');
|
|
const utils = require('./utils/utils');
|
|
|
|
let TMP;
|
|
const BITMASK = parseInt('777', 8);
|
|
|
|
test.before(() => {
|
|
TMP = utils.getTempDir();
|
|
shell.cp('-r', 'test/resources', TMP);
|
|
shell.config.silent = true;
|
|
});
|
|
|
|
test.after(() => {
|
|
shell.rm('-rf', TMP);
|
|
});
|
|
|
|
//
|
|
// Invalids
|
|
//
|
|
|
|
test('invalid permissions', t => {
|
|
let result = shell.chmod('blah');
|
|
t.truthy(shell.error());
|
|
t.is(result.code, 1);
|
|
result = shell.chmod('893', `${TMP}/chmod`); // invalid permissions - mode must be in octal
|
|
t.truthy(shell.error());
|
|
t.is(result.code, 1);
|
|
});
|
|
|
|
test('Basic usage with octal codes', t => {
|
|
utils.skipOnWin(t, () => {
|
|
let result = shell.chmod('755', `${TMP}/chmod/file1`);
|
|
t.is(result.code, 0);
|
|
t.is(
|
|
common.statFollowLinks(`${TMP}/chmod/file1`).mode & BITMASK,
|
|
parseInt('755', 8)
|
|
);
|
|
result = shell.chmod('644', `${TMP}/chmod/file1`);
|
|
t.is(result.code, 0);
|
|
t.is(
|
|
common.statFollowLinks(`${TMP}/chmod/file1`).mode & BITMASK,
|
|
parseInt('644', 8)
|
|
);
|
|
});
|
|
});
|
|
|
|
test('symbolic mode', t => {
|
|
utils.skipOnWin(t, () => {
|
|
let result = shell.chmod('o+x', `${TMP}/chmod/file1`);
|
|
t.is(result.code, 0);
|
|
t.is(
|
|
common.statFollowLinks(`${TMP}/chmod/file1`).mode & parseInt('007', 8),
|
|
parseInt('005', 8)
|
|
);
|
|
result = shell.chmod('644', `${TMP}/chmod/file1`);
|
|
t.is(result.code, 0);
|
|
});
|
|
});
|
|
|
|
test('symbolic mode, without group', t => {
|
|
utils.skipOnWin(t, () => {
|
|
let result = shell.chmod('+x', `${TMP}/chmod/file1`);
|
|
t.is(result.code, 0);
|
|
t.is(
|
|
common.statFollowLinks(`${TMP}/chmod/file1`).mode & BITMASK,
|
|
parseInt('755', 8)
|
|
);
|
|
result = shell.chmod('644', `${TMP}/chmod/file1`);
|
|
t.is(result.code, 0);
|
|
});
|
|
});
|
|
|
|
test('Test setuid', t => {
|
|
utils.skipOnWin(t, () => {
|
|
let result = shell.chmod('u+s', `${TMP}/chmod/file1`);
|
|
t.is(result.code, 0);
|
|
t.is(
|
|
common.statFollowLinks(`${TMP}/chmod/file1`).mode & parseInt('4000', 8),
|
|
parseInt('4000', 8)
|
|
);
|
|
result = shell.chmod('u-s', `${TMP}/chmod/file1`);
|
|
t.is(result.code, 0);
|
|
t.is(
|
|
common.statFollowLinks(`${TMP}/chmod/file1`).mode & BITMASK,
|
|
parseInt('644', 8)
|
|
);
|
|
|
|
// according to POSIX standards at http://linux.die.net/man/1/chmod,
|
|
// setuid is never cleared from a directory unless explicitly asked for.
|
|
result = shell.chmod('u+s', `${TMP}/chmod/c`);
|
|
|
|
t.is(result.code, 0);
|
|
result = shell.chmod('755', `${TMP}/chmod/c`);
|
|
t.is(result.code, 0);
|
|
t.is(
|
|
common.statFollowLinks(`${TMP}/chmod/c`).mode & parseInt('4000', 8),
|
|
parseInt('4000', 8)
|
|
);
|
|
result = shell.chmod('u-s', `${TMP}/chmod/c`);
|
|
t.is(result.code, 0);
|
|
});
|
|
});
|
|
|
|
test('Test setgid', t => {
|
|
utils.skipOnWin(t, () => {
|
|
let result = shell.chmod('g+s', `${TMP}/chmod/file1`);
|
|
t.is(result.code, 0);
|
|
t.is(
|
|
common.statFollowLinks(`${TMP}/chmod/file1`).mode & parseInt('2000', 8),
|
|
parseInt('2000', 8)
|
|
);
|
|
result = shell.chmod('g-s', `${TMP}/chmod/file1`);
|
|
t.is(result.code, 0);
|
|
t.is(
|
|
common.statFollowLinks(`${TMP}/chmod/file1`).mode & BITMASK,
|
|
parseInt('644', 8)
|
|
);
|
|
});
|
|
});
|
|
|
|
test('Test sticky bit', t => {
|
|
utils.skipOnWin(t, () => {
|
|
let result = shell.chmod('+t', `${TMP}/chmod/file1`);
|
|
t.is(result.code, 0);
|
|
t.is(
|
|
common.statFollowLinks(`${TMP}/chmod/file1`).mode & parseInt('1000', 8),
|
|
parseInt('1000', 8)
|
|
);
|
|
result = shell.chmod('-t', `${TMP}/chmod/file1`);
|
|
t.is(result.code, 0);
|
|
t.is(
|
|
common.statFollowLinks(`${TMP}/chmod/file1`).mode & BITMASK,
|
|
parseInt('644', 8)
|
|
);
|
|
t.is(common.statFollowLinks(`${TMP}/chmod/file1`).mode & parseInt('1000', 8), 0);
|
|
});
|
|
});
|
|
|
|
test('Test directories', t => {
|
|
utils.skipOnWin(t, () => {
|
|
let result = shell.chmod('a-w', `${TMP}/chmod/b/a/b`);
|
|
t.is(result.code, 0);
|
|
t.is(
|
|
common.statFollowLinks(`${TMP}/chmod/b/a/b`).mode & BITMASK,
|
|
parseInt('555', 8)
|
|
);
|
|
result = shell.chmod('755', `${TMP}/chmod/b/a/b`);
|
|
t.is(result.code, 0);
|
|
});
|
|
});
|
|
|
|
test('Test recursion', t => {
|
|
utils.skipOnWin(t, () => {
|
|
let result = shell.chmod('-R', 'a+w', `${TMP}/chmod/b`);
|
|
t.is(result.code, 0);
|
|
t.is(
|
|
common.statFollowLinks(`${TMP}/chmod/b/a/b`).mode & BITMASK,
|
|
BITMASK
|
|
);
|
|
result = shell.chmod('-R', '755', `${TMP}/chmod/b`);
|
|
t.is(result.code, 0);
|
|
t.is(
|
|
common.statFollowLinks(`${TMP}/chmod/b/a/b`).mode & BITMASK,
|
|
parseInt('755', 8)
|
|
);
|
|
});
|
|
});
|
|
|
|
test('Test symbolic links w/ recursion - WARNING: *nix only', t => {
|
|
utils.skipOnWin(t, () => {
|
|
fs.symlinkSync(`${TMP}/chmod/b/a`, `${TMP}/chmod/a/b/c/link`, 'dir');
|
|
let result = shell.chmod('-R', 'u-w', `${TMP}/chmod/a/b`);
|
|
t.is(result.code, 0);
|
|
t.is(
|
|
common.statFollowLinks(`${TMP}/chmod/a/b/c`).mode & parseInt('700', 8),
|
|
parseInt('500', 8)
|
|
);
|
|
t.is(
|
|
common.statFollowLinks(`${TMP}/chmod/b/a`).mode & parseInt('700', 8),
|
|
parseInt('700', 8)
|
|
);
|
|
result = shell.chmod('-R', 'u+w', `${TMP}/chmod/a/b`);
|
|
t.is(result.code, 0);
|
|
fs.unlinkSync(`${TMP}/chmod/a/b/c/link`);
|
|
});
|
|
});
|
|
|
|
test('Test combinations', t => {
|
|
let result = shell.chmod('a-rwx', `${TMP}/chmod/file1`);
|
|
t.is(result.code, 0);
|
|
t.is(
|
|
common.statFollowLinks(`${TMP}/chmod/file1`).mode & parseInt('000', 8),
|
|
parseInt('000', 8)
|
|
);
|
|
result = shell.chmod('644', `${TMP}/chmod/file1`);
|
|
t.is(result.code, 0);
|
|
});
|
|
|
|
test('multiple symbolic modes', t => {
|
|
let result = shell.chmod('a-rwx,u+r', `${TMP}/chmod/file1`);
|
|
t.is(result.code, 0);
|
|
t.is(
|
|
common.statFollowLinks(`${TMP}/chmod/file1`).mode & parseInt('400', 8),
|
|
parseInt('400', 8)
|
|
);
|
|
result = shell.chmod('644', `${TMP}/chmod/file1`);
|
|
t.is(result.code, 0);
|
|
});
|
|
|
|
test('multiple symbolic modes #2', t => {
|
|
let result = shell.chmod('a-rwx,u+rw', `${TMP}/chmod/file1`);
|
|
t.is(result.code, 0);
|
|
t.is(
|
|
common.statFollowLinks(`${TMP}/chmod/file1`).mode & parseInt('600', 8),
|
|
parseInt('600', 8)
|
|
);
|
|
result = shell.chmod('644', `${TMP}/chmod/file1`);
|
|
t.is(result.code, 0);
|
|
});
|
|
|
|
test('multiple symbolic modes #3', t => {
|
|
utils.skipOnWin(t, () => {
|
|
let result = shell.chmod('a-rwx,u+rwx', `${TMP}/chmod/file1`);
|
|
t.is(result.code, 0);
|
|
t.is(
|
|
common.statFollowLinks(`${TMP}/chmod/file1`).mode & parseInt('700', 8),
|
|
parseInt('700', 8)
|
|
);
|
|
result = shell.chmod('644', `${TMP}/chmod/file1`);
|
|
t.is(result.code, 0);
|
|
});
|
|
});
|
|
|
|
test('u+rw', t => {
|
|
let result = shell.chmod('000', `${TMP}/chmod/file1`);
|
|
t.is(result.code, 0);
|
|
result = shell.chmod('u+rw', `${TMP}/chmod/file1`);
|
|
t.is(result.code, 0);
|
|
t.is(
|
|
common.statFollowLinks(`${TMP}/chmod/file1`).mode & parseInt('600', 8),
|
|
parseInt('600', 8)
|
|
);
|
|
result = shell.chmod('644', `${TMP}/chmod/file1`);
|
|
t.is(result.code, 0);
|
|
});
|
|
|
|
test('u+wx', t => {
|
|
utils.skipOnWin(t, () => {
|
|
let result = shell.chmod('000', `${TMP}/chmod/file1`);
|
|
t.is(result.code, 0);
|
|
result = shell.chmod('u+wx', `${TMP}/chmod/file1`);
|
|
t.is(result.code, 0);
|
|
t.is(
|
|
common.statFollowLinks(`${TMP}/chmod/file1`).mode & parseInt('300', 8),
|
|
parseInt('300', 8)
|
|
);
|
|
result = shell.chmod('644', `${TMP}/chmod/file1`);
|
|
t.is(result.code, 0);
|
|
});
|
|
});
|
|
|
|
test('Multiple symbolic modes at once', t => {
|
|
utils.skipOnWin(t, () => {
|
|
let result = shell.chmod('000', `${TMP}/chmod/file1`);
|
|
t.is(result.code, 0);
|
|
result = shell.chmod('u+r,g+w,o+x', `${TMP}/chmod/file1`);
|
|
t.is(result.code, 0);
|
|
t.is(
|
|
common.statFollowLinks(`${TMP}/chmod/file1`).mode & parseInt('421', 8),
|
|
parseInt('421', 8)
|
|
);
|
|
result = shell.chmod('644', `${TMP}/chmod/file1`);
|
|
t.is(result.code, 0);
|
|
});
|
|
});
|
|
|
|
test('u+rw,g+wx', t => {
|
|
utils.skipOnWin(t, () => {
|
|
let result = shell.chmod('000', `${TMP}/chmod/file1`);
|
|
t.is(result.code, 0);
|
|
result = shell.chmod('u+rw,g+wx', `${TMP}/chmod/file1`);
|
|
t.is(result.code, 0);
|
|
t.is(
|
|
common.statFollowLinks(`${TMP}/chmod/file1`).mode & parseInt('630', 8),
|
|
parseInt('630', 8)
|
|
);
|
|
result = shell.chmod('644', `${TMP}/chmod/file1`);
|
|
t.is(result.code, 0);
|
|
});
|
|
});
|
|
|
|
test('u-x,g+rw', t => {
|
|
let result = shell.chmod('700', `${TMP}/chmod/file1`);
|
|
t.is(result.code, 0);
|
|
result = shell.chmod('u-x,g+rw', `${TMP}/chmod/file1`);
|
|
t.is(result.code, 0);
|
|
t.is(
|
|
common.statFollowLinks(`${TMP}/chmod/file1`).mode & parseInt('660', 8),
|
|
parseInt('660', 8)
|
|
);
|
|
result = shell.chmod('644', `${TMP}/chmod/file1`);
|
|
t.is(result.code, 0);
|
|
});
|
|
|
|
test('a-rwx,u+rw', t => {
|
|
let result = shell.chmod('a-rwx,u+rw', `${TMP}/chmod/file1`);
|
|
t.is(result.code, 0);
|
|
t.is(
|
|
common.statFollowLinks(`${TMP}/chmod/file1`).mode & parseInt('600', 8),
|
|
parseInt('600', 8)
|
|
);
|
|
result = shell.chmod('a-rwx,u+rw', `${TMP}/chmod/file1`);
|
|
t.is(result.code, 0);
|
|
t.is(
|
|
common.statFollowLinks(`${TMP}/chmod/file1`).mode & parseInt('600', 8),
|
|
parseInt('600', 8)
|
|
);
|
|
result = shell.chmod('644', `${TMP}/chmod/file1`);
|
|
t.is(result.code, 0);
|
|
});
|
|
|
|
test('Numeric modes', t => {
|
|
let result = shell.chmod('744', `${TMP}/chmod/xdir`);
|
|
t.is(result.code, 0);
|
|
result = shell.chmod('644', `${TMP}/chmod/xdir/file`);
|
|
t.is(result.code, 0);
|
|
result = shell.chmod('744', `${TMP}/chmod/xdir/deep`);
|
|
t.is(result.code, 0);
|
|
result = shell.chmod('644', `${TMP}/chmod/xdir/deep/file`);
|
|
t.is(result.code, 0);
|
|
result = shell.chmod('-R', 'a+X', `${TMP}/chmod/xdir`);
|
|
t.is(result.code, 0);
|
|
});
|
|
|
|
test('Make sure chmod succeeds for a variety of octal codes', t => {
|
|
utils.skipOnWin(t, () => {
|
|
t.is(
|
|
common.statFollowLinks(`${TMP}/chmod/xdir`).mode & parseInt('755', 8),
|
|
parseInt('755', 8)
|
|
);
|
|
t.is(
|
|
common.statFollowLinks(`${TMP}/chmod/xdir/file`).mode & parseInt('644', 8),
|
|
parseInt('644', 8)
|
|
);
|
|
t.is(
|
|
common.statFollowLinks(`${TMP}/chmod/xdir/deep`).mode & parseInt('755', 8),
|
|
parseInt('755', 8)
|
|
);
|
|
t.is(
|
|
common.statFollowLinks(`${TMP}/chmod/xdir/deep/file`).mode & parseInt('644', 8),
|
|
parseInt('644', 8)
|
|
);
|
|
});
|
|
});
|