Skip to content

Instantly share code, notes, and snippets.

@sylvainbx
Created December 1, 2022 08:34
Show Gist options
  • Save sylvainbx/56c5a69a282a2243edd07d79743f1540 to your computer and use it in GitHub Desktop.
Save sylvainbx/56c5a69a282a2243edd07d79743f1540 to your computer and use it in GitHub Desktop.
Typescript: Mock a FileList for unit testing purposes.
interface FileListHelper {
empty: () => globalThis.FileList,
fromFiles: (files: File[]) => globalThis.FileList
}
class FileList {
private readonly files: File[];
public length: number;
constructor (files?: File[]) {
this.files = files || [];
this.length = files?.length || 0;
}
item (index: number) {
return this.files[index];
}
nextFile () {
let index = -1;
const files = this.files || [];
return {
next: () => ({ value: files[++index], done: !(index in files) })
};
}
[Symbol.iterator] = this.nextFile;
}
export const fileList: FileListHelper = {
empty: () => {
const input = document.createElement('input');
input.type = 'file';
return input.files;
},
fromFiles: (files) => {
return new Proxy(new FileList(files), {
get (target, prop, receiver) {
if (!isNaN(parseInt(String(prop), 10))) {
return target.item(parseInt(String(prop), 10));
}
if (prop !== 'files') return Reflect.get(target, prop, receiver);
},
ownKeys (target: FileList): Array<string|symbol> {
return (['constructor', 'item', 'length', Symbol.iterator]).concat(
[...Array(target.length).keys()].map(k => String(k))
);
},
getOwnPropertyDescriptor (target, prop) {
return Object.getOwnPropertyDescriptor(target, prop) || {
enumerable: true,
configurable: true
};
}
}) as unknown as globalThis.FileList;
}
};
@sylvainbx
Copy link
Author

usage :

import { fileList } from 'lib/file-list-helper';
const file = new File(['(⌐□_□)'], 'document.pdf', { type: 'application/pdf' });
fileList.fromFiles([file])

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment