Skip to content

Instantly share code, notes, and snippets.

@juliandescottes
Created May 23, 2019 07:20
Show Gist options
  • Save juliandescottes/e4bd217efcf8bf01cd323a14694f3626 to your computer and use it in GitHub Desktop.
Save juliandescottes/e4bd217efcf8bf01cd323a14694f3626 to your computer and use it in GitHub Desktop.
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
// Tests that preference helpers work properly with custom types of Float and Json.
const { PrefObserver } = require("devtools/client/shared/prefs");
// Use sinon for mocking.
const {sinon} = ChromeUtils.import("resource://testing-common/Sinon.jsm");
const AUTO_CLOSE = "devtools.editor.autoclosebrackets";
const TAB_SIZE = "devtools.editor.tabsize";
add_task(async function testPrefObserver() {
info("Init pref to a given value");
Services.prefs.setBoolPref(AUTO_CLOSE, false);
Services.prefs.setIntPref(TAB_SIZE, 2);
const prefObserver = new PrefObserver("devtools.editor.");
const autoCloseBracketSpy = sinon.spy();
prefObserver.on(AUTO_CLOSE, autoCloseBracketSpy);
const tabSizeSpy = sinon.spy();
prefObserver.on(TAB_SIZE, tabSizeSpy);
Services.prefs.setBoolPref(AUTO_CLOSE, true);
Services.prefs.setIntPref(TAB_SIZE, 3);
Services.prefs.setBoolPref(AUTO_CLOSE, false);
Services.prefs.setIntPref(TAB_SIZE, 9);
Services.prefs.setBoolPref(AUTO_CLOSE, true);
is(tabSizeSpy.callCount, 2, `${TAB_SIZE} observer was called as expected`);
is(autoCloseBracketSpy.callCount, 3, `${AUTO_CLOSE} observer was called as expected`);
prefObserver.destroy();
const weakPrefObserver = new PrefObserver("devtools.editor.", true);
weakPrefObserver.on(AUTO_CLOSE, autoCloseBracketSpy);
Services.prefs.setBoolPref(AUTO_CLOSE, false);
is(autoCloseBracketSpy.callCount, 4, `${AUTO_CLOSE} observer was called as expected`);
weakPrefObserver.destroy();
Services.prefs.setBoolPref(AUTO_CLOSE, true);
is(autoCloseBracketSpy.callCount, 4, `${AUTO_CLOSE} observer was called as expected`);
createAnotherWeakObserver(autoCloseBracketSpy);
await forceGC();
Services.prefs.setBoolPref(AUTO_CLOSE, false);
// should be immediately removed since nobody has a reference on this observer.
is(autoCloseBracketSpy.callCount, 4, `${AUTO_CLOSE} observer was called as expected`);
let obj = {};
obj.referencedWeakObserver = createAnotherWeakObserver(autoCloseBracketSpy);
await forceGC();
Services.prefs.setBoolPref(AUTO_CLOSE, true);
// should be caught since we have reference on the observer this time.
is(autoCloseBracketSpy.callCount, 5, `${AUTO_CLOSE} observer was called as expected`);
obj.referencedWeakObserver = null;
delete obj.referencedWeakObserver;
obj = null;
await forceGC();
await forceGC();
await forceGC();
Services.prefs.setBoolPref(AUTO_CLOSE, false);
// I would expect the observer to be gone after so many GC, but it's still called.
is(autoCloseBracketSpy.callCount, 5, `${AUTO_CLOSE} observer was called as expected`);
});
function createAnotherWeakObserver(spy) {
const weakPrefObserver = new PrefObserver("devtools.editor.", true);
weakPrefObserver.on(AUTO_CLOSE, spy);
return weakPrefObserver;
}
async function forceGC() {
for (let i = 0; i < 3; i++) {
// See minimizeMemoryUsage code here to justify the GC+CC+GC:
// https://searchfox.org/mozilla-central/rev/be78e6ea9b10b1f5b2b3b013f01d86e1062abb2b/dom/base/nsJSEnvironment.cpp#341-349
Cu.forceGC();
Cu.forceCC();
Cu.forceGC();
await new Promise(done => setTimeout(done, 0));
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment