2019-03-27 02:01:25 +08:00
|
|
|
import * as fs from "fs";
|
|
|
|
import * as os from "os";
|
|
|
|
import * as path from "path";
|
|
|
|
import * as rimraf from "rimraf";
|
|
|
|
import * as util from "util";
|
|
|
|
import { IDisposable } from "@coder/disposable";
|
2019-01-12 03:33:44 +08:00
|
|
|
import { Emitter } from "@coder/events";
|
|
|
|
import { Client } from "../src/browser/client";
|
2019-01-16 02:36:09 +08:00
|
|
|
import { Server, ServerOptions } from "../src/node/server";
|
2019-01-12 03:33:44 +08:00
|
|
|
|
2019-03-27 02:01:25 +08:00
|
|
|
// So we only make the directory once when running multiple tests.
|
|
|
|
let mkdirPromise: Promise<void> | undefined;
|
|
|
|
|
|
|
|
export class Helper {
|
|
|
|
private i = 0;
|
|
|
|
public coderDir: string;
|
|
|
|
private baseDir = path.join(os.tmpdir(), "coder");
|
|
|
|
|
|
|
|
public constructor(directoryName: string) {
|
|
|
|
if (!directoryName.trim()) {
|
|
|
|
throw new Error("no directory name");
|
|
|
|
}
|
|
|
|
|
|
|
|
this.coderDir = path.join(this.baseDir, directoryName);
|
|
|
|
}
|
|
|
|
|
|
|
|
public tmpFile(): string {
|
|
|
|
return path.join(this.coderDir, `${this.i++}`);
|
|
|
|
}
|
|
|
|
|
|
|
|
public async createTmpFile(): Promise<string> {
|
|
|
|
const tf = this.tmpFile();
|
|
|
|
await util.promisify(fs.writeFile)(tf, "");
|
|
|
|
|
|
|
|
return tf;
|
|
|
|
}
|
|
|
|
|
|
|
|
public async prepare(): Promise<void> {
|
|
|
|
if (!mkdirPromise) {
|
|
|
|
mkdirPromise = util.promisify(fs.mkdir)(this.baseDir).catch((error) => {
|
|
|
|
if (error.code !== "EEXIST" && error.code !== "EISDIR") {
|
|
|
|
throw error;
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
await mkdirPromise;
|
|
|
|
await util.promisify(rimraf)(this.coderDir);
|
|
|
|
await util.promisify(fs.mkdir)(this.coderDir);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-01-16 02:36:09 +08:00
|
|
|
export const createClient = (serverOptions?: ServerOptions): Client => {
|
2019-01-12 03:58:31 +08:00
|
|
|
const s2c = new Emitter<Uint8Array | Buffer>();
|
|
|
|
const c2s = new Emitter<Uint8Array | Buffer>();
|
2019-02-20 00:42:32 +08:00
|
|
|
const closeCallbacks = <Array<() => void>>[];
|
2019-01-12 03:33:44 +08:00
|
|
|
|
2019-02-20 00:42:32 +08:00
|
|
|
// tslint:disable-next-line no-unused-expression
|
2019-01-12 03:58:31 +08:00
|
|
|
new Server({
|
2019-02-20 00:42:32 +08:00
|
|
|
close: (): void => closeCallbacks.forEach((cb) => cb()),
|
2019-03-27 02:01:25 +08:00
|
|
|
onDown: (_cb: () => void): void => undefined,
|
|
|
|
onUp: (_cb: () => void): void => undefined,
|
2019-02-20 00:42:32 +08:00
|
|
|
onClose: (cb: () => void): number => closeCallbacks.push(cb),
|
2019-03-27 02:01:25 +08:00
|
|
|
onMessage: (cb): IDisposable => c2s.event((d) => cb(d)),
|
2019-01-16 02:36:09 +08:00
|
|
|
send: (data): NodeJS.Timer => setTimeout(() => s2c.emit(data), 0),
|
|
|
|
}, serverOptions);
|
2019-01-12 03:33:44 +08:00
|
|
|
|
2019-01-12 03:58:31 +08:00
|
|
|
const client = new Client({
|
2019-02-20 00:42:32 +08:00
|
|
|
close: (): void => closeCallbacks.forEach((cb) => cb()),
|
2019-03-27 02:01:25 +08:00
|
|
|
onDown: (_cb: () => void): void => undefined,
|
|
|
|
onUp: (_cb: () => void): void => undefined,
|
2019-02-20 00:42:32 +08:00
|
|
|
onClose: (cb: () => void): number => closeCallbacks.push(cb),
|
2019-03-27 02:01:25 +08:00
|
|
|
onMessage: (cb): IDisposable => s2c.event((d) => cb(d)),
|
2019-01-16 02:36:09 +08:00
|
|
|
send: (data): NodeJS.Timer => setTimeout(() => c2s.emit(data), 0),
|
2019-01-12 03:58:31 +08:00
|
|
|
});
|
2019-01-12 03:33:44 +08:00
|
|
|
|
2019-01-12 03:58:31 +08:00
|
|
|
return client;
|
2019-01-12 03:33:44 +08:00
|
|
|
};
|