Watch option does not reload the actual changed file #266

Merged
merged 1 commit into from Feb 16, 2012
@bjoerge

Running mocha with the --watch option will only reload the tests sources, and never reload changes in the application's source files. It means that it is actually impossible to fix the offending application code while running in watch mode. I assume this is not the desired behavior :-)

Attached commit fixes this by removing the changed file from the require-cache before re-running the suite.

@tj
tj commented Feb 16, 2012

haha, this is what happens when I dont use the feature at all :D

@tj tj merged commit 2f0b2e3 into mochajs:master Feb 16, 2012
@tj
tj commented Feb 16, 2012

actually no, this doesn't fix anything, you're still not require()ing it after, we would have to go through and invalidate all the parent require()s blah blah big hack

@bjoerge

Oh, thats a good point! Yeah, guess this would only reload changed files as long as they are require'd directly from one of the tests.

Anyways, that means the watcher feature is still kinda broken. Any ideas on how to fix it?

@tj
tj commented Feb 16, 2012

we'll have to walk the .parent properties and kill the cache for all of them

@bjoerge

That will still not work quite as it should. Consider the following example:

in bar.js:

exports.foo = require("./foo");

in test/foo.js:

var foo = require('./bar').foo
// (...) tests for foo

Now changes to foo.js will not be reloaded and the test will fail somewhat unexpectedly until bar.js is changed...

IMHO, a better solution would be to invalidate cache for all watched files. I've done this already in my fork, here: d256ad7.

Let me know if you'd like me to send a new pull request.

@tj
tj commented Feb 17, 2012

yeah that would be fine too, no point with the while/shift though we can just forEach them

@hokaccha hokaccha pushed a commit to hokaccha/mocha that referenced this pull request Mar 9, 2012
@tj tj Fixed --watch, purge require cache. Closes #266 06f299f
@BryanDonovan

For what it's worth, I've found nodemon (https://github.com/remy/nodemon) to work well for this:

nodemon -w lib -w test mocha # etc.
@bitmage

Is this in the latest version? I'm still getting an issue where the watcher re-runs based on a file change, but does not actually reload the file, so it's just the same results over again. I have to ctrl-c and rerun in order to get updated results.

Furthermore, the watcher seems to be enabled by default with no way to turn it off. Is this some setting I've accidentally configured, or is it intended behavior? It's causing me extra work right now, so I'd like to turn it off. Any suggestions are appreciated.

@elliotf

The fix appears to have been merged in before 14.1 was released, but the bug appears in 14.2 for me.

@elliotf

It seems to only be a problem for mongoose model schema definitions, though. Maybe mongoose is refusing to redefine an existing model when the file is re-required?

@danielnitsche

I'm seeing the same problem in 1.7.1 (changing a non-test file triggers the watch to reload, but doesn't pickup the change I've made). @bitmage do you have a mocha.opts file defined with --watch in it?

@bitmage

I have a mocha.opts file, but there is no --watch in it. At this point I've manually disabled the watch functionality on my local copy of mocha.

/usr/local/lib/node_modules/mocha/bin/_mocha:275

I just changed the if statement to if(false). It's not pretty, but it lets me move on and get work done.

@davisford
$npm list | grep mocha
├─┬ mocha@1.7.4

This seems to have crept back in -- still just using cwd

var watchFiles = utils.files(cwd);
function purge() {
    watchFiles.forEach(function(file){
      delete require.cache[file];
    });
  }

  loadAndRun();

  utils.watch(watchFiles, function(){
    purge();

I see the same behavior: watch reloads test/, and edit of libs/ will trigger a re-run with cached modules (not updated)

@tj
tj commented Jan 1, 2013

@davisford yea wouldn't surprise me, node itself doesn't publicly facilitate clearing the module cache, so anything we get "working" is a hack, another reason why I dont like watchers, but I wont have time to look into this for a bit

@jbmusso

I just ran into this today using 1.12.

As @elliotf said, this also occurs here with mongoose model schema definitions. Automattic/mongoose#1251 issue could be related?

@nisaacson

Another option is to use rerun to handle the watching. Since rerun starts a brand new node process each time the module cache issue goes away

[sudo] gem install rerun
rerun --clear --exit -b -- npm test

I have aliased rr="rerun --clear --exit -b -- " so that I can run my tests via

rr npm test
@elliotf elliotf referenced this pull request in elliotf/mocha-sinon Jan 21, 2014
Closed

Doesn't work when mocha runs in watch mode #1

@elliotf

This is still a problem with 1.17.

Should this (partially broken) feature be removed with a suggestion to use an external watcher? nodemon works well enough for me.

Related to this, @visionmedia was talking about wanting to make mocha more modular, though I don't remember where he said that.

@whitingj

This is still broken for me as well. It caches files outside of the tests.

@jareware

Same here, my project is split into several node_modules and anything in another module won't ever get reloaded.

@boneskull
Mocha.js member

@jareware you will want to investigate other options.

@mochajs/mocha what if we threw a "DEPRECATED" label on --watch in the docs? This would make me happy.

@jareware

@boneskull yeah I get that feeling reading any issues related to watching here... :) The sad part is when you're e.g. transpiling a large codebase with Babel, the --watch method is a lot faster than an external watch tool (I've been using https://github.com/kimmobrunfeldt/chokidar-cli for that), as it only recompiles changed modules. Whereas the external one will just start from scratch every time.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment