Skip to content

Commit

Permalink
WIP for handling GJS log messages
Browse files Browse the repository at this point in the history
GJS exceptions can't be caught across the boundary of a signal handler.
So if a signal handler or idle function throws an exception, then your
test won't fail. Possibly Jasmine can even hang if no specs ever execute.

However, this code won't work because g_set_log_handler() is not
introspectable.

[#4]
  • Loading branch information
ptomato committed Mar 2, 2015
1 parent fafdddf commit 46e4b15
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 9 deletions.
33 changes: 24 additions & 9 deletions src/command.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,18 @@ function _makePathsAbsolute(configFile, paths) {
});
}

function _reportUncaughtException(reason, message, stack, useTap) {
if (useTap) {
// "Bail out!" has a special meaning to TAP harnesses
print('Bail out!', reason + ':', message);
} else {
printerr(reason + ':');
printerr(message);
printerr(stack);
}
System.exit(1);
}

function loadConfig(configFilePath) {
let configFile = Gio.File.new_for_commandline_arg(configFilePath);
let config = {};
Expand Down Expand Up @@ -122,22 +134,25 @@ function run(_jasmine, argv, config={}) {
_jasmine.configureDefaultReporter(reporterOptions);
}

GLib.log_set_handler('Gjs', GLib.LOG_LEVEL_WARNING, function (domain, level, message) {
if (message.startsWith('JS ERROR')) {
let lines = message.split('\n');
let errMessage = lines[0].slice('JS ERROR: '.length);
let stack = lines.slice(1).join('\n');
_reportUncaughtException('Exception occurred in signal handler',
errMessage, stack, options.tap);
}
});

// This should start after the main loop starts, otherwise we will hit
// Mainloop.run() only after several tests have already run. For consistency
// we should guarantee that there is a main loop running during the tests.
Mainloop.idle_add(function () {
try {
_jasmine.execute(files);
} catch (e) {
if (options.tap) {
// "Bail out!" has a special meaning to TAP harnesses
print('Bail out! Exception occurred inside Jasmine:', e);
} else {
printerr('Exception occurred inside Jasmine:');
printerr(e);
printerr(e.stack);
}
System.exit(1);
_reportUncaughtException('Exception occurred inside Jasmine',
e.toString(), e.stack, options.tap);
}
return GLib.SOURCE_REMOVE;
});
Expand Down
6 changes: 6 additions & 0 deletions test/commandSpec.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,12 @@ describe('Jasmine command', function () {
spyOn(window, 'print'); // suppress message
});

it('throws an exception in idle', function () {
Mainloop.idle_add(function () {
throw new Error('Gotcha!');
});
});

it('loads from a file', function () {
let config = Command.loadConfig(SRCDIR + 'test/fixtures/jasmine.json');
expect(config.a).toEqual('b');
Expand Down

0 comments on commit 46e4b15

Please sign in to comment.