193fb6ee3Sopenharmony_ciimport { ParserStream } from '../lib/index.js';
293fb6ee3Sopenharmony_ciimport { generateParsingTests } from 'parse5-test-utils/utils/generate-parsing-tests.js';
393fb6ee3Sopenharmony_ciimport { makeChunks, generateTestsForEachTreeAdapter, finished } from 'parse5-test-utils/utils/common.js';
493fb6ee3Sopenharmony_ciimport { runInNewContext } from 'node:vm';
593fb6ee3Sopenharmony_ci
693fb6ee3Sopenharmony_cifunction pause(): Promise<void> {
793fb6ee3Sopenharmony_ci    return new Promise((resolve) => setTimeout(resolve, 5));
893fb6ee3Sopenharmony_ci}
993fb6ee3Sopenharmony_ci
1093fb6ee3Sopenharmony_ciconst suitePath = new URL('../../../test/data/tree-construction-scripting', import.meta.url);
1193fb6ee3Sopenharmony_ci
1293fb6ee3Sopenharmony_cigenerateParsingTests(
1393fb6ee3Sopenharmony_ci    'ParserStream - Scripting',
1493fb6ee3Sopenharmony_ci    'ParserStream - Scripting',
1593fb6ee3Sopenharmony_ci    {
1693fb6ee3Sopenharmony_ci        withoutErrors: true,
1793fb6ee3Sopenharmony_ci        suitePath,
1893fb6ee3Sopenharmony_ci    },
1993fb6ee3Sopenharmony_ci    async (test, opts) => {
2093fb6ee3Sopenharmony_ci        const chunks = makeChunks(test.input);
2193fb6ee3Sopenharmony_ci        const parser = test.fragmentContext
2293fb6ee3Sopenharmony_ci            ? ParserStream.getFragmentStream(test.fragmentContext, opts)
2393fb6ee3Sopenharmony_ci            : new ParserStream(opts);
2493fb6ee3Sopenharmony_ci
2593fb6ee3Sopenharmony_ci        parser.on('script', async (scriptElement, documentWrite, resume) => {
2693fb6ee3Sopenharmony_ci            const scriptTextNode = opts.treeAdapter.getChildNodes(scriptElement)[0];
2793fb6ee3Sopenharmony_ci            const script = scriptTextNode ? opts.treeAdapter.getTextNodeContent(scriptTextNode) : '';
2893fb6ee3Sopenharmony_ci
2993fb6ee3Sopenharmony_ci            //NOTE: emulate postponed script execution
3093fb6ee3Sopenharmony_ci            await pause();
3193fb6ee3Sopenharmony_ci
3293fb6ee3Sopenharmony_ci            try {
3393fb6ee3Sopenharmony_ci                runInNewContext(script, { document: { write: documentWrite } });
3493fb6ee3Sopenharmony_ci                resume();
3593fb6ee3Sopenharmony_ci            } catch (error) {
3693fb6ee3Sopenharmony_ci                parser.emit('error', error);
3793fb6ee3Sopenharmony_ci            }
3893fb6ee3Sopenharmony_ci        });
3993fb6ee3Sopenharmony_ci
4093fb6ee3Sopenharmony_ci        //NOTE: emulate async input stream behavior
4193fb6ee3Sopenharmony_ci        for (const chunk of chunks) {
4293fb6ee3Sopenharmony_ci            parser.write(chunk);
4393fb6ee3Sopenharmony_ci            await pause();
4493fb6ee3Sopenharmony_ci        }
4593fb6ee3Sopenharmony_ci
4693fb6ee3Sopenharmony_ci        parser.end();
4793fb6ee3Sopenharmony_ci
4893fb6ee3Sopenharmony_ci        await finished(parser);
4993fb6ee3Sopenharmony_ci
5093fb6ee3Sopenharmony_ci        return {
5193fb6ee3Sopenharmony_ci            node: test.fragmentContext ? parser.getFragment() : parser.document,
5293fb6ee3Sopenharmony_ci            chunks,
5393fb6ee3Sopenharmony_ci        };
5493fb6ee3Sopenharmony_ci    }
5593fb6ee3Sopenharmony_ci);
5693fb6ee3Sopenharmony_ci
5793fb6ee3Sopenharmony_cigenerateTestsForEachTreeAdapter('ParserStream', (treeAdapter) => {
5893fb6ee3Sopenharmony_ci    test('Regression - Synchronously calling resume() leads to crash (GH-98)', (done) => {
5993fb6ee3Sopenharmony_ci        const parser = new ParserStream({ treeAdapter });
6093fb6ee3Sopenharmony_ci
6193fb6ee3Sopenharmony_ci        parser.on('script', (_el, _docWrite, resume) => resume());
6293fb6ee3Sopenharmony_ci
6393fb6ee3Sopenharmony_ci        parser.end('<!doctype html><script>abc</script>');
6493fb6ee3Sopenharmony_ci
6593fb6ee3Sopenharmony_ci        process.nextTick(done);
6693fb6ee3Sopenharmony_ci    });
6793fb6ee3Sopenharmony_ci
6893fb6ee3Sopenharmony_ci    test('Regression - Parsing loop lock causes accidental hang ups (GH-101)', () => {
6993fb6ee3Sopenharmony_ci        const parser = new ParserStream({ treeAdapter });
7093fb6ee3Sopenharmony_ci
7193fb6ee3Sopenharmony_ci        parser.on('script', (_scriptElement, _documentWrite, resume) => process.nextTick(resume));
7293fb6ee3Sopenharmony_ci
7393fb6ee3Sopenharmony_ci        parser.write('<script>yo</script>');
7493fb6ee3Sopenharmony_ci        parser.end('dawg');
7593fb6ee3Sopenharmony_ci
7693fb6ee3Sopenharmony_ci        return finished(parser);
7793fb6ee3Sopenharmony_ci    });
7893fb6ee3Sopenharmony_ci});
79