/* vim: set ts=2 et sw=2 tw=80: */ /* Any copyright is dedicated to the Public Domain. http://creativecommons.org/publicdomain/zero/1.0/ */ "use strict"; const {NetUtil} = Cu.import("resource://gre/modules/NetUtil.jsm", {}); const {FileUtils} = Cu.import("resource://gre/modules/FileUtils.jsm", {}); const {Promise: promise} = Cu.import("resource://gre/modules/Promise.jsm", {}); let gScratchpadWindow; // Reference to the Scratchpad chrome window object /** * Open a Scratchpad window. * * @param function aReadyCallback * Optional. The function you want invoked when the Scratchpad instance * is ready. * @param object aOptions * Optional. Options for opening the scratchpad: * - window * Provide this if there's already a Scratchpad window you want to wait * loading for. * - state * Scratchpad state object. This is used when Scratchpad is open. * - noFocus * Boolean that tells you do not want the opened window to receive * focus. * @return nsIDOMWindow * The new window object that holds Scratchpad. Note that the * gScratchpadWindow global is also updated to reference the new window * object. */ function openScratchpad(aReadyCallback, aOptions) { aOptions = aOptions || {}; let win = aOptions.window || Scratchpad.ScratchpadManager.openScratchpad(aOptions.state); if (!win) { return; } let onLoad = function() { win.removeEventListener("load", onLoad, false); win.Scratchpad.addObserver({ onReady: function(aScratchpad) { aScratchpad.removeObserver(this); if (aOptions.noFocus) { aReadyCallback(win, aScratchpad); } else { waitForFocus(aReadyCallback.bind(null, win, aScratchpad), win); } } }); }; if (aReadyCallback) { win.addEventListener("load", onLoad, false); } gScratchpadWindow = win; return gScratchpadWindow; } /** * Create a temporary file, write to it and call a callback * when done. * * @param string aName * Name of your temporary file. * @param string aContent * Temporary file's contents. * @param function aCallback * Optional callback to be called when we're done writing * to the file. It will receive two parameters: status code * and a file object. */ function createTempFile(aName, aContent, aCallback=function(){}) { // Create a temporary file. let file = FileUtils.getFile("TmpD", [aName]); file.createUnique(Ci.nsIFile.NORMAL_FILE_TYPE, parseInt("666", 8)); // Write the temporary file. let fout = Cc["@mozilla.org/network/file-output-stream;1"]. createInstance(Ci.nsIFileOutputStream); fout.init(file.QueryInterface(Ci.nsILocalFile), 0x02 | 0x08 | 0x20, parseInt("644", 8), fout.DEFER_OPEN); let converter = Cc["@mozilla.org/intl/scriptableunicodeconverter"]. createInstance(Ci.nsIScriptableUnicodeConverter); converter.charset = "UTF-8"; let fileContentStream = converter.convertToInputStream(aContent); NetUtil.asyncCopy(fileContentStream, fout, function (aStatus) { aCallback(aStatus, file); }); } /** * Run a set of asychronous tests sequentially defined by input and output. * * @param Scratchpad aScratchpad * The scratchpad to use in running the tests. * @param array aTests * An array of test objects, each with the following properties: * - method * Scratchpad method to use, one of "run", "display", or "inspect". * - code * Code to run in the scratchpad. * - result * Expected code that will be in the scratchpad upon completion. * - label * The tests label which will be logged in the test runner output. * @return Promise * The promise that will be resolved when all tests are finished. */ function runAsyncTests(aScratchpad, aTests) { let deferred = promise.defer(); (function runTest() { if (aTests.length) { let test = aTests.shift(); aScratchpad.setText(test.code); aScratchpad[test.method]().then(function success() { is(aScratchpad.getText(), test.result, test.label); runTest(); }, function failure(error) { ok(false, error.stack + " " + test.label); runTest(); }); } else { deferred.resolve(); } })(); return deferred.promise; } /** * Run a set of asychronous tests sequentially with callbacks to prepare each * test and to be called when the test result is ready. * * @param Scratchpad aScratchpad * The scratchpad to use in running the tests. * @param array aTests * An array of test objects, each with the following properties: * - method * Scratchpad method to use, one of "run", "display", or "inspect". * - prepare * The callback to run just prior to executing the scratchpad method. * - then * The callback to run when the scratchpad execution promise resolves. * @return Promise * The promise that will be resolved when all tests are finished. */ function runAsyncCallbackTests(aScratchpad, aTests) { let deferred = promise.defer(); (function runTest() { if (aTests.length) { let test = aTests.shift(); test.prepare(); aScratchpad[test.method]().then(test.then.bind(test)).then(runTest); } else { deferred.resolve(); } })(); return deferred.promise; } function cleanup() { if (gScratchpadWindow) { gScratchpadWindow.close(); gScratchpadWindow = null; } while (gBrowser.tabs.length > 1) { gBrowser.removeCurrentTab(); } } registerCleanupFunction(cleanup);