license import * as chai from 'chai' ; import * as dom5 from 'dom5' ; import * as parse5 from 'parse5' ; import { Analyzer , FsUrlLoader , FsUrlResolver , PackageRelativeUrl } from 'polymer-analyzer' ; import { generateSharedDepsMergeStrategy , generateShellMergeStrategy } from '../bundle-manifest' ; import { Bundler , BundleResult } from '../bundler' ; import { Options as BundlerOptions } from '../bundler' ; chai . config . showDiff = true ; const assert = chai . assert ; const preds = dom5 . predicates ; const domModulePredicate = ( id ) => { return preds . AND ( preds . hasAttrValue ( 'id' , id ) , preds . hasTagName ( 'dom-module' ) ) ; } ; suite ( 'Bundler' , ( ) => { let analyzer ; let bundler ; const shell = resolve ( 'shards/shop_style_project/shell.html' ) ; const common = resolve ( 'shards/shop_style_project/common.html' ) ; const entrypoint1 = resolve ( 'shards/shop_style_project/entrypoint1.html' ) ; const entrypoint2 = resolve ( 'shards/shop_style_project/entrypoint2.html' ) ; setup ( ( ) => { analyzer = undefined ; bundler = undefined ; } ) ; function getAnalyzer ( ) { if ( ! analyzer ) { analyzer = new Analyzer ( { urlResolver : new FsUrlResolver ( 'test/html' ) , urlLoader : new FsUrlLoader ( 'test/html' ) , } ) ; } return analyzer ; } function getBundler ( opts ? ) { if ( bundler === undefined ) { bundler = new Bundler ( { analyzer : getAnalyzer ( ) , ... opts } ) ; } return bundler ; } function resolve ( url ) { return getAnalyzer ( ) . resolveUrl ( url as PackageRelativeUrl ) ! ; } async function bundleMultiple ( inputPath , opts ? ) { const bundler = getBundler ( opts ) ; const manifest = await bundler . generateManifest ( inputPath . map ( ( e ) => bundler . analyzer . resolveUrl ( e ) ! ) ) ; return await bundler . bundle ( manifest ) ; } function assertContainsAndExcludes ( doc , contains , excludes ) { for ( const test of contains ) { const found = dom5 . queryAll ( doc , test ) ; assert . equal ( found . length , 1 ) ; } for ( const test of excludes ) { const found = dom5 . queryAll ( doc , test ) ; assert . equal ( found . length , 0 ) ; } } suite ( 'Sharded builds' , ( ) => { test ( 'with 3 entrypoints, all deps are in their places' , async ( ) => { const { documents } = await bundleMultiple ( [ common , entrypoint1 , entrypoint2 ] , { strategy : generateSharedDepsMergeStrategy ( 2 ) } ) ; assert . equal ( documents . size , 4 ) ; const commonDoc = documents . get ( common ) ! . ast as dom5 . Node ; assert . isDefined ( commonDoc ) ; const entrypoint1Doc = documents . get ( entrypoint1 ) ! . ast as dom5 . Node ; assert . isDefined ( entrypoint1Doc ) ; const entrypoint2Doc = documents . get ( entrypoint2 ) ! . ast as dom5 . Node ; assert . isDefined ( entrypoint2Doc ) ; const sharedDoc = documents . get ( resolve ( 'shared_bundle_1.html' ) ) ! . ast as dom5 . Node ; assert . isDefined ( sharedDoc ) ; const commonModule = domModulePredicate ( 'common-module' ) ; const elOne = domModulePredicate ( 'el-one' ) ; const elTwo = domModulePredicate ( 'el-two' ) ; const depOne = domModulePredicate ( 'el-dep1' ) ; const depTwo = domModulePredicate ( 'el-dep2' ) ; assertContainsAndExcludes ( commonDoc , [ commonModule ] , [ elOne , elTwo , depOne , depTwo ] ) ; assertContainsAndExcludes ( sharedDoc , [ depOne ] , [ elOne , elTwo , depTwo ] ) ; assertContainsAndExcludes ( entrypoint1Doc , [ elOne ] , [ commonModule , elTwo , depOne , depTwo ] ) ; assertContainsAndExcludes ( entrypoint2Doc , [ elTwo , depTwo ] , [ commonModule , elOne , depOne ] ) ; } ) ; test ( 'with 2 entrypoints and shell, all deps in their places' , async ( ) => { const analyzer = getAnalyzer ( ) ; const { documents } = await bundleMultiple ( [ shell , entrypoint1 , entrypoint2 ] , { strategy : generateShellMergeStrategy ( analyzer . resolveUrl ( shell ) ! , 2 ) } ) ; assert . equal ( documents . size , 3 ) ; const shellDoc = documents . get ( shell ) ! . ast as dom5 . Node ; assert . isDefined ( shellDoc ) ; const entrypoint1Doc = documents . get ( entrypoint1 ) ! . ast as dom5 . Node ; assert . isDefined ( entrypoint1Doc ) ; const entrypoint2Doc = documents . get ( entrypoint2 ) ! . ast as dom5 . Node ; assert . isDefined ( entrypoint2Doc ) ; const shellDiv = dom5 . predicates . hasAttrValue ( 'id' , 'shell' ) ; const shellImport = dom5 . predicates . AND ( dom5 . predicates . hasTagName ( 'link' ) , dom5 . predicates . hasSpaceSeparatedAttrValue ( 'rel' , 'import' ) , dom5 . predicates . hasAttrValue ( 'href' , 'shell.html' ) ) ; const commonModule = domModulePredicate ( 'common-module' ) ; const elOne = domModulePredicate ( 'el-one' ) ; const elTwo = domModulePredicate ( 'el-two' ) ; const depOne = domModulePredicate ( 'el-dep1' ) ; const depTwo = domModulePredicate ( 'el-dep2' ) ; assertContainsAndExcludes ( shellDoc , [ shellDiv , commonModule , depOne ] , [ elOne , elTwo , depTwo ] ) ; assertContainsAndExcludes ( entrypoint1Doc , [ elOne ] , [ commonModule , elTwo , depOne , depTwo , shellImport ] ) ; assertContainsAndExcludes ( entrypoint2Doc , [ elTwo , depTwo ] , [ commonModule , elOne , depOne , shellImport ] ) ; } ) ; } ) ; } ) ;