diff options
author | Kevin (Kun) "Kassimo" Qian <kevinkassimo@gmail.com> | 2019-08-17 09:51:51 -0700 |
---|---|---|
committer | Ryan Dahl <ry@tinyclouds.org> | 2019-08-17 12:51:51 -0400 |
commit | 9acb17742fc2c7ee503e6b2be8f88b97dae65dc6 (patch) | |
tree | 0a25e25a8f7049a1c124fb7825ce43af6eafc582 /js | |
parent | de713e42c8807e3124c9b5d418a69d2ea3460058 (diff) |
Implement console.trace() (#2780)
groupCollapsed alias to group, remove noTrailingNewline, move newline
out of stringifyArgs, fix console.dir, add tests, and fix a repl log quirk.
For repl logging quirks, I believe we should not indent repl logging. If
we really want such indentation, we probably also want to indent "> "
prompts.
Diffstat (limited to 'js')
-rw-r--r-- | js/console.ts | 54 | ||||
-rw-r--r-- | js/console_test.ts | 63 | ||||
-rw-r--r-- | js/repl.ts | 27 |
3 files changed, 81 insertions, 63 deletions
diff --git a/js/console.ts b/js/console.ts index ed6040f1d..002be6e2f 100644 --- a/js/console.ts +++ b/js/console.ts @@ -11,7 +11,6 @@ type ConsoleOptions = Partial<{ depth: number; colors: boolean; indentLevel: number; - collapsedAt: number | null; }>; // Default depth of logging nested objects @@ -469,18 +468,13 @@ export function stringifyArgs( a++; } - const { collapsedAt, indentLevel } = options; - const isCollapsed = - collapsedAt != null && indentLevel != null && collapsedAt <= indentLevel; - if (!isCollapsed) { - if (indentLevel != null && indentLevel > 0) { - const groupIndent = " ".repeat(indentLevel); - if (str.indexOf("\n") !== -1) { - str = str.replace(/\n/g, `\n${groupIndent}`); - } - str = groupIndent + str; + const { indentLevel } = options; + if (indentLevel != null && indentLevel > 0) { + const groupIndent = " ".repeat(indentLevel); + if (str.indexOf("\n") !== -1) { + str = str.replace(/\n/g, `\n${groupIndent}`); } - str += "\n"; + str = groupIndent + str; } return str; @@ -494,13 +488,11 @@ export const isConsoleInstance = Symbol("isConsoleInstance"); export class Console { indentLevel: number; - collapsedAt: number | null; [isConsoleInstance]: boolean = false; /** @internal */ constructor(private printFunc: PrintFunc) { this.indentLevel = 0; - this.collapsedAt = null; this[isConsoleInstance] = true; // ref https://console.spec.whatwg.org/#console-namespace @@ -516,9 +508,8 @@ export class Console { log = (...args: unknown[]): void => { this.printFunc( stringifyArgs(args, { - indentLevel: this.indentLevel, - collapsedAt: this.collapsedAt - }), + indentLevel: this.indentLevel + }) + "\n", false ); }; @@ -530,16 +521,15 @@ export class Console { /** Writes the properties of the supplied `obj` to stdout */ dir = (obj: unknown, options: ConsoleOptions = {}): void => { - this.log(stringifyArgs([obj], options)); + this.printFunc(stringifyArgs([obj], options) + "\n", false); }; /** Writes the arguments to stdout */ warn = (...args: unknown[]): void => { this.printFunc( stringifyArgs(args, { - indentLevel: this.indentLevel, - collapsedAt: this.collapsedAt - }), + indentLevel: this.indentLevel + }) + "\n", true ); }; @@ -732,21 +722,12 @@ export class Console { this.indentLevel += 2; }; - groupCollapsed = (...label: unknown[]): void => { - if (this.collapsedAt == null) { - this.collapsedAt = this.indentLevel; - } - this.group(...label); - }; + groupCollapsed = this.group; groupEnd = (): void => { if (this.indentLevel > 0) { this.indentLevel -= 2; } - if (this.collapsedAt != null && this.collapsedAt >= this.indentLevel) { - this.collapsedAt = null; - this.log(); // When the collapsed state ended, outputs a sinle new line. - } }; clear = (): void => { @@ -755,6 +736,17 @@ export class Console { clearScreenDown(stdout); }; + trace = (...args: unknown[]): void => { + const message = stringifyArgs(args, { indentLevel: 0 }); + const err = { + name: "Trace", + message + }; + // @ts-ignore + Error.captureStackTrace(err, this.trace); + this.error((err as Error).stack); + }; + static [Symbol.hasInstance](instance: Console): boolean { return instance[isConsoleInstance]; } diff --git a/js/console_test.ts b/js/console_test.ts index e7cc360bc..8070ee0f0 100644 --- a/js/console_test.ts +++ b/js/console_test.ts @@ -143,7 +143,7 @@ test(function consoleTestStringifyCircular(): void { assertEquals(stringify(JSON), "{}"); assertEquals( stringify(console), - "{ printFunc, log, debug, info, dir, warn, error, assert, count, countReset, table, time, timeLog, timeEnd, group, groupCollapsed, groupEnd, clear, indentLevel, collapsedAt }" + "{ printFunc, log, debug, info, dir, warn, error, assert, count, countReset, table, time, timeLog, timeEnd, group, groupCollapsed, groupEnd, clear, trace, indentLevel }" ); // test inspect is working the same assertEquals(inspect(nestedObj), nestedObjExpected); @@ -155,16 +155,16 @@ test(function consoleTestStringifyWithDepth(): void { const nestedObj: any = { a: { b: { c: { d: { e: { f: 42 } } } } } }; assertEquals( stringifyArgs([nestedObj], { depth: 3 }), - "{ a: { b: { c: [Object] } } }\n" + "{ a: { b: { c: [Object] } } }" ); assertEquals( stringifyArgs([nestedObj], { depth: 4 }), - "{ a: { b: { c: { d: [Object] } } } }\n" + "{ a: { b: { c: { d: [Object] } } } }" ); - assertEquals(stringifyArgs([nestedObj], { depth: 0 }), "[Object]\n"); + assertEquals(stringifyArgs([nestedObj], { depth: 0 }), "[Object]"); assertEquals( stringifyArgs([nestedObj], { depth: null }), - "{ a: { b: { c: { d: [Object] } } } }\n" + "{ a: { b: { c: { d: [Object] } } } }" ); // test inspect is working the same way assertEquals( @@ -378,15 +378,8 @@ test(function consoleGroup(): void { console.log("4"); console.groupEnd(); console.groupEnd(); - - console.groupCollapsed("5"); + console.log("5"); console.log("6"); - console.group("7"); - console.log("8"); - console.groupEnd(); - console.groupEnd(); - console.log("9"); - console.log("10"); assertEquals( out.toString(), @@ -394,9 +387,8 @@ test(function consoleGroup(): void { 2 3 4 -5678 -9 -10 +5 +6 ` ); } @@ -417,16 +409,8 @@ test(function consoleGroupWarn(): void { console.groupEnd(); console.warn("5"); - console.groupCollapsed(); console.warn("6"); - console.group(); console.warn("7"); - console.groupEnd(); - console.warn("8"); - console.groupEnd(); - - console.warn("9"); - console.warn("10"); assertEquals( both.toString(), `1 @@ -434,9 +418,8 @@ test(function consoleGroupWarn(): void { 3 4 5 -678 -9 -10 +6 +7 ` ); } @@ -652,3 +635,29 @@ test(function consoleLogShouldNotThrowError(): void { } ); }); + +// console.dir test +test(function consoleDir(): void { + 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"); + } + ); +}); + +// console.trace test +test(function consoleTrace(): void { + mockConsole( + (console, _out, err): void => { + console.trace("%s", "custom message"); + assert(err.toString().includes("Trace: custom message")); + } + ); +}); diff --git a/js/repl.ts b/js/repl.ts index be162cb7e..daf4fd154 100644 --- a/js/repl.ts +++ b/js/repl.ts @@ -8,6 +8,23 @@ import { exit } from "./os"; import { window } from "./window"; import { core } from "./core"; import { formatError } from "./format_error"; +import { stringifyArgs } from "./console"; + +/** + * REPL logging. + * In favor of console.log to avoid unwanted indentation + */ +function replLog(...args: unknown[]): void { + core.print(stringifyArgs(args) + "\n"); +} + +/** + * REPL logging for errors. + * In favor of console.error to avoid unwanted indentation + */ +function replError(...args: unknown[]): void { + core.print(stringifyArgs(args) + "\n", true); +} const helpMsg = [ "exit Exit the REPL", @@ -86,7 +103,7 @@ function isRecoverableError(e: Error): boolean { function evaluate(code: string): boolean { const [result, errInfo] = core.evalContext(code); if (!errInfo) { - console.log(result); + replLog(result); } else if (errInfo.isCompileError && isRecoverableError(errInfo.thrown)) { // Recoverable compiler error return false; // don't consume code. @@ -95,9 +112,9 @@ function evaluate(code: string): boolean { const formattedError = formatError( core.errorToJSON(errInfo.thrown as Error) ); - console.error(formattedError); + replError(formattedError); } else { - console.error("Thrown:", errInfo.thrown); + replError("Thrown:", errInfo.thrown); } } return true; @@ -135,7 +152,7 @@ export async function replLoop(): Promise<void> { // e.g. this happens when we have deno.close(3). // We want to display the problem. const formattedError = formatError(core.errorToJSON(err)); - console.error(formattedError); + replError(formattedError); } // Quit REPL anyways. quitRepl(1); @@ -157,7 +174,7 @@ export async function replLoop(): Promise<void> { // e.g. this happens when we have deno.close(3). // We want to display the problem. const formattedError = formatError(core.errorToJSON(err)); - console.error(formattedError); + replError(formattedError); quitRepl(1); } } |