193fb6ee3Sopenharmony_ciimport { html, type TreeAdapterTypeMap, type TreeAdapter } from 'parse5';
293fb6ee3Sopenharmony_ci
393fb6ee3Sopenharmony_cifunction createFragmentContext<T extends TreeAdapterTypeMap>(
493fb6ee3Sopenharmony_ci    tagName: string | undefined,
593fb6ee3Sopenharmony_ci    treeAdapter: TreeAdapter<T>
693fb6ee3Sopenharmony_ci): T['element'] | null {
793fb6ee3Sopenharmony_ci    if (!tagName) {
893fb6ee3Sopenharmony_ci        return null;
993fb6ee3Sopenharmony_ci    }
1093fb6ee3Sopenharmony_ci
1193fb6ee3Sopenharmony_ci    let namespace = html.NS.HTML;
1293fb6ee3Sopenharmony_ci    const parts = tagName.split(' ');
1393fb6ee3Sopenharmony_ci
1493fb6ee3Sopenharmony_ci    if (parts.length > 1) {
1593fb6ee3Sopenharmony_ci        tagName = parts[1];
1693fb6ee3Sopenharmony_ci
1793fb6ee3Sopenharmony_ci        if (parts[0] === 'svg') {
1893fb6ee3Sopenharmony_ci            namespace = html.NS.SVG;
1993fb6ee3Sopenharmony_ci        } else if (parts[0] === 'math') {
2093fb6ee3Sopenharmony_ci            namespace = html.NS.MATHML;
2193fb6ee3Sopenharmony_ci        }
2293fb6ee3Sopenharmony_ci    }
2393fb6ee3Sopenharmony_ci
2493fb6ee3Sopenharmony_ci    return treeAdapter.createElement(tagName, namespace, []);
2593fb6ee3Sopenharmony_ci}
2693fb6ee3Sopenharmony_ci
2793fb6ee3Sopenharmony_ciexport interface DatFile<T extends TreeAdapterTypeMap> {
2893fb6ee3Sopenharmony_ci    input: string;
2993fb6ee3Sopenharmony_ci    expected: string;
3093fb6ee3Sopenharmony_ci    expectedErrors: string[];
3193fb6ee3Sopenharmony_ci    disableEntitiesDecoding: boolean;
3293fb6ee3Sopenharmony_ci    lineNum: number;
3393fb6ee3Sopenharmony_ci    scriptingEnabled: boolean;
3493fb6ee3Sopenharmony_ci    fragmentContext: T['element'] | null;
3593fb6ee3Sopenharmony_ci}
3693fb6ee3Sopenharmony_ci
3793fb6ee3Sopenharmony_ciexport function parseDatFile<T extends TreeAdapterTypeMap>(testSet: string, treeAdapter: TreeAdapter<T>): DatFile<T>[] {
3893fb6ee3Sopenharmony_ci    const testDescrs: Record<string, number | string[]>[] = [];
3993fb6ee3Sopenharmony_ci    let curDirective = '';
4093fb6ee3Sopenharmony_ci    let curDescr: Record<string, number | string[]> = {};
4193fb6ee3Sopenharmony_ci
4293fb6ee3Sopenharmony_ci    for (const [idx, line] of testSet.split(/\r?\n/).entries()) {
4393fb6ee3Sopenharmony_ci        if (line === '#data') {
4493fb6ee3Sopenharmony_ci            curDescr = { '#line': idx + 1 };
4593fb6ee3Sopenharmony_ci            testDescrs.push(curDescr);
4693fb6ee3Sopenharmony_ci        }
4793fb6ee3Sopenharmony_ci
4893fb6ee3Sopenharmony_ci        if (line[0] === '#') {
4993fb6ee3Sopenharmony_ci            curDirective = line;
5093fb6ee3Sopenharmony_ci            curDescr[curDirective] = [];
5193fb6ee3Sopenharmony_ci        } else {
5293fb6ee3Sopenharmony_ci            (curDescr[curDirective] as string[]).push(line);
5393fb6ee3Sopenharmony_ci        }
5493fb6ee3Sopenharmony_ci    }
5593fb6ee3Sopenharmony_ci
5693fb6ee3Sopenharmony_ci    return testDescrs.map((descr) => {
5793fb6ee3Sopenharmony_ci        const fragmentContextTagName = (descr['#document-fragment'] as string[] | undefined)?.[0];
5893fb6ee3Sopenharmony_ci
5993fb6ee3Sopenharmony_ci        return {
6093fb6ee3Sopenharmony_ci            input: (descr['#data'] as string[]).join('\n'),
6193fb6ee3Sopenharmony_ci            expected: (descr['#document'] as string[]).join('\n'),
6293fb6ee3Sopenharmony_ci            expectedErrors: descr['#new-errors'] || [],
6393fb6ee3Sopenharmony_ci            disableEntitiesDecoding: !!descr['#disable-html-entities-decoding'],
6493fb6ee3Sopenharmony_ci            lineNum: descr['#line'],
6593fb6ee3Sopenharmony_ci            scriptingEnabled: !descr['#script-off'],
6693fb6ee3Sopenharmony_ci            fragmentContext: createFragmentContext<T>(fragmentContextTagName, treeAdapter),
6793fb6ee3Sopenharmony_ci        } as DatFile<T>;
6893fb6ee3Sopenharmony_ci    });
6993fb6ee3Sopenharmony_ci}
70