[test] Pretty print object properties on assert failure
Because I don't get much out of "Object() != Object()" Change-Id: I5a765b9cb0a272d30edcd834ec7b60d2fd03190b Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3497352 Reviewed-by: Camillo Bruni <cbruni@chromium.org> Auto-Submit: Leszek Swirski <leszeks@chromium.org> Commit-Queue: Leszek Swirski <leszeks@chromium.org> Cr-Commit-Position: refs/heads/main@{#79370}
This commit is contained in:
parent
d05a38f9ad
commit
5704f86c58
@ -3,7 +3,7 @@ test/mjsunit/mjsunit.js:{NUMBER}: Failure: expected <not same as 1> found <1>
|
||||
Stack: MjsUnitAssertionError
|
||||
at assertNotSame *mjsunit.js {NUMBER}:{NUMBER}
|
||||
at *%(basename)s 7:1
|
||||
throw new MjsUnitAssertionError(message);
|
||||
throw new MjsUnitAssertionError(
|
||||
^
|
||||
MjsUnitAssertionError
|
||||
at assertNotSame *mjsunit.js {NUMBER}:{NUMBER}
|
||||
|
@ -3,7 +3,7 @@ test/mjsunit/mjsunit.js:{NUMBER}: Failure: expected <true> found <false>
|
||||
Stack: MjsUnitAssertionError
|
||||
at assertTrue *mjsunit.js {NUMBER}:{NUMBER}
|
||||
at *%(basename)s 7:1
|
||||
throw new MjsUnitAssertionError(message);
|
||||
throw new MjsUnitAssertionError(
|
||||
^
|
||||
MjsUnitAssertionError
|
||||
at assertTrue *mjsunit.js {NUMBER}:{NUMBER}
|
||||
|
@ -25,18 +25,34 @@
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
function MjsUnitAssertionError(message) {
|
||||
this.message = message;
|
||||
// Temporarily install a custom stack trace formatter and restore the
|
||||
// previous value.
|
||||
let prevPrepareStackTrace = Error.prepareStackTrace;
|
||||
try {
|
||||
Error.prepareStackTrace = MjsUnitAssertionError.prepareStackTrace;
|
||||
// This allows fetching the stack trace using TryCatch::StackTrace.
|
||||
this.stack = new Error("MjsUnitAssertionError").stack;
|
||||
} finally {
|
||||
Error.prepareStackTrace = prevPrepareStackTrace;
|
||||
var MjsUnitAssertionError = class MjsUnitAssertionError {
|
||||
#cached_message = undefined;
|
||||
#message_func = undefined;
|
||||
|
||||
constructor(message_func) {
|
||||
this.#message_func = message_func;
|
||||
// Temporarily install a custom stack trace formatter and restore the
|
||||
// previous value.
|
||||
let prevPrepareStackTrace = Error.prepareStackTrace;
|
||||
try {
|
||||
Error.prepareStackTrace = MjsUnitAssertionError.prepareStackTrace;
|
||||
// This allows fetching the stack trace using TryCatch::StackTrace.
|
||||
this.stack = new Error("MjsUnitAssertionError").stack;
|
||||
} finally {
|
||||
Error.prepareStackTrace = prevPrepareStackTrace;
|
||||
}
|
||||
}
|
||||
|
||||
get message() {
|
||||
if (this.#cached_message === undefined) {
|
||||
this.#cached_message = this.#message_func();
|
||||
}
|
||||
return this.#cached_message
|
||||
}
|
||||
|
||||
toString() {
|
||||
return this.message + "\n\nStack: " + this.stack;
|
||||
};
|
||||
}
|
||||
|
||||
/*
|
||||
@ -45,11 +61,6 @@ function MjsUnitAssertionError(message) {
|
||||
* the f-word and ignore all other lines.
|
||||
*/
|
||||
|
||||
MjsUnitAssertionError.prototype.toString = function () {
|
||||
return this.message + "\n\nStack: " + this.stack;
|
||||
};
|
||||
|
||||
|
||||
// Expected and found values the same objects, or the same primitive
|
||||
// values.
|
||||
// For known primitive values, please use assertEquals.
|
||||
@ -258,69 +269,82 @@ var prettyPrinted;
|
||||
|
||||
|
||||
prettyPrinted = function prettyPrinted(value) {
|
||||
switch (typeof value) {
|
||||
case "string":
|
||||
return JSONStringify(value);
|
||||
case "bigint":
|
||||
return String(value) + "n";
|
||||
case "number":
|
||||
if (value === 0 && (1 / value) < 0) return "-0";
|
||||
// FALLTHROUGH.
|
||||
case "boolean":
|
||||
case "undefined":
|
||||
case "function":
|
||||
case "symbol":
|
||||
return String(value);
|
||||
case "object":
|
||||
if (value === null) return "null";
|
||||
var objectClass = classOf(value);
|
||||
switch (objectClass) {
|
||||
case "Number":
|
||||
case "BigInt":
|
||||
case "String":
|
||||
case "Boolean":
|
||||
case "Date":
|
||||
return objectClass + "(" + prettyPrinted(ValueOf(value)) + ")";
|
||||
case "RegExp":
|
||||
return RegExpPrototypeToString.call(value);
|
||||
case "Array":
|
||||
var mapped = ArrayPrototypeMap.call(
|
||||
value, prettyPrintedArrayElement);
|
||||
var joined = ArrayPrototypeJoin.call(mapped, ",");
|
||||
return "[" + joined + "]";
|
||||
case "Uint8Array":
|
||||
case "Int8Array":
|
||||
case "Int16Array":
|
||||
case "Uint16Array":
|
||||
case "Uint32Array":
|
||||
case "Int32Array":
|
||||
case "Float32Array":
|
||||
case "Float64Array":
|
||||
var joined = ArrayPrototypeJoin.call(value, ",");
|
||||
return objectClass + "([" + joined + "])";
|
||||
case "Object":
|
||||
break;
|
||||
let visited = new Set();
|
||||
function prettyPrint(value) {
|
||||
try {
|
||||
switch (typeof value) {
|
||||
case "string":
|
||||
return JSONStringify(value);
|
||||
case "bigint":
|
||||
return String(value) + "n";
|
||||
case "number":
|
||||
if (value === 0 && (1 / value) < 0) return "-0";
|
||||
// FALLTHROUGH.
|
||||
case "boolean":
|
||||
case "undefined":
|
||||
case "function":
|
||||
case "symbol":
|
||||
return String(value);
|
||||
case "object":
|
||||
if (value === null) return "null";
|
||||
// Guard against re-visiting.
|
||||
if (visited.has(value)) return "<...>";
|
||||
visited.add(value);
|
||||
var objectClass = classOf(value);
|
||||
switch (objectClass) {
|
||||
case "Number":
|
||||
case "BigInt":
|
||||
case "String":
|
||||
case "Boolean":
|
||||
case "Date":
|
||||
return objectClass + "(" + prettyPrint(ValueOf(value)) + ")";
|
||||
case "RegExp":
|
||||
return RegExpPrototypeToString.call(value);
|
||||
case "Array":
|
||||
var mapped = ArrayPrototypeMap.call(
|
||||
value, (v,i,array)=>{
|
||||
if (v === undefined && !(i in array)) return "";
|
||||
return prettyPrint(v, visited);
|
||||
});
|
||||
var joined = ArrayPrototypeJoin.call(mapped, ",");
|
||||
return "[" + joined + "]";
|
||||
case "Uint8Array":
|
||||
case "Int8Array":
|
||||
case "Int16Array":
|
||||
case "Uint16Array":
|
||||
case "Uint32Array":
|
||||
case "Int32Array":
|
||||
case "Float32Array":
|
||||
case "Float64Array":
|
||||
var joined = ArrayPrototypeJoin.call(value, ",");
|
||||
return objectClass + "([" + joined + "])";
|
||||
case "Object":
|
||||
break;
|
||||
default:
|
||||
return objectClass + "(" + String(value) + ")";
|
||||
}
|
||||
// classOf() returned "Object".
|
||||
var name = value.constructor?.name ?? "Object";
|
||||
var pretty_properties = [];
|
||||
for (let [k,v] of Object.entries(value)) {
|
||||
ArrayPrototypePush.call(
|
||||
pretty_properties, `${k}:${prettyPrint(v, visited)}`);
|
||||
}
|
||||
var joined = ArrayPrototypeJoin.call(pretty_properties, ",");
|
||||
return `${name}({${joined}})`;
|
||||
default:
|
||||
return objectClass + "(" + String(value) + ")";
|
||||
return "-- unknown value --";
|
||||
}
|
||||
// classOf() returned "Object".
|
||||
var name = value.constructor.name;
|
||||
if (name) return name + "()";
|
||||
return "Object()";
|
||||
default:
|
||||
return "-- unknown value --";
|
||||
} catch (e) {
|
||||
// Guard against general exceptions (especially stack overflows).
|
||||
return "<error>"
|
||||
}
|
||||
}
|
||||
return prettyPrint(value);
|
||||
}
|
||||
|
||||
|
||||
function prettyPrintedArrayElement(value, index, array) {
|
||||
if (value === undefined && !(index in array)) return "";
|
||||
return prettyPrinted(value);
|
||||
}
|
||||
|
||||
|
||||
failWithMessage = function failWithMessage(message) {
|
||||
throw new MjsUnitAssertionError(message);
|
||||
throw new MjsUnitAssertionError(()=>message);
|
||||
}
|
||||
|
||||
formatFailureText = function(expectedText, found, name_opt) {
|
||||
@ -340,7 +364,8 @@ var prettyPrinted;
|
||||
}
|
||||
|
||||
function fail(expectedText, found, name_opt) {
|
||||
return failWithMessage(formatFailureText(expectedText, found, name_opt));
|
||||
throw new MjsUnitAssertionError(
|
||||
()=>formatFailureText(expectedText, found, name_opt));
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user