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
logger
property is used to log debugging information or errors. Uselogger.debug()
to log any debugging information that will only be reported withdebug: true
setting,logger.trace()
to log any debugging information that will only be reported withtrace: true
setting, orlogger.error
/logger.warn
to report errors. - The
anyFilesAdded
andanyFilesDeleted
properties return whether or not any files have been added or deleted for the current batch of changes. - The
nodeModulesDir
property returns the local project node modules folder. - The
baseDir
property returns wallaby cache project folder. Please note that tests run on the files in this folder (not on the local project files). - The
allFiles
,affectedFiles
andaffectedTestFiles
properties 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. TheallFiles
set contains theaffectedFiles
set, and theaffectedFiles
set contains theaffectedTestFiles
set. ‘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.js
is covered by tests from the fileb.js
, anda.js
changes, thenallFiles
will havea.js
,b.js
and other project files,affectedFiles
will containa.js
andb.js
, andaffectedTestFiles
will containb.js
. - The
createFile
function can create a new file, or overwrite or clone/transform an existing one. The function returns a promise. - The
setFileOrder
function can create change an order of an existing files without changing its content. The function takes an object withfile
andorder
properties as an argument, wherefile
should be set to the original file object andorder
to its desired order. The function returns a promise.
The file objects inside allFiles
, affectedFiles
and affectedTestFiles
have the following structure:
- The
path
string property contains the relative path of the file (relative tobaseDir
). - The
fullPath
string property contains the full path of the file inbaseDir
. - The
binary
boolean property returns true if the file is a binary file (file content in this case is a base64 encoded string). - The
ts
property contains the file change timestamp. - The
id
property contains the file integer identifier in wallaby.js. - The
type
property 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
load
boolean property is the same as in the configurationfiles
object. 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
instrument
boolean property is the same as in the configurationfiles
object. - The
test
boolean property allows you to determine whether the file is a test file. - The
getContent
function 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
path
string property that contains the relative path of the file (relative tobaseDir
). - The
load
boolean property is the same as in the configurationfiles
object. 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
order
numeric 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 toInfinity
will make it last. - The
ts
numeric 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,ts
will be set to the current time. - The
content
property is the string content of the file. - The
sourceMap
property 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 theoriginal
file property. - The
original
file property allows you to pass another file object, for example fromallFiles
,affectedFiles
oraffectedTestFiles
. When theoriginal
file 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.