blob: 61808fb1d97077ec7ab697d705904bf6f147db5b [file]
/**
* @license
* Copyright 2019 The Bazel Authors. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
*
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import * as assert from 'assert';
// windows cant find the right types
// import * as fs from 'fs';
const fs = require('fs');
import {withFixtures} from 'inline-fixtures';
import * as path from 'path';
import * as util from 'util';
import {patcher} from '../../src/fs';
describe('testing lstat', () => {
it('can lstat symlink in root', async () => {
await withFixtures(
{
a: {},
b: {file: 'contents'},
},
async fixturesDir => {
fixturesDir = fs.realpathSync(fixturesDir);
// create symlink from a/link to b/file
fs.symlinkSync(path.join(fixturesDir, 'b', 'file'), path.join(fixturesDir, 'a', 'link'));
const patchedFs = Object.assign({}, fs);
patchedFs.promises = Object.assign({}, fs.promises);
patcher(patchedFs, [path.join(fixturesDir)]);
const linkPath = path.join(fixturesDir, 'a', 'link');
assert.ok(
patchedFs.lstatSync(linkPath).isSymbolicLink(),
'lstatSync should find symbolic link if link is the root');
assert.ok(
(await util.promisify(patchedFs.lstat)(linkPath)).isSymbolicLink(),
'lstat should find symbolic link if link is the root');
assert.ok(
(await patchedFs.promises.lstat(linkPath)).isSymbolicLink(),
'promises.lstat should find symbolic link if link is the root');
});
});
it('can lstat symlink in guard is file', async () => {
await withFixtures(
{
a: {g: {}},
b: {file: 'contents'},
},
async fixturesDir => {
fixturesDir = fs.realpathSync(fixturesDir);
// create symlink from a/g/link to b/file
fs.symlinkSync(
path.join(fixturesDir, 'b', 'file'), path.join(fixturesDir, 'a', 'g', 'link'));
const patchedFs = Object.assign({}, fs);
patchedFs.promises = Object.assign({}, fs.promises);
patcher(patchedFs, [path.join(fixturesDir), path.join(fixturesDir, 'a', 'g')]);
const linkPath = path.join(fixturesDir, 'a', 'g', 'link');
assert.ok(
patchedFs.lstatSync(linkPath).isFile(),
'lstatSync should find file if link is in guard');
assert.ok(
(await util.promisify(patchedFs.lstat)(linkPath)).isFile(),
'lstat should find file if link is in guard');
assert.ok(
(await patchedFs.promises.lstat(linkPath)).isFile(),
'promises.lstat should find file if link is in guard');
});
});
it('lstat of symlink out of root is file.', async () => {
await withFixtures(
{
a: {},
b: {file: 'contents'},
},
async fixturesDir => {
fixturesDir = fs.realpathSync(fixturesDir);
// create symlink from a/link to b/file
fs.symlinkSync(path.join(fixturesDir, 'b', 'file'), path.join(fixturesDir, 'a', 'link'));
const patchedFs = Object.assign({}, fs);
patchedFs.promises = Object.assign({}, fs.promises);
patcher(patchedFs, [path.join(fixturesDir, 'a')]);
const linkPath = path.join(fixturesDir, 'a', 'link');
assert.ok(
patchedFs.lstatSync(linkPath).isFile(),
'lstatSync should find file it file link is out of root');
assert.ok(
(await util.promisify(patchedFs.lstat)(linkPath)).isFile(),
'lstat should find file it file link is out of root');
assert.ok(
(await patchedFs.promises.lstat(linkPath)).isFile(),
'promises.lstat should find file it file link is out of root');
let brokenLinkPath = path.join(fixturesDir, 'a', 'broken-link');
fs.symlinkSync(path.join(fixturesDir, 'doesnt-exist'), brokenLinkPath);
let stat = await patchedFs.promises.lstat(brokenLinkPath);
assert.ok(
stat.isSymbolicLink(), 'if a symlink is broken but is escaping return it as a link.');
brokenLinkPath = path.join(fixturesDir, 'a', 'broken-link2');
fs.symlinkSync(path.join(fixturesDir, 'a', 'doesnt-exist'), brokenLinkPath);
stat = await patchedFs.promises.lstat(brokenLinkPath);
assert.ok(
stat.isSymbolicLink(),
'if a symlink is broken but not escaping return it as a link.');
});
});
it('not in root, symlinks do what they would have before.', async () => {
await withFixtures(
{
a: {},
b: {file: 'contents'},
},
async fixturesDir => {
fixturesDir = fs.realpathSync(fixturesDir);
// create symlink from a/link to b/file
fs.symlinkSync(path.join(fixturesDir, 'b', 'file'), path.join(fixturesDir, 'b', 'link'));
const patchedFs = Object.assign({}, fs);
patchedFs.promises = Object.assign({}, fs.promises);
patcher(patchedFs, [path.join(fixturesDir, 'a')]);
const linkPath = path.join(fixturesDir, 'b', 'link');
assert.ok(
patchedFs.lstatSync(linkPath).isSymbolicLink(),
'lstatSync should find symbolic link if link is out of the root');
const stat = await util.promisify(patchedFs.lstat)(linkPath);
assert.ok(stat.isSymbolicLink(), 'lstat should find symbolic link if link is outside');
assert.ok(
(await patchedFs.promises.lstat(linkPath)).isSymbolicLink(),
'promises.lstat should find symbolic link if link is outside');
});
});
});