diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index d5dd315..7d61535 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -17,4 +17,6 @@ jobs: node-version: 18.x cache: "pnpm" - run: pnpm install --frozen-lockfile - - run: pnpm run lint && pnpm run build + - run: pnpm run lint + - run: pnpm run test + - run: pnpm run build diff --git a/package.json b/package.json index 78e2ed2..f0363bf 100644 --- a/package.json +++ b/package.json @@ -9,6 +9,7 @@ "build": "tsup src/index.ts --format cjs,esm --dts", "release": "pnpm run build && changeset publish", "lint": "tsc", + "test": "vitest", "generate:changelog": "changeset", "generate:version": "changeset version", "db:generate": "drizzle-kit generate:sqlite", @@ -43,7 +44,8 @@ "drizzle-kit": "^0.19.13", "tsup": "^7.2.0", "tsx": "^3.12.8", - "typescript": "^5.2.2" + "typescript": "^5.2.2", + "vitest": "^0.34.4" }, "publishConfig": { "access": "public" diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index ccfd404..1d9c0ad 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -37,6 +37,9 @@ devDependencies: typescript: specifier: ^5.2.2 version: 5.2.2 + vitest: + specifier: ^0.34.4 + version: 0.34.4 packages: @@ -476,6 +479,13 @@ packages: dev: true optional: true + /@jest/schemas@29.6.3: + resolution: {integrity: sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@sinclair/typebox': 0.27.8 + dev: true + /@jridgewell/gen-mapping@0.3.3: resolution: {integrity: sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==} engines: {node: '>=6.0.0'} @@ -547,11 +557,25 @@ packages: fastq: 1.15.0 dev: true + /@sinclair/typebox@0.27.8: + resolution: {integrity: sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==} + dev: true + /@types/better-sqlite3@7.6.4: resolution: {integrity: sha512-dzrRZCYPXIXfSR1/surNbJ/grU3scTaygS0OMzjlGf71i9sc2fGyHPXXiXmEvNIoE0cGwsanEFMVJxPXmco9Eg==} dependencies: '@types/node': 20.6.0 + /@types/chai-subset@1.3.3: + resolution: {integrity: sha512-frBecisrNGz+F4T6bcc+NLeolfiojh5FxW2klu669+8BARtyQv2C/GkNW6FUodVe4BroGMP/wER/YDGc7rEllw==} + dependencies: + '@types/chai': 4.3.6 + dev: true + + /@types/chai@4.3.6: + resolution: {integrity: sha512-VOVRLM1mBxIRxydiViqPcKn6MIxZytrbMpd6RJLIWKxUNr3zux8no0Oc7kJx0WAPIitgZ0gkrDS+btlqQpubpw==} + dev: true + /@types/is-ci@3.0.0: resolution: {integrity: sha512-Q0Op0hdWbYd1iahB+IFNQcWXFq4O0Q5MwQP7uN0souuQ4rPg1vEYcnIOfr1gY+M+6rc8FGoRaBO1mOOvL29sEQ==} dependencies: @@ -577,6 +601,55 @@ packages: resolution: {integrity: sha512-cJRQXpObxfNKkFAZbJl2yjWtJCqELQIdShsogr1d2MilP8dKD9TE/nEKHkJgUNHdGKCQaf9HbIynuV2csLGVLg==} dev: true + /@vitest/expect@0.34.4: + resolution: {integrity: sha512-XlMKX8HyYUqB8dsY8Xxrc64J2Qs9pKMt2Z8vFTL4mBWXJsg4yoALHzJfDWi8h5nkO4Zua4zjqtapQ/IluVkSnA==} + dependencies: + '@vitest/spy': 0.34.4 + '@vitest/utils': 0.34.4 + chai: 4.3.8 + dev: true + + /@vitest/runner@0.34.4: + resolution: {integrity: sha512-hwwdB1StERqUls8oV8YcpmTIpVeJMe4WgYuDongVzixl5hlYLT2G8afhcdADeDeqCaAmZcSgLTLtqkjPQF7x+w==} + dependencies: + '@vitest/utils': 0.34.4 + p-limit: 4.0.0 + pathe: 1.1.1 + dev: true + + /@vitest/snapshot@0.34.4: + resolution: {integrity: sha512-GCsh4coc3YUSL/o+BPUo7lHQbzpdttTxL6f4q0jRx2qVGoYz/cyTRDJHbnwks6TILi6560bVWoBpYC10PuTLHw==} + dependencies: + magic-string: 0.30.3 + pathe: 1.1.1 + pretty-format: 29.6.3 + dev: true + + /@vitest/spy@0.34.4: + resolution: {integrity: sha512-PNU+fd7DUPgA3Ya924b1qKuQkonAW6hL7YUjkON3wmBwSTIlhOSpy04SJ0NrRsEbrXgMMj6Morh04BMf8k+w0g==} + dependencies: + tinyspy: 2.1.1 + dev: true + + /@vitest/utils@0.34.4: + resolution: {integrity: sha512-yR2+5CHhp/K4ySY0Qtd+CAL9f5Yh1aXrKfAT42bq6CtlGPh92jIDDDSg7ydlRow1CP+dys4TrOrbELOyNInHSg==} + dependencies: + diff-sequences: 29.6.3 + loupe: 2.3.6 + pretty-format: 29.6.3 + dev: true + + /acorn-walk@8.2.0: + resolution: {integrity: sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==} + engines: {node: '>=0.4.0'} + dev: true + + /acorn@8.10.0: + resolution: {integrity: sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==} + engines: {node: '>=0.4.0'} + hasBin: true + dev: true + /ansi-colors@4.1.3: resolution: {integrity: sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==} engines: {node: '>=6'} @@ -601,6 +674,11 @@ packages: color-convert: 2.0.1 dev: true + /ansi-styles@5.2.0: + resolution: {integrity: sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==} + engines: {node: '>=10'} + dev: true + /any-promise@1.3.0: resolution: {integrity: sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==} dev: true @@ -659,6 +737,10 @@ packages: engines: {node: '>=0.10.0'} dev: true + /assertion-error@1.1.0: + resolution: {integrity: sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==} + dev: true + /available-typed-arrays@1.0.5: resolution: {integrity: sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==} engines: {node: '>= 0.4'} @@ -779,6 +861,19 @@ packages: engines: {node: '>=14.16'} dev: true + /chai@4.3.8: + resolution: {integrity: sha512-vX4YvVVtxlfSZ2VecZgFUTU5qPCYsobVI2O9FmwEXBhDigYGQA6jRXCycIs1yJnnWbZ6/+a2zNIF5DfVCcJBFQ==} + engines: {node: '>=4'} + dependencies: + assertion-error: 1.1.0 + check-error: 1.0.2 + deep-eql: 4.1.3 + get-func-name: 2.0.0 + loupe: 2.3.6 + pathval: 1.1.1 + type-detect: 4.0.8 + dev: true + /chalk@2.4.2: resolution: {integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==} engines: {node: '>=4'} @@ -805,6 +900,10 @@ packages: resolution: {integrity: sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==} dev: true + /check-error@1.0.2: + resolution: {integrity: sha512-BrgHpW9NURQgzoNyjfq0Wu6VFO6D7IZEmJNdtgNqpzGG8RuNFHt2jQxWlAs4HMe119chBnv+34syEZtc6IhLtA==} + dev: true + /chokidar@3.5.3: resolution: {integrity: sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==} engines: {node: '>= 8.10.0'} @@ -973,6 +1072,13 @@ packages: dependencies: mimic-response: 3.1.0 + /deep-eql@4.1.3: + resolution: {integrity: sha512-WaEtAOpRA1MQ0eohqZjpGD8zdI0Ovsm8mmFhaDN8dvDZzyoUMcYDnf5Y6iu7HTXxf8JDS23qWa4a+hKCDyOPzw==} + engines: {node: '>=6'} + dependencies: + type-detect: 4.0.8 + dev: true + /deep-extend@0.6.0: resolution: {integrity: sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==} engines: {node: '>=4.0.0'} @@ -1000,6 +1106,11 @@ packages: resolution: {integrity: sha512-UX6sGumvvqSaXgdKGUsgZWqcUyIXZ/vZTrlRT/iobiKhGL0zL4d3osHj3uqllWJK+i+sixDS/3COVEOFbupFyw==} engines: {node: '>=8'} + /diff-sequences@29.6.3: + resolution: {integrity: sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dev: true + /difflib@0.2.4: resolution: {integrity: sha512-9YVwmMb0wQHQNr5J9m6BSj6fk4pfGITGQOOs+D9Fl+INODWFOfvhIU1hNv6GgR1RBoC/9NJcwu77zShxV0kT7w==} dependencies: @@ -1451,6 +1562,10 @@ packages: engines: {node: 6.* || 8.* || >= 10.*} dev: true + /get-func-name@2.0.0: + resolution: {integrity: sha512-Hm0ixYtaSZ/V7C8FJrtZIuBBI+iSgL+1Aq82zSu8VQNB4S3Gk8e7Qs3VwBDJAhmRZcFqkl3tQu36g/Foh5I5ig==} + dev: true + /get-intrinsic@1.2.1: resolution: {integrity: sha512-2DcsyfABl+gVHEfCOaTrWgyt+tb6MSEGmKq+kI5HwLbIYgjgmMcV8KQ41uaKz1xxUcn9tJtgFbQUEVcEbd0FYw==} dependencies: @@ -1856,6 +1971,10 @@ packages: resolution: {integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==} dev: true + /jsonc-parser@3.2.0: + resolution: {integrity: sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w==} + dev: true + /jsonfile@4.0.0: resolution: {integrity: sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==} optionalDependencies: @@ -1896,6 +2015,11 @@ packages: strip-bom: 3.0.0 dev: true + /local-pkg@0.4.3: + resolution: {integrity: sha512-SFppqq5p42fe2qcZQqqEOiVRXl+WCP1MdT6k7BDEW1j++sp5fIY+/fdRQitvKgB5BrBcmrs5m/L0v2FrU5MY1g==} + engines: {node: '>=14'} + dev: true + /locate-path@5.0.0: resolution: {integrity: sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==} engines: {node: '>=8'} @@ -1922,6 +2046,12 @@ packages: resolution: {integrity: sha512-wIkUCfVKpVsWo3JSZlc+8MB5it+2AN5W8J7YVMST30UrvcQNZ1Okbj+rbVniijTWE6FGYy4XJq/rHkas8qJMLQ==} dev: true + /loupe@2.3.6: + resolution: {integrity: sha512-RaPMZKiMy8/JruncMU5Bt6na1eftNoo++R4Y+N2FrxkDVTrGvcyzFTsaGif4QTeKESheMGegbhw6iUAq+5A8zA==} + dependencies: + get-func-name: 2.0.0 + dev: true + /lru-cache@4.1.5: resolution: {integrity: sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==} dependencies: @@ -1941,6 +2071,13 @@ packages: es5-ext: 0.10.62 dev: true + /magic-string@0.30.3: + resolution: {integrity: sha512-B7xGbll2fG/VjP+SWg4sX3JynwIU0mjoTc6MPpKNuIvftk6u6vqhDnk1R80b8C2GBR6ywqy+1DcKBrevBg+bmw==} + engines: {node: '>=12'} + dependencies: + '@jridgewell/sourcemap-codec': 1.4.15 + dev: true + /map-obj@1.0.1: resolution: {integrity: sha512-7N/q3lyZ+LVCp7PzuxrJr4KMbBE2hW7BT7YNia330OFxIf4d3r5zVpicP2650l7CPN6RM9zOJRl3NGpqSiw3Eg==} engines: {node: '>=0.10.0'} @@ -2052,6 +2189,15 @@ packages: /mkdirp-classic@0.5.3: resolution: {integrity: sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==} + /mlly@1.4.2: + resolution: {integrity: sha512-i/Ykufi2t1EZ6NaPLdfnZk2AX8cs0d+mTzVKuPfqPKPatxLApaBoxJQ9x1/uckXtrS/U5oisPMDkNs0yQTaBRg==} + dependencies: + acorn: 8.10.0 + pathe: 1.1.1 + pkg-types: 1.0.3 + ufo: 1.3.0 + dev: true + /ms@2.1.2: resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==} dev: true @@ -2064,6 +2210,12 @@ packages: thenify-all: 1.6.0 dev: true + /nanoid@3.3.6: + resolution: {integrity: sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==} + engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} + hasBin: true + dev: true + /napi-build-utils@1.0.2: resolution: {integrity: sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg==} @@ -2164,6 +2316,13 @@ packages: yocto-queue: 0.1.0 dev: true + /p-limit@4.0.0: + resolution: {integrity: sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + dependencies: + yocto-queue: 1.0.0 + dev: true + /p-locate@4.1.0: resolution: {integrity: sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==} engines: {node: '>=8'} @@ -2222,6 +2381,18 @@ packages: engines: {node: '>=8'} dev: true + /pathe@1.1.1: + resolution: {integrity: sha512-d+RQGp0MAYTIaDBIMmOfMwz3E+LOZnxx1HZd5R18mmCZY0QBlK0LDZfPc8FW8Ed2DlvsuE6PRjroDY+wg4+j/Q==} + dev: true + + /pathval@1.1.1: + resolution: {integrity: sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==} + dev: true + + /picocolors@1.0.0: + resolution: {integrity: sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==} + dev: true + /picomatch@2.3.1: resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} engines: {node: '>=8.6'} @@ -2244,6 +2415,14 @@ packages: find-up: 4.1.0 dev: true + /pkg-types@1.0.3: + resolution: {integrity: sha512-nN7pYi0AQqJnoLPC9eHFQ8AcyaixBUOwvqc5TDnIKCMEE6I0y8P7OKA7fPexsXGCGxQDl/cmrLAp26LhcwxZ4A==} + dependencies: + jsonc-parser: 3.2.0 + mlly: 1.4.2 + pathe: 1.1.1 + dev: true + /postcss-load-config@4.0.1: resolution: {integrity: sha512-vEJIc8RdiBRu3oRAI0ymerOn+7rPuMvRXslTvZUKZonDHFIczxztIyJ1urxM1x9JXEikvpWWTUUqal5j/8QgvA==} engines: {node: '>= 14'} @@ -2260,6 +2439,15 @@ packages: yaml: 2.3.2 dev: true + /postcss@8.4.29: + resolution: {integrity: sha512-cbI+jaqIeu/VGqXEarWkRCCffhjgXc0qjBtXpqJhTBohMUjUQnbBr0xqX3vEKudc4iviTewcJo5ajcec5+wdJw==} + engines: {node: ^10 || ^12 || >=14} + dependencies: + nanoid: 3.3.6 + picocolors: 1.0.0 + source-map-js: 1.0.2 + dev: true + /prebuild-install@7.1.1: resolution: {integrity: sha512-jAXscXWMcCK8GgCoHOfIr0ODh5ai8mj63L2nWrjuAgXE6tDyYGnx4/8o/rCgU+B4JSyZBKbeZqzhtwtC3ovxjw==} engines: {node: '>=10'} @@ -2294,6 +2482,15 @@ packages: hasBin: true dev: true + /pretty-format@29.6.3: + resolution: {integrity: sha512-ZsBgjVhFAj5KeK+nHfF1305/By3lechHQSMWCTl8iHSbfOm2TN5nHEtFc/+W7fAyUeCs2n5iow72gld4gW0xDw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@jest/schemas': 29.6.3 + ansi-styles: 5.2.0 + react-is: 18.2.0 + dev: true + /pseudomap@1.0.2: resolution: {integrity: sha512-b/YwNhb8lk1Zz2+bXXpS/LK9OisiZZ1SNsSLxN1x2OXVEhW2Ckr/7mWE5vrC1ZTiJlD9g19jWszTmJsB+oEpFQ==} dev: true @@ -2327,6 +2524,10 @@ packages: minimist: 1.2.8 strip-json-comments: 2.0.1 + /react-is@18.2.0: + resolution: {integrity: sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==} + dev: true + /read-pkg-up@7.0.1: resolution: {integrity: sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==} engines: {node: '>=8'} @@ -2511,6 +2712,10 @@ packages: object-inspect: 1.12.3 dev: true + /siginfo@2.0.0: + resolution: {integrity: sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==} + dev: true + /signal-exit@3.0.7: resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==} dev: true @@ -2547,6 +2752,11 @@ packages: yargs: 15.4.1 dev: true + /source-map-js@1.0.2: + resolution: {integrity: sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==} + engines: {node: '>=0.10.0'} + dev: true + /source-map-support@0.5.21: resolution: {integrity: sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==} dependencies: @@ -2599,6 +2809,14 @@ packages: resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==} dev: true + /stackback@0.0.2: + resolution: {integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==} + dev: true + + /std-env@3.4.3: + resolution: {integrity: sha512-f9aPhy8fYBuMN+sNfakZV18U39PbalgjXG3lLB9WkaYTxijru61wb57V9wxxNthXM5Sd88ETBWi29qLAsHO52Q==} + dev: true + /stream-transform@2.1.3: resolution: {integrity: sha512-9GHUiM5hMiCi6Y03jD2ARC1ettBXkQBoQAe7nJsPknnI0ow10aXjTnew8QtYQmLjzn974BnmWEAJgCY6ZP1DeQ==} dependencies: @@ -2672,6 +2890,12 @@ packages: resolution: {integrity: sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==} engines: {node: '>=0.10.0'} + /strip-literal@1.3.0: + resolution: {integrity: sha512-PugKzOsyXpArk0yWmUwqOZecSO0GH0bPoctLcqNDH9J04pVW3lflYE0ujElBGTloevcxF5MofAOZ7C5l2b+wLg==} + dependencies: + acorn: 8.10.0 + dev: true + /sucrase@3.34.0: resolution: {integrity: sha512-70/LQEZ07TEcxiU2dz51FKaE6hCTWC6vr7FOk3Gr0U60C3shtAN+H+BFr9XlYe5xqf3RA8nrc+VIwzCfnxuXJw==} engines: {node: '>=8'} @@ -2748,6 +2972,20 @@ packages: next-tick: 1.1.0 dev: true + /tinybench@2.5.0: + resolution: {integrity: sha512-kRwSG8Zx4tjF9ZiyH4bhaebu+EDz1BOx9hOigYHlUW4xxI/wKIUQUqo018UlU4ar6ATPBsaMrdbKZ+tmPdohFA==} + dev: true + + /tinypool@0.7.0: + resolution: {integrity: sha512-zSYNUlYSMhJ6Zdou4cJwo/p7w5nmAH17GRfU/ui3ctvjXFErXXkruT4MWW6poDeXgCaIBlGLrfU6TbTXxyGMww==} + engines: {node: '>=14.0.0'} + dev: true + + /tinyspy@2.1.1: + resolution: {integrity: sha512-XPJL2uSzcOyBMky6OFrusqWlzfFrXtE0hPuMgW8A2HmaqrPo4ZQHRN/V0QXN3FSjKxpsbRrFc5LI7KOwBsT1/w==} + engines: {node: '>=14.0.0'} + dev: true + /tmp@0.0.33: resolution: {integrity: sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==} engines: {node: '>=0.6.0'} @@ -2848,6 +3086,11 @@ packages: dependencies: safe-buffer: 5.2.1 + /type-detect@4.0.8: + resolution: {integrity: sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==} + engines: {node: '>=4'} + dev: true + /type-fest@0.13.1: resolution: {integrity: sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg==} engines: {node: '>=10'} @@ -2915,6 +3158,10 @@ packages: hasBin: true dev: true + /ufo@1.3.0: + resolution: {integrity: sha512-bRn3CsoojyNStCZe0BG0Mt4Nr/4KF+rhFlnNXybgqt5pXHNFRlqinSoQaTrGyzE4X8aHplSb+TorH+COin9Yxw==} + dev: true + /unbox-primitive@1.0.2: resolution: {integrity: sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==} dependencies: @@ -2939,6 +3186,129 @@ packages: spdx-expression-parse: 3.0.1 dev: true + /vite-node@0.34.4(@types/node@20.6.0): + resolution: {integrity: sha512-ho8HtiLc+nsmbwZMw8SlghESEE3KxJNp04F/jPUCLVvaURwt0d+r9LxEqCX5hvrrOQ0GSyxbYr5ZfRYhQ0yVKQ==} + engines: {node: '>=v14.18.0'} + hasBin: true + dependencies: + cac: 6.7.14 + debug: 4.3.4 + mlly: 1.4.2 + pathe: 1.1.1 + picocolors: 1.0.0 + vite: 4.4.9(@types/node@20.6.0) + transitivePeerDependencies: + - '@types/node' + - less + - lightningcss + - sass + - stylus + - sugarss + - supports-color + - terser + dev: true + + /vite@4.4.9(@types/node@20.6.0): + resolution: {integrity: sha512-2mbUn2LlUmNASWwSCNSJ/EG2HuSRTnVNaydp6vMCm5VIqJsjMfbIWtbH2kDuwUVW5mMUKKZvGPX/rqeqVvv1XA==} + engines: {node: ^14.18.0 || >=16.0.0} + hasBin: true + peerDependencies: + '@types/node': '>= 14' + less: '*' + lightningcss: ^1.21.0 + sass: '*' + stylus: '*' + sugarss: '*' + terser: ^5.4.0 + peerDependenciesMeta: + '@types/node': + optional: true + less: + optional: true + lightningcss: + optional: true + sass: + optional: true + stylus: + optional: true + sugarss: + optional: true + terser: + optional: true + dependencies: + '@types/node': 20.6.0 + esbuild: 0.18.20 + postcss: 8.4.29 + rollup: 3.29.0 + optionalDependencies: + fsevents: 2.3.3 + dev: true + + /vitest@0.34.4: + resolution: {integrity: sha512-SE/laOsB6995QlbSE6BtkpXDeVNLJc1u2LHRG/OpnN4RsRzM3GQm4nm3PQCK5OBtrsUqnhzLdnT7se3aeNGdlw==} + engines: {node: '>=v14.18.0'} + hasBin: true + peerDependencies: + '@edge-runtime/vm': '*' + '@vitest/browser': '*' + '@vitest/ui': '*' + happy-dom: '*' + jsdom: '*' + playwright: '*' + safaridriver: '*' + webdriverio: '*' + peerDependenciesMeta: + '@edge-runtime/vm': + optional: true + '@vitest/browser': + optional: true + '@vitest/ui': + optional: true + happy-dom: + optional: true + jsdom: + optional: true + playwright: + optional: true + safaridriver: + optional: true + webdriverio: + optional: true + dependencies: + '@types/chai': 4.3.6 + '@types/chai-subset': 1.3.3 + '@types/node': 20.6.0 + '@vitest/expect': 0.34.4 + '@vitest/runner': 0.34.4 + '@vitest/snapshot': 0.34.4 + '@vitest/spy': 0.34.4 + '@vitest/utils': 0.34.4 + acorn: 8.10.0 + acorn-walk: 8.2.0 + cac: 6.7.14 + chai: 4.3.8 + debug: 4.3.4 + local-pkg: 0.4.3 + magic-string: 0.30.3 + pathe: 1.1.1 + picocolors: 1.0.0 + std-env: 3.4.3 + strip-literal: 1.3.0 + tinybench: 2.5.0 + tinypool: 0.7.0 + vite: 4.4.9(@types/node@20.6.0) + vite-node: 0.34.4(@types/node@20.6.0) + why-is-node-running: 2.2.2 + transitivePeerDependencies: + - less + - lightningcss + - sass + - stylus + - sugarss + - supports-color + - terser + dev: true + /wcwidth@1.0.1: resolution: {integrity: sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==} dependencies: @@ -3005,6 +3375,15 @@ packages: isexe: 2.0.0 dev: true + /why-is-node-running@2.2.2: + resolution: {integrity: sha512-6tSwToZxTOcotxHeA+qGCq1mVzKR3CwcJGmVcY+QE8SHy6TnpFnh8PAvPNHYr7EcuVeG0QSMxtYCuO1ta/G/oA==} + engines: {node: '>=8'} + hasBin: true + dependencies: + siginfo: 2.0.0 + stackback: 0.0.2 + dev: true + /wordwrap@1.0.0: resolution: {integrity: sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==} dev: true @@ -3099,6 +3478,11 @@ packages: engines: {node: '>=10'} dev: true + /yocto-queue@1.0.0: + resolution: {integrity: sha512-9bnSc/HEW2uRy67wc+T8UwauLuPJVn28jb+GtJY16iiKWyvmYJRXVT4UamsAEGQfPohgr2q4Tq0sQbQlxTfi1g==} + engines: {node: '>=12.20'} + dev: true + /zod@3.22.2: resolution: {integrity: sha512-wvWkphh5WQsJbVk1tbx1l1Ly4yg+XecD+Mq280uBGt9wa5BKSWf4Mhp6GmrkPixhMxmabYY7RbzlwVP32pbGCg==} dev: true diff --git a/test/index.test.ts b/test/index.test.ts new file mode 100644 index 0000000..fe7b978 --- /dev/null +++ b/test/index.test.ts @@ -0,0 +1,1701 @@ +import { Cursor, generateCursor } from "../src"; +import { and, asc, desc, eq, gt, lt, or } from "drizzle-orm"; +import { describe, expect, test } from "vitest"; +import { integer, sqliteTable, text } from "drizzle-orm/sqlite-core"; + +import { e } from "vitest/dist/reporters-cb94c88b"; + +const table = sqliteTable("users", { + id: integer("id").primaryKey({ autoIncrement: true }), + firstName: text("first_name"), + middleName: text("middle_name"), + lastName: text("last_name"), + phone: text("phone"), + email: text("email"), +}); + +describe("index", () => { + describe("generateCursor", () => { + const primaryCursorDefault: Cursor = { key: "id", schema: table.id }; + const primaryCursorASC: Cursor = { + key: "id", + order: "ASC", + schema: table.id, + }; + const primaryCursorDESC: Cursor = { + key: "id", + order: "DESC", + schema: table.id, + }; + + describe("with only primaryCursor", () => { + describe("without previous data generates only orderBy and where is undefined", () => { + test("with primaryCursorDefault", () => { + expect( + generateCursor({ primaryCursor: primaryCursorDefault }) + ).to.deep.equal({ + orderBy: [asc(table.id)], + where: undefined, + }); + }); + + test("with primaryCursorASC", () => { + expect( + generateCursor({ primaryCursor: primaryCursorASC }) + ).to.deep.equal({ + orderBy: [asc(table.id)], + where: undefined, + }); + }); + + test("with primaryCursorDESC", () => { + expect( + generateCursor({ primaryCursor: primaryCursorDESC }) + ).to.deep.equal({ + orderBy: [desc(table.id)], + where: undefined, + }); + }); + }); + describe("with previous data generates orderBy and where", () => { + const previousData = { + id: 1, + firstName: "John", + middleName: "Doe", + lastName: "Smith", + phone: "123456789", + email: "johndoe", + }; + + test("with primaryCursorDefault", () => { + expect( + generateCursor( + { primaryCursor: primaryCursorDefault }, + previousData + ) + ).to.deep.equal({ + orderBy: [asc(table.id)], + where: and(or(gt(table.id, previousData.id))), + }); + }); + + test("with primaryCursorASC", () => { + expect( + generateCursor({ primaryCursor: primaryCursorASC }, previousData) + ).to.deep.equal({ + orderBy: [asc(table.id)], + where: and(or(gt(table.id, previousData.id))), + }); + }); + + test("with primaryCursorDESC", () => { + expect( + generateCursor({ primaryCursor: primaryCursorDESC }, previousData) + ).to.deep.equal({ + orderBy: [desc(table.id)], + where: and(or(lt(table.id, previousData.id))), + }); + }); + }); + }); + + describe("with one cursor", () => { + const cursorDefault: Cursor = { + key: "lastName", + schema: table.lastName, + }; + + const cursorASC: Cursor = { + key: "lastName", + order: "ASC", + schema: table.lastName, + }; + + const cursorDESC: Cursor = { + key: "lastName", + order: "DESC", + schema: table.lastName, + }; + + describe("without previous data generates only orderBy and where is undefined", () => { + test("with primaryCursorDefault and cursorDefault", () => { + expect( + generateCursor({ + primaryCursor: primaryCursorDefault, + cursors: [cursorDefault], + }) + ).to.deep.equal({ + orderBy: [asc(table.lastName), asc(table.id)], + where: undefined, + }); + }); + + test("with primaryCursorDefault and cursorASC", () => { + expect( + generateCursor({ + primaryCursor: primaryCursorDefault, + cursors: [cursorASC], + }) + ).to.deep.equal({ + orderBy: [asc(table.lastName), asc(table.id)], + where: undefined, + }); + }); + + test("with primaryCursorDefault and cursorDESC", () => { + expect( + generateCursor({ + primaryCursor: primaryCursorDefault, + cursors: [cursorDESC], + }) + ).to.deep.equal({ + orderBy: [desc(table.lastName), asc(table.id)], + where: undefined, + }); + }); + + test("with primaryCursorASC and cursorDefault", () => { + expect( + generateCursor({ + primaryCursor: primaryCursorASC, + cursors: [cursorDefault], + }) + ).to.deep.equal({ + orderBy: [asc(table.lastName), asc(table.id)], + where: undefined, + }); + }); + + test("with primaryCursorASC and cursorASC", () => { + expect( + generateCursor({ + primaryCursor: primaryCursorASC, + cursors: [cursorASC], + }) + ).to.deep.equal({ + orderBy: [asc(table.lastName), asc(table.id)], + where: undefined, + }); + }); + + test("with primaryCursorASC and cursorDESC", () => { + expect( + generateCursor({ + primaryCursor: primaryCursorASC, + cursors: [cursorDESC], + }) + ).to.deep.equal({ + orderBy: [desc(table.lastName), asc(table.id)], + where: undefined, + }); + }); + + test("with primaryCursorDESC and cursorDefault", () => { + expect( + generateCursor({ + primaryCursor: primaryCursorDESC, + cursors: [cursorDefault], + }) + ).to.deep.equal({ + orderBy: [asc(table.lastName), desc(table.id)], + where: undefined, + }); + }); + + test("with primaryCursorDESC and cursorASC", () => { + expect( + generateCursor({ + primaryCursor: primaryCursorDESC, + cursors: [cursorASC], + }) + ).to.deep.equal({ + orderBy: [asc(table.lastName), desc(table.id)], + where: undefined, + }); + }); + + test("with primaryCursorDESC and cursorDESC", () => { + expect( + generateCursor({ + primaryCursor: primaryCursorDESC, + cursors: [cursorDESC], + }) + ).to.deep.equal({ + orderBy: [desc(table.lastName), desc(table.id)], + where: undefined, + }); + }); + }); + + describe("with previous data generates orderBy and where", () => { + const previousData = { + id: 1, + firstName: "John", + middleName: "Doe", + lastName: "Smith", + phone: "123456789", + email: "johndoe", + }; + + test("with primaryCursorDefault and cursorDefault", () => { + expect( + generateCursor( + { primaryCursor: primaryCursorDefault, cursors: [cursorDefault] }, + previousData + ) + ).to.deep.equal({ + orderBy: [asc(table.lastName), asc(table.id)], + where: or( + and(gt(table.lastName, previousData.lastName)), + and( + eq(table.lastName, previousData.lastName), + gt(table.id, previousData.id) + ) + ), + }); + }); + + test("with primaryCursorDefault and cursorASC", () => { + expect( + generateCursor( + { primaryCursor: primaryCursorDefault, cursors: [cursorASC] }, + previousData + ) + ).to.deep.equal({ + orderBy: [asc(table.lastName), asc(table.id)], + where: or( + and(gt(table.lastName, previousData.lastName)), + and( + eq(table.lastName, previousData.lastName), + gt(table.id, previousData.id) + ) + ), + }); + }); + + test("with primaryCursorDefault and cursorDESC", () => { + expect( + generateCursor( + { primaryCursor: primaryCursorDefault, cursors: [cursorDESC] }, + previousData + ) + ).to.deep.equal({ + orderBy: [desc(table.lastName), asc(table.id)], + where: or( + and(lt(table.lastName, previousData.lastName)), + and( + eq(table.lastName, previousData.lastName), + gt(table.id, previousData.id) + ) + ), + }); + }); + + test("with primaryCursorASC and cursorDefault", () => { + expect( + generateCursor( + { primaryCursor: primaryCursorASC, cursors: [cursorDefault] }, + previousData + ) + ).to.deep.equal({ + orderBy: [asc(table.lastName), asc(table.id)], + where: or( + and(gt(table.lastName, previousData.lastName)), + and( + eq(table.lastName, previousData.lastName), + gt(table.id, previousData.id) + ) + ), + }); + }); + + test("with primaryCursorASC and cursorASC", () => { + expect( + generateCursor( + { primaryCursor: primaryCursorASC, cursors: [cursorASC] }, + previousData + ) + ).to.deep.equal({ + orderBy: [asc(table.lastName), asc(table.id)], + where: or( + and(gt(table.lastName, previousData.lastName)), + and( + eq(table.lastName, previousData.lastName), + gt(table.id, previousData.id) + ) + ), + }); + }); + + test("with primaryCursorASC and cursorDESC", () => { + expect( + generateCursor( + { primaryCursor: primaryCursorASC, cursors: [cursorDESC] }, + previousData + ) + ).to.deep.equal({ + orderBy: [desc(table.lastName), asc(table.id)], + where: or( + and(lt(table.lastName, previousData.lastName)), + and( + eq(table.lastName, previousData.lastName), + gt(table.id, previousData.id) + ) + ), + }); + }); + + test("with primaryCursorDESC and cursorDefault", () => { + expect( + generateCursor( + { primaryCursor: primaryCursorDESC, cursors: [cursorDefault] }, + previousData + ) + ).to.deep.equal({ + orderBy: [asc(table.lastName), desc(table.id)], + where: or( + and(gt(table.lastName, previousData.lastName)), + and( + eq(table.lastName, previousData.lastName), + lt(table.id, previousData.id) + ) + ), + }); + }); + + test("with primaryCursorDESC and cursorASC", () => { + expect( + generateCursor( + { primaryCursor: primaryCursorDESC, cursors: [cursorASC] }, + previousData + ) + ).to.deep.equal({ + orderBy: [asc(table.lastName), desc(table.id)], + where: or( + and(gt(table.lastName, previousData.lastName)), + and( + eq(table.lastName, previousData.lastName), + lt(table.id, previousData.id) + ) + ), + }); + }); + + test("with primaryCursorDESC and cursorDESC", () => { + expect( + generateCursor( + { primaryCursor: primaryCursorDESC, cursors: [cursorDESC] }, + previousData + ) + ).to.deep.equal({ + orderBy: [desc(table.lastName), desc(table.id)], + where: or( + and(lt(table.lastName, previousData.lastName)), + and( + eq(table.lastName, previousData.lastName), + lt(table.id, previousData.id) + ) + ), + }); + }); + + //----------------- + }); + }); + + describe("with two cursors", () => { + const cursorDefault: Cursor = { + key: "lastName", + schema: table.lastName, + }; + + const cursorASC: Cursor = { + key: "lastName", + order: "ASC", + schema: table.lastName, + }; + + const cursorDESC: Cursor = { + key: "lastName", + order: "DESC", + schema: table.lastName, + }; + + const cursor2Default: Cursor = { + key: "firstName", + schema: table.firstName, + }; + + const cursor2ASC: Cursor = { + key: "firstName", + order: "ASC", + schema: table.firstName, + }; + + const cursor2DESC: Cursor = { + key: "firstName", + order: "DESC", + schema: table.firstName, + }; + + describe("without previous data generates only orderBy and where is undefined", () => { + test("with primaryCursorDefault and cursorDefault and cursor2Default", () => { + expect( + generateCursor({ + primaryCursor: primaryCursorDefault, + cursors: [cursorDefault, cursor2Default], + }) + ).to.deep.equal({ + orderBy: [asc(table.lastName), asc(table.firstName), asc(table.id)], + where: undefined, + }); + }); + + test("with primaryCursorDefault and cursorDefault and cursor2ASC", () => { + expect( + generateCursor({ + primaryCursor: primaryCursorDefault, + cursors: [cursorDefault, cursor2ASC], + }) + ).to.deep.equal({ + orderBy: [asc(table.lastName), asc(table.firstName), asc(table.id)], + where: undefined, + }); + }); + + test("with primaryCursorDefault and cursorDefault and cursor2DESC", () => { + expect( + generateCursor({ + primaryCursor: primaryCursorDefault, + cursors: [cursorDefault, cursor2DESC], + }) + ).to.deep.equal({ + orderBy: [ + asc(table.lastName), + desc(table.firstName), + asc(table.id), + ], + where: undefined, + }); + }); + + test("with primaryCursorDefault and cursorASC and cursor2Default", () => { + expect( + generateCursor({ + primaryCursor: primaryCursorDefault, + cursors: [cursorASC, cursor2Default], + }) + ).to.deep.equal({ + orderBy: [asc(table.lastName), asc(table.firstName), asc(table.id)], + where: undefined, + }); + }); + + test("with primaryCursorDefault and cursorASC and cursor2ASC", () => { + expect( + generateCursor({ + primaryCursor: primaryCursorDefault, + cursors: [cursorASC, cursor2ASC], + }) + ).to.deep.equal({ + orderBy: [asc(table.lastName), asc(table.firstName), asc(table.id)], + where: undefined, + }); + }); + + test("with primaryCursorDefault and cursorASC and cursor2DESC", () => { + expect( + generateCursor({ + primaryCursor: primaryCursorDefault, + cursors: [cursorASC, cursor2DESC], + }) + ).to.deep.equal({ + orderBy: [ + asc(table.lastName), + desc(table.firstName), + asc(table.id), + ], + where: undefined, + }); + }); + + test("with primaryCursorDefault and cursorDESC and cursor2Default", () => { + expect( + generateCursor({ + primaryCursor: primaryCursorDefault, + cursors: [cursorDESC, cursor2Default], + }) + ).to.deep.equal({ + orderBy: [ + desc(table.lastName), + asc(table.firstName), + asc(table.id), + ], + where: undefined, + }); + }); + + test("with primaryCursorDefault and cursorDESC and cursor2ASC", () => { + expect( + generateCursor({ + primaryCursor: primaryCursorDefault, + cursors: [cursorDESC, cursor2ASC], + }) + ).to.deep.equal({ + orderBy: [ + desc(table.lastName), + asc(table.firstName), + asc(table.id), + ], + where: undefined, + }); + }); + + test("with primaryCursorDefault and cursorDESC and cursor2DESC", () => { + expect( + generateCursor({ + primaryCursor: primaryCursorDefault, + cursors: [cursorDESC, cursor2DESC], + }) + ).to.deep.equal({ + orderBy: [ + desc(table.lastName), + desc(table.firstName), + asc(table.id), + ], + where: undefined, + }); + }); + + test("with primaryCursorASC and cursorDefault and cursor2Default", () => { + expect( + generateCursor({ + primaryCursor: primaryCursorASC, + cursors: [cursorDefault, cursor2Default], + }) + ).to.deep.equal({ + orderBy: [asc(table.lastName), asc(table.firstName), asc(table.id)], + where: undefined, + }); + }); + + test("with primaryCursorASC and cursorDefault and cursor2ASC", () => { + expect( + generateCursor({ + primaryCursor: primaryCursorASC, + cursors: [cursorDefault, cursor2ASC], + }) + ).to.deep.equal({ + orderBy: [asc(table.lastName), asc(table.firstName), asc(table.id)], + where: undefined, + }); + }); + + test("with primaryCursorASC and cursorDefault and cursor2DESC", () => { + expect( + generateCursor({ + primaryCursor: primaryCursorASC, + cursors: [cursorDefault, cursor2DESC], + }) + ).to.deep.equal({ + orderBy: [ + asc(table.lastName), + desc(table.firstName), + asc(table.id), + ], + where: undefined, + }); + }); + + test("with primaryCursorASC and cursorASC and cursor2Default", () => { + expect( + generateCursor({ + primaryCursor: primaryCursorASC, + cursors: [cursorASC, cursor2Default], + }) + ).to.deep.equal({ + orderBy: [asc(table.lastName), asc(table.firstName), asc(table.id)], + where: undefined, + }); + }); + + test("with primaryCursorASC and cursorASC and cursor2ASC", () => { + expect( + generateCursor({ + primaryCursor: primaryCursorASC, + cursors: [cursorASC, cursor2ASC], + }) + ).to.deep.equal({ + orderBy: [asc(table.lastName), asc(table.firstName), asc(table.id)], + where: undefined, + }); + }); + + test("with primaryCursorASC and cursorASC and cursor2DESC", () => { + expect( + generateCursor({ + primaryCursor: primaryCursorASC, + cursors: [cursorASC, cursor2DESC], + }) + ).to.deep.equal({ + orderBy: [ + asc(table.lastName), + desc(table.firstName), + asc(table.id), + ], + where: undefined, + }); + }); + + test("with primaryCursorASC and cursorDESC and cursor2Default", () => { + expect( + generateCursor({ + primaryCursor: primaryCursorASC, + cursors: [cursorDESC, cursor2Default], + }) + ).to.deep.equal({ + orderBy: [ + desc(table.lastName), + asc(table.firstName), + asc(table.id), + ], + where: undefined, + }); + }); + + test("with primaryCursorASC and cursorDESC and cursor2ASC", () => { + expect( + generateCursor({ + primaryCursor: primaryCursorASC, + cursors: [cursorDESC, cursor2ASC], + }) + ).to.deep.equal({ + orderBy: [ + desc(table.lastName), + asc(table.firstName), + asc(table.id), + ], + where: undefined, + }); + }); + + test("with primaryCursorASC and cursorDESC and cursor2DESC", () => { + expect( + generateCursor({ + primaryCursor: primaryCursorASC, + cursors: [cursorDESC, cursor2DESC], + }) + ).to.deep.equal({ + orderBy: [ + desc(table.lastName), + desc(table.firstName), + asc(table.id), + ], + where: undefined, + }); + }); + + test("with primaryCursorDESC and cursorDefault and cursor2Default", () => { + expect( + generateCursor({ + primaryCursor: primaryCursorDESC, + cursors: [cursorDefault, cursor2Default], + }) + ).to.deep.equal({ + orderBy: [ + asc(table.lastName), + asc(table.firstName), + desc(table.id), + ], + where: undefined, + }); + }); + + test("with primaryCursorDESC and cursorDefault and cursor2ASC", () => { + expect( + generateCursor({ + primaryCursor: primaryCursorDESC, + cursors: [cursorDefault, cursor2ASC], + }) + ).to.deep.equal({ + orderBy: [ + asc(table.lastName), + asc(table.firstName), + desc(table.id), + ], + where: undefined, + }); + }); + + test("with primaryCursorDESC and cursorDefault and cursor2DESC", () => { + expect( + generateCursor({ + primaryCursor: primaryCursorDESC, + cursors: [cursorDefault, cursor2DESC], + }) + ).to.deep.equal({ + orderBy: [ + asc(table.lastName), + desc(table.firstName), + desc(table.id), + ], + where: undefined, + }); + }); + + test("with primaryCursorDESC and cursorASC and cursor2Default", () => { + expect( + generateCursor({ + primaryCursor: primaryCursorDESC, + cursors: [cursorASC, cursor2Default], + }) + ).to.deep.equal({ + orderBy: [ + asc(table.lastName), + asc(table.firstName), + desc(table.id), + ], + where: undefined, + }); + }); + + test("with primaryCursorDESC and cursorASC and cursor2ASC", () => { + expect( + generateCursor({ + primaryCursor: primaryCursorDESC, + cursors: [cursorASC, cursor2ASC], + }) + ).to.deep.equal({ + orderBy: [ + asc(table.lastName), + asc(table.firstName), + desc(table.id), + ], + where: undefined, + }); + }); + + test("with primaryCursorDESC and cursorASC and cursor2DESC", () => { + expect( + generateCursor({ + primaryCursor: primaryCursorDESC, + cursors: [cursorASC, cursor2DESC], + }) + ).to.deep.equal({ + orderBy: [ + asc(table.lastName), + desc(table.firstName), + desc(table.id), + ], + where: undefined, + }); + }); + + test("with primaryCursorDESC and cursorDESC and cursor2Default", () => { + expect( + generateCursor({ + primaryCursor: primaryCursorDESC, + cursors: [cursorDESC, cursor2Default], + }) + ).to.deep.equal({ + orderBy: [ + desc(table.lastName), + asc(table.firstName), + desc(table.id), + ], + where: undefined, + }); + }); + + test("with primaryCursorDESC and cursorDESC and cursor2ASC", () => { + expect( + generateCursor({ + primaryCursor: primaryCursorDESC, + cursors: [cursorDESC, cursor2ASC], + }) + ).to.deep.equal({ + orderBy: [ + desc(table.lastName), + asc(table.firstName), + desc(table.id), + ], + where: undefined, + }); + }); + + test("with primaryCursorDESC and cursorDESC and cursor2DESC", () => { + expect( + generateCursor({ + primaryCursor: primaryCursorDESC, + cursors: [cursorDESC, cursor2DESC], + }) + ).to.deep.equal({ + orderBy: [ + desc(table.lastName), + desc(table.firstName), + desc(table.id), + ], + where: undefined, + }); + }); + }); + + describe("with previous data generates orderBy and where", () => { + const previousData = { + id: 1, + firstName: "John", + middleName: "Doe", + lastName: "Smith", + phone: "123456789", + email: "johndoe", + }; + + test("with primaryCursorDefault and cursorDefault and cursor2Default", () => { + expect( + generateCursor( + { + primaryCursor: primaryCursorDefault, + cursors: [cursorDefault, cursor2Default], + }, + previousData + ) + ).to.deep.equal({ + orderBy: [asc(table.lastName), asc(table.firstName), asc(table.id)], + where: or( + and(gt(table.lastName, previousData.lastName)), + and( + eq(table.lastName, previousData.lastName), + gt(table.firstName, previousData.firstName) + ), + and( + eq(table.lastName, previousData.lastName), + eq(table.firstName, previousData.firstName), + gt(table.id, previousData.id) + ) + ), + }); + }); + + test("with primaryCursorDefault and cursorDefault and cursor2ASC", () => { + expect( + generateCursor( + { + primaryCursor: primaryCursorDefault, + cursors: [cursorDefault, cursor2ASC], + }, + previousData + ) + ).to.deep.equal({ + orderBy: [asc(table.lastName), asc(table.firstName), asc(table.id)], + where: or( + and(gt(table.lastName, previousData.lastName)), + and( + eq(table.lastName, previousData.lastName), + gt(table.firstName, previousData.firstName) + ), + and( + eq(table.lastName, previousData.lastName), + eq(table.firstName, previousData.firstName), + gt(table.id, previousData.id) + ) + ), + }); + }); + + test("with primaryCursorDefault and cursorDefault and cursor2DESC", () => { + expect( + generateCursor( + { + primaryCursor: primaryCursorDefault, + cursors: [cursorDefault, cursor2DESC], + }, + previousData + ) + ).to.deep.equal({ + orderBy: [ + asc(table.lastName), + desc(table.firstName), + asc(table.id), + ], + where: or( + and(gt(table.lastName, previousData.lastName)), + and( + eq(table.lastName, previousData.lastName), + lt(table.firstName, previousData.firstName) + ), + and( + eq(table.lastName, previousData.lastName), + eq(table.firstName, previousData.firstName), + gt(table.id, previousData.id) + ) + ), + }); + }); + + test("with primaryCursorDefault and cursorASC and cursor2Default", () => { + expect( + generateCursor( + { + primaryCursor: primaryCursorDefault, + cursors: [cursorASC, cursor2Default], + }, + previousData + ) + ).to.deep.equal({ + orderBy: [asc(table.lastName), asc(table.firstName), asc(table.id)], + where: or( + and(gt(table.lastName, previousData.lastName)), + and( + eq(table.lastName, previousData.lastName), + gt(table.firstName, previousData.firstName) + ), + and( + eq(table.lastName, previousData.lastName), + eq(table.firstName, previousData.firstName), + gt(table.id, previousData.id) + ) + ), + }); + }); + + test("with primaryCursorDefault and cursorASC and cursor2ASC", () => { + expect( + generateCursor( + { + primaryCursor: primaryCursorDefault, + cursors: [cursorASC, cursor2ASC], + }, + previousData + ) + ).to.deep.equal({ + orderBy: [asc(table.lastName), asc(table.firstName), asc(table.id)], + where: or( + and(gt(table.lastName, previousData.lastName)), + and( + eq(table.lastName, previousData.lastName), + gt(table.firstName, previousData.firstName) + ), + and( + eq(table.lastName, previousData.lastName), + eq(table.firstName, previousData.firstName), + gt(table.id, previousData.id) + ) + ), + }); + }); + + test("with primaryCursorDefault and cursorASC and cursor2DESC", () => { + expect( + generateCursor( + { + primaryCursor: primaryCursorDefault, + cursors: [cursorASC, cursor2DESC], + }, + previousData + ) + ).to.deep.equal({ + orderBy: [ + asc(table.lastName), + desc(table.firstName), + asc(table.id), + ], + where: or( + and(gt(table.lastName, previousData.lastName)), + and( + eq(table.lastName, previousData.lastName), + lt(table.firstName, previousData.firstName) + ), + and( + eq(table.lastName, previousData.lastName), + eq(table.firstName, previousData.firstName), + gt(table.id, previousData.id) + ) + ), + }); + }); + + test("with primaryCursorDefault and cursorDESC and cursor2Default", () => { + expect( + generateCursor( + { + primaryCursor: primaryCursorDefault, + cursors: [cursorDESC, cursor2Default], + }, + previousData + ) + ).to.deep.equal({ + orderBy: [ + desc(table.lastName), + asc(table.firstName), + asc(table.id), + ], + where: or( + and(lt(table.lastName, previousData.lastName)), + and( + eq(table.lastName, previousData.lastName), + gt(table.firstName, previousData.firstName) + ), + and( + eq(table.lastName, previousData.lastName), + eq(table.firstName, previousData.firstName), + gt(table.id, previousData.id) + ) + ), + }); + }); + + test("with primaryCursorDefault and cursorDESC and cursor2ASC", () => { + expect( + generateCursor( + { + primaryCursor: primaryCursorDefault, + cursors: [cursorDESC, cursor2ASC], + }, + previousData + ) + ).to.deep.equal({ + orderBy: [ + desc(table.lastName), + asc(table.firstName), + asc(table.id), + ], + where: or( + and(lt(table.lastName, previousData.lastName)), + and( + eq(table.lastName, previousData.lastName), + gt(table.firstName, previousData.firstName) + ), + and( + eq(table.lastName, previousData.lastName), + eq(table.firstName, previousData.firstName), + gt(table.id, previousData.id) + ) + ), + }); + }); + + test("with primaryCursorDefault and cursorDESC and cursor2DESC", () => { + expect( + generateCursor( + { + primaryCursor: primaryCursorDefault, + cursors: [cursorDESC, cursor2DESC], + }, + previousData + ) + ).to.deep.equal({ + orderBy: [ + desc(table.lastName), + desc(table.firstName), + asc(table.id), + ], + where: or( + and(lt(table.lastName, previousData.lastName)), + and( + eq(table.lastName, previousData.lastName), + lt(table.firstName, previousData.firstName) + ), + and( + eq(table.lastName, previousData.lastName), + eq(table.firstName, previousData.firstName), + gt(table.id, previousData.id) + ) + ), + }); + }); + + test("with primaryCursorASC and cursorDefault and cursor2Default", () => { + expect( + generateCursor( + { + primaryCursor: primaryCursorASC, + cursors: [cursorDefault, cursor2Default], + }, + previousData + ) + ).to.deep.equal({ + orderBy: [asc(table.lastName), asc(table.firstName), asc(table.id)], + where: or( + and(gt(table.lastName, previousData.lastName)), + and( + eq(table.lastName, previousData.lastName), + gt(table.firstName, previousData.firstName) + ), + and( + eq(table.lastName, previousData.lastName), + eq(table.firstName, previousData.firstName), + gt(table.id, previousData.id) + ) + ), + }); + }); + + test("with primaryCursorASC and cursorDefault and cursor2ASC", () => { + expect( + generateCursor( + { + primaryCursor: primaryCursorASC, + cursors: [cursorDefault, cursor2ASC], + }, + previousData + ) + ).to.deep.equal({ + orderBy: [asc(table.lastName), asc(table.firstName), asc(table.id)], + where: or( + and(gt(table.lastName, previousData.lastName)), + and( + eq(table.lastName, previousData.lastName), + gt(table.firstName, previousData.firstName) + ), + and( + eq(table.lastName, previousData.lastName), + eq(table.firstName, previousData.firstName), + gt(table.id, previousData.id) + ) + ), + }); + }); + + test("with primaryCursorASC and cursorDefault and cursor2DESC", () => { + expect( + generateCursor( + { + primaryCursor: primaryCursorASC, + cursors: [cursorDefault, cursor2DESC], + }, + previousData + ) + ).to.deep.equal({ + orderBy: [ + asc(table.lastName), + desc(table.firstName), + asc(table.id), + ], + where: or( + and(gt(table.lastName, previousData.lastName)), + and( + eq(table.lastName, previousData.lastName), + lt(table.firstName, previousData.firstName) + ), + and( + eq(table.lastName, previousData.lastName), + eq(table.firstName, previousData.firstName), + gt(table.id, previousData.id) + ) + ), + }); + }); + + test("with primaryCursorASC and cursorASC and cursor2Default", () => { + expect( + generateCursor( + { + primaryCursor: primaryCursorASC, + cursors: [cursorASC, cursor2Default], + }, + previousData + ) + ).to.deep.equal({ + orderBy: [asc(table.lastName), asc(table.firstName), asc(table.id)], + where: or( + and(gt(table.lastName, previousData.lastName)), + and( + eq(table.lastName, previousData.lastName), + gt(table.firstName, previousData.firstName) + ), + and( + eq(table.lastName, previousData.lastName), + eq(table.firstName, previousData.firstName), + gt(table.id, previousData.id) + ) + ), + }); + }); + + test("with primaryCursorASC and cursorASC and cursor2ASC", () => { + expect( + generateCursor( + { + primaryCursor: primaryCursorASC, + cursors: [cursorASC, cursor2ASC], + }, + previousData + ) + ).to.deep.equal({ + orderBy: [asc(table.lastName), asc(table.firstName), asc(table.id)], + where: or( + and(gt(table.lastName, previousData.lastName)), + and( + eq(table.lastName, previousData.lastName), + gt(table.firstName, previousData.firstName) + ), + and( + eq(table.lastName, previousData.lastName), + eq(table.firstName, previousData.firstName), + gt(table.id, previousData.id) + ) + ), + }); + }); + + test("with primaryCursorASC and cursorASC and cursor2DESC", () => { + expect( + generateCursor( + { + primaryCursor: primaryCursorASC, + cursors: [cursorASC, cursor2DESC], + }, + previousData + ) + ).to.deep.equal({ + orderBy: [ + asc(table.lastName), + desc(table.firstName), + asc(table.id), + ], + where: or( + and(gt(table.lastName, previousData.lastName)), + and( + eq(table.lastName, previousData.lastName), + lt(table.firstName, previousData.firstName) + ), + and( + eq(table.lastName, previousData.lastName), + eq(table.firstName, previousData.firstName), + gt(table.id, previousData.id) + ) + ), + }); + }); + + test("with primaryCursorASC and cursorDESC and cursor2Default", () => { + expect( + generateCursor( + { + primaryCursor: primaryCursorASC, + cursors: [cursorDESC, cursor2Default], + }, + previousData + ) + ).to.deep.equal({ + orderBy: [ + desc(table.lastName), + asc(table.firstName), + asc(table.id), + ], + where: or( + and(lt(table.lastName, previousData.lastName)), + and( + eq(table.lastName, previousData.lastName), + gt(table.firstName, previousData.firstName) + ), + and( + eq(table.lastName, previousData.lastName), + eq(table.firstName, previousData.firstName), + gt(table.id, previousData.id) + ) + ), + }); + }); + + test("with primaryCursorASC and cursorDESC and cursor2ASC", () => { + expect( + generateCursor( + { + primaryCursor: primaryCursorASC, + cursors: [cursorDESC, cursor2ASC], + }, + previousData + ) + ).to.deep.equal({ + orderBy: [ + desc(table.lastName), + asc(table.firstName), + asc(table.id), + ], + where: or( + and(lt(table.lastName, previousData.lastName)), + and( + eq(table.lastName, previousData.lastName), + gt(table.firstName, previousData.firstName) + ), + and( + eq(table.lastName, previousData.lastName), + eq(table.firstName, previousData.firstName), + gt(table.id, previousData.id) + ) + ), + }); + }); + + test("with primaryCursorASC and cursorDESC and cursor2DESC", () => { + expect( + generateCursor( + { + primaryCursor: primaryCursorASC, + cursors: [cursorDESC, cursor2DESC], + }, + previousData + ) + ).to.deep.equal({ + orderBy: [ + desc(table.lastName), + desc(table.firstName), + asc(table.id), + ], + where: or( + and(lt(table.lastName, previousData.lastName)), + and( + eq(table.lastName, previousData.lastName), + lt(table.firstName, previousData.firstName) + ), + and( + eq(table.lastName, previousData.lastName), + eq(table.firstName, previousData.firstName), + gt(table.id, previousData.id) + ) + ), + }); + }); + + test("with primaryCursorDESC and cursorDefault and cursor2Default", () => { + expect( + generateCursor( + { + primaryCursor: primaryCursorDESC, + cursors: [cursorDefault, cursor2Default], + }, + previousData + ) + ).to.deep.equal({ + orderBy: [ + asc(table.lastName), + asc(table.firstName), + desc(table.id), + ], + where: or( + and(gt(table.lastName, previousData.lastName)), + and( + eq(table.lastName, previousData.lastName), + gt(table.firstName, previousData.firstName) + ), + and( + eq(table.lastName, previousData.lastName), + eq(table.firstName, previousData.firstName), + lt(table.id, previousData.id) + ) + ), + }); + }); + + test("with primaryCursorDESC and cursorDefault and cursor2ASC", () => { + expect( + generateCursor( + { + primaryCursor: primaryCursorDESC, + cursors: [cursorDefault, cursor2ASC], + }, + previousData + ) + ).to.deep.equal({ + orderBy: [ + asc(table.lastName), + asc(table.firstName), + desc(table.id), + ], + where: or( + and(gt(table.lastName, previousData.lastName)), + and( + eq(table.lastName, previousData.lastName), + gt(table.firstName, previousData.firstName) + ), + and( + eq(table.lastName, previousData.lastName), + eq(table.firstName, previousData.firstName), + lt(table.id, previousData.id) + ) + ), + }); + }); + + test("with primaryCursorDESC and cursorDefault and cursor2DESC", () => { + expect( + generateCursor( + { + primaryCursor: primaryCursorDESC, + cursors: [cursorDefault, cursor2DESC], + }, + previousData + ) + ).to.deep.equal({ + orderBy: [ + asc(table.lastName), + desc(table.firstName), + desc(table.id), + ], + where: or( + and(gt(table.lastName, previousData.lastName)), + and( + eq(table.lastName, previousData.lastName), + lt(table.firstName, previousData.firstName) + ), + and( + eq(table.lastName, previousData.lastName), + eq(table.firstName, previousData.firstName), + lt(table.id, previousData.id) + ) + ), + }); + }); + + test("with primaryCursorDESC and cursorASC and cursor2Default", () => { + expect( + generateCursor( + { + primaryCursor: primaryCursorDESC, + cursors: [cursorASC, cursor2Default], + }, + previousData + ) + ).to.deep.equal({ + orderBy: [ + asc(table.lastName), + asc(table.firstName), + desc(table.id), + ], + where: or( + and(gt(table.lastName, previousData.lastName)), + and( + eq(table.lastName, previousData.lastName), + gt(table.firstName, previousData.firstName) + ), + and( + eq(table.lastName, previousData.lastName), + eq(table.firstName, previousData.firstName), + lt(table.id, previousData.id) + ) + ), + }); + }); + + test("with primaryCursorDESC and cursorASC and cursor2ASC", () => { + expect( + generateCursor( + { + primaryCursor: primaryCursorDESC, + cursors: [cursorASC, cursor2ASC], + }, + previousData + ) + ).to.deep.equal({ + orderBy: [ + asc(table.lastName), + asc(table.firstName), + desc(table.id), + ], + where: or( + and(gt(table.lastName, previousData.lastName)), + and( + eq(table.lastName, previousData.lastName), + gt(table.firstName, previousData.firstName) + ), + and( + eq(table.lastName, previousData.lastName), + eq(table.firstName, previousData.firstName), + lt(table.id, previousData.id) + ) + ), + }); + }); + + test("with primaryCursorDESC and cursorASC and cursor2DESC", () => { + expect( + generateCursor( + { + primaryCursor: primaryCursorDESC, + cursors: [cursorASC, cursor2DESC], + }, + previousData + ) + ).to.deep.equal({ + orderBy: [ + asc(table.lastName), + desc(table.firstName), + desc(table.id), + ], + where: or( + and(gt(table.lastName, previousData.lastName)), + and( + eq(table.lastName, previousData.lastName), + lt(table.firstName, previousData.firstName) + ), + and( + eq(table.lastName, previousData.lastName), + eq(table.firstName, previousData.firstName), + lt(table.id, previousData.id) + ) + ), + }); + }); + + test("with primaryCursorDESC and cursorDESC and cursor2Default", () => { + expect( + generateCursor( + { + primaryCursor: primaryCursorDESC, + cursors: [cursorDESC, cursor2Default], + }, + previousData + ) + ).to.deep.equal({ + orderBy: [ + desc(table.lastName), + asc(table.firstName), + desc(table.id), + ], + where: or( + and(lt(table.lastName, previousData.lastName)), + and( + eq(table.lastName, previousData.lastName), + gt(table.firstName, previousData.firstName) + ), + and( + eq(table.lastName, previousData.lastName), + eq(table.firstName, previousData.firstName), + lt(table.id, previousData.id) + ) + ), + }); + }); + + test("with primaryCursorDESC and cursorDESC and cursor2ASC", () => { + expect( + generateCursor( + { + primaryCursor: primaryCursorDESC, + cursors: [cursorDESC, cursor2ASC], + }, + previousData + ) + ).to.deep.equal({ + orderBy: [ + desc(table.lastName), + asc(table.firstName), + desc(table.id), + ], + where: or( + and(lt(table.lastName, previousData.lastName)), + and( + eq(table.lastName, previousData.lastName), + gt(table.firstName, previousData.firstName) + ), + and( + eq(table.lastName, previousData.lastName), + eq(table.firstName, previousData.firstName), + lt(table.id, previousData.id) + ) + ), + }); + }); + + test("with primaryCursorDESC and cursorDESC and cursor2DESC", () => { + expect( + generateCursor( + { + primaryCursor: primaryCursorDESC, + cursors: [cursorDESC, cursor2DESC], + }, + previousData + ) + ).to.deep.equal({ + orderBy: [ + desc(table.lastName), + desc(table.firstName), + desc(table.id), + ], + where: or( + and(lt(table.lastName, previousData.lastName)), + and( + eq(table.lastName, previousData.lastName), + lt(table.firstName, previousData.firstName) + ), + and( + eq(table.lastName, previousData.lastName), + eq(table.firstName, previousData.firstName), + lt(table.id, previousData.id) + ) + ), + }); + }); + }); + }); + + describe("with multiple cursors", () => { + test("with three cursors and no previous data", () => { + expect( + generateCursor({ + primaryCursor: { key: "id", schema: table.id, order: "DESC" }, + cursors: [ + { key: "firstName", schema: table.firstName }, + { key: "lastName", schema: table.lastName, order: "DESC" }, + { key: "middleName", schema: table.middleName }, + ], + }) + ).to.deep.equal({ + orderBy: [ + asc(table.firstName), + desc(table.lastName), + asc(table.middleName), + desc(table.id), + ], + where: undefined, + }); + }); + + test("with three cursors and previous data", () => { + expect( + generateCursor( + { + cursors: [ + { key: "firstName", schema: table.firstName, order: "DESC" }, + { key: "lastName", schema: table.lastName }, + { key: "middleName", schema: table.middleName, order: "DESC" }, + ], + primaryCursor: { key: "id", schema: table.id, order: "ASC" }, + }, + { + id: 1, + firstName: "John", + middleName: "Doe", + lastName: "Smith", + phone: "123456789", + email: "johndoe", + } + ) + ).to.deep.equal({ + orderBy: [ + desc(table.firstName), + asc(table.lastName), + desc(table.middleName), + asc(table.id), + ], + where: or( + and(lt(table.firstName, "John")), + and(eq(table.firstName, "John"), gt(table.lastName, "Smith")), + and( + eq(table.firstName, "John"), + eq(table.lastName, "Smith"), + lt(table.middleName, "Doe") + ), + and( + eq(table.firstName, "John"), + eq(table.lastName, "Smith"), + eq(table.middleName, "Doe"), + gt(table.id, 1) + ) + ), + }); + }); + }); + }); +}); diff --git a/test/utils.test.ts b/test/utils.test.ts new file mode 100644 index 0000000..767bd69 --- /dev/null +++ b/test/utils.test.ts @@ -0,0 +1,36 @@ +import { describe, expect, test } from "vitest"; + +import { generateSubArrays } from "../src/utils"; + +describe("generateSubArrays", () => { + test("empty array generates empty", () => { + expect(generateSubArrays([])).to.have.length(0); + }); + test("single element generates array of array with one element", () => { + expect(generateSubArrays([1])).to.have.length(1); + expect(generateSubArrays([1])).to.deep.equal([[1]]); + }); + test("two elements generates array of array with two elements", () => { + expect(generateSubArrays([1, 2])).to.have.length(2); + expect(generateSubArrays([1, 2])).to.deep.equal([[1], [1, 2]]); + }); + test("three elements generates array of array with three elements", () => { + expect(generateSubArrays([1, 2, 3])).to.have.length(3); + expect(generateSubArrays([1, 2, 3])).to.deep.equal([ + [1], + [1, 2], + [1, 2, 3], + ]); + }); + test("works also with complex objects", () => { + const obj1 = { a: 1 }; + const obj2 = { b: 2 }; + const obj3 = { c: 3 }; + expect(generateSubArrays([obj1, obj2, obj3])).to.have.length(3); + expect(generateSubArrays([obj1, obj2, obj3])).to.deep.equal([ + [obj1], + [obj1, obj2], + [obj1, obj2, obj3], + ]); + }); +});