Kreitzo Kreitzo - 3 months ago 7
Javascript Question

How to test a function with different inputs

function addTwo (a, b) {
return a + b;
}

//Leave the function call
addTwo(50, 100);


I'm learning React and I'm trying to create a codecademy type site as a 'learning project', but have run into a JS problem.

Say you have the function above, how do you test it for more than one case? So far I'm testing with:

eval(CODE PULLED IN HERE) === 150 ? alert('Correct!') : alert('Wrong!');


which is obviously going to alert Correct, which is ok for this case. But for other questions (and even this one) I'm going to want more than one test case and that's where I'm stuck.

So, how can I test for multiple test cases, or is there just a whole other way of doing what I'm trying to achieve?

Any help/tips greatly appreciated,

For those who know React here's some code to see a bit of what I currently have :

const CodeEditor = React.createClass({
getInitialState () {
var initialValue = [
"function addTwo () {",
" ",
"}",
"//Leave the function call",
"addTwo(50, 100);"
].join("\n");

return {
kataValue: initialValue
}
},
onChange (newValue) {
this.setState({kataValue: newValue});
},
evalCode () {
var val = this.state.kataValue
eval(val) === 150 ? alert('Correct!') : alert('Wrong!');
},
render () {
return (
<div className="code-editor-wrapper">
<AceEditor
name="editor"
mode="sh"
theme="chaos"
onChange={this.onChange}
value={this.state.kataValue}
editorProps={{$blockScrolling: true}}
/>
<button onClick={this.evalCode} className="spec-btn submit-code-btn">Evaluate</button>
</div>
)
}
})

Answer

Don't include the function call in the user's code. Only require the function to be named in a certain way. Instead of directly evaling the user's code, embed into a function that returns the user's function:

function getUserFunction(code, functionName) {
  var userCode = new Function(code + '; return ' + functionName + ';');
  return userCode();
}

After calling getUserFunction you have a reference to the function the user wrote and you can execute it as often as you want. How you structure your test cases and how much feedback you want to give to the user is up to you.

Here is small example:

var userFn = getUserFunction(this.state.kataValue, 'addTwo');
var testCases = [
  [[50, 100], 150],
  [[1, 2], 3],
];
var passes = testCases.every(
  ([input, output]) => userFn(...input) === output
);
if (passes) {
  // all test cases pass
}
Comments