mirror of
https://github.com/denoland/deno.git
synced 2024-11-25 15:29:32 -05:00
fix(inspect): eliminate panic inspecting event classes (#10979)
This commit is contained in:
parent
8f699d6133
commit
1909da47fe
2 changed files with 79 additions and 15 deletions
|
@ -1,5 +1,10 @@
|
|||
// Copyright 2018-2021 the Deno authors. All rights reserved. MIT license.
|
||||
import { assert, assertEquals, unitTest } from "./test_util.ts";
|
||||
import {
|
||||
assert,
|
||||
assertEquals,
|
||||
assertStringIncludes,
|
||||
unitTest,
|
||||
} from "./test_util.ts";
|
||||
|
||||
unitTest(function eventInitializedWithType(): void {
|
||||
const type = "click";
|
||||
|
@ -127,3 +132,30 @@ unitTest(function eventInspectOutput(): void {
|
|||
assertEquals(Deno.inspect(event), outputProvider(event));
|
||||
}
|
||||
});
|
||||
|
||||
unitTest(function inspectEvent(): void {
|
||||
// has a customInspect implementation that previously would throw on a getter
|
||||
assertEquals(
|
||||
Deno.inspect(Event.prototype),
|
||||
`Event {
|
||||
bubbles: [Getter/Setter],
|
||||
cancelable: [Getter/Setter],
|
||||
composed: [Getter/Setter],
|
||||
currentTarget: [Getter/Setter],
|
||||
defaultPrevented: [Getter/Setter],
|
||||
eventPhase: [Getter/Setter],
|
||||
srcElement: [Getter/Setter],
|
||||
target: [Getter/Setter],
|
||||
returnValue: [Getter/Setter],
|
||||
timeStamp: [Getter/Setter],
|
||||
type: [Getter/Setter]
|
||||
}`,
|
||||
);
|
||||
|
||||
// ensure this still works
|
||||
assertStringIncludes(
|
||||
Deno.inspect(new Event("test")),
|
||||
// check a substring because one property is a timestamp
|
||||
`Event {\n bubbles: false,\n cancelable: false,`,
|
||||
);
|
||||
});
|
||||
|
|
|
@ -144,7 +144,7 @@
|
|||
}
|
||||
|
||||
[Symbol.for("Deno.customInspect")](inspect) {
|
||||
return buildCustomInspectOutput(this, EVENT_PROPS, inspect);
|
||||
return inspect(buildFilteredPropertyInspectObject(this, EVENT_PROPS));
|
||||
}
|
||||
|
||||
get type() {
|
||||
|
@ -395,9 +395,41 @@
|
|||
}
|
||||
}
|
||||
|
||||
function buildCustomInspectOutput(object, keys, inspect) {
|
||||
const inspectObject = Object.fromEntries(keys.map((k) => [k, object[k]]));
|
||||
return `${object.constructor.name} ${inspect(inspectObject)}`;
|
||||
function buildFilteredPropertyInspectObject(object, keys) {
|
||||
// forward the subset of properties from `object` without evaluating
|
||||
// as evaluation could lead to an error, which is better handled
|
||||
// in the inspect code
|
||||
return new Proxy({}, {
|
||||
get(_target, key) {
|
||||
if (key === Symbol.toStringTag) {
|
||||
return object.constructor?.name;
|
||||
} else if (keys.includes(key)) {
|
||||
return Reflect.get(object, key);
|
||||
} else {
|
||||
return undefined;
|
||||
}
|
||||
},
|
||||
getOwnPropertyDescriptor(_target, key) {
|
||||
if (!keys.includes(key)) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return Reflect.getOwnPropertyDescriptor(object, key) ??
|
||||
(object.prototype &&
|
||||
Reflect.getOwnPropertyDescriptor(object.prototype, key)) ??
|
||||
{
|
||||
configurable: true,
|
||||
enumerable: true,
|
||||
value: object[key],
|
||||
};
|
||||
},
|
||||
has(_target, key) {
|
||||
return keys.includes(key);
|
||||
},
|
||||
ownKeys() {
|
||||
return keys;
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
function defineEnumerableProps(
|
||||
|
@ -1053,14 +1085,14 @@
|
|||
}
|
||||
|
||||
[Symbol.for("Deno.customInspect")](inspect) {
|
||||
return buildCustomInspectOutput(this, [
|
||||
return inspect(buildFilteredPropertyInspectObject(this, [
|
||||
...EVENT_PROPS,
|
||||
"message",
|
||||
"filename",
|
||||
"lineno",
|
||||
"colno",
|
||||
"error",
|
||||
], inspect);
|
||||
]));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1107,12 +1139,12 @@
|
|||
}
|
||||
|
||||
[Symbol.for("Deno.customInspect")](inspect) {
|
||||
return buildCustomInspectOutput(this, [
|
||||
return inspect(buildFilteredPropertyInspectObject(this, [
|
||||
...EVENT_PROPS,
|
||||
"wasClean",
|
||||
"code",
|
||||
"reason",
|
||||
], inspect);
|
||||
]));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1134,12 +1166,12 @@
|
|||
}
|
||||
|
||||
[Symbol.for("Deno.customInspect")](inspect) {
|
||||
return buildCustomInspectOutput(this, [
|
||||
return inspect(buildFilteredPropertyInspectObject(this, [
|
||||
...EVENT_PROPS,
|
||||
"data",
|
||||
"origin",
|
||||
"lastEventId",
|
||||
], inspect);
|
||||
]));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1164,10 +1196,10 @@
|
|||
}
|
||||
|
||||
[Symbol.for("Deno.customInspect")](inspect) {
|
||||
return buildCustomInspectOutput(this, [
|
||||
return inspect(buildFilteredPropertyInspectObject(this, [
|
||||
...EVENT_PROPS,
|
||||
"detail",
|
||||
], inspect);
|
||||
]));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1187,12 +1219,12 @@
|
|||
}
|
||||
|
||||
[Symbol.for("Deno.customInspect")](inspect) {
|
||||
return buildCustomInspectOutput(this, [
|
||||
return inspect(buildFilteredPropertyInspectObject(this, [
|
||||
...EVENT_PROPS,
|
||||
"lengthComputable",
|
||||
"loaded",
|
||||
"total",
|
||||
], inspect);
|
||||
]));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue