https://github.com/angular/angular
Raw File
Tip revision: 5e9eb7abbd09740deecd3e814a7e01f53ba912d8 authored by Andrew Kushnir on 15 September 2021, 17:37:18 UTC
release: cut the v13.0.0-next.6 release (#43464)
Tip revision: 5e9eb7a
source_map_spec.ts
/**
 * @license
 * Copyright Google LLC All Rights Reserved.
 *
 * Use of this source code is governed by an MIT-style license that can be
 * found in the LICENSE file at https://angular.io/license
 */

import {SourceMapGenerator, toBase64String} from '@angular/compiler/src/output/source_map';

{
  describe('source map generation', () => {
    describe('generation', () => {
      it('should generate a valid source map', () => {
        const map = new SourceMapGenerator('out.js')
                        .addSource('a.js', null)
                        .addLine()
                        .addMapping(0, 'a.js', 0, 0)
                        .addMapping(4, 'a.js', 0, 6)
                        .addMapping(5, 'a.js', 0, 7)
                        .addMapping(8, 'a.js', 0, 22)
                        .addMapping(9, 'a.js', 0, 23)
                        .addMapping(10, 'a.js', 0, 24)
                        .addLine()
                        .addMapping(0, 'a.js', 1, 0)
                        .addMapping(4, 'a.js', 1, 6)
                        .addMapping(5, 'a.js', 1, 7)
                        .addMapping(8, 'a.js', 1, 10)
                        .addMapping(9, 'a.js', 1, 11)
                        .addMapping(10, 'a.js', 1, 12)
                        .addLine()
                        .addMapping(0, 'a.js', 3, 0)
                        .addMapping(2, 'a.js', 3, 2)
                        .addMapping(3, 'a.js', 3, 3)
                        .addMapping(10, 'a.js', 3, 10)
                        .addMapping(11, 'a.js', 3, 11)
                        .addMapping(21, 'a.js', 3, 11)
                        .addMapping(22, 'a.js', 3, 12)
                        .addLine()
                        .addMapping(4, 'a.js', 4, 4)
                        .addMapping(11, 'a.js', 4, 11)
                        .addMapping(12, 'a.js', 4, 12)
                        .addMapping(15, 'a.js', 4, 15)
                        .addMapping(16, 'a.js', 4, 16)
                        .addMapping(21, 'a.js', 4, 21)
                        .addMapping(22, 'a.js', 4, 22)
                        .addMapping(23, 'a.js', 4, 23)
                        .addLine()
                        .addMapping(0, 'a.js', 5, 0)
                        .addMapping(1, 'a.js', 5, 1)
                        .addMapping(2, 'a.js', 5, 2)
                        .addMapping(3, 'a.js', 5, 2);

        // Generated with https://sokra.github.io/source-map-visualization using a TS source map
        expect(map.toJSON()!.mappings)
            .toEqual(
                'AAAA,IAAM,CAAC,GAAe,CAAC,CAAC;AACxB,IAAM,CAAC,GAAG,CAAC,CAAC;AAEZ,EAAE,CAAC,OAAO,CAAC,UAAA,CAAC;IACR,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;AACvB,CAAC,CAAC,CAAA');
      });

      it('should include the files and their contents', () => {
        const map = new SourceMapGenerator('out.js')
                        .addSource('inline.ts', 'inline')
                        .addSource('inline.ts', 'inline')  // make sur the sources are dedup
                        .addSource('url.ts', null)
                        .addLine()
                        .addMapping(0, 'inline.ts', 0, 0)
                        .toJSON()!;

        expect(map.file).toEqual('out.js');
        expect(map.sources).toEqual(['inline.ts', 'url.ts']);
        expect(map.sourcesContent).toEqual(['inline', null]);
      });

      it('should not generate source maps when there is no mapping', () => {
        const smg = new SourceMapGenerator('out.js').addSource('inline.ts', 'inline').addLine();

        expect(smg.toJSON()).toEqual(null);
        expect(smg.toJsComment()).toEqual('');
      });
    });

    describe('encodeB64String', () => {
      it('should return the b64 encoded value', () => {
        [['', ''],
         ['a', 'YQ=='],
         ['Foo', 'Rm9v'],
         ['Foo1', 'Rm9vMQ=='],
         ['Foo12', 'Rm9vMTI='],
         ['Foo123', 'Rm9vMTIz'],
        ].forEach(([src, b64]) => expect(toBase64String(src)).toEqual(b64));
      });
    });

    describe('errors', () => {
      it('should throw when mappings are added out of order', () => {
        expect(() => {
          new SourceMapGenerator('out.js')
              .addSource('in.js')
              .addLine()
              .addMapping(10, 'in.js', 0, 0)
              .addMapping(0, 'in.js', 0, 0);
        }).toThrowError('Mapping should be added in output order');
      });

      it('should throw when adding segments before any line is created', () => {
        expect(() => {
          new SourceMapGenerator('out.js').addSource('in.js').addMapping(0, 'in.js', 0, 0);
        }).toThrowError('A line must be added before mappings can be added');
      });

      it('should throw when adding segments referencing unknown sources', () => {
        expect(() => {
          new SourceMapGenerator('out.js').addSource('in.js').addLine().addMapping(
              0, 'in_.js', 0, 0);
        }).toThrowError('Unknown source file "in_.js"');
      });

      it('should throw when adding segments without column', () => {
        expect(() => {
          new SourceMapGenerator('out.js').addSource('in.js').addLine().addMapping(null!);
        }).toThrowError('The column in the generated code must be provided');
      });

      it('should throw when adding segments with a source url but no position', () => {
        expect(() => {
          new SourceMapGenerator('out.js').addSource('in.js').addLine().addMapping(0, 'in.js');
        }).toThrowError('The source location must be provided when a source url is provided');
        expect(() => {
          new SourceMapGenerator('out.js').addSource('in.js').addLine().addMapping(0, 'in.js', 0);
        }).toThrowError('The source location must be provided when a source url is provided');
      });
    });
  });
}
back to top