Skip to content

Commit

Permalink
Better function and class instance print
Browse files Browse the repository at this point in the history
  • Loading branch information
kevinkassimo committed Jun 7, 2018
1 parent 70457c2 commit 4ff0521
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 8 deletions.
52 changes: 44 additions & 8 deletions console.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,17 @@
// tslint:disable-next-line:no-any
type ConsoleContext = Set<any>;

// tslint:disable-next-line:no-any
function getClassInstanceName(instance: any): string {
if (typeof instance !== "object") {
return "";
}
if (instance && instance.__proto__ && instance.__proto__.constructor) {
return instance.__proto__.constructor.name; // could be "Object" or "Array"
}
return "";
}

// tslint:disable-next-line:no-any
function stringify(ctx: ConsoleContext, value: any): string {
switch (typeof value) {
Expand All @@ -9,8 +20,12 @@ function stringify(ctx: ConsoleContext, value: any): string {
case "number":
case "boolean":
case "undefined":
case "symbol":
return String(value);
case "function":
if (value.name && value.name !== "anonymous") { // from MDN spec
return `[Function: ${value.name}]`;
}
return "[Function]";
case "object":
if (value === null) {
Expand All @@ -22,30 +37,51 @@ function stringify(ctx: ConsoleContext, value: any): string {
}

ctx.add(value);
const valStrings = [];
let entries: string[] = [];

if (Array.isArray(value)) {
for (const el of value) {
valStrings.push(stringify(ctx, el));
entries.push(stringify(ctx, el));
}

ctx.delete(value);

if (valStrings.length === 0) {
if (entries.length === 0) {
return "[]";
}
return `[ ${valStrings.join(", ")} ]`;
return `[ ${entries.join(", ")} ]`;
} else {
let baseString = "";

const className = getClassInstanceName(value);
let shouldShowClassName = false;
if (className && className !== "Object" && className !== "anonymous") {
shouldShowClassName = true;
}

for (const key of Object.keys(value)) {
valStrings.push(`${key}: ${stringify(ctx, value[key])}`);
const keyVal = value[key];
// do not show methods of class instance
if (!shouldShowClassName || typeof keyVal !== "function") {
entries.push(`${key}: ${stringify(ctx, value[key])}`);
}
}

entries = entries.filter(e => !!e); // remove empty entries

ctx.delete(value);

if (valStrings.length === 0) {
return "{}";
if (entries.length === 0) {
baseString = "{}";
} else {
baseString = `{ ${entries.join(", ")} }`;
}
return `{ ${valStrings.join(", ")} }`;

if (shouldShowClassName) {
baseString = `${className} ${baseString}`;
}

return baseString;
}
default:
return "[Not Implemented]";
Expand Down
13 changes: 13 additions & 0 deletions tests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,16 @@ test(function tests_console_assert() {
});

test(function tests_console_stringify_circular() {
class Base {
a = 1;
m1() {}
}

class Extended extends Base {
b = 2;
m2() {}
}

// tslint:disable-next-line:no-any
const nestedObj: any = {
num: 1,
Expand All @@ -77,6 +87,8 @@ test(function tests_console_stringify_circular() {
method() {},
un: undefined,
nu: null,
arrowFunc: () => {},
extendedClass: new Extended(),
};

const circularObj = {
Expand All @@ -89,6 +101,7 @@ test(function tests_console_stringify_circular() {
nested: nestedObj,
emptyObj: {},
arr: [1, "s", false, null, nestedObj],
baseClass: new Base(),
};

nestedObj.o = circularObj;
Expand Down

0 comments on commit 4ff0521

Please sign in to comment.