DataStore.spec.ts 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. import { describe, expect, it } from "vitest";
  2. import { DataStore } from "./DataStore.js";
  3. import { compress, decompress } from "./crypto.js";
  4. class TestDataStore<TData extends object = object> extends DataStore<TData> {
  5. public async test_getValue<TValue extends GM.Value = string>(name: string, defaultValue: TValue): Promise<string | TValue> {
  6. return await this.getValue(name, defaultValue);
  7. }
  8. public async test_setValue(name: string, value: GM.Value): Promise<void> {
  9. return await this.setValue(name, value);
  10. }
  11. }
  12. describe("DataStore", () => {
  13. it("Basic usage", async () => {
  14. const store = new DataStore({
  15. id: "test-1",
  16. defaultData: { a: 1, b: 2 },
  17. formatVersion: 1,
  18. storageMethod: "sessionStorage",
  19. });
  20. // should equal defaultData:
  21. expect(store.getData().a).toBe(1);
  22. await store.loadData();
  23. // synchronous in-memory change:
  24. const prom = store.setData({ ...store.getData(), a: 2 });
  25. expect(store.getData().a).toBe(2);
  26. await prom;
  27. // only clears persistent data, not the stuff in memory:
  28. await store.deleteData();
  29. expect(store.getData().a).toBe(2);
  30. // refreshes memory data:
  31. await store.loadData();
  32. expect(store.getData().a).toBe(1);
  33. expect(store.encodingEnabled()).toBe(false);
  34. // restore initial state:
  35. await store.deleteData();
  36. });
  37. it("Works with encoding", async () => {
  38. const store = new DataStore({
  39. id: "test-2",
  40. defaultData: { a: 1, b: 2 },
  41. formatVersion: 1,
  42. storageMethod: "sessionStorage",
  43. encodeData: async (data) => await compress(data, "deflate-raw", "string"),
  44. decodeData: async (data) => await decompress(data, "deflate-raw", "string"),
  45. });
  46. await store.loadData();
  47. await store.setData({ ...store.getData(), a: 2 });
  48. await store.loadData();
  49. expect(store.getData()).toEqual({ a: 2, b: 2 });
  50. expect(store.encodingEnabled()).toBe(true);
  51. });
  52. it("Data and ID migrations work", async () => {
  53. const firstStore = new DataStore({
  54. id: "test-3",
  55. defaultData: { a: 1, b: 2 },
  56. formatVersion: 1,
  57. storageMethod: "sessionStorage",
  58. });
  59. await firstStore.loadData();
  60. await firstStore.setData({ ...firstStore.getData(), a: 2 });
  61. // new store with increased format version & new ID:
  62. const secondStore = new DataStore({
  63. id: "test-4",
  64. migrateIds: [firstStore.id],
  65. defaultData: { a: -1337, b: -1337, c: 69 },
  66. formatVersion: 2,
  67. storageMethod: "sessionStorage",
  68. migrations: {
  69. 2: (oldData: Record<string, unknown>) => ({ ...oldData, c: 1 }),
  70. },
  71. });
  72. const data1 = await secondStore.loadData();
  73. expect(data1.a).toBe(2);
  74. expect(data1.b).toBe(2);
  75. expect(data1.c).toBe(1);
  76. await secondStore.saveDefaultData();
  77. const data2 = secondStore.getData();
  78. expect(data2.a).toBe(-1337);
  79. expect(data2.b).toBe(-1337);
  80. expect(data2.c).toBe(69);
  81. // migrate with migrateId method:
  82. const thirdStore = new TestDataStore({
  83. id: "test-5",
  84. defaultData: secondStore.defaultData,
  85. formatVersion: 3,
  86. storageMethod: "sessionStorage",
  87. });
  88. await thirdStore.migrateId(secondStore.id);
  89. const thirdData = await thirdStore.loadData();
  90. expect(thirdData.a).toBe(-1337);
  91. expect(thirdData.b).toBe(-1337);
  92. expect(thirdData.c).toBe(69);
  93. expect(await thirdStore.test_getValue("_uucfgver-test-5", "")).toBe("2");
  94. await thirdStore.setData(thirdStore.getData());
  95. expect(await thirdStore.test_getValue("_uucfgver-test-5", "")).toBe("3");
  96. expect(await thirdStore.test_getValue("_uucfgver-test-3", "")).toBe("");
  97. expect(await thirdStore.test_getValue("_uucfgver-test-4", "")).toBe("");
  98. });
  99. });