https://github.com/angular/angular
Raw File
Tip revision: 61e69c87e6b577f1c5a71fb5c39c3bd6125c4b91 authored by Dylan Hunn on 21 November 2022, 20:43:37 UTC
release: cut the v14.2.12 release
Tip revision: 61e69c8
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