tap
Version:
A Test-Anything-Protocol library for JavaScript
171 lines (139 loc) • 5.45 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = exports.isEmptyPath = void 0;
var _addComment = _interopRequireDefault(require("../addComment"));
var _Node = _interopRequireDefault(require("./Node"));
var _Pair = _interopRequireDefault(require("./Pair"));
var _Scalar = _interopRequireDefault(require("./Scalar"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
// null, undefined, or an empty non-string iterable (e.g. [])
const isEmptyPath = path => path == null || typeof path === 'object' && path[Symbol.iterator]().next().done;
exports.isEmptyPath = isEmptyPath;
class Collection extends _Node.default {
constructor(...args) {
super(...args);
_defineProperty(this, "items", []);
}
addIn(path, value) {
if (isEmptyPath(path)) this.add(value);else {
const [key, ...rest] = path;
const node = this.get(key, true);
if (node instanceof Collection) node.addIn(rest, value);else throw new Error(`Expected YAML collection at ${key}. Remaining path: ${rest}`);
}
}
deleteIn([key, ...rest]) {
if (rest.length === 0) return this.delete(key);
const node = this.get(key, true);
if (node instanceof Collection) return node.deleteIn(rest);else throw new Error(`Expected YAML collection at ${key}. Remaining path: ${rest}`);
}
getIn([key, ...rest], keepScalar) {
const node = this.get(key, true);
if (rest.length === 0) return !keepScalar && node instanceof _Scalar.default ? node.value : node;else return node instanceof Collection ? node.getIn(rest, keepScalar) : undefined;
}
hasAllNullValues() {
return this.items.every(node => {
if (!(node instanceof _Pair.default)) return false;
const n = node.value;
return n == null || n instanceof _Scalar.default && n.value == null && !n.commentBefore && !n.comment && !n.tag;
});
}
hasIn([key, ...rest]) {
if (rest.length === 0) return this.has(key);
const node = this.get(key, true);
return node instanceof Collection ? node.hasIn(rest) : false;
}
setIn([key, ...rest], value) {
if (rest.length === 0) {
this.set(key, value);
} else {
const node = this.get(key, true);
if (node instanceof Collection) node.setIn(rest, value);else throw new Error(`Expected YAML collection at ${key}. Remaining path: ${rest}`);
}
} // overridden in implementations
toJSON() {
return null;
}
toString(ctx, {
blockItem,
flowChars,
isMap,
itemIndent
}, onComment, onChompKeep) {
const {
doc,
indent
} = ctx;
const inFlow = this.type && this.type.substr(0, 4) === 'FLOW' || ctx.inFlow;
if (inFlow) itemIndent += ' ';
const allNullValues = isMap && this.hasAllNullValues();
ctx = Object.assign({}, ctx, {
allNullValues,
indent: itemIndent,
inFlow,
type: null
});
let chompKeep = false;
let hasItemWithNewLine = false;
const nodes = this.items.reduce((nodes, item, i) => {
let comment;
if (item) {
if (!chompKeep && item.spaceBefore) nodes.push({
type: 'comment',
str: ''
});
if (item.commentBefore) item.commentBefore.match(/^.*$/gm).forEach(line => {
nodes.push({
type: 'comment',
str: `#${line}`
});
});
if (item.comment) comment = item.comment;
if (inFlow && (!chompKeep && item.spaceBefore || item.commentBefore || item.comment || item.key && (item.key.commentBefore || item.key.comment) || item.value && (item.value.commentBefore || item.value.comment))) hasItemWithNewLine = true;
}
chompKeep = false;
let str = doc.schema.stringify(item, ctx, () => comment = null, () => chompKeep = true);
if (inFlow && !hasItemWithNewLine && str.includes('\n')) hasItemWithNewLine = true;
if (inFlow && i < this.items.length - 1) str += ',';
str = (0, _addComment.default)(str, itemIndent, comment);
if (chompKeep && (comment || inFlow)) chompKeep = false;
nodes.push({
type: 'item',
str
});
return nodes;
}, []);
let str;
if (nodes.length === 0) {
str = flowChars.start + flowChars.end;
} else if (inFlow) {
const {
start,
end
} = flowChars;
const strings = nodes.map(n => n.str);
if (hasItemWithNewLine || strings.reduce((sum, str) => sum + str.length + 2, 2) > Collection.maxFlowStringSingleLineLength) {
str = start;
for (const s of strings) {
str += s ? `\n ${indent}${s}` : '\n';
}
str += `\n${indent}${end}`;
} else {
str = `${start} ${strings.join(' ')} ${end}`;
}
} else {
const strings = nodes.map(blockItem);
str = strings.shift();
for (const s of strings) str += s ? `\n${indent}${s}` : '\n';
}
if (this.comment) {
str += '\n' + this.comment.replace(/^/gm, `${indent}#`);
if (onComment) onComment();
} else if (chompKeep && onChompKeep) onChompKeep();
return str;
}
}
exports.default = Collection;
_defineProperty(Collection, "maxFlowStringSingleLineLength", 60);