Skip to content

Commit 102cf25

Browse files
author
Hesam Bahrami
authored
test: drag and drop tests (#21)
* moving the test files into a dedicated folder * installing jsdom * replacing the window and document with their jsdom equivalents for all the tests. * saving the jsdom instance in a global variable. * removing the test folder from the test coverage report. * refactoring the code a bit to help with writing simpler tests. * refactoring the canBeDropped method and writing some tests for it * refactoring the maybeDrop method and writing some tests for it * removing some redundant code. * refactoring the addPlaceholderList method and writing a test for it. * refactoring the onDragEnter method and writing a new test for it.
1 parent adb8ff0 commit 102cf25

File tree

11 files changed

+1387
-170
lines changed

11 files changed

+1387
-170
lines changed

.babelrc

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,11 @@
77
}
88
}]
99
],
10+
"plugins": [
11+
["@babel/plugin-transform-runtime", {
12+
"regenerator": true
13+
}]
14+
],
1015
"env": {
1116
"test": {
1217
"presets": [["@babel/preset-env"]]

jest.config.js

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
module.exports = {
2+
setupFiles: [
3+
'./test/__mocks__/dom.js',
4+
],
5+
coveragePathIgnorePatterns: [
6+
'/node_modules/',
7+
'/test/',
8+
]
9+
}

package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,14 @@
1313
},
1414
"devDependencies": {
1515
"@babel/core": "7.9.0",
16+
"@babel/plugin-transform-runtime": "^7.11.5",
1617
"@babel/preset-env": "7.9.5",
1718
"babel-core": "7.0.0-bridge.0",
1819
"babel-jest": "24.9.0",
1920
"concurrently": "4.1.2",
2021
"husky": "^4.2.5",
2122
"jest": "24.9.0",
23+
"jsdom": "^16.4.0",
2224
"rollup": "1.32.1",
2325
"rollup-plugin-babel": "4.4.0",
2426
"rollup-plugin-commonjs": "10.1.0",

rollup.config.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ export default [
1717
commonjs(),
1818
babel({
1919
exclude: 'node_modules/**',
20+
runtimeHelpers: true,
2021
}),
2122
],
2223
},

src/main.js

Lines changed: 44 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,12 @@ class NestedSort {
147147
}
148148
}
149149

