mirror of
https://github.com/coder/code-server.git
synced 2024-12-04 15:00:38 +08:00
dc2253e718
* Replace evaluations with proxies and messages * Return proxies synchronously Otherwise events can be lost. * Ensure events cannot be missed * Refactor remaining fills * Use more up-to-date version of util For callbackify. * Wait for dispose to come back before removing This prevents issues with the "done" event not always being the last event fired. For example a socket might close and then end, but only if the caller called end. * Remove old node-pty tests * Fix emitting events twice on duplex streams * Preserve environment when spawning processes * Throw a better error if the proxy doesn't exist * Remove rimraf dependency from ide * Update net.Server.listening * Use exit event instead of killed Doesn't look like killed is even a thing. * Add response timeout to server * Fix trash * Require node-pty & spdlog after they get unpackaged This fixes an error when running in the binary. * Fix errors in down emitter preventing reconnecting * Fix disposing proxies when nothing listens to "error" event * Refactor event tests to use jest.fn() * Reject proxy call when disconnected Otherwise it'll wait for the timeout which is a waste of time since we already know the connection is dead. * Use nbin for binary packaging * Remove additional module requires * Attempt to remove require for local bootstrap-fork * Externalize fsevents
100 lines
2.5 KiB
TypeScript
100 lines
2.5 KiB
TypeScript
import { IPty } from "node-pty";
|
|
import { Module } from "../src/common/proxy";
|
|
import { createClient } from "./helpers";
|
|
|
|
describe("node-pty", () => {
|
|
const client = createClient();
|
|
const pty = client.modules[Module.NodePty];
|
|
|
|
/**
|
|
* Returns a function that when called returns a promise that resolves with
|
|
* the next chunk of data from the process.
|
|
*/
|
|
const promisifyData = (proc: IPty): (() => Promise<string>) => {
|
|
// Use a persistent callback instead of creating it in the promise since
|
|
// otherwise we could lose data that comes in while no promise is listening.
|
|
let onData: (() => void) | undefined;
|
|
let buffer: string | undefined;
|
|
proc.on("data", (data) => {
|
|
// Remove everything that isn't a letter, number, or $ to avoid issues
|
|
// with ANSI escape codes printing inside the test output.
|
|
buffer = (buffer || "") + data.toString().replace(/[^a-zA-Z0-9$]/g, "");
|
|
if (onData) {
|
|
onData();
|
|
}
|
|
});
|
|
|
|
return (): Promise<string> => new Promise((resolve): void => {
|
|
onData = (): void => {
|
|
if (typeof buffer !== "undefined") {
|
|
const data = buffer;
|
|
buffer = undefined;
|
|
onData = undefined;
|
|
resolve(data);
|
|
}
|
|
};
|
|
onData();
|
|
});
|
|
};
|
|
|
|
it("should create shell", async () => {
|
|
// Setting the config file to something that shouldn't exist so the test
|
|
// isn't affected by custom configuration.
|
|
const proc = pty.spawn("/bin/bash", ["--rcfile", "/tmp/test/nope/should/not/exist"], {
|
|
cols: 100,
|
|
rows: 10,
|
|
});
|
|
|
|
const getData = promisifyData(proc);
|
|
|
|
// Wait for [hostname@user]$
|
|
let data = "";
|
|
while (!data.includes("$")) {
|
|
data = await getData();
|
|
}
|
|
|
|
proc.kill();
|
|
|
|
await new Promise((resolve): void => {
|
|
proc.on("exit", resolve);
|
|
});
|
|
});
|
|
|
|
it("should resize", async () => {
|
|
// Requires the `tput lines` cmd to be available.
|
|
// Setting the config file to something that shouldn't exist so the test
|
|
// isn't affected by custom configuration.
|
|
const proc = pty.spawn("/bin/bash", ["--rcfile", "/tmp/test/nope/should/not/exist"], {
|
|
cols: 10,
|
|
rows: 912,
|
|
});
|
|
|
|
const getData = promisifyData(proc);
|
|
|
|
proc.write("tput lines\n");
|
|
|
|
let data = "";
|
|
while (!data.includes("912")) {
|
|
data = await getData();
|
|
}
|
|
proc.resize(10, 219);
|
|
proc.write("tput lines\n");
|
|
|
|
while (!data.includes("219")) {
|
|
data = await getData();
|
|
}
|
|
|
|
proc.kill();
|
|
await new Promise((resolve): void => {
|
|
proc.on("exit", resolve);
|
|
});
|
|
});
|
|
|
|
it("should dispose", (done) => {
|
|
setTimeout(() => {
|
|
client.dispose();
|
|
done();
|
|
}, 100);
|
|
});
|
|
});
|