summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--frontend/.eslintrc.json10
-rw-r--r--frontend/.prettierignore2
-rw-r--r--frontend/package-lock.json875
-rw-r--r--frontend/package.json11
-rw-r--r--frontend/src/components/bazarr/Language.test.tsx82
-rw-r--r--frontend/src/components/inputs/Action.test.tsx38
-rw-r--r--frontend/src/components/inputs/ChipInput.test.tsx46
-rw-r--r--frontend/src/components/inputs/Selector.test.tsx147
-rw-r--r--frontend/src/modules/modals/modal.test.ts12
-rw-r--r--frontend/src/pages/Authentication.test.tsx20
-rw-r--r--frontend/src/pages/Authentication.tsx2
-rw-r--r--frontend/src/pages/Settings/components/Layout.test.tsx31
-rw-r--r--frontend/src/pages/Settings/components/Section.test.tsx38
-rw-r--r--frontend/src/pages/Settings/components/forms.test.tsx42
-rw-r--r--frontend/src/types/react-table.d.ts5
-rw-r--r--frontend/test/render.test.tsx23
-rw-r--r--frontend/test/setup.ts27
17 files changed, 1273 insertions, 138 deletions
diff --git a/frontend/.eslintrc.json b/frontend/.eslintrc.json
index 7292b8a84..d0d37a2ac 100644
--- a/frontend/.eslintrc.json
+++ b/frontend/.eslintrc.json
@@ -11,5 +11,15 @@
"plugin:react-hooks/recommended",
"eslint:recommended",
"plugin:@typescript-eslint/recommended"
+ ],
+ "plugins": ["testing-library"],
+ "overrides": [
+ {
+ "files": [
+ "**/__tests__/**/*.[jt]s?(x)",
+ "**/?(*.)+(spec|test).[jt]s?(x)"
+ ],
+ "extends": ["plugin:testing-library/react"]
+ }
]
}
diff --git a/frontend/.prettierignore b/frontend/.prettierignore
index a8d998e96..2fd8bf549 100644
--- a/frontend/.prettierignore
+++ b/frontend/.prettierignore
@@ -1,4 +1,4 @@
build
dist
-converage
+coverage
public
diff --git a/frontend/package-lock.json b/frontend/package-lock.json
index a68c73554..b6a813bd9 100644
--- a/frontend/package-lock.json
+++ b/frontend/package-lock.json
@@ -30,7 +30,7 @@
"@fortawesome/free-solid-svg-icons": "^6.2.0",
"@fortawesome/react-fontawesome": "^0.2.0",
"@testing-library/jest-dom": "^5.16.5",
- "@testing-library/react": "^12.1.5",
+ "@testing-library/react": "^12.1.0",
"@testing-library/react-hooks": "^8.0.1",
"@testing-library/user-event": "^14.4.3",
"@types/lodash": "^4.14.0",
@@ -39,10 +39,13 @@
"@types/react-dom": "^17.0.0",
"@types/react-table": "^7.7.0",
"@vitejs/plugin-react": "^2.2.0",
+ "@vitest/coverage-c8": "^0.25.0",
+ "@vitest/ui": "^0.25.0",
"clsx": "^1.2.0",
"eslint": "^8.26.0",
"eslint-config-react-app": "^7.0.1",
"eslint-plugin-react-hooks": "^4.6.0",
+ "eslint-plugin-testing-library": "^5.9.0",
"husky": "^8.0.2",
"jsdom": "^20.0.1",
"lodash": "^4.17.0",
@@ -56,7 +59,7 @@
"typescript": "^4",
"vite": "^3.2.1",
"vite-plugin-checker": "^0.5.5",
- "vitest": "^0.24.3"
+ "vitest": "^0.25.0"
}
},
"node_modules/@adobe/css-tools": {
@@ -1939,6 +1942,12 @@
"node": ">=6.9.0"
}
},
+ "node_modules/@bcoe/v8-coverage": {
+ "version": "0.2.3",
+ "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz",
+ "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==",
+ "dev": true
+ },
"node_modules/@emotion/babel-plugin": {
"version": "11.10.5",
"resolved": "https://registry.npmjs.org/@emotion/babel-plugin/-/babel-plugin-11.10.5.tgz",
@@ -2295,6 +2304,15 @@
"integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==",
"dev": true
},
+ "node_modules/@istanbuljs/schema": {
+ "version": "0.1.3",
+ "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz",
+ "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
"node_modules/@jest/expect-utils": {
"version": "29.2.2",
"resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-29.2.2.tgz",
@@ -2630,6 +2648,12 @@
"node": ">= 8"
}
},
+ "node_modules/@polka/url": {
+ "version": "1.0.0-next.21",
+ "resolved": "https://registry.npmjs.org/@polka/url/-/url-1.0.0-next.21.tgz",
+ "integrity": "sha512-a5Sab1C4/icpTZVzZc5Ghpz88yQtGOyNqYXcZgOssB2uuAr+wF/MvN6bgtW32q7HHrvBki+BsZ0OuNv6EV3K9g==",
+ "dev": true
+ },
"node_modules/@radix-ui/number": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/@radix-ui/number/-/number-1.0.0.tgz",
@@ -3033,9 +3057,9 @@
"dev": true
},
"node_modules/@types/chai": {
- "version": "4.3.3",
- "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.3.tgz",
- "integrity": "sha512-hC7OMnszpxhZPduX+m+nrx+uFoLkWOMiR4oa/AZF3MuSETYTZmFfJAHqZEM8MVlvfG7BEUcgvtwoCTxBp6hm3g==",
+ "version": "4.3.4",
+ "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.4.tgz",
+ "integrity": "sha512-KnRanxnpfpjUTqTCXslZSEdLfXExwgNxYPdiO2WGUj8+HDjFi8R3k5RVKPeSCzLjCcshCAtVO2QBbVuAV4kTnw==",
"dev": true
},
"node_modules/@types/chai-subset": {
@@ -3563,6 +3587,28 @@
"vite": "^3.0.0"
}
},
+ "node_modules/@vitest/coverage-c8": {
+ "version": "0.25.8",
+ "resolved": "https://registry.npmjs.org/@vitest/coverage-c8/-/coverage-c8-0.25.8.tgz",
+ "integrity": "sha512-fWgzQoK2KNzTTNnDcLCyibfO9/pbcpPOMtZ9Yvq/Eggpi2X8lewx/OcKZkO5ba5q9dl6+BBn6d5hTcS1709rZw==",
+ "dev": true,
+ "dependencies": {
+ "c8": "^7.12.0",
+ "vitest": "0.25.8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/antfu"
+ }
+ },
+ "node_modules/@vitest/ui": {
+ "version": "0.25.8",
+ "resolved": "https://registry.npmjs.org/@vitest/ui/-/ui-0.25.8.tgz",
+ "integrity": "sha512-wfuhghldD5QHLYpS46GK8Ru8P3XcMrWvFjRQD21KNzc9Y/qtJsqoC8KmT6xWVkMNw4oHYixpo3a4ZySRJdserw==",
+ "dev": true,
+ "dependencies": {
+ "sirv": "^2.0.2"
+ }
+ },
"node_modules/abab": {
"version": "2.0.6",
"resolved": "https://registry.npmjs.org/abab/-/abab-2.0.6.tgz",
@@ -4034,6 +4080,32 @@
"node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7"
}
},
+ "node_modules/c8": {
+ "version": "7.12.0",
+ "resolved": "https://registry.npmjs.org/c8/-/c8-7.12.0.tgz",
+ "integrity": "sha512-CtgQrHOkyxr5koX1wEUmN/5cfDa2ckbHRA4Gy5LAL0zaCFtVWJS5++n+w4/sr2GWGerBxgTjpKeDclk/Qk6W/A==",
+ "dev": true,
+ "dependencies": {
+ "@bcoe/v8-coverage": "^0.2.3",
+ "@istanbuljs/schema": "^0.1.3",
+ "find-up": "^5.0.0",
+ "foreground-child": "^2.0.0",
+ "istanbul-lib-coverage": "^3.2.0",
+ "istanbul-lib-report": "^3.0.0",
+ "istanbul-reports": "^3.1.4",
+ "rimraf": "^3.0.2",
+ "test-exclude": "^6.0.0",
+ "v8-to-istanbul": "^9.0.0",
+ "yargs": "^16.2.0",
+ "yargs-parser": "^20.2.9"
+ },
+ "bin": {
+ "c8": "bin/c8.js"
+ },
+ "engines": {
+ "node": ">=10.12.0"
+ }
+ },
"node_modules/call-bind": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz",
@@ -4071,14 +4143,14 @@
]
},
"node_modules/chai": {
- "version": "4.3.6",
- "resolved": "https://registry.npmjs.org/chai/-/chai-4.3.6.tgz",
- "integrity": "sha512-bbcp3YfHCUzMOvKqsztczerVgBKSsEijCySNlHHbX3VG1nskvqjz5Rfso1gGwD6w6oOV3eI60pKuMOV5MV7p3Q==",
+ "version": "4.3.7",
+ "resolved": "https://registry.npmjs.org/chai/-/chai-4.3.7.tgz",
+ "integrity": "sha512-HLnAzZ2iupm25PlN0xFreAlBA5zaBSv3og0DdeGA4Ar6h6rJ3A0rolRUKJhSF2V10GZKDgWF/VmAEsNWjCRB+A==",
"dev": true,
"dependencies": {
"assertion-error": "^1.1.0",
"check-error": "^1.0.2",
- "deep-eql": "^3.0.1",
+ "deep-eql": "^4.1.2",
"get-func-name": "^2.0.0",
"loupe": "^2.3.1",
"pathval": "^1.1.1",
@@ -4169,6 +4241,17 @@
"integrity": "sha512-CSbhY4cFEJRe6/GQzIk5qXZ4Jeg5pcsP7b5peFSDpffpe1cqjASH/n9UTjBwOp6XpMSTwQ8Za2K5V02ueA7Tmw==",
"dev": true
},
+ "node_modules/cliui": {
+ "version": "7.0.4",
+ "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz",
+ "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==",
+ "dev": true,
+ "dependencies": {
+ "string-width": "^4.2.0",
+ "strip-ansi": "^6.0.0",
+ "wrap-ansi": "^7.0.0"
+ }
+ },
"node_modules/clsx": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/clsx/-/clsx-1.2.1.tgz",
@@ -4446,15 +4529,15 @@
"dev": true
},
"node_modules/deep-eql": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz",
- "integrity": "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==",
+ "version": "4.1.3",
+ "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-4.1.3.tgz",
+ "integrity": "sha512-WaEtAOpRA1MQ0eohqZjpGD8zdI0Ovsm8mmFhaDN8dvDZzyoUMcYDnf5Y6iu7HTXxf8JDS23qWa4a+hKCDyOPzw==",
"dev": true,
"dependencies": {
"type-detect": "^4.0.0"
},
"engines": {
- "node": ">=0.12"
+ "node": ">=6"
}
},
"node_modules/deep-equal": {
@@ -5201,9 +5284,9 @@
}
},
"node_modules/eslint": {
- "version": "8.26.0",
- "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.26.0.tgz",
- "integrity": "sha512-kzJkpaw1Bfwheq4VXUezFriD1GxszX6dUekM7Z3aC2o4hju+tsR/XyTC3RcoSD7jmy9VkPU3+N6YjVU2e96Oyg==",
+ "version": "8.29.0",
+ "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.29.0.tgz",
+ "integrity": "sha512-isQ4EEiyUjZFbEKvEGJKKGBwXtvXX+zJbkVKCgTuB9t/+jUBcy8avhkEwWJecI15BkRkOYmvIM5ynbhRjEkoeg==",
"dev": true,
"dependencies": {
"@eslint/eslintrc": "^1.3.3",
@@ -5977,6 +6060,19 @@
"is-callable": "^1.1.3"
}
},
+ "node_modules/foreground-child": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-2.0.0.tgz",
+ "integrity": "sha512-dCIq9FpEcyQyXKCkyzmlPTFNgrCzPudOe+mhvJU5zAtlBnGVy2yKxtfsxK2tQBThwq225jcvBjpw1Gr40uzZCA==",
+ "dev": true,
+ "dependencies": {
+ "cross-spawn": "^7.0.0",
+ "signal-exit": "^3.0.2"
+ },
+ "engines": {
+ "node": ">=8.0.0"
+ }
+ },
"node_modules/form-data": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz",
@@ -6072,6 +6168,15 @@
"node": ">=6.9.0"
}
},
+ "node_modules/get-caller-file": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
+ "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==",
+ "dev": true,
+ "engines": {
+ "node": "6.* || 8.* || >= 10.*"
+ }
+ },
"node_modules/get-func-name": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz",
@@ -6293,6 +6398,12 @@
"node": ">=12"
}
},
+ "node_modules/html-escaper": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz",
+ "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==",
+ "dev": true
+ },
"node_modules/http-proxy-agent": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz",
@@ -6546,6 +6657,15 @@
"node": ">=0.10.0"
}
},
+ "node_modules/is-fullwidth-code-point": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
+ "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
"node_modules/is-glob": {
"version": "4.0.3",
"resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
@@ -6762,6 +6882,63 @@
"integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==",
"dev": true
},
+ "node_modules/istanbul-lib-coverage": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz",
+ "integrity": "sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/istanbul-lib-report": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz",
+ "integrity": "sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw==",
+ "dev": true,
+ "dependencies": {
+ "istanbul-lib-coverage": "^3.0.0",
+ "make-dir": "^3.0.0",
+ "supports-color": "^7.1.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/istanbul-lib-report/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/istanbul-lib-report/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/istanbul-reports": {
+ "version": "3.1.5",
+ "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.5.tgz",
+ "integrity": "sha512-nUsEMa9pBt/NOHqbcbeJEgqIlY/K7rVWUX6Lql2orY5e9roQOthbR3vtY4zzf2orPELg80fnxxk9zUyPlgwD1w==",
+ "dev": true,
+ "dependencies": {
+ "html-escaper": "^2.0.0",
+ "istanbul-lib-report": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
"node_modules/jest-diff": {
"version": "29.2.1",
"resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-29.2.1.tgz",
@@ -7243,18 +7420,18 @@
}
},
"node_modules/jsdom": {
- "version": "20.0.1",
- "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-20.0.1.tgz",
- "integrity": "sha512-pksjj7Rqoa+wdpkKcLzQRHhJCEE42qQhl/xLMUKHgoSejaKOdaXEAnqs6uDNwMl/fciHTzKeR8Wm8cw7N+g98A==",
+ "version": "20.0.3",
+ "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-20.0.3.tgz",
+ "integrity": "sha512-SYhBvTh89tTfCD/CRdSOm13mOBa42iTaTyfyEWBdKcGdPxPtLFBXuHR8XHb33YNYaP+lLbmSvBTsnoesCNJEsQ==",
"dev": true,
"dependencies": {
"abab": "^2.0.6",
- "acorn": "^8.8.0",
+ "acorn": "^8.8.1",
"acorn-globals": "^7.0.0",
"cssom": "^0.5.0",
"cssstyle": "^2.3.0",
"data-urls": "^3.0.2",
- "decimal.js": "^10.4.1",
+ "decimal.js": "^10.4.2",
"domexception": "^4.0.0",
"escodegen": "^2.0.0",
"form-data": "^4.0.0",
@@ -7267,12 +7444,12 @@
"saxes": "^6.0.0",
"symbol-tree": "^3.2.4",
"tough-cookie": "^4.1.2",
- "w3c-xmlserializer": "^3.0.0",
+ "w3c-xmlserializer": "^4.0.0",
"webidl-conversions": "^7.0.0",
"whatwg-encoding": "^2.0.0",
"whatwg-mimetype": "^3.0.0",
"whatwg-url": "^11.0.0",
- "ws": "^8.9.0",
+ "ws": "^8.11.0",
"xml-name-validator": "^4.0.0"
},
"engines": {
@@ -7464,9 +7641,9 @@
}
},
"node_modules/loupe": {
- "version": "2.3.4",
- "resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.4.tgz",
- "integrity": "sha512-OvKfgCC2Ndby6aSTREl5aCCPTNIzlDfQZvZxNUrBrihDhL3xcrYegTblhmEiCrg2kKQz4XsFIaemE5BF4ybSaQ==",
+ "version": "2.3.6",
+ "resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.6.tgz",
+ "integrity": "sha512-RaPMZKiMy8/JruncMU5Bt6na1eftNoo++R4Y+N2FrxkDVTrGvcyzFTsaGif4QTeKESheMGegbhw6iUAq+5A8zA==",
"dev": true,
"dependencies": {
"get-func-name": "^2.0.0"
@@ -7505,6 +7682,21 @@
"node": ">=12"
}
},
+ "node_modules/make-dir": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz",
+ "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==",
+ "dev": true,
+ "dependencies": {
+ "semver": "^6.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
"node_modules/match-sorter": {
"version": "6.3.1",
"resolved": "https://registry.npmjs.org/match-sorter/-/match-sorter-6.3.1.tgz",
@@ -7622,6 +7814,15 @@
"node": ">=4"
}
},
+ "node_modules/mrmime": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/mrmime/-/mrmime-1.0.1.tgz",
+ "integrity": "sha512-hzzEagAgDyoU1Q6yg5uI+AorQgdvMCur3FcKf7NhMKWsaYg+RnbTyHRa/9IlLF9rf455MOCtcqqrQQ83pPP7Uw==",
+ "dev": true,
+ "engines": {
+ "node": ">=10"
+ }
+ },
"node_modules/ms": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
@@ -8051,9 +8252,9 @@
}
},
"node_modules/prettier": {
- "version": "2.7.1",
- "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.7.1.tgz",
- "integrity": "sha512-ujppO+MkdPqoVINuDFDRLClm7D78qbDt0/NR+wp5FqEZOoTNAjPHWj17QRhu7geIHJfcNhRk1XVQmF8Bp3ye+g==",
+ "version": "2.8.1",
+ "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.1.tgz",
+ "integrity": "sha512-lqGoSJBQNJidqCHE80vqZJHWHRFoNYsSpP9AjFhlhi9ODCJA541svILes/+/1GM3VaL/abZi7cpFzOpdR9UPKg==",
"dev": true,
"bin": {
"prettier": "bin-prettier.js"
@@ -8066,16 +8267,20 @@
}
},
"node_modules/prettier-plugin-organize-imports": {
- "version": "3.1.1",
- "resolved": "https://registry.npmjs.org/prettier-plugin-organize-imports/-/prettier-plugin-organize-imports-3.1.1.tgz",
- "integrity": "sha512-6bHIQzybqA644h0WGUW3gpWEVbMBvzui5wCMRBi7qA++d5ov2xjjfDk8pxJJ/ardfZrGAwizKMq/fQMFdJ+0Zw==",
+ "version": "3.2.1",
+ "resolved": "https://registry.npmjs.org/prettier-plugin-organize-imports/-/prettier-plugin-organize-imports-3.2.1.tgz",
+ "integrity": "sha512-bty7C2Ecard5EOXirtzeCAqj4FU4epeuWrQt/Z+sh8UVEpBlBZ3m3KNPz2kFu7KgRTQx/C9o4/TdquPD1jOqjQ==",
"dev": true,
"peerDependencies": {
- "@volar/vue-typescript": ">=0.40.2",
+ "@volar/vue-language-plugin-pug": "^1.0.4",
+ "@volar/vue-typescript": "^1.0.4",
"prettier": ">=2.0",
"typescript": ">=2.9"
},
"peerDependenciesMeta": {
+ "@volar/vue-language-plugin-pug": {
+ "optional": true
+ },
"@volar/vue-typescript": {
"optional": true
}
@@ -8723,6 +8928,15 @@
"resolved": "https://registry.npmjs.org/remove-accents/-/remove-accents-0.4.2.tgz",
"integrity": "sha512-7pXIJqJOq5tFgG1A2Zxti3Ht8jJF337m4sowbuHsW30ZnkQFnDzy9qBNhgzX8ZLW4+UBcXiiR7SwR6pokHsxiA=="
},
+ "node_modules/require-directory": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
+ "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
"node_modules/requires-port": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz",
@@ -8922,6 +9136,20 @@
"integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==",
"dev": true
},
+ "node_modules/sirv": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/sirv/-/sirv-2.0.2.tgz",
+ "integrity": "sha512-4Qog6aE29nIjAOKe/wowFTxOdmbEZKb+3tsLljaBRzJwtqto0BChD2zzH0LhgCSXiI+V7X+Y45v14wBZQ1TK3w==",
+ "dev": true,
+ "dependencies": {
+ "@polka/url": "^1.0.0-next.20",
+ "mrmime": "^1.0.0",
+ "totalist": "^3.0.0"
+ },
+ "engines": {
+ "node": ">= 10"
+ }
+ },
"node_modules/slash": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz",
@@ -9008,6 +9236,26 @@
"integrity": "sha512-n3sPwynL1nwKi3WJ6AIsClwBMa0zTi54fn2oLU6ndfTSIO05xaznjSf15PcBZU6FNWbmN5Q6cxT4V5hGvB4taw==",
"dev": true
},
+ "node_modules/string-width": {
+ "version": "4.2.3",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
+ "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
+ "dev": true,
+ "dependencies": {
+ "emoji-regex": "^8.0.0",
+ "is-fullwidth-code-point": "^3.0.0",
+ "strip-ansi": "^6.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/string-width/node_modules/emoji-regex": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
+ "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
+ "dev": true
+ },
"node_modules/string.prototype.matchall": {
"version": "4.0.7",
"resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.7.tgz",
@@ -9110,12 +9358,12 @@
}
},
"node_modules/strip-literal": {
- "version": "0.4.2",
- "resolved": "https://registry.npmjs.org/strip-literal/-/strip-literal-0.4.2.tgz",
- "integrity": "sha512-pv48ybn4iE1O9RLgCAN0iU4Xv7RlBTiit6DKmMiErbs9x1wH6vXBs45tWc0H5wUIF6TLTrKweqkmYF/iraQKNw==",
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/strip-literal/-/strip-literal-1.0.0.tgz",
+ "integrity": "sha512-5o4LsH1lzBzO9UFH63AJ2ad2/S2AVx6NtjOcaz+VTT2h1RiRvbipW72z8M/lxEhcPHDBQwpDrnTF7sXy/7OwCQ==",
"dev": true,
"dependencies": {
- "acorn": "^8.8.0"
+ "acorn": "^8.8.1"
},
"funding": {
"url": "https://github.com/sponsors/antfu"
@@ -9155,6 +9403,20 @@
"integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==",
"dev": true
},
+ "node_modules/test-exclude": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz",
+ "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==",
+ "dev": true,
+ "dependencies": {
+ "@istanbuljs/schema": "^0.1.2",
+ "glob": "^7.1.4",
+ "minimatch": "^3.0.4"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
"node_modules/text-table": {
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz",
@@ -9211,6 +9473,15 @@
"node": ">=8.0"
}
},
+ "node_modules/totalist": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/totalist/-/totalist-3.0.0.tgz",
+ "integrity": "sha512-eM+pCBxXO/njtF7vdFsHuqb+ElbxqtI4r5EAvk6grfAFyJ6IvWlSkfZ5T9ozC6xWw3Fj1fGoSmrl0gUs46JVIw==",
+ "dev": true,
+ "engines": {
+ "node": ">=6"
+ }
+ },
"node_modules/tough-cookie": {
"version": "4.1.2",
"resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.2.tgz",
@@ -9488,6 +9759,20 @@
}
}
},
+ "node_modules/v8-to-istanbul": {
+ "version": "9.0.1",
+ "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.0.1.tgz",
+ "integrity": "sha512-74Y4LqY74kLE6IFyIjPtkSTWzUZmj8tdHT9Ii/26dvQ6K9Dl2NbEfj0XgU2sHCtKgt5VupqhlO/5aWuqS+IY1w==",
+ "dev": true,
+ "dependencies": {
+ "@jridgewell/trace-mapping": "^0.3.12",
+ "@types/istanbul-lib-coverage": "^2.0.1",
+ "convert-source-map": "^1.6.0"
+ },
+ "engines": {
+ "node": ">=10.12.0"
+ }
+ },
"node_modules/vite": {
"version": "3.2.1",
"resolved": "https://registry.npmjs.org/vite/-/vite-3.2.1.tgz",
@@ -9668,22 +9953,25 @@
}
},
"node_modules/vitest": {
- "version": "0.24.3",
- "resolved": "https://registry.npmjs.org/vitest/-/vitest-0.24.3.tgz",
- "integrity": "sha512-aM0auuPPgMSstWvr851hB74g/LKaKBzSxcG3da7ejfZbx08Y21JpZmbmDYrMTCGhVZKqTGwzcnLMwyfz2WzkhQ==",
+ "version": "0.25.8",
+ "resolved": "https://registry.npmjs.org/vitest/-/vitest-0.25.8.tgz",
+ "integrity": "sha512-X75TApG2wZTJn299E/TIYevr4E9/nBo1sUtZzn0Ci5oK8qnpZAZyhwg0qCeMSakGIWtc6oRwcQFyFfW14aOFWg==",
"dev": true,
"dependencies": {
- "@types/chai": "^4.3.3",
+ "@types/chai": "^4.3.4",
"@types/chai-subset": "^1.3.3",
"@types/node": "*",
- "chai": "^4.3.6",
+ "acorn": "^8.8.1",
+ "acorn-walk": "^8.2.0",
+ "chai": "^4.3.7",
"debug": "^4.3.4",
"local-pkg": "^0.4.2",
- "strip-literal": "^0.4.2",
- "tinybench": "^2.3.0",
+ "source-map": "^0.6.1",
+ "strip-literal": "^1.0.0",
+ "tinybench": "^2.3.1",
"tinypool": "^0.3.0",
"tinyspy": "^1.0.2",
- "vite": "^3.0.0"
+ "vite": "^3.0.0 || ^4.0.0"
},
"bin": {
"vitest": "vitest.mjs"
@@ -9719,6 +10007,15 @@
}
}
},
+ "node_modules/vitest/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/vscode-jsonrpc": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-6.0.0.tgz",
@@ -9798,15 +10095,15 @@
"dev": true
},
"node_modules/w3c-xmlserializer": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-3.0.0.tgz",
- "integrity": "sha512-3WFqGEgSXIyGhOmAFtlicJNMjEps8b1MG31NCA0/vOF9+nKMUW1ckhi9cnNHmf88Rzw5V+dwIwsm2C7X8k9aQg==",
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-4.0.0.tgz",
+ "integrity": "sha512-d+BFHzbiCx6zGfz0HyQ6Rg69w9k19nviJspaj4yNscGjrHu94sVP+aRm75yEbCh+r2/yR+7q6hux9LVtbuTGBw==",
"dev": true,
"dependencies": {
"xml-name-validator": "^4.0.0"
},
"engines": {
- "node": ">=12"
+ "node": ">=14"
}
},
"node_modules/webidl-conversions": {
@@ -9927,15 +10224,65 @@
"node": ">=0.10.0"
}
},
+ "node_modules/wrap-ansi": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
+ "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
+ "dev": true,
+ "dependencies": {
+ "ansi-styles": "^4.0.0",
+ "string-width": "^4.1.0",
+ "strip-ansi": "^6.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/wrap-ansi?sponsor=1"
+ }
+ },
+ "node_modules/wrap-ansi/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/wrap-ansi/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/wrap-ansi/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/wrappy": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
"integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ=="
},
"node_modules/ws": {
- "version": "8.10.0",
- "resolved": "https://registry.npmjs.org/ws/-/ws-8.10.0.tgz",
- "integrity": "sha512-+s49uSmZpvtAsd2h37vIPy1RBusaLawVe8of+GyEPsaJTCMpj/2v8NpeK1SHXjBlQ95lQTmQofOJnFiLoaN3yw==",
+ "version": "8.11.0",
+ "resolved": "https://registry.npmjs.org/ws/-/ws-8.11.0.tgz",
+ "integrity": "sha512-HPG3wQd9sNQoT9xHyNCXoDUa+Xw/VevmY9FoHyQ+g+rrMn4j6FB4np7Z0OhdTgjx6MgQLK7jwSy1YecU1+4Asg==",
"dev": true,
"engines": {
"node": ">=10.0.0"
@@ -9976,6 +10323,15 @@
"node": ">=0.4.0"
}
},
+ "node_modules/y18n": {
+ "version": "5.0.8",
+ "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz",
+ "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==",
+ "dev": true,
+ "engines": {
+ "node": ">=10"
+ }
+ },
"node_modules/yallist": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
@@ -9990,6 +10346,33 @@
"node": ">= 6"
}
},
+ "node_modules/yargs": {
+ "version": "16.2.0",
+ "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz",
+ "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==",
+ "dev": true,
+ "dependencies": {
+ "cliui": "^7.0.2",
+ "escalade": "^3.1.1",
+ "get-caller-file": "^2.0.5",
+ "require-directory": "^2.1.1",
+ "string-width": "^4.2.0",
+ "y18n": "^5.0.5",
+ "yargs-parser": "^20.2.2"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/yargs-parser": {
+ "version": "20.2.9",
+ "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz",
+ "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==",
+ "dev": true,
+ "engines": {
+ "node": ">=10"
+ }
+ },
"node_modules/yocto-queue": {
"version": "0.1.0",
"resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz",
@@ -11289,6 +11672,12 @@
"to-fast-properties": "^2.0.0"
}
},
+ "@bcoe/v8-coverage": {
+ "version": "0.2.3",
+ "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz",
+ "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==",
+ "dev": true
+ },
"@emotion/babel-plugin": {
"version": "11.10.5",
"resolved": "https://registry.npmjs.org/@emotion/babel-plugin/-/babel-plugin-11.10.5.tgz",
@@ -11552,6 +11941,12 @@
"integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==",
"dev": true
},
+ "@istanbuljs/schema": {
+ "version": "0.1.3",
+ "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz",
+ "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==",
+ "dev": true
+ },
"@jest/expect-utils": {
"version": "29.2.2",
"resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-29.2.2.tgz",
@@ -11801,6 +12196,12 @@
"fastq": "^1.6.0"
}
},
+ "@polka/url": {
+ "version": "1.0.0-next.21",
+ "resolved": "https://registry.npmjs.org/@polka/url/-/url-1.0.0-next.21.tgz",
+ "integrity": "sha512-a5Sab1C4/icpTZVzZc5Ghpz88yQtGOyNqYXcZgOssB2uuAr+wF/MvN6bgtW32q7HHrvBki+BsZ0OuNv6EV3K9g==",
+ "dev": true
+ },
"@radix-ui/number": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/@radix-ui/number/-/number-1.0.0.tgz",
@@ -12095,9 +12496,9 @@
"dev": true
},
"@types/chai": {
- "version": "4.3.3",
- "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.3.tgz",
- "integrity": "sha512-hC7OMnszpxhZPduX+m+nrx+uFoLkWOMiR4oa/AZF3MuSETYTZmFfJAHqZEM8MVlvfG7BEUcgvtwoCTxBp6hm3g==",
+ "version": "4.3.4",
+ "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.4.tgz",
+ "integrity": "sha512-KnRanxnpfpjUTqTCXslZSEdLfXExwgNxYPdiO2WGUj8+HDjFi8R3k5RVKPeSCzLjCcshCAtVO2QBbVuAV4kTnw==",
"dev": true
},
"@types/chai-subset": {
@@ -12495,6 +12896,25 @@
"react-refresh": "^0.14.0"
}
},
+ "@vitest/coverage-c8": {
+ "version": "0.25.8",
+ "resolved": "https://registry.npmjs.org/@vitest/coverage-c8/-/coverage-c8-0.25.8.tgz",
+ "integrity": "sha512-fWgzQoK2KNzTTNnDcLCyibfO9/pbcpPOMtZ9Yvq/Eggpi2X8lewx/OcKZkO5ba5q9dl6+BBn6d5hTcS1709rZw==",
+ "dev": true,
+ "requires": {
+ "c8": "^7.12.0",
+ "vitest": "0.25.8"
+ }
+ },
+ "@vitest/ui": {
+ "version": "0.25.8",
+ "resolved": "https://registry.npmjs.org/@vitest/ui/-/ui-0.25.8.tgz",
+ "integrity": "sha512-wfuhghldD5QHLYpS46GK8Ru8P3XcMrWvFjRQD21KNzc9Y/qtJsqoC8KmT6xWVkMNw4oHYixpo3a4ZySRJdserw==",
+ "dev": true,
+ "requires": {
+ "sirv": "^2.0.2"
+ }
+ },
"abab": {
"version": "2.0.6",
"resolved": "https://registry.npmjs.org/abab/-/abab-2.0.6.tgz",
@@ -12841,6 +13261,26 @@
"update-browserslist-db": "^1.0.9"
}
},
+ "c8": {
+ "version": "7.12.0",
+ "resolved": "https://registry.npmjs.org/c8/-/c8-7.12.0.tgz",
+ "integrity": "sha512-CtgQrHOkyxr5koX1wEUmN/5cfDa2ckbHRA4Gy5LAL0zaCFtVWJS5++n+w4/sr2GWGerBxgTjpKeDclk/Qk6W/A==",
+ "dev": true,
+ "requires": {
+ "@bcoe/v8-coverage": "^0.2.3",
+ "@istanbuljs/schema": "^0.1.3",
+ "find-up": "^5.0.0",
+ "foreground-child": "^2.0.0",
+ "istanbul-lib-coverage": "^3.2.0",
+ "istanbul-lib-report": "^3.0.0",
+ "istanbul-reports": "^3.1.4",
+ "rimraf": "^3.0.2",
+ "test-exclude": "^6.0.0",
+ "v8-to-istanbul": "^9.0.0",
+ "yargs": "^16.2.0",
+ "yargs-parser": "^20.2.9"
+ }
+ },
"call-bind": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz",
@@ -12862,14 +13302,14 @@
"integrity": "sha512-lfXQ73oB9c8DP5Suxaszm+Ta2sr/4tf8+381GkIm1MLj/YdLf+rEDyDSRCzeltuyTVGm+/s18gdZ0q+Wmp8VsQ=="
},
"chai": {
- "version": "4.3.6",
- "resolved": "https://registry.npmjs.org/chai/-/chai-4.3.6.tgz",
- "integrity": "sha512-bbcp3YfHCUzMOvKqsztczerVgBKSsEijCySNlHHbX3VG1nskvqjz5Rfso1gGwD6w6oOV3eI60pKuMOV5MV7p3Q==",
+ "version": "4.3.7",
+ "resolved": "https://registry.npmjs.org/chai/-/chai-4.3.7.tgz",
+ "integrity": "sha512-HLnAzZ2iupm25PlN0xFreAlBA5zaBSv3og0DdeGA4Ar6h6rJ3A0rolRUKJhSF2V10GZKDgWF/VmAEsNWjCRB+A==",
"dev": true,
"requires": {
"assertion-error": "^1.1.0",
"check-error": "^1.0.2",
- "deep-eql": "^3.0.1",
+ "deep-eql": "^4.1.2",
"get-func-name": "^2.0.0",
"loupe": "^2.3.1",
"pathval": "^1.1.1",
@@ -12938,6 +13378,17 @@
"integrity": "sha512-CSbhY4cFEJRe6/GQzIk5qXZ4Jeg5pcsP7b5peFSDpffpe1cqjASH/n9UTjBwOp6XpMSTwQ8Za2K5V02ueA7Tmw==",
"dev": true
},
+ "cliui": {
+ "version": "7.0.4",
+ "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz",
+ "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==",
+ "dev": true,
+ "requires": {
+ "string-width": "^4.2.0",
+ "strip-ansi": "^6.0.0",
+ "wrap-ansi": "^7.0.0"
+ }
+ },
"clsx": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/clsx/-/clsx-1.2.1.tgz",
@@ -13179,9 +13630,9 @@
"dev": true
},
"deep-eql": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz",
- "integrity": "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==",
+ "version": "4.1.3",
+ "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-4.1.3.tgz",
+ "integrity": "sha512-WaEtAOpRA1MQ0eohqZjpGD8zdI0Ovsm8mmFhaDN8dvDZzyoUMcYDnf5Y6iu7HTXxf8JDS23qWa4a+hKCDyOPzw==",
"dev": true,
"requires": {
"type-detect": "^4.0.0"
@@ -13653,9 +14104,9 @@
}
},
"eslint": {
- "version": "8.26.0",
- "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.26.0.tgz",
- "integrity": "sha512-kzJkpaw1Bfwheq4VXUezFriD1GxszX6dUekM7Z3aC2o4hju+tsR/XyTC3RcoSD7jmy9VkPU3+N6YjVU2e96Oyg==",
+ "version": "8.29.0",
+ "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.29.0.tgz",
+ "integrity": "sha512-isQ4EEiyUjZFbEKvEGJKKGBwXtvXX+zJbkVKCgTuB9t/+jUBcy8avhkEwWJecI15BkRkOYmvIM5ynbhRjEkoeg==",
"dev": true,
"requires": {
"@eslint/eslintrc": "^1.3.3",
@@ -14231,6 +14682,16 @@
"is-callable": "^1.1.3"
}
},
+ "foreground-child": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-2.0.0.tgz",
+ "integrity": "sha512-dCIq9FpEcyQyXKCkyzmlPTFNgrCzPudOe+mhvJU5zAtlBnGVy2yKxtfsxK2tQBThwq225jcvBjpw1Gr40uzZCA==",
+ "dev": true,
+ "requires": {
+ "cross-spawn": "^7.0.0",
+ "signal-exit": "^3.0.2"
+ }
+ },
"form-data": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz",
@@ -14300,6 +14761,12 @@
"resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz",
"integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg=="
},
+ "get-caller-file": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
+ "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==",
+ "dev": true
+ },
"get-func-name": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz",
@@ -14458,6 +14925,12 @@
"whatwg-encoding": "^2.0.0"
}
},
+ "html-escaper": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz",
+ "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==",
+ "dev": true
+ },
"http-proxy-agent": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz",
@@ -14636,6 +15109,12 @@
"integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
"dev": true
},
+ "is-fullwidth-code-point": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
+ "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
+ "dev": true
+ },
"is-glob": {
"version": "4.0.3",
"resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
@@ -14783,6 +15262,50 @@
"integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==",
"dev": true
},
+ "istanbul-lib-coverage": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz",
+ "integrity": "sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw==",
+ "dev": true
+ },
+ "istanbul-lib-report": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz",
+ "integrity": "sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw==",
+ "dev": true,
+ "requires": {
+ "istanbul-lib-coverage": "^3.0.0",
+ "make-dir": "^3.0.0",
+ "supports-color": "^7.1.0"
+ },
+ "dependencies": {
+ "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"
+ }
+ }
+ }
+ },
+ "istanbul-reports": {
+ "version": "3.1.5",
+ "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.5.tgz",
+ "integrity": "sha512-nUsEMa9pBt/NOHqbcbeJEgqIlY/K7rVWUX6Lql2orY5e9roQOthbR3vtY4zzf2orPELg80fnxxk9zUyPlgwD1w==",
+ "dev": true,
+ "requires": {
+ "html-escaper": "^2.0.0",
+ "istanbul-lib-report": "^3.0.0"
+ }
+ },
"jest-diff": {
"version": "29.2.1",
"resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-29.2.1.tgz",
@@ -15149,18 +15672,18 @@
}
},
"jsdom": {
- "version": "20.0.1",
- "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-20.0.1.tgz",
- "integrity": "sha512-pksjj7Rqoa+wdpkKcLzQRHhJCEE42qQhl/xLMUKHgoSejaKOdaXEAnqs6uDNwMl/fciHTzKeR8Wm8cw7N+g98A==",
+ "version": "20.0.3",
+ "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-20.0.3.tgz",
+ "integrity": "sha512-SYhBvTh89tTfCD/CRdSOm13mOBa42iTaTyfyEWBdKcGdPxPtLFBXuHR8XHb33YNYaP+lLbmSvBTsnoesCNJEsQ==",
"dev": true,
"requires": {
"abab": "^2.0.6",
- "acorn": "^8.8.0",
+ "acorn": "^8.8.1",
"acorn-globals": "^7.0.0",
"cssom": "^0.5.0",
"cssstyle": "^2.3.0",
"data-urls": "^3.0.2",
- "decimal.js": "^10.4.1",
+ "decimal.js": "^10.4.2",
"domexception": "^4.0.0",
"escodegen": "^2.0.0",
"form-data": "^4.0.0",
@@ -15173,12 +15696,12 @@
"saxes": "^6.0.0",
"symbol-tree": "^3.2.4",
"tough-cookie": "^4.1.2",
- "w3c-xmlserializer": "^3.0.0",
+ "w3c-xmlserializer": "^4.0.0",
"webidl-conversions": "^7.0.0",
"whatwg-encoding": "^2.0.0",
"whatwg-mimetype": "^3.0.0",
"whatwg-url": "^11.0.0",
- "ws": "^8.9.0",
+ "ws": "^8.11.0",
"xml-name-validator": "^4.0.0"
}
},
@@ -15320,9 +15843,9 @@
}
},
"loupe": {
- "version": "2.3.4",
- "resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.4.tgz",
- "integrity": "sha512-OvKfgCC2Ndby6aSTREl5aCCPTNIzlDfQZvZxNUrBrihDhL3xcrYegTblhmEiCrg2kKQz4XsFIaemE5BF4ybSaQ==",
+ "version": "2.3.6",
+ "resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.6.tgz",
+ "integrity": "sha512-RaPMZKiMy8/JruncMU5Bt6na1eftNoo++R4Y+N2FrxkDVTrGvcyzFTsaGif4QTeKESheMGegbhw6iUAq+5A8zA==",
"dev": true,
"requires": {
"get-func-name": "^2.0.0"
@@ -15352,6 +15875,15 @@
"sourcemap-codec": "^1.4.8"
}
},
+ "make-dir": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz",
+ "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==",
+ "dev": true,
+ "requires": {
+ "semver": "^6.0.0"
+ }
+ },
"match-sorter": {
"version": "6.3.1",
"resolved": "https://registry.npmjs.org/match-sorter/-/match-sorter-6.3.1.tgz",
@@ -15439,6 +15971,12 @@
"integrity": "sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==",
"dev": true
},
+ "mrmime": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/mrmime/-/mrmime-1.0.1.tgz",
+ "integrity": "sha512-hzzEagAgDyoU1Q6yg5uI+AorQgdvMCur3FcKf7NhMKWsaYg+RnbTyHRa/9IlLF9rf455MOCtcqqrQQ83pPP7Uw==",
+ "dev": true
+ },
"ms": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
@@ -15741,15 +16279,15 @@
"dev": true
},
"prettier": {
- "version": "2.7.1",
- "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.7.1.tgz",
- "integrity": "sha512-ujppO+MkdPqoVINuDFDRLClm7D78qbDt0/NR+wp5FqEZOoTNAjPHWj17QRhu7geIHJfcNhRk1XVQmF8Bp3ye+g==",
+ "version": "2.8.1",
+ "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.1.tgz",
+ "integrity": "sha512-lqGoSJBQNJidqCHE80vqZJHWHRFoNYsSpP9AjFhlhi9ODCJA541svILes/+/1GM3VaL/abZi7cpFzOpdR9UPKg==",
"dev": true
},
"prettier-plugin-organize-imports": {
- "version": "3.1.1",
- "resolved": "https://registry.npmjs.org/prettier-plugin-organize-imports/-/prettier-plugin-organize-imports-3.1.1.tgz",
- "integrity": "sha512-6bHIQzybqA644h0WGUW3gpWEVbMBvzui5wCMRBi7qA++d5ov2xjjfDk8pxJJ/ardfZrGAwizKMq/fQMFdJ+0Zw==",
+ "version": "3.2.1",
+ "resolved": "https://registry.npmjs.org/prettier-plugin-organize-imports/-/prettier-plugin-organize-imports-3.2.1.tgz",
+ "integrity": "sha512-bty7C2Ecard5EOXirtzeCAqj4FU4epeuWrQt/Z+sh8UVEpBlBZ3m3KNPz2kFu7KgRTQx/C9o4/TdquPD1jOqjQ==",
"dev": true,
"requires": {}
},
@@ -16224,6 +16762,12 @@
"resolved": "https://registry.npmjs.org/remove-accents/-/remove-accents-0.4.2.tgz",
"integrity": "sha512-7pXIJqJOq5tFgG1A2Zxti3Ht8jJF337m4sowbuHsW30ZnkQFnDzy9qBNhgzX8ZLW4+UBcXiiR7SwR6pokHsxiA=="
},
+ "require-directory": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
+ "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==",
+ "dev": true
+ },
"requires-port": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz",
@@ -16360,6 +16904,17 @@
"integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==",
"dev": true
},
+ "sirv": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/sirv/-/sirv-2.0.2.tgz",
+ "integrity": "sha512-4Qog6aE29nIjAOKe/wowFTxOdmbEZKb+3tsLljaBRzJwtqto0BChD2zzH0LhgCSXiI+V7X+Y45v14wBZQ1TK3w==",
+ "dev": true,
+ "requires": {
+ "@polka/url": "^1.0.0-next.20",
+ "mrmime": "^1.0.0",
+ "totalist": "^3.0.0"
+ }
+ },
"slash": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz",
@@ -16427,6 +16982,25 @@
"integrity": "sha512-n3sPwynL1nwKi3WJ6AIsClwBMa0zTi54fn2oLU6ndfTSIO05xaznjSf15PcBZU6FNWbmN5Q6cxT4V5hGvB4taw==",
"dev": true
},
+ "string-width": {
+ "version": "4.2.3",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
+ "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
+ "dev": true,
+ "requires": {
+ "emoji-regex": "^8.0.0",
+ "is-fullwidth-code-point": "^3.0.0",
+ "strip-ansi": "^6.0.1"
+ },
+ "dependencies": {
+ "emoji-regex": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
+ "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
+ "dev": true
+ }
+ }
+ },
"string.prototype.matchall": {
"version": "4.0.7",
"resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.7.tgz",
@@ -16502,12 +17076,12 @@
"dev": true
},
"strip-literal": {
- "version": "0.4.2",
- "resolved": "https://registry.npmjs.org/strip-literal/-/strip-literal-0.4.2.tgz",
- "integrity": "sha512-pv48ybn4iE1O9RLgCAN0iU4Xv7RlBTiit6DKmMiErbs9x1wH6vXBs45tWc0H5wUIF6TLTrKweqkmYF/iraQKNw==",
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/strip-literal/-/strip-literal-1.0.0.tgz",
+ "integrity": "sha512-5o4LsH1lzBzO9UFH63AJ2ad2/S2AVx6NtjOcaz+VTT2h1RiRvbipW72z8M/lxEhcPHDBQwpDrnTF7sXy/7OwCQ==",
"dev": true,
"requires": {
- "acorn": "^8.8.0"
+ "acorn": "^8.8.1"
}
},
"stylis": {
@@ -16535,6 +17109,17 @@
"integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==",
"dev": true
},
+ "test-exclude": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz",
+ "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==",
+ "dev": true,
+ "requires": {
+ "@istanbuljs/schema": "^0.1.2",
+ "glob": "^7.1.4",
+ "minimatch": "^3.0.4"
+ }
+ },
"text-table": {
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz",
@@ -16579,6 +17164,12 @@
"is-number": "^7.0.0"
}
},
+ "totalist": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/totalist/-/totalist-3.0.0.tgz",
+ "integrity": "sha512-eM+pCBxXO/njtF7vdFsHuqb+ElbxqtI4r5EAvk6grfAFyJ6IvWlSkfZ5T9ozC6xWw3Fj1fGoSmrl0gUs46JVIw==",
+ "dev": true
+ },
"tough-cookie": {
"version": "4.1.2",
"resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.2.tgz",
@@ -16775,6 +17366,17 @@
"use-isomorphic-layout-effect": "^1.1.1"
}
},
+ "v8-to-istanbul": {
+ "version": "9.0.1",
+ "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.0.1.tgz",
+ "integrity": "sha512-74Y4LqY74kLE6IFyIjPtkSTWzUZmj8tdHT9Ii/26dvQ6K9Dl2NbEfj0XgU2sHCtKgt5VupqhlO/5aWuqS+IY1w==",
+ "dev": true,
+ "requires": {
+ "@jridgewell/trace-mapping": "^0.3.12",
+ "@types/istanbul-lib-coverage": "^2.0.1",
+ "convert-source-map": "^1.6.0"
+ }
+ },
"vite": {
"version": "3.2.1",
"resolved": "https://registry.npmjs.org/vite/-/vite-3.2.1.tgz",
@@ -16864,22 +17466,33 @@
}
},
"vitest": {
- "version": "0.24.3",
- "resolved": "https://registry.npmjs.org/vitest/-/vitest-0.24.3.tgz",
- "integrity": "sha512-aM0auuPPgMSstWvr851hB74g/LKaKBzSxcG3da7ejfZbx08Y21JpZmbmDYrMTCGhVZKqTGwzcnLMwyfz2WzkhQ==",
+ "version": "0.25.8",
+ "resolved": "https://registry.npmjs.org/vitest/-/vitest-0.25.8.tgz",
+ "integrity": "sha512-X75TApG2wZTJn299E/TIYevr4E9/nBo1sUtZzn0Ci5oK8qnpZAZyhwg0qCeMSakGIWtc6oRwcQFyFfW14aOFWg==",
"dev": true,
"requires": {
- "@types/chai": "^4.3.3",
+ "@types/chai": "^4.3.4",
"@types/chai-subset": "^1.3.3",
"@types/node": "*",
- "chai": "^4.3.6",
+ "acorn": "^8.8.1",
+ "acorn-walk": "^8.2.0",
+ "chai": "^4.3.7",
"debug": "^4.3.4",
"local-pkg": "^0.4.2",
- "strip-literal": "^0.4.2",
- "tinybench": "^2.3.0",
+ "source-map": "^0.6.1",
+ "strip-literal": "^1.0.0",
+ "tinybench": "^2.3.1",
"tinypool": "^0.3.0",
"tinyspy": "^1.0.2",
- "vite": "^3.0.0"
+ "vite": "^3.0.0 || ^4.0.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
+ }
}
},
"vscode-jsonrpc": {
@@ -16948,9 +17561,9 @@
"dev": true
},
"w3c-xmlserializer": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-3.0.0.tgz",
- "integrity": "sha512-3WFqGEgSXIyGhOmAFtlicJNMjEps8b1MG31NCA0/vOF9+nKMUW1ckhi9cnNHmf88Rzw5V+dwIwsm2C7X8k9aQg==",
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-4.0.0.tgz",
+ "integrity": "sha512-d+BFHzbiCx6zGfz0HyQ6Rg69w9k19nviJspaj4yNscGjrHu94sVP+aRm75yEbCh+r2/yR+7q6hux9LVtbuTGBw==",
"dev": true,
"requires": {
"xml-name-validator": "^4.0.0"
@@ -17041,15 +17654,52 @@
"integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==",
"dev": true
},
+ "wrap-ansi": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
+ "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^4.0.0",
+ "string-width": "^4.1.0",
+ "strip-ansi": "^6.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"
+ }
+ },
+ "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
+ }
+ }
+ },
"wrappy": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
"integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ=="
},
"ws": {
- "version": "8.10.0",
- "resolved": "https://registry.npmjs.org/ws/-/ws-8.10.0.tgz",
- "integrity": "sha512-+s49uSmZpvtAsd2h37vIPy1RBusaLawVe8of+GyEPsaJTCMpj/2v8NpeK1SHXjBlQ95lQTmQofOJnFiLoaN3yw==",
+ "version": "8.11.0",
+ "resolved": "https://registry.npmjs.org/ws/-/ws-8.11.0.tgz",
+ "integrity": "sha512-HPG3wQd9sNQoT9xHyNCXoDUa+Xw/VevmY9FoHyQ+g+rrMn4j6FB4np7Z0OhdTgjx6MgQLK7jwSy1YecU1+4Asg==",
"dev": true,
"requires": {}
},
@@ -17070,6 +17720,12 @@
"resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-2.0.0.tgz",
"integrity": "sha512-QKxVRxiRACQcVuQEYFsI1hhkrMlrXHPegbbd1yn9UHOmRxY+si12nQYzri3vbzt8VdTTRviqcKxcyllFas5z2A=="
},
+ "y18n": {
+ "version": "5.0.8",
+ "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz",
+ "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==",
+ "dev": true
+ },
"yallist": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
@@ -17081,6 +17737,27 @@
"resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz",
"integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg=="
},
+ "yargs": {
+ "version": "16.2.0",
+ "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz",
+ "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==",
+ "dev": true,
+ "requires": {
+ "cliui": "^7.0.2",
+ "escalade": "^3.1.1",
+ "get-caller-file": "^2.0.5",
+ "require-directory": "^2.1.1",
+ "string-width": "^4.2.0",
+ "y18n": "^5.0.5",
+ "yargs-parser": "^20.2.2"
+ }
+ },
+ "yargs-parser": {
+ "version": "20.2.9",
+ "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz",
+ "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==",
+ "dev": true
+ },
"yocto-queue": {
"version": "0.1.0",
"resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz",
diff --git a/frontend/package.json b/frontend/package.json
index 886e09934..abd29036f 100644
--- a/frontend/package.json
+++ b/frontend/package.json
@@ -14,11 +14,11 @@
"private": true,
"dependencies": {
"@mantine/core": "^5.6.0",
+ "@mantine/dropzone": "^5.6.0",
"@mantine/form": "^5.6.0",
"@mantine/hooks": "^5.6.0",
"@mantine/modals": "^5.6.0",
"@mantine/notifications": "^5.6.0",
- "@mantine/dropzone": "^5.6.0",
"axios": "^0.27.2",
"react": "^17.0.2",
"react-dom": "^17.0.2",
@@ -34,7 +34,7 @@
"@fortawesome/free-solid-svg-icons": "^6.2.0",
"@fortawesome/react-fontawesome": "^0.2.0",
"@testing-library/jest-dom": "^5.16.5",
- "@testing-library/react": "^12.1.5",
+ "@testing-library/react": "^12.1.0",
"@testing-library/react-hooks": "^8.0.1",
"@testing-library/user-event": "^14.4.3",
"@types/lodash": "^4.14.0",
@@ -43,10 +43,13 @@
"@types/react-dom": "^17.0.0",
"@types/react-table": "^7.7.0",
"@vitejs/plugin-react": "^2.2.0",
+ "@vitest/coverage-c8": "^0.25.0",
+ "@vitest/ui": "^0.25.0",
"clsx": "^1.2.0",
"eslint": "^8.26.0",
"eslint-config-react-app": "^7.0.1",
"eslint-plugin-react-hooks": "^4.6.0",
+ "eslint-plugin-testing-library": "^5.9.0",
"husky": "^8.0.2",
"jsdom": "^20.0.1",
"lodash": "^4.17.0",
@@ -60,7 +63,7 @@
"typescript": "^4",
"vite": "^3.2.1",
"vite-plugin-checker": "^0.5.5",
- "vitest": "^0.24.3"
+ "vitest": "^0.25.0"
},
"scripts": {
"start": "vite",
@@ -70,6 +73,8 @@
"check:ts": "tsc --noEmit --incremental false",
"check:fmt": "prettier -c .",
"test": "vitest",
+ "test:ui": "vitest --ui",
+ "coverage": "vitest run --coverage",
"format": "prettier -w .",
"prepare": "cd .. && husky install frontend/.husky"
},
diff --git a/frontend/src/components/bazarr/Language.test.tsx b/frontend/src/components/bazarr/Language.test.tsx
new file mode 100644
index 000000000..6b2ff93a5
--- /dev/null
+++ b/frontend/src/components/bazarr/Language.test.tsx
@@ -0,0 +1,82 @@
+import { render, screen } from "@testing-library/react";
+import { describe, it } from "vitest";
+import { Language } from ".";
+
+describe("Language text", () => {
+ const testLanguage: Language.Info = {
+ code2: "en",
+ name: "English",
+ };
+
+ it("should show short text", () => {
+ render(<Language.Text value={testLanguage}></Language.Text>);
+
+ expect(screen.getByText(testLanguage.code2)).toBeDefined();
+ });
+
+ it("should show long text", () => {
+ render(<Language.Text value={testLanguage} long></Language.Text>);
+
+ expect(screen.getByText(testLanguage.name)).toBeDefined();
+ });
+
+ const testLanguageWithHi: Language.Info = { ...testLanguage, hi: true };
+
+ it("should show short text with HI", () => {
+ render(<Language.Text value={testLanguageWithHi}></Language.Text>);
+
+ const expectedText = `${testLanguageWithHi.code2}:HI`;
+
+ expect(screen.getByText(expectedText)).toBeDefined();
+ });
+
+ it("should show long text with HI", () => {
+ render(<Language.Text value={testLanguageWithHi} long></Language.Text>);
+
+ const expectedText = `${testLanguageWithHi.name} HI`;
+
+ expect(screen.getByText(expectedText)).toBeDefined();
+ });
+
+ const testLanguageWithForced: Language.Info = {
+ ...testLanguage,
+ forced: true,
+ };
+
+ it("should show short text with Forced", () => {
+ render(<Language.Text value={testLanguageWithForced}></Language.Text>);
+
+ const expectedText = `${testLanguageWithHi.code2}:Forced`;
+
+ expect(screen.getByText(expectedText)).toBeDefined();
+ });
+
+ it("should show long text with Forced", () => {
+ render(<Language.Text value={testLanguageWithForced} long></Language.Text>);
+
+ const expectedText = `${testLanguageWithHi.name} Forced`;
+
+ expect(screen.getByText(expectedText)).toBeDefined();
+ });
+});
+
+describe("Language list", () => {
+ const elements: Language.Info[] = [
+ {
+ code2: "en",
+ name: "English",
+ },
+ {
+ code2: "zh",
+ name: "Chinese",
+ },
+ ];
+
+ it("should show all languages", () => {
+ render(<Language.List value={elements}></Language.List>);
+
+ elements.forEach((value) => {
+ expect(screen.getByText(value.name)).toBeDefined();
+ });
+ });
+});
diff --git a/frontend/src/components/inputs/Action.test.tsx b/frontend/src/components/inputs/Action.test.tsx
new file mode 100644
index 000000000..60c0bf646
--- /dev/null
+++ b/frontend/src/components/inputs/Action.test.tsx
@@ -0,0 +1,38 @@
+import { faStickyNote } from "@fortawesome/free-regular-svg-icons";
+import { render, screen } from "@testing-library/react";
+import userEvent from "@testing-library/user-event";
+import { describe, it, vitest } from "vitest";
+import Action from "./Action";
+
+const testLabel = "Test Label";
+const testIcon = faStickyNote;
+
+describe("Action button", () => {
+ it("should be a button", () => {
+ render(<Action icon={testIcon} label={testLabel}></Action>);
+ const element = screen.getByRole("button", { name: testLabel });
+
+ expect(element.getAttribute("type")).toEqual("button");
+ expect(element.getAttribute("aria-label")).toEqual(testLabel);
+ });
+
+ it("should show icon", () => {
+ render(<Action icon={testIcon} label={testLabel}></Action>);
+ // TODO: use getBy...
+ const element = screen.getByRole("img", { hidden: true });
+
+ expect(element.getAttribute("data-prefix")).toEqual(testIcon.prefix);
+ expect(element.getAttribute("data-icon")).toEqual(testIcon.iconName);
+ });
+
+ it("should call on-click event when clicked", async () => {
+ const onClickFn = vitest.fn();
+ render(
+ <Action icon={testIcon} label={testLabel} onClick={onClickFn}></Action>
+ );
+
+ await userEvent.click(screen.getByRole("button", { name: testLabel }));
+
+ expect(onClickFn).toHaveBeenCalled();
+ });
+});
diff --git a/frontend/src/components/inputs/ChipInput.test.tsx b/frontend/src/components/inputs/ChipInput.test.tsx
new file mode 100644
index 000000000..8cb7a099e
--- /dev/null
+++ b/frontend/src/components/inputs/ChipInput.test.tsx
@@ -0,0 +1,46 @@
+import { render, screen } from "@testing-library/react";
+import userEvent from "@testing-library/user-event";
+import { describe, it, vitest } from "vitest";
+import ChipInput from "./ChipInput";
+
+describe("ChipInput", () => {
+ const existedValues = ["value_1", "value_2"];
+
+ // TODO: Support default value
+ it.skip("should works with default value", () => {
+ render(<ChipInput defaultValue={existedValues}></ChipInput>);
+
+ existedValues.forEach((value) => {
+ expect(screen.getByText(value)).toBeDefined();
+ });
+ });
+
+ it("should works with value", () => {
+ render(<ChipInput value={existedValues}></ChipInput>);
+
+ existedValues.forEach((value) => {
+ expect(screen.getByText(value)).toBeDefined();
+ });
+ });
+
+ it.skip("should allow user creates new value", async () => {
+ const typedValue = "value_3";
+ const mockedFn = vitest.fn((values: string[]) => {
+ expect(values).toContain(typedValue);
+ });
+
+ render(<ChipInput value={existedValues} onChange={mockedFn}></ChipInput>);
+
+ const element = screen.getByRole("searchbox");
+
+ await userEvent.type(element, typedValue);
+
+ expect(element).toHaveValue(typedValue);
+
+ const createBtn = screen.getByText(`Add "${typedValue}"`);
+
+ await userEvent.click(createBtn);
+
+ expect(mockedFn).toBeCalledTimes(1);
+ });
+});
diff --git a/frontend/src/components/inputs/Selector.test.tsx b/frontend/src/components/inputs/Selector.test.tsx
new file mode 100644
index 000000000..43221ccae
--- /dev/null
+++ b/frontend/src/components/inputs/Selector.test.tsx
@@ -0,0 +1,147 @@
+import { render, screen } from "@testing-library/react";
+import userEvent from "@testing-library/user-event";
+import { describe, it, vitest } from "vitest";
+import { Selector, SelectorOption } from "./Selector";
+
+const selectorName = "Test Selections";
+const testOptions: SelectorOption<string>[] = [
+ {
+ label: "Option 1",
+ value: "option_1",
+ },
+ {
+ label: "Option 2",
+ value: "option_2",
+ },
+];
+
+describe("Selector", () => {
+ describe("options", () => {
+ it("should work with the SelectorOption", () => {
+ render(<Selector name={selectorName} options={testOptions}></Selector>);
+
+ // TODO: selectorName
+ expect(screen.getByRole("searchbox")).toBeDefined();
+ });
+
+ it("should display when clicked", async () => {
+ render(<Selector name={selectorName} options={testOptions}></Selector>);
+
+ const element = screen.getByRole("searchbox");
+
+ await userEvent.click(element);
+
+ expect(screen.queryAllByRole("option")).toHaveLength(testOptions.length);
+
+ testOptions.forEach((option) => {
+ expect(screen.getByText(option.label)).toBeDefined();
+ });
+ });
+
+ it("shouldn't show default value", async () => {
+ const option = testOptions[0];
+ render(
+ <Selector
+ name={selectorName}
+ options={testOptions}
+ defaultValue={option.value}
+ ></Selector>
+ );
+
+ expect(screen.getByDisplayValue(option.label)).toBeDefined();
+ });
+
+ it("shouldn't show value", async () => {
+ const option = testOptions[0];
+ render(
+ <Selector
+ name={selectorName}
+ options={testOptions}
+ value={option.value}
+ ></Selector>
+ );
+
+ expect(screen.getByDisplayValue(option.label)).toBeDefined();
+ });
+ });
+
+ describe("event", () => {
+ it("should fire on-change event when clicking option", async () => {
+ const clickedOption = testOptions[0];
+ const mockedFn = vitest.fn((value: string | null) => {
+ expect(value).toEqual(clickedOption.value);
+ });
+ render(
+ <Selector
+ name={selectorName}
+ options={testOptions}
+ onChange={mockedFn}
+ ></Selector>
+ );
+
+ const element = screen.getByRole("searchbox");
+
+ await userEvent.click(element);
+
+ await userEvent.click(screen.getByText(clickedOption.label));
+
+ expect(mockedFn).toBeCalled();
+ });
+ });
+
+ describe("with object options", () => {
+ const objectOptions: SelectorOption<{ name: string }>[] = [
+ {
+ label: "Option 1",
+ value: {
+ name: "option_1",
+ },
+ },
+ {
+ label: "Option 2",
+ value: {
+ name: "option_2",
+ },
+ },
+ ];
+
+ it("should fire on-change event with payload", async () => {
+ const clickedOption = objectOptions[0];
+
+ const mockedFn = vitest.fn((value: { name: string } | null) => {
+ expect(value).toEqual(clickedOption.value);
+ });
+ render(
+ <Selector
+ name={selectorName}
+ options={objectOptions}
+ onChange={mockedFn}
+ getkey={(v) => v.name}
+ ></Selector>
+ );
+
+ const element = screen.getByRole("searchbox");
+
+ await userEvent.click(element);
+
+ await userEvent.click(screen.getByText(clickedOption.label));
+
+ expect(mockedFn).toBeCalled();
+ });
+ });
+
+ describe("placeholder", () => {
+ it("should show when no selection", () => {
+ const placeholder = "Empty Selection";
+ render(
+ <Selector
+ name={selectorName}
+ options={testOptions}
+ placeholder={placeholder}
+ ></Selector>
+ );
+
+ expect(screen.getByPlaceholderText(placeholder)).toBeDefined();
+ });
+ });
+});
diff --git a/frontend/src/modules/modals/modal.test.ts b/frontend/src/modules/modals/modal.test.ts
deleted file mode 100644
index b4c80f71f..000000000
--- a/frontend/src/modules/modals/modal.test.ts
+++ /dev/null
@@ -1,12 +0,0 @@
-import { describe, it } from "vitest";
-import { StaticModals } from "./WithModal";
-
-describe("modal tests", () => {
- it.skip("no duplicated modals", () => {
- const existedKeys = new Set<string>();
- StaticModals.forEach(({ modalKey }) => {
- expect(existedKeys.has(modalKey)).toBeFalsy();
- existedKeys.add(modalKey);
- });
- });
-});
diff --git a/frontend/src/pages/Authentication.test.tsx b/frontend/src/pages/Authentication.test.tsx
new file mode 100644
index 000000000..47114dad5
--- /dev/null
+++ b/frontend/src/pages/Authentication.test.tsx
@@ -0,0 +1,20 @@
+import { render, screen } from "@testing-library/react";
+import { QueryClientProvider } from "react-query";
+import { describe, it } from "vitest";
+import Authentication from "./Authentication";
+
+import queryClient from "@/apis/queries";
+
+describe("Authentication", () => {
+ it("should render without crash", () => {
+ render(
+ <QueryClientProvider client={queryClient}>
+ <Authentication></Authentication>
+ </QueryClientProvider>
+ );
+
+ expect(screen.getByPlaceholderText("Username")).toBeDefined();
+ expect(screen.getByPlaceholderText("Password")).toBeDefined();
+ expect(screen.getByRole("button", { name: "Login" })).toBeDefined();
+ });
+});
diff --git a/frontend/src/pages/Authentication.tsx b/frontend/src/pages/Authentication.tsx
index d4266111c..baf21f6cd 100644
--- a/frontend/src/pages/Authentication.tsx
+++ b/frontend/src/pages/Authentication.tsx
@@ -40,11 +40,13 @@ const Authentication: FunctionComponent = () => {
>
<Stack>
<TextInput
+ name="Username"
placeholder="Username"
required
{...form.getInputProps("username")}
></TextInput>
<PasswordInput
+ name="Password"
required
placeholder="Password"
{...form.getInputProps("password")}
diff --git a/frontend/src/pages/Settings/components/Layout.test.tsx b/frontend/src/pages/Settings/components/Layout.test.tsx
new file mode 100644
index 000000000..696b98797
--- /dev/null
+++ b/frontend/src/pages/Settings/components/Layout.test.tsx
@@ -0,0 +1,31 @@
+import queryClient from "@/apis/queries";
+import { Text } from "@mantine/core";
+import { render, screen } from "@testing-library/react";
+import { QueryClientProvider } from "react-query";
+import { BrowserRouter } from "react-router-dom";
+import { describe, it } from "vitest";
+import Layout from "./Layout";
+
+const renderLayout = () => {
+ render(
+ <BrowserRouter>
+ <QueryClientProvider client={queryClient}>
+ <Layout name="Test Settings">
+ <Text>Value</Text>
+ </Layout>
+ </QueryClientProvider>
+ </BrowserRouter>
+ );
+};
+
+describe("Settings layout", () => {
+ it.concurrent("should be able to render without issues", () => {
+ renderLayout();
+ });
+
+ it.concurrent("save button should be disabled by default", () => {
+ renderLayout();
+
+ expect(screen.getByRole("button", { name: "Save" })).toBeDisabled();
+ });
+});
diff --git a/frontend/src/pages/Settings/components/Section.test.tsx b/frontend/src/pages/Settings/components/Section.test.tsx
new file mode 100644
index 000000000..2241bd40d
--- /dev/null
+++ b/frontend/src/pages/Settings/components/Section.test.tsx
@@ -0,0 +1,38 @@
+import { Text } from "@mantine/core";
+import { render, screen } from "@testing-library/react";
+import { describe, it } from "vitest";
+import { Section } from "./Section";
+
+describe("Settings section", () => {
+ const header = "Section Header";
+ it("should show header", () => {
+ render(<Section header="Section Header"></Section>);
+
+ expect(screen.getByText(header)).toBeDefined();
+ expect(screen.getByRole("separator")).toBeDefined();
+ });
+
+ it("should show children", () => {
+ const text = "Section Child";
+ render(
+ <Section header="Section Header">
+ <Text>{text}</Text>
+ </Section>
+ );
+
+ expect(screen.getByText(header)).toBeDefined();
+ expect(screen.getByText(text)).toBeDefined();
+ });
+
+ it("should work with hidden", () => {
+ const text = "Section Child";
+ render(
+ <Section header="Section Header" hidden>
+ <Text>{text}</Text>
+ </Section>
+ );
+
+ expect(screen.getByText(header)).not.toBeVisible();
+ expect(screen.getByText(text)).not.toBeVisible();
+ });
+});
diff --git a/frontend/src/pages/Settings/components/forms.test.tsx b/frontend/src/pages/Settings/components/forms.test.tsx
new file mode 100644
index 000000000..7ff6eefbe
--- /dev/null
+++ b/frontend/src/pages/Settings/components/forms.test.tsx
@@ -0,0 +1,42 @@
+import { useForm } from "@mantine/form";
+import { render, screen } from "@testing-library/react";
+import { FunctionComponent } from "react";
+import { describe, it } from "vitest";
+import { FormContext, FormValues } from "../utilities/FormValues";
+import { Number, Text } from "./forms";
+
+const FormSupport: FunctionComponent = ({ children }) => {
+ const form = useForm<FormValues>({
+ initialValues: {
+ settings: {},
+ hooks: {},
+ },
+ });
+ return <FormContext.Provider value={form}>{children}</FormContext.Provider>;
+};
+
+describe("Settings form", () => {
+ describe("number component", () => {
+ it("should be able to render", () => {
+ render(
+ <FormSupport>
+ <Number settingKey="test-numberValue"></Number>
+ </FormSupport>
+ );
+
+ expect(screen.getByRole("textbox")).toBeDefined();
+ });
+ });
+
+ describe("text component", () => {
+ it("should be able to render", () => {
+ render(
+ <FormSupport>
+ <Text settingKey="test-textValue"></Text>
+ </FormSupport>
+ );
+
+ expect(screen.getByRole("textbox")).toBeDefined();
+ });
+ });
+});
diff --git a/frontend/src/types/react-table.d.ts b/frontend/src/types/react-table.d.ts
index 4e4405711..e1acd4230 100644
--- a/frontend/src/types/react-table.d.ts
+++ b/frontend/src/types/react-table.d.ts
@@ -45,9 +45,8 @@ declare module "react-table" {
interface CustomTableProps<D extends Record<string, unknown>>
extends useSelectionProps<D> {}
- export interface TableOptions<
- D extends Record<string, unknown>
- > extends UseExpandedOptions<D>,
+ export interface TableOptions<D extends Record<string, unknown>>
+ extends UseExpandedOptions<D>,
// UseFiltersOptions<D>,
// UseGlobalFiltersOptions<D>,
UseGroupByOptions<D>,
diff --git a/frontend/test/render.test.tsx b/frontend/test/render.test.tsx
index c3f4ea968..097b93e49 100644
--- a/frontend/test/render.test.tsx
+++ b/frontend/test/render.test.tsx
@@ -1,27 +1,10 @@
import { render } from "@testing-library/react";
import { StrictMode } from "react";
-import { describe, it, vitest } from "vitest";
+import { describe, it } from "vitest";
import { Main } from "../src/main";
-describe("render test", () => {
- beforeAll(() => {
- // From https://stackoverflow.com/questions/39830580/jest-test-fails-typeerror-window-matchmedia-is-not-a-function
- Object.defineProperty(window, "matchMedia", {
- writable: true,
- value: vitest.fn().mockImplementation((query) => ({
- matches: false,
- media: query,
- onchange: null,
- addListener: vitest.fn(), // Deprecated
- removeListener: vitest.fn(), // Deprecated
- addEventListener: vitest.fn(),
- removeEventListener: vitest.fn(),
- dispatchEvent: vitest.fn(),
- })),
- });
- });
-
- it("render without crashing", () => {
+describe("App", () => {
+ it("should render without crash", () => {
render(
<StrictMode>
<Main />
diff --git a/frontend/test/setup.ts b/frontend/test/setup.ts
index d0de870dc..858b64791 100644
--- a/frontend/test/setup.ts
+++ b/frontend/test/setup.ts
@@ -1 +1,28 @@
+/* eslint-disable @typescript-eslint/no-empty-function */
+
import "@testing-library/jest-dom";
+import { vitest } from "vitest";
+
+// From https://stackoverflow.com/questions/39830580/jest-test-fails-typeerror-window-matchmedia-is-not-a-function
+Object.defineProperty(window, "matchMedia", {
+ writable: true,
+ value: vitest.fn().mockImplementation((query) => ({
+ matches: false,
+ media: query,
+ onchange: null,
+ addListener: vitest.fn(), // Deprecated
+ removeListener: vitest.fn(), // Deprecated
+ addEventListener: vitest.fn(),
+ removeEventListener: vitest.fn(),
+ dispatchEvent: vitest.fn(),
+ })),
+});
+
+// From https://github.com/mantinedev/mantine/blob/master/configuration/jest/jsdom.mocks.js
+class ResizeObserver {
+ observe() {}
+ unobserve() {}
+ disconnect() {}
+}
+
+window.ResizeObserver = ResizeObserver;