1
0
Fork 0

fix(test): begin covering child process utils

This commit is contained in:
ssube 2020-03-30 23:37:58 -05:00
parent cdf1acd40f
commit f690cdcac2
Signed by: ssube
GPG Key ID: 3EED7B957D362AF1
8 changed files with 75 additions and 46 deletions

View File

@ -1,11 +0,0 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
[Home](./index.md) &gt; [@apextoaster/js-utils](./js-utils.md) &gt; [ChildOptions](./js-utils.childoptions.md) &gt; [cwd](./js-utils.childoptions.cwd.md)
## ChildOptions.cwd property
<b>Signature:</b>
```typescript
cwd: string;
```

View File

@ -1,11 +0,0 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
[Home](./index.md) &gt; [@apextoaster/js-utils](./js-utils.md) &gt; [ChildOptions](./js-utils.childoptions.md) &gt; [env](./js-utils.childoptions.env.md)
## ChildOptions.env property
<b>Signature:</b>
```typescript
env: Array<NameValuePair<string>>;
```

View File

@ -7,7 +7,7 @@
<b>Signature:</b> <b>Signature:</b>
```typescript ```typescript
export interface ChildOptions export interface ChildOptions extends ChildProcessOptions
``` ```
## Properties ## Properties
@ -16,7 +16,4 @@ export interface ChildOptions
| --- | --- | --- | | --- | --- | --- |
| [args](./js-utils.childoptions.args.md) | <code>Array&lt;string&gt;</code> | | | [args](./js-utils.childoptions.args.md) | <code>Array&lt;string&gt;</code> | |
| [command](./js-utils.childoptions.command.md) | <code>string</code> | | | [command](./js-utils.childoptions.command.md) | <code>string</code> | |
| [cwd](./js-utils.childoptions.cwd.md) | <code>string</code> | |
| [env](./js-utils.childoptions.env.md) | <code>Array&lt;NameValuePair&lt;string&gt;&gt;</code> | |
| [timeout](./js-utils.childoptions.timeout.md) | <code>number</code> | |

View File

@ -1,11 +0,0 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
[Home](./index.md) &gt; [@apextoaster/js-utils](./js-utils.md) &gt; [ChildOptions](./js-utils.childoptions.md) &gt; [timeout](./js-utils.childoptions.timeout.md)
## ChildOptions.timeout property
<b>Signature:</b>
```typescript
timeout: number;
```

View File

@ -7,5 +7,5 @@
<b>Signature:</b> <b>Signature:</b>
```typescript ```typescript
export declare type ChildSpawner = typeof spawn; export declare type ChildSpawner = (command: string, args: Array<string>, options: Partial<ChildProcessOptions>) => ChildStreams;
``` ```

View File

@ -7,14 +7,14 @@
<b>Signature:</b> <b>Signature:</b>
```typescript ```typescript
export declare function waitForChild(child: ChildProcessWithoutNullStreams): Promise<ChildResult>; export declare function waitForChild(child: ChildStreams): Promise<ChildResult>;
``` ```
## Parameters ## Parameters
| Parameter | Type | Description | | Parameter | Type | Description |
| --- | --- | --- | | --- | --- | --- |
| child | <code>ChildProcessWithoutNullStreams</code> | | | child | <code>ChildStreams</code> | |
<b>Returns:</b> <b>Returns:</b>

View File

@ -1,4 +1,4 @@
import { ChildProcessWithoutNullStreams, spawn } from 'child_process'; import { ChildProcessWithoutNullStreams, spawn, ChildProcess } from 'child_process';
import { BaseError } from 'noicejs'; import { BaseError } from 'noicejs';
import { Writable } from 'stream'; import { Writable } from 'stream';
@ -7,28 +7,37 @@ import { ChildProcessError } from '../error/ChildProcessError';
import { encode } from './Buffer'; import { encode } from './Buffer';
import { NameValuePair } from './Map'; import { NameValuePair } from './Map';
export interface ChildOptions { export interface ChildProcessOptions {
args: Array<string>;
command: string;
cwd: string; cwd: string;
env: Array<NameValuePair<string>>; env: Array<NameValuePair<string>>;
timeout: number; timeout: number;
} }
export interface ChildOptions extends ChildProcessOptions {
args: Array<string>;
command: string;
}
export interface ChildResult { export interface ChildResult {
status: number; status: number;
stderr: string; stderr: string;
stdout: string; stdout: string;
} }
export type ChildSpawner = typeof spawn; export type ChildStreams = ChildProcessWithoutNullStreams;
export type ChildSpawner = (
command: string,
args: Array<string>,
options: Partial<ChildProcessOptions>
) => ChildStreams;
const CHILD_ENCODING = 'utf-8'; const CHILD_ENCODING = 'utf-8';
const CHILD_EVENT = 'child process emitted error event'; const CHILD_EVENT = 'child process emitted error event';
const CHILD_STATUS = 'child process exited with error status'; const CHILD_STATUS = 'child process exited with error status';
const CHILD_OUTPUT = 'child process emitted error output'; const CHILD_OUTPUT = 'child process emitted error output';
export function waitForChild(child: ChildProcessWithoutNullStreams): Promise<ChildResult> { export function waitForChild(child: ChildStreams): Promise<ChildResult> {
return new Promise((res, rej) => { return new Promise((res, rej) => {
const stderr: Array<Buffer> = []; const stderr: Array<Buffer> = [];
const stdout: Array<Buffer> = []; const stdout: Array<Buffer> = [];

56
test/utils/TestChild.ts Normal file
View File

@ -0,0 +1,56 @@
import { expect } from 'chai';
import { mustExist, Optional } from '../../src/utils';
import { ChildStreams, waitForChild } from '../../src/utils/Child';
import { describeLeaks, itLeaks } from '../helpers/async';
import { ChildProcessError } from '../../src';
type Closer = (status: number) => Promise<void>;
function createChild(): ChildStreams & { closer: Optional<Closer> } {
return {
closer /* Optional<Closer> */ : undefined,
on(event: string, fn: Closer) {
if (event === 'close') {
this.closer = fn;
}
},
stderr: {
on() {
/* noop */
},
},
stdout: {
on() {
/* noop */
},
},
/* eslint-disable @typescript-eslint/no-explicit-any */
} as any;
}
describeLeaks('child process utils', async () => {
describeLeaks('wait for child helper', async () => {
itLeaks('should read stdout data', async () => {
const child = createChild();
const resultPromise = waitForChild(child);
await mustExist(child.closer)(0);
const result = await resultPromise;
expect(result.status).to.equal(0);
});
itLeaks('should read stderr data');
itLeaks('should resolve on success status');
itLeaks('should reject on failure status', async () => {
const child = createChild();
const resultPromise = waitForChild(child);
await mustExist(child.closer)(1);
return expect(resultPromise).to.eventually.be.rejectedWith(ChildProcessError);
});
});
});