diff --git a/.gitignore b/.gitignore index a345ae0..2b6042d 100644 --- a/.gitignore +++ b/.gitignore @@ -43,6 +43,9 @@ build/ # testing /coverage +# wrapper +/node + # production /build diff --git a/.nvmrc b/.nvmrc new file mode 100644 index 0000000..0b77208 --- /dev/null +++ b/.nvmrc @@ -0,0 +1 @@ +16.14.0 \ No newline at end of file diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..6da516c --- /dev/null +++ b/.travis.yml @@ -0,0 +1,26 @@ +jobs: + include: + - language: node_js + - language: java + cache: + directories: + - "$HOME/.m2" + before_install: + - nvm install $(< .nvmrc) + script: + - npm install + - npm test + - mvn clean verify sonar:sonar -Pcoverage -DskipRedundantTests -Dsonar.projectKey=silentsoft_hits -Dsonar.sources=src/main/java,src/main/react -Dsonar.coverage.exclusions=**/index.*,**/setupTests.*,**/*.d.ts,**/__tests__/**/*,**/*.spec.*,**/*.test.* -Dsonar.javascript.lcov.reportPaths=coverage/lcov.info + +git: + depth: false + +addons: + sonarcloud: + organization: "silentsoft" + token: + secure: "O9I2+3DaVmoEuRblOn+Wv2EQSWlzCoujmBxBYmBlAudvmFXIPocPcHJXJT2hnLdKJDhVBv922JRuawwLSqVnGnNZuN9NWqDZbN79lEOXA6789V3Dd2M6LZhbEzRzNcCh2oqv8T8estta6Cf7po7CNkplZ1lbCxnKmzyv6Vuw8pqSf5UgYfZoMg+noL44qigt2d5RB3eZK9zkvNCbG8y+oHg9jmEsXJ+RVUEzHhKQwly5rlGiTqBf7yqD79hgSCmFDy7hUWpf/s8zLJQm0TdeiMn0lC82nWG0tjGwUMPbK98dhxEzFJL6NJTo4BkuDDHGAkshexwA0I7kTaWIsbHdgeFqKLy1fCz9QeL1fotzq4Cbcn1WyuvmWzBflRiNaHuKuh21Exk6iHCbe742eQu7BLpzoyhdUyUkIlaUTaJQ3AbX1oCsKCzdb5z0p9a6sMjNpSVuthXeQnc5cE+8MJnxE/kv6Bx/+ptDSWkoFkHZm+RPVLp7eNlct3NfXNcDyXAvKfRCwo+8uLi0BskKQE3Qb0rnxG1usJiAmMBc83z30A6gKPmEF6kvowl6Ej269bCL/MI1PcPiTsVEdW147oPtKzkyccYa+UKhPbER/1iJaFpTUQeyBHWK9A+yjo7V7Bsw2oyHzqukhKPoA1A504nWmuquyTJ0MvjFGbbMfYop1hE=" + +notifications: + slack: + secure: "wnKJB3Yaxaw77Ls5WiDSNzrHbNmUhdgiigCiFk121UncDfX1zBhlUAze05v7FllnY4/iHTeJoXRCDUMHfj7KPjLXutaoqa0YidpVQxWtxPJMbajBesSTjuOwjjrl5LDCWriNnRhUfcSDZwoDJSVH6ArhaXcftUX0yyHHqnr2TNc60+hfSScJNolmmgy9ht14D/7Pi2p92CmbNEVf1+sDxRnjtanV0Sk9neMTDcNuLvJYxnf+Y7mJtSgjkQsz/3UgLYDbEWmpVynONuSOu05sAG0zWTLZIXJPGL7+W2mW3VSP85wF8APVvLDB9lafY129Q1XnTUaFdu6F3ZMu9L7+CIbXhDspoikjonkhthCJDm6KtJ4+KBxLN03GDwqXy/rVpk6ER6i9jOp5bwrt7BHCbin5zYpsoMWZdpj1TyeI8zRDJdLm0GIxRxx08jAxHJSphnt+dzR7qMIymD9nv12rYVCejcosGooLWRBD+EtNSwdD/8Ne3MnfhN8m9cuiZHtcNKPjcS1Uk6m0GWU4pL4ZP0An+0cbfcnoMWZiG3Ic3iA9Ho9bSCfm1c1uNV/lwJfV4/hfx/8tiAjzoijTFTN8oIBXqsMnnDsPax1OXDGZvKCM8mWHtSmPLcIJMErY6fwEJgMnlr752RPA2ZQHR+tvT3eZa0PZonOqDPl30bt21Is=" \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index ea2ea93..66964b0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +# 1.4.0 (18 Mar 2022) + +## Enhancements +- Add auto focus feature. +- Remove terminal component. +- Supports [simple-icons v6.14.0](https://github.com/simple-icons/simple-icons/releases/tag/6.14.0). + # 1.3.0 (2 Mar 2022) ## Enhancements diff --git a/NOTICE.md b/NOTICE.md index 03b12d1..853c6c0 100644 --- a/NOTICE.md +++ b/NOTICE.md @@ -1,10 +1,6 @@ # Hits Copyright (c) silentsoft.org. All rights reserved. -__Terminal Style Portfolio in ReactJS by Jacob Lockett__ - * https://codepen.io/HuntingHawk/pen/rNaEZxW - * MIT License - __combined-stream 1.0.8__ * http://debuggable.com/ * MIT License @@ -4817,7 +4813,7 @@ __lombok 1.18.20__ * https://projectlombok.org * MIT License -__badge4j 1.7.0__ +__badge4j 1.9.0__ * https://github.com/silentsoft/badge4j * Apache License 2.0 @@ -4825,7 +4821,7 @@ __csscolor4j 1.0.0__ * https://github.com/silentsoft/csscolor4j * Apache License 2.0 -__simpleicons4j 1.5.0__ +__simpleicons4j 1.7.0__ * https://github.com/silentsoft/simpleicons4j * Apache License 2.0 diff --git a/config-overrides.js b/config-overrides.js index 22d67e9..f024f30 100644 --- a/config-overrides.js +++ b/config-overrides.js @@ -12,6 +12,31 @@ module.exports = { paths.appBuild = path.resolve(__dirname, 'target/classes/public'); return paths; }, + jest: function(config) { + config.rootDir = path.resolve(__dirname, 'src/main/react'); + config.roots = [ + '' + ]; + config.setupFilesAfterEnv = [ + '/setupTests.js' + ]; + config.transformIgnorePatterns = [ + '/node_modules/', + '\\.pnp\\.[^\\\/]+$' + ]; + config.testMatch = [ + '/**/__tests__/**/*.{js,jsx,ts,tsx}', + '/**/*.{spec,test}.{js,jsx,ts,tsx}' + ]; + config.collectCoverage = true; + config.collectCoverageFrom = [ + '**/*.{js,jsx,ts,tsx}', + '!**/*.d.ts', + '!index.{js,jsx,ts,tsx}', + ]; + config.coverageDirectory = path.resolve(__dirname, 'coverage'); + return config; + }, webpack: override( addPostcssPlugins([ require('tailwindcss'), diff --git a/package-lock.json b/package-lock.json index 7d290d2..7dd5b7f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "hits", - "version": "1.3.0", + "version": "1.4.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "hits", - "version": "1.3.0", + "version": "1.4.0", "dependencies": { "@nivo/calendar": "^0.79.1", "@nivo/colors": "^0.79.1", @@ -21,8 +21,12 @@ "react-scripts": "5.0.0" }, "devDependencies": { + "@testing-library/jest-dom": "^5.16.2", + "@testing-library/react": "^12.1.4", + "@testing-library/user-event": "^13.5.0", "autoprefixer": "^10.4.2", "customize-cra": "^1.0.0", + "jest-canvas-mock": "^2.3.1", "license-checker": "^25.0.1", "postcss": "^8.4.7", "react-app-rewired": "^2.2.1", @@ -3410,6 +3414,236 @@ "url": "https://github.com/sponsors/gregberge" } }, + "node_modules/@testing-library/dom": { + "version": "8.11.3", + "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-8.11.3.tgz", + "integrity": "sha512-9LId28I+lx70wUiZjLvi1DB/WT2zGOxUh46glrSNMaWVx849kKAluezVzZrXJfTKKoQTmEOutLes/bHg4Bj3aA==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.10.4", + "@babel/runtime": "^7.12.5", + "@types/aria-query": "^4.2.0", + "aria-query": "^5.0.0", + "chalk": "^4.1.0", + "dom-accessibility-api": "^0.5.9", + "lz-string": "^1.4.4", + "pretty-format": "^27.0.2" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@testing-library/dom/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@testing-library/dom/node_modules/aria-query": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.0.0.tgz", + "integrity": "sha512-V+SM7AbUwJ+EBnB8+DXs0hPZHO0W6pqBcc0dW90OwtVG02PswOu/teuARoLQjdDOH+t9pJgGnW5/Qmouf3gPJg==", + "dev": true, + "engines": { + "node": ">=6.0" + } + }, + "node_modules/@testing-library/dom/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/@testing-library/dom/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/@testing-library/dom/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/@testing-library/dom/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/@testing-library/dom/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@testing-library/jest-dom": { + "version": "5.16.2", + "resolved": "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-5.16.2.tgz", + "integrity": "sha512-6ewxs1MXWwsBFZXIk4nKKskWANelkdUehchEOokHsN8X7c2eKXGw+77aRV63UU8f/DTSVUPLaGxdrj4lN7D/ug==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.9.2", + "@types/testing-library__jest-dom": "^5.9.1", + "aria-query": "^5.0.0", + "chalk": "^3.0.0", + "css": "^3.0.0", + "css.escape": "^1.5.1", + "dom-accessibility-api": "^0.5.6", + "lodash": "^4.17.15", + "redent": "^3.0.0" + }, + "engines": { + "node": ">=8", + "npm": ">=6", + "yarn": ">=1" + } + }, + "node_modules/@testing-library/jest-dom/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@testing-library/jest-dom/node_modules/aria-query": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.0.0.tgz", + "integrity": "sha512-V+SM7AbUwJ+EBnB8+DXs0hPZHO0W6pqBcc0dW90OwtVG02PswOu/teuARoLQjdDOH+t9pJgGnW5/Qmouf3gPJg==", + "dev": true, + "engines": { + "node": ">=6.0" + } + }, + "node_modules/@testing-library/jest-dom/node_modules/chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@testing-library/jest-dom/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/@testing-library/jest-dom/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/@testing-library/jest-dom/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/@testing-library/jest-dom/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@testing-library/react": { + "version": "12.1.4", + "resolved": "https://registry.npmjs.org/@testing-library/react/-/react-12.1.4.tgz", + "integrity": "sha512-jiPKOm7vyUw311Hn/HlNQ9P8/lHNtArAx0PisXyFixDDvfl8DbD6EUdbshK5eqauvBSvzZd19itqQ9j3nferJA==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.12.5", + "@testing-library/dom": "^8.0.0", + "@types/react-dom": "*" + }, + "engines": { + "node": ">=12" + }, + "peerDependencies": { + "react": "*", + "react-dom": "*" + } + }, + "node_modules/@testing-library/user-event": { + "version": "13.5.0", + "resolved": "https://registry.npmjs.org/@testing-library/user-event/-/user-event-13.5.0.tgz", + "integrity": "sha512-5Kwtbo3Y/NowpkbRuSepbyMFkZmHgD+vPzYB/RJ4oxt5Gj/avFFBYjhw27cqSVPVw/3a67NK1PbiIr9k4Gwmdg==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.12.5" + }, + "engines": { + "node": ">=10", + "npm": ">=6" + }, + "peerDependencies": { + "@testing-library/dom": ">=7.21.4" + } + }, "node_modules/@tootallnate/once": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz", @@ -3426,6 +3660,12 @@ "node": ">=10.13.0" } }, + "node_modules/@types/aria-query": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@types/aria-query/-/aria-query-4.2.2.tgz", + "integrity": "sha512-HnYpAE1Y6kRyKM/XkEuiRQhTHvkzMBurTHnpFLYLBGPIylZNPs9jJcuOOYWxPLJCSEtmZT0Y8rHDokKN7rRTig==", + "dev": true + }, "node_modules/@types/babel__core": { "version": "7.1.18", "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.18.tgz", @@ -3583,6 +3823,16 @@ "@types/istanbul-lib-report": "*" } }, + "node_modules/@types/jest": { + "version": "27.4.1", + "resolved": "https://registry.npmjs.org/@types/jest/-/jest-27.4.1.tgz", + "integrity": "sha512-23iPJADSmicDVrWk+HT58LMJtzLAnB2AgIzplQuq/bSrGaxCrlvRFjGbXmamnnk/mAmCdLStiGqggu28ocUyiw==", + "dev": true, + "dependencies": { + "jest-matcher-utils": "^27.0.0", + "pretty-format": "^27.0.0" + } + }, "node_modules/@types/json-schema": { "version": "7.0.9", "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.9.tgz", @@ -3613,6 +3863,12 @@ "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.4.4.tgz", "integrity": "sha512-ReVR2rLTV1kvtlWFyuot+d1pkpG2Fw/XKE3PDAdj57rbM97ttSp9JZ2UsP+2EHTylra9cUf6JA7tGwW1INzUrA==" }, + "node_modules/@types/prop-types": { + "version": "15.7.4", + "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.4.tgz", + "integrity": "sha512-rZ5drC/jWjrArrS8BR6SIr4cWpW09RNTYt9AMZo3Jwwif+iacXAqgVjm0B0Bv/S1jhDXKHqRVNCbACkJ89RAnQ==", + "dev": true + }, "node_modules/@types/q": { "version": "1.5.5", "resolved": "https://registry.npmjs.org/@types/q/-/q-1.5.5.tgz", @@ -3628,6 +3884,26 @@ "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.4.tgz", "integrity": "sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw==" }, + "node_modules/@types/react": { + "version": "17.0.40", + "resolved": "https://registry.npmjs.org/@types/react/-/react-17.0.40.tgz", + "integrity": "sha512-UrXhD/JyLH+W70nNSufXqMZNuUD2cXHu6UjCllC6pmOQgBX4SGXOH8fjRka0O0Ee0HrFxapDD8Bwn81Kmiz6jQ==", + "dev": true, + "dependencies": { + "@types/prop-types": "*", + "@types/scheduler": "*", + "csstype": "^3.0.2" + } + }, + "node_modules/@types/react-dom": { + "version": "17.0.13", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-17.0.13.tgz", + "integrity": "sha512-wEP+B8hzvy6ORDv1QBhcQia4j6ea4SFIBttHYpXKPFZRviBvknq0FRh3VrIxeXUmsPkwuXVZrVGG7KUVONmXCQ==", + "dev": true, + "dependencies": { + "@types/react": "*" + } + }, "node_modules/@types/resolve": { "version": "1.17.1", "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.17.1.tgz", @@ -3641,6 +3917,12 @@ "resolved": "https://registry.npmjs.org/@types/retry/-/retry-0.12.1.tgz", "integrity": "sha512-xoDlM2S4ortawSWORYqsdU+2rxdh4LRW9ytc3zmT37RIKQh6IHyKwwtKhKis9ah8ol07DCkZxPt8BBvPjC6v4g==" }, + "node_modules/@types/scheduler": { + "version": "0.16.2", + "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.2.tgz", + "integrity": "sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew==", + "dev": true + }, "node_modules/@types/serve-index": { "version": "1.9.1", "resolved": "https://registry.npmjs.org/@types/serve-index/-/serve-index-1.9.1.tgz", @@ -3671,6 +3953,15 @@ "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.1.tgz", "integrity": "sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==" }, + "node_modules/@types/testing-library__jest-dom": { + "version": "5.14.3", + "resolved": "https://registry.npmjs.org/@types/testing-library__jest-dom/-/testing-library__jest-dom-5.14.3.tgz", + "integrity": "sha512-oKZe+Mf4ioWlMuzVBaXQ9WDnEm1+umLx0InILg+yvZVBBDmzV5KfZyLrCvadtWcx8+916jLmHafcmqqffl+iIw==", + "dev": true, + "dependencies": { + "@types/jest": "*" + } + }, "node_modules/@types/trusted-types": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.2.tgz", @@ -4570,6 +4861,18 @@ "node": ">= 4.0.0" } }, + "node_modules/atob": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", + "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==", + "dev": true, + "bin": { + "atob": "bin/atob.js" + }, + "engines": { + "node": ">= 4.5.0" + } + }, "node_modules/autoprefixer": { "version": "10.4.2", "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.2.tgz", @@ -5628,6 +5931,17 @@ "node": ">=8" } }, + "node_modules/css": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/css/-/css-3.0.0.tgz", + "integrity": "sha512-DG9pFfwOrzc+hawpmqX/dHYHJG+Bsdb0klhyi1sDneOgGOXy9wQIC8hzyVp1e4NRYDBdxcylvywPkkXCHAzTyQ==", + "dev": true, + "dependencies": { + "inherits": "^2.0.4", + "source-map": "^0.6.1", + "source-map-resolve": "^0.6.0" + } + }, "node_modules/css-blank-pseudo": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/css-blank-pseudo/-/css-blank-pseudo-3.0.3.tgz", @@ -5874,6 +6188,21 @@ "url": "https://github.com/sponsors/fb55" } }, + "node_modules/css.escape": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/css.escape/-/css.escape-1.5.1.tgz", + "integrity": "sha1-QuJ9T6BK4y+TGktNQZH6nN3ul8s=", + "dev": true + }, + "node_modules/css/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/cssdb": { "version": "6.4.0", "resolved": "https://registry.npmjs.org/cssdb/-/cssdb-6.4.0.tgz", @@ -5890,6 +6219,12 @@ "node": ">=4" } }, + "node_modules/cssfontparser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/cssfontparser/-/cssfontparser-1.2.1.tgz", + "integrity": "sha1-9AIvyPlwDGgCnVQghK+69CWj8+M=", + "dev": true + }, "node_modules/cssnano": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/cssnano/-/cssnano-5.1.0.tgz", @@ -6020,6 +6355,12 @@ "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.8.tgz", "integrity": "sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==" }, + "node_modules/csstype": { + "version": "3.0.11", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.0.11.tgz", + "integrity": "sha512-sa6P2wJ+CAbgyy4KFssIb/JNMLxFvKF1pCYCSXS8ZMuqZnMsrxqI2E5sPyoTpxoPU/gVZMzr2zjOfg8GIZOMsw==", + "dev": true + }, "node_modules/customize-cra": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/customize-cra/-/customize-cra-1.0.0.tgz", @@ -6150,6 +6491,15 @@ "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.3.1.tgz", "integrity": "sha512-V0pfhfr8suzyPGOx3nmq4aHqabehUZn6Ch9kyFpV79TGDTWFmHqUqXdabR7QHqxzrYolF4+tVmJhUG4OURg5dQ==" }, + "node_modules/decode-uri-component": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", + "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=", + "dev": true, + "engines": { + "node": ">=0.10" + } + }, "node_modules/dedent": { "version": "0.7.0", "resolved": "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz", @@ -6391,6 +6741,12 @@ "node": ">=6.0.0" } }, + "node_modules/dom-accessibility-api": { + "version": "0.5.13", + "resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.5.13.tgz", + "integrity": "sha512-R305kwb5CcMDIpSHUnLyIAp7SrSPBx6F0VfQFB3M75xVMHhXJJIdePYgbPPh1o57vCHNu5QztokWUPsLjWzFqw==", + "dev": true + }, "node_modules/dom-converter": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/dom-converter/-/dom-converter-0.2.0.tgz", @@ -9202,6 +9558,16 @@ } } }, + "node_modules/jest-canvas-mock": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/jest-canvas-mock/-/jest-canvas-mock-2.3.1.tgz", + "integrity": "sha512-5FnSZPrX3Q2ZfsbYNE3wqKR3+XorN8qFzDzB5o0golWgt6EOX1+emBnpOc9IAQ+NXFj8Nzm3h7ZdE/9H0ylBcg==", + "dev": true, + "dependencies": { + "cssfontparser": "^1.2.1", + "moo-color": "^1.0.2" + } + }, "node_modules/jest-changed-files": { "version": "27.5.1", "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-27.5.1.tgz", @@ -11214,6 +11580,15 @@ "node": ">=10" } }, + "node_modules/lz-string": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/lz-string/-/lz-string-1.4.4.tgz", + "integrity": "sha1-wNjq82BZ9wV5bh40SBHPTEmNOiY=", + "dev": true, + "bin": { + "lz-string": "bin/bin.js" + } + }, "node_modules/magic-string": { "version": "0.25.7", "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.7.tgz", @@ -11357,6 +11732,15 @@ "node": ">=6" } }, + "node_modules/min-indent": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", + "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==", + "dev": true, + "engines": { + "node": ">=4" + } + }, "node_modules/mini-css-extract-plugin": { "version": "2.5.3", "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-2.5.3.tgz", @@ -11456,6 +11840,21 @@ "mkdirp": "bin/cmd.js" } }, + "node_modules/moo-color": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/moo-color/-/moo-color-1.0.2.tgz", + "integrity": "sha512-5iXz5n9LWQzx/C2WesGFfpE6RLamzdHwsn3KpfzShwbfIqs7stnoEpaNErf/7+3mbxwZ4s8Foq7I0tPxw7BWHg==", + "dev": true, + "dependencies": { + "color-name": "^1.1.4" + } + }, + "node_modules/moo-color/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, "node_modules/ms": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", @@ -13902,6 +14301,19 @@ "node": "*" } }, + "node_modules/redent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz", + "integrity": "sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==", + "dev": true, + "dependencies": { + "indent-string": "^4.0.0", + "strip-indent": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/regenerate": { "version": "1.4.2", "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz", @@ -14614,6 +15026,17 @@ "webpack": "^5.0.0" } }, + "node_modules/source-map-resolve": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.6.0.tgz", + "integrity": "sha512-KXBr9d/fO/bWo97NXsPIAW1bFSBOuCnjbNTBMO7N59hsv5i9yzRDfcYwwt0l04+VqnKC+EwzvJZIP/qkuMgR/w==", + "deprecated": "See https://github.com/lydell/source-map-resolve#deprecated", + "dev": true, + "dependencies": { + "atob": "^2.1.2", + "decode-uri-component": "^0.2.0" + } + }, "node_modules/source-map-support": { "version": "0.5.21", "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", @@ -14960,6 +15383,18 @@ "node": ">=6" } }, + "node_modules/strip-indent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz", + "integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==", + "dev": true, + "dependencies": { + "min-indent": "^1.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/strip-json-comments": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", @@ -19025,6 +19460,173 @@ "loader-utils": "^2.0.0" } }, + "@testing-library/dom": { + "version": "8.11.3", + "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-8.11.3.tgz", + "integrity": "sha512-9LId28I+lx70wUiZjLvi1DB/WT2zGOxUh46glrSNMaWVx849kKAluezVzZrXJfTKKoQTmEOutLes/bHg4Bj3aA==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.10.4", + "@babel/runtime": "^7.12.5", + "@types/aria-query": "^4.2.0", + "aria-query": "^5.0.0", + "chalk": "^4.1.0", + "dom-accessibility-api": "^0.5.9", + "lz-string": "^1.4.4", + "pretty-format": "^27.0.2" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "aria-query": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.0.0.tgz", + "integrity": "sha512-V+SM7AbUwJ+EBnB8+DXs0hPZHO0W6pqBcc0dW90OwtVG02PswOu/teuARoLQjdDOH+t9pJgGnW5/Qmouf3gPJg==", + "dev": true + }, + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "@testing-library/jest-dom": { + "version": "5.16.2", + "resolved": "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-5.16.2.tgz", + "integrity": "sha512-6ewxs1MXWwsBFZXIk4nKKskWANelkdUehchEOokHsN8X7c2eKXGw+77aRV63UU8f/DTSVUPLaGxdrj4lN7D/ug==", + "dev": true, + "requires": { + "@babel/runtime": "^7.9.2", + "@types/testing-library__jest-dom": "^5.9.1", + "aria-query": "^5.0.0", + "chalk": "^3.0.0", + "css": "^3.0.0", + "css.escape": "^1.5.1", + "dom-accessibility-api": "^0.5.6", + "lodash": "^4.17.15", + "redent": "^3.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "aria-query": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.0.0.tgz", + "integrity": "sha512-V+SM7AbUwJ+EBnB8+DXs0hPZHO0W6pqBcc0dW90OwtVG02PswOu/teuARoLQjdDOH+t9pJgGnW5/Qmouf3gPJg==", + "dev": true + }, + "chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "@testing-library/react": { + "version": "12.1.4", + "resolved": "https://registry.npmjs.org/@testing-library/react/-/react-12.1.4.tgz", + "integrity": "sha512-jiPKOm7vyUw311Hn/HlNQ9P8/lHNtArAx0PisXyFixDDvfl8DbD6EUdbshK5eqauvBSvzZd19itqQ9j3nferJA==", + "dev": true, + "requires": { + "@babel/runtime": "^7.12.5", + "@testing-library/dom": "^8.0.0", + "@types/react-dom": "*" + } + }, + "@testing-library/user-event": { + "version": "13.5.0", + "resolved": "https://registry.npmjs.org/@testing-library/user-event/-/user-event-13.5.0.tgz", + "integrity": "sha512-5Kwtbo3Y/NowpkbRuSepbyMFkZmHgD+vPzYB/RJ4oxt5Gj/avFFBYjhw27cqSVPVw/3a67NK1PbiIr9k4Gwmdg==", + "dev": true, + "requires": { + "@babel/runtime": "^7.12.5" + } + }, "@tootallnate/once": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz", @@ -19035,6 +19637,12 @@ "resolved": "https://registry.npmjs.org/@trysound/sax/-/sax-0.2.0.tgz", "integrity": "sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==" }, + "@types/aria-query": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@types/aria-query/-/aria-query-4.2.2.tgz", + "integrity": "sha512-HnYpAE1Y6kRyKM/XkEuiRQhTHvkzMBurTHnpFLYLBGPIylZNPs9jJcuOOYWxPLJCSEtmZT0Y8rHDokKN7rRTig==", + "dev": true + }, "@types/babel__core": { "version": "7.1.18", "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.18.tgz", @@ -19192,6 +19800,16 @@ "@types/istanbul-lib-report": "*" } }, + "@types/jest": { + "version": "27.4.1", + "resolved": "https://registry.npmjs.org/@types/jest/-/jest-27.4.1.tgz", + "integrity": "sha512-23iPJADSmicDVrWk+HT58LMJtzLAnB2AgIzplQuq/bSrGaxCrlvRFjGbXmamnnk/mAmCdLStiGqggu28ocUyiw==", + "dev": true, + "requires": { + "jest-matcher-utils": "^27.0.0", + "pretty-format": "^27.0.0" + } + }, "@types/json-schema": { "version": "7.0.9", "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.9.tgz", @@ -19222,6 +19840,12 @@ "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.4.4.tgz", "integrity": "sha512-ReVR2rLTV1kvtlWFyuot+d1pkpG2Fw/XKE3PDAdj57rbM97ttSp9JZ2UsP+2EHTylra9cUf6JA7tGwW1INzUrA==" }, + "@types/prop-types": { + "version": "15.7.4", + "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.4.tgz", + "integrity": "sha512-rZ5drC/jWjrArrS8BR6SIr4cWpW09RNTYt9AMZo3Jwwif+iacXAqgVjm0B0Bv/S1jhDXKHqRVNCbACkJ89RAnQ==", + "dev": true + }, "@types/q": { "version": "1.5.5", "resolved": "https://registry.npmjs.org/@types/q/-/q-1.5.5.tgz", @@ -19237,6 +19861,26 @@ "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.4.tgz", "integrity": "sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw==" }, + "@types/react": { + "version": "17.0.40", + "resolved": "https://registry.npmjs.org/@types/react/-/react-17.0.40.tgz", + "integrity": "sha512-UrXhD/JyLH+W70nNSufXqMZNuUD2cXHu6UjCllC6pmOQgBX4SGXOH8fjRka0O0Ee0HrFxapDD8Bwn81Kmiz6jQ==", + "dev": true, + "requires": { + "@types/prop-types": "*", + "@types/scheduler": "*", + "csstype": "^3.0.2" + } + }, + "@types/react-dom": { + "version": "17.0.13", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-17.0.13.tgz", + "integrity": "sha512-wEP+B8hzvy6ORDv1QBhcQia4j6ea4SFIBttHYpXKPFZRviBvknq0FRh3VrIxeXUmsPkwuXVZrVGG7KUVONmXCQ==", + "dev": true, + "requires": { + "@types/react": "*" + } + }, "@types/resolve": { "version": "1.17.1", "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.17.1.tgz", @@ -19250,6 +19894,12 @@ "resolved": "https://registry.npmjs.org/@types/retry/-/retry-0.12.1.tgz", "integrity": "sha512-xoDlM2S4ortawSWORYqsdU+2rxdh4LRW9ytc3zmT37RIKQh6IHyKwwtKhKis9ah8ol07DCkZxPt8BBvPjC6v4g==" }, + "@types/scheduler": { + "version": "0.16.2", + "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.2.tgz", + "integrity": "sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew==", + "dev": true + }, "@types/serve-index": { "version": "1.9.1", "resolved": "https://registry.npmjs.org/@types/serve-index/-/serve-index-1.9.1.tgz", @@ -19280,6 +19930,15 @@ "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.1.tgz", "integrity": "sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==" }, + "@types/testing-library__jest-dom": { + "version": "5.14.3", + "resolved": "https://registry.npmjs.org/@types/testing-library__jest-dom/-/testing-library__jest-dom-5.14.3.tgz", + "integrity": "sha512-oKZe+Mf4ioWlMuzVBaXQ9WDnEm1+umLx0InILg+yvZVBBDmzV5KfZyLrCvadtWcx8+916jLmHafcmqqffl+iIw==", + "dev": true, + "requires": { + "@types/jest": "*" + } + }, "@types/trusted-types": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.2.tgz", @@ -19931,6 +20590,12 @@ "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==" }, + "atob": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", + "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==", + "dev": true + }, "autoprefixer": { "version": "10.4.2", "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.2.tgz", @@ -20734,6 +21399,25 @@ "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-2.0.0.tgz", "integrity": "sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA==" }, + "css": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/css/-/css-3.0.0.tgz", + "integrity": "sha512-DG9pFfwOrzc+hawpmqX/dHYHJG+Bsdb0klhyi1sDneOgGOXy9wQIC8hzyVp1e4NRYDBdxcylvywPkkXCHAzTyQ==", + "dev": true, + "requires": { + "inherits": "^2.0.4", + "source-map": "^0.6.1", + "source-map-resolve": "^0.6.0" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } + } + }, "css-blank-pseudo": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/css-blank-pseudo/-/css-blank-pseudo-3.0.3.tgz", @@ -20882,6 +21566,12 @@ "resolved": "https://registry.npmjs.org/css-what/-/css-what-5.1.0.tgz", "integrity": "sha512-arSMRWIIFY0hV8pIxZMEfmMI47Wj3R/aWpZDDxWYCPEiOMv6tfOrnpDtgxBYPEQD4V0Y/958+1TdC3iWTFcUPw==" }, + "css.escape": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/css.escape/-/css.escape-1.5.1.tgz", + "integrity": "sha1-QuJ9T6BK4y+TGktNQZH6nN3ul8s=", + "dev": true + }, "cssdb": { "version": "6.4.0", "resolved": "https://registry.npmjs.org/cssdb/-/cssdb-6.4.0.tgz", @@ -20892,6 +21582,12 @@ "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==" }, + "cssfontparser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/cssfontparser/-/cssfontparser-1.2.1.tgz", + "integrity": "sha1-9AIvyPlwDGgCnVQghK+69CWj8+M=", + "dev": true + }, "cssnano": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/cssnano/-/cssnano-5.1.0.tgz", @@ -20993,6 +21689,12 @@ } } }, + "csstype": { + "version": "3.0.11", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.0.11.tgz", + "integrity": "sha512-sa6P2wJ+CAbgyy4KFssIb/JNMLxFvKF1pCYCSXS8ZMuqZnMsrxqI2E5sPyoTpxoPU/gVZMzr2zjOfg8GIZOMsw==", + "dev": true + }, "customize-cra": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/customize-cra/-/customize-cra-1.0.0.tgz", @@ -21119,6 +21821,12 @@ "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.3.1.tgz", "integrity": "sha512-V0pfhfr8suzyPGOx3nmq4aHqabehUZn6Ch9kyFpV79TGDTWFmHqUqXdabR7QHqxzrYolF4+tVmJhUG4OURg5dQ==" }, + "decode-uri-component": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", + "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=", + "dev": true + }, "dedent": { "version": "0.7.0", "resolved": "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz", @@ -21310,6 +22018,12 @@ "esutils": "^2.0.2" } }, + "dom-accessibility-api": { + "version": "0.5.13", + "resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.5.13.tgz", + "integrity": "sha512-R305kwb5CcMDIpSHUnLyIAp7SrSPBx6F0VfQFB3M75xVMHhXJJIdePYgbPPh1o57vCHNu5QztokWUPsLjWzFqw==", + "dev": true + }, "dom-converter": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/dom-converter/-/dom-converter-0.2.0.tgz", @@ -23299,6 +24013,16 @@ "jest-cli": "^27.5.1" } }, + "jest-canvas-mock": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/jest-canvas-mock/-/jest-canvas-mock-2.3.1.tgz", + "integrity": "sha512-5FnSZPrX3Q2ZfsbYNE3wqKR3+XorN8qFzDzB5o0golWgt6EOX1+emBnpOc9IAQ+NXFj8Nzm3h7ZdE/9H0ylBcg==", + "dev": true, + "requires": { + "cssfontparser": "^1.2.1", + "moo-color": "^1.0.2" + } + }, "jest-changed-files": { "version": "27.5.1", "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-27.5.1.tgz", @@ -24776,6 +25500,12 @@ "yallist": "^4.0.0" } }, + "lz-string": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/lz-string/-/lz-string-1.4.4.tgz", + "integrity": "sha1-wNjq82BZ9wV5bh40SBHPTEmNOiY=", + "dev": true + }, "magic-string": { "version": "0.25.7", "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.7.tgz", @@ -24882,6 +25612,12 @@ "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==" }, + "min-indent": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", + "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==", + "dev": true + }, "mini-css-extract-plugin": { "version": "2.5.3", "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-2.5.3.tgz", @@ -24953,6 +25689,23 @@ "minimist": "^1.2.5" } }, + "moo-color": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/moo-color/-/moo-color-1.0.2.tgz", + "integrity": "sha512-5iXz5n9LWQzx/C2WesGFfpE6RLamzdHwsn3KpfzShwbfIqs7stnoEpaNErf/7+3mbxwZ4s8Foq7I0tPxw7BWHg==", + "dev": true, + "requires": { + "color-name": "^1.1.4" + }, + "dependencies": { + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + } + } + }, "ms": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", @@ -26616,6 +27369,16 @@ } } }, + "redent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz", + "integrity": "sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==", + "dev": true, + "requires": { + "indent-string": "^4.0.0", + "strip-indent": "^3.0.0" + } + }, "regenerate": { "version": "1.4.2", "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz", @@ -27135,6 +27898,16 @@ "source-map-js": "^1.0.1" } }, + "source-map-resolve": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.6.0.tgz", + "integrity": "sha512-KXBr9d/fO/bWo97NXsPIAW1bFSBOuCnjbNTBMO7N59hsv5i9yzRDfcYwwt0l04+VqnKC+EwzvJZIP/qkuMgR/w==", + "dev": true, + "requires": { + "atob": "^2.1.2", + "decode-uri-component": "^0.2.0" + } + }, "source-map-support": { "version": "0.5.21", "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", @@ -27418,6 +28191,15 @@ "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==" }, + "strip-indent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz", + "integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==", + "dev": true, + "requires": { + "min-indent": "^1.0.0" + } + }, "strip-json-comments": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", diff --git a/package.json b/package.json index 1aaf49e..2e65f0c 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "hits", - "version": "1.3.0", + "version": "1.4.0", "private": true, "dependencies": { "@nivo/calendar": "^0.79.1", @@ -35,8 +35,12 @@ ] }, "devDependencies": { + "@testing-library/jest-dom": "^5.16.2", + "@testing-library/react": "^12.1.4", + "@testing-library/user-event": "^13.5.0", "autoprefixer": "^10.4.2", "customize-cra": "^1.0.0", + "jest-canvas-mock": "^2.3.1", "license-checker": "^25.0.1", "postcss": "^8.4.7", "react-app-rewired": "^2.2.1", diff --git a/pom.xml b/pom.xml index 2c7fd13..78089ce 100644 --- a/pom.xml +++ b/pom.xml @@ -11,7 +11,7 @@ org.silentsoft hits - 1.3.0 + 1.4.0 Hits Hit Counter for Your GitHub or Any Kind of Websites You Want @@ -61,6 +61,36 @@ ${project.artifactId} + + coverage + + dev + build:dev + + + + + org.jacoco + jacoco-maven-plugin + 0.8.5 + + + prepare-agent + + prepare-agent + + + + report + + report + + + + + + + @@ -77,40 +107,62 @@ + + org.apache.maven.plugins + maven-compiler-plugin + 3.8.0 + + 1.8 + 1.8 + + + + org.apache.maven.plugins + maven-surefire-plugin + 2.22.2 + + + org.apache.maven.plugins + maven-failsafe-plugin + 2.22.2 + org.springframework.boot spring-boot-maven-plugin - org.codehaus.mojo - exec-maven-plugin - 1.6.0 + com.github.eirslett + frontend-maven-plugin + 1.9.1 + + v16.14.0 + + + install-node-and-npm + + install-node-and-npm + + generate-resources + npm-install - initialize - exec + npm + generate-resources - npm - - install - + install npm-run-build - process-resources - exec + npm + generate-resources - npm - - run - ${npmBuildScript} - + run ${npmBuildScript} @@ -137,12 +189,12 @@ org.silentsoft simpleicons4j - 1.5.0 + 1.7.0 org.silentsoft badge4j - 1.7.0 + 1.9.0 org.silentsoft.oss diff --git a/src/main/react/App.js b/src/main/react/App.js index f7c8ef7..e401b4f 100644 --- a/src/main/react/App.js +++ b/src/main/react/App.js @@ -1,31 +1,12 @@ -import Header from "./Header"; -import Content from "./Content"; -import Footer from "./Footer"; -import Terminal from "./terminal/Terminal"; +import {Routes, Route} from "react-router-dom"; +import Home from "./Home"; +import Dashboard from "./Dashboard"; export default function App() { return ( -
-
-
-
-
-
-

