diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ea33c43..834afa9 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -21,5 +21,5 @@ jobs: - run: pnpm install - run: pnpm lint - run: pnpm build - - run: pnpm vitest --coverage + - run: pnpm vitest --coverage --typecheck - uses: codecov/codecov-action@v3 diff --git a/.gitignore b/.gitignore index d3ea3e8..48be4cd 100644 --- a/.gitignore +++ b/.gitignore @@ -8,3 +8,4 @@ types *.log* *.conf* *.env* +tsconfig.vitest-temp.json diff --git a/package.json b/package.json index 69b6de0..c582ffe 100644 --- a/package.json +++ b/package.json @@ -21,22 +21,22 @@ ], "scripts": { "build": "unbuild", - "dev": "vitest dev", + "dev": "vitest dev --typecheck", "lint": "eslint --cache --ext .ts,.js,.mjs,.cjs . && prettier -c src test", "lint:fix": "eslint --cache --ext .ts,.js,.mjs,.cjs . --fix && prettier -c src test -w", "prepack": "pnpm run build", "release": "pnpm test && changelogen --release --push && npm publish", - "test": "pnpm lint && vitest run --coverage" + "test": "pnpm lint && vitest run --typecheck --coverage" }, "devDependencies": { "@types/node": "^20.9.0", - "@vitest/coverage-v8": "^0.34.6", + "@vitest/coverage-v8": "^1.0.0-beta.4", "eslint": "^8.53.0", "eslint-config-unjs": "^0.2.1", "prettier": "^3.1.0", "typescript": "^5.2.2", "unbuild": "^2.0.0", - "vitest": "^0.34.6" + "vitest": "^1.0.0-beta.4" }, "packageManager": "pnpm@8.10.5" } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 85aa481..8fc4807 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -9,8 +9,8 @@ devDependencies: specifier: ^20.9.0 version: 20.9.0 '@vitest/coverage-v8': - specifier: ^0.34.6 - version: 0.34.6(vitest@0.34.6) + specifier: ^1.0.0-beta.4 + version: 1.0.0-beta.4(vitest@1.0.0-beta.4) eslint: specifier: ^8.53.0 version: 8.53.0 @@ -27,8 +27,8 @@ devDependencies: specifier: ^2.0.0 version: 2.0.0(typescript@5.2.2) vitest: - specifier: ^0.34.6 - version: 0.34.6 + specifier: ^1.0.0-beta.4 + version: 1.0.0-beta.4(@types/node@20.9.0) packages: @@ -857,16 +857,6 @@ packages: resolution: {integrity: sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==} dev: true - /@types/chai-subset@1.3.5: - resolution: {integrity: sha512-c2mPnw+xHtXDoHmdtcCXGwyLMiauiAyxWMzhGpqHC4nqI/Y5G2XhTampslK2rb59kpcuHon03UH8W6iYUzw88A==} - dependencies: - '@types/chai': 4.3.10 - dev: true - - /@types/chai@4.3.10: - resolution: {integrity: sha512-of+ICnbqjmFCiixUnqRulbylyXQrPqIGf/B3Jax1wIF3DvSheysQxAWvqHhZiW3IQrycvokcLcFQlveGp+vyNg==} - dev: true - /@types/estree@1.0.5: resolution: {integrity: sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==} dev: true @@ -1035,10 +1025,10 @@ packages: resolution: {integrity: sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==} dev: true - /@vitest/coverage-v8@0.34.6(vitest@0.34.6): - resolution: {integrity: sha512-fivy/OK2d/EsJFoEoxHFEnNGTg+MmdZBAVK9Ka4qhXR2K3J0DS08vcGVwzDtXSuUMabLv4KtPcpSKkcMXFDViw==} + /@vitest/coverage-v8@1.0.0-beta.4(vitest@1.0.0-beta.4): + resolution: {integrity: sha512-ybSkTDgz1qtWAT3sRJ8xDFnZY1JsFLGGaW2FyZQGxi+pEngjFjR9LcHYSDgHOnaOlZtlAqyrrx98uuimnm9NDw==} peerDependencies: - vitest: '>=0.32.0 <1' + vitest: ^1.0.0-0 dependencies: '@ampproject/remapping': 2.2.1 '@bcoe/v8-coverage': 0.2.3 @@ -1051,43 +1041,43 @@ packages: std-env: 3.5.0 test-exclude: 6.0.0 v8-to-istanbul: 9.1.3 - vitest: 0.34.6 + vitest: 1.0.0-beta.4(@types/node@20.9.0) transitivePeerDependencies: - supports-color dev: true - /@vitest/expect@0.34.6: - resolution: {integrity: sha512-QUzKpUQRc1qC7qdGo7rMK3AkETI7w18gTCUrsNnyjjJKYiuUB9+TQK3QnR1unhCnWRC0AbKv2omLGQDF/mIjOw==} + /@vitest/expect@1.0.0-beta.4: + resolution: {integrity: sha512-JOpNEva2AFxfySH3F+X+hT52Kq/ZdIrGtzWYbj6yRuBuxFqM55n/7/jV4XtQG+XkmehP3OUZGx5zISOU8KHPQw==} dependencies: - '@vitest/spy': 0.34.6 - '@vitest/utils': 0.34.6 + '@vitest/spy': 1.0.0-beta.4 + '@vitest/utils': 1.0.0-beta.4 chai: 4.3.10 dev: true - /@vitest/runner@0.34.6: - resolution: {integrity: sha512-1CUQgtJSLF47NnhN+F9X2ycxUP0kLHQ/JWvNHbeBfwW8CzEGgeskzNnHDyv1ieKTltuR6sdIHV+nmR6kPxQqzQ==} + /@vitest/runner@1.0.0-beta.4: + resolution: {integrity: sha512-rlXCMp5MxMVVVN5hdhzPL9NpIkfZC0EXwAtN5gwBbCBoVRv9dBQiZ5qTw+LaNmugPl8gm76U4e4/nMZS9s6wyw==} dependencies: - '@vitest/utils': 0.34.6 + '@vitest/utils': 1.0.0-beta.4 p-limit: 4.0.0 pathe: 1.1.1 dev: true - /@vitest/snapshot@0.34.6: - resolution: {integrity: sha512-B3OZqYn6k4VaN011D+ve+AA4whM4QkcwcrwaKwAbyyvS/NB1hCWjFIBQxAQQSQir9/RtyAAGuq+4RJmbn2dH4w==} + /@vitest/snapshot@1.0.0-beta.4: + resolution: {integrity: sha512-CzmHLGo4RNEQUojYtuEz8wWKp9/p3hvXskejRRJB1iCRH48uWROmoyb2iEQUhgpQw/+WwI4wRP7jek5lp48pRA==} dependencies: magic-string: 0.30.5 pathe: 1.1.1 pretty-format: 29.7.0 dev: true - /@vitest/spy@0.34.6: - resolution: {integrity: sha512-xaCvneSaeBw/cz8ySmF7ZwGvL0lBjfvqc1LpQ/vcdHEvpLn3Ff1vAvjw+CoGn0802l++5L/pxb7whwcWAw+DUQ==} + /@vitest/spy@1.0.0-beta.4: + resolution: {integrity: sha512-YvKUUl7KucKzLJb8+RTd8H3G24EVPGk+CVMFawwtD/KuYjBzM8RCh3oJTTba6ktLpB8JLVy8NVTNL4Oeigqs8A==} dependencies: tinyspy: 2.2.0 dev: true - /@vitest/utils@0.34.6: - resolution: {integrity: sha512-IG5aDD8S6zlvloDsnzHw0Ut5xczlF+kv2BOTo+iXfPr54Yhi5qbVOgGB1hZaVq4iJ4C/MZ2J0y15IlsV/ZcI0A==} + /@vitest/utils@1.0.0-beta.4: + resolution: {integrity: sha512-YY4bhhVqyTxuNwuZJXiCM4/D0Z7Z3H3JDHNM8gXty7EyRUf4iPDQtXzIWe1r4zdTtoFnzFAeMr+891pWlv4SPA==} dependencies: diff-sequences: 29.6.3 loupe: 2.3.7 @@ -3351,8 +3341,8 @@ packages: resolution: {integrity: sha512-65NKvSuAVDP/n4CqH+a9w2kTlLReS9vhsAP06MWx+/89nMinJyB2icyl58RIcqCmIggpojIGeuJGhjU1aGMBSg==} dev: true - /tinypool@0.7.0: - resolution: {integrity: sha512-zSYNUlYSMhJ6Zdou4cJwo/p7w5nmAH17GRfU/ui3ctvjXFErXXkruT4MWW6poDeXgCaIBlGLrfU6TbTXxyGMww==} + /tinypool@0.8.1: + resolution: {integrity: sha512-zBTCK0cCgRROxvs9c0CGK838sPkeokNGdQVUUwHAbynHFlmyJYj825f/oRs528HaIJ97lo0pLIlDUzwN+IorWg==} engines: {node: '>=14.0.0'} dev: true @@ -3576,9 +3566,9 @@ packages: spdx-expression-parse: 3.0.1 dev: true - /vite-node@0.34.6(@types/node@20.9.0): - resolution: {integrity: sha512-nlBMJ9x6n7/Amaz6F3zJ97EBwR2FkzhBRxF5e+jE6LA3yi6Wtc2lyTij1OnDMIr34v5g/tVQtsVAzhT0jc5ygA==} - engines: {node: '>=v14.18.0'} + /vite-node@1.0.0-beta.4(@types/node@20.9.0): + resolution: {integrity: sha512-YODjVvHd2Jih+TGMG3B99ktSyvET9w2cMevorAjcuQ3KKiPhDxEf2bRia2KsDHfnUGIfSpwoUdbcDdJ5xR7epg==} + engines: {node: ^18.0.0 || >=20.0.0} hasBin: true dependencies: cac: 6.7.14 @@ -3634,22 +3624,22 @@ packages: fsevents: 2.3.3 dev: true - /vitest@0.34.6: - resolution: {integrity: sha512-+5CALsOvbNKnS+ZHMXtuUC7nL8/7F1F2DnHGjSsszX8zCjWSSviphCb/NuS9Nzf4Q03KyyDRBAXhF/8lffME4Q==} - engines: {node: '>=v14.18.0'} + /vitest@1.0.0-beta.4(@types/node@20.9.0): + resolution: {integrity: sha512-WOJTqxY3hWqn4yy26SK+cx+BlPBeK/KtY9ALWkD6FLWLhSGY0QFEmarc8sdb/UGZQ8xs5pOvcQQS9JJSV8HH8g==} + engines: {node: ^18.0.0 || >=20.0.0} hasBin: true peerDependencies: '@edge-runtime/vm': '*' + '@types/node': ^18.0.0 || >=20.0.0 '@vitest/browser': '*' '@vitest/ui': '*' happy-dom: '*' jsdom: '*' - playwright: '*' - safaridriver: '*' - webdriverio: '*' peerDependenciesMeta: '@edge-runtime/vm': optional: true + '@types/node': + optional: true '@vitest/browser': optional: true '@vitest/ui': @@ -3658,21 +3648,13 @@ packages: optional: true jsdom: optional: true - playwright: - optional: true - safaridriver: - optional: true - webdriverio: - optional: true dependencies: - '@types/chai': 4.3.10 - '@types/chai-subset': 1.3.5 '@types/node': 20.9.0 - '@vitest/expect': 0.34.6 - '@vitest/runner': 0.34.6 - '@vitest/snapshot': 0.34.6 - '@vitest/spy': 0.34.6 - '@vitest/utils': 0.34.6 + '@vitest/expect': 1.0.0-beta.4 + '@vitest/runner': 1.0.0-beta.4 + '@vitest/snapshot': 1.0.0-beta.4 + '@vitest/spy': 1.0.0-beta.4 + '@vitest/utils': 1.0.0-beta.4 acorn: 8.11.2 acorn-walk: 8.3.0 cac: 6.7.14 @@ -3685,9 +3667,9 @@ packages: std-env: 3.5.0 strip-literal: 1.3.0 tinybench: 2.5.1 - tinypool: 0.7.0 + tinypool: 0.8.1 vite: 4.5.0(@types/node@20.9.0) - vite-node: 0.34.6(@types/node@20.9.0) + vite-node: 1.0.0-beta.4(@types/node@20.9.0) why-is-node-running: 2.2.2 transitivePeerDependencies: - less diff --git a/src/types.ts b/src/types.ts index fcf36d4..1d064d9 100644 --- a/src/types.ts +++ b/src/types.ts @@ -1,10 +1,3 @@ -type Assert = T; -type Equal = (() => T extends X ? 1 : 2) extends () => T extends Y - ? 1 - : 2 - ? true - : false; - type Splitter = "-" | "_" | "/" | "."; type FirstOfString = S extends `${infer F}${string}` ? F @@ -99,7 +92,7 @@ export type SplitByCase< : string[] : Accumulator; -type JoinByCase = string extends T +export type JoinByCase = string extends T ? string : string[] extends T ? string @@ -138,65 +131,3 @@ export type SnakeCase = JoinByCase< T, "_" >; - -// eslint-disable-next-line @typescript-eslint/no-unused-vars -type __tests = [ - // SplitByCase - Assert, string[]>>, - // default splitters - Assert, []>>, - Assert, ["foo"]>>, - Assert, ["foo", "bar", "baz", "qux"]>>, - Assert, ["foo", "", "bar", "Baz"]>>, - Assert, ["foo123", "bar"]>>, - Assert, ["foo", "Bar"]>>, - Assert, ["foo", "BAR", "Baz"]>>, - Assert, ["FOO", "Bar"]>>, - Assert, ["A", "Link"]>>, - // custom splitters - Assert< - Equal< - SplitByCase<"foo\\Bar.fuzz-FIZz", "\\" | "." | "-">, - ["foo", "Bar", "fuzz", "FI", "Zz"] - > - >, - - // PascalCase - Assert, string>>, - Assert, string>>, - // string - Assert, "">>, - Assert, "Foo">>, - Assert, "FooBAr">>, - Assert, "FooBARb">>, - Assert, "FooBarBazQux">>, - Assert, "FooBarBaz">>, - // array - Assert, "FooBar">>, - Assert< - Equal, "FooBarFuzzFIZz"> - >, - - // CamelCase - Assert, string>>, - Assert, string>>, - // string - Assert, "">>, - Assert, "foo">>, - Assert, "fooBARb">>, - Assert, "fooBarBazQux">>, - // array - Assert, "fooBar">>, - - // JoinByCase - Assert, string>>, - Assert, string>>, - // string - Assert, "">>, - Assert, "foo">>, - Assert, "foo-ba-rb">>, - Assert, "foo-bar-baz-qux">>, - // array - Assert, "foo-bar">>, -]; -/* eslint-enable @typescript-eslint/no-unused-vars */ diff --git a/test/types.test-d.ts b/test/types.test-d.ts new file mode 100644 index 0000000..f7da892 --- /dev/null +++ b/test/types.test-d.ts @@ -0,0 +1,94 @@ +import { describe, test, assertType, expectTypeOf } from "vitest"; +import type { + SplitByCase, + PascalCase, + CamelCase, + JoinByCase, +} from "../src/types"; + +describe("SplitByCase", () => { + test("types", () => { + expectTypeOf>().toEqualTypeOf(); + }); + + test("default splitters", () => { + assertType>([]); + assertType>(["foo"]); + assertType>(["foo", "bar", "baz", "qux"]); + assertType>(["foo", "", "bar", "Baz"]); + assertType>(["foo123", "bar"]); + assertType>(["foo", "Bar"]); + assertType>(["foo", "BAR", "Baz"]); + assertType>(["FOO", "Bar"]); + assertType>(["A", "Link"]); + }); + + test("custom splitters", () => { + assertType>([ + "foo", + "Bar", + "fuzz", + "FI", + "Zz", + ]); + }); +}); + +describe("PascalCase", () => { + test("types", () => { + expectTypeOf>().toEqualTypeOf(); + expectTypeOf>().toEqualTypeOf(); + }); + + test("string", () => { + assertType>(""); + assertType>("Foo"); + assertType>("FooBAr"); + assertType>("FooBARb"); + assertType>("FooBarBazQux"); + assertType>("FooBarBaz"); + }); + + test("array", () => { + assertType>("FooBar"); + assertType>( + "FooBarFuzzFIZz", + ); + }); +}); + +describe("CamelCase", () => { + test("types", () => { + expectTypeOf>().toEqualTypeOf(); + expectTypeOf>().toEqualTypeOf(); + }); + + test("string", () => { + assertType>(""); + assertType>("foo"); + assertType>("fooBARb"); + assertType>("fooBarBazQux"); + }); + + test("array", () => { + assertType>("fooBar"); + }); +}); + +describe("JoinByCase", () => { + test("types", () => { + expectTypeOf>().toEqualTypeOf(); + expectTypeOf>().toEqualTypeOf(); + }); + + test("string", () => { + assertType>(""); + assertType>("foo"); + assertType>("foo-ba-rb"); + assertType>("foo-bar-baz-qux"); + }); + + test("array", () => { + assertType>("foo-bar"); + }); +}); diff --git a/tsconfig.json b/tsconfig.json index e9588d9..2b934df 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -6,5 +6,5 @@ "esModuleInterop": true, "strict": true }, - "include": ["src"] + "include": ["src", "test"] }