From 176227549d1fd9a88b16175b0cc3aab46aa81506 Mon Sep 17 00:00:00 2001 From: Joel Einbinder Date: Thu, 13 Aug 2020 14:35:05 -0700 Subject: [PATCH] feat(testrunner): cache transformed files (#3451) This makes parsing faster to the point where it is not worth it to report when files are parsed. --- test/runner/fixturesUI.js | 14 ++------- test/runner/index.js | 9 ------ test/runner/transform.js | 60 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 62 insertions(+), 21 deletions(-) create mode 100644 test/runner/transform.js diff --git a/test/runner/fixturesUI.js b/test/runner/fixturesUI.js index 73c03eb836..d932168ff2 100644 --- a/test/runner/fixturesUI.js +++ b/test/runner/fixturesUI.js @@ -16,8 +16,7 @@ const { FixturePool, registerFixture, registerWorkerFixture } = require('./fixturePool'); const { Test, Suite } = require('mocha'); -const pirates = require('pirates'); -const babel = require('@babel/core'); +const {installTransform} = require('./transform'); const commonSuite = require('mocha/lib/interfaces/common'); Error.stackTraceLimit = 15; @@ -135,16 +134,7 @@ function fixturesUI(trialRun, suite) { context.fit = it.only(true); context.xit = it.skip(true); - revertBabelRequire = pirates.addHook((code, filename) => { - const result = babel.transformFileSync(filename, { - presets: [ - ['@babel/preset-env', {targets: {node: 'current'}}], - '@babel/preset-typescript'] - }); - return result.code; - }, { - exts: ['.ts'] - }); + revertBabelRequire = installTransform(); }); suite.on(Suite.constants.EVENT_FILE_POST_REQUIRE, function(context, file, mocha) { diff --git a/test/runner/index.js b/test/runner/index.js index 3cdf026f13..8c00688a66 100644 --- a/test/runner/index.js +++ b/test/runner/index.js @@ -39,10 +39,6 @@ program const files = collectFiles(path.join(process.cwd(), command.args[0]), command.args.slice(1)); const rootSuite = new Mocha.Suite('', new Mocha.Context(), true); - if (!command.reporter) { - // TODO: extend reporter interface. - console.log(`Parsing ${files.length} test files`); - } let total = 0; // Build the test model, suite per file. for (const file of files) { @@ -59,11 +55,6 @@ program let runner; await new Promise(f => { runner = mocha.run(f); - if (!command.reporter) { - runner.on(constants.EVENT_RUN_BEGIN, () => { - process.stdout.write(colors.yellow('\u00B7')); - }); - } }); total += runner.grepTotal(mocha.suite); diff --git a/test/runner/transform.js b/test/runner/transform.js new file mode 100644 index 0000000000..c9d7cab257 --- /dev/null +++ b/test/runner/transform.js @@ -0,0 +1,60 @@ +/** + * Copyright (c) Microsoft Corporation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +const crypto = require('crypto'); +const os = require('os'); +const path = require('path'); +const fs = require('fs'); +const pirates = require('pirates'); +const babel = require('@babel/core'); +const version = 0; +const cacheDir = path.join(os.tmpdir(), 'playwright-transform-cache'); + +/** + * @param {string} content + * @param {string} filePath + * @return {string} + */ +function calculateCachePath(content, filePath) { + const hash = crypto.createHash('sha1').update(content).update(filePath).update(String(version)).digest('hex'); + const fileName = path.basename(filePath, path.extname(filePath)).replace(/\W/g, '') + '_' + hash; + + return path.join(cacheDir, hash[0] + hash[1], fileName); +} + +function installTransform() { + return pirates.addHook((code, filename) => { + const cachePath = calculateCachePath(code, filename); + const codePath = cachePath + '.js'; + if (fs.existsSync(codePath)) + return fs.readFileSync(codePath, 'utf8'); + + const result = babel.transformFileSync(filename, { + presets: [ + ['@babel/preset-env', {targets: {node: 'current'}}], + '@babel/preset-typescript'], + }); + if (result.code) { + fs.mkdirSync(path.dirname(cachePath), {recursive: true}); + fs.writeFileSync(codePath, result.code, 'utf8'); + } + // TODO(einbinder) sourcemaps + return result.code; + }, { + exts: ['.ts'] + }); +} + +module.exports = {installTransform};