11// @flow
22/* eslint-env jest */
33
4- import React from ' react' ;
5- import _ from ' lodash' ;
6- import ResponsiveReactGridLayout from '../../lib/ResponsiveReactGridLayout' ;
7- import ReactGridLayout from ' ../../lib/ReactGridLayout' ;
8- import BasicLayout from ' ../examples/1-basic' ;
9- import ShowcaseLayout from ' ../examples/0-showcase' ;
10- import deepFreeze from ' ../util/deepFreeze' ;
11- import { shallow , mount } from 'enzyme' ;
12-
13- describe ( 'Lifecycle tests' , function ( ) {
4+ import React from " react" ;
5+ import _ from " lodash" ;
6+ import TestUtils from "react-dom/test-utils" ;
7+ import ResponsiveReactGridLayout from " ../../lib/ResponsiveReactGridLayout" ;
8+ import ReactGridLayout from " ../../lib/ReactGridLayout" ;
9+ import BasicLayout from " ../examples/1-basic" ;
10+ import ShowcaseLayout from " ../examples/0-showcase" ;
11+ import DroppableLayout from "../examples/15-drag-from-outside" ;
12+ import deepFreeze from "../util/deepFreeze" ;
13+ import { shallow , mount } from "enzyme" ;
1414
15+ describe ( "Lifecycle tests" , function ( ) {
1516 // Example layouts use randomness
1617 let randIdx = 0 ;
1718 beforeAll ( ( ) => {
1819 const randArr = [ 0.001 , 0.1 , 0.2 , 0.3 , 0.4 , 0.5 , 0.6 , 0.7 , 0.8 , 0.9 , 0.999 ] ;
19- jest . spyOn ( global . Math , ' random' ) . mockImplementation ( ( ) => {
20+ jest . spyOn ( global . Math , " random" ) . mockImplementation ( ( ) => {
2021 randIdx = ( randIdx + 1 ) % randArr . length ;
2122 return randArr [ randIdx ] ;
2223 } ) ;
@@ -30,46 +31,163 @@ describe('Lifecycle tests', function() {
3031 global . Math . random . mockRestore ( ) ;
3132 } ) ;
3233
33- describe ( ' <ReactGridLayout>' , function ( ) {
34- it ( ' Basic Render' , async function ( ) {
34+ describe ( " <ReactGridLayout>" , function ( ) {
35+ it ( " Basic Render" , async function ( ) {
3536 const wrapper = mount ( < BasicLayout /> ) ;
3637 expect ( wrapper ) . toMatchSnapshot ( ) ;
3738 } ) ;
38- } ) ;
3939
40- describe ( '<ResponsiveReactGridLayout>' , function ( ) {
40+ describe ( "Droppability" , function ( ) {
41+ it ( "Updates when an item is dropped in" , function ( ) {
42+ const wrapper = mount ( < DroppableLayout /> ) ;
43+ const gridLayout = wrapper . find ( "ReactGridLayout" ) ;
44+ expect ( gridLayout ) . toHaveLength ( 1 ) ;
45+
46+ // Start: no dropping node.
47+ expect ( gridLayout . state ( "droppingDOMNode" ) ) . toEqual ( null ) ;
48+
49+ // Find the droppable element and drag it over the grid layout.
50+ const droppable = wrapper . find ( ".droppable-element" ) ;
51+ TestUtils . Simulate . dragOver ( gridLayout . getDOMNode ( ) , {
52+ nativeEvent : {
53+ target : droppable . getDOMNode ( ) ,
54+ layerX : 200 ,
55+ layerY : 150
56+ }
57+ } ) ;
58+
59+ // We should have the position in our state.
60+ expect ( gridLayout . state ( "droppingPosition" ) ) . toHaveProperty (
61+ "left" ,
62+ 200
63+ ) ;
64+ expect ( gridLayout . state ( "droppingPosition" ) ) . toHaveProperty ( "top" , 150 ) ;
65+ // We should now have the placeholder element in our state.
66+ expect ( gridLayout . state ( "droppingDOMNode" ) ) . toHaveProperty (
67+ "type" ,
68+ "div"
69+ ) ;
70+ expect ( gridLayout . state ( "droppingDOMNode" ) ) . toHaveProperty (
71+ "key" ,
72+ "__dropping-elem__"
73+ ) ;
74+
75+ // It should also have a layout item assigned to it.
76+ let layoutItem = gridLayout
77+ . state ( "layout" )
78+ . find ( item => item . i === "__dropping-elem__" ) ;
79+ expect ( layoutItem ) . toEqual ( {
80+ i : "__dropping-elem__" ,
81+ h : 1 ,
82+ w : 1 ,
83+ x : 1 ,
84+ y : 4 ,
85+ static : false ,
86+ isDraggable : true
87+ } ) ;
88+
89+ // Let's move it some more.
90+ TestUtils . Simulate . dragOver ( gridLayout . getDOMNode ( ) , {
91+ nativeEvent : {
92+ target : droppable . getDOMNode ( ) ,
93+ layerX : 0 ,
94+ layerY : 300
95+ }
96+ } ) ;
4197
42- it ( 'Basic Render' , async function ( ) {
98+ // State should change.
99+ expect ( gridLayout . state ( "droppingPosition" ) ) . toHaveProperty ( "left" , 0 ) ;
100+ expect ( gridLayout . state ( "droppingPosition" ) ) . toHaveProperty ( "top" , 300 ) ;
101+
102+ layoutItem = gridLayout
103+ . state ( "layout" )
104+ . find ( item => item . i === "__dropping-elem__" ) ;
105+ // Using toMatchObject() here as this will inherit some undefined properties from the cloning
106+ expect ( layoutItem ) . toMatchObject ( {
107+ i : "__dropping-elem__" ,
108+ h : 1 ,
109+ w : 1 ,
110+ x : 0 ,
111+ y : 9 ,
112+ static : false ,
113+ isDraggable : true
114+ } ) ;
115+ } ) ;
116+ } ) ;
117+ } ) ;
118+
119+ describe ( "<ResponsiveReactGridLayout>" , function ( ) {
120+ it ( "Basic Render" , async function ( ) {
43121 const wrapper = mount ( < ShowcaseLayout /> ) ;
44122 expect ( wrapper ) . toMatchSnapshot ( ) ;
45123 } ) ;
46124
47- it ( ' Does not modify layout on movement' , async function ( ) {
125+ it ( " Does not modify layout on movement" , async function ( ) {
48126 const layouts = {
49127 lg : [
50- ..._ . times ( 3 , ( i ) => ( {
128+ ..._ . times ( 3 , i => ( {
51129 i : String ( i ) ,
52130 x : i ,
53131 y : 0 ,
54132 w : 1 ,
55- h : 1 ,
133+ h : 1
56134 } ) )
57135 ]
58136 } ;
59- const frozenLayouts = deepFreeze ( layouts , { set : true , get : false /* don't crash on unknown gets */ } ) ;
137+ const frozenLayouts = deepFreeze ( layouts , {
138+ set : true ,
139+ get : false /* don't crash on unknown gets */
140+ } ) ;
60141 // Render the basic Responsive layout.
61142 const wrapper = mount (
62- < ResponsiveReactGridLayout layouts = { frozenLayouts } width = { 1280 } breakpoint = "lg" >
63- { _ . times ( 3 , ( i ) => < div key = { i } /> ) }
143+ < ResponsiveReactGridLayout
144+ layouts = { frozenLayouts }
145+ width = { 1280 }
146+ breakpoint = "lg"
147+ >
148+ { _ . times ( 3 , i => (
149+ < div key = { i } />
150+ ) ) }
64151 </ ResponsiveReactGridLayout >
65152 ) ;
66153
67154 // Set that layout as state and ensure it doesn't change.
68- wrapper . setState ( { layouts : frozenLayouts } ) ;
69- wrapper . setProps ( { width : 800 , breakpoint : 'md' } ) ; // will generate new layout
155+ wrapper . setState ( { layouts : frozenLayouts } ) ;
156+ wrapper . setProps ( { width : 800 , breakpoint : "md" } ) ; // will generate new layout
70157 wrapper . render ( ) ;
71158
72- expect ( frozenLayouts ) . not . toContain ( 'md' ) ;
159+ expect ( frozenLayouts ) . not . toContain ( "md" ) ;
73160 } ) ;
74161 } ) ;
75- } ) ;
162+ } ) ;
163+
164+ function simulateMovementFromTo ( node , fromX , fromY , toX , toY ) {
165+ TestUtils . Simulate . mouseDown ( node , { clientX : fromX , clientY : fromX } ) ;
166+ mouseMove ( node , toX , toY ) ;
167+ TestUtils . Simulate . mouseUp ( node ) ;
168+ }
169+
170+ function mouseMove ( node , x , y ) {
171+ const doc = node ? node . ownerDocument : document ;
172+ const evt = doc . createEvent ( "MouseEvents" ) ;
173+ // $FlowIgnore get with it, flow
174+ evt . initMouseEvent (
175+ "mousemove" ,
176+ true ,
177+ true ,
178+ window ,
179+ 0 ,
180+ 0 ,
181+ 0 ,
182+ x ,
183+ y ,
184+ false ,
185+ false ,
186+ false ,
187+ false ,
188+ 0 ,
189+ null
190+ ) ;
191+ doc . dispatchEvent ( evt ) ;
192+ return evt ;
193+ }
0 commit comments