mirror of
https://github.com/facebook/react.git
synced 2025-11-01 09:12:30 +00:00
[babel] Make gating option a pair of module and project
There are some internal restrictions in Metro that only allow us to specify one
gating module as an injected dependency. To allow multiple projects, this PR
updates the Babel plugin to take a gating options config specifiying a project
name. The project name is used as a suffix for the generated import; for
example:
```js
const options = {
// ...
gating: {
module: "ReactForgetFeatureFlag",
importSpecifierName: "isForgetEnabled_Secret",
};
// generates
import {isForgetEnabled_Secret} from "ReactForgetFeatureFlag"; // a module that
exports multiple flags
// ...
```
This commit is contained in:
@@ -12,14 +12,16 @@ import jsx from "@babel/plugin-syntax-jsx";
|
||||
import * as t from "@babel/types";
|
||||
import invariant from "invariant";
|
||||
import { compile } from "../CompilerPipeline";
|
||||
import { parsePluginOptions, PluginOptions } from "./PluginOptions";
|
||||
import {
|
||||
GatingOptions,
|
||||
parsePluginOptions,
|
||||
PluginOptions,
|
||||
} from "./PluginOptions";
|
||||
|
||||
type BabelPluginPass = {
|
||||
opts: PluginOptions;
|
||||
};
|
||||
|
||||
const testId = t.identifier("isForgetEnabled");
|
||||
|
||||
function hasUseForgetDirective(directives: t.Directive[]): boolean {
|
||||
for (const directive of directives) {
|
||||
if (directive.value.value === "use forget") {
|
||||
@@ -46,7 +48,7 @@ export default function ReactForgetBabelPlugin(
|
||||
hasForgetCompiledCode = true;
|
||||
const compiled = compile(fn, pass.opts.environment);
|
||||
|
||||
if (pass.opts.gatingModule) {
|
||||
if (pass.opts.gating != null) {
|
||||
// Rename existing function
|
||||
invariant(fn.node.id, "FunctionDeclaration must have a name");
|
||||
const original = fn.node.id;
|
||||
@@ -59,7 +61,14 @@ export default function ReactForgetBabelPlugin(
|
||||
compiledFn.skip();
|
||||
|
||||
// Build and append gating test
|
||||
compiledFn.insertAfter(buildGatingTest(fn, compiled.id, original));
|
||||
compiledFn.insertAfter(
|
||||
buildGatingTest({
|
||||
originalFnDecl: fn,
|
||||
compiledIdent: compiled.id,
|
||||
originalIdent: original,
|
||||
gating: pass.opts.gating,
|
||||
})
|
||||
);
|
||||
} else {
|
||||
fn.replaceWith(compiled);
|
||||
}
|
||||
@@ -108,10 +117,10 @@ export default function ReactForgetBabelPlugin(
|
||||
opts: { ...pass.opts, ...options },
|
||||
});
|
||||
|
||||
if (options.gatingModule && hasForgetCompiledCode) {
|
||||
if (options.gating != null && hasForgetCompiledCode) {
|
||||
path.unshiftContainer(
|
||||
"body",
|
||||
buildImportForGatingModule(options.gatingModule)
|
||||
buildImportForGatingModule(options.gating)
|
||||
);
|
||||
}
|
||||
} catch (err) {
|
||||
@@ -194,62 +203,63 @@ function buildBlockStatement(
|
||||
return body.node;
|
||||
}
|
||||
|
||||
function buildGatingTest(
|
||||
uncompiled: BabelCore.NodePath<t.FunctionDeclaration>,
|
||||
compiled: t.Identifier,
|
||||
original: t.Identifier
|
||||
): t.Node | t.Node[] {
|
||||
const test = buildTest({
|
||||
uncompiled: uncompiled.node.id!,
|
||||
compiled,
|
||||
original,
|
||||
});
|
||||
type GatingTestOptions = {
|
||||
originalFnDecl: BabelCore.NodePath<t.FunctionDeclaration>;
|
||||
compiledIdent: t.Identifier;
|
||||
originalIdent: t.Identifier;
|
||||
gating: GatingOptions;
|
||||
};
|
||||
function buildGatingTest({
|
||||
originalFnDecl,
|
||||
compiledIdent,
|
||||
originalIdent,
|
||||
gating,
|
||||
}: GatingTestOptions): t.Node | t.Node[] {
|
||||
const testVarDecl = t.variableDeclaration("const", [
|
||||
t.variableDeclarator(
|
||||
originalIdent,
|
||||
t.conditionalExpression(
|
||||
t.callExpression(buildSpecifierIdent(gating), []),
|
||||
compiledIdent,
|
||||
originalFnDecl.node.id!
|
||||
)
|
||||
),
|
||||
]);
|
||||
|
||||
// Re-export new declaration
|
||||
const parent = uncompiled.parentPath;
|
||||
const parent = originalFnDecl.parentPath;
|
||||
if (t.isExportDefaultDeclaration(parent)) {
|
||||
// Re-add uncompiled function
|
||||
parent.replaceWith(uncompiled)[0].skip();
|
||||
parent.replaceWith(originalFnDecl)[0].skip();
|
||||
|
||||
// Add test and synthesize new export
|
||||
return [test, t.exportDefaultDeclaration(original)];
|
||||
return [testVarDecl, t.exportDefaultDeclaration(originalIdent)];
|
||||
} else if (t.isExportNamedDeclaration(parent)) {
|
||||
// Re-add uncompiled function
|
||||
parent.replaceWith(uncompiled)[0].skip();
|
||||
parent.replaceWith(originalFnDecl)[0].skip();
|
||||
|
||||
// Add and export test
|
||||
return t.exportNamedDeclaration(test);
|
||||
return t.exportNamedDeclaration(testVarDecl);
|
||||
}
|
||||
|
||||
// Just add the test, no need for re-export
|
||||
return test;
|
||||
return testVarDecl;
|
||||
}
|
||||
|
||||
function addSuffix(id: t.Identifier, suffix: string): t.Identifier {
|
||||
return t.identifier(`${id.name}${suffix}`);
|
||||
}
|
||||
|
||||
function buildTest(ids: {
|
||||
uncompiled: t.Identifier;
|
||||
compiled: t.Identifier;
|
||||
original: t.Identifier;
|
||||
}): t.VariableDeclaration {
|
||||
return t.variableDeclaration("const", [
|
||||
t.variableDeclarator(
|
||||
ids.original,
|
||||
t.conditionalExpression(
|
||||
t.callExpression(testId, []),
|
||||
ids.compiled,
|
||||
ids.uncompiled
|
||||
)
|
||||
),
|
||||
]);
|
||||
}
|
||||
|
||||
function buildImportForGatingModule(gatingModule: string): t.ImportDeclaration {
|
||||
const importDefaultSpecifier = t.importDefaultSpecifier(testId);
|
||||
function buildImportForGatingModule(
|
||||
gating: GatingOptions
|
||||
): t.ImportDeclaration {
|
||||
const specifierIdent = buildSpecifierIdent(gating);
|
||||
return t.importDeclaration(
|
||||
[importDefaultSpecifier],
|
||||
t.stringLiteral(gatingModule)
|
||||
[t.importSpecifier(specifierIdent, specifierIdent)],
|
||||
t.stringLiteral(gating.source)
|
||||
);
|
||||
}
|
||||
|
||||
function buildSpecifierIdent(gating: GatingOptions): t.Identifier {
|
||||
return t.identifier(gating.importSpecifierName);
|
||||
}
|
||||
|
||||
@@ -7,6 +7,17 @@
|
||||
|
||||
import { EnvironmentConfig } from "../HIR/Environment";
|
||||
|
||||
export type GatingOptions = {
|
||||
/**
|
||||
* Source for the imported module that exports the `importSpecifierName` functions
|
||||
*/
|
||||
source: string;
|
||||
/**
|
||||
* Unique name for the feature flag test condition, eg `isForgetEnabled_ProjectName`
|
||||
*/
|
||||
importSpecifierName: string;
|
||||
};
|
||||
|
||||
export type PluginOptions = {
|
||||
/**
|
||||
* Enable to make Forget only compile functions containing the 'use forget' directive.
|
||||
@@ -18,23 +29,26 @@ export type PluginOptions = {
|
||||
logger: Logger | null;
|
||||
|
||||
/**
|
||||
* Specifying a `gatingModule`, makes Forget compile and emit a separate
|
||||
* version of the function gated by importing an `isForgetEnabled` from the
|
||||
* specified `gatingModule`.
|
||||
* Specifying a `gating` config, makes Forget compile and emit a separate
|
||||
* version of the function gated by importing the `gating.importSpecifierName` from the
|
||||
* specified `gating.source`.
|
||||
*
|
||||
* For example:
|
||||
* gatingModule: 'ReactForgetFeatureFlag'
|
||||
* gating: {
|
||||
* source: 'ReactForgetFeatureFlag',
|
||||
* importSpecifierName: 'isForgetEnabled_Pokes',
|
||||
* }
|
||||
*
|
||||
* produces:
|
||||
* import isForgetEnabled from ReactForgetFeatureFlag
|
||||
* import {isForgetEnabled_Pokes} from 'ReactForgetFeatureFlag';
|
||||
*
|
||||
* Foo_forget() {}
|
||||
*
|
||||
* Foo_uncompiled() {}
|
||||
*
|
||||
* var Foo = isForgetEnabled ? Foo_forget : Foo_uncompiled;
|
||||
* var Foo = isForgetEnabled_Pokes() ? Foo_forget : Foo_uncompiled;
|
||||
*/
|
||||
gatingModule: string | null;
|
||||
gating: GatingOptions | null;
|
||||
};
|
||||
|
||||
export type Logger = {
|
||||
@@ -45,7 +59,7 @@ export const defaultOptions: PluginOptions = {
|
||||
enableOnlyOnUseForgetDirective: false,
|
||||
environment: null,
|
||||
logger: null,
|
||||
gatingModule: null,
|
||||
gating: null,
|
||||
} as const;
|
||||
|
||||
export function parsePluginOptions(obj: unknown): PluginOptions {
|
||||
|
||||
@@ -56,7 +56,7 @@ describe("React Forget", () => {
|
||||
]),
|
||||
},
|
||||
logger: null,
|
||||
gatingModule: options.gatingModule,
|
||||
gating: options.gating,
|
||||
}).code,
|
||||
});
|
||||
} catch (e) {
|
||||
|
||||
@@ -52,7 +52,7 @@ describe("React Forget (Disable memoization of JSX elements)", () => {
|
||||
]),
|
||||
},
|
||||
logger: null,
|
||||
gatingModule: options.gatingModule,
|
||||
gating: options.gating,
|
||||
}).code,
|
||||
});
|
||||
} catch (e) {
|
||||
|
||||
+5
-3
@@ -2,7 +2,7 @@
|
||||
## Input
|
||||
|
||||
```javascript
|
||||
// @gatingModule
|
||||
// @gating
|
||||
const ErrorView = (error, _retry) => <MessageBox error={error}></MessageBox>;
|
||||
|
||||
export default ErrorView;
|
||||
@@ -12,7 +12,7 @@ export default ErrorView;
|
||||
## Code
|
||||
|
||||
```javascript
|
||||
import isForgetEnabled from "ReactForgetFeatureFlag"; // @gatingModule
|
||||
import { isForgetEnabled_Fixtures } from "ReactForgetFeatureFlag"; // @gating
|
||||
function ErrorView_uncompiled(error, _retry) {
|
||||
return <MessageBox error={error}></MessageBox>;
|
||||
}
|
||||
@@ -29,7 +29,9 @@ function ErrorView_forget(error, _retry) {
|
||||
}
|
||||
return t0;
|
||||
}
|
||||
const ErrorView = isForgetEnabled() ? ErrorView_forget : ErrorView_uncompiled;
|
||||
const ErrorView = isForgetEnabled_Fixtures()
|
||||
? ErrorView_forget
|
||||
: ErrorView_uncompiled;
|
||||
|
||||
export default ErrorView;
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// @gatingModule
|
||||
// @gating
|
||||
const ErrorView = (error, _retry) => <MessageBox error={error}></MessageBox>;
|
||||
|
||||
export default ErrorView;
|
||||
|
||||
+1
-1
@@ -2,7 +2,7 @@
|
||||
## Input
|
||||
|
||||
```javascript
|
||||
// @gatingModule
|
||||
// @gating
|
||||
const ErrorView = (error, _retry) => <MessageBox error={error}></MessageBox>;
|
||||
|
||||
export default Renderer = (props) => (
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
// @gatingModule
|
||||
// @gating
|
||||
const ErrorView = (error, _retry) => <MessageBox error={error}></MessageBox>;
|
||||
|
||||
export default Renderer = (props) => (
|
||||
|
||||
+4
-4
@@ -2,7 +2,7 @@
|
||||
## Input
|
||||
|
||||
```javascript
|
||||
// @gatingModule @forgetDirective
|
||||
// @gating @forgetDirective
|
||||
export default function Bar(props) {
|
||||
"use forget";
|
||||
return <div>{props.bar}</div>;
|
||||
@@ -22,7 +22,7 @@ function Foo(props) {
|
||||
## Code
|
||||
|
||||
```javascript
|
||||
import isForgetEnabled from "ReactForgetFeatureFlag"; // @gatingModule @forgetDirective
|
||||
import { isForgetEnabled_Fixtures } from "ReactForgetFeatureFlag"; // @gating @forgetDirective
|
||||
function Bar_uncompiled(props) {
|
||||
"use forget";
|
||||
return <div>{props.bar}</div>;
|
||||
@@ -40,7 +40,7 @@ function Bar_forget(props) {
|
||||
}
|
||||
return t0;
|
||||
}
|
||||
const Bar = isForgetEnabled() ? Bar_forget : Bar_uncompiled;
|
||||
const Bar = isForgetEnabled_Fixtures() ? Bar_forget : Bar_uncompiled;
|
||||
export default Bar;
|
||||
|
||||
function NoForget(props) {
|
||||
@@ -64,7 +64,7 @@ function Foo_forget(props) {
|
||||
}
|
||||
return t0;
|
||||
}
|
||||
const Foo = isForgetEnabled() ? Foo_forget : Foo_uncompiled;
|
||||
const Foo = isForgetEnabled_Fixtures() ? Foo_forget : Foo_uncompiled;
|
||||
|
||||
```
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
// @gatingModule @forgetDirective
|
||||
// @gating @forgetDirective
|
||||
export default function Bar(props) {
|
||||
"use forget";
|
||||
return <div>{props.bar}</div>;
|
||||
|
||||
+4
-4
@@ -2,7 +2,7 @@
|
||||
## Input
|
||||
|
||||
```javascript
|
||||
// @gatingModule @forgetDirective
|
||||
// @gating @forgetDirective
|
||||
export default function Bar(props) {
|
||||
"use forget";
|
||||
return <div>{props.bar}</div>;
|
||||
@@ -22,7 +22,7 @@ export function Foo(props) {
|
||||
## Code
|
||||
|
||||
```javascript
|
||||
import isForgetEnabled from "ReactForgetFeatureFlag"; // @gatingModule @forgetDirective
|
||||
import { isForgetEnabled_Fixtures } from "ReactForgetFeatureFlag"; // @gating @forgetDirective
|
||||
function Bar_uncompiled(props) {
|
||||
"use forget";
|
||||
return <div>{props.bar}</div>;
|
||||
@@ -40,7 +40,7 @@ function Bar_forget(props) {
|
||||
}
|
||||
return t0;
|
||||
}
|
||||
const Bar = isForgetEnabled() ? Bar_forget : Bar_uncompiled;
|
||||
const Bar = isForgetEnabled_Fixtures() ? Bar_forget : Bar_uncompiled;
|
||||
export default Bar;
|
||||
|
||||
function NoForget(props) {
|
||||
@@ -64,7 +64,7 @@ function Foo_forget(props) {
|
||||
}
|
||||
return t0;
|
||||
}
|
||||
export const Foo = isForgetEnabled() ? Foo_forget : Foo_uncompiled;
|
||||
export const Foo = isForgetEnabled_Fixtures() ? Foo_forget : Foo_uncompiled;
|
||||
|
||||
```
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
// @gatingModule @forgetDirective
|
||||
// @gating @forgetDirective
|
||||
export default function Bar(props) {
|
||||
"use forget";
|
||||
return <div>{props.bar}</div>;
|
||||
|
||||
+4
-4
@@ -2,7 +2,7 @@
|
||||
## Input
|
||||
|
||||
```javascript
|
||||
// @gatingModule @forgetDirective
|
||||
// @gating @forgetDirective
|
||||
export function Bar(props) {
|
||||
"use forget";
|
||||
return <div>{props.bar}</div>;
|
||||
@@ -22,7 +22,7 @@ export function Foo(props) {
|
||||
## Code
|
||||
|
||||
```javascript
|
||||
import isForgetEnabled from "ReactForgetFeatureFlag"; // @gatingModule @forgetDirective
|
||||
import { isForgetEnabled_Fixtures } from "ReactForgetFeatureFlag"; // @gating @forgetDirective
|
||||
function Bar_uncompiled(props) {
|
||||
"use forget";
|
||||
return <div>{props.bar}</div>;
|
||||
@@ -40,7 +40,7 @@ function Bar_forget(props) {
|
||||
}
|
||||
return t0;
|
||||
}
|
||||
export const Bar = isForgetEnabled() ? Bar_forget : Bar_uncompiled;
|
||||
export const Bar = isForgetEnabled_Fixtures() ? Bar_forget : Bar_uncompiled;
|
||||
|
||||
export function NoForget(props) {
|
||||
return <Bar>{props.noForget}</Bar>;
|
||||
@@ -63,7 +63,7 @@ function Foo_forget(props) {
|
||||
}
|
||||
return t0;
|
||||
}
|
||||
export const Foo = isForgetEnabled() ? Foo_forget : Foo_uncompiled;
|
||||
export const Foo = isForgetEnabled_Fixtures() ? Foo_forget : Foo_uncompiled;
|
||||
|
||||
```
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// @gatingModule @forgetDirective
|
||||
// @gating @forgetDirective
|
||||
export function Bar(props) {
|
||||
"use forget";
|
||||
return <div>{props.bar}</div>;
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
## Input
|
||||
|
||||
```javascript
|
||||
// @gatingModule @forgetDirective
|
||||
// @gating @forgetDirective
|
||||
function Bar(props) {
|
||||
"use forget";
|
||||
return <div>{props.bar}</div>;
|
||||
@@ -22,7 +22,7 @@ function Foo(props) {
|
||||
## Code
|
||||
|
||||
```javascript
|
||||
import isForgetEnabled from "ReactForgetFeatureFlag"; // @gatingModule @forgetDirective
|
||||
import { isForgetEnabled_Fixtures } from "ReactForgetFeatureFlag"; // @gating @forgetDirective
|
||||
function Bar_uncompiled(props) {
|
||||
"use forget";
|
||||
return <div>{props.bar}</div>;
|
||||
@@ -40,7 +40,7 @@ function Bar_forget(props) {
|
||||
}
|
||||
return t0;
|
||||
}
|
||||
const Bar = isForgetEnabled() ? Bar_forget : Bar_uncompiled;
|
||||
const Bar = isForgetEnabled_Fixtures() ? Bar_forget : Bar_uncompiled;
|
||||
|
||||
function NoForget(props) {
|
||||
return <Bar>{props.noForget}</Bar>;
|
||||
@@ -63,7 +63,7 @@ function Foo_forget(props) {
|
||||
}
|
||||
return t0;
|
||||
}
|
||||
const Foo = isForgetEnabled() ? Foo_forget : Foo_uncompiled;
|
||||
const Foo = isForgetEnabled_Fixtures() ? Foo_forget : Foo_uncompiled;
|
||||
|
||||
```
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// @gatingModule @forgetDirective
|
||||
// @gating @forgetDirective
|
||||
function Bar(props) {
|
||||
"use forget";
|
||||
return <div>{props.bar}</div>;
|
||||
|
||||
+6
-4
@@ -2,7 +2,7 @@
|
||||
## Input
|
||||
|
||||
```javascript
|
||||
// @gatingModule
|
||||
// @gating
|
||||
const ErrorView = (error, _retry) => <MessageBox error={error}></MessageBox>;
|
||||
|
||||
export const Renderer = (props) => (
|
||||
@@ -17,7 +17,7 @@ export const Renderer = (props) => (
|
||||
## Code
|
||||
|
||||
```javascript
|
||||
import isForgetEnabled from "ReactForgetFeatureFlag"; // @gatingModule
|
||||
import { isForgetEnabled_Fixtures } from "ReactForgetFeatureFlag"; // @gating
|
||||
function ErrorView_uncompiled(error, _retry) {
|
||||
return <MessageBox error={error}></MessageBox>;
|
||||
}
|
||||
@@ -34,7 +34,9 @@ function ErrorView_forget(error, _retry) {
|
||||
}
|
||||
return t0;
|
||||
}
|
||||
const ErrorView = isForgetEnabled() ? ErrorView_forget : ErrorView_uncompiled;
|
||||
const ErrorView = isForgetEnabled_Fixtures()
|
||||
? ErrorView_forget
|
||||
: ErrorView_uncompiled;
|
||||
function Renderer_uncompiled(props) {
|
||||
return (
|
||||
<Foo>
|
||||
@@ -73,7 +75,7 @@ function Renderer_forget(props) {
|
||||
}
|
||||
return t2;
|
||||
}
|
||||
export const Renderer = isForgetEnabled()
|
||||
export const Renderer = isForgetEnabled_Fixtures()
|
||||
? Renderer_forget
|
||||
: Renderer_uncompiled;
|
||||
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
// @gatingModule
|
||||
// @gating
|
||||
const ErrorView = (error, _retry) => <MessageBox error={error}></MessageBox>;
|
||||
|
||||
export const Renderer = (props) => (
|
||||
|
||||
+8
-4
@@ -2,7 +2,7 @@
|
||||
## Input
|
||||
|
||||
```javascript
|
||||
// @gatingModule
|
||||
// @gating
|
||||
const ErrorView = (error, _retry) => <MessageBox error={error}></MessageBox>;
|
||||
|
||||
const Renderer = (props) => (
|
||||
@@ -19,7 +19,7 @@ export default Renderer;
|
||||
## Code
|
||||
|
||||
```javascript
|
||||
import isForgetEnabled from "ReactForgetFeatureFlag"; // @gatingModule
|
||||
import { isForgetEnabled_Fixtures } from "ReactForgetFeatureFlag"; // @gating
|
||||
function ErrorView_uncompiled(error, _retry) {
|
||||
return <MessageBox error={error}></MessageBox>;
|
||||
}
|
||||
@@ -36,7 +36,9 @@ function ErrorView_forget(error, _retry) {
|
||||
}
|
||||
return t0;
|
||||
}
|
||||
const ErrorView = isForgetEnabled() ? ErrorView_forget : ErrorView_uncompiled;
|
||||
const ErrorView = isForgetEnabled_Fixtures()
|
||||
? ErrorView_forget
|
||||
: ErrorView_uncompiled;
|
||||
function Renderer_uncompiled(props) {
|
||||
return (
|
||||
<Foo>
|
||||
@@ -75,7 +77,9 @@ function Renderer_forget(props) {
|
||||
}
|
||||
return t2;
|
||||
}
|
||||
const Renderer = isForgetEnabled() ? Renderer_forget : Renderer_uncompiled;
|
||||
const Renderer = isForgetEnabled_Fixtures()
|
||||
? Renderer_forget
|
||||
: Renderer_uncompiled;
|
||||
export default Renderer;
|
||||
|
||||
```
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// @gatingModule
|
||||
// @gating
|
||||
const ErrorView = (error, _retry) => <MessageBox error={error}></MessageBox>;
|
||||
|
||||
const Renderer = (props) => (
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
|
||||
import fs from "fs";
|
||||
import path from "path";
|
||||
import { GatingOptions, PluginOptions } from "../../Babel/PluginOptions";
|
||||
|
||||
const EXPECT_SUFFIX = ".expect.md";
|
||||
|
||||
@@ -40,17 +41,16 @@ expect.extend({
|
||||
},
|
||||
});
|
||||
|
||||
type FixtureTestOptions = {
|
||||
debug: boolean;
|
||||
language: "flow" | "typescript";
|
||||
};
|
||||
export default function generateTestsFromFixtures(
|
||||
fixturesPath: string,
|
||||
transform: (
|
||||
input: string,
|
||||
file: any,
|
||||
options: {
|
||||
debug: boolean;
|
||||
enableOnlyOnUseForgetDirective: boolean;
|
||||
gatingModule: string | null;
|
||||
language: "flow" | "typescript";
|
||||
}
|
||||
options: FixtureTestOptions & PluginOptions
|
||||
) => string
|
||||
) {
|
||||
let files: Array<string>;
|
||||
@@ -90,7 +90,7 @@ export default function generateTestsFromFixtures(
|
||||
let input: string | null = null;
|
||||
let debug = false;
|
||||
let enableOnlyOnUseForgetDirective = false;
|
||||
let gatingModule: string | null = null;
|
||||
let gating: GatingOptions | null = null;
|
||||
|
||||
if (inputFile != null) {
|
||||
input = fs.readFileSync(inputFile, "utf8");
|
||||
@@ -105,8 +105,11 @@ export default function generateTestsFromFixtures(
|
||||
if (lines[0]!.indexOf("@forgetDirective") !== -1) {
|
||||
enableOnlyOnUseForgetDirective = true;
|
||||
}
|
||||
if (lines[0]!.indexOf("@gatingModule") !== -1) {
|
||||
gatingModule = "ReactForgetFeatureFlag";
|
||||
if (lines[0]!.indexOf("@gating") !== -1) {
|
||||
gating = {
|
||||
source: "ReactForgetFeatureFlag",
|
||||
importSpecifierName: "isForgetEnabled_Fixtures",
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -114,9 +117,11 @@ export default function generateTestsFromFixtures(
|
||||
let receivedOutput;
|
||||
if (input !== null) {
|
||||
receivedOutput = transform(input, basename, {
|
||||
environment: null,
|
||||
logger: null,
|
||||
debug,
|
||||
enableOnlyOnUseForgetDirective,
|
||||
gatingModule,
|
||||
gating,
|
||||
language: parseLanguage(input),
|
||||
});
|
||||
} else {
|
||||
|
||||
Reference in New Issue
Block a user