diff options
-rw-r--r-- | cli/dts/lib.deno.ns.d.ts | 14 | ||||
-rw-r--r-- | cli/rt/02_console.js | 91 | ||||
-rw-r--r-- | cli/tests/unit/console_test.ts | 12 | ||||
-rw-r--r-- | std/fmt/printf_test.ts | 23 | ||||
-rw-r--r-- | std/testing/asserts.ts | 4 |
5 files changed, 89 insertions, 55 deletions
diff --git a/cli/dts/lib.deno.ns.d.ts b/cli/dts/lib.deno.ns.d.ts index 141e66a24..f2845f492 100644 --- a/cli/dts/lib.deno.ns.d.ts +++ b/cli/dts/lib.deno.ns.d.ts @@ -1941,19 +1941,21 @@ declare namespace Deno { export function run<T extends RunOptions = RunOptions>(opt: T): Process<T>; export interface InspectOptions { - /** Traversal depth for nested objects. Defaults to 4. */ - depth?: number; - /** Sort Object, Set and Map entries by key. Defaults to false. */ - sorted?: boolean; - /** Add a trailing comma for multiline collections. Defaults to false. */ - trailingComma?: boolean; + /** Stylize output with ANSI colors. Defaults to false. */ + colors?: boolean; /** Try to fit more than one entry of a collection on the same line. * Defaults to true. */ compact?: boolean; + /** Traversal depth for nested objects. Defaults to 4. */ + depth?: number; /** The maximum number of iterable entries to print. Defaults to 100. */ iterableLimit?: number; /** Show a Proxy's target and handler. Defaults to false. */ showProxy?: boolean; + /** Sort Object, Set and Map entries by key. Defaults to false. */ + sorted?: boolean; + /** Add a trailing comma for multiline collections. Defaults to false. */ + trailingComma?: boolean; } /** Converts the input into a string that has the same format as printed by diff --git a/cli/rt/02_console.js b/cli/rt/02_console.js index 43638efed..b5cab7617 100644 --- a/cli/rt/02_console.js +++ b/cli/rt/02_console.js @@ -3,16 +3,7 @@ ((window) => { const core = window.Deno.core; const exposeForTest = window.__bootstrap.internals.exposeForTest; - const { - stripColor, - yellow, - dim, - cyan, - red, - green, - magenta, - bold, - } = window.__bootstrap.colors; + const colors = window.__bootstrap.colors; function isInvalidDate(x) { return isNaN(x.getTime()); @@ -88,7 +79,7 @@ } function getStringWidth(str) { - str = stripColor(str).normalize("NFC"); + str = colors.stripColor(str).normalize("NFC"); let width = 0; for (const ch of str) { @@ -165,6 +156,7 @@ compact: true, iterableLimit: 100, showProxy: false, + colors: false, }; const DEFAULT_INDENT = " "; // Default indent string @@ -198,6 +190,10 @@ return ""; } + function maybeColor(fn, inspectOptions) { + return inspectOptions.colors ? fn : (s) => s; + } + function inspectFunction(value, _ctx) { if (customInspect in value && typeof value[customInspect] === "function") { try { @@ -220,6 +216,7 @@ options, inspectOptions, ) { + const cyan = maybeColor(colors.cyan, inspectOptions); if (level >= inspectOptions.depth) { return cyan(`[${options.typeName}]`); } @@ -274,7 +271,7 @@ } else { iContent = entries.length === 0 ? "" : ` ${entries.join(", ")} `; if ( - stripColor(iContent).length > LINE_BREAKING_LENGTH || + colors.stripColor(iContent).length > LINE_BREAKING_LENGTH || !inspectOptions.compact ) { iContent = `${initIndentation}${ @@ -309,7 +306,7 @@ for (let i = 0; i < entriesLength; i++) { // Taking colors into account: removing the ANSI color // codes from the string before measuring its length - const len = stripColor(entries[i]).length; + const len = colors.stripColor(entries[i]).length; dataLen[i] = len; totalLength += len + separatorSpace; if (maxLength < len) maxLength = len; @@ -414,6 +411,13 @@ : inspectValue(proxyDetails[0], ctx, level, inspectOptions); } + const green = maybeColor(colors.green, inspectOptions); + const yellow = maybeColor(colors.yellow, inspectOptions); + const dim = maybeColor(colors.dim, inspectOptions); + const cyan = maybeColor(colors.cyan, inspectOptions); + const bold = maybeColor(colors.bold, inspectOptions); + const red = maybeColor(colors.red, inspectOptions); + switch (typeof value) { case "string": return green(quoteString(value)); @@ -512,6 +516,7 @@ level, inspectOptions, ) { + const green = maybeColor(colors.green, inspectOptions); switch (typeof value) { case "string": const trunc = value.length > STR_ABBREVIATE_SIZE @@ -529,6 +534,7 @@ level, inspectOptions, ) { + const dim = maybeColor(colors.dim, inspectOptions); const options = { typeName: "Array", displayName: "", @@ -630,32 +636,39 @@ ); } - function inspectWeakSet() { + function inspectWeakSet(inspectOptions) { + const cyan = maybeColor(colors.cyan, inspectOptions); return `WeakSet { ${cyan("[items unknown]")} }`; // as seen in Node, with cyan color } - function inspectWeakMap() { + function inspectWeakMap(inspectOptions) { + const cyan = maybeColor(colors.cyan, inspectOptions); return `WeakMap { ${cyan("[items unknown]")} }`; // as seen in Node, with cyan color } - function inspectDate(value) { + function inspectDate(value, inspectOptions) { // without quotes, ISO format, in magenta like before + const magenta = maybeColor(colors.magenta, inspectOptions); return magenta(isInvalidDate(value) ? "Invalid Date" : value.toISOString()); } - function inspectRegExp(value) { + function inspectRegExp(value, inspectOptions) { + const red = maybeColor(colors.red, inspectOptions); return red(value.toString()); // RegExps are red } - function inspectStringObject(value) { + function inspectStringObject(value, inspectOptions) { + const cyan = maybeColor(colors.cyan, inspectOptions); return cyan(`[String: "${value.toString()}"]`); // wrappers are in cyan } - function inspectBooleanObject(value) { + function inspectBooleanObject(value, inspectOptions) { + const cyan = maybeColor(colors.cyan, inspectOptions); return cyan(`[Boolean: ${value.toString()}]`); // wrappers are in cyan } - function inspectNumberObject(value) { + function inspectNumberObject(value, inspectOptions) { + const cyan = maybeColor(colors.cyan, inspectOptions); return cyan(`[Number: ${value.toString()}]`); // wrappers are in cyan } @@ -671,6 +684,9 @@ level, inspectOptions, ) { + const cyan = maybeColor(colors.cyan, inspectOptions); + const red = maybeColor(colors.red, inspectOptions); + const [state, result] = core.getPromiseDetails(value); if (state === PromiseState.Pending) { @@ -714,6 +730,8 @@ level, inspectOptions, ) { + const cyan = maybeColor(colors.cyan, inspectOptions); + if (level >= inspectOptions.depth) { return cyan("[Object]"); // wrappers are in cyan } @@ -770,7 +788,7 @@ } // Making sure color codes are ignored when calculating the total length const totalLength = entries.length + level + - stripColor(entries.join("")).length; + colors.stripColor(entries.join("")).length; ctx.delete(value); @@ -822,25 +840,25 @@ } else if (Array.isArray(value)) { return inspectArray(value, consoleContext, level, inspectOptions); } else if (value instanceof Number) { - return inspectNumberObject(value); + return inspectNumberObject(value, inspectOptions); } else if (value instanceof Boolean) { - return inspectBooleanObject(value); + return inspectBooleanObject(value, inspectOptions); } else if (value instanceof String) { - return inspectStringObject(value); + return inspectStringObject(value, inspectOptions); } else if (value instanceof Promise) { return inspectPromise(value, consoleContext, level, inspectOptions); } else if (value instanceof RegExp) { - return inspectRegExp(value); + return inspectRegExp(value, inspectOptions); } else if (value instanceof Date) { - return inspectDate(value); + return inspectDate(value, inspectOptions); } else if (value instanceof Set) { return inspectSet(value, consoleContext, level, inspectOptions); } else if (value instanceof Map) { return inspectMap(value, consoleContext, level, inspectOptions); } else if (value instanceof WeakSet) { - return inspectWeakSet(); + return inspectWeakSet(inspectOptions); } else if (value instanceof WeakMap) { - return inspectWeakMap(); + return inspectWeakMap(inspectOptions); } else if (isTypedArray(value)) { return inspectTypedArray( Object.getPrototypeOf(value).constructor.name, @@ -1318,6 +1336,11 @@ const timerMap = new Map(); const isConsoleInstance = Symbol("isConsoleInstance"); + const CONSOLE_INSPECT_OPTIONS = { + ...DEFAULT_INSPECT_OPTIONS, + colors: true, + }; + class Console { #printFunc = null; [isConsoleInstance] = false; @@ -1339,6 +1362,7 @@ log = (...args) => { this.#printFunc( inspectArgs(args, { + ...CONSOLE_INSPECT_OPTIONS, indentLevel: this.indentLevel, }) + "\n", false, @@ -1349,7 +1373,10 @@ info = this.log; dir = (obj, options = {}) => { - this.#printFunc(inspectArgs([obj], options) + "\n", false); + this.#printFunc( + inspectArgs([obj], { ...CONSOLE_INSPECT_OPTIONS, ...options }) + "\n", + false, + ); }; dirxml = this.dir; @@ -1357,6 +1384,7 @@ warn = (...args) => { this.#printFunc( inspectArgs(args, { + ...CONSOLE_INSPECT_OPTIONS, indentLevel: this.indentLevel, }) + "\n", true, @@ -1560,7 +1588,10 @@ }; trace = (...args) => { - const message = inspectArgs(args, { indentLevel: 0 }); + const message = inspectArgs( + args, + { ...CONSOLE_INSPECT_OPTIONS, indentLevel: 0 }, + ); const err = { name: "Trace", message, diff --git a/cli/tests/unit/console_test.ts b/cli/tests/unit/console_test.ts index eb2c51aef..514b29cc2 100644 --- a/cli/tests/unit/console_test.ts +++ b/cli/tests/unit/console_test.ts @@ -8,7 +8,12 @@ // std/fmt/colors auto determines whether to put colors in or not. We need // better infrastructure here so we can properly test the colors. -import { assert, assertEquals, unitTest } from "./test_util.ts"; +import { + assert, + assertEquals, + assertStringContains, + unitTest, +} from "./test_util.ts"; import { stripColor } from "../../../std/fmt/colors.ts"; const customInspect = Deno.customInspect; @@ -1650,3 +1655,8 @@ unitTest(function inspectProxy(): void { "Proxy [ [Function: fn], { get: [Function: get] } ]", ); }); + +unitTest(function inspectColors(): void { + assertEquals(Deno.inspect(1), "1"); + assertStringContains(Deno.inspect(1, { colors: true }), "\x1b["); +}); diff --git a/std/fmt/printf_test.ts b/std/fmt/printf_test.ts index 81e172f81..e4399812b 100644 --- a/std/fmt/printf_test.ts +++ b/std/fmt/printf_test.ts @@ -7,7 +7,6 @@ import { sprintf } from "./printf.ts"; import { assertEquals } from "../testing/asserts.ts"; -import { cyan, yellow } from "./colors.ts"; const S = sprintf; @@ -607,12 +606,12 @@ Deno.test("testWeirdos", function (): void { Deno.test("formatV", function (): void { const a = { a: { a: { a: { a: { a: { a: { a: {} } } } } } } }; assertEquals(S("%v", a), "[object Object]"); - assertEquals(S("%#v", a), `{ a: { a: { a: { a: ${cyan("[Object]")} } } } }`); + assertEquals(S("%#v", a), `{ a: { a: { a: { a: [Object] } } } }`); assertEquals( S("%#.8v", a), "{ a: { a: { a: { a: { a: { a: { a: {} } } } } } } }", ); - assertEquals(S("%#.1v", a), `{ a: ${cyan("[Object]")} }`); + assertEquals(S("%#.1v", a), `{ a: [Object] }`); }); Deno.test("formatJ", function (): void { @@ -625,9 +624,7 @@ Deno.test("flagLessThan", function (): void { const aArray = [a, a, a]; assertEquals( S("%<#.1v", aArray), - `[ { a: ${cyan("[Object]")} }, { a: ${cyan("[Object]")} }, { a: ${ - cyan("[Object]") - } } ]`, + `[ { a: [Object] }, { a: [Object] }, { a: [Object] } ]`, ); const fArray = [1.2345, 0.98765, 123456789.5678]; assertEquals(S("%<.2f", fArray), "[ 1.23, 0.99, 123456789.57 ]"); @@ -649,27 +646,21 @@ Deno.test("testErrors", function (): void { assertEquals(S("%.*f", "a", 1.1), "%!(BAD PREC 'a')"); assertEquals( S("%.[2]*f", 1.23, "p"), - `%!(BAD PREC 'p')%!(EXTRA '${yellow("1.23")}')`, + `%!(BAD PREC 'p')%!(EXTRA '1.23')`, ); assertEquals(S("%.[2]*[1]f Yippie!", 1.23, "p"), "%!(BAD PREC 'p') Yippie!"); assertEquals(S("%[1]*.2f", "a", "p"), "%!(BAD WIDTH 'a')"); - assertEquals( - S("A", "a", "p"), - `A%!(EXTRA '\x1b[32m"a"\x1b[39m' '\x1b[32m"p"\x1b[39m')`, - ); - assertEquals( - S("%[2]s %[2]s", "a", "p"), - `p p%!(EXTRA '\x1b[32m"a"\x1b[39m')`, - ); + assertEquals(S("A", "a", "p"), `A%!(EXTRA '"a"' '"p"')`); + assertEquals(S("%[2]s %[2]s", "a", "p"), `p p%!(EXTRA '"a"')`); // remains to be determined how to handle bad indices ... // (realistically) the entire error handling is still up for grabs. assertEquals(S("%[hallo]s %d %d %d", 1, 2, 3, 4), "%!(BAD INDEX) 2 3 4"); assertEquals( S("%[5]s", 1, 2, 3, 4), - `%!(BAD INDEX)%!(EXTRA '${yellow("2")}' '${yellow("3")}' '${yellow("4")}')`, + `%!(BAD INDEX)%!(EXTRA '2' '3' '4')`, ); assertEquals(S("%[5]f"), "%!(BAD INDEX)"); assertEquals(S("%.[5]f"), "%!(BAD INDEX)"); diff --git a/std/testing/asserts.ts b/std/testing/asserts.ts index 05bb995ab..889a622fd 100644 --- a/std/testing/asserts.ts +++ b/std/testing/asserts.ts @@ -21,13 +21,13 @@ export class AssertionError extends Error { export function _format(v: unknown): string { return globalThis.Deno - ? stripColor(Deno.inspect(v, { + ? Deno.inspect(v, { depth: Infinity, sorted: true, trailingComma: true, compact: false, iterableLimit: Infinity, - })) + }) : `"${String(v).replace(/(?=["\\])/g, "\\")}"`; } |