mirror of
https://github.com/status-im/metro.git
synced 2025-03-03 04:00:29 +00:00
metro-memory-fs: add lstat() and fstat()
Reviewed By: mjesun Differential Revision: D7257967 fbshipit-source-id: 56c59ca088bfd71fc111efdfda2f5393d6abbd9b
This commit is contained in:
parent
bfecccd180
commit
23bd78220b
@ -317,13 +317,46 @@ it('gives the real path via a symlinked directory', () => {
|
|||||||
expect(fs.realpathSync('/baz/foo.txt')).toEqual('/glo/foo.txt');
|
expect(fs.realpathSync('/baz/foo.txt')).toEqual('/glo/foo.txt');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('gives stat about a regular file', () => {
|
describe('stat', () => {
|
||||||
fs.writeFileSync('/foo.txt', 'test');
|
it('works for a regular file', () => {
|
||||||
const st = fs.statSync('/foo.txt');
|
fs.writeFileSync('/foo.txt', 'test');
|
||||||
expect(st.isFile()).toBe(true);
|
const st = fs.statSync('/foo.txt');
|
||||||
expect(st.isDirectory()).toBe(false);
|
expect(st.isFile()).toBe(true);
|
||||||
expect(st.isSymbolicLink()).toBe(false);
|
expect(st.isDirectory()).toBe(false);
|
||||||
expect(st.size).toBe(4);
|
expect(st.isSymbolicLink()).toBe(false);
|
||||||
|
expect(st.size).toBe(4);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('works for a symlinked file', () => {
|
||||||
|
fs.writeFileSync('/foo.txt', 'test');
|
||||||
|
fs.symlinkSync('foo.txt', '/bar.txt');
|
||||||
|
const st = fs.statSync('/bar.txt');
|
||||||
|
expect(st.isFile()).toBe(true);
|
||||||
|
expect(st.isDirectory()).toBe(false);
|
||||||
|
expect(st.isSymbolicLink()).toBe(false);
|
||||||
|
expect(st.size).toBe(4);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('lstat', () => {
|
||||||
|
it('works for a regular file', () => {
|
||||||
|
fs.writeFileSync('/foo.txt', 'test');
|
||||||
|
const st = fs.lstatSync('/foo.txt');
|
||||||
|
expect(st.isFile()).toBe(true);
|
||||||
|
expect(st.isDirectory()).toBe(false);
|
||||||
|
expect(st.isSymbolicLink()).toBe(false);
|
||||||
|
expect(st.size).toBe(4);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('works for a symlink', () => {
|
||||||
|
const linkStr = 'foo/bar/baz.txt';
|
||||||
|
fs.symlinkSync(linkStr, '/bar.txt');
|
||||||
|
const st = fs.lstatSync('/bar.txt');
|
||||||
|
expect(st.isFile()).toBe(false);
|
||||||
|
expect(st.isDirectory()).toBe(false);
|
||||||
|
expect(st.isSymbolicLink()).toBe(true);
|
||||||
|
expect(st.size).toBe(linkStr.length);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('able to list files of a directory', () => {
|
it('able to list files of a directory', () => {
|
||||||
|
@ -83,6 +83,8 @@ const FLAGS_SPECS: {
|
|||||||
|
|
||||||
const ASYNC_FUNC_NAMES = [
|
const ASYNC_FUNC_NAMES = [
|
||||||
'close',
|
'close',
|
||||||
|
'fstat',
|
||||||
|
'lstat',
|
||||||
'open',
|
'open',
|
||||||
'read',
|
'read',
|
||||||
'readdir',
|
'readdir',
|
||||||
@ -204,10 +206,7 @@ class MemoryFs {
|
|||||||
length: number,
|
length: number,
|
||||||
position: ?number,
|
position: ?number,
|
||||||
): number => {
|
): number => {
|
||||||
const desc = this._fds.get(fd);
|
const desc = this._getDesc(fd);
|
||||||
if (desc == null) {
|
|
||||||
throw makeError('EBADF', null, 'file descriptor is not open');
|
|
||||||
}
|
|
||||||
if (!desc.readable) {
|
if (!desc.readable) {
|
||||||
throw makeError('EBADF', null, 'file descriptor cannot be written to');
|
throw makeError('EBADF', null, 'file descriptor cannot be written to');
|
||||||
}
|
}
|
||||||
@ -417,6 +416,22 @@ class MemoryFs {
|
|||||||
return new Stats(node);
|
return new Stats(node);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
lstatSync = (filePath: string | Buffer) => {
|
||||||
|
filePath = pathStr(filePath);
|
||||||
|
const {node} = this._resolve(filePath, {
|
||||||
|
keepFinalSymlink: true,
|
||||||
|
});
|
||||||
|
if (node == null) {
|
||||||
|
throw makeError('ENOENT', filePath, 'no such file or directory');
|
||||||
|
}
|
||||||
|
return new Stats(node);
|
||||||
|
};
|
||||||
|
|
||||||
|
fstatSync = (fd: number) => {
|
||||||
|
const desc = this._getDesc(fd);
|
||||||
|
return new Stats(desc.node);
|
||||||
|
};
|
||||||
|
|
||||||
createReadStream = (
|
createReadStream = (
|
||||||
filePath: string | Buffer,
|
filePath: string | Buffer,
|
||||||
options?:
|
options?:
|
||||||
@ -540,7 +555,14 @@ class MemoryFs {
|
|||||||
* Implemented according with
|
* Implemented according with
|
||||||
* http://man7.org/linux/man-pages/man7/path_resolution.7.html
|
* http://man7.org/linux/man-pages/man7/path_resolution.7.html
|
||||||
*/
|
*/
|
||||||
_resolve(originalFilePath: string): Resolution {
|
_resolve(
|
||||||
|
originalFilePath: string,
|
||||||
|
options?: {keepFinalSymlink: boolean},
|
||||||
|
): Resolution {
|
||||||
|
let keepFinalSymlink = false;
|
||||||
|
if (options != null) {
|
||||||
|
({keepFinalSymlink} = options);
|
||||||
|
}
|
||||||
let filePath = originalFilePath;
|
let filePath = originalFilePath;
|
||||||
let drive = '';
|
let drive = '';
|
||||||
if (path === path.win32 && filePath.match(/^[a-zA-Z]:\\/)) {
|
if (path === path.win32 && filePath.match(/^[a-zA-Z]:\\/)) {
|
||||||
@ -562,6 +584,7 @@ class MemoryFs {
|
|||||||
nodePath: [['', this._root]],
|
nodePath: [['', this._root]],
|
||||||
entNames,
|
entNames,
|
||||||
symlinkCount: 0,
|
symlinkCount: 0,
|
||||||
|
keepFinalSymlink,
|
||||||
};
|
};
|
||||||
while (context.entNames.length > 0) {
|
while (context.entNames.length > 0) {
|
||||||
const entName = context.entNames.shift();
|
const entName = context.entNames.shift();
|
||||||
@ -597,7 +620,11 @@ class MemoryFs {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const childNode = entries.get(entName);
|
const childNode = entries.get(entName);
|
||||||
if (childNode == null || childNode.type !== 'symbolicLink') {
|
if (
|
||||||
|
childNode == null ||
|
||||||
|
childNode.type !== 'symbolicLink' ||
|
||||||
|
(context.keepFinalSymlink && context.entNames.length === 0)
|
||||||
|
) {
|
||||||
context.node = childNode;
|
context.node = childNode;
|
||||||
context.nodePath.push([entName, childNode]);
|
context.nodePath.push([entName, childNode]);
|
||||||
return;
|
return;
|
||||||
@ -623,10 +650,7 @@ class MemoryFs {
|
|||||||
length: number,
|
length: number,
|
||||||
position: ?number,
|
position: ?number,
|
||||||
): number {
|
): number {
|
||||||
const desc = this._fds.get(fd);
|
const desc = this._getDesc(fd);
|
||||||
if (desc == null) {
|
|
||||||
throw makeError('EBADF', null, 'file descriptor is not open');
|
|
||||||
}
|
|
||||||
if (!desc.writable) {
|
if (!desc.writable) {
|
||||||
throw makeError('EBADF', null, 'file descriptor cannot be written to');
|
throw makeError('EBADF', null, 'file descriptor cannot be written to');
|
||||||
}
|
}
|
||||||
@ -655,6 +679,14 @@ class MemoryFs {
|
|||||||
this._fds.set(fd, desc);
|
this._fds.set(fd, desc);
|
||||||
return fd;
|
return fd;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_getDesc(fd: number): Descriptor {
|
||||||
|
const desc = this._fds.get(fd);
|
||||||
|
if (desc == null) {
|
||||||
|
throw makeError('EBADF', null, 'file descriptor is not open');
|
||||||
|
}
|
||||||
|
return desc;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class Stats {
|
class Stats {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user