Implement a simple, non-interactive --watch
mode
#4
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
This PR introduces a
--watch
mode, inspired by similar features in jest, guard, and retest.It uses the listen gem to monitor the file system for changes. When changes are detected, mighty_test uses a simple heuristic to locate the test file(s) associated with the changes. This logic is encapsulated in a new
FileSystem
class.Tests are run via an event loop. This simplifies testing, as it means the test execution happens synchronously on the main thread, even though the file system changes are detected asynchronously via a background thread managed by the listen gem. The file system changes detected in the listener thread are posted as event to the run loop, which then gets picked up and processed on the next "tick".
The event loop is implemented using Concurrent::MVar, which is essentially a blocking queue of length 1 to which events are posted and then consumed.
The tricky part of implementing this is how to handle ctrl-c. Normally when ctrl-c is pressed, all Ruby threads are interrupted with an
Interrupt
exception, and all child processed are killed. This includes the background process that is monitoring for file system changes.I want ctrl-c to interrupt any tests that are currently being run, but not exit the watch process. This will allow a user to interrupt a slow/stuck test and then continue TDD, without having to start the watch command again from scratch.
My solution was to
rescue Interrupt
when running tests, and then restart the file system listener (since ctrl-c will have killed its background process). This seems to work well.If a test is not currently running, then ctrl-c works normally and causes the watch process to exit.