1+ import { Directionality } from '@angular/cdk/bidi' ;
2+ import {
3+ createMouseEvent ,
4+ createTouchEvent ,
5+ dispatchEvent ,
6+ dispatchMouseEvent ,
7+ dispatchTouchEvent ,
8+ } from '@angular/cdk/testing' ;
19import {
210 AfterViewInit ,
11+ ChangeDetectionStrategy ,
312 Component ,
413 ElementRef ,
14+ Input ,
515 NgZone ,
616 Provider ,
717 QueryList ,
818 Type ,
919 ViewChild ,
1020 ViewChildren ,
1121 ViewEncapsulation ,
12- ChangeDetectionStrategy ,
1322} from '@angular/core' ;
14- import { TestBed , ComponentFixture , fakeAsync , flush , tick } from '@angular/core/testing' ;
15- import { DragDropModule } from '../drag-drop-module' ;
16- import {
17- createMouseEvent ,
18- dispatchEvent ,
19- dispatchMouseEvent ,
20- dispatchTouchEvent ,
21- createTouchEvent ,
22- } from '@angular/cdk/testing' ;
23- import { Directionality } from '@angular/cdk/bidi' ;
23+ import { ComponentFixture , fakeAsync , flush , TestBed , tick } from '@angular/core/testing' ;
2424import { of as observableOf } from 'rxjs' ;
25- import { CdkDrag , CDK_DRAG_CONFIG } from './drag' ;
25+
26+ import { DragDropModule } from '../drag-drop-module' ;
2627import { CdkDragDrop } from '../drag-events' ;
28+ import { DragRefConfig } from '../drag-ref' ;
29+ import { extendStyles } from '../drag-styling' ;
2730import { moveItemInArray } from '../drag-utils' ;
28- import { CdkDropList } from './drop-list' ;
31+
32+ import { CDK_DRAG_CONFIG , CdkDrag } from './drag' ;
2933import { CdkDragHandle } from './drag-handle' ;
34+ import { CdkDropList } from './drop-list' ;
3035import { CdkDropListGroup } from './drop-list-group' ;
31- import { extendStyles } from '../drag-styling' ;
32- import { DragRefConfig } from '../drag-ref' ;
3336
3437const ITEM_HEIGHT = 25 ;
3538const ITEM_WIDTH = 75 ;
3639
3740describe ( 'CdkDrag' , ( ) => {
38- function createComponent < T > ( componentType : Type < T > , providers : Provider [ ] = [ ] , dragDistance = 0 ) :
39- ComponentFixture < T > {
40- TestBed . configureTestingModule ( {
41- imports : [ DragDropModule ] ,
42- declarations : [ componentType , PassthroughComponent ] ,
43- providers : [
44- {
45- provide : CDK_DRAG_CONFIG ,
46- useValue : {
47- // We default the `dragDistance` to zero, because the majority of the tests
48- // don't care about it and drags are a lot easier to simulate when we don't
49- // have to deal with thresholds.
50- dragStartThreshold : dragDistance ,
51- pointerDirectionChangeThreshold : 5
52- } as DragRefConfig
53- } ,
54- ...providers
55- ] ,
56- } ) . compileComponents ( ) ;
41+ function createComponent < T > (
42+ componentType : Type < T > , providers : Provider [ ] = [ ] , dragDistance = 0 ,
43+ extraDeclarations : Type < any > [ ] = [ ] ) : ComponentFixture < T > {
44+ TestBed
45+ . configureTestingModule ( {
46+ imports : [ DragDropModule ] ,
47+ declarations : [ componentType , PassthroughComponent , ...extraDeclarations ] ,
48+ providers : [
49+ {
50+ provide : CDK_DRAG_CONFIG ,
51+ useValue : {
52+ // We default the `dragDistance` to zero, because the majority of the tests
53+ // don't care about it and drags are a lot easier to simulate when we don't
54+ // have to deal with thresholds.
55+ dragStartThreshold : dragDistance ,
56+ pointerDirectionChangeThreshold : 5
57+ } as DragRefConfig
58+ } ,
59+ ...providers
60+ ] ,
61+ } )
62+ . compileComponents ( ) ;
5763
5864 return TestBed . createComponent < T > ( componentType ) ;
5965 }
@@ -2715,55 +2721,69 @@ describe('CdkDrag', () => {
27152721 } ) ;
27162722 } ) ) ;
27172723
2718- it ( 'should set a class when a container can receive an item' , fakeAsync ( ( ) => {
2719- const fixture = createComponent ( ConnectedDropZones ) ;
2720- fixture . detectChanges ( ) ;
2724+ it ( 'should set a class when a container can receive an item' , fakeAsync ( ( ) => {
2725+ const fixture = createComponent ( ConnectedDropZones ) ;
2726+ fixture . detectChanges ( ) ;
27212727
2722- const dropZones = fixture . componentInstance . dropInstances . map ( d => d . element . nativeElement ) ;
2723- const item = fixture . componentInstance . groupedDragItems [ 0 ] [ 1 ] ;
2728+ const dropZones =
2729+ fixture . componentInstance . dropInstances . map ( d => d . element . nativeElement ) ;
2730+ const item = fixture . componentInstance . groupedDragItems [ 0 ] [ 1 ] ;
27242731
2725- expect ( dropZones . every ( c => ! c . classList . contains ( 'cdk-drop-list-receiving' ) ) )
2726- . toBe ( true , 'Expected neither of the containers to have the class.' ) ;
2732+ expect ( dropZones . every ( c => ! c . classList . contains ( 'cdk-drop-list-receiving' ) ) )
2733+ . toBe ( true , 'Expected neither of the containers to have the class.' ) ;
27272734
2728- startDraggingViaMouse ( fixture , item . element . nativeElement ) ;
2729- fixture . detectChanges ( ) ;
2735+ startDraggingViaMouse ( fixture , item . element . nativeElement ) ;
2736+ fixture . detectChanges ( ) ;
27302737
2731- expect ( dropZones [ 0 ] . classList ) . not . toContain ( 'cdk-drop-list-receiving' ,
2732- 'Expected source container not to have the receiving class.' ) ;
2738+ expect ( dropZones [ 0 ] . classList )
2739+ . not . toContain (
2740+ 'cdk-drop-list-receiving' ,
2741+ 'Expected source container not to have the receiving class.' ) ;
27332742
2734- expect ( dropZones [ 1 ] . classList ) . toContain ( 'cdk-drop-list-receiving' ,
2735- 'Expected target container to have the receiving class.' ) ;
2736- } ) ) ;
2743+ expect ( dropZones [ 1 ] . classList )
2744+ . toContain (
2745+ 'cdk-drop-list-receiving' ,
2746+ 'Expected target container to have the receiving class.' ) ;
2747+ } ) ) ;
27372748
2738- it ( 'should toggle the `receiving` class when the item enters a new list' , fakeAsync ( ( ) => {
2739- const fixture = createComponent ( ConnectedDropZones ) ;
2740- fixture . detectChanges ( ) ;
2749+ it ( 'should toggle the `receiving` class when the item enters a new list' , fakeAsync ( ( ) => {
2750+ const fixture = createComponent ( ConnectedDropZones ) ;
2751+ fixture . detectChanges ( ) ;
27412752
2742- const groups = fixture . componentInstance . groupedDragItems ;
2743- const dropZones = fixture . componentInstance . dropInstances . map ( d => d . element . nativeElement ) ;
2744- const item = groups [ 0 ] [ 1 ] ;
2745- const targetRect = groups [ 1 ] [ 2 ] . element . nativeElement . getBoundingClientRect ( ) ;
2753+ const groups = fixture . componentInstance . groupedDragItems ;
2754+ const dropZones =
2755+ fixture . componentInstance . dropInstances . map ( d => d . element . nativeElement ) ;
2756+ const item = groups [ 0 ] [ 1 ] ;
2757+ const targetRect = groups [ 1 ] [ 2 ] . element . nativeElement . getBoundingClientRect ( ) ;
27462758
2747- expect ( dropZones . every ( c => ! c . classList . contains ( 'cdk-drop-list-receiving' ) ) )
2748- . toBe ( true , 'Expected neither of the containers to have the class.' ) ;
2759+ expect ( dropZones . every ( c => ! c . classList . contains ( 'cdk-drop-list-receiving' ) ) )
2760+ . toBe ( true , 'Expected neither of the containers to have the class.' ) ;
27492761
2750- startDraggingViaMouse ( fixture , item . element . nativeElement ) ;
2762+ startDraggingViaMouse ( fixture , item . element . nativeElement ) ;
27512763
2752- expect ( dropZones [ 0 ] . classList ) . not . toContain ( 'cdk-drop-list-receiving' ,
2753- 'Expected source container not to have the receiving class.' ) ;
2764+ expect ( dropZones [ 0 ] . classList )
2765+ . not . toContain (
2766+ 'cdk-drop-list-receiving' ,
2767+ 'Expected source container not to have the receiving class.' ) ;
27542768
2755- expect ( dropZones [ 1 ] . classList ) . toContain ( 'cdk-drop-list-receiving' ,
2756- 'Expected target container to have the receiving class.' ) ;
2769+ expect ( dropZones [ 1 ] . classList )
2770+ . toContain (
2771+ 'cdk-drop-list-receiving' ,
2772+ 'Expected target container to have the receiving class.' ) ;
27572773
2758- dispatchMouseEvent ( document , 'mousemove' , targetRect . left + 1 , targetRect . top + 1 ) ;
2759- fixture . detectChanges ( ) ;
2774+ dispatchMouseEvent ( document , 'mousemove' , targetRect . left + 1 , targetRect . top + 1 ) ;
2775+ fixture . detectChanges ( ) ;
27602776
2761- expect ( dropZones [ 0 ] . classList ) . toContain ( 'cdk-drop-list-receiving' ,
2762- 'Expected old container not to have the receiving class after exiting.' ) ;
2777+ expect ( dropZones [ 0 ] . classList )
2778+ . toContain (
2779+ 'cdk-drop-list-receiving' ,
2780+ 'Expected old container not to have the receiving class after exiting.' ) ;
27632781
2764- expect ( dropZones [ 1 ] . classList ) . not . toContain ( 'cdk-drop-list-receiving' ,
2765- 'Expected new container not to have the receiving class after entering.' ) ;
2766- } ) ) ;
2782+ expect ( dropZones [ 1 ] . classList )
2783+ . not . toContain (
2784+ 'cdk-drop-list-receiving' ,
2785+ 'Expected new container not to have the receiving class after entering.' ) ;
2786+ } ) ) ;
27672787
27682788 it ( 'should be able to move the item over an intermediate container before ' +
27692789 'dropping it into the final one' , fakeAsync ( ( ) => {
@@ -2822,8 +2842,50 @@ describe('CdkDrag', () => {
28222842
28232843 } ) ) ;
28242844
2845+ it ( 'should toggle a class when dragging an item inside a wrapper component component ' +
2846+ 'with OnPush change detection' ,
2847+ fakeAsync ( ( ) => {
2848+ const fixture =
2849+ createComponent ( ConnectedWrappedDropZones , [ ] , 0 , [ WrappedDropContainerComponent ] ) ;
2850+ fixture . detectChanges ( ) ;
2851+
2852+ const [ startZone , targetZone ] = fixture . nativeElement . querySelectorAll ( '.cdk-drop-list' ) ;
2853+ const item = startZone . querySelector ( '.cdk-drag' ) ;
2854+ const targetRect = targetZone . getBoundingClientRect ( ) ;
2855+
2856+ expect ( startZone . classList )
2857+ . not . toContain (
2858+ 'cdk-drop-list-dragging' ,
2859+ 'Expected start container not to have dragging class on init.' ) ;
2860+ expect ( targetZone . classList )
2861+ . not . toContain (
2862+ 'cdk-drop-list-dragging' ,
2863+ 'Expected target container not to have dragging class on init.' ) ;
2864+
2865+ startDraggingViaMouse ( fixture , item ) ;
2866+
2867+ expect ( startZone . classList )
2868+ . toContain (
2869+ 'cdk-drop-list-dragging' ,
2870+ 'Expected start container to have dragging class after dragging has started.' ) ;
2871+ expect ( targetZone . classList )
2872+ . not . toContain (
2873+ 'cdk-drop-list-dragging' ,
2874+ 'Expected target container not to have dragging class after dragging has started.' ) ;
2875+
2876+ dispatchMouseEvent ( document , 'mousemove' , targetRect . left + 1 , targetRect . top + 1 ) ;
2877+ fixture . detectChanges ( ) ;
2878+
2879+ expect ( startZone . classList )
2880+ . not . toContain (
2881+ 'cdk-drop-list-dragging' ,
2882+ 'Expected start container not to have dragging class once item has been moved over.' ) ;
2883+ expect ( targetZone . classList )
2884+ . toContain (
2885+ 'cdk-drop-list-dragging' ,
2886+ 'Expected target container to have dragging class once item has been moved over.' ) ;
2887+ } ) ) ;
28252888 } ) ;
2826-
28272889} ) ;
28282890
28292891@Component ( {
@@ -3301,6 +3363,34 @@ class DraggableInDropZoneWithoutEvents {
33013363 ] ;
33023364}
33033365
3366+ @Component ( {
3367+ encapsulation : ViewEncapsulation . None ,
3368+ styles : [ `
3369+ .cdk-drop-list {
3370+ display: block;
3371+ width: 100px;
3372+ min-height: ${ ITEM_HEIGHT } px;
3373+ background: hotpink;
3374+ }
3375+
3376+ .cdk-drag {
3377+ display: block;
3378+ height: ${ ITEM_HEIGHT } px;
3379+ background: red;
3380+ }
3381+ ` ] ,
3382+ template : `
3383+ <div cdkDropListGroup>
3384+ <wrapped-drop-container [items]="todo"></wrapped-drop-container>
3385+ <wrapped-drop-container [items]="done"></wrapped-drop-container>
3386+ </div>
3387+ `
3388+ } )
3389+ class ConnectedWrappedDropZones {
3390+ todo = [ 'Zero' , 'One' , 'Two' , 'Three' ] ;
3391+ done = [ 'Four' , 'Five' , 'Six' ] ;
3392+ }
3393+
33043394/**
33053395 * Component that passes through whatever content is projected into it.
33063396 * Used to test having drag elements being projected into a component.
@@ -3311,6 +3401,21 @@ class DraggableInDropZoneWithoutEvents {
33113401} )
33123402class PassthroughComponent { }
33133403
3404+
3405+ /** Component that wraps a drop container and uses OnPush change detection. */
3406+ @Component ( {
3407+ selector : 'wrapped-drop-container' ,
3408+ template : `
3409+ <div cdkDropList [cdkDropListData]="items">
3410+ <div *ngFor="let item of items" cdkDrag>{{item}}</div>
3411+ </div>
3412+ ` ,
3413+ changeDetection : ChangeDetectionStrategy . OnPush
3414+ } )
3415+ class WrappedDropContainerComponent {
3416+ @Input ( ) items : string [ ] ;
3417+ }
3418+
33143419/**
33153420 * Drags an element to a position on the page using the mouse.
33163421 * @param fixture Fixture on which to run change detection.
0 commit comments