summaryrefslogtreecommitdiff
path: root/testing
diff options
context:
space:
mode:
Diffstat (limited to 'testing')
-rw-r--r--testing/diff.ts97
-rw-r--r--testing/format.ts303
-rw-r--r--testing/format_test.ts27
-rw-r--r--testing/mod.ts101
-rw-r--r--testing/pretty.ts8
-rw-r--r--testing/pretty_test.ts6
-rw-r--r--testing/test.ts2
7 files changed, 280 insertions, 264 deletions
diff --git a/testing/diff.ts b/testing/diff.ts
index a1385b88a..4fab75e4a 100644
--- a/testing/diff.ts
+++ b/testing/diff.ts
@@ -15,7 +15,7 @@ const REMOVED = 1;
const COMMON = 2;
const ADDED = 3;
-function createCommon<T>(A: T[], B: T[], reverse?: boolean) {
+function createCommon<T>(A: T[], B: T[], reverse?: boolean): T[] {
const common = [];
if (A.length === 0 || B.length === 0) return [];
for (let i = 0; i < Math.min(A.length, B.length); i += 1) {
@@ -30,13 +30,55 @@ function createCommon<T>(A: T[], B: T[], reverse?: boolean) {
return common;
}
-export default function diff<T>(A: T[], B: T[]): DiffResult<T>[] {
+export default function diff<T>(A: T[], B: T[]): Array<DiffResult<T>> {
+ const prefixCommon = createCommon(A, B);
+ const suffixCommon = createCommon(
+ A.slice(prefixCommon.length),
+ B.slice(prefixCommon.length),
+ true
+ ).reverse();
+ A = suffixCommon.length
+ ? A.slice(prefixCommon.length, -suffixCommon.length)
+ : A.slice(prefixCommon.length);
+ B = suffixCommon.length
+ ? B.slice(prefixCommon.length, -suffixCommon.length)
+ : B.slice(prefixCommon.length);
+ const swapped = B.length > A.length;
+ [A, B] = swapped ? [B, A] : [A, B];
+ const M = A.length;
+ const N = B.length;
+ if (!M && !N && !suffixCommon.length && !prefixCommon.length) return [];
+ if (!N) {
+ return [
+ ...prefixCommon.map(c => ({ type: "common" as DiffType, value: c })),
+ ...A.map(a => ({
+ type: (swapped ? "added" : "removed") as DiffType,
+ value: a
+ })),
+ ...suffixCommon.map(c => ({ type: "common" as DiffType, value: c }))
+ ];
+ }
+ const offset = N;
+ const delta = M - N;
+ const size = M + N + 1;
+ const fp = new Array(size).fill({ y: -1 });
+ // INFO: This buffer is used to save memory and improve performance.
+ // The first half is used to save route and last half is used to save diff type.
+ // This is because, when I kept new uint8array area to save type, performance worsened.
+ const routes = new Uint32Array((M * N + size + 1) * 2);
+ const diffTypesPtrOffset = routes.length / 2;
+ let ptr = 0;
+ let p = -1;
+
function backTrace<T>(
A: T[],
B: T[],
current: FarthestPoint,
swapped: boolean
- ) {
+ ): Array<{
+ type: DiffType;
+ value: T;
+ }> {
const M = A.length;
const N = B.length;
const result = [];
@@ -74,8 +116,7 @@ export default function diff<T>(A: T[], B: T[]): DiffResult<T>[] {
slide: FarthestPoint,
down: FarthestPoint,
k: number,
- M: number,
- N: number
+ M: number
): FarthestPoint {
if (slide && slide.y === -1 && (down && down.y === -1))
return { y: 0, id: 0 };
@@ -102,14 +143,14 @@ export default function diff<T>(A: T[], B: T[]): DiffResult<T>[] {
k: number,
slide: FarthestPoint,
down: FarthestPoint,
- offset: number,
+ _offset: number,
A: T[],
B: T[]
- ) {
+ ): FarthestPoint {
const M = A.length;
const N = B.length;
- if (k < -N || M < k) return { y: -1 };
- const fp = createFP(slide, down, k, M, N);
+ if (k < -N || M < k) return { y: -1, id: -1 };
+ const fp = createFP(slide, down, k, M);
while (fp.y + k < M && fp.y < N && A[fp.y + k] === B[fp.y]) {
const prev = fp.id;
ptr++;
@@ -121,44 +162,6 @@ export default function diff<T>(A: T[], B: T[]): DiffResult<T>[] {
return fp;
}
- const prefixCommon = createCommon(A, B);
- const suffixCommon = createCommon(
- A.slice(prefixCommon.length),
- B.slice(prefixCommon.length),
- true
- ).reverse();
- A = suffixCommon.length
- ? A.slice(prefixCommon.length, -suffixCommon.length)
- : A.slice(prefixCommon.length);
- B = suffixCommon.length
- ? B.slice(prefixCommon.length, -suffixCommon.length)
- : B.slice(prefixCommon.length);
- const swapped = B.length > A.length;
- [A, B] = swapped ? [B, A] : [A, B];
- const M = A.length;
- const N = B.length;
- if (!M && !N && !suffixCommon.length && !prefixCommon.length) return [];
- if (!N) {
- return [
- ...prefixCommon.map(c => ({ type: "common" as DiffType, value: c })),
- ...A.map(a => ({
- type: (swapped ? "added" : "removed") as DiffType,
- value: a
- })),
- ...suffixCommon.map(c => ({ type: "common" as DiffType, value: c }))
- ];
- }
- const offset = N;
- const delta = M - N;
- const size = M + N + 1;
- const fp = new Array(size).fill({ y: -1 });
- // INFO: This buffer is used to save memory and improve performance.
- // The first half is used to save route and last half is used to save diff type.
- // This is because, when I kept new uint8array area to save type, performance worsened.
- const routes = new Uint32Array((M * N + size + 1) * 2);
- const diffTypesPtrOffset = routes.length / 2;
- let ptr = 0;
- let p = -1;
while (fp[delta + offset].y < N) {
p = p + 1;
for (let k = -p; k < delta; ++k) {
diff --git a/testing/format.ts b/testing/format.ts
index 8434db1c2..9a8b02ac6 100644
--- a/testing/format.ts
+++ b/testing/format.ts
@@ -6,6 +6,7 @@
* LICENSE file in the root directory of this source tree.
*
*/
+// eslint-disable-next-line @typescript-eslint/no-explicit-any
export type Refs = any[];
export type Optional<T> = { [K in keyof T]?: T[K] };
@@ -32,7 +33,7 @@ export interface Config {
}
export type Printer = (
- val: any,
+ val: unknown,
config: Config,
indentation: string,
depth: number,
@@ -66,12 +67,15 @@ interface BasicValueOptions {
* Explicitly comparing typeof constructor to function avoids undefined as name
* when mock identity-obj-proxy returns the key as the value for any key.
*/
-const getConstructorName = (val: new (...args: any[]) => any) =>
+// eslint-disable-next-line @typescript-eslint/no-explicit-any
+const getConstructorName = (val: new (...args: any[]) => any): string =>
(typeof val.constructor === "function" && val.constructor.name) || "Object";
/* global window */
/** Is val is equal to global window object? Works even if it does not exist :) */
-const isWindow = (val: any) => typeof window !== "undefined" && val === window;
+// eslint-disable-next-line @typescript-eslint/no-explicit-any
+const isWindow = (val: any): val is Window =>
+ typeof window !== "undefined" && val === window;
const SYMBOL_REGEXP = /^Symbol\((.*)\)(.*)$/;
@@ -116,11 +120,12 @@ function printError(val: Error): string {
* data-types in JS.
*/
function printBasicValue(
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
val: any,
{ printFunctionName, escapeRegex, escapeString }: BasicValueOptions
): string | null {
if (val === true || val === false) {
- return "" + val;
+ return String(val);
}
if (val === undefined) {
return "undefined";
@@ -136,9 +141,9 @@ function printBasicValue(
}
if (typeOf === "string") {
if (escapeString) {
- return '"' + val.replace(/"|\\/g, "\\$&") + '"';
+ return `"${val.replace(/"|\\/g, "\\$&")}"`;
}
- return '"' + val + '"';
+ return `"${val}"`;
}
if (typeOf === "function") {
return printFunction(val, printFunctionName);
@@ -185,95 +190,8 @@ function printBasicValue(
return null;
}
-/**
- * Handles more complex objects ( such as objects with circular references.
- * maps and sets etc )
- */
-function printComplexValue(
- val: any,
- config: Config,
- indentation: string,
- depth: number,
- refs: Refs,
- hasCalledToJSON?: boolean
-): string {
- if (refs.indexOf(val) !== -1) {
- return "[Circular]";
- }
- refs = refs.slice();
- refs.push(val);
-
- const hitMaxDepth = ++depth > config.maxDepth;
- const { min, callToJSON } = config;
-
- if (
- callToJSON &&
- !hitMaxDepth &&
- val.toJSON &&
- typeof val.toJSON === "function" &&
- !hasCalledToJSON
- ) {
- return printer(val.toJSON(), config, indentation, depth, refs, true);
- }
-
- const toStringed = toString.call(val);
- if (toStringed === "[object Arguments]") {
- return hitMaxDepth
- ? "[Arguments]"
- : (min ? "" : "Arguments ") +
- "[" +
- printListItems(val, config, indentation, depth, refs, printer) +
- "]";
- }
- if (isToStringedArrayType(toStringed)) {
- return hitMaxDepth
- ? "[" + val.constructor.name + "]"
- : (min ? "" : val.constructor.name + " ") +
- "[" +
- printListItems(val, config, indentation, depth, refs, printer) +
- "]";
- }
- if (toStringed === "[object Map]") {
- return hitMaxDepth
- ? "[Map]"
- : "Map {" +
- printIteratorEntries(
- val.entries(),
- config,
- indentation,
- depth,
- refs,
- printer,
- " => "
- ) +
- "}";
- }
- if (toStringed === "[object Set]") {
- return hitMaxDepth
- ? "[Set]"
- : "Set {" +
- printIteratorValues(
- val.values(),
- config,
- indentation,
- depth,
- refs,
- printer
- ) +
- "}";
- }
-
- // Avoid failure to serialize global window object in jsdom test environment.
- // For example, not even relevant if window is prop of React element.
- return hitMaxDepth || isWindow(val)
- ? "[" + getConstructorName(val) + "]"
- : (min ? "" : getConstructorName(val) + " ") +
- "{" +
- printObjectProperties(val, config, indentation, depth, refs, printer) +
- "}";
-}
-
function printer(
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
val: any,
config: Config,
indentation: string,
@@ -285,6 +203,7 @@ function printer(
if (basicResult !== null) {
return basicResult;
}
+ // eslint-disable-next-line @typescript-eslint/no-use-before-define
return printComplexValue(
val,
config,
@@ -295,30 +214,44 @@ function printer(
);
}
-const getConfig = (options: Options): Config => ({
- ...options,
- indent: options.min ? "" : createIndent(options.indent),
- spacingInner: options.min ? " " : "\n",
- spacingOuter: options.min ? "" : "\n"
-});
+/**
+ * Return items (for example, of an array)
+ * with spacing, indentation, and comma
+ * without surrounding punctuation (for example, brackets)
+ */
+function printListItems(
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
+ list: any,
+ config: Config,
+ indentation: string,
+ depth: number,
+ refs: Refs,
+ printer: Printer
+): string {
+ let result = "";
-function createIndent(indent: number): string {
- return new Array(indent + 1).join(" ");
-}
+ if (list.length) {
+ result += config.spacingOuter;
-const getKeysOfEnumerableProperties = (object: {}) => {
- const keys: Array<string | symbol> = Object.keys(object).sort();
+ const indentationNext = indentation + config.indent;
- if (Object.getOwnPropertySymbols) {
- Object.getOwnPropertySymbols(object).forEach(symbol => {
- if (Object.getOwnPropertyDescriptor(object, symbol)!.enumerable) {
- keys.push(symbol);
+ for (let i = 0; i < list.length; i++) {
+ result +=
+ indentationNext +
+ printer(list[i], config, indentationNext, depth, refs);
+
+ if (i < list.length - 1) {
+ result += "," + config.spacingInner;
+ } else if (!config.min) {
+ result += ",";
}
- });
+ }
+
+ result += config.spacingOuter + indentation;
}
- return keys;
-};
+ return result;
+}
/**
* Return entries (for example, of a map)
@@ -326,6 +259,7 @@ const getKeysOfEnumerableProperties = (object: {}) => {
* without surrounding punctuation (for example, braces)
*/
function printIteratorEntries(
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
iterator: any,
config: Config,
indentation: string,
@@ -384,6 +318,7 @@ function printIteratorEntries(
* without surrounding punctuation (braces or brackets)
*/
function printIteratorValues(
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
iterator: Iterator<any>,
config: Config,
indentation: string,
@@ -419,43 +354,19 @@ function printIteratorValues(
return result;
}
-/**
- * Return items (for example, of an array)
- * with spacing, indentation, and comma
- * without surrounding punctuation (for example, brackets)
- */
-function printListItems(
- list: any,
- config: Config,
- indentation: string,
- depth: number,
- refs: Refs,
- printer: Printer
-): string {
- let result = "";
-
- if (list.length) {
- result += config.spacingOuter;
-
- const indentationNext = indentation + config.indent;
-
- for (let i = 0; i < list.length; i++) {
- result +=
- indentationNext +
- printer(list[i], config, indentationNext, depth, refs);
+const getKeysOfEnumerableProperties = (object: {}): Array<string | symbol> => {
+ const keys: Array<string | symbol> = Object.keys(object).sort();
- if (i < list.length - 1) {
- result += "," + config.spacingInner;
- } else if (!config.min) {
- result += ",";
+ if (Object.getOwnPropertySymbols) {
+ Object.getOwnPropertySymbols(object).forEach(symbol => {
+ if (Object.getOwnPropertyDescriptor(object, symbol)!.enumerable) {
+ keys.push(symbol);
}
- }
-
- result += config.spacingOuter + indentation;
+ });
}
- return result;
-}
+ return keys;
+};
/**
* Return properties of an object
@@ -505,10 +416,112 @@ function printObjectProperties(
}
/**
+ * Handles more complex objects ( such as objects with circular references.
+ * maps and sets etc )
+ */
+function printComplexValue(
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
+ val: any,
+ config: Config,
+ indentation: string,
+ depth: number,
+ refs: Refs,
+ hasCalledToJSON?: boolean
+): string {
+ if (refs.indexOf(val) !== -1) {
+ return "[Circular]";
+ }
+ refs = refs.slice();
+ refs.push(val);
+
+ const hitMaxDepth = ++depth > config.maxDepth;
+ const { min, callToJSON } = config;
+
+ if (
+ callToJSON &&
+ !hitMaxDepth &&
+ val.toJSON &&
+ typeof val.toJSON === "function" &&
+ !hasCalledToJSON
+ ) {
+ return printer(val.toJSON(), config, indentation, depth, refs, true);
+ }
+
+ const toStringed = toString.call(val);
+ if (toStringed === "[object Arguments]") {
+ return hitMaxDepth
+ ? "[Arguments]"
+ : (min ? "" : "Arguments ") +
+ "[" +
+ printListItems(val, config, indentation, depth, refs, printer) +
+ "]";
+ }
+ if (isToStringedArrayType(toStringed)) {
+ return hitMaxDepth
+ ? `[${val.constructor.name}]`
+ : (min ? "" : `${val.constructor.name} `) +
+ "[" +
+ printListItems(val, config, indentation, depth, refs, printer) +
+ "]";
+ }
+ if (toStringed === "[object Map]") {
+ return hitMaxDepth
+ ? "[Map]"
+ : "Map {" +
+ printIteratorEntries(
+ val.entries(),
+ config,
+ indentation,
+ depth,
+ refs,
+ printer,
+ " => "
+ ) +
+ "}";
+ }
+ if (toStringed === "[object Set]") {
+ return hitMaxDepth
+ ? "[Set]"
+ : "Set {" +
+ printIteratorValues(
+ val.values(),
+ config,
+ indentation,
+ depth,
+ refs,
+ printer
+ ) +
+ "}";
+ }
+
+ // Avoid failure to serialize global window object in jsdom test environment.
+ // For example, not even relevant if window is prop of React element.
+ return hitMaxDepth || isWindow(val)
+ ? "[" + getConstructorName(val) + "]"
+ : (min ? "" : getConstructorName(val) + " ") +
+ "{" +
+ printObjectProperties(val, config, indentation, depth, refs, printer) +
+ "}";
+}
+
+// TODO this is better done with `.padStart()`
+function createIndent(indent: number): string {
+ return new Array(indent + 1).join(" ");
+}
+
+const getConfig = (options: Options): Config => ({
+ ...options,
+ indent: options.min ? "" : createIndent(options.indent),
+ spacingInner: options.min ? " " : "\n",
+ spacingOuter: options.min ? "" : "\n"
+});
+
+/**
* Returns a presentation string of your `val` object
* @param val any potential JavaScript object
* @param options Custom settings
*/
+// eslint-disable-next-line @typescript-eslint/no-explicit-any
export function format(val: any, options: Optional<Options> = {}): string {
const opts = Object.keys(DEFAULT_OPTIONS).reduce(
(acc: Options, k: keyof Options) => {
diff --git a/testing/format_test.ts b/testing/format_test.ts
index 3e6da4480..7ca0235a5 100644
--- a/testing/format_test.ts
+++ b/testing/format_test.ts
@@ -9,17 +9,19 @@
import { test, assertEqual } from "./mod.ts";
import { format } from "./format.ts";
-function returnArguments(..._args: Array<unknown>) {
+// eslint-disable-next-line @typescript-eslint/no-unused-vars,@typescript-eslint/no-explicit-any
+function returnArguments(...args: any[]): IArguments {
return arguments;
}
-function MyObject(value: unknown) {
+function MyObject(value: unknown): void {
// @ts-ignore
this.name = value;
}
class MyArray<T> extends Array<T> {}
+// eslint-disable-next-line @typescript-eslint/explicit-function-return-type
const createVal = () => [
{
id: "8658c1d0-9eda-4a90-95e1-8001e8eb6036",
@@ -32,6 +34,7 @@ const createVal = () => [
}
];
+// eslint-disable-next-line @typescript-eslint/explicit-function-return-type
const createExpected = () =>
[
"Array [",
@@ -58,7 +61,7 @@ test({
test({
name: "prints an empty array",
fn() {
- const val: any[] = [];
+ const val: unknown[] = [];
assertEqual(format(val), "Array []");
}
});
@@ -151,7 +154,7 @@ test({
name: "prints an anonymous callback function",
fn() {
let val;
- function f(cb: () => void) {
+ function f(cb: () => void): void {
val = cb;
}
// tslint:disable-next-line:no-empty
@@ -164,7 +167,7 @@ test({
name: "prints an anonymous assigned function",
fn() {
// tslint:disable-next-line:no-empty
- const val = () => {};
+ const val = (): void => {};
const formatted = format(val);
assertEqual(
formatted === "[Function anonymous]" || formatted === "[Function val]",
@@ -177,7 +180,7 @@ test({
name: "prints a named function",
fn() {
// tslint:disable-next-line:no-empty
- const val = function named() {};
+ const val = function named(): void {};
assertEqual(format(val), "[Function named]");
}
});
@@ -185,7 +188,7 @@ test({
test({
name: "prints a named generator function",
fn() {
- const val = function* generate() {
+ const val = function* generate(): IterableIterator<number> {
yield 1;
yield 2;
yield 3;
@@ -198,7 +201,7 @@ test({
name: "can customize function names",
fn() {
// tslint:disable-next-line:no-empty
- const val = function named() {};
+ const val = function named(): void {};
assertEqual(
format(val, {
printFunctionName: false
@@ -248,6 +251,7 @@ test({
test({
name: "prints a map with non-string keys",
fn() {
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
const val = new Map<any, any>([
[false, "boolean"],
["false", "string"],
@@ -373,6 +377,7 @@ test({
test({
name: "prints an object with properties and symbols",
fn() {
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
const val: any = {};
val[Symbol("symbol1")] = "value2";
val[Symbol("symbol2")] = "value3";
@@ -388,7 +393,7 @@ test({
name:
"prints an object without non-enumerable properties which have string key",
fn() {
- const val: any = {
+ const val = {
enumerable: true
};
const key = "non-enumerable";
@@ -404,7 +409,7 @@ test({
name:
"prints an object without non-enumerable properties which have symbol key",
fn() {
- const val: any = {
+ const val = {
enumerable: true
};
const key = Symbol("non-enumerable");
@@ -609,6 +614,7 @@ test({
test({
name: "prints circular references",
fn() {
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
const val: any = {};
val.prop = val;
assertEqual(format(val), 'Object {\n "prop": [Circular],\n}');
@@ -787,6 +793,7 @@ test({
name: "calls toJSON on Sets",
fn() {
const set = new Set([1]);
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
(set as any).toJSON = () => "map";
assertEqual(format(set), '"map"');
}
diff --git a/testing/mod.ts b/testing/mod.ts
index 41ae61bea..c1bf2015b 100644
--- a/testing/mod.ts
+++ b/testing/mod.ts
@@ -3,9 +3,37 @@
import { green, red } from "../colors/mod.ts";
interface Constructor {
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
new (...args: any[]): any;
}
+export function equal(c: unknown, d: unknown): boolean {
+ const seen = new Map();
+ return (function compare(a: unknown, b: unknown) {
+ if (Object.is(a, b)) {
+ return true;
+ }
+ if (a && typeof a === "object" && b && typeof b === "object") {
+ if (seen.get(a) === b) {
+ return true;
+ }
+ if (Object.keys(a || {}).length !== Object.keys(b || {}).length) {
+ return false;
+ }
+ const merged = { ...a, ...b };
+ for (const key in merged) {
+ type Key = keyof typeof merged;
+ if (!compare(a && a[key as Key], b && b[key as Key])) {
+ return false;
+ }
+ }
+ seen.set(a, b);
+ return true;
+ }
+ return false;
+ })(c, d);
+}
+
const assertions = {
/** Make an assertion, if not `true`, then throw. */
assert(expr: boolean, msg = ""): void {
@@ -78,6 +106,7 @@ const assertions = {
* Forcefully throws a failed assertion
*/
fail(msg?: string): void {
+ // eslint-disable-next-line @typescript-eslint/no-use-before-define
assert(false, `Failed assertion${msg ? `: ${msg}` : "."}`);
},
@@ -163,33 +192,6 @@ export const assert = assertions.assert as Assert;
*/
export const assertEqual = assert.equal;
-export function equal(c: unknown, d: unknown): boolean {
- const seen = new Map();
- return (function compare(a: unknown, b: unknown) {
- if (Object.is(a, b)) {
- return true;
- }
- if (a && typeof a === "object" && b && typeof b === "object") {
- if (seen.get(a) === b) {
- return true;
- }
- if (Object.keys(a || {}).length !== Object.keys(b || {}).length) {
- return false;
- }
- const merged = { ...a, ...b };
- for (const key in merged) {
- type Key = keyof typeof merged;
- if (!compare(a && a[key as Key], b && b[key as Key])) {
- return false;
- }
- }
- seen.set(a, b);
- return true;
- }
- return false;
- })(c, d);
-}
-
export type TestFunction = () => void | Promise<void>;
export interface TestDefinition {
@@ -203,14 +205,20 @@ let filterRegExp: RegExp | null;
const tests: TestDefinition[] = [];
let filtered = 0;
-const ignored = 0;
-const measured = 0;
// Must be called before any test() that needs to be filtered.
export function setFilter(s: string): void {
filterRegExp = new RegExp(s, "i");
}
+function filter(name: string): boolean {
+ if (filterRegExp) {
+ return filterRegExp.test(name);
+ } else {
+ return true;
+ }
+}
+
export function test(t: TestDefinition | TestFunction): void {
const fn: TestFunction = typeof t === "function" ? t : t.fn;
const name: string = t.name;
@@ -225,21 +233,8 @@ export function test(t: TestDefinition | TestFunction): void {
}
}
-function filter(name: string): boolean {
- if (filterRegExp) {
- return filterRegExp.test(name);
- } else {
- return true;
- }
-}
-
-function red_failed() {
- return red("FAILED");
-}
-
-function green_ok() {
- return green("ok");
-}
+const RED_FAILED = red("FAILED");
+const GREEN_OK = green("ok");
interface TestStats {
filtered: number;
@@ -261,7 +256,7 @@ interface TestResults {
cases: Map<number, TestResult>;
}
-function createTestResults(tests: Array<TestDefinition>): TestResults {
+function createTestResults(tests: TestDefinition[]): TestResults {
return tests.reduce(
(acc: TestResults, { name }: TestDefinition, i: number): TestResults => {
acc.keys.set(name, i);
@@ -274,10 +269,10 @@ function createTestResults(tests: Array<TestDefinition>): TestResults {
function report(result: TestResult): void {
if (result.ok) {
- console.log(`test ${result.name} ... ${green_ok()}`);
+ console.log(`test ${result.name} ... ${GREEN_OK}`);
} else if (result.error) {
console.error(
- `test ${result.name} ... ${red_failed()}\n${result.error.stack}`
+ `test ${result.name} ... ${RED_FAILED}\n${result.error.stack}`
);
} else {
console.log(`test ${result.name} ... unresolved`);
@@ -302,7 +297,7 @@ function printResults(
}
// Attempting to match the output of Rust's test runner.
console.log(
- `\ntest result: ${stats.failed ? red_failed() : green_ok()}. ` +
+ `\ntest result: ${stats.failed ? RED_FAILED : GREEN_OK}. ` +
`${stats.passed} passed; ${stats.failed} failed; ` +
`${stats.ignored} ignored; ${stats.measured} measured; ` +
`${stats.filtered} filtered out\n`
@@ -342,7 +337,7 @@ async function createTestCase(
function initTestCases(
stats: TestStats,
results: TestResults,
- tests: Array<TestDefinition>
+ tests: TestDefinition[]
): Array<Promise<void>> {
return tests.map(createTestCase.bind(null, stats, results));
}
@@ -350,7 +345,7 @@ function initTestCases(
async function runTestsParallel(
stats: TestStats,
results: TestResults,
- tests: Array<TestDefinition>
+ tests: TestDefinition[]
): Promise<void> {
try {
await Promise.all(initTestCases(stats, results, tests));
@@ -362,7 +357,7 @@ async function runTestsParallel(
async function runTestsSerial(
stats: TestStats,
- tests: Array<TestDefinition>
+ tests: TestDefinition[]
): Promise<void> {
for (const { fn, name } of tests) {
// See https://github.com/denoland/deno/pull/1452
@@ -371,10 +366,10 @@ async function runTestsSerial(
try {
await fn();
stats.passed++;
- console.log("...", green_ok());
+ console.log("...", GREEN_OK);
console.groupEnd();
} catch (err) {
- console.log("...", red_failed());
+ console.log("...", RED_FAILED);
console.groupEnd();
console.error(err.stack);
stats.failed++;
diff --git a/testing/pretty.ts b/testing/pretty.ts
index aa90f2469..b27b3ccd7 100644
--- a/testing/pretty.ts
+++ b/testing/pretty.ts
@@ -15,7 +15,7 @@ function createStr(v: unknown): string {
}
}
-function createColor(diffType: DiffType) {
+function createColor(diffType: DiffType): (s: string) => string {
switch (diffType) {
case "added":
return (s: string) => green(bold(s));
@@ -26,7 +26,7 @@ function createColor(diffType: DiffType) {
}
}
-function createSign(diffType: DiffType) {
+function createSign(diffType: DiffType): string {
switch (diffType) {
case "added":
return "+ ";
@@ -37,7 +37,7 @@ function createSign(diffType: DiffType) {
}
}
-function buildMessage(diffResult: ReadonlyArray<DiffResult<string>>) {
+function buildMessage(diffResult: ReadonlyArray<DiffResult<string>>): string[] {
const messages = [];
messages.push("");
messages.push("");
@@ -55,7 +55,7 @@ function buildMessage(diffResult: ReadonlyArray<DiffResult<string>>) {
return messages;
}
-export function assertEqual(actual: unknown, expected: unknown) {
+export function assertEqual(actual: unknown, expected: unknown): void {
if (equal(actual, expected)) {
return;
}
diff --git a/testing/pretty_test.ts b/testing/pretty_test.ts
index f3b087aff..89b35c088 100644
--- a/testing/pretty_test.ts
+++ b/testing/pretty_test.ts
@@ -4,7 +4,7 @@ import { test, assert } from "./mod.ts";
import { red, green, white, gray, bold } from "../colors/mod.ts";
import { assertEqual } from "./pretty.ts";
-const createHeader = () => [
+const createHeader = (): string[] => [
"",
"",
` ${gray(bold("[Diff]"))} ${red(bold("Left"))} / ${green(bold("Right"))}`,
@@ -12,8 +12,8 @@ const createHeader = () => [
""
];
-const added = (s: string) => green(bold(s));
-const removed = (s: string) => red(bold(s));
+const added: (s: string) => string = (s: string): string => green(bold(s));
+const removed: (s: string) => string = (s: string): string => red(bold(s));
test({
name: "pass case",
diff --git a/testing/test.ts b/testing/test.ts
index 0d79c2218..7182a5783 100644
--- a/testing/test.ts
+++ b/testing/test.ts
@@ -35,8 +35,6 @@ test(function testingAssertEqual() {
});
test(function testingAssertFail() {
- let didThrow = false;
-
assert.throws(assert.fail, Error, "Failed assertion.");
assert.throws(
() => {