Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow testing logs with @babel/helper-transform-fixture-test-runner #10326

Merged
merged 6 commits into from Aug 14, 2019
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
15 changes: 15 additions & 0 deletions packages/babel-helper-fixtures/src/index.js
Expand Up @@ -120,6 +120,8 @@ export default function get(entryLoc): Array<Suite> {
const expectLoc =
findFile(taskDir + "/output", true /* allowJSON */) ||
taskDir + "/output.js";
const stdoutLoc = taskDir + "/stdout.txt";
const stderrLoc = taskDir + "/stderr.txt";

const actualLocAlias =
suiteName + "/" + taskName + "/" + path.basename(actualLoc);
Expand All @@ -146,6 +148,9 @@ export default function get(entryLoc): Array<Suite> {
title: humanize(taskName, true),
disabled: taskName[0] === ".",
options: taskOpts,
validateLogs: taskOpts.validateLogs,
stdout: { loc: stdoutLoc, code: readFile(stdoutLoc) },
stderr: { loc: stderrLoc, code: readFile(stderrLoc) },
exec: {
loc: execLoc,
code: readFile(execLoc),
Expand Down Expand Up @@ -222,6 +227,16 @@ export default function get(entryLoc): Array<Suite> {
);
}
}

if (!test.validateLogs && (test.stdout.code || test.stderr.code)) {
throw new Error(
"stdout.txt and stderr.txt are only allowed when the 'validateLogs' option is enabled: " +
(test.stdout.code ? stdoutLoc : stderrLoc),
);
}

// Delete to avoid option validation error
delete test.options.validateLogs;
}
}

Expand Down
83 changes: 55 additions & 28 deletions packages/babel-helper-transform-fixture-test-runner/src/index.js
Expand Up @@ -131,11 +131,16 @@ function wrapPackagesArray(type, names, optionsDir) {
}

