You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1163 lines
40 KiB
JavaScript

// Copyright 2014, 2015, 2016, 2017 Simon Lydell
// X11 (“MIT”) Licensed. (See LICENSE.)
var test = require("tape")
var asyncify = require("simple-asyncify")
var common = require("./common")
var u = common.u
var read = common.read
var Throws = common.Throws
var identity = common.identity
var sourceMapResolve = require("../")
// Polyfills.
require("setimmediate")
if (typeof window !== "undefined" && !window.atob) {
window.atob = require("Base64").atob
}
"use strict"
var map = {
simple: {
mappings: "AAAA",
sources: ["foo.js"],
names: []
},
sourceRoot: {
mappings: "AAAA",
sourceRoot: "/static/js/app/",
sources: ["foo.js", "lib/bar.js", "../vendor/dom.js", "/version.js", "//foo.org/baz.js"],
names: []
},
sourceRootNoSlash: {
mappings: "AAAA",
sourceRoot: "/static/js/app",
sources: ["foo.js", "lib/bar.js", "../vendor/dom.js", "/version.js", "//foo.org/baz.js"],
names: []
},
sourceRootEmpty: {
mappings: "AAAA",
sourceRoot: "",
sources: ["foo.js", "lib/bar.js", "../vendor/dom.js", "/version.js", "//foo.org/baz.js"],
names: []
},
sourcesContent: {
mappings: "AAAA",
sourceRoot: "/static/js/app/",
sources: ["foo.js", "lib/bar.js", "../vendor/dom.js", "/version.js", "//foo.org/baz.js"],
sourcesContent: ["foo.js", "lib/bar.js", "../vendor/dom.js", "/version.js", "//foo.org/baz.js"],
names: []
},
mixed: {
mappings: "AAAA",
sources: ["foo.js", "lib/bar.js", "../vendor/dom.js", "/version.js", "//foo.org/baz.js"],
sourcesContent: ["foo.js", null , null , "/version.js", "//foo.org/baz.js"],
names: []
},
noSources: {
mappings: "",
sources: [],
names: []
},
empty: {}
}
map.simpleString = JSON.stringify(map.simple)
map.XSSIsafe = ")]}'" + map.simpleString
var code = {
fileRelative: u("foo.js.map"),
domainRelative: u("/foo.js.map"),
schemeRelative: u("//foo.org/foo.js.map"),
absolute: u("https://foo.org/foo.js.map"),
dataUri: u("data:application/json," +
"%7B%22mappings%22%3A%22AAAA%22%2C%22sources%22%3A%5B%22" +
"foo.js%22%5D%2C%22names%22%3A%5B%5D%7D"),
base64: u("data:application/json;base64," +
"eyJtYXBwaW5ncyI6IkFBQUEiLCJzb3VyY2VzIjpbImZvby5qcyJdLCJuYW1lcyI6W119"),
dataUriText: u("data:text/json," +
"%7B%22mappings%22%3A%22AAAA%22%2C%22sources%22%3A%5B%22" +
"foo.js%22%5D%2C%22names%22%3A%5B%5D%7D"),
dataUriParameter: u("data:application/json;charset=UTF-8;foo=bar," +
"%7B%22mappings%22%3A%22AAAA%22%2C%22sources%22%3A%5B%22" +
"foo.js%22%5D%2C%22names%22%3A%5B%5D%7D"),
dataUriNoMime: u("data:,foo"),
dataUriInvalidMime: u("data:text/html,foo"),
dataUriInvalidJSON: u("data:application/json,foo"),
dataUriXSSIsafe: u("data:application/json," + ")%5D%7D%27" +
"%7B%22mappings%22%3A%22AAAA%22%2C%22sources%22%3A%5B%22" +
"foo.js%22%5D%2C%22names%22%3A%5B%5D%7D"),
dataUriEmpty: u("data:"),
noMap: ""
}
function testResolveSourceMap(method, sync) {
return function(t) {
var wrap = (sync ? identity : asyncify)
var codeUrl = "http://example.com/a/b/c/foo.js"
t.plan(1 + 12*3 + 6*4)
t.equal(typeof method, "function", "is a function")
if (sync) {
method = asyncify(method)
}
var next = false
function isAsync() { t.ok(next, "is async") }
method(code.fileRelative, codeUrl, wrap(read(map.simpleString)), function(error, result) {
t.error(error)
t.deepEqual(result, {
sourceMappingURL: "foo.js.map",
url: "http://example.com/a/b/c/foo.js.map",
sourcesRelativeTo: "http://example.com/a/b/c/foo.js.map",
map: map.simple
}, "fileRelative")
isAsync()
})
method(code.domainRelative, codeUrl, wrap(read(map.simpleString)), function(error, result) {
t.error(error)
t.deepEqual(result, {
sourceMappingURL: "/foo.js.map",
url: "http://example.com/foo.js.map",
sourcesRelativeTo: "http://example.com/foo.js.map",
map: map.simple
}, "domainRelative")
isAsync()
})
method(code.schemeRelative, codeUrl, wrap(read(map.simpleString)), function(error, result) {
t.error(error)
t.deepEqual(result, {
sourceMappingURL: "//foo.org/foo.js.map",
url: "http://foo.org/foo.js.map",
sourcesRelativeTo: "http://foo.org/foo.js.map",
map: map.simple
}, "schemeRelative")
isAsync()
})
method(code.absolute, codeUrl, wrap(read(map.simpleString)), function(error, result) {
t.error(error)
t.deepEqual(result, {
sourceMappingURL: "https://foo.org/foo.js.map",
url: "https://foo.org/foo.js.map",
sourcesRelativeTo: "https://foo.org/foo.js.map",
map: map.simple
}, "absolute")
isAsync()
})
method(code.dataUri, codeUrl, wrap(Throws), function(error, result) {
t.error(error)
t.deepEqual(result, {
sourceMappingURL: "data:application/json," +
"%7B%22mappings%22%3A%22AAAA%22%2C%22sources%22%3A%5B%22" +
"foo.js%22%5D%2C%22names%22%3A%5B%5D%7D",
url: null,
sourcesRelativeTo: codeUrl,
map: map.simple
}, "dataUri")
isAsync()
})
method(code.base64, codeUrl, wrap(Throws), function(error, result) {
t.error(error)
t.deepEqual(result, {
sourceMappingURL: "data:application/json;base64," +
"eyJtYXBwaW5ncyI6IkFBQUEiLCJzb3VyY2VzIjpbImZvby5qcyJdLCJuYW1lcyI6W119",
url: null,
sourcesRelativeTo: codeUrl,
map: map.simple
}, "base64")
isAsync()
})
method(code.dataUriText, codeUrl, wrap(Throws), function(error, result) {
t.error(error)
t.deepEqual(result, {
sourceMappingURL: "data:text/json," +
"%7B%22mappings%22%3A%22AAAA%22%2C%22sources%22%3A%5B%22" +
"foo.js%22%5D%2C%22names%22%3A%5B%5D%7D",
url: null,
sourcesRelativeTo: codeUrl,
map: map.simple
}, "dataUriText")
isAsync()
})
method(code.dataUriParameter, codeUrl, wrap(Throws), function(error, result) {
t.error(error)
t.deepEqual(result, {
sourceMappingURL: "data:application/json;charset=UTF-8;foo=bar," +
"%7B%22mappings%22%3A%22AAAA%22%2C%22sources%22%3A%5B%22" +
"foo.js%22%5D%2C%22names%22%3A%5B%5D%7D",
url: null,
sourcesRelativeTo: codeUrl,
map: map.simple
}, "dataUriParameter")
isAsync()
})
method(code.dataUriNoMime, codeUrl, wrap(Throws), function(error, result) {
t.deepEqual(error.sourceMapData, {
sourceMappingURL: "data:,foo",
url: null,
sourcesRelativeTo: codeUrl,
map: "foo"
}, "dataUriNoMime .sourceMapData")
t.ok(error.message.match(/mime type.+text\/plain/), "dataUriNoMime")
t.notOk(result)
isAsync()
})
method(code.dataUriInvalidMime, codeUrl, wrap(Throws), function(error, result) {
t.deepEqual(error.sourceMapData, {
sourceMappingURL: "data:text/html,foo",
url: null,
sourcesRelativeTo: codeUrl,
map: "foo"
}, "dataUriInvalidMime .sourceMapData")
t.ok(error.message.match(/mime type.+text\/html/), "dataUriInvalidMime")
t.notOk(result)
isAsync()
})
method(code.dataUriInvalidJSON, codeUrl, wrap(Throws), function(error, result) {
t.deepEqual(error.sourceMapData, {
sourceMappingURL: "data:application/json,foo",
url: null,
sourcesRelativeTo: codeUrl,
map: "foo"
}, "dataUriInvalidJSON .sourceMapData")
t.ok(error instanceof SyntaxError && error.message !== "data:application/json,foo",
"dataUriInvalidJSON")
t.notOk(result)
isAsync()
})
method(code.dataUriXSSIsafe, codeUrl, wrap(Throws), function(error, result) {
t.error(error)
t.deepEqual(result, {
sourceMappingURL: "data:application/json," + ")%5D%7D%27" +
"%7B%22mappings%22%3A%22AAAA%22%2C%22sources%22%3A%5B%22" +
"foo.js%22%5D%2C%22names%22%3A%5B%5D%7D",
url: null,
sourcesRelativeTo: codeUrl,
map: map.simple
}, "dataUriXSSIsafe")
isAsync()
})
method(code.dataUriEmpty, codeUrl, wrap(Throws), function(error, result) {
t.deepEqual(error.sourceMapData, {
sourceMappingURL: "data:",
url: null,
sourcesRelativeTo: codeUrl,
map: ""
}, "dataUriEmpty .sourceMapData")
t.ok(error.message.match(/mime type.+text\/plain/), "dataUriEmpty")
t.notOk(result)
isAsync()
})
method(code.noMap, codeUrl, wrap(Throws), function(error, result) {
t.error(error)
t.equal(result, null, "noMap")
isAsync()
})
method(code.absolute, codeUrl, wrap(read([map.simpleString])), function(error, result) {
t.error(error)
t.deepEqual(result, {
sourceMappingURL: "https://foo.org/foo.js.map",
url: "https://foo.org/foo.js.map",
sourcesRelativeTo: "https://foo.org/foo.js.map",
map: map.simple
}, "read non-string")
isAsync()
})
method(code.absolute, codeUrl, wrap(read("invalid JSON")), function(error, result) {
t.deepEqual(error.sourceMapData, {
sourceMappingURL: "https://foo.org/foo.js.map",
url: "https://foo.org/foo.js.map",
sourcesRelativeTo: "https://foo.org/foo.js.map",
map: "invalid JSON"
}, "read invalid JSON .sourceMapData")
t.ok(error instanceof SyntaxError, "read invalid JSON")
t.notOk(result)
isAsync()
})
method(code.absolute, codeUrl, wrap(read(map.XSSIsafe)), function(error, result) {
t.error(error)
t.deepEqual(result, {
sourceMappingURL: "https://foo.org/foo.js.map",
url: "https://foo.org/foo.js.map",
sourcesRelativeTo: "https://foo.org/foo.js.map",
map: map.simple
}, "XSSIsafe map")
isAsync()
})
method(code.absolute, codeUrl, wrap(Throws), function(error, result) {
t.deepEqual(error.sourceMapData, {
sourceMappingURL: "https://foo.org/foo.js.map",
url: "https://foo.org/foo.js.map",
sourcesRelativeTo: "https://foo.org/foo.js.map",
map: null
}, "read throws .sourceMapData")
t.equal(error.message, "https://foo.org/foo.js.map", "read throws")
t.notOk(result)
isAsync()
})
next = true
}
}
test(".resolveSourceMap", testResolveSourceMap(sourceMapResolve.resolveSourceMap, false))
test(".resolveSourceMapSync", testResolveSourceMap(sourceMapResolve.resolveSourceMapSync, true))
function testResolveSources(method, sync) {
return function(t) {
var wrap = (sync ? identity : asyncify)
var mapUrl = "http://example.com/a/b/c/foo.js.map"
t.plan(1 + 11*3 + 4)
t.equal(typeof method, "function", "is a function")
if (sync) {
method = asyncify(method)
}
var next = false
function isAsync() { t.ok(next, "is async") }
var options
method(map.simple, mapUrl, wrap(identity), function(error, result) {
t.error(error)
t.deepEqual(result, {
sourcesResolved: ["http://example.com/a/b/c/foo.js"],
sourcesContent: ["http://example.com/a/b/c/foo.js"]
}, "simple")
isAsync()
})
method(map.sourceRoot, mapUrl, wrap(identity), function(error, result) {
t.error(error)
t.deepEqual(result, {
sourcesResolved: [
"http://example.com/static/js/app/foo.js",
"http://example.com/static/js/app/lib/bar.js",
"http://example.com/static/js/vendor/dom.js",
"http://example.com/version.js",
"http://foo.org/baz.js"
],
sourcesContent: [
"http://example.com/static/js/app/foo.js",
"http://example.com/static/js/app/lib/bar.js",
"http://example.com/static/js/vendor/dom.js",
"http://example.com/version.js",
"http://foo.org/baz.js"
]
}, "sourceRoot")
isAsync()
})
options = {sourceRoot: false}
method(map.sourceRoot, mapUrl, wrap(identity), options, function(error, result) {
t.error(error)
t.deepEqual(result, {
sourcesResolved: [
"http://example.com/a/b/c/foo.js",
"http://example.com/a/b/c/lib/bar.js",
"http://example.com/a/b/vendor/dom.js",
"http://example.com/version.js",
"http://foo.org/baz.js"
],
sourcesContent: [
"http://example.com/a/b/c/foo.js",
"http://example.com/a/b/c/lib/bar.js",
"http://example.com/a/b/vendor/dom.js",
"http://example.com/version.js",
"http://foo.org/baz.js"
]
}, "ignore sourceRoot")
isAsync()
})
options = {sourceRoot: "/static/js/"}
method(map.sourceRoot, mapUrl, wrap(identity), options, function(error, result) {
t.error(error)
t.deepEqual(result, {
sourcesResolved: [
"http://example.com/static/js/foo.js",
"http://example.com/static/js/lib/bar.js",
"http://example.com/static/vendor/dom.js",
"http://example.com/version.js",
"http://foo.org/baz.js"
],
sourcesContent: [
"http://example.com/static/js/foo.js",
"http://example.com/static/js/lib/bar.js",
"http://example.com/static/vendor/dom.js",
"http://example.com/version.js",
"http://foo.org/baz.js"
]
}, "custom sourceRoot")
isAsync()
})
method(map.sourceRootNoSlash, mapUrl, wrap(identity), function(error, result) {
t.error(error)
t.deepEqual(result, {
sourcesResolved: [
"http://example.com/static/js/app/foo.js",
"http://example.com/static/js/app/lib/bar.js",
"http://example.com/static/js/vendor/dom.js",
"http://example.com/version.js",
"http://foo.org/baz.js"
],
sourcesContent: [
"http://example.com/static/js/app/foo.js",
"http://example.com/static/js/app/lib/bar.js",
"http://example.com/static/js/vendor/dom.js",
"http://example.com/version.js",
"http://foo.org/baz.js"
]
}, "sourceRootNoSlash")
isAsync()
})
method(map.sourceRootEmpty, mapUrl, wrap(identity), function(error, result) {
t.error(error)
t.deepEqual(result, {
sourcesResolved: [
"http://example.com/a/b/c/foo.js",
"http://example.com/a/b/c/lib/bar.js",
"http://example.com/a/b/vendor/dom.js",
"http://example.com/version.js",
"http://foo.org/baz.js"
],
sourcesContent: [
"http://example.com/a/b/c/foo.js",
"http://example.com/a/b/c/lib/bar.js",
"http://example.com/a/b/vendor/dom.js",
"http://example.com/version.js",
"http://foo.org/baz.js"
]
}, "sourceRootEmpty")
isAsync()
})
method(map.sourcesContent, mapUrl, wrap(Throws), function(error, result) {
t.error(error)
t.deepEqual(result, {
sourcesResolved: [
"http://example.com/static/js/app/foo.js",
"http://example.com/static/js/app/lib/bar.js",
"http://example.com/static/js/vendor/dom.js",
"http://example.com/version.js",
"http://foo.org/baz.js"
],
sourcesContent: [
"foo.js",
"lib/bar.js",
"../vendor/dom.js",
"/version.js",
"//foo.org/baz.js"
]
}, "sourcesContent")
isAsync()
})
method(map.mixed, mapUrl, wrap(identity), function(error, result) {
t.error(error)
t.deepEqual(result, {
sourcesResolved: [
"http://example.com/a/b/c/foo.js",
"http://example.com/a/b/c/lib/bar.js",
"http://example.com/a/b/vendor/dom.js",
"http://example.com/version.js",
"http://foo.org/baz.js"
],
sourcesContent: [
"foo.js",
"http://example.com/a/b/c/lib/bar.js",
"http://example.com/a/b/vendor/dom.js",
"/version.js",
"//foo.org/baz.js"
]
}, "mixed")
isAsync()
})
method(map.noSources, mapUrl, wrap(identity), function(error, result) {
t.error(error)
t.deepEqual(result, {
sourcesResolved: [],
sourcesContent: []
}, "noSources")
isAsync()
})
method(map.empty, mapUrl, wrap(identity), function(error, result) {
t.error(error)
t.deepEqual(result, {
sourcesResolved: [],
sourcesContent: []
}, "empty")
isAsync()
})
method(map.simple, mapUrl, wrap(read(["non", "string"])), function(error, result) {
t.error(error)
t.deepEqual(result, {
sourcesResolved: ["http://example.com/a/b/c/foo.js"],
sourcesContent: ["non,string"]
}, "read non-string")
isAsync()
})
method(map.mixed, mapUrl, wrap(Throws), function(error, result) {
t.error(error)
t.deepEqual(result.sourcesResolved, [
"http://example.com/a/b/c/foo.js",
"http://example.com/a/b/c/lib/bar.js",
"http://example.com/a/b/vendor/dom.js",
"http://example.com/version.js",
"http://foo.org/baz.js"
], "read throws .sourcesResolved")
var sourcesContent = result.sourcesContent
for (var index = 0, len = sourcesContent.length; index < len; index++) {
var item = sourcesContent[index]
if (item instanceof Error) {
sourcesContent[index] = null
}
}
t.deepEqual(sourcesContent, [
"foo.js",
null,
null,
"/version.js",
"//foo.org/baz.js"
], "read throws .sourcesContent")
isAsync()
})
next = true
}
}
test(".resolveSources", testResolveSources(sourceMapResolve.resolveSources, false))
test(".resolveSourcesSync", testResolveSources(sourceMapResolve.resolveSourcesSync, true))
test(".resolveSourcesSync no read", function(t) {
t.plan(1)
var mapUrl = "http://example.com/a/b/c/foo.js.map"
var result = sourceMapResolve.resolveSourcesSync(map.mixed, mapUrl, null)
t.deepEqual(result, {
sourcesResolved: [
"http://example.com/a/b/c/foo.js",
"http://example.com/a/b/c/lib/bar.js",
"http://example.com/a/b/vendor/dom.js",
"http://example.com/version.js",
"http://foo.org/baz.js"
],
sourcesContent: []
})
})
function testResolve(method, sync) {
return function(t) {
var wrap = (sync ? identity : asyncify)
var wrapMap = function(mapFn, fn) {
return wrap(function(url) {
if (/\.map$/.test(url)) {
return mapFn(url)
}
return fn(url)
})
}
var codeUrl = "http://example.com/a/b/c/foo.js"
t.plan(1 + 15*3 + 21*4 + 4)
t.equal(typeof method, "function", "is a function")
if (sync) {
method = asyncify(method)
}
var next = false
function isAsync() { t.ok(next, "is async") }
var readSimple = wrapMap(read(map.simpleString), identity)
method(code.fileRelative, codeUrl, readSimple, function(error, result) {
t.error(error)
t.deepEqual(result, {
sourceMappingURL: "foo.js.map",
url: "http://example.com/a/b/c/foo.js.map",
sourcesRelativeTo: "http://example.com/a/b/c/foo.js.map",
map: map.simple,
sourcesResolved: ["http://example.com/a/b/c/foo.js"],
sourcesContent: ["http://example.com/a/b/c/foo.js"]
}, "fileRelative")
isAsync()
})
method(code.domainRelative, codeUrl, readSimple, function(error, result) {
t.error(error)
t.deepEqual(result, {
sourceMappingURL: "/foo.js.map",
url: "http://example.com/foo.js.map",
sourcesRelativeTo: "http://example.com/foo.js.map",
map: map.simple,
sourcesResolved: ["http://example.com/foo.js"],
sourcesContent: ["http://example.com/foo.js"]
}, "domainRelative")
isAsync()
})
method(code.schemeRelative, codeUrl, readSimple, function(error, result) {
t.error(error)
t.deepEqual(result, {
sourceMappingURL: "//foo.org/foo.js.map",
url: "http://foo.org/foo.js.map",
sourcesRelativeTo: "http://foo.org/foo.js.map",
map: map.simple,
sourcesResolved: ["http://foo.org/foo.js"],
sourcesContent: ["http://foo.org/foo.js"]
}, "schemeRelative")
isAsync()
})
method(code.absolute, codeUrl, readSimple, function(error, result) {
t.error(error)
t.deepEqual(result, {
sourceMappingURL: "https://foo.org/foo.js.map",
url: "https://foo.org/foo.js.map",
sourcesRelativeTo: "https://foo.org/foo.js.map",
map: map.simple,
sourcesResolved: ["https://foo.org/foo.js"],
sourcesContent: ["https://foo.org/foo.js"]
}, "absolute")
isAsync()
})
method(code.dataUri, codeUrl, wrapMap(Throws, identity), function(error, result) {
t.error(error)
t.deepEqual(result, {
sourceMappingURL: "data:application/json," +
"%7B%22mappings%22%3A%22AAAA%22%2C%22sources%22%3A%5B%22" +
"foo.js%22%5D%2C%22names%22%3A%5B%5D%7D",
url: null,
sourcesRelativeTo: codeUrl,
map: map.simple,
sourcesResolved: ["http://example.com/a/b/c/foo.js"],
sourcesContent: ["http://example.com/a/b/c/foo.js"]
}, "dataUri")
isAsync()
})
method(code.base64, codeUrl, wrapMap(Throws, identity), function(error, result) {
t.error(error)
t.deepEqual(result, {
sourceMappingURL: "data:application/json;base64," +
"eyJtYXBwaW5ncyI6IkFBQUEiLCJzb3VyY2VzIjpbImZvby5qcyJdLCJuYW1lcyI6W119",
url: null,
sourcesRelativeTo: codeUrl,
map: map.simple,
sourcesResolved: ["http://example.com/a/b/c/foo.js"],
sourcesContent: ["http://example.com/a/b/c/foo.js"]
}, "base64")
isAsync()
})
method(code.dataUriText, codeUrl, wrapMap(Throws, identity), function(error, result) {
t.error(error)
t.deepEqual(result, {
sourceMappingURL: "data:text/json," +
"%7B%22mappings%22%3A%22AAAA%22%2C%22sources%22%3A%5B%22" +
"foo.js%22%5D%2C%22names%22%3A%5B%5D%7D",
url: null,
sourcesRelativeTo: codeUrl,
map: map.simple,
sourcesResolved: ["http://example.com/a/b/c/foo.js"],
sourcesContent: ["http://example.com/a/b/c/foo.js"]
}, "dataUriText")
isAsync()
})
method(code.dataUriParameter, codeUrl, wrapMap(Throws, identity), function(error, result) {
t.error(error)
t.deepEqual(result, {
sourceMappingURL: "data:application/json;charset=UTF-8;foo=bar," +
"%7B%22mappings%22%3A%22AAAA%22%2C%22sources%22%3A%5B%22" +
"foo.js%22%5D%2C%22names%22%3A%5B%5D%7D",
url: null,
sourcesRelativeTo: codeUrl,
map: map.simple,
sourcesResolved: ["http://example.com/a/b/c/foo.js"],
sourcesContent: ["http://example.com/a/b/c/foo.js"]
}, "dataUriParameter")
isAsync()
})
method(code.dataUriNoMime, codeUrl, wrap(Throws), function(error, result) {
t.deepEqual(error.sourceMapData, {
sourceMappingURL: "data:,foo",
url: null,
sourcesRelativeTo: codeUrl,
map: "foo"
}, "dataUriNoMime .sourceMapData")
t.ok(error.message.match(/mime type.+text\/plain/), "dataUriNoMime")
t.notOk(result)
isAsync()
})
method(code.dataUriInvalidMime, codeUrl, wrap(Throws), function(error, result) {
t.deepEqual(error.sourceMapData, {
sourceMappingURL: "data:text/html,foo",
url: null,
sourcesRelativeTo: codeUrl,
map: "foo"
}, "dataUriInvalidMime .sourceMapData")
t.ok(error.message.match(/mime type.+text\/html/), "dataUriInvalidMime")
t.notOk(result)
isAsync()
})
method(code.dataUriInvalidJSON, codeUrl, wrap(Throws), function(error, result) {
t.deepEqual(error.sourceMapData, {
sourceMappingURL: "data:application/json,foo",
url: null,
sourcesRelativeTo: codeUrl,
map: "foo"
}, "dataUriInvalidJSON .sourceMapData")
t.ok(error instanceof SyntaxError && error.message !== "data:application/json,foo",
"dataUriInvalidJSON")
t.notOk(result)
isAsync()
})
method(code.dataUriXSSIsafe, codeUrl, wrapMap(Throws, identity), function(error, result) {
t.error(error)
t.deepEqual(result, {
sourceMappingURL: "data:application/json," + ")%5D%7D%27" +
"%7B%22mappings%22%3A%22AAAA%22%2C%22sources%22%3A%5B%22" +
"foo.js%22%5D%2C%22names%22%3A%5B%5D%7D",
url: null,
sourcesRelativeTo: codeUrl,
map: map.simple,
sourcesResolved: ["http://example.com/a/b/c/foo.js"],
sourcesContent: ["http://example.com/a/b/c/foo.js"]
}, "dataUriXSSIsafe")
isAsync()
})
method(code.dataUriEmpty, codeUrl, wrap(Throws), function(error, result) {
t.deepEqual(error.sourceMapData, {
sourceMappingURL: "data:",
url: null,
sourcesRelativeTo: codeUrl,
map: ""
}, "dataUriEmpty .sourceMapData")
t.ok(error.message.match(/mime type.+text\/plain/), "dataUriEmpty")
t.notOk(result)
isAsync()
})
method(code.noMap, codeUrl, wrap(Throws), function(error, result) {
t.error(error)
t.equal(result, null, "noMap")
isAsync()
})
method(code.absolute, codeUrl, wrap(read([map.simpleString])), function(error, result) {
t.error(error)
t.deepEqual(result, {
sourceMappingURL: "https://foo.org/foo.js.map",
url: "https://foo.org/foo.js.map",
sourcesRelativeTo: "https://foo.org/foo.js.map",
map: map.simple,
sourcesResolved: ["https://foo.org/foo.js"],
sourcesContent: [map.simpleString]
}, "read non-string")
isAsync()
})
method(code.absolute, codeUrl, wrap(read("invalid JSON")), function(error, result) {
t.deepEqual(error.sourceMapData, {
sourceMappingURL: "https://foo.org/foo.js.map",
url: "https://foo.org/foo.js.map",
sourcesRelativeTo: "https://foo.org/foo.js.map",
map: "invalid JSON"
}, "read invalid JSON .sourceMapData")
t.ok(error instanceof SyntaxError, "read invalid JSON")
t.notOk(result)
isAsync()
})
method(code.absolute, codeUrl, wrapMap(read(map.XSSIsafe), identity), function(error, result) {
t.error(error)
t.deepEqual(result, {
sourceMappingURL: "https://foo.org/foo.js.map",
url: "https://foo.org/foo.js.map",
sourcesRelativeTo: "https://foo.org/foo.js.map",
map: map.simple,
sourcesResolved: ["https://foo.org/foo.js"],
sourcesContent: ["https://foo.org/foo.js"]
}, "XSSIsafe map")
isAsync()
})
method(code.absolute, codeUrl, wrap(Throws), function(error, result) {
t.deepEqual(error.sourceMapData, {
sourceMappingURL: "https://foo.org/foo.js.map",
url: "https://foo.org/foo.js.map",
sourcesRelativeTo: "https://foo.org/foo.js.map",
map: null
}, "read throws .sourceMapData")
t.equal(error.message, "https://foo.org/foo.js.map", "read throws")
t.notOk(result)
isAsync()
})
function readMap(what) {
return wrapMap(read(JSON.stringify(what)), identity)
}
var options
method(code.fileRelative, codeUrl, readMap(map.simple), function(error, result) {
t.error(error)
t.deepEqual(result.sourcesResolved, ["http://example.com/a/b/c/foo.js"], "simple")
t.deepEqual(result.sourcesContent, ["http://example.com/a/b/c/foo.js"], "simple")
isAsync()
})
method(code.fileRelative, codeUrl, readMap(map.sourceRoot), function(error, result) {
t.error(error)
t.deepEqual(result.sourcesResolved, [
"http://example.com/static/js/app/foo.js",
"http://example.com/static/js/app/lib/bar.js",
"http://example.com/static/js/vendor/dom.js",
"http://example.com/version.js",
"http://foo.org/baz.js"
], "sourceRoot")
t.deepEqual(result.sourcesContent, [
"http://example.com/static/js/app/foo.js",
"http://example.com/static/js/app/lib/bar.js",
"http://example.com/static/js/vendor/dom.js",
"http://example.com/version.js",
"http://foo.org/baz.js"
], "sourceRoot")
isAsync()
})
options = {sourceRoot: false}
method(code.fileRelative, codeUrl, readMap(map.sourceRoot), options, function(error, result) {
t.error(error)
t.deepEqual(result.sourcesResolved, [
"http://example.com/a/b/c/foo.js",
"http://example.com/a/b/c/lib/bar.js",
"http://example.com/a/b/vendor/dom.js",
"http://example.com/version.js",
"http://foo.org/baz.js"
], "ignore sourceRoot")
t.deepEqual(result.sourcesContent, [
"http://example.com/a/b/c/foo.js",
"http://example.com/a/b/c/lib/bar.js",
"http://example.com/a/b/vendor/dom.js",
"http://example.com/version.js",
"http://foo.org/baz.js"
], "ignore sourceRoot")
isAsync()
})
options = {sourceRoot: "/static/js/"}
method(code.fileRelative, codeUrl, readMap(map.sourceRoot), options, function(error, result) {
t.error(error)
t.deepEqual(result.sourcesResolved, [
"http://example.com/static/js/foo.js",
"http://example.com/static/js/lib/bar.js",
"http://example.com/static/vendor/dom.js",
"http://example.com/version.js",
"http://foo.org/baz.js"
], "custom sourceRoot")
t.deepEqual(result.sourcesContent, [
"http://example.com/static/js/foo.js",
"http://example.com/static/js/lib/bar.js",
"http://example.com/static/vendor/dom.js",
"http://example.com/version.js",
"http://foo.org/baz.js"
], "custom sourceRoot")
isAsync()
})
method(code.fileRelative, codeUrl, readMap(map.sourceRootNoSlash), function(error, result) {
t.error(error)
t.deepEqual(result.sourcesResolved, [
"http://example.com/static/js/app/foo.js",
"http://example.com/static/js/app/lib/bar.js",
"http://example.com/static/js/vendor/dom.js",
"http://example.com/version.js",
"http://foo.org/baz.js"
], "sourceRootNoSlash")
t.deepEqual(result.sourcesContent, [
"http://example.com/static/js/app/foo.js",
"http://example.com/static/js/app/lib/bar.js",
"http://example.com/static/js/vendor/dom.js",
"http://example.com/version.js",
"http://foo.org/baz.js"
], "sourceRootNoSlash")
isAsync()
})
method(code.fileRelative, codeUrl, readMap(map.sourceRootEmpty), function(error, result) {
t.error(error)
t.deepEqual(result.sourcesResolved, [
"http://example.com/a/b/c/foo.js",
"http://example.com/a/b/c/lib/bar.js",
"http://example.com/a/b/vendor/dom.js",
"http://example.com/version.js",
"http://foo.org/baz.js"
], "sourceRootEmpty")
t.deepEqual(result.sourcesContent, [
"http://example.com/a/b/c/foo.js",
"http://example.com/a/b/c/lib/bar.js",
"http://example.com/a/b/vendor/dom.js",
"http://example.com/version.js",
"http://foo.org/baz.js"
], "sourceRootEmpty")
isAsync()
})
method(code.fileRelative, codeUrl, readMap(map.sourcesContent), function(error, result) {
t.error(error)
t.deepEqual(result.sourcesResolved, [
"http://example.com/static/js/app/foo.js",
"http://example.com/static/js/app/lib/bar.js",
"http://example.com/static/js/vendor/dom.js",
"http://example.com/version.js",
"http://foo.org/baz.js"
], "sourcesContent")
t.deepEqual(result.sourcesContent, [
"foo.js",
"lib/bar.js",
"../vendor/dom.js",
"/version.js",
"//foo.org/baz.js"
], "sourcesContent")
isAsync()
})
method(code.fileRelative, codeUrl, readMap(map.mixed), function(error, result) {
t.error(error)
t.deepEqual(result.sourcesResolved, [
"http://example.com/a/b/c/foo.js",
"http://example.com/a/b/c/lib/bar.js",
"http://example.com/a/b/vendor/dom.js",
"http://example.com/version.js",
"http://foo.org/baz.js"
], "mixed")
t.deepEqual(result.sourcesContent, [
"foo.js",
"http://example.com/a/b/c/lib/bar.js",
"http://example.com/a/b/vendor/dom.js",
"/version.js",
"//foo.org/baz.js"
], "mixed")
isAsync()
})
method(code.fileRelative, codeUrl, readMap(map.noSources), function(error, result) {
t.error(error)
t.deepEqual(result.sourcesResolved, [], "noSources")
t.deepEqual(result.sourcesContent, [], "noSources")
isAsync()
})
method(code.fileRelative, codeUrl, readMap(map.empty), function(error, result) {
t.error(error)
t.deepEqual(result.sourcesResolved, [], "noSources")
t.deepEqual(result.sourcesContent, [], "noSources")
isAsync()
})
method(code.fileRelative, codeUrl, wrap(read([map.simpleString])), function(error, result) {
t.error(error)
t.deepEqual(result.sourcesResolved, ["http://example.com/a/b/c/foo.js"], "read non-string")
t.deepEqual(result.sourcesContent, [map.simpleString], "read non-string")
isAsync()
})
function ThrowsMap(what) {
return wrapMap(read(JSON.stringify(what)), Throws)
}
method(code.fileRelative, codeUrl, ThrowsMap(map.mixed), function(error, result) {
t.error(error)
t.deepEqual(result.sourcesResolved, [
"http://example.com/a/b/c/foo.js",
"http://example.com/a/b/c/lib/bar.js",
"http://example.com/a/b/vendor/dom.js",
"http://example.com/version.js",
"http://foo.org/baz.js"
], "read throws .sourcesResolved")
var sourcesContent = result.sourcesContent
for (var index = 0, len = sourcesContent.length; index < len; index++) {
var item = sourcesContent[index]
if (item instanceof Error) {
sourcesContent[index] = null
}
}
t.deepEqual(sourcesContent, [
"foo.js",
null,
null,
"/version.js",
"//foo.org/baz.js"
], "read throws .sourcesContent")
isAsync()
})
var mapUrl = "https://foo.org/foo.js.map"
method(null, mapUrl, readSimple, function(error, result) {
t.error(error)
t.deepEqual(result, {
sourceMappingURL: null,
url: "https://foo.org/foo.js.map",
sourcesRelativeTo: "https://foo.org/foo.js.map",
map: map.simple,
sourcesResolved: ["https://foo.org/foo.js"],
sourcesContent: ["https://foo.org/foo.js"]
}, "mapUrl simple")
isAsync()
})
method(null, mapUrl, wrap(read([map.simpleString])), function(error, result) {
t.error(error)
t.deepEqual(result, {
sourceMappingURL: null,
url: "https://foo.org/foo.js.map",
sourcesRelativeTo: "https://foo.org/foo.js.map",
map: map.simple,
sourcesResolved: ["https://foo.org/foo.js"],
sourcesContent: [map.simpleString]
}, "mapUrl read non-string")
isAsync()
})
method(null, mapUrl, wrap(read("invalid JSON")), function(error, result) {
t.deepEqual(error.sourceMapData, {
sourceMappingURL: null,
url: "https://foo.org/foo.js.map",
sourcesRelativeTo: "https://foo.org/foo.js.map",
map: "invalid JSON"
}, "mapUrl read invalid JSON .sourceMapData")
t.ok(error instanceof SyntaxError, "mapUrl read invalid JSON")
t.notOk(result)
isAsync()
})
method(null, mapUrl, wrapMap(read(map.XSSIsafe), identity), function(error, result) {
t.error(error)
t.deepEqual(result, {
sourceMappingURL: null,
url: "https://foo.org/foo.js.map",
sourcesRelativeTo: "https://foo.org/foo.js.map",
map: map.simple,
sourcesResolved: ["https://foo.org/foo.js"],
sourcesContent: ["https://foo.org/foo.js"]
}, "mapUrl XSSIsafe map")
isAsync()
})
method(null, mapUrl, wrap(Throws), function(error, result) {
t.deepEqual(error.sourceMapData, {
sourceMappingURL: null,
url: "https://foo.org/foo.js.map",
sourcesRelativeTo: "https://foo.org/foo.js.map",
map: null
}, "mapUrl read throws .sourceMapData")
t.equal(error.message, "https://foo.org/foo.js.map", "mapUrl read throws")
t.notOk(result)
isAsync()
})
mapUrl = "http://example.com/a/b/c/foo.js.map"
options = {sourceRoot: "/static/js/"}
method(null, mapUrl, readMap(map.sourceRoot), options, function(error, result) {
t.error(error)
t.deepEqual(result.sourcesResolved, [
"http://example.com/static/js/foo.js",
"http://example.com/static/js/lib/bar.js",
"http://example.com/static/vendor/dom.js",
"http://example.com/version.js",
"http://foo.org/baz.js"
], "mapUrl custom sourceRoot")
t.deepEqual(result.sourcesContent, [
"http://example.com/static/js/foo.js",
"http://example.com/static/js/lib/bar.js",
"http://example.com/static/vendor/dom.js",
"http://example.com/version.js",
"http://foo.org/baz.js"
], "mapUrl custom sourceRoot")
isAsync()
})
method(null, mapUrl, readMap(map.mixed), function(error, result) {
t.error(error)
t.deepEqual(result.sourcesResolved, [
"http://example.com/a/b/c/foo.js",
"http://example.com/a/b/c/lib/bar.js",
"http://example.com/a/b/vendor/dom.js",
"http://example.com/version.js",
"http://foo.org/baz.js"
], "mapUrl mixed")
t.deepEqual(result.sourcesContent, [
"foo.js",
"http://example.com/a/b/c/lib/bar.js",
"http://example.com/a/b/vendor/dom.js",
"/version.js",
"//foo.org/baz.js"
], "mapUrl mixed")
isAsync()
})
next = true
}
}
test(".resolve", testResolve(sourceMapResolve.resolve, false))
test(".resolveSync", testResolve(sourceMapResolve.resolveSync, true))
test(".parseMapToJSON", function(t) {
t.plan(1)
t.deepEqual(sourceMapResolve.parseMapToJSON(map.XSSIsafe), map.simple)
})