mirror of
https://github.com/denoland/deno.git
synced 2024-12-22 15:24:46 -05:00
Implement console.groupCollapsed (#1452)
This implementation of groupCollapsed is intentionally different from the spec defined by whatwg. See the conversation in #1355 and #1363.
This commit is contained in:
parent
1b7938e3aa
commit
cae71ed841
9 changed files with 143 additions and 10 deletions
|
@ -7,6 +7,8 @@ type ConsoleOptions = Partial<{
|
|||
showHidden: boolean;
|
||||
depth: number;
|
||||
colors: boolean;
|
||||
indentLevel: number;
|
||||
collapsedAt: number | null;
|
||||
}>;
|
||||
|
||||
// Default depth of logging nested objects
|
||||
|
@ -322,6 +324,18 @@ function stringifyWithQuotes(
|
|||
}
|
||||
}
|
||||
|
||||
// Returns true when the console is collapsed.
|
||||
function isCollapsed(
|
||||
collapsedAt: number | null | undefined,
|
||||
indentLevel: number | null | undefined
|
||||
) {
|
||||
if (collapsedAt == null || indentLevel == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return collapsedAt <= indentLevel;
|
||||
}
|
||||
|
||||
/** TODO Do not expose this from "deno" namespace. */
|
||||
export function stringifyArgs(
|
||||
// tslint:disable-next-line:no-any
|
||||
|
@ -329,6 +343,7 @@ export function stringifyArgs(
|
|||
options: ConsoleOptions = {}
|
||||
): string {
|
||||
const out: string[] = [];
|
||||
const { collapsedAt, indentLevel } = options;
|
||||
for (const a of args) {
|
||||
if (typeof a === "string") {
|
||||
out.push(a);
|
||||
|
@ -346,22 +361,45 @@ export function stringifyArgs(
|
|||
);
|
||||
}
|
||||
}
|
||||
return out.join(" ");
|
||||
let outstr = out.join(" ");
|
||||
if (
|
||||
!isCollapsed(collapsedAt, indentLevel) &&
|
||||
indentLevel != null &&
|
||||
indentLevel > 0
|
||||
) {
|
||||
const groupIndent = " ".repeat(indentLevel);
|
||||
if (outstr.indexOf("\n") !== -1) {
|
||||
outstr = outstr.replace(/\n/g, `\n${groupIndent}`);
|
||||
}
|
||||
outstr = groupIndent + outstr;
|
||||
}
|
||||
return outstr;
|
||||
}
|
||||
|
||||
type PrintFunc = (x: string, isErr?: boolean) => void;
|
||||
type PrintFunc = (x: string, isErr?: boolean, printsNewline?: boolean) => void;
|
||||
|
||||
const countMap = new Map<string, number>();
|
||||
const timerMap = new Map<string, number>();
|
||||
|
||||
/** TODO Do not expose this from "deno". */
|
||||
export class Console {
|
||||
constructor(private printFunc: PrintFunc) {}
|
||||
indentLevel: number;
|
||||
collapsedAt: number | null;
|
||||
constructor(private printFunc: PrintFunc) {
|
||||
this.indentLevel = 0;
|
||||
this.collapsedAt = null;
|
||||
}
|
||||
|
||||
/** Writes the arguments to stdout */
|
||||
// tslint:disable-next-line:no-any
|
||||
log = (...args: any[]): void => {
|
||||
this.printFunc(stringifyArgs(args));
|
||||
this.printFunc(
|
||||
stringifyArgs(args, {
|
||||
indentLevel: this.indentLevel,
|
||||
collapsedAt: this.collapsedAt
|
||||
}),
|
||||
false,
|
||||
!isCollapsed(this.collapsedAt, this.indentLevel)
|
||||
);
|
||||
};
|
||||
|
||||
/** Writes the arguments to stdout */
|
||||
|
@ -372,13 +410,20 @@ export class Console {
|
|||
/** Writes the properties of the supplied `obj` to stdout */
|
||||
// tslint:disable-next-line:no-any
|
||||
dir = (obj: any, options: ConsoleOptions = {}) => {
|
||||
this.printFunc(stringifyArgs([obj], options));
|
||||
this.log(stringifyArgs([obj], options));
|
||||
};
|
||||
|
||||
/** Writes the arguments to stdout */
|
||||
// tslint:disable-next-line:no-any
|
||||
warn = (...args: any[]): void => {
|
||||
this.printFunc(stringifyArgs(args), true);
|
||||
this.printFunc(
|
||||
stringifyArgs(args, {
|
||||
indentLevel: this.indentLevel,
|
||||
collapsedAt: this.collapsedAt
|
||||
}),
|
||||
true,
|
||||
!isCollapsed(this.collapsedAt, this.indentLevel)
|
||||
);
|
||||
};
|
||||
|
||||
/** Writes the arguments to stdout */
|
||||
|
@ -473,6 +518,30 @@ export class Console {
|
|||
|
||||
this.info(`${label}: ${duration}ms`);
|
||||
};
|
||||
|
||||
group = (...label: Array<unknown>): void => {
|
||||
if (label.length > 0) {
|
||||
this.log(...label);
|
||||
}
|
||||
this.indentLevel += 2;
|
||||
};
|
||||
|
||||
groupCollapsed = (...label: Array<unknown>): void => {
|
||||
if (this.collapsedAt == null) {
|
||||
this.collapsedAt = this.indentLevel;
|
||||
}
|
||||
this.group(...label);
|
||||
};
|
||||
|
||||
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.
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -116,7 +116,7 @@ test(function consoleTestStringifyCircular() {
|
|||
assertEqual(
|
||||
stringify(console),
|
||||
// tslint:disable-next-line:max-line-length
|
||||
"Console { printFunc: [Function], log: [Function], debug: [Function], info: [Function], dir: [Function], warn: [Function], error: [Function], assert: [Function], count: [Function], countReset: [Function], time: [Function], timeLog: [Function], timeEnd: [Function] }"
|
||||
"Console { printFunc: [Function], log: [Function], debug: [Function], info: [Function], dir: [Function], warn: [Function], error: [Function], assert: [Function], count: [Function], countReset: [Function], time: [Function], timeLog: [Function], timeEnd: [Function], group: [Function], groupCollapsed: [Function], groupEnd: [Function], indentLevel: 0, collapsedAt: null }"
|
||||
);
|
||||
// test inspect is working the same
|
||||
assertEqual(inspect(nestedObj), nestedObjExpected);
|
||||
|
@ -189,6 +189,8 @@ test(function consoleDetachedLog() {
|
|||
const consoleTime = console.time;
|
||||
const consoleTimeLog = console.timeLog;
|
||||
const consoleTimeEnd = console.timeEnd;
|
||||
const consoleGroup = console.group;
|
||||
const consoleGroupEnd = console.groupEnd;
|
||||
log("Hello world");
|
||||
dir("Hello world");
|
||||
debug("Hello world");
|
||||
|
@ -201,4 +203,6 @@ test(function consoleDetachedLog() {
|
|||
consoleTime("Hello world");
|
||||
consoleTimeLog("Hello world");
|
||||
consoleTimeEnd("Hello world");
|
||||
consoleGroup("Hello world");
|
||||
consoleGroupEnd();
|
||||
});
|
||||
|
|
|
@ -191,7 +191,7 @@ void PromiseRejectCallback(v8::PromiseRejectMessage promise_reject_message) {
|
|||
|
||||
void Print(const v8::FunctionCallbackInfo<v8::Value>& args) {
|
||||
CHECK_GE(args.Length(), 1);
|
||||
CHECK_LE(args.Length(), 2);
|
||||
CHECK_LE(args.Length(), 3);
|
||||
auto* isolate = args.GetIsolate();
|
||||
DenoIsolate* d = FromIsolate(isolate);
|
||||
auto context = d->context_.Get(d->isolate_);
|
||||
|
@ -199,9 +199,13 @@ void Print(const v8::FunctionCallbackInfo<v8::Value>& args) {
|
|||
v8::String::Utf8Value str(isolate, args[0]);
|
||||
bool is_err =
|
||||
args.Length() >= 2 ? args[1]->BooleanValue(context).ToChecked() : false;
|
||||
bool prints_newline =
|
||||
args.Length() >= 3 ? args[2]->BooleanValue(context).ToChecked() : true;
|
||||
FILE* file = is_err ? stderr : stdout;
|
||||
fwrite(*str, sizeof(**str), str.length(), file);
|
||||
fprintf(file, "\n");
|
||||
if (prints_newline) {
|
||||
fprintf(file, "\n");
|
||||
}
|
||||
fflush(file);
|
||||
}
|
||||
|
||||
|
|
2
tests/console_group.test
Normal file
2
tests/console_group.test
Normal file
|
@ -0,0 +1,2 @@
|
|||
args: tests/console_group.ts --reload
|
||||
output: tests/console_group.ts.out
|
15
tests/console_group.ts
Normal file
15
tests/console_group.ts
Normal file
|
@ -0,0 +1,15 @@
|
|||
console.group("1");
|
||||
console.log("2");
|
||||
console.group("3");
|
||||
console.log("4");
|
||||
console.groupEnd();
|
||||
console.groupEnd();
|
||||
|
||||
console.groupCollapsed("5");
|
||||
console.log("6");
|
||||
console.group("7");
|
||||
console.log("8");
|
||||
console.groupEnd();
|
||||
console.groupEnd();
|
||||
console.log("9");
|
||||
console.log("10");
|
7
tests/console_group.ts.out
Normal file
7
tests/console_group.ts.out
Normal file
|
@ -0,0 +1,7 @@
|
|||
1
|
||||
2
|
||||
3
|
||||
4
|
||||
5678
|
||||
9
|
||||
10
|
3
tests/console_group_warn.test
Normal file
3
tests/console_group_warn.test
Normal file
|
@ -0,0 +1,3 @@
|
|||
args: tests/console_group_warn.ts --reload
|
||||
check_stderr: true
|
||||
output: tests/console_group_warn.ts.out
|
20
tests/console_group_warn.ts
Normal file
20
tests/console_group_warn.ts
Normal file
|
@ -0,0 +1,20 @@
|
|||
console.warn("1");
|
||||
console.group();
|
||||
console.warn("2");
|
||||
console.group();
|
||||
console.warn("3");
|
||||
console.groupEnd();
|
||||
console.warn("4");
|
||||
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");
|
9
tests/console_group_warn.ts.out
Normal file
9
tests/console_group_warn.ts.out
Normal file
|
@ -0,0 +1,9 @@
|
|||
Compiling [WILDCARD].ts
|
||||
1
|
||||
2
|
||||
3
|
||||
4
|
||||
5
|
||||
678
|
||||
9
|
||||
10
|
Loading…
Reference in a new issue