forked from mirrors/gecko-dev
		
	
		
			
				
	
	
		
			207 lines
		
	
	
	
		
			5.4 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			207 lines
		
	
	
	
		
			5.4 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
const { SharedDataMap } = ChromeUtils.importESModule(
 | 
						|
  "resource://nimbus/lib/SharedDataMap.sys.mjs"
 | 
						|
);
 | 
						|
const { FileTestUtils } = ChromeUtils.importESModule(
 | 
						|
  "resource://testing-common/FileTestUtils.sys.mjs"
 | 
						|
);
 | 
						|
const { TestUtils } = ChromeUtils.importESModule(
 | 
						|
  "resource://testing-common/TestUtils.sys.mjs"
 | 
						|
);
 | 
						|
 | 
						|
const PATH = FileTestUtils.getTempFile("shared-data-map").path;
 | 
						|
 | 
						|
function with_sharedDataMap(test) {
 | 
						|
  let testTask = async () => {
 | 
						|
    const sandbox = sinon.createSandbox();
 | 
						|
    const instance = new SharedDataMap("xpcshell", {
 | 
						|
      path: PATH,
 | 
						|
      isParent: true,
 | 
						|
    });
 | 
						|
    try {
 | 
						|
      await test({ instance, sandbox });
 | 
						|
    } finally {
 | 
						|
      sandbox.restore();
 | 
						|
    }
 | 
						|
  };
 | 
						|
 | 
						|
  // Copy the name of the test function to identify the test
 | 
						|
  Object.defineProperty(testTask, "name", { value: test.name });
 | 
						|
  add_task(testTask);
 | 
						|
}
 | 
						|
 | 
						|
with_sharedDataMap(async function test_set_notify({ instance, sandbox }) {
 | 
						|
  await instance.init();
 | 
						|
  let updateStub = sandbox.stub();
 | 
						|
 | 
						|
  instance.on("parent-store-update:foo", updateStub);
 | 
						|
  instance.set("foo", "bar");
 | 
						|
 | 
						|
  Assert.equal(updateStub.callCount, 1, "Update event sent");
 | 
						|
  Assert.equal(updateStub.firstCall.args[1], "bar", "Update event sent value");
 | 
						|
});
 | 
						|
 | 
						|
with_sharedDataMap(async function test_set_child_notify({ instance, sandbox }) {
 | 
						|
  await instance.init();
 | 
						|
 | 
						|
  let updateStub = sandbox.stub();
 | 
						|
  const childInstance = new SharedDataMap("xpcshell", {
 | 
						|
    path: PATH,
 | 
						|
    isParent: false,
 | 
						|
  });
 | 
						|
 | 
						|
  childInstance.on("child-store-update:foo", updateStub);
 | 
						|
  let childStoreUpdate = new Promise(resolve =>
 | 
						|
    childInstance.on("child-store-update:foo", resolve)
 | 
						|
  );
 | 
						|
  instance.set("foo", "bar");
 | 
						|
 | 
						|
  await childStoreUpdate;
 | 
						|
 | 
						|
  Assert.equal(updateStub.callCount, 1, "Update event sent");
 | 
						|
  Assert.equal(updateStub.firstCall.args[1], "bar", "Update event sent value");
 | 
						|
});
 | 
						|
 | 
						|
with_sharedDataMap(async function test_async({ instance, sandbox }) {
 | 
						|
  const spy = sandbox.spy(instance._store, "load");
 | 
						|
  await instance.init();
 | 
						|
 | 
						|
  instance.set("foo", "bar");
 | 
						|
 | 
						|
  Assert.equal(spy.callCount, 1, "Should init async");
 | 
						|
  Assert.equal(instance.get("foo"), "bar", "It should retrieve a string value");
 | 
						|
});
 | 
						|
 | 
						|
with_sharedDataMap(async function test_saveSoon({ instance, sandbox }) {
 | 
						|
  await instance.init();
 | 
						|
  const stub = sandbox.stub(instance._store, "saveSoon");
 | 
						|
 | 
						|
  instance.set("foo", "bar");
 | 
						|
 | 
						|
  Assert.equal(stub.callCount, 1, "Should call save soon when setting a value");
 | 
						|
});
 | 
						|
 | 
						|
with_sharedDataMap(async function test_init_safe({ instance, sandbox }) {
 | 
						|
  let stub = sandbox.stub(instance._store, "load");
 | 
						|
  sandbox.replaceGetter(instance._store, "data", () => {
 | 
						|
    throw new Error("expected xpcshell");
 | 
						|
  });
 | 
						|
 | 
						|
  try {
 | 
						|
    await instance.init();
 | 
						|
    Assert.ok(stub.calledOnce, "Load should be called");
 | 
						|
  } catch (e) {
 | 
						|
    Assert.ok(false, "Error should be caught in SharedDataMap");
 | 
						|
  }
 | 
						|
});
 | 
						|
 | 
						|
