diff --git a/.travis.yml b/.travis.yml index fbde39faa..2fa4381b7 100644 --- a/.travis.yml +++ b/.travis.yml @@ -35,21 +35,12 @@ jobs: os: linux addons: firefox: latest-beta - # - stage: test - # before_script: - # # needs an audio output device to run - # - HOMEBREW_NO_AUTO_UPDATE=1 brew install Caskroom/cask/soundflower - # env : BROWSER=safari - # os: osx - # osx_image: xcode9.2 - # - stage: test - # # puppeteer tests - # before_script: npm install puppeteer - # script: - # - npm run build - # - npm run test:html - # - npm run test:node - # env : BROWSER=puppeteer + - stage: test + script: + - npm run build + - npm run docs + - npm run test:examples + env : TEST=jsdoc_examples - stage: deploy os: linux script: npm run build diff --git a/package-lock.json b/package-lock.json index 465896bba..f1f9444a1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -491,6 +491,12 @@ "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==", "dev": true }, + "arg": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.1.tgz", + "integrity": "sha512-SlmP3fEA88MBv0PypnXZ8ZfJhwmDeIE3SP71j37AiXQBXYosPV0x6uISAaHYSlSVhmHOVkomen0tbGk6Anlebw==", + "dev": true + }, "argparse": { "version": "1.0.10", "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", @@ -616,21 +622,10 @@ "dev": true }, "async": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/async/-/async-2.6.2.tgz", - "integrity": "sha512-H1qVYh1MYhEEFLsP97cVKqCGo7KfCyTt6uEWqsTBr9SO84oK9Uwbyd/yCW+6rKJLHksBNUVWZDAjfS+Ccx0Bbg==", - "dev": true, - "requires": { - "lodash": "^4.17.11" - }, - "dependencies": { - "lodash": { - "version": "4.17.14", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.14.tgz", - "integrity": "sha512-mmKYbW3GLuJeX+iGP+Y7Gp1AiGHGbXHCOh/jZmrawMmsE7MS4znI3RL2FsjbqOyMayHInjOeykW7PEajUk1/xw==", - "dev": true - } - } + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/async/-/async-3.1.0.tgz", + "integrity": "sha512-4vx/aaY6j/j3Lw3fbCHNWP0pPaTCew3F6F3hYyl/tHs/ndmV1q7NW9T5yuJ2XAGwdQrP+6Wu20x06U4APo/iQQ==", + "dev": true }, "async-each": { "version": "1.0.1", @@ -3978,14 +3973,22 @@ } }, "fs-extra": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", - "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", + "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", "dev": true, "requires": { - "graceful-fs": "^4.1.2", + "graceful-fs": "^4.2.0", "jsonfile": "^4.0.0", "universalify": "^0.1.0" + }, + "dependencies": { + "graceful-fs": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.2.tgz", + "integrity": "sha512-IItsdsea19BoLC7ELy13q1iJFNmd7ofZH5+X/pJr90/nRoPEX0DJo1dHDbgtYWOhJhcCgMDTOw84RZ72q6lB+Q==", + "dev": true + } } }, "fs-write-stream-atomic": { @@ -6455,6 +6458,12 @@ } } }, + "make-error": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.5.tgz", + "integrity": "sha512-c3sIjNUow0+8swNwVpqoH4YCShKNFkMaw6oH1mNS2haDZQqkeZFlHS3dhoeEbKKmJB4vXpJucU6oH75aDYeE9g==", + "dev": true + }, "mamacro": { "version": "0.0.3", "resolved": "https://registry.npmjs.org/mamacro/-/mamacro-0.0.3.tgz", @@ -8929,6 +8938,15 @@ "lodash": "^4.17.11" }, "dependencies": { + "async": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/async/-/async-2.6.3.tgz", + "integrity": "sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg==", + "dev": true, + "requires": { + "lodash": "^4.17.14" + } + }, "debug": { "version": "3.2.6", "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", @@ -8938,6 +8956,17 @@ "ms": "^2.1.1" } }, + "fs-extra": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", + "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + } + }, "ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", @@ -9245,6 +9274,49 @@ "os-tmpdir": "~1.0.2" } }, + "tmp-promise": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/tmp-promise/-/tmp-promise-2.0.2.tgz", + "integrity": "sha512-zl71nFWjPKW2KXs+73gEk8RmqvtAeXPxhWDkTUoa3MSMkjq3I+9OeknjF178MQoMYsdqL730hfzvNfEkePxq9Q==", + "dev": true, + "requires": { + "tmp": "0.1.0" + }, + "dependencies": { + "glob": { + "version": "7.1.5", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.5.tgz", + "integrity": "sha512-J9dlskqUXK1OeTOYBEn5s8aMukWMwWfs+rPTn/jn50Ux4MNXVhubL1wu/j2t+H4NVI+cXEcCaYellqaPVGXNqQ==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "dev": true, + "requires": { + "glob": "^7.1.3" + } + }, + "tmp": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.1.0.tgz", + "integrity": "sha512-J7Z2K08jbGcdA1kkQpJSqLF6T0tdQqpR2pnSUXsIchbPdTI9v3e85cLW0d6WDhwuAleOV71j2xWs8qMPfK7nKw==", + "dev": true, + "requires": { + "rimraf": "^2.6.3" + } + } + } + }, "to-array": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/to-array/-/to-array-0.1.4.tgz", @@ -9458,6 +9530,27 @@ } } }, + "ts-node": { + "version": "8.4.1", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-8.4.1.tgz", + "integrity": "sha512-5LpRN+mTiCs7lI5EtbXmF/HfMeCjzt7DH9CZwtkr6SywStrNQC723wG+aOWFiLNn7zT3kD/RnFqi3ZUfr4l5Qw==", + "dev": true, + "requires": { + "arg": "^4.1.0", + "diff": "^4.0.1", + "make-error": "^1.1.1", + "source-map-support": "^0.5.6", + "yn": "^3.0.0" + }, + "dependencies": { + "diff": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.1.tgz", + "integrity": "sha512-s2+XdvhPCOF01LRQBC8hf4vhbVmI2CGS5aZnxLJlT5FtdhPCDFq80q++zK2KlrVorVDdL5BOGZ/VfLrVtYNF+Q==", + "dev": true + } + } + }, "tslib": { "version": "1.9.3", "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.9.3.tgz", @@ -10527,6 +10620,12 @@ "resolved": "https://registry.npmjs.org/yeast/-/yeast-0.1.2.tgz", "integrity": "sha1-AI4G2AlDIMNy28L47XagymyKxBk=", "dev": true + }, + "yn": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", + "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", + "dev": true } } } diff --git a/package.json b/package.json index 34558ce80..f92b68b3c 100644 --- a/package.json +++ b/package.json @@ -33,6 +33,7 @@ "test:watch": "npm run collect:tests && npm run karma:watch", "test:browser": "npm run karma:browser", "test:travis": "npm run build && npm run lint && npm run test", + "test:examples": "node scripts/test_examples", "test:html": "mocha ./test/html/testHTML.js --timeout 30000", "test:node": "node ./test/html/node_test.js", "ts:build": "tsc --project ./scripts/tsconfig.build.json", @@ -67,11 +68,13 @@ "@types/ua-parser-js": "^0.7.32", "@typescript-eslint/eslint-plugin": "^1.13.0", "@typescript-eslint/parser": "^1.13.0", + "async": "^3.1.0", "chai": "^1.10.0", "codecov": "^3.1.0", "cross-var": "^1.1.0", "eslint": "^6.4.0", "eslint-plugin-jsdoc": "^15.12.0", + "fs-extra": "^8.1.0", "glob": "^7.1.2", "html-webpack-plugin": "^3.2.0", "http-server": "^0.11.1", @@ -88,7 +91,9 @@ "mocha": "^5.1.1", "semver": "^5.5.0", "teoria": "^2.5.0", + "tmp-promise": "^2.0.2", "ts-loader": "^6.0.4", + "ts-node": "^8.4.1", "typedoc": "^0.15.0", "typescript": "^3.5.3", "ua-parser-js": "^0.7.20", diff --git a/scripts/test_examples.js b/scripts/test_examples.js new file mode 100644 index 000000000..765990c96 --- /dev/null +++ b/scripts/test_examples.js @@ -0,0 +1,79 @@ +/* eslint-disable @typescript-eslint/no-var-requires */ +const { resolve } = require("path"); +const { exec } = require("child_process"); +const { file } = require("tmp-promise"); +const { writeFile } = require("fs-extra"); +const toneJson = require("../docs/tone.json"); +const eachLimit = require("async/eachLimit"); + +/** + * Get all of the examples + */ +function findExamples(obj) { + let examples = []; + for (let prop in obj) { + if (Array.isArray(obj[prop])) { + obj[prop].forEach(child => { + examples = [...examples, ...findExamples(child)]; + }); + } else if (prop === "comment" && obj[prop].tags) { + examples = [ + ...examples, + ...obj[prop].tags.filter(tag => tag.tag === "example").map(tag => tag.text) + ]; + } else if (typeof obj[prop] === "object") { + examples = [...examples, ...findExamples(obj[prop])]; + } else { + // console.log(prop); + } + } + // filter any repeats + return [...new Set(examples)]; +} + +/** + * A promise version of exec + */ +function execPromise(cmd) { + return new Promise((done, error) => { + exec(cmd, (e, output) => { + if (e) { + error(output); + } else { + done(); + } + }); + }); +} + +/** + * Run the string through the typescript compiler + */ +async function testExampleString(str) { + str = str.replace("from \"tone\"", `from "${resolve(__dirname, "../")}"`); + const { path, cleanup } = await file({ postfix: ".ts" }); + // work with file here in fd + await writeFile(path, str); + try { + await execPromise(`tsc ${path}`); + } finally { + cleanup(); + } +} + +const examples = findExamples(toneJson); + +async function main() { + let passed = 0; + await eachLimit(examples, 4, async example => { + try { + await testExampleString(example); + passed++; + } catch (e) { + console.log(example + "\n" + e); + } + }); + console.log(`valid examples ${passed}/${examples.length}`); +} +main(); +