|
1 /* This Source Code Form is subject to the terms of the Mozilla Public |
|
2 * License, v. 2.0. If a copy of the MPL was not distributed with this |
|
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
|
4 |
|
5 const prefs = require("sdk/preferences/service"); |
|
6 const { id, name } = require("sdk/self"); |
|
7 const { Cc, Cu, Ci } = require("chrome"); |
|
8 const { loadSubScript } = Cc['@mozilla.org/moz/jssubscript-loader;1']. |
|
9 getService(Ci.mozIJSSubScriptLoader); |
|
10 |
|
11 const ADDON_LOG_LEVEL_PREF = "extensions." + id + ".sdk.console.logLevel"; |
|
12 const SDK_LOG_LEVEL_PREF = "extensions.sdk.console.logLevel"; |
|
13 |
|
14 const HAS_ORIGINAL_ADDON_LOG_LEVEL = prefs.has(ADDON_LOG_LEVEL_PREF); |
|
15 const ORIGINAL_ADDON_LOG_LEVEL = prefs.get(ADDON_LOG_LEVEL_PREF); |
|
16 const HAS_ORIGINAL_SDK_LOG_LEVEL = prefs.has(SDK_LOG_LEVEL_PREF); |
|
17 const ORIGINAL_SDK_LOG_LEVEL = prefs.get(SDK_LOG_LEVEL_PREF); |
|
18 |
|
19 exports.testPlainTextConsole = function(assert) { |
|
20 let prints = []; |
|
21 function print(message) { |
|
22 prints.push(message); |
|
23 } |
|
24 function lastPrint() { |
|
25 let last = prints.slice(-1)[0]; |
|
26 prints = []; |
|
27 return last; |
|
28 } |
|
29 |
|
30 prefs.set(SDK_LOG_LEVEL_PREF, "all"); |
|
31 prefs.reset(ADDON_LOG_LEVEL_PREF); |
|
32 |
|
33 let Console = require("sdk/console/plain-text").PlainTextConsole; |
|
34 let con = new Console(print); |
|
35 |
|
36 assert.ok("PlainTextConsole instantiates"); |
|
37 |
|
38 con.log('testing', 1, [2, 3, 4]); |
|
39 assert.equal(lastPrint(), "console.log: " + name + ": testing 1 Array [2,3,4]\n", |
|
40 "PlainTextConsole.log() must work."); |
|
41 |
|
42 con.info('testing', 1, [2, 3, 4]); |
|
43 assert.equal(lastPrint(), "console.info: " + name + ": testing 1 Array [2,3,4]\n", |
|
44 "PlainTextConsole.info() must work."); |
|
45 |
|
46 con.warn('testing', 1, [2, 3, 4]); |
|
47 assert.equal(lastPrint(), "console.warn: " + name + ": testing 1 Array [2,3,4]\n", |
|
48 "PlainTextConsole.warn() must work."); |
|
49 |
|
50 con.error('testing', 1, [2, 3, 4]); |
|
51 assert.equal(prints[0], "console.error: " + name + ": \n", |
|
52 "PlainTextConsole.error() must work."); |
|
53 assert.equal(prints[1], " testing\n") |
|
54 assert.equal(prints[2], " 1\n") |
|
55 assert.equal(prints[3], "Array\n - 0 = 2\n - 1 = 3\n - 2 = 4\n - length = 3\n"); |
|
56 prints = []; |
|
57 |
|
58 con.debug('testing', 1, [2, 3, 4]); |
|
59 assert.equal(prints[0], "console.debug: " + name + ": \n", |
|
60 "PlainTextConsole.debug() must work."); |
|
61 assert.equal(prints[1], " testing\n") |
|
62 assert.equal(prints[2], " 1\n") |
|
63 assert.equal(prints[3], "Array\n - 0 = 2\n - 1 = 3\n - 2 = 4\n - length = 3\n"); |
|
64 prints = []; |
|
65 |
|
66 con.log('testing', undefined); |
|
67 assert.equal(lastPrint(), "console.log: " + name + ": testing undefined\n", |
|
68 "PlainTextConsole.log() must stringify undefined."); |
|
69 |
|
70 con.log('testing', null); |
|
71 assert.equal(lastPrint(), "console.log: " + name + ": testing null\n", |
|
72 "PlainTextConsole.log() must stringify null."); |
|
73 |
|
74 // TODO: Fix console.jsm to detect custom toString. |
|
75 con.log("testing", { toString: function() "obj.toString()" }); |
|
76 assert.equal(lastPrint(), "console.log: " + name + ": testing {}\n", |
|
77 "PlainTextConsole.log() doesn't printify custom toString."); |
|
78 |
|
79 con.log("testing", { toString: function() { throw "fail!"; } }); |
|
80 assert.equal(lastPrint(), "console.log: " + name + ": testing {}\n", |
|
81 "PlainTextConsole.log() must stringify custom bad toString."); |
|
82 |
|
83 |
|
84 con.exception(new Error("blah")); |
|
85 |
|
86 |
|
87 assert.equal(prints[0], "console.error: " + name + ": \n"); |
|
88 let tbLines = prints[1].split("\n"); |
|
89 assert.equal(tbLines[0], " Message: Error: blah"); |
|
90 assert.equal(tbLines[1], " Stack:"); |
|
91 assert.ok(prints[1].indexOf(module.uri + ":84") !== -1); |
|
92 prints = [] |
|
93 |
|
94 try { |
|
95 loadSubScript("invalid-url", {}); |
|
96 assert.fail("successed in calling loadSubScript with invalid-url"); |
|
97 } |
|
98 catch(e) { |
|
99 con.exception(e); |
|
100 } |
|
101 assert.equal(prints[0], "console.error: " + name + ": \n"); |
|
102 assert.equal(prints[1], " Error creating URI (invalid URL scheme?)\n"); |
|
103 prints = []; |
|
104 |
|
105 con.trace(); |
|
106 let tbLines = prints[0].split("\n"); |
|
107 assert.equal(tbLines[0], "console.trace: " + name + ": "); |
|
108 assert.ok(tbLines[1].indexOf("_ain-text-console.js 105") == 0); |
|
109 prints = []; |
|
110 |
|
111 // Whether or not console methods should print at the various log levels, |
|
112 // structured as a hash of levels, each of which contains a hash of methods, |
|
113 // each of whose value is whether or not it should print, i.e.: |
|
114 // { [level]: { [method]: [prints?], ... }, ... }. |
|
115 let levels = { |
|
116 all: { debug: true, log: true, info: true, warn: true, error: true }, |
|
117 debug: { debug: true, log: true, info: true, warn: true, error: true }, |
|
118 info: { debug: false, log: true, info: true, warn: true, error: true }, |
|
119 warn: { debug: false, log: false, info: false, warn: true, error: true }, |
|
120 error: { debug: false, log: false, info: false, warn: false, error: true }, |
|
121 off: { debug: false, log: false, info: false, warn: false, error: false }, |
|
122 }; |
|
123 |
|
124 // The messages we use to test the various methods, as a hash of methods. |
|
125 let messages = { |
|
126 debug: "console.debug: " + name + ": \n \n", |
|
127 log: "console.log: " + name + ": \n", |
|
128 info: "console.info: " + name + ": \n", |
|
129 warn: "console.warn: " + name + ": \n", |
|
130 error: "console.error: " + name + ": \n \n", |
|
131 }; |
|
132 |
|
133 for (let level in levels) { |
|
134 let methods = levels[level]; |
|
135 for (let method in methods) { |
|
136 // We have to reset the log level pref each time we run the test |
|
137 // because the test runner relies on the console to print test output, |
|
138 // and test results would not get printed to the console for some |
|
139 // values of the pref. |
|
140 prefs.set(SDK_LOG_LEVEL_PREF, level); |
|
141 con[method](""); |
|
142 prefs.set(SDK_LOG_LEVEL_PREF, "all"); |
|
143 assert.equal(prints.join(""), |
|
144 (methods[method] ? messages[method] : ""), |
|
145 "at log level '" + level + "', " + method + "() " + |
|
146 (methods[method] ? "prints" : "doesn't print")); |
|
147 prints = []; |
|
148 } |
|
149 } |
|
150 |
|
151 prefs.set(SDK_LOG_LEVEL_PREF, "off"); |
|
152 prefs.set(ADDON_LOG_LEVEL_PREF, "all"); |
|
153 con.debug(""); |
|
154 assert.equal(prints.join(""), messages["debug"], |
|
155 "addon log level 'all' overrides SDK log level 'off'"); |
|
156 prints = []; |
|
157 |
|
158 prefs.set(SDK_LOG_LEVEL_PREF, "all"); |
|
159 prefs.set(ADDON_LOG_LEVEL_PREF, "off"); |
|
160 con.error(""); |
|
161 prefs.reset(ADDON_LOG_LEVEL_PREF); |
|
162 assert.equal(lastPrint(), null, |
|
163 "addon log level 'off' overrides SDK log level 'all'"); |
|
164 |
|
165 restorePrefs(); |
|
166 }; |
|
167 |
|
168 exports.testPlainTextConsoleBoundMethods = function(assert) { |
|
169 let prints = []; |
|
170 function print(message) { |
|
171 prints.push(message); |
|
172 } |
|
173 function lastPrint() { |
|
174 let last = prints.slice(-1)[0]; |
|
175 prints = []; |
|
176 return last; |
|
177 } |
|
178 |
|
179 prefs.set(SDK_LOG_LEVEL_PREF, "all"); |
|
180 prefs.reset(ADDON_LOG_LEVEL_PREF); |
|
181 |
|
182 let Console = require("sdk/console/plain-text").PlainTextConsole; |
|
183 let { log, info, warn, error, debug, exception, trace } = new Console(print); |
|
184 |
|
185 assert.ok("PlainTextConsole instantiates"); |
|
186 |
|
187 log('testing', 1, [2, 3, 4]); |
|
188 assert.equal(lastPrint(), "console.log: " + name + ": testing 1 Array [2,3,4]\n", |
|
189 "PlainTextConsole.log() must work."); |
|
190 |
|
191 info('testing', 1, [2, 3, 4]); |
|
192 assert.equal(lastPrint(), "console.info: " + name + ": testing 1 Array [2,3,4]\n", |
|
193 "PlainTextConsole.info() must work."); |
|
194 |
|
195 warn('testing', 1, [2, 3, 4]); |
|
196 assert.equal(lastPrint(), "console.warn: " + name + ": testing 1 Array [2,3,4]\n", |
|
197 "PlainTextConsole.warn() must work."); |
|
198 |
|
199 error('testing', 1, [2, 3, 4]); |
|
200 assert.equal(prints[0], "console.error: " + name + ": \n", |
|
201 "PlainTextConsole.error() must work."); |
|
202 assert.equal(prints[1], " testing\n") |
|
203 assert.equal(prints[2], " 1\n") |
|
204 assert.equal(prints[3], "Array\n - 0 = 2\n - 1 = 3\n - 2 = 4\n - length = 3\n"); |
|
205 prints = []; |
|
206 |
|
207 debug('testing', 1, [2, 3, 4]); |
|
208 assert.equal(prints[0], "console.debug: " + name + ": \n", |
|
209 "PlainTextConsole.debug() must work."); |
|
210 assert.equal(prints[1], " testing\n") |
|
211 assert.equal(prints[2], " 1\n") |
|
212 assert.equal(prints[3], "Array\n - 0 = 2\n - 1 = 3\n - 2 = 4\n - length = 3\n"); |
|
213 prints = []; |
|
214 |
|
215 exception(new Error("blah")); |
|
216 |
|
217 assert.equal(prints[0], "console.error: " + name + ": \n"); |
|
218 let tbLines = prints[1].split("\n"); |
|
219 assert.equal(tbLines[0], " Message: Error: blah"); |
|
220 assert.equal(tbLines[1], " Stack:"); |
|
221 assert.ok(prints[1].indexOf(module.uri + ":215") !== -1); |
|
222 prints = [] |
|
223 |
|
224 trace(); |
|
225 let tbLines = prints[0].split("\n"); |
|
226 assert.equal(tbLines[0], "console.trace: " + name + ": "); |
|
227 assert.ok(tbLines[1].indexOf("_ain-text-console.js 224") === 0); |
|
228 prints = []; |
|
229 |
|
230 restorePrefs(); |
|
231 }; |
|
232 |
|
233 exports.testConsoleInnerID = function(assert) { |
|
234 let Console = require("sdk/console/plain-text").PlainTextConsole; |
|
235 let { log, info, warn, error, debug, exception, trace } = new Console(function() {}, "test ID"); |
|
236 |
|
237 let messages = []; |
|
238 function onMessage({ subject }) { |
|
239 let message = subject.wrappedJSObject; |
|
240 messages.push({ msg: message.arguments[0], type: message.level, innerID: message.innerID }); |
|
241 } |
|
242 |
|
243 const system = require("sdk/system/events"); |
|
244 system.on("console-api-log-event", onMessage); |
|
245 |
|
246 log("Test log"); |
|
247 warn("Test warning"); |
|
248 error("Test error"); |
|
249 |
|
250 assert.equal(messages.length, 3, "Should see 3 log events"); |
|
251 assert.deepEqual(messages[0], { msg: "Test log", type: "log", innerID: "test ID" }, "Should see the right event"); |
|
252 assert.deepEqual(messages[1], { msg: "Test warning", type: "warn", innerID: "test ID" }, "Should see the right event"); |
|
253 assert.deepEqual(messages[2], { msg: "Test error", type: "error", innerID: "test ID" }, "Should see the right event"); |
|
254 |
|
255 system.off("console-api-log-event", onMessage); |
|
256 }; |
|
257 |
|
258 function restorePrefs() { |
|
259 if (HAS_ORIGINAL_ADDON_LOG_LEVEL) |
|
260 prefs.set(ADDON_LOG_LEVEL_PREF, ORIGINAL_ADDON_LOG_LEVEL); |
|
261 else |
|
262 prefs.reset(ADDON_LOG_LEVEL_PREF); |
|
263 |
|
264 if (HAS_ORIGINAL_SDK_LOG_LEVEL) |
|
265 prefs.set(SDK_LOG_LEVEL_PREF, ORIGINAL_SDK_LOG_LEVEL); |
|
266 else |
|
267 prefs.reset(SDK_LOG_LEVEL_PREF); |
|
268 } |
|
269 |
|
270 require("test").run(exports); |