For every file change or batch of file changes, wallaby.js uses the following processing pipeline:
- compilers
- instrumentation
- preprocessors
- postprocessor
- test run
Wallaby.js compilers and preprocessors are simple stateless functions that take a file argument and are supposed to return processed content along with some other related data. It is not recommended to keep any state between function calls because preprocessors and compilers may run in different node processes.
Postprocessor is a function that runs for every batch of file changes after all compilers and preprocessors. It has access not to just one file, but to all files (compiled and preprocessed, as well as original ones). It is also guaranteed to always run in the same node process, so it can keep some required state.
Considering all of the above, postprocessor is an ideal place for something like a module bundler, or anything else that needs to keep some state between test runs and have access to all files at the same time.
From an implementation perspective, postprocessor is a function that takes a single argument and is supposed to return a promise.
module.exports = function () {
return {
files: [
'src/**/*.js'
],
tests: [
'test/**/*Spec.js'
],
postprocessor: function (wallaby) {
return new Promise(
function (resolve, reject) {
try {
// postprocessor work here
// ...
// resolve when the work is done
// or reject on errors
resolve();
} catch (err) {
reject(err);
}
});
}
};
};
The function argument is the wallaby.js context where you can find some properties and functions to control emitted test files. Here is a list of the argument properties and functions:
- The
loggerproperty is used to log debugging information or errors. Uselogger.debug()to log any debugging information that will only be reported withdebug: truesetting,logger.trace()to log any debugging information that will only be reported withtrace: truesetting, orlogger.error/logger.warnto report errors. - The
anyFilesAddedandanyFilesDeletedproperties return whether or not any files have been added or deleted for the current batch of changes. - The
nodeModulesDirproperty returns the local project node modules folder. - The
baseDirproperty returns wallaby cache project folder. Please note that tests run on the files in this folder (not on the local project files). - The
allFiles,affectedFilesandaffectedTestFilesproperties return an array of all file objects that are tracked by wallaby.js, all source and test files affected by the current batch of file changes, and just the test files affected by the current batch of file changes, respectively. TheallFilesset contains theaffectedFilesset, and theaffectedFilesset contains theaffectedTestFilesset. ‘Affected’ in the context of test files means not only changed test files, but also files containing tests to run as a result of the whole change. For example, if the filea.jsis covered by tests from the fileb.js, anda.jschanges, thenallFileswill havea.js,b.jsand other project files,affectedFileswill containa.jsandb.js, andaffectedTestFileswill containb.js. - The
createFilefunction can create a new file, or overwrite or clone/transform an existing one. The function returns a promise. - The
setFileOrderfunction can create change an order of an existing files without changing its content. The function takes an object withfileandorderproperties as an argument, wherefileshould be set to the original file object andorderto its desired order. The function returns a promise.
The file objects inside allFiles, affectedFiles and affectedTestFiles have the following structure:
- The
pathstring property contains the relative path of the file (relative tobaseDir). - The
fullPathstring property contains the full path of the file inbaseDir. - The
binaryboolean property returns true if the file is a binary file (file content in this case is a base64 encoded string). - The
tsproperty contains the file change timestamp. - The
idproperty contains the file integer identifier in wallaby.js. - The
typeproperty contains the file type, like ‘js’ or ‘html’. The type is initially taken from the file name extension. Note that compilers and preprocessors may change the type (compilers do it without changing the file name extension). - The
loadboolean property is the same as in the configurationfilesobject. In case of JavaScript file type, it allows you to determine whether the file is loaded via a script tag into the generated sandbox. - The
instrumentboolean property is the same as in the configurationfilesobject. - The
testboolean property allows you to determine whether the file is a test file. - The
getContentfunction returns a promise; when resolved it returns the file string content.
File objects passed to the createFile function as an argument should have the following structure:
- The
pathstring property that contains the relative path of the file (relative tobaseDir). - The
loadboolean property is the same as in the configurationfilesobject. In case of JavaScript file type, it allows you to determine whether the file is loaded via a script tag into the generated sandbox. If not set, the default value istrue. - The
ordernumeric property that allows you to control the file order in the list of all files included into the sandbox. Setting it to some negative value tells wallaby.js that the file should be first; setting it toInfinitywill make it last. - The
tsnumeric property allows you to set the file timestamp. File timestamps are used in the caching mechanism; if the timestamp doesn’t change, browser/phantomJs may use a cached copy. If not passed explicitly,tswill be set to the current time. - The
contentproperty is the string content of the file. - The
sourceMapproperty allows you to pass the source map in case the created file is a transformed version of some other file. The property should be used in conjunction with theoriginalfile property. - The
originalfile property allows you to pass another file object, for example fromallFiles,affectedFilesoraffectedTestFiles. When theoriginalfile is passed along withsourceMap, wallaby.js will make sure to correctly connect the transformed and original files so that when the transformed file code is executed in the generated sandbox, error stack and code coverage is reported for the original file. This can be useful when you would like to execute a transformed version of some file without overwriting the original version.
For examples on how to write your own postprocessor, look into the wallaby.js postprocessor for webpack, browserify, or wallaby-angular-filesort.