summaryrefslogtreecommitdiffstats
path: root/testing/mochitest/tests/SimpleTest/MockObjects.js
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-28 14:29:10 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-28 14:29:10 +0000
commit2aa4a82499d4becd2284cdb482213d541b8804dd (patch)
treeb80bf8bf13c3766139fbacc530efd0dd9d54394c /testing/mochitest/tests/SimpleTest/MockObjects.js
parentInitial commit. (diff)
downloadfirefox-upstream.tar.xz
firefox-upstream.zip
Adding upstream version 86.0.1.upstream/86.0.1upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'testing/mochitest/tests/SimpleTest/MockObjects.js')
-rw-r--r--testing/mochitest/tests/SimpleTest/MockObjects.js98
1 files changed, 98 insertions, 0 deletions
diff --git a/testing/mochitest/tests/SimpleTest/MockObjects.js b/testing/mochitest/tests/SimpleTest/MockObjects.js
new file mode 100644
index 0000000000..780a36d32f
--- /dev/null
+++ b/testing/mochitest/tests/SimpleTest/MockObjects.js
@@ -0,0 +1,98 @@
+/* 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
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+/**
+ * Allows registering a mock XPCOM component, that temporarily replaces the
+ * original one when an object implementing a given ContractID is requested
+ * using createInstance.
+ *
+ * @param aContractID
+ * The ContractID of the component to replace, for example
+ * "@mozilla.org/filepicker;1".
+ *
+ * @param aReplacementCtor
+ * The constructor function for the JavaScript object that will be
+ * created every time createInstance is called. This object must
+ * implement QueryInterface and provide the XPCOM interfaces required by
+ * the specified ContractID (for example
+ * Components.interfaces.nsIFilePicker).
+ */
+
+function MockObjectRegisterer(aContractID, aReplacementCtor) {
+ this._contractID = aContractID;
+ this._replacementCtor = aReplacementCtor;
+}
+
+MockObjectRegisterer.prototype = {
+ /**
+ * Replaces the current factory with one that returns a new mock object.
+ *
+ * After register() has been called, it is mandatory to call unregister() to
+ * restore the original component. Usually, you should use a try-catch block
+ * to ensure that unregister() is called.
+ */
+ register: function MOR_register() {
+ if (this._originalCID) {
+ throw new Error("Invalid object state when calling register()");
+ }
+
+ // Define a factory that creates a new object using the given constructor.
+ var isChrome = location.protocol == "chrome:";
+ var providedConstructor = this._replacementCtor;
+ this._mockFactory = {
+ createInstance: function MF_createInstance(aOuter, aIid) {
+ if (aOuter != null) {
+ throw SpecialPowers.Cr.NS_ERROR_NO_AGGREGATION;
+ }
+ var inst = new providedConstructor().QueryInterface(aIid);
+ if (!isChrome) {
+ inst = SpecialPowers.wrapCallbackObject(inst);
+ }
+ return inst;
+ },
+ };
+ if (!isChrome) {
+ this._mockFactory = SpecialPowers.wrapCallbackObject(this._mockFactory);
+ }
+
+ var retVal = SpecialPowers.swapFactoryRegistration(
+ null,
+ this._contractID,
+ this._mockFactory
+ );
+ if ("error" in retVal) {
+ throw new Error("ERROR: " + retVal.error);
+ } else {
+ this._originalCID = retVal.originalCID;
+ }
+ },
+
+ /**
+ * Restores the original factory.
+ */
+ unregister: function MOR_unregister() {
+ if (!this._originalCID) {
+ throw new Error("Invalid object state when calling unregister()");
+ }
+
+ // Free references to the mock factory.
+ SpecialPowers.swapFactoryRegistration(this._originalCID, this._contractID);
+
+ // Allow registering a mock factory again later.
+ this._originalCID = null;
+ this._mockFactory = null;
+ },
+
+ // --- Private methods and properties ---
+
+ /**
+ * The factory of the component being replaced.
+ */
+ _originalCID: null,
+
+ /**
+ * The nsIFactory that was automatically generated by this object.
+ */
+ _mockFactory: null,
+};