mirror of
https://github.com/LukeHagar/vercel.git
synced 2025-12-10 04:22:12 +00:00
This PR is a follow-up to #8039, which provides an intuitive syntax for writing unit tests for interactive CLI commands. The heart of this is the new `await expect(stream).toOutput(test)` custom Jest matcher, which is intended for use with the mock Client `stdout` and `stderr` stream properties. The `test` is a string that will wait for the stream to output via "data" events until a match is found, or it will timeout (after 3 seconds by default). The timeout error has nice Jest-style formatting so that you can easily identify what was output: <img width="553" alt="Screen Shot 2022-06-29 at 10 33 06 PM" src="https://user-images.githubusercontent.com/71256/176600324-cb1ebecb-e891-42d9-bdc9-4864d3594a8c.png"> Below is an example of a unit test that was added for an interactive `vc login` session: ```typescript it('should allow login via email', async () => { const user = useUser(); const exitCodePromise = login(client); // Wait for login interactive prompt await expect(client.stderr).toOutput(`> Log in to Vercel`); // Move down to "Email" option client.stdin.write('\x1B[B'); // Down arrow client.stdin.write('\x1B[B'); // Down arrow client.stdin.write('\x1B[B'); // Down arrow client.stdin.write('\r'); // Return key // Wait for email input prompt await expect(client.stderr).toOutput('> Enter your email address:'); // Write user email address into prompt client.stdin.write(`${user.email}\n`); // Wait for login success message await expect(client.stderr).toOutput( `Success! Email authentication complete for ${user.email}` ); // Assert that the `login()` command returned 0 exit code await expect(exitCodePromise).resolves.toEqual(0); }); ``` **Note:** as a consequence of this PR, prompts are now written to stderr instead of stdout, so this change _may_ be considered a breaking change, in which case we should tag it for major release.
28 lines
895 B
TypeScript
28 lines
895 B
TypeScript
import { client } from '../../mocks/client';
|
|
import { useUser } from '../../mocks/user';
|
|
import whoami from '../../../src/commands/whoami';
|
|
|
|
describe('whoami', () => {
|
|
it('should reject invalid arguments', async () => {
|
|
client.setArgv('--invalid');
|
|
await expect(whoami(client)).rejects.toThrow(
|
|
'unknown or unexpected option: --invalid'
|
|
);
|
|
});
|
|
|
|
it('should print the Vercel username', async () => {
|
|
const user = useUser();
|
|
const exitCode = await whoami(client);
|
|
expect(exitCode).toEqual(0);
|
|
await expect(client.stderr).toOutput(`> ${user.username}\n`);
|
|
});
|
|
|
|
it('should print only the Vercel username when output is not a TTY', async () => {
|
|
const user = useUser();
|
|
client.stdout.isTTY = false;
|
|
const exitCode = await whoami(client);
|
|
expect(exitCode).toEqual(0);
|
|
await expect(client.stdout).toOutput(`${user.username}\n`);
|
|
});
|
|
});
|