Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions grade.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<!DOCTYPE html>
<html lang="en"><link rel="stylesheet" href="styles/grade.css">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>flapjs grading</title>
</head>
<body>

<input type="file" name="test cases" id="test_cases">
<input type="text" name="machine url" id="machine_url">
<button id="start_test">test</button>
<div id="display_test_cases"></div>

</body>
<script src="scripts/grade.js" type="module"></script>
</html>
2 changes: 1 addition & 1 deletion scripts/compute.js
Original file line number Diff line number Diff line change
Expand Up @@ -393,7 +393,7 @@ function* run_input_Moore(graph, input, interactive) {
* @param {string} input - input string
* @param {boolean} interactive - whether to step through and highlight the computation
* @returns {Iterable} return a generator that
* if noninteractive, evaluates to the final accept/reject immediately in one step
* if noninteractive, evaluates to the final accept/reject immediately in one step
* if interactive, evaluates step by step with highlight
*/
export function run_input(graph, machine_type, input, interactive=false) {
Expand Down
109 changes: 109 additions & 0 deletions scripts/grade.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
/** @module grade */

import * as compute from './compute.js';
import * as permalink from './permalink.js';

// if not in browser, don't run
if (typeof document !== 'undefined') {
const cur_file_path = window.location.pathname;
if (cur_file_path.includes('grade.html')) {
document.addEventListener('DOMContentLoaded', init);
}
}

let test_cases = [];
let graph = {};

function display_test_cases(test_cases) {
const test_cases_display_area = document.getElementById('display_test_cases');
while (test_cases_display_area.childElementCount) { // wipe all elements
test_cases_display_area.removeChild(test_cases_display_area.firstChild);
}
for (const [input_string, accepted] of test_cases) {
const test_case_div = document.createElement('div');
const test_string_span = document.createElement('span');
const test_result_span = document.createElement('span');
test_result_span.className = 'result_class';
test_result_span.id = `${input_string}_result`;
test_string_span.innerText = input_string;
test_result_span.innerText = accepted ? 'accepted' : 'rejected';
test_case_div.appendChild(test_string_span);
test_case_div.appendChild(test_result_span);
test_cases_display_area.appendChild(test_case_div);
}
}

/**
* given test cases as plain text, parse the document and store the results in `test_cases`
* @param {string} text - a string consisting of lines of input. every two line specify a test case, with
* the first line being the input string and the second line being accept/reject
*/
function parse_test_cases(text) {
test_cases = []; // clear
const lines = text.trimEnd().split('\n') // if the file ends with a new line, remove it
if (lines.length & 1) {
alert('invalid test file: odd number of lines');
return;
}
for (let i = 0; i < lines.length; i+=2) {
let accepted;
switch (lines[i+1]) {
case 'accepted':
accepted = true;
break;
case 'rejected':
accepted = false;
break;
default:
alert('invalid test file: keywords other than "accepted" or "rejected"');
return;
}
test_cases.push([lines[i], accepted]);
}
display_test_cases(test_cases);
}

function test_all_cases() {
const url_input = document.getElementById('machine_url');
const url = url_input.value;
const graph_str = url.substring(url.indexOf('#')+1);
let type, graph;
try {
[type, graph] = permalink.deserialize(graph_str);
} catch {
alert('invalid graph')
return;
}

for (const [input_string, expected] of test_cases) {
// eslint-disable-next-line no-unused-vars
const { value: actual, _ } = compute.run_input(graph, type, input_string).next();
const color = (expected == actual) ? 'green' : 'red';
const input_string_result = document.getElementById(`${input_string}_result`);
input_string_result.style.background = color;
}
}

function upload_test_cases() {
const test_case_uploader = document.getElementById('test_cases');
const fr = new FileReader();
fr.onload = () => parse_test_cases(fr.result);
if (test_case_uploader.files.length) {
fr.readAsText(test_case_uploader.files[0])
}
}

function init() {
const test_case_uploader = document.getElementById('test_cases');
test_case_uploader.addEventListener('change', upload_test_cases);
const start_test_btn = document.getElementById('start_test');
start_test_btn.addEventListener('click', test_all_cases);
const url_input = document.getElementById('machine_url');
url_input.addEventListener('click', () => {
for (const elem of document.getElementsByClassName('result_class')) {
if (elem.style.background) {
elem.style.background = '';
}
}
});
}
12 changes: 8 additions & 4 deletions scripts/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,15 @@ import * as ui_setup from './ui_setup.js';

// if not in browser, don't run
if (typeof document !== 'undefined') {
document.addEventListener('DOMContentLoaded', init);
window.addEventListener('resize', () => drawing.draw(graph));
// get current page
const cur_file_path = window.location.pathname;
if (!cur_file_path.includes('grade.html')) {
document.addEventListener('DOMContentLoaded', init);
window.addEventListener('resize', () => drawing.draw(graph));
}
}

let graph = {}; // global graph
let graph = {}; // global graph, initially empty

/** handles double click */
function bind_double_click() {
Expand Down Expand Up @@ -415,7 +419,7 @@ function init() {
bind_dd();
bind_permalink();
bind_mousemove();
ui_setup.bind_plus_minus();
ui_setup.bind_plus_minus(``);
ui_setup.add_input_bar(); // called so one input bar appears on opening of homepage
ui_setup.htmlSetUp(); // initiate eventlisteners for sidenavbar, second sidenavbar, and popup tutorial
init_graph(); // leave this last since we want it to override some of the above
Expand Down
4 changes: 4 additions & 0 deletions styles/grade.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#display_test_cases > div {
display: flex;
justify-content: space-between;
}
10 changes: 10 additions & 0 deletions test_cases.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
101
rejected
01
accepted

accepted
0011
accepted
00111
rejected