summaryrefslogtreecommitdiffstats
path: root/devtools/client/shared/source-map-loader/test/browser
diff options
context:
space:
mode:
Diffstat (limited to 'devtools/client/shared/source-map-loader/test/browser')
-rw-r--r--devtools/client/shared/source-map-loader/test/browser/browser.ini14
-rw-r--r--devtools/client/shared/source-map-loader/test/browser/browser_getContentType.js32
-rw-r--r--devtools/client/shared/source-map-loader/test/browser/browser_locations.js141
-rw-r--r--devtools/client/shared/source-map-loader/test/browser/browser_source-map.js169
-rw-r--r--devtools/client/shared/source-map-loader/test/browser/browser_wasm-source-map.js126
-rw-r--r--devtools/client/shared/source-map-loader/test/browser/fixtures/absolute.js2
-rw-r--r--devtools/client/shared/source-map-loader/test/browser/fixtures/absolute.js.map10
-rw-r--r--devtools/client/shared/source-map-loader/test/browser/fixtures/bundle.js94
-rw-r--r--devtools/client/shared/source-map-loader/test/browser/fixtures/bundle.js.map21
-rw-r--r--devtools/client/shared/source-map-loader/test/browser/fixtures/empty.js2
-rw-r--r--devtools/client/shared/source-map-loader/test/browser/fixtures/empty.js.map10
-rw-r--r--devtools/client/shared/source-map-loader/test/browser/fixtures/if.js12
-rw-r--r--devtools/client/shared/source-map-loader/test/browser/fixtures/if.out.js16
-rw-r--r--devtools/client/shared/source-map-loader/test/browser/fixtures/if.out.js.map7
-rw-r--r--devtools/client/shared/source-map-loader/test/browser/fixtures/intermingled-sources.js62
-rw-r--r--devtools/client/shared/source-map-loader/test/browser/fixtures/intermingled-sources.js.map8
-rw-r--r--devtools/client/shared/source-map-loader/test/browser/fixtures/missingmap.js2
-rw-r--r--devtools/client/shared/source-map-loader/test/browser/fixtures/noroot.js2
-rw-r--r--devtools/client/shared/source-map-loader/test/browser/fixtures/noroot.js.map9
-rw-r--r--devtools/client/shared/source-map-loader/test/browser/fixtures/noroot2.js2
-rw-r--r--devtools/client/shared/source-map-loader/test/browser/fixtures/noroot2.js.map10
-rw-r--r--devtools/client/shared/source-map-loader/test/browser/fixtures/wasm.js.map7
-rw-r--r--devtools/client/shared/source-map-loader/test/browser/head.js27
23 files changed, 785 insertions, 0 deletions
diff --git a/devtools/client/shared/source-map-loader/test/browser/browser.ini b/devtools/client/shared/source-map-loader/test/browser/browser.ini
new file mode 100644
index 0000000000..5c8b69c3b2
--- /dev/null
+++ b/devtools/client/shared/source-map-loader/test/browser/browser.ini
@@ -0,0 +1,14 @@
+[DEFAULT]
+tags = devtools
+subsuite = devtools
+support-files =
+ head.js
+ fixtures/*
+ !/devtools/client/shared/test/shared-head.js
+ !/devtools/client/shared/test/telemetry-test-helpers.js
+
+[browser_getContentType.js]
+[browser_locations.js]
+[browser_source-map.js]
+[browser_wasm-source-map.js]
+skip-if = http3 # Bug 1829298
diff --git a/devtools/client/shared/source-map-loader/test/browser/browser_getContentType.js b/devtools/client/shared/source-map-loader/test/browser/browser_getContentType.js
new file mode 100644
index 0000000000..5ac402951c
--- /dev/null
+++ b/devtools/client/shared/source-map-loader/test/browser/browser_getContentType.js
@@ -0,0 +1,32 @@
+/* Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/ */
+
+"use strict";
+
+// Cover the automatic mapping of content type based on file extension
+
+const {
+ getContentType,
+ contentMapForTesting,
+} = require("resource://devtools/client/shared/source-map-loader/utils/index.js");
+
+add_task(async () => {
+ for (const ext in contentMapForTesting) {
+ is(
+ getContentType(`whatever.${ext}`),
+ contentMapForTesting[ext],
+ `${ext} file extension is correctly mapping the expected content type`
+ );
+ }
+ is(
+ getContentType(`whateverjs`),
+ "text/plain",
+ `A valid extension in file name doesn't cause a special content type mapping`
+ );
+
+ is(
+ getContentType("whatever.platypus"),
+ "text/plain",
+ "Test unknown extension defaults to text plain"
+ );
+});
diff --git a/devtools/client/shared/source-map-loader/test/browser/browser_locations.js b/devtools/client/shared/source-map-loader/test/browser/browser_locations.js
new file mode 100644
index 0000000000..4d43df5902
--- /dev/null
+++ b/devtools/client/shared/source-map-loader/test/browser/browser_locations.js
@@ -0,0 +1,141 @@
+/* Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/ */
+
+"use strict";
+
+// Covert getOriginalLocation and getGeneratedLocation functions.
+
+add_task(async function testGetOriginalLocation() {
+ await fetchFixtureSourceMap("bundle");
+
+ const generatedLocation = {
+ sourceId: "bundle.js",
+ line: 49,
+ };
+
+ const originalLocation = await gSourceMapLoader.getOriginalLocation(
+ generatedLocation
+ );
+ Assert.deepEqual(
+ originalLocation,
+ {
+ column: 0,
+ line: 3,
+ sourceId: "bundle.js/originalSource-fe2c41d3535b76c158e39ba4f3ff826a",
+ sourceUrl: "webpack:///entry.js",
+ },
+ "Mapped a generated location"
+ );
+
+ const originalLocation2 = await gSourceMapLoader.getOriginalLocation(
+ originalLocation
+ );
+ Assert.deepEqual(originalLocation2, null, "No mapped location");
+
+ gSourceMapLoader.clearSourceMaps();
+ const originalLocation3 = await gSourceMapLoader.getOriginalLocation(
+ generatedLocation
+ );
+ Assert.deepEqual(
+ originalLocation3,
+ null,
+ "after clearing the source maps, the same generated location no longer maps"
+ );
+});
+
+add_task(async function testGetGeneratedLocation() {
+ await fetchFixtureSourceMap("bundle");
+
+ const originalLocation = {
+ column: 0,
+ line: 3,
+ sourceId: "bundle.js/originalSource-fe2c41d3535b76c158e39ba4f3ff826a",
+ };
+
+ const source = {
+ url: "webpack:///entry.js",
+ id: "bundle.js/originalSource-fe2c41d3535b76c158e39ba4f3ff826a",
+ };
+
+ const generatedLocation = await gSourceMapLoader.getGeneratedLocation(
+ originalLocation,
+ source
+ );
+ Assert.deepEqual(
+ generatedLocation,
+ {
+ sourceId: "bundle.js",
+ line: 49,
+ column: 0,
+ },
+ "Map an original location"
+ );
+
+ {
+ gSourceMapLoader.clearSourceMaps();
+
+ const secondGeneratedLocation = await gSourceMapLoader.getGeneratedLocation(
+ originalLocation,
+ source
+ );
+ Assert.deepEqual(
+ secondGeneratedLocation,
+ null,
+ "after clearing source maps, the same location no longer maps to an original location"
+ );
+ }
+
+ {
+ // we expect symmetric mappings, which means that if
+ // we map a generated location to an original location,
+ // and then map it back, we should get the original generated value.
+ // e.g. G[8, 0] -> O[5, 4] -> G[8, 0]
+ await fetchFixtureSourceMap("if.out");
+
+ const genLoc1 = {
+ sourceId: "if.out.js",
+ column: 0,
+ line: 8,
+ };
+
+ const ifSource = {
+ url: "if.js",
+ id: "if.out.js/originalSource-5ad3141023dae912c5f8833c7e03beeb",
+ };
+
+ const oLoc = await gSourceMapLoader.getOriginalLocation(genLoc1);
+ const genLoc2 = await gSourceMapLoader.getGeneratedLocation(oLoc, ifSource);
+
+ Assert.deepEqual(genLoc2, genLoc1, "location mapping is symmetric");
+ }
+
+ {
+ // we expect that an undefined column will be handled like a
+ // location w/ column 0. e.g. G[8, u] -> O[5, 4] -> G[8, 0]
+ await fetchFixtureSourceMap("if.out");
+
+ const genLoc1 = {
+ sourceId: "if.out.js",
+ column: undefined,
+ line: 8,
+ };
+
+ const ifSource = {
+ url: "if.js",
+ id: "if.out.js/originalSource-5ad3141023dae912c5f8833c7e03beeb",
+ };
+
+ const oLoc = await gSourceMapLoader.getOriginalLocation(genLoc1);
+ const genLoc2 = await gSourceMapLoader.getGeneratedLocation(oLoc, ifSource);
+
+ Assert.deepEqual(
+ genLoc2,
+ {
+ sourceId: "if.out.js",
+ column: 0,
+ line: 8,
+ },
+ "undefined column is handled like 0 column"
+ );
+ }
+});
diff --git a/devtools/client/shared/source-map-loader/test/browser/browser_source-map.js b/devtools/client/shared/source-map-loader/test/browser/browser_source-map.js
new file mode 100644
index 0000000000..3493953d1c
--- /dev/null
+++ b/devtools/client/shared/source-map-loader/test/browser/browser_source-map.js
@@ -0,0 +1,169 @@
+/* Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/ */
+
+"use strict";
+
+// Cover the high level API of these modules:
+// getOriginalURLs getGeneratedRangesForOriginal functions
+
+async function assertFixtureOriginalURLs(
+ fixtureName,
+ expectedUrls,
+ testMessage
+) {
+ const originalSources = await fetchFixtureSourceMap(fixtureName);
+ const urls = originalSources.map(s => s.url);
+ Assert.deepEqual(urls, expectedUrls, testMessage);
+}
+
+add_task(async function testGetOriginalURLs() {
+ await assertFixtureOriginalURLs(
+ "absolute",
+ ["https://example.com/cheese/heart.js"],
+ "Test absolute URL"
+ );
+
+ await assertFixtureOriginalURLs(
+ "bundle",
+ [
+ "webpack:///webpack/bootstrap%204ef8c7ec7c1df790781e",
+ "webpack:///entry.js",
+ "webpack:///times2.js",
+ "webpack:///output.js",
+ "webpack:///opts.js",
+ ],
+ "Test source with a url"
+ );
+
+ await assertFixtureOriginalURLs(
+ "empty",
+ [`${URL_ROOT_SSL}fixtures/heart.js`],
+ "Test empty sourceRoot resolution"
+ );
+
+ await assertFixtureOriginalURLs(
+ "noroot",
+ [`${URL_ROOT_SSL}fixtures/heart.js`],
+ "Test Non-existing sourceRoot resolution"
+ );
+
+ await assertFixtureOriginalURLs(
+ "noroot2",
+ [`${URL_ROOT_SSL}fixtures/heart.js`],
+ "Test Non-existing sourceRoot resolution with relative URLs"
+ );
+});
+
+add_task(async function testGetGeneratedRangesForOriginal() {
+ const originals = await fetchFixtureSourceMap("intermingled-sources");
+
+ const ranges = await gSourceMapLoader.getGeneratedRangesForOriginal(
+ originals[0].id
+ );
+
+ Assert.deepEqual(
+ ranges,
+ [
+ {
+ start: {
+ line: 4,
+ column: 69,
+ },
+ end: {
+ line: 9,
+ column: Infinity,
+ },
+ },
+ {
+ start: {
+ line: 11,
+ column: 0,
+ },
+ end: {
+ line: 17,
+ column: 3,
+ },
+ },
+ {
+ start: {
+ line: 19,
+ column: 18,
+ },
+ end: {
+ line: 19,
+ column: 22,
+ },
+ },
+ {
+ start: {
+ line: 26,
+ column: 0,
+ },
+ end: {
+ line: 26,
+ column: Infinity,
+ },
+ },
+ {
+ start: {
+ line: 28,
+ column: 0,
+ },
+ end: {
+ line: 28,
+ column: Infinity,
+ },
+ },
+ ],
+ "Test the overall generated ranges on the source"
+ );
+
+ {
+ // Note that we have to clear the source map in order to get the merged ranges,
+ // otherwise we are still fetching the previous unmerged ones!
+ const secondOriginals = await fetchFixtureSourceMap("intermingled-sources");
+ const mergedRanges = await gSourceMapLoader.getGeneratedRangesForOriginal(
+ secondOriginals[0].id,
+ true
+ );
+
+ Assert.deepEqual(
+ mergedRanges,
+ [
+ {
+ start: {
+ line: 4,
+ column: 69,
+ },
+ end: {
+ line: 28,
+ column: Infinity,
+ },
+ },
+ ],
+ "Test the merged generated ranges on the source"
+ );
+ }
+});
+
+add_task(async function testBaseURLErrorHandling() {
+ const source = {
+ id: "missingmap.js",
+ sourceMapURL: "missingmap.js.map",
+ // Notice the duplicated ":" which cause the error here
+ sourceMapBaseURL: "http:://example.com/",
+ };
+
+ const onError = gSourceMapLoader.once("source-map-error");
+ is(
+ await gSourceMapLoader.getOriginalURLs(source),
+ null,
+ "The error is silented..."
+ );
+ info("Wait for source-map-error event");
+ const error = await onError;
+ is(
+ error,
+ `Source map error: Error: URL constructor: http:://example.com/ is not a valid URL.\nResource URL: undefined\nSource Map URL: missingmap.js.map`
+ );
+});
diff --git a/devtools/client/shared/source-map-loader/test/browser/browser_wasm-source-map.js b/devtools/client/shared/source-map-loader/test/browser/browser_wasm-source-map.js
new file mode 100644
index 0000000000..0f69d7b038
--- /dev/null
+++ b/devtools/client/shared/source-map-loader/test/browser/browser_wasm-source-map.js
@@ -0,0 +1,126 @@
+/* Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/ */
+
+"use strict";
+
+// Test source mappings WASM sources.
+// This test is quite general and test various functions.
+
+const {
+ WasmRemap,
+} = require("resource://devtools/client/shared/source-map-loader/utils/wasmRemap.js");
+const {
+ SourceMapConsumer,
+} = require("resource://devtools/client/shared/vendor/source-map/source-map.js");
+
+SourceMapConsumer.initialize({
+ "lib/mappings.wasm":
+ "resource://devtools/client/shared/vendor/source-map/lib/mappings.wasm",
+});
+
+add_task(async function smokeTest() {
+ const testMap1 = {
+ version: 3,
+ file: "min.js",
+ names: [],
+ sources: ["one.js", "two.js"],
+ sourceRoot: "/the/root",
+ mappings: "CAAC,IAAM,SACU,GAAC",
+ };
+ const testMap1Entries = [
+ { offset: 1, line: 1, column: 1 },
+ { offset: 5, line: 1, column: 7 },
+ { offset: 14, line: 2, column: 17 },
+ { offset: 17, line: 2, column: 18 },
+ ];
+
+ const map1 = await new SourceMapConsumer(testMap1);
+
+ const remap1 = new WasmRemap(map1);
+
+ is(remap1.file, "min.js");
+ is(remap1.hasContentsOfAllSources(), false);
+ is(remap1.sources.length, 2);
+ is(remap1.sources[0], "/the/root/one.js");
+ is(remap1.sources[1], "/the/root/two.js");
+
+ const expectedEntries = testMap1Entries.slice(0);
+ remap1.eachMapping(function (entry) {
+ const expected = expectedEntries.shift();
+ is(entry.generatedLine, expected.offset);
+ is(entry.generatedColumn, 0);
+ is(entry.originalLine, expected.line);
+ is(entry.originalColumn, expected.column);
+ is(entry.name, null);
+ });
+
+ const pos1 = remap1.originalPositionFor({ line: 5, column: 0 });
+ is(pos1.line, 1);
+ is(pos1.column, 7);
+ is(pos1.source, "/the/root/one.js");
+
+ const pos2 = remap1.generatedPositionFor({
+ source: "/the/root/one.js",
+ line: 2,
+ column: 18,
+ });
+ is(pos2.line, 17);
+ is(pos2.column, 0);
+ is(pos2.lastColumn, undefined);
+
+ remap1.computeColumnSpans();
+ const pos3 = remap1.allGeneratedPositionsFor({
+ source: "/the/root/one.js",
+ line: 2,
+ column: 17,
+ });
+ is(pos3.length, 1);
+ is(pos3[0].line, 14);
+ is(pos3[0].column, 0);
+ is(pos3[0].lastColumn, 0);
+
+ map1.destroy();
+});
+
+add_task(async function contentPresents() {
+ const testMap2 = {
+ version: 3,
+ file: "none.js",
+ names: [],
+ sources: ["zero.js"],
+ mappings: "",
+ sourcesContent: ["//test"],
+ };
+
+ const map2 = await new SourceMapConsumer(testMap2);
+ const remap2 = new WasmRemap(map2);
+ is(remap2.file, "none.js");
+ ok(remap2.hasContentsOfAllSources());
+ is(remap2.sourceContentFor("zero.js"), "//test");
+
+ map2.destroy();
+});
+
+add_task(async function readAndTransposeWasmMap() {
+ const source = {
+ id: "wasm.js",
+ sourceMapBaseURL: "wasm:http://example.com/whatever/:min.js",
+ sourceMapURL: `${URL_ROOT}fixtures/wasm.js.map`,
+ isWasm: true,
+ };
+
+ const urls = await gSourceMapLoader.getOriginalURLs(source);
+ Assert.deepEqual(urls, [
+ {
+ id: "wasm.js/originalSource-63954a1c231200652c0d99c6a69cd178",
+ url: `${URL_ROOT}fixtures/one.js`,
+ },
+ ]);
+
+ const { line, column } = await gSourceMapLoader.getOriginalLocation({
+ sourceId: source.id,
+ line: 5,
+ });
+ is(line, 1);
+ is(column, 7);
+});
diff --git a/devtools/client/shared/source-map-loader/test/browser/fixtures/absolute.js b/devtools/client/shared/source-map-loader/test/browser/fixtures/absolute.js
new file mode 100644
index 0000000000..adcc337eca
--- /dev/null
+++ b/devtools/client/shared/source-map-loader/test/browser/fixtures/absolute.js
@@ -0,0 +1,2 @@
+/* Doesn't really matter what is in here. */
+// # sourceMappingURL=absolute.js.map
diff --git a/devtools/client/shared/source-map-loader/test/browser/fixtures/absolute.js.map b/devtools/client/shared/source-map-loader/test/browser/fixtures/absolute.js.map
new file mode 100644
index 0000000000..0597515870
--- /dev/null
+++ b/devtools/client/shared/source-map-loader/test/browser/fixtures/absolute.js.map
@@ -0,0 +1,10 @@
+{
+ "version": 3,
+ "sources": [
+ "heart.js"
+ ],
+ "names": [],
+ "mappings": ";AAAA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA,uBAAe;AACf;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;;AAGA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;;;;;;ACtCA;AACA,QAAO,SAAS;AAChB;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;;;;;;ACfA;AACA;AACA;;;;;;;ACFA;AACA;AACA;;AAEA,mBAAkB;;;;;;;ACJlB;AACA;AACA",
+ "file": "absolute.js",
+ "sourceRoot": "https://example.com/cheese/"
+}
diff --git a/devtools/client/shared/source-map-loader/test/browser/fixtures/bundle.js b/devtools/client/shared/source-map-loader/test/browser/fixtures/bundle.js
new file mode 100644
index 0000000000..9ee477b856
--- /dev/null
+++ b/devtools/client/shared/source-map-loader/test/browser/fixtures/bundle.js
@@ -0,0 +1,94 @@
+/** ****/ (function(modules) { // webpackBootstrap
+/** ****/ // The module cache
+/** ****/ var installedModules = {};
+/** ****/
+/** ****/ // The require function
+/** ****/ function __webpack_require__(moduleId) {
+/** ****/
+/** ****/ // Check if module is in cache
+/** ****/ if (installedModules[moduleId])
+/** ****/ {return installedModules[moduleId].exports;}
+/** ****/
+/** ****/ // Create a new module (and put it into the cache)
+/** ****/ var module = installedModules[moduleId] = {
+/** ****/ exports: {},
+/** ****/ id: moduleId,
+/** ****/ loaded: false
+/** ****/ };
+/** ****/
+/** ****/ // Execute the module function
+/** ****/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
+/** ****/
+/** ****/ // Flag the module as loaded
+/** ****/ module.loaded = true;
+/** ****/
+/** ****/ // Return the exports of the module
+/** ****/ return module.exports;
+/** ****/ }
+/** ****/
+/** ****/
+/** ****/ // expose the modules object (__webpack_modules__)
+/** ****/ __webpack_require__.m = modules;
+/** ****/
+/** ****/ // expose the module cache
+/** ****/ __webpack_require__.c = installedModules;
+/** ****/
+/** ****/ // __webpack_public_path__
+/** ****/ __webpack_require__.p = "";
+/** ****/
+/** ****/ // Load entry module and return exports
+/** ****/ return __webpack_require__(0);
+/** ****/ })([
+/* 0 */
+/** */ function(module, exports, __webpack_require__) {
+
+ const times2 = __webpack_require__(1);
+ const { output } = __webpack_require__(2);
+ const opts = __webpack_require__(3);
+
+ output(times2(1));
+ output(times2(2));
+
+ if (opts.extra) {
+ output(times2(3));
+}
+
+ window.keepMeAlive = function() {
+ // This function exists to make sure this script is never garbage
+ // collected. It is also callable from tests.
+ return times2(4);
+};
+
+/** *
+/ },
+/* 1 */
+/** */ function(module, exports) {
+
+ module.exports = function(x) {
+ return x * 2;
+};
+
+/** *
+/ },
+/* 2 */
+/** */ function(module, exports) {
+
+ function output(str) {
+ console.log(str);
+}
+
+ module.exports = { output };
+
+/** *
+/ },
+/* 3 */
+/** */ function(module, exports) {
+
+ module.exports = {
+ extra: true
+};
+
+/** *
+/ }
+/** ****/ ]);
+// # sourceMappingURL=bundle.js.map
diff --git a/devtools/client/shared/source-map-loader/test/browser/fixtures/bundle.js.map b/devtools/client/shared/source-map-loader/test/browser/fixtures/bundle.js.map
new file mode 100644
index 0000000000..f53036cb8e
--- /dev/null
+++ b/devtools/client/shared/source-map-loader/test/browser/fixtures/bundle.js.map
@@ -0,0 +1,21 @@
+{
+ "version": 3,
+ "sources": [
+ "webpack:///webpack/bootstrap 4ef8c7ec7c1df790781e",
+ "webpack:///./entry.js",
+ "webpack:///./times2.js",
+ "webpack:///./output.js",
+ "webpack:///./opts.js"
+ ],
+ "names": [],
+ "mappings": ";AAAA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA,uBAAe;AACf;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;;AAGA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;;;;;;ACtCA;AACA,QAAO,SAAS;AAChB;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;;;;;;ACfA;AACA;AACA;;;;;;;ACFA;AACA;AACA;;AAEA,mBAAkB;;;;;;;ACJlB;AACA;AACA",
+ "file": "bundle.js",
+ "sourcesContent": [
+ " \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId])\n \t\t\treturn installedModules[moduleId].exports;\n\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\texports: {},\n \t\t\tid: moduleId,\n \t\t\tloaded: false\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.loaded = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(0);\n\n\n\n// WEBPACK FOOTER //\n// webpack/bootstrap 4ef8c7ec7c1df790781e",
+ "const times2 = require(\"./times2\");\nconst { output } = require(\"./output\");\nconst opts = require(\"./opts\");\n\noutput(times2(1));\noutput(times2(2));\n\nif(opts.extra) {\n output(times2(3));\n}\n\nwindow.keepMeAlive = function() {\n // This function exists to make sure this script is never garbage\n // collected. It is also callable from tests.\n return times2(4);\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./entry.js\n// module id = 0\n// module chunks = 0",
+ "module.exports = function(x) {\n return x * 2;\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./times2.js\n// module id = 1\n// module chunks = 0",
+ "function output(str) {\n console.log(str);\n}\n\nmodule.exports = { output };\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./output.js\n// module id = 2\n// module chunks = 0",
+ "module.exports = {\n extra: true\n};\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./opts.js\n// module id = 3\n// module chunks = 0"
+ ],
+ "sourceRoot": ""
+}
diff --git a/devtools/client/shared/source-map-loader/test/browser/fixtures/empty.js b/devtools/client/shared/source-map-loader/test/browser/fixtures/empty.js
new file mode 100644
index 0000000000..72c472a745
--- /dev/null
+++ b/devtools/client/shared/source-map-loader/test/browser/fixtures/empty.js
@@ -0,0 +1,2 @@
+/* Doesn't really matter what is in here. */
+// # sourceMappingURL=empty.js.map
diff --git a/devtools/client/shared/source-map-loader/test/browser/fixtures/empty.js.map b/devtools/client/shared/source-map-loader/test/browser/fixtures/empty.js.map
new file mode 100644
index 0000000000..9ebfec598d
--- /dev/null
+++ b/devtools/client/shared/source-map-loader/test/browser/fixtures/empty.js.map
@@ -0,0 +1,10 @@
+{
+ "version": 3,
+ "sources": [
+ "heart.js"
+ ],
+ "names": [],
+ "mappings": ";AAAA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA,uBAAe;AACf;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;;AAGA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;;;;;;ACtCA;AACA,QAAO,SAAS;AAChB;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;;;;;;ACfA;AACA;AACA;;;;;;;ACFA;AACA;AACA;;AAEA,mBAAkB;;;;;;;ACJlB;AACA;AACA",
+ "file": "empty.js",
+ "sourceRoot": ""
+}
diff --git a/devtools/client/shared/source-map-loader/test/browser/fixtures/if.js b/devtools/client/shared/source-map-loader/test/browser/fixtures/if.js
new file mode 100644
index 0000000000..4ee69b19ef
--- /dev/null
+++ b/devtools/client/shared/source-map-loader/test/browser/fixtures/if.js
@@ -0,0 +1,12 @@
+function componentWillReceiveProps(nextProps) {
+ console.log("start");
+ const { selectedSource } = nextProps;
+
+ if (
+ nextProps.startPanelSize !== this.props.startPanelSize ||
+ nextProps.endPanelSize !== this.props.endPanelSize
+ ) {
+ this.state.editor.codeMirror.setSize();
+ }
+ console.log("done");
+}
diff --git a/devtools/client/shared/source-map-loader/test/browser/fixtures/if.out.js b/devtools/client/shared/source-map-loader/test/browser/fixtures/if.out.js
new file mode 100644
index 0000000000..9bb0752a92
--- /dev/null
+++ b/devtools/client/shared/source-map-loader/test/browser/fixtures/if.out.js
@@ -0,0 +1,16 @@
+"use strict";
+
+function componentWillReceiveProps(nextProps) {
+ console.log("start");
+ var selectedSource = nextProps.selectedSource;
+
+ if (
+ nextProps.startPanelSize !== this.props.startPanelSize ||
+ nextProps.endPanelSize !== this.props.endPanelSize
+ ) {
+ this.state.editor.codeMirror.setSize();
+ }
+ console.log("done");
+}
+
+//# sourceMappingURL=if.out.js.map
diff --git a/devtools/client/shared/source-map-loader/test/browser/fixtures/if.out.js.map b/devtools/client/shared/source-map-loader/test/browser/fixtures/if.out.js.map
new file mode 100644
index 0000000000..27feb5278f
--- /dev/null
+++ b/devtools/client/shared/source-map-loader/test/browser/fixtures/if.out.js.map
@@ -0,0 +1,7 @@
+{
+ "version":3,
+ "sources":["if.js"],
+ "names":[],
+ "mappings":";;AAAA,SAAS,yBAAT,CAAmC,SAAnC,EAA8C;AAC7C,UAAQ,GAAR,CAAY,OAAZ;AAD6C,MAElC,cAFkC,GAEf,SAFe,CAElC,cAFkC;;;AAI1C,MACE,UAAU,cAAV,KAA6B,KAAK,KAAL,CAAW,cAAxC,IACA,UAAU,YAAV,KAA2B,KAAK,KAAL,CAAW,YAFxC,EAGE;AACA,SAAK,KAAL,CAAW,MAAX,CAAkB,UAAlB,CAA6B,OAA7B;AACD;AACJ,UAAQ,GAAR,CAAY,MAAZ;AACA","file":"if.out.js",
+ "sourcesContent":["function componentWillReceiveProps(nextProps) {\n\tconsole.log('start');\n const { selectedSource } = nextProps;\n\n if (\n nextProps.startPanelSize !== this.props.startPanelSize ||\n nextProps.endPanelSize !== this.props.endPanelSize\n ) {\n this.state.editor.codeMirror.setSize();\n }\n\tconsole.log('done');\n}\n"]
+}
diff --git a/devtools/client/shared/source-map-loader/test/browser/fixtures/intermingled-sources.js b/devtools/client/shared/source-map-loader/test/browser/fixtures/intermingled-sources.js
new file mode 100644
index 0000000000..c3d9a150bd
--- /dev/null
+++ b/devtools/client/shared/source-map-loader/test/browser/fixtures/intermingled-sources.js
@@ -0,0 +1,62 @@
+"use strict";
+
+var decl = (function() {
+ var _ref = _asyncToGenerator(
+ /*#__PURE__*/ regeneratorRuntime.mark(function _callee() {
+ return regeneratorRuntime.wrap(
+ function _callee$(_context) {
+ while (1) {
+ switch ((_context.prev = _context.next)) {
+ case 0:
+ console.log("2");
+
+ case 1:
+ case "end":
+ return _context.stop();
+ }
+ }
+ },
+ _callee,
+ this
+ );
+ })
+ );
+
+ return function decl() {
+ return _ref.apply(this, arguments);
+ };
+})();
+
+function _asyncToGenerator(fn) {
+ return function() {
+ var gen = fn.apply(this, arguments);
+ return new Promise(function(resolve, reject) {
+ function step(key, arg) {
+ try {
+ var info = gen[key](arg);
+ var value = info.value;
+ } catch (error) {
+ reject(error);
+ return;
+ }
+ if (info.done) {
+ resolve(value);
+ } else {
+ return Promise.resolve(value).then(
+ function(value) {
+ step("next", value);
+ },
+ function(err) {
+ step("throw", err);
+ }
+ );
+ }
+ }
+ return step("next");
+ });
+ };
+}
+
+console.log("1");
+
+console.log("3");
diff --git a/devtools/client/shared/source-map-loader/test/browser/fixtures/intermingled-sources.js.map b/devtools/client/shared/source-map-loader/test/browser/fixtures/intermingled-sources.js.map
new file mode 100644
index 0000000000..2876b9900b
--- /dev/null
+++ b/devtools/client/shared/source-map-loader/test/browser/fixtures/intermingled-sources.js.map
@@ -0,0 +1,8 @@
+{
+ "version":3,
+ "file":"output.js",
+ "mappings":";;;qEAEA;AAAA;AAAA;AAAA;AAAA;AACE,oBAAQ,GAAR,CAAY,GAAZ;;AADF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,G;;kBAAe,I;;;;;;;AAFf,QAAQ,GAAR,CAAY,GAAZ;;AAMA,QAAQ,GAAR,CAAY,GAAZ",
+ "sources":["input.js"],
+ "sourcesContent":["console.log(\"1\")\n\nasync function decl(){\n console.log(\"2\");\n}\n\nconsole.log(\"3\");"],
+ "names":[]
+} \ No newline at end of file
diff --git a/devtools/client/shared/source-map-loader/test/browser/fixtures/missingmap.js b/devtools/client/shared/source-map-loader/test/browser/fixtures/missingmap.js
new file mode 100644
index 0000000000..5a162652a7
--- /dev/null
+++ b/devtools/client/shared/source-map-loader/test/browser/fixtures/missingmap.js
@@ -0,0 +1,2 @@
+// Source where the map is missing.
+// # sourceMappingURL=missingmap.js.map
diff --git a/devtools/client/shared/source-map-loader/test/browser/fixtures/noroot.js b/devtools/client/shared/source-map-loader/test/browser/fixtures/noroot.js
new file mode 100644
index 0000000000..33d15cf494
--- /dev/null
+++ b/devtools/client/shared/source-map-loader/test/browser/fixtures/noroot.js
@@ -0,0 +1,2 @@
+/* Doesn't really matter what is in here. */
+// # sourceMappingURL=noroot.js.map
diff --git a/devtools/client/shared/source-map-loader/test/browser/fixtures/noroot.js.map b/devtools/client/shared/source-map-loader/test/browser/fixtures/noroot.js.map
new file mode 100644
index 0000000000..dfeee2d765
--- /dev/null
+++ b/devtools/client/shared/source-map-loader/test/browser/fixtures/noroot.js.map
@@ -0,0 +1,9 @@
+{
+ "version": 3,
+ "sources": [
+ "heart.js"
+ ],
+ "names": [],
+ "mappings": ";AAAA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA,uBAAe;AACf;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;;AAGA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;;;;;;ACtCA;AACA,QAAO,SAAS;AAChB;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;;;;;;ACfA;AACA;AACA;;;;;;;ACFA;AACA;AACA;;AAEA,mBAAkB;;;;;;;ACJlB;AACA;AACA",
+ "file": "noroot.js"
+}
diff --git a/devtools/client/shared/source-map-loader/test/browser/fixtures/noroot2.js b/devtools/client/shared/source-map-loader/test/browser/fixtures/noroot2.js
new file mode 100644
index 0000000000..35aa77b92c
--- /dev/null
+++ b/devtools/client/shared/source-map-loader/test/browser/fixtures/noroot2.js
@@ -0,0 +1,2 @@
+/* Doesn't really matter what is in here. */
+// # sourceMappingURL=noroot2.js.map
diff --git a/devtools/client/shared/source-map-loader/test/browser/fixtures/noroot2.js.map b/devtools/client/shared/source-map-loader/test/browser/fixtures/noroot2.js.map
new file mode 100644
index 0000000000..1d22100178
--- /dev/null
+++ b/devtools/client/shared/source-map-loader/test/browser/fixtures/noroot2.js.map
@@ -0,0 +1,10 @@
+{
+ "version": 3,
+ "sources": [
+ "heart.js"
+ ],
+ "names": [],
+ "mappings": ";AAAA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA,uBAAe;AACf;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;;AAGA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;;;;;;ACtCA;AACA,QAAO,SAAS;AAChB;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;;;;;;ACfA;AACA;AACA;;;;;;;ACFA;AACA;AACA;;AAEA,mBAAkB;;;;;;;ACJlB;AACA;AACA",
+ "file": "noroot.js",
+ "sourceContents": ["this is the full text"]
+}
diff --git a/devtools/client/shared/source-map-loader/test/browser/fixtures/wasm.js.map b/devtools/client/shared/source-map-loader/test/browser/fixtures/wasm.js.map
new file mode 100644
index 0000000000..828f6a9aa4
--- /dev/null
+++ b/devtools/client/shared/source-map-loader/test/browser/fixtures/wasm.js.map
@@ -0,0 +1,7 @@
+{
+ "version": 3,
+ "file": "wasm.js",
+ "names": [],
+ "sources": ["one.js"],
+ "mappings": "CAAC,IAAM"
+}
diff --git a/devtools/client/shared/source-map-loader/test/browser/head.js b/devtools/client/shared/source-map-loader/test/browser/head.js
new file mode 100644
index 0000000000..0f54e5a5f5
--- /dev/null
+++ b/devtools/client/shared/source-map-loader/test/browser/head.js
@@ -0,0 +1,27 @@
+/* Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/ */
+
+"use strict";
+
+Services.scriptloader.loadSubScript(
+ "chrome://mochitests/content/browser/devtools/client/shared/test/shared-head.js",
+ this
+);
+
+const {
+ SourceMapLoader,
+} = require("resource://devtools/client/shared/source-map-loader/index.js");
+
+const gSourceMapLoader = new SourceMapLoader();
+
+function fetchFixtureSourceMap(name) {
+ gSourceMapLoader.clearSourceMaps();
+
+ const source = {
+ id: `${name}.js`,
+ sourceMapURL: `${name}.js.map`,
+ sourceMapBaseURL: `${URL_ROOT_SSL}fixtures/${name}.js`,
+ };
+
+ return gSourceMapLoader.getOriginalURLs(source);
+}