Skip to content

Commit 8baee44

Browse files
committed
test: Use source files for yaml-test-suite tests
1 parent 280a861 commit 8baee44

2 files changed

Lines changed: 108 additions & 95 deletions

File tree

tests/yaml-test-suite

Submodule yaml-test-suite updated 3758 files

tests/yaml-test-suite.ts

Lines changed: 107 additions & 94 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,36 @@
11
import { existsSync, readdirSync, readFileSync } from 'fs'
2-
import { join, resolve } from 'path'
2+
import { resolve } from 'path'
33

4-
import { CST, Document, Lexer, parseAllDocuments, Parser } from 'yaml'
4+
import { CST, Document, Lexer, parse, parseAllDocuments, Parser } from 'yaml'
55
import { testEvents } from '../src/test-events' // no public export
66

7+
type TestCase = {
8+
yaml: string
9+
fail?: boolean
10+
tree?: string
11+
json?: string
12+
emit?: string
13+
dump?: string
14+
}
15+
16+
type TestFile = [TestCase & { name: string }, ...TestCase[]]
17+
718
const skip: Record<string, boolean | string[]> = {
8-
'9MMA': ['errors'], // allow stream with directive & no docs
9-
SF5V: ['errors'], // allow duplicate %YAML directives
19+
'2JQS/0': ['test.event', 'errors'], //
20+
'9MMA/0': ['errors'], // allow stream with directive & no docs
21+
'SF5V/0': ['errors'], // allow duplicate %YAML directives
1022

1123
// FIXME recent upstream additions
12-
'DK95/00': true,
13-
'DK95/04': true,
14-
'DK95/05': true,
15-
'Y79Y/004': ['errors'],
16-
'Y79Y/005': ['errors'],
17-
'Y79Y/006': ['errors'],
18-
'Y79Y/007': ['errors'],
19-
'Y79Y/008': ['errors'],
20-
'Y79Y/009': ['errors']
24+
'DK95/0': true,
25+
'DK95/4': true,
26+
'DK95/5': true,
27+
'Y79Y/4': ['errors'],
28+
'Y79Y/5': ['errors'],
29+
'Y79Y/6': ['errors'],
30+
'Y79Y/7': ['errors'],
31+
'Y79Y/8': ['errors'],
32+
'Y79Y/9': ['errors'],
33+
'ZYU8/2': ['errors']
2134
}
2235

