Pop-up JavaScript challenges in your browser
Try thesedemos:
Challenger is a drop-in JavaScript library that adds interactive programming challenges to any page. Challenges are flexible and expressive, and are super simple to write.
A challenge has requirements based on code structure and program output, and gives users a code editor to experiment in. When new code is written, it's run in a sandbox and the output is analyzed.
Challenges can be presented as one-off tests or linked together to form courses.
Challenges are defined as simple JavaScript objects. The following optional keys can be set:
title
— the challenge's title
description
— a short description of the challenge
initialCode
— text to be loaded into the code editor on initialization
whitelist
— an array of ParserAPI strings, indicating expressions that must exist in the student's code
blacklist
— same as whitelist, but these expressions must not exist in the student's code
nestedRules
— an object indicating nested requirements. Naming conventions are consistent with the whitelist
and blacklist
, but each expression key can take another nested object as its value. Setting the required
attribute on an expression indicates when the expression is required or disallowed. For example:
// indicates that the student must include an if statement within a while
// statement, but must not include a for statement within a while statement.
var challenge = {
// ...
nestedRules: {
WhileStatement: {
IfStatement: {
required: true
},
ForStatement: {
required: false
}
}
}
};
customRules
— an array of objects describing custom rules. Each object must have two keys:
description
— a string that describes the rule
verify
— a function that takes the current user input as a string and returns a boolean
For example:
var challenge = {
// ...
customRules: [
{
description: 'Program must have the word \'foobar\' in it',
verify: function (str) { return str.indexOf('foobar') > -1; }
},
{
description: 'Program must be under 140 characters',
verify: function (str) { return str.length < 140; }
}
]
};
output
— an object specifying the program's expected behavior. The following keys can be set:
description
— a string that describes the rule
setup
— a string of code to run before the user's code
verify
— a function that accepts non-object, non-function arguments and returns a boolean. It is aliased to __verify__
in the challenge, and can be called from setup
and teardown
teardown
— a string of code to run after the user's code
For example:
// outer variables
var unsorted = [6, 1, 8, 6, 7, 2, 4, 3, 1];
var expected = unsorted.sort((a, b) => a > b);
var challenge = {
// ...
output: {
description: 'Program must sort an array of ints called "unsorted" in ' +
'ascending order and save it to a variable called "sorted"',
setup: `var unsorted = [${unsorted}];`,
verify: (...sorted) => sorted.every((n, i) => n === expected[i]),
teardown: 'if (Array.isArray(sorted)) __verify__(...sorted);'
}
};
Note: the above snippet uses features of ECMAScript 6. Good news: users can write their challenges using ES6 and it will be transpiled to ES5 before running!
To load a single challenge, pass its object into the challenger
function:
var challenger = require('challenger');
var newChallenge = {
title: 'My new challenge',
description: 'It\'s all about the Pentiums',
whitelist: ['DoWhileStatement']
};
challenger.loadCourse(newChallenge);
To create a course out of multiple challenges in sequence, pass an array of challenges into the challenger
function:
// ...
challenger.loadCourse([challenge1, challenge2, challenge3/*, ... */]);
The challenger
function can accept an options object as its last argument. The following keys can be set:
parent
— DOM Node to insert the challenge into. Defaults to document.body
onExit(success)
— a callback function to run when the challenge is closed; success
is boolean
successText
— a string to display when the user is successful
To install the library, use npm or bower:
bower install challenger # or...
npm install challenger
Challenger is also hosted on GitHub and cdnjs.
All necessary files exist within the /client/dist/
directory:
challenger.min.js
— the main library file
challenger.min.css
— the base stylesheet. Even if you plan on restyling the challenges, it's recommended that you include this; it will give the challenges some initial structure to work with
operative.min.js
— helper module, required if running output
rules in IE10
Sadly if you need to use IE10 with output
rules, require('challenger')
won't work without also copying operative.min.js
to the same folder as your script. Challenger runs all client code in a sandboxed Worker or iframe, and certain components need to be broken out and re-loaded into the sandbox. For more information on how sandboxing is implemented, check out operative.
9+ | 18+ | 15+ | 9+ | 5.1+ | 7+ |
If you need to support older browsers, include krisowal's es5-shim along with es5-sham.js
from the same repository. You might also need to tweak the CSS.