inline-source-map.js 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342
  1. 'use strict';
  2. /*jshint asi: true*/
  3. var test = require('tap').test
  4. var generator = require('..');
  5. var foo = '' + function foo () {
  6. var hello = 'hello';
  7. var world = 'world';
  8. console.log('%s %s', hello, world);
  9. }
  10. var bar = '' + function bar () {
  11. console.log('yes?');
  12. }
  13. function decode(base64) {
  14. return new Buffer(base64, 'base64').toString();
  15. }
  16. function inspect(obj, depth) {
  17. console.error(require('util').inspect(obj, false, depth || 5, true));
  18. }
  19. test('generated mappings', function (t) {
  20. t.test('one file no offset', function (t) {
  21. var gen = generator()
  22. .addGeneratedMappings('foo.js', foo)
  23. t.deepEqual(
  24. gen._mappings()
  25. , [ { generatedLine: 1,
  26. generatedColumn: 0,
  27. originalLine: 1,
  28. originalColumn: 0,
  29. source: 'foo.js',
  30. name: null },
  31. { generatedLine: 2,
  32. generatedColumn: 0,
  33. originalLine: 2,
  34. originalColumn: 0,
  35. source: 'foo.js',
  36. name: null },
  37. { generatedLine: 3,
  38. generatedColumn: 0,
  39. originalLine: 3,
  40. originalColumn: 0,
  41. source: 'foo.js',
  42. name: null },
  43. { generatedLine: 4,
  44. generatedColumn: 0,
  45. originalLine: 4,
  46. originalColumn: 0,
  47. source: 'foo.js',
  48. name: null },
  49. { generatedLine: 5,
  50. generatedColumn: 0,
  51. originalLine: 5,
  52. originalColumn: 0,
  53. source: 'foo.js',
  54. name: null } ]
  55. , 'generates correct mappings'
  56. )
  57. t.deepEqual(
  58. JSON.parse(decode(gen.base64Encode()))
  59. , {"version":3,"file":"","sources":["foo.js"],"names":[],"mappings":"AAAA;AACA;AACA;AACA;AACA","sourceRoot":""}
  60. , 'encodes generated mappings'
  61. )
  62. t.equal(
  63. gen.inlineMappingUrl()
  64. , '//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImZvby5qcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwiZmlsZSI6IiIsInNvdXJjZVJvb3QiOiIifQ=='
  65. , 'returns correct inline mapping url'
  66. )
  67. t.end()
  68. })
  69. t.test('two files no offset', function (t) {
  70. var gen = generator()
  71. .addGeneratedMappings('foo.js', foo)
  72. .addGeneratedMappings('bar.js', bar)
  73. t.deepEqual(
  74. gen._mappings()
  75. , [ { generatedLine: 1,
  76. generatedColumn: 0,
  77. originalLine: 1,
  78. originalColumn: 0,
  79. source: 'foo.js',
  80. name: null },
  81. { generatedLine: 2,
  82. generatedColumn: 0,
  83. originalLine: 2,
  84. originalColumn: 0,
  85. source: 'foo.js',
  86. name: null },
  87. { generatedLine: 3,
  88. generatedColumn: 0,
  89. originalLine: 3,
  90. originalColumn: 0,
  91. source: 'foo.js',
  92. name: null },
  93. { generatedLine: 4,
  94. generatedColumn: 0,
  95. originalLine: 4,
  96. originalColumn: 0,
  97. source: 'foo.js',
  98. name: null },
  99. { generatedLine: 5,
  100. generatedColumn: 0,
  101. originalLine: 5,
  102. originalColumn: 0,
  103. source: 'foo.js',
  104. name: null },
  105. { generatedLine: 1,
  106. generatedColumn: 0,
  107. originalLine: 1,
  108. originalColumn: 0,
  109. source: 'bar.js',
  110. name: null },
  111. { generatedLine: 2,
  112. generatedColumn: 0,
  113. originalLine: 2,
  114. originalColumn: 0,
  115. source: 'bar.js',
  116. name: null },
  117. { generatedLine: 3,
  118. generatedColumn: 0,
  119. originalLine: 3,
  120. originalColumn: 0,
  121. source: 'bar.js',
  122. name: null } ]
  123. , 'generates correct mappings'
  124. )
  125. t.deepEqual(
  126. JSON.parse(decode(gen.base64Encode()))
  127. , {"version":3,"file":"","sources":["foo.js","bar.js"],"names":[],"mappings":"ACAA,ADAA;ACCA,ADAA;ACCA,ADAA;AACA;AACA","sourceRoot": ""}
  128. , 'encodes generated mappings'
  129. )
  130. t.equal(
  131. gen.inlineMappingUrl()
  132. , '//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImZvby5qcyIsImJhci5qcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUNBQSxBREFBO0FDQ0EsQURBQTtBQ0NBLEFEQUE7QUFDQTtBQUNBIiwiZmlsZSI6IiIsInNvdXJjZVJvb3QiOiIifQ=='
  133. , 'returns correct inline mapping url'
  134. )
  135. t.end()
  136. })
  137. t.test('one line source', function (t) {
  138. var gen = generator().addGeneratedMappings('one-liner.js', 'console.log("line one");')
  139. t.deepEqual(
  140. gen._mappings()
  141. , [ { generatedLine: 1,
  142. generatedColumn: 0,
  143. originalLine: 1,
  144. originalColumn: 0,
  145. source: 'one-liner.js',
  146. name: null } ]
  147. , 'generates correct mappings'
  148. )
  149. t.end()
  150. })
  151. t.test('with offset', function (t) {
  152. var gen = generator()
  153. .addGeneratedMappings('foo.js', foo, { line: 20 })
  154. .addGeneratedMappings('bar.js', bar, { line: 23, column: 22 })
  155. t.deepEqual(
  156. gen._mappings()
  157. , [ { generatedLine: 21,
  158. generatedColumn: 0,
  159. originalLine: 1,
  160. originalColumn: 0,
  161. source: 'foo.js',
  162. name: null },
  163. { generatedLine: 22,
  164. generatedColumn: 0,
  165. originalLine: 2,
  166. originalColumn: 0,
  167. source: 'foo.js',
  168. name: null },
  169. { generatedLine: 23,
  170. generatedColumn: 0,
  171. originalLine: 3,
  172. originalColumn: 0,
  173. source: 'foo.js',
  174. name: null },
  175. { generatedLine: 24,
  176. generatedColumn: 0,
  177. originalLine: 4,
  178. originalColumn: 0,
  179. source: 'foo.js',
  180. name: null },
  181. { generatedLine: 25,
  182. generatedColumn: 0,
  183. originalLine: 5,
  184. originalColumn: 0,
  185. source: 'foo.js',
  186. name: null },
  187. { generatedLine: 24,
  188. generatedColumn: 22,
  189. originalLine: 1,
  190. originalColumn: 0,
  191. source: 'bar.js',
  192. name: null },
  193. { generatedLine: 25,
  194. generatedColumn: 22,
  195. originalLine: 2,
  196. originalColumn: 0,
  197. source: 'bar.js',
  198. name: null },
  199. { generatedLine: 26,
  200. generatedColumn: 22,
  201. originalLine: 3,
  202. originalColumn: 0,
  203. source: 'bar.js',
  204. name: null } ]
  205. , 'generates correct mappings'
  206. )
  207. t.deepEqual(
  208. JSON.parse(decode(gen.base64Encode()))
  209. , {"version":3,"file":"","sources":["foo.js","bar.js"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AACA;AACA;AACA,sBCHA;ADIA,sBCHA;sBACA", "sourceRoot": ""}
  210. , 'encodes generated mappings with offset'
  211. )
  212. t.end()
  213. })
  214. })
  215. test('given mappings, with one having no original', function (t) {
  216. t.test('no offset', function (t) {
  217. var gen = generator()
  218. .addMappings('foo.js', [{ original: { line: 2, column: 3 } , generated: { line: 5, column: 10 } }])
  219. // This addresses an edgecase in which a transpiler generates mappings but doesn't include the original position.
  220. // If we set source to sourceFile (as usual) in that case, the mappings are considered invalid by the source-map module's
  221. // SourceMapGenerator. Keeping source undefined fixes this problem.
  222. // Raised issue: https://github.com/thlorenz/inline-source-map/issues/2
  223. // Validate function: https://github.com/mozilla/source-map/blob/a3372ea78e662582087dd25ebda999c06424e047/lib/source-map/source-map-generator.js#L232
  224. .addMappings('bar.js', [
  225. { original: { line: 6, column: 0 } , generated: { line: 7, column: 20 } }
  226. , { generated: { line: 8, column: 30 } }
  227. ])
  228. t.deepEqual(
  229. gen._mappings()
  230. , [ { generatedLine: 5,
  231. generatedColumn: 10,
  232. originalLine: 2,
  233. originalColumn: 3,
  234. source: 'foo.js',
  235. name: null },
  236. { generatedLine: 7,
  237. generatedColumn: 20,
  238. originalLine: 6,
  239. originalColumn: 0,
  240. source: 'bar.js',
  241. name: null },
  242. { generatedLine: 8,
  243. generatedColumn: 30,
  244. originalLine: false,
  245. originalColumn: false,
  246. source: undefined,
  247. name: null } ]
  248. , 'adds correct mappings'
  249. )
  250. t.deepEqual(
  251. JSON.parse(decode(gen.base64Encode()))
  252. , {"version":3,"file":"","sources":["foo.js","bar.js"],"names":[],"mappings":";;;;UACG;;oBCIH;8B", sourceRoot: ""}
  253. , 'encodes generated mappings'
  254. )
  255. t.equal(
  256. gen.inlineMappingUrl()
  257. , '//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImZvby5qcyIsImJhci5qcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7O1VBQ0c7O29CQ0lIOzhCIiwiZmlsZSI6IiIsInNvdXJjZVJvb3QiOiIifQ=='
  258. , 'returns correct inline mapping url'
  259. )
  260. t.end()
  261. })
  262. t.test('with offset', function (t) {
  263. var gen = generator()
  264. .addMappings('foo.js', [{ original: { line: 2, column: 3 } , generated: { line: 5, column: 10 } }], { line: 5 })
  265. .addMappings('bar.js', [{ original: { line: 6, column: 0 } , generated: { line: 7, column: 20 } }, { generated: { line: 8, column: 30 } }], { line: 9, column: 3 })
  266. t.deepEqual(
  267. gen._mappings()
  268. , [ { generatedLine: 10,
  269. generatedColumn: 10,
  270. originalLine: 2,
  271. originalColumn: 3,
  272. source: 'foo.js',
  273. name: null },
  274. { generatedLine: 16,
  275. generatedColumn: 23,
  276. originalLine: 6,
  277. originalColumn: 0,
  278. source: 'bar.js',
  279. name: null },
  280. { generatedLine: 17,
  281. generatedColumn: 33,
  282. originalLine: false,
  283. originalColumn: false,
  284. source: undefined,
  285. name: null } ]
  286. , 'adds correct mappings'
  287. )
  288. t.deepEqual(
  289. JSON.parse(decode(gen.base64Encode()))
  290. , {"version":3,"file":"","sources":["foo.js","bar.js"],"names":[],"mappings":";;;;;;;;;UACG;;;;;;uBCIH;iC", sourceRoot: ""}
  291. , 'encodes mappings with offset'
  292. )
  293. t.end()
  294. })
  295. });
  296. test('inline mapping url with charset opt', function(t){
  297. t.test('set inline mapping url charset to gbk', function(t){
  298. var gen = generator({charset: 'gbk'})
  299. .addGeneratedMappings('foo.js', foo);
  300. t.equal(
  301. gen.inlineMappingUrl(),
  302. '//# sourceMappingURL=data:application/json;charset=gbk;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImZvby5qcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwiZmlsZSI6IiIsInNvdXJjZVJvb3QiOiIifQ==',
  303. 'charset set to gbk'
  304. );
  305. t.end();
  306. });
  307. t.test('default charset should be utf-8', function(t){
  308. var gen = generator()
  309. .addGeneratedMappings('foo.js', foo);
  310. t.equal(
  311. gen.inlineMappingUrl(),
  312. '//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImZvby5qcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwiZmlsZSI6IiIsInNvdXJjZVJvb3QiOiIifQ==',
  313. 'charset default to utf-8'
  314. );
  315. t.end();
  316. });
  317. });