Last active
June 22, 2018 14:17
-
-
Save ChALkeR/a592f1e79624806b383007d7c5d4a395 to your computer and use it in GitHub Desktop.
Node.js error test (https://github.com/nodejs/node/issues/21440)
This file contains 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
// Flags: --expose-internals | |
// Note: this script reads Node.js sources and docs, and expects to be run on | |
// the very same Node.js version as the source and doc tree is. | |
const errors = require('internal/errors').codes; | |
const assert = require('assert'); | |
const fs = require('fs'); | |
const natives = process.binding('natives'); | |
// --report prints only the list of failed checks and does not assert | |
const report = process.argv[2] === '--report'; | |
const results = []; | |
function check(ok, type, name, reason) { | |
if (report) { | |
if (!ok) results.push(`${type}: ${name} - ${reason}`); | |
} else { | |
assert.ok(ok, `${type}: ${name} - ${reason}`); | |
} | |
} | |
const set = { | |
all: new Set(), | |
js: new Set(), | |
doc: new Set(), | |
cpp: new Set(), | |
noargs: new Set(), | |
// `set.manual` contains errors manually created from js and not defined in | |
// internals/errors. That is not scanned now, update this list if required. | |
manual: new Set(['ERR_HTTP2_ERROR', 'ERR_UNKNOWN_BUILTIN_MODULE']) | |
}; | |
// File containing error definitions | |
const jsdata = natives['internal/errors']; | |
// File containing error documentation | |
const docdata = fs.readFileSync('doc/api/errors.md', 'utf-8'); | |
// File containing cpp-side errors | |
const cppdata = fs.readFileSync('src/node_errors.h', 'utf-8'); | |
function addSource(source, type) { | |
const re = /(.)?(ERR_[A-Z0-9_]+)(..)?/g; | |
let match; | |
while (match = re.exec(source)) { | |
if (match[1] === '_') continue; // does not start with ERR_ | |
set.all.add(match[2]); | |
set[type].add(match[2]); | |
if (type === 'js' && match[3] === '()') { | |
// Is directly called without arguments from js, we will try that | |
set.noargs.add(match[2]); | |
} | |
} | |
} | |
// Scan all JS natives | |
for (const file of Object.keys(natives)) addSource(natives[file], 'js'); | |
// Add all errors from doc/api/errors and src/node_errors | |
addSource(docdata, 'doc'); | |
addSource(cppdata, 'cpp'); | |
// Check that we have all js errors | |
for (const name of set.js) { | |
if (set.manual.has(name)) continue; | |
const defined = jsdata.includes(`E('${name}',`); | |
check(defined, 'js', name, 'missing JS implementation (source)'); | |
if (defined) { | |
check(errors[name], 'js', name, 'missing JS implementation (runtime)'); | |
} | |
} | |
// Check that we have can initialize errors called without args | |
for (const name of set.noargs) { | |
if (!errors[name]) continue; // Already catched that above | |
let ok = true; | |
try { | |
new errors[name](); | |
} catch (e) { | |
ok = false; | |
} | |
check(ok, 'init', name, 'failed 0 args init, but is called with "()"'); | |
} | |
// Check that we have all documented errors | |
for (const name of set.doc) { | |
const ok = set.manual.has(name) || | |
jsdata.includes(`E('${name}',`) || | |
cppdata.includes(`V(${name}, `); | |
check(ok, 'impl', name, 'documented, missing implementation'); | |
} | |
// Check error documentation for all errors | |
for (const name of set.all) { | |
const ok = docdata.includes(`### ${name}\n`); | |
check(ok, 'doc', name, 'missing documentation'); | |
} | |
if (report) { | |
console.log('Report mode'); | |
console.log(results.join('\n')); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment