Skip to content
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

Add typeahead to watch mode #2324

Merged
merged 11 commits into from Jan 13, 2017
Merged

Add typeahead to watch mode #2324

merged 11 commits into from Jan 13, 2017

Conversation

rogeliog
Copy link
Contributor

@rogeliog rogeliog commented Dec 14, 2016

Summary

@cpojer I found #2251 really interesting, so I started working on it just to get a bit more familiar with the internals of Jest, of which I know nothing.

This is a really primitive prototype, which still has several issues that need to be address, as well as testing.

This is the typeahead running in the React repo
jest-typeahead

In the issue you mentioned that there is some refactor that will make this easier to accomplish, so I guess that this might not be the right way of implementing it:

may be easier to accomplish once we do the following:

  • Split jest's watch feature into a separate package and refactor it.

Assuming that we want to move forward with the feature here are a couple of things that I'm still missing

  • A better understanding of Jest's architecture to figure out if that is the right place to put that logic.
  • Figure out the appropriate user experience for it.
  • Handling error cases and some keys that break it.
  • Handle pluralization(file vs files)
  • Handle screen resizing
  • Add tests to the typeahead.
  • Some weird cursor positioning
  • How expensive is Runtime.createHasteContext? Is it something that I should be caching?

@cpojer
Copy link
Member

cpojer commented Dec 14, 2016

Lol I literally just saw your comment on the issue and there is already a PR. Oh man. Let me see…

@cpojer
Copy link
Member

cpojer commented Dec 14, 2016

Ok, so this is really cool! You did point out the question about how expensive creating an instance of jest-haste-map is (through Runtime.createHasteContext) and this is really what this comes down to and why I recommended the refactor: In our internal codebases this takes upwards of 1-3 seconds, which is crazy long.

However, we implemented file-watching in jest-haste-map (using a watch argument) and we can actually change our watch mode here to use that, which will make the watch mode a ton faster for any mid to large project and will help us massively at FB.

Originally I was thinking the watch mode should be its own separate package but I don't think we need to go that far. If we split out the watch mode into a separate file within jest-cli, I'm fine with it too. You were able to figure out how it works really well but the current implementation is quite a mess and all the CLI code is just mixed in this one jest.js file. I don't have a strong opinion whether it should be its own package or not but the potential for it is that other test frameworks could potentially use the jest-watch package and get the same watch mode that we have, which would be pretty awesome!

So, to lay out the steps:

  • Refactor this watch mode into its own file.
  • Currently jest.js has its own watch feature and creates a haste context object inside of runJest. We need to invert this to create the haste context based on the configuration, set the watch flag to true in jest-haste-map and then use the change event to re-run Jest. This will also allow us to remove a bunch of duplicated code in jest.js.
  • Once we inverted this, running tests after a file change will be instant because we won't have to wait for jest-haste-map to reconcile with the file system. Basically instead of re-creating a haste context for each run, we'll have one in memory and get an updated version of hasteFS and moduleMap and a list of changed files with every file change event.

See https://github.com/facebook/react-native/blob/master/packager/react-packager/src/node-haste/index.js#L211-L216 for how the watch feature is used in react-native's packager.

After that we can consider:

  • How do we polish this typeahead? It may even make sense to get rid of the "usage" or condense the usage information, which can get pretty long and annoying.
  • How do we test all of this? Currently it is all manual; in the past we were thinking we could potentially use snapshot tests for this.
  • I think it would be pretty cool if we could highlight the matched parts in the test names with color, what do you think?

Again, I'd like to invite you to our discord channel ( http://facebook.github.io/jest/support.html ) and I'm also happy to have a chat over google hangouts or something to walk you through in person.

Let me know what you think about this plan! I love that you started on this and this refactor is going to make Jest a ton faster for engineers at FB :)

@codecov-io
Copy link

codecov-io commented Dec 15, 2016

Current coverage is 66.19% (diff: 85.24%)

Merging #2324 into master will increase coverage by 1.38%

@@             master      #2324   diff @@
==========================================
  Files           125        122     -3   
  Lines          4871       4840    -31   
  Methods           0          0          
  Messages          0          0          
  Branches          0          0          
