123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309 |
- import StringDiff from "./../../util/string_diff";
- import { LocalizedStrings } from "./../../services/localizedStringsService";
- export class OutputAssessmentResult {
- static get PAGE_TEMPLATE () {
- return `<!DOCTYPE html>
- <html>
- <head>
- <meta http-equiv='content-type' content='text/html; charset=UTF-8'>
- <link rel='stylesheet' href='css/ivprog-assessment.css' type='text/css'/>
- </head>
- <body>
- :assessment-result:
- </body>
- </html>`;
- }
- static get DETAIL_TEMPLATE () {
- return `<div class='details-body'>
- <div class='details-header'>
- <h2>:test-name:</h2>
- <p>:time-label:: <span>:time:ms</span></p>
- <p>:grade-label:: <span>:grade:%</span></p>
- </div>
- <div>
- <h3>:input-label:</h3>
- <ul>
- <li>:input-list:</li>
- </ul>
- </div>
- <div>
- <h3>:output-label:</h3>
- :output-result:
- </div>
- </div>`;
- }
- static get OUPUT_TABLE_TEMPLATE () {
- return `<div class='detaisl-div-table'>
- <table class='assessment-output-table'>
- <tr>
- <th>:expected-label:</th>
- <th>:generated-label:</th>
- <th>:result-label:</th>
- </tr>
- :results:
- </table>
- </div>`;
- }
- static get OUTPUT_TEMPLATE () {
- return `<tr><td class=':class-expected:'>$0</td>
- <td class=':class-generated:'>$1</td>
- <td class=':class-result:'>$2</td></tr>`;
- }
- static get EMPTY_OUTPUT_TEMPLATE () {
- return `<div class='assessment-popup'><img class='assessment-empty-output' src='img/empty.svg'>
- <span class='assessment-popuptext'>$0</span></div>`;
- }
- static get FAILED_TEMPLATE () {
- return `<p class='assessment-failed-execution'><span class='assessment-failed-case'>✗</span>$0</p>`;
- }
- static get INPUT_INFO_TEMPLATE () {
- return `<span class='$0'>$1</span>`;
- }
- // Status code - it is not grade related!
- // 0 - Succesful execution
- // 1 - failed execution
- constructor (
- name,
- status,
- inputs,
- result,
- store,
- time,
- tags,
- error_msg = "",
- error_id = ""
- ) {
- this.name = name;
- this.status = status;
- this.inputs = inputs;
- this.results = result;
- this.store = store;
- this.time = time;
- this.error_msg = error_msg;
- this.tags = tags;
- this.error_id = error_id;
- }
- get grade () {
- if (this.results == null) {
- return 0;
- }
- 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);
- 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") {
- return this.formatString(result);
- } else if (result.type == "number") {
- return this.formatNumber(result);
- } else {
- return this.formatBool(result);
- }
- }, this);
- template = template.replace(
- ":output-result:",
- this.prepareOutputTable(output_rows)
- );
- } else {
- let failed_text = OutputAssessmentResult.FAILED_TEMPLATE;
- failed_text = failed_text.replace("$0", this.error_msg);
- template = template.replace(":output-result:", failed_text);
- }
- return template;
- }
- prepareInputList (input_list) {
- const list = input_list.map((input) => {
- let template = OutputAssessmentResult.INPUT_INFO_TEMPLATE;
- template = template.replace("$1", input.value);
- 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"));
- }
- 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(""));
- return template;
- }
- generateOutput () {
- 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, "><");
- return page;
- }
- formatNumber (result) {
- 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";
- const template = this.formatOutput(
- "assessment-bool-expected",
- "assessment-bool-generated",
- result_class,
- result
- );
- return template;
- }
- formatOutput (expected_class, generated_class, result_class, result) {
- let template = OutputAssessmentResult.OUTPUT_TEMPLATE;
- template = template.replace(":class-expected:", expected_class);
- template = template.replace(":class-generated:", generated_class);
- 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")
- );
- }
- template = template.replace("$0", expected_tmpl);
- template = template.replace("$1", generated_tmpl);
- const final_result = result.grade == 1 ? "✓" : "✗";
- template = template.replace("$2", final_result);
- return template;
- }
- formatString (result) {
- const expected_class = "assessment-string-expected";
- const generated_class = "assessment-string-generated";
- //const result_class = 'assessment-string-result';
- let template = OutputAssessmentResult.OUTPUT_TEMPLATE;
- template = template.replace(":class-expected:", expected_class);
- template = template.replace(":class-generated:", generated_class);
- //template = template.replace(":class-result:", result_class);
- const g_string = result.generated || "";
- const e_string = result.expected || "";
- // 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")
- );
- } else if (result.expected == null) {
- 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) {
- template = template.replace("$2", "✓");
- 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_string = diff_vec.reduce((prev, actual) => prev + actual, "");
- 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>";
- // Fix missing whitespace when its a single element
- text = text.replace(/\s/g, " ");
- switch (action) {
- case StringDiff.INSERT:
- return template.replace("$0", "stringdiff-insert").replace("$1", text);
- case StringDiff.DELETE:
- return template.replace("$0", "stringdiff-delete").replace("$1", text);
- case StringDiff.EQUAL:
- return template.replace("$0", "stringdiff-equal").replace("$1", text);
- }
- }
- }
|