testr.js
testr.js copied to clipboard
Require callbacks not being fired
I believe I have found a bug and would like to clarify. Around line 100 of testr.js you will find:
var thisRequire = origRequire(cfg, cfg.deps, function() {
cfg.callback && cfg.callback();
if(++requireLoadedCount === requireCount) {
// all requires have finished loading, execute testr callback
complete();
}
}
This is part of the replacement require function. cfg.callback is invoked if it is defined, however cfg.callback is never set to a value. I believe the code should be invoking the callback passed to the require function as when I call require with testr loaded on the page none of the require callback methods are invoked.
Hi Ben,
That sounds like it's functioning as it should. When testr is present on the page, the callbacks are collected but never executed. They are treated as factory functions which will return a new instance of the module when required.
To extract a new instance of a module (which, in turn, executes the callback), use var module = testr('path/to/module');
Cheers, Matt.
I agree this is the desired behaviour for calls to define. The factory functions are not immediately executed as it is not known what to resolve the dependencies of the factory to until testr is invoked.
However my issue is with the require function, not the define function. I do not believe this is how the require function should behave, specifically when it is called in order to load modules needed to set up the test fixture. And the code quoted above seems to be written to deal with exactly this case. It looks to me like it is supposed to execute the callback passed to require but is pointing to the wrong place.
cfg.callback && cfg.callback();
should be
callback && callback()
I should point out that requirejs was written in a way that allows multiple types of setup, which is probably the cause of most of the confusion when setting up testr.js. With requirejs, you can have:
// method one
require(['app'], function(app) {
app.run();
});
or
// method two
require({
deps: ['app'],
callback: function(app) {
app.run();
}
});
testr.js will only execute the callback in the second method and not the first. This is because callbacks to the require function are typically used to bootstrap the app, which you would not want to do in a test environment, given that you are interested in only testing individual modules. Method two was setup to execute the callback so that you have the option of executing or not.
Give method two a try and let me know how you go with it. Alternatively, happy to look at a example repo.
Cheers, Matt.
@BenSayers any luck?