@@ -50,7 +50,8 @@ describe('MatMenu', () => {
5050 let overlayContainerElement : HTMLElement ;
5151 let focusMonitor : FocusMonitor ;
5252
53- function createComponent < T > ( component : Type < T > , providers : Provider [ ] = [ ] ,
53+ function createComponent < T > ( component : Type < T > ,
54+ providers : Provider [ ] = [ ] ,
5455 declarations : any [ ] = [ ] ) : ComponentFixture < T > {
5556 TestBed . configureTestingModule ( {
5657 imports : [ MatMenuModule , NoopAnimationsModule ] ,
@@ -491,6 +492,68 @@ describe('MatMenu', () => {
491492 } ) ) ;
492493 } ) ;
493494
495+ describe ( 'positions' , ( ) => {
496+ let fixture : ComponentFixture < PositionedMenu > ;
497+ let panel : HTMLElement ;
498+
499+ beforeEach ( ( ) => {
500+ fixture = createComponent ( PositionedMenu ) ;
501+ fixture . detectChanges ( ) ;
502+
503+ const trigger = fixture . componentInstance . triggerEl . nativeElement ;
504+
505+ // Push trigger to the bottom edge of viewport,so it has space to open "above"
506+ trigger . style . position = 'fixed' ;
507+ trigger . style . top = '600px' ;
508+
509+ // Push trigger to the right, so it has space to open "before"
510+ trigger . style . left = '100px' ;
511+
512+ fixture . componentInstance . trigger . openMenu ( ) ;
513+ fixture . detectChanges ( ) ;
514+ panel = overlayContainerElement . querySelector ( '.mat-menu-panel' ) as HTMLElement ;
515+ } ) ;
516+
517+ it ( 'should append mat-menu-before if the x position is changed' , ( ) => {
518+ expect ( panel . classList ) . toContain ( 'mat-menu-before' ) ;
519+ expect ( panel . classList ) . not . toContain ( 'mat-menu-after' ) ;
520+
521+ fixture . componentInstance . xPosition = 'after' ;
522+ fixture . detectChanges ( ) ;
523+
524+ expect ( panel . classList ) . toContain ( 'mat-menu-after' ) ;
525+ expect ( panel . classList ) . not . toContain ( 'mat-menu-before' ) ;
526+ } ) ;
527+
528+ it ( 'should append mat-menu-above if the y position is changed' , ( ) => {
529+ expect ( panel . classList ) . toContain ( 'mat-menu-above' ) ;
530+ expect ( panel . classList ) . not . toContain ( 'mat-menu-below' ) ;
531+
532+ fixture . componentInstance . yPosition = 'below' ;
533+ fixture . detectChanges ( ) ;
534+
535+ expect ( panel . classList ) . toContain ( 'mat-menu-below' ) ;
536+ expect ( panel . classList ) . not . toContain ( 'mat-menu-above' ) ;
537+ } ) ;
538+
539+ it ( 'should default to the "below" and "after" positions' , ( ) => {
540+ overlayContainer . ngOnDestroy ( ) ;
541+ fixture . destroy ( ) ;
542+ TestBed . resetTestingModule ( ) ;
543+
544+ const newFixture = createComponent ( SimpleMenu , [ ] , [ FakeIcon ] ) ;
545+
546+ newFixture . detectChanges ( ) ;
547+ newFixture . componentInstance . trigger . openMenu ( ) ;
548+ newFixture . detectChanges ( ) ;
549+ panel = overlayContainerElement . querySelector ( '.mat-menu-panel' ) as HTMLElement ;
550+
551+ expect ( panel . classList ) . toContain ( 'mat-menu-below' ) ;
552+ expect ( panel . classList ) . toContain ( 'mat-menu-after' ) ;
553+ } ) ;
554+
555+ } ) ;
556+
494557 describe ( 'fallback positions' , ( ) => {
495558
496559 it ( 'should fall back to "before" mode if "after" mode would not fit on screen' , ( ) => {
@@ -696,6 +759,14 @@ describe('MatMenu', () => {
696759 . toBe ( Math . floor ( subject . triggerRect . top ) ,
697760 `Expected menu to open in "above" position if "below" position wouldn't fit.` ) ;
698761 } ) ;
762+
763+ it ( 'repositions the origin to be below, so the menu opens from the trigger' , ( ) => {
764+ subject . openMenu ( ) ;
765+ subject . fixture . detectChanges ( ) ;
766+
767+ expect ( subject . menuPanel ! . classList ) . toContain ( 'mat-menu-below' ) ;
768+ expect ( subject . menuPanel ! . classList ) . not . toContain ( 'mat-menu-above' ) ;
769+ } ) ;
699770 } ) ;
700771 } ) ;
701772
0 commit comments