-
-
Notifications
You must be signed in to change notification settings - Fork 668
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
Have Jest cover Android-only codepaths. #4700
Have Jest cover Android-only codepaths. #4700
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks @chrisbobbe ! This will be great. Comments below.
tools/test
Outdated
@@ -117,6 +117,10 @@ run_native() { | |||
) | |||
} | |||
|
|||
run_native() { | |||
run_native_android || return |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The || return
is redundant:
- If the
run_native_android
command succeeds, the||
won't be used. - If it fails, then:
- The
||
will be used, andreturn
with no arguments means we'll return the exit status of that command. (Seehelp return
or the entry here in the manual.) - If OTOH the whole command were just
run_native_android
, with no|| return
, thenset -e
already means that on failure the function would return with that exit code.
- The
A lot of spots in this script have a pattern || return 0
. That has the key difference that if the left-hand command fails, it makes the function return but with success (exit status 0). So it's used for conditions that mean there's no work to be done, like if there are no relevant files.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Huh, interesting! It looks like something strange is happening.
I added || return
because, without it, I found that run_native_android
could fail without causing run_native
to exit immediately with the same exit code. (I caused a failure in run_native_android
by putting garbage in one of our Kotlin files.)
I've tried a few things just now, and I think I found the culprit. From the Bash manual on set -e
(emphasis mine),
The shell does not exit if the command that fails is part of the command list immediately following a
while
oruntil
keyword, part of the test in anif
statement, part of any command executed in a&&
or||
list except the command following the final&&
or||
, any command in a pipeline but the last, or if the command’s return status is being inverted with!
.
If I make this change just after the case "$suite" in
block, in the for suite in "${suites[@]}"
loop, I can then remove the || return
and it works as expected (a run_native_android
failure immediately causes run_native
to exit with the same exit code):
- esac || failed+=($suite)
+ esac
🤯
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this diagnosis right, and if so, how would you like to proceed? Maybe we could rewrite the conditional that controls whether failed+=($suite)
runs.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Urgh, right. Thanks for catching that. This is the main gotcha in set -e
, where it doesn't do everything you'd think it does (because any reasonable version of it absolutely would.) 🤯 is right on.
This also explains why I wrote a similar || return
in one spot in the existing code, at check_node || return
. When I wrote this comment I was wondering about that...
I guess the short of it is that inside all these functions, we effectively don't have the benefit of set -e
. And we can't even re-enable it from inside each function, as this bit later in that same manual item explains:
If a compound command or shell function sets
-e
while executing in a context where-e
is ignored, that setting will not have any effect until the compound command or the command containing the function call completes.
I think the right immediate fix is to use || return
just as this branch does. Basically we need that wherever we have a nontrivial command that isn't the final command of its function. I think the existing code is all OK in this respect, thanks to that || return
in one place we did need it.
That and maybe a comment on the set -e
at the top, warning that it doesn't (and sadly can't) actually apply to most of the code.
Then... if we want to get back set -e
behavior inside these functions, while still being able to "catch" its propagation at the outer loop so that we can go on to run the other suites, I think basically what's required is to fork a subshell (with the ( … )
syntax -- like we already do inside run_android
in order to use cd
and contain its effect.) I think that's the real point of what that quoted bit of docs is saying: set -e
stops having any effect if it isn't going to be able to go all the way to exit the whole shell. That's a bit of overhead, but only like a millisecond each:
$ time bash -c 'for i in {1..100}; do ( : ); done'
time: 0.099s wall (0.065s u, 0.041s s)
so not a problem at all. (That fast startup time is one of Bash's handful of great strengths, compared to almost any other language that doesn't require a compile step.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK, sounds good! Glad to see the 🤯 feeling is shared! 😅 I'll put a comment on the set -e
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure what's the best strategy for forking a subshell where appropriate; we'd of course like to leave a good signpost if any run_foo
functions we add in the future have to remember to do something.
docs/howto/testing.md
Outdated
We've configured Jest to run two different | ||
["projects"](https://jestjs.io/docs/configuration#projects-arraystring--projectconfig): | ||
one with an iOS preset, and one with an Android preset. | ||
`tools/test jest` will run one or the other, or both, depending on | ||
what you pass for `--platform`. | ||
|
||
If it makes sense for a test file to be dedicated to just one | ||
platform, and that's unlikely to change, you can instead suffix it | ||
with `-test.ios.js` or `-test.android.js`, and it will be ignored when | ||
the other platform's project runs. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This feels more detailed about the Jest specifics than is needed here -- those details can be left to the code that controls them. (E.g. I think the concept of a Jest "project" can be left to jest.config.js
and to that case
block in tools/test
that sets --selectedProjects
.)
For this doc the ideal thing is to be more direct about what happens by default, and what you might want to do instead (and when.)
Thanks for the prompt review, @gnprice! Reading now. |
We've had Jest 26 as a direct dependency for a while (since fb23341), so it's surprising that the `jest` command hasn't been using it. As Greg points out [0], that turns out to be because `jest-expo` apparently provides its own wrapper for the `jest` command, using the Jest that `jest-expo` depends on. That's Jest 25, even in `jest-expo`'s latest. And Yarn ends up giving us that wrapper. We know we'll soon want to use Jest 26 for a few things: - The "modern" implementation of fake timers [1], for zulip#4165. - The `selectProjects` CLI argument [2], for testing Android codepaths in a nice way (later in this series). But we've *also* realized that we don't really want to jettison `jest-expo` again, as we've done a few times as we learn new things: 62621ef jest: Add `jest-expo` preset, to be used in the next commit. 347aa96 jest: Back out `jest-expo` preset, for now. c4fca9d jest: Add and use `jest-expo` preset, again. In particular, we really want to use the `jest-expo/ios` and `jest-expo/android` presets (which we'll do later in this series). This is a hack because the `resolutions.jest-expo/jest` range `^26.4.1` is incompatible with the original range that `jest-expo` declares; that's `^25.2.0`. We believe this should get us a warning from Yarn; according to a doc [3], "You will receive a warning if your resolution version or range is not compatible with the original version range." I haven't seen a warning like that, even after removing node_modules and running `yarn`; this seems like a Yarn bug. I've opened expo/expo#12735 to bump Jest in the `jest-expo` project; this hack should hopefully be fine while we wait for that. [0] zulip#4700 (comment) [1] https://github.com/facebook/jest/blob/master/CHANGELOG.md#2600 [2] https://github.com/facebook/jest/blob/master/CHANGELOG.md#2610 [3] https://classic.yarnpkg.com/en/docs/selective-version-resolutions/#toc-tips-tricks
As Greg suggests at zulip#4700 (comment). These made sense before `tools/test` existed, and they were good shortcuts for complicated commands. Now, even if they still work, they're just obstacles in the way of getting familiar with `tools/test` and all its features.
This doesn't control which suites are run; it controls which files are tested. So, give it a name that makes more explicit what it does and doesn't do. As Greg suggests: zulip#4700 (comment).
Thanks again for the review! Revision pushed. I've also replied inline to some of your comments, and you've already responded to some. |
As Greg explains; see zulip#4700 (comment).
And promote it in the release docs and run it in CI. As Greg suggests: zulip#4700 (comment).
4cb5033
to
b17a4f3
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for doing this! I'm very happy that we'll be getting more coverage here. Just a few comments :)
tools/test
Outdated
# """ | ||
# The shell does not exit if the command that fails is [...] part of | ||
# any command executed in a `&&` or `||` list except the command | ||
# following the final `&&` or `||` [...]. | ||
# """ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: I would use:
> blockquote style
rather than the triple quotes, since I think that's clearer, and uses less vertical space.
tools/test
Outdated
@@ -1,4 +1,21 @@ | |||
#!/usr/bin/env bash | |||
|
|||
# Careful! This doesn't do everything you'd think it does. In fact, we |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would replace This
here with 'set -e'
, since otherwise it's unclear what this comment is referring to until you read the entire thing.
tools/test
Outdated
Run tests as if on iOS, or Android, or both. The default, | ||
"sloppy", takes a shortcut in some suites, so the tests | ||
run faster but full coverage of both platforms isn't | ||
guaranteed. In particular, while the vast majority of | ||
our Jest tests don't depend meaningfully on the platform, | ||
we don't yet have a clever way to identify the ones that | ||
do. So, "sloppy" just picks one platform to simulate | ||
(iOS). Don't use "sloppy" if you want coverage of the | ||
other platform. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this could be clearer:
Run tests as if on iOS, or Android, or both. The default,
"sloppy", takes a shortcut in some suites, so the tests
run faster but full coverage of both platforms isn't
guaranteed. Specifically, "sloppy" will run both Android and iOS
native tests, but will run Jest tests on only one platform (iOS).
This is usually fine, because the vast majority of our Jest tests
don't depend meaningfully on the platform.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I like it!
# This is where `sloppy` is sloppy: we just choose iOS, so the | ||
# tests will run faster, but at the expense of a (relatively | ||
# small) loss of coverage. | ||
sloppy) jest_args+=( --selectProjects ios );; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A possibly dumb idea — we could pick whether it runs as iOS or Android randomly. The idea there being that if it's only failing on one, picking randomly would cause you to notice sooner during local development, rather than it only being caught in CI. And while that makes it flaky, it's a pretty reasonable type of flake, since it'll always be catching a real test failure.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Interesting; I kind of like this idea. @gnprice, what do you think?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, maybe. I like the idea of causing you to notice sooner. I think this would definitely best be done as a separate change.
@@ -82,6 +84,7 @@ while (( $# )); do | |||
esac | |||
shift | |||
;; | |||
--all) files=all; platform=both; shift;; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it someone does tools/test --all --platform=android
or similar, the --platform
will overwrite the --all
, is that right?
Probably we should just fail if someone passes both --all
and --platform
or --diff
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Makes sense. I also wondered if we should write the first line of the usage string differently, to reflect that:
usage: tools/test [--all-files | --diff COMMIT] [--platform <ios|android|both|sloppy>] [--all] [SUITES]
(I.e., from reading that it looks like it's perfectly fine to do --all
and --platform
or --diff
.)
But I'm not sure how best to do that while preserving readability. Maybe it's fine as-is.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, looking again, I'm not sure what's the best way to enforce these rules on what gets passed. (I see that we're already not enforcing that only one of --diff
and --all-files
gets passed.)
I'm not super familiar with Bash, yet. It seems plausible to me that the best way to start enforcing these things will be after we've started using getopt
for something different; Greg suggested that here. Do you think that's right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For --all-files
and --diff
, I think the behavior is actually fine: they're each setting the same option to different values, and the last one wins. That's a common CLI convention, and it can come in handy when you want to have some default command line (e.g. an alias in your interactive shell) and sometimes pass additional arguments, and sometimes override an option that was already in the default version of the command.
I think the way --all
interacts with those two and --platform
is also fine for the same reason. It means that, for example, you could have an alias that expands to tools/test --all
, and effectively it'd be tools/test
but with your custom choice of a different default -- you'd still be able to override it to get other behavior when you wanted.
(For the real thorough version of that, we'd also add a flag that means the default files=branch
behavior as opposed to --all-files
or --diff
.)
If we did want behavior where some options are mutually exclusive, that's actually orthogonal to getopt; the way you'd implement it if we were using getopt is basically the same as how you'd implement it now.
jest/jestSetup.js
Outdated
compress: async (input: string) => `${header}${input}`, | ||
decompress: async (input: string) => input.replace(header, ''), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is fine as is, but I'd be a bit more comfortable with something that mangles the whole string. Possibly base64encoding it, in addition to adding the header? (I'm not sure what JS runtime our jest tests execute in, so I'm not sure if we have a reasonable base64 function easily available to us, but if we do, that seems like a good option).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sounds good; there is such a thing: Buffer
. This isn't available for JS that runs in an app build; it looks like we do use an NPM package called base-64
for that in some places.
The Jest tests execute in Node, and we currently recommend the latest 12.x and use that in CI (see f83ccc6 for what this means more concretely). #4263 is open to upgrade to 14.
// `ZulipAsyncStorage-test.android.js`, to target entire test suites | ||
// to Android and iOS. | ||
describe('ZulipAsyncStorage', () => { | ||
describe('setItem', () => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we test getItem
as well?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure! My work on the getItem
tests today has led to some reworking (and increased coverage) of the setItem
tests, too. It's enough that I think it makes sense for that stuff to go in its own PR, so I'll take the setItem
tests out of this PR and send a new PR that tests that and getItem
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks great, thanks!
Other than the two small things below, and the things in threads above where I feel like I need to explore a bit in order to have a concrete suggestion and so I may try for myself later, I have just one other comment:
I think the series can be simplified somewhat by taking the three commits where --full
gets renamed, --platform
introduced, and we have both --all-files
and --all
, and rearranging to:
- One commit renames
--full
directly to--all
. After all, in the end that's what we want in all the known use cases of the old--full
. At this stage it means the same thing as--all-files
would, because there's no--platform
yet. - Then in the commit that adds
--platform
,--all
starts including the meaning of--platform both
, and we introduce--all-files
for the behavior that's only about thefiles
variable.
In particular this means the places we mention --full
change only in the first of those commits, instead of all three of the existing sequence.
We've had Jest 26 as a direct dependency for a while (since fb23341), so it's surprising that the `jest` command hasn't been using it. As Greg points out [0], that turns out to be because `jest-expo` apparently provides its own wrapper for the `jest` command, using the Jest that `jest-expo` depends on. That's Jest 25, even in `jest-expo`'s latest. And Yarn ends up giving us that wrapper. We know we'll soon want to use Jest 26 for a few things: - The "modern" implementation of fake timers [1], for zulip#4165. - The `selectProjects` CLI argument [2], for testing Android codepaths in a nice way (later in this series). But we've *also* realized that we don't really want to jettison `jest-expo` again, as we've done a few times as we learn new things: 62621ef jest: Add `jest-expo` preset, to be used in the next commit. 347aa96 jest: Back out `jest-expo` preset, for now. c4fca9d jest: Add and use `jest-expo` preset, again. In particular, we really want to use the `jest-expo/ios` and `jest-expo/android` presets (which we'll do later in this series). This is a hack because the `resolutions.jest-expo/jest` range `^26.4.1` is incompatible with the original range that `jest-expo` declares; that's `^25.2.0`. We believe this should get us a warning from Yarn; according to a doc [3], "You will receive a warning if your resolution version or range is not compatible with the original version range." I haven't seen a warning like that, even after removing node_modules and running `yarn`; this seems like a Yarn bug. I've opened expo/expo#12735 to bump Jest in the `jest-expo` project; this hack should hopefully be fine while we wait for that. [0] zulip#4700 (comment) [1] https://github.com/facebook/jest/blob/master/CHANGELOG.md#2600 [2] https://github.com/facebook/jest/blob/master/CHANGELOG.md#2610 [3] https://classic.yarnpkg.com/en/docs/selective-version-resolutions/#toc-tips-tricks
As Greg explains; see zulip#4700 (comment).
As Greg suggests at zulip#4700 (comment). These made sense before `tools/test` existed, and they were good shortcuts for complicated commands. Now, even if they still work, they're just obstacles in the way of getting familiar with `tools/test` and all its features.
b17a4f3
to
64e9db6
Compare
Thanks for the review! Revision pushed. I've removed addition of tests for |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks @chrisbobbe ! Looks great -- tiny comments below.
I'm about to merge, so I'll just fix these along the way.
tools/test
Outdated
# > The shell does not exit if the command that fails is [...] part of | ||
# any command executed in a `&&` or `||` list except the command | ||
# following the final `&&` or `||` [...]. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: using >
on each line makes it clearer this is all part of the quote
tools/test
Outdated
files=branch | ||
fix= | ||
platform=sloppy | ||
suites=() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
tiny nit: clearest if these are kept in the same order as the cases that operate on them, below
We've had Jest 26 as a direct dependency for a while (since fb23341), so it's surprising that the `jest` command hasn't been using it. As Greg points out [0], that turns out to be because `jest-expo` apparently provides its own wrapper for the `jest` command, using the Jest that `jest-expo` depends on. That's Jest 25, even in `jest-expo`'s latest. And Yarn ends up giving us that wrapper. We know we'll soon want to use Jest 26 for a few things: - The "modern" implementation of fake timers [1], for zulip#4165. - The `selectProjects` CLI argument [2], for testing Android codepaths in a nice way (later in this series). But we've *also* realized that we don't really want to jettison `jest-expo` again, as we've done a few times as we learn new things: 62621ef jest: Add `jest-expo` preset, to be used in the next commit. 347aa96 jest: Back out `jest-expo` preset, for now. c4fca9d jest: Add and use `jest-expo` preset, again. In particular, we really want to use the `jest-expo/ios` and `jest-expo/android` presets (which we'll do later in this series). This is a hack because the `resolutions.jest-expo/jest` range `^26.4.1` is incompatible with the original range that `jest-expo` declares; that's `^25.2.0`. We believe this should get us a warning from Yarn; according to a doc [3], "You will receive a warning if your resolution version or range is not compatible with the original version range." I haven't seen a warning like that, even after removing node_modules and running `yarn`; this seems like a Yarn bug. I've opened expo/expo#12735 to bump Jest in the `jest-expo` project; this hack should hopefully be fine while we wait for that. [0] zulip#4700 (comment) [1] https://github.com/facebook/jest/blob/master/CHANGELOG.md#2600 [2] https://github.com/facebook/jest/blob/master/CHANGELOG.md#2610 [3] https://classic.yarnpkg.com/en/docs/selective-version-resolutions/#toc-tips-tricks
As Greg explains; see zulip#4700 (comment).
As Greg suggests at zulip#4700 (comment). These made sense before `tools/test` existed, and they were good shortcuts for complicated commands. Now, even if they still work, they're just obstacles in the way of getting familiar with `tools/test` and all its features.
64e9db6
to
0250567
Compare
Thanks for the reviews!
I've gone ahead and made the two targeted fixes for the nits you pointed out (and made no further changes), and pushed that to this branch, just in case that's helpful. 😛 (I haven't merged in case your hesitation is because you found a problem.) |
We've had Jest 26 as a direct dependency for a while (since fb23341), so it's surprising that the `jest` command hasn't been using it. As Greg points out [0], that turns out to be because `jest-expo` apparently provides its own wrapper for the `jest` command, using the Jest that `jest-expo` depends on. That's Jest 25, even in `jest-expo`'s latest. And Yarn ends up giving us that wrapper. We know we'll soon want to use Jest 26 for a few things: - The "modern" implementation of fake timers [1], for zulip#4165. - The `selectProjects` CLI argument [2], for testing Android codepaths in a nice way (later in this series). But we've *also* realized that we don't really want to jettison `jest-expo` again, as we've done a few times as we learn new things: 62621ef jest: Add `jest-expo` preset, to be used in the next commit. 347aa96 jest: Back out `jest-expo` preset, for now. c4fca9d jest: Add and use `jest-expo` preset, again. In particular, we really want to use the `jest-expo/ios` and `jest-expo/android` presets (which we'll do later in this series). This is a hack because the `resolutions.jest-expo/jest` range `^26.4.1` is incompatible with the original range that `jest-expo` declares; that's `^25.2.0`. We believe this should get us a warning from Yarn; according to a doc [3], "You will receive a warning if your resolution version or range is not compatible with the original version range." I haven't seen a warning like that, even after removing node_modules and running `yarn`; this seems like a Yarn bug. I've opened expo/expo#12735 to bump Jest in the `jest-expo` project; this hack should hopefully be fine while we wait for that. [0] zulip#4700 (comment) [1] https://github.com/facebook/jest/blob/master/CHANGELOG.md#2600 [2] https://github.com/facebook/jest/blob/master/CHANGELOG.md#2610 [3] https://classic.yarnpkg.com/en/docs/selective-version-resolutions/#toc-tips-tricks
As Greg explains; see zulip#4700 (comment).
As Greg suggests at zulip#4700 (comment). These made sense before `tools/test` existed, and they were good shortcuts for complicated commands. Now, even if they still work, they're just obstacles in the way of getting familiar with `tools/test` and all its features.
In my local test runs, at least, I noticed that none of the tests in the "Parse" describe block were getting run. That's not good! At least they pass after this commit that fixes that bug, though. When our code in the "Parse" describe block started running, the object at `stringified` was empty, so the `.forEach` loop was iterating through...an empty array. Our mistake was assuming that the code that built up that object would be finished running in time. It wasn't finished in time, because that code was inside a test block of its own. Jest tests generally run concurrently, so we can't generally expect one test to be run before another, even if we define the test blocks in a particular order.
As Greg points out [1], this isn't a best fit for snapshot tests. A blog post [2] linked from a Jest doc says, """ The first thing that became clear to me while using snapshot testing is that they’re not for everything. They are optimized for a different case than normal assertion-based tests. Classic assertion based tests are perfect for testing clearly defined behavior that is expected to remain relatively stable. Snapshot tests are great for testing less clearly defined behavior that may change often. """ Which we think is basically right. [1] zulip#4348 (comment) [2] https://benmccormick.org/2016/09/19/testing-with-jest-snapshots-first-impressions/
We've had Jest 26 as a direct dependency for a while (since fb23341), so it's surprising that the `jest` command hasn't been using it. As Greg points out [0], that turns out to be because `jest-expo` apparently provides its own wrapper for the `jest` command, using the Jest that `jest-expo` depends on. That's Jest 25, even in `jest-expo`'s latest. And Yarn ends up giving us that wrapper. We know we'll soon want to use Jest 26 for a few things: - The "modern" implementation of fake timers [1], for zulip#4165. - The `selectProjects` CLI argument [2], for testing Android codepaths in a nice way (later in this series). But we've *also* realized that we don't really want to jettison `jest-expo` again, as we've done a few times as we learn new things: 62621ef jest: Add `jest-expo` preset, to be used in the next commit. 347aa96 jest: Back out `jest-expo` preset, for now. c4fca9d jest: Add and use `jest-expo` preset, again. In particular, we really want to use the `jest-expo/ios` and `jest-expo/android` presets (which we'll do later in this series). This is a hack because the `resolutions.jest-expo/jest` range `^26.4.1` is incompatible with the original range that `jest-expo` declares; that's `^25.2.0`. We believe this should get us a warning from Yarn; according to a doc [3], "You will receive a warning if your resolution version or range is not compatible with the original version range." I haven't seen a warning like that, even after removing node_modules and running `yarn`; this seems like a Yarn bug. I've opened expo/expo#12735 to bump Jest in the `jest-expo` project; this hack should hopefully be fine while we wait for that. [0] zulip#4700 (comment) [1] https://github.com/facebook/jest/blob/master/CHANGELOG.md#2600 [2] https://github.com/facebook/jest/blob/master/CHANGELOG.md#2610 [3] https://classic.yarnpkg.com/en/docs/selective-version-resolutions/#toc-tips-tricks
When we've used the `jest-expo` preset or the `react-native` preset, the tests get run "in the standard React Native environment (iOS)" [1]. The key piece of this is that they run with `Platform.OS` mocked to 'ios'. We're about to add another "project" to test Android codepaths with `jest-expo/android`. First, though, swap out the old `jest-expo` preset for this more explicit one so we don't have to think about three presets. [1] https://github.com/expo/expo/blob/master/packages/jest-expo/README.md#platforms
This means that our Jest tests will take ~twice as long as they took before. We'll soon add an option to `tools/test` to run the Jest tests for just one platform, which we can use locally to speed things up, just without getting as much coverage as we'd otherwise get. See discussion at https://chat.zulip.org/#narrow/stream/243-mobile-team/topic/.60jest-expo.2Fios.60.20and.20.60jest-expo.2Fandroid.60/near/1169139.
We're about to add a `--platform` option, and we'd like it to determine the behavior of some test suites, including this one. So, give this an accurate but not platform-specific name. (That's a cleaner way to do it than having the new option alter the list of suites to run; such an interface would conflict with the current interface that allows the runner to list the suites they want to run.)
As Greg explains; see zulip#4700 (comment).
Using the workaround from the big warning we just put on `set -e` at the top.
As Greg suggests at zulip#4700 (comment). These made sense before `tools/test` existed, and they were good shortcuts for complicated commands. Now, even if they still work, they're just obstacles in the way of getting familiar with `tools/test` and all its features.
Soon, this option will grow to include the meaning "run tests for both platforms", when we add a `--platform` option, coming up.
And expand `--all`, which runs in CI and at releases, to include the behavior of `--platform both`. Leave the current behavior as the default, with the name "sloppy", to not slow down local testing. Greg points out [1], """ From looking at a couple of recent CI builds, it looks like running Jest both ways doubles the Jest time, as you'd expect; it goes from about 60s to about 120s. Our CI times are around 8-9 minutes now, so that adds one minute -- not awesome, but I think worth it for getting coverage of this sort of code. """ [1] https://chat.zulip.org/#narrow/stream/243-mobile-team/topic/.60jest-expo.2Fios.60.20and.20.60jest-expo.2Fandroid.60/near/1169341
And promote a `global-require` ESLint ignore to a file-global ignore, rather than figuring out how to get the `$FlowIgnore` and the line-specific ESLint ignore to both work.
0250567
to
5fd977a
Compare
Thanks for the reviews! @gnprice, I've decided to merge, having timed out on waiting for discussion and some changes you mentioned you'd like to make, on last week's call. See discussion here where I gave some heads-up about this plan. 🙂 I think the risk of doing this is unknown, but most likely low: the last review (#4700 (review)) only requested tiny changes, and I made those. My sense is that the more substantive things Greg has in mind are mostly follow-up changes that don't require things to change inside this branch; I'll file an issue for those changes to be described and then made (edit: #4742). E.g., I guess it'd be ideal to have the best interface from the beginning, but addressing something like #4700 (comment) can very likely be done as a followup; things aren't unusably broken without that. Now, we can
|
Thanks @chrisbobbe! Sorry I dropped this for a bit. I actually thought I'd merged it an hour or two before you eventually did (i.e., late that morning here); must be that that failed with a "there are upstream changes, you need to rebase first" and I didn't notice. Here's the version I thought I'd pushed: I'll go ahead and push the additional commits that were in that version -- all comment- and doc-only changes. Other than those, the differences were just
So indeed, merging this version as it was was just fine. 🙂 Then after those I have some draft changes which split |
OK, pushed those additional commits: |
Great, thanks! |
This will give us more coverage of android when we're running tools/test in sloppy mode (which is the default). This does make things somewhat flaky, but on the whole it makes us more likely to notice failures that only occur on one platform sooner. See prior discussion: zulip#4700 (comment)
This will give us more coverage of android when we're running tools/test in sloppy mode (which is the default). This does make things somewhat flaky, but on the whole it makes us more likely to notice failures that only occur on one platform sooner. See prior discussion: #4700 (comment)
Forking from @WesleyAC's comment at #4694 (comment), which prompted me to realize that it's past time to have Jest include coverage of codepaths with both 'ios' and 'android' for
Platform.OS
.Both platforms will be covered in CI, but only one (iOS) will run by default in local testing, for speed. That can be changed by passing
--platform both
totools/test
.See discussion here.
Also fix some issues with the
replaceRevive
tests.