Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Tools: Initial import of check-examples script
- Loading branch information
Showing
4 changed files
with
153 additions
and
0 deletions.
There are no files selected for viewing
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
module.exports = { | ||
"extends": "google", | ||
"env": { | ||
"browser": true | ||
}, | ||
"parserOptions": { | ||
"ecmaVersion": 2017 | ||
}, | ||
"parser": "babel-eslint", | ||
"rules": { | ||
"require-jsdoc": "off", | ||
"eol-last": "off", | ||
"comma-dangle": "off", | ||
"no-unused-vars": "off", | ||
"quotes": "off", | ||
"max-len": "off", | ||
}, | ||
"plugins": [ | ||
"html" | ||
], | ||
}; |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
# Check Examples | ||
A script that extracts the example code snippets from the specification and | ||
runs a code linter on them. | ||
|
||
## Install and Run | ||
`$ npm install` | ||
`$ node check.js ../webrtc.html` | ||
|
||
## Self Linting | ||
Run the linter on the script itself with the same rules that are used for | ||
specification examples: | ||
`$ npm run linter` |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,101 @@ | ||
const fs = require('fs'); | ||
const {spawn} = require('child_process'); | ||
const htmlparser = require('htmlparser2'); | ||
const Entities = require('html-entities').XmlEntities; | ||
|
||
const entities = new Entities(); | ||
let isExampleText = false; | ||
let exampleCounter = 0; | ||
let nonPassingCounter = 0; | ||
|
||
const parser = new htmlparser.Parser({ | ||
onopentag: (tagName, attributes) => { | ||
if (tagName === 'pre' && 'class' in attributes && attributes.class.includes('example')) { | ||
isExampleText = true; | ||
} | ||
}, | ||
ontext: (text) => { | ||
if (isExampleText) { | ||
checkExample(text); | ||
isExampleText = false; | ||
} | ||
}, | ||
}, {decodeEntities: false}); | ||
|
||
function printWithLineNumbers(str) { | ||
let count = 1; | ||
const out = str.replace(/^|\n/g, () => `\n${String(count++).padStart(3, '0')} `); | ||
console.log(out); | ||
} | ||
|
||
function checkExample(tagText) { | ||
let text = entities.decode(tagText).trim(); | ||
const testName = `Example_${++exampleCounter}`; | ||
const fileExt = text.includes('<script') ? 'html' : 'js'; | ||
|
||
const check = spawn('node_modules/.bin/eslint', [ | ||
'--stdin', | ||
'--stdin-filename', | ||
`${testName}.${fileExt}`, // A filename helps to load plugins | ||
]); | ||
|
||
// If the "bare" code contains await statements it needs to be wrapped in an async function | ||
if (fileExt != 'html' && text.includes('await ')) { | ||
text = `async () => {\n${text}\n};`; | ||
} | ||
|
||
// ESLint doesn't seem to like anonymous objects | ||
if (text.startsWith('{') && text.endsWith('}')) { | ||
text = `temp = ${text};`; | ||
} | ||
|
||
check.stdin.setEncoding('utf-8'); | ||
check.stdin.write(text); | ||
check.stdin.end(); | ||
|
||
function printOutput(data) { | ||
console.log(`=== ${testName} ===`); | ||
printWithLineNumbers(text); | ||
console.log('=== Linter output ==='); | ||
console.log(data.toString()); | ||
} | ||
|
||
check.stdout.on('data', printOutput); | ||
check.stderr.on('data', printOutput); | ||
|
||
check.on('close', (code) => { | ||
if (code == 0) { | ||
console.log(`${testName}: Passed`); | ||
} else { | ||
console.error(`${testName}: Linter process exited with code ${code}\n`); | ||
nonPassingCounter++; | ||
} | ||
parser.resume(); | ||
}); | ||
|
||
parser.pause(); | ||
} | ||
|
||
process.on('exit', () => { | ||
const message = nonPassingCounter == 0 ? 'All examples passed' | ||
: `${nonPassingCounter} of ${exampleCounter} examples did not pass`; | ||
console.log(`\nSummary: ${message}`); | ||
}); | ||
|
||
const filenameIndex = process.argv[0].includes('node') ? 2 : 1; | ||
if (process.argv.length < filenameIndex + 1) { | ||
console.warn('Missing filename'); | ||
process.exit(); | ||
} | ||
|
||
const filename = process.argv[filenameIndex]; | ||
fs.readFile(filename, 'utf8', (err, data) => { | ||
if (err) { | ||
console.error(err.toString()); | ||
return; | ||
} | ||
|
||
console.info(`Checking ${filename}`); | ||
parser.write(data); | ||
parser.end(); | ||
}); |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
{ | ||
"name": "check-examples", | ||
"version": "1.0.0", | ||
"description": "Validate example code snippets in a W3C specification.", | ||
"main": "check.js", | ||
"scripts": { | ||
"test": "echo \"Error: no test specified\" && exit 1", | ||
"linter": "eslint check.js" | ||
}, | ||
"author": "adambe", | ||
"dependencies": { | ||
"babel-eslint": "^8.0.1", | ||
"eslint": "^4.9.0", | ||
"eslint-plugin-html": "^3.2.2", | ||
"html-entities": "^1.2.1", | ||
"htmlparser2": "^3.9.2", | ||
"eslint-config-google": "^0.9.1" | ||
} | ||
} |