Skip to content

Commit

Permalink
Add tests (#857)
Browse files Browse the repository at this point in the history
* Add tests

* Test setInitialState

* Add test

* Add test

* Add test

* Typo

* Add test

* Add tests

* Add tests for handleContextmenu

* Add tests for handleDblclick

* Add tests for touchStart

* Add test for touchend

* Fix test

* Test touchMove

* Remove check for current item

* binarySearch

* Lint

* Add test for drag and drop handler

* Add jsdom-testing-mocks

* Set skipLibCheck option because jsdom-testing-mocks types fail

* Don't check multiple times for current element

* Extract mockLayout

* Use generateHtmlElementsForTree

* Add test

* Test mouseCapture

* Test mouseStart

* Wip

* Test mouseDrag

* Test mouseDrag

* Add tests
  • Loading branch information
mbraak authored Dec 21, 2024
1 parent 2f355a6 commit 980058b
Show file tree
Hide file tree
Showing 10 changed files with 1,330 additions and 32 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@
"jest-axe": "^9.0.0",
"jest-extended": "^4.0.2",
"jest-fixed-jsdom": "^0.0.8",
"jsdom-testing-mocks": "^1.13.1",
"jsonfile": "^6.1.0",
"lodash": "^4.17.21",
"msw": "^2.6.2",
Expand Down
22 changes: 22 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

27 changes: 27 additions & 0 deletions src/dragAndDropHandler/binarySearch.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
function binarySearch<T>(items: T[], compareFn: (a: T) => number): null | T {
let low = 0;
let high = items.length;

while (low < high) {
const mid = (low + high) >> 1;
const item = items[mid];

if (item === undefined) {
return null;
}

const compareResult = compareFn(item);

if (compareResult > 0) {
high = mid;
} else if (compareResult < 0) {
low = mid + 1;
} else {
return item;
}
}

return null;
}

export default binarySearch;
49 changes: 17 additions & 32 deletions src/dragAndDropHandler/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import { Node } from "../node";
import NodeElement from "../nodeElement";
import { getPositionName, Position } from "../position";
import { getElementPosition } from "../util";
import binarySearch from "./binarySearch";
import DragElement from "./dragElement";
import generateHitAreas from "./generateHitAreas";
import { DropHint, HitArea } from "./types";
Expand Down Expand Up @@ -114,18 +115,14 @@ export class DragAndDropHandler {
this.currentItem = null;
}

private canMoveToArea(area: HitArea): boolean {
private canMoveToArea(area: HitArea, currentItem: NodeElement): boolean {
if (!this.onCanMoveTo) {
return true;
}

if (!this.currentItem) {
return false;
}

const positionName = getPositionName(area.position);

return this.onCanMoveTo(this.currentItem.node, area.node, positionName);
return this.onCanMoveTo(currentItem.node, area.node, positionName);
}

private clear(): void {
Expand All @@ -147,37 +144,26 @@ export class DragAndDropHandler {
return null;
}

let low = 0;
let high = this.hitAreas.length;
while (low < high) {
const mid = (low + high) >> 1;
const area = this.hitAreas[mid];

if (!area) {
return null;
}

return binarySearch<HitArea>(this.hitAreas, (area) => {
if (y < area.top) {
high = mid;
return 1;
} else if (y > area.bottom) {
low = mid + 1;
return -1;
} else {
return area;
return 0;
}
}

return null;
});
}

private generateHitAreas(): void {
private generateHitAreas(currentNode: Node): void {
const tree = this.getTree();

if (!this.currentItem || !tree) {
if (!tree) {
this.hitAreas = [];
} else {
this.hitAreas = generateHitAreas(
tree,
this.currentItem.node,
currentNode,
this.getTreeDimensions().bottom,
);
}
Expand All @@ -198,12 +184,13 @@ export class DragAndDropHandler {
};
}

/* Move the dragged node to the selected position in the tree. */
private moveItem(positionInfo: PositionInfo): void {
if (
this.currentItem &&
this.hoveredArea &&
this.hoveredArea.position !== Position.None &&
this.canMoveToArea(this.hoveredArea)
this.canMoveToArea(this.hoveredArea, this.currentItem)
) {
const movedNode = this.currentItem.node;
const targetNode = this.hoveredArea.node;
Expand Down Expand Up @@ -351,7 +338,7 @@ export class DragAndDropHandler {
positionInfo.pageY,
);

if (area && this.canMoveToArea(area)) {
if (area && this.canMoveToArea(area, this.currentItem)) {
if (!area.node.isFolder()) {
this.stopOpenFolderTimer();
}
Expand Down Expand Up @@ -440,11 +427,9 @@ export class DragAndDropHandler {
this.removeHitAreas();

if (this.currentItem) {
this.generateHitAreas();

this.currentItem = this.getNodeElementForNode(
this.currentItem.node,
);
const currentNode = this.currentItem.node;
this.generateHitAreas(currentNode);
this.currentItem = this.getNodeElementForNode(currentNode);

if (this.isDragging) {
this.currentItem.element.classList.add("jqtree-moving");
Expand Down
31 changes: 31 additions & 0 deletions src/test/dragAndDropHandler/binarySearch.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import binarySearch from "../../dragAndDropHandler/binarySearch";

it("returns null when the array is empty", () => {
const compareFn = (_item: number) => 0;

const result = binarySearch<number>([], compareFn);
expect(result).toBeNull();
});

it("finds a value", () => {
const compareFn = (item: number) => item - 5;

const result = binarySearch<number>([1, 5, 7, 9], compareFn);
expect(result).toEqual(5);
});

it("returns null when the value doesn't exist", () => {
const compareFn = (item: number) => item - 6;

const result = binarySearch<number>([1, 5, 7, 9], compareFn);
expect(result).toBeNull();
});

it("handles undefined values in the array", () => {
const compareFn = (item: number) => item - 6;
const array = [1, 5, 7, 9];
(array as any)[1] = undefined; // eslint-disable-line @typescript-eslint/no-unsafe-member-access

const result = binarySearch<number>(array, compareFn);
expect(result).toBeNull();
});
Loading

0 comments on commit 980058b

Please sign in to comment.