source-maps.js 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221
  1. var test = require('tap').test;
  2. var pack = require('../');
  3. var path = require('path');
  4. function decode(base64) {
  5. return new Buffer(base64, 'base64').toString();
  6. }
  7. function unmountPrelude(sources) {
  8. return sources.map(function (x) {
  9. var basename = path.basename(x);
  10. return basename === '_prelude.js' ? basename : x;
  11. });
  12. }
  13. function grabSourceMap(lastLine) {
  14. var base64 = lastLine.split(',').pop();
  15. var sm = JSON.parse(decode(base64));
  16. sm.sources = unmountPrelude(sm.sources);
  17. return sm;
  18. }
  19. function grabLastLine(src) {
  20. return src.split('\n').slice(-2)[0];
  21. }
  22. test('pack one file with source file field and one without', function (t) {
  23. t.plan(7);
  24. var p = pack();
  25. var src = '';
  26. p.on('data', function (buf) { src += buf });
  27. p.on('end', function () {
  28. var r = Function(['T'], 'return ' + src)(t);
  29. t.equal(r('xyz')(5), 555);
  30. t.equal(r('xyz')(5), 555);
  31. var lastLine = grabLastLine(src);
  32. var sm = grabSourceMap(lastLine);
  33. t.ok(/^\/\/# sourceMappingURL/.test(lastLine), 'contains source mapping url as last line');
  34. t.deepEqual(sm.sources, [ '_prelude.js', 'foo.js' ], 'includes mappings for sourceFile and prelude only');
  35. t.equal(sm.mappings, 'AAAA;;;ACAA;AACA;AACA;AACA', 'adds offset mapping for each line' );
  36. });
  37. p.end(JSON.stringify([
  38. {
  39. id: 'abc',
  40. source: 'T.equal(require("./xyz")(3), 333)',
  41. entry: true,
  42. deps: { './xyz': 'xyz' }
  43. },
  44. {
  45. id: 'xyz',
  46. source: 'T.ok(true);\nmodule.exports=function(n){\n return n*111 \n}',
  47. sourceFile: 'foo.js'
  48. }
  49. ]));
  50. });
  51. test('pack two files with source file field', function (t) {
  52. t.plan(7);
  53. var p = pack();
  54. var src = '';
  55. p.on('data', function (buf) { src += buf });
  56. p.on('end', function () {
  57. var r = Function(['T'], 'return ' + src)(t);
  58. t.equal(r('xyz')(5), 555);
  59. t.equal(r('xyz')(5), 555);
  60. var lastLine = grabLastLine(src);
  61. var sm = grabSourceMap(lastLine);
  62. t.ok(/^\/\/# sourceMappingURL/.test(lastLine), 'contains source mapping url as last line');
  63. t.deepEqual(sm.sources, [ '_prelude.js', 'wunder/bar.js', 'foo.js' ], 'includes mappings for both files and prelude');
  64. t.equal(sm.mappings, 'AAAA;ACAA;;ACAA;AACA;AACA;AACA', 'adds offset mapping for each line' );
  65. });
  66. p.end(JSON.stringify([
  67. {
  68. id: 'abc',
  69. source: 'T.equal(require("./xyz")(3), 333)',
  70. entry: true,
  71. deps: { './xyz': 'xyz' },
  72. sourceFile: 'wunder/bar.js'
  73. },
  74. {
  75. id: 'xyz',
  76. source: 'T.ok(true);\nmodule.exports=function(n){\n return n*111 \n}',
  77. sourceFile: 'foo.js'
  78. }
  79. ]));
  80. });
  81. test('pack two files without source file field', function (t) {
  82. t.plan(5);
  83. var p = pack();
  84. var src = '';
  85. p.on('data', function (buf) { src += buf });
  86. p.on('end', function () {
  87. var r = Function(['T'], 'return ' + src)(t);
  88. t.equal(r('xyz')(5), 555);
  89. t.equal(r('xyz')(5), 555);
  90. var lastLine = grabLastLine(src);
  91. t.notOk(/^\/\/# sourceMappingURL/.test(lastLine), 'contains no source mapping url');
  92. });
  93. p.end(JSON.stringify([
  94. {
  95. id: 'abc',
  96. source: 'T.equal(require("./xyz")(3), 333)',
  97. entry: true,
  98. deps: { './xyz': 'xyz' }
  99. },
  100. {
  101. id: 'xyz',
  102. source: 'T.ok(true);\nmodule.exports=function(n){\n return n*111 \n}'
  103. }
  104. ]));
  105. });
  106. test('pack two files with source file field, one with nomap flag', function (t) {
  107. t.plan(7);
  108. var p = pack();
  109. var src = '';
  110. p.on('data', function (buf) { src += buf });
  111. p.on('end', function () {
  112. var r = Function(['T'], 'return ' + src)(t);
  113. t.equal(r('xyz')(5), 555);
  114. t.equal(r('xyz')(5), 555);
  115. var lastLine = grabLastLine(src);
  116. var sm = grabSourceMap(lastLine);
  117. t.ok(/^\/\/# sourceMappingURL/.test(lastLine), 'contains source mapping url as last line');
  118. t.deepEqual(sm.sources, [ '_prelude.js', 'wunder/bar.js' ], 'includes mappings for only the file without the "nomap" flag and prelude');
  119. t.equal(sm.mappings, 'AAAA;ACAA', 'adds offset mapping for each line of mapped file' );
  120. t.end()
  121. });
  122. p.end(JSON.stringify([
  123. {
  124. id: 'abc',
  125. source: 'T.equal(require("./xyz")(3), 333)',
  126. entry: true,
  127. deps: { './xyz': 'xyz' },
  128. sourceFile: 'wunder/bar.js'
  129. },
  130. {
  131. id: 'xyz',
  132. source: 'T.ok(true);\nmodule.exports=function(n){\n return n*111 \n}',
  133. sourceFile: 'foo.js',
  134. nomap: true
  135. }
  136. ]));
  137. });
  138. test('custom sourceMapPrefix for //@', function (t) {
  139. t.plan(7);
  140. var p = pack({ sourceMapPrefix: '//@' });
  141. var src = '';
  142. p.on('data', function (buf) { src += buf });
  143. p.on('end', function () {
  144. var r = Function(['T'], 'return ' + src)(t);
  145. t.equal(r('xyz')(5), 555);
  146. t.equal(r('xyz')(5), 555);
  147. var lastLine = grabLastLine(src);
  148. var sm = grabSourceMap(lastLine);
  149. t.ok(/^\/\/@ sourceMappingURL/.test(lastLine), 'contains source mapping url as last line');
  150. t.deepEqual(sm.sources, [ '_prelude.js', 'foo.js' ], 'includes mappings for sourceFile and prelude only');
  151. t.equal(sm.mappings, 'AAAA;;;ACAA;AACA;AACA;AACA', 'adds offset mapping for each line' );
  152. });
  153. p.end(JSON.stringify([
  154. {
  155. id: 'abc',
  156. source: 'T.equal(require("./xyz")(3), 333)',
  157. entry: true,
  158. deps: { './xyz': 'xyz' }
  159. },
  160. {
  161. id: 'xyz',
  162. source: 'T.ok(true);\nmodule.exports=function(n){\n return n*111 \n}',
  163. sourceFile: 'foo.js'
  164. }
  165. ]));
  166. });
  167. test('custom sourceRoot', function (t) {
  168. t.plan(1);
  169. var p = pack({ sourceRoot: '/custom-root' });
  170. var src = '';
  171. p.on('data', function (buf) { src += buf });
  172. p.on('end', function () {
  173. var lastLine = grabLastLine(src);
  174. var sm = grabSourceMap(lastLine);
  175. t.equal(sm.sourceRoot, '/custom-root', 'sets a custom source root' );
  176. });
  177. p.end(JSON.stringify([
  178. {
  179. id: 'abc',
  180. source: 'T.equal(require("./xyz")(3), 333)',
  181. entry: true,
  182. deps: { './xyz': 'xyz' }
  183. },
  184. {
  185. id: 'xyz',
  186. source: 'T.ok(true);\nmodule.exports=function(n){\n return n*111 \n}',
  187. sourceFile: 'foo.js'
  188. }
  189. ]));
  190. });