fix(client): use proxy logger in test worker

This commit is contained in:
Valeriy S
2018-12-10 15:06:39 +03:00
committed by Stuart Taylor
parent 8d2c350b3f
commit de7798c753
3 changed files with 40 additions and 15 deletions

View File

@ -3,12 +3,11 @@ import '@babel/polyfill';
const oldLog = self.console.log.bind(self.console); const oldLog = self.console.log.bind(self.console);
self.console.log = function proxyConsole(...args) { self.console.log = function proxyConsole(...args) {
self.__logs = [...self.__logs, ...args]; self.postMessage({ type: 'LOG', data: String(args) });
return oldLog(...args); return oldLog(...args);
}; };
onmessage = async e => { onmessage = async e => {
self.__logs = [];
const { script: __test, code } = e.data; const { script: __test, code } = e.data;
/* eslint-disable no-unused-vars */ /* eslint-disable no-unused-vars */
const assert = chai.assert; const assert = chai.assert;
@ -21,14 +20,13 @@ onmessage = async e => {
if (typeof testResult === 'function') { if (typeof testResult === 'function') {
await testResult(() => code); await testResult(() => code);
} }
self.postMessage({ pass: true, logs: self.__logs.map(String) }); self.postMessage({ pass: true });
} catch (err) { } catch (err) {
self.postMessage({ self.postMessage({
err: { err: {
message: err.message, message: err.message,
stack: err.stack stack: err.stack
}, }
logs: self.__logs.map(String)
}); });
if (!(err instanceof chai.AssertionError)) { if (!(err instanceof chai.AssertionError)) {
console.error(err); console.error(err);

View File

@ -67,15 +67,29 @@ function* ExecuteChallengeSaga() {
} }
} }
function* logToConsole(channel) {
yield takeEvery(channel, function*(args) {
yield put(updateLogs(args));
});
}
function* ExecuteJSChallengeSaga() { function* ExecuteJSChallengeSaga() {
const files = yield select(challengeFilesSelector); const files = yield select(challengeFilesSelector);
const { code, solution } = yield call(buildJSFromFiles, files); const { code, solution } = yield call(buildJSFromFiles, files);
const consoleProxy = yield channel();
yield fork(logToConsole, consoleProxy);
const log = args => consoleProxy.put(args);
testWorker.on('LOG', log);
const testResults = yield call(executeTests, { const testResults = yield call(executeTests, {
testRunner: testWorker, testRunner: testWorker,
code, code,
solution solution
}); });
testWorker.remove('LOG', log);
consoleProxy.close();
return testResults; return testResults;
} }
@ -86,12 +100,6 @@ function createTestFrame(state, ctx, proxyLogger) {
}).then(() => console.log('Frame ready')); }).then(() => console.log('Frame ready'));
} }
function* logToConsole(channel) {
yield takeEvery(channel, function*(args) {
yield put(updateLogs(args));
});
}
function* ExecuteDOMChallengeSaga() { function* ExecuteDOMChallengeSaga() {
const state = yield select(); const state = yield select();
const ctx = yield call(buildFromFiles, state); const ctx = yield call(buildFromFiles, state);
@ -166,14 +174,11 @@ function* executeTests({ testRunner, code = '', solution = '' }) {
for (const { text, testString } of tests) { for (const { text, testString } of tests) {
const newTest = { text, testString }; const newTest = { text, testString };
try { try {
const { pass, err, logs = [] } = yield call( const { pass, err } = yield call(
testRunner.execute, testRunner.execute,
{ script: solution + '\n' + testString, code }, { script: solution + '\n' + testString, code },
testTimeout testTimeout
); );
for (const log of logs) {
yield put(updateLogs(log));
}
if (pass) { if (pass) {
newTest.pass = true; newTest.pass = true;
} else { } else {

View File

@ -2,6 +2,7 @@ export default class WorkerExecutor {
constructor(workerName) { constructor(workerName) {
this.workerName = workerName; this.workerName = workerName;
this.worker = null; this.worker = null;
this.observers = {};
this.execute = this.execute.bind(this); this.execute = this.execute.bind(this);
this.killWorker = this.killWorker.bind(this); this.killWorker = this.killWorker.bind(this);
@ -36,6 +37,13 @@ export default class WorkerExecutor {
// Handle result // Handle result
worker.onmessage = e => { worker.onmessage = e => {
if (e.data && e.data.type) {
const observers = this.observers[e.data.type] || [];
for (const observer of observers) {
observer(e.data.data);
}
return;
}
clearTimeout(timeoutId); clearTimeout(timeoutId);
resolve(e.data); resolve(e.data);
}; };
@ -46,4 +54,18 @@ export default class WorkerExecutor {
}; };
}); });
} }
on(type, callback) {
const observers = this.observers[type] || [];
observers.push(callback);
this.observers[type] = observers;
}
remove(type, callback) {
const observers = this.observers[type] || [];
const index = observers.indexOf(callback);
if (index !== -1) {
observers.splice(index, 1);
}
}
} }