Created
December 6, 2019 08:48
-
-
Save garryyao/cacb10f90f809a05855abbb81862a3fa to your computer and use it in GitHub Desktop.
Coding Challenge full-stack engineer challenge // source https://jsbin.com/hovusux
This file contains hidden or 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
<html> | |
<head> | |
<meta name="description" content="full-stack engineer challenge" /> | |
<title>Coding Challenge</title> | |
<style id="jsbin-css"> | |
body { | |
font-family: Arial; | |
font-size: 80%; | |
} | |
ul.expected { | |
font-family: Courier; | |
} | |
ul.output { | |
font-family: Courier; | |
background-color: white; | |
border: 1px solid #999999; | |
padding: 10px 30px 10px 30px; | |
} | |
ul.output li {; | |
margin-bottom: 10px; | |
} | |
ul.output li code { | |
font-size: 1.2em; | |
color: blue; | |
} | |
</style> | |
</head> | |
<body> | |
<h1>Terms of the Exercise</h1> | |
<ul> | |
<li>Try and stay away from libraries if possible</li> | |
<li>You can take as long as you like to complete the exercise, but for an indicative timescale we expect a senior developer can accomplish this in an hour.</li> | |
<li>You may use online resources to assist you with specific techniques, syntax etc. but please do not just copy code.</li> | |
<li>Please don't share this exercise with any third party</li> | |
<li>To submit your completed test, save here in jsbin and send us the new Url</li> | |
</ul> | |
<h1>The Challenge</h1> | |
<p> | |
The aim of the exercise is to demonstrate your problem solving and understanding of JavaScript by implementing something found in every unit testing tool - an "assertEquals" method.</p> | |
<ul> | |
<li>Fill in the "assertEquals" function such that it will correctly compare the passed "expected" vs "actual" parameters.</li> | |
<li>You may add more functions.</li> | |
<li>We are big on TDD, so we expect you to complete this test using this approach.</li> | |
<li>Credit will be given for approach, correctly identifying "failed" assertEquals, <b>clean, testable</b> code and coding style.</li> | |
<li>The set of tests provided isn't exhaustive - there are cases that they don't handle. We expect you to add more tests.</li> | |
</ul> | |
<h1>Expected Result</h1> | |
The following tests should "fail": <strong>02, 03, 04, 07, 08 and 09</strong> - and the failures should be reported using the provided mechanism.<br/> | |
We expect the following output for the lsit of tests we have provided, but we also expect you to add more tests: | |
<ul class="expected"> | |
<li>Test 02: Expected "abcdef" found "abc"</li> | |
<li>Test 03: Expected type Array but found type Object</li> | |
<li>Test 04: Expected array length 2 but found 3</li> | |
<li>Test 07: Expected propB.propA[1].propB "b" but found "c"</li> | |
<li>Test 08: Expected propB.propC but was not found</li> | |
<li>Test 09: Expected type Null but found type Object</li> | |
</ul> | |
<h1>Output</h1> | |
<ul class="output" id="messages"></ul> | |
<script id="jsbin-javascript"> | |
//jshint esnext:true | |
/** | |
* Asserts "expected" versus "actual", | |
* 'failing' the assertion (via Error) if a difference is found. | |
* | |
* @param {String} message The comparison message passed by the user | |
* @param {*} expected The expected item | |
* @param {*} actual The actual item | |
*/ | |
function assertEquals(message, expected, actual) { | |
} | |
/* -- Test running code: --- */ | |
/** | |
* Runs a "assertEquals" test. | |
* | |
* @param {String} message The initial message to pass | |
* @param {*} expected Expected item | |
* @param {*} actual The actual item | |
*/ | |
function runTest({ message, expected, actual }) { | |
try { | |
assertEquals(message, expected, actual); | |
} catch (error) { | |
return error.message; | |
} | |
} | |
function runAll() { | |
var complexObject1 = { | |
propA: 1, | |
propB: { | |
propA: [1, { propA: 'a', propB: 'b' }, 3], | |
propB: 1, | |
propC: 2 | |
} | |
}; | |
var complexObject1Copy = { | |
propA: 1, | |
propB: { | |
propA: [1, { propA: 'a', propB: 'b' }, 3], | |
propB: 1, | |
propC: 2 | |
} | |
}; | |
var complexObject2 = { | |
propA: 1, | |
propB: { | |
propB: 1, | |
propA: [1, { propA: 'a', propB: 'c' }, 3], | |
propC: 2 | |
} | |
}; | |
var complexObject3 = { | |
propA: 1, | |
propB: { | |
propA: [1, { propA: 'a', propB: 'b' }, 3], | |
propB: 1 | |
} | |
}; | |
var testCases = [ | |
{ message: 'Test 01', expected: 'abc', actual: 'abc' }, | |
{ message: 'Test 02', expected: 'abcdef', actual: 'abc' }, | |
{ message: 'Test 03', expected: ['a'], actual: {0: 'a'} }, | |
{ message: 'Test 04', expected: ['a', 'b'], actual: ['a', 'b', 'c'] }, | |
{ message: 'Test 05', expected: ['a', 'b', 'c'], actual: ['a', 'b', 'c'] }, | |
{ message: 'Test 06', expected: complexObject1, actual: complexObject1Copy }, | |
{ message: 'Test 07', expected: complexObject1, actual: complexObject2 }, | |
{ message: 'Test 08', expected: complexObject1, actual: complexObject3 }, | |
{ message: 'Test 09', expected: null, actual: {} }, | |
]; | |
assertionFailures = testCases.map(runTest) | |
.filter(result => result !== undefined) | |
.forEach(addToList) | |
} | |
function addToList(message) { | |
var messagesEl = document.getElementById('messages'); | |
var newListEl = document.createElement('li'); | |
newListEl.innerHTML = message; | |
messagesEl.appendChild(newListEl); | |
} | |
runAll(); | |
</script> | |
<script id="jsbin-source-css" type="text/css">body { | |
font-family: Arial; | |
font-size: 80%; | |
} | |
ul.expected { | |
font-family: Courier; | |
} | |
ul.output { | |
font-family: Courier; | |
background-color: white; | |
border: 1px solid #999999; | |
padding: 10px 30px 10px 30px; | |
} | |
ul.output li {; | |
margin-bottom: 10px; | |
} | |
ul.output li code { | |
font-size: 1.2em; | |
color: blue; | |
}</script> | |
<script id="jsbin-source-javascript" type="text/javascript">//jshint esnext:true | |
/** | |
* Asserts "expected" versus "actual", | |
* 'failing' the assertion (via Error) if a difference is found. | |
* | |
* @param {String} message The comparison message passed by the user | |
* @param {*} expected The expected item | |
* @param {*} actual The actual item | |
*/ | |
function assertEquals(message, expected, actual) { | |
} | |
/* -- Test running code: --- */ | |
/** | |
* Runs a "assertEquals" test. | |
* | |
* @param {String} message The initial message to pass | |
* @param {*} expected Expected item | |
* @param {*} actual The actual item | |
*/ | |
function runTest({ message, expected, actual }) { | |
try { | |
assertEquals(message, expected, actual); | |
} catch (error) { | |
return error.message; | |
} | |
} | |
function runAll() { | |
var complexObject1 = { | |
propA: 1, | |
propB: { | |
propA: [1, { propA: 'a', propB: 'b' }, 3], | |
propB: 1, | |
propC: 2 | |
} | |
}; | |
var complexObject1Copy = { | |
propA: 1, | |
propB: { | |
propA: [1, { propA: 'a', propB: 'b' }, 3], | |
propB: 1, | |
propC: 2 | |
} | |
}; | |
var complexObject2 = { | |
propA: 1, | |
propB: { | |
propB: 1, | |
propA: [1, { propA: 'a', propB: 'c' }, 3], | |
propC: 2 | |
} | |
}; | |
var complexObject3 = { | |
propA: 1, | |
propB: { | |
propA: [1, { propA: 'a', propB: 'b' }, 3], | |
propB: 1 | |
} | |
}; | |
var testCases = [ | |
{ message: 'Test 01', expected: 'abc', actual: 'abc' }, | |
{ message: 'Test 02', expected: 'abcdef', actual: 'abc' }, | |
{ message: 'Test 03', expected: ['a'], actual: {0: 'a'} }, | |
{ message: 'Test 04', expected: ['a', 'b'], actual: ['a', 'b', 'c'] }, | |
{ message: 'Test 05', expected: ['a', 'b', 'c'], actual: ['a', 'b', 'c'] }, | |
{ message: 'Test 06', expected: complexObject1, actual: complexObject1Copy }, | |
{ message: 'Test 07', expected: complexObject1, actual: complexObject2 }, | |
{ message: 'Test 08', expected: complexObject1, actual: complexObject3 }, | |
{ message: 'Test 09', expected: null, actual: {} }, | |
]; | |
assertionFailures = testCases.map(runTest) | |
.filter(result => result !== undefined) | |
.forEach(addToList) | |
} | |
function addToList(message) { | |
var messagesEl = document.getElementById('messages'); | |
var newListEl = document.createElement('li'); | |
newListEl.innerHTML = message; | |
messagesEl.appendChild(newListEl); | |
} | |
runAll();</script></body> | |
</html> |
This file contains hidden or 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
body { | |
font-family: Arial; | |
font-size: 80%; | |
} | |
ul.expected { | |
font-family: Courier; | |
} | |
ul.output { | |
font-family: Courier; | |
background-color: white; | |
border: 1px solid #999999; | |
padding: 10px 30px 10px 30px; | |
} | |
ul.output li {; | |
margin-bottom: 10px; | |
} | |
ul.output li code { | |
font-size: 1.2em; | |
color: blue; | |
} |
This file contains hidden or 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
//jshint esnext:true | |
/** | |
* Asserts "expected" versus "actual", | |
* 'failing' the assertion (via Error) if a difference is found. | |
* | |
* @param {String} message The comparison message passed by the user | |
* @param {*} expected The expected item | |
* @param {*} actual The actual item | |
*/ | |
function assertEquals(message, expected, actual) { | |
} | |
/* -- Test running code: --- */ | |
/** | |
* Runs a "assertEquals" test. | |
* | |
* @param {String} message The initial message to pass | |
* @param {*} expected Expected item | |
* @param {*} actual The actual item | |
*/ | |
function runTest({ message, expected, actual }) { | |
try { | |
assertEquals(message, expected, actual); | |
} catch (error) { | |
return error.message; | |
} | |
} | |
function runAll() { | |
var complexObject1 = { | |
propA: 1, | |
propB: { | |
propA: [1, { propA: 'a', propB: 'b' }, 3], | |
propB: 1, | |
propC: 2 | |
} | |
}; | |
var complexObject1Copy = { | |
propA: 1, | |
propB: { | |
propA: [1, { propA: 'a', propB: 'b' }, 3], | |
propB: 1, | |
propC: 2 | |
} | |
}; | |
var complexObject2 = { | |
propA: 1, | |
propB: { | |
propB: 1, | |
propA: [1, { propA: 'a', propB: 'c' }, 3], | |
propC: 2 | |
} | |
}; | |
var complexObject3 = { | |
propA: 1, | |
propB: { | |
propA: [1, { propA: 'a', propB: 'b' }, 3], | |
propB: 1 | |
} | |
}; | |
var testCases = [ | |
{ message: 'Test 01', expected: 'abc', actual: 'abc' }, | |
{ message: 'Test 02', expected: 'abcdef', actual: 'abc' }, | |
{ message: 'Test 03', expected: ['a'], actual: {0: 'a'} }, | |
{ message: 'Test 04', expected: ['a', 'b'], actual: ['a', 'b', 'c'] }, | |
{ message: 'Test 05', expected: ['a', 'b', 'c'], actual: ['a', 'b', 'c'] }, | |
{ message: 'Test 06', expected: complexObject1, actual: complexObject1Copy }, | |
{ message: 'Test 07', expected: complexObject1, actual: complexObject2 }, | |
{ message: 'Test 08', expected: complexObject1, actual: complexObject3 }, | |
{ message: 'Test 09', expected: null, actual: {} }, | |
]; | |
assertionFailures = testCases.map(runTest) | |
.filter(result => result !== undefined) | |
.forEach(addToList) | |
} | |
function addToList(message) { | |
var messagesEl = document.getElementById('messages'); | |
var newListEl = document.createElement('li'); | |
newListEl.innerHTML = message; | |
messagesEl.appendChild(newListEl); | |
} | |
runAll(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment