Skip to content

Commit

Permalink
feat: 🎸 implement .values() and .entries()
Browse files Browse the repository at this point in the history
  • Loading branch information
streamich committed Jun 20, 2023
1 parent f603262 commit f13de3b
Show file tree
Hide file tree
Showing 3 changed files with 105 additions and 16 deletions.
35 changes: 20 additions & 15 deletions src/node-to-fsa/NodeFileSystemDirectoryHandle.ts
@@ -1,5 +1,6 @@
import {NodeFileSystemHandle} from "./NodeFileSystemHandle";
import {basename, ctx as createCtx} from "./util";
import {NodeFileSystemFileHandle} from "./NodeFileSystemFileHandle";
import type {NodeFsaContext, NodeFsaFs} from "./types";

/**
Expand All @@ -14,25 +15,29 @@ export class NodeFileSystemDirectoryHandle extends NodeFileSystemHandle {
super('directory', basename(path, ctx.separator!));
}

/**
* @see https://developer.mozilla.org/en-US/docs/Web/API/FileSystemDirectoryHandle/entries
*/
public entries(): AsyncIterableIterator<[string, NodeFileSystemHandle]> {
throw new Error('Not implemented');
}

/**
* Returns a new array iterator containing the keys for each item in
* {@link NodeFileSystemDirectoryHandle} object.
*
* @see https://developer.mozilla.org/en-US/docs/Web/API/FileSystemDirectoryHandle/keys
*/
public keys(): AsyncIterableIterator<string> {
const {path, fs} = this;
return (async function*() {
const list = await fs.promises.readdir(path);
for (const name of list) yield name;
})();
public async * keys(): AsyncIterableIterator<string> {
const list = await this.fs.promises.readdir(this.path);
for (const name of list) yield name;
}

/**
* @see https://developer.mozilla.org/en-US/docs/Web/API/FileSystemDirectoryHandle/entries
*/
public async * entries(): AsyncIterableIterator<[string, NodeFileSystemHandle]> {
const {path, fs, ctx} = this;
const list = await fs.promises.readdir(path, {withFileTypes: true});
for (const dirent of list) {
const name = dirent.name;
const newPath = path + ctx.separator! + name;
if (dirent.isDirectory()) yield [name, new NodeFileSystemDirectoryHandle(fs, newPath, ctx)];
else if (dirent.isFile()) yield [name, new NodeFileSystemFileHandle(fs, name, ctx)];
}
}

/**
Expand All @@ -41,8 +46,8 @@ export class NodeFileSystemDirectoryHandle extends NodeFileSystemHandle {
*
* @see https://developer.mozilla.org/en-US/docs/Web/API/FileSystemDirectoryHandle/values
*/
public values(): AsyncIterableIterator<NodeFileSystemHandle> {
throw new Error('Not implemented');
public async * values(): AsyncIterableIterator<NodeFileSystemHandle> {
for await (const [, value] of this.entries()) yield value;
}

/**
Expand Down
2 changes: 1 addition & 1 deletion src/node-to-fsa/NodeFileSystemFileHandle.ts
Expand Up @@ -9,7 +9,7 @@ export class NodeFileSystemFileHandle extends NodeFileSystemHandle {
protected readonly path: string,
protected readonly ctx: Partial<NodeFsaContext> = createCtx(ctx),
) {
super('directory', basename(path, ctx.separator!));
super('file', basename(path, ctx.separator!));
}

/**
Expand Down
84 changes: 84 additions & 0 deletions src/node-to-fsa/__tests__/NodeFileSystemDirectoryHandle.test.ts
@@ -1,5 +1,7 @@
import {DirectoryJSON, memfs} from '../..';
import {NodeFileSystemDirectoryHandle} from '../NodeFileSystemDirectoryHandle';
import {NodeFileSystemFileHandle} from '../NodeFileSystemFileHandle';
import {NodeFileSystemHandle} from '../NodeFileSystemHandle';

const setup = (json: DirectoryJSON = {}) => {
const fs = memfs(json, '/');
Expand Down Expand Up @@ -45,3 +47,85 @@ describe('.keys()', () => {
expect(list).toEqual(['file.txt']);
});
});

describe('.entries()', () => {
test('returns an empty iterator for an empty directory', async () => {
const {dir} = setup();
const keys = dir.entries();
expect(await keys.next()).toEqual({done: true, value: undefined});
});

test('returns a folder', async () => {
const {dir} = setup({'My Documents': null});
for await (const [name, subdir] of dir.entries()) {
expect(name).toBe('My Documents');
expect(subdir).toBeInstanceOf(NodeFileSystemDirectoryHandle);
expect(subdir.kind).toBe('directory');
expect(subdir.name).toBe('My Documents');
}
});

test('returns a file', async () => {
const {dir} = setup({
'file.txt': 'Hello, world!',
});
for await (const [name, file] of dir.entries()) {
expect(name).toBe('file.txt');
expect(file).toBeInstanceOf(NodeFileSystemFileHandle);
expect(file.kind).toBe('file');
expect(file.name).toBe('file.txt');
}
});

test('returns two entries', async () => {
const {dir} = setup({
'index.html': '<nobr>Hello, world!</nobr>',
'another/folder': null,
});
const handles: NodeFileSystemHandle[] = [];
for await (const entry of dir.entries()) handles.push(entry[1]);
expect(handles.length).toBe(2);
expect(handles.find(handle => handle.name === 'index.html')).toBeInstanceOf(NodeFileSystemFileHandle);
expect(handles.find(handle => handle.name === 'another')).toBeInstanceOf(NodeFileSystemDirectoryHandle);
});
});

describe('.values()', () => {
test('returns an empty iterator for an empty directory', async () => {
const {dir} = setup();
const values = dir.values();
expect(await values.next()).toEqual({done: true, value: undefined});
});

test('returns a folder', async () => {
const {dir} = setup({'My Documents': null});
for await (const subdir of dir.values()) {
expect(subdir).toBeInstanceOf(NodeFileSystemDirectoryHandle);
expect(subdir.kind).toBe('directory');
expect(subdir.name).toBe('My Documents');
}
});

test('returns a file', async () => {
const {dir} = setup({
'file.txt': 'Hello, world!',
});
for await (const file of dir.values()) {
expect(file).toBeInstanceOf(NodeFileSystemFileHandle);
expect(file.kind).toBe('file');
expect(file.name).toBe('file.txt');
}
});

test('returns two entries', async () => {
const {dir} = setup({
'index.html': '<nobr>Hello, world!</nobr>',
'another/folder': null,
});
const handles: NodeFileSystemHandle[] = [];
for await (const entry of dir.values()) handles.push(entry);
expect(handles.length).toBe(2);
expect(handles.find(handle => handle.name === 'index.html')).toBeInstanceOf(NodeFileSystemFileHandle);
expect(handles.find(handle => handle.name === 'another')).toBeInstanceOf(NodeFileSystemDirectoryHandle);
});
});

0 comments on commit f13de3b

Please sign in to comment.