diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-28 14:29:10 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-28 14:29:10 +0000 |
commit | 2aa4a82499d4becd2284cdb482213d541b8804dd (patch) | |
tree | b80bf8bf13c3766139fbacc530efd0dd9d54394c /testing/mochitest/tests/SimpleTest/MockObjects.js | |
parent | Initial commit. (diff) | |
download | firefox-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.js | 98 |
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, +}; |