UNPKG

25.1 kBJavaScriptView Raw
1// Copyright 2014 Simon Lydell
2// X11 (“MIT”) Licensed. (See LICENSE.)
3
4var test = require("tape")
5var asyncify = require("simple-asyncify")
6var common = require("./common")
7var u = common.u
8var read = common.read
9var Throws = common.Throws
10var identity = common.identity
11
12var sourceMapResolve = require("../")
13
14// Polyfills.
15require("setimmediate")
16if (typeof window !== "undefined" && !window.atob) {
17 window.atob = require("Base64").atob
18}
19
20"use strict"
21
22var 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 sourceContents: {
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 sourceContents: ["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 sourceContents: ["foo.js", null , null , "/version.js", "//foo.org/baz.js"],
51 names: []
52 }
53}
54map.simpleString = JSON.stringify(map.simple)
55map.XSSIsafe = ")]}'" + map.simpleString
56
57var 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
83function 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
91function 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
298test(".resolveSourceMap", testResolveSourceMap(sourceMapResolve.resolveSourceMap, false))
299
300test(".resolveSourceMapSync", testResolveSourceMap(sourceMapResolve.resolveSourceMapSync, true))
301
302
303function 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.sourceContents, 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 ], "sourceContents")
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
407test(".resolveSources", testResolveSources(sourceMapResolve.resolveSources, false))
408
409test(".resolveSourcesSync", testResolveSources(sourceMapResolve.resolveSourcesSync, true))
410
411
412function 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.sourceContents), 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 ], "sourceContents")
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
717test(".resolve", testResolve(sourceMapResolve.resolve, false))
718
719test(".resolveSync", testResolve(sourceMapResolve.resolveSync, true))