Source code

Revision control

Copy as Markdown

Other Tools

Test Info:

/* Any copyright is dedicated to the Public Domain.
"use strict";
const { FeatureGateImplementation } = ChromeUtils.importESModule(
"resource://featuregates/FeatureGateImplementation.sys.mjs"
);
const kDefinitionDefaults = {
id: "test-feature",
title: "Test Feature",
description: "A feature for testing",
restartRequired: false,
type: "boolean",
preference: "test.feature",
defaultValue: false,
isPublic: false,
};
function definitionFactory(override = {}) {
return Object.assign({}, kDefinitionDefaults, override);
}
// getValue should work
add_task(async function testGetValue() {
const preference = "test.pref";
equal(
Services.prefs.getPrefType(preference),
Services.prefs.PREF_INVALID,
"Before creating the feature gate, the preference should not exist"
);
const feature = new FeatureGateImplementation(
definitionFactory({ preference, defaultValue: false })
);
equal(
Services.prefs.getPrefType(preference),
Services.prefs.PREF_INVALID,
"Instantiating a feature gate should not set its default value"
);
equal(
await feature.getValue(),
false,
"getValue() should return the feature gate's default"
);
Services.prefs.setBoolPref(preference, true);
equal(
await feature.getValue(),
true,
"getValue() should return the new value"
);
Services.prefs.setBoolPref(preference, false);
equal(
await feature.getValue(),
false,
"getValue() should return the third value"
);
// cleanup
Services.prefs.getDefaultBranch("").deleteBranch(preference);
});
// event observers should work
add_task(async function testGetValue() {
const preference = "test.pref";
const feature = new FeatureGateImplementation(
definitionFactory({ preference, defaultValue: false })
);
const observer = {
onChange: sinon.stub(),
onEnable: sinon.stub(),
onDisable: sinon.stub(),
};
let rv = await feature.addObserver(observer);
equal(rv, false, "addObserver returns the current value");
Assert.deepEqual(observer.onChange.args, [], "onChange should not be called");
Assert.deepEqual(observer.onEnable.args, [], "onEnable should not be called");
Assert.deepEqual(
observer.onDisable.args,
[],
"onDisable should not be called"
);
Services.prefs.setBoolPref(preference, true);
await Promise.resolve(); // Allow events to be called async
Assert.deepEqual(
observer.onChange.args,
[[true]],
"onChange should be called with the new value"
);
Assert.deepEqual(observer.onEnable.args, [[]], "onEnable should be called");
Assert.deepEqual(
observer.onDisable.args,
[],
"onDisable should not be called"
);
Services.prefs.setBoolPref(preference, false);
await Promise.resolve(); // Allow events to be called async
Assert.deepEqual(
observer.onChange.args,
[[true], [false]],
"onChange should be called again with the new value"
);
Assert.deepEqual(
observer.onEnable.args,
[[]],
"onEnable should not be called a second time"
);
Assert.deepEqual(
observer.onDisable.args,
[[]],
"onDisable should be called for the first time"
);
Services.prefs.setBoolPref(preference, false);
await Promise.resolve(); // Allow events to be called async
Assert.deepEqual(
observer.onChange.args,
[[true], [false]],
"onChange should not be called if the value did not change"
);
Assert.deepEqual(
observer.onEnable.args,
[[]],
"onEnable should not be called again if the value did not change"
);
Assert.deepEqual(
observer.onDisable.args,
[[]],
"onDisable should not be called if the value did not change"
);
// cleanup
feature.removeAllObservers();
Services.prefs.getDefaultBranch("").deleteBranch(preference);
});