Commit Graph
19463 Commits
Author SHA1 Message Date
Lauren Tan 3a9be52f51 Update test262 2023-08-22 15:07:46 -04:00
lauren a0dc166991 [rfc] Remove top level forget directory
Sorry about the thrash in advance! This removes the top level `forget` directory 
which adds unnecessary nesting to our repo 

Hopefully everything still works
2023-08-22 15:04:54 -04:00
Josh Story 86198b9231 [Float][Fizz][Legacy] hoisted elements no longer emit before <html> in legacy apis such as renderToString() (#27269)
renderToString is a legacy server API which used a trick to avoid having
the DOCTYPE included when rendering full documents by setting the root
formatcontext to HTML_MODE rather than ROOT_HTML_MODE. Previously this
was of little consequence but with Float the Root mode started to be
used for things like determining if we could flush hoistable elements
yet. In issue #27177 we see that hoisted elements can appear before the
<html> tag when using a legacy API `renderToString`.

This change exports a DOCTYPE from FizzConfigDOM and FizzConfigDOMLegacy
respectively, using an empty chunk in the legacy case. The only runtime
perf cost here is that for legacy APIs there is an extra empty chunk to
write when rendering a top level <html> tag which is trivial enough

Fixes #27177
2023-08-22 10:54:33 -07:00
Andrew Clark dd480ef923 Fix: Stylesheet in error UI suspends indefinitely (#27265)
This fixes the regression test added in the previous commit. The
"Suspensey commit" implementation relies on the
`shouldRemainOnPreviousScreen` function to determine whether to 1)
suspend the commit 2) activate a parent fallback and schedule a retry.
The issue was that we were sometimes attempting option 2 even when there
was no parent fallback.

