-
Notifications
You must be signed in to change notification settings - Fork 8
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Add gitignore * Add support for JS files - Needed for WebGL code brought in from cadet-frontend - Changes build directory to avoid overwriting JS files * Stop ignoring JS files * Add lodash dependency * Add dependencies * Add graphics and matrix library * Add rune autograder test cases * Include rune library and fix run to take in Library * Fix globals in test_runes * Add build script and ensure build works * Remove commented-out line * Use import instead of require * Add tests for 3D runes * Fix broken build script * Ignore grader.zip * Add dummy visualisation functions - No parameters causes a slang runtime error - Not defining the functions will also cause a runtime error * Use dynamic import for graphics library The handler used in the AWS lambda is runAll. However, we have no idea whether the gloval environment (modified by rune_library.js) is preserved between lambda calls (or if it was there to begin with). This change causes the rune library to be loaded everytime the handler is called, ensuring the pre-condition of having the rune libraries. If needed, event.name can be used to load up particular libraries if there are clashes. Note that this behavior parallels how the libraries are loaded in the frontend, having to be loaded into the global scope. * Update README with rune functions
- Loading branch information
Showing
12 changed files
with
5,298 additions
and
6 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
node_modules/ | ||
*.map | ||
build/ | ||
grader.zip |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
#!/bin/bash - | ||
|
||
if [ -d node_modules ] | ||
then | ||
rm -rf node_modules | ||
fi | ||
|
||
if [ -d build ] | ||
then | ||
rm -rf build | ||
fi | ||
|
||
if [ -f grader.zip ] | ||
then | ||
rm grader.zip | ||
fi | ||
|
||
yarn install --production=true | ||
tsc | ||
cd build && zip -r --exclude=*terraform* ../grader.zip index.js graphics/ && cd .. | ||
zip -ur grader.zip node_modules/ | ||
yarn install --production=false |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,94 @@ | ||
import { Grader, Student } from './types'; | ||
|
||
const validStudentCorrect = | ||
` | ||
const a = () => blue(quarter_turn_left(quarter_turn_left(quarter_turn_left(nova_bb)))); | ||
const b = () => stack(quarter_turn_right(nova_bb), quarter_turn_right(nova_bb)); | ||
const c = (p1, p2, p3, p4) => beside(stack(p1, p2), stack(p3, p4)); | ||
function d(rune, n) { | ||
if (n === 1) { | ||
return rune; | ||
} else { | ||
return beside(rune, stack(d(rune, n - 1), d(rune, n - 1))); | ||
} | ||
} | ||
` | ||
|
||
const validStudentWrong = | ||
` | ||
const a = () => quarter_turn_left(nova_bb); | ||
const b = () => stack(quarter_turn_left(nova_bb), quarter_turn_right(nova_bb)); | ||
const c = (p1, p2, p3, p4) => beside(stack(p2, p1), stack(p4, p3)); | ||
const d = (rune, n) => rune; | ||
` | ||
|
||
const validStudentPartial = | ||
` | ||
const a = () => blue(quarter_turn_right(nova_bb)); | ||
const b = () => stack(quarter_turn_left(nova_bb), quarter_turn_left(nova_bb)); | ||
const c = (p1, p2, p3, p4) => stack(beside(p1, p3), beside(p2, p4)); | ||
const d = (rune, n) => (n === 1) ? rune : beside(rune, stack(d(rune, n - 1), d(rune, n - 1))); | ||
` | ||
|
||
export const student: Student = { | ||
invalid: { | ||
runtime: null, | ||
syntax: null | ||
}, | ||
valid: { | ||
correct: validStudentCorrect, | ||
wrong: validStudentWrong, | ||
partial: validStudentPartial | ||
} | ||
} | ||
|
||
const validGrader = [ | ||
` | ||
function rune_testcase_a() { | ||
const expected_result = quarter_turn_right(blue(nova_bb)); | ||
const actual_result = a(); | ||
return __are_pictures_equal(actual_result, expected_result) ? 2 : 0; | ||
} | ||
rune_testcase_a(); | ||
`, | ||
` | ||
function rune_testcase_b() { | ||
const expected_result = stack(quarter_turn_right(nova_bb), quarter_turn_right(nova_bb)); | ||
const actual_result = b(); | ||
return __are_pictures_equal(actual_result, expected_result) ? 2 : 0; | ||
} | ||
rune_testcase_b(); | ||
`, | ||
` | ||
function rune_testcase_c() { | ||
const expected_result = beside(stack(nova_bb, heart_bb), stack(rcross_bb, circle_bb)); | ||
const actual_result = c(nova_bb, heart_bb, rcross_bb, circle_bb); | ||
return __are_pictures_equal(actual_result, expected_result) ? 2 : 0; | ||
} | ||
rune_testcase_c(); | ||
`, | ||
` | ||
function rune_testcase_d() { | ||
function fractal(rune, n) { | ||
if (n === 1) { | ||
return rune; | ||
} else { | ||
const pic = fractal(rune, n - 1); | ||
return beside(rune, stack(pic, pic)); | ||
} | ||
} | ||
const expected_result = fractal(nova_bb, 7); | ||
const actual_result = d(nova_bb, 7); | ||
return __are_pictures_equal(actual_result, expected_result) ? 2 : 0; | ||
} | ||
rune_testcase_d(); | ||
`, | ||
] | ||
|
||
export const grader: Grader = { | ||
invalid: { | ||
runtime: null, | ||
syntax: null | ||
}, | ||
valid: validGrader | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,95 @@ | ||
import { Grader, Student } from './types'; | ||
|
||
const validStudentCorrect = | ||
` | ||
const a = () => overlay_frac(0.5, heart_bb, nova_bb); | ||
const b = () => overlay_frac(0.25, quarter_turn_left(quarter_turn_left(quarter_turn_left(nova_bb))), scale(0.4, heart_bb)); | ||
const c = (p1, p2, p3, p4) => overlay(stack(beside(p1, p2), beside(blank_bb, blank_bb)), stack(beside(blank_bb, blank_bb), beside(p3, p4))); | ||
function d(rune, n) { | ||
if (n === 1) { | ||
return rune; | ||
} else { | ||
const bottom = d(rune, n - 1); | ||
return overlay_frac(1/n, scale(1/n, rune), bottom); | ||
} | ||
} | ||
` | ||
|
||
const validStudentWrong = | ||
` | ||
const a = () => overlay(nova_bb, heart_bb); | ||
const b = () => overlay_frac(0.25, quarter_turn_left(quarter_turn_left(quarter_turn_left(nova_bb))), scale(0.3, heart_bb)); | ||
const c = (p1, p2, p3, p4) => overlay(stack(beside(p1, blank_bb), beside(blank_bb, p2)), stack(beside(blank_bb, p3), beside(p4, blank_bb))); | ||
const d = (rune, n) => rune; | ||
` | ||
|
||
const validStudentPartial = | ||
` | ||
const a = () => overlay_frac(0.5, heart_bb, nova_bb); | ||
const b = () => overlay_frac(0.3, quarter_turn_left(quarter_turn_left(quarter_turn_left(nova_bb))), scale(0.4, heart_bb)); | ||
const c = (p1, p2, p3, p4) => overlay(beside(stack(p1, blank_bb), stack(p2, blank_bb)), beside(stack(blank_bb, p3), stack(blank_bb, p4))); | ||
const d = (rune, n) => (n === 1) ? rune : beside(rune, stack(d(rune, n - 1), d(rune, n - 1))); | ||
` | ||
|
||
export const student: Student = { | ||
invalid: { | ||
runtime: null, | ||
syntax: null | ||
}, | ||
valid: { | ||
correct: validStudentCorrect, | ||
wrong: validStudentWrong, | ||
partial: validStudentPartial | ||
} | ||
} | ||
|
||
const validGrader = [ | ||
` | ||
function rune_testcase_a() { | ||
const expected_result = overlay(heart_bb, nova_bb); | ||
const actual_result = a(); | ||
return __are_pictures_equal(actual_result, expected_result) ? 2 : 0; | ||
} | ||
rune_testcase_a(); | ||
`, | ||
` | ||
function rune_testcase_b() { | ||
const expected_result = overlay_frac(0.25, quarter_turn_right(nova_bb), scale(0.4, heart_bb)); | ||
const actual_result = b(); | ||
return __are_pictures_equal(actual_result, expected_result) ? 2 : 0; | ||
} | ||
rune_testcase_b(); | ||
`, | ||
` | ||
function rune_testcase_c() { | ||
const expected_result = overlay(stack(beside(nova_bb, heart_bb), beside(blank_bb, blank_bb)), stack(beside(blank_bb, blank_bb), beside(rcross_bb, circle_bb))); | ||
const actual_result = c(nova_bb, heart_bb, rcross_bb, circle_bb); | ||
return __are_pictures_equal(actual_result, expected_result) ? 2 : 0; | ||
} | ||
rune_testcase_c(); | ||
`, | ||
` | ||
function rune_testcase_d() { | ||
function tree(rune, n) { | ||
if (n === 1) { | ||
return rune; | ||
} else { | ||
const bottom = tree(rune, n - 1); | ||
return overlay_frac(1/n, scale(1/n, rune), bottom); | ||
} | ||
} | ||
const expected_result = tree(nova_bb, 7); | ||
const actual_result = d(nova_bb, 7); | ||
return __are_pictures_equal(actual_result, expected_result) ? 2 : 0; | ||
} | ||
rune_testcase_d(); | ||
`, | ||
] | ||
|
||
export const grader: Grader = { | ||
invalid: { | ||
runtime: null, | ||
syntax: null | ||
}, | ||
valid: validGrader | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
import { grader, student } from './examples/runes2d' | ||
import { awsEventFactory } from './helpers' | ||
import { runAll } from '../index' | ||
|
||
const makeAwsEvent = awsEventFactory({ | ||
chapter: 1, | ||
external: { | ||
name: 'TWO_DIM_RUNES', | ||
symbols: [ | ||
'red', | ||
'pink', | ||
'purple', | ||
'indigo', | ||
'blue', | ||
'green', | ||
'yellow', | ||
'orange', | ||
'brown', | ||
'black', | ||
'white', | ||
'black_bb', | ||
'blank_bb', | ||
'rcross_bb', | ||
'sail_bb', | ||
'corner_bb', | ||
'nova_bb', | ||
'circle_bb', | ||
'heart_bb', | ||
'pentagram_bb', | ||
'ribbon_bb', | ||
'quarter_turn_left', | ||
'quarter_turn_right', | ||
'scale_independent', | ||
'scale', | ||
'translate', | ||
'rotate', | ||
'stack_frac', | ||
'stack', | ||
'stackn', | ||
'beside_frac', | ||
'beside', | ||
'flip_vert', | ||
'flip_horiz', | ||
'make_cross', | ||
'repeat_pattern', | ||
'overlay_frac', | ||
'overlay', | ||
'__compile', | ||
'__are_pictures_equal', | ||
] | ||
}, | ||
globals: [] | ||
}) | ||
|
||
test('rune grader OK, student OK, correct', async () => { | ||
const results = await runAll(makeAwsEvent(grader.valid, student.valid.correct)) | ||
expect(results).toEqual([ | ||
{'grade': 2, 'resultType': 'pass'}, | ||
{'grade': 2, 'resultType': 'pass'}, | ||
{'grade': 2, 'resultType': 'pass'}, | ||
{'grade': 2, 'resultType': 'pass'}, | ||
]) | ||
}) | ||
|
||
test('rune grader OK, student OK, wrong', async () => { | ||
const results = await runAll(makeAwsEvent(grader.valid, student.valid.wrong)) | ||
expect(results).toEqual([ | ||
{'grade': 0, 'resultType': 'pass'}, | ||
{'grade': 0, 'resultType': 'pass'}, | ||
{'grade': 0, 'resultType': 'pass'}, | ||
{'grade': 0, 'resultType': 'pass'}, | ||
]) | ||
}) | ||
|
||
test('rune grader OK, student OK, partial', async () => { | ||
const results = await runAll(makeAwsEvent(grader.valid, student.valid.partial)) | ||
expect(results).toEqual([ | ||
{'grade': 2, 'resultType': 'pass'}, | ||
{'grade': 0, 'resultType': 'pass'}, | ||
{'grade': 2, 'resultType': 'pass'}, | ||
{'grade': 2, 'resultType': 'pass'}, | ||
]) | ||
}) |
Oops, something went wrong.