+2018-10-31 Devin Rousso <drousso@apple.com>
+
+ Web Inspector: Audit: save imported audits across WebInspector sessions
+ https://bugs.webkit.org/show_bug.cgi?id=190858
+ <rdar://problem/45527625>
+
+ Reviewed by Brian Burg.
+
+ * inspector/unit-tests/objectStore/add-expected.txt: Added.
+ * inspector/unit-tests/objectStore/add.html: Added.
+ * inspector/unit-tests/objectStore/addObject-expected.txt: Added.
+ * inspector/unit-tests/objectStore/addObject.html: Added.
+ * inspector/unit-tests/objectStore/basic-expected.txt: Added.
+ * inspector/unit-tests/objectStore/basic.html: Added.
+ * inspector/unit-tests/objectStore/delete-expected.txt: Added.
+ * inspector/unit-tests/objectStore/delete.html: Added.
+ * inspector/unit-tests/objectStore/deleteObject-expected.txt: Added.
+ * inspector/unit-tests/objectStore/deleteObject.html: Added.
+ * inspector/unit-tests/objectStore/resources/objectStore-utilities.js: Added.
+ (TestPage.registerInitializer.InspectorTest.ObjectStore.TestObject):
+ (TestPage.registerInitializer.InspectorTest.ObjectStore.TestObject.prototype.toJSON):
+ (TestPage.registerInitializer.InspectorTest.ObjectStore.createSuite):
+ (TestPage.registerInitializer.InspectorTest.ObjectStore.createObjectStore):
+ (TestPage.registerInitializer.InspectorTest.ObjectStore.add):
+ (TestPage.registerInitializer.InspectorTest.ObjectStore.addObject):
+ (TestPage.registerInitializer.InspectorTest.ObjectStore.delete):
+ (TestPage.registerInitializer.InspectorTest.ObjectStore.deleteObject):
+ (TestPage.registerInitializer.InspectorTest.ObjectStore.logValues):
+ (TestPage.registerInitializer.InspectorTest.ObjectStore.wrapTest):
+
2018-10-31 Alicia Boya GarcĂa <aboya@igalia.com>
[MSE] Use tolerance when growing the coded frame group
--- /dev/null
+Tests WI.ObjectStore.prototype.add.
+
+
+== Running test suite: WI.ObjectStore.prototype.add
+-- Running test case: WI.ObjectStore.prototype.add.NoParameters
+PASS: Should produce an exception.
+TypeError: Not enough arguments
+[]
+
+-- Running test case: WI.ObjectStore.prototype.add.Boolean
+add: [false]
+add: [false,true]
+[false,true]
+
+-- Running test case: WI.ObjectStore.prototype.add.Number
+add: [11]
+add: [11,22]
+[11,22]
+
+-- Running test case: WI.ObjectStore.prototype.add.String
+add: ["foo"]
+add: ["foo","bar"]
+["foo","bar"]
+
+-- Running test case: WI.ObjectStore.prototype.add.Array
+add: [[11]]
+add: [[11],[22]]
+[[11],[22]]
+
+-- Running test case: WI.ObjectStore.prototype.add.Null
+add: [null]
+[null]
+
+-- Running test case: WI.ObjectStore.prototype.add.Object.WithoutKeyPathOrAutoIncrement
+PASS: Should produce an exception.
+DataError: Failed to store record in an IDBObjectStore: The object store uses out-of-line keys and has no key generator and the key parameter was not provided.
+[]
+
+-- Running test case: WI.ObjectStore.prototype.add.Object.KeyPathMissingOnObjectWithoutAutoIncrement
+PASS: Should produce an exception.
+DataError: Failed to store record in an IDBObjectStore: Evaluating the object store's key path did not yield a value.
+[]
+
+-- Running test case: WI.ObjectStore.prototype.add.Object.KeyPathSetOnObjectWithoutAutoIncrement
+add: [{"KeyPathSetOnObjectWithoutAutoIncrement":42,"a":1}]
+add: [{"KeyPathSetOnObjectWithoutAutoIncrement":42,"a":1},{"KeyPathSetOnObjectWithoutAutoIncrement":99,"b":2}]
+[{"KeyPathSetOnObjectWithoutAutoIncrement":42,"a":1},{"KeyPathSetOnObjectWithoutAutoIncrement":99,"b":2}]
+
+-- Running test case: WI.ObjectStore.prototype.add.Object.KeyPathMissingOnObjectWithAutoIncrement
+add: [{"a":1,"KeyPathMissingOnObjectWithAutoIncrement":1}]
+add: [{"a":1,"KeyPathMissingOnObjectWithAutoIncrement":1},{"b":2,"KeyPathMissingOnObjectWithAutoIncrement":2}]
+[{"a":1,"KeyPathMissingOnObjectWithAutoIncrement":1},{"b":2,"KeyPathMissingOnObjectWithAutoIncrement":2}]
+
+-- Running test case: WI.ObjectStore.prototype.add.Object.KeyPathSetOnObjectWithAutoIncrement
+add: [{"KeyPathSetOnObjectWithAutoIncrement":42,"a":1}]
+add: [{"KeyPathSetOnObjectWithAutoIncrement":42,"a":1},{"KeyPathSetOnObjectWithAutoIncrement":99,"b":2}]
+[{"KeyPathSetOnObjectWithAutoIncrement":42,"a":1},{"KeyPathSetOnObjectWithAutoIncrement":99,"b":2}]
+
+-- Running test case: WI.ObjectStore.prototype.add.Object.AutoIncrementWithoutKeyPath
+add: [{"a":1}]
+add: [{"a":1},{"b":2}]
+[{"a":1},{"b":2}]
+
+-- Running test case: WI.ObjectStore.prototype.add.Object.KeyPathSetOnObjectWithoutAutoIncrement.Sub
+add: [{"KeyPathSetOnObjectWithoutAutoIncrement":{"Sub":42},"a":1}]
+add: [{"KeyPathSetOnObjectWithoutAutoIncrement":{"Sub":42},"a":1},{"KeyPathSetOnObjectWithoutAutoIncrement":{"Sub":99},"b":2}]
+[{"KeyPathSetOnObjectWithoutAutoIncrement":{"Sub":42},"a":1},{"KeyPathSetOnObjectWithoutAutoIncrement":{"Sub":99},"b":2}]
+
+-- Running test case: WI.ObjectStore.prototype.add.Object.KeyPathMissingOnObjectWithAutoIncrement.Sub
+add: [{"a":1,"KeyPathMissingOnObjectWithAutoIncrement":{"Sub":1}}]
+add: [{"a":1,"KeyPathMissingOnObjectWithAutoIncrement":{"Sub":1}},{"b":2,"KeyPathMissingOnObjectWithAutoIncrement":{"Sub":2}}]
+[{"a":1,"KeyPathMissingOnObjectWithAutoIncrement":{"Sub":1}},{"b":2,"KeyPathMissingOnObjectWithAutoIncrement":{"Sub":2}}]
+
+-- Running test case: WI.ObjectStore.prototype.add.Object.KeyPathSetOnObjectWithAutoIncrement.Sub
+add: [{"KeyPathSetOnObjectWithAutoIncrement":{"Sub":42},"a":1}]
+add: [{"KeyPathSetOnObjectWithAutoIncrement":{"Sub":42},"a":1},{"KeyPathSetOnObjectWithAutoIncrement":{"Sub":99},"b":2}]
+[{"KeyPathSetOnObjectWithAutoIncrement":{"Sub":42},"a":1},{"KeyPathSetOnObjectWithAutoIncrement":{"Sub":99},"b":2}]
+
--- /dev/null
+<!DOCTYPE html>
+<html>
+<head>
+<script src="../../../http/tests/inspector/resources/inspector-test.js"></script>
+<script src="resources/objectStore-utilities.js"></script>
+<script>
+function test()
+{
+ let suite = InspectorTest.ObjectStore.createSuite("WI.ObjectStore.prototype.add");
+
+ function testAdd(name, {options, tests}) {
+ InspectorTest.ObjectStore.wrapTest(name, async function() {
+ InspectorTest.ObjectStore.createObjectStore(options);
+
+ for (let {value, expected} of tests)
+ await InspectorTest.ObjectStore.add(value, expected);
+ });
+ }
+
+ InspectorTest.ObjectStore.wrapTest("WI.ObjectStore.prototype.add.NoParameters", async function() {
+ let objectStore = InspectorTest.ObjectStore.createObjectStore();
+
+ await InspectorTest.expectException(async function() {
+ await objectStore.add();
+ await objectStore.add(InspectorTest.ObjectStore.basicObject2);
+ });
+ });
+
+ testAdd("WI.ObjectStore.prototype.add.Boolean", {
+ options: {autoIncrement: true},
+ tests: [
+ {value: false, expected: 1},
+ {value: true, expected: 2},
+ ],
+ });
+
+ testAdd("WI.ObjectStore.prototype.add.Number", {
+ options: {autoIncrement: true},
+ tests: [
+ {value: 11, expected: 1},
+ {value: 22, expected: 2},
+ ],
+ });
+
+ testAdd("WI.ObjectStore.prototype.add.String", {
+ options: {autoIncrement: true},
+ tests: [
+ {value: "foo", expected: 1},
+ {value: "bar", expected: 2},
+ ],
+ });
+
+ testAdd("WI.ObjectStore.prototype.add.Array", {
+ options: {autoIncrement: true},
+ tests: [
+ {value: [11], expected: 1},
+ {value: [22], expected: 2},
+ ],
+ });
+
+ testAdd("WI.ObjectStore.prototype.add.Null", {
+ options: {autoIncrement: true},
+ tests: [
+ {value: null, expected: 1},
+ ],
+ });
+
+ InspectorTest.ObjectStore.wrapTest("WI.ObjectStore.prototype.add.Object.WithoutKeyPathOrAutoIncrement", async function() {
+ let objectStore = InspectorTest.ObjectStore.createObjectStore();
+
+ await InspectorTest.expectException(async function() {
+ await objectStore.add(InspectorTest.ObjectStore.basicObject1);
+ await objectStore.add(InspectorTest.ObjectStore.basicObject2);
+ });
+ });
+
+ InspectorTest.ObjectStore.wrapTest("WI.ObjectStore.prototype.add.Object.KeyPathMissingOnObjectWithoutAutoIncrement", async function() {
+ const options = {
+ keyPath: "KeyPathMissingOnObjectWithoutAutoIncrement",
+ };
+ let objectStore = InspectorTest.ObjectStore.createObjectStore(options);
+
+ await InspectorTest.expectException(async function() {
+ await objectStore.add(InspectorTest.ObjectStore.basicObject1);
+ await objectStore.add(InspectorTest.ObjectStore.basicObject2);
+ });
+ });
+
+ testAdd("WI.ObjectStore.prototype.add.Object.KeyPathSetOnObjectWithoutAutoIncrement", {
+ options: {keyPath: "KeyPathSetOnObjectWithoutAutoIncrement"},
+ tests: [
+ {value: {KeyPathSetOnObjectWithoutAutoIncrement: 42, ...InspectorTest.ObjectStore.basicObject1}, expected: 42},
+ {value: {KeyPathSetOnObjectWithoutAutoIncrement: 99, ...InspectorTest.ObjectStore.basicObject2}, expected: 99},
+ ],
+ });
+
+ testAdd("WI.ObjectStore.prototype.add.Object.KeyPathMissingOnObjectWithAutoIncrement", {
+ options: {keyPath: "KeyPathMissingOnObjectWithAutoIncrement", autoIncrement: true},
+ tests: [
+ {value: InspectorTest.ObjectStore.basicObject1, expected: 1},
+ {value: InspectorTest.ObjectStore.basicObject2, expected: 2},
+ ],
+ });
+
+ testAdd("WI.ObjectStore.prototype.add.Object.KeyPathSetOnObjectWithAutoIncrement", {
+ options: {keyPath: "KeyPathSetOnObjectWithAutoIncrement", autoIncrement: true},
+ tests: [
+ {value: {KeyPathSetOnObjectWithAutoIncrement: 42, ...InspectorTest.ObjectStore.basicObject1}, expected: 42},
+ {value: {KeyPathSetOnObjectWithAutoIncrement: 99, ...InspectorTest.ObjectStore.basicObject2}, expected: 99},
+ ],
+ });
+
+ testAdd("WI.ObjectStore.prototype.add.Object.AutoIncrementWithoutKeyPath", {
+ options: {autoIncrement: true},
+ tests: [
+ {value: InspectorTest.ObjectStore.basicObject1, expected: 1},
+ {value: InspectorTest.ObjectStore.basicObject2, expected: 2},
+ ],
+ });
+
+ testAdd("WI.ObjectStore.prototype.add.Object.KeyPathSetOnObjectWithoutAutoIncrement.Sub", {
+ options: {keyPath: "KeyPathSetOnObjectWithoutAutoIncrement.Sub"},
+ tests: [
+ {value: {KeyPathSetOnObjectWithoutAutoIncrement: {Sub: 42}, ...InspectorTest.ObjectStore.basicObject1}, expected: 42},
+ {value: {KeyPathSetOnObjectWithoutAutoIncrement: {Sub: 99}, ...InspectorTest.ObjectStore.basicObject2}, expected: 99},
+ ],
+ });
+
+ testAdd("WI.ObjectStore.prototype.add.Object.KeyPathMissingOnObjectWithAutoIncrement.Sub", {
+ options: {keyPath: "KeyPathMissingOnObjectWithAutoIncrement.Sub", autoIncrement: true},
+ tests: [
+ {value: InspectorTest.ObjectStore.basicObject1, expected: 1},
+ {value: InspectorTest.ObjectStore.basicObject2, expected: 2},
+ ],
+ });
+
+ testAdd("WI.ObjectStore.prototype.add.Object.KeyPathSetOnObjectWithAutoIncrement.Sub", {
+ options: {keyPath: "KeyPathSetOnObjectWithAutoIncrement.Sub", autoIncrement: true},
+ tests: [
+ {value: {KeyPathSetOnObjectWithAutoIncrement: {Sub: 42}, ...InspectorTest.ObjectStore.basicObject1}, expected: 42},
+ {value: {KeyPathSetOnObjectWithAutoIncrement: {Sub: 99}, ...InspectorTest.ObjectStore.basicObject2}, expected: 99},
+ ],
+ });
+
+ suite.runTestCasesAndFinish();
+}
+</script>
+</head>
+<body onload="runTest()">
+ <p>Tests WI.ObjectStore.prototype.add.</p>
+</body>
+</html>
--- /dev/null
+Tests WI.ObjectStore.prototype.addObject.
+
+
+== Running test suite: WI.ObjectStore.prototype.addObject
+-- Running test case: WI.ObjectStore.prototype.addObject.NoParameters
+PASS: Should produce an exception.
+TypeError: undefined is not an object (evaluating 'object.toJSON')
+[]
+
+-- Running test case: WI.ObjectStore.prototype.addObject.WithoutKeyPathOrAutoIncrement
+PASS: Should produce an exception.
+DataError: Failed to store record in an IDBObjectStore: The object store uses out-of-line keys and has no key generator and the key parameter was not provided.
+[]
+
+-- Running test case: WI.ObjectStore.prototype.addObject.KeyPathMissingOnObjectWithoutAutoIncrement
+PASS: Should produce an exception.
+DataError: Failed to store record in an IDBObjectStore: Evaluating the object store's key path did not yield a value.
+[]
+
+-- Running test case: WI.ObjectStore.prototype.addObject.KeyPathSetOnObjectWithoutAutoIncrement
+addObject: [{"KeyPathSetOnObjectWithoutAutoIncrement":42,"a":1}]
+addObject: [{"KeyPathSetOnObjectWithoutAutoIncrement":42,"a":1},{"KeyPathSetOnObjectWithoutAutoIncrement":99,"b":2}]
+[{"KeyPathSetOnObjectWithoutAutoIncrement":42,"a":1},{"KeyPathSetOnObjectWithoutAutoIncrement":99,"b":2}]
+
+-- Running test case: WI.ObjectStore.prototype.addObject.KeyPathMissingOnObjectWithAutoIncrement
+addObject: [{"a":1,"KeyPathMissingOnObjectWithAutoIncrement":1}]
+addObject: [{"a":1,"KeyPathMissingOnObjectWithAutoIncrement":1},{"b":2,"KeyPathMissingOnObjectWithAutoIncrement":2}]
+[{"a":1,"KeyPathMissingOnObjectWithAutoIncrement":1},{"b":2,"KeyPathMissingOnObjectWithAutoIncrement":2}]
+
+-- Running test case: WI.ObjectStore.prototype.addObject.KeyPathSetOnObjectWithAutoIncrement
+addObject: [{"KeyPathSetOnObjectWithAutoIncrement":42,"a":1}]
+addObject: [{"KeyPathSetOnObjectWithAutoIncrement":42,"a":1},{"KeyPathSetOnObjectWithAutoIncrement":99,"b":2}]
+[{"KeyPathSetOnObjectWithAutoIncrement":42,"a":1},{"KeyPathSetOnObjectWithAutoIncrement":99,"b":2}]
+
+-- Running test case: WI.ObjectStore.prototype.addObject.AutoIncrementWithoutKeyPath
+addObject: [{"a":1}]
+addObject: [{"a":1},{"b":2}]
+[{"a":1},{"b":2}]
+
+-- Running test case: WI.ObjectStore.prototype.addObject.KeyPathSetOnObjectWithoutAutoIncrement.Sub
+addObject: [{"KeyPathSetOnObjectWithoutAutoIncrement":{"Sub":42},"a":1}]
+addObject: [{"KeyPathSetOnObjectWithoutAutoIncrement":{"Sub":42},"a":1},{"KeyPathSetOnObjectWithoutAutoIncrement":{"Sub":99},"b":2}]
+[{"KeyPathSetOnObjectWithoutAutoIncrement":{"Sub":42},"a":1},{"KeyPathSetOnObjectWithoutAutoIncrement":{"Sub":99},"b":2}]
+
+-- Running test case: WI.ObjectStore.prototype.addObject.KeyPathMissingOnObjectWithAutoIncrement.Sub
+addObject: [{"a":1,"KeyPathMissingOnObjectWithAutoIncrement":{"Sub":1}}]
+addObject: [{"a":1,"KeyPathMissingOnObjectWithAutoIncrement":{"Sub":1}},{"b":2,"KeyPathMissingOnObjectWithAutoIncrement":{"Sub":2}}]
+[{"a":1,"KeyPathMissingOnObjectWithAutoIncrement":{"Sub":1}},{"b":2,"KeyPathMissingOnObjectWithAutoIncrement":{"Sub":2}}]
+
+-- Running test case: WI.ObjectStore.prototype.addObject.KeyPathSetOnObjectWithAutoIncrement.Sub
+addObject: [{"KeyPathSetOnObjectWithAutoIncrement":{"Sub":42},"a":1}]
+addObject: [{"KeyPathSetOnObjectWithAutoIncrement":{"Sub":42},"a":1},{"KeyPathSetOnObjectWithAutoIncrement":{"Sub":99},"b":2}]
+[{"KeyPathSetOnObjectWithAutoIncrement":{"Sub":42},"a":1},{"KeyPathSetOnObjectWithAutoIncrement":{"Sub":99},"b":2}]
+
--- /dev/null
+<!DOCTYPE html>
+<html>
+<head>
+<script src="../../../http/tests/inspector/resources/inspector-test.js"></script>
+<script src="resources/objectStore-utilities.js"></script>
+<script>
+function test()
+{
+ let suite = InspectorTest.ObjectStore.createSuite("WI.ObjectStore.prototype.addObject");
+
+ function testAddObject(name, {options, tests}) {
+ InspectorTest.ObjectStore.wrapTest(name, async function() {
+ InspectorTest.ObjectStore.createObjectStore(options);
+
+ for (let {value, expected} of tests)
+ await InspectorTest.ObjectStore.addObject(new InspectorTest.ObjectStore.TestObject(value), expected);
+ });
+ }
+
+ InspectorTest.ObjectStore.wrapTest("WI.ObjectStore.prototype.addObject.NoParameters", async function() {
+ let objectStore = InspectorTest.ObjectStore.createObjectStore();
+
+ await InspectorTest.expectException(async function() {
+ await objectStore.addObject();
+ await objectStore.addObject(new InspectorTest.ObjectStore.TestObject(InspectorTest.ObjectStore.basicObject2));
+ });
+ });
+
+ InspectorTest.ObjectStore.wrapTest("WI.ObjectStore.prototype.addObject.WithoutKeyPathOrAutoIncrement", async function() {
+ let objectStore = InspectorTest.ObjectStore.createObjectStore();
+
+ await InspectorTest.expectException(async function() {
+ await objectStore.addObject(new InspectorTest.ObjectStore.TestObject(InspectorTest.ObjectStore.basicObject1));
+ await objectStore.addObject(new InspectorTest.ObjectStore.TestObject(InspectorTest.ObjectStore.basicObject2));
+ });
+ });
+
+ InspectorTest.ObjectStore.wrapTest("WI.ObjectStore.prototype.addObject.KeyPathMissingOnObjectWithoutAutoIncrement", async function() {
+ const options = {
+ keyPath: "KeyPathMissingOnObjectWithoutAutoIncrement",
+ };
+ let objectStore = InspectorTest.ObjectStore.createObjectStore(options);
+
+ await InspectorTest.expectException(async function() {
+ await objectStore.addObject(new InspectorTest.ObjectStore.TestObject(InspectorTest.ObjectStore.basicObject1));
+ await objectStore.addObject(new InspectorTest.ObjectStore.TestObject(InspectorTest.ObjectStore.basicObject2));
+ });
+ });
+
+ testAddObject("WI.ObjectStore.prototype.addObject.KeyPathSetOnObjectWithoutAutoIncrement", {
+ options: {keyPath: "KeyPathSetOnObjectWithoutAutoIncrement"},
+ tests: [
+ {value: {KeyPathSetOnObjectWithoutAutoIncrement: 42, ...InspectorTest.ObjectStore.basicObject1}, expected: 42},
+ {value: {KeyPathSetOnObjectWithoutAutoIncrement: 99, ...InspectorTest.ObjectStore.basicObject2}, expected: 99},
+ ],
+ });
+
+ testAddObject("WI.ObjectStore.prototype.addObject.KeyPathMissingOnObjectWithAutoIncrement", {
+ options: {keyPath: "KeyPathMissingOnObjectWithAutoIncrement", autoIncrement: true},
+ tests: [
+ {value: InspectorTest.ObjectStore.basicObject1, expected: 1},
+ {value: InspectorTest.ObjectStore.basicObject2, expected: 2},
+ ],
+ });
+
+ testAddObject("WI.ObjectStore.prototype.addObject.KeyPathSetOnObjectWithAutoIncrement", {
+ options: {keyPath: "KeyPathSetOnObjectWithAutoIncrement", autoIncrement: true},
+ tests: [
+ {value: {KeyPathSetOnObjectWithAutoIncrement: 42, ...InspectorTest.ObjectStore.basicObject1}, expected: 42},
+ {value: {KeyPathSetOnObjectWithAutoIncrement: 99, ...InspectorTest.ObjectStore.basicObject2}, expected: 99},
+ ],
+ });
+
+ testAddObject("WI.ObjectStore.prototype.addObject.AutoIncrementWithoutKeyPath", {
+ options: {autoIncrement: true},
+ tests: [
+ {value: InspectorTest.ObjectStore.basicObject1, expected: 1},
+ {value: InspectorTest.ObjectStore.basicObject2, expected: 2},
+ ],
+ });
+
+ testAddObject("WI.ObjectStore.prototype.addObject.KeyPathSetOnObjectWithoutAutoIncrement.Sub", {
+ options: {keyPath: "KeyPathSetOnObjectWithoutAutoIncrement.Sub"},
+ tests: [
+ {value: {KeyPathSetOnObjectWithoutAutoIncrement: {Sub: 42}, ...InspectorTest.ObjectStore.basicObject1}, expected: 42},
+ {value: {KeyPathSetOnObjectWithoutAutoIncrement: {Sub: 99}, ...InspectorTest.ObjectStore.basicObject2}, expected: 99},
+ ],
+ });
+
+ testAddObject("WI.ObjectStore.prototype.addObject.KeyPathMissingOnObjectWithAutoIncrement.Sub", {
+ options: {keyPath: "KeyPathMissingOnObjectWithAutoIncrement.Sub", autoIncrement: true},
+ tests: [
+ {value: InspectorTest.ObjectStore.basicObject1, expected: 1},
+ {value: InspectorTest.ObjectStore.basicObject2, expected: 2},
+ ],
+ });
+
+ testAddObject("WI.ObjectStore.prototype.addObject.KeyPathSetOnObjectWithAutoIncrement.Sub", {
+ options: {keyPath: "KeyPathSetOnObjectWithAutoIncrement.Sub", autoIncrement: true},
+ tests: [
+ {value: {KeyPathSetOnObjectWithAutoIncrement: {Sub: 42}, ...InspectorTest.ObjectStore.basicObject1}, expected: 42},
+ {value: {KeyPathSetOnObjectWithAutoIncrement: {Sub: 99}, ...InspectorTest.ObjectStore.basicObject2}, expected: 99},
+ ],
+ });
+
+ suite.runTestCasesAndFinish();
+}
+</script>
+</head>
+<body onload="runTest()">
+ <p>Tests WI.ObjectStore.prototype.addObject.</p>
+</body>
+</html>
--- /dev/null
+Tests basic functionality of WI.ObjectStore.
+
+
+== Running test suite: WI.ObjectStore
+-- Running test case: WI.ObjectStore.InitiallyNull
+PASS: The database should initially be null/closed.
+
+-- Running test case: WI.ObjectStore.prototype._resolveKeyPath.Exists
+{"object":{"a":1},"key":["a"],"value":1}
+[]
+
+-- Running test case: WI.ObjectStore.prototype._resolveKeyPath.MissingPart
+{"object":{"sub.a":0,"a":1,"b":2},"key":"sub.a","value":0}
+[]
+
+-- Running test case: WI.ObjectStore.prototype._resolveKeyPath.MissingWhole
+{"object":{"a":1,"b":2},"key":"sub.a"}
+[]
+
--- /dev/null
+<!DOCTYPE html>
+<html>
+<head>
+<script src="../../../http/tests/inspector/resources/inspector-test.js"></script>
+<script src="resources/objectStore-utilities.js"></script>
+<script>
+function test()
+{
+ let suite = InspectorTest.ObjectStore.createSuite("WI.ObjectStore");
+
+ InspectorTest.ObjectStore.wrapTest("WI.ObjectStore.InitiallyNull", async function() {
+ InspectorTest.expectNull(WI.ObjectStore._database, "The database should initially be null/closed.");
+ });
+
+ InspectorTest.ObjectStore.wrapTest("WI.ObjectStore.prototype._resolveKeyPath.Exists", async function() {
+ const options = {
+ keyPath: "sub.a",
+ };
+ let objectStore = InspectorTest.ObjectStore.createObjectStore(options);
+
+ const object = {sub: {a: 1}, b: 2};
+ InspectorTest.log(objectStore._resolveKeyPath(object));
+ });
+
+ InspectorTest.ObjectStore.wrapTest("WI.ObjectStore.prototype._resolveKeyPath.MissingPart", async function() {
+ const options = {
+ keyPath: "sub.a",
+ };
+ let objectStore = InspectorTest.ObjectStore.createObjectStore(options);
+
+ const object = {"sub.a": 0, a: 1, b: 2};
+ InspectorTest.log(objectStore._resolveKeyPath(object));
+ });
+
+ InspectorTest.ObjectStore.wrapTest("WI.ObjectStore.prototype._resolveKeyPath.MissingWhole", async function() {
+ const options = {
+ keyPath: "sub.a",
+ };
+ let objectStore = InspectorTest.ObjectStore.createObjectStore(options);
+
+ const object = {a: 1, b: 2};
+ InspectorTest.log(objectStore._resolveKeyPath(object));
+ });
+
+ suite.runTestCasesAndFinish();
+}
+</script>
+</head>
+<body onload="runTest()">
+ <p>Tests basic functionality of WI.ObjectStore.</p>
+</body>
+</html>
--- /dev/null
+Tests WI.ObjectStore.prototype.delete.
+
+
+== Running test suite: WI.ObjectStore.prototype.delete
+-- Running test case: WI.ObjectStore.prototype.delete.NoParameters
+add: [{"b":2}]
+PASS: Should produce an exception.
+TypeError: Not enough arguments
+[{"b":2}]
+
+-- Running test case: WI.ObjectStore.prototype.delete.MissingObject
+add: [{"b":2}]
+PASS: Should produce an exception.
+DataError: Failed to execute 'delete' on 'IDBObjectStore': The parameter is not a valid key.
+[{"b":2}]
+
+-- Running test case: WI.ObjectStore.prototype.delete.Boolean
+add: [false]
+add: [false,true]
+delete: [true]
+delete: []
+[]
+
+-- Running test case: WI.ObjectStore.prototype.delete.Number
+add: [11]
+add: [11,22]
+delete: [22]
+delete: []
+[]
+
+-- Running test case: WI.ObjectStore.prototype.delete.String
+add: ["foo"]
+add: ["foo","bar"]
+delete: ["bar"]
+delete: []
+[]
+
+-- Running test case: WI.ObjectStore.prototype.delete.Array
+add: [[11]]
+add: [[11],[22]]
+delete: [[22]]
+delete: []
+[]
+
+-- Running test case: WI.ObjectStore.prototype.delete.Null
+add: [null]
+delete: []
+[]
+
+-- Running test case: WI.ObjectStore.prototype.delete.Object.WithoutKeyPathOrAutoIncrement
+PASS: Should produce an exception.
+DataError: Failed to store record in an IDBObjectStore: The object store uses out-of-line keys and has no key generator and the key parameter was not provided.
+[]
+
+-- Running test case: WI.ObjectStore.prototype.delete.Object.KeyPathMissingOnObjectWithoutAutoIncrement
+PASS: Should produce an exception.
+DataError: Failed to store record in an IDBObjectStore: Evaluating the object store's key path did not yield a value.
+[]
+
+-- Running test case: WI.ObjectStore.prototype.delete.Object.KeyPathSetOnObjectWithoutAutoIncrement
+add: [{"KeyPathSetOnObjectWithoutAutoIncrement":42,"a":1}]
+add: [{"KeyPathSetOnObjectWithoutAutoIncrement":42,"a":1},{"KeyPathSetOnObjectWithoutAutoIncrement":99,"b":2}]
+delete: [{"KeyPathSetOnObjectWithoutAutoIncrement":99,"b":2}]
+delete: []
+[]
+
+-- Running test case: WI.ObjectStore.prototype.delete.Object.KeyPathMissingOnObjectWithAutoIncrement
+add: [{"a":1,"KeyPathMissingOnObjectWithAutoIncrement":1}]
+add: [{"a":1,"KeyPathMissingOnObjectWithAutoIncrement":1},{"b":2,"KeyPathMissingOnObjectWithAutoIncrement":2}]
+delete: [{"b":2,"KeyPathMissingOnObjectWithAutoIncrement":2}]
+delete: []
+[]
+
+-- Running test case: WI.ObjectStore.prototype.delete.Object.KeyPathSetOnObjectWithAutoIncrement
+add: [{"KeyPathSetOnObjectWithAutoIncrement":42,"a":1}]
+add: [{"KeyPathSetOnObjectWithAutoIncrement":42,"a":1},{"KeyPathSetOnObjectWithAutoIncrement":99,"b":2}]
+delete: [{"KeyPathSetOnObjectWithAutoIncrement":99,"b":2}]
+delete: []
+[]
+
+-- Running test case: WI.ObjectStore.prototype.delete.Object.AutoIncrementWithoutKeyPath
+add: [{"a":1}]
+add: [{"a":1},{"b":2}]
+delete: [{"b":2}]
+delete: []
+[]
+
+-- Running test case: WI.ObjectStore.prototype.delete.Object.KeyPathSetOnObjectWithoutAutoIncrement.Sub
+add: [{"KeyPathSetOnObjectWithoutAutoIncrement":{"Sub":42},"a":1}]
+add: [{"KeyPathSetOnObjectWithoutAutoIncrement":{"Sub":42},"a":1},{"KeyPathSetOnObjectWithoutAutoIncrement":{"Sub":99},"b":2}]
+delete: [{"KeyPathSetOnObjectWithoutAutoIncrement":{"Sub":99},"b":2}]
+delete: []
+[]
+
+-- Running test case: WI.ObjectStore.prototype.delete.Object.KeyPathMissingOnObjectWithAutoIncrement.Sub
+add: [{"a":1,"KeyPathMissingOnObjectWithAutoIncrement":{"Sub":1}}]
+add: [{"a":1,"KeyPathMissingOnObjectWithAutoIncrement":{"Sub":1}},{"b":2,"KeyPathMissingOnObjectWithAutoIncrement":{"Sub":2}}]
+delete: [{"b":2,"KeyPathMissingOnObjectWithAutoIncrement":{"Sub":2}}]
+delete: []
+[]
+
+-- Running test case: WI.ObjectStore.prototype.delete.Object.KeyPathSetOnObjectWithAutoIncrement.Sub
+add: [{"KeyPathSetOnObjectWithAutoIncrement":{"Sub":42},"a":1}]
+add: [{"KeyPathSetOnObjectWithAutoIncrement":{"Sub":42},"a":1},{"KeyPathSetOnObjectWithAutoIncrement":{"Sub":99},"b":2}]
+delete: [{"KeyPathSetOnObjectWithAutoIncrement":{"Sub":99},"b":2}]
+delete: []
+[]
+
--- /dev/null
+<!DOCTYPE html>
+<html>
+<head>
+<script src="../../../http/tests/inspector/resources/inspector-test.js"></script>
+<script src="resources/objectStore-utilities.js"></script>
+<script>
+function test()
+{
+ let suite = InspectorTest.ObjectStore.createSuite("WI.ObjectStore.prototype.delete");
+
+ function testDelete(name, {options, tests}) {
+ InspectorTest.ObjectStore.wrapTest(name, async function() {
+ InspectorTest.ObjectStore.createObjectStore(options);
+
+ let keys = [];
+ for (let {value, expected} of tests)
+ keys.push(await InspectorTest.ObjectStore.add(value, expected));
+
+ for (let key of keys)
+ await InspectorTest.ObjectStore.delete(key);
+ });
+ }
+
+ InspectorTest.ObjectStore.wrapTest("WI.ObjectStore.prototype.delete.NoParameters", async function() {
+ const options = {
+ autoIncrement: true,
+ };
+ let objectStore = InspectorTest.ObjectStore.createObjectStore(options);
+
+ await InspectorTest.ObjectStore.add(InspectorTest.ObjectStore.basicObject2, 1);
+
+ await InspectorTest.expectException(async () => {
+ await objectStore.delete();
+ await objectStore.delete(InspectorTest.ObjectStore.basicObject2);
+ });
+ });
+
+ InspectorTest.ObjectStore.wrapTest("WI.ObjectStore.prototype.delete.MissingObject", async function() {
+ const options = {
+ autoIncrement: true,
+ };
+ let objectStore = InspectorTest.ObjectStore.createObjectStore(options);
+
+ await InspectorTest.ObjectStore.add(InspectorTest.ObjectStore.basicObject2, 1);
+
+ await InspectorTest.expectException(async () => {
+ await objectStore.delete(InspectorTest.ObjectStore.basicObject1);
+ await objectStore.delete(InspectorTest.ObjectStore.basicObject2);
+ });
+ });
+
+ testDelete("WI.ObjectStore.prototype.delete.Boolean", {
+ options: {autoIncrement: true},
+ tests: [
+ {value: false, expected: 1},
+ {value: true, expected: 2},
+ ],
+ });
+
+ testDelete("WI.ObjectStore.prototype.delete.Number", {
+ options: {autoIncrement: true},
+ tests: [
+ {value: 11, expected: 1},
+ {value: 22, expected: 2},
+ ],
+ });
+
+ testDelete("WI.ObjectStore.prototype.delete.String", {
+ options: {autoIncrement: true},
+ tests: [
+ {value: "foo", expected: 1},
+ {value: "bar", expected: 2},
+ ],
+ });
+
+ testDelete("WI.ObjectStore.prototype.delete.Array", {
+ options: {autoIncrement: true},
+ tests: [
+ {value: [11], expected: 1},
+ {value: [22], expected: 2},
+ ],
+ });
+
+ testDelete("WI.ObjectStore.prototype.delete.Null", {
+ options: {autoIncrement: true},
+ tests: [
+ {value: null, expected: 1},
+ ],
+ });
+
+ InspectorTest.ObjectStore.wrapTest("WI.ObjectStore.prototype.delete.Object.WithoutKeyPathOrAutoIncrement", async function() {
+ let objectStore = InspectorTest.ObjectStore.createObjectStore();
+
+ await InspectorTest.expectException(async function() {
+ await objectStore.add(InspectorTest.ObjectStore.basicObject1);
+ await objectStore.add(InspectorTest.ObjectStore.basicObject2);
+ });
+ });
+
+ InspectorTest.ObjectStore.wrapTest("WI.ObjectStore.prototype.delete.Object.KeyPathMissingOnObjectWithoutAutoIncrement", async function() {
+ const options = {
+ keyPath: "KeyPathMissingOnObjectWithoutAutoIncrement",
+ };
+ let objectStore = InspectorTest.ObjectStore.createObjectStore(options);
+
+ await InspectorTest.expectException(async function() {
+ await objectStore.add(InspectorTest.ObjectStore.basicObject1);
+ await objectStore.add(InspectorTest.ObjectStore.basicObject2);
+ });
+ });
+
+ testDelete("WI.ObjectStore.prototype.delete.Object.KeyPathSetOnObjectWithoutAutoIncrement", {
+ options: {keyPath: "KeyPathSetOnObjectWithoutAutoIncrement"},
+ tests: [
+ {value: {KeyPathSetOnObjectWithoutAutoIncrement: 42, ...InspectorTest.ObjectStore.basicObject1}, expected: 42},
+ {value: {KeyPathSetOnObjectWithoutAutoIncrement: 99, ...InspectorTest.ObjectStore.basicObject2}, expected: 99},
+ ],
+ });
+
+ testDelete("WI.ObjectStore.prototype.delete.Object.KeyPathMissingOnObjectWithAutoIncrement", {
+ options: {keyPath: "KeyPathMissingOnObjectWithAutoIncrement", autoIncrement: true},
+ tests: [
+ {value: InspectorTest.ObjectStore.basicObject1, expected: 1},
+ {value: InspectorTest.ObjectStore.basicObject2, expected: 2},
+ ],
+ });
+
+ testDelete("WI.ObjectStore.prototype.delete.Object.KeyPathSetOnObjectWithAutoIncrement", {
+ options: {keyPath: "KeyPathSetOnObjectWithAutoIncrement", autoIncrement: true},
+ tests: [
+ {value: {KeyPathSetOnObjectWithAutoIncrement: 42, ...InspectorTest.ObjectStore.basicObject1}, expected: 42},
+ {value: {KeyPathSetOnObjectWithAutoIncrement: 99, ...InspectorTest.ObjectStore.basicObject2}, expected: 99},
+ ],
+ });
+
+ testDelete("WI.ObjectStore.prototype.delete.Object.AutoIncrementWithoutKeyPath", {
+ options: {autoIncrement: true},
+ tests: [
+ {value: InspectorTest.ObjectStore.basicObject1, expected: 1},
+ {value: InspectorTest.ObjectStore.basicObject2, expected: 2},
+ ],
+ });
+
+ testDelete("WI.ObjectStore.prototype.delete.Object.KeyPathSetOnObjectWithoutAutoIncrement.Sub", {
+ options: {keyPath: "KeyPathSetOnObjectWithoutAutoIncrement.Sub"},
+ tests: [
+ {value: {KeyPathSetOnObjectWithoutAutoIncrement: {Sub: 42}, ...InspectorTest.ObjectStore.basicObject1}, expected: 42},
+ {value: {KeyPathSetOnObjectWithoutAutoIncrement: {Sub: 99}, ...InspectorTest.ObjectStore.basicObject2}, expected: 99},
+ ],
+ });
+
+ testDelete("WI.ObjectStore.prototype.delete.Object.KeyPathMissingOnObjectWithAutoIncrement.Sub", {
+ options: {keyPath: "KeyPathMissingOnObjectWithAutoIncrement.Sub", autoIncrement: true},
+ tests: [
+ {value: InspectorTest.ObjectStore.basicObject1, expected: 1},
+ {value: InspectorTest.ObjectStore.basicObject2, expected: 2},
+ ],
+ });
+
+ testDelete("WI.ObjectStore.prototype.delete.Object.KeyPathSetOnObjectWithAutoIncrement.Sub", {
+ options: {keyPath: "KeyPathSetOnObjectWithAutoIncrement.Sub", autoIncrement: true},
+ tests: [
+ {value: {KeyPathSetOnObjectWithAutoIncrement: {Sub: 42}, ...InspectorTest.ObjectStore.basicObject1}, expected: 42},
+ {value: {KeyPathSetOnObjectWithAutoIncrement: {Sub: 99}, ...InspectorTest.ObjectStore.basicObject2}, expected: 99},
+ ],
+ });
+
+ suite.runTestCasesAndFinish();
+}
+</script>
+</head>
+<body onload="runTest()">
+ <p>Tests WI.ObjectStore.prototype.delete.</p>
+</body>
+</html>
--- /dev/null
+Tests WI.ObjectStore.prototype.deleteObject.
+
+
+== Running test suite: WI.ObjectStore.prototype.deleteObject
+-- Running test case: WI.ObjectStore.prototype.deleteObject.NoParameters
+add: [{"_object":{"b":2}}]
+PASS: Should produce an exception.
+TypeError: undefined is not an object (evaluating 'object[key]')
+[{"_object":{"b":2}}]
+
+-- Running test case: WI.ObjectStore.prototype.deleteObject.MissingObject
+add: [{"_object":{"b":2}}]
+PASS: Should produce an exception.
+DataError: Failed to execute 'delete' on 'IDBObjectStore': The parameter is not a valid key range.
+[{"_object":{"b":2}}]
+
+-- Running test case: WI.ObjectStore.prototype.deleteObject.KeyPathMissingOnObjectWithoutAutoIncrement
+PASS: Should produce an exception.
+DataError: Failed to execute 'delete' on 'IDBObjectStore': The parameter is not a valid key range.
+[]
+
+-- Running test case: WI.ObjectStore.prototype.deleteObject.WithoutKeyPathOrAutoIncrement
+PASS: Should produce an exception.
+DataError: Failed to store record in an IDBObjectStore: The object store uses out-of-line keys and has no key generator and the key parameter was not provided.
+[]
+
+-- Running test case: WI.ObjectStore.prototype.deleteObject.KeyPathMissingOnObjectWithoutAutoIncrement
+PASS: Should produce an exception.
+DataError: Failed to store record in an IDBObjectStore: Evaluating the object store's key path did not yield a value.
+[]
+
+-- Running test case: WI.ObjectStore.prototype.deleteObject.KeyPathSetOnObjectWithoutAutoIncrement
+addObject: [{"KeyPathSetOnObjectWithoutAutoIncrement":42,"a":1}]
+addObject: [{"KeyPathSetOnObjectWithoutAutoIncrement":42,"a":1},{"KeyPathSetOnObjectWithoutAutoIncrement":99,"b":2}]
+deleteObject: [{"KeyPathSetOnObjectWithoutAutoIncrement":99,"b":2}]
+deleteObject: []
+[]
+
+-- Running test case: WI.ObjectStore.prototype.deleteObject.KeyPathMissingOnObjectWithAutoIncrement
+addObject: [{"a":1,"KeyPathMissingOnObjectWithAutoIncrement":1}]
+addObject: [{"a":1,"KeyPathMissingOnObjectWithAutoIncrement":1},{"b":2,"KeyPathMissingOnObjectWithAutoIncrement":2}]
+deleteObject: [{"b":2,"KeyPathMissingOnObjectWithAutoIncrement":2}]
+deleteObject: []
+[]
+
+-- Running test case: WI.ObjectStore.prototype.deleteObject.KeyPathSetOnObjectWithAutoIncrement
+addObject: [{"KeyPathSetOnObjectWithAutoIncrement":42,"a":1}]
+addObject: [{"KeyPathSetOnObjectWithAutoIncrement":42,"a":1},{"KeyPathSetOnObjectWithAutoIncrement":99,"b":2}]
+deleteObject: [{"KeyPathSetOnObjectWithAutoIncrement":99,"b":2}]
+deleteObject: []
+[]
+
+-- Running test case: WI.ObjectStore.prototype.deleteObject.AutoIncrementWithoutKeyPath
+addObject: [{"a":1}]
+addObject: [{"a":1},{"b":2}]
+deleteObject: [{"b":2}]
+deleteObject: []
+[]
+
+-- Running test case: WI.ObjectStore.prototype.deleteObject.KeyPathSetOnObjectWithoutAutoIncrement.Sub
+addObject: [{"KeyPathSetOnObjectWithoutAutoIncrement":{"Sub":42},"a":1}]
+addObject: [{"KeyPathSetOnObjectWithoutAutoIncrement":{"Sub":42},"a":1},{"KeyPathSetOnObjectWithoutAutoIncrement":{"Sub":99},"b":2}]
+deleteObject: [{"KeyPathSetOnObjectWithoutAutoIncrement":{"Sub":99},"b":2}]
+deleteObject: []
+[]
+
+-- Running test case: WI.ObjectStore.prototype.deleteObject.KeyPathMissingOnObjectWithAutoIncrement.Sub
+addObject: [{"a":1,"KeyPathMissingOnObjectWithAutoIncrement":{"Sub":1}}]
+addObject: [{"a":1,"KeyPathMissingOnObjectWithAutoIncrement":{"Sub":1}},{"b":2,"KeyPathMissingOnObjectWithAutoIncrement":{"Sub":2}}]
+deleteObject: [{"b":2,"KeyPathMissingOnObjectWithAutoIncrement":{"Sub":2}}]
+deleteObject: []
+[]
+
+-- Running test case: WI.ObjectStore.prototype.deleteObject.KeyPathSetOnObjectWithAutoIncrement.Sub
+addObject: [{"KeyPathSetOnObjectWithAutoIncrement":{"Sub":42},"a":1}]
+addObject: [{"KeyPathSetOnObjectWithAutoIncrement":{"Sub":42},"a":1},{"KeyPathSetOnObjectWithAutoIncrement":{"Sub":99},"b":2}]
+deleteObject: [{"KeyPathSetOnObjectWithAutoIncrement":{"Sub":99},"b":2}]
+deleteObject: []
+[]
+
--- /dev/null
+<!DOCTYPE html>
+<html>
+<head>
+<script src="../../../http/tests/inspector/resources/inspector-test.js"></script>
+<script src="resources/objectStore-utilities.js"></script>
+<script>
+function test()
+{
+ let suite = InspectorTest.ObjectStore.createSuite("WI.ObjectStore.prototype.deleteObject");
+
+ function testDeleteObject(name, {options, tests}) {
+ InspectorTest.ObjectStore.wrapTest(name, async function() {
+ InspectorTest.ObjectStore.createObjectStore(options);
+
+ let objects = []
+ for (let {value, expected} of tests) {
+ let object = new InspectorTest.ObjectStore.TestObject(value);
+ await InspectorTest.ObjectStore.addObject(object, expected);
+ objects.push(object);
+ }
+
+ for (let object of objects)
+ await InspectorTest.ObjectStore.deleteObject(object);
+ });
+ }
+
+ InspectorTest.ObjectStore.wrapTest("WI.ObjectStore.prototype.deleteObject.NoParameters", async function() {
+ const options = {
+ autoIncrement: true,
+ };
+ let objectStore = InspectorTest.ObjectStore.createObjectStore(options);
+
+ await InspectorTest.ObjectStore.add(new InspectorTest.ObjectStore.TestObject(InspectorTest.ObjectStore.basicObject2), 1);
+
+ await InspectorTest.expectException(async () => {
+ await objectStore.deleteObject();
+ await objectStore.deleteObject(new InspectorTest.ObjectStore.TestObject(InspectorTest.ObjectStore.basicObject2));
+ });
+ });
+
+ InspectorTest.ObjectStore.wrapTest("WI.ObjectStore.prototype.deleteObject.MissingObject", async function() {
+ const options = {
+ autoIncrement: true,
+ };
+ let objectStore = InspectorTest.ObjectStore.createObjectStore(options);
+
+ await InspectorTest.ObjectStore.add(new InspectorTest.ObjectStore.TestObject(InspectorTest.ObjectStore.basicObject2), 1);
+
+ await InspectorTest.expectException(async () => {
+ await objectStore.deleteObject(new InspectorTest.ObjectStore.TestObject(InspectorTest.ObjectStore.basicObject1));
+ await objectStore.deleteObject(new InspectorTest.ObjectStore.TestObject(InspectorTest.ObjectStore.basicObject2));
+ });
+ });
+
+ InspectorTest.ObjectStore.wrapTest("WI.ObjectStore.prototype.deleteObject.KeyPathMissingOnObjectWithoutAutoIncrement", async function() {
+ const options = {
+ keyPath: "KeyPathMissingOnObjectWithoutAutoIncrement",
+ };
+ let objectStore = InspectorTest.ObjectStore.createObjectStore(options);
+
+ await InspectorTest.expectException(async function() {
+ await objectStore.deleteObject(new InspectorTest.ObjectStore.TestObject(InspectorTest.ObjectStore.basicObject1));
+ await objectStore.deleteObject(new InspectorTest.ObjectStore.TestObject(InspectorTest.ObjectStore.basicObject2));
+ });
+ });
+
+ InspectorTest.ObjectStore.wrapTest("WI.ObjectStore.prototype.deleteObject.WithoutKeyPathOrAutoIncrement", async function() {
+ let objectStore = InspectorTest.ObjectStore.createObjectStore();
+
+ await InspectorTest.expectException(async function() {
+ await objectStore.add(InspectorTest.ObjectStore.basicObject1);
+ await objectStore.add(InspectorTest.ObjectStore.basicObject2);
+ });
+ });
+
+ InspectorTest.ObjectStore.wrapTest("WI.ObjectStore.prototype.deleteObject.KeyPathMissingOnObjectWithoutAutoIncrement", async function() {
+ const options = {
+ keyPath: "KeyPathMissingOnObjectWithoutAutoIncrement",
+ };
+ let objectStore = InspectorTest.ObjectStore.createObjectStore(options);
+
+ await InspectorTest.expectException(async function() {
+ await objectStore.add(InspectorTest.ObjectStore.basicObject1);
+ await objectStore.add(InspectorTest.ObjectStore.basicObject2);
+ });
+ });
+
+ testDeleteObject("WI.ObjectStore.prototype.deleteObject.KeyPathSetOnObjectWithoutAutoIncrement", {
+ options: {keyPath: "KeyPathSetOnObjectWithoutAutoIncrement"},
+ tests: [
+ {value: {KeyPathSetOnObjectWithoutAutoIncrement: 42, ...InspectorTest.ObjectStore.basicObject1}, expected: 42},
+ {value: {KeyPathSetOnObjectWithoutAutoIncrement: 99, ...InspectorTest.ObjectStore.basicObject2}, expected: 99},
+ ],
+ });
+
+ testDeleteObject("WI.ObjectStore.prototype.deleteObject.KeyPathMissingOnObjectWithAutoIncrement", {
+ options: {keyPath: "KeyPathMissingOnObjectWithAutoIncrement", autoIncrement: true},
+ tests: [
+ {value: InspectorTest.ObjectStore.basicObject1, expected: 1},
+ {value: InspectorTest.ObjectStore.basicObject2, expected: 2},
+ ],
+ });
+
+ testDeleteObject("WI.ObjectStore.prototype.deleteObject.KeyPathSetOnObjectWithAutoIncrement", {
+ options: {keyPath: "KeyPathSetOnObjectWithAutoIncrement", autoIncrement: true},
+ tests: [
+ {value: {KeyPathSetOnObjectWithAutoIncrement: 42, ...InspectorTest.ObjectStore.basicObject1}, expected: 42},
+ {value: {KeyPathSetOnObjectWithAutoIncrement: 99, ...InspectorTest.ObjectStore.basicObject2}, expected: 99},
+ ],
+ });
+
+ testDeleteObject("WI.ObjectStore.prototype.deleteObject.AutoIncrementWithoutKeyPath", {
+ options: {autoIncrement: true},
+ tests: [
+ {value: InspectorTest.ObjectStore.basicObject1, expected: 1},
+ {value: InspectorTest.ObjectStore.basicObject2, expected: 2},
+ ],
+ });
+
+ testDeleteObject("WI.ObjectStore.prototype.deleteObject.KeyPathSetOnObjectWithoutAutoIncrement.Sub", {
+ options: {keyPath: "KeyPathSetOnObjectWithoutAutoIncrement.Sub"},
+ tests: [
+ {value: {KeyPathSetOnObjectWithoutAutoIncrement: {Sub: 42}, ...InspectorTest.ObjectStore.basicObject1}, expected: 42},
+ {value: {KeyPathSetOnObjectWithoutAutoIncrement: {Sub: 99}, ...InspectorTest.ObjectStore.basicObject2}, expected: 99},
+ ],
+ });
+
+ testDeleteObject("WI.ObjectStore.prototype.deleteObject.KeyPathMissingOnObjectWithAutoIncrement.Sub", {
+ options: {keyPath: "KeyPathMissingOnObjectWithAutoIncrement.Sub", autoIncrement: true},
+ tests: [
+ {value: InspectorTest.ObjectStore.basicObject1, expected: 1},
+ {value: InspectorTest.ObjectStore.basicObject2, expected: 2},
+ ],
+ });
+
+ testDeleteObject("WI.ObjectStore.prototype.deleteObject.KeyPathSetOnObjectWithAutoIncrement.Sub", {
+ options: {keyPath: "KeyPathSetOnObjectWithAutoIncrement.Sub", autoIncrement: true},
+ tests: [
+ {value: {KeyPathSetOnObjectWithAutoIncrement: {Sub: 42}, ...InspectorTest.ObjectStore.basicObject1}, expected: 42},
+ {value: {KeyPathSetOnObjectWithAutoIncrement: {Sub: 99}, ...InspectorTest.ObjectStore.basicObject2}, expected: 99},
+ ],
+ });
+
+ suite.runTestCasesAndFinish();
+}
+</script>
+</head>
+<body onload="runTest()">
+ <p>Tests WI.ObjectStore.prototype.deleteObject.</p>
+</body>
+</html>
--- /dev/null
+TestPage.registerInitializer(() => {
+ let suite = null;
+
+ InspectorTest.ObjectStore = {};
+
+ InspectorTest.ObjectStore.TestObject = class TestObject {
+ constructor(object) {
+ this._object = object;
+ }
+ toJSON() {
+ return this._object;
+ }
+ };
+
+ InspectorTest.ObjectStore.basicObject1 = {a: 1};
+ InspectorTest.ObjectStore.basicObject2 = {b: 2};
+
+ InspectorTest.ObjectStore.createSuite = function(name) {
+ suite = InspectorTest.createAsyncSuite(name);
+ return suite;
+ };
+
+ InspectorTest.ObjectStore.createObjectStore = function(options = {}) {
+ WI.ObjectStore.__testObjectStore = new WI.ObjectStore("__testing", options);
+ return WI.ObjectStore.__testObjectStore;
+ };
+
+ InspectorTest.ObjectStore.add = async function(value, expected) {
+ let result = await WI.ObjectStore.__testObjectStore.add(value);
+ InspectorTest.assert(result === expected, `the key of the added item should be ${expected}, but is actually ${result}`);
+
+ await InspectorTest.ObjectStore.logValues("add: ");
+ return result;
+ };
+
+ InspectorTest.ObjectStore.addObject = async function(object, expected) {
+ let result = await WI.ObjectStore.__testObjectStore.addObject(object);
+ InspectorTest.assert(result === expected, `the key of the added item should be ${expected}, but is actually ${result}`);
+
+ let resolved = WI.ObjectStore.__testObjectStore._resolveKeyPath(object);
+ InspectorTest.assert(resolved.value === expected, `the resolved keyPath on the object should equal ${expected}, but is actually ${resolved.value}`);
+
+ await InspectorTest.ObjectStore.logValues("addObject: ");
+ return result;
+ };
+
+ InspectorTest.ObjectStore.delete = async function(value) {
+ let result = await WI.ObjectStore.__testObjectStore.delete(value);
+ InspectorTest.assert(result === undefined, `delete shouldn't return anything`);
+
+ await InspectorTest.ObjectStore.logValues("delete: ");
+ };
+
+ InspectorTest.ObjectStore.deleteObject = async function(object) {
+ let resolved = WI.ObjectStore.__testObjectStore._resolveKeyPath(object);
+ InspectorTest.assert(resolved.key in resolved.object, `the resolved keyPath on the object should exist`);
+
+ let result = await WI.ObjectStore.__testObjectStore.deleteObject(object);
+ InspectorTest.assert(result === undefined, `deleteObject shouldn't return anything`);
+
+ await InspectorTest.ObjectStore.logValues("deleteObject: ");
+ };
+
+ InspectorTest.ObjectStore.logValues = async function(prefix) {
+ if (!WI.ObjectStore.__testObjectStore)
+ return;
+
+ prefix = prefix || "";
+ let results = await WI.ObjectStore.__testObjectStore.getAll();
+ InspectorTest.log(prefix + JSON.stringify(results));
+ };
+
+ InspectorTest.ObjectStore.wrapTest = function(name, func) {
+ suite.addTestCase({
+ name,
+ async test() {
+ InspectorTest.assert(!WI.ObjectStore.__testObjectStore, "__testObjectStore should be deleted after each test");
+
+ await func();
+ await InspectorTest.ObjectStore.logValues();
+
+ delete WI.ObjectStore.__testObjectStore;
+
+ if (WI.ObjectStore._database) {
+ WI.ObjectStore._database.close();
+ WI.ObjectStore._database = null;
+ }
+
+ indexedDB.deleteDatabase(WI.ObjectStore._databaseName);
+ },
+ });
+ };
+});
+2018-10-31 Devin Rousso <drousso@apple.com>
+
+ Web Inspector: Audit: save imported audits across WebInspector sessions
+ https://bugs.webkit.org/show_bug.cgi?id=190858
+ <rdar://problem/45527625>
+
+ Reviewed by Brian Burg.
+
+ * UserInterface/Base/ObjectStore.js: Added.
+ (WI.ObjectStore):
+ (WI.ObjectStore.supported):
+ (WI.ObjectStore._open):
+ (WI.ObjectStore.get _databaseName):
+ (WI.ObjectStore.prototype.associateObject):
+ (WI.ObjectStore.prototype.async getAll):
+ (WI.ObjectStore.prototype.async add):
+ (WI.ObjectStore.prototype.async addObject):
+ (WI.ObjectStore.prototype.async delete):
+ (WI.ObjectStore.prototype.async deleteObject):
+ (WI.ObjectStore.prototype._resolveKeyPath):
+ (WI.ObjectStore.prototype.async _operation.listener):
+ (WI.ObjectStore.prototype.async _operation):
+ Wrapper for a global `IndexedDB` instance for all of WebInspector (per level). Instances of
+ `WI.ObjectStore` are able to control a given `IDBObjectStore` using a promise-based API.
+
+ *NOTE*: due to the constraint that `IDBObjectStore`s are only able to be created when the
+ owner `IndexedDB` is "upgrade"d, all `WI.ObjectStore` must be declared before the database
+ is opened for the first time. Additionally, any time a new `WI.ObjectStore` is added, the
+ `version` needs to be incremented to ensure that the "upgrade" event fires.
+
+ To use any of the `*Object` functions, one must implement a `toJSON` on the object provided.
+ This is so that `WI.ObjectStore` is able to add the resulting identifier value to the owner
+ object while storing its `toJSON` value in the IndexedDB (e.g. for objects that have cycles).
+
+ * UserInterface/Controllers/AuditManager.js:
+ (WI.AuditManager.prototype.import):
+ (WI.AuditManager.prototype.loadStoredTests): Added.
+ (WI.AuditManager.prototype.removeTest): Added.
+ (WI.AuditManager.prototype._addTest):
+
+ * UserInterface/Views/AuditTabContentView.js:
+ (WI.AuditTabContentView.prototype.initialLayout): Added.
+ Attempt to load stored audits when the Audit tab is first shown (lazy-load).
+
+ * UserInterface/Views/AuditNavigationSidebarPanel.js:
+ (WI.AuditNavigationSidebarPanel.prototype.initialLayout):
+ (WI.AuditNavigationSidebarPanel.prototype._handleAuditTestRemoved): Added.
+
+ * UserInterface/Views/AuditTreeElement.js:
+ (WI.AuditTreeElement.prototype.ondelete):
+ Only allow top-level audits to be deleted, as that is what matches the `WI.ObjectStore`.
+
+ * UserInterface/Main.html:
+ * UserInterface/Test.html:
+
2018-10-31 Joseph Pecoraro <pecoraro@apple.com>
Web Inspector: Move a few remaining global WI settings to WI.settings
--- /dev/null
+/*
+ * Copyright (C) 2018 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+WI.ObjectStore = class ObjectStore
+{
+ constructor(name, options = {})
+ {
+ this._name = name;
+ this._options = options;
+ }
+
+ // Static
+
+ static supported()
+ {
+ return (!window.InspectorTest || WI.ObjectStore.__testObjectStore) && window.indexedDB;
+ }
+
+ static get _databaseName()
+ {
+ let inspectionLevel = InspectorFrontendHost ? InspectorFrontendHost.inspectionLevel() : 1;
+ let levelString = (inspectionLevel > 1) ? "-" + inspectionLevel : "";
+ return "com.apple.WebInspector" + levelString;
+ }
+
+ static _open(callback)
+ {
+ if (WI.ObjectStore._database) {
+ callback(WI.ObjectStore._database);
+ return;
+ }
+
+ const version = 1; // Increment this for every edit to `WI.objectStores`.
+
+ let databaseRequest = indexedDB.open(WI.ObjectStore._databaseName, version);
+ databaseRequest.addEventListener("upgradeneeded", (event) => {
+ let database = databaseRequest.result;
+
+ let objectStores = Object.values(WI.objectStores);
+ if (WI.ObjectStore.__testObjectStore)
+ objectStores.push(WI.ObjectStore.__testObjectStore);
+
+ let existingNames = new Set;
+ for (let objectStore of objectStores) {
+ if (!database.objectStoreNames.contains(objectStore._name))
+ database.createObjectStore(objectStore._name, objectStore._options);
+
+ existingNames.add(objectStore._name);
+ }
+
+ for (let objectStoreName of database.objectStoreNames) {
+ if (!existingNames.has(objectStoreName))
+ database.deleteObjectStore(objectStoreName);
+ }
+ });
+ databaseRequest.addEventListener("success", (successEvent) => {
+ WI.ObjectStore._database = databaseRequest.result;
+ WI.ObjectStore._database.addEventListener("close", (closeEvent) => {
+ WI.ObjectStore._database = null;
+ });
+
+ callback(WI.ObjectStore._database);
+ });
+ }
+
+ // Public
+
+ associateObject(object, key, value)
+ {
+ if (typeof value === "object")
+ value = this._resolveKeyPath(value, key).value;
+
+ let resolved = this._resolveKeyPath(object, key);
+ resolved.object[resolved.key] = value;
+ }
+
+ async getAll(...args)
+ {
+ if (!WI.ObjectStore.supported())
+ return undefined;
+
+ return this._operation("readonly", (objectStore) => objectStore.getAll(...args));
+ }
+
+ async add(...args)
+ {
+ if (!WI.ObjectStore.supported())
+ return undefined;
+
+ return this._operation("readwrite", (objectStore) => objectStore.add(...args));
+ }
+
+ async addObject(object, ...args)
+ {
+ if (!WI.ObjectStore.supported())
+ return undefined;
+
+ console.assert(typeof object.toJSON === "function", "ObjectStore cannot store an object without JSON serialization", object.constructor.name);
+ let result = await this.add(object.toJSON(), ...args);
+ this.associateObject(object, args[0], result);
+ return result;
+ }
+
+ async delete(...args)
+ {
+ if (!WI.ObjectStore.supported())
+ return undefined;
+
+ return this._operation("readwrite", (objectStore) => objectStore.delete(...args));
+ }
+
+ async deleteObject(object, ...args)
+ {
+ if (!WI.ObjectStore.supported())
+ return undefined;
+
+ return this.delete(this._resolveKeyPath(object).value, ...args);
+ }
+
+ // Private
+
+ _resolveKeyPath(object, keyPath)
+ {
+ keyPath = keyPath || this._options.keyPath || "";
+
+ let parts = keyPath.split(".");
+ let key = parts.splice(-1, 1);
+ while (parts.length) {
+ if (!object.hasOwnProperty(parts[0]))
+ break;
+ object = object[parts.shift()];
+ }
+
+ if (parts.length)
+ key = parts.join(".") + "." + key;
+
+ return {
+ object,
+ key,
+ value: object[key],
+ };
+ }
+
+ async _operation(mode, func)
+ {
+ // IndexedDB transactions will auto-close if there are no active operations at the end of a
+ // microtask, so we need to do everything using event listeners instead of promises.
+ return new Promise((resolve, reject) => {
+ WI.ObjectStore._open((database) => {
+ let transaction = database.transaction([this._name], mode);
+ let objectStore = transaction.objectStore(this._name);
+ let request = null;
+
+ try {
+ request = func(objectStore);
+ } catch (e) {
+ reject(e);
+ return;
+ }
+
+ function listener(event) {
+ transaction.removeEventListener("complete", listener);
+ transaction.removeEventListener("error", listener);
+ request.removeEventListener("success", listener);
+ request.removeEventListener("error", listener);
+
+ if (request.error) {
+ reject(request.error);
+ return;
+ }
+
+ resolve(request.result);
+ }
+ transaction.addEventListener("complete", listener, {once: true});
+ transaction.addEventListener("error", listener, {once: true});
+ request.addEventListener("success", listener, {once: true});
+ request.addEventListener("error", listener, {once: true});
+ });
+ });
+ }
+};
+
+WI.ObjectStore._database = null;
+
+// Be sure to update the `version` above when making changes.
+WI.objectStores = {
+ audits: new WI.ObjectStore("audit-manager-tests", {keyPath: "__id", autoIncrement: true}),
+};
}
}
- if (object instanceof WI.AuditTestBase)
+ if (object instanceof WI.AuditTestBase) {
this._addTest(object);
- else if (object instanceof WI.AuditTestResultBase)
+ WI.objectStores.audits.addObject(object);
+ } else if (object instanceof WI.AuditTestResultBase)
this._addResult(object);
});
}
});
}
+ loadStoredTests()
+ {
+ WI.objectStores.audits.getAll().then(async (tests) => {
+ for (let payload of tests) {
+ let test = await WI.AuditTestGroup.fromPayload(payload) || await WI.AuditTestCase.fromPayload(payload);
+ if (!test)
+ continue;
+
+ const key = null;
+ WI.objectStores.audits.associateObject(test, key, payload);
+
+ this._addTest(test);
+ }
+ });
+ }
+
+ removeTest(test)
+ {
+ this._tests.remove(test);
+
+ this.dispatchEventToListeners(WI.AuditManager.Event.TestRemoved, {test});
+
+ WI.objectStores.audits.deleteObject(test);
+ }
+
// Private
_addTest(test)
WI.AuditManager.Event = {
TestAdded: "audit-manager-test-added",
TestCompleted: "audit-manager-test-completed",
+ TestRemoved: "audit-manager-test-removed",
TestScheduled: "audit-manager-test-scheduled",
};
<script src="Base/ImageUtilities.js"></script>
<script src="Base/LoadLocalizedStrings.js"></script>
<script src="Base/MIMETypeUtilities.js"></script>
+ <script src="Base/ObjectStore.js"></script>
<script src="Base/URLUtilities.js"></script>
<script src="Base/Utilities.js"></script>
<script src="Base/Setting.js"></script>
<script src="Base/EventListenerSet.js"></script>
<script src="Base/ImageUtilities.js"></script>
<script src="Base/MIMETypeUtilities.js"></script>
+ <script src="Base/ObjectStore.js"></script>
<script src="Base/URLUtilities.js"></script>
<script src="Base/Utilities.js"></script>
<script src="Base/Setting.js"></script>
WI.auditManager.addEventListener(WI.AuditManager.Event.TestAdded, this._handleAuditTestAdded, this);
WI.auditManager.addEventListener(WI.AuditManager.Event.TestCompleted, this._handleAuditTestCompleted, this);
+ WI.auditManager.addEventListener(WI.AuditManager.Event.TestRemoved, this._handleAuditTestRemoved, this);
WI.auditManager.addEventListener(WI.AuditManager.Event.TestScheduled, this._handleAuditTestScheduled, this);
this.contentTreeOutline.addEventListener(WI.TreeOutline.Event.SelectionDidChange, this._treeSelectionDidChange, this);
this._addResult(result, index);
}
+ _handleAuditTestRemoved(event)
+ {
+ let {test} = event.data;
+ let treeElement = this.treeElementForRepresentedObject(test);
+ this.contentTreeOutline.removeChild(treeElement);
+ }
+
_handleAuditTestScheduled(event)
{
this._updateStartStopButtonNavigationItemState();
super.hidden();
}
+ // Protected
+
+ initialLayout()
+ {
+ super.initialLayout();
+
+ WI.auditManager.loadStoredTests();
+ }
+
// Private
_handleSpace(event)
}
}
+ ondelete()
+ {
+ if (!(this.representedObject instanceof WI.AuditTestBase))
+ return false;
+
+ if (!(this.parent instanceof WI.TreeOutline))
+ return false;
+
+ WI.auditManager.removeTest(this.representedObject);
+
+ return true;
+ }
+
populateContextMenu(contextMenu, event)
{
if (WI.auditManager.runningState === WI.AuditManager.RunningState.Inactive) {