diff --git a/README.md b/README.md index 908cc6f..230f1fb 100644 --- a/README.md +++ b/README.md @@ -63,55 +63,79 @@ The library is bundled and has no dependencies. ## Features -- array mapper - - map elements to keys by order - - skip initial, gather remaining -- async - - defer - - promise timeout - - wait for predicate -- async tracker - - track and log leaking async resources for tests -- buffer -- checklist - - include/exclude mode (whitelist/blacklist) -- child process - - wait for exit and gather output - - write and flush -- env - - check `DEBUG` -- list - - concat lists -- logger - - get test logger (null or console depending on `DEBUG`) -- map - - must get (assertion) - - get or default - - get head from list value - - get head or default - - set or push to key - - merge maps - - push-merge maps - - convert dict to map and vice versa - - normalize map values to lists - - create map from name-value pairs -- maybe - - is nil test (negative nil test) - - count array or maybe - - filter nil from list - - must find (assertion) - - does exist (positive nil test) - - must exist (assertion) - - must default (assertion) -- pid file - - write pid file - - delete pid file -- reflect - - get constructor name - - get methods from prototype chain -- signals - - wait for OS signal -- string - - left pad (please don't import just for this) - - trim with suffix +Features utilities and helpers for: +- Array + - assertions/guards: + - `hasItems` + - `isArray` for both `Array`/`ReadonlyArray` + - `isEmpty` + - `lengthOf` + - conversion + - `filterZip` + - `toArray` +- Array Mapper + - array-to-map converter, reduces an array of values to a map, using an array of keys +- Async + - timed promises + - `defer`/`deferValue` + - `deferUntil` + - `timeout` +- Buffer + - concatenation + - `concat` + - `encode` +- Checklist + - allow/deny list +- Child Process + - `childResult` + - `writeInput` +- Env Vars + - `isDebug` +- Logger + - test logging helpers +- Map + - types + - `MapLike` + - assertions/guards: + - `mustGet` + - null-safe helpers + - `getOrDefault` + - helpers for `Map>` + - `getHead`/`getHeadOrDefault` + - `setOrPush` + - concat/merge + - `mergeMap` + - `pushMergeMap` + - conversion + - `entriesOf` + - `makeDict` + - `makeMap` + - `pairsToMap` +- Math + - predicates for functional methods + - `sum` +- Maybe + - types + - `Maybe` + - `None` + - assertions/guards + - `doesExist` + - `mustExist` + - `mustDefault` + - `mustFind` + - `removeNone` + - null-safe helpers + - `isNone` + - `isSome` +- Predicate + - types for functional methods +- Reflect + - `getConstructor` + - `getMethods` +- Signal + - wait for OS signal + - `signal` +- String + - `leftPad` + - `trim` with suffix diff --git a/docs/api/js-utils.deferuntil.md b/docs/api/js-utils.deferuntil.md new file mode 100644 index 0000000..1d41c32 --- /dev/null +++ b/docs/api/js-utils.deferuntil.md @@ -0,0 +1,30 @@ + + +[Home](./index.md) > [@apextoaster/js-utils](./js-utils.md) > [deferUntil](./js-utils.deferuntil.md) + +## deferUntil() function + +Reject after a set number of attempts if the given predicate does not return true. + +Signature: + +```typescript +export declare function deferUntil(cb: PredicateC0, step: number, tries: number): Promise; +``` + +## Parameters + +| Parameter | Type | Description | +| --- | --- | --- | +| cb | PredicateC0 | | +| step | number | | +| tries | number | | + +Returns: + +Promise<void> + +## Exceptions + +TimeoutError + diff --git a/docs/api/js-utils.externalmodule.data.md b/docs/api/js-utils.externalmodule.data.md deleted file mode 100644 index 8cc84dc..0000000 --- a/docs/api/js-utils.externalmodule.data.md +++ /dev/null @@ -1,11 +0,0 @@ - - -[Home](./index.md) > [@apextoaster/js-utils](./js-utils.md) > [ExternalModule](./js-utils.externalmodule.md) > [data](./js-utils.externalmodule.data.md) - -## ExternalModule.data property - -Signature: - -```typescript -data?: unknown; -``` diff --git a/docs/api/js-utils.externalmodule.export.md b/docs/api/js-utils.externalmodule.export.md deleted file mode 100644 index 7719542..0000000 --- a/docs/api/js-utils.externalmodule.export.md +++ /dev/null @@ -1,11 +0,0 @@ - - -[Home](./index.md) > [@apextoaster/js-utils](./js-utils.md) > [ExternalModule](./js-utils.externalmodule.md) > [export](./js-utils.externalmodule.export.md) - -## ExternalModule.export property - -Signature: - -```typescript -export: string; -``` diff --git a/docs/api/js-utils.externalmodule.md b/docs/api/js-utils.externalmodule.md deleted file mode 100644 index e17c066..0000000 --- a/docs/api/js-utils.externalmodule.md +++ /dev/null @@ -1,20 +0,0 @@ - - -[Home](./index.md) > [@apextoaster/js-utils](./js-utils.md) > [ExternalModule](./js-utils.externalmodule.md) - -## ExternalModule interface - -Signature: - -```typescript -export interface ExternalModule -``` - -## Properties - -| Property | Type | Description | -| --- | --- | --- | -| [data?](./js-utils.externalmodule.data.md) | unknown | (Optional) | -| [export](./js-utils.externalmodule.export.md) | string | | -| [require](./js-utils.externalmodule.require.md) | string | | - diff --git a/docs/api/js-utils.externalmodule.require.md b/docs/api/js-utils.externalmodule.require.md deleted file mode 100644 index a499da4..0000000 --- a/docs/api/js-utils.externalmodule.require.md +++ /dev/null @@ -1,11 +0,0 @@ - - -[Home](./index.md) > [@apextoaster/js-utils](./js-utils.md) > [ExternalModule](./js-utils.externalmodule.md) > [require](./js-utils.externalmodule.require.md) - -## ExternalModule.require property - -Signature: - -```typescript -require: string; -``` diff --git a/docs/api/js-utils.md b/docs/api/js-utils.md index 6a85143..7567205 100644 --- a/docs/api/js-utils.md +++ b/docs/api/js-utils.md @@ -27,10 +27,12 @@ | Function | Description | | --- | --- | +| [childResult(child)](./js-utils.childresult.md) | Wait for a child process to exit, collecting output, errors, and exit status. | | [concat(chunks)](./js-utils.concat.md) | Concatenate a list of buffers. | | [constructorName(val)](./js-utils.constructorname.md) | Get the constructor name from an instance. | | [defaultWhen(condition, items)](./js-utils.defaultwhen.md) | Return the first element when condition is true and the second element when condition is false. | | [defer(ms)](./js-utils.defer.md) | Resolve after a set amount of time. | +| [deferUntil(cb, step, tries)](./js-utils.deferuntil.md) | Reject after a set number of attempts if the given predicate does not return true. | | [deferValue(ms, val)](./js-utils.defervalue.md) | | | [doesExist(val)](./js-utils.doesexist.md) | Check if a variable is some T. | | [encode(chunks, encoding)](./js-utils.encode.md) | Concatenate then encode a list of buffers. | @@ -77,14 +79,15 @@ | [removeNone(list)](./js-utils.removenone.md) | Remove any null or undefined items from the list. | | [setOrPush(map, key, val)](./js-utils.setorpush.md) | Set a map key to a new array or push to the existing value. | | [signal(signals)](./js-utils.signal.md) | | -| [spyLogger(spies)](./js-utils.spylogger.md) | Create a spy logger using the provided methods, which returns itself as a child. | +| [spyLogger(spies)](./js-utils.spylogger.md) | Create a spy logger using the provided methods, which returns itself as a child. ensure all methods are present by extending null logger | | [sum(a, b)](./js-utils.sum.md) | Add numbers. PredicateR2<number, number> | -| [timeout(ms, oper)](./js-utils.timeout.md) | Reject after a set amount of time if the original promise has not yet resolved. | +| [timeout(ms, inner)](./js-utils.timeout.md) | Reject after a set amount of time if the original promise has not yet resolved. | | [toArray(val)](./js-utils.toarray.md) | | | [toArray(val)](./js-utils.toarray_1.md) | | | [trim(val, max, tail)](./js-utils.trim.md) | | -| [waitFor(cb, step, count)](./js-utils.waitfor.md) | Reject after a set number of attempts if the given predicate does not return true. | -| [waitForChild(child)](./js-utils.waitforchild.md) | Wait for a child process to exit, collecting output, errors, and exit status. | +| [waitFor(cb, step, tries)](./js-utils.waitfor.md) | | +| [waitForChild(child)](./js-utils.waitforchild.md) | | +| [writeInput(stream, value)](./js-utils.writeinput.md) | | | [writeValue(stream, value)](./js-utils.writevalue.md) | | ## Interfaces @@ -96,7 +99,6 @@ | [ChildOptions](./js-utils.childoptions.md) | | | [ChildResult](./js-utils.childresult.md) | | | [Dict](./js-utils.dict.md) | | -| [ExternalModule](./js-utils.externalmodule.md) | | ## Variables @@ -114,7 +116,6 @@ | [ChildSpawner](./js-utils.childspawner.md) | | | [MapLike](./js-utils.maplike.md) | A Map or dictionary object with string keys and TVal values. | | [Maybe](./js-utils.maybe.md) | Value that may be nil. | -| [ModuleCtor](./js-utils.modulector.md) | | | [Nil](./js-utils.nil.md) | Old name for None. | | [None](./js-utils.none.md) | Unset value. | | [Optional](./js-utils.optional.md) | Old name for Maybe. | diff --git a/docs/api/js-utils.modulector.md b/docs/api/js-utils.modulector.md deleted file mode 100644 index a6d09d4..0000000 --- a/docs/api/js-utils.modulector.md +++ /dev/null @@ -1,11 +0,0 @@ - - -[Home](./index.md) > [@apextoaster/js-utils](./js-utils.md) > [ModuleCtor](./js-utils.modulector.md) - -## ModuleCtor type - -Signature: - -```typescript -export declare type ModuleCtor = new (data: unknown) => Module; -``` diff --git a/docs/api/js-utils.spylogger.md b/docs/api/js-utils.spylogger.md index d4cc34f..9d85a41 100644 --- a/docs/api/js-utils.spylogger.md +++ b/docs/api/js-utils.spylogger.md @@ -6,6 +6,8 @@ Create a spy logger using the provided methods, which returns itself as a child. + ensure all methods are present by extending null logger + Signature: ```typescript diff --git a/docs/api/js-utils.timeout.md b/docs/api/js-utils.timeout.md index 8f2a00a..637f023 100644 --- a/docs/api/js-utils.timeout.md +++ b/docs/api/js-utils.timeout.md @@ -9,7 +9,7 @@ Reject after a set amount of time if the original promise has not yet resolved. Signature: ```typescript -export declare function timeout(ms: number, oper: Promise): Promise; +export declare function timeout(ms: number, inner: Promise): Promise; ``` ## Parameters @@ -17,7 +17,7 @@ export declare function timeout(ms: number, oper: Promise): Promise; | Parameter | Type | Description | | --- | --- | --- | | ms | number | | -| oper | Promise<T> | | +| inner | Promise<T> | | Returns: diff --git a/docs/api/js-utils.waitfor.md b/docs/api/js-utils.waitfor.md index 94118e6..5414beb 100644 --- a/docs/api/js-utils.waitfor.md +++ b/docs/api/js-utils.waitfor.md @@ -4,12 +4,14 @@ ## waitFor() function -Reject after a set number of attempts if the given predicate does not return true. +> Warning: This API is now obsolete. +> +> Signature: ```typescript -export declare function waitFor(cb: PredicateC0, step: number, count: number): Promise; +export declare function waitFor(cb: PredicateC0, step: number, tries: number): Promise; ``` ## Parameters @@ -18,13 +20,9 @@ export declare function waitFor(cb: PredicateC0, step: number, count: number): P | --- | --- | --- | | cb | PredicateC0 | | | step | number | | -| count | number | | +| tries | number | | Returns: Promise<void> -## Exceptions - -TimeoutError - diff --git a/docs/api/js-utils.waitforchild.md b/docs/api/js-utils.waitforchild.md index 36c7888..fb964e5 100644 --- a/docs/api/js-utils.waitforchild.md +++ b/docs/api/js-utils.waitforchild.md @@ -4,7 +4,9 @@ ## waitForChild() function -Wait for a child process to exit, collecting output, errors, and exit status. +> Warning: This API is now obsolete. +> +> Signature: diff --git a/docs/api/js-utils.writeinput.md b/docs/api/js-utils.writeinput.md new file mode 100644 index 0000000..f26808b --- /dev/null +++ b/docs/api/js-utils.writeinput.md @@ -0,0 +1,23 @@ + + +[Home](./index.md) > [@apextoaster/js-utils](./js-utils.md) > [writeInput](./js-utils.writeinput.md) + +## writeInput() function + +Signature: + +```typescript +export declare function writeInput(stream: Writable, value: string): Promise; +``` + +## Parameters + +| Parameter | Type | Description | +| --- | --- | --- | +| stream | Writable | | +| value | string | | + +Returns: + +Promise<boolean> + diff --git a/docs/api/js-utils.writevalue.md b/docs/api/js-utils.writevalue.md index aac6844..ff3c466 100644 --- a/docs/api/js-utils.writevalue.md +++ b/docs/api/js-utils.writevalue.md @@ -4,6 +4,10 @@ ## writeValue() function +> Warning: This API is now obsolete. +> +> + Signature: ```typescript diff --git a/src/Async.ts b/src/Async.ts index 7031e74..905e7d8 100644 --- a/src/Async.ts +++ b/src/Async.ts @@ -25,14 +25,14 @@ export function deferValue(ms: number, val: T): Promise { * Reject after a set amount of time if the original promise has not yet resolved. * @public */ -export function timeout(ms: number, oper: Promise): Promise { +export function timeout(ms: number, inner: Promise): Promise { const limit = new Promise((_res, rej) => { setTimeout(() => { rej(new TimeoutError()); }, ms); }); - return Promise.race([limit, oper]); + return Promise.race([limit, inner]); } /** @@ -40,15 +40,23 @@ export function timeout(ms: number, oper: Promise): Promise { * @public * @throws TimeoutError */ -export async function waitFor(cb: PredicateC0, step: number, count: number): Promise { - let accum = 0; - while (accum < count) { +export async function deferUntil(cb: PredicateC0, step: number, tries: number): Promise { + let count = 0; + while (count < tries) { await defer(step); if (cb()) { return; } - accum += 1; + count += 1; } throw new TimeoutError(); } + +/** + * @public + * @deprecated + */ +export async function waitFor(cb: PredicateC0, step: number, tries: number): Promise { + return deferUntil(cb, step, tries); +} diff --git a/src/Child.ts b/src/Child.ts index dfb6f5a..93e026b 100644 --- a/src/Child.ts +++ b/src/Child.ts @@ -37,7 +37,7 @@ const CHILD_OUTPUT = 'child process emitted error output'; * * @public */ -export function waitForChild(child: ChildStreams): Promise { +export function childResult(child: ChildStreams): Promise { return new Promise((res, rej) => { const stderr: Array = []; const stdout: Array = []; @@ -78,7 +78,15 @@ export function waitForChild(child: ChildStreams): Promise { }); } -export function writeValue(stream: Writable, value: string): Promise { +/** + * @public + * @deprecated + */ +export function waitForChild(child: ChildStreams): Promise { + return childResult(child); +} + +export function writeInput(stream: Writable, value: string): Promise { return new Promise((res, rej) => { stream.write(value, (err: Maybe) => { if (doesExist(err)) { @@ -91,3 +99,11 @@ export function writeValue(stream: Writable, value: string): Promise { }); }); } + +/** + * @public + * @deprecated + */ +export function writeValue(stream: Writable, value: string): Promise { + return writeInput(stream, value); +} diff --git a/src/ExternalModule.ts b/src/ExternalModule.ts deleted file mode 100644 index 0f2671c..0000000 --- a/src/ExternalModule.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { Module } from 'noicejs'; - -export interface ExternalModule { - data?: unknown; - export: string; - require: string; -} - -export type ModuleCtor = new (data: unknown) => Module; - -export function isModule(it: object): it is ModuleCtor { - const p = Reflect.getPrototypeOf(it); - return p === Module || p instanceof Module; -} diff --git a/src/Logger.ts b/src/Logger.ts index 60eabf5..2f3dfac 100644 --- a/src/Logger.ts +++ b/src/Logger.ts @@ -14,11 +14,14 @@ export function getTestLogger(verbose = false): Logger { /** * Create a spy logger using the provided methods, which returns itself as a child. + * + * @todo ensure all methods are present by extending null logger */ export function spyLogger(spies: Partial): Logger { const logger = { ...spies, child: () => logger, } as Logger; + return logger; } diff --git a/src/index.ts b/src/index.ts index 7bad082..adf14a9 100644 --- a/src/index.ts +++ b/src/index.ts @@ -24,6 +24,7 @@ export { defer, deferValue, timeout, + deferUntil, waitFor, } from './Async'; export { @@ -40,16 +41,14 @@ export { ChildOptions, ChildResult, ChildSpawner, + childResult, waitForChild, + writeInput, writeValue, } from './Child'; export { isDebug } from './Env'; -export { - ExternalModule, - ModuleCtor, -} from './ExternalModule'; export { getTestLogger, spyLogger, diff --git a/test/utils/TestChild.ts b/test/utils/TestChild.ts index 9867090..1e1bb62 100644 --- a/test/utils/TestChild.ts +++ b/test/utils/TestChild.ts @@ -1,7 +1,7 @@ import { expect } from 'chai'; import { ChildProcessError } from '../../src'; -import { ChildStreams, waitForChild } from '../../src/Child'; +import { ChildStreams, childResult } from '../../src/Child'; import { Maybe, mustExist } from '../../src/Maybe'; type Closer = (status: number) => Promise; @@ -33,7 +33,7 @@ describe('child process utils', async () => { it('should read stdout data', async () => { const child = createChild(); - const resultPromise = waitForChild(child); + const resultPromise = childResult(child); await mustExist(child.closer)(0); const result = await resultPromise; @@ -46,7 +46,7 @@ describe('child process utils', async () => { it('should reject on failure status', async () => { const child = createChild(); - const resultPromise = waitForChild(child); + const resultPromise = childResult(child); await mustExist(child.closer)(1); return expect(resultPromise).to.eventually.be.rejectedWith(ChildProcessError);