"How do I test the source maps my compiler/transpiler/build tool creates?"

I have seen this question come up a few times, and unfortunately, people usually don't find an answer, give up, and don't test their source maps. However, testing source maps isn't too hard if you are using Node.js and the mozilla/source-map library. If you aren't using Node.js and the mozilla/source-map library, you can still use the following techniques, but you will need to implement a source map consumer.

Your tool most likely has a function that generates both the JavaScript that will be executed by the browser's JavaScript engine/Node/whatever, and a source map. Something like this:

var result = compile(input, { url: inputUrl, sourceMap: true });
result.code;      // The JavaScript code
result.sourceMap; // The source map

It is easiest to base your tests around this function.

To test generated source maps:

  1. Create some test input to compile.

  2. Select some different bits of code in the test input and record their { url, line, column } locations. Generally, a "bit of code" should be a specific token, function invocation, etc.

  3. Compile and generate a source map for the test input.

  4. Create a SourceMapConsumer for the generated source map.

    var smc = new SourceMapConsumer(result.sourceMap);
  5. Inspect the compiled code and find the generated code that corresponds to the bits of code you selected in step (2). For each of the { line, column } locations in the compiled code, add an assertion to your test that smc.originalPositionFor(location) is equal to the expected location in your original source.

There is another approach, that is easier for compilers targeting JavaScript than for build tools, which can be used when you don't want to inspect the generated JavaScript at all.

  1. You can add a location debugging statement to your language that compiles to JavaScript code similar to:

    // SpiderMonkey (Firefox)
    (function (e) { console.log(e.lineNumber, e.columnNumber); }(new Error()));
    // In other engines, you need to parse the first frame from the error's
    // stack property yourself
    (function (e) { console.log(parseLocation(e.stack)); }(new Error()));
  2. Create test input which has one or more of these location debugging statements.

  3. Compile the test input and create a SourceMapConsumer for your generated source map.

  4. Run the compiled input and read its output.

  5. Assert that querying the SourceMapConsumer for the original location(s) of that output points to the expected location(s) in your original test input source.

For reference, here are some existing source map test suites from various projects (hopefully this post helps them expand their tests as well):