function run(task) {
const actual = task.actual;
const expected = task.expect;
const exec = task.exec;
const opts = task.options;
const optionsDir = task.optionsDir;
const {
actual,
expect: expected,
exec,
options: opts,
optionsDir,
validateLogs,
stdout,
stderr,
} = task;

function getOpts(self) {
const newOpts = merge(
Expand Down Expand Up @@ -191,19 +196,27 @@ function run(task) {
}
}

let actualCode = actual.code;
const expectCode = expected.code;
if (!execCode || actualCode) {
result = babel.transform(actualCode, getOpts(actual));
const expectedCode = result.code.replace(
escapeRegExp(path.resolve(__dirname, "../../../")),
"<CWD>",
);
const inputCode = actual.code;
const expectedCode = expected.code;
if (!execCode || inputCode) {
const actualLogs = { stdout: "", stderr: "" };
if (validateLogs) {
jest.spyOn(console, "log").mockImplementation(msg => {
actualLogs.stdout += `${msg}\n`;
});
jest.spyOn(console, "warn").mockImplementation(msg => {
actualLogs.stderr += `${msg}\n`;
});
}

result = babel.transform(inputCode, getOpts(actual));

const outputCode = normalizeOutput(result.code);

checkDuplicatedNodes(babel, result.ast);
if (
!expected.code &&
expectedCode &&
outputCode &&
!opts.throws &&
fs.statSync(path.dirname(expected.loc)).isDirectory() &&
!process.env.CI
Expand All @@ -214,33 +227,27 @@ function run(task) {
);

console.log(`New test file created: ${expectedFile}`);
fs.writeFileSync(expectedFile, `${expectedCode}\n`);
fs.writeFileSync(expectedFile, `${outputCode}\n`);

if (expected.loc !== expectedFile) {
try {
fs.unlinkSync(expected.loc);
} catch (e) {}
}
} else {
actualCode = expectedCode.trim();
try {
expect(actualCode).toEqualFile({
filename: expected.loc,
code: expectCode,
});
} catch (e) {
if (!process.env.OVERWRITE) throw e;
validateFile(outputCode, expected.loc, expectedCode);

console.log(`Updated test file: ${expected.loc}`);
fs.writeFileSync(expected.loc, `${expectedCode}\n`);
}

if (actualCode) {
if (inputCode) {
expect(expected.loc).toMatch(
result.sourceType === "module" ? /\.mjs$/ : /\.js$/,
);
}
}

if (validateLogs) {
validateFile(normalizeOutput(actualLogs.stdout), stdout.loc, stdout.code);
validateFile(normalizeOutput(actualLogs.stderr), stderr.loc, stderr.code);
}
}

if (task.sourceMap) {
Expand All @@ -263,6 +270,26 @@ function run(task) {
}
}

function validateFile(actualCode, expectedLoc, expectedCode) {
try {
expect(actualCode).toEqualFile({
filename: expectedLoc,
code: expectedCode,
});
} catch (e) {
if (!process.env.OVERWRITE) throw e;

console.log(`Updated test file: ${expectedLoc}`);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we don't restore the console.log mock, would this line go to the actualLogs?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's right

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think this is expected. Updated test file: foo.js is used to remind the developer and therefore should always print to stdout, regardless of validateLogs.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I meant: "You are right, I will fix it" 😅

fs.writeFileSync(expectedLoc, `${actualCode}\n`);
}
}

function normalizeOutput(code) {
return code
.trim()
.replace(escapeRegExp(path.resolve(__dirname, "../../../")), "<CWD>");
}

const toEqualFile = () => ({
compare: (actual, { filename, code }) => {
const pass = actual === code;
Expand Down
@@ -1,4 +1,5 @@
{
"validateLogs": true,
"plugins": [
"syntax-dynamic-import",
"transform-modules-systemjs",
Expand Down
@@ -0,0 +1,3 @@
WARNING: Dynamic import() transformation must be enabled using the
@babel/plugin-proposal-dynamic-import plugin. Babel 8 will
no longer transform import() without using that plugin.
@@ -1,4 +1,5 @@
{
"validateLogs": true,
"presets": [
[
"../../../../lib",
Expand Down
@@ -0,0 +1,33 @@
@babel/preset-env: `DEBUG` option

Using targets:
{
"chrome": "61",
"edge": "16",
"firefox": "60",
"ios": "10.3",
"opera": "48",
"safari": "10.1"
}

Using modules transform: false

Using plugins:
transform-template-literals { "ios":"10.3", "safari":"10.1" }
transform-function-name { "edge":"16" }
transform-dotall-regex { "chrome":"61", "edge":"16", "firefox":"60", "ios":"10.3", "opera":"48", "safari":"10.1" }
transform-unicode-regex { "ios":"10.3", "safari":"10.1" }
transform-parameters { "edge":"16" }
transform-block-scoping { "ios":"10.3", "safari":"10.1" }
transform-async-to-generator { "ios":"10.3", "safari":"10.1" }
proposal-async-generator-functions { "chrome":"61", "edge":"16", "ios":"10.3", "opera":"48", "safari":"10.1" }
proposal-object-rest-spread { "edge":"16", "ios":"10.3", "safari":"10.1" }
proposal-unicode-property-regex { "chrome":"61", "edge":"16", "firefox":"60", "ios":"10.3", "opera":"48", "safari":"10.1" }
proposal-json-strings { "chrome":"61", "edge":"16", "firefox":"60", "ios":"10.3", "opera":"48", "safari":"10.1" }
proposal-optional-catch-binding { "chrome":"61", "edge":"16", "ios":"10.3", "opera":"48", "safari":"10.1" }
transform-named-capturing-groups-regex { "chrome":"61", "edge":"16", "firefox":"60", "ios":"10.3", "opera":"48", "safari":"10.1" }

Using polyfills with `usage` option:

[<CWD>/packages/babel-preset-env/test/fixtures/corejs2/usage-browserslist-config-ignore/input.mjs] Added following core-js polyfill:
web.dom.iterable { "chrome":"61", "edge":"16", "firefox":"60", "ios":"10.3", "opera":"48", "safari":"10.1" }
@@ -1,4 +1,5 @@
{
"validateLogs": true,
"presets": [
[
"../../../../lib",
Expand Down
@@ -0,0 +1,34 @@
@babel/preset-env: `DEBUG` option

Using targets:
{
"chrome": "61",
"edge": "16",
"firefox": "60",
"ios": "10.3",
"opera": "48",
"safari": "10.1"
}

Using modules transform: false

Using plugins:
transform-template-literals { "ios":"10.3", "safari":"10.1" }
transform-function-name { "edge":"16" }
transform-dotall-regex { "chrome":"61", "edge":"16", "firefox":"60", "ios":"10.3", "opera":"48", "safari":"10.1" }
transform-unicode-regex { "ios":"10.3", "safari":"10.1" }
transform-parameters { "edge":"16" }
transform-block-scoping { "ios":"10.3", "safari":"10.1" }
transform-async-to-generator { "ios":"10.3", "safari":"10.1" }
proposal-async-generator-functions { "chrome":"61", "edge":"16", "ios":"10.3", "opera":"48", "safari":"10.1" }
proposal-object-rest-spread { "edge":"16", "ios":"10.3", "safari":"10.1" }
proposal-unicode-property-regex { "chrome":"61", "edge":"16", "firefox":"60", "ios":"10.3", "opera":"48", "safari":"10.1" }
proposal-json-strings { "chrome":"61", "edge":"16", "firefox":"60", "ios":"10.3", "opera":"48", "safari":"10.1" }
proposal-optional-catch-binding { "chrome":"61", "edge":"16", "ios":"10.3", "opera":"48", "safari":"10.1" }
transform-named-capturing-groups-regex { "chrome":"61", "edge":"16", "firefox":"60", "ios":"10.3", "opera":"48", "safari":"10.1" }

Using polyfills with `usage` option:

[<CWD>/packages/babel-preset-env/test/fixtures/corejs3/usage-browserslist-config-ignore/input.mjs] Added following core-js polyfills:
es.array.iterator { "chrome":"61", "opera":"48" }
web.dom-collections.iterator { "chrome":"61", "edge":"16", "ios":"10.3", "opera":"48", "safari":"10.1" }
@@ -1,4 +1,5 @@
{
"validateLogs": true,
"caller": {
"name": "test-fixture",
"supportsStaticESM": true,
Expand Down
@@ -1,4 +1,5 @@
{
"validateLogs": true,
"caller": {
"name": "test-fixture",
"supportsStaticESM": true,
Expand Down
@@ -0,0 +1 @@
Dynamic import can only be supported when transforming ES modules to AMD, CommonJS or SystemJS. Only the parser plugin will be enabled.
@@ -1,4 +1,5 @@
{
"validateLogs": true,
"caller": {
"name": "test-fixture",
"supportsStaticESM": false,
Expand Down
@@ -1,3 +1,4 @@
{
"validateLogs": true,
"presets": [["env", { "modules": "amd" }]]
}
@@ -1,3 +1,4 @@
{
"validateLogs": true,
"presets": [["env", { "modules": "cjs" }]]
}
@@ -1,3 +1,4 @@
{
"validateLogs": true,
"presets": [["env", { "modules": false }]]
}
@@ -1,3 +1,4 @@
{
"validateLogs": true,
"presets": [["env", { "modules": "systemjs" }]]
}
@@ -1,3 +1,4 @@
{
"validateLogs": true,
"presets": [["env", { "modules": "umd" }]]
}
@@ -0,0 +1 @@
Dynamic import can only be supported when transforming ES modules to AMD, CommonJS or SystemJS. Only the parser plugin will be enabled.
@@ -1,4 +1,5 @@
{
"validateLogs": true,
"presets": [
[
"../../../../lib",
Expand Down
@@ -0,0 +1,24 @@
@babel/preset-env: `DEBUG` option

Using targets:
{
"safari": "10"
}

Using modules transform: auto

Using plugins:
transform-template-literals { "safari":"10" }
transform-dotall-regex { "safari":"10" }
transform-unicode-regex { "safari":"10" }
transform-block-scoping { "safari":"10" }
transform-exponentiation-operator { "safari":"10" }
transform-async-to-generator { "safari":"10" }
proposal-async-generator-functions { "safari":"10" }
proposal-object-rest-spread { "safari":"10" }
proposal-unicode-property-regex { "safari":"10" }
proposal-json-strings { "safari":"10" }
proposal-optional-catch-binding { "safari":"10" }
transform-named-capturing-groups-regex { "safari":"10" }

Using polyfills: No polyfills were added, since the `useBuiltIns` option was not set.