JSFiddle - React, Tailwind, and code Playground
by ellhn
HTML
<html>
<head>
<meta name="description" content="JS Developer Code Challenge" /><html>
<head>
<title>Coding Challenge</title>
<style>
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>The purpose is to save both candidates and ourselves from wasting time in interviews - it is therefore not in your interest to cheat.</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><b>DO NOT</b> share this exercise with any third party - this will undermine the use of the exercise with future candidates.</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>Credit will be given for approach, correctly identifying "failed" assertEquals, "clean" code and coding style.</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/>
Ideally the failure messages should report further information:
<ul class="expected">
<li>Test 02: Expected "abcdef" found "abc"</li>
...
JavaScript
function detectType (obj) {
return Object.prototype.toString.call(obj).split(' ')[1].slice(0, -1);
}
function Failed(analyticalMessage){
this.message=analyticalMessage;
}
function arrayCompare(a, b, path) { //it also manipulates nested arrays and objects inside arrays
// different types - fail
if (detectType(a)!==detectType(b)) {
let newPath="Expected type "+detectType(a)+" but found type "+detectType(b)+" in position "+path;
return newPath;
}
// object inside array
if (detectType(a)==='Object'){
return objectCompare(a,b,path);
}
// comparison of primitive values
if (detectType(a) !== 'Array') {
return a === b ? '' :"Expected "+a+" but found "+b+" in position "+ path;
}
if (a.length !== b.length) {
let output=" Expected Array length "+a.length+" but found length "+b.length;
return output;
}
let res = '';
// compare all the values of array a with the corresponding values of array b until we find a difference
a.some((elem,index) =>
res = arrayCompare(a[index], b[index], path+'['+index+']')
);
// return '' or the first failed path
return res;
} // end of arrayCompare
function objectCompare(a, b, path) {
// different types - fail
if (detectType(a)!==detectType(b)) {
let newPath="Expected type "+detectType(a)+" but found type "+detectType(b)+" in position "+path.substring(1);
return newPath;
}
// array inside object
if (detectType(a)==='Array'){
return arrayCompare(a,b,path);
}
// comparison of primitive values
if (detectType(a) !== 'Object') {
return a === b ? '' : "Expected "+a+" but found "+b+" in position "+ path.substring(1);
}
// make a set of keys from both objects
let keys = Object.keys(a).concat(Object.keys(b)).filter((elem, index, self) =>
self.indexOf(elem) === index
);
let res = '';
// for each key in set, compare values until we find a difference
keys.some(elem =>
res = objectCompare(a[elem], b[elem],...