/ packages / store / test.ts
test.ts
  1  import { assert, assertEquals } from "@std/assert";
  2  import type { AbstractStoreConstructor } from "./mod.ts";
  3  
  4  function generateRandomUint8Array(length: number): Uint8Array {
  5    return crypto.getRandomValues(new Uint8Array(length));
  6  }
  7  
  8  export default function Test(
  9    Store: AbstractStoreConstructor,
 10  ) {
 11    Deno.test(`${Store.name} - Basic operations`, async () => {
 12      const store = new Store();
 13  
 14      // Generate random key and value
 15      const key = generateRandomUint8Array(32);
 16      const value = generateRandomUint8Array(64);
 17  
 18      // Store the value
 19      await store.set(key, value);
 20  
 21      // Retrieve and verify the value
 22      const retrieved = await store.get(key);
 23      assert(retrieved !== undefined, "Retrieved value should not be undefined");
 24      assertEquals(
 25        retrieved,
 26        value,
 27        "Retrieved value should match stored value",
 28      );
 29    });
 30  
 31    Deno.test(`${Store.name} - Get non-existent key`, async () => {
 32      const store = new Store();
 33  
 34      // Try to get a key that hasn't been set
 35      const nonExistentKey = generateRandomUint8Array(32);
 36      const result = await store.get(nonExistentKey);
 37  
 38      assertEquals(
 39        result,
 40        undefined,
 41        "Getting non-existent key should return undefined",
 42      );
 43    });
 44  
 45    Deno.test(`${Store.name} - Overwrite existing key`, async () => {
 46      const store = new Store();
 47  
 48      const key = generateRandomUint8Array(32);
 49      const value1 = generateRandomUint8Array(64);
 50      const value2 = generateRandomUint8Array(64);
 51  
 52      // Store initial value
 53      await store.set(key, value1);
 54  
 55      // Overwrite with new value
 56      await store.set(key, value2);
 57  
 58      // Retrieve and verify the new value
 59      const retrieved = await store.get(key);
 60      assert(retrieved !== undefined, "Retrieved value should not be undefined");
 61      assertEquals(
 62        retrieved,
 63        value2,
 64        "Retrieved value should match the overwritten value",
 65      );
 66    });
 67  
 68    Deno.test(`${Store.name} - Multiple random key-value pairs`, async () => {
 69      const store = new Store();
 70      const pairCount = 100; // Test with 100 random pairs
 71  
 72      const pairs = Array.from({ length: pairCount }, () => ({
 73        key: generateRandomUint8Array(32),
 74        value: generateRandomUint8Array(64),
 75      }));
 76  
 77      // Store all pairs
 78      for (const pair of pairs) {
 79        await store.set(pair.key, pair.value);
 80      }
 81  
 82      // Verify all pairs
 83      for (const pair of pairs) {
 84        const retrieved = await store.get(pair.key);
 85        assert(
 86          retrieved !== undefined,
 87          "Retrieved value should not be undefined",
 88        );
 89        assertEquals(
 90          retrieved,
 91          pair.value,
 92          "Retrieved value should match stored value",
 93        );
 94      }
 95    });
 96  
 97    Deno.test(`${Store.name} - Collision resistance with similar keys`, async () => {
 98      const store = new Store();
 99  
100      // Create two similar but different keys
101      const key1 = new Uint8Array([1, 255]);
102      const key2 = new Uint8Array([1, 255, 0]);
103  
104      const value1 = generateRandomUint8Array(64);
105      const value2 = generateRandomUint8Array(64);
106  
107      await store.set(key1, value1);
108      await store.set(key2, value2);
109  
110      const retrieved1 = await store.get(key1);
111      const retrieved2 = await store.get(key2);
112  
113      assert(
114        retrieved1 !== undefined,
115        "Retrieved value 1 should not be undefined",
116      );
117      assert(
118        retrieved2 !== undefined,
119        "Retrieved value 2 should not be undefined",
120      );
121      assertEquals(retrieved1, value1, "First key should retrieve first value");
122      assertEquals(retrieved2, value2, "Second key should retrieve second value");
123    });
124  
125    Deno.test(`${Store.name} - Stress test with varying size data`, async () => {
126      const store = new Store();
127      const testCount = 50;
128  
129      const pairs = Array.from({ length: testCount }, () => {
130        // Random sizes between 1 and 1024 bytes
131        const keySize = Math.floor(Math.random() * 1024) + 1;
132        const valueSize = Math.floor(Math.random() * 1024) + 1;
133  
134        return {
135          key: generateRandomUint8Array(keySize),
136          value: generateRandomUint8Array(valueSize),
137        };
138      });
139  
140      // Store all pairs
141      await Promise.all(pairs.map((pair) => store.set(pair.key, pair.value)));
142  
143      // Verify all pairs
144      for (const pair of pairs) {
145        const retrieved = await store.get(pair.key);
146        assert(
147          retrieved !== undefined,
148          "Retrieved value should not be undefined",
149        );
150        assertEquals(
151          retrieved,
152          pair.value,
153          "Retrieved value should match stored value",
154        );
155      }
156    });
157  }