-
-
Notifications
You must be signed in to change notification settings - Fork 6.5k
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
Fix bug with watchers on macOS causing test to crash #2957
Conversation
Codecov Report
@@ Coverage Diff @@
## master #2957 +/- ##
==========================================
+ Coverage 67.6% 67.61% +<.01%
==========================================
Files 146 146
Lines 5338 5339 +1
==========================================
+ Hits 3609 3610 +1
Misses 1729 1729
Continue to review full report at Codecov.
|
Thanks! Shouldn't we use |
@cpojer - For examples Create React App uses: |
Hmm, in Jest, |
Ping @ro-savage! |
@cpojer - Updated to use Tested by linking updated jest. Would crash with when package.json was using Previous to this, we were using this fix locally and was working 100% of the time for a week (20+ runs). I don't think anyone has taken time to test. But certainly appears to fix the issue and as far as I can tell the changes a very minor and shouldn't cause any unforeseen issues. Let me know if you'd like to merge and I can rebase into a single commit. |
Wait, are you sure this version works? Sane uses |
Yes I am sure. I tested with and without the anymatch accepts
and was taking a regex in the first PR as well which has been more extensively tested. |
Would you mind double checking whether a duck-typed RegEx will also work? We are using it here: https://github.com/facebook/react-native/blob/0cb2bc104f9958dfea2a7e22b229a19abeb59fca/packager/src/node-haste/index.js#L105 Arguably that's not a great use of this API, but we had to make it work. If this doesn't work, we have to change the code in react-native to support it somehow :) |
So if this was used as the I am not sure why it's ducked typed? We could make it a real |
Mainly because we couldn't change react-native. react-native needs a function to evaluate this instead of a regex and we need to make sure this use-case continues to work. We can type |
Yes that sounds correct to me. (Although I admit I still don't fully understand how the ducktyping works. As |
That's because the only use of the pattern is here: https://github.com/cpojer/jest/blob/master/packages/jest-haste-map/src/index.js#L687 Would you mind changing the flow types to also accept a function instead and change the code to call |
Sorry, not entirely sure what you'd like me to do. Do you mean changing So that anymatch will received the regex, or a function/string held in And then flowtype should be Or... Will react-native here https://github.com/facebook/react-native/blob/0cb2bc104f9958dfea2a7e22b229a19abeb59fca/packager/src/node-haste/index.js#L105 be changed to pass a function? In which case Or... Did I totally miss what you wanted? |
The latter, yes! You still need to update the one place inside of jest-haste-map where we call test directly to check for function/regex and do the right thing. |
I spent a while trying to figure this flowtype error out, but no luck. (Never used flow type or any type system before).
_ignore(filePath: Path): boolean {
const ignorePattern = this._options.ignorePattern;
const ignoreMatched =
Object.prototype.toString.call(ignorePattern) === '[object RegExp]'
? ignorePattern.test(filePath)
: ignorePattern(filePath);
return (
ignoreMatched ||
(!this._options.retainAllFiles && this._isNodeModulesDir(filePath))
);
} typecheck throws
My guess is this is because RegExp aren't callable in their type definition. But I don't understand why it doesn't use the |
Ah ok, for this one, you can do |
62ddbe3
to
ef28d7b
Compare
Dang. Spent a while trying to figure that one out. Changes have been made. As usual, let me know any feedback. Or if ready to merge I can rebase into a single commit. |
Let's do it. Thanks @ro-savage |
return this._options.ignorePattern.test(filePath) || | ||
const ignorePattern = this._options.ignorePattern; | ||
const ignoreMatched = | ||
Object.prototype.toString.call(ignorePattern) === '[object RegExp]' |
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.
You can do ignorePattern instanceof RegExp
, maybe flow understands that?
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.
Yep that worked actually. Will submit another PR to make that change. Thanks for the tip Simen.
* Update to pass ignorepath regex to sane * Changed jest-haste-map to pass modulePathIgnorePatterns * Update jest-haste-map ignorePattern to accept RegExp or Function
…e key (#4063) I plan to revert `ignorePattern` to only being a strict `RegExp`, after removing the function use case from React Native and Metro bundler. The reason for getting rid of the function use case is that `ignorePattern` should be part of the cache key, and a function is not analysable at runtime. If it can only be a `RegExp`, then we can use `ignorePattern.toString()` as part of the cache key. The reason it needs to be part of the cache key is because the cache needs to be discarded—or at least reevaluated—when the ignore pattern changes. Otherwise, we can be missing some new modules that should be included, or the reverse, we can be including modules that should now be ignored. I have observed considerable trouble caused by this issue. For example, in React Native, people would reload a project and it wouldn't find a module, or, duplicates modules would be detected while in fact one of them should have been ignored. This changeset add a deprecation notice for the functional use case (so that we can release this as a minor/revision), and starts using the string representation of the ignore pattern in the cache key (so that we can get a correct behavior as soon as possible for callsites that do already use a `RegExp`). See also #2957, that introduced `ignorePattern` as a function. Alternatively, we could require callsites to provide their own cache key if they do want to use a function, but this makes it more complicated and I'm not sure there's really any other callsites than React Native that does that, that we will fix ourselves as well.
* Update to pass ignorepath regex to sane * Changed jest-haste-map to pass modulePathIgnorePatterns * Update jest-haste-map ignorePattern to accept RegExp or Function
…e key (jestjs#4063) I plan to revert `ignorePattern` to only being a strict `RegExp`, after removing the function use case from React Native and Metro bundler. The reason for getting rid of the function use case is that `ignorePattern` should be part of the cache key, and a function is not analysable at runtime. If it can only be a `RegExp`, then we can use `ignorePattern.toString()` as part of the cache key. The reason it needs to be part of the cache key is because the cache needs to be discarded—or at least reevaluated—when the ignore pattern changes. Otherwise, we can be missing some new modules that should be included, or the reverse, we can be including modules that should now be ignored. I have observed considerable trouble caused by this issue. For example, in React Native, people would reload a project and it wouldn't find a module, or, duplicates modules would be detected while in fact one of them should have been ignored. This changeset add a deprecation notice for the functional use case (so that we can release this as a minor/revision), and starts using the string representation of the ignore pattern in the cache key (so that we can get a correct behavior as soon as possible for callsites that do already use a `RegExp`). See also jestjs#2957, that introduced `ignorePattern` as a function. Alternatively, we could require callsites to provide their own cache key if they do want to use a function, but this makes it more complicated and I'm not sure there's really any other callsites than React Native that does that, that we will fix ourselves as well.
This pull request has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs. |
Summary
This fixes an issue on OS X when there are too many files/folders to watch that causes the test to crash with error
2016-09-22 10:49 node[79167] (FSEvents.framework) FSEventStreamStart: register_with_server: ERROR: f2d_register_rpc() => (null) (-22)
See Issue #1767
This solve the issue by updating sane to 1.6.0 and passing a regular expression passed on the the
testPathIgnorePatterns
config option. This allowssane
to never apply the watchers.Currently there are no defaults. Maybe it should default to ignoring
.git|node_modules
if nothing is passed? Or else people may still encounter the error.The error is caused by some mixture node/OSX. (See nodejs/node-v0.x-archive/issues/5463), where node/osx can't handle the amount of watchers.
Reproduction
On macOS Sierra, uninstall watchman (if installed), run test in watch mode on a sufficiently large app. Jest exits with exception.
Test plan
I am unsure how to test this change. Feedback welcome.
Questions
I was unsure of the best way to handle the typing.
I went with
testPathIgnorePattern: RegExp | null,
with allows us to pass null if no test patterns have been supplied.The other option was to pass a RegExp of
/(?:)/
that matches everything, and then expect only type RegExp.Help wanted
I have tested this on my machine and it working (linking to my project that fails usually). It has also passed the the test suite.
It would be great to have it tested by others to make sure that it solves the problem for everyone. Any who encountered the issue in the past and solve by installing
watchman
will need to uninstall (brew uninstall watchman
) and try run the tests.Steps to test:
brew uninstall watchman
git clone https://github.com/ro-savage/jest.git
git checkout fix-watcher-bug-osx
yarn install
yarn build
cd packages/jest-cli
yarn link
Then go to your project that you had crashing tests in a run
yarn link "jest-cli"
Make sure you have
testPathIgnorePatterns
config set to includenode_modules
Run your tests as usual.
Feedback
This is a minor code change, but took me a long time to track down and fix (and its now 430am). Any feedback, suggestions are very welcome.