Befor generating

This commit is contained in:
marys
2026-06-01 13:17:37 +02:00
parent 3383f4bf4a
commit 1aa1b5f625
6756 changed files with 649946 additions and 1 deletions
+3
View File
@@ -0,0 +1,3 @@
.nyc_output
coverage
dist
+6
View File
@@ -0,0 +1,6 @@
{
"extends": "joyent-portal",
"rules": {
"jsx-a11y/href-no-hash": 0
}
}
+64
View File
@@ -0,0 +1,64 @@
# @fmvilas/pseudo-yaml-ast
> This project is a fork of [pseudo-yaml-ast](https://github.com/yldio/pseudo-yaml-ast)
Parse a YAML string into an object with location properties.
## Table of Contents
* [Install](#install)
* [Usage](#usage)
* [License](#license)
## Install
```
npm install @fmvilas/pseudo-yaml-ast
```
## Usage
```js
const { yamlAST, loc } = require('pseudo-yaml-ast');
const assert = require('assert');
const ast = yamlAST(`
obj:
arr:
- nums:
- 1
- 2
- 3
strs1:
- '1'
- '2'
- '3'
str: '1'
num: 1
`);
assert.deepEqual(Object.keys(ast), ['obj']);
assert.deepEqual(ast[loc].start.line, 2);
assert.deepEqual(ast[loc].end.line, 14);
assert.deepEqual(Object.keys(ast.obj), ['arr', 'str', 'num']);
assert.deepEqual(ast.obj[loc].start.line, 2);
assert.deepEqual(ast.obj[loc].end.line, 13);
assert.deepEqual(ast.obj.str[loc].start.line, 12);
assert.deepEqual(ast.obj.str[loc].end.line, 12);
assert.deepEqual(ast.obj.num[loc].start.line, 13);
assert.deepEqual(ast.obj.num[loc].end.line, 13);
assert.deepEqual(ast.obj.arr[0][loc].start.line, 4);
assert.deepEqual(ast.obj.arr[0][loc].end.line, 12);
assert.deepEqual(Object.keys(ast.obj.arr[0]), ['nums', 'strs1']);
assert.deepEqual(ast.obj.arr[0].nums[loc].start.line, 4);
assert.deepEqual(ast.obj.arr[0].nums[loc].end.line, 8);
assert.deepEqual(ast.obj.arr[0].strs1[loc].start.line, 8);
assert.deepEqual(ast.obj.arr[0].strs1[loc].end.line, 12);
```
## License
Apache 2.0
@@ -0,0 +1,223 @@
body, html {
margin:0; padding: 0;
height: 100%;
}
body {
font-family: Helvetica Neue, Helvetica, Arial;
font-size: 14px;
color:#333;
}
.small { font-size: 12px; }
*, *:after, *:before {
-webkit-box-sizing:border-box;
-moz-box-sizing:border-box;
box-sizing:border-box;
}
h1 { font-size: 20px; margin: 0;}
h2 { font-size: 14px; }
pre {
font: 12px/1.4 Consolas, "Liberation Mono", Menlo, Courier, monospace;
margin: 0;
padding: 0;
-moz-tab-size: 2;
-o-tab-size: 2;
tab-size: 2;
}
a { color:#0074D9; text-decoration:none; }
a:hover { text-decoration:underline; }
.strong { font-weight: bold; }
.space-top1 { padding: 10px 0 0 0; }
.pad2y { padding: 20px 0; }
.pad1y { padding: 10px 0; }
.pad2x { padding: 0 20px; }
.pad2 { padding: 20px; }
.pad1 { padding: 10px; }
.space-left2 { padding-left:55px; }
.space-right2 { padding-right:20px; }
.center { text-align:center; }
.clearfix { display:block; }
.clearfix:after {
content:'';
display:block;
height:0;
clear:both;
visibility:hidden;
}
.fl { float: left; }
@media only screen and (max-width:640px) {
.col3 { width:100%; max-width:100%; }
.hide-mobile { display:none!important; }
}
.quiet {
color: #7f7f7f;
color: rgba(0,0,0,0.5);
}
.quiet a { opacity: 0.7; }
.fraction {
font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace;
font-size: 10px;
color: #555;
background: #E8E8E8;
padding: 4px 5px;
border-radius: 3px;
vertical-align: middle;
}
div.path a:link, div.path a:visited { color: #333; }
table.coverage {
border-collapse: collapse;
margin: 10px 0 0 0;
padding: 0;
}
table.coverage td {
margin: 0;
padding: 0;
vertical-align: top;
}
table.coverage td.line-count {
text-align: right;
padding: 0 5px 0 20px;
}
table.coverage td.line-coverage {
text-align: right;
padding-right: 10px;
min-width:20px;
}
table.coverage td span.cline-any {
display: inline-block;
padding: 0 5px;
width: 100%;
}
.missing-if-branch {
display: inline-block;
margin-right: 5px;
border-radius: 3px;
position: relative;
padding: 0 4px;
background: #333;
color: yellow;
}
.skip-if-branch {
display: none;
margin-right: 10px;
position: relative;
padding: 0 4px;
background: #ccc;
color: white;
}
.missing-if-branch .typ, .skip-if-branch .typ {
color: inherit !important;
}
.coverage-summary {
border-collapse: collapse;
width: 100%;
}
.coverage-summary tr { border-bottom: 1px solid #bbb; }
.keyline-all { border: 1px solid #ddd; }
.coverage-summary td, .coverage-summary th { padding: 10px; }
.coverage-summary tbody { border: 1px solid #bbb; }
.coverage-summary td { border-right: 1px solid #bbb; }
.coverage-summary td:last-child { border-right: none; }
.coverage-summary th {
text-align: left;
font-weight: normal;
white-space: nowrap;
}
.coverage-summary th.file { border-right: none !important; }
.coverage-summary th.pct { }
.coverage-summary th.pic,
.coverage-summary th.abs,
.coverage-summary td.pct,
.coverage-summary td.abs { text-align: right; }
.coverage-summary td.file { white-space: nowrap; }
.coverage-summary td.pic { min-width: 120px !important; }
.coverage-summary tfoot td { }
.coverage-summary .sorter {
height: 10px;
width: 7px;
display: inline-block;
margin-left: 0.5em;
background: url(sort-arrow-sprite.png) no-repeat scroll 0 0 transparent;
}
.coverage-summary .sorted .sorter {
background-position: 0 -20px;
}
.coverage-summary .sorted-desc .sorter {
background-position: 0 -10px;
}
.status-line { height: 10px; }
/* yellow */
.cbranch-no { background: yellow !important; color: #111; }
/* dark red */
.red.solid, .status-line.low, .low .cover-fill { background:#C21F39 }
.low .chart { border:1px solid #C21F39 }
.highlighted,
.highlighted .cstat-no, .highlighted .fstat-no, .highlighted .cbranch-no{
background: #C21F39 !important;
}
/* medium red */
.cstat-no, .fstat-no, .cbranch-no, .cbranch-no { background:#F6C6CE }
/* light red */
.low, .cline-no { background:#FCE1E5 }
/* light green */
.high, .cline-yes { background:rgb(230,245,208) }
/* medium green */
.cstat-yes { background:rgb(161,215,106) }
/* dark green */
.status-line.high, .high .cover-fill { background:rgb(77,146,33) }
.high .chart { border:1px solid rgb(77,146,33) }
.medium .chart { border:1px solid #666; }
.medium .cover-fill { background: #666; }
.cstat-skip { background: #ddd; color: #111; }
.fstat-skip { background: #ddd; color: #111 !important; }
.cbranch-skip { background: #ddd !important; color: #111; }
span.cline-neutral { background: #eaeaea; }
.medium { background: #eaeaea; }
.coverage-summary td.empty {
opacity: .5;
padding-top: 4px;
padding-bottom: 4px;
line-height: 1;
color: #888;
}
.cover-fill, .cover-empty {
display:inline-block;
height: 12px;
}
.chart {
line-height: 0;
}
.cover-empty {
background: white;
}
.cover-full {
border-right: none !important;
}
pre.prettyprint {
border: none !important;
padding: 0 !important;
margin: 0 !important;
}
.com { color: #999 !important; }
.ignore-none { color: #999; font-weight: normal; }
.wrapper {
min-height: 100%;
height: auto !important;
height: 100%;
margin: 0 auto -48px;
}
.footer, .push {
height: 48px;
}
@@ -0,0 +1,63 @@
var jumpToCode = (function init () {
// Classes of code we would like to highlight
var missingCoverageClasses = [ '.cbranch-no', '.cstat-no', '.fstat-no' ];
// We don't want to select elements that are direct descendants of another match
var notSelector = ':not(' + missingCoverageClasses.join('):not(') + ') > '; // becomes `:not(a):not(b) > `
// Selecter that finds elements on the page to which we can jump
var selector = notSelector + missingCoverageClasses.join(', ' + notSelector); // becomes `:not(a):not(b) > a, :not(a):not(b) > b`
// The NodeList of matching elements
var missingCoverageElements = document.querySelectorAll(selector);
var currentIndex;
function toggleClass(index) {
missingCoverageElements.item(currentIndex).classList.remove('highlighted');
missingCoverageElements.item(index).classList.add('highlighted');
}
function makeCurrent(index) {
toggleClass(index);
currentIndex = index;
missingCoverageElements.item(index)
.scrollIntoView({ behavior: 'smooth', block: 'center', inline: 'center' });
}
function goToPrevious() {
var nextIndex = 0;
if (typeof currentIndex !== 'number' || currentIndex === 0) {
nextIndex = missingCoverageElements.length - 1;
} else if (missingCoverageElements.length > 1) {
nextIndex = currentIndex - 1;
}
makeCurrent(nextIndex);
}
function goToNext() {
var nextIndex = 0;
if (typeof currentIndex === 'number' && currentIndex < (missingCoverageElements.length - 1)) {
nextIndex = currentIndex + 1;
}
makeCurrent(nextIndex);
}
return function jump(event) {
switch (event.which) {
case 78: // n
case 74: // j
goToNext();
break;
case 66: // b
case 75: // k
case 80: // p
goToPrevious();
break;
}
};
}());
window.addEventListener('keydown', jumpToCode);
@@ -0,0 +1,84 @@
<!doctype html>
<html lang="en">
<head>
<title>Code coverage report for All files</title>
<meta charset="utf-8" />
<link rel="stylesheet" href="prettify.css" />
<link rel="stylesheet" href="base.css" />
<meta name="viewport" content="width=device-width, initial-scale=1">
<style type='text/css'>
.coverage-summary .sorter {
background-image: url(sort-arrow-sprite.png);
}
</style>
</head>
<body>
<div class='wrapper'>
<div class='pad1'>
<h1>
All files
</h1>
<div class='clearfix'>
<div class='fl pad1y space-right2'>
<span class="strong">Unknown% </span>
<span class="quiet">Statements</span>
<span class='fraction'>0/0</span>
</div>
<div class='fl pad1y space-right2'>
<span class="strong">Unknown% </span>
<span class="quiet">Branches</span>
<span class='fraction'>0/0</span>
</div>
<div class='fl pad1y space-right2'>
<span class="strong">Unknown% </span>
<span class="quiet">Functions</span>
<span class='fraction'>0/0</span>
</div>
<div class='fl pad1y space-right2'>
<span class="strong">Unknown% </span>
<span class="quiet">Lines</span>
<span class='fraction'>0/0</span>
</div>
</div>
<p class="quiet">
Press <em>n</em> or <em>j</em> to go to the next uncovered block, <em>b</em>, <em>p</em> or <em>k</em> for the previous block.
</p>
</div>
<div class='status-line medium'></div>
<div class="pad1">
<table class="coverage-summary">
<thead>
<tr>
<th data-col="file" data-fmt="html" data-html="true" class="file">File</th>
<th data-col="pic" data-type="number" data-fmt="html" data-html="true" class="pic"></th>
<th data-col="statements" data-type="number" data-fmt="pct" class="pct">Statements</th>
<th data-col="statements_raw" data-type="number" data-fmt="html" class="abs"></th>
<th data-col="branches" data-type="number" data-fmt="pct" class="pct">Branches</th>
<th data-col="branches_raw" data-type="number" data-fmt="html" class="abs"></th>
<th data-col="functions" data-type="number" data-fmt="pct" class="pct">Functions</th>
<th data-col="functions_raw" data-type="number" data-fmt="html" class="abs"></th>
<th data-col="lines" data-type="number" data-fmt="pct" class="pct">Lines</th>
<th data-col="lines_raw" data-type="number" data-fmt="html" class="abs"></th>
</tr>
</thead>
<tbody></tbody>
</table>
</div><div class='push'></div><!-- for sticky footer -->
</div><!-- /wrapper -->
<div class='footer quiet pad2 space-top1 center small'>
Code coverage
generated by <a href="https://istanbul.js.org/" target="_blank">istanbul</a> at Fri Apr 10 2020 18:21:53 GMT+0200 (CEST)
</div>
</div>
<script src="prettify.js"></script>
<script>
window.onload = function () {
if (typeof prettyPrint === 'function') {
prettyPrint();
}
};
</script>
<script src="sorter.js"></script>
<script src="block-navigation.js"></script>
</body>
</html>
@@ -0,0 +1 @@
.pln{color:#000}@media screen{.str{color:#080}.kwd{color:#008}.com{color:#800}.typ{color:#606}.lit{color:#066}.pun,.opn,.clo{color:#660}.tag{color:#008}.atn{color:#606}.atv{color:#080}.dec,.var{color:#606}.fun{color:red}}@media print,projection{.str{color:#060}.kwd{color:#006;font-weight:bold}.com{color:#600;font-style:italic}.typ{color:#404;font-weight:bold}.lit{color:#044}.pun,.opn,.clo{color:#440}.tag{color:#006;font-weight:bold}.atn{color:#404}.atv{color:#060}}pre.prettyprint{padding:2px;border:1px solid #888}ol.linenums{margin-top:0;margin-bottom:0}li.L0,li.L1,li.L2,li.L3,li.L5,li.L6,li.L7,li.L8{list-style-type:none}li.L1,li.L3,li.L5,li.L7,li.L9{background:#eee}
File diff suppressed because one or more lines are too long
Binary file not shown.

After

Width:  |  Height:  |  Size: 209 B

@@ -0,0 +1,158 @@
var addSorting = (function () {
"use strict";
var cols,
currentSort = {
index: 0,
desc: false
};
// returns the summary table element
function getTable() { return document.querySelector('.coverage-summary'); }
// returns the thead element of the summary table
function getTableHeader() { return getTable().querySelector('thead tr'); }
// returns the tbody element of the summary table
function getTableBody() { return getTable().querySelector('tbody'); }
// returns the th element for nth column
function getNthColumn(n) { return getTableHeader().querySelectorAll('th')[n]; }
// loads all columns
function loadColumns() {
var colNodes = getTableHeader().querySelectorAll('th'),
colNode,
cols = [],
col,
i;
for (i = 0; i < colNodes.length; i += 1) {
colNode = colNodes[i];
col = {
key: colNode.getAttribute('data-col'),
sortable: !colNode.getAttribute('data-nosort'),
type: colNode.getAttribute('data-type') || 'string'
};
cols.push(col);
if (col.sortable) {
col.defaultDescSort = col.type === 'number';
colNode.innerHTML = colNode.innerHTML + '<span class="sorter"></span>';
}
}
return cols;
}
// attaches a data attribute to every tr element with an object
// of data values keyed by column name
function loadRowData(tableRow) {
var tableCols = tableRow.querySelectorAll('td'),
colNode,
col,
data = {},
i,
val;
for (i = 0; i < tableCols.length; i += 1) {
colNode = tableCols[i];
col = cols[i];
val = colNode.getAttribute('data-value');
if (col.type === 'number') {
val = Number(val);
}
data[col.key] = val;
}
return data;
}
// loads all row data
function loadData() {
var rows = getTableBody().querySelectorAll('tr'),
i;
for (i = 0; i < rows.length; i += 1) {
rows[i].data = loadRowData(rows[i]);
}
}
// sorts the table using the data for the ith column
function sortByIndex(index, desc) {
var key = cols[index].key,
sorter = function (a, b) {
a = a.data[key];
b = b.data[key];
return a < b ? -1 : a > b ? 1 : 0;
},
finalSorter = sorter,
tableBody = document.querySelector('.coverage-summary tbody'),
rowNodes = tableBody.querySelectorAll('tr'),
rows = [],
i;
if (desc) {
finalSorter = function (a, b) {
return -1 * sorter(a, b);
};
}
for (i = 0; i < rowNodes.length; i += 1) {
rows.push(rowNodes[i]);
tableBody.removeChild(rowNodes[i]);
}
rows.sort(finalSorter);
for (i = 0; i < rows.length; i += 1) {
tableBody.appendChild(rows[i]);
}
}
// removes sort indicators for current column being sorted
function removeSortIndicators() {
var col = getNthColumn(currentSort.index),
cls = col.className;
cls = cls.replace(/ sorted$/, '').replace(/ sorted-desc$/, '');
col.className = cls;
}
// adds sort indicators for current column being sorted
function addSortIndicators() {
getNthColumn(currentSort.index).className += currentSort.desc ? ' sorted-desc' : ' sorted';
}
// adds event listeners for all sorter widgets
function enableUI() {
var i,
el,
ithSorter = function ithSorter(i) {
var col = cols[i];
return function () {
var desc = col.defaultDescSort;
if (currentSort.index === i) {
desc = !currentSort.desc;
}
sortByIndex(i, desc);
removeSortIndicators();
currentSort.index = i;
currentSort.desc = desc;
addSortIndicators();
};
};
for (i =0 ; i < cols.length; i += 1) {
if (cols[i].sortable) {
// add the click event handler on the th so users
// dont have to click on those tiny arrows
el = getNthColumn(i).querySelector('.sorter').parentElement;
if (el.addEventListener) {
el.addEventListener('click', ithSorter(i));
} else {
el.attachEvent('onclick', ithSorter(i));
}
}
}
}
// adds sorting functionality to the UI
return function () {
if (!getTable()) {
return;
}
cols = loadColumns();
loadData(cols);
addSortIndicators();
enableUI();
};
})();
window.addEventListener('load', addSorting);
+42
View File
@@ -0,0 +1,42 @@
{
"name": "@fmvilas/pseudo-yaml-ast",
"description": "Fork of pseudo-yaml-ast. Parse a YAML string into an object with location properties",
"version": "0.3.1",
"publishConfig": {
"access": "public"
},
"license": "Apache-2.0",
"keywords": [
"parse",
"yaml",
"yml",
"json",
"ast",
"abstract",
"syntax",
"tree",
"loc",
"location"
],
"main": "src/index.js",
"scripts": {
"lint": "eslint . --fix --ext .js --ext .md",
"ava": "cross-env NODE_ENV=test nyc --reporter=lcov --reporter=text ava",
"test": "npm run lint && npm run ava"
},
"dependencies": {
"yaml-ast-parser": "0.0.43"
},
"devDependencies": {
"ava": "^0.25.0",
"lodash.get": "^4.4.2",
"nyc": "^11.2.1"
},
"nyc": {
"sourceMap": false,
"instrument": false
},
"ava": {
"tap": true
}
}
+133
View File
@@ -0,0 +1,133 @@
const { load, Kind } = require('yaml-ast-parser');
const loc = Symbol('pseudo-yaml-ast-loc');
const hasOwnProp = (obj, key) => (obj && typeof obj === 'object' && Object.prototype.hasOwnProperty.call(obj, key));
const isUndefined = v => v === undefined;
const isNull = v => v === null;
const isPrimitive = v =>
Number.isNaN(v) || isNull(v) || isUndefined(v) || typeof v === 'symbol';
const isPrimitiveNode = node =>
isPrimitive(node.value) || !hasOwnProp(node, 'value');
const isBetween = (start, pos, end) => pos <= end && pos >= start;
const getLoc = (input, { start = 0, end = 0 }) => {
const lines = input.split(/\n/);
const loc = {
start: {},
end: {}
};
let sum = 0;
for (const i of lines.keys()) {
const line = lines[i];
const ls = sum;
const le = sum + line.length;
if (isUndefined(loc.start.line) && isBetween(ls, start, le)) {
loc.start.line = i + 1;
loc.start.column = start - ls;
loc.start.offset = start;
}
if (isUndefined(loc.end.line) && isBetween(ls, end, le)) {
loc.end.line = i + 1;
loc.end.column = end - ls;
loc.end.offset = end;
}
sum = le + 1; // +1 because the break is also a char
}
return loc;
};
const visitors = {
MAP: (node = {}, input = '', ctx = {}) =>
Object.assign(walk(node.mappings, input), {
[loc]: getLoc(input, {
start: node.startPosition,
end: node.endPosition
})
}),
MAPPING: (node = {}, input = '', ctx = {}) => {
const value = walk([node.value], input);
if (!isPrimitive(value)) {
value[loc] = getLoc(input, {
start: node.startPosition,
end: node.endPosition
});
}
return Object.assign(ctx, {
[node.key.value]: value
});
},
SCALAR: (node = {}, input = '') => {
if (isPrimitiveNode(node)) {
return node.value;
}
const _loc = getLoc(input, {
start: node.startPosition,
end: node.endPosition
});
const wrappable = Constructor => () => {
const v = new Constructor(node.value);
v[loc] = _loc;
return v;
};
const object = () => {
node.value[loc] = _loc;
return node.value;
};
const types = {
boolean: wrappable(Boolean),
number: wrappable(Number),
string: wrappable(String),
function: object,
object
};
return types[typeof node.value]();
},
SEQ: (node = {}, input = '') => {
const items = walk(node.items, input, []);
items[loc] = getLoc(input, {
start: node.startPosition,
end: node.endPosition
});
return items;
}
};
const walk = (nodes = [], input, ctx = {}) => {
const onNode = (node, ctx, fallback) => {
let visitor;
if (node) visitor = visitors[Kind[node.kind]];
return visitor ? visitor(node, input, ctx) : fallback;
};
const walkObj = () =>
nodes.reduce((sum, node) => {
return onNode(node, sum, sum);
}, ctx);
const walkArr = () =>
nodes.map(node => onNode(node, ctx, null), ctx).filter(Boolean);
return Array.isArray(ctx) ? walkArr() : walkObj();
};
module.exports.loc = loc;
module.exports.yamlAST = input => walk([load(input)], input);
+146
View File
@@ -0,0 +1,146 @@
const { yamlAST, loc } = require('../src/index');
const get = require('lodash.get');
const test = require('ava');
const testCases = [{
name: 'tree with leading whitespace',
input: `
obj:
arr:
- nums:
- 1
- 2
- 3
strs1:
- '1'
- '2'
- '3'
str: '1'
num: 1
`,
nodesToCheck: [{
path: [],
expectedKeys: ['obj'],
expectedLoc: {
start: {line: 2, column: 4},
end: {line: 14, column: 2}
},
}, {
path: ['obj'],
expectedKeys: ['arr', 'str', 'num'],
expectedLoc: {
start: {line: 2, column: 4},
end: {line: 13, column: 12}
},
}, {
path: ['obj', 'str'],
expectedLoc: {
start: {line: 12, column: 6},
end: {line: 12, column: 14}
},
}, {
path: ['obj', 'num'],
expectedLoc: {
start: {line: 13, column: 6},
end: {line: 13, column: 12}
},
}, {
path: ['obj', 'arr', 0],
expectedKeys: ['nums', 'strs1'],
expectedLoc: {
start: {line: 4, column: 8},
end: {line: 12, column: 6}
},
}, {
path: ['obj', 'arr', 0, 'nums'],
expectedLoc: {
start: {line: 4, column: 8},
end: {line: 8, column: 8}
},
}, {
path: ['obj', 'arr', 0, 'strs1'],
expectedLoc: {
start: {line: 8, column: 8},
end: {line: 12, column: 6}
},
}]
}, {
name: 'tree with no leading whitespace',
input: `obj:
arr:
- nums:
- 1
- 2
- 3
strs1:
- '1'
- '2'
- '3'
str: '1'
num: 1
`,
nodesToCheck: [{
path: [],
expectedKeys: ['obj'],
expectedLoc: {
start: {line: 1, column: 0},
end: {line: 13, column: 0}
},
}, {
path: ['obj'],
expectedKeys: ['arr', 'str', 'num'],
expectedLoc: {
start: {line: 1, column: 0},
end: {line: 12, column: 8}
},
}, {
path: ['obj', 'str'],
expectedLoc: {
start: {line: 11, column: 2},
end: {line: 11, column: 10}
},
}, {
path: ['obj', 'num'],
expectedLoc: {
start: {line: 12, column: 2},
end: {line: 12, column: 8}
},
}, {
path: ['obj', 'arr', 0],
expectedKeys: ['nums', 'strs1'],
expectedLoc: {
start: {line: 3, column: 4},
end: {line: 11, column: 2}
},
}, {
path: ['obj', 'arr', 0, 'nums'],
expectedLoc: {
start: {line: 3, column: 4},
end: {line: 7, column: 4}
},
}, {
path: ['obj', 'arr', 0, 'strs1'],
expectedLoc: {
start: {line: 7, column: 4},
end: {line: 11, column: 2}
},
}]
}];
testCases.forEach(testCase => {
test(`works for ${testCase.name}`, t => {
const ast = yamlAST(testCase.input);
testCase.nodesToCheck.forEach(nodeDefinition => {
const node = nodeDefinition.path.length ? get(ast, nodeDefinition.path) : ast;
const pathAsStr = nodeDefinition.path.join(' → ') || 'root';
if (nodeDefinition.expectedKeys) {
t.deepEqual(Object.keys(node), nodeDefinition.expectedKeys, `keys for ${pathAsStr}`);
}
if (nodeDefinition.expectedLoc) {
t.deepEqual(node[loc], nodeDefinition.expectedLoc, `loc for ${pathAsStr}`);
}
});
});
});