@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
JavaScript
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
;