• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// Flags: --enable-source-maps
2'use strict';
3
4require('../common');
5const assert = require('assert');
6const { findSourceMap, SourceMap } = require('module');
7const { readFileSync } = require('fs');
8
9// findSourceMap() can lookup source-maps based on URIs, in the
10// non-exceptional case.
11{
12  require('../fixtures/source-map/disk-relative-path.js');
13  const sourceMap = findSourceMap(
14    require.resolve('../fixtures/source-map/disk-relative-path.js')
15  );
16  const {
17    originalLine,
18    originalColumn,
19    originalSource
20  } = sourceMap.findEntry(0, 29);
21  assert.strictEqual(originalLine, 2);
22  assert.strictEqual(originalColumn, 4);
23  assert(originalSource.endsWith('disk.js'));
24}
25
26// findSourceMap() can be used in Error.prepareStackTrace() to lookup
27// source-map attached to error.
28{
29  let callSite;
30  let sourceMap;
31  Error.prepareStackTrace = (error, trace) => {
32    const throwingRequireCallSite = trace[0];
33    if (throwingRequireCallSite.getFileName().endsWith('typescript-throw.js')) {
34      sourceMap = findSourceMap(throwingRequireCallSite.getFileName(), error);
35      callSite = throwingRequireCallSite;
36    }
37  };
38  try {
39    // Require a file that throws an exception, and has a source map.
40    require('../fixtures/source-map/typescript-throw.js');
41  } catch (err) {
42    err.stack; // Force prepareStackTrace() to be called.
43  }
44  assert(callSite);
45  assert(sourceMap);
46  const {
47    generatedLine,
48    generatedColumn,
49    originalLine,
50    originalColumn,
51    originalSource
52  } = sourceMap.findEntry(
53    callSite.getLineNumber() - 1,
54    callSite.getColumnNumber() - 1
55  );
56
57  assert.strictEqual(generatedLine, 19);
58  assert.strictEqual(generatedColumn, 14);
59
60  assert.strictEqual(originalLine, 17);
61  assert.strictEqual(originalColumn, 10);
62  assert(originalSource.endsWith('typescript-throw.ts'));
63}
64
65// SourceMap can be instantiated with Source Map V3 object as payload.
66{
67  const payload = JSON.parse(readFileSync(
68    require.resolve('../fixtures/source-map/disk.map'), 'utf8'
69  ));
70  const sourceMap = new SourceMap(payload);
71  const {
72    originalLine,
73    originalColumn,
74    originalSource
75  } = sourceMap.findEntry(0, 29);
76  assert.strictEqual(originalLine, 2);
77  assert.strictEqual(originalColumn, 4);
78  assert(originalSource.endsWith('disk.js'));
79  // The stored payload should be a clone:
80  assert.strictEqual(payload.mappings, sourceMap.payload.mappings);
81  assert.notStrictEqual(payload, sourceMap.payload);
82  assert.strictEqual(payload.sources[0], sourceMap.payload.sources[0]);
83  assert.notStrictEqual(payload.sources, sourceMap.payload.sources);
84}
85
86// Test various known decodings to ensure decodeVLQ works correctly.
87{
88  function makeMinimalMap(column) {
89    return {
90      sources: ['test.js'],
91      // Mapping from the 0th line, 0th column of the output file to the 0th
92      // source file, 0th line, ${column}th column.
93      mappings: `AAA${column}`,
94    };
95  }
96  const knownDecodings = {
97    'A': 0,
98    'B': -2147483648,
99    'C': 1,
100    'D': -1,
101    'E': 2,
102    'F': -2,
103
104    // 2^31 - 1, maximum values
105    '+/////D': 2147483647,
106    '8/////D': 2147483646,
107    '6/////D': 2147483645,
108    '4/////D': 2147483644,
109    '2/////D': 2147483643,
110    '0/////D': 2147483642,
111
112    // -2^31 + 1, minimum values
113    '//////D': -2147483647,
114    '9/////D': -2147483646,
115    '7/////D': -2147483645,
116    '5/////D': -2147483644,
117    '3/////D': -2147483643,
118    '1/////D': -2147483642,
119  };
120
121  for (const column in knownDecodings) {
122    const sourceMap = new SourceMap(makeMinimalMap(column));
123    const { originalColumn } = sourceMap.findEntry(0, 0);
124    assert.strictEqual(originalColumn, knownDecodings[column]);
125  }
126}
127
128// Test that generated columns are sorted when a negative offset is
129// observed, see: https://github.com/mozilla/source-map/pull/92
130{
131  function makeMinimalMap(generatedColumns, originalColumns) {
132    return {
133      sources: ['test.js'],
134      // Mapping from the 0th line, ${g}th column of the output file to the 0th
135      // source file, 0th line, ${column}th column.
136      mappings: generatedColumns.map((g, i) => `${g}AA${originalColumns[i]}`)
137        .join(',')
138    };
139  }
140  // U = 10
141  // F = -2
142  // A = 0
143  // E = 2
144  const sourceMap = new SourceMap(makeMinimalMap(
145    ['U', 'F', 'F'],
146    ['A', 'E', 'E']
147  ));
148  assert.strictEqual(sourceMap.findEntry(0, 6).originalColumn, 4);
149  assert.strictEqual(sourceMap.findEntry(0, 8).originalColumn, 2);
150  assert.strictEqual(sourceMap.findEntry(0, 10).originalColumn, 0);
151}
152