瀏覽代碼

Implement assessment detail page to open when clicked on the assessment result

Lucas Mendonça 4 年之前
父節點
當前提交
0ecfebc1d8

+ 7 - 0
css/ivprog-term.css

@@ -185,4 +185,11 @@
   padding: 0;
   margin: 0;
   line-height: 1rem;
+}
+
+.assessment-div-detail:hover {
+  cursor: pointer;
+}
+.assessment-div-detail:hover > span {
+  text-decoration: underline;
 }

+ 3 - 2
i18n/pt/error.json

@@ -84,8 +84,9 @@
   "invalid_array_literal_column": "Esperava-se $0 colunas mas encontrou $1.",
   "exceeded_input_request": "A quantidade de leituras requisitadas execedeu a quantidade de entradas disponíveis.",
   "test_case_few_reads": "Caso de teste $0 falhou: ainda restam entradas!",
-  "test_case_failed": "Caso de teste $0 falhou: <ul> <li>entrada(s): $1</li> <li>saída(s) esperada(s): $2</li> <li>saída(s): $3</li></ul>",
-  "test_case_failed_exception": "Caso de teste $0 falhou: $1",
+  "test_case_failed": "<div class='assessment-div-detail' onClick='ivprogCore.openAssessmentDetail(event)' data-page=\"$4\"> <span>Caso de teste $0 falhou</span>: <ul> <li>entrada(s): $1</li> <li>saída(s) esperada(s): $2</li> <li>saída(s): $3</li></ul></div>",
+  "test_case_failed_exception": "<div class='assessment-div-detail' onClick='ivprogCore.openAssessmentDetail(event)' data-page=\"$2\"> <span>Caso de teste $0 falhou</span>: $1",
+  "test_case_exception": "Ocorreu uma exceção no caso de teste $0: $1",
   "invalid_type_conversion": "O valor $0 não pode ser convertido para o tipo $1",
   "invalid_read_type":"A entrada \"$0\" não é do tipo $1, que é o tipo da variável <span class='ivprog-error-varname'>$2</span>.",
   "invalid_read_type_array":"A entrada \"$0\" não é do tipo $1, que é o tipo aceito pela variável <span class='ivprog-error-varname'>$2</span> que é um $3.",

+ 1 - 1
i18n/pt/message.json

@@ -1,5 +1,5 @@
 {
-  "test_case_success": "Caso de teste $0: OK",
+  "test_case_success": "<div class='assessment-div-detail' onClick='ivprogCore.openAssessmentDetail(event)' data-page=\"$1\"><span>Caso de teste $0</span>: OK</div>",
   "test_case_duration": "Levou $0ms",
   "test_suite_grade": "A sua solução alcançou $0% da nota.",
   "awaiting_input_message": "O seu programa está em execução e aguardando uma entrada! Digite algo e pressione ENTER..."

+ 2 - 2
i18n/pt/ui.json

@@ -121,7 +121,7 @@
   "assessment-detail-grade-label": "Nota",
   "assessment-detail-input-label": "Entradas",
   "assessment-detail-output-label": "Saídas",
-  "assessment-detail-expected-label": "Esperadas",
-  "assessment-detail-generated-label": "Geradas",
+  "assessment-detail-expected-label": "Esperava",
+  "assessment-detail-generated-label": "Gerou",
   "assessment-detail-result-label": "Resultado"
 }

+ 40 - 9
js/assessment/ivprogAssessment.js

@@ -6,6 +6,7 @@ import { OutputTest } from "./../util/outputTest";
 import { DOMConsole} from "./../io/domConsole";
 import * as LocalizedStringsService from "../services/localizedStringsService";
 import { Config } from "../util/config";
+import { OutputMatching } from './output_matching/output_matching';
 
 
 const LocalizedStrings = LocalizedStringsService.getInstance();
@@ -26,19 +27,49 @@ export class IVProgAssessment {
     try {
       // loop test cases and show messages through domconsole
       const partialTests = this.testCases.map( (t, name) => {
-        return outerRef.partialEvaluateTestCase(new IVProgProcessor(outerRef.ast_code), t.input, t.output, name);
+        return new OutputMatching(new IVProgProcessor(outerRef.ast_code), t.input, t.output, name);
       });
-      const testResult = partialTests.reduce((acc, curr) => acc.then(curr), Promise.resolve(0));
-      return testResult.then(function (total) {
-        const grade = total / outerRef.testCases.length;
+      const testResult = partialTests.map(om => om.eval());
+      return Promise.all(testResult).then(results => {
+        let grade = 0;
+        for(let i = 0; i < results.length; ++i) {
+          const result = results[i];
+          grade += result.grade;
+          if(result.grade == 1) {
+            outerRef.writeToConsole(DOMConsole.INFO, StringTypes.MESSAGE,'test_case_success',
+              result.name+1, result.generateOutput());
+          } else if (result.status == 1) {
+            outerRef.writeToConsole(DOMConsole.ERR, StringTypes.ERROR,'test_case_failed_exception',
+              result.name+1,
+              result.error_msg,
+              result.generateOutput());
+          } else {
+            const inputs = result.inputs.map(input => input.value);
+            const outputs = result.results;
+            const expected_output = outputs.map(r => r.expected || '').filter( str => (''+str).length > 0);
+            const generated_output = outputs.map(r => r.generated || '').filter( str => (''+str).length > 0);
+            outerRef.writeToConsole(DOMConsole.ERR, StringTypes.ERROR,'test_case_failed',
+              result.name+1,
+              inputs.join(LocalizedStrings.getUI('text_join_assessment_outputs')),
+              expected_output.join(LocalizedStrings.getUI('text_join_assessment_outputs')),
+              generated_output.join(LocalizedStrings.getUI('text_join_assessment_outputs')),
+              result.generateOutput());
+          }
+        }
+        grade /= results.length;
         const channel = grade == 1 ? DOMConsole.INFO : DOMConsole.ERR;
         outerRef.writeToConsole(channel, StringTypes.MESSAGE, "test_suite_grade", (grade * 100).toFixed(2));
-        return Promise.resolve(grade)
-      }).catch(err => {
-        outerRef.domConsole.err("Erro inesperado durante o cálculo da nota.");// try and show error messages through domconsole
-        outerRef.domConsole.err(err.message);
-        return Promise.resolve(0);
       });
+      // return testResult.then(function (total) {
+      //   const grade = total / outerRef.testCases.length;
+      //   const channel = grade == 1 ? DOMConsole.INFO : DOMConsole.ERR;
+      //   outerRef.writeToConsole(channel, StringTypes.MESSAGE, "test_suite_grade", (grade * 100).toFixed(2));
+      //   return Promise.resolve(grade)
+      // }).catch(err => {
+      //   outerRef.domConsole.err("Erro inesperado durante o cálculo da nota.");// try and show error messages through domconsole
+      //   outerRef.domConsole.err(err.message);
+      //   return Promise.resolve(0);
+      // });
     } catch (error) {
       outerRef.domConsole.err("Erro inesperado durante a execução do programa");// try and show error messages through domconsole
       outerRef.domConsole.err(error.message);

+ 1 - 1
js/assessment/output_matching/output_matching.js

@@ -65,7 +65,7 @@ export class OutputMatching {
       return new OutputAssessmentResult(this.name, 0,  input.input_list, result, sto, final_time);
     }).catch(error => {
       return new OutputAssessmentResult(this.name, 1,  input.input_list, null, null,
-        null, refThis.getErrorMessage('test_case_failed_exception', this.name + 1, error.message))
+        null, refThis.getErrorMessage('test_case_exception', this.name + 1, error.message))
     });
   }
 

+ 3 - 1
js/main.js

@@ -6,6 +6,7 @@ import * as LocalizedStringsService from './services/localizedStringsService';
 import { i18nHelper } from "./services/i18nHelper";
 import { ActionTypes, getLogs, getLogsAsString, registerClick, registerUserEvent, parseLogs } from "./services/userLog";
 import { prepareActivityToStudentHelper, autoEval } from "./util/iassignHelpers";
+import { openAssessmentDetail } from "./util/utils";
 import * as CodeEditorAll from "./visualUI/text_editor";
 
 const CodeEditor = {
@@ -36,5 +37,6 @@ export {
   registerUserEvent,
   parseLogs,
   ActionTypes,
-  CodeEditor
+  CodeEditor,
+  openAssessmentDetail
 }

+ 13 - 0
js/util/utils.js

@@ -253,3 +253,16 @@ export function levenshteinDistance (a, b) {
   }
   return matrix[b.length][a.length];
 }
+
+let win = null
+export function openAssessmentDetail (event) {
+  event.preventDefault();
+  const page_code = event.currentTarget.dataset.page;
+  if(win != null) {
+    win.close()
+  }
+  win = window.open("", "DetailWindow", "width=800,height=600");
+  win.document.open();
+  win.document.write(page_code);
+  win.document.close();
+}