chore: drop Node.js v6 support (#5045)
Node.js v6 was end-of-life'd in April, 2019, with AWS Lambda prohibiting updaets to the Node.js v6 runtime since June 30, 2019. This makes it quite safe for us to remove the Node 6 support from the repository.
This commit is contained in:
parent
c0ba8f9a19
commit
11ff374ca3
@ -1,8 +1,6 @@
|
||||
environment:
|
||||
matrix:
|
||||
- nodejs_version: "6.12.3"
|
||||
FLAKINESS_DASHBOARD_NAME: Appveyor Chromium (Win + node6)
|
||||
- nodejs_version: "8.11.3"
|
||||
- nodejs_version: "8.16.0"
|
||||
FLAKINESS_DASHBOARD_NAME: Appveyor Chromium (Win + node8)
|
||||
FLAKINESS_DASHBOARD_PASSWORD:
|
||||
secure: g66jP+j6C+hkXLutBV9fdxB5fRJgcQQzy93SgQzXUmcCl/RjkJwnzyHvX0xfCVnv
|
||||
@ -13,11 +11,9 @@ install:
|
||||
- ps: $env:FLAKINESS_DASHBOARD_BUILD_URL="https://ci.appveyor.com/project/aslushnikov/puppeteer/builds/$env:APPVEYOR_BUILD_ID/job/$env:APPVEYOR_JOB_ID"
|
||||
- ps: Install-Product node $env:nodejs_version
|
||||
- npm install
|
||||
- if "%nodejs_version%" == "8.11.3" (
|
||||
- if "%nodejs_version%" == "8.16.0" (
|
||||
npm run lint &&
|
||||
npm run coverage &&
|
||||
npm run test-doclint &&
|
||||
npm run test-types
|
||||
) else (
|
||||
npm run unit-node6
|
||||
)
|
||||
|
@ -1,17 +0,0 @@
|
||||
FROM node:6.12.3
|
||||
|
||||
RUN apt-get update && \
|
||||
apt-get -y install xvfb gconf-service libasound2 libatk1.0-0 libc6 libcairo2 libcups2 \
|
||||
libdbus-1-3 libexpat1 libfontconfig1 libgcc1 libgconf-2-4 libgdk-pixbuf2.0-0 libglib2.0-0 \
|
||||
libgtk-3-0 libnspr4 libpango-1.0-0 libpangocairo-1.0-0 libstdc++6 libx11-6 libx11-xcb1 libxcb1 \
|
||||
libxcomposite1 libxcursor1 libxdamage1 libxext6 libxfixes3 libxi6 libxrandr2 libxrender1 libxss1 \
|
||||
libxtst6 ca-certificates fonts-liberation libappindicator1 libnss3 lsb-release xdg-utils wget && \
|
||||
rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# Add user so we don't need --no-sandbox.
|
||||
RUN groupadd -r pptruser && useradd -r -g pptruser -G audio,video pptruser \
|
||||
&& mkdir -p /home/pptruser/Downloads \
|
||||
&& chown -R pptruser:pptruser /home/pptruser
|
||||
|
||||
# Run everything after as non-privileged user.
|
||||
USER pptruser
|
@ -4,15 +4,6 @@ env:
|
||||
FLAKINESS_DASHBOARD_NAME: Cirrus ${CIRRUS_TASK_NAME}
|
||||
FLAKINESS_DASHBOARD_BUILD_URL: https://cirrus-ci.com/task/${CIRRUS_TASK_ID}
|
||||
|
||||
task:
|
||||
matrix:
|
||||
- name: Chromium (node6 + linux)
|
||||
container:
|
||||
dockerfile: .ci/node6/Dockerfile.linux
|
||||
xvfb_start_background_script: Xvfb :99 -ac -screen 0 1024x768x24
|
||||
install_script: npm install --unsafe-perm
|
||||
test_script: npm run unit-node6
|
||||
|
||||
task:
|
||||
matrix:
|
||||
- name: Chromium (node8 + linux)
|
||||
|
10
.travis.yml
10
.travis.yml
@ -24,24 +24,18 @@ script:
|
||||
- 'if [ "$NODE8" = "true" ]; then npm run test-types; fi'
|
||||
- 'if [ "$NODE8" = "true" ]; then npm run bundle; fi'
|
||||
- 'if [ "$NODE8" = "true" ]; then npm run unit-bundle; fi'
|
||||
- 'if [ "$NODE6" = "true" ]; then npm run unit-node6; fi'
|
||||
jobs:
|
||||
include:
|
||||
- node_js: "8.11.3"
|
||||
- node_js: "8.16.0"
|
||||
env:
|
||||
- NODE8=true
|
||||
- FLAKINESS_DASHBOARD_NAME="Travis Chromium (node8 + linux)"
|
||||
- FLAKINESS_DASHBOARD_BUILD_URL="${TRAVIS_JOB_WEB_URL}"
|
||||
- node_js: "8.11.3"
|
||||
- node_js: "8.16.0"
|
||||
env:
|
||||
- FIREFOX=true
|
||||
- FLAKINESS_DASHBOARD_NAME="Travis Firefox (node8 + linux)"
|
||||
- FLAKINESS_DASHBOARD_BUILD_URL="${TRAVIS_JOB_WEB_URL}"
|
||||
- node_js: "6.12.3"
|
||||
env:
|
||||
- NODE6=true
|
||||
- FLAKINESS_DASHBOARD_NAME="Travis Chromium (node6 + linux)"
|
||||
- FLAKINESS_DASHBOARD_BUILD_URL="${TRAVIS_JOB_WEB_URL}"
|
||||
before_deploy: "npm run apply-next-version"
|
||||
deploy:
|
||||
provider: npm
|
||||
|
@ -14,15 +14,4 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
let asyncawait = true;
|
||||
try {
|
||||
new Function('async function test(){await 1}');
|
||||
} catch (error) {
|
||||
asyncawait = false;
|
||||
}
|
||||
|
||||
// If node does not support async await, use the compiled version.
|
||||
if (asyncawait)
|
||||
module.exports = require('./lib/DeviceDescriptors');
|
||||
else
|
||||
module.exports = require('./node6/lib/DeviceDescriptors');
|
||||
module.exports = require('./lib/DeviceDescriptors');
|
||||
|
13
Errors.js
13
Errors.js
@ -14,15 +14,4 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
let asyncawait = true;
|
||||
try {
|
||||
new Function('async function test(){await 1}');
|
||||
} catch (error) {
|
||||
asyncawait = false;
|
||||
}
|
||||
|
||||
// If node does not support async await, use the compiled version.
|
||||
if (asyncawait)
|
||||
module.exports = require('./lib/Errors');
|
||||
else
|
||||
module.exports = require('./node6/lib/Errors');
|
||||
module.exports = require('./lib/Errors');
|
||||
|
@ -57,7 +57,10 @@ See [puppeteer vs puppeteer-core](https://github.com/GoogleChrome/puppeteer/blob
|
||||
|
||||
### Usage
|
||||
|
||||
Note: Puppeteer requires at least Node v6.4.0, but the examples below use async/await which is only supported in Node v7.6.0 or greater.
|
||||
Puppeteer follows the latest [maintenance LTS](https://github.com/nodejs/Release#release-schedule) version of Node.
|
||||
|
||||
Note: Prior to v1.18.1, Puppeteer required at least Node v6.4.0. All subsequent versions rely on
|
||||
Node 8.9.0+. All examples below use async/await which is only supported in Node v7.6.0 or greater.
|
||||
|
||||
Puppeteer will be familiar to people using other browser testing frameworks. You create an instance
|
||||
of `Browser`, open pages, and then manipulate them with [Puppeteer's API](https://github.com/GoogleChrome/puppeteer/blob/v1.20.0/docs/api.md#).
|
||||
|
@ -14,15 +14,4 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
let asyncawait = true;
|
||||
try {
|
||||
new Function('async function test(){await 1}');
|
||||
} catch (error) {
|
||||
asyncawait = false;
|
||||
}
|
||||
|
||||
// If node does not support async await, use the compiled version.
|
||||
if (asyncawait)
|
||||
module.exports = require('./lib/DeviceDescriptors');
|
||||
else
|
||||
module.exports = require('./node6/lib/DeviceDescriptors');
|
||||
module.exports = require('./lib/DeviceDescriptors');
|
||||
|
@ -4,7 +4,6 @@ const {Dialog} = require('./Dialog');
|
||||
const {TimeoutError} = require('./Errors');
|
||||
const fs = require('fs');
|
||||
const mime = require('mime');
|
||||
const util = require('util');
|
||||
const EventEmitter = require('events');
|
||||
const {createHandle} = require('./JSHandle');
|
||||
const {Events} = require('./Events');
|
||||
@ -15,7 +14,7 @@ const {TimeoutSettings} = require('./TimeoutSettings');
|
||||
const {NavigationWatchdog} = require('./NavigationWatchdog');
|
||||
const {Accessibility} = require('./Accessibility');
|
||||
|
||||
const writeFileAsync = util.promisify(fs.writeFile);
|
||||
const writeFileAsync = helper.promisify(fs.writeFile);
|
||||
|
||||
class Page extends EventEmitter {
|
||||
/**
|
||||
|
@ -65,6 +65,10 @@ class Helper {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {function} nodeFunction
|
||||
* @return {function}
|
||||
*/
|
||||
static promisify(nodeFunction) {
|
||||
function promisified(...args) {
|
||||
return new Promise((resolve, reject) => {
|
||||
|
@ -1,14 +1,14 @@
|
||||
const os = require('os');
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const util = require('util');
|
||||
|
||||
// Install browser preferences after downloading and unpacking
|
||||
// firefox instances.
|
||||
// Based on: https://developer.mozilla.org/en-US/docs/Mozilla/Firefox/Enterprise_deployment_before_60#Configuration
|
||||
async function installFirefoxPreferences(executablePath) {
|
||||
const firefoxFolder = path.dirname(executablePath);
|
||||
const {helper} = require('../lib/helper');
|
||||
const mkdirAsync = helper.promisify(fs.mkdir.bind(fs));
|
||||
const mkdirAsync = util.promisify(fs.mkdir.bind(fs));
|
||||
|
||||
let prefPath = '';
|
||||
let configPath = '';
|
||||
|
23
index.js
23
index.js
@ -14,25 +14,16 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
let asyncawait = true;
|
||||
try {
|
||||
new Function('async function test(){await 1}');
|
||||
} catch (error) {
|
||||
asyncawait = false;
|
||||
}
|
||||
|
||||
if (asyncawait) {
|
||||
const {helper} = require('./lib/helper');
|
||||
const api = require('./lib/api');
|
||||
for (const className in api) {
|
||||
// Puppeteer-web excludes certain classes from bundle, e.g. BrowserFetcher.
|
||||
if (typeof api[className] === 'function')
|
||||
helper.installAsyncStackHooks(api[className]);
|
||||
}
|
||||
const {helper} = require('./lib/helper');
|
||||
const api = require('./lib/api');
|
||||
for (const className in api) {
|
||||
// Puppeteer-web excludes certain classes from bundle, e.g. BrowserFetcher.
|
||||
if (typeof api[className] === 'function')
|
||||
helper.installAsyncStackHooks(api[className]);
|
||||
}
|
||||
|
||||
// If node does not support async await, use the compiled version.
|
||||
const Puppeteer = asyncawait ? require('./lib/Puppeteer') : require('./node6/lib/Puppeteer');
|
||||
const Puppeteer = require('./lib/Puppeteer');
|
||||
const packageJson = require('./package.json');
|
||||
const preferredRevision = packageJson.puppeteer.chromium_revision;
|
||||
const isPuppeteerCore = packageJson.name === 'puppeteer-core';
|
||||
|
29
install.js
29
install.js
@ -18,8 +18,6 @@
|
||||
if (require('./package.json').name === 'puppeteer-core')
|
||||
return;
|
||||
|
||||
buildNode6IfNecessary();
|
||||
|
||||
if (process.env.PUPPETEER_SKIP_CHROMIUM_DOWNLOAD) {
|
||||
logPolitely('**INFO** Skipping Chromium download. "PUPPETEER_SKIP_CHROMIUM_DOWNLOAD" environment variable was found.');
|
||||
return;
|
||||
@ -109,34 +107,7 @@ function toMegabytes(bytes) {
|
||||
return `${Math.round(mb * 10) / 10} Mb`;
|
||||
}
|
||||
|
||||
function buildNode6IfNecessary() {
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
|
||||
// if this package is installed from NPM, then it already has up-to-date node6
|
||||
// folder.
|
||||
if (!fs.existsSync(path.join('utils', 'node6-transform')))
|
||||
return;
|
||||
// if async/await is supported, then node6 is not needed.
|
||||
if (supportsAsyncAwait())
|
||||
return;
|
||||
// Re-build node6/ folder.
|
||||
logPolitely('Building Puppeteer for Node 6');
|
||||
require(path.join(__dirname, 'utils', 'node6-transform'));
|
||||
}
|
||||
|
||||
function supportsAsyncAwait() {
|
||||
try {
|
||||
new Function('async function test(){await 1}');
|
||||
} catch (error) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
function generateProtocolTypesIfNecessary(updated) {
|
||||
if (!supportsAsyncAwait())
|
||||
return;
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
if (!fs.existsSync(path.join(__dirname, 'utils', 'protocol-types-generator')))
|
||||
|
@ -17,8 +17,8 @@
|
||||
const os = require('os');
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const extract = require('extract-zip');
|
||||
const util = require('util');
|
||||
const extract = require('extract-zip');
|
||||
const URL = require('url');
|
||||
const {helper, assert} = require('./helper');
|
||||
const removeRecursive = require('rimraf');
|
||||
|
@ -31,6 +31,7 @@ const {Worker} = require('./Worker');
|
||||
const {createJSHandle} = require('./JSHandle');
|
||||
const {Accessibility} = require('./Accessibility');
|
||||
const {TimeoutSettings} = require('./TimeoutSettings');
|
||||
|
||||
const writeFileAsync = helper.promisify(fs.writeFile);
|
||||
|
||||
class Page extends EventEmitter {
|
||||
|
@ -156,6 +156,10 @@ class Helper {
|
||||
return typeof obj === 'number' || obj instanceof Number;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {function} nodeFunction
|
||||
* @return {function}
|
||||
*/
|
||||
static promisify(nodeFunction) {
|
||||
function promisified(...args) {
|
||||
return new Promise((resolve, reject) => {
|
||||
|
@ -5,7 +5,7 @@
|
||||
"main": "index.js",
|
||||
"repository": "github:GoogleChrome/puppeteer",
|
||||
"engines": {
|
||||
"node": ">=6.4.0"
|
||||
"node": ">=8.16.0"
|
||||
},
|
||||
"puppeteer": {
|
||||
"chromium_revision": "686378"
|
||||
@ -15,14 +15,11 @@
|
||||
"funit": "BROWSER=firefox node test/test.js",
|
||||
"debug-unit": "node --inspect-brk test/test.js",
|
||||
"test-doclint": "node utils/doclint/check_public_api/test/test.js && node utils/doclint/preprocessor/test.js",
|
||||
"test": "npm run lint --silent && npm run coverage && npm run test-doclint && npm run test-node6-transformer && npm run test-types && node utils/testrunner/test/test.js",
|
||||
"test": "npm run lint --silent && npm run coverage && npm run test-doclint && npm run test-types && node utils/testrunner/test/test.js",
|
||||
"install": "node install.js",
|
||||
"lint": "([ \"$CI\" = true ] && eslint --quiet -f codeframe . || eslint .) && npm run tsc && npm run doc",
|
||||
"doc": "node utils/doclint/cli.js",
|
||||
"coverage": "cross-env COVERAGE=true npm run unit",
|
||||
"test-node6-transformer": "node utils/node6-transform/test/test.js",
|
||||
"build": "node utils/node6-transform/index.js && node utils/doclint/generate_types",
|
||||
"unit-node6": "node node6/test/test.js",
|
||||
"tsc": "tsc -p .",
|
||||
"prepublishOnly": "npm run build",
|
||||
"apply-next-version": "node utils/apply_next_version.js",
|
||||
@ -63,7 +60,6 @@
|
||||
},
|
||||
"browser": {
|
||||
"./lib/BrowserFetcher.js": false,
|
||||
"./node6/lib/Puppeteer": false,
|
||||
"ws": "./utils/browser/WebSocket",
|
||||
"fs": false,
|
||||
"child_process": false,
|
||||
|
@ -16,13 +16,6 @@
|
||||
|
||||
const utils = require('./utils');
|
||||
|
||||
let asyncawait = true;
|
||||
try {
|
||||
new Function('async function foo() {await 1}');
|
||||
} catch (e) {
|
||||
asyncawait = false;
|
||||
}
|
||||
|
||||
const bigint = typeof BigInt !== 'undefined';
|
||||
|
||||
module.exports.addTests = function({testRunner, expect}) {
|
||||
@ -74,14 +67,12 @@ module.exports.addTests = function({testRunner, expect}) {
|
||||
it_fails_ffox('should return undefined for objects with symbols', async({page, server}) => {
|
||||
expect(await page.evaluate(() => [Symbol('foo4')])).toBe(undefined);
|
||||
});
|
||||
(asyncawait ? it : xit)('should work with function shorthands', async({page, server}) => {
|
||||
// trick node6 transpiler to not touch our object.
|
||||
// TODO(lushnikov): remove eval once Node6 is dropped.
|
||||
const a = eval(`({
|
||||
it('should work with function shorthands', async({page, server}) => {
|
||||
const a = {
|
||||
sum(a, b) { return a + b; },
|
||||
|
||||
async mult(a, b) { return a * b; }
|
||||
})`);
|
||||
};
|
||||
expect(await page.evaluate(a.sum, 1, 2)).toBe(3);
|
||||
expect(await page.evaluate(a.mult, 2, 4)).toBe(8);
|
||||
});
|
||||
|
@ -17,11 +17,12 @@
|
||||
const path = require('path');
|
||||
const os = require('os');
|
||||
const fs = require('fs');
|
||||
const {helper} = require('../lib/helper');
|
||||
const rmAsync = helper.promisify(require('rimraf'));
|
||||
const util = require('util');
|
||||
const utils = require('./utils');
|
||||
const {waitEvent} = utils;
|
||||
const mkdtempAsync = helper.promisify(fs.mkdtemp);
|
||||
|
||||
const rmAsync = util.promisify(require('rimraf'));
|
||||
const mkdtempAsync = util.promisify(fs.mkdtemp);
|
||||
|
||||
const TMP_FOLDER = path.join(os.tmpdir(), 'pptr_tmp_folder-');
|
||||
|
||||
|
@ -233,9 +233,10 @@ module.exports.addTests = function({testRunner, expect, defaultBrowserOptions, p
|
||||
const browser = await puppeteer.launch(options);
|
||||
const pages = await browser.pages();
|
||||
expect(pages.length).toBe(1);
|
||||
if (pages[0].url() !== server.EMPTY_PAGE)
|
||||
await pages[0].waitForNavigation();
|
||||
expect(pages[0].url()).toBe(server.EMPTY_PAGE);
|
||||
const page = pages[0];
|
||||
if (page.url() !== server.EMPTY_PAGE)
|
||||
await page.waitForNavigation();
|
||||
expect(page.url()).toBe(server.EMPTY_PAGE);
|
||||
await browser.close();
|
||||
});
|
||||
it('should set the default viewport', async() => {
|
||||
|
@ -15,11 +15,12 @@
|
||||
*/
|
||||
|
||||
const path = require('path');
|
||||
const util = require('util');
|
||||
const fs = require('fs');
|
||||
|
||||
const readFileAsync = promisify(fs.readFile);
|
||||
const readdirAsync = promisify(fs.readdir);
|
||||
const writeFileAsync = promisify(fs.writeFile);
|
||||
const readFileAsync = util.promisify(fs.readFile);
|
||||
const readdirAsync = util.promisify(fs.readdir);
|
||||
const writeFileAsync = util.promisify(fs.writeFile);
|
||||
|
||||
const PROJECT_DIR = path.join(__dirname, '..', '..');
|
||||
|
||||
@ -110,26 +111,3 @@ class Source {
|
||||
}
|
||||
module.exports = Source;
|
||||
|
||||
/**
|
||||
* @param {function(?)} nodeFunction
|
||||
* @return {function(?):!Promise<?>}
|
||||
*/
|
||||
function promisify(nodeFunction) {
|
||||
/**
|
||||
* @param {!Array<?>} options
|
||||
* @return {!Promise<?>}
|
||||
*/
|
||||
return function(...options) {
|
||||
return new Promise(function(fulfill, reject) {
|
||||
options.push(callback);
|
||||
nodeFunction.call(null, ...options);
|
||||
function callback(err, result) {
|
||||
if (err)
|
||||
reject(err);
|
||||
else
|
||||
fulfill(result);
|
||||
}
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -1,156 +0,0 @@
|
||||
/**
|
||||
* Copyright 2017 Google Inc. All rights reserved.
|
||||
*
|
||||
* 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 esprima = require('esprima');
|
||||
const ESTreeWalker = require('../ESTreeWalker');
|
||||
|
||||
// This is converted from Babel's "transform-async-to-generator"
|
||||
// https://babeljs.io/docs/plugins/transform-async-to-generator/
|
||||
const asyncToGenerator = fn => {
|
||||
const gen = fn.call(this);
|
||||
return new Promise((resolve, reject) => {
|
||||
function step(key, arg) {
|
||||
let info, value;
|
||||
try {
|
||||
info = gen[key](arg);
|
||||
value = info.value;
|
||||
} catch (error) {
|
||||
reject(error);
|
||||
return;
|
||||
}
|
||||
if (info.done) {
|
||||
resolve(value);
|
||||
} else {
|
||||
return Promise.resolve(value).then(
|
||||
value => {
|
||||
step('next', value);
|
||||
},
|
||||
err => {
|
||||
step('throw', err);
|
||||
});
|
||||
}
|
||||
}
|
||||
return step('next');
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {string} text
|
||||
* @return {string}
|
||||
*/
|
||||
function transformAsyncFunctions(text) {
|
||||
/**
|
||||
* @type {!Array<{from: number, to: number, replacement: string}>}
|
||||
*/
|
||||
const edits = [];
|
||||
|
||||
const ast = esprima.parseScript(text, {range: true, tolerant: true});
|
||||
const walker = new ESTreeWalker(node => {
|
||||
if (node.type === 'FunctionExpression' || node.type === 'FunctionDeclaration' || node.type === 'ArrowFunctionExpression')
|
||||
onBeforeFunction(node);
|
||||
else if (node.type === 'AwaitExpression')
|
||||
onBeforeAwait(node);
|
||||
}, node => {
|
||||
if (node.type === 'FunctionExpression' || node.type === 'FunctionDeclaration' || node.type === 'ArrowFunctionExpression')
|
||||
onAfterFunction(node);
|
||||
else if (node.type === 'AwaitExpression')
|
||||
onAfterAwait(node);
|
||||
});
|
||||
walker.walk(ast);
|
||||
|
||||
edits.reverse();
|
||||
for (const {replacement, from, to} of edits)
|
||||
text = text.substring(0, from) + replacement + text.substring(to);
|
||||
|
||||
return text;
|
||||
|
||||
/**
|
||||
* @param {ESTree.Node} node
|
||||
*/
|
||||
function onBeforeFunction(node) {
|
||||
if (!node.async) return;
|
||||
|
||||
let range;
|
||||
if (node.parent.type === 'MethodDefinition')
|
||||
range = node.parent.range;
|
||||
else
|
||||
range = node.range;
|
||||
const index = text.substring(range[0], range[1]).indexOf('async') + range[0];
|
||||
insertText(index, index + 'async'.length, '/* async */');
|
||||
|
||||
let before = `{return (${asyncToGenerator.toString()})(function*()`;
|
||||
if (node.body.type !== 'BlockStatement') {
|
||||
before += `{ return `;
|
||||
|
||||
// Remove parentheses that might wrap an arrow function
|
||||
const beforeBody = text.substring(node.range[0], node.body.range[0]);
|
||||
if (/\(\s*$/.test(beforeBody)) {
|
||||
const openParen = node.range[0] + beforeBody.lastIndexOf('(');
|
||||
insertText(openParen, openParen + 1, ' ');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
insertText(node.body.range[0], node.body.range[0], before);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {ESTree.Node} node
|
||||
*/
|
||||
function onAfterFunction(node) {
|
||||
if (!node.async) return;
|
||||
|
||||
let after = `);}`;
|
||||
if (node.body.type !== 'BlockStatement')
|
||||
after = `; }` + after;
|
||||
insertText(node.body.range[1], node.body.range[1], after);
|
||||
|
||||
if (node.body.type !== 'BlockStatement') {
|
||||
// Remove parentheses that might wrap an arrow function
|
||||
const beforeBody = text.substring(node.range[0], node.body.range[0]);
|
||||
if (/\(\s*$/.test(beforeBody)) {
|
||||
const afterBody = text.substring(node.body.range[1], node.range[1]);
|
||||
const closeParen = node.body.range[1] + afterBody.indexOf(')');
|
||||
insertText(closeParen, closeParen + 1, ' ');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {ESTree.Node} node
|
||||
*/
|
||||
function onBeforeAwait(node) {
|
||||
const index = text.substring(node.range[0], node.range[1]).indexOf('await') + node.range[0];
|
||||
insertText(index, index + 'await'.length, '(yield');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {ESTree.Node} node
|
||||
*/
|
||||
function onAfterAwait(node) {
|
||||
insertText(node.range[1], node.range[1], ')');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {number} from
|
||||
* @param {number} to
|
||||
*/
|
||||
function insertText(from, to, replacement) {
|
||||
edits.push({from, to, replacement});
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = transformAsyncFunctions;
|
@ -1,64 +0,0 @@
|
||||
/**
|
||||
* Copyright 2017 Google Inc. All rights reserved.
|
||||
*
|
||||
* 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 fs = require('fs');
|
||||
const path = require('path');
|
||||
const removeRecursive = require('rimraf').sync;
|
||||
const transformAsyncFunctions = require('./TransformAsyncFunctions');
|
||||
|
||||
const root = path.join(__dirname, '..', '..');
|
||||
const dest = path.join(__dirname, '..', '..', 'node6');
|
||||
|
||||
const excludes = [
|
||||
path.resolve(root, 'test', 'assets'),
|
||||
];
|
||||
|
||||
if (fs.existsSync(dest))
|
||||
removeRecursive(dest);
|
||||
fs.mkdirSync(dest);
|
||||
fs.mkdirSync(path.join(dest, 'utils'));
|
||||
|
||||
copyFolder(path.join(root, 'lib'), path.join(dest, 'lib'));
|
||||
copyFolder(path.join(root, 'test'), path.join(dest, 'test'));
|
||||
copyFolder(path.join(root, 'utils', 'testrunner'), path.join(dest, 'utils', 'testrunner'));
|
||||
copyFolder(path.join(root, 'utils', 'testserver'), path.join(dest, 'utils', 'testserver'));
|
||||
copyFolder(path.join(root, 'utils', 'flakiness-dashboard'), path.join(dest, 'utils', 'flakiness-dashboard'));
|
||||
|
||||
function copyFolder(source, target) {
|
||||
if (fs.existsSync(target))
|
||||
removeRecursive(target);
|
||||
fs.mkdirSync(target);
|
||||
|
||||
fs.readdirSync(source).forEach(file => {
|
||||
const from = path.join(source, file);
|
||||
const to = path.join(target, file);
|
||||
if (fs.lstatSync(from).isDirectory())
|
||||
copyFolder(from, to);
|
||||
else
|
||||
copyFile(from, to);
|
||||
});
|
||||
}
|
||||
|
||||
function copyFile(from, to) {
|
||||
let text = fs.readFileSync(from);
|
||||
const isExcluded = excludes.some(exclude => from.startsWith(exclude));
|
||||
if (!isExcluded && from.endsWith('.js')) {
|
||||
text = text.toString();
|
||||
const prefix = text.startsWith('#!') ? text.substring(0, text.indexOf('\n')) : '';
|
||||
text = prefix + transformAsyncFunctions(text.substring(prefix.length));
|
||||
}
|
||||
fs.writeFileSync(to, text);
|
||||
}
|
@ -1,97 +0,0 @@
|
||||
/**
|
||||
* Copyright 2017 Google Inc. All rights reserved.
|
||||
*
|
||||
* 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 transformAsyncFunctions = require('../TransformAsyncFunctions');
|
||||
|
||||
const {TestRunner, Reporter, Matchers} = require('../../testrunner/');
|
||||
const runner = new TestRunner();
|
||||
new Reporter(runner);
|
||||
|
||||
const {describe, xdescribe, fdescribe} = runner;
|
||||
const {it, fit, xit} = runner;
|
||||
const {beforeAll, beforeEach, afterAll, afterEach} = runner;
|
||||
|
||||
const {expect} = new Matchers();
|
||||
|
||||
describe('TransformAsyncFunctions', function() {
|
||||
it('should convert a function expression', function(done) {
|
||||
const input = `(async function(){ return 123 })()`;
|
||||
const output = eval(transformAsyncFunctions(input));
|
||||
expect(output instanceof Promise).toBe(true);
|
||||
output.then(result => expect(result).toBe(123)).then(done);
|
||||
});
|
||||
it('should convert an arrow function', function(done) {
|
||||
const input = `(async () => 123)()`;
|
||||
const output = eval(transformAsyncFunctions(input));
|
||||
expect(output instanceof Promise).toBe(true);
|
||||
output.then(result => expect(result).toBe(123)).then(done);
|
||||
});
|
||||
it('should convert an arrow function with curly braces', function(done) {
|
||||
const input = `(async () => { return 123 })()`;
|
||||
const output = eval(transformAsyncFunctions(input));
|
||||
expect(output instanceof Promise).toBe(true);
|
||||
output.then(result => expect(result).toBe(123)).then(done);
|
||||
});
|
||||
it('should convert a function declaration', function(done) {
|
||||
const input = `async function f(){ return 123; } f();`;
|
||||
const output = eval(transformAsyncFunctions(input));
|
||||
expect(output instanceof Promise).toBe(true);
|
||||
output.then(result => expect(result).toBe(123)).then(done);
|
||||
});
|
||||
it('should convert await', function(done) {
|
||||
const input = `async function f(){ return 23 + await Promise.resolve(100); } f();`;
|
||||
const output = eval(transformAsyncFunctions(input));
|
||||
expect(output instanceof Promise).toBe(true);
|
||||
output.then(result => expect(result).toBe(123)).then(done);
|
||||
});
|
||||
it('should convert method', function(done) {
|
||||
const input = `class X{async f() { return 123 }} (new X()).f();`;
|
||||
const output = eval(transformAsyncFunctions(input));
|
||||
expect(output instanceof Promise).toBe(true);
|
||||
output.then(result => expect(result).toBe(123)).then(done);
|
||||
});
|
||||
it('should pass arguments', function(done) {
|
||||
const input = `(async function(a, b){ return await a + await b })(Promise.resolve(100), 23)`;
|
||||
const output = eval(transformAsyncFunctions(input));
|
||||
expect(output instanceof Promise).toBe(true);
|
||||
output.then(result => expect(result).toBe(123)).then(done);
|
||||
});
|
||||
it('should still work across eval', function(done) {
|
||||
const input = `var str = (async function(){ return 123; }).toString(); eval('(' + str + ')')();`;
|
||||
const output = eval(transformAsyncFunctions(input));
|
||||
expect(output instanceof Promise).toBe(true);
|
||||
output.then(result => expect(result).toBe(123)).then(done);
|
||||
});
|
||||
it('should work with double await', function(done) {
|
||||
const input = `async function f(){ return 23 + await Promise.resolve(50 + await Promise.resolve(50)); } f();`;
|
||||
const output = eval(transformAsyncFunctions(input));
|
||||
expect(output instanceof Promise).toBe(true);
|
||||
output.then(result => expect(result).toBe(123)).then(done);
|
||||
});
|
||||
it('should work paren around arrow function', function(done) {
|
||||
const input = `(async x => ( 123))()`;
|
||||
const output = eval(transformAsyncFunctions(input));
|
||||
expect(output instanceof Promise).toBe(true);
|
||||
output.then(result => expect(result).toBe(123)).then(done);
|
||||
});
|
||||
it('should work async arrow with await', function(done) {
|
||||
const input = `(async() => await 123)()`;
|
||||
const output = eval(transformAsyncFunctions(input));
|
||||
expect(output instanceof Promise).toBe(true);
|
||||
output.then(result => expect(result).toBe(123)).then(done);
|
||||
});
|
||||
});
|
||||
|
||||
runner.run();
|
Loading…
Reference in New Issue
Block a user