==========================================
+ Hits           3157       3204    +47   
+ Misses         1714       1636    -78   
  Partials          0          0          

Powered by Codecov. Last update 8256904...e250003

@rogeliog
Copy link
Contributor Author

Thanks a lot, this feedback is super helpful, I'll definitely reach out if needed :)

@rogeliog rogeliog mentioned this pull request Dec 19, 2016
@cpojer
Copy link
Member

cpojer commented Jan 8, 2017

Alright, now that watch mode was rewritten, I believe we can pretty easily make this work with a great experience!

Some thoughts:

  • I'd recommend against a testPatternTypeahead option for now.
  • Can we highlight the matched parts in the typeahead? @thymikee is an expert on pretty cli printing now. Any suggestions?
  • cc @gaearon and @tomocchino who are UX experts on this. Do you have any thoughts about what this should feel like?

@thymikee
Copy link
Collaborator

thymikee commented Jan 8, 2017

I'm a big fan of highlighting search phrases. I believe yellow bg with dark text would be more than enough here, just like with Ctrl+F on Chrome

@cpojer
Copy link
Member

cpojer commented Jan 8, 2017

That may work well, yeah! The other option I can think of is dim vs reset for matches, which is more subtle.

@rogeliog
Copy link
Contributor Author

rogeliog commented Jan 9, 2017

Here are some gifs of how each of the highlighting options could look :)

typeahead-dim
typeahead-yellow

@benmccormick
Copy link
Contributor

👍 for the highlighting option. The dimming is clean but a bit too subtle I think. Also not sure how it would look on a light terminal background

@gaearon
Copy link
Contributor

gaearon commented Jan 10, 2017

I would personally prefer the less aggressive dimming.
(I got a bit confused by the Twitter poll and what everybody referred to as “highlighting”.)

Chrome does highlighting because you need to find these words between other words on the page. In this case, all results are displayed below, and you don’t really need to interact with them anyway. I’m not convinced we need to use a bright color here but YMMV.

@cpojer
Copy link
Member

cpojer commented Jan 10, 2017

I agree with @gaearon. I think dimming is fine for this.

@thymikee
Copy link
Collaborator

thymikee commented Jan 10, 2017

I'm also happier with dimming/highlighting text instead of background highlight 🙂

@cpojer
Copy link
Member

cpojer commented Jan 10, 2017

Alright, @rogeliog let's go with the dimming for now and see how people react to the next release.

