gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[taler-wallet-core] 02/03: add more tests and fix various issues


From: gnunet
Subject: [taler-wallet-core] 02/03: add more tests and fix various issues
Date: Tue, 16 Feb 2021 13:47:06 +0100

This is an automated email from the git hooks/post-receive script.

dold pushed a commit to branch master
in repository wallet-core.

commit db59275b6b43f8fa7f36899ae81cb7139a2e80cb
Author: Florian Dold <florian@dold.me>
AuthorDate: Tue Feb 16 11:34:50 2021 +0100

    add more tests and fix various issues
---
 packages/idb-bridge/src/MemoryBackend.test.ts      |   2 +-
 packages/idb-bridge/src/MemoryBackend.ts           |  14 +-
 packages/idb-bridge/src/bridge-idb.ts              |  10 +-
 .../src/idb-wpt-ported/idbobjectstore_add.test.ts  | 270 +++++++++++++++++++++
 .../idb-bridge/src/idb-wpt-ported/wptsupport.ts    |   4 +-
 packages/idb-bridge/src/util/cmp.ts                |   6 +-
 packages/idb-bridge/src/util/enforceRange.ts       |   4 +-
 packages/idb-bridge/src/util/extractKey.ts         |   6 +-
 packages/idb-bridge/src/util/getIndexKeys.ts       |   6 +-
 packages/idb-bridge/src/util/injectKey.ts          |  20 +-
 packages/idb-bridge/src/util/makeStoreKeyValue.ts  |   6 +-
 packages/idb-bridge/src/util/openPromise.ts        |   4 +-
 packages/idb-bridge/src/util/validateKeyPath.ts    |   7 +-
 packages/idb-bridge/src/util/valueToKey.ts         |   4 +-
 14 files changed, 310 insertions(+), 53 deletions(-)

diff --git a/packages/idb-bridge/src/MemoryBackend.test.ts 
b/packages/idb-bridge/src/MemoryBackend.test.ts
index 281a72e3..8f988bb9 100644
--- a/packages/idb-bridge/src/MemoryBackend.test.ts
+++ b/packages/idb-bridge/src/MemoryBackend.test.ts
@@ -23,7 +23,7 @@ import {
   BridgeIDBRequest,
   BridgeIDBTransaction,
 } from "./bridge-idb";
