Skip to content

Commit

Permalink
chore: add tests
Browse files Browse the repository at this point in the history
  • Loading branch information
amandesai01 committed Jul 25, 2024
1 parent 45bdc53 commit 3813e0e
Show file tree
Hide file tree
Showing 2 changed files with 198 additions and 0 deletions.
16 changes: 16 additions & 0 deletions test/driver.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { describe } from "vitest";
import { s3Driver } from "../src";
import { testDriver } from "./utils";

describe("s3 driver", () => {
testDriver({
driver: s3Driver({
accessKeyId: process.env.VITE_S3_ACCESS_KEY_ID!,
secretAccessKey: process.env.VITE_S3_SECRET_ACCESS_KEY!,
accountId: process.env.VITE_S3_ACCOUNT_ID,
bucket: process.env.VITE_S3_BUCKET!,
endpoint: process.env.VITE_S3_ENDPOINT!,
region: process.env.VITE_S3_REGION!,
}),
});
});
182 changes: 182 additions & 0 deletions test/utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,182 @@
/**
* Source: https://github.com/unjs/unstorage/blob/main/test/drivers/utils.ts
*/

import {
type Driver,
type Storage,
createStorage,
restoreSnapshot,
} from "unstorage";
import { expect, it } from "vitest";

export interface TestContext {
storage: Storage;
driver: Driver;
}

export interface TestOptions {
driver: Driver;
additionalTests?: (ctx: TestContext) => void;
}

export function testDriver(opts: TestOptions) {
const ctx: TestContext = {
storage: createStorage({ driver: opts.driver }),
driver: opts.driver,
};

it("init", async () => {
await restoreSnapshot(ctx.storage, { initial: "works" });
expect(await ctx.storage.getItem("initial")).toBe("works");
await ctx.storage.clear();
});

it("initial state", async () => {
expect(await ctx.storage.hasItem("s1:a")).toBe(false);
expect(await ctx.storage.getItem("s2:a")).toBe(undefined);
expect(await ctx.storage.getKeys()).toMatchObject([]);
});

it("setItem", async () => {
await ctx.storage.setItem("s1:a", "test_data");
await ctx.storage.setItem("s2:a", "test_data");
await ctx.storage.setItem("s3:a?q=1", "test_data");
expect(await ctx.storage.hasItem("s1:a")).toBe(true);
expect(await ctx.storage.getItem("s1:a")).toBe("test_data");
expect(await ctx.storage.getItem("s3:a?q=2")).toBe("test_data");
});

it("getKeys", async () => {
expect(await ctx.storage.getKeys().then((k) => k.sort())).toMatchObject(
["s1:a", "s2:a", "s3:a"].sort(),
);
expect(await ctx.storage.getKeys("s1").then((k) => k.sort())).toMatchObject(
["s1:a"].sort(),
);
});

it("serialize (object)", async () => {
await ctx.storage.setItem("/data/test.json", { json: "works" });
expect(await ctx.storage.getItem("/data/test.json")).toMatchObject({
json: "works",
});
});

it("serialize (primitive)", async () => {
await ctx.storage.setItem("/data/true.json", true);
expect(await ctx.storage.getItem("/data/true.json")).toBe(true);
});

it("serialize (lossy object with toJSON())", async () => {
class Test1 {
toJSON() {
return "SERIALIZED";
}
}
await ctx.storage.setItem("/data/serialized1.json", new Test1());
expect(await ctx.storage.getItem("/data/serialized1.json")).toBe(
"SERIALIZED",
);
class Test2 {
toJSON() {
return { serializedObj: "works" };
}
}
await ctx.storage.setItem("/data/serialized2.json", new Test2());
expect(await ctx.storage.getItem("/data/serialized2.json")).toMatchObject({
serializedObj: "works",
});
});

it("serialize (error for non primitives)", async () => {
class Test {}
expect(
ctx.storage.setItem("/data/badvalue.json", new Test()),
).rejects.toThrow("[unstorage] Cannot stringify value!");
});

it("raw support", async () => {
const value = new Uint8Array([1, 2, 3]);
await ctx.storage.setItemRaw("/data/raw.bin", value);
const rValue = await ctx.storage.getItemRaw("/data/raw.bin");
const rValueLen = rValue?.size || rValue?.byteLength;
if (rValueLen !== value.length) {
console.log("Invalid raw value length:", rValue, "Length:", rValueLen);
}
expect(rValueLen).toBe(value.length);
expect(Buffer.from(rValue).toString("base64")).toBe(
Buffer.from(value).toString("base64"),
);
});

// Bulk tests
it("setItems", async () => {
await ctx.storage.setItems([
{ key: "t:1", value: "test_data_t1" },
{ key: "t:2", value: "test_data_t2" },
{ key: "t:3", value: "test_data_t3" },
]);
expect(await ctx.storage.getItem("t:1")).toBe("test_data_t1");
expect(await ctx.storage.getItem("t:2")).toBe("test_data_t2");
expect(await ctx.storage.getItem("t:3")).toBe("test_data_t3");
});

it("getItems", async () => {
await ctx.storage.setItem("v1:a", "test_data_v1:a");
await ctx.storage.setItem("v2:a", "test_data_v2:a");
await ctx.storage.setItem("v3:a?q=1", "test_data_v3:a?q=1");

expect(
await ctx.storage.getItems([
{ key: "v1:a" },
"v2:a",
{ key: "v3:a?q=1" },
]),
).toMatchObject([
{
key: "v1:a",
value: "test_data_v1:a",
},
{
key: "v2:a",
value: "test_data_v2:a",
},
{
key: "v3:a", // key should lose the querystring
value: "test_data_v3:a?q=1",
},
]);
});

it("getItem - return falsy values when set in storage", async () => {
await ctx.storage.setItem("zero", 0);
expect(await ctx.storage.getItem("zero")).toBe(0);

await ctx.storage.setItem("my-false-flag", false);
expect(await ctx.storage.getItem("my-false-flag")).toBe(false);
});

// TODO: Refactor to move after cleanup
if (opts.additionalTests) {
opts.additionalTests(ctx);
}

it("removeItem", async () => {
await ctx.storage.removeItem("s1:a", false);
expect(await ctx.storage.hasItem("s1:a")).toBe(false);
expect(await ctx.storage.getItem("s1:a")).toBe(undefined);
});

it("clear", async () => {
await ctx.storage.clear();
expect(await ctx.storage.getKeys()).toMatchObject([]);
// ensure we can clear empty storage as well: #162
await ctx.storage.clear();
expect(await ctx.storage.getKeys()).toMatchObject([]);
});

it("dispose", async () => {
await ctx.storage.dispose();
});
}

0 comments on commit 3813e0e

Please sign in to comment.