1 |
|
2 |
|
3 |
|
4 | var test = require("tape")
|
5 | var asyncify = require("simple-asyncify")
|
6 | var common = require("./common")
|
7 | var u = common.u
|
8 | var read = common.read
|
9 | var Throws = common.Throws
|
10 | var identity = common.identity
|
11 |
|
12 | var sourceMapResolve = require("../")
|
13 |
|
14 |
|
15 | require("setimmediate")
|
16 | if (typeof window !== "undefined" && !window.atob) {
|
17 | window.atob = require("Base64").atob
|
18 | }
|
19 |
|
20 | "use strict"
|
21 |
|
22 | var map = {
|
23 | simple: {
|
24 | mappings: "AAAA",
|
25 | sources: ["foo.js"],
|
26 | names: []
|
27 | },
|
28 | sourceRoot: {
|
29 | mappings: "AAAA",
|
30 | sourceRoot: "/static/js/app/",
|
31 | sources: ["foo.js", "lib/bar.js", "../vendor/dom.js", "/version.js", "//foo.org/baz.js"],
|
32 | names: []
|
33 | },
|
34 | sourceRootNoSlash: {
|
35 | mappings: "AAAA",
|
36 | sourceRoot: "/static/js/app",
|
37 | sources: ["foo.js", "lib/bar.js", "../vendor/dom.js", "/version.js", "//foo.org/baz.js"],
|
38 | names: []
|
39 | },
|
40 | sourcesContent: {
|
41 | mappings: "AAAA",
|
42 | sourceRoot: "/static/js/app/",
|
43 | sources: ["foo.js", "lib/bar.js", "../vendor/dom.js", "/version.js", "//foo.org/baz.js"],
|
44 | sourcesContent: ["foo.js", "lib/bar.js", "../vendor/dom.js", "/version.js", "//foo.org/baz.js"],
|
45 | names: []
|
46 | },
|
47 | mixed: {
|
48 | mappings: "AAAA",
|
49 | sources: ["foo.js", "lib/bar.js", "../vendor/dom.js", "/version.js", "//foo.org/baz.js"],
|
50 | sourcesContent: ["foo.js", null , null , "/version.js", "//foo.org/baz.js"],
|
51 | names: []
|
52 | }
|
53 | }
|
54 | map.simpleString = JSON.stringify(map.simple)
|
55 | map.XSSIsafe = ")]}'" + map.simpleString
|
56 |
|
57 | var code = {
|
58 | fileRelative: u("foo.js.map"),
|
59 | domainRelative: u("/foo.js.map"),
|
60 | schemeRelative: u("//foo.org/foo.js.map"),
|
61 | absolute: u("https://foo.org/foo.js.map"),
|
62 | dataUri: u("data:application/json," +
|
63 | "%7B%22mappings%22%3A%22AAAA%22%2C%22sources%22%3A%5B%22" +
|
64 | "foo.js%22%5D%2C%22names%22%3A%5B%5D%7D"),
|
65 | base64: u("data:application/json;base64," +
|
66 | "eyJtYXBwaW5ncyI6IkFBQUEiLCJzb3VyY2VzIjpbImZvby5qcyJdLCJuYW1lcyI6W119"),
|
67 | dataUriText: u("data:text/json," +
|
68 | "%7B%22mappings%22%3A%22AAAA%22%2C%22sources%22%3A%5B%22" +
|
69 | "foo.js%22%5D%2C%22names%22%3A%5B%5D%7D"),
|
70 | dataUriParameter: u("data:application/json;charset=UTF-8;foo=bar," +
|
71 | "%7B%22mappings%22%3A%22AAAA%22%2C%22sources%22%3A%5B%22" +
|
72 | "foo.js%22%5D%2C%22names%22%3A%5B%5D%7D"),
|
73 | dataUriNoMime: u("data:,foo"),
|
74 | dataUriInvalidMime: u("data:text/html,foo"),
|
75 | dataUriInvalidJSON: u("data:application/json,foo"),
|
76 | dataUriXSSIsafe: u("data:application/json," + ")%5D%7D%27" +
|
77 | "%7B%22mappings%22%3A%22AAAA%22%2C%22sources%22%3A%5B%22" +
|
78 | "foo.js%22%5D%2C%22names%22%3A%5B%5D%7D"),
|
79 | dataUriEmpty: u("data:"),
|
80 | noMap: ""
|
81 | }
|
82 |
|
83 | function throwsError(t, method, args, num, desc) {
|
84 | t["throws"](
|
85 | function() { method.apply(null, args) },
|
86 | RegExp("argument " + num + ".+" + desc + ".+\\n" + args[num-1])
|
87 | )
|
88 | }
|
89 |
|
90 |
|
91 | function testResolveSourceMap(method, sync) {
|
92 | return function(t) {
|
93 | var wrap = (sync ? identity : asyncify)
|
94 |
|
95 | var codeUrl = "http://example.com/a/b/c/foo.js"
|
96 |
|
97 | t.plan(1 + (sync ? 7 : 10) + 18*3)
|
98 |
|
99 | t.equal(typeof method, "function", "is a function")
|
100 |
|
101 | throwsError(t, method, [ ], 1, "code")
|
102 | throwsError(t, method, [null ], 1, "code")
|
103 | throwsError(t, method, ["foo" ], 2, "code url")
|
104 | throwsError(t, method, ["foo", null ], 2, "code url")
|
105 | throwsError(t, method, ["foo", "bar" ], 3, "read")
|
106 | throwsError(t, method, ["foo", "bar", null ], 3, "read")
|
107 | throwsError(t, method, ["foo", "bar", "baz"], 3, "read")
|
108 | if (!sync) {
|
109 | throwsError(t, method, ["foo", "bar", read() ], 4, "callback")
|
110 | throwsError(t, method, ["foo", "bar", read(), null ], 4, "callback")
|
111 | throwsError(t, method, ["foo", "bar", read(), "baz"], 4, "callback")
|
112 | }
|
113 |
|
114 | if (sync) {
|
115 | method = asyncify(method)
|
116 | }
|
117 |
|
118 | var next = false
|
119 | function isAsync() { t.ok(next, "is async") }
|
120 |
|
121 | method(code.fileRelative, codeUrl, wrap(read(map.simpleString)), function(error, result) {
|
122 | t.error(error)
|
123 | t.deepEqual(result, {
|
124 | sourceMappingURL: "foo.js.map",
|
125 | url: "http://example.com/a/b/c/foo.js.map",
|
126 | sourcesRelativeTo: "http://example.com/a/b/c/foo.js.map",
|
127 | map: map.simple
|
128 | }, "fileRelative")
|
129 | isAsync()
|
130 | })
|
131 |
|
132 | method(code.domainRelative, codeUrl, wrap(read(map.simpleString)), function(error, result) {
|
133 | t.error(error)
|
134 | t.deepEqual(result, {
|
135 | sourceMappingURL: "/foo.js.map",
|
136 | url: "http://example.com/foo.js.map",
|
137 | sourcesRelativeTo: "http://example.com/foo.js.map",
|
138 | map: map.simple
|
139 | }, "domainRelative")
|
140 | isAsync()
|
141 | })
|
142 |
|
143 | method(code.schemeRelative, codeUrl, wrap(read(map.simpleString)), function(error, result) {
|
144 | t.error(error)
|
145 | t.deepEqual(result, {
|
146 | sourceMappingURL: "//foo.org/foo.js.map",
|
147 | url: "http://foo.org/foo.js.map",
|
148 | sourcesRelativeTo: "http://foo.org/foo.js.map",
|
149 | map: map.simple
|
150 | }, "schemeRelative")
|
151 | isAsync()
|
152 | })
|
153 |
|
154 | method(code.absolute, codeUrl, wrap(read(map.simpleString)), function(error, result) {
|
155 | t.error(error)
|
156 | t.deepEqual(result, {
|
157 | sourceMappingURL: "https://foo.org/foo.js.map",
|
158 | url: "https://foo.org/foo.js.map",
|
159 | sourcesRelativeTo: "https://foo.org/foo.js.map",
|
160 | map: map.simple
|
161 | }, "absolute")
|
162 | isAsync()
|
163 | })
|
164 |
|
165 | method(code.dataUri, codeUrl, wrap(Throws), function(error, result) {
|
166 | t.error(error)
|
167 | t.deepEqual(result, {
|
168 | sourceMappingURL: "data:application/json," +
|
169 | "%7B%22mappings%22%3A%22AAAA%22%2C%22sources%22%3A%5B%22" +
|
170 | "foo.js%22%5D%2C%22names%22%3A%5B%5D%7D",
|
171 | url: null,
|
172 | sourcesRelativeTo: codeUrl,
|
173 | map: map.simple
|
174 | }, "dataUri")
|
175 | isAsync()
|
176 | })
|
177 |
|
178 | method(code.base64, codeUrl, wrap(Throws), function(error, result) {
|
179 | t.error(error)
|
180 | t.deepEqual(result, {
|
181 | sourceMappingURL: "data:application/json;base64," +
|
182 | "eyJtYXBwaW5ncyI6IkFBQUEiLCJzb3VyY2VzIjpbImZvby5qcyJdLCJuYW1lcyI6W119",
|
183 | url: null,
|
184 | sourcesRelativeTo: codeUrl,
|
185 | map: map.simple
|
186 | }, "base64")
|
187 | isAsync()
|
188 | })
|
189 |
|
190 | method(code.dataUriText, codeUrl, wrap(Throws), function(error, result) {
|
191 | t.error(error)
|
192 | t.deepEqual(result, {
|
193 | sourceMappingURL: "data:text/json," +
|
194 | "%7B%22mappings%22%3A%22AAAA%22%2C%22sources%22%3A%5B%22" +
|
195 | "foo.js%22%5D%2C%22names%22%3A%5B%5D%7D",
|
196 | url: null,
|
197 | sourcesRelativeTo: codeUrl,
|
198 | map: map.simple
|
199 | }, "dataUriText")
|
200 | isAsync()
|
201 | })
|
202 |
|
203 | method(code.dataUriParameter, codeUrl, wrap(Throws), function(error, result) {
|
204 | t.error(error)
|
205 | t.deepEqual(result, {
|
206 | sourceMappingURL: "data:application/json;charset=UTF-8;foo=bar," +
|
207 | "%7B%22mappings%22%3A%22AAAA%22%2C%22sources%22%3A%5B%22" +
|
208 | "foo.js%22%5D%2C%22names%22%3A%5B%5D%7D",
|
209 | url: null,
|
210 | sourcesRelativeTo: codeUrl,
|
211 | map: map.simple
|
212 | }, "dataUriParameter")
|
213 | isAsync()
|
214 | })
|
215 |
|
216 | method(code.dataUriNoMime, codeUrl, wrap(Throws), function(error, result) {
|
217 | t.ok(error.message.match(/mime type.+text\/plain/), "dataUriNoMime")
|
218 | t.notOk(result)
|
219 | isAsync()
|
220 | })
|
221 |
|
222 | method(code.dataUriInvalidMime, codeUrl, wrap(Throws), function(error, result) {
|
223 | t.ok(error.message.match(/mime type.+text\/html/), "dataUriInvalidMime")
|
224 | t.notOk(result)
|
225 | isAsync()
|
226 | })
|
227 |
|
228 | method(code.dataUriInvalidJSON, codeUrl, wrap(Throws), function(error, result) {
|
229 | t.ok(error instanceof SyntaxError && error.message !== "data:application/json,foo",
|
230 | "dataUriInvalidJSON")
|
231 | t.notOk(result)
|
232 | isAsync()
|
233 | })
|
234 |
|
235 | method(code.dataUriXSSIsafe, codeUrl, wrap(Throws), function(error, result) {
|
236 | t.error(error)
|
237 | t.deepEqual(result, {
|
238 | sourceMappingURL: "data:application/json," + ")%5D%7D%27" +
|
239 | "%7B%22mappings%22%3A%22AAAA%22%2C%22sources%22%3A%5B%22" +
|
240 | "foo.js%22%5D%2C%22names%22%3A%5B%5D%7D",
|
241 | url: null,
|
242 | sourcesRelativeTo: codeUrl,
|
243 | map: map.simple
|
244 | }, "dataUriXSSIsafe")
|
245 | isAsync()
|
246 | })
|
247 |
|
248 | method(code.dataUriEmpty, codeUrl, wrap(Throws), function(error, result) {
|
249 | t.ok(error.message.match(/mime type.+text\/plain/), "dataUriEmpty")
|
250 | t.notOk(result)
|
251 | isAsync()
|
252 | })
|
253 |
|
254 | method(code.noMap, codeUrl, wrap(Throws), function(error, result) {
|
255 | t.error(error)
|
256 | t.equal(result, null, "noMap")
|
257 | isAsync()
|
258 | })
|
259 |
|
260 | method(code.absolute, codeUrl, wrap(read([map.simpleString])), function(error, result) {
|
261 | t.error(error)
|
262 | t.deepEqual(result, {
|
263 | sourceMappingURL: "https://foo.org/foo.js.map",
|
264 | url: "https://foo.org/foo.js.map",
|
265 | sourcesRelativeTo: "https://foo.org/foo.js.map",
|
266 | map: map.simple
|
267 | }, "read non-string")
|
268 | isAsync()
|
269 | })
|
270 |
|
271 | method(code.absolute, codeUrl, wrap(read("invalid JSON")), function(error, result) {
|
272 | t.ok(error instanceof SyntaxError, "read invalid JSON")
|
273 | t.notOk(result)
|
274 | isAsync()
|
275 | })
|
276 |
|
277 | method(code.absolute, codeUrl, wrap(read(map.XSSIsafe)), function(error, result) {
|
278 | t.error(error)
|
279 | t.deepEqual(result, {
|
280 | sourceMappingURL: "https://foo.org/foo.js.map",
|
281 | url: "https://foo.org/foo.js.map",
|
282 | sourcesRelativeTo: "https://foo.org/foo.js.map",
|
283 | map: map.simple
|
284 | }, "XSSIsafe map")
|
285 | isAsync()
|
286 | })
|
287 |
|
288 | method(code.absolute, codeUrl, wrap(Throws), function(error, result) {
|
289 | t.equal(error.message, "https://foo.org/foo.js.map", "read throws")
|
290 | t.notOk(result)
|
291 | isAsync()
|
292 | })
|
293 |
|
294 | next = true
|
295 | }
|
296 | }
|
297 |
|
298 | test(".resolveSourceMap", testResolveSourceMap(sourceMapResolve.resolveSourceMap, false))
|
299 |
|
300 | test(".resolveSourceMapSync", testResolveSourceMap(sourceMapResolve.resolveSourceMapSync, true))
|
301 |
|
302 |
|
303 | function testResolveSources(method, sync) {
|
304 | return function(t) {
|
305 | var wrap = (sync ? identity : asyncify)
|
306 |
|
307 | var mapUrl = "http://example.com/a/b/c/foo.js.map"
|
308 |
|
309 | t.plan(1 + (sync ? 8 : 11) + 6*3 + 4)
|
310 |
|
311 | t.equal(typeof method, "function", "is a function")
|
312 |
|
313 | throwsError(t, method, [ ], 1, "source map")
|
314 | throwsError(t, method, [null ], 1, "source map")
|
315 | throwsError(t, method, ["foo" ], 1, "source map")
|
316 | throwsError(t, method, [{} ], 2, "map url")
|
317 | throwsError(t, method, [{}, null ], 2, "map url")
|
318 | throwsError(t, method, [{}, "bar" ], 3, "read")
|
319 | throwsError(t, method, [{}, "bar", null ], 3, "read")
|
320 | throwsError(t, method, [{}, "bar", "baz" ], 3, "read")
|
321 | if (!sync) {
|
322 | throwsError(t, method, [{}, "bar", read() ], 4, "callback")
|
323 | throwsError(t, method, [{}, "bar", read(), null ], 4, "callback")
|
324 | throwsError(t, method, [{}, "bar", read(), "baz"], 4, "callback")
|
325 | }
|
326 |
|
327 | if (sync) {
|
328 | method = asyncify(method)
|
329 | }
|
330 |
|
331 | var next = false
|
332 | function isAsync() { t.ok(next, "is async") }
|
333 |
|
334 | method(map.simple, mapUrl, wrap(identity), function(error, result) {
|
335 | t.error(error)
|
336 | t.deepEqual(result, ["http://example.com/a/b/c/foo.js"], "simple")
|
337 | isAsync()
|
338 | })
|
339 |
|
340 | method(map.sourceRoot, mapUrl, wrap(identity), function(error, result) {
|
341 | t.error(error)
|
342 | t.deepEqual(result, [
|
343 | "http://example.com/static/js/app/foo.js",
|
344 | "http://example.com/static/js/app/lib/bar.js",
|
345 | "http://example.com/static/js/vendor/dom.js",
|
346 | "http://example.com/version.js",
|
347 | "http://foo.org/baz.js"
|
348 | ], "sourceRoot")
|
349 | isAsync()
|
350 | })
|
351 |
|
352 | method(map.sourceRootNoSlash, mapUrl, wrap(identity), function(error, result) {
|
353 | t.error(error)
|
354 | t.deepEqual(result, [
|
355 | "http://example.com/static/js/app/foo.js",
|
356 | "http://example.com/static/js/app/lib/bar.js",
|
357 | "http://example.com/static/js/vendor/dom.js",
|
358 | "http://example.com/version.js",
|
359 | "http://foo.org/baz.js"
|
360 | ], "sourceRootNoSlash")
|
361 | isAsync()
|
362 | })
|
363 |
|
364 | method(map.sourcesContent, mapUrl, wrap(Throws), function(error, result) {
|
365 | t.error(error)
|
366 | t.deepEqual(result, [
|
367 | "foo.js",
|
368 | "lib/bar.js",
|
369 | "../vendor/dom.js",
|
370 | "/version.js",
|
371 | "//foo.org/baz.js"
|
372 | ], "sourcesContent")
|
373 | isAsync()
|
374 | })
|
375 |
|
376 | method(map.mixed, mapUrl, wrap(identity), function(error, result) {
|
377 | t.error(error)
|
378 | t.deepEqual(result, [
|
379 | "foo.js",
|
380 | "http://example.com/a/b/c/lib/bar.js",
|
381 | "http://example.com/a/b/vendor/dom.js",
|
382 | "/version.js",
|
383 | "//foo.org/baz.js"
|
384 | ], "mixed")
|
385 | isAsync()
|
386 | })
|
387 |
|
388 | method(map.simple, mapUrl, wrap(read(["non", "string"])), function(error, result) {
|
389 | t.error(error)
|
390 | t.deepEqual(result, ["non,string"], "read non-string")
|
391 | isAsync()
|
392 | })
|
393 |
|
394 | var calledBack = false
|
395 | method(map.mixed, mapUrl, wrap(Throws), function(error, result) {
|
396 | t.equal(calledBack, false)
|
397 | calledBack = true
|
398 | t.equal(error.message, "http://example.com/a/b/c/lib/bar.js", "read throws")
|
399 | t.notOk(result)
|
400 | isAsync()
|
401 | })
|
402 |
|
403 | next = true
|
404 | }
|
405 | }
|
406 |
|
407 | test(".resolveSources", testResolveSources(sourceMapResolve.resolveSources, false))
|
408 |
|
409 | test(".resolveSourcesSync", testResolveSources(sourceMapResolve.resolveSourcesSync, true))
|
410 |
|
411 |
|
412 | function testResolve(method, sync) {
|
413 | return function(t) {
|
414 | var wrap = (sync ? identity : asyncify)
|
415 | var wrapMap = function(mapFn, fn) {
|
416 | return wrap(function(url) {
|
417 | if (/\.map$/.test(url)) {
|
418 | return mapFn(url)
|
419 | }
|
420 | return fn(url)
|
421 | })
|
422 | }
|
423 |
|
424 | var codeUrl = "http://example.com/a/b/c/foo.js"
|
425 |
|
426 | t.plan(1 + (sync ? 7 : 10) + 18*3 + 6*3 + 4)
|
427 |
|
428 | t.equal(typeof method, "function", "is a function")
|
429 |
|
430 | throwsError(t, method, [ ], 1, "code")
|
431 | throwsError(t, method, [null ], 1, "code")
|
432 | throwsError(t, method, ["foo" ], 2, "code url")
|
433 | throwsError(t, method, ["foo", null ], 2, "code url")
|
434 | throwsError(t, method, ["foo", "bar" ], 3, "read")
|
435 | throwsError(t, method, ["foo", "bar", null ], 3, "read")
|
436 | throwsError(t, method, ["foo", "bar", "baz"], 3, "read")
|
437 | if (!sync) {
|
438 | throwsError(t, method, ["foo", "bar", read(map.simpleString) ], 4, "callback")
|
439 | throwsError(t, method, ["foo", "bar", read(map.simpleString), null ], 4, "callback")
|
440 | throwsError(t, method, ["foo", "bar", read(map.simpleString), "baz"], 4, "callback")
|
441 | }
|
442 |
|
443 | if (sync) {
|
444 | method = asyncify(method)
|
445 | }
|
446 |
|
447 | var next = false
|
448 | function isAsync() { t.ok(next, "is async") }
|
449 |
|
450 | var readSimple = wrapMap(read(map.simpleString), identity)
|
451 |
|
452 | method(code.fileRelative, codeUrl, readSimple, function(error, result) {
|
453 | t.error(error)
|
454 | t.deepEqual(result, {
|
455 | sourceMappingURL: "foo.js.map",
|
456 | url: "http://example.com/a/b/c/foo.js.map",
|
457 | sourcesRelativeTo: "http://example.com/a/b/c/foo.js.map",
|
458 | map: map.simple,
|
459 | sources: ["http://example.com/a/b/c/foo.js"]
|
460 | }, "fileRelative")
|
461 | isAsync()
|
462 | })
|
463 |
|
464 | method(code.domainRelative, codeUrl, readSimple, function(error, result) {
|
465 | t.error(error)
|
466 | t.deepEqual(result, {
|
467 | sourceMappingURL: "/foo.js.map",
|
468 | url: "http://example.com/foo.js.map",
|
469 | sourcesRelativeTo: "http://example.com/foo.js.map",
|
470 | map: map.simple,
|
471 | sources: ["http://example.com/foo.js"]
|
472 | }, "domainRelative")
|
473 | isAsync()
|
474 | })
|
475 |
|
476 | method(code.schemeRelative, codeUrl, readSimple, function(error, result) {
|
477 | t.error(error)
|
478 | t.deepEqual(result, {
|
479 | sourceMappingURL: "//foo.org/foo.js.map",
|
480 | url: "http://foo.org/foo.js.map",
|
481 | sourcesRelativeTo: "http://foo.org/foo.js.map",
|
482 | map: map.simple,
|
483 | sources: ["http://foo.org/foo.js"]
|
484 | }, "schemeRelative")
|
485 | isAsync()
|
486 | })
|
487 |
|
488 | method(code.absolute, codeUrl, readSimple, function(error, result) {
|
489 | t.error(error)
|
490 | t.deepEqual(result, {
|
491 | sourceMappingURL: "https://foo.org/foo.js.map",
|
492 | url: "https://foo.org/foo.js.map",
|
493 | sourcesRelativeTo: "https://foo.org/foo.js.map",
|
494 | map: map.simple,
|
495 | sources: ["https://foo.org/foo.js"]
|
496 | }, "absolute")
|
497 | isAsync()
|
498 | })
|
499 |
|
500 | method(code.dataUri, codeUrl, wrapMap(Throws, identity), function(error, result) {
|
501 | t.error(error)
|
502 | t.deepEqual(result, {
|
503 | sourceMappingURL: "data:application/json," +
|
504 | "%7B%22mappings%22%3A%22AAAA%22%2C%22sources%22%3A%5B%22" +
|
505 | "foo.js%22%5D%2C%22names%22%3A%5B%5D%7D",
|
506 | url: null,
|
507 | sourcesRelativeTo: codeUrl,
|
508 | map: map.simple,
|
509 | sources: ["http://example.com/a/b/c/foo.js"]
|
510 | }, "dataUri")
|
511 | isAsync()
|
512 | })
|
513 |
|
514 | method(code.base64, codeUrl, wrapMap(Throws, identity), function(error, result) {
|
515 | t.error(error)
|
516 | t.deepEqual(result, {
|
517 | sourceMappingURL: "data:application/json;base64," +
|
518 | "eyJtYXBwaW5ncyI6IkFBQUEiLCJzb3VyY2VzIjpbImZvby5qcyJdLCJuYW1lcyI6W119",
|
519 | url: null,
|
520 | sourcesRelativeTo: codeUrl,
|
521 | map: map.simple,
|
522 | sources: ["http://example.com/a/b/c/foo.js"]
|
523 | }, "base64")
|
524 | isAsync()
|
525 | })
|
526 |
|
527 | method(code.dataUriText, codeUrl, wrapMap(Throws, identity), function(error, result) {
|
528 | t.error(error)
|
529 | t.deepEqual(result, {
|
530 | sourceMappingURL: "data:text/json," +
|
531 | "%7B%22mappings%22%3A%22AAAA%22%2C%22sources%22%3A%5B%22" +
|
532 | "foo.js%22%5D%2C%22names%22%3A%5B%5D%7D",
|
533 | url: null,
|
534 | sourcesRelativeTo: codeUrl,
|
535 | map: map.simple,
|
536 | sources: ["http://example.com/a/b/c/foo.js"]
|
537 | }, "dataUriText")
|
538 | isAsync()
|
539 | })
|
540 |
|
541 | method(code.dataUriParameter, codeUrl, wrapMap(Throws, identity), function(error, result) {
|
542 | t.error(error)
|
543 | t.deepEqual(result, {
|
544 | sourceMappingURL: "data:application/json;charset=UTF-8;foo=bar," +
|
545 | "%7B%22mappings%22%3A%22AAAA%22%2C%22sources%22%3A%5B%22" +
|
546 | "foo.js%22%5D%2C%22names%22%3A%5B%5D%7D",
|
547 | url: null,
|
548 | sourcesRelativeTo: codeUrl,
|
549 | map: map.simple,
|
550 | sources: ["http://example.com/a/b/c/foo.js"]
|
551 | }, "dataUriParameter")
|
552 | isAsync()
|
553 | })
|
554 |
|
555 | method(code.dataUriNoMime, codeUrl, wrap(Throws), function(error, result) {
|
556 | t.ok(error.message.match(/mime type.+text\/plain/), "dataUriNoMime")
|
557 | t.notOk(result)
|
558 | isAsync()
|
559 | })
|
560 |
|
561 | method(code.dataUriInvalidMime, codeUrl, wrap(Throws), function(error, result) {
|
562 | t.ok(error.message.match(/mime type.+text\/html/), "dataUriInvalidMime")
|
563 | t.notOk(result)
|
564 | isAsync()
|
565 | })
|
566 |
|
567 | method(code.dataUriInvalidJSON, codeUrl, wrap(Throws), function(error, result) {
|
568 | t.ok(error instanceof SyntaxError && error.message !== "data:application/json,foo",
|
569 | "dataUriInvalidJSON")
|
570 | t.notOk(result)
|
571 | isAsync()
|
572 | })
|
573 |
|
574 | method(code.dataUriXSSIsafe, codeUrl, wrapMap(Throws, identity), function(error, result) {
|
575 | t.error(error)
|
576 | t.deepEqual(result, {
|
577 | sourceMappingURL: "data:application/json," + ")%5D%7D%27" +
|
578 | "%7B%22mappings%22%3A%22AAAA%22%2C%22sources%22%3A%5B%22" +
|
579 | "foo.js%22%5D%2C%22names%22%3A%5B%5D%7D",
|
580 | url: null,
|
581 | sourcesRelativeTo: codeUrl,
|
582 | map: map.simple,
|
583 | sources: ["http://example.com/a/b/c/foo.js"]
|
584 | }, "dataUriXSSIsafe")
|
585 | isAsync()
|
586 | })
|
587 |
|
588 | method(code.dataUriEmpty, codeUrl, wrap(Throws), function(error, result) {
|
589 | t.ok(error.message.match(/mime type.+text\/plain/), "dataUriEmpty")
|
590 | t.notOk(result)
|
591 | isAsync()
|
592 | })
|
593 |
|
594 | method(code.noMap, codeUrl, wrap(Throws), function(error, result) {
|
595 | t.error(error)
|
596 | t.equal(result, null, "noMap")
|
597 | isAsync()
|
598 | })
|
599 |
|
600 | method(code.absolute, codeUrl, wrap(read([map.simpleString])), function(error, result) {
|
601 | t.error(error)
|
602 | t.deepEqual(result, {
|
603 | sourceMappingURL: "https://foo.org/foo.js.map",
|
604 | url: "https://foo.org/foo.js.map",
|
605 | sourcesRelativeTo: "https://foo.org/foo.js.map",
|
606 | map: map.simple,
|
607 | sources: [map.simpleString]
|
608 | }, "read non-string")
|
609 | isAsync()
|
610 | })
|
611 |
|
612 | method(code.absolute, codeUrl, wrap(read("invalid JSON")), function(error, result) {
|
613 | t.ok(error instanceof SyntaxError, "read invalid JSON")
|
614 | t.notOk(result)
|
615 | isAsync()
|
616 | })
|
617 |
|
618 | method(code.absolute, codeUrl, wrapMap(read(map.XSSIsafe), identity), function(error, result) {
|
619 | t.error(error)
|
620 | t.deepEqual(result, {
|
621 | sourceMappingURL: "https://foo.org/foo.js.map",
|
622 | url: "https://foo.org/foo.js.map",
|
623 | sourcesRelativeTo: "https://foo.org/foo.js.map",
|
624 | map: map.simple,
|
625 | sources: ["https://foo.org/foo.js"]
|
626 | }, "XSSIsafe map")
|
627 | isAsync()
|
628 | })
|
629 |
|
630 | method(code.absolute, codeUrl, wrap(Throws), function(error, result) {
|
631 | t.equal(error.message, "https://foo.org/foo.js.map", "read throws")
|
632 | t.notOk(result)
|
633 | isAsync()
|
634 | })
|
635 |
|
636 | function readMap(what) {
|
637 | return wrapMap(read(JSON.stringify(what)), identity)
|
638 | }
|
639 |
|
640 | method(code.fileRelative, codeUrl, readMap(map.simple), function(error, result) {
|
641 | t.error(error)
|
642 | t.deepEqual(result.sources, ["http://example.com/a/b/c/foo.js"], "simple")
|
643 | isAsync()
|
644 | })
|
645 |
|
646 | method(code.fileRelative, codeUrl, readMap(map.sourceRoot), function(error, result) {
|
647 | t.error(error)
|
648 | t.deepEqual(result.sources, [
|
649 | "http://example.com/static/js/app/foo.js",
|
650 | "http://example.com/static/js/app/lib/bar.js",
|
651 | "http://example.com/static/js/vendor/dom.js",
|
652 | "http://example.com/version.js",
|
653 | "http://foo.org/baz.js"
|
654 | ], "sourceRoot")
|
655 | isAsync()
|
656 | })
|
657 |
|
658 | method(code.fileRelative, codeUrl, readMap(map.sourceRootNoSlash), function(error, result) {
|
659 | t.error(error)
|
660 | t.deepEqual(result.sources, [
|
661 | "http://example.com/static/js/app/foo.js",
|
662 | "http://example.com/static/js/app/lib/bar.js",
|
663 | "http://example.com/static/js/vendor/dom.js",
|
664 | "http://example.com/version.js",
|
665 | "http://foo.org/baz.js"
|
666 | ], "sourceRootNoSlash")
|
667 | isAsync()
|
668 | })
|
669 |
|
670 | method(code.fileRelative, codeUrl, readMap(map.sourcesContent), function(error, result) {
|
671 | t.error(error)
|
672 | t.deepEqual(result.sources, [
|
673 | "foo.js",
|
674 | "lib/bar.js",
|
675 | "../vendor/dom.js",
|
676 | "/version.js",
|
677 | "//foo.org/baz.js"
|
678 | ], "sourcesContent")
|
679 | isAsync()
|
680 | })
|
681 |
|
682 | method(code.fileRelative, codeUrl, readMap(map.mixed), function(error, result) {
|
683 | t.error(error)
|
684 | t.deepEqual(result.sources, [
|
685 | "foo.js",
|
686 | "http://example.com/a/b/c/lib/bar.js",
|
687 | "http://example.com/a/b/vendor/dom.js",
|
688 | "/version.js",
|
689 | "//foo.org/baz.js"
|
690 | ], "mixed")
|
691 | isAsync()
|
692 | })
|
693 |
|
694 | method(code.fileRelative, codeUrl, wrap(read([map.simpleString])), function(error, result) {
|
695 | t.error(error)
|
696 | t.deepEqual(result.sources, [map.simpleString], "read non-string")
|
697 | isAsync()
|
698 | })
|
699 |
|
700 | function ThrowsMap(what) {
|
701 | return wrapMap(read(JSON.stringify(what)), Throws)
|
702 | }
|
703 |
|
704 | var calledBack = false
|
705 | method(code.fileRelative, codeUrl, ThrowsMap(map.mixed), function(error, result) {
|
706 | t.equal(calledBack, false)
|
707 | calledBack = true
|
708 | t.equal(error.message, "http://example.com/a/b/c/lib/bar.js", "read throws")
|
709 | t.notOk(result)
|
710 | isAsync()
|
711 | })
|
712 |
|
713 | next = true
|
714 | }
|
715 | }
|
716 |
|
717 | test(".resolve", testResolve(sourceMapResolve.resolve, false))
|
718 |
|
719 | test(".resolveSync", testResolve(sourceMapResolve.resolveSync, true))
|