with_sharedDataMap(async function test_childInit({ instance, sandbox }) {
 | 
						|
  sandbox.stub(instance, "isParent").get(() => false);
 | 
						|
  const stubA = sandbox.stub(instance._store, "ensureDataReady");
 | 
						|
  const stubB = sandbox.stub(instance._store, "load");
 | 
						|
 | 
						|
  await instance.init();
 | 
						|
 | 
						|
  Assert.equal(
 | 
						|
    stubA.callCount,
 | 
						|
    0,
 | 
						|
    "It should not try to initialize sync from child"
 | 
						|
  );
 | 
						|
  Assert.equal(
 | 
						|
    stubB.callCount,
 | 
						|
    0,
 | 
						|
    "It should not try to initialize async from child"
 | 
						|
  );
 | 
						|
});
 | 
						|
 | 
						|
with_sharedDataMap(async function test_parentChildSync_synchronously({
 | 
						|
  instance: parentInstance,
 | 
						|
  sandbox,
 | 
						|
}) {
 | 
						|
  await parentInstance.init();
 | 
						|
  parentInstance.set("foo", { bar: 1 });
 | 
						|
 | 
						|
  const childInstance = new SharedDataMap("xpcshell", {
 | 
						|
    path: PATH,
 | 
						|
    isParent: false,
 | 
						|
  });
 | 
						|
 | 
						|
  await parentInstance.ready();
 | 
						|
  await childInstance.ready();
 | 
						|
 | 
						|
  await TestUtils.waitForCondition(
 | 
						|
    () => childInstance.get("foo"),
 | 
						|
    "Wait for child to sync"
 | 
						|
  );
 | 
						|
 | 
						|
  Assert.deepEqual(
 | 
						|
    childInstance.get("foo"),
 | 
						|
    parentInstance.get("foo"),
 | 
						|
    "Parent and child should be in sync"
 | 
						|
  );
 | 
						|
});
 | 
						|
 | 
						|
with_sharedDataMap(async function test_parentChildSync_async({
 | 
						|
  instance: parentInstance,
 | 
						|
  sandbox,
 | 
						|
}) {
 | 
						|
  const childInstance = new SharedDataMap("xpcshell", {
 | 
						|
    path: PATH,
 | 
						|
    isParent: false,
 | 
						|
  });
 | 
						|
 | 
						|
  await parentInstance.init();
 | 
						|
  parentInstance.set("foo", { bar: 1 });
 | 
						|
 | 
						|
  await parentInstance.ready();
 | 
						|
  await childInstance.ready();
 | 
						|
 | 
						|
  await TestUtils.waitForCondition(
 | 
						|
    () => childInstance.get("foo"),
 | 
						|
    "Wait for child to sync"
 | 
						|
  );
 | 
						|
 | 
						|
  Assert.deepEqual(
 | 
						|
    childInstance.get("foo"),
 | 
						|
    parentInstance.get("foo"),
 | 
						|
    "Parent and child should be in sync"
 | 
						|
  );
 | 
						|
});
 | 
						|
 | 
						|
with_sharedDataMap(async function test_earlyChildSync({
 | 
						|
  instance: parentInstance,
 | 
						|
  sandbox,
 | 
						|
}) {
 | 
						|
  const childInstance = new SharedDataMap("xpcshell", {
 | 
						|
    path: PATH,
 | 
						|
    isParent: false,
 | 
						|
  });
 | 
						|
 | 
						|
  Assert.equal(childInstance.has("baz"), false, "Should not fail");
 | 
						|
 | 
						|
  await parentInstance.init();
 | 
						|
  parentInstance.set("baz", { bar: 1 });
 | 
						|
 | 
						|
  await TestUtils.waitForCondition(
 | 
						|
    () => childInstance.get("baz"),
 | 
						|
    "Wait for child to sync"
 | 
						|
  );
 | 
						|
 | 
						|
  Assert.deepEqual(
 | 
						|
    childInstance.get("baz"),
 | 
						|
    parentInstance.get("baz"),
 | 
						|
    "Parent and child should be in sync"
 | 
						|
  );
 | 
						|
});
 | 
						|
 | 
						|
with_sharedDataMap(async function test_updateStoreData({ instance, sandbox }) {
 | 
						|
  await instance.init();
 | 
						|
 | 
						|
  Assert.ok(!instance.get("foo"), "No value initially");
 | 
						|
 | 
						|
  instance.set("foo", "foo");
 | 
						|
  instance.set("bar", "bar");
 | 
						|
  instance._removeEntriesByKeys(["bar"]);
 | 
						|
 | 
						|
  Assert.ok(instance.get("foo"), "We keep one of the values");
 | 
						|
  Assert.ok(!instance.get("bar"), "The other value is removed");
 | 
						|
});
 |