diff --git a/webapp/src/app/live-edit.js b/webapp/src/app/live-edit.js index 99802c08..41cf355f 100644 --- a/webapp/src/app/live-edit.js +++ b/webapp/src/app/live-edit.js @@ -32,48 +32,46 @@ class LiveEdit { .replace(/'/g, '''); } - processGccCompletion(result) { - SysGlobalObservables.gccErrorCount(0); - SysGlobalObservables.gccWarningCount(0); - - if (!result) { - // cancelled - SysGlobalObservables.compileStatus('Cancelled'); - return; - } - - // null if cancelled - // result = { 'exitcode':gcc_exit_code, 'stats':stats,'annotations':annotations,'gcc_ouput':gcc_output} - - this.runtime.sendKeys('tty0', 'clear\n'); - - const aceAnnotations = []; - const buildCmdErrors = []; - result.annotations.forEach((annotation) => { - if (annotation.isBuildCmdError) { - buildCmdErrors.push(annotation); + runCode(buildCmd, execCmd) { + SysGlobalObservables.fileBrowser.saveActiveFile(); + const callback = (result) => { + SysGlobalObservables.gccErrorCount(0); + SysGlobalObservables.gccWarningCount(0); + + if (!result) { + // cancelled + SysGlobalObservables.compileStatus('Cancelled'); + return; + } + + // null if cancelled + // result = { 'exitcode':gcc_exit_code, 'stats':stats,'annotations':annotations,'gcc_ouput':gcc_output} + + this.runtime.sendKeys('tty0', 'clear\n'); + + const aceAnnotations = []; + const buildCmdErrors = []; + result.annotations.forEach((annotation) => { + if (annotation.isBuildCmdError) { + buildCmdErrors.push(annotation); + } else { + aceAnnotations.push(annotation); + } + }); + + SysGlobalObservables.editorAnnotations(aceAnnotations); + SysGlobalObservables.lastGccOutput(result.gccOutput); + SysGlobalObservables.gccErrorCount(result.stats.error); + SysGlobalObservables.gccWarningCount(result.stats.warning); + SysGlobalObservables.gccOptsError(buildCmdErrors.map((error) => error.text).join('\n')); + + if (result.exitCode === 0) { + SysGlobalObservables.compileStatus(result.stats.warning > 0 ? 'Warnings' : 'Success'); + this.runtime.sendExecCmd(execCmd); } else { - aceAnnotations.push(annotation); + SysGlobalObservables.compileStatus('Failed'); } - }); - - SysGlobalObservables.editorAnnotations(aceAnnotations); - SysGlobalObservables.lastGccOutput(result.gccOutput); - SysGlobalObservables.gccErrorCount(result.stats.error); - SysGlobalObservables.gccWarningCount(result.stats.warning); - SysGlobalObservables.gccOptsError(buildCmdErrors.map((error) => error.text).join('\n')); - - if (result.exitCode === 0) { - SysGlobalObservables.compileStatus(result.stats.warning > 0 ? 'Warnings' : 'Success'); - this.runtime.sendExecCmd(SysGlobalObservables.execCmd()); - } else { - SysGlobalObservables.compileStatus('Failed'); } - } - - runCode(buildCmd) { - SysGlobalObservables.fileBrowser.saveActiveFile(); - const callback = this.processGccCompletion.bind(this); SysGlobalObservables.compileStatus('Compiling'); this.runtime.startBuild(buildCmd, callback); } diff --git a/webapp/src/app/sys-global-observables.js b/webapp/src/app/sys-global-observables.js index dc1b8090..28dabe62 100644 --- a/webapp/src/app/sys-global-observables.js +++ b/webapp/src/app/sys-global-observables.js @@ -4,10 +4,11 @@ export const vmState = ko.observable(''); export const compileStatus = ko.observable(''); export const focusTerm = ko.observable((tty) => {}); -export const runCode = ko.observable((gccOptions) => {}); +export const runCode = ko.observable((gccOptions, nextCommand) => {}); export const buildCmd = ko.observable(''); export const execCmd = ko.observable(''); +export const testCmd = ko.observable(''); export const lastGccOutput = ko.observable(''); export const gccOptsError = ko.observable(''); diff --git a/webapp/src/app/sys-runtime.js b/webapp/src/app/sys-runtime.js index 270c3a55..95b89167 100644 --- a/webapp/src/app/sys-runtime.js +++ b/webapp/src/app/sys-runtime.js @@ -226,9 +226,6 @@ class SysRuntime { if (!cmd) { return; } - if (cmd[0] !== '/' && cmd[0] !== '.') { - cmd = './' + cmd.replace(' ', '\\ '); - } cmd = cmd.replace('\\', '\\\\').replace('\n', '\\n'); // Don't \x03 ; it interrupts the clear command this.sendKeys('tty0', '\n' + cmd + '\n'); diff --git a/webapp/src/components/compiler-controls/compiler-controls.html b/webapp/src/components/compiler-controls/compiler-controls.html index b5413a3a..dedd71e8 100644 --- a/webapp/src/components/compiler-controls/compiler-controls.html +++ b/webapp/src/components/compiler-controls/compiler-controls.html @@ -23,5 +23,12 @@ Run It
+ diff --git a/webapp/src/components/compiler-controls/compiler-controls.js b/webapp/src/components/compiler-controls/compiler-controls.js index 63638730..3df62c40 100644 --- a/webapp/src/components/compiler-controls/compiler-controls.js +++ b/webapp/src/components/compiler-controls/compiler-controls.js @@ -29,6 +29,18 @@ class CompilerControls { $compileBtn.popover('hide'); }); + const $testBtn = $('#test-btn'); + $testBtn.click(() => { + params.testCallback(); + $testBtn.popover('hide'); + }); + + if (params.enableTest) { + $testBtn.show(); + } else { + $testBtn.hide(); + } + // Initialize Bootstrap popovers $compileBtn.popover(); // We don't want the "gcc opts errors" popover to be dismissed when clicked diff --git a/webapp/src/components/play-activity-page/play-activity-page.js b/webapp/src/components/play-activity-page/play-activity-page.js index 329493a5..d01bd463 100644 --- a/webapp/src/components/play-activity-page/play-activity-page.js +++ b/webapp/src/components/play-activity-page/play-activity-page.js @@ -23,6 +23,7 @@ int main() { `; const defaultBuildCmd = 'gcc -lm -Wall -fmax-errors=10 -Wextra program.c -o program'; const defaultExecCmd = './program'; +const defaultTestCmd = 'echo "No tests!"'; class PlayActivityPage { @@ -63,6 +64,17 @@ class PlayActivityPage { } this.compilerParams.execCmd(execCmd); + let testCmd = defaultTestCmd; + this.compilerParams.enableTest = true; + if (typeof playActivity.testCmd !== 'undefined') { + testCmd = playActivity.testCmd + } else if (typeof playActivity.testLocation !== 'undefined') { + testCmd = `${playActivity.testLocation}` + } else { + this.compilerParams.enableTest = false; + } + this.compilerParams.testCmd(testCmd); + if (playActivity.docFile) { this.doc = { url: 'https://cs-education.github.io/sysassets/' + playActivity.docFile, @@ -80,6 +92,7 @@ class PlayActivityPage { this.editorParams.initialEditorText = defaultEditorText; this.compilerParams.buildCmd(defaultBuildCmd); this.compilerParams.execCmd(defaultExecCmd); + this.compilerParams.testCmd(defaultTestCmd) this.doc = { text: '# Welcome\n' + @@ -129,6 +142,7 @@ class PlayActivityPage { this.compilerParams = { buildCmd: SysGlobalObservables.buildCmd, execCmd: SysGlobalObservables.execCmd, + testCmd: SysGlobalObservables.testCmd, compileStatus: SysGlobalObservables.compileStatus, lastGccOutput: SysGlobalObservables.lastGccOutput, gccOptsError: SysGlobalObservables.gccOptsError, @@ -155,11 +169,25 @@ class PlayActivityPage { this.autoIncluder.addMissingHeaders(this.editorParams.editorTextGetter); } const buildCmd = this.compilerParams.buildCmd(); - (SysGlobalObservables.runCode())(buildCmd); + const execCmd = this.compilerParams.execCmd(); + + (SysGlobalObservables.runCode())(buildCmd, execCmd); }; this.compilerParams.compileCallback = compile; + const compileAndTest = () => { + if (this.editorParams.autoInclude()) { + this.autoIncluder.addMissingHeaders(this.editorParams.editorTextGetter); + } + const buildCmd = this.compilerParams.buildCmd(); + const testCmd = this.compilerParams.testCmd(); + + (SysGlobalObservables.runCode())(buildCmd, testCmd); + }; + + this.compilerParams.testCallback = compileAndTest; + this.editorParams.keyboardShortcuts.push([ 'compileAndRunShortcut', compileShortcut,