-import MemoryBackend from "./MemoryBackend";
+import { MemoryBackend } from "./MemoryBackend";
 
 function promiseFromRequest(request: BridgeIDBRequest): Promise<any> {
   return new Promise((resolve, reject) => {
diff --git a/packages/idb-bridge/src/MemoryBackend.ts 
b/packages/idb-bridge/src/MemoryBackend.ts
index 2b4437bc..9a952772 100644
--- a/packages/idb-bridge/src/MemoryBackend.ts
+++ b/packages/idb-bridge/src/MemoryBackend.ts
@@ -29,7 +29,6 @@ import {
 } from "./backend-interface";
 import {
   structuredClone,
-  structuredEncapsulate,
   structuredRevive,
 } from "./util/structuredClone";
 import {
@@ -39,12 +38,11 @@ import {
   DataError,
 } from "./util/errors";
 import BTree, { ISortedMapF } from "./tree/b+tree";
-import compareKeys from "./util/cmp";
+import { compareKeys } from "./util/cmp";
 import { StoreKeyResult, makeStoreKeyValue } from "./util/makeStoreKeyValue";
-import getIndexKeys from "./util/getIndexKeys";
-import openPromise from "./util/openPromise";
+import { getIndexKeys } from "./util/getIndexKeys";
+import { openPromise } from "./util/openPromise";
 import {
-  IDBKeyPath,
   IDBKeyRange,
   IDBTransactionMode,
   IDBValidKey,
@@ -1440,7 +1438,7 @@ export class MemoryBackend implements Backend {
       const hasKey = modifiedData.has(key);
 
       if (hasKey && storeReq.storeLevel !== StoreLevel.AllowOverwrite) {
-        throw Error("refusing to overwrite");
+        throw new ConstraintError("refusing to overwrite");
       }
     }
 
@@ -1537,7 +1535,7 @@ export class MemoryBackend implements Backend {
     }
     const myConn = this.connectionsByTransaction[btx.transactionCookie];
     if (!myConn) {
-      throw Error("unknown connection");
+      throw Error("unknown transaction");
     }
     const db = this.databases[myConn.dbName];
     if (!db) {
@@ -1626,5 +1624,3 @@ export class MemoryBackend implements Backend {
     }
   }
 }
-
-export default MemoryBackend;
diff --git a/packages/idb-bridge/src/bridge-idb.ts 
b/packages/idb-bridge/src/bridge-idb.ts
index c4c58979..f519b9c2 100644
--- a/packages/idb-bridge/src/bridge-idb.ts
+++ b/packages/idb-bridge/src/bridge-idb.ts
@@ -42,8 +42,8 @@ import {
   IDBTransactionMode,
   IDBValidKey,
 } from "./idbtypes";
-import compareKeys from "./util/cmp";
-import enforceRange from "./util/enforceRange";
+import { compareKeys } from "./util/cmp";
+import { enforceRange } from "./util/enforceRange";
 import {
   AbortError,
   ConstraintError,
@@ -59,15 +59,15 @@ import { fakeDOMStringList } from 
"./util/fakeDOMStringList";
 import FakeEvent from "./util/FakeEvent";
 import FakeEventTarget from "./util/FakeEventTarget";
 import { normalizeKeyPath } from "./util/normalizeKeyPath";
-import openPromise from "./util/openPromise";
+import { openPromise } from "./util/openPromise";
 import queueTask from "./util/queueTask";
 import {
   structuredClone,
   structuredEncapsulate,
   structuredRevive,
 } from "./util/structuredClone";
-import validateKeyPath from "./util/validateKeyPath";
-import valueToKey from "./util/valueToKey";
+import { validateKeyPath } from "./util/validateKeyPath";
+import { valueToKey } from "./util/valueToKey";
 
 /** @public */
 export type CursorSource = BridgeIDBIndex | BridgeIDBObjectStore;
diff --git a/packages/idb-bridge/src/idb-wpt-ported/idbobjectstore_add.test.ts 
b/packages/idb-bridge/src/idb-wpt-ported/idbobjectstore_add.test.ts
new file mode 100644
index 00000000..b0c1de2d
--- /dev/null
+++ b/packages/idb-bridge/src/idb-wpt-ported/idbobjectstore_add.test.ts
@@ -0,0 +1,270 @@
+import test from "ava";
+import { IDBDatabase } from "../idbtypes";
+import { createdb } from "./wptsupport";
+
+// IDBObjectStore.add() - add with an inline key
+test("WPT idbobjectstore_add.htm", async (t) => {
+  await new Promise<void>((resolve, reject) => {
+    var db: IDBDatabase | undefined;
+    const record = { key: 1, property: "data" };
+
+    var open_rq = createdb(t);
+    open_rq.onupgradeneeded = function (e: any) {
+      db = e.target.result;
+      var objStore = db!.createObjectStore("store", { keyPath: "key" });
+
+      objStore.add(record);
+    };
+
+    open_rq.onsuccess = function (e) {
+      var rq = db!.transaction("store").objectStore("store").get(record.key);
+
+      rq.onsuccess = function (e: any) {
+        t.deepEqual(e.target.result.property, record.property);
+        t.deepEqual(e.target.result.key, record.key);
+        resolve();
+      };
+    };
+  });
+  t.pass();
+});
+
+// IDBObjectStore.add() - add with an out-of-line key
+test("WPT idbobjectstore_add2.htm", async (t) => {
+  await new Promise<void>((resolve, reject) => {
+    var db: any;
+    const key = 1;
+    const record = { property: "data" };
+
+    var open_rq = createdb(t);
+    open_rq.onupgradeneeded = function (e: any) {
+      db = e.target.result;
+      var objStore = db.createObjectStore("store");
+
+      objStore.add(record, key);
+    };
+
+    open_rq.onsuccess = function (e) {
+      var rq = db.transaction("store").objectStore("store").get(key);
+
+      rq.onsuccess = function (e: any) {
+        t.deepEqual(e.target.result.property, record.property);
+        resolve();
+      };
+    };
+  });
+  t.pass();
+});
+
+// IDBObjectStore.add() - record with same key already exists
+test("WPT idbobjectstore_add3.htm", async (t) => {
+  await new Promise<void>((resolve, reject) => {
+    var db: any;
+    const record = { key: 1, property: "data" };
+
+    var open_rq = createdb(t);
+    open_rq.onupgradeneeded = function (e: any) {
+      db = e.target.result;
+      var objStore = db.createObjectStore("store", { keyPath: "key" });
+      objStore.add(record);
+
+      var rq = objStore.add(record);
+      rq.onsuccess = () => t.fail("success on adding duplicate record");
+
+      rq.onerror = function (e: any) {
+        t.deepEqual(e.target.error.name, "ConstraintError");
+        t.deepEqual(rq.error.name, "ConstraintError");
+        t.deepEqual(e.type, "error");
+        e.preventDefault();
+        e.stopPropagation();
+      };
+    };
+
+    // Defer done, giving rq.onsuccess a chance to run
+    open_rq.onsuccess = function (e) {
+      resolve();
+    };
+  });
+  t.pass();
+});
+
+// IDBObjectStore.add() - add where an index has unique:true specified
+test("WPT idbobjectstore_add4.htm", async (t) => {
+  await new Promise<void>((resolve, reject) => {
+    let db: any;
+    let record = { key: 1, property: "data" };
+
+    var open_rq = createdb(t);
+    open_rq.onupgradeneeded = function (e: any) {
+      db = e.target.result;
+      var objStore = db.createObjectStore("store", { autoIncrement: true });
+      objStore.createIndex("i1", "property", { unique: true });
+      objStore.add(record);
+
+      var rq = objStore.add(record);
+      rq.onsuccess = () => t.fail("success on adding duplicate indexed 
record");
+
+      rq.onerror = function (e: any) {
+        t.deepEqual(rq.error.name, "ConstraintError");
+        t.deepEqual(e.target.error.name, "ConstraintError");
+        t.deepEqual(e.type, "error");
+        e.preventDefault();
+        e.stopPropagation();
+      };
+    };
+
+    // Defer done, giving a spurious rq.onsuccess a chance to run
+    open_rq.onsuccess = function (e) {
+      resolve();
+    };
+  });
+  t.pass();
+});
+
+// IDBObjectStore.add() - object store's key path is an object attribute
+test("WPT idbobjectstore_add5.htm", async (t) => {
+  await new Promise<void>((resolve, reject) => {
+    var db: any;
+    const record = { test: { obj: { key: 1 } }, property: "data" };
+
+    var open_rq = createdb(t);
+    open_rq.onupgradeneeded = function (e: any) {
+      db = e.target.result;
+      var objStore = db.createObjectStore("store", { keyPath: "test.obj.key" 
});
+      objStore.add(record);
+    };
+
+    open_rq.onsuccess = function (e: any) {
+      var rq = db
+        .transaction("store")
+        .objectStore("store")
+        .get(record.test.obj.key);
+
+      rq.onsuccess = function (e: any) {
+        t.deepEqual(e.target.result.property, record.property);
+        resolve();
+      };
+    };
+  });
+  t.pass();
+});
+
+// IDBObjectStore.add() - autoIncrement and inline keys
+test("WPT idbobjectstore_add6.htm", async (t) => {
+  await new Promise<void>((resolve, reject) => {
+    var db: any;
+    const record = { property: "data" };
+    const expected_keys = [1, 2, 3, 4];
+
+    var open_rq = createdb(t);
+    open_rq.onupgradeneeded = function (e: any) {
+      db = e.target.result;
+      var objStore = db.createObjectStore("store", {
+        keyPath: "key",
+        autoIncrement: true,
+      });
+
+      objStore.add(record);
+      objStore.add(record);
+      objStore.add(record);
+      objStore.add(record);
+    };
+
+    open_rq.onsuccess = function (e) {
+      var actual_keys: any[] = [],
+        rq = db.transaction("store").objectStore("store").openCursor();
+
+      rq.onsuccess = function (e: any) {
+        var cursor = e.target.result;
+
+        if (cursor) {
+          actual_keys.push(cursor.value.key);
+          cursor.continue();
+        } else {
+          t.deepEqual(actual_keys, expected_keys);
+          resolve();
+        }
+      };
+    };
+  });
+  t.pass();
+});
+
+// IDBObjectStore.add() - autoIncrement and out-of-line keys
+test("WPT idbobjectstore_add7.htm", async (t) => {
+  await new Promise<void>((resolve, reject) => {
+    var db: any;
+    const record = { property: "data" };
+    const expected_keys = [1, 2, 3, 4];
+
+    var open_rq = createdb(t);
+    open_rq.onupgradeneeded = function (e: any) {
+      db = e.target.result;
+      var objStore = db.createObjectStore("store", { autoIncrement: true });
+
+      objStore.add(record);
+      objStore.add(record);
+      objStore.add(record);
+      objStore.add(record);
+    };
+
+    open_rq.onsuccess = function (e) {
+      var actual_keys: any[] = [],
+        rq = db.transaction("store").objectStore("store").openCursor();
+
+      rq.onsuccess = function (e: any) {
+        var cursor = e.target.result;
+
+        if (cursor) {
+          actual_keys.push(cursor.key);
+          cursor.continue();
+        } else {
+          t.deepEqual(actual_keys, expected_keys);
+          resolve();
+        }
+      };
+    };
+  });
+  t.pass();
+});
+
+// IDBObjectStore.add() - object store has autoIncrement:true and the key path 
is an object attribute
+test("WPT idbobjectstore_add8.htm", async (t) => {
+  await new Promise<void>((resolve, reject) => {
+    var db: any;
+    const record = { property: "data" };
+    const expected_keys = [1, 2, 3, 4];
+
+    var open_rq = createdb(t);
+    open_rq.onupgradeneeded = function (e: any) {
+      db = e.target.result;
+      var objStore = db.createObjectStore("store", {
+        keyPath: "test.obj.key",
+        autoIncrement: true,
+      });
+
+      objStore.add(record);
+      objStore.add(record);
+      objStore.add(record);
+      objStore.add(record);
+    };
+
+    open_rq.onsuccess = function (e) {
+      var actual_keys: any[] = [],
+        rq = db.transaction("store").objectStore("store").openCursor();
+
+      rq.onsuccess = function (e: any) {
+        var cursor = e.target.result;
+
+        if (cursor) {
+          actual_keys.push(cursor.value.test.obj.key);
+          cursor.continue();
+        } else {
+          t.deepEqual(actual_keys, expected_keys);
+          resolve();
+        }
+      };
+    };
+  });
+  t.pass();
+});
diff --git a/packages/idb-bridge/src/idb-wpt-ported/wptsupport.ts 
b/packages/idb-bridge/src/idb-wpt-ported/wptsupport.ts
index f7b065f2..92e78a68 100644
--- a/packages/idb-bridge/src/idb-wpt-ported/wptsupport.ts
+++ b/packages/idb-bridge/src/idb-wpt-ported/wptsupport.ts
@@ -1,8 +1,8 @@
 import { ExecutionContext } from "ava";
 import { BridgeIDBFactory } from "..";
 import { IDBOpenDBRequest } from "../idbtypes";
-import MemoryBackend from "../MemoryBackend";
-import compareKeys from "../util/cmp";
+import { MemoryBackend } from "../MemoryBackend";
+import { compareKeys } from "../util/cmp";
 
 BridgeIDBFactory.enableTracing = true;
 const idbFactory = new BridgeIDBFactory(new MemoryBackend());
diff --git a/packages/idb-bridge/src/util/cmp.ts 
b/packages/idb-bridge/src/util/cmp.ts
index ddd43f2a..e7f26bf1 100644
--- a/packages/idb-bridge/src/util/cmp.ts
+++ b/packages/idb-bridge/src/util/cmp.ts
@@ -15,7 +15,7 @@
  */
 
 import { DataError } from "./errors";
-import valueToKey from "./valueToKey";
+import { valueToKey } from "./valueToKey";
 
 const getType = (x: any) => {
   if (typeof x === "number") {
@@ -38,7 +38,7 @@ const getType = (x: any) => {
 };
 
 // https://w3c.github.io/IndexedDB/#compare-two-keys
-const compareKeys = (first: any, second: any): -1 | 0 | 1 => {
+export const compareKeys = (first: any, second: any): -1 | 0 | 1 => {
   if (second === undefined) {
     throw new TypeError();
   }
@@ -104,5 +104,3 @@ const compareKeys = (first: any, second: any): -1 | 0 | 1 
=> {
 
   return first > second ? 1 : -1;
 };
-
-export default compareKeys;
diff --git a/packages/idb-bridge/src/util/enforceRange.ts 
b/packages/idb-bridge/src/util/enforceRange.ts
index 87e13579..ed463a33 100644
--- a/packages/idb-bridge/src/util/enforceRange.ts
+++ b/packages/idb-bridge/src/util/enforceRange.ts
@@ -17,7 +17,7 @@
 
 // https://heycam.github.io/webidl/#EnforceRange
 
-const enforceRange = (
+export const enforceRange = (
   num: number,
   type: "MAX_SAFE_INTEGER" | "unsigned long",
 ) => {
@@ -31,5 +31,3 @@ const enforceRange = (
     return Math.floor(num);
   }
 };
-
-export default enforceRange;
diff --git a/packages/idb-bridge/src/util/extractKey.ts 
b/packages/idb-bridge/src/util/extractKey.ts
index 7aa8bd17..09306dde 100644
--- a/packages/idb-bridge/src/util/extractKey.ts
+++ b/packages/idb-bridge/src/util/extractKey.ts
@@ -16,10 +16,10 @@
 */
 
 import { IDBKeyPath, IDBValidKey } from "../idbtypes";
-import valueToKey from "./valueToKey";
+import { valueToKey } from "./valueToKey";
 
 // 
http://www.w3.org/TR/2015/REC-IndexedDB-20150108/#dfn-steps-for-extracting-a-key-from-a-value-using-a-key-path
-const extractKey = (keyPath: IDBKeyPath | IDBKeyPath[], value: any) => {
+export const extractKey = (keyPath: IDBKeyPath | IDBKeyPath[], value: any) => {
   if (Array.isArray(keyPath)) {
     const result: IDBValidKey[] = [];
 
@@ -68,5 +68,3 @@ const extractKey = (keyPath: IDBKeyPath | IDBKeyPath[], 
value: any) => {
 
   return object;
 };
-
-export default extractKey;
diff --git a/packages/idb-bridge/src/util/getIndexKeys.ts 
b/packages/idb-bridge/src/util/getIndexKeys.ts
index 77b96b12..8515d79e 100644
--- a/packages/idb-bridge/src/util/getIndexKeys.ts
+++ b/packages/idb-bridge/src/util/getIndexKeys.ts
@@ -16,8 +16,8 @@
 */
 
 import { IDBKeyPath, IDBValidKey } from "../idbtypes";
-import extractKey from "./extractKey";
-import valueToKey from "./valueToKey";
+import { extractKey } from "./extractKey";
+import { valueToKey } from "./valueToKey";
 
 export function getIndexKeys(
   value: any,
@@ -43,5 +43,3 @@ export function getIndexKeys(
     throw Error(`unsupported key path: ${typeof keyPath}`);
   }
 }
-
-export default getIndexKeys;
diff --git a/packages/idb-bridge/src/util/injectKey.ts 
b/packages/idb-bridge/src/util/injectKey.ts
index 63c8deda..02acfaa4 100644
--- a/packages/idb-bridge/src/util/injectKey.ts
+++ b/packages/idb-bridge/src/util/injectKey.ts
@@ -30,6 +30,11 @@ export function injectKey(
     );
   }
 
+  const newValue = structuredClone(value);
+
+  // Position inside the new value where we'll place the key eventually.
+  let ptr = newValue;
+
   const identifiers = keyPath.split(".");
   if (identifiers.length === 0) {
     throw new Error("Assert: identifiers is not empty");
@@ -42,26 +47,23 @@ export function injectKey(
   }
 
   for (const identifier of identifiers) {
-    if (typeof value !== "object" && !Array.isArray(value)) {
-      return false;
+    if (typeof ptr !== "object" && !Array.isArray(ptr)) {
+      throw new Error("can't inject key");
     }
 
     const hop = value.hasOwnProperty(identifier);
     if (!hop) {
-      return true;
+      ptr[identifier] = {};
     }
 
-    value = value[identifier];
+    ptr = ptr[identifier];
   }
 
-  if (!(typeof value === "object" || Array.isArray(value))) {
+  if (!(typeof ptr === "object" || Array.isArray(ptr))) {
     throw new Error("can't inject key");
   }
 
-  const newValue = structuredClone(value);
-  newValue[lastIdentifier] = structuredClone(key);
+  ptr[lastIdentifier] = structuredClone(key);
 
   return newValue;
 }
-
-export default injectKey;
diff --git a/packages/idb-bridge/src/util/makeStoreKeyValue.ts 
b/packages/idb-bridge/src/util/makeStoreKeyValue.ts
index 2281e983..442a69ff 100644
--- a/packages/idb-bridge/src/util/makeStoreKeyValue.ts
+++ b/packages/idb-bridge/src/util/makeStoreKeyValue.ts
@@ -14,11 +14,11 @@
  permissions and limitations under the License.
 */
 
-import extractKey from "./extractKey";
+import { extractKey } from "./extractKey";
 import { DataError } from "./errors";
-import valueToKey from "./valueToKey";
+import { valueToKey } from "./valueToKey";
 import { structuredClone } from "./structuredClone";
-import injectKey from "./injectKey";
+import { injectKey } from "./injectKey";
 import { IDBKeyPath, IDBValidKey } from "../idbtypes";
 
 export interface StoreKeyResult {
diff --git a/packages/idb-bridge/src/util/openPromise.ts 
b/packages/idb-bridge/src/util/openPromise.ts
index 915060de..395d69e7 100644
--- a/packages/idb-bridge/src/util/openPromise.ts
+++ b/packages/idb-bridge/src/util/openPromise.ts
@@ -14,7 +14,7 @@
  permissions and limitations under the License.
 */
 
-function openPromise<T>(): {
+export function openPromise<T>(): {
   promise: Promise<T>;
   resolve: (v?: T | PromiseLike<T>) => void;
   reject: (err?: any) => void;
@@ -34,5 +34,3 @@ function openPromise<T>(): {
 
   return { promise, resolve, reject };
 }
-
-export default openPromise;
diff --git a/packages/idb-bridge/src/util/validateKeyPath.ts 
b/packages/idb-bridge/src/util/validateKeyPath.ts
index 2beb3c46..3bbe653b 100644
--- a/packages/idb-bridge/src/util/validateKeyPath.ts
+++ b/packages/idb-bridge/src/util/validateKeyPath.ts
@@ -17,7 +17,10 @@
 import { IDBKeyPath } from "../idbtypes";
 
 // http://www.w3.org/TR/2015/REC-IndexedDB-20150108/#dfn-valid-key-path
-const validateKeyPath = (keyPath: IDBKeyPath | IDBKeyPath[], parent?: "array" 
| "string") => {
+export const validateKeyPath = (
+  keyPath: IDBKeyPath | IDBKeyPath[],
+  parent?: "array" | "string",
+) => {
   // This doesn't make sense to me based on the spec, but it is needed to pass 
the W3C KeyPath tests (see same
   // comment in extractKey)
   let myKeyPath: IDBKeyPath | IDBKeyPath[] = keyPath;
@@ -74,5 +77,3 @@ const validateKeyPath = (keyPath: IDBKeyPath | IDBKeyPath[], 
parent?: "array" |
 
   throw new SyntaxError();
 };
-
-export default validateKeyPath;
diff --git a/packages/idb-bridge/src/util/valueToKey.ts 
b/packages/idb-bridge/src/util/valueToKey.ts
index c3661f9a..cfef779f 100644
--- a/packages/idb-bridge/src/util/valueToKey.ts
+++ b/packages/idb-bridge/src/util/valueToKey.ts
@@ -18,7 +18,7 @@ import { IDBValidKey } from "..";
 import { DataError } from "./errors";
 
 // https://w3c.github.io/IndexedDB/#convert-a-value-to-a-input
-function valueToKey(
+export function valueToKey(
   input: any,
   seen?: Set<object>,
 ): IDBValidKey | IDBValidKey[] {
@@ -68,5 +68,3 @@ function valueToKey(
     throw new DataError();
   }
 }
-
-export default valueToKey;

-- 
To stop receiving notification emails like this one, please contact
gnunet@gnunet.org.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]