UNPKG

@serenity-js/core

Version:

The core Serenity/JS framework, providing the Screenplay Pattern interfaces, as well as the test reporting and integration infrastructure

116 lines 3.99 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.stringified = stringified; const util_1 = require("util"); const Question_1 = require("../screenplay/Question"); const ValueInspector_1 = require("./reflection/ValueInspector"); const indentationPrefix = ' '; /** * Provides a human-readable description of the [`Answerable<T>`](https://serenity-js.org/api/core/#Answerable). * Similar to [Node util~inspect](https://nodejs.org/api/util.html#utilinspectobject-options). * * @param value * @param config * - inline - Return a single-line string instead of the default potentially multi-line description * - markQuestions - Surround the description of async values, such as Promises and Questions with <<value>> */ function stringified(value, config) { const { indentationLevel, inline, markQuestions } = { indentationLevel: 0, inline: false, markQuestions: false, ...config }; if (!isDefined(value)) { return (0, util_1.inspect)(value); } if (Array.isArray(value)) { return stringifiedArray(value, { indentationLevel, inline, markQuestions }); } if (ValueInspector_1.ValueInspector.isPromise(value)) { return markAs('Promise', markQuestions); } if (Question_1.Question.isAQuestion(value)) { return markAs(value.toString(), markQuestions); } if (ValueInspector_1.ValueInspector.isDate(value)) { return value.toISOString(); } if (ValueInspector_1.ValueInspector.hasItsOwnToString(value)) { return value.toString(); } if (ValueInspector_1.ValueInspector.isInspectable(value)) { return value.inspect(); } if (ValueInspector_1.ValueInspector.isFunction(value)) { return hasName(value) ? value.name : markAs(`Function`, true); } if (!ValueInspector_1.ValueInspector.hasCustomInspectionFunction(value) && ValueInspector_1.ValueInspector.isPlainObject(value) && isSerialisableAsJSON(value)) { return stringifiedToJson(value, { indentationLevel, inline, markQuestions }); } return (0, util_1.inspect)(value, { breakLength: Number.POSITIVE_INFINITY, compact: inline ? 3 : false, sorted: false }); } function indented(line, config) { const indentation = config.inline ? '' : indentationPrefix.repeat(config.indentationLevel || 0); return indentation + line; } function stringifiedToJson(value, config) { const jsonLineIndentation = config.inline ? 0 : indentationPrefix.length; const [first, ...rest] = JSON.stringify(value, undefined, jsonLineIndentation).split('\n'); return [ first, ...rest.map(line => indented(line, config)) ].join('\n'); } function stringifiedArray(value, config) { const lineSeparator = config.inline ? ' ' : '\n'; const inspectedItem = (item, index) => { const nestedItemConfig = { ...config, indentationLevel: config.indentationLevel + 1 }; return [ indented('', nestedItemConfig), stringified(item, nestedItemConfig), index < value.length - 1 ? ',' : '' ].join(''); }; return [ `[`, ...value.map(inspectedItem), indented(']', config), ].join(lineSeparator); } function markAs(value, markValue) { const [left, right] = markValue && !value.startsWith('<<') ? ['<<', '>>'] : ['', '']; return [left, value, right].join(''); } /** * Checks if the value is defined * * @param v */ function isDefined(v) { return !!v; } /** * Checks if the value is has a property called 'name' with a non-empty value. * * @param v */ function hasName(v) { return typeof v.name === 'string' && v.name !== ''; } /** * Checks if the value is a JSON object that can be stringified * * @param v */ function isSerialisableAsJSON(v) { try { JSON.stringify(v); return true; } catch { return false; } } //# sourceMappingURL=stringified.js.map