UNPKG

4.27 kBJavaScriptView Raw
1'use strict';
2
3var identity = require('./nodes/identity.js');
4var publicApi = require('./public-api.js');
5var visit = require('./visit.js');
6
7const scalarChar = {
8 BLOCK_FOLDED: '>',
9 BLOCK_LITERAL: '|',
10 PLAIN: ':',
11 QUOTE_DOUBLE: '"',
12 QUOTE_SINGLE: "'"
13};
14function anchorExists(doc, anchor) {
15 let found = false;
16 visit.visit(doc, {
17 Value(_key, node) {
18 if (node.anchor === anchor) {
19 found = true;
20 return visit.visit.BREAK;
21 }
22 }
23 });
24 return found;
25}
26// test harness for yaml-test-suite event tests
27function testEvents(src) {
28 const docs = publicApi.parseAllDocuments(src);
29 const errDoc = docs.find(doc => doc.errors.length > 0);
30 const error = errDoc ? errDoc.errors[0].message : null;
31 const events = ['+STR'];
32 try {
33 for (let i = 0; i < docs.length; ++i) {
34 const doc = docs[i];
35 let root = doc.contents;
36 if (Array.isArray(root))
37 root = root[0];
38 const [rootStart] = doc.range || [0];
39 const error = doc.errors[0];
40 if (error && (!error.pos || error.pos[0] < rootStart))
41 throw new Error();
42 let docStart = '+DOC';
43 if (doc.directives.docStart)
44 docStart += ' ---';
45 else if (doc.contents &&
46 doc.contents.range[2] === doc.contents.range[0] &&
47 !doc.contents.anchor &&
48 !doc.contents.tag)
49 continue;
50 events.push(docStart);
51 addEvents(events, doc, error?.pos[0] ?? -1, root);
52 let docEnd = '-DOC';
53 if (doc.directives.docEnd)
54 docEnd += ' ...';
55 events.push(docEnd);
56 }
57 }
58 catch (e) {
59 return { events, error: error ?? e };
60 }
61 events.push('-STR');
62 return { events, error };
63}
64function addEvents(events, doc, errPos, node) {
65 if (!node) {
66 events.push('=VAL :');
67 return;
68 }
69 if (errPos !== -1 && identity.isNode(node) && node.range[0] >= errPos)
70 throw new Error();
71 let props = '';
72 let anchor = identity.isScalar(node) || identity.isCollection(node) ? node.anchor : undefined;
73 if (anchor) {
74 if (/\d$/.test(anchor)) {
75 const alt = anchor.replace(/\d$/, '');
76 if (anchorExists(doc, alt))
77 anchor = alt;
78 }
79 props = ` &${anchor}`;
80 }
81 if (identity.isNode(node) && node.tag)
82 props += ` <${node.tag}>`;
83 if (identity.isMap(node)) {
84 const ev = node.flow ? '+MAP {}' : '+MAP';
85 events.push(`${ev}${props}`);
86 node.items.forEach(({ key, value }) => {
87 addEvents(events, doc, errPos, key);
88 addEvents(events, doc, errPos, value);
89 });
90 events.push('-MAP');
91 }
92 else if (identity.isSeq(node)) {
93 const ev = node.flow ? '+SEQ []' : '+SEQ';
94 events.push(`${ev}${props}`);
95 node.items.forEach(item => {
96 addEvents(events, doc, errPos, item);
97 });
98 events.push('-SEQ');
99 }
100 else if (identity.isPair(node)) {
101 events.push(`+MAP${props}`);
102 addEvents(events, doc, errPos, node.key);
103 addEvents(events, doc, errPos, node.value);
104 events.push('-MAP');
105 }
106 else if (identity.isAlias(node)) {
107 let alias = node.source;
108 if (alias && /\d$/.test(alias)) {
109 const alt = alias.replace(/\d$/, '');
110 if (anchorExists(doc, alt))
111 alias = alt;
112 }
113 events.push(`=ALI${props} *${alias}`);
114 }
115 else {
116 const scalar = scalarChar[String(node.type)];
117 if (!scalar)
118 throw new Error(`Unexpected node type ${node.type}`);
119 const value = node.source
120 .replace(/\\/g, '\\\\')
121 .replace(/\0/g, '\\0')
122 .replace(/\x07/g, '\\a')
123 .replace(/\x08/g, '\\b')
124 .replace(/\t/g, '\\t')
125 .replace(/\n/g, '\\n')
126 .replace(/\v/g, '\\v')
127 .replace(/\f/g, '\\f')
128 .replace(/\r/g, '\\r')
129 .replace(/\x1b/g, '\\e');
130 events.push(`=VAL${props} ${scalar}${value}`);
131 }
132}
133
134exports.testEvents = testEvents;