Don't build testbinding-related code by default (#37034)

Disabling the TestBinding-related bindings and implementations saves 2mb
in a release build. Also, we lost the related test preferences when we
turned the layout-2020 tests on, so the tests have all been failing for
a long time.

Testing: Existing tests in CI.

---------

Signed-off-by: Josh Matthews <josh@joshmatthews.net>
This commit is contained in:
Josh Matthews 2025-05-17 10:14:19 +02:00 committed by GitHub
parent 2eab9c6df1
commit a028291466
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
35 changed files with 72 additions and 149 deletions

View file

@ -18,6 +18,7 @@ crown = ['js/crown']
debugmozjs = ['js/debugmozjs'] debugmozjs = ['js/debugmozjs']
jitspew = ['js/jitspew'] jitspew = ['js/jitspew']
profilemozjs = ['js/profilemozjs'] profilemozjs = ['js/profilemozjs']
testbinding = ["script_bindings/testbinding"]
tracing = ["dep:tracing", "script_bindings/tracing"] tracing = ["dep:tracing", "script_bindings/tracing"]
webgl_backtrace = ["canvas_traits/webgl_backtrace"] webgl_backtrace = ["canvas_traits/webgl_backtrace"]
js_backtrace = [] js_backtrace = []

View file

@ -549,17 +549,29 @@ pub(crate) mod svgelement;
pub(crate) mod svggraphicselement; pub(crate) mod svggraphicselement;
pub(crate) mod svgimageelement; pub(crate) mod svgimageelement;
pub(crate) mod svgsvgelement; pub(crate) mod svgsvgelement;
#[cfg(feature = "testbinding")]
pub(crate) mod testbinding; pub(crate) mod testbinding;
#[cfg(feature = "testbinding")]
pub(crate) mod testbindingiterable; pub(crate) mod testbindingiterable;
#[cfg(feature = "testbinding")]
pub(crate) mod testbindingmaplikewithinterface; pub(crate) mod testbindingmaplikewithinterface;
#[cfg(feature = "testbinding")]
pub(crate) mod testbindingmaplikewithprimitive; pub(crate) mod testbindingmaplikewithprimitive;
#[cfg(feature = "testbinding")]
pub(crate) mod testbindingpairiterable; pub(crate) mod testbindingpairiterable;
#[cfg(feature = "testbinding")]
pub(crate) mod testbindingproxy; pub(crate) mod testbindingproxy;
#[cfg(feature = "testbinding")]
pub(crate) mod testbindingsetlikewithinterface; pub(crate) mod testbindingsetlikewithinterface;
#[cfg(feature = "testbinding")]
pub(crate) mod testbindingsetlikewithprimitive; pub(crate) mod testbindingsetlikewithprimitive;
#[cfg(feature = "testbinding")]
pub(crate) mod testns; pub(crate) mod testns;
#[cfg(feature = "testbinding")]
pub(crate) mod testutils; pub(crate) mod testutils;
#[cfg(feature = "testbinding")]
pub(crate) mod testworklet; pub(crate) mod testworklet;
#[cfg(feature = "testbinding")]
pub(crate) mod testworkletglobalscope; pub(crate) mod testworkletglobalscope;
pub(crate) mod text; pub(crate) mod text;
pub(crate) mod textcontrol; pub(crate) mod textcontrol;

View file

