Source code
Revision control
Copy as Markdown
Other Tools
Test Info:
/* Any copyright is dedicated to the Public Domain.
add_task(async function test_metadata() {
await PlacesUtils.metadata.set("test/integer", 123);
Assert.strictEqual(
await PlacesUtils.metadata.get("test/integer"),
123,
"Should store new integer value"
);
await PlacesUtils.metadata.set("test/double", 123.45);
Assert.strictEqual(
await PlacesUtils.metadata.get("test/double"),
123.45,
"Should store new double value"
);
await PlacesUtils.metadata.set("test/double", 567.89);
Assert.strictEqual(
await PlacesUtils.metadata.get("test/double"),
567.89,
"Should update existing double value"
);
await PlacesUtils.metadata.set("test/boolean", false);
Assert.strictEqual(
await PlacesUtils.metadata.get("test/boolean"),
false,
"Should store new Boolean value"
);
await PlacesUtils.metadata.set("test/boolean", true);
Assert.strictEqual(
await PlacesUtils.metadata.get("test/boolean"),
true,
"Should update existing Boolean value"
);
await PlacesUtils.metadata.set("test/string", "hi");
Assert.equal(
await PlacesUtils.metadata.get("test/string"),
"hi",
"Should store new string value"
);
await PlacesUtils.metadata.cache.clear();
Assert.equal(
await PlacesUtils.metadata.get("test/string"),
"hi",
"Should return string value after clearing cache"
);
await Assert.rejects(
PlacesUtils.metadata.get("test/nonexistent"),
/No data stored for key test\/nonexistent/,
"Should reject for a non-existent key and no default value."
);
Assert.equal(
await PlacesUtils.metadata.get("test/nonexistent", "defaultValue"),
"defaultValue",
"Should return the default value for a non-existent key."
);
// Values are untyped; it's OK to store a value of a different type for the
// same key.
await PlacesUtils.metadata.set("test/string", 111);
Assert.strictEqual(
await PlacesUtils.metadata.get("test/string"),
111,
"Should replace string with integer"
);
await PlacesUtils.metadata.set("test/string", null);
await Assert.rejects(
PlacesUtils.metadata.get("test/string"),
/No data stored for key test\/string/,
"Should clear value when setting to NULL"
);
await PlacesUtils.metadata.delete("test/string", "test/boolean");
await Assert.rejects(
PlacesUtils.metadata.get("test/string"),
/No data stored for key test\/string/,
"Should delete string value"
);
await Assert.rejects(
PlacesUtils.metadata.get("test/boolean"),
/No data stored for key test\/boolean/,
"Should delete Boolean value"
);
Assert.strictEqual(
await PlacesUtils.metadata.get("test/integer"),
123,
"Should keep undeleted integer value"
);
await PlacesTestUtils.clearMetadata();
await Assert.rejects(
PlacesUtils.metadata.get("test/integer"),
/No data stored for key test\/integer/,
"Should clear integer value"
);
await Assert.rejects(
PlacesUtils.metadata.get("test/double"),
/No data stored for key test\/double/,
"Should clear double value"
);
});
add_task(async function test_metadata_canonical_keys() {
await PlacesUtils.metadata.set("Test/Integer", 123);
Assert.strictEqual(
await PlacesUtils.metadata.get("tEsT/integer"),
123,
"New keys should be case-insensitive"
);
await PlacesUtils.metadata.set("test/integer", 456);
Assert.strictEqual(
await PlacesUtils.metadata.get("TEST/INTEGER"),
456,
"Existing keys should be case-insensitive"
);
await Assert.rejects(
PlacesUtils.metadata.set("", 123),
/Invalid metadata key/,
"Should reject empty keys"
);
await Assert.rejects(
PlacesUtils.metadata.get(123),
/Invalid metadata key/,
"Should reject numeric keys"
);
await Assert.rejects(
PlacesUtils.metadata.delete(true),
/Invalid metadata key/,
"Should reject Boolean keys"
);
await Assert.rejects(
PlacesUtils.metadata.set({}),
/Invalid metadata key/,
"Should reject object keys"
);
await Assert.rejects(
PlacesUtils.metadata.get(null),
/Invalid metadata key/,
"Should reject null keys"
);
await Assert.rejects(
PlacesUtils.metadata.delete("!@#$"),
/Invalid metadata key/,
"Should reject keys with invalid characters"
);
});
add_task(async function test_metadata_blobs() {
let blob = new Uint8Array([1, 2, 3]);
await PlacesUtils.metadata.set("test/blob", blob);
let sameBlob = await PlacesUtils.metadata.get("test/blob");
Assert.equal(
ChromeUtils.getClassName(sameBlob),
"Uint8Array",
"Should cache typed array for blob value"
);
Assert.deepEqual(sameBlob, blob, "Should store new blob value");
info("Remove blob from cache");
await PlacesUtils.metadata.cache.clear();
let newBlob = await PlacesUtils.metadata.get("test/blob");
Assert.equal(
ChromeUtils.getClassName(newBlob),
"Uint8Array",
"Should inflate blob into typed array"
);
Assert.deepEqual(
newBlob,
blob,
"Should return same blob after clearing cache"
);
await PlacesTestUtils.clearMetadata();
});
add_task(async function test_metadata_arrays() {
let array = [1, 2, 3, "\u2713 \u00E0 la mode"];
await PlacesUtils.metadata.set("test/array", array);
let sameArray = await PlacesUtils.metadata.get("test/array");
Assert.ok(Array.isArray(sameArray), "Should cache array for array value");
Assert.deepEqual(sameArray, array, "Should store new array value");
info("Remove array from cache");
await PlacesUtils.metadata.cache.clear();
let newArray = await PlacesUtils.metadata.get("test/array");
Assert.ok(Array.isArray(newArray), "Should inflate into array");
Assert.deepEqual(
newArray,
array,
"Should return same array after clearing cache"
);
await PlacesTestUtils.clearMetadata();
});
add_task(async function test_metadata_objects() {
let object = { foo: 123, bar: "test", meow: "\u2713 \u00E0 la mode" };
await PlacesUtils.metadata.set("test/object", object);
let sameObject = await PlacesUtils.metadata.get("test/object");
Assert.equal(
typeof sameObject,
"object",
"Should cache object for object value"
);
Assert.deepEqual(sameObject, object, "Should store new object value");
info("Remove object from cache");
await PlacesUtils.metadata.cache.clear();
let newObject = await PlacesUtils.metadata.get("test/object");
Assert.equal(typeof newObject, "object", "Should inflate into object");
Assert.deepEqual(
newObject,
object,
"Should return same object after clearing cache"
);
await PlacesTestUtils.clearMetadata();
});
add_task(async function test_metadata_unparsable() {
await PlacesUtils.withConnectionWrapper("test_medata", db => {
let data = PlacesUtils.metadata._base64Encode("{hjjkhj}");
return db.execute(`
INSERT INTO moz_meta (key, value)
VALUES ("test/unparsable", "data:application/json;base64,${data}")
`);
});
await Assert.rejects(
PlacesUtils.metadata.get("test/unparsable"),
/SyntaxError: JSON.parse/,
"Should reject for an unparsable value with no default"
);
Assert.deepEqual(
await PlacesUtils.metadata.get("test/unparsable", { foo: 1 }),
{ foo: 1 },
"Should return the default when encountering an unparsable value."
);
await PlacesTestUtils.clearMetadata();
});
add_task(async function test_metadata_setMany() {
await PlacesUtils.metadata.setMany(
new Map([
["test/string", "hi"],
["test/boolean", true],
])
);
await PlacesUtils.metadata.set("test/string", "hi");
Assert.deepEqual(
await PlacesUtils.metadata.get("test/string"),
"hi",
"Should store new string value"
);
Assert.deepEqual(
await PlacesUtils.metadata.get("test/boolean"),
true,
"Should store new boolean value"
);
await PlacesUtils.metadata.cache.clear();
Assert.equal(
await PlacesUtils.metadata.get("test/string"),
"hi",
"Should return string value after clearing cache"
);
Assert.deepEqual(
await PlacesUtils.metadata.get("test/boolean"),
true,
"Should store new boolean value"
);
await PlacesTestUtils.clearMetadata();
});