2019-01-01 19:58:40 -05:00
|
|
|
// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
|
2019-01-24 13:24:39 -05:00
|
|
|
import { Console, libdeno, stringifyArgs, inspect, write, stdout } from "deno";
|
2019-01-12 09:16:18 -05:00
|
|
|
import { test, assertEqual } from "./test_util.ts";
|
2018-08-27 14:59:38 -04:00
|
|
|
|
2018-12-17 11:54:33 -05:00
|
|
|
const console = new Console(libdeno.print);
|
|
|
|
|
2018-08-27 14:59:38 -04:00
|
|
|
// tslint:disable-next-line:no-any
|
|
|
|
function stringify(...args: any[]): string {
|
|
|
|
return stringifyArgs(args);
|
|
|
|
}
|
|
|
|
|
2018-12-14 14:36:08 -05:00
|
|
|
test(function consoleTestAssertShouldNotThrowError() {
|
2018-08-27 14:59:38 -04:00
|
|
|
console.assert(true);
|
|
|
|
|
2018-12-14 14:36:08 -05:00
|
|
|
let hasThrown = undefined;
|
2018-08-27 14:59:38 -04:00
|
|
|
try {
|
|
|
|
console.assert(false);
|
2018-12-14 14:36:08 -05:00
|
|
|
hasThrown = false;
|
2018-08-27 14:59:38 -04:00
|
|
|
} catch {
|
|
|
|
hasThrown = true;
|
|
|
|
}
|
2018-12-14 14:36:08 -05:00
|
|
|
assertEqual(hasThrown, false);
|
2018-08-27 14:59:38 -04:00
|
|
|
});
|
|
|
|
|
|
|
|
test(function consoleTestStringifyComplexObjects() {
|
|
|
|
assertEqual(stringify("foo"), "foo");
|
|
|
|
assertEqual(stringify(["foo", "bar"]), `[ "foo", "bar" ]`);
|
|
|
|
assertEqual(stringify({ foo: "bar" }), `{ foo: "bar" }`);
|
|
|
|
});
|
|
|
|
|
|
|
|
test(function consoleTestStringifyCircular() {
|
|
|
|
class Base {
|
|
|
|
a = 1;
|
|
|
|
m1() {}
|
|
|
|
}
|
|
|
|
|
|
|
|
class Extended extends Base {
|
|
|
|
b = 2;
|
|
|
|
m2() {}
|
|
|
|
}
|
|
|
|
|
|
|
|
// tslint:disable-next-line:no-any
|
|
|
|
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;
|
2018-10-05 10:20:10 -04:00
|
|
|
// tslint:disable-next-line:max-line-length
|
2018-12-10 12:01:02 -05:00
|
|
|
const nestedObjExpected = `{ num: 1, bool: true, str: "a", method: [Function: method], asyncMethod: [AsyncFunction: asyncMethod], generatorMethod: [GeneratorFunction: generatorMethod], un: undefined, nu: null, arrowFunc: [Function: arrowFunc], extendedClass: Extended { a: 1, b: 2 }, nFunc: [Function], extendedCstr: [Function: Extended], o: { num: 2, bool: false, str: "b", method: [Function: method], un: undefined, nu: null, nested: [Circular], emptyObj: {}, arr: [ 1, "s", false, null, [Circular] ], baseClass: Base { a: 1 } } }`;
|
2018-08-27 14:59:38 -04:00
|
|
|
|
|
|
|
assertEqual(stringify(1), "1");
|
2018-11-30 19:59:41 -05:00
|
|
|
assertEqual(stringify(1n), "1n");
|
2018-08-27 14:59:38 -04:00
|
|
|
assertEqual(stringify("s"), "s");
|
|
|
|
assertEqual(stringify(false), "false");
|
2018-12-10 12:01:02 -05:00
|
|
|
// tslint:disable-next-line:no-construct
|
|
|
|
assertEqual(stringify(new Number(1)), "[Number: 1]");
|
|
|
|
// tslint:disable-next-line:no-construct
|
|
|
|
assertEqual(stringify(new Boolean(true)), "[Boolean: true]");
|
|
|
|
// tslint:disable-next-line:no-construct
|
|
|
|
assertEqual(stringify(new String("deno")), `[String: "deno"]`);
|
|
|
|
assertEqual(stringify(/[0-9]*/), "/[0-9]*/");
|
|
|
|
assertEqual(
|
|
|
|
stringify(new Date("2018-12-10T02:26:59.002Z")),
|
|
|
|
"2018-12-10T02:26:59.002Z"
|
|
|
|
);
|
|
|
|
assertEqual(stringify(new Set([1, 2, 3])), "Set { 1, 2, 3 }");
|
|
|
|
assertEqual(
|
|
|
|
stringify(new Map([[1, "one"], [2, "two"]])),
|
|
|
|
`Map { 1 => "one", 2 => "two" }`
|
|
|
|
);
|
|
|
|
assertEqual(stringify(new WeakSet()), "WeakSet { [items unknown] }");
|
|
|
|
assertEqual(stringify(new WeakMap()), "WeakMap { [items unknown] }");
|
2018-08-27 14:59:38 -04:00
|
|
|
assertEqual(stringify(Symbol(1)), "Symbol(1)");
|
|
|
|
assertEqual(stringify(null), "null");
|
|
|
|
assertEqual(stringify(undefined), "undefined");
|
|
|
|
assertEqual(stringify(new Extended()), "Extended { a: 1, b: 2 }");
|
|
|
|
assertEqual(stringify(function f() {}), "[Function: f]");
|
2018-09-24 10:06:48 -04:00
|
|
|
assertEqual(stringify(async function af() {}), "[AsyncFunction: af]");
|
|
|
|
assertEqual(stringify(function* gf() {}), "[GeneratorFunction: gf]");
|
|
|
|
assertEqual(
|
|
|
|
stringify(async function* agf() {}),
|
|
|
|
"[AsyncGeneratorFunction: agf]"
|
|
|
|
);
|
2018-12-10 12:01:02 -05:00
|
|
|
assertEqual(stringify(new Uint8Array([1, 2, 3])), "Uint8Array [ 1, 2, 3 ]");
|
2018-12-12 02:32:24 -05:00
|
|
|
assertEqual(stringify(Uint8Array.prototype), "TypedArray []");
|
2018-12-10 12:01:02 -05:00
|
|
|
assertEqual(
|
|
|
|
stringify({ a: { b: { c: { d: new Set([1]) } } } }),
|
|
|
|
"{ a: { b: { c: { d: [Set] } } } }"
|
|
|
|
);
|
2018-08-27 14:59:38 -04:00
|
|
|
assertEqual(stringify(nestedObj), nestedObjExpected);
|
|
|
|
assertEqual(stringify(JSON), "{}");
|
2018-08-27 20:00:54 -04:00
|
|
|
assertEqual(
|
|
|
|
stringify(console),
|
2018-10-05 07:29:55 -04:00
|
|
|
// tslint:disable-next-line:max-line-length
|
2019-01-28 16:41:29 -05:00
|
|
|
"Console { printFunc: [Function], log: [Function], debug: [Function], info: [Function], dir: [Function], warn: [Function], error: [Function], assert: [Function], count: [Function], countReset: [Function], table: [Function], time: [Function], timeLog: [Function], timeEnd: [Function], group: [Function], groupCollapsed: [Function], groupEnd: [Function], clear: [Function], indentLevel: 0, collapsedAt: null }"
|
2018-08-27 20:00:54 -04:00
|
|
|
);
|
2018-12-19 22:08:49 -05:00
|
|
|
// test inspect is working the same
|
|
|
|
assertEqual(inspect(nestedObj), nestedObjExpected);
|
2018-08-27 14:59:38 -04:00
|
|
|
});
|
2018-09-26 12:44:59 -04:00
|
|
|
|
2018-09-30 18:10:20 -04:00
|
|
|
test(function consoleTestStringifyWithDepth() {
|
2018-10-05 10:20:10 -04:00
|
|
|
// tslint:disable-next-line:no-any
|
2018-09-30 18:10:20 -04:00
|
|
|
const nestedObj: any = { a: { b: { c: { d: { e: { f: 42 } } } } } };
|
|
|
|
assertEqual(
|
|
|
|
stringifyArgs([nestedObj], { depth: 3 }),
|
2018-12-10 12:01:02 -05:00
|
|
|
"{ a: { b: { c: [Object] } } }"
|
2018-09-30 18:10:20 -04:00
|
|
|
);
|
|
|
|
assertEqual(
|
|
|
|
stringifyArgs([nestedObj], { depth: 4 }),
|
2018-12-10 12:01:02 -05:00
|
|
|
"{ a: { b: { c: { d: [Object] } } } }"
|
2018-09-30 18:10:20 -04:00
|
|
|
);
|
2018-12-10 12:01:02 -05:00
|
|
|
assertEqual(stringifyArgs([nestedObj], { depth: 0 }), "[Object]");
|
2018-09-30 18:10:20 -04:00
|
|
|
assertEqual(
|
|
|
|
stringifyArgs([nestedObj], { depth: null }),
|
2018-12-10 12:01:02 -05: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
|
|
|
|
assertEqual(
|
|
|
|
inspect(nestedObj, { depth: 4 }),
|
|
|
|
"{ a: { b: { c: { d: [Object] } } } }"
|
|
|
|
);
|
2018-09-30 18:10:20 -04:00
|
|
|
});
|
|
|
|
|
2019-01-24 12:07:08 -05:00
|
|
|
test(function consoleTestWithIntegerFormatSpecifier() {
|
|
|
|
assertEqual(stringify("%i"), "%i");
|
|
|
|
assertEqual(stringify("%i", 42.0), "42");
|
|
|
|
assertEqual(stringify("%i", 42), "42");
|
|
|
|
assertEqual(stringify("%i", "42"), "42");
|
|
|
|
assertEqual(stringify("%i", "42.0"), "42");
|
|
|
|
assertEqual(stringify("%i", 1.5), "1");
|
|
|
|
assertEqual(stringify("%i", -0.5), "0");
|
|
|
|
assertEqual(stringify("%i", ""), "NaN");
|
|
|
|
assertEqual(stringify("%i", Symbol()), "NaN");
|
|
|
|
assertEqual(stringify("%i %d", 42, 43), "42 43");
|
|
|
|
assertEqual(stringify("%d %i", 42), "42 %i");
|
|
|
|
assertEqual(stringify("%d", 12345678901234567890123), "1");
|
|
|
|
assertEqual(
|
|
|
|
stringify("%i", 12345678901234567890123n),
|
|
|
|
"12345678901234567890123n"
|
|
|
|
);
|
|
|
|
});
|
|
|
|
|
|
|
|
test(function consoleTestWithFloatFormatSpecifier() {
|
|
|
|
assertEqual(stringify("%f"), "%f");
|
|
|
|
assertEqual(stringify("%f", 42.0), "42");
|
|
|
|
assertEqual(stringify("%f", 42), "42");
|
|
|
|
assertEqual(stringify("%f", "42"), "42");
|
|
|
|
assertEqual(stringify("%f", "42.0"), "42");
|
|
|
|
assertEqual(stringify("%f", 1.5), "1.5");
|
|
|
|
assertEqual(stringify("%f", -0.5), "-0.5");
|
|
|
|
assertEqual(stringify("%f", Math.PI), "3.141592653589793");
|
|
|
|
assertEqual(stringify("%f", ""), "NaN");
|
|
|
|
assertEqual(stringify("%f", Symbol("foo")), "NaN");
|
|
|
|
assertEqual(stringify("%f", 5n), "5");
|
|
|
|
assertEqual(stringify("%f %f", 42, 43), "42 43");
|
|
|
|
assertEqual(stringify("%f %f", 42), "42 %f");
|
|
|
|
});
|
|
|
|
|
|
|
|
test(function consoleTestWithStringFormatSpecifier() {
|
|
|
|
assertEqual(stringify("%s"), "%s");
|
|
|
|
assertEqual(stringify("%s", undefined), "undefined");
|
|
|
|
assertEqual(stringify("%s", "foo"), "foo");
|
|
|
|
assertEqual(stringify("%s", 42), "42");
|
|
|
|
assertEqual(stringify("%s", "42"), "42");
|
|
|
|
assertEqual(stringify("%s %s", 42, 43), "42 43");
|
|
|
|
assertEqual(stringify("%s %s", 42), "42 %s");
|
|
|
|
assertEqual(stringify("%s", Symbol("foo")), "Symbol(foo)");
|
|
|
|
});
|
|
|
|
|
|
|
|
test(function consoleTestWithObjectFormatSpecifier() {
|
|
|
|
assertEqual(stringify("%o"), "%o");
|
|
|
|
assertEqual(stringify("%o", 42), "42");
|
|
|
|
assertEqual(stringify("%o", "foo"), "foo");
|
|
|
|
assertEqual(stringify("o: %o, a: %O", {}, []), "o: {}, a: []");
|
|
|
|
assertEqual(stringify("%o", { a: 42 }), "{ a: 42 }");
|
|
|
|
assertEqual(
|
|
|
|
stringify("%o", { a: { b: { c: { d: new Set([1]) } } } }),
|
|
|
|
"{ a: { b: { c: { d: [Set] } } } }"
|
|
|
|
);
|
|
|
|
});
|
|
|
|
|
|
|
|
test(function consoleTestWithVariousOrInvalidFormatSpecifier() {
|
|
|
|
assertEqual(stringify("%s:%s"), "%s:%s");
|
|
|
|
assertEqual(stringify("%i:%i"), "%i:%i");
|
|
|
|
assertEqual(stringify("%d:%d"), "%d:%d");
|
|
|
|
assertEqual(stringify("%%s%s", "foo"), "%sfoo");
|
|
|
|
assertEqual(stringify("%s:%s", undefined), "undefined:%s");
|
|
|
|
assertEqual(stringify("%s:%s", "foo", "bar"), "foo:bar");
|
|
|
|
assertEqual(stringify("%s:%s", "foo", "bar", "baz"), "foo:bar baz");
|
|
|
|
assertEqual(stringify("%%%s%%", "hi"), "%hi%");
|
|
|
|
assertEqual(stringify("%d:%d", 12), "12:%d");
|
|
|
|
assertEqual(stringify("%i:%i", 12), "12:%i");
|
|
|
|
assertEqual(stringify("%f:%f", 12), "12:%f");
|
|
|
|
assertEqual(stringify("o: %o, a: %o", {}), "o: {}, a: %o");
|
|
|
|
assertEqual(stringify("abc%", 1), "abc% 1");
|
|
|
|
});
|
|
|
|
|
2018-12-17 11:54:33 -05:00
|
|
|
test(function consoleTestCallToStringOnLabel() {
|
|
|
|
const methods = ["count", "countReset", "time", "timeLog", "timeEnd"];
|
|
|
|
|
|
|
|
for (const method of methods) {
|
|
|
|
let hasCalled = false;
|
|
|
|
|
|
|
|
console[method]({
|
|
|
|
toString() {
|
|
|
|
hasCalled = true;
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
assertEqual(hasCalled, true);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
2018-09-26 12:44:59 -04:00
|
|
|
test(function consoleTestError() {
|
|
|
|
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) {
|
|
|
|
assertEqual(stringify(e).split("\n")[0], "MyError: This is an error");
|
|
|
|
}
|
|
|
|
});
|
2018-10-01 12:41:37 -04:00
|
|
|
|
2019-01-24 13:24:39 -05:00
|
|
|
test(function consoleTestClear() {
|
|
|
|
const stdoutWrite = stdout.write;
|
|
|
|
const uint8 = new TextEncoder().encode("\x1b[1;1H" + "\x1b[0J");
|
|
|
|
let buffer = new Uint8Array(0);
|
|
|
|
|
|
|
|
stdout.write = async u8 => {
|
|
|
|
const tmp = new Uint8Array(buffer.length + u8.length);
|
|
|
|
tmp.set(buffer, 0);
|
|
|
|
tmp.set(u8, buffer.length);
|
|
|
|
buffer = tmp;
|
|
|
|
|
|
|
|
return await write(stdout.rid, u8);
|
|
|
|
};
|
|
|
|
console.clear();
|
|
|
|
stdout.write = stdoutWrite;
|
|
|
|
assertEqual(buffer, uint8);
|
|
|
|
});
|
|
|
|
|
2018-10-01 12:41:37 -04:00
|
|
|
// Test bound this issue
|
|
|
|
test(function consoleDetachedLog() {
|
|
|
|
const log = console.log;
|
|
|
|
const dir = console.dir;
|
|
|
|
const debug = console.debug;
|
|
|
|
const info = console.info;
|
|
|
|
const warn = console.warn;
|
|
|
|
const error = console.error;
|
|
|
|
const consoleAssert = console.assert;
|
2018-12-17 11:54:33 -05:00
|
|
|
const consoleCount = console.count;
|
|
|
|
const consoleCountReset = console.countReset;
|
2019-01-28 16:41:29 -05:00
|
|
|
const consoleTable = console.table;
|
2018-12-17 11:54:33 -05:00
|
|
|
const consoleTime = console.time;
|
|
|
|
const consoleTimeLog = console.timeLog;
|
|
|
|
const consoleTimeEnd = console.timeEnd;
|
2019-01-06 16:34:52 -05:00
|
|
|
const consoleGroup = console.group;
|
|
|
|
const consoleGroupEnd = console.groupEnd;
|
2019-01-24 13:24:39 -05:00
|
|
|
const consoleClear = console.clear;
|
2018-10-01 12:41:37 -04:00
|
|
|
log("Hello world");
|
|
|
|
dir("Hello world");
|
|
|
|
debug("Hello world");
|
|
|
|
info("Hello world");
|
|
|
|
warn("Hello world");
|
|
|
|
error("Hello world");
|
|
|
|
consoleAssert(true);
|
2018-12-17 11:54:33 -05:00
|
|
|
consoleCount("Hello world");
|
|
|
|
consoleCountReset("Hello world");
|
2019-01-28 16:41:29 -05:00
|
|
|
consoleTable({ test: "Hello world" });
|
2018-12-17 11:54:33 -05:00
|
|
|
consoleTime("Hello world");
|
|
|
|
consoleTimeLog("Hello world");
|
|
|
|
consoleTimeEnd("Hello world");
|
2019-01-06 16:34:52 -05:00
|
|
|
consoleGroup("Hello world");
|
|
|
|
consoleGroupEnd();
|
2019-01-24 13:24:39 -05:00
|
|
|
console.clear();
|
2018-10-01 12:41:37 -04:00
|
|
|
});
|