diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 4efdeb9db..7466f8475 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1,20 +1,14 @@ -# derived from -# https://github.com/actions/starter-workflows/blob/main/ci/node.js.yml -# This workflow will do a clean install of node dependencies, build the source code and run tests across different versions of node -# For more information see: https://help.github.com/actions/language-and-framework-guides/using-nodejs-with-github-actions +# this workflow will run nodejs coverages and tests and +# upload build-artifacts to branch-gh-pages name: CI on: push: branches: - - alpha - - beta - - master - - sandbox - # - none - # - pull_request: - # branches: - # - alpha - # - beta + - alpha + - beta + - master + - sandbox +# shCiBase - start jobs: build: runs-on: ${{ matrix.os }} @@ -43,9 +37,13 @@ jobs: architecture: ${{ matrix.architecture }} # fetch ci.sh from trusted source - run: git fetch origin alpha && git checkout origin/alpha ci.sh - - run: sh ci.sh shGithubCi + # run nodejs coverages and tests + - run: sh ci.sh shCiBase +# shCiBase - end + # fetch ci.sh from trusted source - run: git fetch origin alpha && git checkout origin/alpha ci.sh - - run: sh ci.sh shGithubArtifactUpload + # upload build-artifacts to branch-gh-pages + - run: sh ci.sh shCiArtifactUpload env: CI_NODE_VERSION_ARCH_PLATFORM: v14.x64.linux GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/on_pull_request.yml b/.github/workflows/on_pull_request.yml new file mode 100644 index 000000000..9274873fc --- /dev/null +++ b/.github/workflows/on_pull_request.yml @@ -0,0 +1,36 @@ +# this workflow will run nodejs coverages and tests +name: on_pull_request +on: + - pull_request +# shCiBase - start +jobs: + build: + runs-on: ${{ matrix.os }} + strategy: + matrix: + architecture: + # - arm64 + - x64 + # - x86 + node_version: + - 12 + - 14 + - 16 + os: + - macos-latest + - ubuntu-latest + - windows-latest + name: node . v${{ matrix.node_version }} . ${{ matrix.architecture }} . ${{ matrix.os }} + steps: + # https://github.com/actions/checkout + - uses: actions/checkout@v2 + # https://github.com/actions/setup-node + - uses: actions/setup-node@v2 + with: + node-version: ${{ matrix.node_version }} + architecture: ${{ matrix.architecture }} + # fetch ci.sh from trusted source + - run: git fetch origin alpha && git checkout origin/alpha ci.sh + # run nodejs coverages and tests + - run: sh ci.sh shCiBase +# shCiBase - end diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 000000000..3eee5b2f6 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,29 @@ +# Changelog + +## Todo +- doc - add svg package-listing. +- ci - continue addng regression tests and improve code-coverage. +- none + +## v9999.99.99 +- none + +## v2021.5.21 +- this ci-release does not change any core-functionality of file jslint.js +- doc - add file CHANGELOG.md +- ci - begin addng regression tests and improve code-coverage. +- ci - allow pull-requests to run restricted-ci (cannot upload artifacts). +- gh-pages - fix missing assets and insecure http-links. +- gh-pages - merge file jslint.css into index.html. +- gh-pages - add files image-jslint-xxx.png. +- gh-pages - cleanup asset naming-convention. +- fix missing fonts in function.html and help.html. +- add files .gitconfig, Daley-Bold.woff2, Programma-Bold.woff2, icon-folder-open-solid.svg, icon-window-maximize-regular.svg. +- ci - fix http-links after moving to jslint-org. +- doc - migrate file README to README.md with embedded ci links and screenshots. +- ci - add macos and windows to ci-matrix. +- ci - ci now fails if jslint-check fails for any of the files in branches. +- ci - add github-workflows to generate code-coverage for jslint.js. + +## v2020.11.6 +- vestigial diff --git a/README.md b/README.md index fe68c7169..31ba717c7 100644 --- a/README.md +++ b/README.md @@ -3,20 +3,20 @@ Douglas Crockford douglas@crockford.com -2020-11-06 +## v2021.5.21 ## Status | Branch | [master](https://github.com/jslint-org/jslint/tree/master) | [beta](https://github.com/jslint-org/jslint/tree/beta) | [alpha](https://github.com/jslint-org/jslint/tree/alpha)| |--:|:--:|:--:|:--:| | CI | [![ci](https://github.com/jslint-org/jslint/actions/workflows/ci.yml/badge.svg?branch=master)](https://github.com/jslint-org/jslint/actions?query=branch%3Amaster) | [![ci](https://github.com/jslint-org/jslint/actions/workflows/ci.yml/badge.svg?branch=beta)](https://github.com/jslint-org/jslint/actions?query=branch%3Abeta) | [![ci](https://github.com/jslint-org/jslint/actions/workflows/ci.yml/badge.svg?branch=alpha)](https://github.com/jslint-org/jslint/actions?query=branch%3Aalpha)| | Coverage | [![coverage](https://jslint-org.github.io/jslint/branch.master/.build/coverage/coverage-badge.svg)](https://jslint-org.github.io/jslint/branch.master/.build/coverage/index.html) | [![coverage](https://jslint-org.github.io/jslint/branch.beta/.build/coverage/coverage-badge.svg)](https://jslint-org.github.io/jslint/branch.beta/.build/coverage/index.html) | [![coverage](https://jslint-org.github.io/jslint/branch.alpha/.build/coverage/coverage-badge.svg)](https://jslint-org.github.io/jslint/branch.alpha/.build/coverage/index.html)| -| Demo | [](https://jslint-org.github.io/jslint/branch.master/index.html) | [](https://jslint-org.github.io/jslint/branch.beta/index.html) | [](https://jslint-org.github.io/jslint/branch.alpha/index.html)| -| Artifacts | [](https://github.com/jslint-org/jslint/tree/gh-pages/branch.master/.build) | [](https://github.com/jslint-org/jslint/tree/gh-pages/branch.beta/.build) | [](https://github.com/jslint-org/jslint/tree/gh-pages/branch.alpha/.build)| +| Demo | [](https://jslint-org.github.io/jslint/branch.master/index.html) | [](https://jslint-org.github.io/jslint/branch.beta/index.html) | [](https://jslint-org.github.io/jslint/branch.alpha/index.html)| +| Artifacts | [](https://github.com/jslint-org/jslint/tree/gh-pages/branch.master/.build) | [](https://github.com/jslint-org/jslint/tree/gh-pages/branch.beta/.build) | [](https://github.com/jslint-org/jslint/tree/gh-pages/branch.alpha/.build)| ## Live Web Demo - [https://jslint-org.github.io/jslint/index.html](https://jslint-org.github.io/jslint/index.html) -[![screenshot](https://jslint-org.github.io/jslint/branch.master/.build/screenshot.browser.%252Findex.html.png)](https://jslint-org.github.io/jslint/index.html) +[![screenshot](https://jslint-org.github.io/jslint/branch.master/.build/screenshot.browser._2findex.html.png)](https://jslint-org.github.io/jslint/index.html) ## Description `jslint.js` contains the jslint function. It parses and analyzes a source file, @@ -51,18 +51,3 @@ This applies to programming as well. Conforming to a consistent style improves readability, and frees you to express yourself in ways that matter. JSLint here plays the part of a stern but benevolent editor, helping you to get the style right so that you can focus your creative energy where it is most needed. - -## Changelog Since v2020.11.6 -- add files .gitconfig, Daley-Bold.woff2, Programma-Bold.woff2, icon-folder-open-solid.svg, icon-window-maximize-regular.svg -- ci - fix http-links after moving to jslint-org -- doc - migrate file README to README.md with embedded ci links and screenshots. -- ci - add macos and windows to ci-matrix. -- ci - ci now fails if jslint-check fails for any of the files in branches. -- ci - add github-workflows to generate code-coverage for jslint.js. -- none - -## Todo -- ci - allow pr to run ci -- doc - add svg package-listing. -- ci - add regression tests and improve code-coverage. -- none diff --git a/ci.sh b/ci.sh index b9eec48ea..25a56e3d1 100755 --- a/ci.sh +++ b/ci.sh @@ -4,7 +4,8 @@ ' shBrowserScreenshot() {(set -e -# this function will screenshot url "$1" with headless-chrome +# this function will run headless-chrome to screenshot url $1 with +# window-size $2 node -e ' // init debugInline if (!globalThis.debugInline) { @@ -41,7 +42,9 @@ if (!globalThis.debugInline) { if (String(file + "/").indexOf(process.cwd() + "/") === 0) { file = file.replace(process.cwd(), ""); } - file = ".build/screenshot.browser." + encodeURIComponent(file); + file = ".build/screenshot.browser." + encodeURIComponent(file).replace(( + /%/g + ), "_").toLowerCase(); process.on("exit", function (exitCode) { if (typeof exitCode === "object" && exitCode) { console.error(exitCode); @@ -67,7 +70,7 @@ if (!globalThis.debugInline) { "--incognito", "--timeout=30000", "--user-data-dir=/dev/null", - "--window-size=800x600", + "--window-size=" + (process.argv[2] || "800x600"), ( extname === ".html" ? "--dump-dom" @@ -112,7 +115,172 @@ if (!globalThis.debugInline) { ); }); }()); -' "$1" # ' +' "$@" # "' +)} + +shCiArtifactUpload() {(set -e +# this function will upload build-artifacts to branch-gh-pages + node -e ' +process.exit( + `${process.version.split(".")[0]}.${process.arch}.${process.platform}` !== + process.env.CI_NODE_VERSION_ARCH_PLATFORM +); +' || return 0 + local BRANCH + # init $BRANCH + BRANCH="$(git rev-parse --abbrev-ref HEAD)" + # init .git/config + git config --local user.email "github-actions@users.noreply.github.com" + git config --local user.name "github-actions" + # update README.md with $GITHUB_REPOSITORY + sed -i \ + -e "s|\bjslint-org/jslint\b|$GITHUB_REPOSITORY|g" \ + -e "s|\bjslint-org\.github\.io/jslint\b|$( + printf "$GITHUB_REPOSITORY" | sed -e "s|/|.github.io/|" + )|g" \ + README.md + # add dir .build + git add -f .build + git commit -am "add dir .build" + # checkout branch-gh-pages + git checkout -b gh-pages + git fetch origin gh-pages + git reset --hard origin/gh-pages + # update dir branch.$BRANCH + rm -rf "branch.$BRANCH" + mkdir "branch.$BRANCH" + (set -e + cd "branch.$BRANCH" + git init -b branch1 + git pull --depth=1 .. "$BRANCH" + rm -rf .git + git add -f . + ) + # update root-dir with branch-master + if [ "$BRANCH" = master ] + then + git rm -rf .build + git checkout master . + fi + git status + git commit -am "update dir branch.$BRANCH" || true + # if branch-gh-pages has more than 100 commits, + # then backup and squash commits + if [ "$(git rev-list --count gh-pages)" -gt 100 ] + then + # backup + shGitCmdWithGithubToken push origin -f gh-pages:gh-pages.backup + # squash commits + git checkout --orphan squash1 + git commit --quiet -am squash || true + # reset branch-gh-pages to squashed-commit + git push . -f squash1:gh-pages + git checkout gh-pages + # force-push squashed-commit + shGitCmdWithGithubToken push origin -f gh-pages + fi + # list files + shGitLsTree + # push branch-gh-pages + shGitCmdWithGithubToken push origin gh-pages + # validate http-links + (set -e + cd "branch.$BRANCH" + sleep 15 + shDirHttplinkValidate + ) +)} + +shCiBase() {(set -e +# this function will run github-ci + # jslint all files + shJslintCli . + # run test with coverage-report + shRunWithCoverage node test.js + # screenshot live-web-demo + shBrowserScreenshot index.html +)} + +shDirHttplinkValidate() {(set -e +# this function will validate http-links embedded in .html and .md files + node -e ' +(function () { + "use strict"; + let dict = {}; + require("fs").readdirSync(".").forEach(async function (file) { + if (!( + /.\.html$|.\.md$/m + ).test(file)) { + return; + } + let data = await require("fs").promises.readFile(file, "utf8"); + data.replace(( + /\bhttps?:\/\/.*?(?:[")\]]|$)/gm + ), function (match0) { + match0 = match0.slice(0, -1).replace(( + /[\u0022\u0027]/g + ), "").replace(( + /\/branch\.\w+?\//g + ), "/branch.alpha/").replace(( + /\bjslint-org\/jslint\b/g + ), process.env.GITHUB_REPOSITORY || "jslint-org/jslint").replace(( + /\bjslint-org\.github\.io\/jslint\b/g + ), String( + process.env.GITHUB_REPOSITORY || "jslint-org/jslint" + ).replace("/", ".github.io/")); + if (match0.indexOf("http://") === 0) { + throw new Error( + "shDirHttplinkValidate - insecure link " + match0 + ); + } + // ignore duplicate-link + if (dict.hasOwnProperty(match0)) { + return ""; + } + dict[match0] = true; + let req = require("https").request(require("url").parse( + match0 + ), function (res) { + console.error( + "shDirHttplinkValidate " + res.statusCode + " " + match0 + ); + if (!(res.statusCode < 400)) { + throw new Error( + "shDirHttplinkValidate - " + file + + " - unreachable link " + match0 + ); + } + req.abort(); + res.destroy(); + }); + req.setTimeout(30000); + req.end(); + return ""; + }); + data.replace(( + /(?:\bhref=|\bsrc=|\burl\().(.*?)(?:[")\]]|$)/gm + ), function (ignore, match1) { + if (!( + /^https?|^mailto:|^[#\/]/m + ).test(match1)) { + require("fs").stat(match1, function (ignore, exists) { + console.error( + "shDirHttplinkValidate " + Boolean(exists) + " " + + match1 + ); + if (!exists) { + throw new Error( + "shDirHttplinkValidate - " + file + + " - unreachable link " + match1 + ); + } + }); + } + return ""; + }); + }); +}()); +' # "' )} shGitCmdWithGithubToken() {(set -e @@ -209,82 +377,7 @@ shGitLsTree() {(set -e }).join("")); }); }()); -' # ' -)} - -shGithubCi() {(set -e -# this function will run github-ci - # jslint all files - shJslintCli . - # create coverage-report - shRunWithCoverage shJslintCli jslint.js - # screenshot live-web-demo - shBrowserScreenshot https://jslint.com/index.html -)} - -shGithubArtifactUpload() {(set -e -# this function will upload build-artifacts to branch-gh-pages - node -e ' -process.exit( - `${process.version.split(".")[0]}.${process.arch}.${process.platform}` !== - process.env.CI_NODE_VERSION_ARCH_PLATFORM -); -' || return 0 - local BRANCH - # init $BRANCH - BRANCH="$(git rev-parse --abbrev-ref HEAD)" - # init .git/config - git config --local user.email "github-actions@users.noreply.github.com" - git config --local user.name "github-actions" - # add dir .build - git add -f .build/ - git commit -am "add dir .build" - # checkout branch-gh-pages - git checkout -b gh-pages - git fetch origin gh-pages - git reset --hard origin/gh-pages - # update dir branch.$BRANCH - rm -rf "branch.$BRANCH" - mkdir "branch.$BRANCH" - (set -e - cd "branch.$BRANCH" - git init -b branch1 - git pull --depth=1 .. "$BRANCH" - rm -rf .git - git add -f . - ) - # update root-dir with branch-master - if [ "$BRANCH" = master ] - then - git checkout master . - fi - git status - git commit -am "update dir branch.$BRANCH" || true - # if branch-gh-pages has more than 100 commits, - # then backup and squash commits - if [ "$(git rev-list --count gh-pages)" -gt 100 ] - then - # backup - shGitCmdWithGithubToken push origin -f gh-pages:gh-pages.backup - # squash commits - git checkout --orphan squash1 - git commit --quiet -am squash || true - # reset branch-gh-pages to squashed-commit - git push . -f squash1:gh-pages - git checkout gh-pages - # force-push squashed-commit - shGitCmdWithGithubToken push origin -f gh-pages - fi - # list files - shGitLsTree - # push branch-gh-pages - shGitCmdWithGithubToken push origin gh-pages - # validate http-links in README.md - (set -e - cd "branch.$BRANCH" - sleep 15 - shReadmeLinkValidate - ) +' # "' )} shJslintCli() {(set -e @@ -607,63 +700,11 @@ async function jslint2({ } process.exit(exitCode); }()); -' --input-type=module "$@" # ' -)} - -shReadmeLinkValidate() {(set -e -# this function will validate http-links embedded in README.md - node -e ' -(function () { - "use strict"; - let dict = {}; - require("fs").readFileSync("README.md", "utf8").replace(( - /[(\[]https?:\/\/.*?[)\]]/g - ), function (match0) { - if (match0.indexOf("http://") === 0) { - throw new Error("shReadmeLinkValidate - insecure link " + match0); - } - match0 = match0.slice(1, -1).replace(( - /[\u0022\u0027]/g - ), "").replace(( - /\/branch\.\w+?\//g - ), "/branch.alpha/").replace(( - /\bjslint-org\/jslint\b/g - ), process.env.GITHUB_REPOSITORY); - // ignore private-link - if ( - process.env.npm_package_private && - match0.indexOf("https://github.com/") === 0 - ) { - return; - } - // ignore duplicate-link - if (dict.hasOwnProperty(match0)) { - return; - } - dict[match0] = true; - let req = require("https").request(require("url").parse( - match0 - ), function (res) { - console.log( - "shReadmeLinkValidate " + res.statusCode + " " + match0 - ); - if (!(res.statusCode < 400)) { - throw new Error( - "shReadmeLinkValidate - unreachable link " + match0 - ); - } - req.abort(); - res.destroy(); - }); - req.setTimeout(30000); - req.end(); - }); -}()); -' # ' +' --input-type=module "$@" # "' )} shRunWithCoverage() {(set -e -# this function will run nodejs command "$@" with v8-coverage and +# this function will run nodejs command $@ with v8-coverage and # create coverage-report .build/coverage/index.html export DIR_COVERAGE=.build/coverage/ rm -rf "$DIR_COVERAGE" @@ -720,7 +761,7 @@ if (!globalThis.debugInline) { ), "&$1"); } html = ""; - html += ` + html += ` coverage-report @@ -1212,11 +1253,11 @@ ${String(count).padStart(7, " ")} pathname: DIR_COVERAGE + "index" }); }()); -' # ' +' # "' )} shRunWithScreenshotTxt() {(set -e -# this function will run cmd "$@" and screenshot text-output +# this function will run cmd $@ and screenshot text-output # https://www.cnx-software.com/2011/09/22/how-to-convert-a-command-line-result-into-an-image-in-linux/ local EXIT_CODE EXIT_CODE=0 @@ -1294,10 +1335,10 @@ shRunWithScreenshotTxt() {(set -e } catch (ignore) {} require("fs").writeFileSync(process.argv[1], result); }()); -' "$SCREENSHOT_SVG" # ' +' "$SCREENSHOT_SVG" # "' shCiPrint "shRunWithScreenshotTxt - wrote - $SCREENSHOT_SVG" return "$EXIT_CODE" )} -# run "$@" +# run $@ "$@" diff --git a/Daley-Bold.woff2 b/font-daley-bold.woff2 similarity index 100% rename from Daley-Bold.woff2 rename to font-daley-bold.woff2 diff --git a/Programma-Bold.woff2 b/font-programma-bold.woff2 similarity index 100% rename from Programma-Bold.woff2 rename to font-programma-bold.woff2 diff --git a/function.html b/function.html index 6191b6ba4..05c02480e 100644 --- a/function.html +++ b/function.html @@ -17,19 +17,20 @@ /> JSLint: jslint function + + +
+
JS
+
Lint
+
+ + diff --git a/image-json160.gif b/image-json160.gif new file mode 100644 index 000000000..3bb55c8dd Binary files /dev/null and b/image-json160.gif differ diff --git a/icon-window-maximize-regular.svg b/image-window-maximize-regular.svg similarity index 100% rename from icon-window-maximize-regular.svg rename to image-window-maximize-regular.svg diff --git a/index.html b/index.html index 822acaad6..46745096e 100644 --- a/index.html +++ b/index.html @@ -1,5 +1,5 @@ - + - JSLint: The JavaScript Code Quality Tool +
JSLint
@@ -41,7 +379,7 @@
Source +
diff --git a/jslint.css b/jslint.css deleted file mode 100644 index cc3bf1696..000000000 --- a/jslint.css +++ /dev/null @@ -1,341 +0,0 @@ -@font-face { - font-family: 'Programma'; - font-weight: bold; - src: url('Programma-Bold.woff2') format('woff2'); -} -@font-face { - font-family: 'Daley'; - font-weight: bold; - src: url('Daley-Bold.woff2') format('woff2'); -} - -body { - background-color: antiquewhite; - color: black; - font-family: 'Daley', sans-serif; - margin: 0; - padding: 0; -} - -#JSLINT_TITLEBOX { - font-family: 'Daley', sans-serif; - margin: 0; - margin-left: 3%; - margin-right: 3%; - padding: 0; -} - -#JSLINT_TITLEBOX ul { - float: right; - font-size: 12pt; -} - -#JSLINT_TITLEBOX div { - color: darkslategray; - float: left; - font-size: 48pt; -} - -#JSLINT_ fieldset { - background-color: gainsboro; - border: 0; - clear: both; - margin-bottom: 1em; - margin-left: 3%; - margin-right: 3%; - margin-top: 1em; - padding: 0; - width: auto; -} -#JSLINT_ legend { - background-color: darkslategray; - border: 0; - color: white; - font-size: 100%; - font-style: normal; - font-weight: normal; - margin: 0; - padding-bottom: 0.25em; - padding-left: 0; - padding-right: 0; - padding-top: 0.25em; - text-align: center; - width: 100%; -} -#JSLINT_ button { - background-color: darkslategray; - border: 0; - color: white; - cursor: pointer; - font-family: 'Daley', sans-serif; - font-size: 100%; - font-style: normal; - margin-left: 1em; - margin-right: 1em; - padding-left: 1em; - padding-right: 1em; - padding-bottom: 0.25em; - padding-top: 0.25em; - text-align: center; -} -#JSLINT_ button:hover { - background-color: slategray; - color: white; - border: 0; -} - -#JSLINT_ button:active { - border: 0; - color: black; -} - -#JSLINT_ button:disabled { - background-color: gray; - border: 0; - color: gainsboro; -} - -a:visited { - color: #69565c; -} - -a:link { - color: black; -} - -#JSLINT_ input[type="text"] { - background-color: white; - border: 0; - color: black; - margin-bottom: 0.2em; - margin-right: 0.5em; - padding-left: 0.5em; - padding-right: 0.5em; - text-align: right; - width: 3em; -} - -#JSLINT_ textarea { - border: 0; - background-color: white; - border: 0; - font-family: Programma, monospace; - font-size: 100%; - font-weight: bold; - resize: none; -} - -#JSLINT_ textarea::selection { - background-color: yellow; - color: black; -} - -#JSLINT_NUMBER { - color: darkgray; - display: inline-block; - height: 4in; - margin: 2%; - margin-right: 0; - overflow: hidden; - padding-right: 0.5%; - text-align: right; - white-space: pre; - width: 4%; -} - -#JSLINT_SOURCE { - color: black; - display: inline-block; - font-size: 100%; - height: 4in; - margin: 2%; - margin-left: 0; - margin-right: 0; - overflow: auto; - padding-left: 0.5%; - white-space: pre; - width: 91%; -} - -#JSLINT_PROPERTY { - background-color: honeydew; - border: 0; - margin: 2%; - padding: 0.5%; - white-space: pre; - width: 95%; -} - -#JSLINT_GLOBAL { - white-space: normal; - width: 95%; -} -#JSLINT_ label { - font-family: sans-serif; - font-size: 90%; - padding-left: 0.25em; -} -#JSLINT_OPTIONS>div { - float: left; - margin: 0.5em; -} - -#JSLINT_ address { - color: black; - display: block; - float: right; - font-family: serif; - font-size: 90%; - margin-left: 1em; -} -#JSLINT_ dl { - background-color: cornsilk; - color: white; - margin: 0; - padding-bottom: 2pt; - padding-left: 1em; - padding-right: 1em; - padding-top: 2pt; -} -#JSLINT_ dfn { - color: black; - display: block; - font-family: Programma, monospace; - font-size: 100%; - font-style: normal; - font-weight: bold; - margin-bottom: 2pt; -} -#JSLINT_ dt { - color: black; - display: block; - float: left; - font-family: serif; - font-size: 75%; - font-style: italic; - margin: 0; - width: 8em; - text-align: right; -} -#JSLINT_ dd { - color: black; - display: block; - font-family: Programma, monospace; - font-weight: bold; - margin-left: 8em; - padding-bottom: 2pt; -} -#JSLINT_WARNINGS>legend { - background-color: indianred; -} -#JSLINT_WARNINGS>div { - background-color: pink; - padding: 1em; -} -#JSLINT_WARNINGS cite { - color: black; - display: block; - font-family: serif; - font-size: 100%; - font-style: normal; - margin-bottom: 4pt; - margin-left: 20pt; - margin-right: 20pt; - margin-top: 4pt; - overflow-x: hidden; -} -#JSLINT_WARNINGS samp { - background-color: lavenderblush; - color: black; - display: block; - font-family: Programma, monospace; - font-size: 100%; - font-style: normal; - font-weight: bold; - padding: 4pt; - margin-bottom: 0; - margin-left: 16pt; - margin-right: 16pt; - margin-top: 0; - white-space: pre-wrap; -} - -#JSLINT_REPORT center { - margin-top: 1em; -} - -#JSLINT_WARNINGS dl address { - color: black; - display: inline; - float: none; - font-size: 80%; - margin: 0; -} - -#JSLINT_REPORT>div { - padding: 1em; -} - -#JSLINT_ dl.level0 { - color: black; - background-color: white; -} - -#JSLINT_ dl.level1 { - color: black; - background-color: #ffffe0; /* yellow */ - margin-left: 1em; -} - -#JSLINT_ dl.level2 { - color: black; - background-color: #e0ffe0; /* green */ - margin-left: 2em; -} - -#JSLINT_ dl.level3 { - color: black; - background-color: #D0D0ff; /* blue */ - margin-left: 3em; -} - -#JSLINT_ dl.level4 { - background-color: #ffe0ff; /* purple */ - color: black; - margin-left: 4em; -} - -#JSLINT_ dl.level5 { - background-color: #ffe0e0; /* red */ - color: black; - margin-left: 5em; -} - -#JSLINT_ dl.level6 { - background-color: #ffe390; /* orange */ - color: black; - margin-left: 6em; -} - -#JSLINT_ dl.level7 { - background-color: #e0e0e0; /* gray */ - color: black; - margin-left: 7em; -} - -#JSLINT_ dl.level8 { - color: black; - margin-left: 8em; -} - -#JSLINT_ dl.level9 { - color: black; - margin-left: 9em; -} - -.none { - display: none; -} -.center { - text-align: center; -} diff --git a/test.js b/test.js new file mode 100644 index 000000000..213133bc2 --- /dev/null +++ b/test.js @@ -0,0 +1,377 @@ +import jslint from "./jslint.js"; + +(function testCaseJslintWarningsValidate() { +/* + * this function will validate each jslint is raised with given + * malformed + */ + Object.entries({ + "and": [ + "aa && aa || aa" + ], + "bad_assignment_a": [ + "/*jslint for*/\nfunction aa(){for (0 in aa){}}", + "0=0", + "const aa=0;for(aa in aa){}" + ], + "bad_directive_a": [ + "/*jslint !*/" + ], + "bad_get": [ + "/*jslint getset*/\naa={get aa(aa){}}" + ], + "bad_module_name_a": [ + "import aa from \"!aa\"" + ], + "bad_option_a": [ + "/*global aa:true*/", + "/*jslint undefined*/" + ], + "bad_property_a": [ + "aa._" + ], + "bad_set": [ + "/*jslint getset*/\naa={set aa(){}}" + ], + "duplicate_a": [ + "aa={\"aa\":0,\"aa\":0}", + "let aa;export {aa,aa}", + "{\"aa\":0,\"aa\":0}" + ], + "empty_block": [ + "function aa(){}" + ], + "escape_mega": [], + "expected_a": [], + "expected_a_at_b_c": [ + "let aa={\n aa:\n0\n};" + ], + "expected_a_b": [ + "!!aa", + "([])=>0", + "(aa)=>{}", + "(aa?0:aa)", + "(aa?aa:0)", + "(aa?false:true)", + "(aa?true:false)", + "/=0", + "0!=0", + "0==0", + ";{", + "`${/ /}`", + "`${`", + "`${{`", + "aa.aa=undefined", + "aa=\"\"+\"\"", + "aa=+aa", + "aa=/[ ]/", + "aa=/aa{/", + "aa=0+\"\"", + "delete [0]", + "for(;;){}", + "isFinite(0)", + "let aa;var aa;", + "new Array(\"\")", + "new Date().getTime()", + "new Object()" + ], + "expected_a_b_from_c_d": [ + "{\"aa\":0" + ], + "expected_a_before_b": [ + ".0", + "/*jslint eval*/\nFunction;eval", + "=>0", + "aa=/(:)/", + "aa=/=/", + "aa=/?/", + "aa=/[/", + "let Aa=Aa()", + "let Aa=Aa.Aa()", + "new Aa" + ], + "expected_a_next_at_b": [], + "expected_digits_after_a": [ + "0x" + ], + "expected_four_digits": [ + "\"\\u0\"" + ], + "expected_identifier_a": [ + "(0)=>0", + "aa.0", + "aa?.0", + "function aa(0){}", + "function aa([aa]){}\nfunction aa([aa],[aa,aa=aa],[0]){}", + "function aa({aa}){}\nfunction aa({aa},{aa:aa,aa=aa},{aa:0}){}", + "function(){}", + "import {", + "let [aa,0]=[]" + ], + "expected_line_break_a_b": [], + "expected_regexp_factor_a": [ + "/ /" + ], + "expected_space_a_b": [ + "/**//**/", + "let aa=0;" + ], + "expected_statements_a": [], + "expected_string_a": [ + "import(aa).then(aa)", + "typeof 0===0" + ], + "expected_type_string_a": [ + "typeof 0===\"aa\"" + ], + "freeze_exports": [ + "export default Object.aa()", + "export function aa(){}" + ], + "function_in_loop": [ + "function aa(){while(0){aa.map(()=>0);}}", + "function aa(){while(0){aa.map(function(){});}}" + ], + "infix_in": [ + "aa in aa" + ], + "label_a": [ + "aa:while(0){aa;}" + ], + "misplaced_a": [ + "if(0){import aa from \"aa\";}" + ], + "misplaced_directive_a": [ + "let aa;\n/*global aa*/" + ], + "missing_browser": [ + "/*global aa*/" + ], + "missing_m": [ + "aa=/$^/" + ], + "naked_block": [], + "nested_comment": [ + "/*/*", + "/*/**/" + ], + "not_label_a": [ + "aa:{break aa;}" + ], + "number_isNaN": [ + "NaN===NaN", + "isNaN(0)" + ], + "out_of_scope_a": [ + "aa:{function aa(aa){break aa;}}", + "function aa(){bb();}\nfunction bb(){}" + ], + "redefinition_a_b": [ + "let aa;let aa" + ], + "required_a_optional_b": [ + "function aa(aa=0,...){}", + "function aa(aa=0,[]){}", + "function aa(aa=0,{}){}" + ], + "reserved_a": [ + "let undefined" + ], + "subscript_a": [ + "aa[`aa`]" + ], + "todo_comment": [ + "// todo" + ], + "too_long": [ + "//".repeat(100) + ], + "too_many_digits": [ + "\"\\u{123456}\"" + ], + "unclosed_comment": [ + "/*" + ], + "unclosed_mega": [ + "`aa" + ], + "unclosed_string": [ + "\"\\", + "\"aa" + ], + "undeclared_a": [ + "aa" + ], + "unexpected_a": [ + "((0))", + "(+0?+0:+0)()", + "/*/", + "/_/", + "0 instanceof 0", + "0===(0==0)", + "0[0][0]", + "0|0", + ";", + "Function", + "[-0x0]", + "[0x0]", + "`${\"`\"}`", + "`${/[`]/}`", + "`${/`/}`", + "aa((0))", + "aa+=NaN", + "aa/=0", + "aa=/[0-]/", + "aa=/_//", + "aa=/_/z", + "aa=aa++", + "aa={aa:aa}", + "aa={set aa(){}}", + "arguments", + "debugger", + "eval", + "export aa", + "export const aa=0", + "for(aa in aa){}", + "for(const ii=0;;){}", + "for(ii=0;ii<0;ii++){}", + "for(ii=0;ii<0;ii+=0){}", + "function aa(){try{return;}catch(ignore){}finally{return;}}", + "function aa(){try{}catch(ignore){}finally{switch(0){case 0:}}}", + "function aa(){while(0){continue;}}", + "function aa(){while(0){try{0;}catch(ignore){}finally{continue;}}}", + "function aa(){}\n[]", + "function aa(){}0", + "function ignore(){let ignore;}", + "ignore", + "ignore:", + "import ignore from \"aa\"", + "import {ignore} from \"aa\"", + "new Date.UTC()", + "new Function()", + "new Symbol()", + "this", + "try{}finally{break;}", + "void 0", + "while((0)){}", + "while(0){}", + "yield /_/", + "{\"\\u{1234}\":0}", + "{\"aa\":", + "{\"aa\":'aa'}", + "{//\n}", + "{0:0}" + ], + "unexpected_a_after_b": [ + "0a" + ], + "unexpected_a_before_b": [ + "aa=\"\\a\"" + ], + "unexpected_at_top_level_a": [], + "unexpected_char_a": [ + "#" + ], + "unexpected_comment": [ + "`${//}`" + ], + "unexpected_directive_a": [ + "/*global aa*/\nimport aa from \"aa\"" + ], + "unexpected_expression_a": [ + "aa++", + "typeof 0===typeof 0" + ], + "unexpected_label_a": [ + "aa:aa" + ], + "unexpected_parens": [ + "aa=(function(){})" + ], + "unexpected_space_a_b": [ + "let aa=( 0 );" + ], + "unexpected_statement_a": [], + "unexpected_trailing_space": [], + "unexpected_typeof_a": [ + "typeof aa===\"undefined\"" + ], + "uninitialized_a": [ + "/*jslint node*/\nlet aa;aa();" + ], + "unreachable_a": [ + "function aa(){while(0){break;0;}}" + ], + "unregistered_property_a": [ + "/*property aa*/\naa.bb" + ], + "unsafe": [], + "unused_a": [ + "/*jslint node*/\nlet aa;" + ], + "use_double": [ + "''" + ], + "use_open": [ + "0?0:0", + "aa=0?0:0" + ], + "use_spaces": [ + "\t" + ], + "var_loop": [ + "function aa(){while(0){var aa;}}" + ], + "var_switch": [ + "function aa(){switch(0){case 0:var aa;}}" + ], + "weird_condition_a": [ + "if(0&&0){0;}", + "if(0||0){0;}" + ], + "weird_expression_a": [ + "aa=RegExp.aa", + "aa=RegExp[0]", + "aa[[0]]", + "self=self[0]", + "window=window[0]" + ], + "weird_loop": [ + "function aa(){do {break;}while(0);}", + "function aa(){while(0){break;}}" + ], + "weird_relation_a": [ + "if(0===0){0;}" + ], + "wrap_condition": [ + "(aa&&!aa?0:1)" + ], + "wrap_immediate": [ + "aa=function(){}()" + ], + "wrap_parameter": [ + "aa=>0" + ], + "wrap_regexp": [ + "!/_/" + ], + "wrap_unary": [ + "0 - -0" + ] + }).forEach(function ([ + expectedWarning, malformedCodeList + ]) { + malformedCodeList.forEach(function (malformedCode) { + if (!jslint(malformedCode).warnings.some(function ({ + code + }) { + return code === expectedWarning; + })) { + throw new Error( + `jslint failed to warn "${expectedWarning}" with ` + + `malfomed code "${malformedCode}"` + ); + } + }); + }); +}());