2016-04-12 09:40:37 -07:00
import {
beforeEach ,
afterEach ,
describe ,
expect ,
inject ,
it ,
2016-05-20 16:11:49 -07:00
AsyncTestCompleter
} from "@angular/core/testing/testing_internal" ;
import { Log } from "@angular/core/testing" ;
import { stringify } from "../../src/facade/lang" ;
2016-04-14 14:52:35 -07:00
import {
2016-05-20 16:11:49 -07:00
BROWSER_PLATFORM_PROVIDERS ,
BROWSER_APP_PROVIDERS ,
BROWSER_APP_COMPILER_PROVIDERS ,
bootstrap
} from "@angular/platform-browser" ;
import { ApplicationRef , disposePlatform } from "@angular/core/src/application_ref" ;
import { Console } from "@angular/core/src/console" ;
import {
Component ,
Directive ,
OnDestroy ,
2016-04-14 14:52:35 -07:00
provide ,
Inject ,
PLATFORM_INITIALIZER ,
APP_INITIALIZER ,
coreLoadAndBootstrap ,
createPlatform ,
2016-05-20 16:11:49 -07:00
ReflectiveInjector ,
ExceptionHandler
} from "@angular/core" ;
import { getDOM } from "@angular/platform-browser/src/dom/dom_adapter" ;
import { DOCUMENT } from "@angular/platform-browser/src/dom/dom_tokens" ;
import { PromiseWrapper } from "../../src/facade/async" ;
import { Testability , TestabilityRegistry } from "@angular/core/src/testability/testability" ;
import { ComponentRef } from "@angular/core/src/linker/component_factory" ;
2015-05-26 09:45:15 -07:00
2016-03-08 13:36:48 -08:00
@Component ( { selector : 'hello-app' , template : '{{greeting}} world!' } )
2015-05-26 09:45:15 -07:00
class HelloRootCmp {
greeting : string ;
constructor ( ) { this . greeting = 'hello' ; }
}
2016-03-08 13:36:48 -08:00
@Component ( { selector : 'hello-app' , template : 'before: <ng-content></ng-content> after: done' } )
2015-05-26 09:45:15 -07:00
class HelloRootCmpContent {
constructor ( ) { }
}
2016-03-08 13:36:48 -08:00
@Component ( { selector : 'hello-app-2' , template : '{{greeting}} world, again!' } )
2015-05-26 09:45:15 -07:00
class HelloRootCmp2 {
greeting : string ;
constructor ( ) { this . greeting = 'hello' ; }
}
2016-03-08 13:36:48 -08:00
@Component ( { selector : 'hello-app' , template : '' } )
2015-05-26 09:45:15 -07:00
class HelloRootCmp3 {
2016-06-08 15:45:15 -07:00
appBinding : any /** TODO #9100 */ ;
2015-05-26 09:45:15 -07:00
2016-06-08 15:45:15 -07:00
constructor ( @Inject ( "appBinding" ) appBinding : any /** TODO #9100 */ ) { this . appBinding = appBinding ; }
2015-05-26 09:45:15 -07:00
}
2016-03-08 13:36:48 -08:00
@Component ( { selector : 'hello-app' , template : '' } )
2015-05-26 09:45:15 -07:00
class HelloRootCmp4 {
2016-06-08 15:45:15 -07:00
appRef : any /** TODO #9100 */ ;
2015-05-26 09:45:15 -07:00
2016-06-08 15:45:15 -07:00
constructor ( @Inject ( ApplicationRef ) appRef : any /** TODO #9100 */ ) { this . appRef = appRef ; }
2015-05-26 09:45:15 -07:00
}
@Component ( { selector : 'hello-app' } )
class HelloRootMissingTemplate {
}
@Directive ( { selector : 'hello-app' } )
class HelloRootDirectiveIsNotCmp {
}
2016-03-08 13:36:48 -08:00
@Component ( { selector : 'hello-app' , template : '' } )
2015-11-10 15:42:22 -08:00
class HelloOnDestroyTickCmp implements OnDestroy {
appRef : ApplicationRef ;
2016-06-08 15:45:15 -07:00
constructor ( @Inject ( ApplicationRef ) appRef : any /** TODO #9100 */ ) { this . appRef = appRef ; }
2015-11-10 15:42:22 -08:00
2015-11-16 17:04:36 -08:00
ngOnDestroy ( ) : void { this . appRef . tick ( ) ; }
2015-11-10 15:42:22 -08:00
}
2015-07-27 15:47:42 -07:00
class _ArrayLogger {
res : any [ ] = [ ] ;
log ( s : any ) : void { this . res . push ( s ) ; }
2015-08-24 11:35:27 -07:00
logError ( s : any ) : void { this . res . push ( s ) ; }
2015-07-27 15:47:42 -07:00
logGroup ( s : any ) : void { this . res . push ( s ) ; }
2015-07-23 18:00:19 -07:00
logGroupEnd ( ) { } ;
}
2015-07-27 15:47:42 -07:00
2015-12-15 08:34:44 -08:00
class DummyConsole implements Console {
2016-06-08 15:45:15 -07:00
log ( message : any /** TODO #9100 */ ) { }
warn ( message : any /** TODO #9100 */ ) { }
2015-12-15 08:34:44 -08:00
}
2015-05-26 09:45:15 -07:00
export function main() {
2016-06-08 15:45:15 -07:00
var fakeDoc : any /** TODO #9100 */ , el : any /** TODO #9100 */ , el2 : any /** TODO #9100 */ , testProviders : any /** TODO #9100 */ , lightDom : any /** TODO #9100 */ ;
2015-05-26 09:45:15 -07:00
describe ( 'bootstrap factory method' , ( ) = > {
2015-06-24 13:46:39 -07:00
beforeEach ( ( ) = > {
2016-04-14 14:52:35 -07:00
disposePlatform ( ) ;
2016-04-28 17:50:03 -07:00
fakeDoc = getDOM ( ) . createHtmlDocument ( ) ;
el = getDOM ( ) . createElement ( 'hello-app' , fakeDoc ) ;
el2 = getDOM ( ) . createElement ( 'hello-app-2' , fakeDoc ) ;
lightDom = getDOM ( ) . createElement ( 'light-dom-el' , fakeDoc ) ;
getDOM ( ) . appendChild ( fakeDoc . body , el ) ;
getDOM ( ) . appendChild ( fakeDoc . body , el2 ) ;
getDOM ( ) . appendChild ( el , lightDom ) ;
getDOM ( ) . setText ( lightDom , 'loading' ) ;
2015-12-15 08:34:44 -08:00
testProviders =
2016-06-02 17:30:40 -07:00
[ { provide : DOCUMENT , useValue : fakeDoc } , { provide : Console , useClass : DummyConsole } ] ;
2015-06-24 13:46:39 -07:00
} ) ;
2015-11-18 09:18:37 -08:00
afterEach ( disposePlatform ) ;
2016-04-14 14:52:35 -07:00
it ( 'should throw if bootstrapped Directive is not a Component' , ( ) = > {
var logger = new _ArrayLogger ( ) ;
var exceptionHandler = new ExceptionHandler ( logger , false ) ;
expect (
( ) = > bootstrap ( HelloRootDirectiveIsNotCmp ,
2016-06-02 17:30:40 -07:00
[ testProviders , { provide : ExceptionHandler , useValue : exceptionHandler } ] ) )
2016-04-14 14:52:35 -07:00
. toThrowError (
` Could not compile ' ${ stringify ( HelloRootDirectiveIsNotCmp ) } ' because it is not a component. ` ) ;
expect ( logger . res . join ( "" ) ) . toContain ( "Could not compile" ) ;
} ) ;
2015-05-26 09:45:15 -07:00
2016-06-08 15:45:15 -07:00
it ( 'should throw if no element is found' , inject ( [ AsyncTestCompleter ] , ( async : any /** TODO #9100 */ ) = > {
2015-07-27 15:47:42 -07:00
var logger = new _ArrayLogger ( ) ;
2016-02-25 14:24:17 -08:00
var exceptionHandler = new ExceptionHandler ( logger , false ) ;
2015-07-23 18:00:19 -07:00
2015-07-27 15:47:42 -07:00
var refPromise =
2016-06-02 17:30:40 -07:00
bootstrap ( HelloRootCmp , [ { provide : ExceptionHandler , useValue : exceptionHandler } ] ) ;
2015-05-26 09:45:15 -07:00
PromiseWrapper . then ( refPromise , null , ( reason ) = > {
expect ( reason . message ) . toContain ( 'The selector "hello-app" did not match any elements' ) ;
async . done ( ) ;
return null ;
} ) ;
} ) ) ;
2016-04-28 17:50:03 -07:00
if ( getDOM ( ) . supportsDOMEvents ( ) ) {
2016-02-25 14:24:17 -08:00
it ( 'should forward the error to promise when bootstrap fails' ,
2016-06-08 15:45:15 -07:00
inject ( [ AsyncTestCompleter ] , ( async : any /** TODO #9100 */ ) = > {
2016-02-25 14:24:17 -08:00
// Skip for dart since it causes a confusing error message in console when test passes.
var logger = new _ArrayLogger ( ) ;
var exceptionHandler = new ExceptionHandler ( logger , false ) ;
var refPromise =
2016-06-02 17:30:40 -07:00
bootstrap ( HelloRootCmp , [ { provide : ExceptionHandler , useValue : exceptionHandler } ] ) ;
2016-01-06 14:13:44 -08:00
PromiseWrapper . then ( refPromise , null , ( reason : any ) = > {
2016-02-25 14:24:17 -08:00
expect ( reason . message )
. toContain ( 'The selector "hello-app" did not match any elements' ) ;
async . done ( ) ;
} ) ;
} ) ) ;
2015-07-27 15:47:42 -07:00
it ( 'should invoke the default exception handler when bootstrap fails' ,
2016-06-08 15:45:15 -07:00
inject ( [ AsyncTestCompleter ] , ( async : any /** TODO #9100 */ ) = > {
2015-07-27 15:47:42 -07:00
var logger = new _ArrayLogger ( ) ;
2016-02-25 14:24:17 -08:00
var exceptionHandler = new ExceptionHandler ( logger , false ) ;
2015-07-27 15:47:42 -07:00
var refPromise =
2016-06-02 17:30:40 -07:00
bootstrap ( HelloRootCmp , [ { provide : ExceptionHandler , useValue : exceptionHandler } ] ) ;
2015-07-27 15:47:42 -07:00
PromiseWrapper . then ( refPromise , null , ( reason ) = > {
2016-04-12 09:40:37 -07:00
expect ( logger . res . join ( "" ) )
2015-07-27 15:47:42 -07:00
. toContain ( 'The selector "hello-app" did not match any elements' ) ;
async . done ( ) ;
return null ;
} ) ;
} ) ) ;
}
2015-05-26 09:45:15 -07:00
it ( 'should create an injector promise' , ( ) = > {
2015-10-10 22:11:13 -07:00
var refPromise = bootstrap ( HelloRootCmp , testProviders ) ;
2015-05-26 09:45:15 -07:00
expect ( refPromise ) . not . toBe ( null ) ;
} ) ;
2016-06-08 15:45:15 -07:00
it ( 'should display hello world' , inject ( [ AsyncTestCompleter ] , ( async : any /** TODO #9100 */ ) = > {
2015-10-10 22:11:13 -07:00
var refPromise = bootstrap ( HelloRootCmp , testProviders ) ;
2015-05-26 09:45:15 -07:00
refPromise . then ( ( ref ) = > {
expect ( el ) . toHaveText ( 'hello world!' ) ;
async . done ( ) ;
} ) ;
} ) ) ;
2016-06-08 15:45:15 -07:00
it ( 'should support multiple calls to bootstrap' , inject ( [ AsyncTestCompleter ] , ( async : any /** TODO #9100 */ ) = > {
2015-10-10 22:11:13 -07:00
var refPromise1 = bootstrap ( HelloRootCmp , testProviders ) ;
var refPromise2 = bootstrap ( HelloRootCmp2 , testProviders ) ;
2016-04-12 09:40:37 -07:00
PromiseWrapper . all ( [ refPromise1 , refPromise2 ] )
. then ( ( refs ) = > {
expect ( el ) . toHaveText ( 'hello world!' ) ;
expect ( el2 ) . toHaveText ( 'hello world, again!' ) ;
async . done ( ) ;
} ) ;
2015-05-26 09:45:15 -07:00
} ) ) ;
2015-11-13 11:21:16 -08:00
2015-11-10 15:42:22 -08:00
it ( 'should not crash if change detection is invoked when the root component is disposed' ,
2016-06-08 15:45:15 -07:00
inject ( [ AsyncTestCompleter ] , ( async : any /** TODO #9100 */ ) = > {
2016-04-12 09:40:37 -07:00
bootstrap ( HelloOnDestroyTickCmp , testProviders )
. then ( ( ref ) = > {
2016-04-13 17:05:17 -07:00
expect ( ( ) = > ref . destroy ( ) ) . not . toThrow ( ) ;
2016-04-12 09:40:37 -07:00
async . done ( ) ;
} ) ;
2015-11-10 15:42:22 -08:00
} ) ) ;
2015-11-10 10:40:33 -08:00
it ( 'should unregister change detectors when components are disposed' ,
2016-06-08 15:45:15 -07:00
inject ( [ AsyncTestCompleter ] , ( async : any /** TODO #9100 */ ) = > {
2016-05-19 14:31:21 -07:00
var platform = createPlatform ( ReflectiveInjector . resolveAndCreate ( BROWSER_PLATFORM_PROVIDERS ) ) ;
2016-05-01 22:50:37 -07:00
var app =
2016-05-20 16:11:49 -07:00
ReflectiveInjector . resolveAndCreate ( [ BROWSER_APP_PROVIDERS , BROWSER_APP_COMPILER_PROVIDERS , testProviders ] ,
2016-05-01 22:50:37 -07:00
platform . injector )
. get ( ApplicationRef ) ;
2016-05-20 11:18:08 -07:00
coreLoadAndBootstrap ( HelloRootCmp , app . injector )
2016-04-12 09:40:37 -07:00
. then ( ( ref ) = > {
2016-04-13 17:05:17 -07:00
ref . destroy ( ) ;
2016-04-12 09:40:37 -07:00
expect ( ( ) = > app . tick ( ) ) . not . toThrow ( ) ;
async . done ( ) ;
} ) ;
2015-11-10 10:40:33 -08:00
} ) ) ;
2015-05-26 09:45:15 -07:00
2016-04-12 09:40:37 -07:00
it ( "should make the provided bindings available to the application component" ,
2016-06-08 15:45:15 -07:00
inject ( [ AsyncTestCompleter ] , ( async : any /** TODO #9100 */ ) = > {
2015-10-10 22:11:13 -07:00
var refPromise = bootstrap (
2016-06-02 17:30:40 -07:00
HelloRootCmp3 , [ testProviders , { provide : "appBinding" , useValue : "BoundValue" } ] ) ;
2015-05-26 09:45:15 -07:00
refPromise . then ( ( ref ) = > {
2016-04-13 17:05:17 -07:00
expect ( ref . instance . appBinding ) . toEqual ( "BoundValue" ) ;
2015-05-26 09:45:15 -07:00
async . done ( ) ;
} ) ;
} ) ) ;
2016-04-12 09:40:37 -07:00
it ( "should avoid cyclic dependencies when root component requires Lifecycle through DI" ,
2016-06-08 15:45:15 -07:00
inject ( [ AsyncTestCompleter ] , ( async : any /** TODO #9100 */ ) = > {
2015-10-10 22:11:13 -07:00
var refPromise = bootstrap ( HelloRootCmp4 , testProviders ) ;
2015-05-26 09:45:15 -07:00
refPromise . then ( ( ref ) = > {
2016-04-13 17:05:17 -07:00
expect ( ref . instance . appRef ) . toBe ( ref . injector . get ( ApplicationRef ) ) ;
2015-05-26 09:45:15 -07:00
async . done ( ) ;
} ) ;
} ) ) ;
2016-04-12 09:40:37 -07:00
it ( "should run platform initializers" , inject ( [ Log ] , ( log : Log ) = > {
2016-04-14 14:52:35 -07:00
let p = createPlatform ( ReflectiveInjector . resolveAndCreate ( [
2016-05-19 14:31:21 -07:00
BROWSER_PLATFORM_PROVIDERS ,
2016-06-02 17:30:40 -07:00
{ provide : PLATFORM_INITIALIZER , useValue : log.fn ( "platform_init1" ) , multi : true } ,
{ provide : PLATFORM_INITIALIZER , useValue : log.fn ( "platform_init2" ) , multi : true }
2016-04-14 14:52:35 -07:00
] ) ) ;
2016-04-12 09:40:37 -07:00
expect ( log . result ( ) ) . toEqual ( "platform_init1; platform_init2" ) ;
2015-11-18 09:18:37 -08:00
log . clear ( ) ;
2016-04-14 14:52:35 -07:00
var a = ReflectiveInjector . resolveAndCreate (
[
2016-05-19 14:31:21 -07:00
BROWSER_APP_PROVIDERS ,
2016-06-02 17:30:40 -07:00
{ provide : APP_INITIALIZER , useValue : log.fn ( "app_init1" ) , multi : true } ,
{ provide : APP_INITIALIZER , useValue : log.fn ( "app_init2" ) , multi : true }
2016-04-14 14:52:35 -07:00
] ,
p . injector ) ;
a . get ( ApplicationRef ) ;
2015-11-18 09:18:37 -08:00
2016-04-12 09:40:37 -07:00
expect ( log . result ( ) ) . toEqual ( "app_init1; app_init2" ) ;
2015-11-18 09:18:37 -08:00
} ) ) ;
2015-05-26 09:45:15 -07:00
it ( 'should register each application with the testability registry' ,
2016-06-08 15:45:15 -07:00
inject ( [ AsyncTestCompleter ] , ( async : any /** TODO #9100 */ ) = > {
2016-04-30 10:52:04 -07:00
var refPromise1 : Promise < ComponentRef < any > > = bootstrap ( HelloRootCmp , testProviders ) ;
var refPromise2 : Promise < ComponentRef < any > > = bootstrap ( HelloRootCmp2 , testProviders ) ;
2015-05-26 09:45:15 -07:00
2016-04-12 09:40:37 -07:00
PromiseWrapper . all ( [ refPromise1 , refPromise2 ] )
2016-04-30 10:52:04 -07:00
. then ( ( refs : ComponentRef < any > [ ] ) = > {
2016-04-12 09:40:37 -07:00
var registry = refs [ 0 ] . injector . get ( TestabilityRegistry ) ;
var testabilities =
[ refs [ 0 ] . injector . get ( Testability ) , refs [ 1 ] . injector . get ( Testability ) ] ;
PromiseWrapper . all ( testabilities )
. then ( ( testabilities : Testability [ ] ) = > {
expect ( registry . findTestabilityInTree ( el ) ) . toEqual ( testabilities [ 0 ] ) ;
expect ( registry . findTestabilityInTree ( el2 ) ) . toEqual ( testabilities [ 1 ] ) ;
async . done ( ) ;
} ) ;
} ) ;
2015-05-26 09:45:15 -07:00
} ) ) ;
} ) ;
}