This app provides monitoring and information features for the common freifunk user and the technical stuff of a freifunk community.
Code base is taken from a TUM Practical Course project and added here to see if Freifunk Altdorf can use it.
https://www.freifunk-altdorf.de
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1162 lines
40 KiB
1162 lines
40 KiB
// 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) |
|
})
|
|
|