From 0c3c48f8fb300e562abc52e8f9a3b21dda5cb4be Mon Sep 17 00:00:00 2001 From: josh Date: Mon, 12 Feb 2024 10:51:01 +0100 Subject: [PATCH 1/2] test: add definition tests for metadata commands --- src/commands/client/fetch/index.test-d.ts | 47 ++++++++++++++++++++ src/commands/client/query/index.test-d.ts | 47 ++++++++++++++++++++ src/commands/client/range/index.test-d.ts | 49 +++++++++++++++++++++ src/commands/client/upsert/index.test-d.ts | 51 ++++++++++++++++++++++ src/commands/client/utils.test-d.ts | 19 ++++++++ 5 files changed, 213 insertions(+) create mode 100644 src/commands/client/fetch/index.test-d.ts create mode 100644 src/commands/client/query/index.test-d.ts create mode 100644 src/commands/client/range/index.test-d.ts create mode 100644 src/commands/client/upsert/index.test-d.ts create mode 100644 src/commands/client/utils.test-d.ts diff --git a/src/commands/client/fetch/index.test-d.ts b/src/commands/client/fetch/index.test-d.ts new file mode 100644 index 0000000..4a887cd --- /dev/null +++ b/src/commands/client/fetch/index.test-d.ts @@ -0,0 +1,47 @@ +import { Index } from "../../../../index"; +import { TypeEqual, expectType, test } from "../utils.test-d"; + +type Metadata = { genre: string; year: number }; + +test("case 1: no metadata is provided, any object should be expected", () => { + const index = new Index(); + + type RetrievedFetchVector = Awaited>[number]; + + type RetrievedMetadata = NonNullable["metadata"]>; + + expectType>>(true); +}); + +test("case 2: index-level metadata is provided, index-level metadata should be expected", () => { + const index = new Index(); + + type RetrievedFetchVector = Awaited>>[number]; + + type RetrievedMetadata = NonNullable["metadata"]>; + + expectType>(true); +}); + +test("case 3: index-level and command-level metadata are provided, command-level metadata should be expected", () => { + const index = new Index(); + + type OverrideMetadata = { director: string }; + + type RetrievedFetchVector = Awaited>>[number]; + + type RetrievedMetadata = NonNullable["metadata"]>; + + expectType>(false); + expectType>(true); +}); + +test("case 4: command-level metadata is provided, command-level metadata should be expected", () => { + const index = new Index(); + + type RetrievedFetchVector = Awaited>>[number]; + + type RetrievedMetadata = NonNullable["metadata"]>; + + expectType>(true); +}); diff --git a/src/commands/client/query/index.test-d.ts b/src/commands/client/query/index.test-d.ts new file mode 100644 index 0000000..6b78bea --- /dev/null +++ b/src/commands/client/query/index.test-d.ts @@ -0,0 +1,47 @@ +import { Index } from "../../../../index"; +import { TypeEqual, expectType, test } from "../utils.test-d"; + +type Metadata = { genre: string; year: number }; + +test("case 1: no metadata is provided, any object should be expected", () => { + const index = new Index(); + + type RetrievedQueryVector = Awaited>[number]; + + type RetrievedMetadata = NonNullable["metadata"]>; + + expectType>>(true); +}); + +test("case 2: index-level metadata is provided, index-level metadata should be expected", () => { + const index = new Index(); + + type RetrievedQueryVector = Awaited>>[number]; + + type RetrievedMetadata = NonNullable["metadata"]>; + + expectType>(true); +}); + +test("case 3: index-level and command-level metadata are provided, command-level metadata should be expected", () => { + const index = new Index(); + + type OverrideMetadata = { director: string }; + + type RetrievedQueryVector = Awaited>>[number]; + + type RetrievedMetadata = NonNullable["metadata"]>; + + expectType>(false); + expectType>(true); +}); + +test("case 4: command-level metadata is provided, command-level metadata should be expected", () => { + const index = new Index(); + + type RetrievedQueryVector = Awaited>>[number]; + + type RetrievedMetadata = NonNullable["metadata"]>; + + expectType>(true); +}); diff --git a/src/commands/client/range/index.test-d.ts b/src/commands/client/range/index.test-d.ts new file mode 100644 index 0000000..99aa26d --- /dev/null +++ b/src/commands/client/range/index.test-d.ts @@ -0,0 +1,49 @@ +import { Index } from "../../../../index"; +import { TypeEqual, expectType, test } from "../utils.test-d"; + +type Metadata = { genre: string; year: number }; + +test("case 1: no metadata is provided, any object should be expected", () => { + const index = new Index(); + + type RetrievedRangeVector = Awaited>["vectors"][number]; + + type RetrievedMetadata = NonNullable["metadata"]>; + + expectType>>(true); +}); + +test("case 2: index-level metadata is provided, index-level metadata should be expected", () => { + const index = new Index(); + + type RetrievedRangeVector = Awaited>>["vectors"][number]; + + type RetrievedMetadata = NonNullable["metadata"]>; + + expectType>(true); +}); + +test("case 3: index-level and command-level metadata are provided, command-level metadata should be expected", () => { + const index = new Index(); + + type OverrideMetadata = { director: string }; + + type RetrievedRangeVector = Awaited< + ReturnType> + >["vectors"][number]; + + type RetrievedMetadata = NonNullable["metadata"]>; + + expectType>(false); + expectType>(true); +}); + +test("case 4: command-level metadata is provided, command-level metadata should be expected", () => { + const index = new Index(); + + type RetrievedRangeVector = Awaited>>["vectors"][number]; + + type RetrievedMetadata = NonNullable["metadata"]>; + + expectType>(true); +}); diff --git a/src/commands/client/upsert/index.test-d.ts b/src/commands/client/upsert/index.test-d.ts new file mode 100644 index 0000000..8d64698 --- /dev/null +++ b/src/commands/client/upsert/index.test-d.ts @@ -0,0 +1,51 @@ +import { Index } from "../../../../index"; +import { NonArrayType, TypeEqual, expectType, test } from "../utils.test-d"; + +type Metadata = { genre: string; year: number }; + +test("case 1: no metadata is provided, any object should be expected", () => { + const index = new Index(); + + // ideally we would not have to pass the same generic again but infer from the index signature + type ExpectedParameters = Parameters["0"]; + type ExpectedMetadata = NonNullable["metadata"]>; + + expectType>>(true); +}); + +test("case 2: index-level metadata is provided, index-level metadata should be expected", () => { + const index = new Index(); + + // ideally we would not have to pass the same generic again but infer from the index signature instead + type ExpectedParameters = Parameters>["0"]; + type ExpectedMetadata = NonNullable["metadata"]>; + + expectType>(true); +}); + +test("case 3: index-level metadata is provided and command-level metadata is provided, command-level metadata should be expected", () => { + const index = new Index(); + + type InitialParameters = Parameters["0"]; + type InitialMetadata = NonNullable>["metadata"]>; + + type OverrideMetadata = { director: string }; + + type ExpectedParameters = Parameters>["0"]; + type ExpectedMetadata = NonNullable>["metadata"]>; + + expectType>(false); + expectType>(true); +}); + +test("case 4: command-level metadata is provided, command-level metadata should be expected", () => { + const index = new Index(); + + type CommandLevelMetadata = { director: string }; + + type ExpectedParameters = Parameters>["0"]; + + type ExpectedMetadata = NonNullable>["metadata"]>; + + expectType>(true); +}); diff --git a/src/commands/client/utils.test-d.ts b/src/commands/client/utils.test-d.ts new file mode 100644 index 0000000..8a66698 --- /dev/null +++ b/src/commands/client/utils.test-d.ts @@ -0,0 +1,19 @@ +export const expectType = (_: T) => { + // Do nothing, the TypeScript compiler handles this for us +}; + +export type TypeEqual = (() => T extends Target ? 1 : 2) extends < + T, +>() => T extends Value ? 1 : 2 + ? true + : false; + +export type NonArrayType = T extends Array ? U : T; + +export type NonNullable = T extends null | undefined ? never : T; + +/** + * because typescript is removed at build-time, this function's sole purpose + * is to avoid namespace collisions in the definition test files. + */ +export function test(_: string, __: () => void) {} From 464325ebe7a9866a5617d51ebf6682fe0025fa49 Mon Sep 17 00:00:00 2001 From: josh Date: Tue, 13 Feb 2024 08:08:51 +0100 Subject: [PATCH 2/2] test: implement vitest and attach typechecks to test script --- bun.lockb | Bin 117397 -> 138399 bytes package.json | 53 +++++++++++---------- src/commands/client/fetch/index.test-d.ts | 11 ++--- src/commands/client/query/index.test-d.ts | 11 ++--- src/commands/client/range/index.test-d.ts | 11 ++--- src/commands/client/upsert/index.test-d.ts | 19 +++----- src/commands/client/utils.test-d.ts | 19 -------- src/utils/test-utils.ts | 2 + vitest.config.ts | 11 +++++ 9 files changed, 62 insertions(+), 75 deletions(-) delete mode 100644 src/commands/client/utils.test-d.ts create mode 100644 vitest.config.ts diff --git a/bun.lockb b/bun.lockb index d07f4971f6d6208cc265447791d7742b8bd04858..39fea15b67885026f304f1de01d3966eacaa7a3f 100755 GIT binary patch delta 34322 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", + "repository": { + "type": "git", + "url": "https://github.com/upstash/vector-js" + }, + "main": "./dist/index.js", + "module": "./dist/index.mjs", + "devDependencies": { + "@biomejs/biome": "^1.4.1", + "@commitlint/cli": "^18.6.0", + "@commitlint/config-conventional": "^18.6.0", + "bun-types": "latest", + "husky": "^8.0.3", + "tsup": "latest", + "typescript": "^5.0.0", + "vitest": "^1.2.2" + }, + "bugs": { + "url": "https://github.com/upstash/vector/issues" + }, + "description": "An HTTP/REST based Vector DB client built on top of Upstash REST API.", + "files": [ + "dist" + ], + "homepage": "https://upstash.com/vector", "keywords": [ "vector", "upstash", "db" ], - "author": "Oguzhan Olguncu ", "license": "MIT", - "files": [ - "dist" - ], - "bugs": { - "url": "https://github.com/upstash/vector/issues" - }, "scripts": { - "test": "bun test src --coverage --bail --coverageSkipTestFiles=[test-utils.ts]", + "test": "bun test src --coverage --bail --coverageSkipTestFiles=[test-utils.ts] && vitest run --typecheck", "fmt": "bunx biome check --apply ./src", "build": "tsup", "prepare": "husky install" }, - "devDependencies": { - "typescript": "^5.0.0", - "@biomejs/biome": "^1.4.1", - "@commitlint/cli": "^18.6.0", - "@commitlint/config-conventional": "^18.6.0", - "bun-types": "latest", - "husky": "^8.0.3", - "tsup": "latest" - }, - "repository": { - "type": "git", - "url": "https://github.com/upstash/vector-js" - }, - "homepage": "https://upstash.com/vector" + "types": "./dist/index.d.ts" } diff --git a/src/commands/client/fetch/index.test-d.ts b/src/commands/client/fetch/index.test-d.ts index 4a887cd..452727a 100644 --- a/src/commands/client/fetch/index.test-d.ts +++ b/src/commands/client/fetch/index.test-d.ts @@ -1,5 +1,5 @@ +import { expectTypeOf, test } from "vitest"; import { Index } from "../../../../index"; -import { TypeEqual, expectType, test } from "../utils.test-d"; type Metadata = { genre: string; year: number }; @@ -10,7 +10,7 @@ test("case 1: no metadata is provided, any object should be expected", () => { type RetrievedMetadata = NonNullable["metadata"]>; - expectType>>(true); + expectTypeOf().toEqualTypeOf>(); }); test("case 2: index-level metadata is provided, index-level metadata should be expected", () => { @@ -20,7 +20,7 @@ test("case 2: index-level metadata is provided, index-level metadata should be e type RetrievedMetadata = NonNullable["metadata"]>; - expectType>(true); + expectTypeOf().toEqualTypeOf(); }); test("case 3: index-level and command-level metadata are provided, command-level metadata should be expected", () => { @@ -32,8 +32,7 @@ test("case 3: index-level and command-level metadata are provided, command-level type RetrievedMetadata = NonNullable["metadata"]>; - expectType>(false); - expectType>(true); + expectTypeOf().toEqualTypeOf(); }); test("case 4: command-level metadata is provided, command-level metadata should be expected", () => { @@ -43,5 +42,5 @@ test("case 4: command-level metadata is provided, command-level metadata should type RetrievedMetadata = NonNullable["metadata"]>; - expectType>(true); + expectTypeOf().toEqualTypeOf(); }); diff --git a/src/commands/client/query/index.test-d.ts b/src/commands/client/query/index.test-d.ts index 6b78bea..44a9ae0 100644 --- a/src/commands/client/query/index.test-d.ts +++ b/src/commands/client/query/index.test-d.ts @@ -1,5 +1,5 @@ +import { expectTypeOf, test } from "vitest"; import { Index } from "../../../../index"; -import { TypeEqual, expectType, test } from "../utils.test-d"; type Metadata = { genre: string; year: number }; @@ -10,7 +10,7 @@ test("case 1: no metadata is provided, any object should be expected", () => { type RetrievedMetadata = NonNullable["metadata"]>; - expectType>>(true); + expectTypeOf().toEqualTypeOf>(); }); test("case 2: index-level metadata is provided, index-level metadata should be expected", () => { @@ -20,7 +20,7 @@ test("case 2: index-level metadata is provided, index-level metadata should be e type RetrievedMetadata = NonNullable["metadata"]>; - expectType>(true); + expectTypeOf().toEqualTypeOf(); }); test("case 3: index-level and command-level metadata are provided, command-level metadata should be expected", () => { @@ -32,8 +32,7 @@ test("case 3: index-level and command-level metadata are provided, command-level type RetrievedMetadata = NonNullable["metadata"]>; - expectType>(false); - expectType>(true); + expectTypeOf().toEqualTypeOf(); }); test("case 4: command-level metadata is provided, command-level metadata should be expected", () => { @@ -43,5 +42,5 @@ test("case 4: command-level metadata is provided, command-level metadata should type RetrievedMetadata = NonNullable["metadata"]>; - expectType>(true); + expectTypeOf().toEqualTypeOf(); }); diff --git a/src/commands/client/range/index.test-d.ts b/src/commands/client/range/index.test-d.ts index 99aa26d..f401c28 100644 --- a/src/commands/client/range/index.test-d.ts +++ b/src/commands/client/range/index.test-d.ts @@ -1,5 +1,5 @@ +import { expectTypeOf, test } from "vitest"; import { Index } from "../../../../index"; -import { TypeEqual, expectType, test } from "../utils.test-d"; type Metadata = { genre: string; year: number }; @@ -10,7 +10,7 @@ test("case 1: no metadata is provided, any object should be expected", () => { type RetrievedMetadata = NonNullable["metadata"]>; - expectType>>(true); + expectTypeOf().toEqualTypeOf>(); }); test("case 2: index-level metadata is provided, index-level metadata should be expected", () => { @@ -20,7 +20,7 @@ test("case 2: index-level metadata is provided, index-level metadata should be e type RetrievedMetadata = NonNullable["metadata"]>; - expectType>(true); + expectTypeOf().toEqualTypeOf(); }); test("case 3: index-level and command-level metadata are provided, command-level metadata should be expected", () => { @@ -34,8 +34,7 @@ test("case 3: index-level and command-level metadata are provided, command-level type RetrievedMetadata = NonNullable["metadata"]>; - expectType>(false); - expectType>(true); + expectTypeOf().toEqualTypeOf(); }); test("case 4: command-level metadata is provided, command-level metadata should be expected", () => { @@ -45,5 +44,5 @@ test("case 4: command-level metadata is provided, command-level metadata should type RetrievedMetadata = NonNullable["metadata"]>; - expectType>(true); + expectTypeOf().toEqualTypeOf(); }); diff --git a/src/commands/client/upsert/index.test-d.ts b/src/commands/client/upsert/index.test-d.ts index 8d64698..e8ced27 100644 --- a/src/commands/client/upsert/index.test-d.ts +++ b/src/commands/client/upsert/index.test-d.ts @@ -1,5 +1,6 @@ +import { NonArrayType } from "@utils/test-utils"; +import { expectTypeOf, test } from "vitest"; import { Index } from "../../../../index"; -import { NonArrayType, TypeEqual, expectType, test } from "../utils.test-d"; type Metadata = { genre: string; year: number }; @@ -10,7 +11,7 @@ test("case 1: no metadata is provided, any object should be expected", () => { type ExpectedParameters = Parameters["0"]; type ExpectedMetadata = NonNullable["metadata"]>; - expectType>>(true); + expectTypeOf().toEqualTypeOf>(); }); test("case 2: index-level metadata is provided, index-level metadata should be expected", () => { @@ -20,32 +21,26 @@ test("case 2: index-level metadata is provided, index-level metadata should be e type ExpectedParameters = Parameters>["0"]; type ExpectedMetadata = NonNullable["metadata"]>; - expectType>(true); + expectTypeOf().toEqualTypeOf(); }); test("case 3: index-level metadata is provided and command-level metadata is provided, command-level metadata should be expected", () => { const index = new Index(); - type InitialParameters = Parameters["0"]; - type InitialMetadata = NonNullable>["metadata"]>; - type OverrideMetadata = { director: string }; type ExpectedParameters = Parameters>["0"]; type ExpectedMetadata = NonNullable>["metadata"]>; - expectType>(false); - expectType>(true); + expectTypeOf().toEqualTypeOf(); }); test("case 4: command-level metadata is provided, command-level metadata should be expected", () => { const index = new Index(); - type CommandLevelMetadata = { director: string }; - - type ExpectedParameters = Parameters>["0"]; + type ExpectedParameters = Parameters>["0"]; type ExpectedMetadata = NonNullable>["metadata"]>; - expectType>(true); + expectTypeOf().toEqualTypeOf(); }); diff --git a/src/commands/client/utils.test-d.ts b/src/commands/client/utils.test-d.ts deleted file mode 100644 index 8a66698..0000000 --- a/src/commands/client/utils.test-d.ts +++ /dev/null @@ -1,19 +0,0 @@ -export const expectType = (_: T) => { - // Do nothing, the TypeScript compiler handles this for us -}; - -export type TypeEqual = (() => T extends Target ? 1 : 2) extends < - T, ->() => T extends Value ? 1 : 2 - ? true - : false; - -export type NonArrayType = T extends Array ? U : T; - -export type NonNullable = T extends null | undefined ? never : T; - -/** - * because typescript is removed at build-time, this function's sole purpose - * is to avoid namespace collisions in the definition test files. - */ -export function test(_: string, __: () => void) {} diff --git a/src/utils/test-utils.ts b/src/utils/test-utils.ts index f935c91..9f8ea63 100644 --- a/src/utils/test-utils.ts +++ b/src/utils/test-utils.ts @@ -1,6 +1,8 @@ import { ResetCommand } from "../commands/client/reset"; import { HttpClient, RetryConfig } from "../http"; +export type NonArrayType = T extends Array ? U : T; + export const newHttpClient = (retry?: RetryConfig | undefined) => { const url = process.env.UPSTASH_VECTOR_REST_URL; if (!url) { diff --git a/vitest.config.ts b/vitest.config.ts new file mode 100644 index 0000000..ebfcd25 --- /dev/null +++ b/vitest.config.ts @@ -0,0 +1,11 @@ +/// +import { defineConfig } from "vite" + +export default defineConfig({ + test: { + typecheck: { + include: ["**/*.test-d.ts"], + only: true, + }, + }, +})