Part of the reason this bug landed is due to how `throwException` is
structured. In the case of Suspensey commits, we pass a special "noop"
thenable to `throwException` as a way to trigger the Suspense path. This
special thenable must never have a listener attached to it. This is not
a great way to structure the logic, it's just a consequence of how the
code evolved over time. We should refactor it into multiple functions so
we can trigger a fallback directly without having to check the type. In
the meantime, I added an internal warning to help detect similar
mistakes in the future.
2023-08-22 11:22:30 -04:00
Jan Kassens e76a5aca78 [easy] remove unused file MaxInts.js (#27259)
While poking around, I noticed this wasn't used.
2023-08-22 10:42:27 -04:00
Jan Kassens 29556a6b0a Flow: upgrade to 0.215.0 (#27264)
Simple bump of Flow and Hermes parser to keep us current.
2023-08-22 10:41:04 -04:00
Jan Kassens 3f5b8c214f Jest: remove haste config (#27257)
Since we're not using haste at all, we can just remove the config to
disable haste instead of enabling, just to inject an implementation that
blocks any haste modules from being recognized.

Test Plan:
Creating a module and required it to get the expected error that the
module doesn't exist.
2023-08-22 10:12:28 -04:00
Joe Savona a13df48d4e [rust] Serialize range as array
ESTree expects the `range` value to be an array of `[start, end]`, we support 
deserializing from that format but serialized as an object of `{start,end}`, now 
we serialize to the array form.
2023-08-21 21:55:08 -07:00
Andrew Clark 7d1c3c1589 Regression test: Stylesheet suspends indefinitely when part of error boundary UI during initial hydration (#27258)
Adds a failing test for a case discovered by Next.js. An error boundary
is triggered during initial hydration, and the error fallback includes a
stylesheet. If the stylesheet has not yet been loaded, the commit
suspends, but never resolves even after the stylesheet finishes loading.

Triggering this bug depends on several very specific code paths being
triggered simultaneously. There are a few ways we could fix the bug;
I'll submit as one or more separate PRs to show that each one is
sufficient.
2023-08-21 19:14:56 -04:00
Joe Savona 9c13e4413c [rust] Expose parse function to napi
Updates the `forget_napi` crate to call the parser and semantic analyzer and 
convert their values to JS.
2023-08-21 16:04:03 -07:00
Joe Savona 7fc7488ac8 [rust] Scaffolding for napi-backed npm package
Scaffolds out a `forget_napi` crate following the guide for https://napi.rs/. 
This crate will be the public JS api for interacting with Forget.
2023-08-21 14:51:10 -07:00
Mofei Zhang 1c56843518 [tests] Allow .ts, .tsx fixture files 2023-08-22 12:54:01 -04:00
Jan Kassens b277259232 [flow] upgrade to 0.214.0 (#27187)
Simple upgrade without any code changes required.

Changelog: https://github.com/facebook/flow/blob/main/Changelog.md
2023-08-21 11:23:47 -04:00
Lauren Tan 6be03b681e [ci] Split out babel-plugin-react-forget jest to its own job 2023-08-18 17:06:52 -04:00
Lauren Tan e426cb553d [ci] Split out babel-plugin-react-forget prettier/eslint to its own job 2023-08-18 15:22:09 -04:00
Joe Savona bcd692fca4 Promote enableOptimizeFunctionExpressions to default/only option
We’ve had this feature turned on internally for a while with only a couple minor 
bugs and no fundamental issues. It’s a necessary change for simplifying function 
expression dependencies and context variables, so let’s remove the feature flag 
and fix forward for any issues.
2023-08-18 12:06:16 -07:00
Lauren Tan c4d000ce49 [ci] Rename TS ci to be consistent with other workflows 2023-08-18 14:16:21 -04:00
Lauren Tan 9e332ee05a [ci] Run yarn workspace tests in parallel 2023-08-18 14:10:41 -04:00
Sebastian Markbåge 98f3f14d2e [Fizz] Track Key Path (#27243)
Tracks the currently executing parent path of a task, using the name of
the component and the key or index.

This can be used to uniquely identify an instance of a component between
requests - assuming nothing in the parents has changed. Even if it has
changed, if things are properly keyed, it should still line up.

It's not used yet but we'll need this for two separate features so
should land this so we can stack on top.

Can be passed to `JSON.stringify(...)` to generate a unique key.
2023-08-18 10:18:33 -04:00
Joe Savona a905a02901 [rust] Add SAFETY comments for unsafe blocks
Adds SAFETY comments for the two instances of unsafe blocks that are *not* just 
FFI. It seems like overkill to annotate all the FFI calls so i'm skipping that, 
let me know if anyone has strong preferences otherwise.
2023-08-17 15:23:46 -07:00
Josh Story 5623f2acf9 Updating forking implementation to match against more general fork implementations (#27205)
Search for more generic fork files if an exact match does not exist. If
`forks/MyFile.dom.js` exists but `forks/MyFile.dom-node.js` does not
then use it when trying to resolve forks for the `"dom-node"` renderer
in flow, tests, and build

consolidate certain fork files that were identical and make semantic
sense to be generalized
add `dom-browser-esm` bundle and use it for
`react-server-dom-esm/client.browser` build
2023-08-17 15:17:46 -07:00
Joe Savona d5a8e80157 [rust][ci] Run cargo check/fmt
Formats the codebase, fixes some clippy lints, and updates CI to check that code 
is formatted.
2023-08-17 12:59:29 -07:00
Josh Story e505316920 [Float][Flight][Fizz][Fiber] Implement preloadModule and preinitModule (#27220)
Stacked on #27224 

### Implements `ReactDOM.preloadModule()`
`preloadModule` is a function to preload modules of various types.
Similar to `preload` this is useful when you expect to use a Resource
soon but can't render that resource directly. At the moment the only
sensible module to preload is script modules along with some other `as`
variants such as `as="serviceworker"`. In the future when there is some
notion of how to preload style module script or json module scripts this
API will be extended to support those as well.

##### Arguments
1. `href: string` -> the href or src value you want to preload.
2. `options?: {...}` -> 
2.1. `options.as?: string` -> the `as` property the modulepreload link
should render with. If not provided it will be omitted which will cause
the modulepreload to be treated like a script module
2.2. `options.crossOrigin?: string` -> modules always load with CORS but
you can provide `use-credentials` if you want to change the default
behavior
2.3. `options.integrity?: string` -> an integrity hash for subresource
integrity APIs
  
##### Rendering
each preloaded module will emit a `<link rel="modulepreload" href="..."
/>`
if `as` is specified and is something other than `"script"` the as
attribute will also be included
if crossOrigin or integrity as specified their attributes will also be
included

During SSR these script tags will be emitted before content. If we have
not yet flushed the document head they will be emitted there after
things that block paint such as font preloads, img preloads, and
stylesheets.

On the client these link tags will be appended to the document.head.
  
### Implements `ReactDOM.preinitModule()`
`preinitModule` is a function to loading module scripts before they are
required. It has the same use cases as `preinit`.

During SSR you would use this to tell the browsers to start fetching
code that will be used without having to wait for bootstrapping to
initiate module fetches.

ON the client you would use this to start fetching a module script early
for an anticipated navigation or other event that is likely to depend on
this module script.

the `as` property for Float methods drew inspiration from the `as`
attribute of the `<link rel="preload" ... >` tag but it is used as a
sort of tag for the kind of thing being targetted by Float methods. For
`preinitModule` we currently only support `as: "script"` and this is
also the assumed default type so you current never need to specify this
`as` value. In the future `preinitModule` will support additional module
script types such as `style` or `json`. The support of these types will
correspond to [Module Import
Attributes](https://github.com/tc39/proposal-import-attributes).

##### Arguments
1. `href: string` -> the href or src value you want to preinitialize
2. `options?: {...}` ->
2.1 `options.as?: string` -> only supports `script` and this is the
default behavior. Until we support import attributes such as `json` and
`style` there will not be much reason to provide an `as` option.
2.2. `options.crossOrigin?: string`: modules always load with CORS but
you can provide `use-credentials` if you want to change the default
behavior
2.3 `options.integrity?: string` -> an integrity hash for subresource
integrity APIs

##### Rendering
each preinitialized `script` module will emit a `<script type="module"
async="" src"...">` During SSR these will appear behind display blocking
resources such as font preloads, img preloads, and stylesheets. In the
browser these will be appende to the head.

Note that for other `as` types the rendered output will be slightly
different. `<script type="module">import "..." with {type: "json"
}</script>`. Since this tag is an inline script variants of React that
do not use inline scripts will simply omit these preinitialization tags
from the SSR output. This is not implemented in this PR but will appear
in a future update.
2023-08-17 10:30:00 -07:00
Sebastian Markbåge ac1a16c67e Add Postpone API (#27238)
This adds an experimental `unstable_postpone(reason)` API.

Currently we don't have a way to model effectively an Infinite Promise.
I.e. something that suspends but never resolves. The reason this is
useful is because you might have something else that unblocks it later.
E.g. by updating in place later, or by client rendering.

On the client this works to model as an Infinite Promise (in fact,
that's what this implementation does). However, in Fizz and Flight that
doesn't work because the stream needs to end at some point. We don't
have any way of knowing that we're suspended on infinite promises. It's
not enough to tag the promises because you could await those and thus
creating new promises. The only way we really have to signal this
through a series of indirections like async functions, is by throwing.
It's not 100% safe because these values can be caught but it's the best
we can do.

Effectively `postpone(reason)` behaves like a built-in [Catch
Boundary](https://github.com/facebook/react/pull/26854). It's like
`raise(Postpone, reason)` except it's built-in so it needs to be able to
be encoded and caught by Suspense boundaries.

In Flight and Fizz these behave pretty much the same as errors. Flight
just forwards it to retrigger on the client. In Fizz they just trigger
client rendering which itself might just postpone again or fill in the
value. The difference is how they get logged.

In Flight and Fizz they log to `onPostpone(reason)` instead of
`onError(error)`. This log is meant to help find deopts on the server
like finding places where you fall back to client rendering. The reason
that you pass in is for that purpose to help the reason for any deopts.

I do track the stack trace in DEV but I don't currently expose it to
`onPostpone`. This seems like a limitation. It might be better to expose
the Postpone object which is an Error object but that's more of an
implementation detail. I could also pass it as a second argument.

On the client after hydration they don't get passed to
`onRecoverableError`. There's no global `onPostpone` API to capture
postponed things on the client just like there's no `onError`. At that
point it's just assumed to be intentional. It doesn't have any `digest`
or reason passed to the client since it's not logged.

There are some hacky solutions that currently just tries to reuse as
much of the existing code as possible but should be more properly
implemented.
- Fiber is currently just converting it to a fake Promise object so that
it behaves like an infinite Promise.
- Fizz is encoding the magic digest string `"POSTPONE"` in the HTML so
we know to ignore it but it should probably just be something neater
that doesn't share namespace with digests.

Next I plan on using this in the `/static` entry points for additional
features.

Why "postpone"? It's basically a synonym to "defer" but we plan on using
"defer" for other purposes and it's overloaded anyway.
2023-08-17 13:26:14 -04:00
Joe Savona 5b6370234c Update readme to mention Rust CI config
This is mostly to test that the new configuration skips the Rust CI step if 
there are no rust changes - yay, that worked! But also worth mentioning in the 
readme so lets land.
2023-08-17 10:15:59 -07:00
Joe Savona 514916d9ce [rust][ci] Only run Rust actions when relevant files change 2023-08-17 10:10:44 -07:00
Joe Savona 3ce4116930 [rust][sema] Only create one scope per function/class
Fixes up function and class handling to not create nested scopes in some cases. 
Doesn't affect name resolution otherwise.
2023-08-17 10:03:00 -07:00
Joe Savona 543d27c2f0 [rust][sema] Support classes
Adds name resolution support for class declarations and expressions. Mostly this 
involves _not_ visiting some `Identifier` nodes that don't actually represent 
variables. For example, method names don't introduce new variables (but if they 
are computed, they may _refer_ to variables).
2023-08-17 10:02:56 -07:00
Joe Savona dafa468765 [rust][sema] Allow defining/resolving known globals
Adds an option to pass a list of known globals into the semantic analyzer so 
that references to globals can be checked. As a follow-up we'll need to 
distinguish between different types of semantic analysis errors, so that callers 
which don't want to validate globals can ignore "unknown variable" reference 
errors while still handling definite errors such as duplicate declarations.
2023-08-16 16:44:40 -07:00
Sebastian Markbåge ade82b8dd9 [Flight] Refactor emit and process functions (#27234)
Since we no longer have externally configured "process" methods, I just
inlined all of those.

The main thing in this refactor is that I just inlined all the error
branches into just `emitErrorChunk`. I'm not sure why it was split up an
repeated before but this seems simpler. I need it since I'm going to be
doing similar copies of this.
2023-08-16 17:04:21 -04:00
Joe Savona bfb7d2bfbd [rust][sema] Handle var/let/const redeclaration
JavaScript has ~sane~ fun rules around where variables can be redeclared or not, 
and which kinds of variables this applies to. Actually the rules are pretty 
straightforward: 

* `var` can be redeclared any number of times. 

* In strict mode, other declarations cannot be redeclared within the same scope. 
This implies that a `var` declaration cannot conflict with these other forms, 
which must take into account hoisting. So you can't have a `var a; let a` in the 
same scope, but you also can't have a `let a` at a scope and then a `var a` 
which will hoist to that same scope.
2023-08-16 12:26:04 -07:00
Joe Savona 796080f4d1 [rust][sema] Statically detect some TDZ violations
The [temporal dead 
zone](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/let#temporal_dead_zone_tdz), 
often abbreviated TDZ, is the period between the start of its declaring block 
and the line that contains the let/const/class declaration. Not all instances of 
TDZ can be detected statically, because whether or not a TDZ error will occur at 
runtime is a property of which control flow path is taken and whether some other 
code has initialized the value. However, a subset of cases can be detected, and 
that's what we implement here. 

When we encounter a variable reference we record the next declaration id at that 
point in time. Then when resolving references after visiting the program, we can 
check: did the reference end up referring to a let/const/class binding whose id 
is equal or greater to that "next declaration"? If so, it means the reference 
refers to a variable that is provably declared later and is a known TDZ 
violation. The catch is that when resolving references, we reset the "next 
declaration" limit value when we bubble up out of a function scope. That's 
because references to let/const within a function may occur after the 
declaration, and we can't statically validate them.
2023-08-15 17:20:34 -07:00
Joe Savona 2edf66ecdf [rust][sema] Resolve all references after traversing program
Previously we attempted to resolve each reference at the close of its defining 
scope, and if it couldn't be resolved yet we bubbled the unresolved reference up 
to the parent scope. That approach isn't ideal for two reasons: 

* First, it's inefficient since we may have to make multiple attempts to resolve 
the same reference. 

* Second, it's incorrect. There can be cases where we think we can resolve a 
reference to a value defined in an outer scope, but there is a hoisted 
declaration from an intermediate scope that we haven't seen yet. 

The safest and most optimal thing is to just queue all references and resolve 
them at the end.
2023-08-15 12:33:45 -07:00
Joe Savona 34914796b2 [rust][sema] Set root scope kind based on program source type
Rather than always create a Global scope and then immediately add a Module child 
node, we now set the kind of the root scope to global (for scripts) or module 
(for modules) based on the program node.
2023-08-15 12:24:38 -07:00
Joe Savona 875d7175ac [rust] cargo fix 2023-08-15 09:31:49 -07:00
Joe Savona b133b6c0b4 [rust][sema] Visit imports as declarations
Teaches the semantic analyzer about import statements. We now treat imports as 
declarations, so that subsequent references to the imported value can be 
resolved.
2023-08-15 09:30:43 -07:00
Joe Savona 15e0ecaa8f [rust] Convert Hermes source locations to ESTree SourceRange
Teaches the hermes->estree conversion to convert source ranges. This means our 
diagnostics now point to the actual source of the error: 

<img width="903" alt="Screenshot 2023-08-14 at 5 39 50 PM" 
src="https://github.com/facebook/react-forget/assets/6425824/2960d114-0cc6-4531-9e7d-00ff3bfb1eb3"> 

Of course I still need to teach our semantic analysis about imports, but that's 
a separate issue!
2023-08-14 17:36:58 -07:00
Joe Savona f2a1a6a6e4 [rust][sema] Test for function hoisting 2023-08-14 17:36:54 -07:00
Mofei Zhang 1ad0460693 [sprout] Add shared runtime, improve error reporting
--- 

I added ~20 more tests to Sprout to get more of a feel for what the test 
framework would need to support all fixtures. I'm relatively confident that the 
approach outlined in [the original workplace 
post](https://fburl.com/workplace/ftu8woch) works to migrate almost all existing 
fixture tests to sprout (TLDR: use shared functions when possible, otherwise 
write helper functions in-file). 

Add `shared-runtime` file to reduce the amount of overhead needed to set up a 
fixture test. 

- All generalizable functions and values should be added here (e.g. 
`shallowCopy`, `deepCopy`, `sum`). 

- Editor integration is set up through a custom tsconfig, so importing from 
`shared-runtime` should just work (with hover annotations, click-to-definition, 
etc). 

<img width="682" alt="Screenshot 2023-08-17 at 11 09 47 AM" 
src="https://github.com/facebook/react-forget/assets/34200447/78c3dff9-ba10-4057-b3f6-2fa842d19b1d"> 

--- 

Tested new test fixtures added to sprout by adding them to `testfilter.txt` and 
running with `--verbose --filter`. 

Note that there are no unexpected exceptions, and all logs + returned values 
match. 

``` 

feifei0@feifei0-mbp babel-plugin-react-forget % yarn sprout:build && yarn sprout 
--verbose --filter 

yarn run v1.22.19 

$ yarn workspace sprout run build 

$ rimraf dist && tsc --build 

✨  Done in 2.07s. 

yarn run v1.22.19 

$ node ../sprout/dist/main.js --verbose --filter 

PASS  console-readonly 

ok {"a":1,"b":2} [ 

"{ a: 1, b: 2 }", 

"{ a: 1, b: 2 }", 

"{ a: 1, b: 2 }", 

"{ a: 1, b: 2 }", 

"{ a: 1, b: 2 }" 

] 

PASS  constant-propagate-global-phis-constant 

ok <div>global string 0</div> 

PASS  constant-propagate-global-phis 

ok <div>global string 1</div> 

PASS  dce-loop 

ok 10 

PASS  destructure-capture-global 

ok {"a":"value 1","someGlobal":{}} 

PASS  destructuring-mixed-scope-and-local-variables-with-default 

ok {"media":null,"allUrls":["url1","url2","url3"],"onClick":"[[ function 
params=1 ]]"} 

PASS  holey-array-expr 

ok [null,"global string 0",{"a":1,"b":2}] 

PASS  infer-global-object 

ok {"primitiveVal1":2,"primitiveVal2":null,"primitiveVal3":null} 

PASS  infer-phi-primitive 

ok 1 

PASS  infer-types-through-type-cast.flow 

ok 4 

PASS  issue933-disjoint-set-infinite-loop 

ok [2] 

PASS  jsx-tag-evaluation-order-non-global 

ok <div>StaticText1<div>StaticText2</div></div> 

PASS  jsx-tag-evaluation-order 

ok <div>StaticText1string value 1<div>StaticText2</div></div> 

PASS  method-call 

ok 4 

PASS  mutable-lifetime-loops 

ok {"a":{"value":6},"b":{"value":5},"c":{"value":4},"d":{"value":6}} 

PASS  mutable-lifetime-with-aliasing 

ok {"b":[{}],"value":[{"c":{},"value":"[[ cyclic ref *0 ]]"},null]} 

PASS  update-expression-in-sequence 

ok [4,2,3,4] 

PASS  update-expression-on-function-parameter 

ok [4,1,4,2,4,3,1,4,4] 

PASS  update-expression 

ok {"x":1,"y":1,"z":2} 

PASS  useMemo-multiple-if-else 

ok 2 

20 Tests, 20 Passed, 0 Failed 

✨  Done in 4.11s. 

```
2023-08-17 13:28:08 -04:00
Mofei Zhang 2b4a1d86ff [pipeline] Recognize "use no forget" directive
--- 

Add "use no forget", not gated behind a feature flag for simplicity ("use no 
forget" should always tell Forget to not compile a component, right?)
2023-08-17 11:03:20 -04:00
Mofei Zhang 28688ade9f [sprout] Add copyright headers etc 2023-08-17 11:03:18 -04:00
Lauren Tan 74aec8aa35 [ez] Add concurrently labels to yarn dev 2023-08-17 12:01:42 -04:00
Lauren Tan 9c2ce7a8c8 Try running tests for babel-plugin-react-forget concurrently
Unscientifically seems to be a little faster. I made sure to preserve the 
ordering of the logs even though the processes will run concurrently, so the ci 
output should still be readable 

![Screenshot 2023-08-17 at 11 51 45 
AM](https://github.com/facebook/react-forget/assets/1390709/b9878983-ed0c-4b93-bc10-61109ff8103d)
2023-08-17 11:58:15 -04:00
Mofei Zhang 5448b33eb0 [yarn workspaces] Add typescript dependencies to tsconfig
--- 

Previously, I used `yarn workspace build fixture-test-utils` and `yarn workspace 
build babel-plugin-react-forget` to recompile dependencies on sprout. However, 
tsc supports project references which was intended to solve this problem 
https://www.typescriptlang.org/docs/handbook/project-references.html 

Note that apparently this places `.tsbuildinfo` in package roots, according to 
https://github.com/microsoft/TypeScript/issues/30925
2023-08-16 15:38:30 -04:00
Mofei Zhang d6dea6b9b9 [sprout][fixtures] Annotate some fixtures
--- 

This PR is an example of how to update fixture to add sprout annotations. 

Running with `yarn sprout --verbose --filter` shows the fixture outputs. 

``` 

PASS  array-access-assignment 

ok [[2],[[2],[],[3]]] 

PASS  array-expression-spread 

ok [0,1,2,3,null,4,5,6,"z"] 

PASS  array-map-frozen-array 

ok [[],[]] 

PASS  array-map-mutable-array-mutating-lambda 

ok [[],[]] 

PASS  array-pattern-params 

ok [{"a":"val1"},{"b":"val2"}] 

PASS  array-properties 

ok {"a":[[1,2],2,"hello"],"x":3,"y":"[[ function params=1 ]]","z":"[[ function 
params=1 ]]"} 

PASS  array-property-call 

ok {"a":[1,2,"hello",42],"x":4,"y":1} 

PASS  assignment-expression-computed 

ok [7] 

PASS  assignment-expression-nested-path 

ok {"b":{"c":6}} 

PASS  capturing-func-mutate-2 

ok {"a":2} 

PASS  capturing-function-alias-computed-load-2 

ok "val2" 

PASS  capturing-function-alias-computed-load-4 

ok "val2" 

```
2023-08-16 15:38:29 -04:00
Mofei Zhang 9d1a842a83 [sprout] Enable sprout on all new fixtures
--- 

Rename `SproutOnlyFilterTodoRemove.ts` to `SproutTodoFilter.ts`. I've tried to 
group the skipped fixtures by difficulty and add comments about what need to be 
done, also happy to change the structure of this. 

From this point, sprout will run on all new fixtures by default. If the fixture 
forgets to export a `FIXTURE_ENTRYPOINT`, sprout will fail with this error. 

<img width="853" alt="Screenshot 2023-08-15 at 5 59 32 PM" 
src="https://github.com/facebook/react-forget/assets/34200447/0f80d650-1dc1-4df4-9710-e49acbb424b0"> 

See #1961 for an example of how to annotate existing skipped fixtures or new 
ones. The `README.md` is also updated with a guide.
2023-08-16 15:38:28 -04:00
Mofei Zhang c4ae2a48dc [sprout] patch bug + add verbose mode
--- 

``` 

yarn sprout --verbose 

``` 

Verbose mode prints out all outputs of tests. The test output is a status (`ok` 
or `exception`), a returned or thrown value, and a set of console logs. 

Currently as of #1960 , this is the output: 

```sh 

$ yarn workspace babel-plugin-react-forget run build && node 
../sprout/dist/main.js --verbose 

$ rimraf dist && tsc 

PASS  alias-nested-member-path 

ok {"y":{"z":[]}} 

PASS  assignment-variations-complex-lvalue 

ok {"y":{"z":4}} 

PASS  assignment-variations 

ok 1 

PASS  chained-assignment-expressions 

ok {"z":null} 

PASS  computed-call-evaluation-order 

ok {"f":"[[ function params=0 ]]"} [ 

"A", 

"B", 

"arg", 

"original" 

] 

PASS  const-propagation-into-function-expression-primitive 

ok 42 [ 

"42" 

] 

PASS  constant-propagation-for 

ok 0 

PASS  constant-propagation-while 

ok 0 

PASS  constant-propagation 

ok -6 [ 

"foo" 

] 

PASS  controlled-input 

ok <input value="0"> 

PASS  do-while-continue 

ok [1.5,1,0.5] 

PASS  do-while-simple 

ok [6,4,2] 

PASS  expression-with-assignment 

ok 5 

PASS  for-of-break 

ok [] 

PASS  for-of-conditional-break 

ok [] 

PASS  for-of-continue 

ok [0.5,1,1.5] 

PASS  for-of-destructure 

ok [0,2,4] 

PASS  for-of-simple 

ok [0,2,4] 

PASS  function-declaration-reassign 

ok {} 

PASS  function-declaration-redeclare 

ok "[[ function params=0 ]]" 

PASS  lambda-reassign-primitive 

ok 41 

PASS  lambda-reassign-shadowed-primitive 

ok {} 

PASS  property-call-evaluation-order 

ok {"f":"[[ function params=0 ]]"} [ 

"A", 

"arg", 

"original" 

] 

PASS  reactive-scope-grouping 

ok {"y":[{}]} 

PASS  sequentially-constant-progagatable-if-test-conditions 

ok "ok" 

PASS  simple-function-1 

ok "[[ function params=1 ]]" 

PASS  ssa-complex-multiple-if 

ok 

PASS  ssa-complex-single-if 

ok 

PASS  ssa-for 

ok 11 

PASS  ssa-if-else 

ok 

PASS  ssa-objectexpression-phi 

ok {"x":1,"y":3} 

PASS  ssa-property-call 

ok {"x":[[]]} 

PASS  ssa-property 

ok {"x":[]} 

PASS  ssa-return 

ok 2 

PASS  ssa-simple-phi 

ok 

PASS  ssa-simple 

ok 

PASS  ssa-single-if 

ok 

PASS  ssa-switch 

ok 

PASS  ssa-throw 

exception undefined 

PASS  ssa-while 

ok 10 

PASS  type-field-load 

ok 1 

PASS  type-test-field-store 

ok {} 

PASS  type-test-primitive 

ok 2 

PASS  update-expression-constant-propagation 

ok {"a":0,"b":0,"c":2,"d":2,"e":0} 

44 Tests, 44 Passed, 0 Failed 

✨  Done in 9.27s. 

```
2023-08-16 15:32:15 -04:00
Mofei Zhang 9d1f2c86ed [sprout] Codemod: add todos for test fixtures
--- 

Codemod to add an `export FIXTURE_ENTRYPOINT` with todo values for params for 
tests with at least one param and 0 refs to external values
2023-08-16 15:32:15 -04:00
Mofei Zhang 43e3cd61f8 [snap] Use sync fs apis to stop crashes
--- 

Not sure why, but snap kept silently crashing when I used fs/promises to write 
to many file handles. I tried a `.catch(...)`, but couldn't figure it out. This 
diff changes snap to use sync fs apis to avoid crashes, but I'd love to get 
feedback if someone knows how to debug this.
2023-08-16 15:32:14 -04:00
Mofei Zhang ce015a164b [sprout] Codemod: add isComponent: false annotations to current fixtures
To keep the type signature simple, let's always have the same set of keys in 
`FIXTURE_ENTRYPOINT`
2023-08-16 15:32:13 -04:00