Skip to content

Instantly share code, notes, and snippets.

@Toxicable
Last active June 6, 2018 22:17
Show Gist options
  • Save Toxicable/a6730d4364b5d84be69c93b356f6fad7 to your computer and use it in GitHub Desktop.
Save Toxicable/a6730d4364b5d84be69c93b356f6fad7 to your computer and use it in GitHub Desktop.
const fs = require('fs');
const path = require('path');
const JasmineRunner = require('jasmine/lib/jasmine');
const {createInterface} = require('readline');
const UTF8 = {
encoding: 'utf-8'
};
// These exit codes are handled specially by Bazel:
// https://github.com/bazelbuild/bazel/blob/486206012a664ecb20bdb196a681efc9a9825049/src/main/java/com/google/devtools/build/lib/util/ExitCode.java#L44
const BAZEL_EXIT_TESTS_FAILED = 3;
const BAZEL_EXIT_NO_TESTS_FOUND = 4;
// ibazel will write this string after a successful build
// We don't want to re-trigger tests if the compilation fails, so
// we should only listen for this event.
const IBAZEL_NOTIFY_BUILD_SUCCESS = 'IBAZEL_BUILD_COMPLETED SUCCESS';
// Set the StackTraceLimit to infinity. This will make stack capturing slower, but more useful.
// Since we are running tests having proper stack traces is very useful and should be always set to
// the maximum (See: https://nodejs.org/api/errors.html#errors_error_stacktracelimit)
Error.stackTraceLimit = Infinity;
function watch(manifest, jrunner) {
// ibazel communicates with us via stdin
const rl = createInterface({input: process.stdin, terminal: false});
rl.on('line', chunk => {
console.log('new line')
if (chunk === IBAZEL_NOTIFY_BUILD_SUCCESS) {
//TODO: clean out old files?
addFiles(manifest, jrunner);
jrunner.execute();
}
});
rl.on('close', () => {
console.log('someone trying to exit me')
// Give ibazel 5s to kill our process, otherwise do it ourselves
setTimeout(() => {
console.error('ibazel failed to stop jasmine after 5s; probably a bug');
process.exit(1);
}, 5000);
});
}
function addFiles(manifest, jrunner){
console.log(manifest)
fs.readFileSync(manifest, UTF8)
.split('\n')
.filter(l => l.length > 0)
.forEach(f => jrunner.addSpecFile(f));
}
function main(args) {
if (!args.length) {
throw new Error('Spec file manifest expected argument missing');
}
const manifest = require.resolve(args[0]);
// Remove the manifest, some tested code may process the argv.
process.argv.splice(2, 1)[0];
const jrunner = new JasmineRunner();
addFiles(manifest, jrunner);
var noSpecsFound = true;
jrunner.addReporter({
specDone: () => {
noSpecsFound = false
},
});
// addReporter throws away the default console reporter
// so we need to add it back
jrunner.configureDefaultReporter({});
jrunner.onComplete((passed) => {
let exitCode = passed ? 0 : BAZEL_EXIT_TESTS_FAILED;
if (noSpecsFound) exitCode = BAZEL_EXIT_NO_TESTS_FOUND;
process.exit(exitCode);
});
// TODO: find out how to determine if we're running under ibazel
if(true) {
// execute the first time then go into watch mode
jrunner.execute();
watch(manifest, jrunner);
} else {
jrunner.execute();
return 0;
}
}
if (require.main === module) {
process.exitCode = main(process.argv.slice(2));
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment