Просмотр исходного кода

refactor: Modify ivprogAssessment.js and output_matching.js to include test tags

Add assessment.js abstract class to handle code assessment
Modify output_matching.js to receive tags and pass on error ids
Modify assessment_result.js to store error ids
Lucas de Souza 3 лет назад
Родитель
Сommit
2666a7bc53

+ 37 - 0
js/assessment/assessment.js

@@ -0,0 +1,37 @@
+import * as LocalizedStringsService from "../services/localizedStringsService";
+import { Config } from "../util/config";
+
+const LocalizedStrings = LocalizedStringsService.getInstance();
+
+const AssessmentConfig = {
+  max_instruction_count: 350250,
+  suspend_threshold: 200,
+};
+
+export class Assessment {
+  constructor (ast_code, testCases, domConsole) {
+    this.ast_code = ast_code;
+    this.testCases = testCases;
+    this.domConsole = domConsole;
+    this.old_config = JSON.parse(JSON.stringify(Config));
+    Config.setConfig(AssessmentConfig);
+  }
+
+  runTest () {
+    // abstract
+  }
+
+  showErrorMessage (errorID, ...args) {
+    this.domConsole.err(LocalizedStrings.getError(errorID, args));
+  }
+
+  showInfoMessage (msgID, ...args) {
+    this.domConsole.info(LocalizedStrings.getMessage(msgID, args));
+  }
+
+  writeToConsole (channel, msgType, msgID, ...args) {
+    let msg = LocalizedStrings.getString(msgID, msgType);
+    msg = LocalizedStrings.processString(msg, args);
+    this.domConsole.writeRawHTML(msg, channel);
+  }
+}

+ 52 - 48
js/assessment/ivprogAssessment.js

@@ -1,56 +1,70 @@
-import line_i18n from 'line-i18n'
+import line_i18n from "line-i18n";
 import { IVProgProcessor } from "./../processor/ivprogProcessor";
-import { DOMConsole} from "./../io/domConsole";
-import * as LocalizedStringsService from "../services/localizedStringsService";
-import { OutputMatching } from './output_matching/output_matching';
-import { Config } from '../util/config';
-
-
-const LocalizedStrings = LocalizedStringsService.getInstance();
+import { DOMConsole } from "./../io/domConsole";
+import { OutputMatching } from "./output_matching/output_matching";
+import { Config } from "../util/config";
+import { Assessment } from "./assessment";
 
 const StringTypes = line_i18n.StringTypes;
 
-const AssessmentConfig = {
-  max_instruction_count: 350250,
-  suspend_threshold: 200
-}
-
-export class IVProgAssessment {
-
+export class IVProgAssessment extends Assessment {
   constructor (ast_code, testCases, domConsole) {
-    this.ast_code = ast_code;
-    this.testCases = testCases;
-    this.domConsole = domConsole;
-    this.old_config = JSON.parse(JSON.stringify(Config));
-    Config.setConfig(AssessmentConfig);
+    super(ast_code, testCases, domConsole);
   }
 
   runTest () {
     try {
       // loop test cases and show messages through domconsole
-      const partialTests = this.testCases.map( (t, name) => {
-        return new OutputMatching(new IVProgProcessor(this.ast_code), t.input, t.output, name);
+      const partialTests = this.testCases.map((t, name) => {
+        return new OutputMatching(
+          new IVProgProcessor(this.ast_code),
+          t.input,
+          t.output,
+          name,
+          t.tag
+        );
       });
-      const testResult = partialTests.map(om => om.eval());
-      return Promise.all(testResult).then(results => {
+      const testResult = partialTests.map((om) => om.eval());
+      return Promise.all(testResult).then((results) => {
         let grade = 0;
-        for(let i = 0; i < results.length; i += 1) {
+        for (let i = 0; i < results.length; i += 1) {
           const result = results[i];
           grade += result.grade;
-          if(result.grade == 1) {
-            this.writeToConsole(DOMConsole.INFO, StringTypes.MESSAGE,'test_case_success',
-              result.name + 1, result.generateOutput());
+          if (result.grade == 1) {
+            this.writeToConsole(
+              DOMConsole.INFO,
+              StringTypes.MESSAGE,
+              "test_case_success",
+              result.name + 1,
+              result.generateOutput()
+            );
           } else if (result.status == 1) {
-            this.writeToConsole(DOMConsole.ERR, StringTypes.ERROR,'test_case_failed_exception',
-              result.name + 1, result.error_msg, result.generateOutput());
+            this.writeToConsole(
+              DOMConsole.ERR,
+              StringTypes.ERROR,
+              "test_case_failed_exception",
+              result.name + 1,
+              result.error_msg,
+              result.generateOutput()
+            );
           } else {
-            this.writeToConsole(DOMConsole.ERR, StringTypes.ERROR,'test_case_failed',
-              result.name + 1, result.generateOutput());
+            this.writeToConsole(
+              DOMConsole.ERR,
+              StringTypes.ERROR,
+              "test_case_failed",
+              result.name + 1,
+              result.generateOutput()
+            );
           }
         }
         grade /= results.length;
         const channel = grade == 1 ? DOMConsole.INFO : DOMConsole.ERR;
-        this.writeToConsole(channel, StringTypes.MESSAGE, "test_suite_grade", (grade * 100).toFixed(2));
+        this.writeToConsole(
+          channel,
+          StringTypes.MESSAGE,
+          "test_suite_grade",
+          (grade * 100).toFixed(2)
+        );
         return grade;
       });
       // return testResult.then(function (total) {
@@ -64,25 +78,15 @@ export class IVProgAssessment {
       //   return Promise.resolve(0);
       // });
     } catch (error) {
-      this.showErrorMessage(DOMConsole.ERR, StringTypes.MESSAGE, "unexpected_execution_error");
+      this.showErrorMessage(
+        DOMConsole.ERR,
+        StringTypes.MESSAGE,
+        "unexpected_execution_error"
+      );
       this.domConsole.err(error.message);
       return Promise.resolve(0);
     } finally {
       Config.setConfig(this.old_config);
     }
   }
-
-  showErrorMessage (errorID, ...args) {
-    this.domConsole.err(LocalizedStrings.getError(errorID, args));
-  }
-
-  showInfoMessage (msgID, ...args) {
-    this.domConsole.info(LocalizedStrings.getMessage(msgID, args));
-  }
-
-  writeToConsole (channel, msgType, msgID, ...args) {
-    let msg = LocalizedStrings.getString(msgID, msgType);
-    msg = LocalizedStrings.processString(msg, args);
-    this.domConsole.writeRawHTML(msg, channel);
-  }
 }

+ 125 - 58
js/assessment/output_matching/assessment_result.js

@@ -1,8 +1,7 @@
 import StringDiff from "./../../util/string_diff";
-import { LocalizedStrings } from './../../services/localizedStringsService'
+import { LocalizedStrings } from "./../../services/localizedStringsService";
 
 export class OutputAssessmentResult {
-
   static get PAGE_TEMPLATE () {
     return `<!DOCTYPE html>
     <html>
@@ -71,7 +70,16 @@ export class OutputAssessmentResult {
   // Status code - it is not grade related!
   // 0 - Succesful execution
   // 1 - failed execution
-  constructor (name, status, inputs, result, store, time, error_msg = '') {
+  constructor (
+    name,
+    status,
+    inputs,
+    result,
+    store,
+    time,
+    error_msg = "",
+    error_id
+  ) {
     this.name = name;
     this.status = status;
     this.inputs = inputs;
@@ -79,31 +87,50 @@ export class OutputAssessmentResult {
     this.store = store;
     this.time = time;
     this.error_msg = error_msg;
+    this.error_id = error_id;
   }
 
   get grade () {
-    if(this.results == null) {
+    if (this.results == null) {
       return 0;
     }
-    return this.results.reduce((prev, val) => prev + val.grade, 0) / this.results.length;
+    return (
+      this.results.reduce((prev, val) => prev + val.grade, 0) /
+      this.results.length
+    );
   }
 
   prepareResults () {
     let template = OutputAssessmentResult.DETAIL_TEMPLATE;
     const grade = (this.grade * 100).toFixed(2);
     const time = this.time || "-";
-    template = template.replace(':test-name:', LocalizedStrings.getUI('assessment-detail-title', [this.name + 1]));
-    template = template.replace(':time-label:', LocalizedStrings.getUI('assessment-detail-time-label'));
-    template = template.replace(':time:', time);
-    template = template.replace(':grade-label:', LocalizedStrings.getUI('assessment-detail-grade-label'));
-    template = template.replace(':grade:', grade);
+    template = template.replace(
+      ":test-name:",
+      LocalizedStrings.getUI("assessment-detail-title", [this.name + 1])
+    );
+    template = template.replace(
+      ":time-label:",
+      LocalizedStrings.getUI("assessment-detail-time-label")
+    );
+    template = template.replace(":time:", time);
+    template = template.replace(
+      ":grade-label:",
+      LocalizedStrings.getUI("assessment-detail-grade-label")
+    );
+    template = template.replace(":grade:", grade);
     const input_spans = this.prepareInputList(this.inputs);
-    template = template.replace(':input-label:', LocalizedStrings.getUI('assessment-detail-input-label'));
-    template = template.replace(':input-list:', input_spans);
-    template = template.replace(':output-label:', LocalizedStrings.getUI('assessment-detail-output-label'));
-    if(this.status == 0) {
-      const output_rows = this.results.map(result => {
-        if(result.type == "string") {
+    template = template.replace(
+      ":input-label:",
+      LocalizedStrings.getUI("assessment-detail-input-label")
+    );
+    template = template.replace(":input-list:", input_spans);
+    template = template.replace(
+      ":output-label:",
+      LocalizedStrings.getUI("assessment-detail-output-label")
+    );
+    if (this.status == 0) {
+      const output_rows = this.results.map((result) => {
+        if (result.type == "string") {
           return this.formatString(result);
         } else if (result.type == "number") {
           return this.formatNumber(result);
@@ -111,9 +138,12 @@ export class OutputAssessmentResult {
           return this.formatBool(result);
         }
       }, this);
-      template = template.replace(':output-result:', this.prepareOutputTable(output_rows));
+      template = template.replace(
+        ":output-result:",
+        this.prepareOutputTable(output_rows)
+      );
     } else {
-      let failed_text =  OutputAssessmentResult.FAILED_TEMPLATE;
+      let failed_text = OutputAssessmentResult.FAILED_TEMPLATE;
       failed_text = failed_text.replace("$0", this.error_msg);
       template = template.replace(":output-result:", failed_text);
     }
@@ -121,48 +151,71 @@ export class OutputAssessmentResult {
   }
 
   prepareInputList (input_list) {
-    const list = input_list.map(input => {
+    const list = input_list.map((input) => {
       let template = OutputAssessmentResult.INPUT_INFO_TEMPLATE;
       template = template.replace("$1", input.value);
-      if(input.read) {
+      if (input.read) {
         template = template.replace("$0", "assessment-input-read");
       } else {
         template = template.replace("$0", "assessment-input-unread");
       }
       return template;
     }, this);
-    return list.join(LocalizedStrings.getUI('text_join_assessment_outputs'));
+    return list.join(LocalizedStrings.getUI("text_join_assessment_outputs"));
   }
 
   prepareOutputTable (output_rows) {
     let template = OutputAssessmentResult.OUPUT_TABLE_TEMPLATE;
-    template = template.replace(':expected-label:', LocalizedStrings.getUI('assessment-detail-expected-label'));
-    template = template.replace(':generated-label:', LocalizedStrings.getUI('assessment-detail-generated-label'));
-    template = template.replace(':result-label:', LocalizedStrings.getUI('assessment-detail-result-label'));
-    template = template.replace(':results:', output_rows.join(''));
+    template = template.replace(
+      ":expected-label:",
+      LocalizedStrings.getUI("assessment-detail-expected-label")
+    );
+    template = template.replace(
+      ":generated-label:",
+      LocalizedStrings.getUI("assessment-detail-generated-label")
+    );
+    template = template.replace(
+      ":result-label:",
+      LocalizedStrings.getUI("assessment-detail-result-label")
+    );
+    template = template.replace(":results:", output_rows.join(""));
     return template;
   }
 
   generateOutput () {
-    const assessment_result =  this.prepareResults();
+    const assessment_result = this.prepareResults();
     let page = OutputAssessmentResult.PAGE_TEMPLATE;
-    page = page.replace(':assessment-result:', assessment_result);
-    page = page.replace(/(\r|\n|\t)/gm,'').replace(/> *</g, '><');
+    page = page.replace(":assessment-result:", assessment_result);
+    page = page.replace(/(\r|\n|\t)/gm, "").replace(/> *</g, "><");
     return page;
   }
 
   formatNumber (result) {
-    const result_class = result.grade == 1 ? 'assessment-number-result' : 'assessment-number-result-failed';
-    let template = this.formatOutput('assessment-number-expected',
-      'assessment-number-generated', result_class, result);
-    return template
+    const result_class =
+      result.grade == 1
+        ? "assessment-number-result"
+        : "assessment-number-result-failed";
+    const template = this.formatOutput(
+      "assessment-number-expected",
+      "assessment-number-generated",
+      result_class,
+      result
+    );
+    return template;
   }
 
   formatBool (result) {
-    const result_class = result.grade == 1 ? 'assessment-bool-result' : 'assessment-bool-result-failed';
-    let template = this.formatOutput('assessment-bool-expected',
-      'assessment-bool-generated', result_class, result);
-    return template
+    const result_class =
+      result.grade == 1
+        ? "assessment-bool-result"
+        : "assessment-bool-result-failed";
+    const template = this.formatOutput(
+      "assessment-bool-expected",
+      "assessment-bool-generated",
+      result_class,
+      result
+    );
+    return template;
   }
 
   formatOutput (expected_class, generated_class, result_class, result) {
@@ -172,23 +225,27 @@ export class OutputAssessmentResult {
     template = template.replace(":class-result:", result_class);
     let expected_tmpl = result.expected;
     let generated_tmpl = result.generated;
-    if(expected_tmpl == null) {
-      expected_tmpl = OutputAssessmentResult.EMPTY_OUTPUT_TEMPLATE.replace('$0',
-        LocalizedStrings.getMessage('assessment-empty-expected-tooltip'));
-    } else if(generated_tmpl == null) {
-      generated_tmpl = OutputAssessmentResult.EMPTY_OUTPUT_TEMPLATE.replace('$0',
-        LocalizedStrings.getMessage('assessment-empty-generated-tooltip'));
+    if (expected_tmpl == null) {
+      expected_tmpl = OutputAssessmentResult.EMPTY_OUTPUT_TEMPLATE.replace(
+        "$0",
+        LocalizedStrings.getMessage("assessment-empty-expected-tooltip")
+      );
+    } else if (generated_tmpl == null) {
+      generated_tmpl = OutputAssessmentResult.EMPTY_OUTPUT_TEMPLATE.replace(
+        "$0",
+        LocalizedStrings.getMessage("assessment-empty-generated-tooltip")
+      );
     }
     template = template.replace("$0", expected_tmpl);
     template = template.replace("$1", generated_tmpl);
-    const final_result = result.grade == 1 ? "✓" : "✗"
+    const final_result = result.grade == 1 ? "✓" : "✗";
     template = template.replace("$2", final_result);
-    return template
+    return template;
   }
 
   formatString (result) {
-    const expected_class = 'assessment-string-expected';
-    const generated_class = 'assessment-string-generated';
+    const expected_class = "assessment-string-expected";
+    const generated_class = "assessment-string-generated";
     //const result_class = 'assessment-string-result';
 
     let template = OutputAssessmentResult.OUTPUT_TEMPLATE;
@@ -201,34 +258,44 @@ export class OutputAssessmentResult {
     // console.log("generated: ", g_string,"expected: ", e_string);
     let g_string_tmpl = g_string;
     let e_string_tmpl = e_string;
-    if(result.generated == null) {
-      g_string_tmpl = OutputAssessmentResult.EMPTY_OUTPUT_TEMPLATE.replace('$0',
-        LocalizedStrings.getMessage('assessment-empty-generated-tooltip'));
+    if (result.generated == null) {
+      g_string_tmpl = OutputAssessmentResult.EMPTY_OUTPUT_TEMPLATE.replace(
+        "$0",
+        LocalizedStrings.getMessage("assessment-empty-generated-tooltip")
+      );
     } else if (result.expected == null) {
-     e_string_tmpl = OutputAssessmentResult.EMPTY_OUTPUT_TEMPLATE.replace('$0',
-        LocalizedStrings.getMessage('assessment-empty-expected-tooltip'));
+      e_string_tmpl = OutputAssessmentResult.EMPTY_OUTPUT_TEMPLATE.replace(
+        "$0",
+        LocalizedStrings.getMessage("assessment-empty-expected-tooltip")
+      );
     }
     template = template.replace("$0", e_string_tmpl);
     template = template.replace("$1", g_string_tmpl);
-    if(result.grade == 1) {
+    if (result.grade == 1) {
       template = template.replace("$2", "✓");
-      template = template.replace(":class-result:", 'assessment-string-result');
+      template = template.replace(":class-result:", "assessment-string-result");
     } else {
       const diff = StringDiff(g_string, e_string);
       // console.log(diff);
-      const diff_vec = diff.map(part => this.getDiffStringStyle(part[1], part[0]), this);
+      const diff_vec = diff.map(
+        (part) => this.getDiffStringStyle(part[1], part[0]),
+        this
+      );
       const diff_string = diff_vec.reduce((prev, actual) => prev + actual, "");
-      template = template.replace("$2", "<span class='assessment-failed-case'>✗</span>" + diff_string);
+      template = template.replace(
+        "$2",
+        "<span class='assessment-failed-case'>✗</span>" + diff_string
+      );
       template = template.replace(":class-result:", "assessment-string-diff");
     }
     return template;
   }
 
   getDiffStringStyle (text, action) {
-    const template = "<span class='$0'>$1</span>"
+    const template = "<span class='$0'>$1</span>";
     // Fix missing whitespace when its a single element
-    text = text.replace(/\s/g,"&#160;");
-    switch(action) {
+    text = text.replace(/\s/g, "&#160;");
+    switch (action) {
       case StringDiff.INSERT:
         return template.replace("$0", "stringdiff-insert").replace("$1", text);
       case StringDiff.DELETE:

+ 159 - 64
js/assessment/output_matching/output_matching.js

@@ -1,9 +1,9 @@
-import { Decimal } from 'decimal.js';
+import { Decimal } from "decimal.js";
 import { InputAssessment } from "../../util/input_assessment";
 import { OutputTest } from "../../util/outputTest";
 import { Config } from "../../util/config";
 import { levenshteinDistance } from "../../util/utils";
-import { OutputAssessmentResult } from './assessment_result';
+import { OutputAssessmentResult } from "./assessment_result";
 import * as TypeParser from "./../../typeSystem/parsers";
 import * as LocalizedStringsService from "../../services/localizedStringsService";
 import * as OutputResult from "./output_result";
@@ -11,7 +11,6 @@ import * as OutputResult from "./output_result";
 const LocalizedStrings = LocalizedStringsService.getInstance();
 
 export class OutputMatching {
-
   static get NUM_REGEX () {
     return /^[+-]?([0-9]+([.][0-9]*)?(e[+-]?[0-9]+)?)$/;
   }
@@ -21,60 +20,121 @@ export class OutputMatching {
   }
 
   static get BOOLEAN_REGEX () {
-    const str = `^(${LocalizedStrings.getUI("logic_value_true")}|${LocalizedStrings.getUI("logic_value_false")})$`;
+    const str = `^(${LocalizedStrings.getUI(
+      "logic_value_true"
+    )}|${LocalizedStrings.getUI("logic_value_false")})$`;
     return new RegExp(str);
   }
 
   static get BOOLEAN_IN_STRING_REGEX () {
-    const str = `(${LocalizedStrings.getUI("logic_value_true")}|${LocalizedStrings.getUI("logic_value_false")})`;
-    return new RegExp(str, 'g');
+    const str = `(${LocalizedStrings.getUI(
+      "logic_value_true"
+    )}|${LocalizedStrings.getUI("logic_value_false")})`;
+    return new RegExp(str, "g");
   }
 
-  constructor (program, input_list, expected_output, test_name) {
+  constructor (program, input_list, expected_output, test_name, tag = null) {
     this.program = program;
     this.name = test_name;
     this.input_list = input_list;
     this.expected_output = expected_output;
+    this.tag = tag;
   }
 
   eval () {
-    const refThis = this;
     const input = new InputAssessment(this.input_list);
     const gen_output = new OutputTest();
     this.program.registerInput(input);
     this.program.registerOutput(gen_output);
     const start_time = Date.now();
-    return this.program.interpretAST().then( sto => {
-      const final_time = Date.now() - start_time;
-      if(input.isInputAvailable()) {
-        return new OutputAssessmentResult(this.name, 1, input.input_list,
-          null, sto, final_time, refThis.getErrorMessage('test_case_few_reads', this.name+1))
-      }
-      const result = gen_output.list.map((g_out, i) => {
-        if(i >= this.expected_output.length) {
-          return new OutputResult.OutputMatchResult(null, g_out, 0, this.getPotentialOutputType(g_out));
+    return this.program
+      .interpretAST()
+      .then((sto) => {
+        const final_time = Date.now() - start_time;
+        if (input.isInputAvailable()) {
+          const error = this.getErrorMessage(
+            "test_case_few_reads",
+            this.name + 1
+          );
+          return new OutputAssessmentResult(
+            this.name,
+            1,
+            input.input_list,
+            null,
+            sto,
+            final_time,
+            error,
+            error.id
+          );
         }
-        return this.outputMatch(g_out, this.expected_output[i]);
-      }, this);
-      if(this.expected_output.length > gen_output.list.length) {
-        console.log("Saída insuficientes!",this.expected_output.length,gen_output.list.length);
-        for(let i = gen_output.list.length; i < this.expected_output.length; ++i) {
-          const e_out = this.expected_output[i];
-          result.push(new OutputResult.OutputMatchResult(e_out, null, 0, this.getPotentialOutputType(e_out)));
+        const result = gen_output.list.map((g_out, i) => {
+          if (i >= this.expected_output.length) {
+            return new OutputResult.OutputMatchResult(
+              null,
+              g_out,
+              0,
+              this.getPotentialOutputType(g_out)
+            );
+          }
+          return this.outputMatch(g_out, this.expected_output[i]);
+        }, this);
+        if (this.expected_output.length > gen_output.list.length) {
+          console.log(
+            "Saída insuficientes!",
+            this.expected_output.length,
+            gen_output.list.length
+          );
+          for (
+            let i = gen_output.list.length;
+            i < this.expected_output.length;
+            ++i
+          ) {
+            const e_out = this.expected_output[i];
+            result.push(
+              new OutputResult.OutputMatchResult(
+                e_out,
+                null,
+                0,
+                this.getPotentialOutputType(e_out)
+              )
+            );
+          }
+        } else if (
+          this.expected_output.length == 0 &&
+          this.expected_output.length == gen_output.list.length
+        ) {
+          // no output expected....
+          result.push(new OutputResult.OutputMatchResult("", "", 1, "string"));
         }
-      } else if (this.expected_output.length == 0 && this.expected_output.length == gen_output.list.length) {
-        // no output expected....
-        result.push(new OutputResult.OutputMatchResult("", "", 1, "string"));
-      }
-      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_exception', this.name + 1, error.message))
-    });
+        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,
+          this.getErrorMessage(
+            "test_case_exception",
+            this.name + 1,
+            error.message
+          ),
+          error.id
+        );
+      });
   }
 
   getPotentialOutputType (output) {
-    if(OutputMatching.NUM_REGEX.test(output)) {
+    if (OutputMatching.NUM_REGEX.test(output)) {
       return "number";
     } else if (OutputMatching.BOOLEAN_REGEX.test(output)) {
       return "bool";
@@ -84,8 +144,8 @@ export class OutputMatching {
   }
 
   outputMatch (g_output, e_output) {
-    if(OutputMatching.NUM_REGEX.test(e_output)) {
-      if(!OutputMatching.NUM_REGEX.test(g_output)) {
+    if (OutputMatching.NUM_REGEX.test(e_output)) {
+      if (!OutputMatching.NUM_REGEX.test(g_output)) {
         return this.checkStrings(g_output, e_output);
       }
       const g_num = new Decimal(g_output);
@@ -93,7 +153,7 @@ export class OutputMatching {
       return this.checkNumbers(g_num, e_num);
     } else if (OutputMatching.BOOLEAN_REGEX.test(e_output)) {
       if (!OutputMatching.BOOLEAN_REGEX.test(g_output)) {
-        return this.checkStrings(g_output, e_output)
+        return this.checkStrings(g_output, e_output);
       }
       const g_bool = TypeParser.toBool(g_output);
       const e_bool = TypeParser.toBool(e_output);
@@ -109,7 +169,11 @@ export class OutputMatching {
     e_num = new Decimal(e_num.toFixed(decimalPlaces, Decimal.ROUND_FLOOR));
     const result = g_num.eq(e_num);
     const grade = result ? 1 : 0;
-    return OutputResult.createNumberResult(e_num.toNumber(), g_num.toNumber(), grade);
+    return OutputResult.createNumberResult(
+      e_num.toNumber(),
+      g_num.toNumber(),
+      grade
+    );
   }
 
   checkBoolean (g_bool, e_bool) {
@@ -120,57 +184,89 @@ export class OutputMatching {
   }
 
   checkStrings (g_output, e_ouput) {
-    const assessmentList = []
+    const assessmentList = [];
     let e_output_clean = e_ouput.trim();
     let g_output_clean = g_output.trim();
     if (OutputMatching.NUM_IN_STRING_REGEX.test(e_ouput)) {
-      const expected_numbers = e_ouput.match(OutputMatching.NUM_IN_STRING_REGEX);
-      const generated_numbers = g_output.match(OutputMatching.NUM_IN_STRING_REGEX) || [];
+      const expected_numbers = e_ouput.match(
+        OutputMatching.NUM_IN_STRING_REGEX
+      );
+      const generated_numbers =
+        g_output.match(OutputMatching.NUM_IN_STRING_REGEX) || [];
       const result = generated_numbers.map((val, i) => {
-        if(i >= expected_numbers.length) {
+        if (i >= expected_numbers.length) {
           return OutputResult.createNumberResult(null, val, 0);
         }
-        const g_val = new Decimal(val)
+        const g_val = new Decimal(val);
         const e_val = new Decimal(expected_numbers[i]);
         return this.checkNumbers(g_val, e_val);
       }, this);
-      if(expected_numbers.length > generated_numbers.length) {
-        for(let i = generated_numbers.length; i < expected_numbers.length; ++i) {
-          result.push(OutputResult.createNumberResult(expected_numbers[i], null, 0));
+      if (expected_numbers.length > generated_numbers.length) {
+        for (
+          let i = generated_numbers.length;
+          i < expected_numbers.length;
+          ++i
+        ) {
+          result.push(
+            OutputResult.createNumberResult(expected_numbers[i], null, 0)
+          );
         }
       }
-      e_output_clean = e_output_clean.replace(OutputMatching.NUM_IN_STRING_REGEX, '');
-      g_output_clean = g_output_clean.replace(OutputMatching.NUM_IN_STRING_REGEX, '');
-      const numberGrade = result.reduce((prev, r) => prev + r.grade, 0) / result.length;
+      e_output_clean = e_output_clean.replace(
+        OutputMatching.NUM_IN_STRING_REGEX,
+        ""
+      );
+      g_output_clean = g_output_clean.replace(
+        OutputMatching.NUM_IN_STRING_REGEX,
+        ""
+      );
+      const numberGrade =
+        result.reduce((prev, r) => prev + r.grade, 0) / result.length;
       assessmentList.push(numberGrade);
     }
-    if(OutputMatching.BOOLEAN_IN_STRING_REGEX.test(e_ouput)) {
-      const expected_bools = e_ouput.match(OutputMatching.BOOLEAN_IN_STRING_REGEX);
-      const generated_bools = g_output.match(OutputMatching.BOOLEAN_IN_STRING_REGEX) || [];
+    if (OutputMatching.BOOLEAN_IN_STRING_REGEX.test(e_ouput)) {
+      const expected_bools = e_ouput.match(
+        OutputMatching.BOOLEAN_IN_STRING_REGEX
+      );
+      const generated_bools =
+        g_output.match(OutputMatching.BOOLEAN_IN_STRING_REGEX) || [];
       const result = generated_bools.map((val, i) => {
-        if(i >= expected_bools.length) {
+        if (i >= expected_bools.length) {
           return OutputResult.createBoolResult(null, val, 0);
         }
         const g_bool = TypeParser.toBool(val);
         const e_bool = TypeParser.toBool(expected_bools[i]);
-        return this.checkBoolean(g_bool, e_bool );
+        return this.checkBoolean(g_bool, e_bool);
       }, this);
-      if(expected_bools.length > generated_bools.length) {
-        for(let i = generated_bools.length; i < expected_bools.length; ++i) {
-          result.push(OutputResult.createBoolResult(expected_bools[i], null, 0));
+      if (expected_bools.length > generated_bools.length) {
+        for (let i = generated_bools.length; i < expected_bools.length; ++i) {
+          result.push(
+            OutputResult.createBoolResult(expected_bools[i], null, 0)
+          );
         }
       }
-      e_output_clean = e_output_clean.replace(OutputMatching.BOOLEAN_IN_STRING_REGEX, '');
-      g_output_clean = g_output_clean.replace(OutputMatching.BOOLEAN_IN_STRING_REGEX, '');
-      const boolGrade = result.reduce((prev, r) => prev + r.grade, 0) / result.length;
+      e_output_clean = e_output_clean.replace(
+        OutputMatching.BOOLEAN_IN_STRING_REGEX,
+        ""
+      );
+      g_output_clean = g_output_clean.replace(
+        OutputMatching.BOOLEAN_IN_STRING_REGEX,
+        ""
+      );
+      const boolGrade =
+        result.reduce((prev, r) => prev + r.grade, 0) / result.length;
       assessmentList.push(boolGrade);
     }
     const dist = levenshteinDistance(g_output_clean, e_output_clean);
-    let gradeDiff = Math.max(0, e_output_clean.length - dist)/e_output_clean.length;
+    let gradeDiff =
+      Math.max(0, e_output_clean.length - dist) / e_output_clean.length;
     gradeDiff = Number.isNaN(gradeDiff) ? 0 : gradeDiff;
     const assessment_size = assessmentList.length + 1;
-    const gradeAcc = assessmentList.reduce((prev, val) => prev + val/assessment_size, 0);
-    const finalGrade = 1 * (gradeDiff/assessment_size + gradeAcc);
+    const gradeAcc = assessmentList.reduce(
+      (prev, val) => prev + val / assessment_size,
+      0
+    );
+    const finalGrade = 1 * (gradeDiff / assessment_size + gradeAcc);
     return OutputResult.createStringResult(e_ouput, g_output, finalGrade);
   }
 
@@ -178,4 +274,3 @@ export class OutputMatching {
     return LocalizedStrings.getError(errorID, args);
   }
 }
-