From 85f04ab4e5762bdc90058ac4f5dcdb3e4eb207e3 Mon Sep 17 00:00:00 2001 From: Derk-Jan Karrenbeld Date: Thu, 24 Dec 2020 23:15:50 +0100 Subject: [PATCH 01/36] Normalise line-endings --- .gitattributes | 1 + .prettierrc | 9 +++++++++ 2 files changed, 10 insertions(+) create mode 100644 .gitattributes create mode 100644 .prettierrc diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 00000000..6313b56c --- /dev/null +++ b/.gitattributes @@ -0,0 +1 @@ +* text=auto eol=lf diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 00000000..366dd620 --- /dev/null +++ b/.prettierrc @@ -0,0 +1,9 @@ +{ + "trailingComma": "es5", + "tabWidth": 2, + "semi": false, + "singleQuote": true, + "arrowParens": "always", + "printWidth": 80, + "endOfLine": "lf" +} From 09367e370a25ec16ed2c798497e1f5ab6577df4a Mon Sep 17 00:00:00 2001 From: Derk-Jan Karrenbeld Date: Thu, 24 Dec 2020 23:15:59 +0100 Subject: [PATCH 02/36] Ignore generated files --- .prettierignore | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 .prettierignore diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 00000000..9fff4844 --- /dev/null +++ b/.prettierignore @@ -0,0 +1,4 @@ +/test/fixtures +/tmp +/dist +/node_modules \ No newline at end of file From 2135fb5208212af7c7558abcb6f00ee6370ee896 Mon Sep 17 00:00:00 2001 From: Derk-Jan Karrenbeld Date: Thu, 24 Dec 2020 23:16:08 +0100 Subject: [PATCH 03/36] Ignore generated directory --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index e6b7f1c3..9f48a9cf 100644 --- a/.gitignore +++ b/.gitignore @@ -9,6 +9,7 @@ jest.json results.json junit.xml results.xml +tmp yarn-error.log From 0d459cf016039f89b249a22328e88de4bbc54936 Mon Sep 17 00:00:00 2001 From: Derk-Jan Karrenbeld Date: Thu, 24 Dec 2020 23:16:33 +0100 Subject: [PATCH 04/36] Rename deploy workflows --- .github/workflows/{dockerhub.yml => deploy.dockerhub.yml} | 2 +- .github/workflows/{deploy.yml => deploy.ecr.yml} | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) rename .github/workflows/{dockerhub.yml => deploy.dockerhub.yml} (91%) rename .github/workflows/{deploy.yml => deploy.ecr.yml} (97%) diff --git a/.github/workflows/dockerhub.yml b/.github/workflows/deploy.dockerhub.yml similarity index 91% rename from .github/workflows/dockerhub.yml rename to .github/workflows/deploy.dockerhub.yml index c37cbc12..b10e5071 100644 --- a/.github/workflows/dockerhub.yml +++ b/.github/workflows/deploy.dockerhub.yml @@ -1,4 +1,4 @@ -name: Push to DockerHub +name: javascript-test-runner / deploy / dockerhub on: push: diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.ecr.yml similarity index 97% rename from .github/workflows/deploy.yml rename to .github/workflows/deploy.ecr.yml index 3baae788..16cfcead 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.ecr.yml @@ -1,4 +1,4 @@ -name: Deploy to Amazon ECR +name: javascript-test-runner / deploy / amazon-ecr env: aws_region: eu-west-2 From ad499258751e740899759af4b8afb892967518d1 Mon Sep 17 00:00:00 2001 From: Derk-Jan Karrenbeld Date: Thu, 24 Dec 2020 23:16:44 +0100 Subject: [PATCH 05/36] Add code-formatting --- .github/workflows/format-code.yml | 110 +++++++++++++++++++ .github/workflows/verify-code-formatting.yml | 18 +++ bin/check-formatting.sh | 3 + bin/format.sh | 9 ++ 4 files changed, 140 insertions(+) create mode 100644 .github/workflows/format-code.yml create mode 100644 .github/workflows/verify-code-formatting.yml create mode 100644 bin/check-formatting.sh create mode 100644 bin/format.sh diff --git a/.github/workflows/format-code.yml b/.github/workflows/format-code.yml new file mode 100644 index 00000000..201bd2a6 --- /dev/null +++ b/.github/workflows/format-code.yml @@ -0,0 +1,110 @@ +name: 'Format code' + +on: + issue_comment: + types: [created] + +jobs: + format: + name: 'Format code' + runs-on: ubuntu-latest + if: github.event.issue.pull_request != '' && contains(github.event.comment.body, '/format') + steps: + - name: 'Post acknowledgement that it will format code' + continue-on-error: true # Never fail the build if this fails + uses: actions/github-script@6e5ee1dc1cb3740e5e5e76ad668e3f526edbfe45 # 2.0.0 + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + script: | + github.issues.createComment({ + issue_number: context.issue.number, + owner: context.repo.owner, + repo: context.repo.repo, + body: 'The "Format code" action has started running.' + }) + + - name: 'Download PR data' + run: | + PR_DATA="/tmp/pr.json" + + jq -r ".issue.pull_request.url" "$GITHUB_EVENT_PATH" | \ + xargs curl --header 'authorization: Bearer ${{ secrets.GITHUB_TOKEN }}' -o "$PR_DATA" --url + + - name: 'Check fork status' + id: fork_status + run: | + IS_FORK="$(jq '.head.repo.fork' "/tmp/pr.json")" + echo "::set-output name=fork::$IS_FORK" + + - name: 'Setup SSH deploy key' + if: steps.fork_status.outputs.fork == 'false' + run: | + mkdir ~/.ssh + echo "${{ secrets.DEPLOY_KEY }}" > ~/.ssh/id_ed25519 + chmod 600 ~/.ssh/id_ed25519 + + - name: 'Checkout code' + run: | + PR_DATA="/tmp/pr.json" + + HEAD_REF=$(jq -r ".head.ref" "$PR_DATA") + + if [ ${{ steps.fork_status.outputs.fork }} == "false" ]; then + echo "::debug::Setting up repo using SSH" + HEAD_REPO=$(jq -r '.head.repo.ssh_url' "$PR_DATA") + else + echo "::debug::Setting up repo using HTTPS" + HEAD_REPO=$(jq -r '.head.repo.clone_url | sub("https://"; "https://x-access-token:${{ secrets.GITHUB_TOKEN }}@")' "$PR_DATA") + fi + + git clone $HEAD_REPO . + git checkout -b "$HEAD_REF" "origin/$HEAD_REF" + + - name: 'Format code' + run: ./bin/format.sh + env: + EXERCISM_PRETTIER_VERSION: '2.2.1' + + - name: 'Commit formatted code' + run: | + # Check if there is nothing to commit (i.e. no formatting changes made) + if [ -z "$(git status --porcelain)" ]; then + echo "Code is already formatted correctly" + exit 0 + fi + + # Setup the git user (required to commit anything) + git config --global user.email "github-actions[bot]@users.noreply.github.com" + git config --global user.name "github-actions[bot]" + + # Commit the changes made by prettier + git add . + git commit -m "[CI] Format code" + git push + + - name: 'Post acknowledgement that it has formatted the code' + continue-on-error: true # Never fail the build if this fails + uses: actions/github-script@6e5ee1dc1cb3740e5e5e76ad668e3f526edbfe45 # 2.0.0 + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + script: | + github.issues.createComment({ + issue_number: context.issue.number, + owner: context.repo.owner, + repo: context.repo.repo, + body: 'The "Format code" action has finished running.' + }) + + - name: 'Post reminder to trigger build manually' + continue-on-error: true # Never fail the build if this fails + if: steps.fork_status.outputs.fork == 'true' + uses: actions/github-script@6e5ee1dc1cb3740e5e5e76ad668e3f526edbfe45 # 2.0.0 + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + script: | + github.issues.createComment({ + issue_number: context.issue.number, + owner: context.repo.owner, + repo: context.repo.repo, + body: 'For security reasons, `/format` does not trigger CI builds when the PR has been submitted from a fork. If checks were not passing due to code format, trigger a build to make the required checks pass, through one of the following ways:\n\n- Push an empty commit to this branch: `git commit --allow-empty -m "Trigger builds"`.\n- Close and reopen the PR.\n- Push a regular commit to this branch.' + }) diff --git a/.github/workflows/verify-code-formatting.yml b/.github/workflows/verify-code-formatting.yml new file mode 100644 index 00000000..26ad0caf --- /dev/null +++ b/.github/workflows/verify-code-formatting.yml @@ -0,0 +1,18 @@ +name: javascript-test-runner / format + +on: + push: + pull_request: + workflow_dispatch: + +jobs: + verify: + runs-on: ubuntu-latest + steps: + - name: 'Checkout code' + uses: actions/checkout@v2 + + - name: 'Verify formatting of all files' + run: ./bin/check-formatting.sh + env: + EXERCISM_PRETTIER_VERSION: '2.2.1' diff --git a/bin/check-formatting.sh b/bin/check-formatting.sh new file mode 100644 index 00000000..4dc27e95 --- /dev/null +++ b/bin/check-formatting.sh @@ -0,0 +1,3 @@ +#!/bin/bash + +npx "prettier@$EXERCISM_PRETTIER_VERSION" --check "**/*.{js,jsx,ts,tsx,css,sass,scss,html,json,md,yml}" diff --git a/bin/format.sh b/bin/format.sh new file mode 100644 index 00000000..2a2141a4 --- /dev/null +++ b/bin/format.sh @@ -0,0 +1,9 @@ +#!/usr/bin/env bash + +if [ -z "$EXERCISM_PRETTIER_VERSION" ]; then + echo "This script requires the EXERCISM_PRETTIER_VERSION variable to work." + echo "Please see https://github.com/exercism/v3/blob/master/docs/maintainers/style-guide.md for guidance." + exit 1 +fi + +npx "prettier@$EXERCISM_PRETTIER_VERSION" --write "**/*.{js,jsx,ts,tsx,css,sass,scss,html,json,md,yml}" From 288a0e4b122516e5ebd9cd98aa22d64aa094ca46 Mon Sep 17 00:00:00 2001 From: Derk-Jan Karrenbeld Date: Thu, 24 Dec 2020 23:17:34 +0100 Subject: [PATCH 06/36] Update dependencies --- package.json | 31 +- yarn.lock | 1456 +++++++++++++++++++++++++------------------------- 2 files changed, 756 insertions(+), 731 deletions(-) diff --git a/package.json b/package.json index 01f494aa..b7175666 100644 --- a/package.json +++ b/package.json @@ -18,28 +18,31 @@ "test:cli": "jest test --no-cache {in}* --outputFile={result_file} --noStackTrace --verbose=false" }, "dependencies": { - "@babel/cli": "^7.12.1", - "@babel/core": "^7.12.3", - "@babel/node": "^7.12.1", - "@babel/preset-env": "^7.12.1", - "@babel/preset-typescript": "^7.12.1", - "babel-jest": "^26.6.0", + "@babel/cli": "^7.12.10", + "@babel/core": "^7.12.10", + "@babel/node": "^7.12.10", + "@babel/preset-env": "^7.12.11", + "@babel/preset-typescript": "^7.12.7", + "babel-jest": "^26.6.3", "chalk": "^4.1.0", - "jest": "^26.6.0", + "jest": "^26.6.3", "jest-junit": "^12.0.0", - "jest-util": "^26.6.0", + "jest-util": "^26.6.2", "slash": "^3.0.0", "string-length": "^4.0.1" }, "devDependencies": { - "@types/jest": "^26.0.14", - "@types/node": "^14.11.10", - "@typescript-eslint/parser": "^4.5.0", - "@typescript-eslint/typescript-estree": "^4.5.0", + "@types/jest": "^26.0.19", + "@types/node": "^14.14.16", + "@typescript-eslint/eslint-plugin": "^4.11.0", + "@typescript-eslint/parser": "^4.11.0", + "@typescript-eslint/typescript-estree": "^4.11.0", "babel-eslint": "^10.1.0", - "eslint": "^7.11.0", + "eslint": "^7.16.0", + "eslint-config-prettier": "^7.1.0", "eslint-plugin-import": "^2.22.1", - "typescript": "^4.0.3" + "eslint-plugin-jest": "^24.1.3", + "typescript": "^4.1.3" }, "jest": { "modulePathIgnorePatterns": [ diff --git a/yarn.lock b/yarn.lock index ffef9076..6704df4c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2,10 +2,10 @@ # yarn lockfile v1 -"@babel/cli@^7.12.1": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/cli/-/cli-7.12.1.tgz#e08a0b1cb6fcd4b9eb6a606ba5602c5c0fe24a0c" - integrity sha512-eRJREyrfAJ2r42Iaxe8h3v6yyj1wu9OyosaUHW6UImjGf9ahGL9nsFNh7OCopvtcPL8WnEo7tp78wrZaZ6vG9g== +"@babel/cli@^7.12.10": + version "7.12.10" + resolved "https://registry.yarnpkg.com/@babel/cli/-/cli-7.12.10.tgz#67a1015b1cd505bde1696196febf910c4c339a48" + integrity sha512-+y4ZnePpvWs1fc/LhZRTHkTesbXkyBYuOB+5CyodZqrEuETXi3zOVfpAQIdgC3lXbHLTDG9dQosxR9BhvLKDLQ== dependencies: commander "^4.0.1" convert-source-map "^1.1.0" @@ -16,7 +16,7 @@ slash "^2.0.0" source-map "^0.5.0" optionalDependencies: - "@nicolo-ribaudo/chokidar-2" "^2.1.8" + "@nicolo-ribaudo/chokidar-2" "2.1.8-no-fsevents" chokidar "^3.4.0" "@babel/code-frame@^7.0.0", "@babel/code-frame@^7.8.3": @@ -33,10 +33,17 @@ dependencies: "@babel/highlight" "^7.10.4" -"@babel/compat-data@^7.12.1": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.12.1.tgz#d7386a689aa0ddf06255005b4b991988021101a0" - integrity sha512-725AQupWJZ8ba0jbKceeFblZTY90McUBWMwHhkFQ9q1zKPJ95GUktljFcgcsIVwRnTnRKlcYzfiNImg5G9m6ZQ== +"@babel/code-frame@^7.12.11": + version "7.12.11" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.12.11.tgz#f4ad435aa263db935b8f10f2c552d23fb716a63f" + integrity sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw== + dependencies: + "@babel/highlight" "^7.10.4" + +"@babel/compat-data@^7.12.5", "@babel/compat-data@^7.12.7": + version "7.12.7" + resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.12.7.tgz#9329b4782a7d6bbd7eef57e11addf91ee3ef1e41" + integrity sha512-YaxPMGs/XIWtYqrdEOZOCPsVWfEoriXopnsz3/i7apYPXQ3698UFhS6dVT1KN5qOsWmVgw/FOrmQgpRaZayGsw== "@babel/core@^7.1.0", "@babel/core@^7.7.5": version "7.8.4" @@ -59,25 +66,24 @@ semver "^5.4.1" source-map "^0.5.0" -"@babel/core@^7.12.3": - version "7.12.3" - resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.12.3.tgz#1b436884e1e3bff6fb1328dc02b208759de92ad8" - integrity sha512-0qXcZYKZp3/6N2jKYVxZv0aNCsxTSVCiK72DTiTYZAu7sjg73W0/aynWjMbiGd87EQL4WyA8reiJVh92AVla9g== +"@babel/core@^7.12.10": + version "7.12.10" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.12.10.tgz#b79a2e1b9f70ed3d84bbfb6d8c4ef825f606bccd" + integrity sha512-eTAlQKq65zHfkHZV0sIVODCPGVgoo1HdBlbSLi9CqOzuZanMv2ihzY+4paiKr1mH+XmYESMAmJ/dpZ68eN6d8w== dependencies: "@babel/code-frame" "^7.10.4" - "@babel/generator" "^7.12.1" + "@babel/generator" "^7.12.10" "@babel/helper-module-transforms" "^7.12.1" - "@babel/helpers" "^7.12.1" - "@babel/parser" "^7.12.3" - "@babel/template" "^7.10.4" - "@babel/traverse" "^7.12.1" - "@babel/types" "^7.12.1" + "@babel/helpers" "^7.12.5" + "@babel/parser" "^7.12.10" + "@babel/template" "^7.12.7" + "@babel/traverse" "^7.12.10" + "@babel/types" "^7.12.10" convert-source-map "^1.7.0" debug "^4.1.0" gensync "^1.0.0-beta.1" json5 "^2.1.2" lodash "^4.17.19" - resolve "^1.3.2" semver "^5.4.1" source-map "^0.5.0" @@ -90,6 +96,15 @@ jsesc "^2.5.1" source-map "^0.5.0" +"@babel/generator@^7.12.10", "@babel/generator@^7.12.11": + version "7.12.11" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.12.11.tgz#98a7df7b8c358c9a37ab07a24056853016aba3af" + integrity sha512-Ggg6WPOJtSi8yYQvLVjG8F/TlpWDlKx0OpS4Kt+xMQPs5OaGYWy+v1A+1TvxI6sAMGZpKWWoAQ1DaeQbImlItA== + dependencies: + "@babel/types" "^7.12.11" + jsesc "^2.5.1" + source-map "^0.5.0" + "@babel/generator@^7.8.4": version "7.8.4" resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.8.4.tgz#35bbc74486956fe4251829f9f6c48330e8d0985e" @@ -115,14 +130,14 @@ "@babel/helper-explode-assignable-expression" "^7.10.4" "@babel/types" "^7.10.4" -"@babel/helper-compilation-targets@^7.12.1": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.12.1.tgz#310e352888fbdbdd8577be8dfdd2afb9e7adcf50" - integrity sha512-jtBEif7jsPwP27GPHs06v4WBV0KrE8a/P7n0N0sSvHn2hwUCYnolP/CLmz51IzAW4NlN+HuoBtb9QcwnRo9F/g== +"@babel/helper-compilation-targets@^7.12.5": + version "7.12.5" + resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.12.5.tgz#cb470c76198db6a24e9dbc8987275631e5d29831" + integrity sha512-+qH6NrscMolUlzOYngSBMIOQpKUGPPsc61Bu5W10mg84LxZ7cmvnBHzARKbDoFxVvqqAbj6Tg6N7bSrWSPXMyw== dependencies: - "@babel/compat-data" "^7.12.1" + "@babel/compat-data" "^7.12.5" "@babel/helper-validator-option" "^7.12.1" - browserslist "^4.12.0" + browserslist "^4.14.5" semver "^5.5.0" "@babel/helper-create-class-features-plugin@^7.12.1": @@ -170,6 +185,15 @@ "@babel/template" "^7.10.4" "@babel/types" "^7.10.4" +"@babel/helper-function-name@^7.12.11": + version "7.12.11" + resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.12.11.tgz#1fd7738aee5dcf53c3ecff24f1da9c511ec47b42" + integrity sha512-AtQKjtYNolKNi6nNNVLQ27CP6D9oFR6bq/HPYSizlzbp7uC1M59XJe8L+0uXjbIaZaUJF99ruHqVGiKXU/7ybA== + dependencies: + "@babel/helper-get-function-arity" "^7.12.10" + "@babel/template" "^7.12.7" + "@babel/types" "^7.12.11" + "@babel/helper-function-name@^7.8.3": version "7.8.3" resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.8.3.tgz#eeeb665a01b1f11068e9fb86ad56a1cb1a824cca" @@ -186,6 +210,13 @@ dependencies: "@babel/types" "^7.10.4" +"@babel/helper-get-function-arity@^7.12.10": + version "7.12.10" + resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.12.10.tgz#b158817a3165b5faa2047825dfa61970ddcc16cf" + integrity sha512-mm0n5BPjR06wh9mPQaDdXWDoll/j5UpCAPl1x8fS71GHm7HA6Ua2V4ylG1Ju8lvcTOietbPNNPaSilKj+pj+Ag== + dependencies: + "@babel/types" "^7.12.10" + "@babel/helper-get-function-arity@^7.8.3": version "7.8.3" resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.8.3.tgz#b894b947bd004381ce63ea1db9f08547e920abd5" @@ -214,6 +245,13 @@ dependencies: "@babel/types" "^7.12.1" +"@babel/helper-module-imports@^7.12.5": + version "7.12.5" + resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.12.5.tgz#1bfc0229f794988f76ed0a4d4e90860850b54dfb" + integrity sha512-SR713Ogqg6++uexFRORf/+nPXMmWIn80TALu0uaFb+iQIUoR7bOC7zBWyzBs5b3tBBJXuyD0cRu1F15GyzjOWA== + dependencies: + "@babel/types" "^7.12.5" + "@babel/helper-module-transforms@^7.12.1": version "7.12.1" resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.12.1.tgz#7954fec71f5b32c48e4b303b437c34453fd7247c" @@ -293,6 +331,13 @@ dependencies: "@babel/types" "^7.11.0" +"@babel/helper-split-export-declaration@^7.12.11": + version "7.12.11" + resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.12.11.tgz#1b4cc424458643c47d37022223da33d76ea4603a" + integrity sha512-LsIVN8j48gHgwzfocYUSkO/hjYAOJqlpJEc7tGXcIm4cubjVUf8LGW6eWRyxEu7gA25q02p0rQUWoCI33HNS5g== + dependencies: + "@babel/types" "^7.12.11" + "@babel/helper-split-export-declaration@^7.8.3": version "7.8.3" resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.8.3.tgz#31a9f30070f91368a7182cf05f831781065fc7a9" @@ -305,11 +350,21 @@ resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.10.4.tgz#a78c7a7251e01f616512d31b10adcf52ada5e0d2" integrity sha512-3U9y+43hz7ZM+rzG24Qe2mufW5KhvFg/NhnNph+i9mgCtdTCtMJuI1TMkrIUiK7Ix4PYlRF9I5dhqaLYA/ADXw== +"@babel/helper-validator-identifier@^7.12.11": + version "7.12.11" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.12.11.tgz#c9a1f021917dcb5ccf0d4e453e399022981fc9ed" + integrity sha512-np/lG3uARFybkoHokJUmf1QfEvRVCPbmQeUQpKow5cQ3xWrV9i3rUHodKDJPQfTVX61qKi+UdYk8kik84n7XOw== + "@babel/helper-validator-option@^7.12.1": version "7.12.1" resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.12.1.tgz#175567380c3e77d60ff98a54bb015fe78f2178d9" integrity sha512-YpJabsXlJVWP0USHjnC/AQDTLlZERbON577YUVO/wLpqyj6HAtVYnWaQaN0iUN+1/tWn3c+uKKXjRut5115Y2A== +"@babel/helper-validator-option@^7.12.11": + version "7.12.11" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.12.11.tgz#d66cb8b7a3e7fe4c6962b32020a131ecf0847f4f" + integrity sha512-TBFCyj939mFSdeX7U7DDj32WtzYY7fDcalgq8v3fBZMNOJQNn7nOYzMaUCiPxPYfCup69mtIpqlKgMZLvQ8Xhw== + "@babel/helper-wrap-function@^7.10.4": version "7.12.3" resolved "https://registry.yarnpkg.com/@babel/helper-wrap-function/-/helper-wrap-function-7.12.3.tgz#3332339fc4d1fbbf1c27d7958c27d34708e990d9" @@ -320,14 +375,14 @@ "@babel/traverse" "^7.10.4" "@babel/types" "^7.10.4" -"@babel/helpers@^7.12.1": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.12.1.tgz#8a8261c1d438ec18cb890434df4ec768734c1e79" - integrity sha512-9JoDSBGoWtmbay98efmT2+mySkwjzeFeAL9BuWNoVQpkPFQF8SIIFUfY5os9u8wVzglzoiPRSW7cuJmBDUt43g== +"@babel/helpers@^7.12.5": + version "7.12.5" + resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.12.5.tgz#1a1ba4a768d9b58310eda516c449913fe647116e" + integrity sha512-lgKGMQlKqA8meJqKsW6rUnc4MdUk35Ln0ATDqdM1a/UpARODdI4j5Y5lVfUScnSNkJcdCRAaWkspykNoFg9sJA== dependencies: "@babel/template" "^7.10.4" - "@babel/traverse" "^7.12.1" - "@babel/types" "^7.12.1" + "@babel/traverse" "^7.12.5" + "@babel/types" "^7.12.5" "@babel/helpers@^7.8.4": version "7.8.4" @@ -356,18 +411,17 @@ esutils "^2.0.2" js-tokens "^4.0.0" -"@babel/node@^7.12.1": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/node/-/node-7.12.1.tgz#66b5ae07b6bf76636e83906405fcfa69bab16c8a" - integrity sha512-S4tWOqo3V3ZuJjJNuheSMFIlDaQd6kbvqnQll+tdJTirksTdFHrauQf3d/xW4rgAM+mHJpxTZMHVeIXjCiDViw== +"@babel/node@^7.12.10": + version "7.12.10" + resolved "https://registry.yarnpkg.com/@babel/node/-/node-7.12.10.tgz#2a78e1a3a98f08e0d5e8adbaba783bed5efb09ae" + integrity sha512-lJT1sXp1bEfAZ7B2ChEOOiUxaGbIWkcAixqZDpbHnJWUqIjoofOGo5ON1bJ9HOmtMdF7rqKiOoM7zZSI87El3g== dependencies: - "@babel/register" "^7.12.1" + "@babel/register" "^7.12.10" commander "^4.0.1" core-js "^3.2.1" lodash "^4.17.19" node-environment-flags "^1.0.5" regenerator-runtime "^0.13.4" - resolve "^1.13.1" v8flags "^3.1.1" "@babel/parser@^7.1.0", "@babel/parser@^7.7.5", "@babel/parser@^7.8.3", "@babel/parser@^7.8.4": @@ -375,11 +429,16 @@ resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.8.4.tgz#d1dbe64691d60358a974295fa53da074dd2ce8e8" integrity sha512-0fKu/QqildpXmPVaRBoXOlyBb3MC+J0A66x97qEfLOMkn3u6nfY5esWogQwi/K0BjASYy4DbnsEWnpNL6qT5Mw== -"@babel/parser@^7.10.4", "@babel/parser@^7.12.1", "@babel/parser@^7.12.3", "@babel/parser@^7.7.0": +"@babel/parser@^7.10.4", "@babel/parser@^7.12.1", "@babel/parser@^7.7.0": version "7.12.3" resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.12.3.tgz#a305415ebe7a6c7023b40b5122a0662d928334cd" integrity sha512-kFsOS0IbsuhO5ojF8Hc8z/8vEIOkylVBrjiZUbLTE3XFe0Qi+uu6HjzQixkFaqr0ZPAMZcBVxEwmsnsLPZ2Xsw== +"@babel/parser@^7.12.10", "@babel/parser@^7.12.11", "@babel/parser@^7.12.7": + version "7.12.11" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.12.11.tgz#9ce3595bcd74bc5c466905e86c535b8b25011e79" + integrity sha512-N3UxG+uuF4CMYoNj8AhnbAcJF0PiuJ9KHuy1lQmkYsxTer/MAH9UBNHsBoAX/4s6NvlDD047No8mYVGGzLL4hg== + "@babel/plugin-proposal-async-generator-functions@^7.12.1": version "7.12.1" resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.12.1.tgz#dc6c1170e27d8aca99ff65f4925bd06b1c90550e" @@ -437,10 +496,10 @@ "@babel/helper-plugin-utils" "^7.10.4" "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.0" -"@babel/plugin-proposal-numeric-separator@^7.12.1": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.12.1.tgz#0e2c6774c4ce48be412119b4d693ac777f7685a6" - integrity sha512-MR7Ok+Af3OhNTCxYVjJZHS0t97ydnJZt/DbR4WISO39iDnhiD8XHrY12xuSJ90FFEGjir0Fzyyn7g/zY6hxbxA== +"@babel/plugin-proposal-numeric-separator@^7.12.7": + version "7.12.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.12.7.tgz#8bf253de8139099fea193b297d23a9d406ef056b" + integrity sha512-8c+uy0qmnRTeukiGsjLGy6uVs/TFjJchGXUeBqlG4VWYOdJWkhhVPdQ3uHwbmalfJwv2JsV0qffXP4asRfL2SQ== dependencies: "@babel/helper-plugin-utils" "^7.10.4" "@babel/plugin-syntax-numeric-separator" "^7.10.4" @@ -462,10 +521,10 @@ "@babel/helper-plugin-utils" "^7.10.4" "@babel/plugin-syntax-optional-catch-binding" "^7.8.0" -"@babel/plugin-proposal-optional-chaining@^7.12.1": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.12.1.tgz#cce122203fc8a32794296fc377c6dedaf4363797" - integrity sha512-c2uRpY6WzaVDzynVY9liyykS+kVU+WRZPMPYpkelXH8KBt1oXoI89kPbZKKG/jDT5UK92FTW2fZkZaJhdiBabw== +"@babel/plugin-proposal-optional-chaining@^7.12.7": + version "7.12.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.12.7.tgz#e02f0ea1b5dc59d401ec16fb824679f683d3303c" + integrity sha512-4ovylXZ0PWmwoOvhU2vhnzVNnm88/Sm9nx7V8BPgMvAzn5zDou3/Awy0EjglyubVHasJj+XCEkr/r1X3P5elCA== dependencies: "@babel/helper-plugin-utils" "^7.10.4" "@babel/helper-skip-transparent-expression-wrappers" "^7.12.1" @@ -578,7 +637,7 @@ dependencies: "@babel/helper-plugin-utils" "^7.8.0" -"@babel/plugin-syntax-top-level-await@^7.12.1": +"@babel/plugin-syntax-top-level-await@^7.12.1", "@babel/plugin-syntax-top-level-await@^7.8.3": version "7.12.1" resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.12.1.tgz#dd6c0b357ac1bb142d98537450a319625d13d2a0" integrity sha512-i7ooMZFS+a/Om0crxZodrTzNEPJHZrlMVGMTEpFAj6rYY/bKCddB0Dk/YxfPuYXOopuhKk/e1jV6h+WUU9XN3A== @@ -615,10 +674,10 @@ dependencies: "@babel/helper-plugin-utils" "^7.10.4" -"@babel/plugin-transform-block-scoping@^7.12.1": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.12.1.tgz#f0ee727874b42a208a48a586b84c3d222c2bbef1" - integrity sha512-zJyAC9sZdE60r1nVQHblcfCj29Dh2Y0DOvlMkcqSo0ckqjiCwNiUezUKw+RjOCwGfpLRwnAeQ2XlLpsnGkvv9w== +"@babel/plugin-transform-block-scoping@^7.12.11": + version "7.12.12" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.12.12.tgz#d93a567a152c22aea3b1929bb118d1d0a175cdca" + integrity sha512-VOEPQ/ExOVqbukuP7BYJtI5ZxxsmegTwzZ04j1aF0dkSypGo9XpDHuOrABsJu+ie+penpSJheDJ11x1BEZNiyQ== dependencies: "@babel/helper-plugin-utils" "^7.10.4" @@ -805,13 +864,12 @@ "@babel/helper-plugin-utils" "^7.10.4" "@babel/helper-skip-transparent-expression-wrappers" "^7.12.1" -"@babel/plugin-transform-sticky-regex@^7.12.1": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.12.1.tgz#5c24cf50de396d30e99afc8d1c700e8bce0f5caf" - integrity sha512-CiUgKQ3AGVk7kveIaPEET1jNDhZZEl1RPMWdTBE1799bdz++SwqDHStmxfCtDfBhQgCl38YRiSnrMuUMZIWSUQ== +"@babel/plugin-transform-sticky-regex@^7.12.7": + version "7.12.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.12.7.tgz#560224613ab23987453948ed21d0b0b193fa7fad" + integrity sha512-VEiqZL5N/QvDbdjfYQBhruN0HYjSPjC4XkeqW4ny/jNtH9gcbgaqBIXYEZCNnESMAGs0/K/R7oFGMhOyu/eIxg== dependencies: "@babel/helper-plugin-utils" "^7.10.4" - "@babel/helper-regex" "^7.10.4" "@babel/plugin-transform-template-literals@^7.12.1": version "7.12.1" @@ -820,10 +878,10 @@ dependencies: "@babel/helper-plugin-utils" "^7.10.4" -"@babel/plugin-transform-typeof-symbol@^7.12.1": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.12.1.tgz#9ca6be343d42512fbc2e68236a82ae64bc7af78a" - integrity sha512-EPGgpGy+O5Kg5pJFNDKuxt9RdmTgj5sgrus2XVeMp/ZIbOESadgILUbm50SNpghOh3/6yrbsH+NB5+WJTmsA7Q== +"@babel/plugin-transform-typeof-symbol@^7.12.10": + version "7.12.10" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.12.10.tgz#de01c4c8f96580bd00f183072b0d0ecdcf0dec4b" + integrity sha512-JQ6H8Rnsogh//ijxspCjc21YPd3VLVoYtAwv3zQmqAt8YGYUtdo5usNhdl4b9/Vir2kPFZl6n1h0PfUz4hJhaA== dependencies: "@babel/helper-plugin-utils" "^7.10.4" @@ -851,16 +909,16 @@ "@babel/helper-create-regexp-features-plugin" "^7.12.1" "@babel/helper-plugin-utils" "^7.10.4" -"@babel/preset-env@^7.12.1": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.12.1.tgz#9c7e5ca82a19efc865384bb4989148d2ee5d7ac2" - integrity sha512-H8kxXmtPaAGT7TyBvSSkoSTUK6RHh61So05SyEbpmr0MCZrsNYn7mGMzzeYoOUCdHzww61k8XBft2TaES+xPLg== +"@babel/preset-env@^7.12.11": + version "7.12.11" + resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.12.11.tgz#55d5f7981487365c93dbbc84507b1c7215e857f9" + integrity sha512-j8Tb+KKIXKYlDBQyIOy4BLxzv1NUOwlHfZ74rvW+Z0Gp4/cI2IMDPBWAgWceGcE7aep9oL/0K9mlzlMGxA8yNw== dependencies: - "@babel/compat-data" "^7.12.1" - "@babel/helper-compilation-targets" "^7.12.1" - "@babel/helper-module-imports" "^7.12.1" + "@babel/compat-data" "^7.12.7" + "@babel/helper-compilation-targets" "^7.12.5" + "@babel/helper-module-imports" "^7.12.5" "@babel/helper-plugin-utils" "^7.10.4" - "@babel/helper-validator-option" "^7.12.1" + "@babel/helper-validator-option" "^7.12.11" "@babel/plugin-proposal-async-generator-functions" "^7.12.1" "@babel/plugin-proposal-class-properties" "^7.12.1" "@babel/plugin-proposal-dynamic-import" "^7.12.1" @@ -868,10 +926,10 @@ "@babel/plugin-proposal-json-strings" "^7.12.1" "@babel/plugin-proposal-logical-assignment-operators" "^7.12.1" "@babel/plugin-proposal-nullish-coalescing-operator" "^7.12.1" - "@babel/plugin-proposal-numeric-separator" "^7.12.1" + "@babel/plugin-proposal-numeric-separator" "^7.12.7" "@babel/plugin-proposal-object-rest-spread" "^7.12.1" "@babel/plugin-proposal-optional-catch-binding" "^7.12.1" - "@babel/plugin-proposal-optional-chaining" "^7.12.1" + "@babel/plugin-proposal-optional-chaining" "^7.12.7" "@babel/plugin-proposal-private-methods" "^7.12.1" "@babel/plugin-proposal-unicode-property-regex" "^7.12.1" "@babel/plugin-syntax-async-generators" "^7.8.0" @@ -889,7 +947,7 @@ "@babel/plugin-transform-arrow-functions" "^7.12.1" "@babel/plugin-transform-async-to-generator" "^7.12.1" "@babel/plugin-transform-block-scoped-functions" "^7.12.1" - "@babel/plugin-transform-block-scoping" "^7.12.1" + "@babel/plugin-transform-block-scoping" "^7.12.11" "@babel/plugin-transform-classes" "^7.12.1" "@babel/plugin-transform-computed-properties" "^7.12.1" "@babel/plugin-transform-destructuring" "^7.12.1" @@ -913,14 +971,14 @@ "@babel/plugin-transform-reserved-words" "^7.12.1" "@babel/plugin-transform-shorthand-properties" "^7.12.1" "@babel/plugin-transform-spread" "^7.12.1" - "@babel/plugin-transform-sticky-regex" "^7.12.1" + "@babel/plugin-transform-sticky-regex" "^7.12.7" "@babel/plugin-transform-template-literals" "^7.12.1" - "@babel/plugin-transform-typeof-symbol" "^7.12.1" + "@babel/plugin-transform-typeof-symbol" "^7.12.10" "@babel/plugin-transform-unicode-escapes" "^7.12.1" "@babel/plugin-transform-unicode-regex" "^7.12.1" "@babel/preset-modules" "^0.1.3" - "@babel/types" "^7.12.1" - core-js-compat "^3.6.2" + "@babel/types" "^7.12.11" + core-js-compat "^3.8.0" semver "^5.5.0" "@babel/preset-modules@^0.1.3": @@ -934,18 +992,19 @@ "@babel/types" "^7.4.4" esutils "^2.0.2" -"@babel/preset-typescript@^7.12.1": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/preset-typescript/-/preset-typescript-7.12.1.tgz#86480b483bb97f75036e8864fe404cc782cc311b" - integrity sha512-hNK/DhmoJPsksdHuI/RVrcEws7GN5eamhi28JkO52MqIxU8Z0QpmiSOQxZHWOHV7I3P4UjHV97ay4TcamMA6Kw== +"@babel/preset-typescript@^7.12.7": + version "7.12.7" + resolved "https://registry.yarnpkg.com/@babel/preset-typescript/-/preset-typescript-7.12.7.tgz#fc7df8199d6aae747896f1e6c61fc872056632a3" + integrity sha512-nOoIqIqBmHBSEgBXWR4Dv/XBehtIFcw9PqZw6rFYuKrzsZmOQm3PR5siLBnKZFEsDb03IegG8nSjU/iXXXYRmw== dependencies: "@babel/helper-plugin-utils" "^7.10.4" + "@babel/helper-validator-option" "^7.12.1" "@babel/plugin-transform-typescript" "^7.12.1" -"@babel/register@^7.12.1": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/register/-/register-7.12.1.tgz#cdb087bdfc4f7241c03231f22e15d211acf21438" - integrity sha512-XWcmseMIncOjoydKZnWvWi0/5CUCD+ZYKhRwgYlWOrA8fGZ/FjuLRpqtIhLOVD/fvR1b9DQHtZPn68VvhpYf+Q== +"@babel/register@^7.12.10": + version "7.12.10" + resolved "https://registry.yarnpkg.com/@babel/register/-/register-7.12.10.tgz#19b87143f17128af4dbe7af54c735663b3999f60" + integrity sha512-EvX/BvMMJRAA3jZgILWgbsrHwBQvllC5T8B29McyME8DvkdOxk4ujESfrMvME8IHSDvWXrmMXxPvA/lx2gqPLQ== dependencies: find-cache-dir "^2.0.0" lodash "^4.17.19" @@ -969,6 +1028,15 @@ "@babel/parser" "^7.10.4" "@babel/types" "^7.10.4" +"@babel/template@^7.12.7": + version "7.12.7" + resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.12.7.tgz#c817233696018e39fbb6c491d2fb684e05ed43bc" + integrity sha512-GkDzmHS6GV7ZeXfJZ0tLRBhZcMcY0/Lnb+eEbXDBfCAcZCjrZKe6p3J4we/D24O9Y8enxWAg1cWwof59yLh2ow== + dependencies: + "@babel/code-frame" "^7.10.4" + "@babel/parser" "^7.12.7" + "@babel/types" "^7.12.7" + "@babel/template@^7.7.4", "@babel/template@^7.8.3": version "7.8.3" resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.8.3.tgz#e02ad04fe262a657809327f578056ca15fd4d1b8" @@ -1008,6 +1076,21 @@ globals "^11.1.0" lodash "^4.17.19" +"@babel/traverse@^7.12.10", "@babel/traverse@^7.12.5": + version "7.12.12" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.12.12.tgz#d0cd87892704edd8da002d674bc811ce64743376" + integrity sha512-s88i0X0lPy45RrLM8b9mz8RPH5FqO9G9p7ti59cToE44xFm1Q+Pjh5Gq4SXBbtb88X7Uy7pexeqRIQDDMNkL0w== + dependencies: + "@babel/code-frame" "^7.12.11" + "@babel/generator" "^7.12.11" + "@babel/helper-function-name" "^7.12.11" + "@babel/helper-split-export-declaration" "^7.12.11" + "@babel/parser" "^7.12.11" + "@babel/types" "^7.12.12" + debug "^4.1.0" + globals "^11.1.0" + lodash "^4.17.19" + "@babel/types@^7.0.0", "@babel/types@^7.3.0", "@babel/types@^7.8.3": version "7.8.3" resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.8.3.tgz#5a383dffa5416db1b73dedffd311ffd0788fb31c" @@ -1026,6 +1109,15 @@ lodash "^4.17.19" to-fast-properties "^2.0.0" +"@babel/types@^7.12.10", "@babel/types@^7.12.11", "@babel/types@^7.12.12", "@babel/types@^7.12.5", "@babel/types@^7.12.7": + version "7.12.12" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.12.12.tgz#4608a6ec313abbd87afa55004d373ad04a96c299" + integrity sha512-lnIX7piTxOH22xE7fDXDbSHg9MM1/6ORnafpJmov5rs0kX5g4BZxeXNJLXsMRiO0U5Rb8/FvMS6xlTnTHvxonQ== + dependencies: + "@babel/helper-validator-identifier" "^7.12.11" + lodash "^4.17.19" + to-fast-properties "^2.0.0" + "@bcoe/v8-coverage@^0.2.3": version "0.2.3" resolved "https://registry.yarnpkg.com/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz#75a2e8b51cb758a7553d6804a5932d7aace75c39" @@ -1039,10 +1131,10 @@ exec-sh "^0.3.2" minimist "^1.2.0" -"@eslint/eslintrc@^0.1.3": - version "0.1.3" - resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-0.1.3.tgz#7d1a2b2358552cc04834c0979bd4275362e37085" - integrity sha512-4YVwPkANLeNtRjMekzux1ci8hIaH5eGKktGqR0d3LWsKNn5B2X/1Z6Trxy7jQXl9EBGE6Yj02O+t09FMeRllaA== +"@eslint/eslintrc@^0.2.2": + version "0.2.2" + resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-0.2.2.tgz#d01fc791e2fc33e88a29d6f3dc7e93d0cd784b76" + integrity sha512-EfB5OHNYp1F4px/LI/FEnGylop7nOqkQ1LRzCM0KccA2U8tvV8w01KBv37LbO7nW4H+YhKyo2LcJhRwjjV17QQ== dependencies: ajv "^6.12.4" debug "^4.1.1" @@ -1070,93 +1162,93 @@ resolved "https://registry.yarnpkg.com/@istanbuljs/schema/-/schema-0.1.2.tgz#26520bf09abe4a5644cd5414e37125a8954241dd" integrity sha512-tsAQNx32a8CoFhjhijUIhI4kccIAgmGhy8LZMZgGfmXcpMbPRUqn5LWmgRttILi6yeGmBJd2xsPkFMs0PzgPCw== -"@jest/console@^26.6.0": - version "26.6.0" - resolved "https://registry.yarnpkg.com/@jest/console/-/console-26.6.0.tgz#fd4a4733df3c50260aefb227414296aee96e682f" - integrity sha512-ArGcZWAEYMWmWnc/QvxLDvFmGRPvmHeulhS7FUUAlUGR5vS/SqMfArsGaYmIFEThSotCMnEihwx1h62I1eg5lg== +"@jest/console@^26.6.2": + version "26.6.2" + resolved "https://registry.yarnpkg.com/@jest/console/-/console-26.6.2.tgz#4e04bc464014358b03ab4937805ee36a0aeb98f2" + integrity sha512-IY1R2i2aLsLr7Id3S6p2BA82GNWryt4oSvEXLAKc+L2zdi89dSkE8xC1C+0kpATG4JhBJREnQOH7/zmccM2B0g== dependencies: - "@jest/types" "^26.6.0" + "@jest/types" "^26.6.2" "@types/node" "*" chalk "^4.0.0" - jest-message-util "^26.6.0" - jest-util "^26.6.0" + jest-message-util "^26.6.2" + jest-util "^26.6.2" slash "^3.0.0" -"@jest/core@^26.6.0": - version "26.6.0" - resolved "https://registry.yarnpkg.com/@jest/core/-/core-26.6.0.tgz#04dd3e046e9ebbe06a4f330e05a67f21f7bb314a" - integrity sha512-7wbunxosnC5zXjxrEtTQSblFjRVOT8qz1eSytw8riEeWgegy3ct91NLPEP440CDuWrmW3cOLcEGxIf9q2u6O9Q== +"@jest/core@^26.6.3": + version "26.6.3" + resolved "https://registry.yarnpkg.com/@jest/core/-/core-26.6.3.tgz#7639fcb3833d748a4656ada54bde193051e45fad" + integrity sha512-xvV1kKbhfUqFVuZ8Cyo+JPpipAHHAV3kcDBftiduK8EICXmTFddryy3P7NfZt8Pv37rA9nEJBKCCkglCPt/Xjw== dependencies: - "@jest/console" "^26.6.0" - "@jest/reporters" "^26.6.0" - "@jest/test-result" "^26.6.0" - "@jest/transform" "^26.6.0" - "@jest/types" "^26.6.0" + "@jest/console" "^26.6.2" + "@jest/reporters" "^26.6.2" + "@jest/test-result" "^26.6.2" + "@jest/transform" "^26.6.2" + "@jest/types" "^26.6.2" "@types/node" "*" ansi-escapes "^4.2.1" chalk "^4.0.0" exit "^0.1.2" graceful-fs "^4.2.4" - jest-changed-files "^26.6.0" - jest-config "^26.6.0" - jest-haste-map "^26.6.0" - jest-message-util "^26.6.0" + jest-changed-files "^26.6.2" + jest-config "^26.6.3" + jest-haste-map "^26.6.2" + jest-message-util "^26.6.2" jest-regex-util "^26.0.0" - jest-resolve "^26.6.0" - jest-resolve-dependencies "^26.6.0" - jest-runner "^26.6.0" - jest-runtime "^26.6.0" - jest-snapshot "^26.6.0" - jest-util "^26.6.0" - jest-validate "^26.6.0" - jest-watcher "^26.6.0" + jest-resolve "^26.6.2" + jest-resolve-dependencies "^26.6.3" + jest-runner "^26.6.3" + jest-runtime "^26.6.3" + jest-snapshot "^26.6.2" + jest-util "^26.6.2" + jest-validate "^26.6.2" + jest-watcher "^26.6.2" micromatch "^4.0.2" p-each-series "^2.1.0" rimraf "^3.0.0" slash "^3.0.0" strip-ansi "^6.0.0" -"@jest/environment@^26.6.0": - version "26.6.0" - resolved "https://registry.yarnpkg.com/@jest/environment/-/environment-26.6.0.tgz#695ee24cbf110456272caa9debbbf7e01afb2f78" - integrity sha512-l+5MSdiC4rUUrz8xPdj0TwHBwuoqMcAbFnsYDTn5FkenJl8b+lvC5NdJl1tVICGHWnx0fnjdd1luRZ7u3U4xyg== +"@jest/environment@^26.6.2": + version "26.6.2" + resolved "https://registry.yarnpkg.com/@jest/environment/-/environment-26.6.2.tgz#ba364cc72e221e79cc8f0a99555bf5d7577cf92c" + integrity sha512-nFy+fHl28zUrRsCeMB61VDThV1pVTtlEokBRgqPrcT1JNq4yRNIyTHfyht6PqtUvY9IsuLGTrbG8kPXjSZIZwA== dependencies: - "@jest/fake-timers" "^26.6.0" - "@jest/types" "^26.6.0" + "@jest/fake-timers" "^26.6.2" + "@jest/types" "^26.6.2" "@types/node" "*" - jest-mock "^26.6.0" + jest-mock "^26.6.2" -"@jest/fake-timers@^26.6.0": - version "26.6.0" - resolved "https://registry.yarnpkg.com/@jest/fake-timers/-/fake-timers-26.6.0.tgz#5b4cc83fab91029963c53e6e2716f02544323b22" - integrity sha512-7VQpjChrwlwvGNysS10lDBLOVLxMvMtpx0Xo6aIotzNVyojYk0NN0CR8R4T6h/eu7Zva/LB3P71jqwGdtADoag== +"@jest/fake-timers@^26.6.2": + version "26.6.2" + resolved "https://registry.yarnpkg.com/@jest/fake-timers/-/fake-timers-26.6.2.tgz#459c329bcf70cee4af4d7e3f3e67848123535aad" + integrity sha512-14Uleatt7jdzefLPYM3KLcnUl1ZNikaKq34enpb5XG9i81JpppDb5muZvonvKyrl7ftEHkKS5L5/eB/kxJ+bvA== dependencies: - "@jest/types" "^26.6.0" + "@jest/types" "^26.6.2" "@sinonjs/fake-timers" "^6.0.1" "@types/node" "*" - jest-message-util "^26.6.0" - jest-mock "^26.6.0" - jest-util "^26.6.0" + jest-message-util "^26.6.2" + jest-mock "^26.6.2" + jest-util "^26.6.2" -"@jest/globals@^26.6.0": - version "26.6.0" - resolved "https://registry.yarnpkg.com/@jest/globals/-/globals-26.6.0.tgz#da2f58d17105b6a7531ee3c8724acb5f233400e2" - integrity sha512-rs3a/a8Lq8FgTx11SxbqIU2bDjsFU2PApl2oK2oUVlo84RSF76afFm2nLojW93AGssr715GHUwhq5b6mpCI5BQ== +"@jest/globals@^26.6.2": + version "26.6.2" + resolved "https://registry.yarnpkg.com/@jest/globals/-/globals-26.6.2.tgz#5b613b78a1aa2655ae908eba638cc96a20df720a" + integrity sha512-85Ltnm7HlB/KesBUuALwQ68YTU72w9H2xW9FjZ1eL1U3lhtefjjl5c2MiUbpXt/i6LaPRvoOFJ22yCBSfQ0JIA== dependencies: - "@jest/environment" "^26.6.0" - "@jest/types" "^26.6.0" - expect "^26.6.0" + "@jest/environment" "^26.6.2" + "@jest/types" "^26.6.2" + expect "^26.6.2" -"@jest/reporters@^26.6.0": - version "26.6.0" - resolved "https://registry.yarnpkg.com/@jest/reporters/-/reporters-26.6.0.tgz#2a8d631ad3b19a722fd0fae58ce9fa25e8aac1cf" - integrity sha512-PXbvHhdci5Rj1VFloolgLb+0kkdtzswhG8MzVENKJRI3O1ndwr52G6E/2QupjwrRcYnApZOelFf4nNpf5+SDxA== +"@jest/reporters@^26.6.2": + version "26.6.2" + resolved "https://registry.yarnpkg.com/@jest/reporters/-/reporters-26.6.2.tgz#1f518b99637a5f18307bd3ecf9275f6882a667f6" + integrity sha512-h2bW53APG4HvkOnVMo8q3QXa6pcaNt1HkwVsOPMBV6LD/q9oSpxNSYZQYkAnjdMjrJ86UuYeLo+aEZClV6opnw== dependencies: "@bcoe/v8-coverage" "^0.2.3" - "@jest/console" "^26.6.0" - "@jest/test-result" "^26.6.0" - "@jest/transform" "^26.6.0" - "@jest/types" "^26.6.0" + "@jest/console" "^26.6.2" + "@jest/test-result" "^26.6.2" + "@jest/transform" "^26.6.2" + "@jest/types" "^26.6.2" chalk "^4.0.0" collect-v8-coverage "^1.0.0" exit "^0.1.2" @@ -1167,83 +1259,73 @@ istanbul-lib-report "^3.0.0" istanbul-lib-source-maps "^4.0.0" istanbul-reports "^3.0.2" - jest-haste-map "^26.6.0" - jest-resolve "^26.6.0" - jest-util "^26.6.0" - jest-worker "^26.5.0" + jest-haste-map "^26.6.2" + jest-resolve "^26.6.2" + jest-util "^26.6.2" + jest-worker "^26.6.2" slash "^3.0.0" source-map "^0.6.0" string-length "^4.0.1" terminal-link "^2.0.0" - v8-to-istanbul "^6.0.1" + v8-to-istanbul "^7.0.0" optionalDependencies: node-notifier "^8.0.0" -"@jest/source-map@^26.5.0": - version "26.5.0" - resolved "https://registry.yarnpkg.com/@jest/source-map/-/source-map-26.5.0.tgz#98792457c85bdd902365cd2847b58fff05d96367" - integrity sha512-jWAw9ZwYHJMe9eZq/WrsHlwF8E3hM9gynlcDpOyCb9bR8wEd9ZNBZCi7/jZyzHxC7t3thZ10gO2IDhu0bPKS5g== +"@jest/source-map@^26.6.2": + version "26.6.2" + resolved "https://registry.yarnpkg.com/@jest/source-map/-/source-map-26.6.2.tgz#29af5e1e2e324cafccc936f218309f54ab69d535" + integrity sha512-YwYcCwAnNmOVsZ8mr3GfnzdXDAl4LaenZP5z+G0c8bzC9/dugL8zRmxZzdoTl4IaS3CryS1uWnROLPFmb6lVvA== dependencies: callsites "^3.0.0" graceful-fs "^4.2.4" source-map "^0.6.0" -"@jest/test-result@^26.6.0": - version "26.6.0" - resolved "https://registry.yarnpkg.com/@jest/test-result/-/test-result-26.6.0.tgz#79705c8a57165777af5ef1d45c65dcc4a5965c11" - integrity sha512-LV6X1ry+sKjseQsIFz3e6XAZYxwidvmeJFnVF08fq98q08dF1mJYI0lDq/LmH/jas+R4s0pwnNGiz1hfC4ZUBw== +"@jest/test-result@^26.6.2": + version "26.6.2" + resolved "https://registry.yarnpkg.com/@jest/test-result/-/test-result-26.6.2.tgz#55da58b62df134576cc95476efa5f7949e3f5f18" + integrity sha512-5O7H5c/7YlojphYNrK02LlDIV2GNPYisKwHm2QTKjNZeEzezCbwYs9swJySv2UfPMyZ0VdsmMv7jIlD/IKYQpQ== dependencies: - "@jest/console" "^26.6.0" - "@jest/types" "^26.6.0" + "@jest/console" "^26.6.2" + "@jest/types" "^26.6.2" "@types/istanbul-lib-coverage" "^2.0.0" collect-v8-coverage "^1.0.0" -"@jest/test-sequencer@^26.6.0": - version "26.6.0" - resolved "https://registry.yarnpkg.com/@jest/test-sequencer/-/test-sequencer-26.6.0.tgz#a9dbc6545b1c59e7f375b05466e172126609906d" - integrity sha512-rWPTMa+8rejvePZnJmnKkmKWh0qILFDPpN0qbSif+KNGvFxqqDGafMo4P2Y8+I9XWrZQBeXL9IxPL4ZzDgRlbw== +"@jest/test-sequencer@^26.6.3": + version "26.6.3" + resolved "https://registry.yarnpkg.com/@jest/test-sequencer/-/test-sequencer-26.6.3.tgz#98e8a45100863886d074205e8ffdc5a7eb582b17" + integrity sha512-YHlVIjP5nfEyjlrSr8t/YdNfU/1XEt7c5b4OxcXCjyRhjzLYu/rO69/WHPuYcbCWkz8kAeZVZp2N2+IOLLEPGw== dependencies: - "@jest/test-result" "^26.6.0" + "@jest/test-result" "^26.6.2" graceful-fs "^4.2.4" - jest-haste-map "^26.6.0" - jest-runner "^26.6.0" - jest-runtime "^26.6.0" + jest-haste-map "^26.6.2" + jest-runner "^26.6.3" + jest-runtime "^26.6.3" -"@jest/transform@^26.6.0": - version "26.6.0" - resolved "https://registry.yarnpkg.com/@jest/transform/-/transform-26.6.0.tgz#1a6b95d0c7f9b4f96dd3aab9d28422a9e5e4043e" - integrity sha512-NUNA1NMCyVV9g5NIQF1jzW7QutQhB/HAocteCiUyH0VhmLXnGMTfPYQu1G6IjPk+k1SWdh2PD+Zs1vMqbavWzg== +"@jest/transform@^26.6.2": + version "26.6.2" + resolved "https://registry.yarnpkg.com/@jest/transform/-/transform-26.6.2.tgz#5ac57c5fa1ad17b2aae83e73e45813894dcf2e4b" + integrity sha512-E9JjhUgNzvuQ+vVAL21vlyfy12gP0GhazGgJC4h6qUt1jSdUXGWJ1wfu/X7Sd8etSgxV4ovT1pb9v5D6QW4XgA== dependencies: "@babel/core" "^7.1.0" - "@jest/types" "^26.6.0" + "@jest/types" "^26.6.2" babel-plugin-istanbul "^6.0.0" chalk "^4.0.0" convert-source-map "^1.4.0" fast-json-stable-stringify "^2.0.0" graceful-fs "^4.2.4" - jest-haste-map "^26.6.0" + jest-haste-map "^26.6.2" jest-regex-util "^26.0.0" - jest-util "^26.6.0" + jest-util "^26.6.2" micromatch "^4.0.2" pirates "^4.0.1" slash "^3.0.0" source-map "^0.6.1" write-file-atomic "^3.0.0" -"@jest/types@^25.5.0": - version "25.5.0" - resolved "https://registry.yarnpkg.com/@jest/types/-/types-25.5.0.tgz#4d6a4793f7b9599fc3680877b856a97dbccf2a9d" - integrity sha512-OXD0RgQ86Tu3MazKo8bnrkDRaDXXMGUqd+kTtLtK1Zb7CRzQcaSRPPPV37SvYTdevXEBVxe0HXylEjs8ibkmCw== - dependencies: - "@types/istanbul-lib-coverage" "^2.0.0" - "@types/istanbul-reports" "^1.1.1" - "@types/yargs" "^15.0.0" - chalk "^3.0.0" - -"@jest/types@^26.6.0": - version "26.6.0" - resolved "https://registry.yarnpkg.com/@jest/types/-/types-26.6.0.tgz#2c045f231bfd79d52514cda3fbc93ef46157fa6a" - integrity sha512-8pDeq/JVyAYw7jBGU83v8RMYAkdrRxLG3BGnAJuqaQAUd6GWBmND2uyl+awI88+hit48suLoLjNFtR+ZXxWaYg== +"@jest/types@^26.6.2": + version "26.6.2" + resolved "https://registry.yarnpkg.com/@jest/types/-/types-26.6.2.tgz#bef5a532030e1d88a2f5a6d933f84e97226ed48e" + integrity sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ== dependencies: "@types/istanbul-lib-coverage" "^2.0.0" "@types/istanbul-reports" "^3.0.0" @@ -1251,12 +1333,22 @@ "@types/yargs" "^15.0.0" chalk "^4.0.0" -"@nicolo-ribaudo/chokidar-2@^2.1.8": - version "2.1.8" - resolved "https://registry.yarnpkg.com/@nicolo-ribaudo/chokidar-2/-/chokidar-2-2.1.8.tgz#eef8d9b47e8dc589499f14d656e8d2dd978c3d14" - integrity sha512-FohwULwAebCUKi/akMFyGi7jfc7JXTeMHzKxuP3umRd9mK/2Y7/SMBSI2jX+YLopPXi+PF9l307NmpfxTdCegA== +"@nicolo-ribaudo/chokidar-2@2.1.8-no-fsevents": + version "2.1.8-no-fsevents" + resolved "https://registry.yarnpkg.com/@nicolo-ribaudo/chokidar-2/-/chokidar-2-2.1.8-no-fsevents.tgz#da7c3996b8e6e19ebd14d82eaced2313e7769f9b" + integrity sha512-+nb9vWloHNNMFHjGofEam3wopE3m1yuambrrd/fnPc+lFOMB9ROTqQlche9ByFWNkdNqfSgR/kkQtQ8DzEWt2w== dependencies: - chokidar "2.1.8" + anymatch "^2.0.0" + async-each "^1.0.1" + braces "^2.3.2" + glob-parent "^3.1.0" + inherits "^2.0.3" + is-binary-path "^1.0.0" + is-glob "^4.0.0" + normalize-path "^3.0.0" + path-is-absolute "^1.0.0" + readdirp "^2.2.1" + upath "^1.1.1" "@nodelib/fs.scandir@2.1.3": version "2.1.3" @@ -1357,14 +1449,6 @@ dependencies: "@types/istanbul-lib-coverage" "*" -"@types/istanbul-reports@^1.1.1": - version "1.1.1" - resolved "https://registry.yarnpkg.com/@types/istanbul-reports/-/istanbul-reports-1.1.1.tgz#7a8cbf6a406f36c8add871625b278eaf0b0d255a" - integrity sha512-UpYjBi8xefVChsCoBpKShdxTllC9pwISirfoZsUa2AAdQg/Jd2KQGtSbw+ya7GPo7x/wAPlH6JBhKhAsXUEZNA== - dependencies: - "@types/istanbul-lib-coverage" "*" - "@types/istanbul-lib-report" "*" - "@types/istanbul-reports@^3.0.0": version "3.0.0" resolved "https://registry.yarnpkg.com/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz#508b13aa344fa4976234e75dddcc34925737d821" @@ -1372,24 +1456,34 @@ dependencies: "@types/istanbul-lib-report" "*" -"@types/jest@^26.0.14": - version "26.0.14" - resolved "https://registry.yarnpkg.com/@types/jest/-/jest-26.0.14.tgz#078695f8f65cb55c5a98450d65083b2b73e5a3f3" - integrity sha512-Hz5q8Vu0D288x3iWXePSn53W7hAjP0H7EQ6QvDO9c7t46mR0lNOLlfuwQ+JkVxuhygHzlzPX+0jKdA3ZgSh+Vg== +"@types/jest@^26.0.19": + version "26.0.19" + resolved "https://registry.yarnpkg.com/@types/jest/-/jest-26.0.19.tgz#e6fa1e3def5842ec85045bd5210e9bb8289de790" + integrity sha512-jqHoirTG61fee6v6rwbnEuKhpSKih0tuhqeFbCmMmErhtu3BYlOZaXWjffgOstMM4S/3iQD31lI5bGLTrs97yQ== dependencies: - jest-diff "^25.2.1" - pretty-format "^25.2.1" + jest-diff "^26.0.0" + pretty-format "^26.0.0" + +"@types/json-schema@^7.0.3": + version "7.0.6" + resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.6.tgz#f4c7ec43e81b319a9815115031709f26987891f0" + integrity sha512-3c+yGKvVP5Y9TYBEibGNR+kLtijnj7mYrXRg+WpFb2X9xm04g/DXYkfg4hmzJQosc9snFNUPkbYIhu+KAm6jJw== "@types/json5@^0.0.29": version "0.0.29" resolved "https://registry.yarnpkg.com/@types/json5/-/json5-0.0.29.tgz#ee28707ae94e11d2b827bcbe5270bcea7f3e71ee" integrity sha1-7ihweulOEdK4J7y+UnC86n8+ce4= -"@types/node@*", "@types/node@^14.11.10": +"@types/node@*": version "14.11.10" resolved "https://registry.yarnpkg.com/@types/node/-/node-14.11.10.tgz#8c102aba13bf5253f35146affbf8b26275069bef" integrity sha512-yV1nWZPlMFpoXyoknm4S56y2nlTAuFYaJuQtYRAOU7xA/FJ9RY0Xm7QOkaYMMmr8ESdHIuUb6oQgR/0+2NqlyA== +"@types/node@^14.14.16": + version "14.14.16" + resolved "https://registry.yarnpkg.com/@types/node/-/node-14.14.16.tgz#3cc351f8d48101deadfed4c9e4f116048d437b4b" + integrity sha512-naXYePhweTi+BMv11TgioE2/FXU4fSl29HAH1ffxVciNsH3rYXjNP2yM8wqmSm7jS20gM8TIklKiTen+1iVncw== + "@types/normalize-package-data@^2.4.0": version "2.4.0" resolved "https://registry.yarnpkg.com/@types/normalize-package-data/-/normalize-package-data-2.4.0.tgz#e486d0d97396d79beedd0a6e33f4534ff6b4973e" @@ -1417,36 +1511,61 @@ dependencies: "@types/yargs-parser" "*" -"@typescript-eslint/parser@^4.5.0": - version "4.5.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-4.5.0.tgz#b2d659f25eec0041c7bc5660b91db1eefe8d7122" - integrity sha512-xb+gmyhQcnDWe+5+xxaQk5iCw6KqXd8VQxGiTeELTMoYeRjpocZYYRP1gFVM2C8Yl0SpUvLa1lhprwqZ00w3Iw== +"@typescript-eslint/eslint-plugin@^4.11.0": + version "4.11.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.11.0.tgz#bc6c1e4175c0cf42083da4314f7931ad12f731cc" + integrity sha512-x4arJMXBxyD6aBXLm3W7mSDZRiABzy+2PCLJbL7OPqlp53VXhaA1HKK7R2rTee5OlRhnUgnp8lZyVIqjnyPT6g== dependencies: - "@typescript-eslint/scope-manager" "4.5.0" - "@typescript-eslint/types" "4.5.0" - "@typescript-eslint/typescript-estree" "4.5.0" + "@typescript-eslint/experimental-utils" "4.11.0" + "@typescript-eslint/scope-manager" "4.11.0" + debug "^4.1.1" + functional-red-black-tree "^1.0.1" + regexpp "^3.0.0" + semver "^7.3.2" + tsutils "^3.17.1" + +"@typescript-eslint/experimental-utils@4.11.0", "@typescript-eslint/experimental-utils@^4.0.1": + version "4.11.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-4.11.0.tgz#d1a47cc6cfe1c080ce4ead79267574b9881a1565" + integrity sha512-1VC6mSbYwl1FguKt8OgPs8xxaJgtqFpjY/UzUYDBKq4pfQ5lBvN2WVeqYkzf7evW42axUHYl2jm9tNyFsb8oLg== + dependencies: + "@types/json-schema" "^7.0.3" + "@typescript-eslint/scope-manager" "4.11.0" + "@typescript-eslint/types" "4.11.0" + "@typescript-eslint/typescript-estree" "4.11.0" + eslint-scope "^5.0.0" + eslint-utils "^2.0.0" + +"@typescript-eslint/parser@^4.11.0": + version "4.11.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-4.11.0.tgz#1dd3d7e42708c10ce9f3aa64c63c0ab99868b4e2" + integrity sha512-NBTtKCC7ZtuxEV5CrHUO4Pg2s784pvavc3cnz6V+oJvVbK4tH9135f/RBP6eUA2KHiFKAollSrgSctQGmHbqJQ== + dependencies: + "@typescript-eslint/scope-manager" "4.11.0" + "@typescript-eslint/types" "4.11.0" + "@typescript-eslint/typescript-estree" "4.11.0" debug "^4.1.1" -"@typescript-eslint/scope-manager@4.5.0": - version "4.5.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-4.5.0.tgz#8dfd53c3256d4357e7d66c2fc8956835f4d239be" - integrity sha512-C0cEO0cTMPJ/w4RA/KVe4LFFkkSh9VHoFzKmyaaDWAnPYIEzVCtJ+Un8GZoJhcvq+mPFXEsXa01lcZDHDG6Www== +"@typescript-eslint/scope-manager@4.11.0": + version "4.11.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-4.11.0.tgz#2d906537db8a3a946721699e4fc0833810490254" + integrity sha512-6VSTm/4vC2dHM3ySDW9Kl48en+yLNfVV6LECU8jodBHQOhO8adAVizaZ1fV0QGZnLQjQ/y0aBj5/KXPp2hBTjA== dependencies: - "@typescript-eslint/types" "4.5.0" - "@typescript-eslint/visitor-keys" "4.5.0" + "@typescript-eslint/types" "4.11.0" + "@typescript-eslint/visitor-keys" "4.11.0" -"@typescript-eslint/types@4.5.0": - version "4.5.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-4.5.0.tgz#98256e07bad1c8d15d0c9627ebec82fd971bb3c3" - integrity sha512-n2uQoXnyWNk0Les9MtF0gCK3JiWd987JQi97dMSxBOzVoLZXCNtxFckVqt1h8xuI1ix01t+iMY4h4rFMj/303g== +"@typescript-eslint/types@4.11.0": + version "4.11.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-4.11.0.tgz#86cf95e7eac4ccfd183f9fcf1480cece7caf4ca4" + integrity sha512-XXOdt/NPX++txOQHM1kUMgJUS43KSlXGdR/aDyEwuAEETwuPt02Nc7v+s57PzuSqMbNLclblQdv3YcWOdXhQ7g== -"@typescript-eslint/typescript-estree@4.5.0", "@typescript-eslint/typescript-estree@^4.5.0": - version "4.5.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-4.5.0.tgz#d50cf91ae3a89878401111031eb6fb6d03554f64" - integrity sha512-gN1mffq3zwRAjlYWzb5DanarOPdajQwx5MEWkWCk0XvqC8JpafDTeioDoow2L4CA/RkYZu7xEsGZRhqrTsAG8w== +"@typescript-eslint/typescript-estree@4.11.0", "@typescript-eslint/typescript-estree@^4.11.0": + version "4.11.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-4.11.0.tgz#1144d145841e5987d61c4c845442a24b24165a4b" + integrity sha512-eA6sT5dE5RHAFhtcC+b5WDlUIGwnO9b0yrfGa1mIOIAjqwSQCpXbLiFmKTdRbQN/xH2EZkGqqLDrKUuYOZ0+Hg== dependencies: - "@typescript-eslint/types" "4.5.0" - "@typescript-eslint/visitor-keys" "4.5.0" + "@typescript-eslint/types" "4.11.0" + "@typescript-eslint/visitor-keys" "4.11.0" debug "^4.1.1" globby "^11.0.1" is-glob "^4.0.1" @@ -1454,12 +1573,12 @@ semver "^7.3.2" tsutils "^3.17.1" -"@typescript-eslint/visitor-keys@4.5.0": - version "4.5.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-4.5.0.tgz#b59f26213ac597efe87f6b13cf2aabee70542af0" - integrity sha512-UHq4FSa55NDZqscRU//O5ROFhHa9Hqn9KWTEvJGTArtTQp5GKv9Zqf6d/Q3YXXcFv4woyBml7fJQlQ+OuqRcHA== +"@typescript-eslint/visitor-keys@4.11.0": + version "4.11.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-4.11.0.tgz#906669a50f06aa744378bb84c7d5c4fdbc5b7d51" + integrity sha512-tRYKyY0i7cMk6v4UIOCjl1LhuepC/pc6adQqJk4Is3YcC6k46HvsV9Wl7vQoLbm9qADgeujiT7KdLrylvFIQ+A== dependencies: - "@typescript-eslint/types" "4.5.0" + "@typescript-eslint/types" "4.11.0" eslint-visitor-keys "^2.0.0" abab@^2.0.3: @@ -1475,7 +1594,7 @@ acorn-globals@^6.0.0: acorn "^7.1.1" acorn-walk "^7.1.1" -acorn-jsx@^5.2.0: +acorn-jsx@^5.2.0, acorn-jsx@^5.3.1: version "5.3.1" resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.1.tgz#fc8661e11b7ac1539c47dbfea2e72b3af34d267b" integrity sha512-K0Ptm/47OKfQRpNQ2J/oIN/3QYiK6FwW+eJbILhsdxh2WTLdl+30o8aGdTbm5JbffpFFAg/g+zi1E+jvJha5ng== @@ -1490,7 +1609,7 @@ acorn@^7.1.1, acorn@^7.4.0: resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.4.1.tgz#feaed255973d2e77555b83dbc08851a6c63520fa" integrity sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A== -ajv@^6.10.0, ajv@^6.10.2: +ajv@^6.10.0: version "6.11.0" resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.11.0.tgz#c3607cbc8ae392d8a5a536f25b21f8e5f3f87fe9" integrity sha512-nCprB/0syFYy9fVYU1ox1l2KN8S9I+tziH8D4zdZuLT3N6RMlGSGt5FSTpAiHB/Whv8Qs1cWHma1aMKZyaHRKA== @@ -1532,7 +1651,7 @@ ansi-regex@^5.0.0: resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.0.tgz#388539f55179bf39339c81af30a654d69f87cb75" integrity sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg== -ansi-styles@^3.2.0, ansi-styles@^3.2.1: +ansi-styles@^3.2.1: version "3.2.1" resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== @@ -1629,10 +1748,10 @@ assign-symbols@^1.0.0: resolved "https://registry.yarnpkg.com/assign-symbols/-/assign-symbols-1.0.0.tgz#59667f41fadd4f20ccbc2bb96b8d4f7f78ec0367" integrity sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c= -astral-regex@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-1.0.0.tgz#6c8c3fb827dd43ee3918f27b82782ab7658a6fd9" - integrity sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg== +astral-regex@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-2.0.0.tgz#483143c567aeed4785759c0865786dc77d7d2e31" + integrity sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ== async-each@^1.0.1: version "1.0.3" @@ -1671,16 +1790,16 @@ babel-eslint@^10.1.0: eslint-visitor-keys "^1.0.0" resolve "^1.12.0" -babel-jest@^26.6.0: - version "26.6.0" - resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-26.6.0.tgz#eca57ac8af99d6e06047e595b1faf0b5adf8a7bb" - integrity sha512-JI66yILI7stzjHccAoQtRKcUwJrJb4oMIxLTirL3GdAjGpaUBQSjZDFi9LsPkN4gftsS4R2AThAJwOjJxadwbg== +babel-jest@^26.6.3: + version "26.6.3" + resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-26.6.3.tgz#d87d25cb0037577a0c89f82e5755c5d293c01056" + integrity sha512-pl4Q+GAVOHwvjrck6jKjvmGhnO3jHX/xuB9d27f+EJZ/6k+6nMuPjorrYp7s++bKKdANwzElBWnLWaObvTnaZA== dependencies: - "@jest/transform" "^26.6.0" - "@jest/types" "^26.6.0" + "@jest/transform" "^26.6.2" + "@jest/types" "^26.6.2" "@types/babel__core" "^7.1.7" babel-plugin-istanbul "^6.0.0" - babel-preset-jest "^26.5.0" + babel-preset-jest "^26.6.2" chalk "^4.0.0" graceful-fs "^4.2.4" slash "^3.0.0" @@ -1703,20 +1822,20 @@ babel-plugin-istanbul@^6.0.0: istanbul-lib-instrument "^4.0.0" test-exclude "^6.0.0" -babel-plugin-jest-hoist@^26.5.0: - version "26.5.0" - resolved "https://registry.yarnpkg.com/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-26.5.0.tgz#3916b3a28129c29528de91e5784a44680db46385" - integrity sha512-ck17uZFD3CDfuwCLATWZxkkuGGFhMij8quP8CNhwj8ek1mqFgbFzRJ30xwC04LLscj/aKsVFfRST+b5PT7rSuw== +babel-plugin-jest-hoist@^26.6.2: + version "26.6.2" + resolved "https://registry.yarnpkg.com/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-26.6.2.tgz#8185bd030348d254c6d7dd974355e6a28b21e62d" + integrity sha512-PO9t0697lNTmcEHH69mdtYiOIkkOlj9fySqfO3K1eCcdISevLAE0xY59VLLUj0SoiPiTX/JU2CYFpILydUa5Lw== dependencies: "@babel/template" "^7.3.3" "@babel/types" "^7.3.3" "@types/babel__core" "^7.0.0" "@types/babel__traverse" "^7.0.6" -babel-preset-current-node-syntax@^0.1.3: - version "0.1.4" - resolved "https://registry.yarnpkg.com/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-0.1.4.tgz#826f1f8e7245ad534714ba001f84f7e906c3b615" - integrity sha512-5/INNCYhUGqw7VbVjT/hb3ucjgkVHKXY7lX3ZjlN4gm565VyFmJUrJ/h+h16ECVB38R/9SF6aACydpKMLZ/c9w== +babel-preset-current-node-syntax@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.0.1.tgz#b4399239b89b2a011f9ddbe3e4f401fc40cff73b" + integrity sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ== dependencies: "@babel/plugin-syntax-async-generators" "^7.8.4" "@babel/plugin-syntax-bigint" "^7.8.3" @@ -1729,14 +1848,15 @@ babel-preset-current-node-syntax@^0.1.3: "@babel/plugin-syntax-object-rest-spread" "^7.8.3" "@babel/plugin-syntax-optional-catch-binding" "^7.8.3" "@babel/plugin-syntax-optional-chaining" "^7.8.3" + "@babel/plugin-syntax-top-level-await" "^7.8.3" -babel-preset-jest@^26.5.0: - version "26.5.0" - resolved "https://registry.yarnpkg.com/babel-preset-jest/-/babel-preset-jest-26.5.0.tgz#f1b166045cd21437d1188d29f7fba470d5bdb0e7" - integrity sha512-F2vTluljhqkiGSJGBg/jOruA8vIIIL11YrxRcO7nviNTMbbofPSHwnm8mgP7d/wS7wRSexRoI6X1A6T74d4LQA== +babel-preset-jest@^26.6.2: + version "26.6.2" + resolved "https://registry.yarnpkg.com/babel-preset-jest/-/babel-preset-jest-26.6.2.tgz#747872b1171df032252426586881d62d31798fee" + integrity sha512-YvdtlVm9t3k777c5NPQIv6cxFFFapys25HiUmuSgHwIZhfifweR5c5Sf5nwE3MAbfu327CYSvps8Yx6ANLyleQ== dependencies: - babel-plugin-jest-hoist "^26.5.0" - babel-preset-current-node-syntax "^0.1.3" + babel-plugin-jest-hoist "^26.6.2" + babel-preset-current-node-syntax "^1.0.0" balanced-match@^1.0.0: version "1.0.0" @@ -1773,13 +1893,6 @@ binary-extensions@^2.0.0: resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.1.0.tgz#30fa40c9e7fe07dbc895678cd287024dea241dd9" integrity sha512-1Yj8h9Q+QDF5FzhMs/c9+6UntbD5MkRfRwac8DoEm9ZfUBZ7tZ55YcGVAzEe4bXsdQHEk+s9S5wsOKVdZrw0tQ== -bindings@^1.5.0: - version "1.5.0" - resolved "https://registry.yarnpkg.com/bindings/-/bindings-1.5.0.tgz#10353c9e945334bc0511a6d90b38fbc7c9c504df" - integrity sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ== - dependencies: - file-uri-to-path "1.0.0" - brace-expansion@^1.1.7: version "1.1.11" resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" @@ -1816,24 +1929,16 @@ browser-process-hrtime@^1.0.0: resolved "https://registry.yarnpkg.com/browser-process-hrtime/-/browser-process-hrtime-1.0.0.tgz#3c9b4b7d782c8121e56f10106d84c0d0ffc94626" integrity sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow== -browserslist@^4.12.0: - version "4.14.5" - resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.14.5.tgz#1c751461a102ddc60e40993639b709be7f2c4015" - integrity sha512-Z+vsCZIvCBvqLoYkBFTwEYH3v5MCQbsAjp50ERycpOjnPmolg1Gjy4+KaWWpm8QOJt9GHkhdqAl14NpCX73CWA== - dependencies: - caniuse-lite "^1.0.30001135" - electron-to-chromium "^1.3.571" - escalade "^3.1.0" - node-releases "^1.1.61" - -browserslist@^4.8.3: - version "4.8.6" - resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.8.6.tgz#96406f3f5f0755d272e27a66f4163ca821590a7e" - integrity sha512-ZHao85gf0eZ0ESxLfCp73GG9O/VTytYDIkIiZDlURppLTI9wErSM/5yAKEq6rcUdxBLjMELmrYUJGg5sxGKMHg== +browserslist@^4.14.5, browserslist@^4.15.0: + version "4.16.0" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.16.0.tgz#410277627500be3cb28a1bfe037586fbedf9488b" + integrity sha512-/j6k8R0p3nxOC6kx5JGAxsnhc9ixaWJfYc+TNTzxg6+ARaESAvQGV7h0uNOB4t+pLQJZWzcrMxXOxjgsCj3dqQ== dependencies: - caniuse-lite "^1.0.30001023" - electron-to-chromium "^1.3.341" - node-releases "^1.1.47" + caniuse-lite "^1.0.30001165" + colorette "^1.2.1" + electron-to-chromium "^1.3.621" + escalade "^3.1.1" + node-releases "^1.1.67" bser@2.1.1: version "2.1.1" @@ -1877,15 +1982,10 @@ camelcase@^6.0.0: resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.1.0.tgz#27dc176173725fb0adf8a48b647f4d7871944d78" integrity sha512-WCMml9ivU60+8rEJgELlFp1gxFcEGxwYleE3bziHEDeqsqAWGHdimB7beBFGjLzVNgPGyDsfgXLQEYMpmIFnVQ== -caniuse-lite@^1.0.30001023: - version "1.0.30001023" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001023.tgz#b82155827f3f5009077bdd2df3d8968bcbcc6fc4" - integrity sha512-C5TDMiYG11EOhVOA62W1p3UsJ2z4DsHtMBQtjzp3ZsUglcQn62WOUgW0y795c7A5uZ+GCEIvzkMatLIlAsbNTA== - -caniuse-lite@^1.0.30001135: - version "1.0.30001148" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001148.tgz#dc97c7ed918ab33bf8706ddd5e387287e015d637" - integrity sha512-E66qcd0KMKZHNJQt9hiLZGE3J4zuTqE1OnU53miEVtylFbwOEmeA5OsRu90noZful+XGSQOni1aT2tiqu/9yYw== +caniuse-lite@^1.0.30001165: + version "1.0.30001170" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001170.tgz#0088bfecc6a14694969e391cc29d7eb6362ca6a7" + integrity sha512-Dd4d/+0tsK0UNLrZs3CvNukqalnVTRrxb5mcQm8rHL49t7V5ZaTygwXkrq+FB+dVDf++4ri8eJnFEJAB8332PA== capture-exit@^2.0.0: version "2.0.0" @@ -1908,14 +2008,6 @@ chalk@^2.0.0: escape-string-regexp "^1.0.5" supports-color "^5.3.0" -chalk@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-3.0.0.tgz#3f73c2bf526591f574cc492c51e2456349f844e4" - integrity sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg== - dependencies: - ansi-styles "^4.1.0" - supports-color "^7.1.0" - chalk@^4.0.0, chalk@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.0.tgz#4e14870a618d9e2edd97dd8345fd9d9dc315646a" @@ -1929,25 +2021,6 @@ char-regex@^1.0.2: resolved "https://registry.yarnpkg.com/char-regex/-/char-regex-1.0.2.tgz#d744358226217f981ed58f479b1d6bcc29545dcf" integrity sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw== -chokidar@2.1.8: - version "2.1.8" - resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-2.1.8.tgz#804b3a7b6a99358c3c5c61e71d8728f041cff917" - integrity sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg== - dependencies: - anymatch "^2.0.0" - async-each "^1.0.1" - braces "^2.3.2" - glob-parent "^3.1.0" - inherits "^2.0.3" - is-binary-path "^1.0.0" - is-glob "^4.0.0" - normalize-path "^3.0.0" - path-is-absolute "^1.0.0" - readdirp "^2.2.1" - upath "^1.1.1" - optionalDependencies: - fsevents "^1.2.7" - chokidar@^3.4.0: version "3.4.3" resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.4.3.tgz#c1df38231448e45ca4ac588e6c79573ba6a57d5b" @@ -1968,6 +2041,11 @@ ci-info@^2.0.0: resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-2.0.0.tgz#67a9e964be31a51e15e5010d58e6f12834002f46" integrity sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ== +cjs-module-lexer@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/cjs-module-lexer/-/cjs-module-lexer-0.6.0.tgz#4186fcca0eae175970aee870b9fe2d6cf8d5655f" + integrity sha512-uc2Vix1frTfnuzxxu1Hp4ktSvM3QaI4oXl4ZUqL1wjTu/BGki9TrCWoqLTg/drR1KwAEarXuRFCG2Svr1GxPFw== + class-utils@^0.3.5: version "0.3.6" resolved "https://registry.yarnpkg.com/class-utils/-/class-utils-0.3.6.tgz#f93369ae8b9a7ce02fd41faad0ca83033190c463" @@ -2029,6 +2107,11 @@ color-name@~1.1.4: resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== +colorette@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/colorette/-/colorette-1.2.1.tgz#4d0b921325c14faf92633086a536db6e89564b1b" + integrity sha512-puCDz0CzydiSYOrnXpz/PKd69zRrribezjtE9yd4zvytoRc8+RY/KJPvtPFKZS3E3wP6neGyMe0vOTlHO5L3Pw== + combined-stream@^1.0.6, combined-stream@~1.0.6: version "1.0.8" resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" @@ -2073,12 +2156,12 @@ copy-descriptor@^0.1.0: resolved "https://registry.yarnpkg.com/copy-descriptor/-/copy-descriptor-0.1.1.tgz#676f6eb3c39997c2ee1ac3a924fd6124748f578d" integrity sha1-Z29us8OZl8LuGsOpJP1hJHSPV40= -core-js-compat@^3.6.2: - version "3.6.4" - resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.6.4.tgz#938476569ebb6cda80d339bcf199fae4f16fff17" - integrity sha512-zAa3IZPvsJ0slViBQ2z+vgyyTuhd3MFn1rBQjZSKVEgB0UMYhUkCj9jJUVPgGTGqWvsBVmfnruXgTcNyTlEiSA== +core-js-compat@^3.8.0: + version "3.8.1" + resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.8.1.tgz#8d1ddd341d660ba6194cbe0ce60f4c794c87a36e" + integrity sha512-a16TLmy9NVD1rkjUGbwuyWkiDoN0FDpAwrfLONvHFQx0D9k7J9y0srwMT8QP/Z6HE3MIFaVynEeYwZwPX1o5RQ== dependencies: - browserslist "^4.8.3" + browserslist "^4.15.0" semver "7.0.0" core-js@^3.2.1: @@ -2231,15 +2314,10 @@ detect-newline@^3.0.0: resolved "https://registry.yarnpkg.com/detect-newline/-/detect-newline-3.1.0.tgz#576f5dfc63ae1a192ff192d8ad3af6308991b651" integrity sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA== -diff-sequences@^25.2.6: - version "25.2.6" - resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-25.2.6.tgz#5f467c00edd35352b7bca46d7927d60e687a76dd" - integrity sha512-Hq8o7+6GaZeoFjtpgvRBUknSXNeJiCx7V9Fr94ZMljNiCr9n9L8H8aJqgWOQiDDGdyn29fRNcDdRVJ5fdyihfg== - -diff-sequences@^26.5.0: - version "26.5.0" - resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-26.5.0.tgz#ef766cf09d43ed40406611f11c6d8d9dd8b2fefd" - integrity sha512-ZXx86srb/iYy6jG71k++wBN9P9J05UNQ5hQHQd9MtMPvcqXPx/vKU69jfHV637D00Q2gSgPk2D+jSx3l1lDW/Q== +diff-sequences@^26.6.2: + version "26.6.2" + resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-26.6.2.tgz#48ba99157de1923412eed41db6b6d4aa9ca7c0b1" + integrity sha512-Mv/TDa3nZ9sbc5soK+OoA74BsS3mL37yixCvUAQkiuA4Wz6YtwP/K47n2rv2ovzHZvoiQeA5FTQOschKkEwB0Q== dir-glob@^3.0.1: version "3.0.1" @@ -2278,26 +2356,16 @@ ecc-jsbn@~0.1.1: jsbn "~0.1.0" safer-buffer "^2.1.0" -electron-to-chromium@^1.3.341: - version "1.3.344" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.344.tgz#f1397a633c35e726730c24be1084cd25c3ee8148" - integrity sha512-tvbx2Wl8WBR+ym3u492D0L6/jH+8NoQXqe46+QhbWH3voVPauGuZYeb1QAXYoOAWuiP2dbSvlBx0kQ1F3hu/Mw== - -electron-to-chromium@^1.3.571: - version "1.3.582" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.582.tgz#1adfac5affce84d85b3d7b3dfbc4ade293a6ffc4" - integrity sha512-0nCJ7cSqnkMC+kUuPs0YgklFHraWGl/xHqtZWWtOeVtyi+YqkoAOMGuZQad43DscXCQI/yizcTa3u6B5r+BLww== +electron-to-chromium@^1.3.621: + version "1.3.632" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.632.tgz#3b1d89fe5065dd6a65a1dafc25bbe6f218ca9326" + integrity sha512-LkaEH9HHr9fodmm3txF4nFMyHN3Yr50HcpD/DBHpLCxzM9doV8AV0er6aBWva4IDs2aA9kGguces0rp+WKL7rg== emittery@^0.7.1: version "0.7.2" resolved "https://registry.yarnpkg.com/emittery/-/emittery-0.7.2.tgz#25595908e13af0f5674ab419396e2fb394cdfa82" integrity sha512-A8OG5SR/ij3SsJdWDJdkkSYUjQdCUx6APQXem0SaEePBSRg4eymGYwBkKo1Y6DU+af/Jn2dBQqDBvjnr9Vi8nQ== -emoji-regex@^7.0.1: - version "7.0.3" - resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-7.0.3.tgz#933a04052860c85e83c122479c4748a8e4c72156" - integrity sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA== - emoji-regex@^8.0.0: version "8.0.0" resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" @@ -2350,7 +2418,7 @@ es-to-primitive@^1.2.1: is-date-object "^1.0.1" is-symbol "^1.0.2" -escalade@^3.1.0: +escalade@^3.1.1: version "3.1.1" resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40" integrity sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw== @@ -2377,6 +2445,11 @@ escodegen@^1.14.1: optionalDependencies: source-map "~0.6.1" +eslint-config-prettier@^7.1.0: + version "7.1.0" + resolved "https://registry.yarnpkg.com/eslint-config-prettier/-/eslint-config-prettier-7.1.0.tgz#5402eb559aa94b894effd6bddfa0b1ca051c858f" + integrity sha512-9sm5/PxaFG7qNJvJzTROMM1Bk1ozXVTKI0buKOyb0Bsr1hrwi0H/TzxF/COtf1uxikIK8SwhX7K6zg78jAzbeA== + eslint-import-resolver-node@^0.3.4: version "0.3.4" resolved "https://registry.yarnpkg.com/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.4.tgz#85ffa81942c25012d8231096ddf679c03042c717" @@ -2412,7 +2485,14 @@ eslint-plugin-import@^2.22.1: resolve "^1.17.0" tsconfig-paths "^3.9.0" -eslint-scope@^5.1.1: +eslint-plugin-jest@^24.1.3: + version "24.1.3" + resolved "https://registry.yarnpkg.com/eslint-plugin-jest/-/eslint-plugin-jest-24.1.3.tgz#fa3db864f06c5623ff43485ca6c0e8fc5fe8ba0c" + integrity sha512-dNGGjzuEzCE3d5EPZQ/QGtmlMotqnYWD/QpCZ1UuZlrMAdhG5rldh0N0haCvhGnUkSeuORS5VNROwF9Hrgn3Lg== + dependencies: + "@typescript-eslint/experimental-utils" "^4.0.1" + +eslint-scope@^5.0.0, eslint-scope@^5.1.1: version "5.1.1" resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-5.1.1.tgz#e786e59a66cb92b3f6c1fb0d508aab174848f48c" integrity sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw== @@ -2420,7 +2500,7 @@ eslint-scope@^5.1.1: esrecurse "^4.3.0" estraverse "^4.1.1" -eslint-utils@^2.1.0: +eslint-utils@^2.0.0, eslint-utils@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-2.1.0.tgz#d2de5e03424e707dc10c74068ddedae708741b27" integrity sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg== @@ -2442,13 +2522,13 @@ eslint-visitor-keys@^2.0.0: resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-2.0.0.tgz#21fdc8fbcd9c795cc0321f0563702095751511a8" integrity sha512-QudtT6av5WXels9WjIM7qz1XD1cWGvX4gGXvp/zBn9nXG02D0utdU3Em2m/QjTnrsk6bBjmCygl3rmj118msQQ== -eslint@^7.11.0: - version "7.11.0" - resolved "https://registry.yarnpkg.com/eslint/-/eslint-7.11.0.tgz#aaf2d23a0b5f1d652a08edacea0c19f7fadc0b3b" - integrity sha512-G9+qtYVCHaDi1ZuWzBsOWo2wSwd70TXnU6UHA3cTYHp7gCTXZcpggWFoUVAMRarg68qtPoNfFbzPh+VdOgmwmw== +eslint@^7.16.0: + version "7.16.0" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-7.16.0.tgz#a761605bf9a7b32d24bb7cde59aeb0fd76f06092" + integrity sha512-iVWPS785RuDA4dWuhhgXTNrGxHHK3a8HLSMBgbbU59ruJDubUraXN8N5rn7kb8tG6sjg74eE0RA3YWT51eusEw== dependencies: "@babel/code-frame" "^7.0.0" - "@eslint/eslintrc" "^0.1.3" + "@eslint/eslintrc" "^0.2.2" ajv "^6.10.0" chalk "^4.0.0" cross-spawn "^7.0.2" @@ -2458,10 +2538,10 @@ eslint@^7.11.0: eslint-scope "^5.1.1" eslint-utils "^2.1.0" eslint-visitor-keys "^2.0.0" - espree "^7.3.0" + espree "^7.3.1" esquery "^1.2.0" esutils "^2.0.2" - file-entry-cache "^5.0.1" + file-entry-cache "^6.0.0" functional-red-black-tree "^1.0.1" glob-parent "^5.0.0" globals "^12.1.0" @@ -2481,7 +2561,7 @@ eslint@^7.11.0: semver "^7.2.1" strip-ansi "^6.0.0" strip-json-comments "^3.1.0" - table "^5.2.3" + table "^6.0.4" text-table "^0.2.0" v8-compile-cache "^2.0.3" @@ -2494,6 +2574,15 @@ espree@^7.3.0: acorn-jsx "^5.2.0" eslint-visitor-keys "^1.3.0" +espree@^7.3.1: + version "7.3.1" + resolved "https://registry.yarnpkg.com/espree/-/espree-7.3.1.tgz#f2df330b752c6f55019f8bd89b7660039c1bbbb6" + integrity sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g== + dependencies: + acorn "^7.4.0" + acorn-jsx "^5.3.1" + eslint-visitor-keys "^1.3.0" + esprima@^4.0.0, esprima@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" @@ -2579,16 +2668,16 @@ expand-brackets@^2.1.4: snapdragon "^0.8.1" to-regex "^3.0.1" -expect@^26.6.0: - version "26.6.0" - resolved "https://registry.yarnpkg.com/expect/-/expect-26.6.0.tgz#f48861317f62bb9f1248eaab7ae9e50a9a5a8339" - integrity sha512-EzhbZ1tbwcaa5Ok39BI11flIMeIUSlg1QsnXOrleaMvltwHsvIQPBtL710l+ma+qDFLUgktCXK4YuQzmHdm7cg== +expect@^26.6.2: + version "26.6.2" + resolved "https://registry.yarnpkg.com/expect/-/expect-26.6.2.tgz#c6b996bf26bf3fe18b67b2d0f51fc981ba934417" + integrity sha512-9/hlOBkQl2l/PLHJx6JjoDF6xPKcJEsUlWKb23rKE7KzeDqUZKXKNMW27KIue5JMdBV9HgmoJPcc8HtO85t9IA== dependencies: - "@jest/types" "^26.6.0" + "@jest/types" "^26.6.2" ansi-styles "^4.0.0" jest-get-type "^26.3.0" - jest-matcher-utils "^26.6.0" - jest-message-util "^26.6.0" + jest-matcher-utils "^26.6.2" + jest-message-util "^26.6.2" jest-regex-util "^26.0.0" extend-shallow@^2.0.1: @@ -2676,17 +2765,12 @@ fb-watchman@^2.0.0: dependencies: bser "2.1.1" -file-entry-cache@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-5.0.1.tgz#ca0f6efa6dd3d561333fb14515065c2fafdf439c" - integrity sha512-bCg29ictuBaKUwwArK4ouCaqDgLZcysCFLmM/Yn/FDoqndh/9vNuQfXRDvTuXKLxfD/JtZQGKFT8MGcJBK644g== +file-entry-cache@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-6.0.0.tgz#7921a89c391c6d93efec2169ac6bf300c527ea0a" + integrity sha512-fqoO76jZ3ZnYrXLDRxBR1YvOvc0k844kcOg40bgsPrE25LAb/PDqTY+ho64Xh2c8ZXgIKldchCFHczG2UVRcWA== dependencies: - flat-cache "^2.0.1" - -file-uri-to-path@1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz#553a7b8446ff6f684359c445f1e37a05dacc33dd" - integrity sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw== + flat-cache "^3.0.4" fill-range@^4.0.0: version "4.0.0" @@ -2736,19 +2820,18 @@ find-up@^4.0.0, find-up@^4.1.0: locate-path "^5.0.0" path-exists "^4.0.0" -flat-cache@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-2.0.1.tgz#5d296d6f04bda44a4630a301413bdbc2ec085ec0" - integrity sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA== +flat-cache@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-3.0.4.tgz#61b0338302b2fe9f957dcc32fc2a87f1c3048b11" + integrity sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg== dependencies: - flatted "^2.0.0" - rimraf "2.6.3" - write "1.0.3" + flatted "^3.1.0" + rimraf "^3.0.2" -flatted@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/flatted/-/flatted-2.0.1.tgz#69e57caa8f0eacbc281d2e2cb458d46fdb449e08" - integrity sha512-a1hQMktqW9Nmqr5aktAux3JMNqaucxGcjtjWnZLHX7yyPCmlSV3M54nGYbqT8K+0GhF3NBgmJCc3ma+WOgX8Jg== +flatted@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.1.0.tgz#a5d06b4a8b01e3a63771daa5cb7a1903e2e57067" + integrity sha512-tW+UkmtNg/jv9CSofAKvgVcO7c2URjhTdW1ZTkcAritblu8tajiYy7YisnIflEwtKssCtOxpnBRoCB7iap0/TA== for-in@^1.0.2: version "1.0.2" @@ -2786,14 +2869,6 @@ fs.realpath@^1.0.0: resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= -fsevents@^1.2.7: - version "1.2.11" - resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-1.2.11.tgz#67bf57f4758f02ede88fb2a1712fef4d15358be3" - integrity sha512-+ux3lx6peh0BpvY0JebGyZoiR4D+oYzdPZMKJwkZ+sFkNJzpL7tXc/wehS49gUAxg3tmMHPHZkA8JU2rhhgDHw== - dependencies: - bindings "^1.5.0" - nan "^2.12.1" - fsevents@^2.1.2: version "2.1.2" resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.1.2.tgz#4c0a1fb34bc68e543b4b82a9ec392bfbda840805" @@ -3140,6 +3215,13 @@ is-core-module@^2.0.0: dependencies: has "^1.0.3" +is-core-module@^2.1.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.2.0.tgz#97037ef3d52224d85163f5597b2b63d9afed981a" + integrity sha512-XRAfAdyyY5F5cOXn7hYQDqh2Xmii+DEfIcQGxK/uNwMHhIkPWO0g8msXcbzLe+MpGoR951MlqM/2iIlU4vKDdQ== + dependencies: + has "^1.0.3" + is-data-descriptor@^0.1.4: version "0.1.4" resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz#0b5ee648388e2c860282e793f1856fec3f301b56" @@ -3199,11 +3281,6 @@ is-extglob@^2.1.0, is-extglob@^2.1.1: resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" integrity sha1-qIwCU1eR8C7TfHahueqXc8gz+MI= -is-fullwidth-code-point@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f" - integrity sha1-o7MKXE8ZkYMWeqq5O+764937ZU8= - is-fullwidth-code-point@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d" @@ -3379,77 +3456,67 @@ istanbul-reports@^3.0.2: html-escaper "^2.0.0" istanbul-lib-report "^3.0.0" -jest-changed-files@^26.6.0: - version "26.6.0" - resolved "https://registry.yarnpkg.com/jest-changed-files/-/jest-changed-files-26.6.0.tgz#63b04aa261b5733c6ade96b7dd24784d12d8bb2d" - integrity sha512-k8PZzlp3cRWDe0fDc/pYs+c4w36+hiWXe1PpW/pW1UJmu1TNTAcQfZUrVYleij+uEqlY6z4mPv7Iff3kY0o5SQ== +jest-changed-files@^26.6.2: + version "26.6.2" + resolved "https://registry.yarnpkg.com/jest-changed-files/-/jest-changed-files-26.6.2.tgz#f6198479e1cc66f22f9ae1e22acaa0b429c042d0" + integrity sha512-fDS7szLcY9sCtIip8Fjry9oGf3I2ht/QT21bAHm5Dmf0mD4X3ReNUf17y+bO6fR8WgbIZTlbyG1ak/53cbRzKQ== dependencies: - "@jest/types" "^26.6.0" + "@jest/types" "^26.6.2" execa "^4.0.0" throat "^5.0.0" -jest-cli@^26.6.0: - version "26.6.0" - resolved "https://registry.yarnpkg.com/jest-cli/-/jest-cli-26.6.0.tgz#dc3ae34fd5937310493ed07dc79c5ffba2bf6671" - integrity sha512-lJAMZGpmML+y3Kfln6L5DGRTfKGQ+n1JDM1RQstojSLUhe/EaXWR8vmcx70v4CyJKvFZs7c/0QDkPX5ra/aDew== +jest-cli@^26.6.3: + version "26.6.3" + resolved "https://registry.yarnpkg.com/jest-cli/-/jest-cli-26.6.3.tgz#43117cfef24bc4cd691a174a8796a532e135e92a" + integrity sha512-GF9noBSa9t08pSyl3CY4frMrqp+aQXFGFkf5hEPbh/pIUFYWMK6ZLTfbmadxJVcJrdRoChlWQsA2VkJcDFK8hg== dependencies: - "@jest/core" "^26.6.0" - "@jest/test-result" "^26.6.0" - "@jest/types" "^26.6.0" + "@jest/core" "^26.6.3" + "@jest/test-result" "^26.6.2" + "@jest/types" "^26.6.2" chalk "^4.0.0" exit "^0.1.2" graceful-fs "^4.2.4" import-local "^3.0.2" is-ci "^2.0.0" - jest-config "^26.6.0" - jest-util "^26.6.0" - jest-validate "^26.6.0" + jest-config "^26.6.3" + jest-util "^26.6.2" + jest-validate "^26.6.2" prompts "^2.0.1" yargs "^15.4.1" -jest-config@^26.6.0: - version "26.6.0" - resolved "https://registry.yarnpkg.com/jest-config/-/jest-config-26.6.0.tgz#cb879a37002f881edb66d673fd40b6704595de89" - integrity sha512-RCR1Kf7MGJ5waVCvrj/k3nCAJKquWZlzs8rkskzj0KlG392hNBOaYd5FQ4cCac08j6pwfIDOwNvMcy0/FqguJg== +jest-config@^26.6.3: + version "26.6.3" + resolved "https://registry.yarnpkg.com/jest-config/-/jest-config-26.6.3.tgz#64f41444eef9eb03dc51d5c53b75c8c71f645349" + integrity sha512-t5qdIj/bCj2j7NFVHb2nFB4aUdfucDn3JRKgrZnplb8nieAirAzRSHP8uDEd+qV6ygzg9Pz4YG7UTJf94LPSyg== dependencies: "@babel/core" "^7.1.0" - "@jest/test-sequencer" "^26.6.0" - "@jest/types" "^26.6.0" - babel-jest "^26.6.0" + "@jest/test-sequencer" "^26.6.3" + "@jest/types" "^26.6.2" + babel-jest "^26.6.3" chalk "^4.0.0" deepmerge "^4.2.2" glob "^7.1.1" graceful-fs "^4.2.4" - jest-environment-jsdom "^26.6.0" - jest-environment-node "^26.6.0" + jest-environment-jsdom "^26.6.2" + jest-environment-node "^26.6.2" jest-get-type "^26.3.0" - jest-jasmine2 "^26.6.0" + jest-jasmine2 "^26.6.3" jest-regex-util "^26.0.0" - jest-resolve "^26.6.0" - jest-util "^26.6.0" - jest-validate "^26.6.0" + jest-resolve "^26.6.2" + jest-util "^26.6.2" + jest-validate "^26.6.2" micromatch "^4.0.2" - pretty-format "^26.6.0" + pretty-format "^26.6.2" -jest-diff@^25.2.1: - version "25.5.0" - resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-25.5.0.tgz#1dd26ed64f96667c068cef026b677dfa01afcfa9" - integrity sha512-z1kygetuPiREYdNIumRpAHY6RXiGmp70YHptjdaxTWGmA085W3iCnXNx0DhflK3vwrKmrRWyY1wUpkPMVxMK7A== - dependencies: - chalk "^3.0.0" - diff-sequences "^25.2.6" - jest-get-type "^25.2.6" - pretty-format "^25.5.0" - -jest-diff@^26.6.0: - version "26.6.0" - resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-26.6.0.tgz#5e5bbbaf93ec5017fae2b3ef12fc895e29988379" - integrity sha512-IH09rKsdWY8YEY7ii2BHlSq59oXyF2pK3GoK+hOK9eD/x6009eNB5Jv1shLMKgxekodPzLlV7eZP1jPFQYds8w== +jest-diff@^26.0.0, jest-diff@^26.6.2: + version "26.6.2" + resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-26.6.2.tgz#1aa7468b52c3a68d7d5c5fdcdfcd5e49bd164394" + integrity sha512-6m+9Z3Gv9wN0WFVasqjCL/06+EFCMTqDEUl/b87HYK2rAPTyfz4ZIuSlPhY51PIQRWx5TaxeF1qmXKe9gfN3sA== dependencies: chalk "^4.0.0" - diff-sequences "^26.5.0" + diff-sequences "^26.6.2" jest-get-type "^26.3.0" - pretty-format "^26.6.0" + pretty-format "^26.6.2" jest-docblock@^26.0.0: version "26.0.0" @@ -3458,95 +3525,90 @@ jest-docblock@^26.0.0: dependencies: detect-newline "^3.0.0" -jest-each@^26.6.0: - version "26.6.0" - resolved "https://registry.yarnpkg.com/jest-each/-/jest-each-26.6.0.tgz#9e9d90a4fc5a79e1d99a008897038325a6c7fbbf" - integrity sha512-7LzSNwNviYnm4FWK46itIE03NqD/8O8/7tVQ5rwTdTNrmPMQoQ1Z7hEFQ1uzRReluOFislpurpnQ0QsclSiDkA== +jest-each@^26.6.2: + version "26.6.2" + resolved "https://registry.yarnpkg.com/jest-each/-/jest-each-26.6.2.tgz#02526438a77a67401c8a6382dfe5999952c167cb" + integrity sha512-Mer/f0KaATbjl8MCJ+0GEpNdqmnVmDYqCTJYTvoo7rqmRiDllmp2AYN+06F93nXcY3ur9ShIjS+CO/uD+BbH4A== dependencies: - "@jest/types" "^26.6.0" + "@jest/types" "^26.6.2" chalk "^4.0.0" jest-get-type "^26.3.0" - jest-util "^26.6.0" - pretty-format "^26.6.0" + jest-util "^26.6.2" + pretty-format "^26.6.2" -jest-environment-jsdom@^26.6.0: - version "26.6.0" - resolved "https://registry.yarnpkg.com/jest-environment-jsdom/-/jest-environment-jsdom-26.6.0.tgz#2ce353fb82d27a9066bfea3ff2c27d9405076c69" - integrity sha512-bXO9IG7a3YlyiHxwfKF+OWoTA+GIw4FrD+Y0pb6CC+nKs5JuSRZmR2ovEX6PWo6KY42ka3JoZOp3KEnXiFPPCg== +jest-environment-jsdom@^26.6.2: + version "26.6.2" + resolved "https://registry.yarnpkg.com/jest-environment-jsdom/-/jest-environment-jsdom-26.6.2.tgz#78d09fe9cf019a357009b9b7e1f101d23bd1da3e" + integrity sha512-jgPqCruTlt3Kwqg5/WVFyHIOJHsiAvhcp2qiR2QQstuG9yWox5+iHpU3ZrcBxW14T4fe5Z68jAfLRh7joCSP2Q== dependencies: - "@jest/environment" "^26.6.0" - "@jest/fake-timers" "^26.6.0" - "@jest/types" "^26.6.0" + "@jest/environment" "^26.6.2" + "@jest/fake-timers" "^26.6.2" + "@jest/types" "^26.6.2" "@types/node" "*" - jest-mock "^26.6.0" - jest-util "^26.6.0" + jest-mock "^26.6.2" + jest-util "^26.6.2" jsdom "^16.4.0" -jest-environment-node@^26.6.0: - version "26.6.0" - resolved "https://registry.yarnpkg.com/jest-environment-node/-/jest-environment-node-26.6.0.tgz#97f6e48085e67bda43b97f48e678ce78d760cd14" - integrity sha512-kWU6ZD1h6fs7sIl6ufuK0sXW/3d6WLaj48iow0NxhgU6eY89d9K+0MVmE0cRcVlh53yMyxTK6b+TnhLOnlGp/A== +jest-environment-node@^26.6.2: + version "26.6.2" + resolved "https://registry.yarnpkg.com/jest-environment-node/-/jest-environment-node-26.6.2.tgz#824e4c7fb4944646356f11ac75b229b0035f2b0c" + integrity sha512-zhtMio3Exty18dy8ee8eJ9kjnRyZC1N4C1Nt/VShN1apyXc8rWGtJ9lI7vqiWcyyXS4BVSEn9lxAM2D+07/Tag== dependencies: - "@jest/environment" "^26.6.0" - "@jest/fake-timers" "^26.6.0" - "@jest/types" "^26.6.0" + "@jest/environment" "^26.6.2" + "@jest/fake-timers" "^26.6.2" + "@jest/types" "^26.6.2" "@types/node" "*" - jest-mock "^26.6.0" - jest-util "^26.6.0" - -jest-get-type@^25.2.6: - version "25.2.6" - resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-25.2.6.tgz#0b0a32fab8908b44d508be81681487dbabb8d877" - integrity sha512-DxjtyzOHjObRM+sM1knti6or+eOgcGU4xVSb2HNP1TqO4ahsT+rqZg+nyqHWJSvWgKC5cG3QjGFBqxLghiF/Ig== + jest-mock "^26.6.2" + jest-util "^26.6.2" jest-get-type@^26.3.0: version "26.3.0" resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-26.3.0.tgz#e97dc3c3f53c2b406ca7afaed4493b1d099199e0" integrity sha512-TpfaviN1R2pQWkIihlfEanwOXK0zcxrKEE4MlU6Tn7keoXdN6/3gK/xl0yEh8DOunn5pOVGKf8hB4R9gVh04ig== -jest-haste-map@^26.6.0: - version "26.6.0" - resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-26.6.0.tgz#4cd392bc51109bd8e0f765b2d5afa746bebb5ce2" - integrity sha512-RpNqAGMR58uG9E9vWITorX2/R7he/tSbHWldX5upt1ymEcmCaXczqXxjqI6xOtRR8Ev6ZEYDfgSA5Fy7WHUL5w== +jest-haste-map@^26.6.2: + version "26.6.2" + resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-26.6.2.tgz#dd7e60fe7dc0e9f911a23d79c5ff7fb5c2cafeaa" + integrity sha512-easWIJXIw71B2RdR8kgqpjQrbMRWQBgiBwXYEhtGUTaX+doCjBheluShdDMeR8IMfJiTqH4+zfhtg29apJf/8w== dependencies: - "@jest/types" "^26.6.0" + "@jest/types" "^26.6.2" "@types/graceful-fs" "^4.1.2" "@types/node" "*" anymatch "^3.0.3" fb-watchman "^2.0.0" graceful-fs "^4.2.4" jest-regex-util "^26.0.0" - jest-serializer "^26.5.0" - jest-util "^26.6.0" - jest-worker "^26.5.0" + jest-serializer "^26.6.2" + jest-util "^26.6.2" + jest-worker "^26.6.2" micromatch "^4.0.2" sane "^4.0.3" walker "^1.0.7" optionalDependencies: fsevents "^2.1.2" -jest-jasmine2@^26.6.0: - version "26.6.0" - resolved "https://registry.yarnpkg.com/jest-jasmine2/-/jest-jasmine2-26.6.0.tgz#1b59e26aa56651bae3d4637965c8cd4d3851de6d" - integrity sha512-2E3c+0A9y2OIK5caw5qlcm3b4doaf8FSfXKTX3xqKTUJoR4zXh0xvERBNWxZP9xMNXEi/2Z3LVsZpR2hROgixA== +jest-jasmine2@^26.6.3: + version "26.6.3" + resolved "https://registry.yarnpkg.com/jest-jasmine2/-/jest-jasmine2-26.6.3.tgz#adc3cf915deacb5212c93b9f3547cd12958f2edd" + integrity sha512-kPKUrQtc8aYwBV7CqBg5pu+tmYXlvFlSFYn18ev4gPFtrRzB15N2gW/Roew3187q2w2eHuu0MU9TJz6w0/nPEg== dependencies: "@babel/traverse" "^7.1.0" - "@jest/environment" "^26.6.0" - "@jest/source-map" "^26.5.0" - "@jest/test-result" "^26.6.0" - "@jest/types" "^26.6.0" + "@jest/environment" "^26.6.2" + "@jest/source-map" "^26.6.2" + "@jest/test-result" "^26.6.2" + "@jest/types" "^26.6.2" "@types/node" "*" chalk "^4.0.0" co "^4.6.0" - expect "^26.6.0" + expect "^26.6.2" is-generator-fn "^2.0.0" - jest-each "^26.6.0" - jest-matcher-utils "^26.6.0" - jest-message-util "^26.6.0" - jest-runtime "^26.6.0" - jest-snapshot "^26.6.0" - jest-util "^26.6.0" - pretty-format "^26.6.0" + jest-each "^26.6.2" + jest-matcher-utils "^26.6.2" + jest-message-util "^26.6.2" + jest-runtime "^26.6.3" + jest-snapshot "^26.6.2" + jest-util "^26.6.2" + pretty-format "^26.6.2" throat "^5.0.0" jest-junit@^12.0.0: @@ -3559,44 +3621,45 @@ jest-junit@^12.0.0: uuid "^3.3.3" xml "^1.0.1" -jest-leak-detector@^26.6.0: - version "26.6.0" - resolved "https://registry.yarnpkg.com/jest-leak-detector/-/jest-leak-detector-26.6.0.tgz#a211c4c7627743e8d87b392bf92502cd64275df3" - integrity sha512-3oMv34imWTl1/nwKnmE/DxYo3QqHnZeF3nO6UzldppkhW0Za7OY2DYyWiamqVzwdUrjhoQkY5g+aF6Oc3alYEQ== +jest-leak-detector@^26.6.2: + version "26.6.2" + resolved "https://registry.yarnpkg.com/jest-leak-detector/-/jest-leak-detector-26.6.2.tgz#7717cf118b92238f2eba65054c8a0c9c653a91af" + integrity sha512-i4xlXpsVSMeKvg2cEKdfhh0H39qlJlP5Ex1yQxwF9ubahboQYMgTtz5oML35AVA3B4Eu+YsmwaiKVev9KCvLxg== dependencies: jest-get-type "^26.3.0" - pretty-format "^26.6.0" + pretty-format "^26.6.2" -jest-matcher-utils@^26.6.0: - version "26.6.0" - resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-26.6.0.tgz#8f57d78353275bfa7a3ccea128c1030b347138e2" - integrity sha512-BUy/dQYb7ELGRazmK4ZVkbfPYCaNnrMtw1YljVhcKzWUxBM0xQ+bffrfnMLdRZp4wUUcT4ahaVnA3VWZtXWP9Q== +jest-matcher-utils@^26.6.2: + version "26.6.2" + resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-26.6.2.tgz#8e6fd6e863c8b2d31ac6472eeb237bc595e53e7a" + integrity sha512-llnc8vQgYcNqDrqRDXWwMr9i7rS5XFiCwvh6DTP7Jqa2mqpcCBBlpCbn+trkG0KNhPu/h8rzyBkriOtBstvWhw== dependencies: chalk "^4.0.0" - jest-diff "^26.6.0" + jest-diff "^26.6.2" jest-get-type "^26.3.0" - pretty-format "^26.6.0" + pretty-format "^26.6.2" -jest-message-util@^26.6.0: - version "26.6.0" - resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-26.6.0.tgz#c3499053022e05765f71b8c2535af63009e2d4be" - integrity sha512-WPAeS38Kza29f04I0iOIQrXeiebRXjmn6cFehzI7KKJOgT0NmqYAcLgjWnIAfKs5FBmEQgje1kXab0DaLKCl2w== +jest-message-util@^26.6.2: + version "26.6.2" + resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-26.6.2.tgz#58173744ad6fc0506b5d21150b9be56ef001ca07" + integrity sha512-rGiLePzQ3AzwUshu2+Rn+UMFk0pHN58sOG+IaJbk5Jxuqo3NYO1U2/MIR4S1sKgsoYSXSzdtSa0TgrmtUwEbmA== dependencies: "@babel/code-frame" "^7.0.0" - "@jest/types" "^26.6.0" + "@jest/types" "^26.6.2" "@types/stack-utils" "^2.0.0" chalk "^4.0.0" graceful-fs "^4.2.4" micromatch "^4.0.2" + pretty-format "^26.6.2" slash "^3.0.0" stack-utils "^2.0.2" -jest-mock@^26.6.0: - version "26.6.0" - resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-26.6.0.tgz#5d13a41f3662a98a55c7742ac67c482e232ded13" - integrity sha512-HsNmL8vVIn1rL1GWA21Drpy9Cl+7GImwbWz/0fkWHrUXVzuaG7rP0vwLtE+/n70Mt0U8nPkz8fxioi3SC0wqhw== +jest-mock@^26.6.2: + version "26.6.2" + resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-26.6.2.tgz#d6cb712b041ed47fe0d9b6fc3474bc6543feb302" + integrity sha512-YyFjePHHp1LzpzYcmgqkJ0nm0gg/lJx2aZFzFy1S6eUqNjXsOqTK10zNRff2dNfssgokjkG65OlWNcIlgd3zew== dependencies: - "@jest/types" "^26.6.0" + "@jest/types" "^26.6.2" "@types/node" "*" jest-pnp-resolver@^1.2.2: @@ -3609,171 +3672,172 @@ jest-regex-util@^26.0.0: resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-26.0.0.tgz#d25e7184b36e39fd466c3bc41be0971e821fee28" integrity sha512-Gv3ZIs/nA48/Zvjrl34bf+oD76JHiGDUxNOVgUjh3j890sblXryjY4rss71fPtD/njchl6PSE2hIhvyWa1eT0A== -jest-resolve-dependencies@^26.6.0: - version "26.6.0" - resolved "https://registry.yarnpkg.com/jest-resolve-dependencies/-/jest-resolve-dependencies-26.6.0.tgz#05bfecc977a3a48929fc7d9876f03d93a16b7df0" - integrity sha512-4di+XUT7LwJJ8b8qFEEDQssC5+aeVjLhvRICCaS4alh/EVS9JCT1armfJ3pnSS8t4o6659WbMmKVo82H4LuUVw== +jest-resolve-dependencies@^26.6.3: + version "26.6.3" + resolved "https://registry.yarnpkg.com/jest-resolve-dependencies/-/jest-resolve-dependencies-26.6.3.tgz#6680859ee5d22ee5dcd961fe4871f59f4c784fb6" + integrity sha512-pVwUjJkxbhe4RY8QEWzN3vns2kqyuldKpxlxJlzEYfKSvY6/bMvxoFrYYzUO1Gx28yKWN37qyV7rIoIp2h8fTg== dependencies: - "@jest/types" "^26.6.0" + "@jest/types" "^26.6.2" jest-regex-util "^26.0.0" - jest-snapshot "^26.6.0" + jest-snapshot "^26.6.2" -jest-resolve@^26.6.0: - version "26.6.0" - resolved "https://registry.yarnpkg.com/jest-resolve/-/jest-resolve-26.6.0.tgz#070fe7159af87b03e50f52ea5e17ee95bbee40e1" - integrity sha512-tRAz2bwraHufNp+CCmAD8ciyCpXCs1NQxB5EJAmtCFy6BN81loFEGWKzYu26Y62lAJJe4X4jg36Kf+NsQyiStQ== +jest-resolve@^26.6.2: + version "26.6.2" + resolved "https://registry.yarnpkg.com/jest-resolve/-/jest-resolve-26.6.2.tgz#a3ab1517217f469b504f1b56603c5bb541fbb507" + integrity sha512-sOxsZOq25mT1wRsfHcbtkInS+Ek7Q8jCHUB0ZUTP0tc/c41QHriU/NunqMfCUWsL4H3MHpvQD4QR9kSYhS7UvQ== dependencies: - "@jest/types" "^26.6.0" + "@jest/types" "^26.6.2" chalk "^4.0.0" graceful-fs "^4.2.4" jest-pnp-resolver "^1.2.2" - jest-util "^26.6.0" + jest-util "^26.6.2" read-pkg-up "^7.0.1" - resolve "^1.17.0" + resolve "^1.18.1" slash "^3.0.0" -jest-runner@^26.6.0: - version "26.6.0" - resolved "https://registry.yarnpkg.com/jest-runner/-/jest-runner-26.6.0.tgz#465a76efc9ec12cfd83a2af3a6cfb695b13a3efe" - integrity sha512-QpeN6pje8PQvFgT+wYOlzeycKd67qAvSw5FgYBiX2cTW+QTiObTzv/k09qRvT09rcCntFxUhy9VB1mgNGFLYIA== +jest-runner@^26.6.3: + version "26.6.3" + resolved "https://registry.yarnpkg.com/jest-runner/-/jest-runner-26.6.3.tgz#2d1fed3d46e10f233fd1dbd3bfaa3fe8924be159" + integrity sha512-atgKpRHnaA2OvByG/HpGA4g6CSPS/1LK0jK3gATJAoptC1ojltpmVlYC3TYgdmGp+GLuhzpH30Gvs36szSL2JQ== dependencies: - "@jest/console" "^26.6.0" - "@jest/environment" "^26.6.0" - "@jest/test-result" "^26.6.0" - "@jest/types" "^26.6.0" + "@jest/console" "^26.6.2" + "@jest/environment" "^26.6.2" + "@jest/test-result" "^26.6.2" + "@jest/types" "^26.6.2" "@types/node" "*" chalk "^4.0.0" emittery "^0.7.1" exit "^0.1.2" graceful-fs "^4.2.4" - jest-config "^26.6.0" + jest-config "^26.6.3" jest-docblock "^26.0.0" - jest-haste-map "^26.6.0" - jest-leak-detector "^26.6.0" - jest-message-util "^26.6.0" - jest-resolve "^26.6.0" - jest-runtime "^26.6.0" - jest-util "^26.6.0" - jest-worker "^26.5.0" + jest-haste-map "^26.6.2" + jest-leak-detector "^26.6.2" + jest-message-util "^26.6.2" + jest-resolve "^26.6.2" + jest-runtime "^26.6.3" + jest-util "^26.6.2" + jest-worker "^26.6.2" source-map-support "^0.5.6" throat "^5.0.0" -jest-runtime@^26.6.0: - version "26.6.0" - resolved "https://registry.yarnpkg.com/jest-runtime/-/jest-runtime-26.6.0.tgz#90f80ea5eb0d97a1089120f582fb84bd36ca5491" - integrity sha512-JEz4YGnybFvtN4NLID6lsZf0bcd8jccwjWcG5TRE3fYVnxoX1egTthPjnC4btIwWJ6QaaHhtOQ/E3AGn8iClAw== - dependencies: - "@jest/console" "^26.6.0" - "@jest/environment" "^26.6.0" - "@jest/fake-timers" "^26.6.0" - "@jest/globals" "^26.6.0" - "@jest/source-map" "^26.5.0" - "@jest/test-result" "^26.6.0" - "@jest/transform" "^26.6.0" - "@jest/types" "^26.6.0" +jest-runtime@^26.6.3: + version "26.6.3" + resolved "https://registry.yarnpkg.com/jest-runtime/-/jest-runtime-26.6.3.tgz#4f64efbcfac398331b74b4b3c82d27d401b8fa2b" + integrity sha512-lrzyR3N8sacTAMeonbqpnSka1dHNux2uk0qqDXVkMv2c/A3wYnvQ4EXuI013Y6+gSKSCxdaczvf4HF0mVXHRdw== + dependencies: + "@jest/console" "^26.6.2" + "@jest/environment" "^26.6.2" + "@jest/fake-timers" "^26.6.2" + "@jest/globals" "^26.6.2" + "@jest/source-map" "^26.6.2" + "@jest/test-result" "^26.6.2" + "@jest/transform" "^26.6.2" + "@jest/types" "^26.6.2" "@types/yargs" "^15.0.0" chalk "^4.0.0" + cjs-module-lexer "^0.6.0" collect-v8-coverage "^1.0.0" exit "^0.1.2" glob "^7.1.3" graceful-fs "^4.2.4" - jest-config "^26.6.0" - jest-haste-map "^26.6.0" - jest-message-util "^26.6.0" - jest-mock "^26.6.0" + jest-config "^26.6.3" + jest-haste-map "^26.6.2" + jest-message-util "^26.6.2" + jest-mock "^26.6.2" jest-regex-util "^26.0.0" - jest-resolve "^26.6.0" - jest-snapshot "^26.6.0" - jest-util "^26.6.0" - jest-validate "^26.6.0" + jest-resolve "^26.6.2" + jest-snapshot "^26.6.2" + jest-util "^26.6.2" + jest-validate "^26.6.2" slash "^3.0.0" strip-bom "^4.0.0" yargs "^15.4.1" -jest-serializer@^26.5.0: - version "26.5.0" - resolved "https://registry.yarnpkg.com/jest-serializer/-/jest-serializer-26.5.0.tgz#f5425cc4c5f6b4b355f854b5f0f23ec6b962bc13" - integrity sha512-+h3Gf5CDRlSLdgTv7y0vPIAoLgX/SI7T4v6hy+TEXMgYbv+ztzbg5PSN6mUXAT/hXYHvZRWm+MaObVfqkhCGxA== +jest-serializer@^26.6.2: + version "26.6.2" + resolved "https://registry.yarnpkg.com/jest-serializer/-/jest-serializer-26.6.2.tgz#d139aafd46957d3a448f3a6cdabe2919ba0742d1" + integrity sha512-S5wqyz0DXnNJPd/xfIzZ5Xnp1HrJWBczg8mMfMpN78OJ5eDxXyf+Ygld9wX1DnUWbIbhM1YDY95NjR4CBXkb2g== dependencies: "@types/node" "*" graceful-fs "^4.2.4" -jest-snapshot@^26.6.0: - version "26.6.0" - resolved "https://registry.yarnpkg.com/jest-snapshot/-/jest-snapshot-26.6.0.tgz#457aa9c1761efc781ac9c02b021a0b21047c6a38" - integrity sha512-mcqJZeIZqxomvBcsaiIbiEe2g7K1UxnUpTwjMoHb+DX4uFGnuZoZ6m28YOYRyCfZsdU9mmq73rNBnEH2atTR4Q== +jest-snapshot@^26.6.2: + version "26.6.2" + resolved "https://registry.yarnpkg.com/jest-snapshot/-/jest-snapshot-26.6.2.tgz#f3b0af1acb223316850bd14e1beea9837fb39c84" + integrity sha512-OLhxz05EzUtsAmOMzuupt1lHYXCNib0ECyuZ/PZOx9TrZcC8vL0x+DUG3TL+GLX3yHG45e6YGjIm0XwDc3q3og== dependencies: "@babel/types" "^7.0.0" - "@jest/types" "^26.6.0" + "@jest/types" "^26.6.2" "@types/babel__traverse" "^7.0.4" "@types/prettier" "^2.0.0" chalk "^4.0.0" - expect "^26.6.0" + expect "^26.6.2" graceful-fs "^4.2.4" - jest-diff "^26.6.0" + jest-diff "^26.6.2" jest-get-type "^26.3.0" - jest-haste-map "^26.6.0" - jest-matcher-utils "^26.6.0" - jest-message-util "^26.6.0" - jest-resolve "^26.6.0" + jest-haste-map "^26.6.2" + jest-matcher-utils "^26.6.2" + jest-message-util "^26.6.2" + jest-resolve "^26.6.2" natural-compare "^1.4.0" - pretty-format "^26.6.0" + pretty-format "^26.6.2" semver "^7.3.2" -jest-util@^26.6.0: - version "26.6.0" - resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-26.6.0.tgz#a81547f6d38738b505c5a594b37d911335dea60f" - integrity sha512-/cUGqcnKeZMjvTQLfJo65nBOEZ/k0RB/8usv2JpfYya05u0XvBmKkIH5o5c4nCh9DD61B1YQjMGGqh1Ha0aXdg== +jest-util@^26.6.2: + version "26.6.2" + resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-26.6.2.tgz#907535dbe4d5a6cb4c47ac9b926f6af29576cbc1" + integrity sha512-MDW0fKfsn0OI7MS7Euz6h8HNDXVQ0gaM9uW6RjfDmd1DAFcaxX9OqIakHIqhbnmF08Cf2DLDG+ulq8YQQ0Lp0Q== dependencies: - "@jest/types" "^26.6.0" + "@jest/types" "^26.6.2" "@types/node" "*" chalk "^4.0.0" graceful-fs "^4.2.4" is-ci "^2.0.0" micromatch "^4.0.2" -jest-validate@^26.6.0: - version "26.6.0" - resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-26.6.0.tgz#b95e2076cca1a58b183e5bcce2bf43af52eebf10" - integrity sha512-FKHNqvh1Pgs4NWas56gsTPmjcIoGAAzSVUCK1+g8euzuCGbmdEr8LRTtOEFjd29uMZUk0PhzmzKGlHPe6j3UWw== +jest-validate@^26.6.2: + version "26.6.2" + resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-26.6.2.tgz#23d380971587150467342911c3d7b4ac57ab20ec" + integrity sha512-NEYZ9Aeyj0i5rQqbq+tpIOom0YS1u2MVu6+euBsvpgIme+FOfRmoC4R5p0JiAUpaFvFy24xgrpMknarR/93XjQ== dependencies: - "@jest/types" "^26.6.0" + "@jest/types" "^26.6.2" camelcase "^6.0.0" chalk "^4.0.0" jest-get-type "^26.3.0" leven "^3.1.0" - pretty-format "^26.6.0" + pretty-format "^26.6.2" -jest-watcher@^26.6.0: - version "26.6.0" - resolved "https://registry.yarnpkg.com/jest-watcher/-/jest-watcher-26.6.0.tgz#06001c22831583a16f9ccb388ee33316a7f4200f" - integrity sha512-gw5BvcgPi0PKpMlNWQjUet5C5A4JOYrT7gexdP6+DR/f7mRm7wE0o1GqwPwcTsTwo0/FNf9c/kIDXTRaSAYwlw== +jest-watcher@^26.6.2: + version "26.6.2" + resolved "https://registry.yarnpkg.com/jest-watcher/-/jest-watcher-26.6.2.tgz#a5b683b8f9d68dbcb1d7dae32172d2cca0592975" + integrity sha512-WKJob0P/Em2csiVthsI68p6aGKTIcsfjH9Gsx1f0A3Italz43e3ho0geSAVsmj09RWOELP1AZ/DXyJgOgDKxXQ== dependencies: - "@jest/test-result" "^26.6.0" - "@jest/types" "^26.6.0" + "@jest/test-result" "^26.6.2" + "@jest/types" "^26.6.2" "@types/node" "*" ansi-escapes "^4.2.1" chalk "^4.0.0" - jest-util "^26.6.0" + jest-util "^26.6.2" string-length "^4.0.1" -jest-worker@^26.5.0: - version "26.5.0" - resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-26.5.0.tgz#87deee86dbbc5f98d9919e0dadf2c40e3152fa30" - integrity sha512-kTw66Dn4ZX7WpjZ7T/SUDgRhapFRKWmisVAF0Rv4Fu8SLFD7eLbqpLvbxVqYhSgaWa7I+bW7pHnbyfNsH6stug== +jest-worker@^26.6.2: + version "26.6.2" + resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-26.6.2.tgz#7f72cbc4d643c365e27b9fd775f9d0eaa9c7a8ed" + integrity sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ== dependencies: "@types/node" "*" merge-stream "^2.0.0" supports-color "^7.0.0" -jest@^26.6.0: - version "26.6.0" - resolved "https://registry.yarnpkg.com/jest/-/jest-26.6.0.tgz#546b25a1d8c888569dbbe93cae131748086a4a25" - integrity sha512-jxTmrvuecVISvKFFhOkjsWRZV7sFqdSUAd1ajOKY+/QE/aLBVstsJ/dX8GczLzwiT6ZEwwmZqtCUHLHHQVzcfA== +jest@^26.6.3: + version "26.6.3" + resolved "https://registry.yarnpkg.com/jest/-/jest-26.6.3.tgz#40e8fdbe48f00dfa1f0ce8121ca74b88ac9148ef" + integrity sha512-lGS5PXGAzR4RF7V5+XObhqz2KZIDUA1yD0DG6pBVmy10eh0ZIXQImRuzocsI/N2XZ1GrLFwTS27In2i2jlpq1Q== dependencies: - "@jest/core" "^26.6.0" + "@jest/core" "^26.6.3" import-local "^3.0.2" - jest-cli "^26.6.0" + jest-cli "^26.6.3" js-tokens@^4.0.0: version "4.0.0" @@ -3984,7 +4048,7 @@ lodash.sortby@^4.7.0: resolved "https://registry.yarnpkg.com/lodash.sortby/-/lodash.sortby-4.7.0.tgz#edd14c824e2cc9c1e0b0a1b42bb5210516a42438" integrity sha1-7dFMgk4sycHgsKG0K7UhBRakJDg= -lodash@^4.17.13, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.19: +lodash@^4.17.13, lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.20: version "4.17.20" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.20.tgz#b44a9b6297bcb698f1c51a3545a2b3b368d59c52" integrity sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA== @@ -4091,11 +4155,6 @@ minimatch@^3.0.4: dependencies: brace-expansion "^1.1.7" -minimist@0.0.8: - version "0.0.8" - resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d" - integrity sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0= - minimist@^1.1.1, minimist@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284" @@ -4114,13 +4173,6 @@ mixin-deep@^1.2.0: for-in "^1.0.2" is-extendable "^1.0.1" -mkdirp@^0.5.1: - version "0.5.1" - resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903" - integrity sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM= - dependencies: - minimist "0.0.8" - mkdirp@^1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e" @@ -4136,11 +4188,6 @@ ms@^2.1.1: resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== -nan@^2.12.1: - version "2.14.0" - resolved "https://registry.yarnpkg.com/nan/-/nan-2.14.0.tgz#7818f722027b2459a86f0295d434d1fc2336c52c" - integrity sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg== - nanomatch@^1.2.9: version "1.2.13" resolved "https://registry.yarnpkg.com/nanomatch/-/nanomatch-1.2.13.tgz#b87a8aa4fc0de8fe6be88895b38983ff265bd119" @@ -4198,17 +4245,10 @@ node-notifier@^8.0.0: uuid "^8.3.0" which "^2.0.2" -node-releases@^1.1.47: - version "1.1.47" - resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.47.tgz#c59ef739a1fd7ecbd9f0b7cf5b7871e8a8b591e4" - integrity sha512-k4xjVPx5FpwBUj0Gw7uvFOTF4Ep8Hok1I6qjwL3pLfwe7Y0REQSAqOwwv9TWBCUtMHxcXfY4PgRLRozcChvTcA== - dependencies: - semver "^6.3.0" - -node-releases@^1.1.61: - version "1.1.64" - resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.64.tgz#71b4ae988e9b1dd7c1ffce58dd9e561752dfebc5" - integrity sha512-Iec8O9166/x2HRMJyLLLWkd0sFFLrFNy+Xf+JQfSQsdBJzPcHpNl3JQ9gD4j+aJxmCa25jNsIbM4bmACtSbkSg== +node-releases@^1.1.67: + version "1.1.67" + resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.67.tgz#28ebfcccd0baa6aad8e8d4d8fe4cbc49ae239c12" + integrity sha512-V5QF9noGFl3EymEwUYzO+3NTDpGfQB4ve6Qfnzf3UNydMhjQRVPR1DZTuvWiLzaFJYw2fmDwAfnRNEVb64hSIg== normalize-package-data@^2.3.2, normalize-package-data@^2.5.0: version "2.5.0" @@ -4564,25 +4604,15 @@ prelude-ls@~1.1.2: resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" integrity sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ= -pretty-format@^25.2.1, pretty-format@^25.5.0: - version "25.5.0" - resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-25.5.0.tgz#7873c1d774f682c34b8d48b6743a2bf2ac55791a" - integrity sha512-kbo/kq2LQ/A/is0PQwsEHM7Ca6//bGPPvU6UnsdDRSKTWxT/ru/xb88v4BJf6a69H+uTytOEsTusT9ksd/1iWQ== - dependencies: - "@jest/types" "^25.5.0" - ansi-regex "^5.0.0" - ansi-styles "^4.0.0" - react-is "^16.12.0" - -pretty-format@^26.6.0: - version "26.6.0" - resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-26.6.0.tgz#1e1030e3c70e3ac1c568a5fd15627671ea159391" - integrity sha512-Uumr9URVB7bm6SbaByXtx+zGlS+0loDkFMHP0kHahMjmfCtmFY03iqd++5v3Ld6iB5TocVXlBN/T+DXMn9d4BA== +pretty-format@^26.0.0, pretty-format@^26.6.2: + version "26.6.2" + resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-26.6.2.tgz#e35c2705f14cb7fe2fe94fa078345b444120fc93" + integrity sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg== dependencies: - "@jest/types" "^26.6.0" + "@jest/types" "^26.6.2" ansi-regex "^5.0.0" ansi-styles "^4.0.0" - react-is "^16.12.0" + react-is "^17.0.1" process-nextick-args@~2.0.0: version "2.0.1" @@ -4625,10 +4655,10 @@ qs@~6.5.2: resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.2.tgz#cb3ae806e8740444584ef154ce8ee98d403f3e36" integrity sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA== -react-is@^16.12.0: - version "16.12.0" - resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.12.0.tgz#2cc0fe0fba742d97fd527c42a13bec4eeb06241c" - integrity sha512-rPCkf/mWBtKc97aLL9/txD8DZdemK0vkA3JMLShjlJB3Pj3s+lpf1KaBzMfQrAmhMQB0n1cU/SUGgKKBCe837Q== +react-is@^17.0.1: + version "17.0.1" + resolved "https://registry.yarnpkg.com/react-is/-/react-is-17.0.1.tgz#5b3531bd76a645a4c9fb6e693ed36419e3301339" + integrity sha512-NAnt2iGDXohE5LI7uBnLnqvLQMtzhkiAOLXTmv+qnF9Ky7xAPcX8Up/xWIhxvLVGJvuLiNc4xQLtuqDRzb4fSA== read-pkg-up@^2.0.0: version "2.0.0" @@ -4727,7 +4757,7 @@ regex-not@^1.0.0, regex-not@^1.0.2: extend-shallow "^3.0.2" safe-regex "^1.1.0" -regexpp@^3.1.0: +regexpp@^3.0.0, regexpp@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-3.1.0.tgz#206d0ad0a5648cffbdb8ae46438f3dc51c9f78e2" integrity sha512-ZOIzd8yVsQQA7j8GCSlPGXwg5PfmA1mrq0JP4nGhh54LaKN3xdai/vHUDu74pKwV8OxseMS65u2NImosQcSD0Q== @@ -4860,6 +4890,14 @@ resolve@^1.17.0: is-core-module "^2.0.0" path-parse "^1.0.6" +resolve@^1.18.1: + version "1.19.0" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.19.0.tgz#1af5bf630409734a067cae29318aac7fa29a267c" + integrity sha512-rArEXAgsBG4UgRGcynxWIWKFvh/XZCcS8UJdHhwy91zwAvCZIbcs+vAbflgBnNjYMs/i/i+/Ux6IZhML1yPvxg== + dependencies: + is-core-module "^2.1.0" + path-parse "^1.0.6" + ret@~0.1.10: version "0.1.15" resolved "https://registry.yarnpkg.com/ret/-/ret-0.1.15.tgz#b8a4825d5bdb1fc3f6f53c2bc33f81388681c7bc" @@ -4870,13 +4908,6 @@ reusify@^1.0.4: resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76" integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== -rimraf@2.6.3: - version "2.6.3" - resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.3.tgz#b2d104fe0d8fb27cf9e0a1cda8262dd3833c6cab" - integrity sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA== - dependencies: - glob "^7.1.3" - rimraf@^3.0.0: version "3.0.1" resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.1.tgz#48d3d4cb46c80d388ab26cd61b1b466ae9ae225a" @@ -4884,6 +4915,13 @@ rimraf@^3.0.0: dependencies: glob "^7.1.3" +rimraf@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a" + integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA== + dependencies: + glob "^7.1.3" + rsvp@^4.8.4: version "4.8.5" resolved "https://registry.yarnpkg.com/rsvp/-/rsvp-4.8.5.tgz#c8f155311d167f68f21e168df71ec5b083113734" @@ -5024,14 +5062,14 @@ slash@^3.0.0: resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634" integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q== -slice-ansi@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-2.1.0.tgz#cacd7693461a637a5788d92a7dd4fba068e81636" - integrity sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ== +slice-ansi@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-4.0.0.tgz#500e8dd0fd55b05815086255b3195adf2a45fe6b" + integrity sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ== dependencies: - ansi-styles "^3.2.0" - astral-regex "^1.0.0" - is-fullwidth-code-point "^2.0.0" + ansi-styles "^4.0.0" + astral-regex "^2.0.0" + is-fullwidth-code-point "^3.0.0" snapdragon-node@^2.0.1: version "2.1.1" @@ -5183,15 +5221,6 @@ string-length@^4.0.1: char-regex "^1.0.2" strip-ansi "^6.0.0" -string-width@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-3.1.0.tgz#22767be21b62af1081574306f69ac51b62203961" - integrity sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w== - dependencies: - emoji-regex "^7.0.1" - is-fullwidth-code-point "^2.0.0" - strip-ansi "^5.1.0" - string-width@^4.1.0, string-width@^4.2.0: version "4.2.0" resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.0.tgz#952182c46cc7b2c313d1596e623992bd163b72b5" @@ -5224,7 +5253,7 @@ string_decoder@~1.1.1: dependencies: safe-buffer "~5.1.0" -strip-ansi@^5.1.0, strip-ansi@^5.2.0: +strip-ansi@^5.2.0: version "5.2.0" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-5.2.0.tgz#8c9a536feb6afc962bdfa5b104a5091c1ad9c0ae" integrity sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA== @@ -5290,15 +5319,15 @@ symbol-tree@^3.2.4: resolved "https://registry.yarnpkg.com/symbol-tree/-/symbol-tree-3.2.4.tgz#430637d248ba77e078883951fb9aa0eed7c63fa2" integrity sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw== -table@^5.2.3: - version "5.4.6" - resolved "https://registry.yarnpkg.com/table/-/table-5.4.6.tgz#1292d19500ce3f86053b05f0e8e7e4a3bb21079e" - integrity sha512-wmEc8m4fjnob4gt5riFRtTu/6+4rSe12TpAELNSqHMfF3IqnA+CH37USM6/YR3qRZv7e56kAEAtd6nKZaxe0Ug== +table@^6.0.4: + version "6.0.4" + resolved "https://registry.yarnpkg.com/table/-/table-6.0.4.tgz#c523dd182177e926c723eb20e1b341238188aa0d" + integrity sha512-sBT4xRLdALd+NFBvwOz8bw4b15htyythha+q+DVZqy2RS08PPC8O2sZFgJYEY7bJvbCFKccs+WIZ/cd+xxTWCw== dependencies: - ajv "^6.10.2" - lodash "^4.17.14" - slice-ansi "^2.1.0" - string-width "^3.0.0" + ajv "^6.12.4" + lodash "^4.17.20" + slice-ansi "^4.0.0" + string-width "^4.2.0" terminal-link@^2.0.0: version "2.1.1" @@ -5463,10 +5492,10 @@ typedarray-to-buffer@^3.1.5: dependencies: is-typedarray "^1.0.0" -typescript@^4.0.3: - version "4.0.3" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.0.3.tgz#153bbd468ef07725c1df9c77e8b453f8d36abba5" - integrity sha512-tEu6DGxGgRJPb/mVPIZ48e69xCn2yRmCgYmDugAVwmJ6o+0u1RI18eO7E7WBTLYLaEVVOhwQmcdhQHweux/WPg== +typescript@^4.1.3: + version "4.1.3" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.1.3.tgz#519d582bd94cba0cf8934c7d8e8467e473f53bb7" + integrity sha512-B3ZIOf1IKeH2ixgHhj6la6xdwR9QrLC5d1VKeCSY4tvkqhF2eqd9O7txNlS0PO3GrBAFIdr3L1ndNwteUbZLYg== unicode-canonical-property-names-ecmascript@^1.0.4: version "1.0.4" @@ -5551,10 +5580,10 @@ v8-compile-cache@^2.0.3: resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.1.0.tgz#e14de37b31a6d194f5690d67efc4e7f6fc6ab30e" integrity sha512-usZBT3PW+LOjM25wbqIlZwPeJV+3OSz3M1k1Ws8snlW39dZyYL9lOGC5FgPVHfk0jKmjiDV8Z0mIbVQPiwFs7g== -v8-to-istanbul@^6.0.1: - version "6.0.1" - resolved "https://registry.yarnpkg.com/v8-to-istanbul/-/v8-to-istanbul-6.0.1.tgz#7ef0e32faa10f841fe4c1b0f8de96ed067c0be1e" - integrity sha512-PzM1WlqquhBvsV+Gco6WSFeg1AGdD53ccMRkFeyHRE/KRZaVacPOmQYP3EeVgDBtKD2BJ8kgynBQ5OtKiHCH+w== +v8-to-istanbul@^7.0.0: + version "7.1.0" + resolved "https://registry.yarnpkg.com/v8-to-istanbul/-/v8-to-istanbul-7.1.0.tgz#5b95cef45c0f83217ec79f8fc7ee1c8b486aee07" + integrity sha512-uXUVqNUCLa0AH1vuVxzi+MI4RfxEOKt9pBgKwHbgH7st8Kv2P1m+jvWNnektzBh5QShF3ODgKmUFCf38LnVz1g== dependencies: "@types/istanbul-lib-coverage" "^2.0.1" convert-source-map "^1.6.0" @@ -5684,13 +5713,6 @@ write-file-atomic@^3.0.0: signal-exit "^3.0.2" typedarray-to-buffer "^3.1.5" -write@1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/write/-/write-1.0.3.tgz#0800e14523b923a387e415123c865616aae0f5c3" - integrity sha512-/lg70HAjtkUgWPVZhZcm+T4hkL8Zbtp1nFNOn3lRrxnlv50SRBv7cR7RqR+GMsd3hUXy9hWBo4CHTbFTcOYwig== - dependencies: - mkdirp "^0.5.1" - ws@^7.2.3: version "7.3.1" resolved "https://registry.yarnpkg.com/ws/-/ws-7.3.1.tgz#d0547bf67f7ce4f12a72dfe31262c68d7dc551c8" From 8225b51c970dbb6f99de0d78787326edcb426159 Mon Sep 17 00:00:00 2001 From: Derk-Jan Karrenbeld Date: Thu, 24 Dec 2020 23:17:52 +0100 Subject: [PATCH 07/36] Add CI workflows and scripts --- .github/workflows/ci.js.yml | 48 ++++++++++++++++++++++++++++ .github/workflows/pr.ci.js.yml | 58 ++++++++++++++++++++++++++++++++++ bin/ci-check.sh | 14 ++++++++ bin/ci.sh | 1 + bin/lint.sh | 1 + bin/pr-check.sh | 14 ++++++++ bin/pr.sh | 1 + 7 files changed, 137 insertions(+) create mode 100644 .github/workflows/ci.js.yml create mode 100644 .github/workflows/pr.ci.js.yml create mode 100644 bin/ci-check.sh create mode 100644 bin/ci.sh create mode 100644 bin/lint.sh create mode 100644 bin/pr-check.sh create mode 100644 bin/pr.sh diff --git a/.github/workflows/ci.js.yml b/.github/workflows/ci.js.yml new file mode 100644 index 00000000..1b351457 --- /dev/null +++ b/.github/workflows/ci.js.yml @@ -0,0 +1,48 @@ +# This workflow will do a clean install of node dependencies 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 + +name: javascript-test-runner / master + +on: + push: + branches: [master] + +jobs: + precheck: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v2 + - name: Use Node.js LTS (14.x) + uses: actions/setup-node@v1 + with: + node-version: 14.x + + - name: Install project dependencies + run: yarn install --frozen-lockfile + + - name: Run exercism/javascript-test-runner ci precheck (lint code) + run: bin/ci-check.sh + + ci: + runs-on: ubuntu-latest + + strategy: + matrix: + node-version: [12.x, 14.x, 15.x] + + steps: + - uses: actions/checkout@v2 + - name: Use Node.js ${{ matrix.node-version }} + uses: actions/setup-node@v1 + with: + node-version: ${{ matrix.node-version }} + + - name: Install project dependencies + run: yarn install --frozen-lockfile + + - name: Build the test-runner (using Node ${{ matrix.node-version }}) + run: yarn build + + - name: Run exercism/javascript-test-runner ci (build and runs tests) + run: bin/ci.sh diff --git a/.github/workflows/pr.ci.js.yml b/.github/workflows/pr.ci.js.yml new file mode 100644 index 00000000..34935d26 --- /dev/null +++ b/.github/workflows/pr.ci.js.yml @@ -0,0 +1,58 @@ +# This workflow will do a clean install of node dependencies 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 + +name: javascript-test-runner / pr + +on: pull_request + +jobs: + precheck: + runs-on: ubuntu-latest + + steps: + - name: Checkout PR + uses: actions/checkout@v2 + + - name: Use Node.js LTS (14.x) + uses: actions/setup-node@v1 + with: + node-version: 14.x + + - name: Install project dependencies + run: yarn install --frozen-lockfile + + - name: Run exercism/javascript ci precheck (lint code) + run: | + PULL_REQUEST_URL=$(jq -r ".pull_request.url" "$GITHUB_EVENT_PATH") + curl --url $"${PULL_REQUEST_URL}/files?per_page=100" --header 'authorization: Bearer ${{ secrets.GITHUB_TOKEN }}' | \ + jq -c '.[] | select(.status == "added" or .status == "modified") | select(.filename | match("\\.(js|jsx|ts|tsx|md|json)$")) | .filename' | \ + xargs -r bin/pr-check.sh + + ci: + runs-on: ubuntu-latest + + strategy: + matrix: + node-version: [12.x, 14.x, 15.x] + + steps: + - name: Checkout PR + uses: actions/checkout@v2 + + - name: Use Node.js ${{ matrix.node-version }} + uses: actions/setup-node@v1 + with: + node-version: ${{ matrix.node-version }} + + - name: Install project dependencies + run: yarn install --frozen-lockfile + + - name: Build the test-runner (using Node ${{ matrix.node-version }}) + run: yarn build + + - name: Run exercism/javascript ci (build and runs tests) + run: | + PULL_REQUEST_URL=$(jq -r ".pull_request.url" "$GITHUB_EVENT_PATH") + curl --url $"${PULL_REQUEST_URL}/files?per_page=100" --header 'authorization: Bearer ${{ secrets.GITHUB_TOKEN }}' | \ + jq -c '.[] | select(.status == "added" or .status == "modified") | select(.filename | match("\\.(js|jsx|ts|tsx|md|json)$")) | .filename' | \ + xargs -r bin/pr.sh diff --git a/bin/ci-check.sh b/bin/ci-check.sh new file mode 100644 index 00000000..2da112d3 --- /dev/null +++ b/bin/ci-check.sh @@ -0,0 +1,14 @@ +#!/usr/bin/env bash + +# Documentation on @ +# https://www.gnu.org/savannah-checkouts/gnu/bash/manual/bash.html#index-_0040 +# Documentation on shift [n] +# https://www.gnu.org/savannah-checkouts/gnu/bash/manual/bash.html#index-shift +# Why quoting the argument is "necessary": +# https://stackoverflow.com/questions/4824590/propagate-all-arguments-in-a-bash-shell-script/4824637#4824637 + +# eats 1 argument +shift 1 + +lint.sh "$@" +check-formatting.sh "$@" \ No newline at end of file diff --git a/bin/ci.sh b/bin/ci.sh new file mode 100644 index 00000000..09e32876 --- /dev/null +++ b/bin/ci.sh @@ -0,0 +1 @@ +yarn test \ No newline at end of file diff --git a/bin/lint.sh b/bin/lint.sh new file mode 100644 index 00000000..c58e8ce8 --- /dev/null +++ b/bin/lint.sh @@ -0,0 +1 @@ +yarn lint \ No newline at end of file diff --git a/bin/pr-check.sh b/bin/pr-check.sh new file mode 100644 index 00000000..4049aaac --- /dev/null +++ b/bin/pr-check.sh @@ -0,0 +1,14 @@ +#!/usr/bin/env bash + +# Documentation on @ +# https://www.gnu.org/savannah-checkouts/gnu/bash/manual/bash.html#index-_0040 +# Documentation on shift [n] +# https://www.gnu.org/savannah-checkouts/gnu/bash/manual/bash.html#index-shift +# Why quoting the argument is "necessary": +# https://stackoverflow.com/questions/4824590/propagate-all-arguments-in-a-bash-shell-script/4824637#4824637 + +# eats 1 argument +shift 1 + +lint.sh "$@" +check-formatting.sh "$@" \ No newline at end of file diff --git a/bin/pr.sh b/bin/pr.sh new file mode 100644 index 00000000..09e32876 --- /dev/null +++ b/bin/pr.sh @@ -0,0 +1 @@ +yarn test \ No newline at end of file From 6941d88131047cd3be28297c2463164238294499 Mon Sep 17 00:00:00 2001 From: Derk-Jan Karrenbeld Date: Thu, 24 Dec 2020 23:18:19 +0100 Subject: [PATCH 08/36] Allow remote downloads in run.sh --- bin/run.bat | 18 +++++++++++ bin/run.sh | 86 ++++++++++++++++++++++++++++++++++++++++++++++------- 2 files changed, 93 insertions(+), 11 deletions(-) create mode 100644 bin/run.bat diff --git a/bin/run.bat b/bin/run.bat new file mode 100644 index 00000000..2b3c8c6d --- /dev/null +++ b/bin/run.bat @@ -0,0 +1,18 @@ +@REM Synopsis: +@REM Automatically tests exercism's JS track solutions against corresponding test files. +@REM Takes two-three arguments and makes sure all the tests are run +@REM +@REM Arguments: +@REM @1: exercise slug +@REM @2: path to solution folder (with trailing slash) +@REM @3: path to output directory (with trailing slash) (defaults to $2) +@REM +@REM Output: +@REM Writes the tests output to the output directory +@REM +@REM Example: +@REM .\bat.sh two-fer path\to\two-fer\solution\folder\ +@REM .\bat.sh two-fer path\to\two-fer\solution\folder\ path\to\output-directory\ + +echo "run.bat is currently not supported. Use run.sh" +exit 1 diff --git a/bin/run.sh b/bin/run.sh index c67dac97..53786347 100755 --- a/bin/run.sh +++ b/bin/run.sh @@ -2,52 +2,116 @@ # Synopsis: # Automatically tests exercism's JS track solutions against corresponding test files. -# Takes two arguments and makes sure all the tests are run +# Takes two-three arguments and makes sure all the tests are run # Arguments: # $1: exercise slug # $2: path to solution folder (with trailing slash) -# $3: path to output directory (with trailing slash) +# $3: path to output directory (with trailing slash) (defaults to $2) # Output: # Writes the tests output to the output directory # Example: +# ./run.sh two-fer path/to/two-fer/solution/folder/ # ./run.sh two-fer path/to/two-fer/solution/folder/ path/to/output-directory/ +if [[ $1 != http?(s)://* ]]; then + if [ -z "$2" ] ; then + echo "Requires at least 2 arguments:" + echo "1: exercise slug" + echo "2: path to solution folder (with trailing slash)" + echo "" + echo "Usage:" + echo " run.sh two-fer path/to/two-fer/solution/folder/" + exit 1 + fi + + if [ -z "$3" ] ; then + OUTPUT="$2" + else + OUTPUT="$3" + fi + + INPUT="$2" + SLUG="$1" +else + # This block allows you to download a solution and run the tests on it. This + # allows passing in any solution URL your locally installed exercism CLI has + # access to: + # + # - published: https://exercism.io/tracks/javascript/exercises/clock/solutions/a7d1b71693fb4298a3a99bd352dd4d74 + # - own: https://exercism.io/my/solutions/a7d1b71693fb4298a3a99bd352dd4d74 + # - mentoring: https://exercism.io/mentor/solutions/a7d1b71693fb4298a3a99bd352dd4d74 + # - private: https://exercism.io/solutions/a7d1b71693fb4298a3a99bd352dd4d74 + # + uuid=$(basename $1) + echo "Exercism remote UUID: $uuid" + + result=$(exercism download --uuid="${uuid}" | sed -n 1p) || exit $? + echo $result + + SLUG=$(basename $result) + TMP="./tmp/${SLUG}/${uuid}/" + + # Jest really doesn't like it when the input files are outside the CWD process + # tree. Instead of trying to resolve that, the code here copies the downloaded + # solution to a local temporary directory. + # + # This will fail if the cwd is not writable. + # + mkdir -p "$TMP" + cp "$result" "$TMP" -r + + INPUT="$TMP$SLUG/" + OUTPUT=$INPUT +fi + +# Forces a trailing slash +INPUT="${INPUT%/}/" + +# Forces a trailing slash +OUTPUT="${OUTPUT%/}/" + set -euo pipefail # Put together the path to the test file -test_file="${2}${1}.spec.js" +test_file="${INPUT}${SLUG}.spec.js" # Put together the path to the test results file -result_file="${3}results.json" +result_file="${OUTPUT}results.json" # Change xtest to test so all tests are run if [[ "$OSTYPE" == "darwin"* ]]; then # Mac OS X # BSD sed -i takes an extra parameter to specify the backup file extension - sed -i 'tmp' 's/xtest/test/g' "${test_file}" - sed -i 'tmp' 's/xit/it/g' "${test_file}" + sed -i 'tmp' 's/xtest(/test(/g' "${test_file}" + sed -i 'tmp' 's/xit(/it(/g' "${test_file}" + sed -i 'tmp' 's/xdescribe(/describe(/g' "${test_file}" else - sed -i 's/xtest/test/g' "${test_file}" - sed -i 's/xit/it/g' "${test_file}" + sed -i 's/xtest(/test(/g' "${test_file}" + sed -i 's/xit(/it(/g' "${test_file}" + sed -i 's/xdescribe(/describe(/g' "${test_file}" fi -mkdir -p "${3}" +mkdir -p "${OUTPUT}" # Disable auto exit set +e # Run tests -./node_modules/.bin/jest test --no-cache "${2}*" \ +./node_modules/.bin/jest test --no-cache "${INPUT}*" \ --outputFile="${result_file}" \ --reporters "./dist/reporter.js" \ --noStackTrace \ --verbose=false \ - --roots "${2}" + --roots "${INPUT}" # Convert exit(1) to exit(0) test_exit=$? + +echo "Find the output at:" +echo $result_file + if [ $test_exit -eq 1 ] then exit 0 From 35b0dd41a721789c261bfef585c72a163aa24053 Mon Sep 17 00:00:00 2001 From: Derk-Jan Karrenbeld Date: Thu, 24 Dec 2020 23:18:29 +0100 Subject: [PATCH 09/36] Update eslint configuration to recognise prettier --- .eslintrc | 34 ++++++++++++++++++++++++---------- 1 file changed, 24 insertions(+), 10 deletions(-) diff --git a/.eslintrc b/.eslintrc index 956afc56..5d25bb78 100644 --- a/.eslintrc +++ b/.eslintrc @@ -16,18 +16,25 @@ "extends": [ "eslint:recommended", "plugin:@typescript-eslint/eslint-recommended", - "plugin:@typescript-eslint/recommended" + "plugin:@typescript-eslint/recommended", + "prettier", + "prettier/@typescript-eslint", + "plugin:import/errors", + "plugin:import/warnings", + "plugin:import/typescript" ], "rules": { "@typescript-eslint/explicit-function-return-type": [ - "warn", { + "warn", + { "allowExpressions": false, "allowTypedFunctionExpressions": true, "allowHigherOrderFunctions": true } ], "@typescript-eslint/explicit-member-accessibility": [ - "warn", { + "warn", + { "accessibility": "no-public", "overrides": { "accessors": "explicit", @@ -38,27 +45,34 @@ } } ], - "@typescript-eslint/indent": ["error", 2], "@typescript-eslint/no-inferrable-types": [ - "error", { + "error", + { "ignoreParameters": true } ], "@typescript-eslint/no-non-null-assertion": "off", "@typescript-eslint/no-parameter-properties": [ - "warn", { + "warn", + { "allows": [ - "private", "protected", "public", - "private readonly", "protected readonly", "public readonly" + "private", + "protected", + "public", + "private readonly", + "protected readonly", + "public readonly" ] } ], "@typescript-eslint/no-unused-vars": "off", "@typescript-eslint/no-use-before-define": [ - "error", { + "error", + { "functions": false, "typedefs": false } - ] + ], + "import/no-unresolved": "off" } } From daef77b91b524bcd584cc5bc0947bbcb54d929a5 Mon Sep 17 00:00:00 2001 From: Derk-Jan Karrenbeld Date: Thu, 24 Dec 2020 23:18:53 +0100 Subject: [PATCH 10/36] Add scripts for easier maintenance --- package.json | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/package.json b/package.json index b7175666..98bcbbc6 100644 --- a/package.json +++ b/package.json @@ -10,12 +10,13 @@ "url": "https://github.com/exercism/javascript-test-runner" }, "scripts": { - "build": "yarn tsc --build .", - "test": "jest --no-cache ./*", - "watch": "jest --no-cache --watch ./*", - "lint": "eslint .", - "lint-test": "eslint . && jest --no-cache ./* ", - "test:cli": "jest test --no-cache {in}* --outputFile={result_file} --noStackTrace --verbose=false" + "execute": "./bin/run.sh", + "execute:dev": "yarn build && yarn execute", + "build": "yarn tsc --project ./tsconfig.json", + "watch": "yarn build -w", + "prepublish": "yarn test", + "lint": "yarn eslint . --ext ts,js,tsx,jsx,mjs", + "test": "yarn build && jest --roots test --testPathIgnorePatterns=\"fixtures/\"" }, "dependencies": { "@babel/cli": "^7.12.10", From 4a606826cfbfc86b0180b88bd6ad14e5dcbffb37 Mon Sep 17 00:00:00 2001 From: Derk-Jan Karrenbeld Date: Thu, 24 Dec 2020 23:19:38 +0100 Subject: [PATCH 11/36] Remove tooling_webserver --- Dockerfile | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/Dockerfile b/Dockerfile index 9d54c658..fcd63ab3 100644 --- a/Dockerfile +++ b/Dockerfile @@ -4,12 +4,12 @@ FROM node:erbium-buster-slim as runner # fetch latest security updates RUN set -ex; \ - apt-get update; \ - apt-get upgrade -y; \ - # curl is required to fetch our webhook from github - # unzip is required for unzipping payloads in development - apt-get install curl unzip -y; \ - rm -rf /var/lib/apt/lists/* + apt-get update; \ + apt-get upgrade -y; \ + # curl is required to fetch our webhook from github + # unzip is required for unzipping payloads in development + apt-get install curl unzip -y; \ + rm -rf /var/lib/apt/lists/* # add a non-root user to run our code as RUN adduser --disabled-password --gecos "" appuser @@ -29,10 +29,5 @@ RUN set -ex; \ # clean our yarn cache yarn cache clean; -# static binary used for webhook when running in dev mode -RUN curl -L -o /usr/local/bin/tooling_webserver \ - https://github.com/exercism/tooling-webserver/releases/latest/download/tooling_webserver -RUN chmod +x /usr/local/bin/tooling_webserver - USER appuser ENTRYPOINT [ "/opt/test-runner/bin/run.sh" ] From cba3066b20c39f66edc0a7685f30ee5778514382 Mon Sep 17 00:00:00 2001 From: Derk-Jan Karrenbeld Date: Thu, 24 Dec 2020 23:19:47 +0100 Subject: [PATCH 12/36] Change LICENSE --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 98bcbbc6..e2577616 100644 --- a/package.json +++ b/package.json @@ -4,7 +4,7 @@ "author": "Derk-Jan Karrenbeld ", "version": "1.0.0", "private": true, - "license": "MIT", + "license": "AGPL-3.0-or-later", "repository": { "type": "git", "url": "https://github.com/exercism/javascript-test-runner" From a31a3b22ba3901cb5e4d86d5c911b565eeb0393a Mon Sep 17 00:00:00 2001 From: Derk-Jan Karrenbeld Date: Thu, 24 Dec 2020 23:19:54 +0100 Subject: [PATCH 13/36] Link directories --- package.json | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/package.json b/package.json index e2577616..2bab61ca 100644 --- a/package.json +++ b/package.json @@ -9,6 +9,12 @@ "type": "git", "url": "https://github.com/exercism/javascript-test-runner" }, + "directories": { + "lib": "./dist", + "bin": "./bin", + "doc": "./docs", + "test": "./test" + }, "scripts": { "execute": "./bin/run.sh", "execute:dev": "yarn build && yarn execute", From 62f7995d950c181c49a51474b3dc757a1ecac9ab Mon Sep 17 00:00:00 2001 From: Derk-Jan Karrenbeld Date: Thu, 24 Dec 2020 23:20:15 +0100 Subject: [PATCH 14/36] Add smoke tests --- test/.eslintrc | 7 + test/fixtures/clock/pass/clock.js | 49 +++++ test/fixtures/clock/pass/clock.spec.js | 219 +++++++++++++++++++++ test/fixtures/two-fer/fail/two-fer.js | 1 + test/fixtures/two-fer/fail/two-fer.spec.js | 17 ++ test/fixtures/two-fer/pass/two-fer.js | 1 + test/fixtures/two-fer/pass/two-fer.spec.js | 17 ++ test/smoke.test.ts | 112 +++++++++++ test/tsconfig.json | 10 + 9 files changed, 433 insertions(+) create mode 100644 test/.eslintrc create mode 100644 test/fixtures/clock/pass/clock.js create mode 100644 test/fixtures/clock/pass/clock.spec.js create mode 100644 test/fixtures/two-fer/fail/two-fer.js create mode 100644 test/fixtures/two-fer/fail/two-fer.spec.js create mode 100644 test/fixtures/two-fer/pass/two-fer.js create mode 100644 test/fixtures/two-fer/pass/two-fer.spec.js create mode 100644 test/smoke.test.ts create mode 100644 test/tsconfig.json diff --git a/test/.eslintrc b/test/.eslintrc new file mode 100644 index 00000000..8e22d8df --- /dev/null +++ b/test/.eslintrc @@ -0,0 +1,7 @@ +{ + "plugins": ["jest"], + "globals": { + "jest/globals": true + }, + "extends": ["../.eslintrc", "plugin:jest/recommended"] +} diff --git a/test/fixtures/clock/pass/clock.js b/test/fixtures/clock/pass/clock.js new file mode 100644 index 00000000..f13931b3 --- /dev/null +++ b/test/fixtures/clock/pass/clock.js @@ -0,0 +1,49 @@ +// +// This is only a SKELETON file for the 'Clock' exercise. It's been provided as a +// convenience to get you started writing code faster. +// + +const MINUTES_PER_HOUR = 60 +const HOURS_ON_THE_CLOCK = 24 +const MINUTES_PER_CLOCK = MINUTES_PER_HOUR * HOURS_ON_THE_CLOCK + +function normalize(minutes) { + while (minutes < 0) { + minutes += MINUTES_PER_CLOCK + } + + return minutes % MINUTES_PER_CLOCK +} + +function clockPad(number) { + return String(number).padStart(2, '0') +} + +export class Clock { + constructor(hours, minutes = 0) { + this.minutes = normalize(hours * MINUTES_PER_HOUR + minutes) + } + + toString() { + const hours = Math.floor(this.minutes / MINUTES_PER_HOUR) + const minutes = this.minutes % MINUTES_PER_HOUR + + return `${clockPad(hours)}:${clockPad(minutes)}` + } + + plus(minutes) { + return new Clock(0, this.minutes + minutes) + } + + minus(minutes) { + return this.plus(-minutes) + } + + valueOf() { + return this.minutes + } + + equals(other) { + return +other === +this + } +} diff --git a/test/fixtures/clock/pass/clock.spec.js b/test/fixtures/clock/pass/clock.spec.js new file mode 100644 index 00000000..8414f446 --- /dev/null +++ b/test/fixtures/clock/pass/clock.spec.js @@ -0,0 +1,219 @@ +import { Clock } from './clock'; + +describe('Clock', () => { + describe('Creating a new clock with an initial time', () => { + test('on the hour', () => { + expect(new Clock(8).toString()).toEqual('08:00'); + }); + + test('past the hour', () => { + expect(new Clock(11, 9).toString()).toEqual('11:09'); + }); + + test('midnight is zero hours', () => { + expect(new Clock(24, 0).toString()).toEqual('00:00'); + }); + + test('hour rolls over', () => { + expect(new Clock(25, 0).toString()).toEqual('01:00'); + }); + + test('hour rolls over continuously', () => { + expect(new Clock(100, 0).toString()).toEqual('04:00'); + }); + + test('sixty minutes is next hour', () => { + expect(new Clock(1, 60).toString()).toEqual('02:00'); + }); + + test('minutes roll over', () => { + expect(new Clock(0, 160).toString()).toEqual('02:40'); + }); + + test('minutes roll over continuously', () => { + expect(new Clock(0, 1723).toString()).toEqual('04:43'); + }); + + test('hour and minutes roll over', () => { + expect(new Clock(25, 160).toString()).toEqual('03:40'); + }); + + test('hour and minutes roll over continuously', () => { + expect(new Clock(201, 3001).toString()).toEqual('11:01'); + }); + + test('hour and minutes roll over to exactly midnight', () => { + expect(new Clock(72, 8640).toString()).toEqual('00:00'); + }); + + test('negative hour', () => { + expect(new Clock(-1, 15).toString()).toEqual('23:15'); + }); + + test('negative hour rolls over', () => { + expect(new Clock(-25, 0).toString()).toEqual('23:00'); + }); + + test('negative hour rolls over continuously', () => { + expect(new Clock(-91, 0).toString()).toEqual('05:00'); + }); + + test('negative minutes', () => { + expect(new Clock(1, -40).toString()).toEqual('00:20'); + }); + + test('negative minutes rolls over', () => { + expect(new Clock(1, -160).toString()).toEqual('22:20'); + }); + + test('negative minutes rolls over continuously', () => { + expect(new Clock(1, -4820).toString()).toEqual('16:40'); + }); + + test('negative sixty minutes is previous hour', () => { + expect(new Clock(2, -60).toString()).toEqual('01:00'); + }); + + test('negative hour and minutes both roll over', () => { + expect(new Clock(-25, -160).toString()).toEqual('20:20'); + }); + + test('negative hour and minutes both roll over continuously', () => { + expect(new Clock(-121, -5810).toString()).toEqual('22:10'); + }); + }); + + describe('Adding minutes', () => { + test('add minutes', () => { + expect(new Clock(10, 0).plus(3).toString()).toEqual('10:03'); + }); + + test('add no minutes', () => { + expect(new Clock(6, 41).plus(0).toString()).toEqual('06:41'); + }); + + test('add to next hour', () => { + expect(new Clock(0, 45).plus(40).toString()).toEqual('01:25'); + }); + + test('add more than one hour', () => { + expect(new Clock(10, 0).plus(61).toString()).toEqual('11:01'); + }); + + test('add more than two hours with carry', () => { + expect(new Clock(0, 45).plus(160).toString()).toEqual('03:25'); + }); + + test('add across midnight', () => { + expect(new Clock(23, 59).plus(2).toString()).toEqual('00:01'); + }); + + test('add more than one day (1500 min = 25 hrs)', () => { + expect(new Clock(5, 32).plus(1500).toString()).toEqual('06:32'); + }); + + test('add more than two days', () => { + expect(new Clock(1, 1).plus(3500).toString()).toEqual('11:21'); + }); + }); + + describe('Subtract minutes', () => { + test('subtract minutes', () => { + expect(new Clock(10, 3).minus(3).toString()).toEqual('10:00'); + }); + + test('subtract to previous hour', () => { + expect(new Clock(10, 3).minus(30).toString()).toEqual('09:33'); + }); + + test('subtract more than an hour', () => { + expect(new Clock(10, 3).minus(70).toString()).toEqual('08:53'); + }); + + test('subtract across midnight', () => { + expect(new Clock(0, 3).minus(4).toString()).toEqual('23:59'); + }); + + test('subtract more than two hours', () => { + expect(new Clock(0, 0).minus(160).toString()).toEqual('21:20'); + }); + + test('subtract more than two hours with borrow', () => { + expect(new Clock(6, 15).minus(160).toString()).toEqual('03:35'); + }); + + test('subtract more than one day (1500 min = 25 hrs)', () => { + expect(new Clock(5, 32).minus(1500).toString()).toEqual('04:32'); + }); + + test('subtract more than two days', () => { + expect(new Clock(2, 20).minus(3000).toString()).toEqual('00:20'); + }); + }); + + describe('Compare two clocks for equality', () => { + test('clocks with same time', () => { + expect(new Clock(15, 37).equals(new Clock(15, 37))).toBe(true); + }); + + test('clocks a minute apart', () => { + expect(new Clock(15, 36).equals(new Clock(15, 37))).toBe(false); + }); + + test('clocks an hour apart', () => { + expect(new Clock(14, 37).equals(new Clock(15, 37))).toBe(false); + }); + + test('clocks with hour overflow', () => { + expect(new Clock(10, 37).equals(new Clock(34, 37))).toBe(true); + }); + + test('clocks with hour overflow by several days', () => { + expect(new Clock(3, 11).equals(new Clock(99, 11))).toBe(true); + }); + + test('clocks with negative hour', () => { + expect(new Clock(22, 40).equals(new Clock(-2, 40))).toBe(true); + }); + + test('clocks with negative hour that wraps', () => { + expect(new Clock(17, 3).equals(new Clock(-31, 3))).toBe(true); + }); + + test('clocks with negative hour that wraps multiple times', () => { + expect(new Clock(13, 49).equals(new Clock(-83, 49))).toBe(true); + }); + + test('clocks with minute overflow', () => { + expect(new Clock(0, 1).equals(new Clock(0, 1441))).toBe(true); + }); + + test('clocks with minute overflow by several days', () => { + expect(new Clock(2, 2).equals(new Clock(2, 4322))).toBe(true); + }); + + test('clocks with negative minute', () => { + expect(new Clock(2, 40).equals(new Clock(3, -20))).toBe(true); + }); + + test('clocks with negative minute that wraps', () => { + expect(new Clock(4, 10).equals(new Clock(5, -1490))).toBe(true); + }); + + test('clocks with negative minute that wraps multiple times', () => { + expect(new Clock(6, 15).equals(new Clock(6, -4305))).toBe(true); + }); + + test('clocks with negative hours and minutes', () => { + expect(new Clock(7, 32).equals(new Clock(-12, -268))).toBe(true); + }); + + test('clocks with negative hours and minutes that wrap', () => { + expect(new Clock(18, 7).equals(new Clock(-54, -11513))).toBe(true); + }); + + test('full clock and zeroed clock', () => { + expect(new Clock(24, 0).equals(new Clock(0, 0))).toBe(true); + }); + }); +}); diff --git a/test/fixtures/two-fer/fail/two-fer.js b/test/fixtures/two-fer/fail/two-fer.js new file mode 100644 index 00000000..8b1d4ccd --- /dev/null +++ b/test/fixtures/two-fer/fail/two-fer.js @@ -0,0 +1 @@ +export const twoFer = () => `One for you, one for me.` diff --git a/test/fixtures/two-fer/fail/two-fer.spec.js b/test/fixtures/two-fer/fail/two-fer.spec.js new file mode 100644 index 00000000..97ed7a9b --- /dev/null +++ b/test/fixtures/two-fer/fail/two-fer.spec.js @@ -0,0 +1,17 @@ +import { twoFer } from './two-fer'; + +describe('twoFer()', () => { + test('no name given', () => { + expect(twoFer()).toEqual('One for you, one for me.'); + }); + + test('a name given', () => { + const name = 'Alice'; + expect(twoFer(name)).toEqual('One for Alice, one for me.'); + }); + + test('another name given', () => { + const name = 'Bob'; + expect(twoFer(name)).toEqual('One for Bob, one for me.'); + }); +}); diff --git a/test/fixtures/two-fer/pass/two-fer.js b/test/fixtures/two-fer/pass/two-fer.js new file mode 100644 index 00000000..e4b18142 --- /dev/null +++ b/test/fixtures/two-fer/pass/two-fer.js @@ -0,0 +1 @@ +export const twoFer = (name = 'you') => `One for ${name}, one for me.` diff --git a/test/fixtures/two-fer/pass/two-fer.spec.js b/test/fixtures/two-fer/pass/two-fer.spec.js new file mode 100644 index 00000000..97ed7a9b --- /dev/null +++ b/test/fixtures/two-fer/pass/two-fer.spec.js @@ -0,0 +1,17 @@ +import { twoFer } from './two-fer'; + +describe('twoFer()', () => { + test('no name given', () => { + expect(twoFer()).toEqual('One for you, one for me.'); + }); + + test('a name given', () => { + const name = 'Alice'; + expect(twoFer(name)).toEqual('One for Alice, one for me.'); + }); + + test('another name given', () => { + const name = 'Bob'; + expect(twoFer(name)).toEqual('One for Bob, one for me.'); + }); +}); diff --git a/test/smoke.test.ts b/test/smoke.test.ts new file mode 100644 index 00000000..cc503df2 --- /dev/null +++ b/test/smoke.test.ts @@ -0,0 +1,112 @@ +import { spawnSync } from 'child_process' +import { join, resolve } from 'path' +import { lstat, mkdtempSync, readFileSync } from 'fs' +import { tmpdir } from 'os' + +const bin = resolve(__dirname, '..', 'bin') +const fixtures = resolve(__dirname, 'fixtures') +const run = resolve(bin, 'run.sh') + +describe('javascript-test-runner', () => { + describe('passing solution', () => { + test('can run the tests', () => { + const spawned = spawnSync( + 'bash', + [run, 'two-fer', join(fixtures, 'two-fer', 'pass')], + { + stdio: 'pipe', + } + ) + + if (spawned.stderr?.length) { + console.warn('Did not expect anything logged to stderr.') + console.warn(spawned.stderr.toString()) + } + + expect(spawned.status).toBe(0) + }) + + test('generates a result.json', () => { + spawnSync('bash', [run, 'two-fer', join(fixtures, 'two-fer', 'pass')], { + stdio: 'pipe', + }) + + return new Promise((resolve, reject) => { + const resultPath = join(fixtures, 'two-fer', 'pass', 'results.json') + lstat(resultPath, (err, _) => { + expect(err).toBeNull() + + const result = JSON.parse(readFileSync(resultPath).toString()) + expect(result.status).toBe('pass') + + if (err) { + reject(err) + } else { + resolve('') + } + }) + }) + }) + + test('generates a result.json at the correct location', () => { + const outputDir = mkdtempSync(join(tmpdir(), 'foo-')) + + spawnSync( + 'bash', + [run, 'clock', join(fixtures, 'clock', 'pass'), outputDir], + { + stdio: 'pipe', + } + ) + + return new Promise((resolve, reject) => { + lstat(join(outputDir, 'results.json'), (err, _) => { + expect(err).toBeNull() + + if (err) { + reject(err) + } else { + resolve('') + } + }) + }) + }) + }) + + describe('failing solution', () => { + test('can run the tests', () => { + const spawned = spawnSync( + 'bash', + [run, 'two-fer', join(fixtures, 'two-fer', 'fail')], + { + stdio: 'pipe', + } + ) + + // Even when the tests fail, the status should be 0 + expect(spawned.status).toBe(0) + }) + + test('generates a result.json', () => { + spawnSync('bash', [run, 'two-fer', join(fixtures, 'two-fer', 'fail')], { + stdio: 'pipe', + }) + + return new Promise((resolve, reject) => { + const resultPath = join(fixtures, 'two-fer', 'fail', 'results.json') + lstat(resultPath, (err, _) => { + expect(err).toBeNull() + + const result = JSON.parse(readFileSync(resultPath).toString()) + expect(result.status).toBe('fail') + + if (err) { + reject(err) + } else { + resolve('') + } + }) + }) + }) + }) +}) diff --git a/test/tsconfig.json b/test/tsconfig.json new file mode 100644 index 00000000..776a2c3c --- /dev/null +++ b/test/tsconfig.json @@ -0,0 +1,10 @@ +{ + "composite": true, + "extends": "../tsconfig.json", + "compilerOptions": { + "baseUrl": "./", + "noEmit": true + }, + "include": ["./", "../src"], + "exclude": ["./fixtures"] +} From d1a581b94465bda34deadb1095c54b61cab5563e Mon Sep 17 00:00:00 2001 From: Derk-Jan Karrenbeld Date: Thu, 24 Dec 2020 23:20:51 +0100 Subject: [PATCH 15/36] Format the code --- babel.config.js | 3 +- jest.config.js | 14 ++-- src/declarations.d.ts | 2 +- src/getResultHeader.ts | 48 ++++++----- src/getSnapshotStatus.ts | 41 ++++----- src/getSummary.ts | 77 +++++++++-------- src/getTestResults.ts | 85 ++++++++++--------- src/jest/console.ts | 40 ++++----- src/jest/setup.ts | 12 ++- src/output.ts | 93 ++++++++++++++------- src/reporter.ts | 25 ++++-- src/status.ts | 147 +++++++++++++++++---------------- src/stdlib.ts | 66 +++++++-------- src/utils/formatTestPath.ts | 13 +-- src/utils/pluralize.ts | 2 +- src/utils/printDisplayName.ts | 8 +- src/utils/relativePath.ts | 16 ++-- src/utils/renderTime.ts | 24 +++--- src/utils/trimAndFormatPath.ts | 31 ++++--- src/utils/wrapAnsiString.ts | 48 +++++------ tsconfig.json | 26 +++--- 21 files changed, 454 insertions(+), 367 deletions(-) diff --git a/babel.config.js b/babel.config.js index 9da4622b..5c5b78a5 100644 --- a/babel.config.js +++ b/babel.config.js @@ -8,7 +8,6 @@ module.exports = { }, useBuiltIns: false, }, - ], ], -}; +} diff --git a/jest.config.js b/jest.config.js index 0e4882c2..507408b6 100644 --- a/jest.config.js +++ b/jest.config.js @@ -1,9 +1,7 @@ module.exports = { - "verbose": true, - "modulePathIgnorePatterns": [ - "package.json" - ], - "transform": { - "^.+\\.[t|j]sx?$": "babel-jest" - } -}; + verbose: true, + modulePathIgnorePatterns: ['package.json'], + transform: { + '^.+\\.[t|j]sx?$': 'babel-jest', + }, +} diff --git a/src/declarations.d.ts b/src/declarations.d.ts index a09d0c89..c21237c0 100644 --- a/src/declarations.d.ts +++ b/src/declarations.d.ts @@ -1 +1 @@ -declare type Window = {} +declare type Window = unknown diff --git a/src/getResultHeader.ts b/src/getResultHeader.ts index e676f7fa..73d0172a 100644 --- a/src/getResultHeader.ts +++ b/src/getResultHeader.ts @@ -1,5 +1,5 @@ import chalk from 'chalk' -import {getConsoleOutput} from '@jest/console'; +import { getConsoleOutput } from '@jest/console' import { Config } from '@jest/types' import { TestResult } from '@jest/test-result' @@ -7,54 +7,58 @@ import { TestResult } from '@jest/test-result' import { formatTestPath } from './utils/formatTestPath' import { printDisplayName } from './utils/printDisplayName' -const LONG_TEST_COLOR = chalk.reset.bold.bgRed; -const TITLE_BULLET = chalk.bold('\u25cf '); +const LONG_TEST_COLOR = chalk.reset.bold.bgRed +const TITLE_BULLET = chalk.bold('\u25cf ') // Explicitly reset for these messages since they can get written out in the // middle of error logging -const FAIL_TEXT = 'FAIL'; -const PASS_TEXT = 'PASS'; +const FAIL_TEXT = 'FAIL' +const PASS_TEXT = 'PASS' const FAIL = chalk.supportsColor ? chalk.reset.inverse.bold.red(` ${FAIL_TEXT} `) - : FAIL_TEXT; + : FAIL_TEXT const PASS = chalk.supportsColor ? chalk.reset.inverse.bold.green(` ${PASS_TEXT} `) - : PASS_TEXT; + : PASS_TEXT -export function getResultHeader(result: TestResult, globalConfig: Config.GlobalConfig, projectConfig: Config.ProjectConfig): string { - const testPath = result.testFilePath; +export function getResultHeader( + result: TestResult, + globalConfig: Config.GlobalConfig, + projectConfig: Config.ProjectConfig +): string { + const testPath = result.testFilePath const status = - result.numFailingTests > 0 || result.testExecError ? FAIL : PASS; + result.numFailingTests > 0 || result.testExecError ? FAIL : PASS const runTime = result.perfStats ? (result.perfStats.end - result.perfStats.start) / 1000 - : null; + : null - const testDetail = []; + const testDetail = [] if (runTime !== null && runTime > 5) { - testDetail.push(LONG_TEST_COLOR(`${runTime}s`)); + testDetail.push(LONG_TEST_COLOR(`${runTime}s`)) } if (result.memoryUsage) { - const toMB = (bytes: number): number => Math.floor(bytes / 1024 / 1024); - testDetail.push(`${toMB(result.memoryUsage)} MB heap size`); + const toMB = (bytes: number): number => Math.floor(bytes / 1024 / 1024) + testDetail.push(`${toMB(result.memoryUsage)} MB heap size`) } const projectDisplayName = projectConfig && projectConfig.displayName ? `${printDisplayName(projectConfig)} ` - : ''; + : '' const testPathDetails = formatTestPath( projectConfig || globalConfig, testPath - ); + ) - const testDetails = testDetail.length ? ` (${testDetail.join(', ')})` : ''; + const testDetails = testDetail.length ? ` (${testDetail.join(', ')})` : '' - let consoleResult = ''; + let consoleResult = '' if (result.console && result.console.length) { consoleResult = '\n ' + @@ -64,8 +68,8 @@ export function getResultHeader(result: TestResult, globalConfig: Config.GlobalC projectConfig.cwd, !!globalConfig.verbose, result.console - ); + ) } - return `${status} ${projectDisplayName}${testPathDetails}${testDetails}${consoleResult}`; -}; + return `${status} ${projectDisplayName}${testPathDetails}${testDetails}${consoleResult}` +} diff --git a/src/getSnapshotStatus.ts b/src/getSnapshotStatus.ts index 2c60724a..f7a4dd70 100644 --- a/src/getSnapshotStatus.ts +++ b/src/getSnapshotStatus.ts @@ -3,22 +3,25 @@ import { pluralize } from './utils/pluralize' import { TestResult } from '@jest/test-result' -const ARROW = ' \u203A '; -const DOT = ' \u2022 '; -const FAIL_COLOR = chalk.bold.red; -const SNAPSHOT_ADDED = chalk.bold.green; -const SNAPSHOT_UPDATED = chalk.bold.green; -const SNAPSHOT_OUTDATED = chalk.bold.yellow; +const ARROW = ' \u203A ' +const DOT = ' \u2022 ' +const FAIL_COLOR = chalk.bold.red +const SNAPSHOT_ADDED = chalk.bold.green +const SNAPSHOT_UPDATED = chalk.bold.green +const SNAPSHOT_OUTDATED = chalk.bold.yellow -export function getSnapshotStatus(snapshot: TestResult['snapshot'], afterUpdate: boolean): string[] { - const statuses: string[] = []; +export function getSnapshotStatus( + snapshot: TestResult['snapshot'], + afterUpdate: boolean +): string[] { + const statuses: string[] = [] if (snapshot.added) { statuses.push( SNAPSHOT_ADDED( `${ARROW + pluralize('snapshot', snapshot.added)} written.` ) - ); + ) } if (snapshot.updated) { @@ -26,13 +29,13 @@ export function getSnapshotStatus(snapshot: TestResult['snapshot'], afterUpdate: SNAPSHOT_UPDATED( `${ARROW + pluralize('snapshot', snapshot.updated)} updated.` ) - ); + ) } if (snapshot.unmatched) { statuses.push( FAIL_COLOR(`${ARROW + pluralize('snapshot', snapshot.unmatched)} failed.`) - ); + ) } if (snapshot.unchecked) { @@ -41,25 +44,25 @@ export function getSnapshotStatus(snapshot: TestResult['snapshot'], afterUpdate: SNAPSHOT_UPDATED( `${ARROW + pluralize('snapshot', snapshot.unchecked)} removed.` ) - ); + ) } else { statuses.push( `${SNAPSHOT_OUTDATED( `${ARROW + pluralize('snapshot', snapshot.unchecked)} obsolete` )}.` - ); + ) } if ((snapshot as any).uncheckedKeys) { - (snapshot as any).uncheckedKeys.forEach((key: string) => { - statuses.push(` ${DOT}${key}`); - }); + ;(snapshot as any).uncheckedKeys.forEach((key: string) => { + statuses.push(` ${DOT}${key}`) + }) } } if (snapshot.fileDeleted) { - statuses.push(SNAPSHOT_UPDATED(`${ARROW}snapshot file removed.`)); + statuses.push(SNAPSHOT_UPDATED(`${ARROW}snapshot file removed.`)) } - return statuses; -}; + return statuses +} diff --git a/src/getSummary.ts b/src/getSummary.ts index 292edb18..5018d6f7 100644 --- a/src/getSummary.ts +++ b/src/getSummary.ts @@ -5,53 +5,57 @@ import { AggregatedResult } from '@jest/test-result' import { pluralize } from './utils/pluralize' import { renderTime } from './utils/renderTime' -export function getSummary(aggregatedResults: AggregatedResult, options?: { roundTime?: boolean; estimatedTime?: number, width?: number }): string { - let runTime = (Date.now() - aggregatedResults.startTime) / 1000; +export function getSummary( + aggregatedResults: AggregatedResult, + options?: { roundTime?: boolean; estimatedTime?: number; width?: number } +): string { + let runTime = (Date.now() - aggregatedResults.startTime) / 1000 if (options && options.roundTime) { - runTime = Math.floor(runTime); + runTime = Math.floor(runTime) } - const estimatedTime = (options && options.estimatedTime) || 0; - const snapshotResults = aggregatedResults.snapshot; - const snapshotsAdded = snapshotResults.added; - const snapshotsFailed = snapshotResults.unmatched; - const snapshotsOutdated = snapshotResults.unchecked; - const snapshotsFilesRemoved = snapshotResults.filesRemoved; - const snapshotsDidUpdate = snapshotResults.didUpdate; - const snapshotsPassed = snapshotResults.matched; - const snapshotsTotal = snapshotResults.total; - const snapshotsUpdated = snapshotResults.updated; - const suitesFailed = aggregatedResults.numFailedTestSuites; - const suitesPassed = aggregatedResults.numPassedTestSuites; - const suitesPending = aggregatedResults.numPendingTestSuites; - const suitesRun = suitesFailed + suitesPassed; - const suitesTotal = aggregatedResults.numTotalTestSuites; - const testsFailed = aggregatedResults.numFailedTests; - const testsPassed = aggregatedResults.numPassedTests; - const testsPending = aggregatedResults.numPendingTests; - const testsTodo = aggregatedResults.numTodoTests; - const testsTotal = aggregatedResults.numTotalTests; - const width = (options && options.width) || 0; + const estimatedTime = (options && options.estimatedTime) || 0 + const snapshotResults = aggregatedResults.snapshot + const snapshotsAdded = snapshotResults.added + const snapshotsFailed = snapshotResults.unmatched + const snapshotsOutdated = snapshotResults.unchecked + const snapshotsFilesRemoved = snapshotResults.filesRemoved + const snapshotsDidUpdate = snapshotResults.didUpdate + const snapshotsPassed = snapshotResults.matched + const snapshotsTotal = snapshotResults.total + const snapshotsUpdated = snapshotResults.updated + const suitesFailed = aggregatedResults.numFailedTestSuites + const suitesPassed = aggregatedResults.numPassedTestSuites + const suitesPending = aggregatedResults.numPendingTestSuites + const suitesRun = suitesFailed + suitesPassed + const suitesTotal = aggregatedResults.numTotalTestSuites + const testsFailed = aggregatedResults.numFailedTests + const testsPassed = aggregatedResults.numPassedTests + const testsPending = aggregatedResults.numPendingTests + const testsTodo = aggregatedResults.numTodoTests + const testsTotal = aggregatedResults.numTotalTests + const width = (options && options.width) || 0 - const suites = `${chalk.bold('Test Suites: ') + + const suites = `${ + chalk.bold('Test Suites: ') + (suitesFailed ? `${chalk.bold.red(`${suitesFailed} failed`)}, ` : '') + (suitesPending ? `${chalk.bold.yellow(`${suitesPending} skipped`)}, ` : '') + (suitesPassed ? `${chalk.bold.green(`${suitesPassed} passed`)}, ` : '') + - (suitesRun !== suitesTotal - ? `${suitesRun} of ${suitesTotal}` - : suitesTotal)} total`; + (suitesRun !== suitesTotal ? `${suitesRun} of ${suitesTotal}` : suitesTotal) + } total` - const tests = `${chalk.bold('Tests: ') + + const tests = `${ + chalk.bold('Tests: ') + (testsFailed ? `${chalk.bold.red(`${testsFailed} failed`)}, ` : '') + (testsPending ? `${chalk.bold.yellow(`${testsPending} skipped`)}, ` : '') + (testsTodo ? `${chalk.bold.magenta(`${testsTodo} todo`)}, ` : '') + - (testsPassed - ? `${chalk.bold.green(`${testsPassed} passed`)}, ` - : '')}${testsTotal} total`; + (testsPassed ? `${chalk.bold.green(`${testsPassed} passed`)}, ` : '') + }${testsTotal} total` - const snapshots = `${chalk.bold('Snapshots: ') + + const snapshots = `${ + chalk.bold('Snapshots: ') + (snapshotsFailed ? `${chalk.bold.red(`${snapshotsFailed} failed`)}, ` : '') + @@ -79,9 +83,10 @@ export function getSummary(aggregatedResults: AggregatedResult, options?: { roun : '') + (snapshotsPassed ? `${chalk.bold.green(`${snapshotsPassed} passed`)}, ` - : '')}${snapshotsTotal} total`; + : '') + }${snapshotsTotal} total` - const time = renderTime(runTime, estimatedTime, width); + const time = renderTime(runTime, estimatedTime, width) - return [suites, tests, snapshots, time].join('\n'); + return [suites, tests, snapshots, time].join('\n') } diff --git a/src/getTestResults.ts b/src/getTestResults.ts index 6264ab2d..210b26e3 100644 --- a/src/getTestResults.ts +++ b/src/getTestResults.ts @@ -1,9 +1,9 @@ import chalk from 'chalk' -import { specialChars } from 'jest-util'; +import { specialChars } from 'jest-util' import { Status, AssertionResult, TestResult } from '@jest/test-result' -const { ICONS } = specialChars; +const { ICONS } = specialChars interface TestSuite { suites: TestSuite[] @@ -14,80 +14,83 @@ interface TestSuite { type TestsBySuites = TestSuite export function getTestResults(testResults: TestResult['testResults']) { - const testSuites = groupTestsBySuites(testResults); + const testSuites = groupTestsBySuites(testResults) - return getLogSuite(testSuites, 0); -}; + return getLogSuite(testSuites, 0) +} function groupTestsBySuites(testResults: TestResult['testResults']) { - const output: TestsBySuites = { suites: [], tests: [], title: '' }; + const output: TestsBySuites = { suites: [], tests: [], title: '' } testResults.forEach((testResult: AssertionResult) => { - let targetSuite = output; + let targetSuite = output // Find the target suite for this test, // creating nested suites as necessary. for (const title of testResult.ancestorTitles) { - let matchingSuite = targetSuite.suites.find(s => s.title === title); + let matchingSuite = targetSuite.suites.find((s) => s.title === title) if (!matchingSuite) { - matchingSuite = { suites: [], tests: [], title }; - targetSuite.suites.push(matchingSuite); + matchingSuite = { suites: [], tests: [], title } + targetSuite.suites.push(matchingSuite) } - targetSuite = matchingSuite; + targetSuite = matchingSuite } - targetSuite.tests.push(testResult); - }); + targetSuite.tests.push(testResult) + }) - return output; -}; + return output +} export function getLogSuite(suite: TestSuite, indentLevel: number): string { - let output = ''; + let output = '' if (suite.title) { - output += getLine(suite.title, indentLevel); + output += getLine(suite.title, indentLevel) } - output += logTests(suite.tests, indentLevel + 1); + output += logTests(suite.tests, indentLevel + 1) suite.suites.forEach( - suite => (output += getLogSuite(suite, indentLevel + 1)) - ); + (suite) => (output += getLogSuite(suite, indentLevel + 1)) + ) - return output; -}; + return output +} export function getLine(str: string, indentLevel: number): string { - const indentation = ' '.repeat(indentLevel || 0); + const indentation = ' '.repeat(indentLevel || 0) - return `${indentation}${str || ''}\n`; -}; + return `${indentation}${str || ''}\n` +} -export function logTests(tests: AssertionResult[], indentLevel: number): string { - let output = ''; - tests.forEach(test => (output += logTest(test, indentLevel))); +export function logTests( + tests: AssertionResult[], + indentLevel: number +): string { + let output = '' + tests.forEach((test) => (output += logTest(test, indentLevel))) - return output; -}; + return output +} -export function logTest(test: AssertionResult, indentLevel : number) { - const status = getIcon(test.status); - const time = test.duration ? ` (${test.duration.toFixed(0)}ms)` : ''; - const testStatus = `${status} ${chalk.dim(test.title + time)}`; +export function logTest(test: AssertionResult, indentLevel: number) { + const status = getIcon(test.status) + const time = test.duration ? ` (${test.duration.toFixed(0)}ms)` : '' + const testStatus = `${status} ${chalk.dim(test.title + time)}` - return getLine(testStatus, indentLevel); -}; + return getLine(testStatus, indentLevel) +} export function getIcon(status: Status): string { switch (status) { case 'failed': - return chalk.red(ICONS.failed); + return chalk.red(ICONS.failed) case 'pending': - return chalk.yellow(ICONS.pending); + return chalk.yellow(ICONS.pending) case 'skipped': - return chalk.magenta(ICONS.todo); + return chalk.magenta(ICONS.todo) default: - return chalk.green(ICONS.success); + return chalk.green(ICONS.success) } -}; +} diff --git a/src/jest/console.ts b/src/jest/console.ts index fb03ef45..f4479abb 100644 --- a/src/jest/console.ts +++ b/src/jest/console.ts @@ -1,33 +1,33 @@ -import { spyOn } from 'jest-mock'; +import { spyOn } from 'jest-mock' -const defaultKeys = ['debug', 'log', 'info', 'warn', 'error'] as const; +const defaultKeys = ['debug', 'log', 'info', 'warn', 'error'] as const -type ConsoleFunction = jest.FunctionPropertyNames; -type Spies = Record>; +type ConsoleFunction = jest.FunctionPropertyNames +type Spies = Record> interface CapturedConsole { - getSpy(key: ConsoleFunction): jest.SpyInstance; - restore(): void; - clear(): void; - calls(): Record; + getSpy(key: ConsoleFunction): jest.SpyInstance + restore(): void + clear(): void + calls(): Record } function captureConsole( keys?: ConsoleFunction | ReadonlyArray ): CapturedConsole { - const capturedKeys = typeof keys === 'string' ? [keys] : keys || defaultKeys; + const capturedKeys = typeof keys === 'string' ? [keys] : keys || defaultKeys // Capture these const spies = capturedKeys.reduce( (result: Partial, key: ConsoleFunction) => { - result[key] = spyOn(global.console, key) as any; - return result; + result[key] = spyOn(global.console, key) as any + return result }, {} - ) as Spies; + ) as Spies function getSpy(spykey: string) { - return spies[spykey as keyof typeof spies]; + return spies[spykey as keyof typeof spies] } // Return function to restore console @@ -35,20 +35,20 @@ function captureConsole( getSpy: getSpy, restore: () => { - Object.keys(spies).forEach((spykey) => getSpy(spykey).mockRestore()); + Object.keys(spies).forEach((spykey) => getSpy(spykey).mockRestore()) }, clear: () => { - Object.keys(spies).forEach((spykey) => getSpy(spykey).mockClear()); + Object.keys(spies).forEach((spykey) => getSpy(spykey).mockClear()) }, calls: () => { return Object.keys(spies).reduce((result, spyKey) => { - result[spyKey] = [...getSpy(spyKey).mock.calls]; - return result; - }, {} as Record); + result[spyKey] = [...getSpy(spyKey).mock.calls] + return result + }, {} as Record) }, - }; + } } -export default captureConsole; +export default captureConsole diff --git a/src/jest/setup.ts b/src/jest/setup.ts index 509deb7a..a49576ff 100644 --- a/src/jest/setup.ts +++ b/src/jest/setup.ts @@ -2,7 +2,11 @@ import spyConsole from './console' const originalDescribe = (jasmine as any).getEnv().describe -;(jasmine as any).getEnv().describe = (description: string, specDefinitions: (...args: T) => void, ...describeArgs: T) => { +;(jasmine as any).getEnv().describe = ( + description: string, + specDefinitions: (...args: T) => void, + ...describeArgs: T +) => { function spiedSpecDefinition(...args: T) { let restores: Array<() => void> = [] @@ -19,5 +23,9 @@ const originalDescribe = (jasmine as any).getEnv().describe return specDefinitions(...args) } - return (originalDescribe as any)(description, spiedSpecDefinition, ...describeArgs) + return (originalDescribe as any)( + description, + spiedSpecDefinition, + ...describeArgs + ) } diff --git a/src/output.ts b/src/output.ts index d322eecd..0611dae9 100644 --- a/src/output.ts +++ b/src/output.ts @@ -3,7 +3,11 @@ import fs from 'fs' import { trimAndFormatPath } from './utils/trimAndFormatPath' import { ConsoleBuffer } from '@jest/console' -import { AggregatedResult, AssertionResult, TestResult } from '@jest/test-result' +import { + AggregatedResult, + AssertionResult, + TestResult, +} from '@jest/test-result' import { Config } from '@jest/types' interface OutputInterface { @@ -20,7 +24,6 @@ interface OutputTestInterface { } export class Output { - private results: Partial & Pick private readonly globalConfig: Config.GlobalConfig private readonly outputFile: string @@ -28,7 +31,8 @@ export class Output { constructor(globalConfig: Config.GlobalConfig) { this.globalConfig = globalConfig this.results = { tests: [] } - this.outputFile = this.globalConfig.outputFile || path.join(process.cwd(), 'results.json') + this.outputFile = + this.globalConfig.outputFile || path.join(process.cwd(), 'results.json') } error(message: string) { @@ -38,12 +42,13 @@ export class Output { finish(aggregatedResults: AggregatedResult) { if (!this.results.status) { - this.results.status = (aggregatedResults.numRuntimeErrorTestSuites === 0) - && (aggregatedResults.numFailedTestSuites === 0) - && (aggregatedResults.numPendingTests === 0) - && (aggregatedResults.numFailedTests === 0) - ? 'pass' - : 'fail' + this.results.status = + aggregatedResults.numRuntimeErrorTestSuites === 0 && + aggregatedResults.numFailedTestSuites === 0 && + aggregatedResults.numPendingTests === 0 && + aggregatedResults.numFailedTests === 0 + ? 'pass' + : 'fail' } const artifact = JSON.stringify(this.results, undefined, 2) @@ -51,20 +56,38 @@ export class Output { fs.writeFileSync(this.outputFile, artifact) } - testFinished(specFilePath: string, testResult: TestResult, results: AggregatedResult) { + testFinished( + specFilePath: string, + testResult: TestResult, + results: AggregatedResult + ) { // Syntax errors etc. These are runtime errors: failures to run if (results.numRuntimeErrorTestSuites > 0) { - this.error(sanitizeErrorMessage(specFilePath, testResult.failureMessage || 'Something went wrong when running the tests.')) + this.error( + sanitizeErrorMessage( + specFilePath, + testResult.failureMessage || + 'Something went wrong when running the tests.' + ) + ) return } // Suites ran fine. Output regurarly. results.testResults.forEach((testResult) => { - return this.testInnerFinished(specFilePath, testResult, testResult.testResults) + return this.testInnerFinished( + specFilePath, + testResult, + testResult.testResults + ) }) } - testInnerFinished(specFilePath: string, testResult: TestResult, innerResults: AssertionResult[]) { + testInnerFinished( + specFilePath: string, + testResult: TestResult, + innerResults: AssertionResult[] + ) { if (testResult.console) { /* // The code below works, but is not accepted by the current runner spec on exercism @@ -83,15 +106,17 @@ export class Output { }) */ - this.results.message = sanitizeErrorMessage(specFilePath, buildOutput(testResult.console)) + this.results.message = sanitizeErrorMessage( + specFilePath, + buildOutput(testResult.console) + ) } const outputs = buildTestOutput(specFilePath, testResult, innerResults) this.results.tests.push(...outputs.map((r) => ({ ...r, output: null }))) } - testStarted(_path: string) { - } + testStarted(_path: string) {} } function buildOutput(buffer: ConsoleBuffer) { @@ -100,7 +125,9 @@ function buildOutput(buffer: ConsoleBuffer) { .join('\n') if (output.length > 500) { - return output.slice(0, 500 - '... (500 chars max)'.length).concat('... (500 chars max)') + return output + .slice(0, 500 - '... (500 chars max)'.length) + .concat('... (500 chars max)') } return output @@ -112,16 +139,18 @@ function buildTestOutput( inner: AssertionResult[] ): Pick[] { if (testResult.testExecError) { - return [{ - message: sanitizeErrorMessage( - path, - testResult.failureMessage - ? removeStackTrace(testResult.failureMessage) - : testResult.testExecError.message - ), - name: testResult.testFilePath, - status: 'error', - }] + return [ + { + message: sanitizeErrorMessage( + path, + testResult.failureMessage + ? removeStackTrace(testResult.failureMessage) + : testResult.testExecError.message + ), + name: testResult.testFilePath, + status: 'error', + }, + ] } return inner.map((assert) => { @@ -130,8 +159,8 @@ function buildTestOutput( status: assert.status === 'passed' ? 'pass' : 'fail', message: sanitizeErrorMessage( testResult.testFilePath, - assert.failureMessages.map(removeStackTrace).join("\n") - ) + assert.failureMessages.map(removeStackTrace).join('\n') + ), } }) } @@ -141,7 +170,7 @@ function removeStackTrace(message: string): string { if (i === -1) { return message } - const split = message.slice(0, i).lastIndexOf("\n") + const split = message.slice(0, i).lastIndexOf('\n') return split === -1 ? message.slice(0, i).trimEnd() : message.slice(0, split).trimEnd() @@ -152,11 +181,11 @@ function sanitizeErrorMessage(specFilePath: string, message: string): string { path.dirname(specFilePath), path.dirname(path.dirname(specFilePath)), process.cwd(), - path.dirname(process.cwd()) + path.dirname(process.cwd()), ] dirs.forEach((sensativePath) => { - while(message.indexOf(sensativePath) !== -1) { + while (message.indexOf(sensativePath) !== -1) { message = message.replace(sensativePath, '') } }) diff --git a/src/reporter.ts b/src/reporter.ts index 58dfdbf9..77afab7a 100644 --- a/src/reporter.ts +++ b/src/reporter.ts @@ -2,8 +2,13 @@ import { Status } from './status' import { Output } from './output' import { isInteractive } from 'jest-util' -import { Config } from '@jest/types'; -import { Context, Test, Reporter, ReporterOnStartOptions } from '@jest/reporters' +import { Config } from '@jest/types' +import { + Context, + Test, + Reporter, + ReporterOnStartOptions, +} from '@jest/reporters' import { AggregatedResult, TestResult } from '@jest/test-result' import { getResultHeader } from './getResultHeader' @@ -68,7 +73,11 @@ class StandardReporter implements Reporter { * @param testResult * @param results */ - onTestResult(test: Test, testResult: TestResult, results: AggregatedResult): void { + onTestResult( + test: Test, + testResult: TestResult, + results: AggregatedResult + ): void { this.status.testFinished(test.context.config, testResult, results) this.output.testFinished(test.path, testResult, results) @@ -90,10 +99,7 @@ class StandardReporter implements Reporter { } const didUpdate = this.globalConfig.updateSnapshot === 'all' - const snapshotStatuses = getSnapshotStatus( - testResult.snapshot, - didUpdate - ) + const snapshotStatuses = getSnapshotStatus(testResult.snapshot, didUpdate) snapshotStatuses.forEach(this.stdlib.log.bind(this.stdlib)) } this.stdlib.forceFlushBufferedOutput() @@ -103,7 +109,10 @@ class StandardReporter implements Reporter { * @param contexts * @param aggregatedResults */ - onRunComplete(_contexts: Set, aggregatedResults: AggregatedResult): Promise | void { + onRunComplete( + _contexts: Set, + aggregatedResults: AggregatedResult + ): Promise | void { this.stdlib.log(getSummary(aggregatedResults, undefined)) this.status.runFinished() this.stdlib.close() diff --git a/src/status.ts b/src/status.ts index 1771804e..a2a96f90 100644 --- a/src/status.ts +++ b/src/status.ts @@ -9,8 +9,8 @@ import { trimAndFormatPath } from './utils/trimAndFormatPath' import { wrapAnsiString } from './utils/wrapAnsiString' import { printDisplayName } from './utils/printDisplayName' -const RUNNING_TEXT = ' RUNS '; -const RUNNING = `${chalk.reset.inverse.yellow.bold(RUNNING_TEXT)} `; +const RUNNING_TEXT = ' RUNS ' +const RUNNING = `${chalk.reset.inverse.yellow.bold(RUNNING_TEXT)} ` interface TestRecord { testPath: string @@ -23,31 +23,31 @@ interface TestRecord { * shifting the whole list. */ class CurrentTestList { - _array: Array; + _array: Array constructor() { - this._array = []; + this._array = [] } add(testPath: string, config: Config.ProjectConfig) { - const index = this._array.indexOf(null); - const record = { config, testPath }; + const index = this._array.indexOf(null) + const record = { config, testPath } if (index !== -1) { - this._array[index] = record; + this._array[index] = record } else { - this._array.push(record); + this._array.push(record) } } delete(testPath: string) { const record = this._array.find( - record => record && record.testPath === testPath - ); - this._array[this._array.indexOf(record || null)] = null; + (record) => record && record.testPath === testPath + ) + this._array[this._array.indexOf(record || null)] = null } get() { - return this._array; + return this._array } } @@ -57,123 +57,130 @@ class CurrentTestList { * from the terminal. */ export class Status { - private readonly _currentTests: CurrentTestList; - private _callback?: () => void; - private _height: number; - private _done: boolean; - private _emitScheduled: boolean; - private _estimatedTime: number; - private _showStatus: boolean; - private _cache: null | { clear: string; content: string }; - private _aggregatedResults?: AggregatedResult; - private _interval?: NodeJS.Timeout; - private _lastUpdated?: number; + private readonly _currentTests: CurrentTestList + private _callback?: () => void + private _height: number + private _done: boolean + private _emitScheduled: boolean + private _estimatedTime: number + private _showStatus: boolean + private _cache: null | { clear: string; content: string } + private _aggregatedResults?: AggregatedResult + private _interval?: NodeJS.Timeout + private _lastUpdated?: number constructor() { - this._cache = null; - this._currentTests = new CurrentTestList(); - this._done = false; - this._emitScheduled = false; - this._estimatedTime = 0; - this._height = 0; - this._showStatus = false; + this._cache = null + this._currentTests = new CurrentTestList() + this._done = false + this._emitScheduled = false + this._estimatedTime = 0 + this._height = 0 + this._showStatus = false } onChange(callback = () => {}) { - this._callback = callback; + this._callback = callback } - runStarted(aggregatedResults: AggregatedResult, options: ReporterOnStartOptions) { - this._estimatedTime = (options && options.estimatedTime) || 0; - this._showStatus = options && options.showStatus; - this._interval = setInterval(() => this._tick(), 1000); - this._aggregatedResults = aggregatedResults; - this._debouncedEmit(); + runStarted( + aggregatedResults: AggregatedResult, + options: ReporterOnStartOptions + ) { + this._estimatedTime = (options && options.estimatedTime) || 0 + this._showStatus = options && options.showStatus + this._interval = setInterval(() => this._tick(), 1000) + this._aggregatedResults = aggregatedResults + this._debouncedEmit() } runFinished() { - this._done = true; - clearInterval(this._interval!); - this._emit(); + this._done = true + clearInterval(this._interval!) + this._emit() } testStarted(testPath: string, config: Config.ProjectConfig) { - this._currentTests.add(testPath, config); + this._currentTests.add(testPath, config) if (!this._showStatus) { - this._emit(); + this._emit() } else { - this._debouncedEmit(); + this._debouncedEmit() } } - testFinished(_config: unknown, testResult: TestResult, aggregatedResults: AggregatedResult) { - const { testFilePath } = testResult; - this._aggregatedResults = aggregatedResults; - this._currentTests.delete(testFilePath); - this._debouncedEmit(); + testFinished( + _config: unknown, + testResult: TestResult, + aggregatedResults: AggregatedResult + ) { + const { testFilePath } = testResult + this._aggregatedResults = aggregatedResults + this._currentTests.delete(testFilePath) + this._debouncedEmit() } get() { if (this._cache) { - return this._cache; + return this._cache } if (this._done) { - return { clear: '', content: '' }; + return { clear: '', content: '' } } // $FlowFixMe - const width = process.stdout.columns; - let content = '\n'; - this._currentTests.get().forEach(record => { + const width = process.stdout.columns + let content = '\n' + this._currentTests.get().forEach((record) => { if (record) { - const { config, testPath } = record; + const { config, testPath } = record const projectDisplayName = config.displayName ? `${printDisplayName(config)} ` - : ''; - const prefix = RUNNING + projectDisplayName; + : '' + const prefix = RUNNING + projectDisplayName content += `${wrapAnsiString( prefix + trimAndFormatPath(stringLength(prefix), config, testPath, width), width - )}\n`; + )}\n` } - }); + }) - let height = 0; + let height = 0 for (let i = 0; i < content.length; i++) { if (content[i] === '\n') { - height++; + height++ } } - const clear = '\r\x1B[K\r\x1B[1A'.repeat(height); + const clear = '\r\x1B[K\r\x1B[1A'.repeat(height) - return (this._cache = { clear, content }); + return (this._cache = { clear, content }) } _emit() { - this._cache = null; - this._lastUpdated = Date.now(); - this._callback && this._callback(); + this._cache = null + this._lastUpdated = Date.now() + this._callback && this._callback() } _debouncedEmit() { if (!this._emitScheduled) { // Perf optimization to avoid two separate renders When // one test finishes and another test starts executing. - this._emitScheduled = true; + this._emitScheduled = true setTimeout(() => { - this._emit(); - this._emitScheduled = false; - }, 100); + this._emit() + this._emitScheduled = false + }, 100) } } _tick() { - this._debouncedEmit(); + this._debouncedEmit() } } diff --git a/src/stdlib.ts b/src/stdlib.ts index ae595d5e..ef46cb8e 100644 --- a/src/stdlib.ts +++ b/src/stdlib.ts @@ -9,84 +9,84 @@ export class Stdlib { private readonly bufferedOutput: Set<() => void> constructor(globalConfig: Config.GlobalConfig) { - this.out = process.stdout.write.bind(process.stdout); - this.err = process.stderr.write.bind(process.stderr); - this.useStderr = globalConfig.useStderr; - this.bufferedOutput = new Set(); - this.wrapStdio(process.stdout); - this.wrapStdio(process.stderr); + this.out = process.stdout.write.bind(process.stdout) + this.err = process.stderr.write.bind(process.stderr) + this.useStderr = globalConfig.useStderr + this.bufferedOutput = new Set() + this.wrapStdio(process.stdout) + this.wrapStdio(process.stderr) } log(message: string) { if (this.useStderr) { - this.err(`${message}\n`); + this.err(`${message}\n`) } else { - this.out(`${message}\n`); + this.out(`${message}\n`) } } error(message: string) { - this.err(`${message}\n`); + this.err(`${message}\n`) } clear() { - clearLine(process.stdout); - clearLine(process.stderr); + clearLine(process.stdout) + clearLine(process.stderr) } close() { - this.forceFlushBufferedOutput(); - process.stdout.write = this.out; - process.stderr.write = this.err; + this.forceFlushBufferedOutput() + process.stdout.write = this.out + process.stderr.write = this.err } // Don't wait for the debounced call and flush all output immediately. forceFlushBufferedOutput() { for (const flushBufferedOutput of this.bufferedOutput) { - flushBufferedOutput(); + flushBufferedOutput() } } wrapStdio(stream: NodeJS.WritableStream) { - const originalWrite = stream.write; + const originalWrite = stream.write - let buffer: Parameters[0][] = []; - let timeout: NodeJS.Timeout | null = null; + let buffer: Parameters[0][] = [] + let timeout: NodeJS.Timeout | null = null const flushBufferedOutput = () => { - const string = buffer.join(''); - buffer = []; + const string = buffer.join('') + buffer = [] if (string) { - originalWrite.call(stream, string); + originalWrite.call(stream, string) } - this.bufferedOutput.delete(flushBufferedOutput); - }; + this.bufferedOutput.delete(flushBufferedOutput) + } - this.bufferedOutput.add(flushBufferedOutput); + this.bufferedOutput.add(flushBufferedOutput) const debouncedFlush = () => { // If the process blows up no errors would be printed. // There should be a smart way to buffer stderr, but for now // we just won't buffer it. if (stream === process.stderr || stream === process.stdout) { - flushBufferedOutput(); + flushBufferedOutput() } else { if (!timeout) { timeout = setTimeout(() => { - flushBufferedOutput(); - timeout = null; - }, 100); + flushBufferedOutput() + timeout = null + }, 100) } } - }; + } stream.write = (chunk: Parameters[0]) => { - buffer.push(chunk); - debouncedFlush(); + buffer.push(chunk) + debouncedFlush() - return true; - }; + return true + } } } diff --git a/src/utils/formatTestPath.ts b/src/utils/formatTestPath.ts index e224f45d..a8a22332 100644 --- a/src/utils/formatTestPath.ts +++ b/src/utils/formatTestPath.ts @@ -1,4 +1,4 @@ -import path from 'path' +import path from 'path' import chalk from 'chalk' import slash from 'slash' @@ -6,8 +6,11 @@ import { Config } from '@jest/types' import { relativePath } from './relativePath' -export function formatTestPath(config: Config.ProjectConfig | Config.GlobalConfig, testPath: string): string { - const { dirname, basename } = relativePath(config, testPath); +export function formatTestPath( + config: Config.ProjectConfig | Config.GlobalConfig, + testPath: string +): string { + const { dirname, basename } = relativePath(config, testPath) - return slash(chalk.dim(dirname + path.sep) + chalk.bold(basename)); -}; + return slash(chalk.dim(dirname + path.sep) + chalk.bold(basename)) +} diff --git a/src/utils/pluralize.ts b/src/utils/pluralize.ts index e35f59c8..8cefb1b6 100644 --- a/src/utils/pluralize.ts +++ b/src/utils/pluralize.ts @@ -1,3 +1,3 @@ -export function pluralize(word: string, count :number): string { +export function pluralize(word: string, count: number): string { return `${count} ${word}${count === 1 ? '' : 's'}` } diff --git a/src/utils/printDisplayName.ts b/src/utils/printDisplayName.ts index a13e0a7f..dcd127d4 100644 --- a/src/utils/printDisplayName.ts +++ b/src/utils/printDisplayName.ts @@ -3,21 +3,21 @@ import chalk from 'chalk' import { Config } from '@jest/types' export function printDisplayName(config: Config.ProjectConfig): string { - const { displayName } = config; + const { displayName } = config if (typeof displayName === 'string') { return chalk.supportsColor ? chalk.reset.inverse.white(` ${displayName} `) - : displayName; + : displayName } if (displayName && typeof displayName === 'object') { return chalk.supportsColor ? chalk.reset.inverse.white(` ${displayName} `) - : displayName.name; + : displayName.name // displayName.color } - return ''; + return '' } diff --git a/src/utils/relativePath.ts b/src/utils/relativePath.ts index d19c267b..68c041a2 100644 --- a/src/utils/relativePath.ts +++ b/src/utils/relativePath.ts @@ -7,13 +7,19 @@ export interface RelativePath { dirname: string } -export function relativePath(config: Config.ProjectConfig | Config.GlobalConfig, testPath: string): RelativePath { +export function relativePath( + config: Config.ProjectConfig | Config.GlobalConfig, + testPath: string +): RelativePath { // this function can be called with ProjectConfigs or GlobalConfigs. GlobalConfigs // do not have config.cwd, only config.rootDir. Try using config.cwd, fallback // to config.rootDir. (Also, some unit just use config.rootDir, which is ok) - testPath = path.relative(('cwd' in config && config.cwd) || config.rootDir, testPath); - const dirname = path.dirname(testPath); - const basename = path.basename(testPath); + testPath = path.relative( + ('cwd' in config && config.cwd) || config.rootDir, + testPath + ) + const dirname = path.dirname(testPath) + const basename = path.basename(testPath) - return { basename, dirname }; + return { basename, dirname } } diff --git a/src/utils/renderTime.ts b/src/utils/renderTime.ts index 3389354a..baaf4b03 100644 --- a/src/utils/renderTime.ts +++ b/src/utils/renderTime.ts @@ -1,32 +1,36 @@ import chalk from 'chalk' -const PROGRESS_BAR_WIDTH = 40; +const PROGRESS_BAR_WIDTH = 40 -export function renderTime(runTime: number, estimatedTime: number, width: number): string { +export function renderTime( + runTime: number, + estimatedTime: number, + width: number +): string { // If we are more than one second over the estimated time, highlight it. const renderedTime = estimatedTime && runTime >= estimatedTime + 1 ? chalk.bold.yellow(`${runTime}s`) - : `${runTime}s`; - let time = `${chalk.bold('Time:')} ${renderedTime}`; + : `${runTime}s` + let time = `${chalk.bold('Time:')} ${renderedTime}` if (runTime < estimatedTime) { - time += `, estimated ${estimatedTime}s`; + time += `, estimated ${estimatedTime}s` } // Only show a progress bar if the test run is actually going to take // some time. if (estimatedTime > 2 && runTime < estimatedTime && width) { - const availableWidth = Math.min(PROGRESS_BAR_WIDTH, width); + const availableWidth = Math.min(PROGRESS_BAR_WIDTH, width) const length = Math.min( Math.floor((runTime / estimatedTime) * availableWidth), availableWidth - ); + ) if (availableWidth >= 2) { time += `\n${chalk.green('█').repeat(length)}${chalk .white('█') - .repeat(availableWidth - length)}`; + .repeat(availableWidth - length)}` } } - return time; -}; + return time +} diff --git a/src/utils/trimAndFormatPath.ts b/src/utils/trimAndFormatPath.ts index e5ec09b2..5d3a7389 100644 --- a/src/utils/trimAndFormatPath.ts +++ b/src/utils/trimAndFormatPath.ts @@ -5,31 +5,36 @@ import slash from 'slash' import { Config } from '@jest/types' import { relativePath } from './relativePath' -export function trimAndFormatPath(pad: number, config: Config.ProjectConfig | Config.GlobalConfig, testPath: string, columns: number): string { - const maxLength = columns - pad; - const relative = relativePath(config, testPath); - const { basename } = relative; - let { dirname } = relative; +export function trimAndFormatPath( + pad: number, + config: Config.ProjectConfig | Config.GlobalConfig, + testPath: string, + columns: number +): string { + const maxLength = columns - pad + const relative = relativePath(config, testPath) + const { basename } = relative + let { dirname } = relative // length is ok if ((dirname + path.sep + basename).length <= maxLength) { - return slash(chalk.dim(dirname + path.sep) + chalk.bold(basename)); + return slash(chalk.dim(dirname + path.sep) + chalk.bold(basename)) } // we can fit trimmed dirname and full basename - const basenameLength = basename.length; + const basenameLength = basename.length if (basenameLength + 4 < maxLength) { - const dirnameLength = maxLength - 4 - basenameLength; + const dirnameLength = maxLength - 4 - basenameLength dirname = `...${dirname.slice( dirname.length - dirnameLength, dirname.length - )}`; + )}` - return slash(chalk.dim(dirname + path.sep) + chalk.bold(basename)); + return slash(chalk.dim(dirname + path.sep) + chalk.bold(basename)) } if (basenameLength + 4 === maxLength) { - return slash(chalk.dim(`...${path.sep}`) + chalk.bold(basename)); + return slash(chalk.dim(`...${path.sep}`) + chalk.bold(basename)) } // can't fit dirname, but can fit trimmed basename @@ -37,5 +42,5 @@ export function trimAndFormatPath(pad: number, config: Config.ProjectConfig | Co chalk.bold( `...${basename.slice(basename.length - maxLength - 4, basename.length)}` ) - ); -}; + ) +} diff --git a/src/utils/wrapAnsiString.ts b/src/utils/wrapAnsiString.ts index 1ba334b4..6058364b 100644 --- a/src/utils/wrapAnsiString.ts +++ b/src/utils/wrapAnsiString.ts @@ -3,29 +3,29 @@ export function wrapAnsiString(string: string, terminalWidth: number): string { if (terminalWidth === 0) { // if the terminal width is zero, don't bother word-wrapping - return string; + return string } - const ANSI_REGEXP = /[\\u001b\\u009b]\[\d{1,2}m/g; - const tokens = []; - let lastIndex = 0; - let match; + const ANSI_REGEXP = /[\\u001b\\u009b]\[\d{1,2}m/g + const tokens = [] + let lastIndex = 0 + let match while ((match = ANSI_REGEXP.exec(string))) { - const ansi = match[0]; - const index = match.index; + const ansi = match[0] + const index = match.index if (index != lastIndex) { - tokens.push(['string', string.slice(lastIndex, index)]); + tokens.push(['string', string.slice(lastIndex, index)]) } - tokens.push(['ansi', ansi]); - lastIndex = index + ansi.length; + tokens.push(['ansi', ansi]) + lastIndex = index + ansi.length } if (lastIndex != string.length - 1) { - tokens.push(['string', string.slice(lastIndex, string.length)]); + tokens.push(['string', string.slice(lastIndex, string.length)]) } - let lastLineLength = 0; + let lastLineLength = 0 return tokens .reduce( @@ -33,30 +33,30 @@ export function wrapAnsiString(string: string, terminalWidth: number): string { if (kind === 'string') { if (lastLineLength + token.length > terminalWidth) { while (token.length) { - const chunk = token.slice(0, terminalWidth - lastLineLength); + const chunk = token.slice(0, terminalWidth - lastLineLength) const remaining = token.slice( terminalWidth - lastLineLength, token.length - ); - lines[lines.length - 1] += chunk; - lastLineLength += chunk.length; - token = remaining; + ) + lines[lines.length - 1] += chunk + lastLineLength += chunk.length + token = remaining if (token.length) { - lines.push(''); - lastLineLength = 0; + lines.push('') + lastLineLength = 0 } } } else { - lines[lines.length - 1] += token; - lastLineLength += token.length; + lines[lines.length - 1] += token + lastLineLength += token.length } } else { - lines[lines.length - 1] += token; + lines[lines.length - 1] += token } - return lines; + return lines }, [''] ) - .join('\n'); + .join('\n') } diff --git a/tsconfig.json b/tsconfig.json index aac369ad..2175908a 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,9 +1,11 @@ { "compilerOptions": { /* Basic Options */ - "target": "es2016", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017','ES2018' or 'ESNEXT'. */ - "module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */ - "lib": ["esnext"], /* Specify library files to be included in the compilation. */ + "target": "es2016" /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017','ES2018' or 'ESNEXT'. */, + "module": "commonjs" /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */, + "lib": [ + "esnext" + ] /* Specify library files to be included in the compilation. */, // "allowJs": true, /* Allow javascript files to be compiled. */ // "checkJs": true, /* Report errors in .js files. */ // "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */ @@ -11,8 +13,10 @@ // "declarationMap": true, /* Generates a sourcemap for each corresponding '.d.ts' file. */ // "sourceMap": true, /* Generates corresponding '.map' file. */ // "outFile": "./", /* Concatenate and emit output to single file. */ - "outDir": "./dist", /* Redirect output structure to the directory. */ - "rootDirs": ["./src"], /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */ + "outDir": "./dist" /* Redirect output structure to the directory. */, + "rootDirs": [ + "./src" + ] /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */, // "composite": true, /* Enable project compilation */ // "removeComments": true, /* Do not emit comments to output. */ // "noEmit": true, /* Do not emit outputs. */ @@ -21,7 +25,7 @@ // "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */ /* Strict Type-Checking Options */ - "strict": true, /* Enable all strict type-checking options. */ + "strict": true /* Enable all strict type-checking options. */, // "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */ // "strictNullChecks": true, /* Enable strict null checks. */ // "strictFunctionTypes": true, /* Enable strict checking of function types. */ @@ -32,19 +36,19 @@ /* Additional Checks */ // "noUnusedLocals": true, /* Report errors on unused locals. */ - "noUnusedParameters": true, /* Report errors on unused parameters. */ + "noUnusedParameters": true /* Report errors on unused parameters. */, // "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */ // "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */ /* Module Resolution Options */ - "moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */ - "baseUrl": "./", /* Base directory to resolve non-absolute module names. */ + "moduleResolution": "node" /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */, + "baseUrl": "./" /* Base directory to resolve non-absolute module names. */, // "paths": { "~src/*": ["./src/*"] }, /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */ // "rootDirs": [], /* List of root folders whose combined content represents the structure of the project at runtime. */ // "typeRoots": [], /* List of folders to include type definitions from. */ // "types": [], /* Type declaration files to be included in compilation. */ - "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */ - "esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */ + "allowSyntheticDefaultImports": true /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */, + "esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */ // "preserveSymlinks": true, /* Do not resolve the real path of symlinks. */ /* Source Map Options */ From d3e977ed703b52304bcb3d74c5d634dfdd7ce685 Mon Sep 17 00:00:00 2001 From: Derk-Jan Karrenbeld Date: Thu, 24 Dec 2020 23:21:03 +0100 Subject: [PATCH 16/36] Add code ql workflow --- .github/workflows/codeql.yml | 61 ++++++++++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) create mode 100644 .github/workflows/codeql.yml diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml new file mode 100644 index 00000000..e47d44c4 --- /dev/null +++ b/.github/workflows/codeql.yml @@ -0,0 +1,61 @@ +# For most projects, this workflow file will not need changing; you simply need +# to commit it to your repository. +# +# You may wish to alter this file to override the set of languages analyzed, +# or to provide custom queries or build logic. +name: 'codeql' + +on: + push: + branches: [master] + pull_request: + # The branches below must be a subset of the branches above + branches: [master] + schedule: + - cron: '0 14 * * 5' + +jobs: + analyze: + runs-on: ubuntu-latest + + strategy: + fail-fast: false + matrix: + # Override automatic language detection by changing the below list + # Supported options are ['csharp', 'cpp', 'go', 'java', 'javascript', 'python'] + language: ['javascript'] + # Learn more... + # https://docs.github.com/en/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#overriding-automatic-language-detection + + steps: + - name: Checkout repository + uses: actions/checkout@v2 + + # Initializes the CodeQL tools for scanning. + - name: Initialize CodeQL + uses: github/codeql-action/init@v1 + with: + languages: ${{ matrix.language }} + # If you wish to specify custom queries, you can do so here or in a config file. + # By default, queries listed here will override any specified in a config file. + # Prefix the list here with "+" to use these queries and those in the config file. + # queries: ./path/to/local/query, your-org/your-repo/queries@main + + # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). + # If this step fails, then you should remove it and run the build manually (see below) + - name: Autobuild + uses: github/codeql-action/autobuild@v1 + + # ℹī¸ Command-line programs to run using the OS shell. + # 📚 https://git.io/JvXDl + + # ✏ī¸ If the Autobuild fails above, remove it and uncomment the following three lines + # and modify them (or add more) to build your code if your project + # uses a compiled language + + #- run: | + # make bootstrap + # make release + + - name: Perform CodeQL Analysis + uses: github/codeql-action/analyze@v1 From b0c20c09e5ebb7458c9011cd72a525ed4037e3c6 Mon Sep 17 00:00:00 2001 From: Derk-Jan Karrenbeld Date: Thu, 24 Dec 2020 23:21:12 +0100 Subject: [PATCH 17/36] Bump the version --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 2bab61ca..e4ec9f6d 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "@exercism/javascript-test-runner", "description": "Automated Test runner for exercism solutions in Javascript.", "author": "Derk-Jan Karrenbeld ", - "version": "1.0.0", + "version": "2.0.0", "private": true, "license": "AGPL-3.0-or-later", "repository": { From c33a90f23634922f1e5ec15c37d309307f1a2e1d Mon Sep 17 00:00:00 2001 From: Derk-Jan Karrenbeld Date: Thu, 24 Dec 2020 23:21:20 +0100 Subject: [PATCH 18/36] Explain how to maintain in the README.md --- README.md | 77 ++++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 74 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 71ea40d0..cc4cc828 100644 --- a/README.md +++ b/README.md @@ -2,17 +2,88 @@ The Docker image for automatically run tests on JavaScript solutions submitted to [exercism][web-exercism]. +## Installation + +Clone this repository and then run: + +```bash +yarn install +``` + +You'll need at least Node LTS for this to work. + +``` +yarn build +``` + +## Usage + +If you're developing this, you can run this via `yarn` or the provided shell script. + +- `.sh` enabled systems (UNIX, WSL): `yarn execute:dev` +- `.bat` fallback (cmd.exe, Git Bash for Windows): _unsupported_ + +You'll want these `:dev` variants because it will _build_ the required code (it will transpile from TypeScript to JavaScript, which is necessary to run this in Node environments, unlike Deno environments). When on Windows, if you're using Git Bash for Windows or a similar terminal, the `.sh` files will work, but will open a new window (which closes after execution). The `.bat` scripts will work in the same terminal. In this case it might be much easier to run `bin/run.sh` directly, so a new shell won't open. + +You can also manually build using `yarn` or `yarn build`, and then run the script directly: `./bin/run.sh arg1 arg2 arg3`. + ## Running the Tests To run a solution's tests, do the following: + 1. Open terminal in project's root -2. Run `./run.sh ` +2. Run `./bin/run.sh []` + +For example: + +```shell +$ ./bin/run.sh two-fer ./test/fixtures/two-fer/pass + +PASS test/fixtures/two-fer/pass/two-fer.spec.js +Test Suites: 1 passed, 1 total +Tests: 3 passed, 3 total +Snapshots: 0 total +Time: 2.817s +Find the output at: +test/fixtures/two-fer/pass/results.json +``` + +## Running the Tests of a Remote Solution + +Instead of passing in an `` and ``, you can also directly pass in an `https://exercism.io` url, as long as you have the `exercism` CLI installed. + +You can pass the following type of URLs: + +- Published solutions: `/tracks/javascript/exercises//` +- Mentor solutions: `/mentor/solutions/` +- Your solutions: `/my/solutions/` +- Private solutions: `/solutions/` + +For example: + +``` +$ ./bin/run.sh https://exercism.io/my/solutions/a7d1b71693fb4298a3a99bd352dd4d74 +Exercism remote UUID: a7d1b71693fb4298a3a99bd352dd4d74 + +Downloaded to +C:\Users\Derk-Jan\Exercism\javascript\clock +PASS tmp/clock/a7d1b71693fb4298a3a99bd352dd4d74/clock/clock.spec.js +Test Suites: 1 passed, 1 total +Tests: 52 passed, 52 total +Snapshots: 0 total +Time: 2.987s +Find the output at: +./tmp/clock/a7d1b71693fb4298a3a99bd352dd4d74/clock/results.json +``` + +As you can see, it will be copied to a local directory. It's up to you to clean-up this directory. ## Running the Tests in Docker container -*This script is provided for testing purposes* +_This script is provided for testing purposes_ To run a solution's test in the Docker container, do the following: + 1. Open terminal in project's root 2. Run `./run-in-docker.sh ` @@ -22,7 +93,7 @@ The `package.json` needs to be in-sync with the [`javascript` track `package.jso ### Known issues -* The output format of the tests still does not conform to the [exercism automated tests][git-automated-tests] standard. +- The output format of the tests still does not conform to the [exercism automated tests][git-automated-tests] standard. [web-exercism]: https://exercism.io [git-automated-tests]: https://github.com/exercism/automated-tests From f666453f9f6f35540aa7962e424e141e0db91610 Mon Sep 17 00:00:00 2001 From: Derk-Jan Karrenbeld Date: Thu, 24 Dec 2020 23:21:25 +0100 Subject: [PATCH 19/36] Create CHANGELOG.md --- CHANGELOG.md | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 CHANGELOG.md diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 00000000..eb499bb7 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,19 @@ +# Changelog + +## 2.0.0 + +- Add deploy to dockerhub +- Add build and run tests on commit +- Add build and run tests on pr +- Add format action workflow +- Add third argument in binary usage +- Add aliases of various binaries +- Add remote solution execution +- Add fallback for arguments without trailing / +- Update traversal of AST to use @typescript-estree +- Update dependencies +- Change LICENSE from MIT to AGPL-3.0-or-later + +## 1.0.0 + +Initial release From 37e4bb4801b759ee209bb43ed6592922db15b11d Mon Sep 17 00:00:00 2001 From: Derk-Jan Karrenbeld Date: Thu, 24 Dec 2020 23:24:22 +0100 Subject: [PATCH 20/36] Expose binary --- package.json | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index e4ec9f6d..5d37d27e 100644 --- a/package.json +++ b/package.json @@ -3,7 +3,6 @@ "description": "Automated Test runner for exercism solutions in Javascript.", "author": "Derk-Jan Karrenbeld ", "version": "2.0.0", - "private": true, "license": "AGPL-3.0-or-later", "repository": { "type": "git", @@ -11,10 +10,12 @@ }, "directories": { "lib": "./dist", - "bin": "./bin", "doc": "./docs", "test": "./test" }, + "bin": { + "javascript-test-runner": "bin/run.sh" + }, "scripts": { "execute": "./bin/run.sh", "execute:dev": "yarn build && yarn execute", From 303bc8ca4df1ce8a358498c97b261dcb2049e204 Mon Sep 17 00:00:00 2001 From: Derk-Jan Karrenbeld Date: Thu, 24 Dec 2020 23:26:12 +0100 Subject: [PATCH 21/36] Make executable --- bin/check-formatting.sh | 0 bin/ci-check.sh | 0 bin/ci.sh | 0 bin/format.sh | 0 bin/lint.sh | 0 bin/pr-check.sh | 0 bin/pr.sh | 0 bin/run.bat | 0 8 files changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 bin/check-formatting.sh mode change 100644 => 100755 bin/ci-check.sh mode change 100644 => 100755 bin/ci.sh mode change 100644 => 100755 bin/format.sh mode change 100644 => 100755 bin/lint.sh mode change 100644 => 100755 bin/pr-check.sh mode change 100644 => 100755 bin/pr.sh mode change 100644 => 100755 bin/run.bat diff --git a/bin/check-formatting.sh b/bin/check-formatting.sh old mode 100644 new mode 100755 diff --git a/bin/ci-check.sh b/bin/ci-check.sh old mode 100644 new mode 100755 diff --git a/bin/ci.sh b/bin/ci.sh old mode 100644 new mode 100755 diff --git a/bin/format.sh b/bin/format.sh old mode 100644 new mode 100755 diff --git a/bin/lint.sh b/bin/lint.sh old mode 100644 new mode 100755 diff --git a/bin/pr-check.sh b/bin/pr-check.sh old mode 100644 new mode 100755 diff --git a/bin/pr.sh b/bin/pr.sh old mode 100644 new mode 100755 diff --git a/bin/run.bat b/bin/run.bat old mode 100644 new mode 100755 From 0a181e44acbbd13eec2bee396d0fae67d7742b56 Mon Sep 17 00:00:00 2001 From: Derk-Jan Karrenbeld Date: Thu, 24 Dec 2020 23:31:23 +0100 Subject: [PATCH 22/36] Check reporter --- bin/run.sh | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/bin/run.sh b/bin/run.sh index 53786347..d9b6c094 100755 --- a/bin/run.sh +++ b/bin/run.sh @@ -75,6 +75,14 @@ OUTPUT="${OUTPUT%/}/" set -euo pipefail +REPORTER="./dist/reporter.js" +if test -f "$REPORTER"; then + echo "Using $REPORTER to generate results.json" +else + echo "Expected $REPORTER to exist. Did you forget to yarn build first?" + exit 1 +fi + # Put together the path to the test file test_file="${INPUT}${SLUG}.spec.js" From 104909694f25101ddad4ff613a249af95344a4ac Mon Sep 17 00:00:00 2001 From: Derk-Jan Karrenbeld Date: Thu, 24 Dec 2020 23:34:04 +0100 Subject: [PATCH 23/36] Echo to stderr --- bin/run.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/bin/run.sh b/bin/run.sh index d9b6c094..5331b7a5 100755 --- a/bin/run.sh +++ b/bin/run.sh @@ -79,7 +79,7 @@ REPORTER="./dist/reporter.js" if test -f "$REPORTER"; then echo "Using $REPORTER to generate results.json" else - echo "Expected $REPORTER to exist. Did you forget to yarn build first?" + >&2 echo "Expected $REPORTER to exist. Did you forget to yarn build first?" exit 1 fi @@ -109,12 +109,12 @@ set +e # Run tests ./node_modules/.bin/jest test --no-cache "${INPUT}*" \ --outputFile="${result_file}" \ - --reporters "./dist/reporter.js" \ + --reporters "${REPORTER}" \ --noStackTrace \ --verbose=false \ --roots "${INPUT}" -# Convert exit(1) to exit(0) +# Convert exit(1) (jest worked, but there are failing tests) to exit(0) test_exit=$? echo "Find the output at:" From a6354ce55c852f2fa595067e262500b525467bd8 Mon Sep 17 00:00:00 2001 From: Derk-Jan Karrenbeld Date: Thu, 24 Dec 2020 23:36:28 +0100 Subject: [PATCH 24/36] Pass in CWD --- test/smoke.test.ts | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/test/smoke.test.ts b/test/smoke.test.ts index cc503df2..3d000ce3 100644 --- a/test/smoke.test.ts +++ b/test/smoke.test.ts @@ -3,8 +3,9 @@ import { join, resolve } from 'path' import { lstat, mkdtempSync, readFileSync } from 'fs' import { tmpdir } from 'os' -const bin = resolve(__dirname, '..', 'bin') +const root = resolve(__dirname, '..') const fixtures = resolve(__dirname, 'fixtures') +const bin = resolve(root, 'bin') const run = resolve(bin, 'run.sh') describe('javascript-test-runner', () => { @@ -15,6 +16,7 @@ describe('javascript-test-runner', () => { [run, 'two-fer', join(fixtures, 'two-fer', 'pass')], { stdio: 'pipe', + cwd: root, } ) @@ -29,6 +31,7 @@ describe('javascript-test-runner', () => { test('generates a result.json', () => { spawnSync('bash', [run, 'two-fer', join(fixtures, 'two-fer', 'pass')], { stdio: 'pipe', + cwd: root, }) return new Promise((resolve, reject) => { @@ -56,6 +59,7 @@ describe('javascript-test-runner', () => { [run, 'clock', join(fixtures, 'clock', 'pass'), outputDir], { stdio: 'pipe', + cwd: root, } ) @@ -80,6 +84,7 @@ describe('javascript-test-runner', () => { [run, 'two-fer', join(fixtures, 'two-fer', 'fail')], { stdio: 'pipe', + cwd: root, } ) @@ -90,6 +95,7 @@ describe('javascript-test-runner', () => { test('generates a result.json', () => { spawnSync('bash', [run, 'two-fer', join(fixtures, 'two-fer', 'fail')], { stdio: 'pipe', + cwd: root, }) return new Promise((resolve, reject) => { From 10e297232fc3ddc336079091abd8d7f61592facd Mon Sep 17 00:00:00 2001 From: Derk-Jan Karrenbeld Date: Thu, 24 Dec 2020 23:46:34 +0100 Subject: [PATCH 25/36] Resolve the root path to find the reporter --- bin/run.sh | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/bin/run.sh b/bin/run.sh index 5331b7a5..fbbaff4c 100755 --- a/bin/run.sh +++ b/bin/run.sh @@ -75,14 +75,19 @@ OUTPUT="${OUTPUT%/}/" set -euo pipefail -REPORTER="./dist/reporter.js" +ROOT="$(realpath $(dirname "$0")/..)" +REPORTER="${ROOT}/dist/reporter.js" if test -f "$REPORTER"; then - echo "Using $REPORTER to generate results.json" + echo "Using reporter: $REPORTER" + echo "Using testroot: $INPUT" + echo "Using baseroot: $ROOT" else >&2 echo "Expected $REPORTER to exist. Did you forget to yarn build first?" exit 1 fi +echo "" + # Put together the path to the test file test_file="${INPUT}${SLUG}.spec.js" @@ -117,6 +122,7 @@ set +e # Convert exit(1) (jest worked, but there are failing tests) to exit(0) test_exit=$? +echo "" echo "Find the output at:" echo $result_file From 4a6626a6e75fb1db76186b62fd06de43edf838f0 Mon Sep 17 00:00:00 2001 From: Derk-Jan Karrenbeld Date: Thu, 24 Dec 2020 23:50:42 +0100 Subject: [PATCH 26/36] Only postinstall when we want it to --- .github/workflows/ci.js.yml | 6 +++--- .github/workflows/pr.ci.js.yml | 7 ++++--- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/.github/workflows/ci.js.yml b/.github/workflows/ci.js.yml index 1b351457..d81342d5 100644 --- a/.github/workflows/ci.js.yml +++ b/.github/workflows/ci.js.yml @@ -19,7 +19,7 @@ jobs: node-version: 14.x - name: Install project dependencies - run: yarn install --frozen-lockfile + run: yarn install --frozen-lockfile --ignore-scripts - name: Run exercism/javascript-test-runner ci precheck (lint code) run: bin/ci-check.sh @@ -39,10 +39,10 @@ jobs: node-version: ${{ matrix.node-version }} - name: Install project dependencies - run: yarn install --frozen-lockfile + run: yarn install --frozen-lockfile --ignore-scripts - name: Build the test-runner (using Node ${{ matrix.node-version }}) run: yarn build - - name: Run exercism/javascript-test-runner ci (build and runs tests) + - name: Run exercism/javascript-test-runner ci (runs tests) run: bin/ci.sh diff --git a/.github/workflows/pr.ci.js.yml b/.github/workflows/pr.ci.js.yml index 34935d26..83571028 100644 --- a/.github/workflows/pr.ci.js.yml +++ b/.github/workflows/pr.ci.js.yml @@ -19,7 +19,7 @@ jobs: node-version: 14.x - name: Install project dependencies - run: yarn install --frozen-lockfile + run: yarn install --frozen-lockfile --ignore-scripts - name: Run exercism/javascript ci precheck (lint code) run: | @@ -45,12 +45,13 @@ jobs: node-version: ${{ matrix.node-version }} - name: Install project dependencies - run: yarn install --frozen-lockfile + run: yarn install --frozen-lockfile --ignore-scripts + - name: Build the test-runner (using Node ${{ matrix.node-version }}) run: yarn build - - name: Run exercism/javascript ci (build and runs tests) + - name: Run exercism/javascript ci (runs tests) run: | PULL_REQUEST_URL=$(jq -r ".pull_request.url" "$GITHUB_EVENT_PATH") curl --url $"${PULL_REQUEST_URL}/files?per_page=100" --header 'authorization: Bearer ${{ secrets.GITHUB_TOKEN }}' | \ From aaf1654e97816a722d56c9b4dfd4bc9457bce0ac Mon Sep 17 00:00:00 2001 From: Derk-Jan Karrenbeld Date: Thu, 24 Dec 2020 23:53:16 +0100 Subject: [PATCH 27/36] Format --- .github/workflows/pr.ci.js.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/pr.ci.js.yml b/.github/workflows/pr.ci.js.yml index 83571028..0615c94e 100644 --- a/.github/workflows/pr.ci.js.yml +++ b/.github/workflows/pr.ci.js.yml @@ -45,8 +45,7 @@ jobs: node-version: ${{ matrix.node-version }} - name: Install project dependencies - run: yarn install --frozen-lockfile --ignore-scripts - + run: yarn install --frozen-lockfile --ignore-scripts - name: Build the test-runner (using Node ${{ matrix.node-version }}) run: yarn build From cff7cf34a3672710d7cd1f8a61c9d30ae57a00d8 Mon Sep 17 00:00:00 2001 From: Derk-Jan Karrenbeld Date: Fri, 25 Dec 2020 00:05:17 +0100 Subject: [PATCH 28/36] Satisfy linter --- bin/ci-check.sh | 5 +++-- bin/pr-check.sh | 5 +++-- package.json | 2 +- src/getSnapshotStatus.ts | 4 ++-- src/getTestResults.ts | 6 +++--- src/jest/console.ts | 13 +++++++------ src/jest/setup.ts | 12 +++++------- src/output.ts | 21 +++++++++++---------- src/reporter.ts | 21 ++++++++++++--------- src/status.ts | 34 +++++++++++++++++++--------------- src/stdlib.ts | 20 +++++++++++--------- 11 files changed, 77 insertions(+), 66 deletions(-) diff --git a/bin/ci-check.sh b/bin/ci-check.sh index 2da112d3..ed478939 100755 --- a/bin/ci-check.sh +++ b/bin/ci-check.sh @@ -10,5 +10,6 @@ # eats 1 argument shift 1 -lint.sh "$@" -check-formatting.sh "$@" \ No newline at end of file +DIRNAME=$(dirname "$0") +"${DIRNAME}/lint.sh" "$@" +"${DIRNAME}/check-formatting.sh" "$@" \ No newline at end of file diff --git a/bin/pr-check.sh b/bin/pr-check.sh index 4049aaac..ed478939 100755 --- a/bin/pr-check.sh +++ b/bin/pr-check.sh @@ -10,5 +10,6 @@ # eats 1 argument shift 1 -lint.sh "$@" -check-formatting.sh "$@" \ No newline at end of file +DIRNAME=$(dirname "$0") +"${DIRNAME}/lint.sh" "$@" +"${DIRNAME}/check-formatting.sh" "$@" \ No newline at end of file diff --git a/package.json b/package.json index 5d37d27e..15de0517 100644 --- a/package.json +++ b/package.json @@ -22,7 +22,7 @@ "build": "yarn tsc --project ./tsconfig.json", "watch": "yarn build -w", "prepublish": "yarn test", - "lint": "yarn eslint . --ext ts,js,tsx,jsx,mjs", + "lint": "yarn eslint . --ext ts,js,tsx,jsx,mjs -c .eslintrc", "test": "yarn build && jest --roots test --testPathIgnorePatterns=\"fixtures/\"" }, "dependencies": { diff --git a/src/getSnapshotStatus.ts b/src/getSnapshotStatus.ts index f7a4dd70..d00aa1d6 100644 --- a/src/getSnapshotStatus.ts +++ b/src/getSnapshotStatus.ts @@ -53,8 +53,8 @@ export function getSnapshotStatus( ) } - if ((snapshot as any).uncheckedKeys) { - ;(snapshot as any).uncheckedKeys.forEach((key: string) => { + if (snapshot.uncheckedKeys) { + snapshot.uncheckedKeys.forEach((key: string) => { statuses.push(` ${DOT}${key}`) }) } diff --git a/src/getTestResults.ts b/src/getTestResults.ts index 210b26e3..628feb69 100644 --- a/src/getTestResults.ts +++ b/src/getTestResults.ts @@ -13,13 +13,13 @@ interface TestSuite { type TestsBySuites = TestSuite -export function getTestResults(testResults: TestResult['testResults']) { +export function getTestResults(testResults: TestResult['testResults']): string { const testSuites = groupTestsBySuites(testResults) return getLogSuite(testSuites, 0) } -function groupTestsBySuites(testResults: TestResult['testResults']) { +function groupTestsBySuites(testResults: TestResult['testResults']): TestSuite { const output: TestsBySuites = { suites: [], tests: [], title: '' } testResults.forEach((testResult: AssertionResult) => { @@ -74,7 +74,7 @@ export function logTests( return output } -export function logTest(test: AssertionResult, indentLevel: number) { +export function logTest(test: AssertionResult, indentLevel: number): string { const status = getIcon(test.status) const time = test.duration ? ` (${test.duration.toFixed(0)}ms)` : '' const testStatus = `${status} ${chalk.dim(test.title + time)}` diff --git a/src/jest/console.ts b/src/jest/console.ts index f4479abb..40a9b457 100644 --- a/src/jest/console.ts +++ b/src/jest/console.ts @@ -1,3 +1,4 @@ +/* eslint-disable @typescript-eslint/no-explicit-any */ import { spyOn } from 'jest-mock' const defaultKeys = ['debug', 'log', 'info', 'warn', 'error'] as const @@ -9,7 +10,7 @@ interface CapturedConsole { getSpy(key: ConsoleFunction): jest.SpyInstance restore(): void clear(): void - calls(): Record + calls(): Record } function captureConsole( @@ -26,7 +27,7 @@ function captureConsole( {} ) as Spies - function getSpy(spykey: string) { + function getSpy(spykey: string): any { return spies[spykey as keyof typeof spies] } @@ -34,19 +35,19 @@ function captureConsole( return { getSpy: getSpy, - restore: () => { + restore: (): void => { Object.keys(spies).forEach((spykey) => getSpy(spykey).mockRestore()) }, - clear: () => { + clear: (): void => { Object.keys(spies).forEach((spykey) => getSpy(spykey).mockClear()) }, - calls: () => { + calls: (): Record => { return Object.keys(spies).reduce((result, spyKey) => { result[spyKey] = [...getSpy(spyKey).mock.calls] return result - }, {} as Record) + }, {} as Record) }, } } diff --git a/src/jest/setup.ts b/src/jest/setup.ts index a49576ff..89ef40dc 100644 --- a/src/jest/setup.ts +++ b/src/jest/setup.ts @@ -1,14 +1,16 @@ import spyConsole from './console' +// eslint-disable-next-line @typescript-eslint/no-explicit-any const originalDescribe = (jasmine as any).getEnv().describe +// eslint-disable-next-line @typescript-eslint/explicit-function-return-type, @typescript-eslint/no-explicit-any ;(jasmine as any).getEnv().describe = ( description: string, specDefinitions: (...args: T) => void, ...describeArgs: T ) => { - function spiedSpecDefinition(...args: T) { - let restores: Array<() => void> = [] + function spiedSpecDefinition(...args: T): void { + const restores: Array<() => void> = [] beforeEach(() => { restores.push(spyConsole().restore) @@ -23,9 +25,5 @@ const originalDescribe = (jasmine as any).getEnv().describe return specDefinitions(...args) } - return (originalDescribe as any)( - description, - spiedSpecDefinition, - ...describeArgs - ) + return originalDescribe(description, spiedSpecDefinition, ...describeArgs) } diff --git a/src/output.ts b/src/output.ts index 0611dae9..ba9ea064 100644 --- a/src/output.ts +++ b/src/output.ts @@ -1,6 +1,5 @@ import path from 'path' import fs from 'fs' -import { trimAndFormatPath } from './utils/trimAndFormatPath' import { ConsoleBuffer } from '@jest/console' import { @@ -35,12 +34,12 @@ export class Output { this.globalConfig.outputFile || path.join(process.cwd(), 'results.json') } - error(message: string) { + public error(message: string): void { this.results.status = 'error' this.results.message = message } - finish(aggregatedResults: AggregatedResult) { + public finish(aggregatedResults: AggregatedResult): void { if (!this.results.status) { this.results.status = aggregatedResults.numRuntimeErrorTestSuites === 0 && @@ -56,11 +55,11 @@ export class Output { fs.writeFileSync(this.outputFile, artifact) } - testFinished( + public testFinished( specFilePath: string, testResult: TestResult, results: AggregatedResult - ) { + ): void { // Syntax errors etc. These are runtime errors: failures to run if (results.numRuntimeErrorTestSuites > 0) { this.error( @@ -73,7 +72,7 @@ export class Output { return } - // Suites ran fine. Output regurarly. + // Suites ran fine. Output normally. results.testResults.forEach((testResult) => { return this.testInnerFinished( specFilePath, @@ -83,11 +82,11 @@ export class Output { }) } - testInnerFinished( + public testInnerFinished( specFilePath: string, testResult: TestResult, innerResults: AssertionResult[] - ) { + ): void { if (testResult.console) { /* // The code below works, but is not accepted by the current runner spec on exercism @@ -116,10 +115,12 @@ export class Output { this.results.tests.push(...outputs.map((r) => ({ ...r, output: null }))) } - testStarted(_path: string) {} + public testStarted(_path: string): void { + // noop + } } -function buildOutput(buffer: ConsoleBuffer) { +function buildOutput(buffer: ConsoleBuffer): string { const output = buffer .map((entry) => `[${entry.type}] ${entry.message}`) .join('\n') diff --git a/src/reporter.ts b/src/reporter.ts index 77afab7a..afc2a77f 100644 --- a/src/reporter.ts +++ b/src/reporter.ts @@ -24,27 +24,27 @@ class StandardReporter implements Reporter { private readonly output: Output private error: null | Error - private clear: string constructor(globalConfig: Config.GlobalConfig) { this.globalConfig = globalConfig this.stdlib = new Stdlib(globalConfig) this.error = null - this.clear = '' this.status = new Status() this.output = new Output(globalConfig) - this.status.onChange(() => {}) + this.status.onChange(() => { + /*noop*/ + }) } - getLastError(): Error | void { + public getLastError(): Error | void { if (this.error) { return this.error } } - setError(error: Error) { + public setError(error: Error): void { this.error = error this.output.error(error.message) } @@ -53,7 +53,10 @@ class StandardReporter implements Reporter { * @param results * @param options */ - onRunStart(results: AggregatedResult, options: ReporterOnStartOptions): void { + public onRunStart( + results: AggregatedResult, + options: ReporterOnStartOptions + ): void { this.status.runStarted(results, options) if (isInteractive) { this.stdlib.clear() @@ -63,7 +66,7 @@ class StandardReporter implements Reporter { /** * @param test */ - onTestStart(test: Test): void { + public onTestStart(test: Test): void { this.status.testStarted(test.path, test.context.config) this.output.testStarted(test.path) } @@ -73,7 +76,7 @@ class StandardReporter implements Reporter { * @param testResult * @param results */ - onTestResult( + public onTestResult( test: Test, testResult: TestResult, results: AggregatedResult @@ -109,7 +112,7 @@ class StandardReporter implements Reporter { * @param contexts * @param aggregatedResults */ - onRunComplete( + public onRunComplete( _contexts: Set, aggregatedResults: AggregatedResult ): Promise | void { diff --git a/src/status.ts b/src/status.ts index a2a96f90..d1424489 100644 --- a/src/status.ts +++ b/src/status.ts @@ -23,13 +23,13 @@ interface TestRecord { * shifting the whole list. */ class CurrentTestList { - _array: Array + private _array: Array constructor() { this._array = [] } - add(testPath: string, config: Config.ProjectConfig) { + public add(testPath: string, config: Config.ProjectConfig): void { const index = this._array.indexOf(null) const record = { config, testPath } if (index !== -1) { @@ -39,14 +39,14 @@ class CurrentTestList { } } - delete(testPath: string) { + public delete(testPath: string): void { const record = this._array.find( (record) => record && record.testPath === testPath ) this._array[this._array.indexOf(record || null)] = null } - get() { + public get(): Array { return this._array } } @@ -79,14 +79,18 @@ export class Status { this._showStatus = false } - onChange(callback = () => {}) { + public onChange( + callback = (): void => { + /*noop*/ + } + ): void { this._callback = callback } - runStarted( + public runStarted( aggregatedResults: AggregatedResult, options: ReporterOnStartOptions - ) { + ): void { this._estimatedTime = (options && options.estimatedTime) || 0 this._showStatus = options && options.showStatus this._interval = setInterval(() => this._tick(), 1000) @@ -94,13 +98,13 @@ export class Status { this._debouncedEmit() } - runFinished() { + public runFinished(): void { this._done = true clearInterval(this._interval!) this._emit() } - testStarted(testPath: string, config: Config.ProjectConfig) { + public testStarted(testPath: string, config: Config.ProjectConfig): void { this._currentTests.add(testPath, config) if (!this._showStatus) { this._emit() @@ -109,18 +113,18 @@ export class Status { } } - testFinished( + public testFinished( _config: unknown, testResult: TestResult, aggregatedResults: AggregatedResult - ) { + ): void { const { testFilePath } = testResult this._aggregatedResults = aggregatedResults this._currentTests.delete(testFilePath) this._debouncedEmit() } - get() { + public get(): { clear: string; content: string } { if (this._cache) { return this._cache } @@ -162,13 +166,13 @@ export class Status { return (this._cache = { clear, content }) } - _emit() { + private _emit(): void { this._cache = null this._lastUpdated = Date.now() this._callback && this._callback() } - _debouncedEmit() { + private _debouncedEmit(): void { if (!this._emitScheduled) { // Perf optimization to avoid two separate renders When // one test finishes and another test starts executing. @@ -180,7 +184,7 @@ export class Status { } } - _tick() { + private _tick(): void { this._debouncedEmit() } } diff --git a/src/stdlib.ts b/src/stdlib.ts index ef46cb8e..2e12fb21 100644 --- a/src/stdlib.ts +++ b/src/stdlib.ts @@ -17,7 +17,7 @@ export class Stdlib { this.wrapStdio(process.stderr) } - log(message: string) { + public log(message: string): void { if (this.useStderr) { this.err(`${message}\n`) } else { @@ -25,35 +25,35 @@ export class Stdlib { } } - error(message: string) { + public error(message: string): void { this.err(`${message}\n`) } - clear() { + public clear(): void { clearLine(process.stdout) clearLine(process.stderr) } - close() { + public close(): void { this.forceFlushBufferedOutput() process.stdout.write = this.out process.stderr.write = this.err } // Don't wait for the debounced call and flush all output immediately. - forceFlushBufferedOutput() { + public forceFlushBufferedOutput(): void { for (const flushBufferedOutput of this.bufferedOutput) { flushBufferedOutput() } } - wrapStdio(stream: NodeJS.WritableStream) { + public wrapStdio(stream: NodeJS.WritableStream): void { const originalWrite = stream.write let buffer: Parameters[0][] = [] let timeout: NodeJS.Timeout | null = null - const flushBufferedOutput = () => { + const flushBufferedOutput = (): void => { const string = buffer.join('') buffer = [] @@ -66,7 +66,7 @@ export class Stdlib { this.bufferedOutput.add(flushBufferedOutput) - const debouncedFlush = () => { + const debouncedFlush = (): void => { // If the process blows up no errors would be printed. // There should be a smart way to buffer stderr, but for now // we just won't buffer it. @@ -82,7 +82,9 @@ export class Stdlib { } } - stream.write = (chunk: Parameters[0]) => { + stream.write = ( + chunk: Parameters[0] + ): boolean => { buffer.push(chunk) debouncedFlush() From 9b249847a3f5416d6c4b3b262a63fc7242221606 Mon Sep 17 00:00:00 2001 From: Derk-Jan Karrenbeld Date: Fri, 25 Dec 2020 00:11:08 +0100 Subject: [PATCH 29/36] Back to dot path --- bin/run.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/run.sh b/bin/run.sh index fbbaff4c..36952a41 100755 --- a/bin/run.sh +++ b/bin/run.sh @@ -76,7 +76,7 @@ OUTPUT="${OUTPUT%/}/" set -euo pipefail ROOT="$(realpath $(dirname "$0")/..)" -REPORTER="${ROOT}/dist/reporter.js" +REPORTER="./dist/reporter.js" if test -f "$REPORTER"; then echo "Using reporter: $REPORTER" echo "Using testroot: $INPUT" From a0592aaf5fe8d39ba91e91e0492d2d0b8c4d3acc Mon Sep 17 00:00:00 2001 From: Derk-Jan Karrenbeld Date: Fri, 25 Dec 2020 00:12:38 +0100 Subject: [PATCH 30/36] Echo those paths --- bin/run.sh | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/bin/run.sh b/bin/run.sh index 36952a41..82b1f477 100755 --- a/bin/run.sh +++ b/bin/run.sh @@ -76,13 +76,16 @@ OUTPUT="${OUTPUT%/}/" set -euo pipefail ROOT="$(realpath $(dirname "$0")/..)" -REPORTER="./dist/reporter.js" +REPORTER="$ROOT/dist/reporter.js" if test -f "$REPORTER"; then echo "Using reporter: $REPORTER" echo "Using testroot: $INPUT" echo "Using baseroot: $ROOT" else - >&2 echo "Expected $REPORTER to exist. Did you forget to yarn build first?" + >&2 echo "Expected reporter.js to exist. Did you forget to yarn build first?" + >&2 echo "With reporter: $REPORTER" + >&2 echo "With testroot: $INPUT" + >&2 echo "With baseroot: $ROOT" exit 1 fi @@ -112,12 +115,12 @@ mkdir -p "${OUTPUT}" set +e # Run tests -./node_modules/.bin/jest test --no-cache "${INPUT}*" \ - --outputFile="${result_file}" \ - --reporters "${REPORTER}" \ - --noStackTrace \ - --verbose=false \ - --roots "${INPUT}" +"$ROOT/node_modules/.bin/jest" test --no-cache "${INPUT}*" \ + --outputFile="${result_file}" \ + --reporters "${REPORTER}" \ + --noStackTrace \ + --verbose=false \ + --roots "${INPUT}" # Convert exit(1) (jest worked, but there are failing tests) to exit(0) test_exit=$? From ee59e2ae7a9584743e6377f844b2a3f244b62a1d Mon Sep 17 00:00:00 2001 From: Derk-Jan Karrenbeld Date: Fri, 25 Dec 2020 00:15:07 +0100 Subject: [PATCH 31/36] Show us DIST please --- bin/run.sh | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/bin/run.sh b/bin/run.sh index 82b1f477..6b29ae16 100755 --- a/bin/run.sh +++ b/bin/run.sh @@ -81,11 +81,15 @@ if test -f "$REPORTER"; then echo "Using reporter: $REPORTER" echo "Using testroot: $INPUT" echo "Using baseroot: $ROOT" + echo "" + echo $(ls $ROOT/dist) else >&2 echo "Expected reporter.js to exist. Did you forget to yarn build first?" >&2 echo "With reporter: $REPORTER" >&2 echo "With testroot: $INPUT" >&2 echo "With baseroot: $ROOT" + >&2 echo "" + >&2 echo $(ls $ROOT/dist) exit 1 fi From c0c29b30770e7076a0126533925a464c1a1c878c Mon Sep 17 00:00:00 2001 From: Derk-Jan Karrenbeld Date: Fri, 25 Dec 2020 00:23:18 +0100 Subject: [PATCH 32/36] Attempt explicitely outputting to dist --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 15de0517..2175b509 100644 --- a/package.json +++ b/package.json @@ -19,7 +19,7 @@ "scripts": { "execute": "./bin/run.sh", "execute:dev": "yarn build && yarn execute", - "build": "yarn tsc --project ./tsconfig.json", + "build": "yarn tsc --project ./tsconfig.json --outDir ./dist", "watch": "yarn build -w", "prepublish": "yarn test", "lint": "yarn eslint . --ext ts,js,tsx,jsx,mjs -c .eslintrc", From ec017b654a6b9a12915a652a25392aa236c82e55 Mon Sep 17 00:00:00 2001 From: Derk-Jan Karrenbeld Date: Fri, 25 Dec 2020 00:29:45 +0100 Subject: [PATCH 33/36] Pipe those failures --- bin/check-formatting.sh | 2 ++ bin/ci-check.sh | 2 ++ bin/ci.sh | 7 ++++++- bin/format.sh | 2 ++ bin/lint.sh | 4 ++++ bin/pr-check.sh | 2 ++ bin/pr.sh | 7 ++++++- package.json | 3 ++- 8 files changed, 26 insertions(+), 3 deletions(-) diff --git a/bin/check-formatting.sh b/bin/check-formatting.sh index 4dc27e95..420232e9 100755 --- a/bin/check-formatting.sh +++ b/bin/check-formatting.sh @@ -1,3 +1,5 @@ #!/bin/bash +set -euo pipefail + npx "prettier@$EXERCISM_PRETTIER_VERSION" --check "**/*.{js,jsx,ts,tsx,css,sass,scss,html,json,md,yml}" diff --git a/bin/ci-check.sh b/bin/ci-check.sh index ed478939..8db7cee5 100755 --- a/bin/ci-check.sh +++ b/bin/ci-check.sh @@ -7,6 +7,8 @@ # Why quoting the argument is "necessary": # https://stackoverflow.com/questions/4824590/propagate-all-arguments-in-a-bash-shell-script/4824637#4824637 +set -euo pipefail + # eats 1 argument shift 1 diff --git a/bin/ci.sh b/bin/ci.sh index 09e32876..1db0fad5 100755 --- a/bin/ci.sh +++ b/bin/ci.sh @@ -1 +1,6 @@ -yarn test \ No newline at end of file +#!/bin/bash + +set -euo pipefail + +yarn build +yarn test:bare \ No newline at end of file diff --git a/bin/format.sh b/bin/format.sh index 2a2141a4..c3a9470d 100755 --- a/bin/format.sh +++ b/bin/format.sh @@ -1,5 +1,7 @@ #!/usr/bin/env bash +set -euo pipefail + if [ -z "$EXERCISM_PRETTIER_VERSION" ]; then echo "This script requires the EXERCISM_PRETTIER_VERSION variable to work." echo "Please see https://github.com/exercism/v3/blob/master/docs/maintainers/style-guide.md for guidance." diff --git a/bin/lint.sh b/bin/lint.sh index c58e8ce8..75f46367 100755 --- a/bin/lint.sh +++ b/bin/lint.sh @@ -1 +1,5 @@ +#!/bin/bash + +set -euo pipefail + yarn lint \ No newline at end of file diff --git a/bin/pr-check.sh b/bin/pr-check.sh index ed478939..8db7cee5 100755 --- a/bin/pr-check.sh +++ b/bin/pr-check.sh @@ -7,6 +7,8 @@ # Why quoting the argument is "necessary": # https://stackoverflow.com/questions/4824590/propagate-all-arguments-in-a-bash-shell-script/4824637#4824637 +set -euo pipefail + # eats 1 argument shift 1 diff --git a/bin/pr.sh b/bin/pr.sh index 09e32876..1db0fad5 100755 --- a/bin/pr.sh +++ b/bin/pr.sh @@ -1 +1,6 @@ -yarn test \ No newline at end of file +#!/bin/bash + +set -euo pipefail + +yarn build +yarn test:bare \ No newline at end of file diff --git a/package.json b/package.json index 2175b509..add09850 100644 --- a/package.json +++ b/package.json @@ -23,7 +23,8 @@ "watch": "yarn build -w", "prepublish": "yarn test", "lint": "yarn eslint . --ext ts,js,tsx,jsx,mjs -c .eslintrc", - "test": "yarn build && jest --roots test --testPathIgnorePatterns=\"fixtures/\"" + "test": "yarn build && yarn test:bare", + "test:bare": "jest --roots test --testPathIgnorePatterns=\"fixtures/\"" }, "dependencies": { "@babel/cli": "^7.12.10", From 43276fda1ff66df4fa92ac45b3ac8c559d418e92 Mon Sep 17 00:00:00 2001 From: Derk-Jan Karrenbeld Date: Fri, 25 Dec 2020 00:37:53 +0100 Subject: [PATCH 34/36] Simplify binaries --- .github/workflows/ci.js.yml | 4 ++-- .github/workflows/pr.ci.js.yml | 12 ++---------- bin/ci-check.sh | 17 ----------------- bin/ci.sh | 6 ------ bin/pr-check.sh | 17 ----------------- bin/pr.sh | 6 ------ 6 files changed, 4 insertions(+), 58 deletions(-) delete mode 100755 bin/ci-check.sh delete mode 100755 bin/ci.sh delete mode 100755 bin/pr-check.sh delete mode 100755 bin/pr.sh diff --git a/.github/workflows/ci.js.yml b/.github/workflows/ci.js.yml index d81342d5..6848cc54 100644 --- a/.github/workflows/ci.js.yml +++ b/.github/workflows/ci.js.yml @@ -22,7 +22,7 @@ jobs: run: yarn install --frozen-lockfile --ignore-scripts - name: Run exercism/javascript-test-runner ci precheck (lint code) - run: bin/ci-check.sh + run: bin/lint.sh ci: runs-on: ubuntu-latest @@ -45,4 +45,4 @@ jobs: run: yarn build - name: Run exercism/javascript-test-runner ci (runs tests) - run: bin/ci.sh + run: yarn test:bare diff --git a/.github/workflows/pr.ci.js.yml b/.github/workflows/pr.ci.js.yml index 0615c94e..551aeb92 100644 --- a/.github/workflows/pr.ci.js.yml +++ b/.github/workflows/pr.ci.js.yml @@ -22,11 +22,7 @@ jobs: run: yarn install --frozen-lockfile --ignore-scripts - name: Run exercism/javascript ci precheck (lint code) - run: | - PULL_REQUEST_URL=$(jq -r ".pull_request.url" "$GITHUB_EVENT_PATH") - curl --url $"${PULL_REQUEST_URL}/files?per_page=100" --header 'authorization: Bearer ${{ secrets.GITHUB_TOKEN }}' | \ - jq -c '.[] | select(.status == "added" or .status == "modified") | select(.filename | match("\\.(js|jsx|ts|tsx|md|json)$")) | .filename' | \ - xargs -r bin/pr-check.sh + run: bin/lint.sh ci: runs-on: ubuntu-latest @@ -51,8 +47,4 @@ jobs: run: yarn build - name: Run exercism/javascript ci (runs tests) - run: | - PULL_REQUEST_URL=$(jq -r ".pull_request.url" "$GITHUB_EVENT_PATH") - curl --url $"${PULL_REQUEST_URL}/files?per_page=100" --header 'authorization: Bearer ${{ secrets.GITHUB_TOKEN }}' | \ - jq -c '.[] | select(.status == "added" or .status == "modified") | select(.filename | match("\\.(js|jsx|ts|tsx|md|json)$")) | .filename' | \ - xargs -r bin/pr.sh + run: yarn test:bare diff --git a/bin/ci-check.sh b/bin/ci-check.sh deleted file mode 100755 index 8db7cee5..00000000 --- a/bin/ci-check.sh +++ /dev/null @@ -1,17 +0,0 @@ -#!/usr/bin/env bash - -# Documentation on @ -# https://www.gnu.org/savannah-checkouts/gnu/bash/manual/bash.html#index-_0040 -# Documentation on shift [n] -# https://www.gnu.org/savannah-checkouts/gnu/bash/manual/bash.html#index-shift -# Why quoting the argument is "necessary": -# https://stackoverflow.com/questions/4824590/propagate-all-arguments-in-a-bash-shell-script/4824637#4824637 - -set -euo pipefail - -# eats 1 argument -shift 1 - -DIRNAME=$(dirname "$0") -"${DIRNAME}/lint.sh" "$@" -"${DIRNAME}/check-formatting.sh" "$@" \ No newline at end of file diff --git a/bin/ci.sh b/bin/ci.sh deleted file mode 100755 index 1db0fad5..00000000 --- a/bin/ci.sh +++ /dev/null @@ -1,6 +0,0 @@ -#!/bin/bash - -set -euo pipefail - -yarn build -yarn test:bare \ No newline at end of file diff --git a/bin/pr-check.sh b/bin/pr-check.sh deleted file mode 100755 index 8db7cee5..00000000 --- a/bin/pr-check.sh +++ /dev/null @@ -1,17 +0,0 @@ -#!/usr/bin/env bash - -# Documentation on @ -# https://www.gnu.org/savannah-checkouts/gnu/bash/manual/bash.html#index-_0040 -# Documentation on shift [n] -# https://www.gnu.org/savannah-checkouts/gnu/bash/manual/bash.html#index-shift -# Why quoting the argument is "necessary": -# https://stackoverflow.com/questions/4824590/propagate-all-arguments-in-a-bash-shell-script/4824637#4824637 - -set -euo pipefail - -# eats 1 argument -shift 1 - -DIRNAME=$(dirname "$0") -"${DIRNAME}/lint.sh" "$@" -"${DIRNAME}/check-formatting.sh" "$@" \ No newline at end of file diff --git a/bin/pr.sh b/bin/pr.sh deleted file mode 100755 index 1db0fad5..00000000 --- a/bin/pr.sh +++ /dev/null @@ -1,6 +0,0 @@ -#!/bin/bash - -set -euo pipefail - -yarn build -yarn test:bare \ No newline at end of file From 80c1eb031929daac16dd64bb508ad4359a807589 Mon Sep 17 00:00:00 2001 From: Derk-Jan Karrenbeld Date: Fri, 25 Dec 2020 00:51:19 +0100 Subject: [PATCH 35/36] Fix build step and simplify workflow further --- .github/workflows/ci.js.yml | 5 +---- .github/workflows/pr.ci.js.yml | 5 +---- bin/test.sh | 7 +++++++ package.json | 4 +++- src/tsconfig.json | 9 +++++++++ 5 files changed, 21 insertions(+), 9 deletions(-) create mode 100644 bin/test.sh create mode 100644 src/tsconfig.json diff --git a/.github/workflows/ci.js.yml b/.github/workflows/ci.js.yml index 6848cc54..205e5eca 100644 --- a/.github/workflows/ci.js.yml +++ b/.github/workflows/ci.js.yml @@ -42,7 +42,4 @@ jobs: run: yarn install --frozen-lockfile --ignore-scripts - name: Build the test-runner (using Node ${{ matrix.node-version }}) - run: yarn build - - - name: Run exercism/javascript-test-runner ci (runs tests) - run: yarn test:bare + run: bin/test.sh diff --git a/.github/workflows/pr.ci.js.yml b/.github/workflows/pr.ci.js.yml index 551aeb92..2c9fd382 100644 --- a/.github/workflows/pr.ci.js.yml +++ b/.github/workflows/pr.ci.js.yml @@ -44,7 +44,4 @@ jobs: run: yarn install --frozen-lockfile --ignore-scripts - name: Build the test-runner (using Node ${{ matrix.node-version }}) - run: yarn build - - - name: Run exercism/javascript ci (runs tests) - run: yarn test:bare + run: bin/test.sh diff --git a/bin/test.sh b/bin/test.sh new file mode 100644 index 00000000..cd4dc06b --- /dev/null +++ b/bin/test.sh @@ -0,0 +1,7 @@ +#!/bin/bash + +set -euo pipefail + +yarn build || exit +yarn test:bare + diff --git a/package.json b/package.json index add09850..30ed756f 100644 --- a/package.json +++ b/package.json @@ -19,7 +19,8 @@ "scripts": { "execute": "./bin/run.sh", "execute:dev": "yarn build && yarn execute", - "build": "yarn tsc --project ./tsconfig.json --outDir ./dist", + "prebuild": "rimraf ./dist", + "build": "yarn tsc --project ./src/tsconfig.json --outDir ./dist", "watch": "yarn build -w", "prepublish": "yarn test", "lint": "yarn eslint . --ext ts,js,tsx,jsx,mjs -c .eslintrc", @@ -51,6 +52,7 @@ "eslint-config-prettier": "^7.1.0", "eslint-plugin-import": "^2.22.1", "eslint-plugin-jest": "^24.1.3", + "rimraf": "^3.0.2", "typescript": "^4.1.3" }, "jest": { diff --git a/src/tsconfig.json b/src/tsconfig.json new file mode 100644 index 00000000..d8730c56 --- /dev/null +++ b/src/tsconfig.json @@ -0,0 +1,9 @@ +{ + "composite": true, + "extends": "../tsconfig.json", + "compilerOptions": { + "baseUrl": "./" + }, + "include": ["./"], + "exclude": ["./fixtures"] +} From 2ea2391d7464e1772e5d79be9861a30c66dc32fe Mon Sep 17 00:00:00 2001 From: Derk-Jan Karrenbeld Date: Fri, 25 Dec 2020 00:51:49 +0100 Subject: [PATCH 36/36] Make executable --- bin/test.sh | 0 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 bin/test.sh diff --git a/bin/test.sh b/bin/test.sh old mode 100644 new mode 100755