idb: make test cases pass

This commit is contained in:
Florian Dold 2021-02-25 16:34:55 +01:00
parent 0e28865018
commit 48acd573b1
No known key found for this signature in database
GPG Key ID: D2E4F00F29D02A4B
3 changed files with 51 additions and 11 deletions

View File

@ -42,11 +42,13 @@ import {
IDBTransactionMode, IDBTransactionMode,
IDBValidKey, IDBValidKey,
} from "./idbtypes"; } from "./idbtypes";
import { canInjectKey } from "./util/canInjectKey";
import { compareKeys } from "./util/cmp"; import { compareKeys } from "./util/cmp";
import { enforceRange } from "./util/enforceRange"; import { enforceRange } from "./util/enforceRange";
import { import {
AbortError, AbortError,
ConstraintError, ConstraintError,
DataCloneError,
DataError, DataError,
InvalidAccessError, InvalidAccessError,
InvalidStateError, InvalidStateError,
@ -62,9 +64,7 @@ import { makeStoreKeyValue } from "./util/makeStoreKeyValue";
import { normalizeKeyPath } from "./util/normalizeKeyPath"; import { normalizeKeyPath } from "./util/normalizeKeyPath";
import { openPromise } from "./util/openPromise"; import { openPromise } from "./util/openPromise";
import queueTask from "./util/queueTask"; import queueTask from "./util/queueTask";
import { import { structuredClone } from "./util/structuredClone";
structuredClone,
} from "./util/structuredClone";
import { validateKeyPath } from "./util/validateKeyPath"; import { validateKeyPath } from "./util/validateKeyPath";
import { valueToKey } from "./util/valueToKey"; import { valueToKey } from "./util/valueToKey";
@ -106,8 +106,9 @@ export class BridgeIDBCursor implements IDBCursor {
private _gotValue: boolean = false; private _gotValue: boolean = false;
private _range: IDBValidKey | IDBKeyRange | undefined | null; private _range: IDBValidKey | IDBKeyRange | undefined | null;
private _indexPosition = undefined; // Key of previously returned record // Key of previously returned record
private _objectStorePosition = undefined; private _indexPosition: IDBValidKey | undefined = undefined;
private _objectStorePosition: IDBValidKey | undefined = undefined;
private _keyOnly: boolean; private _keyOnly: boolean;
private _source: CursorSource; private _source: CursorSource;
@ -251,9 +252,9 @@ export class BridgeIDBCursor implements IDBCursor {
} }
this._gotValue = true; this._gotValue = true;
this._objectStorePosition = structuredClone(response.primaryKeys![0]); this._objectStorePosition = response.primaryKeys![0];
if (response.indexKeys !== undefined && response.indexKeys.length > 0) { if (response.indexKeys !== undefined && response.indexKeys.length > 0) {
this._indexPosition = structuredClone(response.indexKeys[0]); this._indexPosition = response.indexKeys![0];
} }
return this; return this;
@ -290,8 +291,31 @@ export class BridgeIDBCursor implements IDBCursor {
throw new InvalidStateError(); throw new InvalidStateError();
} }
const key = this._primaryKey;
// Effective object store
let os: BridgeIDBObjectStore;
if (this.source instanceof BridgeIDBObjectStore) {
os = this.source;
} else {
os = this.source._objectStore;
}
try {
// Only called for the side effect of throwing an exception
structuredClone(value);
} catch (e) {
throw new DataCloneError();
}
if (os.keyPath !== null && os.keyPath !== undefined) {
if (!canInjectKey(os.keyPath, value)) {
throw new DataError();
}
}
const storeReq: RecordStoreRequest = { const storeReq: RecordStoreRequest = {
key: this._primaryKey, key,
value, value,
objectStoreName: this._objectStoreName, objectStoreName: this._objectStoreName,
storeLevel: StoreLevel.UpdateExisting, storeLevel: StoreLevel.UpdateExisting,

View File

@ -15,7 +15,7 @@
*/ */
import { extractKey } from "./extractKey"; import { extractKey } from "./extractKey";
import { DataError } from "./errors"; import { DataCloneError, DataError } from "./errors";
import { valueToKey } from "./valueToKey"; import { valueToKey } from "./valueToKey";
import { structuredClone } from "./structuredClone"; import { structuredClone } from "./structuredClone";
import { IDBKeyPath, IDBValidKey } from "../idbtypes"; import { IDBKeyPath, IDBValidKey } from "../idbtypes";
@ -26,7 +26,7 @@ export interface StoreKeyResult {
value: any; value: any;
} }
export function injectKey( function injectKey(
keyPath: IDBKeyPath | IDBKeyPath[], keyPath: IDBKeyPath | IDBKeyPath[],
value: any, value: any,
key: IDBValidKey, key: IDBValidKey,
@ -87,7 +87,11 @@ export function makeStoreKeyValue(
// This models a decision table on (haveKey, haveKeyPath, autoIncrement) // This models a decision table on (haveKey, haveKeyPath, autoIncrement)
try {
value = structuredClone(value); value = structuredClone(value);
} catch (e) {
throw new DataCloneError();
}
if (haveKey) { if (haveKey) {
if (haveKeyPath) { if (haveKeyPath) {

View File

@ -29,6 +29,18 @@ test("structured clone", (t) => {
checkClone(t, [new Date()]); checkClone(t, [new Date()]);
checkClone(t, undefined); checkClone(t, undefined);
checkClone(t, [undefined]); checkClone(t, [undefined]);
t.throws(() => {
structuredClone({ foo: () => {} });
});
t.throws(() => {
structuredClone(Promise);
});
t.throws(() => {
structuredClone(Promise.resolve());
});
}); });
test("structured clone (cycles)", (t) => { test("structured clone (cycles)", (t) => {