2336
function testJsonMatch(docs: Document[], json: string) {
@@ -33,99 +46,99 @@ function testJsonMatch(docs: Document[], json: string) {
3346
expect(received).toEqual(expected)
3447
}
3548

36-
const testRoot = resolve(__dirname, 'yaml-test-suite')
37-
const testDirs = readdirSync(testRoot).filter(dir => /^[A-Z0-9]{4}$/.test(dir))
38-
for (let i = testDirs.length - 1; i >= 0; --i) {
39-
const dir = testDirs[i]
40-
const contents = readdirSync(resolve(testRoot, dir))
41-
if (contents.every(cd => /^[0-9]+$/.test(cd))) {
42-
const subs = contents.map(cd => join(dir, cd))
43-
testDirs.splice(i, 1, ...subs)
44-
}
45-
}
49+
const unescape = (text: string) =>
50+
text
51+
.replace(//g, ' ')
52+
.replace(/*»/g, '\t')
53+
.replace(//g, '\r')
54+
.replace(//g, 'x{FEFF}')
55+
.replace(//g, '')
56+
.replace(/\n/g, '')
4657

47-
for (const dir of testDirs) {
48-
const load = (filename: string) => {
49-
const path = resolve(testRoot, dir, filename)
50-
try {
51-
return readFileSync(path, 'utf8')
52-
} catch (_) {
53-
return ''
54-
}
55-
}
56-
const test_ = (name: string, cb: () => void) => {
57-
const sd = skip[dir.replace('\\', '/')] || null
58-
if (sd === true || sd?.includes(name)) test.skip(name, cb)
59-
else test(name, cb)
58+
const testRoot = resolve(__dirname, 'yaml-test-suite', 'src')
59+
60+
for (const fn of readdirSync(testRoot)) {
61+
const [id, ext] = fn.split('.', 2)
62+
if (ext !== 'yaml') {
63+
console.warn(`Not a test file, skipping: ${fn}`)
64+
continue
6065
}
66+
const path = resolve(testRoot, fn)
67+
const file = readFileSync(path, 'utf8')
68+
const testData = parse(file) as TestFile
69+
if (!Array.isArray(testData)) throw new Error(`Unsupported test file: ${fn}`)
6170

62-
const name = load('===').trim()
63-
describe(`${dir}: ${name}`, () => {
64-
const yaml = load('in.yaml')
65-
test('lexer completes', () => {
66-
let n = 0
67-
for (const lex of new Lexer().lex(yaml.replace(/(?<!\r)\n/g, '\r\n'))) {
68-
expect(typeof lex).toBe('string')
69-
if (++n === 9000) throw new Error('Lexer should produce fewer tokens')
70-
}
71-
})
71+
const name = `${id}: ${testData[0].name}`
72+
for (let i = 0; i < testData.length; ++i) {
73+
const sd = skip[`${id}/${i}`] || null
74+
const test_ = (name: string, cb: () => void) => {
75+
if (sd === true || sd?.includes(name)) test.skip(name, cb)
76+
else test(name, cb)
77+
}
7278

73-
test('cst stringify', () => {
74-
let res = ''
75-
for (const tok of new Parser().parse(yaml)) res += CST.stringify(tok)
76-
expect(res).toBe(yaml)
77-
})
79+
describe(testData.length === 1 ? name : `${name} / ${i}`, () => {
80+
const yaml = unescape(testData[i].yaml)
81+
const { fail, tree, json, emit } = testData[i]
7882

79-
const error = existsSync(resolve(testRoot, dir, 'error'))
80-
const events = error ? '' : load('test.event') // Too much variance in event stream length for error cases
81-
if (events) {
82-
test_('test.event', () => {
83-
const res = testEvents(yaml)
84-
const exp = events.replace(/\r\n/g, '\n')
85-
expect(res.events.join('\n') + '\n').toBe(exp)
86-
expect(res.error).toBeNull()
83+
test('lexer completes', () => {
84+
let n = 0
85+
for (const lex of new Lexer().lex(yaml.replace(/(?<!\r)\n/g, '\r\n'))) {
86+
expect(typeof lex).toBe('string')
87+
if (++n === 9000) throw new Error('Lexer should produce fewer tokens')
88+
}
8789
})
88-
}
8990

90-
describe('document parsing', () => {
91-
let docs: Document.Parsed[]
92-
beforeAll(() => {
93-
docs = parseAllDocuments(yaml, { resolveKnownTags: false })
91+
test('cst stringify', () => {
92+
let res = ''
93+
for (const tok of new Parser().parse(yaml)) res += CST.stringify(tok)
94+
expect(res).toBe(yaml)
9495
})
9596

96-
test_('errors', () => {
97-
let errors: Error[] = []
98-
for (const doc of docs) errors = errors.concat(doc.errors)
99-
if (error) {
100-
expect(errors).not.toHaveLength(0)
101-
} else {
102-
expect(errors).toHaveLength(0)
103-
}
104-
})
97+
// Too much variance in event stream length for error cases
98+
if (!fail && tree) {
99+
test_('test.event', () => {
100+
const res = testEvents(yaml)
101+
const exp = unescape(tree).replace(/^\s+/gm, '')
102+
expect(res.events.join('\n') + '\n').toBe(exp)
103+
expect(res.error).toBeNull()
104+
})
105+
}
105106

106-
if (!error) {
107-
const json = load('in.json')
108-
if (json) {
109-
test_('in.json', () => testJsonMatch(docs, json))
107+
describe('document parsing', () => {
108+
let docs: Document.Parsed[]
109+
beforeAll(() => {
110+
docs = parseAllDocuments(yaml, { resolveKnownTags: false })
111+
})
110112

111-
test_('stringfy+re-parse', () => {
112-
const src2 = docs.map(String).join('')
113-
const docs2 = parseAllDocuments(src2, { resolveKnownTags: false })
114-
testJsonMatch(docs2, json)
115-
})
116-
}
113+
test_('errors', () => {
114+
let errors: Error[] = []
115+
for (const doc of docs) errors = errors.concat(doc.errors)
116+
if (fail) expect(errors).not.toHaveLength(0)
117+
else expect(errors).toHaveLength(0)
118+
})
117119

118-
const outYaml = load('out.yaml')
119-
if (outYaml) {
120-
test_('out.yaml', () => {
121-
const resDocs = parseAllDocuments(yaml)
122-
const resJson = resDocs.map(doc => doc.toJS({ mapAsMap: true }))
123-
const expDocs = parseAllDocuments(outYaml)
124-
const expJson = expDocs.map(doc => doc.toJS({ mapAsMap: true }))
125-
expect(resJson).toEqual(expJson)
126-
})
120+
if (!fail) {
121+
if (json) {
122+
test_('in.json', () => testJsonMatch(docs, json))
123+
124+
test_('stringfy+re-parse', () => {
125+
const src2 = docs.map(String).join('')
126+
const docs2 = parseAllDocuments(src2, { resolveKnownTags: false })
127+
testJsonMatch(docs2, json)
128+
})
129+
}
130+
131+
if (emit) {
132+
test_('out.yaml', () => {
133+
const resDocs = parseAllDocuments(yaml)
134+
const resJson = resDocs.map(doc => doc.toJS({ mapAsMap: true }))
135+
const expDocs = parseAllDocuments(unescape(emit))
136+
const expJson = expDocs.map(doc => doc.toJS({ mapAsMap: true }))
137+
expect(resJson).toEqual(expJson)
138+
})
139+
}
127140
}
128-
}
141+
})
129142
})
130-
})
143+
}
131144
}

0 commit comments

Comments
 (0)