Przeglądaj źródła

Merge branch 'autoeval-bug' of LInE/iVProg into master

GitAdmin 4 lat temu
rodzic
commit
03830eaba2

+ 2 - 15
js/assessment/ivprogAssessment.js

@@ -83,19 +83,6 @@ export class IVProgAssessment {
   writeToConsole (channel, msgType, msgID, ...args) {
     let msg = LocalizedStrings.getString(msgID, msgType);
     msg = LocalizedStrings.processString(msg, args);
-    switch(channel) {
-      case DOMConsole.ERR: {
-        this.domConsole.err(msg);
-        break;
-      }
-      case DOMConsole.INFO: {
-        this.domConsole.info(msg);
-        break;
-      }
-      case DOMConsole.USER: {
-        this.domConsole.write(msg);
-        break;
-      }
-    }
+    this.domConsole.writeRawHTML(msg, channel);
   }
-}
+}

+ 98 - 84
js/io/domConsole.js

@@ -3,7 +3,6 @@ import * as Utils from "./../util/utils";
 import { Config } from "./../util/config";
 
 export class DOMConsole {
-
   static get BASH_TEMPLATE () {
     return `
     <div class="bash-title">
@@ -54,11 +53,11 @@ export class DOMConsole {
     this.showBtn = null;
     this.termDiv = null;
     this.anyKey = false;
-    let actualID = elementID
-    if (elementID[0] === '#') {
+    let actualID = elementID;
+    if (elementID[0] === "#") {
       actualID = elementID.substring(1);
     }
-    this.parent = document.getElementById(actualID)
+    this.parent = document.getElementById(actualID);
     this.setup();
     this.inputListeners = [];
     this.hideInput();
@@ -72,10 +71,10 @@ export class DOMConsole {
   }
 
   _setupEvents () {
-    this.input.addEventListener('keydown', this.registerInput.bind(this));
-    this.clearBtn.addEventListener('click', this.clearBtnClick.bind(this));
-    this.hideBtn.addEventListener('click', this.hideBtnClick.bind(this));
-    this.showBtn.addEventListener('click', this.showBtnClick.bind(this));
+    this.input.addEventListener("keydown", this.registerInput.bind(this));
+    this.clearBtn.addEventListener("click", this.clearBtnClick.bind(this));
+    this.hideBtn.addEventListener("click", this.hideBtnClick.bind(this));
+    this.showBtn.addEventListener("click", this.showBtnClick.bind(this));
   }
 
   registerInput (event) {
@@ -89,18 +88,18 @@ export class DOMConsole {
         this.idleInterval = null;
       }
       let text = this.input.value;
-      text = text.replace('[\n\r]+', '');
+      text = text.replace("[\n\r]+", "");
       this.notifyListeners(text);
       this._appendUserInput(text);
-      this.input.value = '';
-      this.inputSpan.innerHTML = '';
+      this.input.value = "";
+      this.inputSpan.innerHTML = "";
       this.currentLine = null;
     }
   }
 
   _setupDom () {
-    const bashNode = document.createElement('div');
-    bashNode.classList.add('bash');
+    const bashNode = document.createElement("div");
+    bashNode.classList.add("bash");
     bashNode.innerHTML = DOMConsole.BASH_TEMPLATE;
     this.termDiv = bashNode.querySelector("#ivprog-term");
     this.termDiv.classList.add("ivprog-term-div");
@@ -117,23 +116,29 @@ export class DOMConsole {
     this.parent.append(bashNode);
     this.inputCMD = this.inputDiv.querySelector("#cmd");
     this.cursorRef = this.inputCMD.querySelector("#cursor");
-    this.inputSpan = this.inputCMD.querySelector('span');
-    this.clearBtn = bashNode.querySelector('#ivprog-console-clearbtn');
-    this.hideBtn = bashNode.querySelector('#ivprog-console-hidebtn');
-    this.showBtn = bashNode.querySelector('#ivprog-console-showbtn');
+    this.inputSpan = this.inputCMD.querySelector("span");
+    this.clearBtn = bashNode.querySelector("#ivprog-console-clearbtn");
+    this.hideBtn = bashNode.querySelector("#ivprog-console-hidebtn");
+    this.showBtn = bashNode.querySelector("#ivprog-console-showbtn");
     this._setupCursor();
     //Jquery tooltips....
-    window.$(this.clearBtn).popup({content:LocalizedStrings.getUI("tooltip_terminal_clear")});
-    window.$(this.showBtn).popup({content:LocalizedStrings.getUI("tooltip_terminal_show")});
-    window.$(this.hideBtn).popup({content:LocalizedStrings.getUI("tooltip_terminal_hide")});
+    window
+      .$(this.clearBtn)
+      .popup({ content: LocalizedStrings.getUI("tooltip_terminal_clear") });
+    window
+      .$(this.showBtn)
+      .popup({ content: LocalizedStrings.getUI("tooltip_terminal_show") });
+    window
+      .$(this.hideBtn)
+      .popup({ content: LocalizedStrings.getUI("tooltip_terminal_hide") });
   }
 
   _setupCursor () {
-    this.inputCMD.addEventListener('click', this.blinkCaretAndFocus.bind(this));
+    this.inputCMD.addEventListener("click", this.blinkCaretAndFocus.bind(this));
     //this.inputCMD.click();
 
-    this.input.addEventListener('keyup', this.updateSpanText.bind(this));
-    this.input.addEventListener('blur', this.stopBlinkCaret.bind(this));
+    this.input.addEventListener("keyup", this.updateSpanText.bind(this));
+    this.input.addEventListener("blur", this.stopBlinkCaret.bind(this));
   }
 
   blinkCaretAndFocus () {
@@ -142,34 +147,37 @@ export class DOMConsole {
     }
     this.input.focus();
     this.cursorInterval = window.setInterval(() => {
-      if (this.cursorRef.style.visibility === 'visible') {
-        this.cursorRef.style.visibility = 'hidden';
+      if (this.cursorRef.style.visibility === "visible") {
+        this.cursorRef.style.visibility = "hidden";
       } else {
-        this.cursorRef.style.visibility = 'visible';
+        this.cursorRef.style.visibility = "visible";
       }
     }, 500);
   }
 
   updateSpanText () {
     this.inputSpan.innerHTML = this.input.value;
-    if (this.idleInterval != null)
-      window.clearInterval(this.idleInterval);
-    this.scheduleNotify()
+    if (this.idleInterval != null) window.clearInterval(this.idleInterval);
+    this.scheduleNotify();
   }
 
   stopBlinkCaret () {
     clearInterval(this.cursorInterval);
     this.cursorInterval = null;
-    this.cursorRef.style.visibility = 'visible';
+    this.cursorRef.style.visibility = "visible";
   }
 
   notifyListeners (text) {
-    this.inputListeners.forEach(resolve => resolve(text));
+    this.inputListeners.forEach((resolve) => resolve(text));
     this.inputListeners.splice(0, this.inputListeners.length);
     this.hideInput();
     this.anyKey = false;
   }
 
+  writeRawHTML (text, channel) {
+    this._appendTextLn(text, channel, false);
+  }
+
   write (text, newLine = false) {
     this._appendText(text, DOMConsole.USER, newLine);
   }
@@ -183,6 +191,7 @@ export class DOMConsole {
   }
 
   async _appendText (text, type, newLine = false) {
+    console.debug("Caling appendText");
     const write_time = Date.now();
     this.pending_writes.push(0);
     await Utils.sleep(5);
@@ -190,13 +199,13 @@ export class DOMConsole {
     if (this.last_clear >= write_time) {
       return;
     }
-    
+
     if (this.currentLine == null) {
       const divClass = this.getClassForType(type);
-      const textDiv = document.createElement('div');
+      const textDiv = document.createElement("div");
       textDiv.classList.add(divClass);
       this.termDiv.insertBefore(textDiv, this.inputDiv);
-      this.currentLine = textDiv
+      this.currentLine = textDiv;
     }
     this.currentLine.innerHTML += this.getOutputText(text);
     if (newLine) {
@@ -215,12 +224,10 @@ export class DOMConsole {
       return;
     }
     const divClass = this.getClassForType(type);
-    const textDiv = document.createElement('div');
+    const textDiv = document.createElement("div");
     textDiv.classList.add(divClass);
-    if (filter)
-      textDiv.innerHTML = this.getOutputText(text);
-    else
-      textDiv.innerHTML = `<span>${text}</span>`;
+    if (filter) textDiv.innerHTML = this.getOutputText(text);
+    else textDiv.innerHTML = `<span>${text}</span>`;
     this.termDiv.insertBefore(textDiv, this.inputDiv);
     this.currentLine = null;
     this.scrollTerm();
@@ -235,7 +242,7 @@ export class DOMConsole {
       return;
     }
     const divClass = this.getClassForType(DOMConsole.INPUT);
-    const textDiv = document.createElement('div');
+    const textDiv = document.createElement("div");
     textDiv.innerHTML = this.getUserInputText(text);
     textDiv.classList.add(divClass);
     this.termDiv.insertBefore(textDiv, this.inputDiv);
@@ -261,7 +268,7 @@ export class DOMConsole {
   }
 
   focus () {
-    this.termDiv.style.display = 'block';
+    this.termDiv.style.display = "block";
     // Is in draggable mode?
     if (!this.disableMarginTop && this.parent.style.top.length == 0) {
       this.parent.style.marginTop = "-160px";
@@ -285,7 +292,7 @@ export class DOMConsole {
     if (!this.disableMarginTop && this.parent.style.top.length == 0) {
       this.parent.style.marginTop = "0";
     }
-    this.termDiv.style.display = 'none';
+    this.termDiv.style.display = "none";
   }
 
   getClassForType (type) {
@@ -302,15 +309,18 @@ export class DOMConsole {
   }
 
   dispose () {
-    this.input.removeEventListener('keyup', this.updateSpanText.bind(this));
-    this.input.removeEventListener('blur', this.stopBlinkCaret.bind(this));
-    this.input.removeEventListener('keydown', this.registerInput.bind(this));
-    this.inputCMD.removeEventListener('click', this.blinkCaretAndFocus.bind(this));
-    this.clearBtn.removeEventListener('click', this.clearBtnClick.bind(this));
-    this.hideBtn.removeEventListener('click', this.hideBtnClick.bind(this));
-    this.showBtn.removeEventListener('click', this.showBtnClick.bind(this));
+    this.input.removeEventListener("keyup", this.updateSpanText.bind(this));
+    this.input.removeEventListener("blur", this.stopBlinkCaret.bind(this));
+    this.input.removeEventListener("keydown", this.registerInput.bind(this));
+    this.inputCMD.removeEventListener(
+      "click",
+      this.blinkCaretAndFocus.bind(this)
+    );
+    this.clearBtn.removeEventListener("click", this.clearBtnClick.bind(this));
+    this.hideBtn.removeEventListener("click", this.hideBtnClick.bind(this));
+    this.showBtn.removeEventListener("click", this.showBtnClick.bind(this));
     this.input = null;
-    this.inputCMD =  null;
+    this.inputCMD = null;
     this.inputDiv = null;
     this.termDiv = null;
     this.inputSpan = null;
@@ -331,7 +341,7 @@ export class DOMConsole {
 
   showInput () {
     this.needInput = true;
-    this.inputDiv.style.display = 'block';
+    this.inputDiv.style.display = "block";
     this.inputCMD.click();
     //this.inputCMD.scrollIntoView();
     this.scrollTerm();
@@ -339,50 +349,49 @@ export class DOMConsole {
 
   hideInput () {
     this.needInput = false;
-    this.inputDiv.style.display = ' none';
+    this.inputDiv.style.display = " none";
     clearInterval(this.cursorInterval);
     this.cursorInterval = null;
   }
 
   requestInput (anyKey = false) {
-    const promise = new Promise( (resolve, _) => {
+    const promise = new Promise((resolve, _) => {
       this.inputListeners.push(resolve);
       this.anyKey = anyKey;
-      if (this.idleInterval == null)
-        this.scheduleNotify();
+      if (this.idleInterval == null) this.scheduleNotify();
       this.showInput();
     });
     return promise;
   }
 
   sendOutput (text) {
-    console.debug(text);
-    let output = ""+text;
-    if (output.indexOf('\n') !== -1) {
-      console.debug("newline");
-      const outputList = output.split('\n');
+    // console.debug(text);
+    let output = "" + text;
+    if (output.indexOf("\n") !== -1) {
+      // console.debug("newline");
+      const outputList = output.split("\n");
       let i = 0;
-      for ( ; i < outputList.length - 1; i += 1) {
-        console.debug("newline write");
+      for (; i < outputList.length - 1; i += 1) {
+        // console.debug("newline write");
         let t = outputList[i];
-        t = t.replace(/\t/g,'&#x0020;&#x0020;');
-        t = t.replace(/\s/g,"&#x0020;");
-        if (t.length == 0)
-          t = "&nbsp;"
-        this.write(t, true);
+        t = t.replace(/\t/g, "&#x0020;&#x0020;");
+        t = t.replace(/\s/g, "&#x0020;");
+        if (t.length == 0) {
+          // t = "&nbsp;";
+          // console.debug('Empty string');
+          this.currentLine = null;
+        } else this.write(t, true);
       }
       let t = outputList[i];
-      t = t.replace(/\t/g,'&#x0020;&#x0020;');
-      t = t.replace(/\s/g,"&#x0020;");
-      if (t.length != 0)
-        this.write(t);
+      t = t.replace(/\t/g, "&#x0020;&#x0020;");
+      t = t.replace(/\s/g, "&#x0020;");
+      if (t.length != 0) this.write(t);
     } else {
-      console.debug("no newline");
-      output = output.replace(/\t/g,'&#x0020;&#x0020;');
-      output = output.replace(/\s/g,"&#x0020;");
+      // console.debug("no newline");
+      output = output.replace(/\t/g, "&#x0020;&#x0020;");
+      output = output.replace(/\s/g, "&#x0020;");
       this.write(output);
     }
-    
   }
 
   clearPendingWrites () {
@@ -390,12 +399,14 @@ export class DOMConsole {
   }
 
   clear () {
-    this.clearPendingWrites()
+    this.clearPendingWrites();
     while (this.inputDiv.parentElement.childNodes.length > 1) {
-      this.inputDiv.parentElement.removeChild(this.inputDiv.parentElement.firstChild);
+      this.inputDiv.parentElement.removeChild(
+        this.inputDiv.parentElement.firstChild
+      );
     }
-    this.input.value = '';
-    this.inputSpan.innerHTML = '';
+    this.input.value = "";
+    this.inputSpan.innerHTML = "";
     this.currentLine = null;
   }
 
@@ -412,23 +423,26 @@ export class DOMConsole {
   }
 
   notifyIdle () {
-    this.info(LocalizedStrings.getMessage('awaiting_input_message'));
+    this.info(LocalizedStrings.getMessage("awaiting_input_message"));
     this.inputCMD.click();
   }
 
   scheduleNotify () {
-    this.idleInterval = window.setInterval(this.notifyIdle.bind(this), Config.idle_input_interval);
+    this.idleInterval = window.setInterval(
+      this.notifyIdle.bind(this),
+      Config.idle_input_interval
+    );
   }
 
   cancelPendingInputRequests () {
-    this.inputListeners.forEach(resolve => resolve(''));
+    this.inputListeners.forEach((resolve) => resolve(""));
     this.inputListeners.splice(0, this.inputListeners.length);
     if (this.idleInterval != null) {
       clearInterval(this.idleInterval);
       this.idleInterval = null;
     }
-    this.input.value = '';
-    this.inputSpan.innerHTML = '';
+    this.input.value = "";
+    this.inputSpan.innerHTML = "";
     this.currentLine = null;
     this.hideInput();
     this.anyKey = false;

+ 31 - 17
js/util/iassignHelpers.js

@@ -8,17 +8,17 @@ import { Maybe } from "./maybe";
 
 function parseActivityData (data) {
   let algorithm_in_ilm = null;
-  if (data.split('\n::algorithm::')[1]) {
-    algorithm_in_ilm = data.split('\n::algorithm::')[1].split('\n::logs::')[0];
-    const logs = data.split('\n::algorithm::')[1].split('\n::logs::')[1];
+  if (data.split("\n::algorithm::")[1]) {
+    algorithm_in_ilm = data.split("\n::algorithm::")[1].split("\n::logs::")[0];
+    const logs = data.split("\n::algorithm::")[1].split("\n::logs::")[1];
     if (logs != null) {
       parseLogs(logs);
     }
   }
   let content;
   try {
-    content = JSON.parse(data.split('\n::algorithm::')[0]);
-    content['algorithm_in_ilm'] = algorithm_in_ilm;
+    content = JSON.parse(data.split("\n::algorithm::")[0]);
+    content["algorithm_in_ilm"] = algorithm_in_ilm;
   } catch (e) {
     console.error(e);
     return Maybe.none();
@@ -28,7 +28,7 @@ function parseActivityData (data) {
 
 export function prepareActivityToStudentHelper (ilm_cont) {
   const maybe_content = parseActivityData(ilm_cont);
-  return maybe_content.map(content => {
+  return maybe_content.map((content) => {
     const testCases = content.testcases;
     setTestCases(testCases);
 
@@ -45,8 +45,8 @@ export function prepareActivityToStudentHelper (ilm_cont) {
       settingsCommands: content.settings_commands,
       settingsFunctions: content.settings_functions,
       algorithmInIlm: content.algorithm_in_ilm,
-      settingsFilter: content.settings_filter
-    }
+      settingsFilter: content.settings_filter,
+    };
   });
 }
 
@@ -68,10 +68,10 @@ function compareTestcases (original, student) {
   for (let i = 0; i < original.length; ++i) {
     const elementO = original[i];
     const elementS = student[i];
-    if(!compareArray(elementO.input, elementS.input)) {
+    if (!compareArray(elementO.input, elementS.input)) {
       return false;
     }
-    if(!compareArray(elementO.output, elementS.output)) {
+    if (!compareArray(elementO.output, elementS.output)) {
       return false;
     }
   }
@@ -80,8 +80,9 @@ function compareTestcases (original, student) {
 
 export function autoEval (originalData, callback) {
   const code = generate();
+  //console.debug(code);
   const original = parseActivityData(originalData).getOrElse(undefined);
-  if(original == null) {
+  if (original == null) {
     alert("iAssign did not provide the original activity data!");
     return callback(null);
   }
@@ -91,11 +92,24 @@ export function autoEval (originalData, callback) {
     if (!compareTestcases(original.testcases, getTestCases())) {
       return callback(-2); // @FeedbackConvention Casos de teste alterados pelo aluno
     }
-    const ast_code = SemanticAnalyser.analyseFromSource(code);
-    const autoAssessment = new IVProgAssessment(ast_code, getTestCases(), new TestConsole([]));
-    autoAssessment.runTest().then( grade => callback(grade)).catch(err => {
-      console.log(err);
-      callback(-5); // @FeedbackConvention Falha na execução
-    });
+    try {
+      const ast_code = SemanticAnalyser.analyseFromSource(code);
+      const con = new TestConsole([]);
+      const autoAssessment = new IVProgAssessment(
+        ast_code,
+        original.testcases,
+        con
+      );
+      autoAssessment
+        .runTest()
+        .then((grade) => callback(grade))
+        .catch((err) => {
+          console.log(err);
+          callback(-5); // @FeedbackConvention Falha na execução
+        });
+    } catch (e) {
+      console.error(e);
+      callback(-5);
+    }
   }
 }

+ 3 - 2
js/util/outputTest.js

@@ -28,8 +28,9 @@ export class OutputTest extends Output {
         t = t.replace(/\t/g, '&#x0020;&#x0020;');
         t = t.replace(/\s/g, "&#x0020;");
         if (t.length == 0)
-          t = "&nbsp;";
-        this.write(t, true);
+          this.currentLine = null;
+        else
+          this.write(t, true);
       });
       last = last.replace(/\t/g, '&#x0020;&#x0020;');
       last = last.replace(/\s/g, "&#x0020;");

+ 9 - 5
js/util/testConsole.js

@@ -13,6 +13,9 @@ export class TestConsole {
     this.currentLine = null;
   }
 
+  writeRawHTML (text) {
+    this._appendTextLn(text);
+  }
   write (text, newLine = false) {
     this._appendText(text, DOMConsole.USER, newLine);
   }
@@ -25,7 +28,7 @@ export class TestConsole {
     this._appendTextLn(text, DOMConsole.ERR);
   }
 
-  _appendText (text, type, newLine = false) {
+  _appendText (text, _type, newLine = false) {
     if (this.currentLine == null) {
       this.currentLine = this.list.push('') - 1;
     }
@@ -54,7 +57,7 @@ export class TestConsole {
 
   requestInput () {
     const promise = new Promise( (resolve, reject) => {
-      if(this.index < this.inputList.length) {      
+      if(this.index < this.inputList.length) {
         resolve(this.inputList[this.index]);
         this.index++;
       } else {
@@ -73,8 +76,9 @@ export class TestConsole {
         t = t.replace(/\t/g, '&#x0020;&#x0020;');
         t = t.replace(/\s/g, "&#x0020;");
         if (t.length == 0)
-          t = "&nbsp;";
-        this.write(t, true);
+          this.currentLine = null;
+        else
+          this.write(t, true);
       });
       last = last.replace(/\t/g, '&#x0020;&#x0020;');
       last = last.replace(/\s/g, "&#x0020;");
@@ -86,4 +90,4 @@ export class TestConsole {
       this.write(output);
     }
   }
-}
+}

+ 6 - 3
js/visualUI/code_generator.js

@@ -68,9 +68,12 @@ function functionsCode (function_obj) {
   } else if (function_obj.return_dimensions == 2) {
     ret += "[][] ";
   }
-
-  ret += function_obj.name + " ( ";
-
+  if (function_obj.is_main) {
+    ret += LocalizedStrings.getUI('start');
+  } else {
+    ret += function_obj.name;
+  }
+  ret += " ( ";
   for (let j = 0; j < function_obj.parameters_list.length; j++) {
     ret += parametersCode(function_obj.parameters_list[j]);
     if (j + 1 < function_obj.parameters_list.length) {

+ 1 - 1
package-lock.json

@@ -5808,7 +5808,7 @@
       }
     },
     "line-i18n": {
-      "version": "git+http://200.144.254.107/git/LInE/line-i18n.git#1f6cd8942338fbbb4b794fb7a7a2fae9bf7c4d87",
+      "version": "git+http://200.144.254.107/git/LInE/line-i18n.git#865a6b5a956aa29958a1177f00ca9cacacdba60e",
       "from": "git+http://200.144.254.107/git/LInE/line-i18n.git",
       "requires": {
         "ts-loader": "^5.4.5",