UNPKG

leaflet.glify

Version:
978 lines (945 loc) 33 kB
import { BaseGlLayer, defaultHoverWait, defaultPane, EventCallback, IBaseGlLayerSettings, } from "./base-gl-layer"; import { ICanvasOverlayDrawEvent } from "./canvas-overlay"; import { LatLng, LatLngBounds, LeafletMouseEvent, Map, Point } from "leaflet"; jest.mock("./canvas-overlay"); describe("BaseGlLayer", () => { interface ITestLayerSettings extends IBaseGlLayerSettings {} class TestLayer extends BaseGlLayer<ITestLayerSettings> { drawOnCanvas(context: ICanvasOverlayDrawEvent): this { return this; } render(): this { return this; } } const defaultSettings: Partial<ITestLayerSettings> = { longitudeKey: 1, latitudeKey: 0, data: {}, pane: "", }; function getGlLayer(settings?: Partial<ITestLayerSettings>) { const element = document.createElement("div"); const map = new Map(element); const vertexShaderSource = ` `; const fragmentShaderSource = ` `; return new TestLayer({ ...defaultSettings, map, vertexShaderSource, fragmentShaderSource, ...settings, }); } function fakeEvent(layer: TestLayer): LeafletMouseEvent { return { type: "fake event", latlng: new LatLng(1, 1), layerPoint: new Point(1, 1), containerPoint: new Point(1, 1), originalEvent: new MouseEvent("fake event"), target: "", sourceTarget: "", propagatedFrom: "", layer, }; } describe("data", () => { describe("when settings.data is falsey", () => { it("throws", () => { const data = null; const layer = getGlLayer({ data }); expect(() => { layer.data; }).toThrow(); }); }); describe("when settings.data is defined", () => { it("is returned", () => { const data = { features: [] }; const layer = getGlLayer({ data }); expect(layer.data).toBe(data); }); }); }); describe("pane", () => { describe("when not defined in settings.pane", () => { it("returns defaultPane value", () => { const layer = getGlLayer({ pane: undefined }); expect(layer.settings.pane).toBe(undefined); expect(layer.pane).toBe(defaultPane); }); }); describe("when defined in settings.pane", () => { it("returns settings.pane", () => { const layer = getGlLayer({ pane: "pane" }); expect(layer.settings.pane).toBe("pane"); expect(layer.pane).toBe("pane"); }); }); }); describe("className", () => { describe("when not defined in settings.className", () => { it("returns empty string", () => { const layer = getGlLayer({ className: undefined }); expect(layer.className).toBe(""); }); }); describe("when defined in settings.className", () => { it("is returned", () => { const layer = getGlLayer({ className: "className" }); expect(layer.className).toBe("className"); }); }); }); describe("map", () => { describe("when settings.map is not defined", () => { it("throws", () => { const layer = getGlLayer(); delete layer.settings.map; expect(() => { layer.map; }).toThrow(); }); }); describe("when settings.map is defined", () => { it("is returned", () => { const layer = getGlLayer(); expect(layer.settings.map).not.toBeFalsy(); expect(layer.map).toBe(layer.settings.map); }); }); }); describe("sensitivity", () => { describe("when settings.sensitivity is not defined", () => { it("throws", () => { const layer = getGlLayer(); delete layer.settings.sensitivity; expect(() => { layer.sensitivity; }).toThrow(); }); }); describe("when settings.sensitivity is defined", () => { it("is returned", () => { const layer = getGlLayer({ sensitivity: 1 }); expect(layer.settings.sensitivity).toBe(1); expect(layer.sensitivity).toBe(layer.settings.sensitivity); }); }); }); describe("sensitivityHover", () => { describe("when settings.sensitivityHover is not defined", () => { it("throws", () => { const layer = getGlLayer(); delete layer.settings.sensitivityHover; expect(() => { layer.sensitivityHover; }).toThrow(); }); }); describe("when settings.sensitivityHover is defined", () => { it("is returned", () => { const layer = getGlLayer({ sensitivityHover: 1 }); expect(layer.settings.sensitivityHover).toBe(1); expect(layer.sensitivityHover).toBe(layer.settings.sensitivityHover); }); }); }); describe("hoverWait", () => { describe("when not defined in settings.hoverWait", () => { it("returns empty string", () => { const layer = getGlLayer({ hoverWait: undefined }); expect(layer.hoverWait).toBe(defaultHoverWait); }); }); describe("when defined in settings.hoverWait", () => { it("is returned", () => { const layer = getGlLayer({ hoverWait: 123 }); expect(layer.hoverWait).toBe(123); }); }); }); describe("longitudeKey", () => { describe("when settings.longitudeKey is not defined", () => { it("throws", () => { const layer = getGlLayer(); delete layer.settings.longitudeKey; expect(() => { layer.longitudeKey; }).toThrow(); }); }); describe("when settings.longitudeKey is defined", () => { it("is returned", () => { const layer = getGlLayer({ longitudeKey: 1 }); expect(layer.settings.longitudeKey).toBe(1); expect(layer.longitudeKey).toBe(layer.settings.longitudeKey); }); }); }); describe("latitudeKey", () => { describe("when settings.latitudeKey is not defined", () => { it("throws", () => { const layer = getGlLayer(); delete layer.settings.latitudeKey; expect(() => { layer.latitudeKey; }).toThrow(); }); }); describe("when settings.longitudeKey is defined", () => { it("is returned", () => { const layer = getGlLayer({ latitudeKey: 1 }); expect(layer.settings.latitudeKey).toBe(1); expect(layer.latitudeKey).toBe(layer.settings.latitudeKey); }); }); }); describe("opacity", () => { describe("when settings.opacity is not defined", () => { it("throws", () => { const layer = getGlLayer(); delete layer.settings.opacity; expect(() => { layer.opacity; }).toThrow(); }); }); describe("when settings.opacity is defined", () => { it("is returned", () => { const layer = getGlLayer({ opacity: 1 }); expect(layer.settings.opacity).toBe(1); expect(layer.opacity).toBe(layer.settings.opacity); }); }); }); describe("color", () => { describe("when settings.color is not defined", () => { it("returns null", () => { const layer = getGlLayer(); delete layer.settings.color; expect(layer.color).toBeNull(); }); }); describe("when settings.color is defined", () => { it("is returned", () => { const color = { r: 1, g: 1, b: 1, a: 1 }; const layer = getGlLayer({ color }); expect(layer.settings.color).toBe(color); expect(layer.color).toBe(layer.settings.color); }); }); }); describe("constructor", () => { it("sets settings from first argument", () => { const element = document.createElement("div"); const map = new Map(element); const layer = new TestLayer({ ...defaultSettings, map }); expect(layer.settings.map).toBe(map); }); it("calls this.canvas.getContext, with preserveDrawingBuffer as boolean and sets this.gl", () => { const element = document.createElement("div"); const map = new Map(element); const layer = new TestLayer({ ...defaultSettings, map, preserveDrawingBuffer: true, }); expect(layer.canvas.getContext).toHaveBeenCalledWith("webgl2", { preserveDrawingBuffer: true, }); expect(layer.gl).toBeInstanceOf(WebGLRenderingContext); }); it("provides a drawOnCanvas lambda, that calls layer.drawOnCanvas", () => { const layer = getGlLayer(); jest.spyOn(layer, "drawOnCanvas"); const event: ICanvasOverlayDrawEvent = { canvas: document.createElement("canvas"), bounds: new LatLngBounds(new LatLng(1, 1), new LatLng(10, 10)), offset: new Point(1, 1), scale: 1, size: new Point(10, 10), zoomScale: 1, zoom: 1, }; layer.layer._userDrawFunc(event); expect(layer.drawOnCanvas).toHaveBeenCalledWith(event); }); }); describe("attachShaderVariables", () => { describe("shaderVariableCount is 0", () => { it("return early", () => { const element = document.createElement("div"); const map = new Map(element); const layer = new TestLayer({ ...defaultSettings, map }); jest.spyOn(layer, "getAttributeLocation"); expect(layer.attachShaderVariables(4)).toBe(layer); expect(layer.getAttributeLocation).not.toHaveBeenCalled(); }); }); describe("shaderVariableCount is 2", () => { it("attaches and enables variables", () => { const element = document.createElement("div"); const map = new Map(element); const layer = new TestLayer({ ...defaultSettings, map, shaderVariables: { one: { type: "FLOAT", start: 0, size: 2, }, two: { type: "FLOAT", start: 3, size: 4, }, }, }); jest.spyOn(layer, "getAttributeLocation"); jest.spyOn(layer.gl, "getAttribLocation").mockReturnValue(999); jest.spyOn(layer.gl, "vertexAttribPointer"); jest.spyOn(layer.gl, "enableVertexAttribArray"); layer.program = new WebGLProgram(); expect(layer.attachShaderVariables(4)).toBe(layer); expect(layer.getAttributeLocation).toHaveBeenCalledWith("one"); expect(layer.getAttributeLocation).toHaveBeenCalledWith("two"); expect(layer.gl.vertexAttribPointer).toHaveBeenCalledWith( 999, 2, layer.gl.FLOAT, false, 0, 0 ); expect(layer.gl.vertexAttribPointer).toHaveBeenCalledWith( 999, 4, layer.gl.FLOAT, false, 0, 8 ); expect(layer.gl.enableVertexAttribArray).toHaveBeenCalledWith(999); expect(layer.gl.enableVertexAttribArray).toHaveBeenCalledWith(999); }); }); describe("getShaderVariableCount", () => { it("returns the count of shaderVariables", () => { const element = document.createElement("div"); const map = new Map(element); const layer0 = new TestLayer({ ...defaultSettings, map }); expect(layer0.getShaderVariableCount()).toBe(0); const layer1 = new TestLayer({ ...defaultSettings, map, shaderVariables: { one: { type: "FLOAT", start: 0, size: 2, }, }, }); expect(layer1.getShaderVariableCount()).toBe(1); }); }); }); describe("setData", () => { it("sets up settings with new data", () => { const element = document.createElement("div"); const map = new Map(element); const layer = new TestLayer({ ...defaultSettings, map }); const { settings } = layer; const data = {}; layer.setData(data); expect(settings).not.toBe(layer.settings); expect(layer.data).toBe(data); }); it("calls this.render()", () => { const layer = getGlLayer(); jest.spyOn(layer, "render"); layer.setData([]); expect(layer.render).toHaveBeenCalled(); }); }); describe("setup", () => { describe("when settings.click and settings.setupClick are truth", () => { it("calls settings.setupClick with this.map", () => { const click = () => {}; const setupClick = jest.fn(); const layer = getGlLayer({ click, setupClick, }); expect(layer.setup()).toBe(layer); expect(setupClick).toHaveBeenCalledWith(layer.map); }); }); describe("when settings.hover and settings.setupHover are truthy", () => { it("calls settings.setupHover with this.map and settings.hoverWait", () => { const hover: EventCallback = () => {}; const setupHover = jest.fn(); const hoverWait = 12; const layer = getGlLayer({ hover, setupHover, hoverWait, }); expect(layer.setup()).toBe(layer); expect(setupHover).toHaveBeenCalledWith(layer.map, hoverWait); }); }); it("calls this.setupVertexShader, this.setupFragmentShader, and this.setupProgram", () => { const layer = getGlLayer(); jest.spyOn(layer, "setupVertexShader"); jest.spyOn(layer, "setupFragmentShader"); jest.spyOn(layer, "setupProgram"); layer.setup(); expect(layer.setupVertexShader).toHaveBeenCalled(); expect(layer.setupFragmentShader).toHaveBeenCalled(); expect(layer.setupProgram).toHaveBeenCalled(); }); }); describe("setupVertexShader", () => { it("sets this.vertexShader", () => { const layer = getGlLayer(); layer.setupVertexShader(); expect(layer.vertexShader).not.toBe(null); }); describe("when typeof settings.vertexShaderSource is a function", () => { it("calls it, and calls gl.shaderSource with returned value", () => { const vertexShaderSource = () => "vertex"; const layer = getGlLayer({ vertexShaderSource }); jest.spyOn(layer.gl, "shaderSource"); layer.setupVertexShader(); expect(layer.gl.shaderSource).toHaveBeenCalledWith( layer.vertexShader, "vertex" ); }); }); describe("when typeof settings.vertexShaderSource is a string", () => { it("calls gl.shaderSource with it", () => { const vertexShaderSource = "vertex"; const layer = getGlLayer({ vertexShaderSource }); jest.spyOn(layer.gl, "shaderSource"); layer.setupVertexShader(); expect(layer.gl.shaderSource).toHaveBeenCalledWith( layer.vertexShader, "vertex" ); }); }); describe("when vertexShader returns null", () => { it("throws", () => { const layer = getGlLayer(); jest.spyOn(layer.gl, "createShader").mockReturnValue(null); expect(() => { layer.setupVertexShader(); }).toThrow(); }); }); describe("when vertexShaderSource is undefined", () => { it("throws", () => { const layer = getGlLayer({ vertexShaderSource: undefined }); expect(() => { layer.setupVertexShader(); }).toThrow(); }); }); it("calls gl.compileShader with vertexShader", () => { const layer = getGlLayer(); jest.spyOn(layer.gl, "compileShader"); layer.setupVertexShader(); expect(layer.gl.compileShader).toBeCalledWith(layer.vertexShader); }); }); describe("setupFragmentShader", () => { it("sets this.fragmentShader", () => { const layer = getGlLayer(); layer.setupFragmentShader(); expect(layer.fragmentShader).not.toBe(null); }); describe("when typeof settings.fragmentShaderSource is a function", () => { it("calls it, and calls gl.shaderSource with returned value", () => { const fragmentShaderSource = () => "fragment"; const layer = getGlLayer({ fragmentShaderSource }); jest.spyOn(layer.gl, "shaderSource"); layer.setupFragmentShader(); expect(layer.gl.shaderSource).toHaveBeenCalledWith( layer.fragmentShader, "fragment" ); }); }); describe("when typeof settings.fragmentShaderSource is a string", () => { it("calls gl.shaderSource with it", () => { const fragmentShaderSource = "fragment"; const layer = getGlLayer({ fragmentShaderSource }); jest.spyOn(layer.gl, "shaderSource"); layer.setupFragmentShader(); expect(layer.gl.shaderSource).toHaveBeenCalledWith( layer.fragmentShader, "fragment" ); }); }); describe("when fragmentShader returns null", () => { it("throws", () => { const layer = getGlLayer(); jest.spyOn(layer.gl, "createShader").mockReturnValue(null); expect(() => { layer.setupFragmentShader(); }).toThrow(); }); }); describe("when fragmentShaderSource is undefined", () => { it("throws", () => { const layer = getGlLayer({ fragmentShaderSource: undefined }); expect(() => { layer.setupFragmentShader(); }).toThrow(); }); }); it("calls gl.compileShader with fragmentShader", () => { const layer = getGlLayer(); jest.spyOn(layer.gl, "compileShader"); layer.setupFragmentShader(); expect(layer.gl.compileShader).toBeCalledWith(layer.fragmentShader); }); }); describe("setupProgram", () => { describe("when setupProgram returns null", () => { it("throws", () => { const layer = getGlLayer(); jest.spyOn(layer.gl, "createProgram").mockReturnValue(null); expect(() => { layer.setupProgram(); }).toThrow(); }); }); describe("when this.vertexShader null", () => { it("throws", () => { const layer = getGlLayer(); expect(layer.vertexShader).toBe(null); expect(() => { layer.setupProgram(); }).toThrow(); }); }); describe("when this.fragmentShader null", () => { it("throws", () => { const layer = getGlLayer(); layer.setupVertexShader(); expect(layer.fragmentShader).toBe(null); expect(() => { layer.setupProgram(); }).toThrow(); }); }); it("sets this.program from gl.createProgram", () => { const layer = getGlLayer().setupVertexShader().setupFragmentShader(); expect(layer.program).toBe(null); layer.setupProgram(); expect(layer.program).not.toBe(null); }); it("calls attachShader with vertexShader", () => { const layer = getGlLayer().setupVertexShader().setupFragmentShader(); jest.spyOn(layer.gl, "attachShader"); layer.setupProgram(); expect(layer.gl.attachShader).toBeCalledWith( layer.program, layer.vertexShader ); }); it("calls attachShader with fragmentShader", () => { const layer = getGlLayer().setupVertexShader().setupFragmentShader(); jest.spyOn(layer.gl, "attachShader"); layer.setupProgram(); expect(layer.gl.attachShader).toBeCalledWith( layer.program, layer.fragmentShader ); }); it("calls gl.linkProgram with program", () => { const layer = getGlLayer().setupVertexShader().setupFragmentShader(); jest.spyOn(layer.gl, "linkProgram"); layer.setupProgram(); expect(layer.gl.linkProgram).toHaveBeenCalledWith(layer.program); }); it("calls gl.useProgram with program", () => { const layer = getGlLayer().setupVertexShader().setupFragmentShader(); jest.spyOn(layer.gl, "useProgram"); layer.setupProgram(); expect(layer.gl.useProgram).toHaveBeenCalledWith(layer.program); }); it("calls gl.blendFunc with gl.SRC_ALPHA and gl.ONE_MINUS_SRC_ALPHA", () => { const layer = getGlLayer().setupVertexShader().setupFragmentShader(); jest.spyOn(layer.gl, "blendFuncSeparate"); layer.setupProgram(); expect(layer.gl.blendFuncSeparate).toHaveBeenCalledWith( layer.gl.SRC_ALPHA, layer.gl.ONE_MINUS_SRC_ALPHA, layer.gl.ONE, layer.gl.ONE_MINUS_SRC_ALPHA ); }); it("calls gl.enable with gl.BLEND", () => { const layer = getGlLayer().setupVertexShader().setupFragmentShader(); jest.spyOn(layer.gl, "enable"); layer.setupProgram(); expect(layer.gl.enable).toHaveBeenCalledWith(layer.gl.BLEND); }); }); describe("addTo", () => { describe("when map argument is omitted", () => { it("calls this.layer.addTo with this.map", () => { const layer = getGlLayer(); jest.spyOn(layer.layer, "addTo"); layer.addTo(); expect(layer.layer.addTo).toHaveBeenCalledWith(layer.map); }); }); describe("when map argument is present", () => { it("calls this.layer.addTo with map", () => { const element = document.createElement("div"); const map = new Map(element); const layer = getGlLayer(); jest.spyOn(layer.layer, "addTo"); layer.addTo(map); expect(layer.layer.addTo).toHaveBeenCalledWith(map); }); }); it("sets this.active to true", () => { const layer = getGlLayer(); layer.active = false; layer.addTo(); expect(layer.active).toBe(true); }); it("calls and returns this.render", () => { const layer = getGlLayer(); jest.spyOn(layer, "render"); layer.addTo(); expect(layer.render).toHaveBeenCalled(); }); }); describe("remove", () => { describe("when indices argument is undefined", () => { it("calls this.map.removeLayer and sets this.active to false", () => { const layer = getGlLayer(); jest.spyOn(layer.map, "removeLayer"); layer.remove(); expect(layer.map.removeLayer).toHaveBeenCalledWith(layer.layer); expect(layer.active).toBe(false); }); }); describe("when indices argument is a number", () => { it("removes it from the data and calls this.render", () => { const feature1 = {}; const feature2 = {}; const data = { features: [feature1, feature2], }; const layer = getGlLayer({ data }); jest.spyOn(layer, "render"); layer.remove(0); expect(layer.data).toEqual({ features: [feature2] }); expect(layer.render).toHaveBeenCalled(); }); }); describe("when indices argument is a number[]", () => { it("removes them from the data and calls this.render", () => { const feature1 = {}; const feature2 = {}; const feature3 = {}; const data = { features: [feature1, feature2, feature3], }; const layer = getGlLayer({ data }); jest.spyOn(layer, "render"); layer.remove([0, 2]); expect(layer.data).toEqual({ features: [feature2] }); expect(layer.render).toHaveBeenCalled(); }); }); describe("when this.settings.data is an array", () => { it("is used, rather than this.settings.data.features", () => { const feature1 = {}; const feature2 = {}; const data = [feature1, feature2]; const layer = getGlLayer({ data }); layer.remove(0); expect(layer.data).toEqual([feature2]); }); }); }); describe("insert", () => { describe("when data has a features property", () => { it("inserts data into defined index", () => { const feature1 = {}; const feature2 = {}; const feature3 = {}; const data = { features: [feature1, feature3] }; const layer = getGlLayer({ data }); layer.insert(feature2, 1); expect(layer.data).toEqual({ features: [feature1, feature2, feature3], }); }); }); describe("when data is an array", () => { it("inserts data into defined index", () => { const feature1 = {}; const feature2 = {}; const feature3 = {}; const data = [feature1, feature3]; const layer = getGlLayer({ data }); layer.insert(feature2, 1); expect(layer.data).toEqual([feature1, feature2, feature3]); }); }); it("calls this.render()", () => { const data = [{}]; const layer = getGlLayer({ data }); jest.spyOn(layer, "render"); layer.insert({}, 0); expect(layer.render).toHaveBeenCalled(); }); }); describe("update", () => { describe("when data has a features property", () => { it("replaces data at defined index", () => { const feature1 = {}; const feature2 = {}; const feature3 = {}; const data = { features: [feature1, feature3] }; const layer = getGlLayer({ data }); layer.update(feature2, 1); expect(layer.data).toEqual({ features: [feature1, feature2] }); }); }); describe("when data is an array", () => { it("replaces data at defined index", () => { const feature1 = {}; const feature2 = {}; const feature3 = {}; const data = [feature1, feature3]; const layer = getGlLayer({ data }); layer.update(feature2, 1); expect(layer.data).toEqual([feature1, feature2]); }); }); it("calls this.render()", () => { const data = [{}]; const layer = getGlLayer({ data }); jest.spyOn(layer, "render"); layer.update({}, 0); expect(layer.render).toHaveBeenCalled(); }); }); describe("getBuffer", () => { describe("when there is not a buffer on this.buffers with name", () => { it("calls this.gl.createBuffer and sets it on this.buffers", () => { const layer = getGlLayer(); expect(layer.buffers.buffer1).toBeUndefined(); jest.spyOn(layer.gl, "createBuffer"); const buffer = layer.getBuffer("buffer1"); expect(buffer).toBeTruthy(); expect(layer.gl.createBuffer).toHaveBeenCalled(); expect(layer.buffers.buffer1).toBe(buffer); }); describe("when this.gl.createBuffer returns null", () => { it("throws", () => { const layer = getGlLayer(); jest.spyOn(layer.gl, "createBuffer").mockReturnValue(null); expect(() => { layer.getBuffer("buffer1"); }).toThrow(); }); }); }); describe("when there is not a buffer on this.buffers with name", () => { it("returns this.buffers with name", () => { const layer = getGlLayer(); jest.spyOn(layer.gl, "createBuffer"); layer.buffers.buffer1 = new WebGLBuffer(); const buffer = layer.getBuffer("buffer1"); expect(buffer).toBe(layer.buffers.buffer1); expect(layer.gl.createBuffer).not.toHaveBeenCalled(); }); }); }); describe("getAttributeLocation", () => { describe("when this.program is null", () => { it("throws", () => { const layer = getGlLayer(); expect(layer.program).toBe(null); expect(() => { layer.getAttributeLocation("attribute1"); }).toThrow(); }); }); describe("when this.attributeLocations[name] is not defined", () => { it("sets this.attributeLocations[name] and returns the attributeLocation", () => { const layer = getGlLayer(); layer.program = new WebGLProgram(); expect(layer.attributeLocations.attribute1).toBeUndefined(); jest.spyOn(layer.gl, "getAttribLocation"); const attribute = layer.getAttributeLocation("attribute1"); expect(attribute).toBeTruthy(); expect(layer.gl.getAttribLocation).toHaveBeenCalledWith( layer.program, "attribute1" ); expect(layer.attributeLocations.attribute1).toBe(attribute); }); }); }); describe("getUniformLocation", () => { describe("when this.program is null", () => { it("throws", () => { const layer = getGlLayer(); expect(layer.program).toBe(null); expect(() => { layer.getUniformLocation("uniformLocation1"); }).toThrow(); }); }); describe("when this.uniformLocations[name] is not defined", () => { it("sets this.uniformLocations[name] and returns the uniformLocation", () => { const layer = getGlLayer(); layer.program = new WebGLProgram(); expect(layer.uniformLocations.uniformLocation1).toBeUndefined(); jest.spyOn(layer.gl, "getUniformLocation"); const uniformLocation = layer.getUniformLocation("uniformLocation1"); expect(uniformLocation).not.toBeFalsy(); expect(layer.gl.getUniformLocation).toHaveBeenCalledWith( layer.program, "uniformLocation1" ); expect(layer.uniformLocations.uniformLocation1).toBe(uniformLocation); }); }); describe("when this.gl.getUniformLocation returns null", () => { it("throws", () => { const layer = getGlLayer(); jest.spyOn(layer.gl, "getUniformLocation").mockReturnValue(null); expect(() => { layer.getUniformLocation("uniformLocation1"); }).toThrow(); }); }); }); describe("click", () => { describe("when this.settings.click is undefined", () => { it("does not throw", () => { const layer = getGlLayer(); expect(layer.settings.click).toBeUndefined(); expect(() => { layer.click(fakeEvent(layer), {}); }).not.toThrow(); }); }); describe("when this.settings.click is defined", () => { describe("when it does not return a value", () => { it("calls this.settings.click and returns void", () => { const click = jest.fn(() => { return undefined; }); const layer = getGlLayer({ click }); const event = fakeEvent(layer); const feature = {}; const result = layer.click(event, feature); expect(click).toHaveBeenCalledWith(event, feature); expect(result).toBeUndefined(); }); }); describe("when it does return a value", () => { it("calls this.settings.click and returns void", () => { const click = jest.fn(() => { return true; }); const layer = getGlLayer({ click }); const event = fakeEvent(layer); const feature = {}; const result = layer.click(event, feature); expect(click).toHaveBeenCalledWith(event, feature); expect(result).toBeTruthy(); }); }); }); }); describe("hover", () => { describe("when this.settings.hover is undefined", () => { it("does not throw", () => { const layer = getGlLayer(); expect(layer.settings.hover).toBeUndefined(); expect(() => { layer.hover(fakeEvent(layer), {}); }).not.toThrow(); }); }); describe("when this.settings.hover is defined", () => { describe("when it does not return a value", () => { it("calls this.settings.hover and returns void", () => { const hover = jest.fn(() => { return undefined; }); const layer = getGlLayer({ hover }); const event = fakeEvent(layer); const feature = {}; const result = layer.hover(event, feature); expect(hover).toHaveBeenCalledWith(event, feature); expect(result).toBeUndefined(); }); }); describe("when it does return a value", () => { it("calls this.settings.hover and returns void", () => { const hover = jest.fn(() => { return true; }); const layer = getGlLayer({ hover }); const feature = {}; const event = fakeEvent(layer); const result = layer.hover(event, feature); expect(hover).toHaveBeenCalledWith(event, feature); expect(result).toBeTruthy(); }); }); }); }); describe("hoverOff", () => { describe("when this.settings.hoverOff is undefined", () => { it("does not throw", () => { const layer = getGlLayer(); expect(layer.settings.hoverOff).toBeUndefined(); expect(() => { layer.hover(fakeEvent(layer), {}); }).not.toThrow(); }); }); describe("when this.settings.hoverOff is defined", () => { describe("when it does not return a value", () => { it("calls this.settings.hoverOff and returns void", () => { const hoverOff = jest.fn(() => { return undefined; }); const layer = getGlLayer({ hoverOff }); const event = fakeEvent(layer); const feature = {}; layer.hoverOff(event, feature); expect(hoverOff).toHaveBeenCalledWith(event, feature); }); }); }); }); });