@ -43,6 +43,7 @@ use crate::dom::bindings::str::USVString;
use crate::dom::bindings::trace::{CustomTraceable, JSTraceable, RootedTraceableBox}; use crate::dom::bindings::trace::{CustomTraceable, JSTraceable, RootedTraceableBox};
use crate::dom::globalscope::GlobalScope; use crate::dom::globalscope::GlobalScope;
use crate::dom::promise::Promise; use crate::dom::promise::Promise;
#[cfg(feature = "testbinding")]
use crate::dom::testworkletglobalscope::TestWorkletTask; use crate::dom::testworkletglobalscope::TestWorkletTask;
use crate::dom::window::Window; use crate::dom::window::Window;
use crate::dom::workletglobalscope::{ use crate::dom::workletglobalscope::{
@ -354,6 +355,7 @@ impl WorkletThreadPool {
} }
/// For testing. /// For testing.
#[cfg(feature = "testbinding")]
pub(crate) fn test_worklet_lookup(&self, id: WorkletId, key: String) -> Option<String> { pub(crate) fn test_worklet_lookup(&self, id: WorkletId, key: String) -> Option<String> {
let (sender, receiver) = unbounded(); let (sender, receiver) = unbounded();
let msg = WorkletData::Task(id, WorkletTask::Test(TestWorkletTask::Lookup(key, sender))); let msg = WorkletData::Task(id, WorkletTask::Test(TestWorkletTask::Lookup(key, sender)));

View file

@ -26,6 +26,7 @@ use crate::dom::bindings::trace::CustomTraceable;
use crate::dom::bindings::utils::define_all_exposed_interfaces; use crate::dom::bindings::utils::define_all_exposed_interfaces;
use crate::dom::globalscope::GlobalScope; use crate::dom::globalscope::GlobalScope;
use crate::dom::paintworkletglobalscope::{PaintWorkletGlobalScope, PaintWorkletTask}; use crate::dom::paintworkletglobalscope::{PaintWorkletGlobalScope, PaintWorkletTask};
#[cfg(feature = "testbinding")]
use crate::dom::testworkletglobalscope::{TestWorkletGlobalScope, TestWorkletTask}; use crate::dom::testworkletglobalscope::{TestWorkletGlobalScope, TestWorkletTask};
#[cfg(feature = "webgpu")] #[cfg(feature = "webgpu")]
use crate::dom::webgpu::identityhub::IdentityHub; use crate::dom::webgpu::identityhub::IdentityHub;
@ -60,6 +61,7 @@ impl WorkletGlobalScope {
init: &WorkletGlobalScopeInit, init: &WorkletGlobalScopeInit,
) -> DomRoot<WorkletGlobalScope> { ) -> DomRoot<WorkletGlobalScope> {
let scope: DomRoot<WorkletGlobalScope> = match scope_type { let scope: DomRoot<WorkletGlobalScope> = match scope_type {
#[cfg(feature = "testbinding")]
WorkletGlobalScopeType::Test => DomRoot::upcast(TestWorkletGlobalScope::new( WorkletGlobalScopeType::Test => DomRoot::upcast(TestWorkletGlobalScope::new(
runtime, runtime,
pipeline_id, pipeline_id,
@ -163,6 +165,7 @@ impl WorkletGlobalScope {
/// Perform a worklet task /// Perform a worklet task
pub(crate) fn perform_a_worklet_task(&self, task: WorkletTask) { pub(crate) fn perform_a_worklet_task(&self, task: WorkletTask) {
match task { match task {
#[cfg(feature = "testbinding")]
WorkletTask::Test(task) => match self.downcast::<TestWorkletGlobalScope>() { WorkletTask::Test(task) => match self.downcast::<TestWorkletGlobalScope>() {
Some(global) => global.perform_a_worklet_task(task), Some(global) => global.perform_a_worklet_task(task),
None => warn!("This is not a test worklet."), None => warn!("This is not a test worklet."),
@ -203,6 +206,7 @@ pub(crate) struct WorkletGlobalScopeInit {
#[derive(Clone, Copy, Debug, JSTraceable, MallocSizeOf)] #[derive(Clone, Copy, Debug, JSTraceable, MallocSizeOf)]
pub(crate) enum WorkletGlobalScopeType { pub(crate) enum WorkletGlobalScopeType {
/// A servo-specific testing worklet /// A servo-specific testing worklet
#[cfg(feature = "testbinding")]
Test, Test,
/// A paint worklet /// A paint worklet
Paint, Paint,
@ -210,6 +214,7 @@ pub(crate) enum WorkletGlobalScopeType {
/// A task which can be performed in the context of a worklet global. /// A task which can be performed in the context of a worklet global.
pub(crate) enum WorkletTask { pub(crate) enum WorkletTask {
#[cfg(feature = "testbinding")]
Test(TestWorkletTask), Test(TestWorkletTask),
Paint(PaintWorkletTask), Paint(PaintWorkletTask),
} }

View file

@ -27,6 +27,7 @@ use crate::dom::bindings::str::DOMString;
use crate::dom::document::{FakeRequestAnimationFrameCallback, RefreshRedirectDue}; use crate::dom::document::{FakeRequestAnimationFrameCallback, RefreshRedirectDue};
use crate::dom::eventsource::EventSourceTimeoutCallback; use crate::dom::eventsource::EventSourceTimeoutCallback;
use crate::dom::globalscope::GlobalScope; use crate::dom::globalscope::GlobalScope;
#[cfg(feature = "testbinding")]
use crate::dom::testbinding::TestBindingCallback; use crate::dom::testbinding::TestBindingCallback;
use crate::dom::types::{Window, WorkerGlobalScope}; use crate::dom::types::{Window, WorkerGlobalScope};
use crate::dom::xmlhttprequest::XHRTimeoutCallback; use crate::dom::xmlhttprequest::XHRTimeoutCallback;
@ -78,6 +79,7 @@ pub(crate) enum OneshotTimerCallback {
XhrTimeout(XHRTimeoutCallback), XhrTimeout(XHRTimeoutCallback),
EventSourceTimeout(EventSourceTimeoutCallback), EventSourceTimeout(EventSourceTimeoutCallback),
JsTimer(JsTimerTask), JsTimer(JsTimerTask),
#[cfg(feature = "testbinding")]
TestBindingCallback(TestBindingCallback), TestBindingCallback(TestBindingCallback),
FakeRequestAnimationFrame(FakeRequestAnimationFrameCallback), FakeRequestAnimationFrame(FakeRequestAnimationFrameCallback),
RefreshRedirectDue(RefreshRedirectDue), RefreshRedirectDue(RefreshRedirectDue),
@ -89,6 +91,7 @@ impl OneshotTimerCallback {
OneshotTimerCallback::XhrTimeout(callback) => callback.invoke(can_gc), OneshotTimerCallback::XhrTimeout(callback) => callback.invoke(can_gc),
OneshotTimerCallback::EventSourceTimeout(callback) => callback.invoke(), OneshotTimerCallback::EventSourceTimeout(callback) => callback.invoke(),
OneshotTimerCallback::JsTimer(task) => task.invoke(this, js_timers, can_gc), OneshotTimerCallback::JsTimer(task) => task.invoke(this, js_timers, can_gc),
#[cfg(feature = "testbinding")]
OneshotTimerCallback::TestBindingCallback(callback) => callback.invoke(), OneshotTimerCallback::TestBindingCallback(callback) => callback.invoke(),
OneshotTimerCallback::FakeRequestAnimationFrame(callback) => callback.invoke(can_gc), OneshotTimerCallback::FakeRequestAnimationFrame(callback) => callback.invoke(can_gc),
OneshotTimerCallback::RefreshRedirectDue(callback) => callback.invoke(can_gc), OneshotTimerCallback::RefreshRedirectDue(callback) => callback.invoke(can_gc),

View file

@ -52,6 +52,7 @@ serde_json = { workspace = true }
[features] [features]
bluetooth = [] bluetooth = []
testbinding = []
tracing = ["dep:tracing"] tracing = ["dep:tracing"]
webgpu = [] webgpu = []
webxr = ["webxr-api"] webxr = ["webxr-api"]

View file

@ -2,6 +2,8 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this * License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
// skip-unless CARGO_FEATURE_TESTBINDING
// This interface is entirely internal to Servo, and should not be accessible to // This interface is entirely internal to Servo, and should not be accessible to
// web pages. // web pages.

View file

@ -2,6 +2,8 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this * License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
// skip-unless CARGO_FEATURE_TESTBINDING
// This interface is entirely internal to Servo, and should not be accessible to // This interface is entirely internal to Servo, and should not be accessible to
// web pages. // web pages.

View file

@ -2,6 +2,8 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this * License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
// skip-unless CARGO_FEATURE_TESTBINDING
// This interface is entirely internal to Servo, and should not be accessible to // This interface is entirely internal to Servo, and should not be accessible to
// web pages. // web pages.

View file

@ -2,6 +2,8 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this * License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
// skip-unless CARGO_FEATURE_TESTBINDING
// This interface is entirely internal to Servo, and should not be accessible to // This interface is entirely internal to Servo, and should not be accessible to
// web pages. // web pages.

View file

@ -2,6 +2,8 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this * License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
// skip-unless CARGO_FEATURE_TESTBINDING
// This interface is entirely internal to Servo, and should not be accessible to // This interface is entirely internal to Servo, and should not be accessible to
// web pages. // web pages.

View file

@ -1,6 +1,9 @@
/* This Source Code Form is subject to the terms of the Mozilla Public /* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this * License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
// skip-unless CARGO_FEATURE_TESTBINDING
/* /*
* This IDL file was created to test the special operations (see * This IDL file was created to test the special operations (see
* https://heycam.github.io/webidl/#idl-special-operations) without converting * https://heycam.github.io/webidl/#idl-special-operations) without converting

View file

@ -2,6 +2,8 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this * License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
// skip-unless CARGO_FEATURE_TESTBINDING
// This interface is entirely internal to Servo, and should not be accessible to // This interface is entirely internal to Servo, and should not be accessible to
// web pages. // web pages.

View file

@ -2,6 +2,8 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this * License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
// skip-unless CARGO_FEATURE_TESTBINDING
// This interface is entirely internal to Servo, and should not be accessible to // This interface is entirely internal to Servo, and should not be accessible to
// web pages. // web pages.

View file

@ -2,6 +2,8 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this * License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
// skip-unless CARGO_FEATURE_TESTBINDING
// https://testutils.spec.whatwg.org/ // https://testutils.spec.whatwg.org/
[Exposed=(Window,Worker), Pref="dom_testutils_enabled"] [Exposed=(Window,Worker), Pref="dom_testutils_enabled"]

View file

@ -2,6 +2,8 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this * License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
// skip-unless CARGO_FEATURE_TESTBINDING
// This interface is entirely internal to Servo, and should not be accessible to // This interface is entirely internal to Servo, and should not be accessible to
// web pages. // web pages.

View file

@ -2,6 +2,8 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this * License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
// skip-unless CARGO_FEATURE_TESTBINDING
// This interface is entirely internal to Servo, and should not be accessible to // This interface is entirely internal to Servo, and should not be accessible to
// web pages. // web pages.

View file

@ -34,6 +34,7 @@ no-wgl = ["mozangle/egl", "mozangle/build_dlls", "surfman/sm-angle-default", "co
dynamic_freetype = ["webrender/dynamic_freetype"] dynamic_freetype = ["webrender/dynamic_freetype"]
profilemozjs = ["script/profilemozjs"] profilemozjs = ["script/profilemozjs"]
refcell_backtrace = ["script/refcell_backtrace"] refcell_backtrace = ["script/refcell_backtrace"]
testbinding = ["script/testbinding"]
tracing = [ tracing = [
"dep:tracing", "dep:tracing",
"compositing/tracing", "compositing/tracing",

View file

@ -63,7 +63,7 @@ icu_locid = "1.5.0"
image = { workspace = true } image = { workspace = true }
keyboard-types = { workspace = true } keyboard-types = { workspace = true }
libc = { workspace = true } libc = { workspace = true }
libservo = { path = "../../components/servo", features = ["background_hang_monitor", "bluetooth"] } libservo = { path = "../../components/servo", features = ["background_hang_monitor", "bluetooth", "testbinding"] }
log = { workspace = true } log = { workspace = true }
mime_guess = { workspace = true } mime_guess = { workspace = true }
raw-window-handle = { workspace = true } raw-window-handle = { workspace = true }

View file

@ -13940,7 +13940,7 @@
] ]
], ],
"preferences.html": [ "preferences.html": [
"a1da58a825e2832c7eb55a87322b7ba840ee2661", "8a65161198c3a692aa007b98643ae3e95b0ae310",
[ [
null, null,
{} {}

View file

@ -1,5 +1,15 @@
prefs: [ prefs: [
"dom_serviceworker_enabled:true", "dom_serviceworker_enabled:true",
"dom_servo_helpers_enabled:true",
"dom_testbinding_enabled:true",
"dom_testbinding_prefcontrolled_enabled:false",
"dom_testbinding_prefcontrolled2_enabled:true",
"dom_testbinding_preference_value_falsy:false",
"dom_testbinding_preference_value_quote_string_test:\"test\"",
"dom_testbinding_preference_value_space_string_test:test1 test2",
"dom_testbinding_preference_value_string_empty:",
"dom_testbinding_preference_value_string_test:test",
"dom_testbinding_preference_value_truthy:true",
"dom_urlpattern_enabled:true", "dom_urlpattern_enabled:true",
"media_testing_enabled:true", "media_testing_enabled:true",
] ]

View file

@ -1,4 +0,0 @@
[binding_keyword.html]
[Conversion of dictionary elements with rust keywords, and null non-required nullable properties works]
expected: FAIL

View file

@ -1,4 +0,0 @@
[codegen_unions.html]
[(DOMString or object) conversion is performed correctly]
expected: FAIL

View file

@ -1,4 +0,0 @@
[custom_auto_rooter.html]
[sequence<any> conversion did not lose any values]
expected: FAIL

View file

@ -1,7 +0,0 @@
[entry.html]
[Incumbent global]
expected: FAIL
[Entry global]
expected: FAIL

View file

@ -1,4 +0,0 @@
[entry.worker.html]
[entry]
expected: FAIL

View file

@ -1,62 +0,0 @@
[interface_member_exposed.html]
expected: ERROR
[Disabled preference hides member controlled by that preference: funcControlledStaticMethodDisabled]
expected: FAIL
[Disabled preference hides member controlled by that preference: prefControlledAttributeDisabled]
expected: FAIL
[Enabled preference shows member controlled by that preference: prefControlledMethodEnabled]
expected: FAIL
[Enabled preference shows member controlled by that preference: prefControlledConstEnabled]
expected: FAIL
[Enabled preference shows member controlled by that preference: funcControlledAttributeEnabled]
expected: FAIL
[Disabled preference hides member controlled by that preference: prefControlledStaticAttributeDisabled]
expected: FAIL
[Disabled preference hides member controlled by that preference: funcControlledMethodDisabled]
expected: FAIL
[Enabled preference shows member controlled by that preference: prefControlledStaticMethodEnabled]
expected: FAIL
[Enabled preference shows member controlled by that preference: prefControlledStaticAttributeEnabled]
expected: FAIL
[Disabled preference hides member controlled by that preference: prefControlledStaticMethodDisabled]
expected: FAIL
[Enabled preference shows member controlled by that preference: prefControlledAttributeEnabled]
expected: FAIL
[Enabled preference shows member controlled by that preference: funcControlledStaticMethodEnabled]
expected: FAIL
[Disabled preference hides member controlled by that preference: funcControlledConstDisabled]
expected: FAIL
[Disabled preference hides member controlled by that preference: prefControlledConstDisabled]
expected: FAIL
[Enabled preference shows member controlled by that preference: funcControlledMethodEnabled]
expected: FAIL
[Disabled preference hides member controlled by that preference: funcControlledAttributeDisabled]
expected: FAIL
[Enabled preference shows member controlled by that preference: funcControlledStaticAttributeEnabled]
expected: FAIL
[Disabled preference hides member controlled by that preference: funcControlledStaticAttributeDisabled]
expected: FAIL
[Enabled preference shows member controlled by that preference: funcControlledConstEnabled]
expected: FAIL
[Disabled preference hides member controlled by that preference: prefControlledMethodDisabled]
expected: FAIL

View file

@ -1 +1 @@
prefs: [dom_webxr_test: false, dom_testutils_enabled: false] prefs: [dom_webxr_test: false, dom_testutils_enabled: false, dom_testbinding_enabled: false]

View file

@ -1 +1 @@
prefs: [dom_testutils_enabled: false] prefs: [dom_testutils_enabled: false, dom_testbinding_enabled: false]

View file

@ -1,19 +0,0 @@
[iterable.html]
[Iterable iterators are iterators]
expected: FAIL
[Pair iterable iterators are iterators]
expected: FAIL
[Empty value iterator]
expected: FAIL
[Empty pair iterator]
expected: FAIL
[Iterators iterate over values]
expected: FAIL
[Pair iterators iterate over key/value pairs]
expected: FAIL

View file

@ -1,4 +1,3 @@
[navigator.html] [navigator.html]
[navigator.platform mac] [navigator.platform mac]
expected: FAIL expected: FAIL

View file

@ -1,4 +0,0 @@
[preferences.html]
[prefs]
expected: FAIL

View file

@ -1,19 +0,0 @@
[promise.html]
[Resolve callback gets argument]
expected: FAIL
[Native promise from async callback can be resolved]
expected: FAIL
[Native reject callback gets argument]
expected: FAIL
[Native code rejects with exception]
expected: FAIL
[Reject callback gets argument]
expected: FAIL
[Native resolve callback gets argument]
expected: FAIL

View file

@ -1,7 +0,0 @@
[variadic-interface.html]
[Default values and variadic arguments work together.]
expected: FAIL
[Variadic interface arguments work.]
expected: FAIL

View file

@ -7,16 +7,16 @@
test(function() { test(function() {
var testBinding = new TestBinding(); var testBinding = new TestBinding();
assert_equals(typeof testBinding.BooleanMozPreference, "function"); assert_equals(typeof testBinding.BooleanMozPreference, "function");
assert_equals(testBinding.BooleanMozPreference("dom.testbinding.preference_value.falsy"), false); assert_equals(testBinding.BooleanMozPreference("dom_testbinding_preference_value_falsy"), false);
assert_equals(testBinding.BooleanMozPreference("dom.testbinding.preference_value.truthy"), true); assert_equals(testBinding.BooleanMozPreference("dom_testbinding_preference_value_truthy"), true);
assert_equals(testBinding.BooleanMozPreference("dom.testbinding.preference_value.string_test"), false); assert_equals(testBinding.BooleanMozPreference("dom_testbinding_preference_value_string_test"), false);
assert_equals(testBinding.BooleanMozPreference("dom.testbinding.preference_value.string_empty"), false); assert_equals(testBinding.BooleanMozPreference("dom_testbinding_preference_value_string_empty"), false);
assert_equals(typeof testBinding.StringMozPreference, "function"); assert_equals(typeof testBinding.StringMozPreference, "function");
assert_equals(testBinding.StringMozPreference("dom.testbinding.preference_value.string_test"), "test"); assert_equals(testBinding.StringMozPreference("dom_testbinding_preference_value_string_test"), "test");
assert_equals(testBinding.StringMozPreference("dom.testbinding.preference_value.string_empty"), ""); assert_equals(testBinding.StringMozPreference("dom_testbinding_preference_value_string_empty"), "");
assert_equals(testBinding.StringMozPreference("dom.testbinding.preference_value.falsy"), ""); assert_equals(testBinding.StringMozPreference("dom_testbinding_preference_value_falsy"), "");
assert_equals(testBinding.StringMozPreference("dom.testbinding.preference_value.truthy"), ""); assert_equals(testBinding.StringMozPreference("dom_testbinding_preference_value_truthy"), "");
assert_equals(testBinding.StringMozPreference("dom.testbinding.preference_value.space_string_test"), "test1 test2"); assert_equals(testBinding.StringMozPreference("dom_testbinding_preference_value_space_string_test"), "test1 test2");
assert_equals(testBinding.StringMozPreference("dom.testbinding.preference_value.space_string_test"), "test1 test2"); assert_equals(testBinding.StringMozPreference("dom_testbinding_preference_value_quote_string_test"), "\"test\"");
}, "prefs"); }, "prefs");
</script> </script>