From f2f5c45855324e9b601be18f2167c23d6db974ea Mon Sep 17 00:00:00 2001 From: ilbrando Date: Sat, 9 Nov 2024 18:10:51 +0100 Subject: [PATCH] Utils vitest + run eslint and tests in CI build (#23) * Setup eslint + test in ci pipeline + tests for text-utils * Type tests * Unit tests for array-utils * Unit tests for object-utils * Rush update * Rush change --- .github/workflows/ci.yml | 4 + .vscode/extensions.json | 2 +- .../utils-vitest_2024-11-09-17-07.json | 10 + .../utils-vitest_2024-11-09-17-07.json | 10 + .../utils-vitest_2024-11-09-17-07.json | 10 + .../utils-vitest_2024-11-09-17-07.json | 10 + .../utils/utils-vitest_2024-11-09-17-07.json | 10 + common/config/rush/command-line.json | 10 +- common/config/rush/pnpm-lock.yaml | 293 +++++++++++++++++- common/scripts/install-run-rush.js | 8 +- common/scripts/install-run.js | 38 +-- examples/joy/package.json | 2 +- examples/storybook/package.json | 3 +- packages/simple-form-joy/package.json | 2 +- packages/simple-form-material-ui/package.json | 2 +- packages/simple-form/package.json | 2 +- packages/utils/package.json | 6 +- packages/utils/src/utils/array-utils.test.ts | 96 ++++++ packages/utils/src/utils/object-utils.test.ts | 150 +++++++++ packages/utils/src/utils/object-utils.ts | 6 +- packages/utils/src/utils/text-utils.test.ts | 38 +++ packages/utils/src/utils/type-utils.test-d.ts | 49 +++ rush.json | 4 +- tools/eslint-plugin/package.json | 3 +- 24 files changed, 722 insertions(+), 46 deletions(-) create mode 100644 common/changes/@ilbrando/eslint-plugin/utils-vitest_2024-11-09-17-07.json create mode 100644 common/changes/@ilbrando/simple-form-joy/utils-vitest_2024-11-09-17-07.json create mode 100644 common/changes/@ilbrando/simple-form-material-ui/utils-vitest_2024-11-09-17-07.json create mode 100644 common/changes/@ilbrando/simple-form/utils-vitest_2024-11-09-17-07.json create mode 100644 common/changes/@ilbrando/utils/utils-vitest_2024-11-09-17-07.json create mode 100644 packages/utils/src/utils/array-utils.test.ts create mode 100644 packages/utils/src/utils/object-utils.test.ts create mode 100644 packages/utils/src/utils/text-utils.test.ts create mode 100644 packages/utils/src/utils/type-utils.test-d.ts diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index e20428e..9ff97fc 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -20,3 +20,7 @@ jobs: run: node common/scripts/install-run-rush.js install - name: Rush rebuild run: node common/scripts/install-run-rush.js rebuild --verbose + - name: Rush test + run: node common/scripts/install-run-rush.js test + - name: Rush eslint + run: node common/scripts/install-run-rush.js eslint diff --git a/.vscode/extensions.json b/.vscode/extensions.json index 395e834..9cb428f 100644 --- a/.vscode/extensions.json +++ b/.vscode/extensions.json @@ -1,3 +1,3 @@ { - "recommendations": ["dbaeumer.vscode-eslint", "esbenp.prettier-vscode", "streetsidesoftware.code-spell-checker"] + "recommendations": ["dbaeumer.vscode-eslint", "esbenp.prettier-vscode", "streetsidesoftware.code-spell-checker", "vitest.explorer"] } diff --git a/common/changes/@ilbrando/eslint-plugin/utils-vitest_2024-11-09-17-07.json b/common/changes/@ilbrando/eslint-plugin/utils-vitest_2024-11-09-17-07.json new file mode 100644 index 0000000..115feab --- /dev/null +++ b/common/changes/@ilbrando/eslint-plugin/utils-vitest_2024-11-09-17-07.json @@ -0,0 +1,10 @@ +{ + "changes": [ + { + "packageName": "@ilbrando/eslint-plugin", + "comment": "Remove eslint script", + "type": "none" + } + ], + "packageName": "@ilbrando/eslint-plugin" +} \ No newline at end of file diff --git a/common/changes/@ilbrando/simple-form-joy/utils-vitest_2024-11-09-17-07.json b/common/changes/@ilbrando/simple-form-joy/utils-vitest_2024-11-09-17-07.json new file mode 100644 index 0000000..57a0609 --- /dev/null +++ b/common/changes/@ilbrando/simple-form-joy/utils-vitest_2024-11-09-17-07.json @@ -0,0 +1,10 @@ +{ + "changes": [ + { + "packageName": "@ilbrando/simple-form-joy", + "comment": "Eslint script", + "type": "patch" + } + ], + "packageName": "@ilbrando/simple-form-joy" +} \ No newline at end of file diff --git a/common/changes/@ilbrando/simple-form-material-ui/utils-vitest_2024-11-09-17-07.json b/common/changes/@ilbrando/simple-form-material-ui/utils-vitest_2024-11-09-17-07.json new file mode 100644 index 0000000..ac2aca6 --- /dev/null +++ b/common/changes/@ilbrando/simple-form-material-ui/utils-vitest_2024-11-09-17-07.json @@ -0,0 +1,10 @@ +{ + "changes": [ + { + "packageName": "@ilbrando/simple-form-material-ui", + "comment": "Esline script", + "type": "patch" + } + ], + "packageName": "@ilbrando/simple-form-material-ui" +} \ No newline at end of file diff --git a/common/changes/@ilbrando/simple-form/utils-vitest_2024-11-09-17-07.json b/common/changes/@ilbrando/simple-form/utils-vitest_2024-11-09-17-07.json new file mode 100644 index 0000000..5803a14 --- /dev/null +++ b/common/changes/@ilbrando/simple-form/utils-vitest_2024-11-09-17-07.json @@ -0,0 +1,10 @@ +{ + "changes": [ + { + "packageName": "@ilbrando/simple-form", + "comment": "Eslint script", + "type": "patch" + } + ], + "packageName": "@ilbrando/simple-form" +} \ No newline at end of file diff --git a/common/changes/@ilbrando/utils/utils-vitest_2024-11-09-17-07.json b/common/changes/@ilbrando/utils/utils-vitest_2024-11-09-17-07.json new file mode 100644 index 0000000..7bbf8be --- /dev/null +++ b/common/changes/@ilbrando/utils/utils-vitest_2024-11-09-17-07.json @@ -0,0 +1,10 @@ +{ + "changes": [ + { + "packageName": "@ilbrando/utils", + "comment": "Eslint script and unit tests", + "type": "patch" + } + ], + "packageName": "@ilbrando/utils" +} \ No newline at end of file diff --git a/common/config/rush/command-line.json b/common/config/rush/command-line.json index b9791c2..b9de70a 100644 --- a/common/config/rush/command-line.json +++ b/common/config/rush/command-line.json @@ -175,11 +175,19 @@ // */ // // "autoinstallerName": "my-task" // } + { + "commandKind": "bulk", + "name": "test", + "summary": "Run unit tests.", + "enableParallelism": true, + "ignoreMissingScript": true + }, { "commandKind": "bulk", "name": "eslint", "summary": "Lints all projects", - "enableParallelism": false + "enableParallelism": false, + "ignoreMissingScript": true } ], diff --git a/common/config/rush/pnpm-lock.yaml b/common/config/rush/pnpm-lock.yaml index cd3e32f..76a893a 100644 --- a/common/config/rush/pnpm-lock.yaml +++ b/common/config/rush/pnpm-lock.yaml @@ -102,7 +102,7 @@ importers: version: 8.1.9(@types/react-dom@18.3.0)(@types/react@18.3.3)(prettier@3.3.2)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@storybook/addon-interactions': specifier: ^8.1.5 - version: 8.1.9 + version: 8.1.9(vitest@2.1.4(@types/node@20.12.14)) '@storybook/addon-links': specifier: ^8.1.5 version: 8.1.9(react@18.3.1) @@ -120,7 +120,7 @@ importers: version: 8.1.9(prettier@3.3.2)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(rollup@4.18.0)(typescript@5.4.5)(vite@5.2.13(@types/node@20.12.14)) '@storybook/test': specifier: ^8.1.5 - version: 8.1.9 + version: 8.1.9(vitest@2.1.4(@types/node@20.12.14)) react: specifier: ^18 version: 18.3.1 @@ -317,6 +317,9 @@ importers: vite: specifier: ~5.2.0 version: 5.2.13(@types/node@20.12.14) + vitest: + specifier: ~2.1.4 + version: 2.1.4(@types/node@20.12.14) ../../tools/eslint-plugin: dependencies: @@ -1440,6 +1443,9 @@ packages: '@jridgewell/sourcemap-codec@1.4.15': resolution: {integrity: sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==} + '@jridgewell/sourcemap-codec@1.5.0': + resolution: {integrity: sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==} + '@jridgewell/trace-mapping@0.3.25': resolution: {integrity: sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==} @@ -2455,18 +2461,47 @@ packages: '@vitest/expect@1.3.1': resolution: {integrity: sha512-xofQFwIzfdmLLlHa6ag0dPV8YsnKOCP1KdAeVVh34vSjN2dcUiXYCD9htu/9eM7t8Xln4v03U9HLxLpPlsXdZw==} + '@vitest/expect@2.1.4': + resolution: {integrity: sha512-DOETT0Oh1avie/D/o2sgMHGrzYUFFo3zqESB2Hn70z6QB1HrS2IQ9z5DfyTqU8sg4Bpu13zZe9V4+UTNQlUeQA==} + + '@vitest/mocker@2.1.4': + resolution: {integrity: sha512-Ky/O1Lc0QBbutJdW0rqLeFNbuLEyS+mIPiNdlVlp2/yhJ0SbyYqObS5IHdhferJud8MbbwMnexg4jordE5cCoQ==} + peerDependencies: + msw: ^2.4.9 + vite: ^5.0.0 + peerDependenciesMeta: + msw: + optional: true + vite: + optional: true + + '@vitest/pretty-format@2.1.4': + resolution: {integrity: sha512-L95zIAkEuTDbUX1IsjRl+vyBSLh3PwLLgKpghl37aCK9Jvw0iP+wKwIFhfjdUtA2myLgjrG6VU6JCFLv8q/3Ww==} + + '@vitest/runner@2.1.4': + resolution: {integrity: sha512-sKRautINI9XICAMl2bjxQM8VfCMTB0EbsBc/EDFA57V6UQevEKY/TOPOF5nzcvCALltiLfXWbq4MaAwWx/YxIA==} + + '@vitest/snapshot@2.1.4': + resolution: {integrity: sha512-3Kab14fn/5QZRog5BPj6Rs8dc4B+mim27XaKWFWHWA87R56AKjHTGcBFKpvZKDzC4u5Wd0w/qKsUIio3KzWW4Q==} + '@vitest/spy@1.3.1': resolution: {integrity: sha512-xAcW+S099ylC9VLU7eZfdT9myV67Nor9w9zhf0mGCYJSO+zM2839tOeROTdikOi/8Qeusffvxb/MyBSOja1Uig==} '@vitest/spy@1.6.0': resolution: {integrity: sha512-leUTap6B/cqi/bQkXUu6bQV5TZPx7pmMBKBQiI0rJA8c3pB56ZsaTbREnF7CJfmvAS4V2cXIBAh/3rVwrrCYgw==} + '@vitest/spy@2.1.4': + resolution: {integrity: sha512-4JOxa+UAizJgpZfaCPKK2smq9d8mmjZVPMt2kOsg/R8QkoRzydHH1qHxIYNvr1zlEaFj4SXiaaJWxq/LPLKaLg==} + '@vitest/utils@1.3.1': resolution: {integrity: sha512-d3Waie/299qqRyHTm2DjADeTaNdNSVsnwHPWrs20JMpjh6eiVq7ggggweO8rc4arhf6rRkWuHKwvxGvejUXZZQ==} '@vitest/utils@1.6.0': resolution: {integrity: sha512-21cPiuGMoMZwiOHa2i4LXkMkMkCGzA+MVFV70jRwHo95dL4x/ts5GZhML1QWuy7yfp3WzK3lRvZi3JnXTYqrBw==} + '@vitest/utils@2.1.4': + resolution: {integrity: sha512-MXDnZn0Awl2S86PSNIim5PWXgIAx8CIkzu35mBdSApUip6RFOGXBCf3YFyeEu8n1IHk4bWD46DeYFu9mQlFIRg==} + '@yarnpkg/esbuild-plugin-pnp@3.0.0-rc.15': resolution: {integrity: sha512-kYzDJO5CA9sy+on/s2aIW0411AklfCi8Ck/4QDivOqsMKpStZA2SsR+X27VTggGwpStWaLrjJcDcdDMowtG8MA==} engines: {node: '>=14.15.0'} @@ -2579,6 +2614,10 @@ packages: assertion-error@1.1.0: resolution: {integrity: sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==} + assertion-error@2.0.1: + resolution: {integrity: sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==} + engines: {node: '>=12'} + ast-types@0.16.1: resolution: {integrity: sha512-6t10qk83GOG8p0vKmaCr8eiilZwO171AvbROMtvvNiwrTly62t+7XkA8RdIIVbpMhCASAsxgAzdRSwh6nw/5Dg==} engines: {node: '>=4'} @@ -2703,6 +2742,10 @@ packages: resolution: {integrity: sha512-13sOfMv2+DWduEU+/xbun3LScLoqN17nBeTLUsmDfKdoiC1fr0n9PU4guu4AhRcOVFk/sW8LyZWHuhWtQZiF+g==} engines: {node: '>=4'} + chai@5.1.2: + resolution: {integrity: sha512-aGtmf24DW6MLHHG5gCx4zaI3uBq3KRtxeVs0DjFH6Z0rDNbsvTxFASFvdj79pxjxZ8/5u3PIiN3IwEIQkiiuPw==} + engines: {node: '>=12'} + chalk@2.4.2: resolution: {integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==} engines: {node: '>=4'} @@ -2718,6 +2761,10 @@ packages: check-error@1.0.3: resolution: {integrity: sha512-iKEoDYaRmd1mxM90a2OEfWhjsjPpYPuQ+lMYsoxB126+t8fw7ySEO48nmDg5COTjxDI65/Y2OWpeEHk3ZOe8zg==} + check-error@2.1.1: + resolution: {integrity: sha512-OAlb+T7V4Op9OwdkjmguYRqncdlx5JiofwOAUkmTF+jNdHwzTaTs4sRAGpzLF3oOz5xAyDGrPgeIDFQmDOTiJw==} + engines: {node: '>= 16'} + chokidar@3.6.0: resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==} engines: {node: '>= 8.10.0'} @@ -2880,10 +2927,23 @@ packages: supports-color: optional: true + debug@4.3.7: + resolution: {integrity: sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + deep-eql@4.1.4: resolution: {integrity: sha512-SUwdGfqdKOwxCPeVYjwSyRpJ7Z+fhpwIAtmCUdZIWZ/YP5R9WAsyuSgpLVDi9bjWoN2LXHNss/dk3urXtdQxGg==} engines: {node: '>=6'} + deep-eql@5.0.2: + resolution: {integrity: sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==} + engines: {node: '>=6'} + deep-equal@2.2.3: resolution: {integrity: sha512-ZIwpnevOurS8bpT4192sqAowWM76JDKSHYzMLty3BZGSswgq6pBaH3DhCSW5xVAZICZyKdOBPjwww5wfgT/6PA==} engines: {node: '>= 0.4'} @@ -3171,6 +3231,10 @@ packages: resolution: {integrity: sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==} engines: {node: '>=16.17'} + expect-type@1.1.0: + resolution: {integrity: sha512-bFi65yM+xZgk+u/KRIpekdSYkTB5W1pEf0Lt8Q8Msh7b+eQ7LXVtIB1Bkm4fvclDEL1b2CZkMhv2mOeF8tMdkA==} + engines: {node: '>=12.0.0'} + express@4.19.2: resolution: {integrity: sha512-5T6nhjsT+EOMzuck8JjBHARTHfMht0POzlA60WV2pMD3gyXw2LZnZ+ueGdNxG+0calOJcWKbpFcuzLZ91YWq9Q==} engines: {node: '>= 0.10.0'} @@ -3809,6 +3873,9 @@ packages: loupe@2.3.7: resolution: {integrity: sha512-zSMINGVYkdpYSOBmLi0D1Uo7JU9nVdQKrHxC8eYlV+9YKK9WePqAlL7lSlorG/U2Fw1w0hTBmaa/jrQ3UbPHtA==} + loupe@3.1.2: + resolution: {integrity: sha512-23I4pFZHmAemUnz8WZXbYRSKYj801VDaNv9ETuMh7IrMc7VuVVSo+Z9iLE3ni30+U48iDWfi30d3twAXBYmnCg==} + lru-cache@10.2.2: resolution: {integrity: sha512-9hp3Vp2/hFQUiIwKo8XCeFVnrg8Pk3TYNPIR7tJADKi5YfcF7vEaK7avFHTlSy3kOKYaJQaalfEo6YuXdceBOQ==} engines: {node: 14 || >=16.14} @@ -3827,6 +3894,9 @@ packages: magic-string@0.30.10: resolution: {integrity: sha512-iIRwTIf0QKV3UAnYK4PU8uiEc4SRh5jX0mwpIwETPpHdhVM4f53RSwS/vXvN1JhGX+Cs7B8qIq3d6AH49O5fAQ==} + magic-string@0.30.12: + resolution: {integrity: sha512-Ea8I3sQMVXr8JhN4z+H/d8zwo+tYDgHE9+5G4Wnrwhs0gaK9fXTKx0Tw5Xwsd/bCPTTZNRAdpyzvoeORe9LYpw==} + make-dir@2.1.0: resolution: {integrity: sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==} engines: {node: '>=6'} @@ -4158,6 +4228,10 @@ packages: pathval@1.1.1: resolution: {integrity: sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==} + pathval@2.0.0: + resolution: {integrity: sha512-vE7JKRyES09KiunauX7nd2Q9/L7lhok4smP9RZTDeD4MVs72Dp2qNFVz39Nz5a0FVEW0BJR6C0DYrq6unoziZA==} + engines: {node: '>= 14.16'} + peek-stream@1.1.3: resolution: {integrity: sha512-FhJ+YbOSBb9/rIl2ZeE/QHEsWn7PqNYt8ARAY3kIgNGOk13g9FGyIY6JIl/xB/3TFRVoTv5as0l11weORrTekA==} @@ -4561,6 +4635,9 @@ packages: resolution: {integrity: sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==} engines: {node: '>= 0.4'} + siginfo@2.0.0: + resolution: {integrity: sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==} + signal-exit@3.0.7: resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==} @@ -4613,10 +4690,16 @@ packages: spdx-license-ids@3.0.18: resolution: {integrity: sha512-xxRs31BqRYHwiMzudOrpSiHtZ8i/GeionCBDSilhYRj+9gIcI8wCZTlXZKu9vZIVqViP3dcp9qE5G6AlIaD+TQ==} + stackback@0.0.2: + resolution: {integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==} + statuses@2.0.1: resolution: {integrity: sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==} engines: {node: '>= 0.8'} + std-env@3.8.0: + resolution: {integrity: sha512-Bc3YwwCB+OzldMxOXJIIvC6cPRWr/LxOp48CdQTOkPyk/t4JWWJbrilwBd7RJzKV8QW7tJkcgAmeuLLJugl5/w==} + stop-iteration-iterator@1.0.0: resolution: {integrity: sha512-iCGQj+0l0HOdZ2AEeBADlsRC+vsnDsZsbdSiH1yNSjcfKM7fdpCMfqAL/dwF5BLiw/XhRft/Wax6zQbhq2BcjQ==} engines: {node: '>= 0.4'} @@ -4754,10 +4837,28 @@ packages: tiny-invariant@1.3.3: resolution: {integrity: sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg==} + tinybench@2.9.0: + resolution: {integrity: sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==} + + tinyexec@0.3.1: + resolution: {integrity: sha512-WiCJLEECkO18gwqIp6+hJg0//p23HXp4S+gGtAKu3mI2F2/sXC4FvHvXvB0zJVVaTPhx1/tOwdbRsa1sOBIKqQ==} + + tinypool@1.0.1: + resolution: {integrity: sha512-URZYihUbRPcGv95En+sz6MfghfIc2OJ1sv/RmhWZLouPY0/8Vo80viwPvg3dlaS9fuq7fQMEfgRRK7BBZThBEA==} + engines: {node: ^18.0.0 || >=20.0.0} + + tinyrainbow@1.2.0: + resolution: {integrity: sha512-weEDEq7Z5eTHPDh4xjX789+fHfF+P8boiFB+0vbWzpbnbsEr/GRaohi/uMKxg8RZMXnl1ItAi/IUHWMsjDV7kQ==} + engines: {node: '>=14.0.0'} + tinyspy@2.2.1: resolution: {integrity: sha512-KYad6Vy5VDWV4GH3fjpseMQ/XU2BhIYP7Vzd0LG44qRWm/Yt2WCOTicFdvmgo6gWaqooMQCawTtILVQJupKu7A==} engines: {node: '>=14.0.0'} + tinyspy@3.0.2: + resolution: {integrity: sha512-n1cw8k1k0x4pgA2+9XrOkFydTerNcJ1zWCO5Nn9scWHTD+5tp8dghT2x1uduQePZTZgd3Tupf+x9BxJjeJi77Q==} + engines: {node: '>=14.0.0'} + to-fast-properties@2.0.0: resolution: {integrity: sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==} engines: {node: '>=4'} @@ -4996,6 +5097,11 @@ packages: resolution: {integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==} engines: {node: '>= 0.8'} + vite-node@2.1.4: + resolution: {integrity: sha512-kqa9v+oi4HwkG6g8ufRnb5AeplcRw8jUF6/7/Qz1qRQOXHImG8YnLbB+LLszENwFnoBl9xIf9nVdCFzNd7GQEg==} + engines: {node: ^18.0.0 || >=20.0.0} + hasBin: true + vite@5.2.13: resolution: {integrity: sha512-SSq1noJfY9pR3I1TUENL3rQYDQCFqgD+lM6fTRAM8Nv6Lsg5hDLaXkjETVeBt+7vZBCMoibD+6IWnT2mJ+Zb/A==} engines: {node: ^18.0.0 || >=20.0.0} @@ -5024,6 +5130,31 @@ packages: terser: optional: true + vitest@2.1.4: + resolution: {integrity: sha512-eDjxbVAJw1UJJCHr5xr/xM86Zx+YxIEXGAR+bmnEID7z9qWfoxpHw0zdobz+TQAFOLT+nEXz3+gx6nUJ7RgmlQ==} + engines: {node: ^18.0.0 || >=20.0.0} + hasBin: true + peerDependencies: + '@edge-runtime/vm': '*' + '@types/node': ^18.0.0 || >=20.0.0 + '@vitest/browser': 2.1.4 + '@vitest/ui': 2.1.4 + happy-dom: '*' + jsdom: '*' + peerDependenciesMeta: + '@edge-runtime/vm': + optional: true + '@types/node': + optional: true + '@vitest/browser': + optional: true + '@vitest/ui': + optional: true + happy-dom: + optional: true + jsdom: + optional: true + watchpack@2.4.1: resolution: {integrity: sha512-8wrBCMtVhqcXP2Sup1ctSkga6uc2Bx0IIvKyT7yTFier5AXHooSI+QyQQAtTb7+E0IUCCKyTFmXqdqgum2XWGg==} engines: {node: '>=10.13.0'} @@ -5070,6 +5201,11 @@ packages: engines: {node: '>= 8'} hasBin: true + why-is-node-running@2.3.0: + resolution: {integrity: sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==} + engines: {node: '>=8'} + hasBin: true + word-wrap@1.2.5: resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==} engines: {node: '>=0.10.0'} @@ -6306,6 +6442,8 @@ snapshots: '@jridgewell/sourcemap-codec@1.4.15': {} + '@jridgewell/sourcemap-codec@1.5.0': {} + '@jridgewell/trace-mapping@0.3.25': dependencies: '@jridgewell/resolve-uri': 3.1.2 @@ -6831,11 +6969,11 @@ snapshots: dependencies: '@storybook/global': 5.0.0 - '@storybook/addon-interactions@8.1.9': + '@storybook/addon-interactions@8.1.9(vitest@2.1.4(@types/node@20.12.14))': dependencies: '@storybook/global': 5.0.0 '@storybook/instrumenter': 8.1.9 - '@storybook/test': 8.1.9 + '@storybook/test': 8.1.9(vitest@2.1.4(@types/node@20.12.14)) '@storybook/types': 8.1.9 polished: 4.3.1 ts-dedent: 2.2.0 @@ -7345,14 +7483,14 @@ snapshots: - prettier - supports-color - '@storybook/test@8.1.9': + '@storybook/test@8.1.9(vitest@2.1.4(@types/node@20.12.14))': dependencies: '@storybook/client-logger': 8.1.9 '@storybook/core-events': 8.1.9 '@storybook/instrumenter': 8.1.9 '@storybook/preview-api': 8.1.9 '@testing-library/dom': 9.3.4 - '@testing-library/jest-dom': 6.4.6 + '@testing-library/jest-dom': 6.4.6(vitest@2.1.4(@types/node@20.12.14)) '@testing-library/user-event': 14.5.2(@testing-library/dom@9.3.4) '@vitest/expect': 1.3.1 '@vitest/spy': 1.6.0 @@ -7391,7 +7529,7 @@ snapshots: lz-string: 1.5.0 pretty-format: 27.5.1 - '@testing-library/jest-dom@6.4.6': + '@testing-library/jest-dom@6.4.6(vitest@2.1.4(@types/node@20.12.14))': dependencies: '@adobe/css-tools': 4.4.0 '@babel/runtime': 7.24.7 @@ -7401,6 +7539,8 @@ snapshots: dom-accessibility-api: 0.6.3 lodash: 4.17.21 redent: 3.0.0 + optionalDependencies: + vitest: 2.1.4(@types/node@20.12.14) '@testing-library/user-event@14.5.2(@testing-library/dom@9.3.4)': dependencies: @@ -7751,6 +7891,36 @@ snapshots: '@vitest/utils': 1.3.1 chai: 4.4.1 + '@vitest/expect@2.1.4': + dependencies: + '@vitest/spy': 2.1.4 + '@vitest/utils': 2.1.4 + chai: 5.1.2 + tinyrainbow: 1.2.0 + + '@vitest/mocker@2.1.4(vite@5.2.13(@types/node@20.12.14))': + dependencies: + '@vitest/spy': 2.1.4 + estree-walker: 3.0.3 + magic-string: 0.30.12 + optionalDependencies: + vite: 5.2.13(@types/node@20.12.14) + + '@vitest/pretty-format@2.1.4': + dependencies: + tinyrainbow: 1.2.0 + + '@vitest/runner@2.1.4': + dependencies: + '@vitest/utils': 2.1.4 + pathe: 1.1.2 + + '@vitest/snapshot@2.1.4': + dependencies: + '@vitest/pretty-format': 2.1.4 + magic-string: 0.30.12 + pathe: 1.1.2 + '@vitest/spy@1.3.1': dependencies: tinyspy: 2.2.1 @@ -7759,6 +7929,10 @@ snapshots: dependencies: tinyspy: 2.2.1 + '@vitest/spy@2.1.4': + dependencies: + tinyspy: 3.0.2 + '@vitest/utils@1.3.1': dependencies: diff-sequences: 29.6.3 @@ -7773,6 +7947,12 @@ snapshots: loupe: 2.3.7 pretty-format: 29.7.0 + '@vitest/utils@2.1.4': + dependencies: + '@vitest/pretty-format': 2.1.4 + loupe: 3.1.2 + tinyrainbow: 1.2.0 + '@yarnpkg/esbuild-plugin-pnp@3.0.0-rc.15(esbuild@0.20.2)': dependencies: esbuild: 0.20.2 @@ -7885,6 +8065,8 @@ snapshots: assertion-error@1.1.0: {} + assertion-error@2.0.1: {} + ast-types@0.16.1: dependencies: tslib: 2.6.3 @@ -8032,6 +8214,14 @@ snapshots: pathval: 1.1.1 type-detect: 4.0.8 + chai@5.1.2: + dependencies: + assertion-error: 2.0.1 + check-error: 2.1.1 + deep-eql: 5.0.2 + loupe: 3.1.2 + pathval: 2.0.0 + chalk@2.4.2: dependencies: ansi-styles: 3.2.1 @@ -8052,6 +8242,8 @@ snapshots: dependencies: get-func-name: 2.0.2 + check-error@2.1.1: {} + chokidar@3.6.0: dependencies: anymatch: 3.1.3 @@ -8208,10 +8400,16 @@ snapshots: dependencies: ms: 2.1.2 + debug@4.3.7: + dependencies: + ms: 2.1.3 + deep-eql@4.1.4: dependencies: type-detect: 4.0.8 + deep-eql@5.0.2: {} + deep-equal@2.2.3: dependencies: array-buffer-byte-length: 1.0.1 @@ -8631,6 +8829,8 @@ snapshots: signal-exit: 4.1.0 strip-final-newline: 3.0.0 + expect-type@1.1.0: {} + express@4.19.2: dependencies: accepts: 1.3.8 @@ -9288,6 +9488,8 @@ snapshots: dependencies: get-func-name: 2.0.2 + loupe@3.1.2: {} + lru-cache@10.2.2: {} lru-cache@5.1.1: @@ -9304,6 +9506,10 @@ snapshots: dependencies: '@jridgewell/sourcemap-codec': 1.4.15 + magic-string@0.30.12: + dependencies: + '@jridgewell/sourcemap-codec': 1.5.0 + make-dir@2.1.0: dependencies: pify: 4.0.1 @@ -9596,6 +9802,8 @@ snapshots: pathval@1.1.1: {} + pathval@2.0.0: {} + peek-stream@1.1.3: dependencies: buffer-from: 1.1.2 @@ -10061,6 +10269,8 @@ snapshots: get-intrinsic: 1.2.4 object-inspect: 1.13.1 + siginfo@2.0.0: {} + signal-exit@3.0.7: {} signal-exit@4.1.0: {} @@ -10102,8 +10312,12 @@ snapshots: spdx-license-ids@3.0.18: {} + stackback@0.0.2: {} + statuses@2.0.1: {} + std-env@3.8.0: {} + stop-iteration-iterator@1.0.0: dependencies: internal-slot: 1.0.7 @@ -10274,8 +10488,18 @@ snapshots: tiny-invariant@1.3.3: {} + tinybench@2.9.0: {} + + tinyexec@0.3.1: {} + + tinypool@1.0.1: {} + + tinyrainbow@1.2.0: {} + tinyspy@2.2.1: {} + tinyspy@3.0.2: {} + to-fast-properties@2.0.0: {} to-regex-range@5.0.1: @@ -10500,6 +10724,22 @@ snapshots: vary@1.1.2: {} + vite-node@2.1.4(@types/node@20.12.14): + dependencies: + cac: 6.7.14 + debug: 4.3.7 + pathe: 1.1.2 + vite: 5.2.13(@types/node@20.12.14) + transitivePeerDependencies: + - '@types/node' + - less + - lightningcss + - sass + - stylus + - sugarss + - supports-color + - terser + vite@5.2.13(@types/node@20.12.14): dependencies: esbuild: 0.20.2 @@ -10509,6 +10749,40 @@ snapshots: '@types/node': 20.12.14 fsevents: 2.3.3 + vitest@2.1.4(@types/node@20.12.14): + dependencies: + '@vitest/expect': 2.1.4 + '@vitest/mocker': 2.1.4(vite@5.2.13(@types/node@20.12.14)) + '@vitest/pretty-format': 2.1.4 + '@vitest/runner': 2.1.4 + '@vitest/snapshot': 2.1.4 + '@vitest/spy': 2.1.4 + '@vitest/utils': 2.1.4 + chai: 5.1.2 + debug: 4.3.7 + expect-type: 1.1.0 + magic-string: 0.30.12 + pathe: 1.1.2 + std-env: 3.8.0 + tinybench: 2.9.0 + tinyexec: 0.3.1 + tinypool: 1.0.1 + tinyrainbow: 1.2.0 + vite: 5.2.13(@types/node@20.12.14) + vite-node: 2.1.4(@types/node@20.12.14) + why-is-node-running: 2.3.0 + optionalDependencies: + '@types/node': 20.12.14 + transitivePeerDependencies: + - less + - lightningcss + - msw + - sass + - stylus + - sugarss + - supports-color + - terser + watchpack@2.4.1: dependencies: glob-to-regexp: 0.4.1 @@ -10568,6 +10842,11 @@ snapshots: dependencies: isexe: 2.0.0 + why-is-node-running@2.3.0: + dependencies: + siginfo: 2.0.0 + stackback: 0.0.2 + word-wrap@1.2.5: {} wordwrap@1.0.0: {} diff --git a/common/scripts/install-run-rush.js b/common/scripts/install-run-rush.js index 9676fc7..20f33d1 100644 --- a/common/scripts/install-run-rush.js +++ b/common/scripts/install-run-rush.js @@ -16,7 +16,7 @@ /******/ "use strict"; /******/ var __webpack_modules__ = ({ -/***/ 657147: +/***/ 179896: /*!*********************!*\ !*** external "fs" ***! \*********************/ @@ -26,7 +26,7 @@ module.exports = require("fs"); /***/ }), -/***/ 371017: +/***/ 16928: /*!***********************!*\ !*** external "path" ***! \***********************/ @@ -111,9 +111,9 @@ var __webpack_exports__ = {}; !*** ./lib-esnext/scripts/install-run-rush.js ***! \************************************************/ __webpack_require__.r(__webpack_exports__); -/* harmony import */ var path__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! path */ 371017); +/* harmony import */ var path__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! path */ 16928); /* harmony import */ var path__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(path__WEBPACK_IMPORTED_MODULE_0__); -/* harmony import */ var fs__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! fs */ 657147); +/* harmony import */ var fs__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! fs */ 179896); /* harmony import */ var fs__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(fs__WEBPACK_IMPORTED_MODULE_1__); // Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license. // See LICENSE in the project root for license information. diff --git a/common/scripts/install-run.js b/common/scripts/install-run.js index 9283c44..b3e9213 100644 --- a/common/scripts/install-run.js +++ b/common/scripts/install-run.js @@ -16,7 +16,7 @@ /******/ "use strict"; /******/ var __webpack_modules__ = ({ -/***/ 679877: +/***/ 832286: /*!************************************************!*\ !*** ./lib-esnext/utilities/npmrcUtilities.js ***! \************************************************/ @@ -24,12 +24,12 @@ __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "isVariableSetInNpmrcFile": () => (/* binding */ isVariableSetInNpmrcFile), -/* harmony export */ "syncNpmrc": () => (/* binding */ syncNpmrc) +/* harmony export */ isVariableSetInNpmrcFile: () => (/* binding */ isVariableSetInNpmrcFile), +/* harmony export */ syncNpmrc: () => (/* binding */ syncNpmrc) /* harmony export */ }); -/* harmony import */ var fs__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! fs */ 657147); +/* harmony import */ var fs__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! fs */ 179896); /* harmony import */ var fs__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(fs__WEBPACK_IMPORTED_MODULE_0__); -/* harmony import */ var path__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! path */ 371017); +/* harmony import */ var path__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! path */ 16928); /* harmony import */ var path__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(path__WEBPACK_IMPORTED_MODULE_1__); // Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license. // See LICENSE in the project root for license information. @@ -164,7 +164,7 @@ function isVariableSetInNpmrcFile(sourceNpmrcFolder, variableKey) { /***/ }), -/***/ 532081: +/***/ 535317: /*!********************************!*\ !*** external "child_process" ***! \********************************/ @@ -174,7 +174,7 @@ module.exports = require("child_process"); /***/ }), -/***/ 657147: +/***/ 179896: /*!*********************!*\ !*** external "fs" ***! \*********************/ @@ -184,7 +184,7 @@ module.exports = require("fs"); /***/ }), -/***/ 822037: +/***/ 370857: /*!*********************!*\ !*** external "os" ***! \*********************/ @@ -194,7 +194,7 @@ module.exports = require("os"); /***/ }), -/***/ 371017: +/***/ 16928: /*!***********************!*\ !*** external "path" ***! \***********************/ @@ -280,21 +280,21 @@ var __webpack_exports__ = {}; \*******************************************/ __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "RUSH_JSON_FILENAME": () => (/* binding */ RUSH_JSON_FILENAME), -/* harmony export */ "findRushJsonFolder": () => (/* binding */ findRushJsonFolder), -/* harmony export */ "getNpmPath": () => (/* binding */ getNpmPath), -/* harmony export */ "installAndRun": () => (/* binding */ installAndRun), -/* harmony export */ "runWithErrorAndStatusCode": () => (/* binding */ runWithErrorAndStatusCode) +/* harmony export */ RUSH_JSON_FILENAME: () => (/* binding */ RUSH_JSON_FILENAME), +/* harmony export */ findRushJsonFolder: () => (/* binding */ findRushJsonFolder), +/* harmony export */ getNpmPath: () => (/* binding */ getNpmPath), +/* harmony export */ installAndRun: () => (/* binding */ installAndRun), +/* harmony export */ runWithErrorAndStatusCode: () => (/* binding */ runWithErrorAndStatusCode) /* harmony export */ }); -/* harmony import */ var child_process__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! child_process */ 532081); +/* harmony import */ var child_process__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! child_process */ 535317); /* harmony import */ var child_process__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(child_process__WEBPACK_IMPORTED_MODULE_0__); -/* harmony import */ var fs__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! fs */ 657147); +/* harmony import */ var fs__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! fs */ 179896); /* harmony import */ var fs__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(fs__WEBPACK_IMPORTED_MODULE_1__); -/* harmony import */ var os__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! os */ 822037); +/* harmony import */ var os__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! os */ 370857); /* harmony import */ var os__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(os__WEBPACK_IMPORTED_MODULE_2__); -/* harmony import */ var path__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! path */ 371017); +/* harmony import */ var path__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! path */ 16928); /* harmony import */ var path__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(path__WEBPACK_IMPORTED_MODULE_3__); -/* harmony import */ var _utilities_npmrcUtilities__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../utilities/npmrcUtilities */ 679877); +/* harmony import */ var _utilities_npmrcUtilities__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../utilities/npmrcUtilities */ 832286); // Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license. // See LICENSE in the project root for license information. /* eslint-disable no-console */ diff --git a/examples/joy/package.json b/examples/joy/package.json index edb2266..54c5f22 100644 --- a/examples/joy/package.json +++ b/examples/joy/package.json @@ -7,7 +7,7 @@ "dev": "vite", "build": "tsc && vite build", "preview": "vite preview", - "eslint": "eslint" + "eslint": "eslint --max-warnings=0" }, "dependencies": { "@ilbrando/utils": "workspace:*", diff --git a/examples/storybook/package.json b/examples/storybook/package.json index f18a0a4..7ae3b18 100644 --- a/examples/storybook/package.json +++ b/examples/storybook/package.json @@ -8,8 +8,7 @@ "build": "tsc && vite build", "preview": "vite preview", "storybook": "storybook dev -p 6006", - "build-storybook": "storybook build", - "eslint": "echo no eslint yet." + "build-storybook": "storybook build" }, "dependencies": { "@chromatic-com/storybook": "^1.5.0", diff --git a/packages/simple-form-joy/package.json b/packages/simple-form-joy/package.json index 2337136..1d94333 100644 --- a/packages/simple-form-joy/package.json +++ b/packages/simple-form-joy/package.json @@ -33,7 +33,7 @@ "vite": "vite", "type-check": "tsc --noEmit --watch", "build": "vite build && tsc -p tsconfig-declarations.json", - "eslint": "eslint" + "eslint": "eslint --max-warnings=0" }, "devDependencies": { "@ilbrando/eslint-plugin": "workspace:*", diff --git a/packages/simple-form-material-ui/package.json b/packages/simple-form-material-ui/package.json index 71f3d15..a95b647 100644 --- a/packages/simple-form-material-ui/package.json +++ b/packages/simple-form-material-ui/package.json @@ -33,7 +33,7 @@ "vite": "vite", "type-check": "tsc --noEmit --watch", "build": "vite build && tsc -p tsconfig-declarations.json", - "eslint": "eslint" + "eslint": "eslint --max-warnings=0" }, "devDependencies": { "@ilbrando/eslint-plugin": "workspace:*", diff --git a/packages/simple-form/package.json b/packages/simple-form/package.json index 720e20e..a6d5a44 100644 --- a/packages/simple-form/package.json +++ b/packages/simple-form/package.json @@ -33,7 +33,7 @@ "vite": "vite", "type-check": "tsc --noEmit --watch", "build": "vite build && tsc -p tsconfig-declarations.json", - "eslint": "eslint" + "eslint": "eslint --max-warnings=0" }, "devDependencies": { "@types/react": "^18", diff --git a/packages/utils/package.json b/packages/utils/package.json index aa7810b..1d1f795 100644 --- a/packages/utils/package.json +++ b/packages/utils/package.json @@ -33,7 +33,8 @@ "vite": "vite", "type-check": "tsc --noEmit --watch", "build": "vite build && tsc -p tsconfig-declarations.json", - "eslint": "eslint" + "test": "vitest run", + "eslint": "eslint --max-warnings=0" }, "devDependencies": { "@types/deep-equal": "~1.0.4", @@ -41,7 +42,8 @@ "eslint": "~9.4.0", "npm-run-all": "~4.1.5", "typescript": "~5.4.5", - "vite": "~5.2.0" + "vite": "~5.2.0", + "vitest": "~2.1.4" }, "peerDependencies": {} } diff --git a/packages/utils/src/utils/array-utils.test.ts b/packages/utils/src/utils/array-utils.test.ts new file mode 100644 index 0000000..24535d5 --- /dev/null +++ b/packages/utils/src/utils/array-utils.test.ts @@ -0,0 +1,96 @@ +import { describe, expect, test } from "vitest"; + +import { compare, single, singleOrUndefined, sort, sortPredicate } from "./array-utils"; + +const list = [1, 2, 3]; + +type ListObject = { + id: number; + b: string; +}; +const listObjects: ListObject[] = [ + { id: 1, b: "xyz" }, + { id: 2, b: "abc" } +]; + +describe("array-utils", () => { + test.each` + list | predicate | expected | description + ${list} | ${(x: number) => x === 1} | ${1} | ${"x => x === 1"} + ${list} | ${(x: number) => x === 2} | ${2} | ${"x => x === 2"} + ${list} | ${(x: number) => x === 3} | ${3} | ${"x => x === 3"} + ${list} | ${(x: number) => x === 4} | ${undefined} | ${"x => x === 4 (returns undefined)"} + `("singleOrUndefined: $description ", ({ list, predicate, expected }) => { + // Act + const actual = singleOrUndefined(list, predicate); + + // Assert + expect(actual).toEqual(expected); + }); + + describe("single", () => { + test("returns found value", () => { + // Act + const expected = 2; + const actual = singleOrUndefined(list, x => x === expected); + + // Assert + expect(actual).toEqual(expected); + }); + + test("throws for not found value", () => { + // Act / Assert + const expected = 5; + expect(() => single(list, x => x === expected)).toThrowError(); + }); + }); + + describe("compare", () => { + const ascending = "ascending"; + const descending = "descending"; + + test.each` + value1 | value2 | order | expected + ${1} | ${1} | ${ascending} | ${0} + ${1} | ${1} | ${descending} | ${0} + ${1} | ${2} | ${ascending} | ${-1} + ${1} | ${2} | ${descending} | ${+1} + ${"abc"} | ${"xyz"} | ${ascending} | ${-1} + ${"xyz"} | ${"abc"} | ${ascending} | ${+1} + `("compare($value1, $value2, $order) => $expected", ({ value1, value2, order, expected }) => { + // Act + const actual = compare(value1, value2, order); + + // Assert + expect(actual).toBe(expected); + }); + }); + + describe("sort", () => { + test.each` + field | expected + ${"id"} | ${[1, 2]} + ${"b"} | ${[2, 1]} + `("sort($field) => $expected", ({ field, expected }) => { + // Act + const actual = sort(listObjects, field); + + // Assert + expect(actual.map(x => x.id)).toEqual(expected); + }); + }); + + describe("sortPredicate", () => { + test.each` + predicate | expected | description + ${(x: ListObject) => x.id} | ${[1, 2]} | ${"x => x.id"} + ${(x: ListObject) => x.b} | ${[2, 1]} | ${"x => x.b"} + `("sort($description) => $expected", ({ predicate, expected }) => { + // Act + const actual = sortPredicate(listObjects, predicate); + + // Assert + expect(actual.map(x => x.id)).toEqual(expected); + }); + }); +}); diff --git a/packages/utils/src/utils/object-utils.test.ts b/packages/utils/src/utils/object-utils.test.ts new file mode 100644 index 0000000..d8a349e --- /dev/null +++ b/packages/utils/src/utils/object-utils.test.ts @@ -0,0 +1,150 @@ +import { describe, expect, test } from "vitest"; + +import { ensureValue, hasValue, hasValueAndNotEmptyString, isEqual, isNumber, isObject, isString, removeNullProps, undefinedToNull } from "./object-utils"; + +describe("object-utils", () => { + test.each` + value | expected + ${1} | ${true} + ${"abc"} | ${true} + ${{ a: 42 }} | ${true} + ${null} | ${false} + ${undefined} | ${false} + `("hasValue($value) => $expected", ({ value, expected }) => { + // Act + const actual = hasValue(value); + + // Assert + expect(actual).toEqual(expected); + }); + + test.each` + value | expected + ${"abc"} | ${true} + ${""} | ${true} + ${1} | ${false} + ${{ a: 42 }} | ${false} + ${null} | ${false} + ${undefined} | ${false} + `("isString($value) => $expected", ({ value, expected }) => { + // Act + const actual = isString(value); + + // Assert + expect(actual).toEqual(expected); + }); + + test.each` + value | expected + ${1} | ${true} + ${"abc"} | ${false} + ${{ a: 42 }} | ${false} + ${null} | ${false} + ${undefined} | ${false} + `("isNumber($value) => $expected", ({ value, expected }) => { + // Act + const actual = isNumber(value); + + // Assert + expect(actual).toEqual(expected); + }); + + test.each` + value | expected + ${{ a: 42 }} | ${true} + ${1} | ${false} + ${"abc"} | ${false} + ${null} | ${false} + ${undefined} | ${false} + `("isObject($value) => $expected", ({ value, expected }) => { + // Act + const actual = isObject(value); + + // Assert + expect(actual).toEqual(expected); + }); + + test.each` + value | expected + ${"abc"} | ${true} + ${""} | ${false} + ${1} | ${false} + ${{ a: 42 }} | ${false} + ${null} | ${false} + ${undefined} | ${false} + `("hasValueAndNotEmptyString($value) => $expected", ({ value, expected }) => { + // Act + const actual = hasValueAndNotEmptyString(value); + + // Assert + expect(actual).toEqual(expected); + }); + + describe("ensureValue", () => { + test("returns value", () => { + // Act + const expected = 2; + const actual = ensureValue(expected); + + // Assert + expect(actual).toEqual(expected); + }); + + test.each` + value + ${null} + ${undefined} + `("ensureValue($value) throws", ({ value }) => { + expect(() => ensureValue(value)).toThrowError(); + }); + }); + + test.each` + value1 | value2 | expected + ${"abc"} | ${"abc"} | ${true} + ${"abc"} | ${"xyz"} | ${false} + ${1} | ${1} | ${true} + ${1} | ${2} | ${false} + ${new Date(2024, 0, 1, 0, 0, 0, 0)} | ${new Date(2024, 0, 1, 0, 0, 0, 0)} | ${true} + ${new Date(2024, 0, 1, 0, 0, 0, 0)} | ${new Date(2024, 0, 1, 0, 0, 0, 1)} | ${false} + ${{ a: 42 }} | ${{ a: 42 }} | ${true} + ${{ a: 42 }} | ${{ a: 43 }} | ${false} + ${{ a: { b: 42 } }} | ${{ a: { b: 42 } }} | ${true} + ${{ a: { b: 42 } }} | ${{ a: { b: 43 } }} | ${false} + ${null} | ${null} | ${true} + ${undefined} | ${undefined} | ${true} + ${null} | ${undefined} | ${false} + `("isEqual($value1, $value2) => $expected", ({ value1, value2, expected }) => { + // Act + const actual = isEqual(value1, value2); + + // Assert + expect(actual).toEqual(expected); + }); + + test.each` + value | expected + ${{ a: 42 }} | ${{ a: 42 }} + ${{ a: 42, b: null }} | ${{ a: 42 }} + ${{ a: 42, b: undefined }} | ${{ a: 42 }} + `("removeNullProps($value) => $expected", ({ value, expected }) => { + // Act + const actual = removeNullProps(value); + + // Assert + expect(actual).toEqual(expected); + }); + + test.each` + value | expected + ${{ a: 42 }} | ${{ a: 42 }} + ${{ a: 42, b: null }} | ${{ a: 42, b: null }} + ${{ a: 42, b: undefined }} | ${{ a: 42, b: null }} + `("undefinedToNull($value) => $expected", ({ value, expected }) => { + // Act + const actual = undefinedToNull(value); + + // Assert + expect(actual).toEqual(expected); + }); +}); diff --git a/packages/utils/src/utils/object-utils.ts b/packages/utils/src/utils/object-utils.ts index 1993466..3d7519f 100644 --- a/packages/utils/src/utils/object-utils.ts +++ b/packages/utils/src/utils/object-utils.ts @@ -21,8 +21,10 @@ export const isObject = (value: unknown): value is object => { }; export const hasValueAndNotEmptyString = (value: T | undefined | null): value is T => { - if (typeof value === "string" && value === "") return false; - return hasValue(value); + if (!hasValue(value)) return false; + if (typeof value !== "string") return false; + if (value === "") return false; + return true; }; /** You can use this when the Typescript compiler can't determine that a value is not diff --git a/packages/utils/src/utils/text-utils.test.ts b/packages/utils/src/utils/text-utils.test.ts new file mode 100644 index 0000000..0fb7abf --- /dev/null +++ b/packages/utils/src/utils/text-utils.test.ts @@ -0,0 +1,38 @@ +import { describe, expect, test } from "vitest"; + +import { emptyStringToNull, occurrences } from "./text-utils"; +import { Maybe } from "./type-utils"; + +describe("text-utils", () => { + test.each` + text | search | allowOverlapping | expected + ${"abc"} | ${"a"} | ${false} | ${1} + ${"abc"} | ${"b"} | ${false} | ${1} + ${"abc"} | ${"c"} | ${false} | ${1} + ${"abc"} | ${"d"} | ${false} | ${0} + ${"abc"} | ${"ab"} | ${false} | ${1} + ${"abba"} | ${"a"} | ${false} | ${2} + ${"aaaa"} | ${"aa"} | ${false} | ${2} + ${"aaaa"} | ${"aa"} | ${true} | ${3} + `("occurrences: ($text, $search) => $expected", ({ text, search, allowOverlapping, expected }: { text: string; search: string; allowOverlapping: boolean; expected: ReturnType }) => { + // Act + const actual = occurrences(text, search, allowOverlapping); + + // Assert + expect(actual).toEqual(expected); + }); + + test.each` + value | expected + ${"abc"} | ${"abc"} + ${""} | ${null} + ${null} | ${null} + ${undefined} | ${null} + `("emptyStringToNull: ($value) => $expected", ({ value, expected }: { value: Maybe; expected: ReturnType }) => { + // Act + const actual = emptyStringToNull(value); + + // Assert + expect(actual).toEqual(expected); + }); +}); diff --git a/packages/utils/src/utils/type-utils.test-d.ts b/packages/utils/src/utils/type-utils.test-d.ts new file mode 100644 index 0000000..bf18c9d --- /dev/null +++ b/packages/utils/src/utils/type-utils.test-d.ts @@ -0,0 +1,49 @@ +import { describe, expectTypeOf, test } from "vitest"; + +import { Arbitrary, InferArrayItem, MakeNullable, MakeOptional, Maybe, OmitSafe, PropKeysOf, RemoveOptional } from "./type-utils"; + +type TestType = { a: number; b: string; c: string; d?: string }; + +describe("type-utils", () => { + test("Maybe", () => { + expectTypeOf("a string").toMatchTypeOf>(); + expectTypeOf(null).toMatchTypeOf>(); + expectTypeOf(undefined).toMatchTypeOf>(); + expectTypeOf(42).toMatchTypeOf>(); + }); + + test("OmitSafe", () => { + expectTypeOf({ a: 42 }).toEqualTypeOf>(); + }); + + test("PropKeysOf", () => { + expectTypeOf("a" as const).toMatchTypeOf>(); + expectTypeOf("b" as const).toMatchTypeOf>(); + expectTypeOf("c" as const).toMatchTypeOf>(); + }); + + test("RemoveOptional", () => { + expectTypeOf({ a: 42, b: "foo", c: "bar" }).toMatchTypeOf(); + expectTypeOf({ a: 42, b: "foo", c: "bar", d: "baz" }).toMatchTypeOf>(); + }); + + test("MakeOptional", () => { + expectTypeOf({}).toMatchTypeOf>(); + expectTypeOf({ a: 42 }).toMatchTypeOf>(); + }); + + test("MakeNullable", () => { + expectTypeOf({ a: null, b: null, c: null }).toMatchTypeOf>(); + }); + + test("InferArrayItem", () => { + expectTypeOf("foo").toMatchTypeOf>(); + }); + + test("Arbitrary", () => { + type X = Arbitrary<"foo" | "bar">; + expectTypeOf("foo").toMatchTypeOf(); + expectTypeOf("bar").toMatchTypeOf(); + expectTypeOf("baz").toMatchTypeOf(); + }); +}); diff --git a/rush.json b/rush.json index d6e7b06..e54baf7 100644 --- a/rush.json +++ b/rush.json @@ -16,7 +16,7 @@ * path segment in the "$schema" field for all your Rush config files. This will ensure * correct error-underlining and tab-completion for editors such as VS Code. */ - "rushVersion": "5.124.2", + "rushVersion": "5.140.1", /** * The next field selects which package manager should be installed and determines its version. @@ -26,7 +26,7 @@ * Specify one of: "pnpmVersion", "npmVersion", or "yarnVersion". See the Rush documentation * for details about these alternatives. */ - "pnpmVersion": "9.1.1", + "pnpmVersion": "9.12.3", // "npmVersion": "6.14.15", // "yarnVersion": "1.9.4", diff --git a/tools/eslint-plugin/package.json b/tools/eslint-plugin/package.json index 68d1038..5869720 100644 --- a/tools/eslint-plugin/package.json +++ b/tools/eslint-plugin/package.json @@ -19,8 +19,7 @@ "dist" ], "scripts": { - "build": "tsup src/index.ts --format esm --dts", - "eslint": "echo no linting in this project for now" + "build": "tsup src/index.ts --format esm --dts" }, "dependencies": { "@types/eslint__js": "~8.42.3",