Skip to content

Commit

Permalink
Merge pull request #10 from upstash/dx-661-add-ts-definition-tests
Browse files Browse the repository at this point in the history
test: add definition tests for metadata commands
  • Loading branch information
joschan21 authored Feb 13, 2024
2 parents 2bb5703 + 464325e commit c565ead
Show file tree
Hide file tree
Showing 8 changed files with 226 additions and 26 deletions.
Binary file modified bun.lockb
Binary file not shown.
53 changes: 27 additions & 26 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,41 +1,42 @@
{
"name": "@upstash/vector",
"description": "An HTTP/REST based Vector DB client built on top of Upstash REST API.",
"module": "./dist/index.mjs",
"main": "./dist/index.js",
"types": "./dist/index.d.ts",
"version": "v0.1.0-alpha-9",
"author": "Oguzhan Olguncu <oguzhan@upstash.com>",
"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 <oguzhan@upstash.com>",
"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"
}
46 changes: 46 additions & 0 deletions src/commands/client/fetch/index.test-d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import { expectTypeOf, test } from "vitest";
import { Index } from "../../../../index";

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<ReturnType<typeof index.fetch>>[number];

type RetrievedMetadata = NonNullable<NonNullable<RetrievedFetchVector>["metadata"]>;

expectTypeOf<RetrievedMetadata>().toEqualTypeOf<Record<string, unknown>>();
});

test("case 2: index-level metadata is provided, index-level metadata should be expected", () => {
const index = new Index<Metadata>();

type RetrievedFetchVector = Awaited<ReturnType<typeof index.fetch<Metadata>>>[number];

type RetrievedMetadata = NonNullable<NonNullable<RetrievedFetchVector>["metadata"]>;

expectTypeOf<RetrievedMetadata>().toEqualTypeOf<Metadata>();
});

test("case 3: index-level and command-level metadata are provided, command-level metadata should be expected", () => {
const index = new Index<Metadata>();

type OverrideMetadata = { director: string };

type RetrievedFetchVector = Awaited<ReturnType<typeof index.fetch<OverrideMetadata>>>[number];

type RetrievedMetadata = NonNullable<NonNullable<RetrievedFetchVector>["metadata"]>;

expectTypeOf<RetrievedMetadata>().toEqualTypeOf<OverrideMetadata>();
});

test("case 4: command-level metadata is provided, command-level metadata should be expected", () => {
const index = new Index();

type RetrievedFetchVector = Awaited<ReturnType<typeof index.fetch<Metadata>>>[number];

type RetrievedMetadata = NonNullable<NonNullable<RetrievedFetchVector>["metadata"]>;

expectTypeOf<RetrievedMetadata>().toEqualTypeOf<Metadata>();
});
46 changes: 46 additions & 0 deletions src/commands/client/query/index.test-d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import { expectTypeOf, test } from "vitest";
import { Index } from "../../../../index";

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<ReturnType<typeof index.query>>[number];

type RetrievedMetadata = NonNullable<NonNullable<RetrievedQueryVector>["metadata"]>;

expectTypeOf<RetrievedMetadata>().toEqualTypeOf<Record<string, unknown>>();
});

test("case 2: index-level metadata is provided, index-level metadata should be expected", () => {
const index = new Index<Metadata>();

type RetrievedQueryVector = Awaited<ReturnType<typeof index.query<Metadata>>>[number];

type RetrievedMetadata = NonNullable<NonNullable<RetrievedQueryVector>["metadata"]>;

expectTypeOf<RetrievedMetadata>().toEqualTypeOf<Metadata>();
});

test("case 3: index-level and command-level metadata are provided, command-level metadata should be expected", () => {
const index = new Index<Metadata>();

type OverrideMetadata = { director: string };

type RetrievedQueryVector = Awaited<ReturnType<typeof index.query<OverrideMetadata>>>[number];

type RetrievedMetadata = NonNullable<NonNullable<RetrievedQueryVector>["metadata"]>;

expectTypeOf<RetrievedMetadata>().toEqualTypeOf<OverrideMetadata>();
});

test("case 4: command-level metadata is provided, command-level metadata should be expected", () => {
const index = new Index();

type RetrievedQueryVector = Awaited<ReturnType<typeof index.query<Metadata>>>[number];

type RetrievedMetadata = NonNullable<NonNullable<RetrievedQueryVector>["metadata"]>;

expectTypeOf<RetrievedMetadata>().toEqualTypeOf<Metadata>();
});
48 changes: 48 additions & 0 deletions src/commands/client/range/index.test-d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import { expectTypeOf, test } from "vitest";
import { Index } from "../../../../index";

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<ReturnType<typeof index.range>>["vectors"][number];

