license import * as chai from 'chai' ; import * as dom5 from 'dom5' ; import * as path from 'path' ; import { Analyzer , FsUrlLoader , FsUrlResolver , PackageRelativeUrl , ResolvedUrl } from 'polymer-analyzer' ; import { MappingItem , RawSourceMap , SourceMapConsumer } from 'source-map' ; import { Bundler } from '../bundler' ; import { Options as BundlerOptions } from '../bundler' ; import { BundledHtmlDocument } from '../document-collection' ; import * as matchers from '../matchers' ; import { getExistingSourcemap } from '../source-map' ; import { resolvePath } from '../url-utils' ; chai . config . showDiff = true ; const assert = chai . assert ; suite ( 'Bundler' , ( ) => { let bundler ; async function bundle ( inputPath , opts ? ) { const bundlerOpts = Object . assign ( { } , opts || { } ) ; if ( ! bundlerOpts . analyzer ) { bundlerOpts . analyzer = new Analyzer ( { urlLoader : new FsUrlLoader ( path . dirname ( inputPath ) ) } ) ; inputPath = path . basename ( inputPath ) ; } bundler = new Bundler ( bundlerOpts ) ; const manifest = await bundler . generateManifest ( [ bundler . analyzer . resolveUrl ( inputPath as PackageRelativeUrl ) ! ] ) ; const { documents } = await bundler . bundle ( manifest ) ; return documents . get ( bundler . analyzer . resolveUrl ( inputPath ) ! ) ! as BundledHtmlDocument ; } function getLine ( original , lineNum ) { const lines = original . split ( '\n' ) ; return lines [ lineNum - 1 ] ; } async function testMapping ( sourcemap , html , name ) { const consumer = new SourceMapConsumer ( sourcemap ! ) ; let foundMapping = false ; const mappings = [ ] ; consumer . eachMapping ( ( mapping ) => mappings . push ( mapping ) ) ; for ( let j = 0 ; j < mappings . length ; j ++ ) { if ( mappings [ j ] . name === name ) { foundMapping = true ; const generatedLine = getLine ( html , mappings [ j ] . generatedLine ) ; assert ( generatedLine , 'generated line not found' ) ; assert . equal ( mappings [ j ] . generatedColumn , generatedLine ! . indexOf ( name ) , 'generated column' ) ; const originalContents = await urlLoader . load ( mappings [ j ] . source as ResolvedUrl ) ; const originalLine = getLine ( originalContents , mappings [ j ] . originalLine ) ; assert ( originalLine , 'original line not found' ) ; assert . equal ( mappings [ j ] . originalColumn , originalLine ! . indexOf ( name ) , 'original column' ) ; } } } const basePath = resolvePath ( 'test/html/sourcemaps/' ) ; const urlLoader = new FsUrlLoader ( basePath ) ; const analyzer = new Analyzer ( { urlResolver : new FsUrlResolver ( basePath ) , urlLoader : urlLoader } ) ; suite ( 'Sourcemaps' , ( ) => { test ( 'inline maps are compiled correctly' , async ( ) => { const { ast : doc , content : compiledHtml } = await bundle ( 'inline.html' , { inlineScripts : true , sourcemaps : true , analyzer : analyzer } ) ; assert ( doc ) ; const inlineScripts = dom5 . queryAll ( doc , matchers . inlineNonModuleScript ) ; assert . equal ( inlineScripts . length , 3 ) ; for ( let i = 0 ; i < inlineScripts . length ; i ++ ) { if ( i === 5 ) { continue ; } const sourcemap = await getExistingSourcemap ( analyzer , 'inline.html' , dom5 . getTextContent ( inlineScripts [ i ] ) ) ; assert ( sourcemap , 'scripts found' ) ; await testMapping ( sourcemap ! , compiledHtml , 'console' ) ; } } ) ; test ( 'external map files are compiled correctly' , async ( ) => { const { ast : doc , content : compiledHtml } = await bundle ( 'external.html' , { inlineScripts : true , sourcemaps : true , analyzer : analyzer } ) ; assert ( doc ) ; const inlineScripts = dom5 . queryAll ( doc , matchers . inlineNonModuleScript ) ; assert . equal ( inlineScripts . length , 3 ) ; for ( let i = 0 ; i < inlineScripts . length ; i ++ ) { const sourcemap = await getExistingSourcemap ( analyzer , 'external.html' , dom5 . getTextContent ( inlineScripts [ i ] ) ) ; assert ( sourcemap , 'scripts found' ) ; await testMapping ( sourcemap ! , compiledHtml , 'console' ) ; } } ) ; test ( 'mix of inline and external maps are compiled correctly' , async ( ) => { const { ast : doc , content : compiledHtml } = await bundle ( 'combined.html' , { inlineScripts : true , sourcemaps : true , analyzer : analyzer } ) ; assert ( doc ) ; const inlineScripts = dom5 . queryAll ( doc , matchers . inlineNonModuleScript ) ; assert . equal ( inlineScripts . length , 7 ) ; for ( let i = 0 ; i < inlineScripts . length ; i ++ ) { const sourcemap = await getExistingSourcemap ( analyzer , 'combined.html' , dom5 . getTextContent ( inlineScripts [ i ] ) ) ; assert ( sourcemap , 'scripts found' ) ; await testMapping ( sourcemap ! , compiledHtml , 'console' ) ; } } ) ; test ( 'invalid maps are compiled correctly' , async ( ) => { const { ast : doc , content : compiledHtml } = await bundle ( 'invalid.html' , { inlineScripts : true , sourcemaps : true , analyzer : analyzer } ) ; assert ( doc ) ; const inlineScripts = dom5 . queryAll ( doc , matchers . inlineNonModuleScript ) ; assert . equal ( inlineScripts . length , 2 ) ; for ( let i = 0 ; i < inlineScripts . length ; i ++ ) { const sourcemap = await getExistingSourcemap ( analyzer , 'invalid.html' , dom5 . getTextContent ( inlineScripts [ i ] ) ) ; assert ( sourcemap , 'scripts found' ) ; await testMapping ( sourcemap ! , compiledHtml , 'console' ) ; } } ) ; } ) ; } ) ;