2016-06-23 09:47:54 -07:00
/ * *
* @license
2020-05-19 12:08:49 -07:00
* Copyright Google LLC All Rights Reserved .
2016-06-23 09:47:54 -07:00
*
* 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
* /
2016-08-19 12:51:01 -07:00
import { CommonModule } from '@angular/common' ;
2021-04-21 21:34:34 +02:00
import { Attribute , Component , Directive , TemplateRef , ViewChild , } from '@angular/core' ;
import { ComponentFixture , TestBed , waitForAsync } from '@angular/core/testing' ;
2017-03-02 12:12:46 -08:00
import { expect } from '@angular/platform-browser/testing/src/matchers' ;
2015-05-26 14:22:35 -07:00
2017-12-16 14:42:55 -08:00
{
2016-09-08 20:37:20 -07:00
describe ( 'NgSwitch' , ( ) = > {
let fixture : ComponentFixture < any > ;
2020-04-13 16:40:21 -07:00
function getComponent ( ) : TestComponent {
return fixture . componentInstance ;
}
2016-09-08 20:37:20 -07:00
function detectChangesAndExpectText ( text : string ) : void {
fixture . detectChanges ( ) ;
expect ( fixture . nativeElement ) . toHaveText ( text ) ;
}
2020-04-13 16:40:21 -07:00
afterEach ( ( ) = > {
fixture = null ! ;
} ) ;
2016-08-15 13:52:57 -07:00
beforeEach ( ( ) = > {
2016-09-08 20:37:20 -07:00
TestBed . configureTestingModule ( {
2019-03-20 15:26:48 +01:00
declarations : [ TestComponent , ComplexComponent ] ,
2016-09-08 20:37:20 -07:00
imports : [ CommonModule ] ,
} ) ;
2016-08-15 13:52:57 -07:00
} ) ;
2015-05-26 14:22:35 -07:00
describe ( 'switch value changes' , ( ) = > {
2016-11-07 12:22:36 -08:00
it ( 'should switch amongst when values' , ( ) = > {
2017-01-06 14:18:17 -08:00
const template = '<ul [ngSwitch]="switchValue">' +
'<li *ngSwitchCase="\'a\'">when a</li>' +
'<li *ngSwitchCase="\'b\'">when b</li>' +
'</ul>' ;
2016-11-07 12:22:36 -08:00
fixture = createTestComponent ( template ) ;
detectChangesAndExpectText ( '' ) ;
getComponent ( ) . switchValue = 'a' ;
detectChangesAndExpectText ( 'when a' ) ;
getComponent ( ) . switchValue = 'b' ;
detectChangesAndExpectText ( 'when b' ) ;
} ) ;
it ( 'should switch amongst when values with fallback to default' , ( ) = > {
2017-01-06 14:18:17 -08:00
const template = '<ul [ngSwitch]="switchValue">' +
'<li *ngSwitchCase="\'a\'">when a</li>' +
'<li *ngSwitchDefault>when default</li>' +
'</ul>' ;
2016-11-07 12:22:36 -08:00
fixture = createTestComponent ( template ) ;
detectChangesAndExpectText ( 'when default' ) ;
getComponent ( ) . switchValue = 'a' ;
detectChangesAndExpectText ( 'when a' ) ;
getComponent ( ) . switchValue = 'b' ;
detectChangesAndExpectText ( 'when default' ) ;
getComponent ( ) . switchValue = 'c' ;
detectChangesAndExpectText ( 'when default' ) ;
} ) ;
it ( 'should support multiple whens with the same value' , ( ) = > {
2017-01-06 14:18:17 -08:00
const template = '<ul [ngSwitch]="switchValue">' +
'<li *ngSwitchCase="\'a\'">when a1;</li>' +
'<li *ngSwitchCase="\'b\'">when b1;</li>' +
'<li *ngSwitchCase="\'a\'">when a2;</li>' +
'<li *ngSwitchCase="\'b\'">when b2;</li>' +
'<li *ngSwitchDefault>when default1;</li>' +
'<li *ngSwitchDefault>when default2;</li>' +
'</ul>' ;
2016-11-07 12:22:36 -08:00
fixture = createTestComponent ( template ) ;
detectChangesAndExpectText ( 'when default1;when default2;' ) ;
getComponent ( ) . switchValue = 'a' ;
detectChangesAndExpectText ( 'when a1;when a2;' ) ;
getComponent ( ) . switchValue = 'b' ;
detectChangesAndExpectText ( 'when b1;when b2;' ) ;
} ) ;
2015-05-26 14:22:35 -07:00
} ) ;
describe ( 'when values changes' , ( ) = > {
2016-11-07 12:22:36 -08:00
it ( 'should switch amongst when values' , ( ) = > {
2017-01-06 14:18:17 -08:00
const template = '<ul [ngSwitch]="switchValue">' +
'<li *ngSwitchCase="when1">when 1;</li>' +
'<li *ngSwitchCase="when2">when 2;</li>' +
'<li *ngSwitchDefault>when default;</li>' +
'</ul>' ;
2016-11-07 12:22:36 -08:00
fixture = createTestComponent ( template ) ;
getComponent ( ) . when1 = 'a' ;
getComponent ( ) . when2 = 'b' ;
getComponent ( ) . switchValue = 'a' ;
detectChangesAndExpectText ( 'when 1;' ) ;
getComponent ( ) . switchValue = 'b' ;
detectChangesAndExpectText ( 'when 2;' ) ;
getComponent ( ) . switchValue = 'c' ;
detectChangesAndExpectText ( 'when default;' ) ;
getComponent ( ) . when1 = 'c' ;
detectChangesAndExpectText ( 'when 1;' ) ;
getComponent ( ) . when1 = 'd' ;
detectChangesAndExpectText ( 'when default;' ) ;
} ) ;
} ) ;
describe ( 'corner cases' , ( ) = > {
it ( 'should not create the default case if another case matches' , ( ) = > {
const log : string [ ] = [ ] ;
@Directive ( { selector : '[test]' } )
class TestDirective {
2020-04-13 16:40:21 -07:00
constructor ( @Attribute ( 'test' ) test : string ) {
log . push ( test ) ;
}
2016-11-07 12:22:36 -08:00
}
const template = '<div [ngSwitch]="switchValue">' +
'<div *ngSwitchCase="\'a\'" test="aCase"></div>' +
'<div *ngSwitchDefault test="defaultCase"></div>' +
'</div>' ;
TestBed . configureTestingModule ( { declarations : [ TestDirective ] } ) ;
2018-08-23 12:45:39 +02:00
const fixture = createTestComponent ( template ) ;
2016-11-07 12:22:36 -08:00
fixture . componentInstance . switchValue = 'a' ;
fixture . detectChanges ( ) ;
expect ( log ) . toEqual ( [ 'aCase' ] ) ;
} ) ;
it ( 'should create the default case if there is no other case' , ( ) = > {
2017-01-06 14:18:17 -08:00
const template = '<ul [ngSwitch]="switchValue">' +
'<li *ngSwitchDefault>when default1;</li>' +
'<li *ngSwitchDefault>when default2;</li>' +
'</ul>' ;
2016-11-07 12:22:36 -08:00
fixture = createTestComponent ( template ) ;
detectChangesAndExpectText ( 'when default1;when default2;' ) ;
} ) ;
it ( 'should allow defaults before cases' , ( ) = > {
2017-01-06 14:18:17 -08:00
const template = '<ul [ngSwitch]="switchValue">' +
'<li *ngSwitchDefault>when default1;</li>' +
'<li *ngSwitchDefault>when default2;</li>' +
'<li *ngSwitchCase="\'a\'">when a1;</li>' +
'<li *ngSwitchCase="\'b\'">when b1;</li>' +
'<li *ngSwitchCase="\'a\'">when a2;</li>' +
'<li *ngSwitchCase="\'b\'">when b2;</li>' +
'</ul>' ;
2016-11-07 12:22:36 -08:00
fixture = createTestComponent ( template ) ;
detectChangesAndExpectText ( 'when default1;when default2;' ) ;
getComponent ( ) . switchValue = 'a' ;
detectChangesAndExpectText ( 'when a1;when a2;' ) ;
getComponent ( ) . switchValue = 'b' ;
detectChangesAndExpectText ( 'when b1;when b2;' ) ;
} ) ;
2019-03-20 15:26:48 +01:00
2021-04-21 21:34:34 +02:00
it ( 'should throw error when ngSwitchCase is used outside of ngSwitch' , waitForAsync ( ( ) = > {
const template = '<div [ngSwitch]="switchValue"></div>' +
'<div *ngSwitchCase="\'a\'"></div>' ;
expect ( ( ) = > createTestComponent ( template ) )
. toThrowError (
'NG0305: An element with the "ngSwitchCase" attribute (matching the "NgSwitchCase" directive) must be located inside an element with the "ngSwitch" attribute (matching "NgSwitch" directive)' ) ;
} ) ) ;
it ( 'should throw error when ngSwitchDefault is used outside of ngSwitch' , waitForAsync ( ( ) = > {
const template = '<div [ngSwitch]="switchValue"></div>' +
'<div *ngSwitchDefault></div>' ;
expect ( ( ) = > createTestComponent ( template ) )
. toThrowError (
'NG0305: An element with the "ngSwitchDefault" attribute (matching the "NgSwitchDefault" directive) must be located inside an element with the "ngSwitch" attribute (matching "NgSwitch" directive)' ) ;
} ) ) ;
2019-03-20 15:26:48 +01:00
it ( 'should support nested NgSwitch on ng-container with ngTemplateOutlet' , ( ) = > {
fixture = TestBed . createComponent ( ComplexComponent ) ;
detectChangesAndExpectText ( 'Foo' ) ;
fixture . componentInstance . state = 'case2' ;
detectChangesAndExpectText ( 'Bar' ) ;
fixture . componentInstance . state = 'notACase' ;
detectChangesAndExpectText ( 'Default' ) ;
fixture . componentInstance . state = 'case1' ;
detectChangesAndExpectText ( 'Foo' ) ;
} ) ;
2015-05-26 14:22:35 -07:00
} ) ;
} ) ;
}
2016-08-19 12:51:01 -07:00
@Component ( { selector : 'test-cmp' , template : '' } )
2015-05-26 14:22:35 -07:00
class TestComponent {
2016-09-08 20:37:20 -07:00
switchValue : any = null ;
when1 : any = null ;
when2 : any = null ;
}
2019-03-20 15:26:48 +01:00
@Component ( {
selector : 'complex-cmp' ,
template : `
< div [ ngSwitch ] = "state" >
< ng - container * ngSwitchCase = "'case1'" [ ngSwitch ] = "true" >
< ng - container * ngSwitchCase = "true" [ ngTemplateOutlet ] = "foo" > < / n g - c o n t a i n e r >
< span * ngSwitchDefault > Should never render < / span >
< / n g - c o n t a i n e r >
< ng - container * ngSwitchCase = "'case2'" [ ngSwitch ] = "true" >
< ng - container * ngSwitchCase = "true" [ ngTemplateOutlet ] = "bar" > < / n g - c o n t a i n e r >
< span * ngSwitchDefault > Should never render < / span >
< / n g - c o n t a i n e r >
< ng - container * ngSwitchDefault [ ngSwitch ] = "false" >
< ng - container * ngSwitchCase = "true" [ ngTemplateOutlet ] = "foo" > < / n g - c o n t a i n e r >
< span * ngSwitchDefault > Default < / span >
< / n g - c o n t a i n e r >
< / div >
< ng - template # foo >
< span > Foo < / span >
< / n g - t e m p l a t e >
< ng - template # bar >
< span > Bar < / span >
< / n g - t e m p l a t e >
`
} )
class ComplexComponent {
2020-04-13 16:40:21 -07:00
@ViewChild ( 'foo' , { static : true } ) foo ! : TemplateRef < any > ;
@ViewChild ( 'bar' , { static : true } ) bar ! : TemplateRef < any > ;
2019-03-20 15:26:48 +01:00
state : string = 'case1' ;
}
2016-09-08 20:37:20 -07:00
function createTestComponent ( template : string ) : ComponentFixture < TestComponent > {
return TestBed . overrideComponent ( TestComponent , { set : { template : template } } )
. createComponent ( TestComponent ) ;
2015-05-26 14:22:35 -07:00
}