• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1'use strict';
2
3const path = require('path');
4const ParserStream = require('../lib');
5const generateParsingTests = require('../../../test/utils/generate-parsing-tests');
6const { makeChunks, generateTestsForEachTreeAdapter } = require('../../../test/utils/common');
7
8function pause() {
9    return new Promise(resolve => setTimeout(resolve, 5));
10}
11
12generateParsingTests(
13    module.exports,
14    'ParserStream - Scripting',
15    {
16        skipFragments: true,
17        withoutErrors: true,
18        testSuite: [path.join(__dirname, '../../../test/data/tree-construction-scripting')]
19    },
20    async (test, opts) => {
21        const chunks = makeChunks(test.input);
22        const parser = new ParserStream(opts);
23        const document = parser.document;
24
25        const completionPromise = new Promise((resolve, reject) => {
26            parser.once('finish', () => resolve({ node: document }));
27
28            parser.on('script', async (scriptElement, documentWrite, resume) => {
29                const scriptTextNode = opts.treeAdapter.getChildNodes(scriptElement)[0];
30                const script = scriptTextNode && opts.treeAdapter.getTextNodeContent(scriptTextNode);
31
32                document.write = documentWrite;
33
34                //NOTE: emulate postponed script execution
35                await pause();
36
37                try {
38                    /* eslint-disable no-eval */
39                    eval(script);
40                    /* eslint-enable no-eval */
41                    resume();
42                } catch (err) {
43                    reject(err);
44                }
45            });
46        });
47
48        //NOTE: emulate async input stream behavior
49        for (const chunk of chunks) {
50            parser.write(chunk);
51            await pause();
52        }
53
54        parser.end();
55
56        return completionPromise;
57    }
58);
59
60generateTestsForEachTreeAdapter(module.exports, (_test, treeAdapter) => {
61    _test['Regression - Synchronously calling resume() leads to crash (GH-98)'] = function(done) {
62        const parser = new ParserStream({ treeAdapter: treeAdapter });
63
64        parser.on('script', (el, docWrite, resume) => {
65            resume();
66        });
67
68        parser.end('<!doctype html><script>abc</script>');
69
70        process.nextTick(done);
71    };
72
73    _test['Regression - Parsing loop lock causes accidental hang ups (GH-101)'] = function(done) {
74        const parser = new ParserStream({ treeAdapter: treeAdapter });
75
76        parser.once('finish', () => {
77            done();
78        });
79
80        parser.on('script', (scriptElement, documentWrite, resume) => {
81            process.nextTick(() => {
82                resume();
83            });
84        });
85
86        parser.write('<script>yo</script>');
87        parser.end('dawg');
88    };
89});
90