const typeahead = (hasteMap, patternInfo) => {
return new SearchSource(hasteMap, config)
.getTestPaths(patternInfo)
.then(data => {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

these should be indented by two spaces.

  return foo
    .then(…)

let typeaheadLinesToClear = 0;

const typeahead = (hasteMap, patternInfo) => {
return new SearchSource(hasteMap, config)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do we need to create a new SearchSource every time the user types? I don't know how slow it is

if (!currentPattern) {
return [];
} else if (total === 0) {
return ['No matching files...'];
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you find of a good way to highlight this? Maybe yellow? Check out what happens when you do jest j23lk2j34l2k on the repo, it will print a nice "No tests found" message, maybe we could align these two things.

@jest-bot
Copy link
Contributor

jest-bot commented Jan 10, 2017

Warnings
⚠️ Please ensure that @flow is enabled on: packages/jest-cli/src/__tests__/watch-pattern-mode-test.js and packages/jest-cli/src/lib/__tests__/highlight-test.js

Generated by 🚫 dangerJS

@cpojer
Copy link
Member

cpojer commented Jan 11, 2017

Alright I think this looks good. The one problem I noticed is when my terminal output pushes me down to the bottom of the screen because of some failures. Typing feels a bit odd then, not sure if we can fix that? Shall we wipe away everything on the screen when entering pattern mode?

@rogeliog was there anything else you wanted to do on this diff?

@rogeliog rogeliog changed the title [WIP] Add typeahead to selection in watch mode Add typeahead to selection in watch mode Jan 11, 2017
@rogeliog rogeliog changed the title Add typeahead to selection in watch mode Add typeahead to watch mode Jan 11, 2017

hasteMap.on('change', ({hasteFS, moduleMap}) => {
hasteContext = createHasteContext(config, {hasteFS, moduleMap});
currentPattern = '';
isEnteringPattern = false;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

did you test this with file changes while you were typing?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep, let me upload some gifs to show the issue

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

pattern

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yup that's what I expected. Nice.

@rogeliog
Copy link
Contributor Author

@cpojer I think it is in a good shape now, apart of the issue when there is not enough room in the terminal. We probably do need to find a good solution for it before merging, because it currently breaks really badly 😞

@cpojer
Copy link
Member

cpojer commented Jan 11, 2017

Do you have any ideas for that one? What about clearing the terminal when entering pattern mode?

@rogeliog
Copy link
Contributor Author

@cpojer Yeah I think we are going to have to do something like that.

Here are some of my thoughts on this

1) Clear the terminal and only show pattern mode

pattern › 


I like how clean this option is but it might also be a bit confusing. We could add a Press ESC to show usage

› Press ESC to show usage.

pattern › 


2) Clear the terminal and show both usage and pattern mode

Watch Usage
 › Press a to run all tests.
 › Press o to only run tests related to changed files.
 › Press p to filter by a filename regex pattern.
 › Press q to quit watch mode.
 › Press Enter to trigger a test run.

 pattern ›


This one might end up in a more familiar experience for current Jest users.

Some issues

Losing test results

One problem I see with either of this solutions is that we lose the test results

Test Suites: 2 passed, 2 total
Tests:       6 passed, 6 total
Snapshots:   9 passed, 9 total
Time:        0.209s, estimated 1s
Ran all test suites related to changed files.

Handle small terminals

Regardless of which one we choose we might still need to handle the case where the terminal height is less than the number of lines printed by pattern mode. Depending on which solution we choose this might not be as much of an issue.

@cpojer
Copy link
Member

cpojer commented Jan 11, 2017

I think showing watch usage only when going into pattern mode might be the least complex and most sensible solution for now. Let's not worry too much about small terminals.


if (pattern) {
if (total) {
pipe.write(`\n\n Pattern matches ${total} ${pluralizeFile(total)}...`);
Copy link
Contributor

@gaearon gaearon Jan 11, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why the ... here? IMO it's unnecessary.

Usually ... is used in the UI on the buttons that present an additional dialog (e.g. Open...).

In this case just . will do.

@rogeliog
Copy link
Contributor Author

rogeliog commented Jan 12, 2017

@cpojer, @gaearon here a gif of the experience as of the latest commit in this PR

pattern-mode-final

After we decide to merge this, there are a couple polish items that I would like to focus on to make the typeahead experience as smooth as is should be. For example: Handling screen resizes by truncateing(...) the results appropiately and investigate a way allow the use of arrows...

Also, I took some decisions on the copy for the "Pattern mode", feedback is more than welcome 😄

@cpojer cpojer merged commit fddd6d3 into jestjs:master Jan 13, 2017
@cpojer
Copy link
Member

cpojer commented Jan 13, 2017

Let's do it. @rogeliog do you care to create a master issue (+ smaller issues referenced from it) to track further polish work? This is a really delightful experience and I'm looking forward to further improvements.

@gaearon
Copy link
Contributor

gaearon commented Jan 13, 2017

So nice.

skovhus pushed a commit to skovhus/jest that referenced this pull request Apr 29, 2017
* Extract typeahead printing logic

* Handle escape when in typeahead

* Add tests and highlight

* Update Flow and fix flow errors.

* Improve printing of test paths.

* Polish

* Fix node 4 CI

* Reset pattern state if FS changes

* Only instantiate searchSource once

* Clear screen when entering typeahead

* Show "pattern mode" and clear screen
tushardhole pushed a commit to tushardhole/jest that referenced this pull request Aug 21, 2017
* Extract typeahead printing logic

* Handle escape when in typeahead

* Add tests and highlight

* Update Flow and fix flow errors.

* Improve printing of test paths.

* Polish

* Fix node 4 CI

* Reset pattern state if FS changes

* Only instantiate searchSource once

* Clear screen when entering typeahead

* Show "pattern mode" and clear screen
@github-actions
Copy link

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.
Please note this issue tracker is not a help forum. We recommend using StackOverflow or our discord channel for questions.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators May 14, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

8 participants