]> git.r.bdr.sh - rbdr/dotfiles/blob
d748bb185618f6fefe5439d99d56bffd06c347f1
[rbdr/dotfiles] /
1 /* -*- Mode: js; js-indent-level: 2; -*- */
2 /*
3 * Copyright 2011 Mozilla Foundation and contributors
4 * Licensed under the New BSD license. See LICENSE or:
5 * http://opensource.org/licenses/BSD-3-Clause
6 */
7 if (typeof define !== 'function') {
8 var define = require('amdefine')(module, require);
9 }
10 define(function (require, exports, module) {
11
12 var SourceMapGenerator = require('../../lib/source-map/source-map-generator').SourceMapGenerator;
13 var SourceMapConsumer = require('../../lib/source-map/source-map-consumer').SourceMapConsumer;
14 var SourceNode = require('../../lib/source-map/source-node').SourceNode;
15 var util = require('./util');
16
17 exports['test some simple stuff'] = function (assert, util) {
18 var map = new SourceMapGenerator({
19 file: 'foo.js',
20 sourceRoot: '.'
21 });
22 assert.ok(true);
23
24 var map = new SourceMapGenerator().toJSON();
25 assert.ok(!('file' in map));
26 assert.ok(!('sourceRoot' in map));
27 };
28
29 exports['test JSON serialization'] = function (assert, util) {
30 var map = new SourceMapGenerator({
31 file: 'foo.js',
32 sourceRoot: '.'
33 });
34 assert.equal(map.toString(), JSON.stringify(map));
35 };
36
37 exports['test adding mappings (case 1)'] = function (assert, util) {
38 var map = new SourceMapGenerator({
39 file: 'generated-foo.js',
40 sourceRoot: '.'
41 });
42
43 assert.doesNotThrow(function () {
44 map.addMapping({
45 generated: { line: 1, column: 1 }
46 });
47 });
48 };
49
50 exports['test adding mappings (case 2)'] = function (assert, util) {
51 var map = new SourceMapGenerator({
52 file: 'generated-foo.js',
53 sourceRoot: '.'
54 });
55
56 assert.doesNotThrow(function () {
57 map.addMapping({
58 generated: { line: 1, column: 1 },
59 source: 'bar.js',
60 original: { line: 1, column: 1 }
61 });
62 });
63 };
64
65 exports['test adding mappings (case 3)'] = function (assert, util) {
66 var map = new SourceMapGenerator({
67 file: 'generated-foo.js',
68 sourceRoot: '.'
69 });
70
71 assert.doesNotThrow(function () {
72 map.addMapping({
73 generated: { line: 1, column: 1 },
74 source: 'bar.js',
75 original: { line: 1, column: 1 },
76 name: 'someToken'
77 });
78 });
79 };
80
81 exports['test adding mappings (invalid)'] = function (assert, util) {
82 var map = new SourceMapGenerator({
83 file: 'generated-foo.js',
84 sourceRoot: '.'
85 });
86
87 // Not enough info.
88 assert.throws(function () {
89 map.addMapping({});
90 });
91
92 // Original file position, but no source.
93 assert.throws(function () {
94 map.addMapping({
95 generated: { line: 1, column: 1 },
96 original: { line: 1, column: 1 }
97 });
98 });
99 };
100
101 exports['test adding mappings with skipValidation'] = function (assert, util) {
102 var map = new SourceMapGenerator({
103 file: 'generated-foo.js',
104 sourceRoot: '.',
105 skipValidation: true
106 });
107
108 // Not enough info, caught by `util.getArgs`
109 assert.throws(function () {
110 map.addMapping({});
111 });
112
113 // Original file position, but no source. Not checked.
114 assert.doesNotThrow(function () {
115 map.addMapping({
116 generated: { line: 1, column: 1 },
117 original: { line: 1, column: 1 }
118 });
119 });
120 };
121
122 exports['test that the correct mappings are being generated'] = function (assert, util) {
123 var map = new SourceMapGenerator({
124 file: 'min.js',
125 sourceRoot: '/the/root'
126 });
127
128 map.addMapping({
129 generated: { line: 1, column: 1 },
130 original: { line: 1, column: 1 },
131 source: 'one.js'
132 });
133 map.addMapping({
134 generated: { line: 1, column: 5 },
135 original: { line: 1, column: 5 },
136 source: 'one.js'
137 });
138 map.addMapping({
139 generated: { line: 1, column: 9 },
140 original: { line: 1, column: 11 },
141 source: 'one.js'
142 });
143 map.addMapping({
144 generated: { line: 1, column: 18 },
145 original: { line: 1, column: 21 },
146 source: 'one.js',
147 name: 'bar'
148 });
149 map.addMapping({
150 generated: { line: 1, column: 21 },
151 original: { line: 2, column: 3 },
152 source: 'one.js'
153 });
154 map.addMapping({
155 generated: { line: 1, column: 28 },
156 original: { line: 2, column: 10 },
157 source: 'one.js',
158 name: 'baz'
159 });
160 map.addMapping({
161 generated: { line: 1, column: 32 },
162 original: { line: 2, column: 14 },
163 source: 'one.js',
164 name: 'bar'
165 });
166
167 map.addMapping({
168 generated: { line: 2, column: 1 },
169 original: { line: 1, column: 1 },
170 source: 'two.js'
171 });
172 map.addMapping({
173 generated: { line: 2, column: 5 },
174 original: { line: 1, column: 5 },
175 source: 'two.js'
176 });
177 map.addMapping({
178 generated: { line: 2, column: 9 },
179 original: { line: 1, column: 11 },
180 source: 'two.js'
181 });
182 map.addMapping({
183 generated: { line: 2, column: 18 },
184 original: { line: 1, column: 21 },
185 source: 'two.js',
186 name: 'n'
187 });
188 map.addMapping({
189 generated: { line: 2, column: 21 },
190 original: { line: 2, column: 3 },
191 source: 'two.js'
192 });
193 map.addMapping({
194 generated: { line: 2, column: 28 },
195 original: { line: 2, column: 10 },
196 source: 'two.js',
197 name: 'n'
198 });
199
200 map = JSON.parse(map.toString());
201
202 util.assertEqualMaps(assert, map, util.testMap);
203 };
204
205 exports['test that adding a mapping with an empty string name does not break generation'] = function (assert, util) {
206 var map = new SourceMapGenerator({
207 file: 'generated-foo.js',
208 sourceRoot: '.'
209 });
210
211 map.addMapping({
212 generated: { line: 1, column: 1 },
213 source: 'bar.js',
214 original: { line: 1, column: 1 },
215 name: ''
216 });
217
218 assert.doesNotThrow(function () {
219 JSON.parse(map.toString());
220 });
221 };
222
223 exports['test that source content can be set'] = function (assert, util) {
224 var map = new SourceMapGenerator({
225 file: 'min.js',
226 sourceRoot: '/the/root'
227 });
228 map.addMapping({
229 generated: { line: 1, column: 1 },
230 original: { line: 1, column: 1 },
231 source: 'one.js'
232 });
233 map.addMapping({
234 generated: { line: 2, column: 1 },
235 original: { line: 1, column: 1 },
236 source: 'two.js'
237 });
238 map.setSourceContent('one.js', 'one file content');
239
240 map = JSON.parse(map.toString());
241 assert.equal(map.sources[0], 'one.js');
242 assert.equal(map.sources[1], 'two.js');
243 assert.equal(map.sourcesContent[0], 'one file content');
244 assert.equal(map.sourcesContent[1], null);
245 };
246
247 exports['test .fromSourceMap'] = function (assert, util) {
248 var map = SourceMapGenerator.fromSourceMap(new SourceMapConsumer(util.testMap));
249 util.assertEqualMaps(assert, map.toJSON(), util.testMap);
250 };
251
252 exports['test .fromSourceMap with sourcesContent'] = function (assert, util) {
253 var map = SourceMapGenerator.fromSourceMap(
254 new SourceMapConsumer(util.testMapWithSourcesContent));
255 util.assertEqualMaps(assert, map.toJSON(), util.testMapWithSourcesContent);
256 };
257
258 exports['test applySourceMap'] = function (assert, util) {
259 var node = new SourceNode(null, null, null, [
260 new SourceNode(2, 0, 'fileX', 'lineX2\n'),
261 'genA1\n',
262 new SourceNode(2, 0, 'fileY', 'lineY2\n'),
263 'genA2\n',
264 new SourceNode(1, 0, 'fileX', 'lineX1\n'),
265 'genA3\n',
266 new SourceNode(1, 0, 'fileY', 'lineY1\n')
267 ]);
268 var mapStep1 = node.toStringWithSourceMap({
269 file: 'fileA'
270 }).map;
271 mapStep1.setSourceContent('fileX', 'lineX1\nlineX2\n');
272 mapStep1 = mapStep1.toJSON();
273
274 node = new SourceNode(null, null, null, [
275 'gen1\n',
276 new SourceNode(1, 0, 'fileA', 'lineA1\n'),
277 new SourceNode(2, 0, 'fileA', 'lineA2\n'),
278 new SourceNode(3, 0, 'fileA', 'lineA3\n'),
279 new SourceNode(4, 0, 'fileA', 'lineA4\n'),
280 new SourceNode(1, 0, 'fileB', 'lineB1\n'),
281 new SourceNode(2, 0, 'fileB', 'lineB2\n'),
282 'gen2\n'
283 ]);
284 var mapStep2 = node.toStringWithSourceMap({
285 file: 'fileGen'
286 }).map;
287 mapStep2.setSourceContent('fileB', 'lineB1\nlineB2\n');
288 mapStep2 = mapStep2.toJSON();
289
290 node = new SourceNode(null, null, null, [
291 'gen1\n',
292 new SourceNode(2, 0, 'fileX', 'lineA1\n'),
293 new SourceNode(2, 0, 'fileA', 'lineA2\n'),
294 new SourceNode(2, 0, 'fileY', 'lineA3\n'),
295 new SourceNode(4, 0, 'fileA', 'lineA4\n'),
296 new SourceNode(1, 0, 'fileB', 'lineB1\n'),
297 new SourceNode(2, 0, 'fileB', 'lineB2\n'),
298 'gen2\n'
299 ]);
300 var expectedMap = node.toStringWithSourceMap({
301 file: 'fileGen'
302 }).map;
303 expectedMap.setSourceContent('fileX', 'lineX1\nlineX2\n');
304 expectedMap.setSourceContent('fileB', 'lineB1\nlineB2\n');
305 expectedMap = expectedMap.toJSON();
306
307 // apply source map "mapStep1" to "mapStep2"
308 var generator = SourceMapGenerator.fromSourceMap(new SourceMapConsumer(mapStep2));
309 generator.applySourceMap(new SourceMapConsumer(mapStep1));
310 var actualMap = generator.toJSON();
311
312 util.assertEqualMaps(assert, actualMap, expectedMap);
313 };
314
315 exports['test applySourceMap throws when file is missing'] = function (assert, util) {
316 var map = new SourceMapGenerator({
317 file: 'test.js'
318 });
319 var map2 = new SourceMapGenerator();
320 assert.throws(function() {
321 map.applySourceMap(new SourceMapConsumer(map2.toJSON()));
322 });
323 };
324
325 exports['test the two additional parameters of applySourceMap'] = function (assert, util) {
326 // Assume the following directory structure:
327 //
328 // http://foo.org/
329 // bar.coffee
330 // app/
331 // coffee/
332 // foo.coffee
333 // temp/
334 // bundle.js
335 // temp_maps/
336 // bundle.js.map
337 // public/
338 // bundle.min.js
339 // bundle.min.js.map
340 //
341 // http://www.example.com/
342 // baz.coffee
343
344 var bundleMap = new SourceMapGenerator({
345 file: 'bundle.js'
346 });
347 bundleMap.addMapping({
348 generated: { line: 3, column: 3 },
349 original: { line: 2, column: 2 },
350 source: '../../coffee/foo.coffee'
351 });
352 bundleMap.setSourceContent('../../coffee/foo.coffee', 'foo coffee');
353 bundleMap.addMapping({
354 generated: { line: 13, column: 13 },
355 original: { line: 12, column: 12 },
356 source: '/bar.coffee'
357 });
358 bundleMap.setSourceContent('/bar.coffee', 'bar coffee');
359 bundleMap.addMapping({
360 generated: { line: 23, column: 23 },
361 original: { line: 22, column: 22 },
362 source: 'http://www.example.com/baz.coffee'
363 });
364 bundleMap.setSourceContent(
365 'http://www.example.com/baz.coffee',
366 'baz coffee'
367 );
368 bundleMap = new SourceMapConsumer(bundleMap.toJSON());
369
370 var minifiedMap = new SourceMapGenerator({
371 file: 'bundle.min.js',
372 sourceRoot: '..'
373 });
374 minifiedMap.addMapping({
375 generated: { line: 1, column: 1 },
376 original: { line: 3, column: 3 },
377 source: 'temp/bundle.js'
378 });
379 minifiedMap.addMapping({
380 generated: { line: 11, column: 11 },
381 original: { line: 13, column: 13 },
382 source: 'temp/bundle.js'
383 });
384 minifiedMap.addMapping({
385 generated: { line: 21, column: 21 },
386 original: { line: 23, column: 23 },
387 source: 'temp/bundle.js'
388 });
389 minifiedMap = new SourceMapConsumer(minifiedMap.toJSON());
390
391 var expectedMap = function (sources) {
392 var map = new SourceMapGenerator({
393 file: 'bundle.min.js',
394 sourceRoot: '..'
395 });
396 map.addMapping({
397 generated: { line: 1, column: 1 },
398 original: { line: 2, column: 2 },
399 source: sources[0]
400 });
401 map.setSourceContent(sources[0], 'foo coffee');
402 map.addMapping({
403 generated: { line: 11, column: 11 },
404 original: { line: 12, column: 12 },
405 source: sources[1]
406 });
407 map.setSourceContent(sources[1], 'bar coffee');
408 map.addMapping({
409 generated: { line: 21, column: 21 },
410 original: { line: 22, column: 22 },
411 source: sources[2]
412 });
413 map.setSourceContent(sources[2], 'baz coffee');
414 return map.toJSON();
415 }
416
417 var actualMap = function (aSourceMapPath) {
418 var map = SourceMapGenerator.fromSourceMap(minifiedMap);
419 // Note that relying on `bundleMap.file` (which is simply 'bundle.js')
420 // instead of supplying the second parameter wouldn't work here.
421 map.applySourceMap(bundleMap, '../temp/bundle.js', aSourceMapPath);
422 return map.toJSON();
423 }
424
425 util.assertEqualMaps(assert, actualMap('../temp/temp_maps'), expectedMap([
426 'coffee/foo.coffee',
427 '/bar.coffee',
428 'http://www.example.com/baz.coffee'
429 ]));
430
431 util.assertEqualMaps(assert, actualMap('/app/temp/temp_maps'), expectedMap([
432 '/app/coffee/foo.coffee',
433 '/bar.coffee',
434 'http://www.example.com/baz.coffee'
435 ]));
436
437 util.assertEqualMaps(assert, actualMap('http://foo.org/app/temp/temp_maps'), expectedMap([
438 'http://foo.org/app/coffee/foo.coffee',
439 'http://foo.org/bar.coffee',
440 'http://www.example.com/baz.coffee'
441 ]));
442
443 // If the third parameter is omitted or set to the current working
444 // directory we get incorrect source paths:
445
446 util.assertEqualMaps(assert, actualMap(), expectedMap([
447 '../coffee/foo.coffee',
448 '/bar.coffee',
449 'http://www.example.com/baz.coffee'
450 ]));
451
452 util.assertEqualMaps(assert, actualMap(''), expectedMap([
453 '../coffee/foo.coffee',
454 '/bar.coffee',
455 'http://www.example.com/baz.coffee'
456 ]));
457
458 util.assertEqualMaps(assert, actualMap('.'), expectedMap([
459 '../coffee/foo.coffee',
460 '/bar.coffee',
461 'http://www.example.com/baz.coffee'
462 ]));
463
464 util.assertEqualMaps(assert, actualMap('./'), expectedMap([
465 '../coffee/foo.coffee',
466 '/bar.coffee',
467 'http://www.example.com/baz.coffee'
468 ]));
469 };
470
471 exports['test applySourceMap name handling'] = function (assert, util) {
472 // Imagine some CoffeeScript code being compiled into JavaScript and then
473 // minified.
474
475 var assertName = function(coffeeName, jsName, expectedName) {
476 var minifiedMap = new SourceMapGenerator({
477 file: 'test.js.min'
478 });
479 minifiedMap.addMapping({
480 generated: { line: 1, column: 4 },
481 original: { line: 1, column: 4 },
482 source: 'test.js',
483 name: jsName
484 });
485
486 var coffeeMap = new SourceMapGenerator({
487 file: 'test.js'
488 });
489 coffeeMap.addMapping({
490 generated: { line: 1, column: 4 },
491 original: { line: 1, column: 0 },
492 source: 'test.coffee',
493 name: coffeeName
494 });
495
496 minifiedMap.applySourceMap(new SourceMapConsumer(coffeeMap.toJSON()));
497
498 new SourceMapConsumer(minifiedMap.toJSON()).eachMapping(function(mapping) {
499 assert.equal(mapping.name, expectedName);
500 });
501 };
502
503 // `foo = 1` -> `var foo = 1;` -> `var a=1`
504 // CoffeeScript doesn’t rename variables, so there’s no need for it to
505 // provide names in its source maps. Minifiers do rename variables and
506 // therefore do provide names in their source maps. So that name should be
507 // retained if the original map lacks names.
508 assertName(null, 'foo', 'foo');
509
510 // `foo = 1` -> `var coffee$foo = 1;` -> `var a=1`
511 // Imagine that CoffeeScript prefixed all variables with `coffee$`. Even
512 // though the minifier then also provides a name, the original name is
513 // what corresponds to the source.
514 assertName('foo', 'coffee$foo', 'foo');
515
516 // `foo = 1` -> `var coffee$foo = 1;` -> `var coffee$foo=1`
517 // Minifiers can turn off variable mangling. Then there’s no need to
518 // provide names in the source map, but the names from the original map are
519 // still needed.
520 assertName('foo', null, 'foo');
521
522 // `foo = 1` -> `var foo = 1;` -> `var foo=1`
523 // No renaming at all.
524 assertName(null, null, null);
525 };
526
527 exports['test sorting with duplicate generated mappings'] = function (assert, util) {
528 var map = new SourceMapGenerator({
529 file: 'test.js'
530 });
531 map.addMapping({
532 generated: { line: 3, column: 0 },
533 original: { line: 2, column: 0 },
534 source: 'a.js'
535 });
536 map.addMapping({
537 generated: { line: 2, column: 0 }
538 });
539 map.addMapping({
540 generated: { line: 2, column: 0 }
541 });
542 map.addMapping({
543 generated: { line: 1, column: 0 },
544 original: { line: 1, column: 0 },
545 source: 'a.js'
546 });
547
548 util.assertEqualMaps(assert, map.toJSON(), {
549 version: 3,
550 file: 'test.js',
551 sources: ['a.js'],
552 names: [],
553 mappings: 'AAAA;A;AACA'
554 });
555 };
556
557 exports['test ignore duplicate mappings.'] = function (assert, util) {
558 var init = { file: 'min.js', sourceRoot: '/the/root' };
559 var map1, map2;
560
561 // null original source location
562 var nullMapping1 = {
563 generated: { line: 1, column: 0 }
564 };
565 var nullMapping2 = {
566 generated: { line: 2, column: 2 }
567 };
568
569 map1 = new SourceMapGenerator(init);
570 map2 = new SourceMapGenerator(init);
571
572 map1.addMapping(nullMapping1);
573 map1.addMapping(nullMapping1);
574
575 map2.addMapping(nullMapping1);
576
577 util.assertEqualMaps(assert, map1.toJSON(), map2.toJSON());
578
579 map1.addMapping(nullMapping2);
580 map1.addMapping(nullMapping1);
581
582 map2.addMapping(nullMapping2);
583
584 util.assertEqualMaps(assert, map1.toJSON(), map2.toJSON());
585
586 // original source location
587 var srcMapping1 = {
588 generated: { line: 1, column: 0 },
589 original: { line: 11, column: 0 },
590 source: 'srcMapping1.js'
591 };
592 var srcMapping2 = {
593 generated: { line: 2, column: 2 },
594 original: { line: 11, column: 0 },
595 source: 'srcMapping2.js'
596 };
597
598 map1 = new SourceMapGenerator(init);
599 map2 = new SourceMapGenerator(init);
600
601 map1.addMapping(srcMapping1);
602 map1.addMapping(srcMapping1);
603
604 map2.addMapping(srcMapping1);
605
606 util.assertEqualMaps(assert, map1.toJSON(), map2.toJSON());
607
608 map1.addMapping(srcMapping2);
609 map1.addMapping(srcMapping1);
610
611 map2.addMapping(srcMapping2);
612
613 util.assertEqualMaps(assert, map1.toJSON(), map2.toJSON());
614
615 // full original source and name information
616 var fullMapping1 = {
617 generated: { line: 1, column: 0 },
618 original: { line: 11, column: 0 },
619 source: 'fullMapping1.js',
620 name: 'fullMapping1'
621 };
622 var fullMapping2 = {
623 generated: { line: 2, column: 2 },
624 original: { line: 11, column: 0 },
625 source: 'fullMapping2.js',
626 name: 'fullMapping2'
627 };
628
629 map1 = new SourceMapGenerator(init);
630 map2 = new SourceMapGenerator(init);
631
632 map1.addMapping(fullMapping1);
633 map1.addMapping(fullMapping1);
634
635 map2.addMapping(fullMapping1);
636
637 util.assertEqualMaps(assert, map1.toJSON(), map2.toJSON());
638
639 map1.addMapping(fullMapping2);
640 map1.addMapping(fullMapping1);
641
642 map2.addMapping(fullMapping2);
643
644 util.assertEqualMaps(assert, map1.toJSON(), map2.toJSON());
645 };
646
647 exports['test github issue #72, check for duplicate names or sources'] = function (assert, util) {
648 var map = new SourceMapGenerator({
649 file: 'test.js'
650 });
651 map.addMapping({
652 generated: { line: 1, column: 1 },
653 original: { line: 2, column: 2 },
654 source: 'a.js',
655 name: 'foo'
656 });
657 map.addMapping({
658 generated: { line: 3, column: 3 },
659 original: { line: 4, column: 4 },
660 source: 'a.js',
661 name: 'foo'
662 });
663 util.assertEqualMaps(assert, map.toJSON(), {
664 version: 3,
665 file: 'test.js',
666 sources: ['a.js'],
667 names: ['foo'],
668 mappings: 'CACEA;;GAEEA'
669 });
670 };
671
672 exports['test setting sourcesContent to null when already null'] = function (assert, util) {
673 var smg = new SourceMapGenerator({ file: "foo.js" });
674 assert.doesNotThrow(function() {
675 smg.setSourceContent("bar.js", null);
676 });
677 };
678
679 });