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' ;
1423import { TestBed , ComponentFixture , fakeAsync , flush , tick } from '@angular/core/testing' ;
1524import { DOCUMENT } from '@angular/common' ;
16- import { DragDropModule } from '../drag-drop-module' ;
17- import {
18- createMouseEvent ,
19- dispatchEvent ,
20- dispatchMouseEvent ,
21- dispatchTouchEvent ,
22- createTouchEvent ,
23- } from '@angular/cdk/testing' ;
24- import { Directionality } from '@angular/cdk/bidi' ;
2525import { of as observableOf } from 'rxjs' ;
26- import { CdkDrag , CDK_DRAG_CONFIG } from './drag' ;
26+
27+ import { DragDropModule } from '../drag-drop-module' ;
2728import { CdkDragDrop } from '../drag-events' ;
29+ import { DragRefConfig , Point } from '../drag-ref' ;
30+ import { extendStyles } from '../drag-styling' ;
2831import { moveItemInArray } from '../drag-utils' ;
29- import { CdkDropList } from './drop-list' ;
32+
33+ import { CDK_DRAG_CONFIG , CdkDrag } from './drag' ;
3034import { CdkDragHandle } from './drag-handle' ;
35+ import { CdkDropList } from './drop-list' ;
3136import { CdkDropListGroup } from './drop-list-group' ;
32- import { extendStyles } from '../drag-styling' ;
33- import { DragRefConfig , Point } from '../drag-ref' ;
3437
3538const ITEM_HEIGHT = 25 ;
3639const ITEM_WIDTH = 75 ;
3740
3841describe ( 'CdkDrag' , ( ) => {
39- function createComponent < T > ( componentType : Type < T > , providers : Provider [ ] = [ ] , dragDistance = 0 ) :
40- ComponentFixture < T > {
41- TestBed . configureTestingModule ( {
42- imports : [ DragDropModule ] ,
43- declarations : [ componentType , PassthroughComponent ] ,
44- providers : [
45- {
46- provide : CDK_DRAG_CONFIG ,
47- useValue : {
48- // We default the `dragDistance` to zero, because the majority of the tests
49- // don't care about it and drags are a lot easier to simulate when we don't
50- // have to deal with thresholds.
51- dragStartThreshold : dragDistance ,
52- pointerDirectionChangeThreshold : 5
53- } as DragRefConfig
54- } ,
55- ...providers
56- ] ,
57- } ) . compileComponents ( ) ;
42+ function createComponent < T > (
43+ componentType : Type < T > , providers : Provider [ ] = [ ] , dragDistance = 0 ,
44+ extraDeclarations : Type < any > [ ] = [ ] ) : ComponentFixture < T > {
45+ TestBed
46+ . configureTestingModule ( {
47+ imports : [ DragDropModule ] ,
48+ declarations : [ componentType , PassthroughComponent , ...extraDeclarations ] ,
49+ providers : [
50+ {
51+ provide : CDK_DRAG_CONFIG ,
52+ useValue : {
53+ // We default the `dragDistance` to zero, because the majority of the tests
54+ // don't care about it and drags are a lot easier to simulate when we don't
55+ // have to deal with thresholds.
56+ dragStartThreshold : dragDistance ,
57+ pointerDirectionChangeThreshold : 5
58+ } as DragRefConfig
59+ } ,
60+ ...providers
61+ ] ,
62+ } )
63+ . compileComponents ( ) ;
5864
5965 return TestBed . createComponent < T > ( componentType ) ;
6066 }
@@ -2928,55 +2934,69 @@ describe('CdkDrag', () => {
29282934 } ) ;
29292935 } ) ) ;
29302936
2931- it ( 'should set a class when a container can receive an item' , fakeAsync ( ( ) => {
2932- const fixture = createComponent ( ConnectedDropZones ) ;
2933- fixture . detectChanges ( ) ;
2937+ it ( 'should set a class when a container can receive an item' , fakeAsync ( ( ) => {
2938+ const fixture = createComponent ( ConnectedDropZones ) ;
2939+ fixture . detectChanges ( ) ;
29342940
2935- const dropZones = fixture . componentInstance . dropInstances . map ( d => d . element . nativeElement ) ;
2936- const item = fixture . componentInstance . groupedDragItems [ 0 ] [ 1 ] ;
2941+ const dropZones =
2942+ fixture . componentInstance . dropInstances . map ( d => d . element . nativeElement ) ;
2943+ const item = fixture . componentInstance . groupedDragItems [ 0 ] [ 1 ] ;
29372944
2938- expect ( dropZones . every ( c => ! c . classList . contains ( 'cdk-drop-list-receiving' ) ) )
2939- . toBe ( true , 'Expected neither of the containers to have the class.' ) ;
2945+ expect ( dropZones . every ( c => ! c . classList . contains ( 'cdk-drop-list-receiving' ) ) )
2946+ . toBe ( true , 'Expected neither of the containers to have the class.' ) ;
29402947
2941- startDraggingViaMouse ( fixture , item . element . nativeElement ) ;
2942- fixture . detectChanges ( ) ;
2948+ startDraggingViaMouse ( fixture , item . element . nativeElement ) ;
2949+ fixture . detectChanges ( ) ;
29432950
2944- expect ( dropZones [ 0 ] . classList ) . not . toContain ( 'cdk-drop-list-receiving' ,
2945- 'Expected source container not to have the receiving class.' ) ;
2951+ expect ( dropZones [ 0 ] . classList )
2952+ . not . toContain (
2953+ 'cdk-drop-list-receiving' ,
2954+ 'Expected source container not to have the receiving class.' ) ;
29462955
2947- expect ( dropZones [ 1 ] . classList ) . toContain ( 'cdk-drop-list-receiving' ,
2948- 'Expected target container to have the receiving class.' ) ;
2949- } ) ) ;
2956+ expect ( dropZones [ 1 ] . classList )
2957+ . toContain (
2958+ 'cdk-drop-list-receiving' ,
2959+ 'Expected target container to have the receiving class.' ) ;
2960+ } ) ) ;
29502961
2951- it ( 'should toggle the `receiving` class when the item enters a new list' , fakeAsync ( ( ) => {
2952- const fixture = createComponent ( ConnectedDropZones ) ;
2953- fixture . detectChanges ( ) ;
2962+ it ( 'should toggle the `receiving` class when the item enters a new list' , fakeAsync ( ( ) => {
2963+ const fixture = createComponent ( ConnectedDropZones ) ;
2964+ fixture . detectChanges ( ) ;
29542965
2955- const groups = fixture . componentInstance . groupedDragItems ;
2956- const dropZones = fixture . componentInstance . dropInstances . map ( d => d . element . nativeElement ) ;
2957- const item = groups [ 0 ] [ 1 ] ;
2958- const targetRect = groups [ 1 ] [ 2 ] . element . nativeElement . getBoundingClientRect ( ) ;
2966+ const groups = fixture . componentInstance . groupedDragItems ;
2967+ const dropZones =
2968+ fixture . componentInstance . dropInstances . map ( d => d . element . nativeElement ) ;
2969+ const item = groups [ 0 ] [ 1 ] ;
2970+ const targetRect = groups [ 1 ] [ 2 ] . element . nativeElement . getBoundingClientRect ( ) ;
29592971
2960- expect ( dropZones . every ( c => ! c . classList . contains ( 'cdk-drop-list-receiving' ) ) )
2961- . toBe ( true , 'Expected neither of the containers to have the class.' ) ;
2972+ expect ( dropZones . every ( c => ! c . classList . contains ( 'cdk-drop-list-receiving' ) ) )
2973+ . toBe ( true , 'Expected neither of the containers to have the class.' ) ;
29622974
2963- startDraggingViaMouse ( fixture , item . element . nativeElement ) ;
2975+ startDraggingViaMouse ( fixture , item . element . nativeElement ) ;
29642976
2965- expect ( dropZones [ 0 ] . classList ) . not . toContain ( 'cdk-drop-list-receiving' ,
2966- 'Expected source container not to have the receiving class.' ) ;
2977+ expect ( dropZones [ 0 ] . classList )
2978+ . not . toContain (
2979+ 'cdk-drop-list-receiving' ,
2980+ 'Expected source container not to have the receiving class.' ) ;
29672981
2968- expect ( dropZones [ 1 ] . classList ) . toContain ( 'cdk-drop-list-receiving' ,
2969- 'Expected target container to have the receiving class.' ) ;
2982+ expect ( dropZones [ 1 ] . classList )
2983+ . toContain (
2984+ 'cdk-drop-list-receiving' ,
2985+ 'Expected target container to have the receiving class.' ) ;
29702986
2971- dispatchMouseEvent ( document , 'mousemove' , targetRect . left + 1 , targetRect . top + 1 ) ;
2972- fixture . detectChanges ( ) ;
2987+ dispatchMouseEvent ( document , 'mousemove' , targetRect . left + 1 , targetRect . top + 1 ) ;
2988+ fixture . detectChanges ( ) ;
29732989
2974- expect ( dropZones [ 0 ] . classList ) . toContain ( 'cdk-drop-list-receiving' ,
2975- 'Expected old container not to have the receiving class after exiting.' ) ;
2990+ expect ( dropZones [ 0 ] . classList )
2991+ . toContain (
2992+ 'cdk-drop-list-receiving' ,
2993+ 'Expected old container not to have the receiving class after exiting.' ) ;
29762994
2977- expect ( dropZones [ 1 ] . classList ) . not . toContain ( 'cdk-drop-list-receiving' ,
2978- 'Expected new container not to have the receiving class after entering.' ) ;
2979- } ) ) ;
2995+ expect ( dropZones [ 1 ] . classList )
2996+ . not . toContain (
2997+ 'cdk-drop-list-receiving' ,
2998+ 'Expected new container not to have the receiving class after entering.' ) ;
2999+ } ) ) ;
29803000
29813001 it ( 'should be able to move the item over an intermediate container before ' +
29823002 'dropping it into the final one' , fakeAsync ( ( ) => {
@@ -3083,8 +3103,50 @@ describe('CdkDrag', () => {
30833103 expect ( fixture . componentInstance . droppedSpy ) . not . toHaveBeenCalled ( ) ;
30843104 } ) ) ;
30853105
3106+ it ( 'should toggle a class when dragging an item inside a wrapper component component ' +
3107+ 'with OnPush change detection' ,
3108+ fakeAsync ( ( ) => {
3109+ const fixture =
3110+ createComponent ( ConnectedWrappedDropZones , [ ] , 0 , [ WrappedDropContainerComponent ] ) ;
3111+ fixture . detectChanges ( ) ;
3112+
3113+ const [ startZone , targetZone ] = fixture . nativeElement . querySelectorAll ( '.cdk-drop-list' ) ;
3114+ const item = startZone . querySelector ( '.cdk-drag' ) ;
3115+ const targetRect = targetZone . getBoundingClientRect ( ) ;
3116+
3117+ expect ( startZone . classList )
3118+ . not . toContain (
3119+ 'cdk-drop-list-dragging' ,
3120+ 'Expected start not to have dragging class on init.' ) ;
3121+ expect ( targetZone . classList )
3122+ . not . toContain (
3123+ 'cdk-drop-list-dragging' ,
3124+ 'Expected target not to have dragging class on init.' ) ;
3125+
3126+ startDraggingViaMouse ( fixture , item ) ;
3127+
3128+ expect ( startZone . classList )
3129+ . toContain (
3130+ 'cdk-drop-list-dragging' ,
3131+ 'Expected start to have dragging class after dragging has started.' ) ;
3132+ expect ( targetZone . classList )
3133+ . not . toContain (
3134+ 'cdk-drop-list-dragging' ,
3135+ 'Expected target not to have dragging class after dragging has started.' ) ;
3136+
3137+ dispatchMouseEvent ( document , 'mousemove' , targetRect . left + 1 , targetRect . top + 1 ) ;
3138+ fixture . detectChanges ( ) ;
3139+
3140+ expect ( startZone . classList )
3141+ . not . toContain (
3142+ 'cdk-drop-list-dragging' ,
3143+ 'Expected start not to have dragging class once item has been moved over.' ) ;
3144+ expect ( targetZone . classList )
3145+ . toContain (
3146+ 'cdk-drop-list-dragging' ,
3147+ 'Expected target to have dragging class once item has been moved over.' ) ;
3148+ } ) ) ;
30863149 } ) ;
3087-
30883150} ) ;
30893151
30903152@Component ( {
@@ -3568,6 +3630,34 @@ class DraggableInDropZoneWithoutEvents {
35683630 ] ;
35693631}
35703632
3633+ @Component ( {
3634+ encapsulation : ViewEncapsulation . None ,
3635+ styles : [ `
3636+ .cdk-drop-list {
3637+ display: block;
3638+ width: 100px;
3639+ min-height: ${ ITEM_HEIGHT } px;
3640+ background: hotpink;
3641+ }
3642+
3643+ .cdk-drag {
3644+ display: block;
3645+ height: ${ ITEM_HEIGHT } px;
3646+ background: red;
3647+ }
3648+ ` ] ,
3649+ template : `
3650+ <div cdkDropListGroup>
3651+ <wrapped-drop-container [items]="todo"></wrapped-drop-container>
3652+ <wrapped-drop-container [items]="done"></wrapped-drop-container>
3653+ </div>
3654+ `
3655+ } )
3656+ class ConnectedWrappedDropZones {
3657+ todo = [ 'Zero' , 'One' , 'Two' , 'Three' ] ;
3658+ done = [ 'Four' , 'Five' , 'Six' ] ;
3659+ }
3660+
35713661/**
35723662 * Component that passes through whatever content is projected into it.
35733663 * Used to test having drag elements being projected into a component.
@@ -3578,6 +3668,21 @@ class DraggableInDropZoneWithoutEvents {
35783668} )
35793669class PassthroughComponent { }
35803670
3671+
3672+ /** Component that wraps a drop container and uses OnPush change detection. */
3673+ @Component ( {
3674+ selector : 'wrapped-drop-container' ,
3675+ template : `
3676+ <div cdkDropList [cdkDropListData]="items">
3677+ <div *ngFor="let item of items" cdkDrag>{{item}}</div>
3678+ </div>
3679+ ` ,
3680+ changeDetection : ChangeDetectionStrategy . OnPush
3681+ } )
3682+ class WrappedDropContainerComponent {
3683+ @Input ( ) items : string [ ] ;
3684+ }
3685+
35813686/**
35823687 * Drags an element to a position on the page using the mouse.
35833688 * @param fixture Fixture on which to run change detection.
0 commit comments