Farmbot-Web-App/frontend/farm_designer/map/__tests__/util_test.ts

490 lines
15 KiB
TypeScript
Raw Normal View History

2018-10-25 18:02:54 -06:00
let mockPath = "";
jest.mock("../../../history", () => ({
2019-04-11 21:17:18 -06:00
getPathArray: jest.fn(() => mockPath.split("/")),
history: { getCurrentLocation: () => ({ pathname: mockPath }) }
2018-10-25 18:02:54 -06:00
}));
2017-09-11 22:42:19 -06:00
import {
2018-01-20 11:31:24 -07:00
round,
translateScreenToGarden,
getBotSize,
getMapSize,
2018-04-11 20:05:08 -06:00
transformXY,
2018-10-25 18:02:54 -06:00
transformForQuadrant,
getGardenCoordinates,
2019-04-11 21:17:18 -06:00
MapPanelStatus,
mapPanelClassName,
2019-08-19 10:05:13 -06:00
getMode,
cursorAtPlant,
allowInteraction,
allowGroupAreaInteraction,
2020-04-13 19:15:11 -06:00
savedGardenOpen,
2017-09-11 22:42:19 -06:00
} from "../util";
2017-09-08 06:01:26 -06:00
import { McuParams } from "farmbot";
2018-10-25 18:02:54 -06:00
import {
2020-02-28 09:35:32 -07:00
AxisNumberProperty, BotSize, MapTransformProps, Mode,
2018-10-25 18:02:54 -06:00
} from "../interfaces";
2017-09-08 06:01:26 -06:00
import { StepsPerMmXY } from "../../../devices/interfaces";
2018-10-25 18:02:54 -06:00
import {
2020-02-28 09:35:32 -07:00
fakeMapTransformProps,
2018-10-25 18:02:54 -06:00
} from "../../../__test_support__/map_transform_props";
import { fakePlant } from "../../../__test_support__/fake_state/resources";
2017-06-29 12:54:02 -06:00
describe("round()", () => {
2017-06-29 12:54:02 -06:00
it("rounds a number", () => {
expect(round(44)).toEqual(40);
expect(round(98)).toEqual(100);
});
2017-09-08 06:01:26 -06:00
});
2017-06-29 12:54:02 -06:00
describe("mapPanelClassName()", () => {
it("returns correct panel status: short panel", () => {
Object.defineProperty(window, "innerWidth", {
value: 400,
configurable: true
});
mockPath = "/app/designer/move_to";
expect(mapPanelClassName()).toEqual("short-panel");
mockPath = "/app/designer/plants/crop_search/mint/add";
expect(mapPanelClassName()).toEqual("short-panel");
});
it("returns correct panel status: panel open", () => {
Object.defineProperty(window, "innerWidth", {
value: 500,
configurable: true
});
mockPath = "/app/designer/move_to";
expect(mapPanelClassName()).toEqual("panel-open");
mockPath = "/app/designer/plants/crop_search/mint/add";
expect(mapPanelClassName()).toEqual("panel-open");
});
});
2017-09-08 06:01:26 -06:00
describe("translateScreenToGarden()", () => {
2018-04-12 14:59:50 -06:00
it("translates screen coords to garden coords: zoomLvl = 1", () => {
const result = translateScreenToGarden({
2018-04-12 21:36:16 -06:00
mapTransformProps: fakeMapTransformProps(),
2018-04-11 20:05:08 -06:00
page: { x: 520, y: 212 },
2018-04-12 14:59:50 -06:00
scroll: { left: 10, top: 20 },
2017-09-08 06:01:26 -06:00
zoomLvl: 1,
2018-04-12 14:59:50 -06:00
gridOffset: { x: 30, y: 40 },
2019-04-11 21:17:18 -06:00
panelStatus: MapPanelStatus.open,
2017-06-29 12:54:02 -06:00
});
2018-04-12 14:59:50 -06:00
expect(result).toEqual({ x: 180, y: 80 });
2017-09-08 06:01:26 -06:00
});
2017-06-29 12:54:02 -06:00
2018-04-12 14:59:50 -06:00
it("translates screen coords to garden coords: zoomLvl < 1", () => {
const result = translateScreenToGarden({
2018-04-12 21:36:16 -06:00
mapTransformProps: fakeMapTransformProps(),
2018-04-11 20:05:08 -06:00
page: { x: 1132, y: 382 },
2018-04-12 14:59:50 -06:00
scroll: { left: 10, top: 20 },
zoomLvl: 0.33,
gridOffset: { x: 30, y: 40 },
2019-04-11 21:17:18 -06:00
panelStatus: MapPanelStatus.open,
2017-06-29 12:54:02 -06:00
});
2018-04-12 14:59:50 -06:00
expect(result).toEqual({ x: 2470, y: 840 });
});
2017-06-29 12:54:02 -06:00
2018-04-12 14:59:50 -06:00
it("translates screen coords to garden coords: zoomLvl > 1", () => {
const result = translateScreenToGarden({
2018-04-12 21:36:16 -06:00
mapTransformProps: fakeMapTransformProps(),
2018-04-12 14:59:50 -06:00
page: { x: 1132, y: 382 },
scroll: { left: 10, top: 20 },
zoomLvl: 1.5,
gridOffset: { x: 30, y: 40 },
2019-04-11 21:17:18 -06:00
panelStatus: MapPanelStatus.open,
2018-04-12 14:59:50 -06:00
});
expect(result).toEqual({ x: 520, y: 150 });
});
it("translates screen coords to garden coords: other case", () => {
const mapTransformProps = fakeMapTransformProps();
mapTransformProps.quadrant = 3;
mapTransformProps.gridSize = { x: 300, y: 150 };
2018-04-12 14:59:50 -06:00
const result = translateScreenToGarden({
mapTransformProps,
2018-04-12 14:59:50 -06:00
page: { x: 332, y: 132 },
scroll: { left: 10, top: 20 },
zoomLvl: 0.75,
gridOffset: { x: 30, y: 40 },
2019-04-11 21:17:18 -06:00
panelStatus: MapPanelStatus.open,
2018-04-12 14:59:50 -06:00
});
expect(result).toEqual({ x: 0, y: 130 });
2017-06-29 12:54:02 -06:00
});
2018-04-13 16:49:20 -06:00
it("translates screen coords to garden coords: swapped X&Y", () => {
const mapTransformProps = fakeMapTransformProps();
mapTransformProps.xySwap = true;
mapTransformProps.quadrant = 3;
mapTransformProps.gridSize = { x: 150, y: 300 };
2018-04-13 16:49:20 -06:00
const result = translateScreenToGarden({
mapTransformProps,
2018-04-13 16:49:20 -06:00
page: { x: 332, y: 132 },
scroll: { left: 10, top: 20 },
zoomLvl: 0.75,
gridOffset: { x: 30, y: 40 },
2019-04-11 21:17:18 -06:00
panelStatus: MapPanelStatus.open,
2018-04-13 16:49:20 -06:00
});
expect(result).toEqual({ x: 130, y: 0 });
});
it("translates screen coords to garden coords: panel closed", () => {
const result = translateScreenToGarden({
mapTransformProps: fakeMapTransformProps(),
page: { x: 520, y: 212 },
scroll: { left: 10, top: 20 },
zoomLvl: 1,
gridOffset: { x: 30, y: 40 },
2019-04-11 21:17:18 -06:00
panelStatus: MapPanelStatus.closed,
});
2018-04-18 20:35:12 -06:00
expect(result).toEqual({ x: 480, y: 30 });
});
2019-04-11 21:17:18 -06:00
it("translates screen coords to garden coords: short panel", () => {
const result = translateScreenToGarden({
mapTransformProps: fakeMapTransformProps(),
page: { x: 520, y: 412 },
scroll: { left: 10, top: 20 },
zoomLvl: 1,
gridOffset: { x: 30, y: 40 },
panelStatus: MapPanelStatus.short,
});
expect(result).toEqual({ x: 480, y: 40 });
});
2017-06-29 12:54:02 -06:00
});
2017-09-08 06:01:26 -06:00
describe("getbotSize()", () => {
function fakeProps() {
const botMcuParams: McuParams = {
movement_stop_at_max_x: undefined,
movement_stop_at_max_y: undefined,
movement_axis_nr_steps_x: undefined,
movement_axis_nr_steps_y: undefined
};
const stepsPerMmXY: StepsPerMmXY = { x: undefined, y: undefined };
const defaultLength: AxisNumberProperty = { x: 3000, y: 1500 };
return {
botMcuParams,
stepsPerMmXY,
defaultLength
};
}
function expectDefaultSize(botSize: BotSize) {
2018-01-12 12:54:37 -07:00
expect(botSize).toEqual({
x: { value: 3000, isDefault: true },
y: { value: 1500, isDefault: true }
});
2017-09-08 06:01:26 -06:00
}
it("returns default bed size: when settings undefined", () => {
const p = fakeProps();
const botSize = getBotSize(p.botMcuParams, p.stepsPerMmXY, p.defaultLength);
expectDefaultSize(botSize);
});
it("returns default bed size: when stop at max disabled", () => {
const p = fakeProps();
p.botMcuParams = {
movement_stop_at_max_x: 0,
movement_stop_at_max_y: 0,
movement_axis_nr_steps_x: 100,
movement_axis_nr_steps_y: 100
};
const botSize = getBotSize(p.botMcuParams, p.stepsPerMmXY, p.defaultLength);
expectDefaultSize(botSize);
});
it("returns default bed size: when axis length is default", () => {
const p = fakeProps();
p.botMcuParams = {
movement_stop_at_max_x: 1,
movement_stop_at_max_y: 1,
movement_axis_nr_steps_x: 0,
movement_axis_nr_steps_y: 0
};
const botSize = getBotSize(p.botMcuParams, p.stepsPerMmXY, p.defaultLength);
expectDefaultSize(botSize);
});
it("returns default bed size: when steps per mm is 0", () => {
const p = fakeProps();
p.botMcuParams = {
movement_stop_at_max_x: 1,
movement_stop_at_max_y: 1,
movement_axis_nr_steps_x: 100,
movement_axis_nr_steps_y: 100
};
p.stepsPerMmXY = { x: 0, y: 0 };
const botSize = getBotSize(p.botMcuParams, p.stepsPerMmXY, p.defaultLength);
expectDefaultSize(botSize);
});
it("calculates correct bed size: both axes", () => {
const p = fakeProps();
p.botMcuParams = {
movement_stop_at_max_x: 1,
movement_stop_at_max_y: 1,
movement_axis_nr_steps_x: 500,
movement_axis_nr_steps_y: 1400
};
p.stepsPerMmXY = { x: 5, y: 7 };
const botSize = getBotSize(p.botMcuParams, p.stepsPerMmXY, p.defaultLength);
2018-01-12 12:54:37 -07:00
expect(botSize).toEqual({
x: { value: 100, isDefault: false },
y: { value: 200, isDefault: false }
});
2017-09-08 06:01:26 -06:00
});
it("calculates correct bed size: one axis", () => {
const p = fakeProps();
p.botMcuParams = {
movement_stop_at_max_x: 0,
movement_stop_at_max_y: 1,
movement_axis_nr_steps_x: 500,
movement_axis_nr_steps_y: 1400
};
p.stepsPerMmXY = { x: 5, y: 7 };
const botSize = getBotSize(p.botMcuParams, p.stepsPerMmXY, p.defaultLength);
2018-01-12 12:54:37 -07:00
expect(botSize).toEqual({
x: { value: 3000, isDefault: true },
y: { value: 200, isDefault: false }
});
2017-09-08 06:01:26 -06:00
});
});
describe("getMapSize()", () => {
it("calculates map size", () => {
const mapSize = getMapSize(
2018-04-13 03:54:00 -06:00
fakeMapTransformProps(),
2017-09-08 06:01:26 -06:00
{ x: 100, y: 50 });
2018-04-13 03:54:00 -06:00
expect(mapSize).toEqual({ h: 1600, w: 3200 });
});
it("calculates map size: X&Y Swapped", () => {
const fakeMPT = fakeMapTransformProps();
fakeMPT.xySwap = true;
const mapSize = getMapSize(
fakeMPT,
{ x: 100, y: 50 });
expect(mapSize).toEqual({ h: 3200, w: 1600 });
2017-09-08 06:01:26 -06:00
});
});
2018-04-11 20:05:08 -06:00
describe("transformXY", () => {
2018-04-12 21:36:16 -06:00
const mapTransformProps = fakeMapTransformProps();
mapTransformProps.gridSize = { x: 2000, y: 1000 };
2018-04-11 20:05:08 -06:00
type QXY = { qx: number, qy: number };
const transformCheck =
(original: QXY, transformed: QXY, transformProps: MapTransformProps) => {
2018-04-13 03:54:00 -06:00
transformProps.xySwap = false;
2018-04-11 20:05:08 -06:00
expect(transformXY(original.qx, original.qy, transformProps))
.toEqual(transformed);
expect(transformXY(transformed.qx, transformed.qy, transformProps))
.toEqual(original);
2018-04-13 03:54:00 -06:00
transformProps.xySwap = true;
const transformedYX = { qx: transformed.qy, qy: transformed.qx };
expect(transformXY(original.qx, original.qy, transformProps))
.toEqual(transformedYX);
expect(transformXY(transformed.qx, transformed.qy, transformProps))
.toEqual({ qx: original.qy, qy: original.qx });
2018-04-11 20:05:08 -06:00
};
2017-09-08 06:01:26 -06:00
it("calculates transformed coordinate: quadrant 2", () => {
2018-04-11 20:05:08 -06:00
const original = { qx: 100, qy: 200 };
const transformed = { qx: 100, qy: 200 };
2018-04-12 21:36:16 -06:00
mapTransformProps.quadrant = 2;
transformCheck(original, transformed, mapTransformProps);
2017-09-08 06:01:26 -06:00
});
it("calculates transformed coordinate: quadrant 4", () => {
2018-04-11 20:05:08 -06:00
const original = { qx: 100, qy: 200 };
const transformed = { qx: 1900, qy: 800 };
2018-04-12 21:36:16 -06:00
mapTransformProps.quadrant = 4;
transformCheck(original, transformed, mapTransformProps);
2017-09-08 06:01:26 -06:00
});
it("calculates transformed coordinate: quadrant 4 (outside of grid)", () => {
2018-04-11 20:05:08 -06:00
const original = { qx: 2200, qy: 1100 };
const transformed = { qx: -200, qy: -100 };
2018-04-12 21:36:16 -06:00
mapTransformProps.quadrant = 4;
transformCheck(original, transformed, mapTransformProps);
2017-09-08 06:01:26 -06:00
});
});
2018-01-20 11:31:24 -07:00
2018-02-13 00:20:00 -07:00
describe("transformForQuadrant()", () => {
2018-04-12 21:36:16 -06:00
const mapTransformProps = fakeMapTransformProps();
mapTransformProps.gridSize = { x: 200, y: 100 };
2018-02-13 00:20:00 -07:00
it("calculates transform for quadrant 1", () => {
2018-04-12 21:36:16 -06:00
mapTransformProps.quadrant = 1;
expect(transformForQuadrant(mapTransformProps))
2018-02-13 00:20:00 -07:00
.toEqual("scale(-1, 1) translate(-200, 0)");
});
it("calculates transform for quadrant 2", () => {
2018-04-12 21:36:16 -06:00
mapTransformProps.quadrant = 2;
expect(transformForQuadrant(mapTransformProps))
2018-02-13 00:20:00 -07:00
.toEqual("scale(1, 1) translate(0, 0)");
});
it("calculates transform for quadrant 3", () => {
2018-04-12 21:36:16 -06:00
mapTransformProps.quadrant = 3;
expect(transformForQuadrant(mapTransformProps))
2018-02-13 00:20:00 -07:00
.toEqual("scale(1, -1) translate(0, -100)");
});
it("calculates transform for quadrant 4", () => {
2018-04-12 21:36:16 -06:00
mapTransformProps.quadrant = 4;
expect(transformForQuadrant(mapTransformProps))
2018-02-13 00:20:00 -07:00
.toEqual("scale(-1, -1) translate(-200, -100)");
});
});
2018-10-25 18:02:54 -06:00
describe("getMode()", () => {
it("returns correct Mode", () => {
mockPath = "/app/designer/plants/crop_search/mint/add";
expect(getMode()).toEqual(Mode.clickToAdd);
mockPath = "/app/designer/plants/1/edit";
expect(getMode()).toEqual(Mode.editPlant);
2019-11-06 10:01:05 -07:00
mockPath = "/app/designer/gardens/templates/1/edit";
2018-10-25 18:02:54 -06:00
expect(getMode()).toEqual(Mode.editPlant);
2019-06-07 18:26:12 -06:00
mockPath = "/app/designer/plants/1";
expect(getMode()).toEqual(Mode.editPlant);
2019-11-06 10:01:05 -07:00
mockPath = "/app/designer/gardens/templates/1";
2019-06-07 18:26:12 -06:00
expect(getMode()).toEqual(Mode.editPlant);
2018-10-25 18:02:54 -06:00
mockPath = "/app/designer/plants/select";
expect(getMode()).toEqual(Mode.boxSelect);
mockPath = "/app/designer/plants/crop_search/mint";
expect(getMode()).toEqual(Mode.addPlant);
2019-03-05 11:59:22 -07:00
mockPath = "/app/designer/move_to";
2018-10-25 18:02:54 -06:00
expect(getMode()).toEqual(Mode.moveTo);
2019-11-01 15:25:39 -06:00
mockPath = "/app/designer/points";
expect(getMode()).toEqual(Mode.points);
2019-08-23 15:18:28 -06:00
mockPath = "/app/designer/points/add";
2018-10-25 18:02:54 -06:00
expect(getMode()).toEqual(Mode.createPoint);
mockPath = "/app/designer/weeds";
expect(getMode()).toEqual(Mode.weeds);
mockPath = "/app/designer/weeds/add";
expect(getMode()).toEqual(Mode.createWeed);
2020-04-13 19:15:11 -06:00
mockPath = "/app/designer/gardens/1";
2018-10-25 18:02:54 -06:00
expect(getMode()).toEqual(Mode.templateView);
2019-08-23 15:18:28 -06:00
mockPath = "/app/designer/groups/1";
2019-11-22 12:57:22 -07:00
expect(getMode()).toEqual(Mode.editGroup);
2019-11-01 15:25:39 -06:00
mockPath = "";
expect(getMode()).toEqual(Mode.none);
2018-10-25 18:02:54 -06:00
});
2020-04-13 19:15:11 -06:00
});
describe("savedGardenOpen", () => {
it("is open", () => {
const result = savedGardenOpen(["", "", "", "gardens", "4", ""]);
expect(result).toEqual(4);
});
2018-10-25 18:02:54 -06:00
});
describe("getGardenCoordinates()", () => {
beforeEach(() => {
Object.defineProperty(document, "querySelector", {
value: () => ({ scrollLeft: 1, scrollTop: 2 }),
configurable: true
});
Object.defineProperty(window, "getComputedStyle", {
2019-11-19 11:22:52 -07:00
value: () => ({ transform: "scale(1)" }), configurable: true
2018-10-25 18:02:54 -06:00
});
});
const fakeProps = () => ({
mapTransformProps: fakeMapTransformProps(),
gridOffset: { x: 10, y: 20 },
pageX: 500,
pageY: 200,
});
it("returns garden coordinates", () => {
const result = getGardenCoordinates(fakeProps());
expect(result).toEqual({ x: 170, y: 70 });
});
it("falls back to zoom level", () => {
Object.defineProperty(window, "getComputedStyle", {
2019-11-19 11:22:52 -07:00
value: () => ({ transform: undefined }), configurable: true
2018-10-25 18:02:54 -06:00
});
const result = getGardenCoordinates(fakeProps());
expect(result).toEqual({ x: 170, y: 70 });
});
it("returns undefined", () => {
Object.defineProperty(document, "querySelector", {
value: () => { },
configurable: true
});
const result = getGardenCoordinates(fakeProps());
expect(result).toEqual(undefined);
});
});
2019-04-11 21:17:18 -06:00
describe("allowInteraction()", () => {
it("allows interaction", () => {
mockPath = "/app/designer/plants";
expect(allowInteraction()).toBeTruthy();
});
it("disallows interaction", () => {
2019-04-16 11:00:00 -06:00
mockPath = "/app/designer/plants/crop_search/mint/add";
expect(allowInteraction()).toBeFalsy();
mockPath = "/app/designer/move_to";
expect(allowInteraction()).toBeFalsy();
mockPath = "/app/designer/points/add";
expect(allowInteraction()).toBeFalsy();
mockPath = "/app/designer/weeds/add";
expect(allowInteraction()).toBeFalsy();
2019-04-16 11:00:00 -06:00
});
});
2019-04-16 11:00:00 -06:00
describe("allowGroupAreaInteraction()", () => {
it("allows interaction", () => {
mockPath = "/app/designer/plants";
expect(allowGroupAreaInteraction()).toBeTruthy();
});
it("disallows interaction", () => {
mockPath = "/app/designer/plants/select";
expect(allowGroupAreaInteraction()).toBeFalsy();
2019-04-16 11:00:00 -06:00
mockPath = "/app/designer/move_to";
expect(allowGroupAreaInteraction()).toBeFalsy();
mockPath = "/app/designer/groups/1";
expect(allowGroupAreaInteraction()).toBeFalsy();
2019-04-11 21:17:18 -06:00
});
});
describe("cursorAtPlant()", () => {
const plant = fakePlant();
plant.body.radius = 25;
plant.body.x = 100;
plant.body.y = 200;
const isAwayFromPlant = (cursor: { x: number, y: number } | undefined) =>
expect(cursorAtPlant(plant, cursor)).toBeFalsy();
const isAtPlant = (cursor: { x: number, y: number } | undefined) =>
expect(cursorAtPlant(plant, cursor)).toBeTruthy();
it("cursor is at the plant", () => {
isAtPlant({ x: 100, y: 200 });
isAtPlant({ x: 75, y: 175 });
isAtPlant({ x: 125, y: 225 });
});
it("cursor is away from the plant", () => {
isAwayFromPlant({ x: 140, y: 200 });
isAwayFromPlant({ x: 60, y: 200 });
isAwayFromPlant({ x: 100, y: 240 });
isAwayFromPlant({ x: 100, y: 160 });
isAwayFromPlant(undefined);
});
});