2020-01-02 15:13:47 -05:00
|
|
|
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
|
2020-03-04 11:31:14 -05:00
|
|
|
import { assert, assertEquals, unitTest } from "./test_util.ts";
|
2018-08-27 14:59:38 -04:00
|
|
|
|
2019-02-13 08:50:15 -05:00
|
|
|
// Some of these APIs aren't exposed in the types and so we have to cast to any
|
|
|
|
// in order to "trick" TypeScript.
|
2019-08-19 11:35:43 -04:00
|
|
|
const {
|
|
|
|
inspect,
|
2019-12-21 03:58:28 -05:00
|
|
|
writeSync,
|
2019-08-19 11:35:43 -04:00
|
|
|
stdout
|
|
|
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
|
|
} = Deno as any;
|
2018-12-17 11:54:33 -05:00
|
|
|
|
2020-01-16 19:42:58 -05:00
|
|
|
const customInspect = Deno.symbols.customInspect;
|
|
|
|
const {
|
|
|
|
Console,
|
|
|
|
stringifyArgs
|
2020-02-19 15:36:18 -05:00
|
|
|
// @ts-ignore TypeScript (as of 3.7) does not support indexing namespaces by symbol
|
|
|
|
} = Deno[Deno.symbols.internal];
|
2020-01-16 19:42:58 -05:00
|
|
|
|
2019-03-09 12:30:38 -05:00
|
|
|
function stringify(...args: unknown[]): string {
|
2019-03-03 20:12:10 -05:00
|
|
|
return stringifyArgs(args).replace(/\n$/, "");
|
2018-08-27 14:59:38 -04:00
|
|
|
}
|
|
|
|
|
2019-04-03 08:37:01 -04:00
|
|
|
// test cases from web-platform-tests
|
|
|
|
// via https://github.com/web-platform-tests/wpt/blob/master/console/console-is-a-namespace.any.js
|
2020-03-04 11:31:14 -05:00
|
|
|
unitTest(function consoleShouldBeANamespace(): void {
|
2019-04-03 08:37:01 -04:00
|
|
|
const prototype1 = Object.getPrototypeOf(console);
|
|
|
|
const prototype2 = Object.getPrototypeOf(prototype1);
|
|
|
|
|
|
|
|
assertEquals(Object.getOwnPropertyNames(prototype1).length, 0);
|
|
|
|
assertEquals(prototype2, Object.prototype);
|
|
|
|
});
|
|
|
|
|
2020-03-04 11:31:14 -05:00
|
|
|
unitTest(function consoleHasRightInstance(): void {
|
2019-04-08 09:25:01 -04:00
|
|
|
assert(console instanceof Console);
|
|
|
|
assertEquals({} instanceof Console, false);
|
|
|
|
});
|
|
|
|
|
2020-03-04 11:31:14 -05:00
|
|
|
unitTest(function consoleTestAssertShouldNotThrowError(): void {
|
2020-03-03 09:51:07 -05:00
|
|
|
mockConsole(console => {
|
|
|
|
console.assert(true);
|
|
|
|
let hasThrown = undefined;
|
|
|
|
try {
|
|
|
|
console.assert(false);
|
|
|
|
hasThrown = false;
|
|
|
|
} catch {
|
|
|
|
hasThrown = true;
|
|
|
|
}
|
|
|
|
assertEquals(hasThrown, false);
|
|
|
|
});
|
2018-08-27 14:59:38 -04:00
|
|
|
});
|
|
|
|
|
2020-03-04 11:31:14 -05:00
|
|
|
unitTest(function consoleTestStringifyComplexObjects(): void {
|
2019-03-06 20:48:46 -05:00
|
|
|
assertEquals(stringify("foo"), "foo");
|
|
|
|
assertEquals(stringify(["foo", "bar"]), `[ "foo", "bar" ]`);
|
|
|
|
assertEquals(stringify({ foo: "bar" }), `{ foo: "bar" }`);
|
2018-08-27 14:59:38 -04:00
|
|
|
});
|
|
|
|
|
2020-03-04 11:31:14 -05:00
|
|
|
unitTest(function consoleTestStringifyLongStrings(): void {
|
2019-03-19 13:52:25 -04:00
|
|
|
const veryLongString = "a".repeat(200);
|
|
|
|
// If we stringify an object containing the long string, it gets abbreviated.
|
|
|
|
let actual = stringify({ veryLongString });
|
|
|
|
assert(actual.includes("..."));
|
|
|
|
assert(actual.length < 200);
|
|
|
|
// However if we stringify the string itself, we get it exactly.
|
|
|
|
actual = stringify(veryLongString);
|
|
|
|
assertEquals(actual, veryLongString);
|
|
|
|
});
|
|
|
|
|
2019-04-21 16:40:10 -04:00
|
|
|
/* eslint-disable @typescript-eslint/explicit-function-return-type */
|
2020-03-04 11:31:14 -05:00
|
|
|
unitTest(function consoleTestStringifyCircular(): void {
|
2018-08-27 14:59:38 -04:00
|
|
|
class Base {
|
|
|
|
a = 1;
|
2019-04-21 16:40:10 -04:00
|
|
|
m1() {}
|
2018-08-27 14:59:38 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
class Extended extends Base {
|
|
|
|
b = 2;
|
2019-04-21 16:40:10 -04:00
|
|
|
m2() {}
|
2018-08-27 14:59:38 -04:00
|
|
|
}
|
|
|
|
|
2019-03-09 12:30:38 -05:00
|
|
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
2018-08-27 14:59:38 -04:00
|
|
|
const nestedObj: any = {
|
|
|
|
num: 1,
|
|
|
|
bool: true,
|
|
|
|
str: "a",
|
|
|
|
method() {},
|
2018-09-24 10:06:48 -04:00
|
|
|
async asyncMethod() {},
|
|
|
|
*generatorMethod() {},
|
2018-08-27 14:59:38 -04:00
|
|
|
un: undefined,
|
|
|
|
nu: null,
|
|
|
|
arrowFunc: () => {},
|
|
|
|
extendedClass: new Extended(),
|
|
|
|
nFunc: new Function(),
|
|
|
|
extendedCstr: Extended
|
|
|
|
};
|
|
|
|
|
|
|
|
const circularObj = {
|
|
|
|
num: 2,
|
|
|
|
bool: false,
|
|
|
|
str: "b",
|
|
|
|
method() {},
|
|
|
|
un: undefined,
|
|
|
|
nu: null,
|
|
|
|
nested: nestedObj,
|
|
|
|
emptyObj: {},
|
|
|
|
arr: [1, "s", false, null, nestedObj],
|
|
|
|
baseClass: new Base()
|
|
|
|
};
|
|
|
|
|
|
|
|
nestedObj.o = circularObj;
|
Improve pretty printing of objects
If an object has more than 5 elements, it is printed in abbeviated form
displaying only the keys. This is useful in the REPL when inspecting
large objects like the Deno namespace:
> Deno
{ args, noColor, pid, env, exit, isTTY, execPath, chdir, cwd, File,
open, stdin, stdout, stderr, read, write, seek, close, copy,
toAsyncIterator, SeekMode, Buffer, readAll, mkdirSync, mkdir,
makeTempDirSync, makeTempDir, chmodSync, chmod, removeSync, remove,
renameSync, rename, readFileSync, readFile, readDirSync, readDir,
copyFileSync, copyFile, readlinkSync, readlink, statSync, lstatSync,
stat, lstat, symlinkSync, symlink, writeFileSync, writeFile, ErrorKind,
DenoError, libdeno, permissions, revokePermission, truncateSync,
truncate, connect, dial, listen, metrics, resources, run, Process,
inspect, build, platform, version, Console, stringifyArgs,
DomIterableMixin }
2019-03-19 12:15:01 -04:00
|
|
|
const nestedObjExpected = `{ num, bool, str, method, asyncMethod, generatorMethod, un, nu, arrowFunc, extendedClass, nFunc, extendedCstr, o }`;
|
2018-08-27 14:59:38 -04:00
|
|
|
|
2019-03-06 20:48:46 -05:00
|
|
|
assertEquals(stringify(1), "1");
|
2019-05-03 14:01:20 -04:00
|
|
|
assertEquals(stringify(-0), "-0");
|
2019-03-06 20:48:46 -05:00
|
|
|
assertEquals(stringify(1n), "1n");
|
|
|
|
assertEquals(stringify("s"), "s");
|
|
|
|
assertEquals(stringify(false), "false");
|
|
|
|
assertEquals(stringify(new Number(1)), "[Number: 1]");
|
|
|
|
assertEquals(stringify(new Boolean(true)), "[Boolean: true]");
|
|
|
|
assertEquals(stringify(new String("deno")), `[String: "deno"]`);
|
|
|
|
assertEquals(stringify(/[0-9]*/), "/[0-9]*/");
|
|
|
|
assertEquals(
|
2018-12-10 12:01:02 -05:00
|
|
|
stringify(new Date("2018-12-10T02:26:59.002Z")),
|
|
|
|
"2018-12-10T02:26:59.002Z"
|
|
|
|
);
|
2019-03-06 20:48:46 -05:00
|
|
|
assertEquals(stringify(new Set([1, 2, 3])), "Set { 1, 2, 3 }");
|
|
|
|
assertEquals(
|
2019-11-13 13:42:34 -05:00
|
|
|
stringify(
|
|
|
|
new Map([
|
|
|
|
[1, "one"],
|
|
|
|
[2, "two"]
|
|
|
|
])
|
|
|
|
),
|
2018-12-10 12:01:02 -05:00
|
|
|
`Map { 1 => "one", 2 => "two" }`
|
|
|
|
);
|
2019-03-06 20:48:46 -05:00
|
|
|
assertEquals(stringify(new WeakSet()), "WeakSet { [items unknown] }");
|
|
|
|
assertEquals(stringify(new WeakMap()), "WeakMap { [items unknown] }");
|
|
|
|
assertEquals(stringify(Symbol(1)), "Symbol(1)");
|
|
|
|
assertEquals(stringify(null), "null");
|
|
|
|
assertEquals(stringify(undefined), "undefined");
|
|
|
|
assertEquals(stringify(new Extended()), "Extended { a: 1, b: 2 }");
|
2019-11-13 13:42:34 -05:00
|
|
|
assertEquals(
|
|
|
|
stringify(function f(): void {}),
|
|
|
|
"[Function: f]"
|
|
|
|
);
|
2019-04-21 16:40:10 -04:00
|
|
|
assertEquals(
|
|
|
|
stringify(async function af(): Promise<void> {}),
|
|
|
|
"[AsyncFunction: af]"
|
|
|
|
);
|
2019-11-13 13:42:34 -05:00
|
|
|
assertEquals(
|
|
|
|
stringify(function* gf() {}),
|
|
|
|
"[GeneratorFunction: gf]"
|
|
|
|
);
|
2019-03-06 20:48:46 -05:00
|
|
|
assertEquals(
|
2018-09-24 10:06:48 -04:00
|
|
|
stringify(async function* agf() {}),
|
|
|
|
"[AsyncGeneratorFunction: agf]"
|
|
|
|
);
|
2019-03-06 20:48:46 -05:00
|
|
|
assertEquals(stringify(new Uint8Array([1, 2, 3])), "Uint8Array [ 1, 2, 3 ]");
|
|
|
|
assertEquals(stringify(Uint8Array.prototype), "TypedArray []");
|
|
|
|
assertEquals(
|
2018-12-10 12:01:02 -05:00
|
|
|
stringify({ a: { b: { c: { d: new Set([1]) } } } }),
|
|
|
|
"{ a: { b: { c: { d: [Set] } } } }"
|
|
|
|
);
|
2019-03-06 20:48:46 -05:00
|
|
|
assertEquals(stringify(nestedObj), nestedObjExpected);
|
|
|
|
assertEquals(stringify(JSON), "{}");
|
|
|
|
assertEquals(
|
2018-08-27 20:00:54 -04:00
|
|
|
stringify(console),
|
2019-08-29 10:56:27 -04:00
|
|
|
"{ printFunc, log, debug, info, dir, dirxml, warn, error, assert, count, countReset, table, time, timeLog, timeEnd, group, groupCollapsed, groupEnd, clear, trace, indentLevel }"
|
2018-08-27 20:00:54 -04:00
|
|
|
);
|
2018-12-19 22:08:49 -05:00
|
|
|
// test inspect is working the same
|
2019-03-06 20:48:46 -05:00
|
|
|
assertEquals(inspect(nestedObj), nestedObjExpected);
|
2018-08-27 14:59:38 -04:00
|
|
|
});
|
2019-04-21 16:40:10 -04:00
|
|
|
/* eslint-enable @typescript-eslint/explicit-function-return-type */
|
2018-09-26 12:44:59 -04:00
|
|
|
|
2020-03-04 11:31:14 -05:00
|
|
|
unitTest(function consoleTestStringifyWithDepth(): void {
|
2019-03-09 12:30:38 -05:00
|
|
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
2018-09-30 18:10:20 -04:00
|
|
|
const nestedObj: any = { a: { b: { c: { d: { e: { f: 42 } } } } } };
|
2019-03-06 20:48:46 -05:00
|
|
|
assertEquals(
|
2018-09-30 18:10:20 -04:00
|
|
|
stringifyArgs([nestedObj], { depth: 3 }),
|
2019-08-17 12:51:51 -04:00
|
|
|
"{ a: { b: { c: [Object] } } }"
|
2018-09-30 18:10:20 -04:00
|
|
|
);
|
2019-03-06 20:48:46 -05:00
|
|
|
assertEquals(
|
2018-09-30 18:10:20 -04:00
|
|
|
stringifyArgs([nestedObj], { depth: 4 }),
|
2019-08-17 12:51:51 -04:00
|
|
|
"{ a: { b: { c: { d: [Object] } } } }"
|
2018-09-30 18:10:20 -04:00
|
|
|
);
|
2019-08-17 12:51:51 -04:00
|
|
|
assertEquals(stringifyArgs([nestedObj], { depth: 0 }), "[Object]");
|
2019-03-06 20:48:46 -05:00
|
|
|
assertEquals(
|
2020-03-10 12:08:58 -04:00
|
|
|
stringifyArgs([nestedObj]),
|
2019-08-17 12:51:51 -04:00
|
|
|
"{ a: { b: { c: { d: [Object] } } } }"
|
2018-09-30 18:10:20 -04:00
|
|
|
);
|
2018-12-19 22:08:49 -05:00
|
|
|
// test inspect is working the same way
|
2019-03-06 20:48:46 -05:00
|
|
|
assertEquals(
|
2018-12-19 22:08:49 -05:00
|
|
|
inspect(nestedObj, { depth: 4 }),
|
|
|
|
"{ a: { b: { c: { d: [Object] } } } }"
|
|
|
|
);
|
2018-09-30 18:10:20 -04:00
|
|
|
});
|
|
|
|
|
2020-03-04 11:31:14 -05:00
|
|
|
unitTest(function consoleTestWithCustomInspector(): void {
|
2019-08-19 11:35:43 -04:00
|
|
|
class A {
|
|
|
|
[customInspect](): string {
|
|
|
|
return "b";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
assertEquals(stringify(new A()), "b");
|
|
|
|
});
|
|
|
|
|
2020-03-04 11:31:14 -05:00
|
|
|
unitTest(function consoleTestWithCustomInspectorError(): void {
|
2019-10-28 18:29:15 -04:00
|
|
|
class A {
|
|
|
|
[customInspect](): string {
|
|
|
|
throw new Error("BOOM");
|
|
|
|
return "b";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
assertEquals(stringify(new A()), "A {}");
|
|
|
|
|
|
|
|
class B {
|
|
|
|
constructor(public field: { a: string }) {}
|
|
|
|
[customInspect](): string {
|
|
|
|
return this.field.a;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
assertEquals(stringify(new B({ a: "a" })), "a");
|
|
|
|
assertEquals(stringify(B.prototype), "{}");
|
|
|
|
});
|
|
|
|
|
2020-03-04 11:31:14 -05:00
|
|
|
unitTest(function consoleTestWithIntegerFormatSpecifier(): void {
|
2019-03-06 20:48:46 -05:00
|
|
|
assertEquals(stringify("%i"), "%i");
|
|
|
|
assertEquals(stringify("%i", 42.0), "42");
|
|
|
|
assertEquals(stringify("%i", 42), "42");
|
|
|
|
assertEquals(stringify("%i", "42"), "42");
|
|
|
|
assertEquals(stringify("%i", "42.0"), "42");
|
|
|
|
assertEquals(stringify("%i", 1.5), "1");
|
|
|
|
assertEquals(stringify("%i", -0.5), "0");
|
|
|
|
assertEquals(stringify("%i", ""), "NaN");
|
|
|
|
assertEquals(stringify("%i", Symbol()), "NaN");
|
|
|
|
assertEquals(stringify("%i %d", 42, 43), "42 43");
|
|
|
|
assertEquals(stringify("%d %i", 42), "42 %i");
|
|
|
|
assertEquals(stringify("%d", 12345678901234567890123), "1");
|
|
|
|
assertEquals(
|
2019-01-24 12:07:08 -05:00
|
|
|
stringify("%i", 12345678901234567890123n),
|
|
|
|
"12345678901234567890123n"
|
|
|
|
);
|
|
|
|
});
|
|
|
|
|
2020-03-04 11:31:14 -05:00
|
|
|
unitTest(function consoleTestWithFloatFormatSpecifier(): void {
|
2019-03-06 20:48:46 -05:00
|
|
|
assertEquals(stringify("%f"), "%f");
|
|
|
|
assertEquals(stringify("%f", 42.0), "42");
|
|
|
|
assertEquals(stringify("%f", 42), "42");
|
|
|
|
assertEquals(stringify("%f", "42"), "42");
|
|
|
|
assertEquals(stringify("%f", "42.0"), "42");
|
|
|
|
assertEquals(stringify("%f", 1.5), "1.5");
|
|
|
|
assertEquals(stringify("%f", -0.5), "-0.5");
|
|
|
|
assertEquals(stringify("%f", Math.PI), "3.141592653589793");
|
|
|
|
assertEquals(stringify("%f", ""), "NaN");
|
|
|
|
assertEquals(stringify("%f", Symbol("foo")), "NaN");
|
|
|
|
assertEquals(stringify("%f", 5n), "5");
|
|
|
|
assertEquals(stringify("%f %f", 42, 43), "42 43");
|
|
|
|
assertEquals(stringify("%f %f", 42), "42 %f");
|
2019-01-24 12:07:08 -05:00
|
|
|
});
|
|
|
|
|
2020-03-04 11:31:14 -05:00
|
|
|
unitTest(function consoleTestWithStringFormatSpecifier(): void {
|
2019-03-06 20:48:46 -05:00
|
|
|
assertEquals(stringify("%s"), "%s");
|
|
|
|
assertEquals(stringify("%s", undefined), "undefined");
|
|
|
|
assertEquals(stringify("%s", "foo"), "foo");
|
|
|
|
assertEquals(stringify("%s", 42), "42");
|
|
|
|
assertEquals(stringify("%s", "42"), "42");
|
|
|
|
assertEquals(stringify("%s %s", 42, 43), "42 43");
|
|
|
|
assertEquals(stringify("%s %s", 42), "42 %s");
|
|
|
|
assertEquals(stringify("%s", Symbol("foo")), "Symbol(foo)");
|
2019-01-24 12:07:08 -05:00
|
|
|
});
|
|
|
|
|
2020-03-04 11:31:14 -05:00
|
|
|
unitTest(function consoleTestWithObjectFormatSpecifier(): void {
|
2019-03-06 20:48:46 -05:00
|
|
|
assertEquals(stringify("%o"), "%o");
|
|
|
|
assertEquals(stringify("%o", 42), "42");
|
|
|
|
assertEquals(stringify("%o", "foo"), "foo");
|
|
|
|
assertEquals(stringify("o: %o, a: %O", {}, []), "o: {}, a: []");
|
|
|
|
assertEquals(stringify("%o", { a: 42 }), "{ a: 42 }");
|
|
|
|
assertEquals(
|
2019-01-24 12:07:08 -05:00
|
|
|
stringify("%o", { a: { b: { c: { d: new Set([1]) } } } }),
|
|
|
|
"{ a: { b: { c: { d: [Set] } } } }"
|
|
|
|
);
|
|
|
|
});
|
|
|
|
|
2020-03-04 11:31:14 -05:00
|
|
|
unitTest(function consoleTestWithVariousOrInvalidFormatSpecifier(): void {
|
2019-03-06 20:48:46 -05:00
|
|
|
assertEquals(stringify("%s:%s"), "%s:%s");
|
|
|
|
assertEquals(stringify("%i:%i"), "%i:%i");
|
|
|
|
assertEquals(stringify("%d:%d"), "%d:%d");
|
|
|
|
assertEquals(stringify("%%s%s", "foo"), "%sfoo");
|
|
|
|
assertEquals(stringify("%s:%s", undefined), "undefined:%s");
|
|
|
|
assertEquals(stringify("%s:%s", "foo", "bar"), "foo:bar");
|
|
|
|
assertEquals(stringify("%s:%s", "foo", "bar", "baz"), "foo:bar baz");
|
|
|
|
assertEquals(stringify("%%%s%%", "hi"), "%hi%");
|
|
|
|
assertEquals(stringify("%d:%d", 12), "12:%d");
|
|
|
|
assertEquals(stringify("%i:%i", 12), "12:%i");
|
|
|
|
assertEquals(stringify("%f:%f", 12), "12:%f");
|
|
|
|
assertEquals(stringify("o: %o, a: %o", {}), "o: {}, a: %o");
|
|
|
|
assertEquals(stringify("abc%", 1), "abc% 1");
|
2019-01-24 12:07:08 -05:00
|
|
|
});
|
|
|
|
|
2020-03-04 11:31:14 -05:00
|
|
|
unitTest(function consoleTestCallToStringOnLabel(): void {
|
2018-12-17 11:54:33 -05:00
|
|
|
const methods = ["count", "countReset", "time", "timeLog", "timeEnd"];
|
2020-03-03 09:51:07 -05:00
|
|
|
mockConsole(console => {
|
|
|
|
for (const method of methods) {
|
|
|
|
let hasCalled = false;
|
|
|
|
// @ts-ignore
|
|
|
|
console[method]({
|
|
|
|
toString(): void {
|
|
|
|
hasCalled = true;
|
|
|
|
}
|
|
|
|
});
|
|
|
|
assertEquals(hasCalled, true);
|
|
|
|
}
|
|
|
|
});
|
2018-12-17 11:54:33 -05:00
|
|
|
});
|
|
|
|
|
2020-03-04 11:31:14 -05:00
|
|
|
unitTest(function consoleTestError(): void {
|
2018-09-26 12:44:59 -04:00
|
|
|
class MyError extends Error {
|
2018-10-03 21:18:23 -04:00
|
|
|
constructor(errStr: string) {
|
|
|
|
super(errStr);
|
2018-09-26 12:44:59 -04:00
|
|
|
this.name = "MyError";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
try {
|
|
|
|
throw new MyError("This is an error");
|
|
|
|
} catch (e) {
|
2019-02-11 12:57:26 -05:00
|
|
|
assert(
|
|
|
|
stringify(e)
|
2019-04-03 08:38:50 -04:00
|
|
|
.split("\n")[0] // error has been caught
|
2019-02-11 12:57:26 -05:00
|
|
|
.includes("MyError: This is an error")
|
|
|
|
);
|
2018-09-26 12:44:59 -04:00
|
|
|
}
|
|
|
|
});
|
2018-10-01 12:41:37 -04:00
|
|
|
|
2020-03-04 11:31:14 -05:00
|
|
|
unitTest(function consoleTestClear(): void {
|
2019-12-21 03:58:28 -05:00
|
|
|
const stdoutWriteSync = stdout.writeSync;
|
2019-01-24 13:24:39 -05:00
|
|
|
const uint8 = new TextEncoder().encode("\x1b[1;1H" + "\x1b[0J");
|
|
|
|
let buffer = new Uint8Array(0);
|
|
|
|
|
2019-12-21 03:58:28 -05:00
|
|
|
stdout.writeSync = (u8: Uint8Array): Promise<number> => {
|
2019-01-24 13:24:39 -05:00
|
|
|
const tmp = new Uint8Array(buffer.length + u8.length);
|
|
|
|
tmp.set(buffer, 0);
|
|
|
|
tmp.set(u8, buffer.length);
|
|
|
|
buffer = tmp;
|
|
|
|
|
2019-12-21 03:58:28 -05:00
|
|
|
return writeSync(stdout.rid, u8);
|
2019-01-24 13:24:39 -05:00
|
|
|
};
|
|
|
|
console.clear();
|
2019-12-21 03:58:28 -05:00
|
|
|
stdout.writeSync = stdoutWriteSync;
|
2019-03-06 20:48:46 -05:00
|
|
|
assertEquals(buffer, uint8);
|
2019-01-24 13:24:39 -05:00
|
|
|
});
|
|
|
|
|
2018-10-01 12:41:37 -04:00
|
|
|
// Test bound this issue
|
2020-03-04 11:31:14 -05:00
|
|
|
unitTest(function consoleDetachedLog(): void {
|
2020-03-03 09:51:07 -05:00
|
|
|
mockConsole(console => {
|
|
|
|
const log = console.log;
|
|
|
|
const dir = console.dir;
|
|
|
|
const dirxml = console.dirxml;
|
|
|
|
const debug = console.debug;
|
|
|
|
const info = console.info;
|
|
|
|
const warn = console.warn;
|
|
|
|
const error = console.error;
|
|
|
|
const consoleAssert = console.assert;
|
|
|
|
const consoleCount = console.count;
|
|
|
|
const consoleCountReset = console.countReset;
|
|
|
|
const consoleTable = console.table;
|
|
|
|
const consoleTime = console.time;
|
|
|
|
const consoleTimeLog = console.timeLog;
|
|
|
|
const consoleTimeEnd = console.timeEnd;
|
|
|
|
const consoleGroup = console.group;
|
|
|
|
const consoleGroupEnd = console.groupEnd;
|
|
|
|
const consoleClear = console.clear;
|
|
|
|
log("Hello world");
|
|
|
|
dir("Hello world");
|
|
|
|
dirxml("Hello world");
|
|
|
|
debug("Hello world");
|
|
|
|
info("Hello world");
|
|
|
|
warn("Hello world");
|
|
|
|
error("Hello world");
|
|
|
|
consoleAssert(true);
|
|
|
|
consoleCount("Hello world");
|
|
|
|
consoleCountReset("Hello world");
|
|
|
|
consoleTable({ test: "Hello world" });
|
|
|
|
consoleTime("Hello world");
|
|
|
|
consoleTimeLog("Hello world");
|
|
|
|
consoleTimeEnd("Hello world");
|
|
|
|
consoleGroup("Hello world");
|
|
|
|
consoleGroupEnd();
|
|
|
|
consoleClear();
|
|
|
|
});
|
2018-10-01 12:41:37 -04:00
|
|
|
});
|
2019-02-25 19:11:54 -05:00
|
|
|
|
|
|
|
class StringBuffer {
|
|
|
|
chunks: string[] = [];
|
2019-03-09 12:30:38 -05:00
|
|
|
add(x: string): void {
|
2019-02-25 19:11:54 -05:00
|
|
|
this.chunks.push(x);
|
|
|
|
}
|
2019-03-09 12:30:38 -05:00
|
|
|
toString(): string {
|
2019-02-25 19:11:54 -05:00
|
|
|
return this.chunks.join("");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
type ConsoleExamineFunc = (
|
2019-03-09 12:30:38 -05:00
|
|
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
|
|
csl: any,
|
2019-02-25 19:11:54 -05:00
|
|
|
out: StringBuffer,
|
|
|
|
err?: StringBuffer,
|
|
|
|
both?: StringBuffer
|
|
|
|
) => void;
|
|
|
|
|
2019-03-09 12:30:38 -05:00
|
|
|
function mockConsole(f: ConsoleExamineFunc): void {
|
2019-02-25 19:11:54 -05:00
|
|
|
const out = new StringBuffer();
|
|
|
|
const err = new StringBuffer();
|
|
|
|
const both = new StringBuffer();
|
|
|
|
const csl = new Console(
|
2019-04-21 16:40:10 -04:00
|
|
|
(x: string, isErr: boolean, printsNewLine: boolean): void => {
|
2019-02-25 19:11:54 -05:00
|
|
|
const content = x + (printsNewLine ? "\n" : "");
|
|
|
|
const buf = isErr ? err : out;
|
|
|
|
buf.add(content);
|
|
|
|
both.add(content);
|
|
|
|
}
|
|
|
|
);
|
|
|
|
f(csl, out, err, both);
|
|
|
|
}
|
|
|
|
|
|
|
|
// console.group test
|
2020-03-04 11:31:14 -05:00
|
|
|
unitTest(function consoleGroup(): void {
|
2019-11-13 13:42:34 -05:00
|
|
|
mockConsole((console, out): void => {
|
|
|
|
console.group("1");
|
|
|
|
console.log("2");
|
|
|
|
console.group("3");
|
|
|
|
console.log("4");
|
|
|
|
console.groupEnd();
|
|
|
|
console.groupEnd();
|
|
|
|
console.log("5");
|
|
|
|
console.log("6");
|
|
|
|
|
|
|
|
assertEquals(
|
|
|
|
out.toString(),
|
|
|
|
`1
|
2019-02-25 19:11:54 -05:00
|
|
|
2
|
|
|
|
3
|
|
|
|
4
|
2019-08-17 12:51:51 -04:00
|
|
|
5
|
|
|
|
6
|
2019-02-25 19:11:54 -05:00
|
|
|
`
|
2019-11-13 13:42:34 -05:00
|
|
|
);
|
|
|
|
});
|
2019-02-25 19:11:54 -05:00
|
|
|
});
|
|
|
|
|
|
|
|
// console.group with console.warn test
|
2020-03-04 11:31:14 -05:00
|
|
|
unitTest(function consoleGroupWarn(): void {
|
2019-11-13 13:42:34 -05:00
|
|
|
mockConsole((console, _out, _err, both): void => {
|
2020-02-19 15:36:18 -05:00
|
|
|
assert(both);
|
2019-11-13 13:42:34 -05:00
|
|
|
console.warn("1");
|
|
|
|
console.group();
|
|
|
|
console.warn("2");
|
|
|
|
console.group();
|
|
|
|
console.warn("3");
|
|
|
|
console.groupEnd();
|
|
|
|
console.warn("4");
|
|
|
|
console.groupEnd();
|
|
|
|
console.warn("5");
|
|
|
|
|
|
|
|
console.warn("6");
|
|
|
|
console.warn("7");
|
|
|
|
assertEquals(
|
|
|
|
both.toString(),
|
|
|
|
`1
|
2019-02-25 19:11:54 -05:00
|
|
|
2
|
|
|
|
3
|
|
|
|
4
|
|
|
|
5
|
2019-08-17 12:51:51 -04:00
|
|
|
6
|
|
|
|
7
|
2019-02-25 19:11:54 -05:00
|
|
|
`
|
2019-11-13 13:42:34 -05:00
|
|
|
);
|
|
|
|
});
|
2019-02-25 19:11:54 -05:00
|
|
|
});
|
|
|
|
|
|
|
|
// console.table test
|
2020-03-04 11:31:14 -05:00
|
|
|
unitTest(function consoleTable(): void {
|
2019-11-13 13:42:34 -05:00
|
|
|
mockConsole((console, out): void => {
|
|
|
|
console.table({ a: "test", b: 1 });
|
|
|
|
assertEquals(
|
|
|
|
out.toString(),
|
|
|
|
`┌─────────┬────────┐
|
2019-02-25 19:11:54 -05:00
|
|
|
│ (index) │ Values │
|
|
|
|
├─────────┼────────┤
|
|
|
|
│ a │ "test" │
|
|
|
|
│ b │ 1 │
|
|
|
|
└─────────┴────────┘
|
|
|
|
`
|
2019-11-13 13:42:34 -05:00
|
|
|
);
|
|
|
|
});
|
|
|
|
mockConsole((console, out): void => {
|
|
|
|
console.table({ a: { b: 10 }, b: { b: 20, c: 30 } }, ["c"]);
|
|
|
|
assertEquals(
|
|
|
|
out.toString(),
|
|
|
|
`┌─────────┬────┐
|
2019-02-25 19:11:54 -05:00
|
|
|
│ (index) │ c │
|
|
|
|
├─────────┼────┤
|
|
|
|
│ a │ │
|
|
|
|
│ b │ 30 │
|
|
|
|
└─────────┴────┘
|
|
|
|
`
|
2019-11-13 13:42:34 -05:00
|
|
|
);
|
|
|
|
});
|
|
|
|
mockConsole((console, out): void => {
|
|
|
|
console.table([1, 2, [3, [4]], [5, 6], [[7], [8]]]);
|
|
|
|
assertEquals(
|
|
|
|
out.toString(),
|
|
|
|
`┌─────────┬───────┬───────┬────────┐
|
2019-02-25 19:11:54 -05:00
|
|
|
│ (index) │ 0 │ 1 │ Values │
|
|
|
|
├─────────┼───────┼───────┼────────┤
|
|
|
|
│ 0 │ │ │ 1 │
|
|
|
|
│ 1 │ │ │ 2 │
|
|
|
|
│ 2 │ 3 │ [ 4 ] │ │
|
|
|
|
│ 3 │ 5 │ 6 │ │
|
|
|
|
│ 4 │ [ 7 ] │ [ 8 ] │ │
|
|
|
|
└─────────┴───────┴───────┴────────┘
|
|
|
|
`
|
2019-11-13 13:42:34 -05:00
|
|
|
);
|
|
|
|
});
|
|
|
|
mockConsole((console, out): void => {
|
|
|
|
console.table(new Set([1, 2, 3, "test"]));
|
|
|
|
assertEquals(
|
|
|
|
out.toString(),
|
|
|
|
`┌───────────────────┬────────┐
|
2019-02-25 19:11:54 -05:00
|
|
|
│ (iteration index) │ Values │
|
|
|
|
├───────────────────┼────────┤
|
|
|
|
│ 0 │ 1 │
|
|
|
|
│ 1 │ 2 │
|
|
|
|
│ 2 │ 3 │
|
|
|
|
│ 3 │ "test" │
|
|
|
|
└───────────────────┴────────┘
|
|
|
|
`
|
2019-11-13 13:42:34 -05:00
|
|
|
);
|
|
|
|
});
|
|
|
|
mockConsole((console, out): void => {
|
|
|
|
console.table(
|
|
|
|
new Map([
|
|
|
|
[1, "one"],
|
|
|
|
[2, "two"]
|
|
|
|
])
|
|
|
|
);
|
|
|
|
assertEquals(
|
|
|
|
out.toString(),
|
|
|
|
`┌───────────────────┬─────┬────────┐
|
2019-02-25 19:11:54 -05:00
|
|
|
│ (iteration index) │ Key │ Values │
|
|
|
|
├───────────────────┼─────┼────────┤
|
|
|
|
│ 0 │ 1 │ "one" │
|
|
|
|
│ 1 │ 2 │ "two" │
|
|
|
|
└───────────────────┴─────┴────────┘
|
|
|
|
`
|
2019-11-13 13:42:34 -05:00
|
|
|
);
|
|
|
|
});
|
|
|
|
mockConsole((console, out): void => {
|
|
|
|
console.table({
|
|
|
|
a: true,
|
|
|
|
b: { c: { d: 10 }, e: [1, 2, [5, 6]] },
|
|
|
|
f: "test",
|
|
|
|
g: new Set([1, 2, 3, "test"]),
|
|
|
|
h: new Map([[1, "one"]])
|
|
|
|
});
|
|
|
|
assertEquals(
|
|
|
|
out.toString(),
|
|
|
|
`┌─────────┬───────────┬───────────────────┬────────┐
|
2019-02-25 19:11:54 -05:00
|
|
|
│ (index) │ c │ e │ Values │
|
|
|
|
├─────────┼───────────┼───────────────────┼────────┤
|
|
|
|
│ a │ │ │ true │
|
|
|
|
│ b │ { d: 10 } │ [ 1, 2, [Array] ] │ │
|
|
|
|
│ f │ │ │ "test" │
|
|
|
|
│ g │ │ │ │
|
|
|
|
│ h │ │ │ │
|
|
|
|
└─────────┴───────────┴───────────────────┴────────┘
|
|
|
|
`
|
2019-11-13 13:42:34 -05:00
|
|
|
);
|
|
|
|
});
|
|
|
|
mockConsole((console, out): void => {
|
|
|
|
console.table([
|
|
|
|
1,
|
|
|
|
"test",
|
|
|
|
false,
|
|
|
|
{ a: 10 },
|
|
|
|
["test", { b: 20, c: "test" }]
|
|
|
|
]);
|
|
|
|
assertEquals(
|
|
|
|
out.toString(),
|
|
|
|
`┌─────────┬────────┬──────────────────────┬────┬────────┐
|
2019-02-25 19:11:54 -05:00
|
|
|
│ (index) │ 0 │ 1 │ a │ Values │
|
|
|
|
├─────────┼────────┼──────────────────────┼────┼────────┤
|
|
|
|
│ 0 │ │ │ │ 1 │
|
|
|
|
│ 1 │ │ │ │ "test" │
|
|
|
|
│ 2 │ │ │ │ false │
|
|
|
|
│ 3 │ │ │ 10 │ │
|
|
|
|
│ 4 │ "test" │ { b: 20, c: "test" } │ │ │
|
|
|
|
└─────────┴────────┴──────────────────────┴────┴────────┘
|
|
|
|
`
|
2019-11-13 13:42:34 -05:00
|
|
|
);
|
|
|
|
});
|
|
|
|
mockConsole((console, out): void => {
|
|
|
|
console.table([]);
|
|
|
|
assertEquals(
|
|
|
|
out.toString(),
|
|
|
|
`┌─────────┐
|
2019-02-25 19:11:54 -05:00
|
|
|
│ (index) │
|
|
|
|
├─────────┤
|
|
|
|
└─────────┘
|
|
|
|
`
|
2019-11-13 13:42:34 -05:00
|
|
|
);
|
|
|
|
});
|
|
|
|
mockConsole((console, out): void => {
|
|
|
|
console.table({});
|
|
|
|
assertEquals(
|
|
|
|
out.toString(),
|
|
|
|
`┌─────────┐
|
2019-02-25 19:11:54 -05:00
|
|
|
│ (index) │
|
|
|
|
├─────────┤
|
|
|
|
└─────────┘
|
|
|
|
`
|
2019-11-13 13:42:34 -05:00
|
|
|
);
|
|
|
|
});
|
|
|
|
mockConsole((console, out): void => {
|
|
|
|
console.table(new Set());
|
|
|
|
assertEquals(
|
|
|
|
out.toString(),
|
|
|
|
`┌───────────────────┐
|
2019-02-25 19:11:54 -05:00
|
|
|
│ (iteration index) │
|
|
|
|
├───────────────────┤
|
|
|
|
└───────────────────┘
|
|
|
|
`
|
2019-11-13 13:42:34 -05:00
|
|
|
);
|
|
|
|
});
|
|
|
|
mockConsole((console, out): void => {
|
|
|
|
console.table(new Map());
|
|
|
|
assertEquals(
|
|
|
|
out.toString(),
|
|
|
|
`┌───────────────────┐
|
2019-02-25 19:11:54 -05:00
|
|
|
│ (iteration index) │
|
|
|
|
├───────────────────┤
|
|
|
|
└───────────────────┘
|
|
|
|
`
|
2019-11-13 13:42:34 -05:00
|
|
|
);
|
|
|
|
});
|
|
|
|
mockConsole((console, out): void => {
|
|
|
|
console.table("test");
|
|
|
|
assertEquals(out.toString(), "test\n");
|
|
|
|
});
|
2019-02-25 19:11:54 -05:00
|
|
|
});
|
2019-04-03 08:38:50 -04:00
|
|
|
|
|
|
|
// console.log(Error) test
|
2020-03-04 11:31:14 -05:00
|
|
|
unitTest(function consoleLogShouldNotThrowError(): void {
|
2020-03-03 09:51:07 -05:00
|
|
|
mockConsole(console => {
|
|
|
|
let result = 0;
|
|
|
|
try {
|
|
|
|
console.log(new Error("foo"));
|
|
|
|
result = 1;
|
|
|
|
} catch (e) {
|
|
|
|
result = 2;
|
|
|
|
}
|
|
|
|
assertEquals(result, 1);
|
|
|
|
});
|
2019-04-03 08:38:50 -04:00
|
|
|
|
|
|
|
// output errors to the console should not include "Uncaught"
|
2019-11-13 13:42:34 -05:00
|
|
|
mockConsole((console, out): void => {
|
|
|
|
console.log(new Error("foo"));
|
|
|
|
assertEquals(out.toString().includes("Uncaught"), false);
|
|
|
|
});
|
2019-04-03 08:38:50 -04:00
|
|
|
});
|
2019-08-17 12:51:51 -04:00
|
|
|
|
|
|
|
// console.dir test
|
2020-03-04 11:31:14 -05:00
|
|
|
unitTest(function consoleDir(): void {
|
2019-11-13 13:42:34 -05:00
|
|
|
mockConsole((console, out): void => {
|
|
|
|
console.dir("DIR");
|
|
|
|
assertEquals(out.toString(), "DIR\n");
|
|
|
|
});
|
|
|
|
mockConsole((console, out): void => {
|
|
|
|
console.dir("DIR", { indentLevel: 2 });
|
|
|
|
assertEquals(out.toString(), " DIR\n");
|
|
|
|
});
|
2019-08-17 12:51:51 -04:00
|
|
|
});
|
|
|
|
|
2019-08-29 10:56:27 -04:00
|
|
|
// console.dir test
|
2020-03-04 11:31:14 -05:00
|
|
|
unitTest(function consoleDirXml(): void {
|
2019-11-13 13:42:34 -05:00
|
|
|
mockConsole((console, out): void => {
|
|
|
|
console.dirxml("DIRXML");
|
|
|
|
assertEquals(out.toString(), "DIRXML\n");
|
|
|
|
});
|
|
|
|
mockConsole((console, out): void => {
|
|
|
|
console.dirxml("DIRXML", { indentLevel: 2 });
|
|
|
|
assertEquals(out.toString(), " DIRXML\n");
|
|
|
|
});
|
2019-08-29 10:56:27 -04:00
|
|
|
});
|
|
|
|
|
2019-08-17 12:51:51 -04:00
|
|
|
// console.trace test
|
2020-03-04 11:31:14 -05:00
|
|
|
unitTest(function consoleTrace(): void {
|
2019-11-13 13:42:34 -05:00
|
|
|
mockConsole((console, _out, err): void => {
|
|
|
|
console.trace("%s", "custom message");
|
2020-02-19 15:36:18 -05:00
|
|
|
assert(err);
|
2019-11-13 13:42:34 -05:00
|
|
|
assert(err.toString().includes("Trace: custom message"));
|
|
|
|
});
|
2019-08-17 12:51:51 -04:00
|
|
|
});
|