3 const process = require('process');
4 process.chdir( __dirname );
6 const webpack = require('webpack');
7 const JSDOM = require("jsdom").JSDOM;
8 const test = require('tape');
9 const { Console } = require('console');
10 var fs = require('fs');
11 const del = require('del');
12 const path = require('path');
13 const glob = require("glob");
14 const nock = require('nock');
15 const node_fetch = require('node-fetch');
17 const { JSAN_to_src_path } = require("./webpack_util/utils.js");
19 const webpackConfig = require('./test.webpack.config');
20 const buildPath = webpackConfig.output.path;
21 const legacyPath = path.resolve(__dirname, "./source/legacy/");
23 // Default DOM contents within which a test script is excecuted in.
28 <meta charset="utf-8">
35 // If the user provided globs, use them instead of running all tests.
36 if(process.argv.length>2){
37 var targets = [].concat(...process.argv.slice(2).map(gt=>glob.sync(gt)))
38 .map(p=>path.resolve(p));
39 if(!targets.length) return console.error("No tests specified.");
40 webpackConfig.entry = targets.reduce((dict,elt)=>{
46 // First test is always that the scripts build!
47 test('Webpack Build '+Object.keys(webpackConfig.entry).join(", "), function (t) {
49 // Remove old built tests
50 del.sync([path.resolve(buildPath)]);
52 webpack(webpackConfig).run((err,stats)=>{
55 var st = JSON.stringify(stats.toJson("minimal"));
56 if(st.errors) t.fail(st);
58 // Once the scripts build, we can run the rest of the tests.
59 runTests(JSON.parse(fs.readFileSync(path.resolve(buildPath,'./mapping.json'))));
64 // Run each test file in a mapping (generated from webpack-filemap-plugin.js)
65 function runTests(mapping){
66 // For each test file:
67 Object.entries(mapping).map(kv=>{
68 // Make unique list of all JSAN Deps resolved to their paths and chunk files
69 return [...new Set(kv[1].legacy
70 .map(jsan=>JSAN_to_src_path(legacyPath,jsan))
71 .concat(kv[1].files.map(fn=>path.resolve(buildPath,fn))))];
72 }).forEach(scrptList=>{
73 // Run a JSDOM Virtual instance with all scripts and deps for each test file
74 const dom = new JSDOM(empty_html, {
75 url:"https://cassavabase.org/test.html",
76 contentType: "text/html",
77 includeNodeLocations: true,
78 runScripts: "dangerously"
80 // Reference tape from the JSDOM window, by name defined in test.webpack.config
81 dom.window[webpackConfig.externals.tape] = test;
82 // Reference nock from the JSDOM window, by name defined in test.webpack.config
83 // also clean up current mocked responses from previous tests
84 dom.window[webpackConfig.externals.nock] = nock;
86 nock.disableNetConnect();
87 // Polyfill JSDOM fetch using node-fetch
88 dom.window.fetch = node_fetch;
89 // Ensure console.log/info/debug statements inside virtual DOM print to stderr
90 // by replacing the default console with one which routes to stderr
91 // This ensures "pure" tap stdout
92 dom.window.console = new Console({ stdout: process.stderr, stderr: process.stderr });
93 // Add script tags to JSDOM, these excute upon insertion (thereby running
94 // the contained tests).
95 scrptList.forEach(file=>{
96 var src = fs.readFileSync(file)+'';
97 var scrpt = dom.window.document.createElement('script');
98 scrpt.innerHTML = src;
99 dom.window.document.head.appendChild(scrpt);