|
1 /* vim: set ts=2 et sw=2 tw=80: */ |
|
2 /* Any copyright is dedicated to the Public Domain. |
|
3 http://creativecommons.org/publicdomain/zero/1.0/ */ |
|
4 |
|
5 "use strict"; |
|
6 |
|
7 const {NetUtil} = Cu.import("resource://gre/modules/NetUtil.jsm", {}); |
|
8 const {FileUtils} = Cu.import("resource://gre/modules/FileUtils.jsm", {}); |
|
9 const {Promise: promise} = Cu.import("resource://gre/modules/Promise.jsm", {}); |
|
10 |
|
11 let gScratchpadWindow; // Reference to the Scratchpad chrome window object |
|
12 |
|
13 gDevTools.testing = true; |
|
14 SimpleTest.registerCleanupFunction(() => { |
|
15 gDevTools.testing = false; |
|
16 }); |
|
17 |
|
18 /** |
|
19 * Open a Scratchpad window. |
|
20 * |
|
21 * @param function aReadyCallback |
|
22 * Optional. The function you want invoked when the Scratchpad instance |
|
23 * is ready. |
|
24 * @param object aOptions |
|
25 * Optional. Options for opening the scratchpad: |
|
26 * - window |
|
27 * Provide this if there's already a Scratchpad window you want to wait |
|
28 * loading for. |
|
29 * - state |
|
30 * Scratchpad state object. This is used when Scratchpad is open. |
|
31 * - noFocus |
|
32 * Boolean that tells you do not want the opened window to receive |
|
33 * focus. |
|
34 * @return nsIDOMWindow |
|
35 * The new window object that holds Scratchpad. Note that the |
|
36 * gScratchpadWindow global is also updated to reference the new window |
|
37 * object. |
|
38 */ |
|
39 function openScratchpad(aReadyCallback, aOptions) |
|
40 { |
|
41 aOptions = aOptions || {}; |
|
42 |
|
43 let win = aOptions.window || |
|
44 Scratchpad.ScratchpadManager.openScratchpad(aOptions.state); |
|
45 if (!win) { |
|
46 return; |
|
47 } |
|
48 |
|
49 let onLoad = function() { |
|
50 win.removeEventListener("load", onLoad, false); |
|
51 |
|
52 win.Scratchpad.addObserver({ |
|
53 onReady: function(aScratchpad) { |
|
54 aScratchpad.removeObserver(this); |
|
55 |
|
56 if (aOptions.noFocus) { |
|
57 aReadyCallback(win, aScratchpad); |
|
58 } else { |
|
59 waitForFocus(aReadyCallback.bind(null, win, aScratchpad), win); |
|
60 } |
|
61 } |
|
62 }); |
|
63 }; |
|
64 |
|
65 if (aReadyCallback) { |
|
66 win.addEventListener("load", onLoad, false); |
|
67 } |
|
68 |
|
69 gScratchpadWindow = win; |
|
70 return gScratchpadWindow; |
|
71 } |
|
72 |
|
73 /** |
|
74 * Create a temporary file, write to it and call a callback |
|
75 * when done. |
|
76 * |
|
77 * @param string aName |
|
78 * Name of your temporary file. |
|
79 * @param string aContent |
|
80 * Temporary file's contents. |
|
81 * @param function aCallback |
|
82 * Optional callback to be called when we're done writing |
|
83 * to the file. It will receive two parameters: status code |
|
84 * and a file object. |
|
85 */ |
|
86 function createTempFile(aName, aContent, aCallback=function(){}) |
|
87 { |
|
88 // Create a temporary file. |
|
89 let file = FileUtils.getFile("TmpD", [aName]); |
|
90 file.createUnique(Ci.nsIFile.NORMAL_FILE_TYPE, parseInt("666", 8)); |
|
91 |
|
92 // Write the temporary file. |
|
93 let fout = Cc["@mozilla.org/network/file-output-stream;1"]. |
|
94 createInstance(Ci.nsIFileOutputStream); |
|
95 fout.init(file.QueryInterface(Ci.nsILocalFile), 0x02 | 0x08 | 0x20, |
|
96 parseInt("644", 8), fout.DEFER_OPEN); |
|
97 |
|
98 let converter = Cc["@mozilla.org/intl/scriptableunicodeconverter"]. |
|
99 createInstance(Ci.nsIScriptableUnicodeConverter); |
|
100 converter.charset = "UTF-8"; |
|
101 let fileContentStream = converter.convertToInputStream(aContent); |
|
102 |
|
103 NetUtil.asyncCopy(fileContentStream, fout, function (aStatus) { |
|
104 aCallback(aStatus, file); |
|
105 }); |
|
106 } |
|
107 |
|
108 /** |
|
109 * Run a set of asychronous tests sequentially defined by input and output. |
|
110 * |
|
111 * @param Scratchpad aScratchpad |
|
112 * The scratchpad to use in running the tests. |
|
113 * @param array aTests |
|
114 * An array of test objects, each with the following properties: |
|
115 * - method |
|
116 * Scratchpad method to use, one of "run", "display", or "inspect". |
|
117 * - code |
|
118 * Code to run in the scratchpad. |
|
119 * - result |
|
120 * Expected code that will be in the scratchpad upon completion. |
|
121 * - label |
|
122 * The tests label which will be logged in the test runner output. |
|
123 * @return Promise |
|
124 * The promise that will be resolved when all tests are finished. |
|
125 */ |
|
126 function runAsyncTests(aScratchpad, aTests) |
|
127 { |
|
128 let deferred = promise.defer(); |
|
129 |
|
130 (function runTest() { |
|
131 if (aTests.length) { |
|
132 let test = aTests.shift(); |
|
133 aScratchpad.setText(test.code); |
|
134 aScratchpad[test.method]().then(function success() { |
|
135 is(aScratchpad.getText(), test.result, test.label); |
|
136 runTest(); |
|
137 }, function failure(error) { |
|
138 ok(false, error.stack + " " + test.label); |
|
139 runTest(); |
|
140 }); |
|
141 } else { |
|
142 deferred.resolve(); |
|
143 } |
|
144 })(); |
|
145 |
|
146 return deferred.promise; |
|
147 } |
|
148 |
|
149 /** |
|
150 * Run a set of asychronous tests sequentially with callbacks to prepare each |
|
151 * test and to be called when the test result is ready. |
|
152 * |
|
153 * @param Scratchpad aScratchpad |
|
154 * The scratchpad to use in running the tests. |
|
155 * @param array aTests |
|
156 * An array of test objects, each with the following properties: |
|
157 * - method |
|
158 * Scratchpad method to use, one of "run", "display", or "inspect". |
|
159 * - prepare |
|
160 * The callback to run just prior to executing the scratchpad method. |
|
161 * - then |
|
162 * The callback to run when the scratchpad execution promise resolves. |
|
163 * @return Promise |
|
164 * The promise that will be resolved when all tests are finished. |
|
165 */ |
|
166 function runAsyncCallbackTests(aScratchpad, aTests) |
|
167 { |
|
168 let deferred = promise.defer(); |
|
169 |
|
170 (function runTest() { |
|
171 if (aTests.length) { |
|
172 let test = aTests.shift(); |
|
173 test.prepare(); |
|
174 aScratchpad[test.method]().then(test.then.bind(test)).then(runTest); |
|
175 } else { |
|
176 deferred.resolve(); |
|
177 } |
|
178 })(); |
|
179 |
|
180 return deferred.promise; |
|
181 } |
|
182 |
|
183 |
|
184 function cleanup() |
|
185 { |
|
186 if (gScratchpadWindow) { |
|
187 gScratchpadWindow.close(); |
|
188 gScratchpadWindow = null; |
|
189 } |
|
190 while (gBrowser.tabs.length > 1) { |
|
191 gBrowser.removeCurrentTab(); |
|
192 } |
|
193 } |
|
194 |
|
195 registerCleanupFunction(cleanup); |