Adjust type asserts (#4952)

This commit is contained in:
Jaco
2022-06-18 13:45:04 +03:00
committed by GitHub
parent 0d2e938674
commit b42669f864
34 changed files with 320 additions and 113 deletions
+14 -7
View File
@@ -4,7 +4,7 @@
import type { HexString } from '@polkadot/util/types';
import type { AnyNumber, Inspect, INumber, IU8a, Registry, UIntBitLength } from '../types';
import { assert, BN, BN_BILLION, BN_HUNDRED, BN_MILLION, BN_QUINTILL, BN_ZERO, bnToBn, bnToHex, bnToU8a, formatBalance, formatNumber, hexToBn, isBn, isHex, isNumber, isString, isU8a, u8aToBn, u8aToNumber } from '@polkadot/util';
import { BN, BN_BILLION, BN_HUNDRED, BN_MILLION, BN_QUINTILL, bnToBn, bnToHex, bnToU8a, formatBalance, formatNumber, hexToBn, isBn, isHex, isNumber, isString, isU8a, u8aToBn, u8aToNumber } from '@polkadot/util';
export const DEFAULT_UINT_BITS = 64;
@@ -27,7 +27,9 @@ function toPercentage (value: BN, divisor: BN): string {
/** @internal */
function decodeAbstractInt (value: Exclude<AnyNumber, Uint8Array>, isNegative: boolean): string | number {
if (isNumber(value)) {
assert(value <= Number.MAX_SAFE_INTEGER && value >= Number.MIN_SAFE_INTEGER && Number.isInteger(value), 'Number needs to be an integer <= Number.MAX_SAFE_INTEGER, i.e. 2 ^ 53 - 1');
if (!Number.isInteger(value) || value > Number.MAX_SAFE_INTEGER || value < Number.MIN_SAFE_INTEGER) {
throw new Error('Number needs to be an integer <= Number.MAX_SAFE_INTEGER, i.e. 2 ^ 53 - 1');
}
return value;
} else if (isString(value)) {
@@ -35,7 +37,9 @@ function decodeAbstractInt (value: Exclude<AnyNumber, Uint8Array>, isNegative: b
return hexToBn(value, { isLe: false, isNegative }).toString();
}
assert(!(value.includes('.') || value.includes(',') || value.includes('e')), 'String should not contain decimal points or scientific notation');
if (value.includes('.') || value.includes(',') || value.includes('e')) {
throw new Error('String should not contain decimal points or scientific notation');
}
return value;
} else if (isBn(value)) {
@@ -79,11 +83,14 @@ export abstract class AbstractInt extends BN implements INumber {
this.encodedLength = this.#bitLength / 8;
this.isUnsigned = !isSigned;
const isPositive = this.gte(BN_ZERO);
const maxBits = bitLength - (isSigned && isPositive ? 1 : 0);
const isNegative = this.isNeg();
const maxBits = bitLength - (isSigned && !isNegative ? 1 : 0);
assert(isSigned || isPositive, () => `${this.toRawType()}: Negative number passed to unsigned type`);
assert(super.bitLength() <= maxBits, () => `${this.toRawType()}: Input too large. Found input with ${super.bitLength()} bits, expected ${maxBits}`);
if (isNegative && !isSigned) {
throw new Error(`${this.toRawType()}: Negative number passed to unsigned type`);
} else if (super.bitLength() > maxBits) {
throw new Error(`${this.toRawType()}: Input too large. Found input with ${super.bitLength()} bits, expected ${maxBits}`);
}
}
/**
@@ -5,6 +5,10 @@ import { TypeRegistry } from '@polkadot/types';
import { CodecDate, Compact, U32 } from '@polkadot/types-codec';
import { BN } from '@polkadot/util';
import { performance } from '../test/performance';
const CompactU32 = Compact.with(U32);
describe('Compact', (): void => {
const registry = new TypeRegistry();
@@ -88,4 +92,6 @@ describe('Compact', (): void => {
});
});
});
performance('Compact', 75_000, [[new Uint8Array([63 << 2])]], (v: Uint8Array) => new CompactU32(registry, v));
});
+13 -5
View File
@@ -4,7 +4,7 @@
import type { HexString } from '@polkadot/util/types';
import type { AnyJson, Codec, CodecClass, IEnum, Inspect, IU8a, Registry } from '../types';
import { assert, isHex, isNumber, isObject, isString, isU8a, isUndefined, objectProperties, stringCamelCase, stringify, stringPascalCase, u8aConcatStrict, u8aToHex, u8aToU8a } from '@polkadot/util';
import { isHex, isNumber, isObject, isString, isU8a, isUndefined, objectProperties, stringCamelCase, stringify, stringPascalCase, u8aConcatStrict, u8aToHex, u8aToU8a } from '@polkadot/util';
import { mapToTypeMap, typesToMap } from '../utils';
import { Null } from './Null';
@@ -45,7 +45,9 @@ function isRustEnum (def: Record<string, string | CodecClass> | Record<string, n
const defValues = Object.values(def);
if (defValues.some((v) => isNumber(v))) {
assert(defValues.every((v) => isNumber(v) && v >= 0 && v <= 255), 'Invalid number-indexed enum definition');
if (!defValues.every((v) => isNumber(v) && v >= 0 && v <= 255)) {
throw new Error('Invalid number-indexed enum definition');
}
return false;
}
@@ -97,7 +99,9 @@ function extractDef (registry: Registry, _def: Record<string, string | CodecClas
function createFromValue (registry: Registry, def: TypesDef, index = 0, value?: unknown): Decoded {
const entry = Object.values(def).find((e) => e.index === index);
assert(!isUndefined(entry), () => `Unable to create Enum via index ${index}, in ${Object.keys(def).join(', ')}`);
if (isUndefined(entry)) {
throw new Error(`Unable to create Enum via index ${index}, in ${Object.keys(def).join(', ')}`);
}
return {
index,
@@ -114,7 +118,9 @@ function decodeFromJSON (registry: Registry, def: TypesDef, key: string, value?:
const keyLower = key.toLowerCase();
const index = keys.indexOf(keyLower);
assert(index !== -1, () => `Cannot map Enum JSON, unable to find '${key}' in ${keys.join(', ')}`);
if (index === -1) {
throw new Error(`Cannot map Enum JSON, unable to find '${key}' in ${keys.join(', ')}`);
}
try {
return createFromValue(registry, def, Object.values(def)[index].index, value);
@@ -223,7 +229,9 @@ export class Enum implements IEnum {
objectProperties(this, isKeys, (_, i) => this.type === keys[i]);
objectProperties(this, asKeys, (k, i): Codec => {
assert(this[isKeys[i] as keyof this], () => `Cannot convert '${this.type}' via ${k}`);
if (!this[isKeys[i] as keyof this]) {
throw new Error(`Cannot convert '${this.type}' via ${k}`);
}
return this.value;
});
+4 -2
View File
@@ -4,7 +4,7 @@
import type { HexString } from '@polkadot/util/types';
import type { AnyJson, Codec, CodecClass, Inspect, IOption, IU8a, Registry } from '../types';
import { assert, isCodec, isNull, isU8a, isUndefined, u8aToHex } from '@polkadot/util';
import { isCodec, isNull, isU8a, isUndefined, u8aToHex } from '@polkadot/util';
import { typeToConstructor } from '../utils';
import { Null } from './Null';
@@ -247,7 +247,9 @@ export class Option<T extends Codec> implements IOption<T> {
* @description Returns the value that the Option represents (if available), throws if null
*/
public unwrap (): T {
assert(this.isSome, 'Option: unwrapping a None value');
if (this.isNone) {
throw new Error('Option: unwrapping a None value');
}
return this.#raw;
}
+6 -4
View File
@@ -3,8 +3,6 @@
import type { Codec, CodecClass, IResult, Registry } from '../types';
import { assert } from '@polkadot/util';
import { Enum } from './Enum';
/**
@@ -31,7 +29,9 @@ export class Result<O extends Codec, E extends Codec> extends Enum implements IR
* @description Returns the wrapper Err value (if isErr)
*/
public get asErr (): E {
assert(this.isErr, 'Cannot extract Err value from Ok result, check isErr first');
if (!this.isErr) {
throw new Error('Cannot extract Err value from Ok result, check isErr first');
}
return this.value as E;
}
@@ -47,7 +47,9 @@ export class Result<O extends Codec, E extends Codec> extends Enum implements IR
* @description Returns the wrapper Ok value (if isOk)
*/
public get asOk (): O {
assert(this.isOk, 'Cannot extract Ok value from Err result, check isOk first');
if (!this.isOk) {
throw new Error('Cannot extract Ok value from Err result, check isOk first');
}
return this.value as O;
}
@@ -5,6 +5,8 @@ import { TypeRegistry } from '@polkadot/types';
import { UInt } from '@polkadot/types-codec';
import { BN, BN_TWO, isBn } from '@polkadot/util';
import { performance } from '../test/performance';
describe('UInt', (): void => {
const registry = new TypeRegistry();
@@ -180,4 +182,6 @@ describe('UInt', (): void => {
expect(registry.createType('Balance', '123456789012345').toHuman()).toEqual('123.4567 Unit');
});
});
performance('UInt', 75_000, [[new Uint8Array([31, 32, 33, 34])]], (v: Uint8Array) => new UInt(registry, v));
});
+6 -1
View File
@@ -5,12 +5,15 @@ import type { PropIndex } from '@polkadot/types/interfaces/democracy';
import type { Codec, CodecTo, ITuple } from '@polkadot/types-codec/types';
import { createTypeUnsafe, GenericAccountId as AccountId, Metadata, TypeRegistry } from '@polkadot/types';
import { Text, Vec } from '@polkadot/types-codec';
import { Text, u32, Vec } from '@polkadot/types-codec';
import rpcMetadata from '@polkadot/types-support/metadata/static-substrate';
import { decodeAddress, randomAsU8a } from '@polkadot/util-crypto';
import { performance } from '../test/performance';
const registry = new TypeRegistry();
const metadata = new Metadata(registry, rpcMetadata);
const VecU32 = Vec.with(u32);
registry.setMetadata(metadata);
@@ -190,4 +193,6 @@ describe('Vec', (): void => {
});
});
});
performance('Vec<U32>', 40_000, [[new Uint8Array([3 << 2, 11, 12, 13, 14, 21, 22, 23, 24, 31, 32, 33, 34])]], (v: Uint8Array) => new VecU32(registry, v));
});
+4 -2
View File
@@ -4,7 +4,7 @@
import type { HexString } from '@polkadot/util/types';
import type { Codec, CodecClass, Registry } from '../types';
import { assert, compactFromU8aLim, isU8a, logger, u8aToU8a } from '@polkadot/util';
import { compactFromU8aLim, isU8a, logger, u8aToU8a } from '@polkadot/util';
import { AbstractArray } from '../abstract/Array';
import { decodeU8aVec, typeToConstructor } from '../utils';
@@ -30,7 +30,9 @@ function decodeVecLength (value: Uint8Array | HexString | unknown[]): [Uint8Arra
const u8a = u8aToU8a(value);
const [startAt, length] = compactFromU8aLim(u8a);
assert(length <= MAX_LENGTH, () => `Vec length ${length.toString()} exceeds ${MAX_LENGTH}`);
if (length > MAX_LENGTH) {
throw new Error(`Vec length ${length.toString()} exceeds ${MAX_LENGTH}`);
}
return [u8a, length, startAt];
}
+4 -2
View File
@@ -3,7 +3,7 @@
import type { AnyU8a, Inspect, Registry } from '../types';
import { assert, compactFromU8aLim, compactToU8a, isString, u8aConcatStrict, u8aToU8a } from '@polkadot/util';
import { compactFromU8aLim, compactToU8a, isString, u8aConcatStrict, u8aToU8a } from '@polkadot/util';
import { Raw } from '../native/Raw';
@@ -17,7 +17,9 @@ function decodeBitVecU8a (value?: Uint8Array): [number, Uint8Array] {
const [offset, length] = compactFromU8aLim(value);
const total = offset + Math.ceil(length / 8);
assert(total <= value.length, () => `BitVec: required length less than remainder, expected at least ${total}, found ${value.length}`);
if (total > value.length) {
throw new Error(`BitVec: required length less than remainder, expected at least ${total}, found ${value.length}`);
}
return [length, value.subarray(offset, total)];
}
+6 -3
View File
@@ -3,7 +3,7 @@
import type { AnyU8a, Inspect, Registry } from '../types';
import { assert, compactAddLength, compactFromU8aLim, compactToU8a, isString, isU8a, u8aToU8a } from '@polkadot/util';
import { compactAddLength, compactFromU8aLim, compactToU8a, isString, isU8a, u8aToU8a } from '@polkadot/util';
import { Raw } from '../native/Raw';
@@ -20,8 +20,11 @@ function decodeBytesU8a (value: Uint8Array): [Uint8Array, number] {
const [offset, length] = compactFromU8aLim(value);
const total = offset + length;
assert(length <= MAX_LENGTH, () => `Bytes length ${length.toString()} exceeds ${MAX_LENGTH}`);
assert(total <= value.length, () => `Bytes: required length less than remainder, expected at least ${total}, found ${value.length}`);
if (length > MAX_LENGTH) {
throw new Error(`Bytes length ${length.toString()} exceeds ${MAX_LENGTH}`);
} else if (total > value.length) {
throw new Error(`Bytes: required length less than remainder, expected at least ${total}, found ${value.length}`);
}
return [value.subarray(offset, total), total];
}
@@ -3,7 +3,7 @@
import type { AnyU8a, CodecClass, Registry, U8aBitLength } from '../types';
import { assert, isU8a, u8aToU8a } from '@polkadot/util';
import { isU8a, u8aToU8a } from '@polkadot/util';
import { Raw } from '../native/Raw';
@@ -16,7 +16,9 @@ function decodeU8aFixed (value: AnyU8a, bitLength: U8aBitLength): [AnyU8a, numbe
return [new Uint8Array(byteLength), 0];
}
assert(isU8a(value) ? u8a.length >= byteLength : u8a.length === byteLength, () => `Expected input with ${byteLength} bytes (${bitLength} bits), found ${u8a.length} bytes`);
if (isU8a(value) ? u8a.length < byteLength : u8a.length !== byteLength) {
throw new Error(`Expected input with ${byteLength} bytes (${bitLength} bits), found ${u8a.length} bytes`);
}
return [u8a.subarray(0, byteLength), byteLength];
}
@@ -3,7 +3,7 @@
import type { AnyJson, AnyU8a, Codec, CodecClass, Inspect, Registry } from '../types';
import { assertReturn, compactAddLength, compactStripLength, compactToU8a, isHex, isU8a } from '@polkadot/util';
import { compactAddLength, compactStripLength, compactToU8a, isHex, isU8a } from '@polkadot/util';
import { Raw } from '../native/Raw';
import { typeToConstructor } from '../utils';
@@ -110,6 +110,10 @@ export class WrapperKeepOpaque<T extends Codec> extends Bytes {
* @description Returns the decoded that the WrapperKeepOpaque represents (if available), throws if non-decodable
*/
public unwrap (): T {
return assertReturn(this.#decoded, () => `${this.#opaqueName}: unwrapping an undecodable value`);
if (!this.#decoded) {
throw new Error(`${this.#opaqueName}: unwrapping an undecodable value`);
}
return this.#decoded;
}
}
+4 -2
View File
@@ -4,7 +4,7 @@
import type { HexString } from '@polkadot/util/types';
import type { AnyJson, AnyU8a, Inspect, IU8a, Registry } from '../types';
import { assert, isAscii, isUndefined, isUtf8, u8aToHex, u8aToString, u8aToU8a } from '@polkadot/util';
import { isAscii, isUndefined, isUtf8, u8aToHex, u8aToString, u8aToU8a } from '@polkadot/util';
/**
* @name Raw
@@ -177,7 +177,9 @@ export class Raw extends Uint8Array implements IU8a {
* @description Returns the wrapped data as a UTF-8 string
*/
public toUtf8 (): string {
assert(this.isUtf8, 'The character sequence is not a valid Utf8 string');
if (!this.isUtf8) {
throw new Error('The character sequence is not a valid Utf8 string');
}
return u8aToString(this);
}
+13 -5
View File
@@ -4,7 +4,7 @@
import type { HexString } from '@polkadot/util/types';
import type { CodecClass, Inspect, ISet, IU8a, Registry } from '../types';
import { assert, BN, bnToBn, bnToU8a, isBn, isNumber, isString, isU8a, isUndefined, objectProperties, stringify, stringPascalCase, u8aToBn, u8aToHex, u8aToU8a } from '@polkadot/util';
import { BN, bnToBn, bnToU8a, isBn, isNumber, isString, isU8a, isUndefined, objectProperties, stringify, stringPascalCase, u8aToBn, u8aToHex, u8aToU8a } from '@polkadot/util';
import { compareArray } from '../utils';
@@ -27,7 +27,9 @@ function decodeSetArray (setValues: SetValues, values: string[]): string[] {
for (let i = 0; i < values.length; i++) {
const key = values[i];
assert(!isUndefined(setValues[key]), () => `Set: Invalid key '${key}' passed to Set, allowed ${Object.keys(setValues).join(', ')}`);
if (isUndefined(setValues[key])) {
throw new Error(`Set: Invalid key '${key}' passed to Set, allowed ${Object.keys(setValues).join(', ')}`);
}
result[i] = key;
}
@@ -51,14 +53,18 @@ function decodeSetNumber (setValues: SetValues, _value: BN | number): string[] {
const computed = encodeSet(setValues, result);
assert(bn.eq(computed), () => `Set: Mismatch decoding '${bn.toString()}', computed as '${computed.toString()}' with ${result.join(', ')}`);
if (!bn.eq(computed)) {
throw new Error(`Set: Mismatch decoding '${bn.toString()}', computed as '${computed.toString()}' with ${result.join(', ')}`);
}
return result;
}
/** @internal */
function decodeSet (setValues: SetValues, value: string[] | Set<string> | Uint8Array | BN | number | string = 0, bitLength: number): string[] {
assert(bitLength % 8 === 0, () => `Expected valid bitLength, power of 8, found ${bitLength}`);
if (bitLength % 8 !== 0) {
throw new Error(`Expected valid bitLength, power of 8, found ${bitLength}`);
}
const byteLength = bitLength / 8;
@@ -161,7 +167,9 @@ export class CodecSet extends Set<string> implements ISet<string> {
// ^^^ add = () property done to assign this instance's this, otherwise Set.add creates "some" chaos
// we have the isUndefined(this._setValues) in here as well, add is used internally
// in the Set constructor (so it is undefined at this point, and should allow)
assert(isUndefined(this.#allowed) || !isUndefined(this.#allowed[key]), () => `Set: Invalid key '${key}' on add`);
if (this.#allowed && isUndefined(this.#allowed[key])) {
throw new Error(`Set: Invalid key '${key}' on add`);
}
super.add(key);
+6 -3
View File
@@ -4,7 +4,7 @@
import type { HexString } from '@polkadot/util/types';
import type { AnyJson, BareOpts, Codec, CodecClass, Inspect, IStruct, IU8a, Registry } from '../types';
import { assert, isBoolean, isFunction, isHex, isObject, isU8a, isUndefined, objectProperties, stringCamelCase, stringify, u8aConcatStrict, u8aToHex, u8aToU8a } from '@polkadot/util';
import { isBoolean, isFunction, isHex, isObject, isU8a, isUndefined, objectProperties, stringCamelCase, stringify, u8aConcatStrict, u8aToHex, u8aToU8a } from '@polkadot/util';
import { compareMap, decodeU8aStruct, mapToTypeMap, typesToMap } from '../utils';
@@ -27,8 +27,11 @@ function decodeStructFromObject (registry: Registry, [Types, keys]: Definition,
const typeofArray = Array.isArray(value);
const typeofMap = value instanceof Map;
assert(typeofArray || typeofMap || isObject(value), () => `Struct: Cannot decode value ${stringify(value)} (typeof ${typeof value}), expected an input object, map or array`);
assert(!typeofArray || value.length === keys.length, () => `Struct: Unable to map ${stringify(value)} array to object with known keys ${keys.join(', ')}`);
if (!typeofArray && !typeofMap && !isObject(value)) {
throw new Error(`Struct: Cannot decode value ${stringify(value)} (typeof ${typeof value}), expected an input object, map or array`);
} else if (typeofArray && value.length !== keys.length) {
throw new Error(`Struct: Unable to map ${stringify(value)} array to object with known keys ${keys.join(', ')}`);
}
const raw = new Array<[string, Codec]>(keys.length);
+5 -1
View File
@@ -7,6 +7,8 @@ import { TypeRegistry } from '@polkadot/types';
import { Bytes, Raw, Text } from '@polkadot/types-codec';
import { stringToU8a } from '@polkadot/util';
import { performance } from '../test/performance';
describe('Text', (): void => {
const registry = new TypeRegistry();
@@ -68,7 +70,7 @@ describe('Text', (): void => {
expect(test).toHaveLength(2);
});
it('has a snae inspect', (): void => {
it('has a sane inspect', (): void => {
expect(
new Text(registry, 'abcde').inspect()
).toEqual({
@@ -76,4 +78,6 @@ describe('Text', (): void => {
});
});
});
performance('Text', 100_000, [[new Uint8Array([6 << 2, 102, 111, 111, 102, 111, 111])]], (v: Uint8Array) => new Text(registry, v));
});
+6 -3
View File
@@ -4,7 +4,7 @@
import type { HexString } from '@polkadot/util/types';
import type { AnyString, AnyU8a, Inspect, IText, IU8a, Registry } from '../types';
import { assert, compactAddLength, compactFromU8aLim, compactToU8a, hexToU8a, isHex, isString, isU8a, stringToU8a, u8aToHex, u8aToString } from '@polkadot/util';
import { compactAddLength, compactFromU8aLim, compactToU8a, hexToU8a, isHex, isString, isU8a, stringToU8a, u8aToHex, u8aToString } from '@polkadot/util';
import { Raw } from './Raw';
@@ -26,8 +26,11 @@ function decodeText (value?: null | AnyString | AnyU8a | { toString: () => strin
const [offset, length] = compactFromU8aLim(value);
const total = offset + length;
assert(length <= MAX_LENGTH, () => `Text: length ${length.toString()} exceeds ${MAX_LENGTH}`);
assert(total <= value.length, () => `Text: required length less than remainder, expected at least ${total}, found ${value.length}`);
if (length > MAX_LENGTH) {
throw new Error(`Text: length ${length.toString()} exceeds ${MAX_LENGTH}`);
} else if (total > value.length) {
throw new Error(`Text: required length less than remainder, expected at least ${total}, found ${value.length}`);
}
return [u8aToString(value.subarray(offset, total)), total];
} else if (isHex(value)) {
@@ -0,0 +1,77 @@
// Copyright 2017-2022 @polkadot/types-codec authors & contributors
// SPDX-License-Identifier: Apache-2.0
// Shamelessly copied from @polkadot/util/test
import { formatDecimal, formatNumber } from '@polkadot/util';
// eslint-disable-next-line @typescript-eslint/no-explicit-any
type ExecFn = (...params: any[]) => unknown;
const NUM_PAD = 16;
const PRE_PAD = 32;
function loop (count: number, inputs: unknown[][], exec: ExecFn): [number, unknown[]] {
const start = Date.now();
const results = new Array<unknown>(inputs.length);
for (let i = 0; i < count; i++) {
const result = exec(...inputs[i % inputs.length]);
if (i < inputs.length) {
results[i] = result;
}
}
return [Date.now() - start, results];
}
export function formatFixed (value: number): string {
const [a, b] = value.toFixed(2).split('.');
return [formatDecimal(a), b].join('.');
}
export function formatOps (count: number, time: number): string {
const micro = (time * 1000) / count;
const ops = 1_000_000 / micro;
return `
${formatFixed(ops).padStart(NUM_PAD + PRE_PAD + 1)} ops/s
${formatFixed(micro).padStart(NUM_PAD + PRE_PAD + 1)} μs/op`;
}
export function performance (name: string, count: number, inputs: unknown[][], exec: ExecFn): void {
it(`performance: ${name}`, (): void => {
const [time] = loop(count, inputs, exec);
console.log(`
performance run for ${name} completed with ${formatNumber(count)} iterations.
${`${name}:`.padStart(PRE_PAD)} ${time.toString().padStart(NUM_PAD)} ms${formatOps(count, time)}
`);
});
}
export function performanceCmp (name: string, [first, second]: [string, string], count: number, inputs: unknown[][], exec: ExecFn): void {
it(`performance: ${name}`, (): void => {
const pa = inputs.map((values) => [...values, false]);
const pb = inputs.map((values) => [...values, true]);
const [ta, ra] = loop(count, pa, exec);
const [tb, rb] = loop(count, pb, exec);
console.log(`
performance run for ${name} completed with ${formatNumber(count)} iterations.
${`${first}:`.padStart(PRE_PAD)} ${ta.toString().padStart(NUM_PAD)} ms ${ta < tb ? '(fastest)' : `(slowest, ${(ta / tb).toFixed(2)}x)`}${formatOps(count, ta)}
${`${second}:`.padStart(PRE_PAD)} ${tb.toString().padStart(NUM_PAD)} ms ${ta > tb ? '(fastest)' : `(slowest, ${(tb / ta).toFixed(2)}x)`}${formatOps(count, tb)}
`);
const unmatched = ra.filter((r, i) =>
JSON.stringify(r) !== JSON.stringify(rb[i])
);
expect(unmatched.length).toEqual(0);
});
}
+2 -1
View File
@@ -9,7 +9,8 @@
"exclude": [
"**/*.data.ts",
"**/checkTypes.manual.ts",
"**/*.spec.ts"
"**/*.spec.ts",
"**/test/*"
],
"references": []
}
+2 -1
View File
@@ -11,7 +11,8 @@
"include": [
"**/*.data.ts",
"**/checkTypes.manual.ts",
"**/*.spec.ts"
"**/*.spec.ts",
"**/test/*"
],
"references": [
{ "path": "../types/tsconfig.build.json" },