remove(utils): use js-utils lib
This commit is contained in:
parent
186f6dfa98
commit
1121b112cc
|
@ -33,6 +33,8 @@
|
|||
"author": "ssube",
|
||||
"license": "MIT",
|
||||
"devDependencies": {
|
||||
"@apextoaster/js-utils": "^0.1.7",
|
||||
"@apextoaster/js-yaml-schema": "^0.2.0",
|
||||
"@istanbuljs/nyc-config-typescript": "1.0.1",
|
||||
"@microsoft/api-documenter": "7.7.16",
|
||||
"@microsoft/api-extractor": "7.7.12",
|
||||
|
|
|
@ -1,16 +1,13 @@
|
|||
import { doesExist, NotFoundError } from '@apextoaster/js-utils';
|
||||
import { Stream } from 'bunyan';
|
||||
import { isString } from 'lodash';
|
||||
import { LogLevel } from 'noicejs';
|
||||
import { join } from 'path';
|
||||
|
||||
import { NotFoundError } from '../error/NotFoundError';
|
||||
import { YamlParser } from '../parser/YamlParser';
|
||||
import { readFile } from '../source';
|
||||
import { doesExist } from '../utils';
|
||||
import { CONFIG_ENV, CONFIG_SCHEMA } from './schema';
|
||||
import { includeSchema } from './type/Include';
|
||||
|
||||
includeSchema.schema = CONFIG_SCHEMA;
|
||||
export const CONFIG_ENV = 'SALTY_HOME';
|
||||
|
||||
export interface ConfigData {
|
||||
data: {
|
||||
|
|
|
@ -1,14 +0,0 @@
|
|||
import { DEFAULT_SAFE_SCHEMA, Schema } from 'js-yaml';
|
||||
|
||||
import { envType } from './type/Env';
|
||||
import { includeType } from './type/Include';
|
||||
import { regexpType } from './type/Regexp';
|
||||
import { streamType } from './type/Stream';
|
||||
|
||||
export const CONFIG_ENV = 'SALTY_HOME';
|
||||
export const CONFIG_SCHEMA = Schema.create([DEFAULT_SAFE_SCHEMA], [
|
||||
envType,
|
||||
includeType,
|
||||
regexpType,
|
||||
streamType,
|
||||
]);
|
|
@ -1,17 +0,0 @@
|
|||
import { Type as YamlType } from 'js-yaml';
|
||||
|
||||
import { NotFoundError } from '../../error/NotFoundError';
|
||||
|
||||
export const envType = new YamlType('!env', {
|
||||
kind: 'scalar',
|
||||
resolve(name: string) {
|
||||
if (Reflect.has(process.env, name)) {
|
||||
return true;
|
||||
} else {
|
||||
throw new NotFoundError(`environment variable not found: ${name}`);
|
||||
}
|
||||
},
|
||||
construct(name: string) {
|
||||
return Reflect.get(process.env, name);
|
||||
},
|
||||
});
|
|
@ -1,47 +0,0 @@
|
|||
import { existsSync, readFileSync, realpathSync } from 'fs';
|
||||
import { SAFE_SCHEMA, safeLoad, Type as YamlType } from 'js-yaml';
|
||||
import { BaseError } from 'noicejs';
|
||||
import { join } from 'path';
|
||||
|
||||
import { NotFoundError } from '../../error/NotFoundError';
|
||||
|
||||
// work around the circular dependency by setting the schema later
|
||||
export const includeSchema = {
|
||||
schema: SAFE_SCHEMA,
|
||||
};
|
||||
|
||||
export const includeType = new YamlType('!include', {
|
||||
kind: 'scalar',
|
||||
resolve(path: string) {
|
||||
try {
|
||||
const canonical = resolvePath(path);
|
||||
// throws in node 11+
|
||||
if (existsSync(canonical)) {
|
||||
return true;
|
||||
} else {
|
||||
throw new NotFoundError('included file does not exist');
|
||||
}
|
||||
} catch (err) {
|
||||
throw new NotFoundError('included file does not exist', err);
|
||||
}
|
||||
},
|
||||
construct(path: string): unknown {
|
||||
try {
|
||||
return safeLoad(readFileSync(resolvePath(path), {
|
||||
encoding: 'utf-8',
|
||||
}), {
|
||||
schema: includeSchema.schema,
|
||||
});
|
||||
} catch (err) {
|
||||
throw new BaseError('error including file', err);
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
export function resolvePath(path: string): string {
|
||||
if (path[0] === '.') {
|
||||
return realpathSync(join(__dirname, path));
|
||||
} else {
|
||||
return realpathSync(path);
|
||||
}
|
||||
}
|
|
@ -1,21 +0,0 @@
|
|||
import { Type as YamlType } from 'js-yaml';
|
||||
import { isNil } from 'lodash';
|
||||
|
||||
import { InvalidArgumentError } from '../../error/InvalidArgumentError';
|
||||
|
||||
export const REGEXP_REGEXP = /^\/(.+)\/([gimsuy]*)$/;
|
||||
|
||||
export const regexpType = new YamlType('!regexp', {
|
||||
kind: 'scalar',
|
||||
resolve(value: string) {
|
||||
return REGEXP_REGEXP.test(value);
|
||||
},
|
||||
construct(value: string): RegExp {
|
||||
const match = REGEXP_REGEXP.exec(value);
|
||||
if (isNil(match)) {
|
||||
throw new InvalidArgumentError('invalid regexp');
|
||||
}
|
||||
const [/* input */, expr, flags] = Array.from(match);
|
||||
return new RegExp(expr, flags);
|
||||
},
|
||||
});
|
|
@ -1,22 +0,0 @@
|
|||
import { Type as YamlType } from 'js-yaml';
|
||||
|
||||
import { NotFoundError } from '../../error/NotFoundError';
|
||||
|
||||
const ALLOWED_STREAMS = new Set([
|
||||
'stdout',
|
||||
'stderr',
|
||||
]);
|
||||
|
||||
export const streamType = new YamlType('!stream', {
|
||||
kind: 'scalar',
|
||||
resolve(name: string) {
|
||||
if (ALLOWED_STREAMS.has(name) && Reflect.has(process, name)) {
|
||||
return true;
|
||||
} else {
|
||||
throw new NotFoundError(`process stream not found: ${name}`);
|
||||
}
|
||||
},
|
||||
construct(name: string) {
|
||||
return Reflect.get(process, name);
|
||||
},
|
||||
});
|
|
@ -1,7 +0,0 @@
|
|||
import { BaseError } from 'noicejs';
|
||||
|
||||
export class InvalidArgumentError extends BaseError {
|
||||
constructor(msg = 'invalid argument passed', ...nested: Array<Error>) {
|
||||
super(msg, ...nested);
|
||||
}
|
||||
}
|
|
@ -1,7 +0,0 @@
|
|||
import { BaseError } from 'noicejs';
|
||||
|
||||
export class NotFoundError extends BaseError {
|
||||
constructor(msg = 'value not found', ...nested: Array<Error>) {
|
||||
super(msg, ...nested);
|
||||
}
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
import { CONFIG_SCHEMA } from '@apextoaster/js-yaml-schema';
|
||||
import { safeDump, safeLoadAll } from 'js-yaml';
|
||||
|
||||
import { CONFIG_SCHEMA } from '../config/schema';
|
||||
import { Parser } from '../parser';
|
||||
|
||||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
import { hasItems } from '@apextoaster/js-utils';
|
||||
import { applyDiff, diff } from 'deep-diff';
|
||||
import { cloneDeep } from 'lodash';
|
||||
|
||||
import { Rule } from '.';
|
||||
import { hasItems } from '../utils';
|
||||
import { Visitor } from '../visitor';
|
||||
import { VisitorContext } from '../visitor/VisitorContext';
|
||||
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
import { doesExist, hasItems } from '@apextoaster/js-utils';
|
||||
import { ErrorObject, ValidateFunction } from 'ajv';
|
||||
import { cloneDeep, defaultTo, isNil } from 'lodash';
|
||||
import { LogLevel } from 'noicejs';
|
||||
|
||||
import { Rule, RuleData } from '.';
|
||||
import { doesExist, hasItems } from '../utils';
|
||||
import { Visitor, VisitorError, VisitorResult } from '../visitor';
|
||||
import { VisitorContext } from '../visitor/VisitorContext';
|
||||
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
import { doesExist, ensureArray } from '@apextoaster/js-utils';
|
||||
import { ValidateFunction } from 'ajv';
|
||||
import { Dictionary, intersection } from 'lodash';
|
||||
import { Minimatch } from 'minimatch';
|
||||
|
@ -7,7 +8,6 @@ import recursive from 'recursive-readdir';
|
|||
import ruleSchemaData from '../../rules/salty-dog.yml';
|
||||
import { YamlParser } from '../parser/YamlParser';
|
||||
import { readFile } from '../source';
|
||||
import { doesExist, ensureArray } from '../utils';
|
||||
import { VisitorResult } from '../visitor';
|
||||
import { VisitorContext } from '../visitor/VisitorContext';
|
||||
import { SchemaRule } from './SchemaRule';
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { isNil } from '@apextoaster/js-utils';
|
||||
import { readdir, readFile as readBack, writeFile as writeBack } from 'fs';
|
||||
import { isNil } from 'lodash';
|
||||
import { promisify } from 'util';
|
||||
|
||||
export const FILE_ENCODING = 'utf-8';
|
||||
|
|
|
@ -1,29 +0,0 @@
|
|||
import { isNil } from 'lodash';
|
||||
|
||||
/* eslint-disable @typescript-eslint/ban-types */
|
||||
|
||||
export function doesExist<T>(val: T | null | undefined): val is T {
|
||||
return !isNil(val);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test if a value is an array with some items (length > 0).
|
||||
*
|
||||
* This is not a general replacement for `.length > 0`, since it is also a typeguard:
|
||||
* `if (hasItems(val)) else { val }` will complain that `val` is `never` in the `else`
|
||||
* branch, since it was proven not to be an array by this function, even if `val` is
|
||||
* simply empty.
|
||||
*/
|
||||
export function hasItems<T>(val: Array<T> | null | undefined): val is Array<T>;
|
||||
export function hasItems<T>(val: ReadonlyArray<T> | null | undefined): val is ReadonlyArray<T>;
|
||||
export function hasItems<T>(val: ReadonlyArray<T> | null | undefined): val is ReadonlyArray<T> {
|
||||
return (Array.isArray(val) && val.length > 0);
|
||||
}
|
||||
|
||||
export function ensureArray<T>(val: Array<T> | undefined): Array<T> {
|
||||
if (isNil(val)) {
|
||||
return [];
|
||||
} else {
|
||||
return Array.from(val);
|
||||
}
|
||||
}
|
|
@ -1,9 +1,9 @@
|
|||
import { doesExist, hasItems } from '@apextoaster/js-utils';
|
||||
import Ajv from 'ajv';
|
||||
import { JSONPath } from 'jsonpath-plus';
|
||||
import { Logger } from 'noicejs';
|
||||
|
||||
import { VisitorError, VisitorResult } from '.';
|
||||
import { doesExist, hasItems } from '../utils';
|
||||
|
||||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
import { NotFoundError } from '@apextoaster/js-utils';
|
||||
import { expect } from 'chai';
|
||||
import { join } from 'path';
|
||||
|
||||
import { loadConfig, readConfig } from '../../src/config';
|
||||
import { NotFoundError } from '../../src/error/NotFoundError';
|
||||
import { describeLeaks, itLeaks } from '../helpers/async';
|
||||
|
||||
describeLeaks('load config helper', async () => {
|
||||
|
|
|
@ -1,22 +0,0 @@
|
|||
import { expect } from 'chai';
|
||||
|
||||
import { envType } from '../../../src/config/type/Env';
|
||||
import { NotFoundError } from '../../../src/error/NotFoundError';
|
||||
import { VERSION_INFO } from '../../../src/version';
|
||||
import { describeLeaks, itLeaks } from '../../helpers/async';
|
||||
|
||||
describeLeaks('env config type', async () => {
|
||||
itLeaks('should throw on missing variables', async () => {
|
||||
expect(() => {
|
||||
envType.resolve('DOES_NOT_EXIST_');
|
||||
}).to.throw(NotFoundError);
|
||||
});
|
||||
|
||||
itLeaks('should resolve existing variables', async () => {
|
||||
expect(envType.resolve('CI_COMMIT_SHA')).to.equal(true);
|
||||
});
|
||||
|
||||
itLeaks('should construct a value from variables', async () => {
|
||||
expect(envType.construct('CI_COMMIT_SHA')).to.equal(VERSION_INFO.git.commit);
|
||||
});
|
||||
});
|
|
@ -1,48 +0,0 @@
|
|||
import { expect } from 'chai';
|
||||
import { BaseError } from 'noicejs';
|
||||
import { join } from 'path';
|
||||
|
||||
import { includeType, resolvePath } from '../../../src/config/type/Include';
|
||||
import { NotFoundError } from '../../../src/error/NotFoundError';
|
||||
import { describeLeaks, itLeaks } from '../../helpers/async';
|
||||
|
||||
const TEST_ROOT = '../test/config/type';
|
||||
const CONFIG_MISSING = 'missing.yml';
|
||||
|
||||
describeLeaks('include config type', async () => {
|
||||
itLeaks('should resolve existing files', async () => {
|
||||
expect(includeType.resolve(join(TEST_ROOT, 'include.yml'))).to.equal(true);
|
||||
});
|
||||
|
||||
itLeaks('should throw when resolving missing files', async () => {
|
||||
expect(() => {
|
||||
includeType.resolve(join(TEST_ROOT, CONFIG_MISSING));
|
||||
}).to.throw(NotFoundError);
|
||||
});
|
||||
|
||||
itLeaks('should construct data from file', async () => {
|
||||
expect(includeType.construct(join(TEST_ROOT, 'include.yml'))).to.equal('test');
|
||||
});
|
||||
|
||||
itLeaks('should throw when constructing missing files', async () => {
|
||||
expect(() => {
|
||||
includeType.construct(join(TEST_ROOT, CONFIG_MISSING));
|
||||
}).to.throw(BaseError);
|
||||
});
|
||||
|
||||
itLeaks('should throw when resolving missing files', async () => {
|
||||
expect(() => {
|
||||
includeType.resolve(join(TEST_ROOT, CONFIG_MISSING));
|
||||
}).to.throw(BaseError);
|
||||
});
|
||||
});
|
||||
|
||||
describeLeaks('resolve path helper', async () => {
|
||||
itLeaks('should resolve relative paths relative to dirname', async () => {
|
||||
expect(resolvePath('./index.js')).to.equal(join(__dirname, 'index.js'));
|
||||
});
|
||||
|
||||
itLeaks('should resolve absolute paths to themselves', async () => {
|
||||
expect(resolvePath('/')).to.equal('/');
|
||||
});
|
||||
});
|
|
@ -1,32 +0,0 @@
|
|||
import { expect } from 'chai';
|
||||
|
||||
import { regexpType } from '../../../src/config/type/Regexp';
|
||||
import { InvalidArgumentError } from '../../../src/error/InvalidArgumentError';
|
||||
import { describeLeaks, itLeaks } from '../../helpers/async';
|
||||
|
||||
describeLeaks('regexp config type', async () => {
|
||||
itLeaks('match slashed strings', async () => {
|
||||
expect(regexpType.resolve('/foo/')).to.equal(true);
|
||||
});
|
||||
|
||||
itLeaks('should match flags', async () => {
|
||||
const regexp: RegExp = regexpType.construct('/foo/g');
|
||||
expect(regexp.flags).to.equal('g');
|
||||
});
|
||||
|
||||
itLeaks('should not match bare strings', async () => {
|
||||
expect(regexpType.resolve('foo')).to.equal(false);
|
||||
});
|
||||
|
||||
itLeaks('should not match invalid flags', async () => {
|
||||
expect(regexpType.resolve('/foo/notrealflags')).to.equal(false);
|
||||
});
|
||||
|
||||
itLeaks('should not match regexp embedded in a longer string', async () => {
|
||||
expect(regexpType.resolve('some/regexp/with-padding')).to.equal(false);
|
||||
});
|
||||
|
||||
itLeaks('should throw when constructing an invalid regexp', async () => {
|
||||
expect(() => regexpType.construct('/foo/notrealflags')).to.throw(InvalidArgumentError);
|
||||
});
|
||||
});
|
|
@ -1,38 +0,0 @@
|
|||
import { expect } from 'chai';
|
||||
|
||||
import { streamType } from '../../../src/config/type/Stream';
|
||||
import { NotFoundError } from '../../../src/error/NotFoundError';
|
||||
import { describeLeaks, itLeaks } from '../../helpers/async';
|
||||
|
||||
const TEST_STREAMS = [{
|
||||
name: 'stderr',
|
||||
stream: process.stderr,
|
||||
}, {
|
||||
name: 'stdin',
|
||||
stream: process.stdin,
|
||||
}, {
|
||||
name: 'stdout',
|
||||
stream: process.stdout,
|
||||
}];
|
||||
|
||||
describeLeaks('stream config type', async () => {
|
||||
itLeaks('should resolve allowed streams', async () => {
|
||||
expect(streamType.resolve('stderr')).to.equal(true);
|
||||
expect(streamType.resolve('stdout')).to.equal(true);
|
||||
});
|
||||
|
||||
itLeaks('should throw when stream is not allowed', async () => {
|
||||
expect(() => streamType.resolve('stdin')).to.throw(NotFoundError);
|
||||
});
|
||||
|
||||
itLeaks('should throw when stream does not exist', async () => {
|
||||
expect(() => streamType.resolve('imaginary')).to.throw(NotFoundError);
|
||||
});
|
||||
|
||||
itLeaks('should construct streams', async () => {
|
||||
for (const {name, stream} of TEST_STREAMS) {
|
||||
expect(streamType.construct(name)).to.equal(stream, `should construct stream ${name}`);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
|
@ -1 +0,0 @@
|
|||
test
|
|
@ -1,34 +0,0 @@
|
|||
import { expect } from 'chai';
|
||||
import { kebabCase } from 'lodash';
|
||||
|
||||
import { InvalidArgumentError } from '../../src/error/InvalidArgumentError';
|
||||
import { NotFoundError } from '../../src/error/NotFoundError';
|
||||
|
||||
const errors = [
|
||||
InvalidArgumentError,
|
||||
NotFoundError,
|
||||
];
|
||||
|
||||
describe('errors', () => {
|
||||
for (const errorType of errors) {
|
||||
describe(kebabCase(errorType.name), () => {
|
||||
it('should have a message', () => {
|
||||
const err = new errorType();
|
||||
expect(err.message).to.not.equal('');
|
||||
});
|
||||
|
||||
it('should include nested errors in the stack trace', () => {
|
||||
const inner = new Error('inner error');
|
||||
const err = new errorType('outer error', inner);
|
||||
expect(err.stack).to.include('inner', 'inner error message').and.include('outer', 'outer error message');
|
||||
});
|
||||
|
||||
it('should have the nested error', () => {
|
||||
const inner = new Error('inner error');
|
||||
const err = new errorType('outer error', inner);
|
||||
expect(err.cause()).to.equal(inner);
|
||||
expect(err.length).to.equal(1);
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
|
@ -1,4 +1,4 @@
|
|||
import { AsyncHook, createHook } from 'async_hooks';
|
||||
import { AsyncTracker, isDebug, isNil } from '@apextoaster/js-utils';
|
||||
|
||||
// this will pull Mocha internals out of the stacks
|
||||
/* eslint-disable-next-line @typescript-eslint/no-var-requires */
|
||||
|
@ -8,97 +8,13 @@ const filterStack = stackTraceFilter();
|
|||
type AsyncMochaTest = (this: Mocha.Context | void) => Promise<void>;
|
||||
type AsyncMochaSuite = (this: Mocha.Suite) => Promise<void>;
|
||||
|
||||
/* eslint-disable-next-line @typescript-eslint/ban-types */
|
||||
function isNil<T>(val: T | null | undefined): val is null | undefined {
|
||||
/* eslint-disable-next-line no-null/no-null */
|
||||
return val === null || val === undefined;
|
||||
}
|
||||
|
||||
export interface TrackedResource {
|
||||
source: string;
|
||||
triggerAsyncId: number;
|
||||
type: string;
|
||||
}
|
||||
|
||||
function debugMode() {
|
||||
return Reflect.has(process.env, 'DEBUG');
|
||||
}
|
||||
|
||||
/**
|
||||
* Async resource tracker using node's internal hooks.
|
||||
*
|
||||
* This probably won't work in a browser. It does not hold references to the resource, to avoid leaks.
|
||||
* Adapted from https://gist.github.com/boneskull/7fe75b63d613fa940db7ec990a5f5843#file-async-dump-js
|
||||
*/
|
||||
export class Tracker {
|
||||
public static getStack(): string {
|
||||
const err = new Error();
|
||||
if (isNil(err.stack)) {
|
||||
return 'no stack trace available';
|
||||
} else {
|
||||
return filterStack(err.stack);
|
||||
}
|
||||
}
|
||||
|
||||
private readonly hook: AsyncHook;
|
||||
private readonly resources: Map<number, TrackedResource>;
|
||||
|
||||
constructor() {
|
||||
this.resources = new Map();
|
||||
this.hook = createHook({
|
||||
destroy: (id: number) => {
|
||||
this.resources.delete(id);
|
||||
},
|
||||
init: (id: number, type: string, triggerAsyncId: number) => {
|
||||
const source = Tracker.getStack();
|
||||
// @TODO: exclude async hooks, including this one
|
||||
this.resources.set(id, {
|
||||
source,
|
||||
triggerAsyncId,
|
||||
type,
|
||||
});
|
||||
},
|
||||
promiseResolve: (id: number) => {
|
||||
this.resources.delete(id);
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
public clear() {
|
||||
this.resources.clear();
|
||||
}
|
||||
|
||||
public disable() {
|
||||
this.hook.disable();
|
||||
}
|
||||
|
||||
/* eslint-disable no-console, no-invalid-this */
|
||||
public dump() {
|
||||
console.error(`tracking ${this.resources.size} async resources`);
|
||||
this.resources.forEach((res, id) => {
|
||||
console.error(`${id}: ${res.type}`);
|
||||
if (debugMode()) {
|
||||
console.error(res.source);
|
||||
console.error('\n');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public enable() {
|
||||
this.hook.enable();
|
||||
}
|
||||
|
||||
public get size(): number {
|
||||
return this.resources.size;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Describe a suite of async tests. This wraps mocha's describe to track async resources and report leaks.
|
||||
*/
|
||||
export function describeLeaks(description: string, cb: AsyncMochaSuite): Mocha.Suite {
|
||||
return describe(description, function trackSuite(this: Mocha.Suite) {
|
||||
const tracker = new Tracker();
|
||||
const tracker = new AsyncTracker();
|
||||
tracker.filter = filterStack;
|
||||
|
||||
beforeEach(() => {
|
||||
tracker.enable();
|
||||
|
@ -112,7 +28,7 @@ export function describeLeaks(description: string, cb: AsyncMochaSuite): Mocha.S
|
|||
if (leaked > 1) {
|
||||
tracker.dump();
|
||||
const msg = `test leaked ${leaked - 1} async resources`;
|
||||
if (debugMode()) {
|
||||
if (isDebug()) {
|
||||
throw new Error(msg);
|
||||
} else {
|
||||
/* eslint-disable-next-line no-console */
|
||||
|
@ -123,6 +39,7 @@ export function describeLeaks(description: string, cb: AsyncMochaSuite): Mocha.S
|
|||
tracker.clear();
|
||||
});
|
||||
|
||||
/* eslint-disable-next-line no-invalid-this */
|
||||
const suite: PromiseLike<void> | undefined = cb.call(this);
|
||||
if (isNil(suite) || !Reflect.has(suite, 'then')) {
|
||||
/* eslint-disable-next-line no-console */
|
||||
|
@ -145,6 +62,7 @@ export function itLeaks(expectation: string, cb?: AsyncMochaTest): Mocha.Test {
|
|||
|
||||
return it(expectation, function trackTest(this: Mocha.Context) {
|
||||
return new Promise<unknown>((res, rej) => {
|
||||
/* eslint-disable-next-line no-invalid-this */
|
||||
cb.call(this).then((value: unknown) => {
|
||||
res(value);
|
||||
}, (err: Error) => {
|
||||
|
|
10
yarn.lock
10
yarn.lock
|
@ -2,6 +2,16 @@
|
|||
# yarn lockfile v1
|
||||
|
||||
|
||||
"@apextoaster/js-utils@^0.1.7":
|
||||
version "0.1.7"
|
||||
resolved "https://artifacts.apextoaster.com/repository/group-npm/@apextoaster/js-utils/-/js-utils-0.1.7.tgz#0abab0b23a0d94ff96405b46bf5907844685722e"
|
||||
integrity sha512-NB1n8y6KjKev8+WZNcYVNCi0FYEA6RVHcNjxTki/gQklZNayKPkGP7WtkVF2IuvEo7L6N0sYkWwxRsl+oQWulw==
|
||||
|
||||
"@apextoaster/js-yaml-schema@^0.2.0":
|
||||
version "0.2.0"
|
||||
resolved "https://artifacts.apextoaster.com/repository/group-npm/@apextoaster/js-yaml-schema/-/js-yaml-schema-0.2.0.tgz#af69f7782ceb7b909e598f0a360fdada06d6693d"
|
||||
integrity sha512-qIqIb6tsY0acv/LZqkWNyB1kooq2mwf7AS3Acs568zvSG6bN82UwBXf8r3yJh6F/0Yjeqp/UZyxTvNPsLizh/w==
|
||||
|
||||
"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.5.5":
|
||||
version "7.5.5"
|
||||
resolved "https://artifacts.apextoaster.com/repository/group-npm/@babel/code-frame/-/code-frame-7.5.5.tgz#bc0782f6d69f7b7d49531219699b988f669a8f9d"
|
||||
|
|
Loading…
Reference in New Issue