150+
removeClassFromEl(el, className) {
151+
if (el && el.classList.contains(className)) {
152+
el.classList.remove(className)
153+
}
154+
}
155+
150156
onDragStart(e) {
151157
this.draggedNode = e.target;
152158
this.draggedNode.classList.add(this.classNames.dragged);
@@ -158,35 +164,25 @@ class NestedSort {
158164
}
159165

160166
onDragEnter(e) {
161-
if (!this.draggedNode) return
167+
if (!(this.draggedNode && ['LI', 'UL'].includes(e.target.nodeName))) return
162168

163-
if (['LI', 'UL'].includes(e.target.nodeName)) {
164-
e.preventDefault(); // prevent default to allow drop
165-
166-
if (this.targetedNode) this.targetedNode.classList.remove(this.classNames.targeted);
167-
this.targetedNode = e.target;
168-
e.target.classList.add(this.classNames.targeted);
169-
}
169+
if (this.targetedNode) this.targetedNode.classList.remove(this.classNames.targeted)
170+
this.targetedNode = e.target
171+
this.targetedNode.classList.add(this.classNames.targeted)
170172
}
171173

172174
onDragLeave(e) {
173-
e.preventDefault();
174-
e.target.removeEventListener('dragover', this.onDrop);
175-
e.target.removeEventListener('drop', this.onDrop);
176-
e.target.removeEventListener('dragleave', this.onDragLeave);
177175
}
178176

179177
onDragEnd(e) {
180-
e.preventDefault();
181178
e.stopPropagation()
182-
this.draggedNode.classList.remove(this.classNames.dragged);
183-
this.targetedNode.classList.remove(this.classNames.targeted)
179+
this.removeClassFromEl(this.draggedNode, this.classNames.dragged)
180+
this.removeClassFromEl(this.targetedNode, this.classNames.targeted)
184181
this.cleanupPlaceholderLists();
185182
this.draggedNode = null
186183
}
187184

188185
onDrop(e) {
189-
e.preventDefault();
190186
e.stopPropagation()
191187
this.maybeDrop();
192188
this.cleanupPlaceholderLists();
@@ -206,29 +202,23 @@ class NestedSort {
206202
this.calcMouseToTargetedElDist();
207203
}
208204

209-
maybeDrop(e) {
210-
if (!this.canBeDropped()) {
211-
return;
212-
}
213-
214-
let dropLocation;
215-
if (this.targetedNode.nodeName === 'LI' && !this.cursorIsIndentedEnough()) {
216-
dropLocation = 'before';
217-
} else if (this.targetedNode.nodeName === 'UL') {
218-
dropLocation = 'inside';
205+
getDropLocation() {
206+
if (this.canBeDropped()) {
207+
if (this.targetedNode.nodeName === 'LI' && !this.cursorIsIndentedEnough()) return 'before'
208+
else if (this.targetedNode.nodeName === 'UL') return 'inside'
219209
}
210+
}
220211

221-
if (dropLocation) this.dropTheItem(dropLocation, e);
212+
maybeDrop(e) {
213+
const location = this.getDropLocation()
214+
if (location) this.dropTheItem(location, e)
222215
}
223216

224217
dropTheItem(place, e) {
225218
switch (place) {
226219
case 'before':
227220
this.targetedNode.parentNode.insertBefore(this.draggedNode, this.targetedNode);
228221
break;
229-
case 'after':
230-
this.insertAfter(this.draggedNode, this.targetedNode);
231-
break;
232222
case 'inside':
233223
this.targetedNode.appendChild(this.draggedNode);
234224
break;
@@ -269,10 +259,6 @@ class NestedSort {
269259
return this.cursor.Y - this.targetNode.Y < this.distances.droppingEdge;
270260
}
271261

272-
insertAfter(newNode, referenceNode) {
273-
referenceNode.parentNode.insertBefore(newNode, referenceNode.nextSibling);
274-
}
275-
276262
managePlaceholderLists(e) {
277263

278264
let actions = this.analysePlaceHolderSituation(e);
@@ -286,8 +272,6 @@ class NestedSort {
286272
case 'cleanup':
287273
this.cleanupPlaceholderLists();
288274
break;
289-
default:
290-
break;
291275
}
292276
});
293277
}
@@ -316,26 +300,38 @@ class NestedSort {
316300
return actions;
317301
}
318302

319-
addPlaceholderList() {
320-
const list = this.getPlaceholderList();
321-
list.style.minHeight = '0';
322-
this.targetedNode.appendChild(list);
323-
list.style.transition = 'min-height ease .2s';
324-
list.style.minHeight = `${this.draggedNode.offsetHeight}px`;
303+
animatePlaceholderList() {
304+
this.placeholderInUse.style.minHeight = '0'
305+
this.placeholderInUse.style.transition = 'min-height ease .2s'
306+
this.placeholderInUse.style.minHeight = `${this.draggedNode.offsetHeight}px`
307+
}
308+
309+
async addPlaceholderList() {
310+
this.getPlaceholderList()
311+
await this.targetedNode.appendChild(this.placeholderInUse)
312+
this.animatePlaceholderList()
325313
}
326314

327315
targetNodeIsIdentified() {
328316
return !!this.targetedNode;
329317
}
330318

331-
canBeDropped() {
332-
let result = true;
319+
targetNodeIsBeingDragged() {
320+
return this.targetNodeIsIdentified()
321+
&& this.targetedNode === this.draggedNode
322+
}
333323

334-
result &= this.targetNodeIsIdentified() && this.targetedNode !== this.draggedNode;
335-
result &= this.targetNodeIsIdentified() && !(this.targetedNode.nodeName === 'UL' && this.targetedNode.querySelectorAll('li').length);
336-
result &= !this.areNested(this.targetedNode, this.draggedNode);
324+
targetNodeIsListWithItems() {
325+
return this.targetNodeIsIdentified()
326+
&& this.targetedNode.nodeName === 'UL'
327+
&& this.targetedNode.querySelectorAll('li').length
328+
}
337329

338-
return result;
330+
canBeDropped() {
331+
return this.targetNodeIsIdentified()
332+
&& !this.targetNodeIsBeingDragged()
333+
&& !this.targetNodeIsListWithItems()
334+
&& !this.areNested(this.targetedNode, this.draggedNode)
339335
}
340336

341337
cleanupPlaceholderLists() {

src/main.test.js

Lines changed: 0 additions & 113 deletions
This file was deleted.

test/__mocks__/dom.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
import { JSDOM } from 'jsdom'
2+
const dom = new JSDOM()
3+
global.jsdom = dom
4+
global.document = dom.window.document
5+
global.window = dom.window

src/data-engine.test.js renamed to test/data-engine.test.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import DataEngine from './data-engine'
1+
import DataEngine from '../src/data-engine'
22

33
describe('DataEngine class', () => {
44
let list

0 commit comments

Comments
 (0)