Skip to content

Commit

Permalink
Inline requires: Flow-type plugin and tests
Browse files Browse the repository at this point in the history
Summary:
Ahead of making some changes/enhancements to `inline-requires-plugin`, make it type-safe.

Changelog: Internal

Reviewed By: vzaidman

Differential Revision: D61869704

fbshipit-source-id: 8d61d22fcffd66a28d4860dc596d4b22f685f977
  • Loading branch information
robhogan authored and facebook-github-bot committed Sep 3, 2024
1 parent cef7a3c commit 00df4ef
Show file tree
Hide file tree
Showing 4 changed files with 222 additions and 75 deletions.
37 changes: 37 additions & 0 deletions flow-typed/npm/babel-plugin-tester_v6.x.x.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @flow strict
* @format
*/

// Partial typings for babel-plugin-tester. Add APIs as you need them.

declare module 'babel-plugin-tester' {
import typeof * as Babel from '@babel/core';
import type {BabelCoreOptions, PluginObj} from '@babel/core';

declare type PluginTesterOptions<TOpts = mixed, TState = mixed> = {
babelOptions?: BabelCoreOptions,
plugin: (babel: Babel) => PluginObj<TState>,
pluginOptions?: TOpts,
tests: $ReadOnly<{
[title: string]: $ReadOnly<{
code: string,
output?: string,
error?: string,
snapshot?: boolean,
...
}>,
}>,
};

declare function pluginTester<TOpts = mixed, TState = mixed>(
opts: PluginTesterOptions<TOpts, TState>,
): void;

declare module.exports: typeof pluginTester;
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,20 @@
* LICENSE file in the root directory of this source tree.
*
* @format
* @flow strict-local
*/

/* eslint-disable max-len */

'use strict';

import type {PluginOptions, State} from '../inline-requires-plugin';

const inlineRequiresPlugin = require('../inline-requires-plugin');
const validateOutputAst = require('./validateOutputAst');
const babel = require('@babel/core');
const pluginTester = require('babel-plugin-tester');
const nullthrows = require('nullthrows');

pluginTester({
pluginTester<PluginOptions, State>({
babelOptions: {
babelrc: false,
configFile: false,
Expand Down Expand Up @@ -246,17 +248,25 @@ pluginTester({
});

describe('inline-requires', () => {
const transform = (source, options) =>
babel.transform(source.join('\n'), {
const transform = (
source: $ReadOnlyArray<string>,
options?: $ReadOnly<{...}>,
) =>
babel.transformSync(source.join('\n'), {
ast: true,
compact: true,
plugins: [
// $FlowFixMe[untyped-import] @babel/plugin-transform-modules-commonjs
[require('@babel/plugin-transform-modules-commonjs'), {strict: false}],
[inlineRequiresPlugin, options],
],
});

const compare = (input, output, options) => {
const compare = (
input: $ReadOnlyArray<string>,
output: $ReadOnlyArray<string>,
options?: $ReadOnly<{...}>,
) => {
expect(transform(input, options).code).toBe(
transform(output, options).code,
);
Expand Down Expand Up @@ -293,16 +303,19 @@ describe('inline-requires', () => {

it('should remove loc information from nodes', function () {
const ast = transform(['var x = require("x"); x']).ast;
const expression = ast.program.body[0].expression;
expect(ast).not.toBeNull();
const expression = nullthrows(ast).program.body[0].expression;

function expectNoLocation(node) {
function expectNodeWithNoLocation(maybeNode: ?BabelNode) {
expect(maybeNode).not.toBeNull();
const node = nullthrows(maybeNode);
expect(node.start).toBeUndefined();
expect(node.end).toBeUndefined();
expect(node.loc).toBeUndefined();
}

expectNoLocation(expression);
expectNoLocation(expression.arguments[0]);
expectNodeWithNoLocation(expression);
expectNodeWithNoLocation(nullthrows(expression?.arguments)[0]);
});

it('should not emit duplicate nodes', function () {
Expand All @@ -311,6 +324,6 @@ describe('inline-requires', () => {
'foo.bar()',
'foo.baz()',
]).ast;
validateOutputAst(ast);
validateOutputAst(nullthrows(ast));
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,24 @@
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @format
* @flow strict
*/

'use strict';

const t = require('@babel/types');

module.exports = function validateOutputAst(ast) {
const seenNodes = new Set();
module.exports = function validateOutputAst(ast: BabelNode) {
const seenNodes = new Set<BabelNode>();
t.traverseFast(ast, function enter(node) {
if (seenNodes.has(node)) {
throw new Error('Found a duplicate node in the output, which can cause'
+ ' undefined behavior in Babel.');
throw new Error(
'Found a duplicate node in the output, which can cause' +
' undefined behavior in Babel.',
);
}
seenNodes.add(node);
})
}
});
};
Loading

0 comments on commit 00df4ef

Please sign in to comment.