- Hit Counter for Your GitHub or Any Kind of Websites You Want -

-

Now it's time to hit's. Happy hacking !

-
-
- -
-
-
-
-
- -
-
-
+ + }/> + }/> + ); } \ No newline at end of file diff --git a/src/main/react/App.test.js b/src/main/react/App.test.js new file mode 100644 index 0000000..6b084ac --- /dev/null +++ b/src/main/react/App.test.js @@ -0,0 +1,14 @@ +import {render} from "@testing-library/react"; +import {BrowserRouter, MemoryRouter} from "react-router-dom"; +import App from "./App"; + +describe("App", () => { + it("should render the Home", () => { + render(); + expect(document.body).toHaveTextContent("Hit Counter for Your GitHub or Any Kind of Websites You Want"); + }); + it("should render the Dashboard", () => { + render(); + expect(document.body).toHaveTextContent("github.com/silentsoft/hits"); + }); +}); \ No newline at end of file diff --git a/src/main/react/Content.js b/src/main/react/Content.js index 8ab18a9..aafb125 100644 --- a/src/main/react/Content.js +++ b/src/main/react/Content.js @@ -117,7 +117,7 @@ export default function Content(props) { - +
diff --git a/src/main/react/Content.test.js b/src/main/react/Content.test.js new file mode 100644 index 0000000..ec345bb --- /dev/null +++ b/src/main/react/Content.test.js @@ -0,0 +1,60 @@ +import {fireEvent, render, screen} from "@testing-library/react"; +import {BrowserRouter} from "react-router-dom"; +import Content from "./Content"; +import userEvent from "@testing-library/user-event"; + +test("Content", () => { + render(); + + const input = screen.getByPlaceholderText("https://github.com/silentsoft/hits"); + expect(input).toBeInTheDocument(); + + const viewType = screen.getByDisplayValue("total"); + expect(viewType).toBeInTheDocument(); + + const style = screen.getByDisplayValue("flat"); + expect(style).toBeInTheDocument(); + + const label = screen.getByPlaceholderText("hits"); + expect(label).toBeInTheDocument(); + + const extraCount = screen.getByPlaceholderText("0"); + expect(extraCount).toBeInTheDocument(); + + const color = screen.getByPlaceholderText("#4c1"); + expect(color).toBeInTheDocument(); + + const labelColor = screen.getByPlaceholderText("#555"); + expect(labelColor).toBeInTheDocument(); + + const logo = screen.getByPlaceholderText("slug or base64"); + expect(logo).toBeInTheDocument(); + + expect(screen.getAllByText("No URL specified")).toHaveLength(3); + + userEvent.type(input, "https://hits"); + expect(screen.getAllByText("Invalid URL")).toHaveLength(3); + + userEvent.clear(input); + userEvent.type(input, "https://hits.sh/"); + expect(screen.getByText(`[![Hits](https://hits.sh/hits.sh.svg)](https://hits.sh/hits.sh/)`)).toBeInTheDocument(); + expect(screen.getByText(`Hits`)).toBeInTheDocument(); + expect(screen.getByText(`https://hits.sh/hits.sh.svg`)).toBeInTheDocument(); + + userEvent.selectOptions(viewType, "today-total"); + userEvent.selectOptions(style, "flat-square"); + userEvent.type(label, "page views"); + + userEvent.type(extraCount, "1"); + fireEvent.keyPress(extraCount, {key: "a", code: "KeyA", charCode: "97", ctrlKey: true}); + fireEvent.keyPress(extraCount, {key: "a", code: "KeyA", charCode: "97"}); + fireEvent.keyPress(extraCount, {key: "0", code: "Digit0", charCode: "48"}); + userEvent.type(extraCount, "000"); + + userEvent.type(color, "#000"); + userEvent.type(labelColor, "#fff"); + userEvent.type(logo, "github"); + expect(screen.getByText(`[![Hits](https://hits.sh/hits.sh.svg?view=today-total&style=flat-square&label=page%20views&extraCount=1000&color=000&labelColor=fff&logo=github)](https://hits.sh/hits.sh/)`)).toBeInTheDocument(); + expect(screen.getByText(`Hits`)).toBeInTheDocument(); + expect(screen.getByText(`https://hits.sh/hits.sh.svg?view=today-total&style=flat-square&label=page%20views&extraCount=1000&color=000&labelColor=fff&logo=github`)).toBeInTheDocument(); +}); \ No newline at end of file diff --git a/src/main/react/Dashboard.js b/src/main/react/Dashboard.js index e5d3652..5e16821 100644 --- a/src/main/react/Dashboard.js +++ b/src/main/react/Dashboard.js @@ -48,15 +48,15 @@ export default function Dashboard() {
-

{weekly}

+

{weekly}

Weekly

-

{monthly}

+

{monthly}

Monthly

-

{total}

+

{total}

Total

@@ -66,7 +66,7 @@ export default function Dashboard() { {items.length > 0 ? ( items.reduce((acc, item, index) => { acc.push( -
+
+
{ + it("should render with items", async () => { + axios.get.mockResolvedValue({ + data: { + total: 3, + monthly: 2, + weekly: 1, + items: [ + { + from: "2021-01-01", + to: "2021-12-31", + data: [ + { + value: 1, + day: "2021-12-31", + }, + ], + }, + { + from: "2022-01-01", + to: "2022-12-31", + data: [ + { + value: 2, + day: "2022-01-01", + }, + ], + } + ] + } + }); + + await render(); + + expect(screen.getByText("github.com/silentsoft/hits")).toBeInTheDocument(); + expect(screen.getByTestId("weekly")).toHaveTextContent("1"); + expect(screen.getByText("Weekly")).toBeInTheDocument(); + expect(screen.getByTestId("monthly")).toHaveTextContent("2"); + expect(screen.getByText("Monthly")).toBeInTheDocument(); + expect(screen.getByTestId("total")).toHaveTextContent("3"); + expect(screen.getByText("Total")).toBeInTheDocument(); + expect(screen.getAllByTestId("chart")).toHaveLength(2); + }); + it("should render without items", () => { + axios.get.mockRejectedValue(new Error()); + + render(); + + expect(screen.getByText("github.com/silentsoft/hits")).toBeInTheDocument(); + expect(screen.queryByTestId("weekly")).not.toBeInTheDocument(); + expect(screen.queryByText("Weekly")).not.toBeInTheDocument(); + expect(screen.queryByTestId("monthly")).not.toBeInTheDocument(); + expect(screen.queryByText("Monthly")).not.toBeInTheDocument(); + expect(screen.queryByTestId("total")).not.toBeInTheDocument(); + expect(screen.queryByText("Total")).not.toBeInTheDocument(); + expect(screen.getAllByTestId("chart")).toHaveLength(1); + }); +}); \ No newline at end of file diff --git a/src/main/react/Footer.test.js b/src/main/react/Footer.test.js new file mode 100644 index 0000000..b868d91 --- /dev/null +++ b/src/main/react/Footer.test.js @@ -0,0 +1,9 @@ +import {render, screen} from "@testing-library/react"; +import Footer from "./Footer"; + +describe("Footer", () => { + it("should render the copyright notice", () => { + render(