-
Notifications
You must be signed in to change notification settings - Fork 0
/
doctest.js
8 lines (8 loc) · 3.65 KB
/
doctest.js
1
2
3
4
5
6
7
8
if('undefined'!=typeof __filename){function isCodeLine(b){return /^\.(\.)+ .*$/.test(b)||/^>>>? .*$/.test(b)}function isEqual(b,d){if(b===d)return!0;var e=Object.prototype.toString.call(b);if(e!==Object.prototype.toString.call(d))return!1;if(0>['[object Array]','[object Object]'].indexOf(e))return!1;var f='[object Array]'===e?b.length:Object.keys(b).length,g='[object Array]'===e?d.length:Object.keys(d).length;if(f!==g)return!1;var h=function(l,m){var n=Object.prototype.toString.call(l);if(!(0<=['[object Array]','[object Object]'].indexOf(n))){if(n!==Object.prototype.toString.call(m))return!1;if('[object Function]'===n){if(l.toString()!==m.toString())return!1;}else if(l!==m)return!1}else if(!isEqual(l,m))return!1};if('[object Array]'===e){for(var j=0;j<f;j++)if(!1===h(b[j],d[j]))return!1;}else for(var k in b)if(b.hasOwnProperty(k)&&!1===h(b[k],d[k]))return!1;return!0}function strike(b){let d='';for(let e of b.split(''))d=d+e+'\u0336';return d}function test(code,output,last){let expected,actual,error=!1,correctLines=0;console.oldLog=console.log,console.log=function(b){return console.oldLog(b),b};try{if(actual=eval(code.join('\n')),void 0==actual||definitions.some(b=>code[code.length-1].startsWith(b+' ')))for(let line,x=code.length-1;0<=x;x--)if(line=code[x],-1!==line.indexOf('='))for(let definition of definitions)if(line.startsWith(definition+' ')){line.endsWith(';')||(line+=';'),line+='\n '+line.split('=')[0].replace(definition,'').trimRight()+';',code[x]=line;let result=eval(code.join('\n'));if(void 0!==result){actual=result;break}}try{expected=eval('('+output.join('\n')+')')}catch(b){expected=output.join('\n')}}catch(err){actual=`${err.name}: ${err.message}`,expected=output.join('\n'),error=!0;for(let x=last+1;x<code.length;x+=1)try{eval(code.slice(0,x)),correctLines+=1}catch(b){break}}console.log=console.oldLog,console.oldLog=void 0;let correct=isEqual(actual,expected);return[error,correct,expected,actual,correctLines]}function itemsFormat(b){return 1===b?'item':'items'}var lineReader=require('readline').createInterface({input:require('fs').createReadStream(__filename)});let definitions=['const','let','var'],lines=[],testing=!1;lineReader.on('line',function(b){if(/`"""/.test(b)&&0===lines.length)return void(testing=!0);/"""`/.test(b)&&(testing=!1);testing&&0!==b.trim().length&&!b.startsWith('//')&&(0===lines.length||isCodeLine(b)||isCodeLine(lines[lines.length-1])?lines.push(b):lines[lines.length-1]+='\n'+b)}).on('close',function(){let b=[],d=[],e=0,f=0,g=0,h=!1;for(let k,j=0;j<lines.length;j+=1)if(k=lines[j],isCodeLine(k))b.push(k.substring(k.indexOf(' ')+1).trim());else if(0!==k.length&&d.push(k),0!==d.length){let l=test(b,d,g);if(l[1])f+=1,console.log('\x1B[92m\u2713 \x1B[0m\x1B[94m'+b[b.length-1]+'\x1B[0m'),h=!0;else{h&&(console.log(strike(Array(80).join('-'))),h=!1);let p='\x1B[94m'+b.slice(g,b.length).map(u=>`\t${u}`).join('\n')+'\x1B[0m',q='\x1B[94m'+(void 0===l[2]?void 0:JSON.stringify(l[2]).replace(/\\n/g,'\n\t'))+'\x1B[0m',r='\x1B[94m'+(void 0===l[3]?void 0:JSON.stringify(l[3]).replace(/\\n/g,'\n\t'))+'\x1B[0m';console.log(`${'\x1B[91mTrying\x1B[0m'}:
${p}
${'\x1B[93mExpecting\x1B[0m'}:
${q}
${'\x1B[92mActual\x1B[0m'}:
${r}`),console.log(strike(Array(80).join('-'))),e+=1}l[0]?b=b.slice(0,g+l[4]):g=b.length,d=[]}if(0!==d.length&&test(b,d),0==e)console.log('All items are correct \x1B[92m'+String.fromCodePoint(128526)+'\x1B[0m');else if(0==f)console.log('All items are incorrect \x1B[91m'+String.fromCodePoint(9760)+'\x1B[0m');else{let j='\x1B[95m'+(f+e)+' '+itemsFormat(f+e)+'\x1B[0m',k='\x1B[92m'+f+' '+itemsFormat(f)+' correct \u2713\x1B[0m',l='\x1B[91m'+e+' '+itemsFormat(e)+' failed \u2715\x1B[0m';console.log(`${j}
${k}
${l}`)}})}