From b19555573f6ec233013e73111ffe3f05f44faa5e Mon Sep 17 00:00:00 2001 From: Lauren Tan Date: Mon, 3 Apr 2023 12:33:23 -0400 Subject: [PATCH] [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 // ... ``` --- compiler/forget/src/Babel/BabelPlugin.ts | 98 ++++++++++--------- compiler/forget/src/Babel/PluginOptions.ts | 30 ++++-- .../forget/src/__tests__/compiler-test.ts | 2 +- .../disableMemoizeJsxElements-test.ts | 2 +- .../arrow-function-expr-gating-test.expect.md | 8 +- .../arrow-function-expr-gating-test.js | 2 +- ...-expr-export-default-gating-test.expect.md | 2 +- ...i-arrow-expr-export-default-gating-test.js | 2 +- ...ing-test-export-default-function.expect.md | 8 +- .../gating-test-export-default-function.js | 2 +- ...test-export-function-and-default.expect.md | 8 +- ...gating-test-export-function-and-default.js | 2 +- .../gating-test-export-function.expect.md | 8 +- .../compiler/gating-test-export-function.js | 2 +- .../fixtures/compiler/gating-test.expect.md | 8 +- .../fixtures/compiler/gating-test.js | 2 +- ...ti-arrow-expr-export-gating-test.expect.md | 10 +- .../multi-arrow-expr-export-gating-test.js | 2 +- .../multi-arrow-expr-gating-test.expect.md | 12 ++- .../compiler/multi-arrow-expr-gating-test.js | 2 +- .../test-utils/generateTestsFromFixtures.ts | 25 +++-- 21 files changed, 137 insertions(+), 100 deletions(-) diff --git a/compiler/forget/src/Babel/BabelPlugin.ts b/compiler/forget/src/Babel/BabelPlugin.ts index 02145b931c..07b1d09456 100644 --- a/compiler/forget/src/Babel/BabelPlugin.ts +++ b/compiler/forget/src/Babel/BabelPlugin.ts @@ -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, - compiled: t.Identifier, - original: t.Identifier -): t.Node | t.Node[] { - const test = buildTest({ - uncompiled: uncompiled.node.id!, - compiled, - original, - }); +type GatingTestOptions = { + originalFnDecl: BabelCore.NodePath; + 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); +} diff --git a/compiler/forget/src/Babel/PluginOptions.ts b/compiler/forget/src/Babel/PluginOptions.ts index eaaf90015c..46ae8bf411 100644 --- a/compiler/forget/src/Babel/PluginOptions.ts +++ b/compiler/forget/src/Babel/PluginOptions.ts @@ -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 { diff --git a/compiler/forget/src/__tests__/compiler-test.ts b/compiler/forget/src/__tests__/compiler-test.ts index f259489f52..ee295d1598 100644 --- a/compiler/forget/src/__tests__/compiler-test.ts +++ b/compiler/forget/src/__tests__/compiler-test.ts @@ -56,7 +56,7 @@ describe("React Forget", () => { ]), }, logger: null, - gatingModule: options.gatingModule, + gating: options.gating, }).code, }); } catch (e) { diff --git a/compiler/forget/src/__tests__/disableMemoizeJsxElements-test.ts b/compiler/forget/src/__tests__/disableMemoizeJsxElements-test.ts index a0c36d19ae..5d2522dd15 100644 --- a/compiler/forget/src/__tests__/disableMemoizeJsxElements-test.ts +++ b/compiler/forget/src/__tests__/disableMemoizeJsxElements-test.ts @@ -52,7 +52,7 @@ describe("React Forget (Disable memoization of JSX elements)", () => { ]), }, logger: null, - gatingModule: options.gatingModule, + gating: options.gating, }).code, }); } catch (e) { diff --git a/compiler/forget/src/__tests__/fixtures/compiler/arrow-function-expr-gating-test.expect.md b/compiler/forget/src/__tests__/fixtures/compiler/arrow-function-expr-gating-test.expect.md index e99b6cfe5c..db8b34f1db 100644 --- a/compiler/forget/src/__tests__/fixtures/compiler/arrow-function-expr-gating-test.expect.md +++ b/compiler/forget/src/__tests__/fixtures/compiler/arrow-function-expr-gating-test.expect.md @@ -2,7 +2,7 @@ ## Input ```javascript -// @gatingModule +// @gating const ErrorView = (error, _retry) => ; 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 ; } @@ -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; diff --git a/compiler/forget/src/__tests__/fixtures/compiler/arrow-function-expr-gating-test.js b/compiler/forget/src/__tests__/fixtures/compiler/arrow-function-expr-gating-test.js index f58800ee36..3debc725be 100644 --- a/compiler/forget/src/__tests__/fixtures/compiler/arrow-function-expr-gating-test.js +++ b/compiler/forget/src/__tests__/fixtures/compiler/arrow-function-expr-gating-test.js @@ -1,4 +1,4 @@ -// @gatingModule +// @gating const ErrorView = (error, _retry) => ; export default ErrorView; diff --git a/compiler/forget/src/__tests__/fixtures/compiler/error._todo.multi-arrow-expr-export-default-gating-test.expect.md b/compiler/forget/src/__tests__/fixtures/compiler/error._todo.multi-arrow-expr-export-default-gating-test.expect.md index 597b7445eb..5f3096a7ab 100644 --- a/compiler/forget/src/__tests__/fixtures/compiler/error._todo.multi-arrow-expr-export-default-gating-test.expect.md +++ b/compiler/forget/src/__tests__/fixtures/compiler/error._todo.multi-arrow-expr-export-default-gating-test.expect.md @@ -2,7 +2,7 @@ ## Input ```javascript -// @gatingModule +// @gating const ErrorView = (error, _retry) => ; export default Renderer = (props) => ( diff --git a/compiler/forget/src/__tests__/fixtures/compiler/error._todo.multi-arrow-expr-export-default-gating-test.js b/compiler/forget/src/__tests__/fixtures/compiler/error._todo.multi-arrow-expr-export-default-gating-test.js index 3dc0baec95..6d20710d2b 100644 --- a/compiler/forget/src/__tests__/fixtures/compiler/error._todo.multi-arrow-expr-export-default-gating-test.js +++ b/compiler/forget/src/__tests__/fixtures/compiler/error._todo.multi-arrow-expr-export-default-gating-test.js @@ -1,4 +1,4 @@ -// @gatingModule +// @gating const ErrorView = (error, _retry) => ; export default Renderer = (props) => ( diff --git a/compiler/forget/src/__tests__/fixtures/compiler/gating-test-export-default-function.expect.md b/compiler/forget/src/__tests__/fixtures/compiler/gating-test-export-default-function.expect.md index 01bdb0e693..3d26ae50f6 100644 --- a/compiler/forget/src/__tests__/fixtures/compiler/gating-test-export-default-function.expect.md +++ b/compiler/forget/src/__tests__/fixtures/compiler/gating-test-export-default-function.expect.md @@ -2,7 +2,7 @@ ## Input ```javascript -// @gatingModule @forgetDirective +// @gating @forgetDirective export default function Bar(props) { "use forget"; return
{props.bar}
; @@ -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
{props.bar}
; @@ -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; ``` \ No newline at end of file diff --git a/compiler/forget/src/__tests__/fixtures/compiler/gating-test-export-default-function.js b/compiler/forget/src/__tests__/fixtures/compiler/gating-test-export-default-function.js index 0402b956f5..0189289a52 100644 --- a/compiler/forget/src/__tests__/fixtures/compiler/gating-test-export-default-function.js +++ b/compiler/forget/src/__tests__/fixtures/compiler/gating-test-export-default-function.js @@ -1,4 +1,4 @@ -// @gatingModule @forgetDirective +// @gating @forgetDirective export default function Bar(props) { "use forget"; return
{props.bar}
; diff --git a/compiler/forget/src/__tests__/fixtures/compiler/gating-test-export-function-and-default.expect.md b/compiler/forget/src/__tests__/fixtures/compiler/gating-test-export-function-and-default.expect.md index ff90b9a097..ec14689124 100644 --- a/compiler/forget/src/__tests__/fixtures/compiler/gating-test-export-function-and-default.expect.md +++ b/compiler/forget/src/__tests__/fixtures/compiler/gating-test-export-function-and-default.expect.md @@ -2,7 +2,7 @@ ## Input ```javascript -// @gatingModule @forgetDirective +// @gating @forgetDirective export default function Bar(props) { "use forget"; return
{props.bar}
; @@ -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
{props.bar}
; @@ -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; ``` \ No newline at end of file diff --git a/compiler/forget/src/__tests__/fixtures/compiler/gating-test-export-function-and-default.js b/compiler/forget/src/__tests__/fixtures/compiler/gating-test-export-function-and-default.js index 5d08dc830d..ecb8eec81c 100644 --- a/compiler/forget/src/__tests__/fixtures/compiler/gating-test-export-function-and-default.js +++ b/compiler/forget/src/__tests__/fixtures/compiler/gating-test-export-function-and-default.js @@ -1,4 +1,4 @@ -// @gatingModule @forgetDirective +// @gating @forgetDirective export default function Bar(props) { "use forget"; return
{props.bar}
; diff --git a/compiler/forget/src/__tests__/fixtures/compiler/gating-test-export-function.expect.md b/compiler/forget/src/__tests__/fixtures/compiler/gating-test-export-function.expect.md index f7a01ac2f7..b83122f382 100644 --- a/compiler/forget/src/__tests__/fixtures/compiler/gating-test-export-function.expect.md +++ b/compiler/forget/src/__tests__/fixtures/compiler/gating-test-export-function.expect.md @@ -2,7 +2,7 @@ ## Input ```javascript -// @gatingModule @forgetDirective +// @gating @forgetDirective export function Bar(props) { "use forget"; return
{props.bar}
; @@ -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
{props.bar}
; @@ -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 {props.noForget}; @@ -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; ``` \ No newline at end of file diff --git a/compiler/forget/src/__tests__/fixtures/compiler/gating-test-export-function.js b/compiler/forget/src/__tests__/fixtures/compiler/gating-test-export-function.js index 476f405558..01039a7f85 100644 --- a/compiler/forget/src/__tests__/fixtures/compiler/gating-test-export-function.js +++ b/compiler/forget/src/__tests__/fixtures/compiler/gating-test-export-function.js @@ -1,4 +1,4 @@ -// @gatingModule @forgetDirective +// @gating @forgetDirective export function Bar(props) { "use forget"; return
{props.bar}
; diff --git a/compiler/forget/src/__tests__/fixtures/compiler/gating-test.expect.md b/compiler/forget/src/__tests__/fixtures/compiler/gating-test.expect.md index 19af7f0224..e19ade1224 100644 --- a/compiler/forget/src/__tests__/fixtures/compiler/gating-test.expect.md +++ b/compiler/forget/src/__tests__/fixtures/compiler/gating-test.expect.md @@ -2,7 +2,7 @@ ## Input ```javascript -// @gatingModule @forgetDirective +// @gating @forgetDirective function Bar(props) { "use forget"; return
{props.bar}
; @@ -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
{props.bar}
; @@ -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 {props.noForget}; @@ -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; ``` \ No newline at end of file diff --git a/compiler/forget/src/__tests__/fixtures/compiler/gating-test.js b/compiler/forget/src/__tests__/fixtures/compiler/gating-test.js index b3505348c6..0270dffc5f 100644 --- a/compiler/forget/src/__tests__/fixtures/compiler/gating-test.js +++ b/compiler/forget/src/__tests__/fixtures/compiler/gating-test.js @@ -1,4 +1,4 @@ -// @gatingModule @forgetDirective +// @gating @forgetDirective function Bar(props) { "use forget"; return
{props.bar}
; diff --git a/compiler/forget/src/__tests__/fixtures/compiler/multi-arrow-expr-export-gating-test.expect.md b/compiler/forget/src/__tests__/fixtures/compiler/multi-arrow-expr-export-gating-test.expect.md index df0fdabf93..b8ce196950 100644 --- a/compiler/forget/src/__tests__/fixtures/compiler/multi-arrow-expr-export-gating-test.expect.md +++ b/compiler/forget/src/__tests__/fixtures/compiler/multi-arrow-expr-export-gating-test.expect.md @@ -2,7 +2,7 @@ ## Input ```javascript -// @gatingModule +// @gating const ErrorView = (error, _retry) => ; 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 ; } @@ -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 ( @@ -73,7 +75,7 @@ function Renderer_forget(props) { } return t2; } -export const Renderer = isForgetEnabled() +export const Renderer = isForgetEnabled_Fixtures() ? Renderer_forget : Renderer_uncompiled; diff --git a/compiler/forget/src/__tests__/fixtures/compiler/multi-arrow-expr-export-gating-test.js b/compiler/forget/src/__tests__/fixtures/compiler/multi-arrow-expr-export-gating-test.js index 6a983b22ad..8f7a29bc0d 100644 --- a/compiler/forget/src/__tests__/fixtures/compiler/multi-arrow-expr-export-gating-test.js +++ b/compiler/forget/src/__tests__/fixtures/compiler/multi-arrow-expr-export-gating-test.js @@ -1,4 +1,4 @@ -// @gatingModule +// @gating const ErrorView = (error, _retry) => ; export const Renderer = (props) => ( diff --git a/compiler/forget/src/__tests__/fixtures/compiler/multi-arrow-expr-gating-test.expect.md b/compiler/forget/src/__tests__/fixtures/compiler/multi-arrow-expr-gating-test.expect.md index b3439994c4..96fd2f8a77 100644 --- a/compiler/forget/src/__tests__/fixtures/compiler/multi-arrow-expr-gating-test.expect.md +++ b/compiler/forget/src/__tests__/fixtures/compiler/multi-arrow-expr-gating-test.expect.md @@ -2,7 +2,7 @@ ## Input ```javascript -// @gatingModule +// @gating const ErrorView = (error, _retry) => ; 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 ; } @@ -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 ( @@ -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; ``` diff --git a/compiler/forget/src/__tests__/fixtures/compiler/multi-arrow-expr-gating-test.js b/compiler/forget/src/__tests__/fixtures/compiler/multi-arrow-expr-gating-test.js index 1b99d393b3..d81a0dfdcd 100644 --- a/compiler/forget/src/__tests__/fixtures/compiler/multi-arrow-expr-gating-test.js +++ b/compiler/forget/src/__tests__/fixtures/compiler/multi-arrow-expr-gating-test.js @@ -1,4 +1,4 @@ -// @gatingModule +// @gating const ErrorView = (error, _retry) => ; const Renderer = (props) => ( diff --git a/compiler/forget/src/__tests__/test-utils/generateTestsFromFixtures.ts b/compiler/forget/src/__tests__/test-utils/generateTestsFromFixtures.ts index 3fa8d5ea3b..830f3a915e 100644 --- a/compiler/forget/src/__tests__/test-utils/generateTestsFromFixtures.ts +++ b/compiler/forget/src/__tests__/test-utils/generateTestsFromFixtures.ts @@ -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; @@ -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 {