type RetrievedMetadata = NonNullable<NonNullable<RetrievedRangeVector>["metadata"]>;

expectTypeOf<RetrievedMetadata>().toEqualTypeOf<Record<string, unknown>>();
});

test("case 2: index-level metadata is provided, index-level metadata should be expected", () => {
const index = new Index<Metadata>();

type RetrievedRangeVector = Awaited<ReturnType<typeof index.range<Metadata>>>["vectors"][number];

type RetrievedMetadata = NonNullable<NonNullable<RetrievedRangeVector>["metadata"]>;

expectTypeOf<RetrievedMetadata>().toEqualTypeOf<Metadata>();
});

test("case 3: index-level and command-level metadata are provided, command-level metadata should be expected", () => {
const index = new Index<Metadata>();

type OverrideMetadata = { director: string };

type RetrievedRangeVector = Awaited<
ReturnType<typeof index.range<OverrideMetadata>>
>["vectors"][number];

type RetrievedMetadata = NonNullable<NonNullable<RetrievedRangeVector>["metadata"]>;

expectTypeOf<RetrievedMetadata>().toEqualTypeOf<OverrideMetadata>();
});

test("case 4: command-level metadata is provided, command-level metadata should be expected", () => {
const index = new Index();

type RetrievedRangeVector = Awaited<ReturnType<typeof index.range<Metadata>>>["vectors"][number];

type RetrievedMetadata = NonNullable<NonNullable<RetrievedRangeVector>["metadata"]>;

expectTypeOf<RetrievedMetadata>().toEqualTypeOf<Metadata>();
});
46 changes: 46 additions & 0 deletions src/commands/client/upsert/index.test-d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import { NonArrayType } from "@utils/test-utils";
import { expectTypeOf, test } from "vitest";
import { Index } from "../../../../index";

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<typeof index.upsert>["0"];
type ExpectedMetadata = NonNullable<NonArrayType<ExpectedParameters>["metadata"]>;

expectTypeOf<ExpectedMetadata>().toEqualTypeOf<Record<string, unknown>>();
});

test("case 2: index-level metadata is provided, index-level metadata should be expected", () => {
const index = new Index<Metadata>();

// ideally we would not have to pass the same generic again but infer from the index signature instead
type ExpectedParameters = Parameters<typeof index.upsert<Metadata>>["0"];
type ExpectedMetadata = NonNullable<NonArrayType<ExpectedParameters>["metadata"]>;

expectTypeOf<ExpectedMetadata>().toEqualTypeOf<Metadata>();
});

test("case 3: index-level metadata is provided and command-level metadata is provided, command-level metadata should be expected", () => {
const index = new Index<Metadata>();

type OverrideMetadata = { director: string };

type ExpectedParameters = Parameters<typeof index.upsert<OverrideMetadata>>["0"];
type ExpectedMetadata = NonNullable<NonNullable<NonArrayType<ExpectedParameters>>["metadata"]>;

expectTypeOf<ExpectedMetadata>().toEqualTypeOf<OverrideMetadata>();
});

test("case 4: command-level metadata is provided, command-level metadata should be expected", () => {
const index = new Index();

type ExpectedParameters = Parameters<typeof index.upsert<Metadata>>["0"];

type ExpectedMetadata = NonNullable<NonNullable<NonArrayType<ExpectedParameters>>["metadata"]>;

expectTypeOf<ExpectedMetadata>().toEqualTypeOf<Metadata>();
});
2 changes: 2 additions & 0 deletions src/utils/test-utils.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import { ResetCommand } from "../commands/client/reset";
import { HttpClient, RetryConfig } from "../http";

export type NonArrayType<T> = T extends Array<infer U> ? U : T;

export const newHttpClient = (retry?: RetryConfig | undefined) => {
const url = process.env.UPSTASH_VECTOR_REST_URL;
if (!url) {
Expand Down
11 changes: 11 additions & 0 deletions vitest.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
/// <reference types="vitest" />
import { defineConfig } from "vite"

export default defineConfig({
test: {
typecheck: {
include: ["**/*.test-d.ts"],
only: true,
},
},
})

0 comments on commit c565ead

Please sign in to comment.