fix: CellOverlay constructor use all parameters to set properties (#159)

The `align` and `verticalAlign` values passed to the constructor weren't
set, so the overlay position was always set to
the default one.

The `align` and `verticalAlign` properties are now using the AlignValue
and VAlignValue types respectively instead of
defining inline types. This improves the consistent in the whole code.

To demonstrate the fix, the Overlays story now set 'align' and
'verticalAlign' randomly.


Also introduce `jest` to test the fix and the whole
implementation of the changed method. Types check support is provided by
`ts-jest`. As maxGraph uses a lot of browser objects, also setup
`jest-jsdom-environment`.
development
Thomas Bouffard 2022-12-16 16:51:51 +01:00 committed by GitHub
parent e730207a3d
commit b7a322b36f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 85 additions and 17 deletions

View File

@ -49,6 +49,9 @@ jobs:
- name: Generate @maxgraph/core types
working-directory: packages/core
run: npm run generate-types
- name: Test @maxgraph/core
working-directory: packages/core
run: npm test
- name: Test TypeScript support
working-directory: packages/ts-support
run: npm test

View File

@ -0,0 +1,40 @@
/*
Copyright 2022-present The maxGraph project Contributors
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
import { describe, expect, test } from '@jest/globals';
import { CellOverlay, Point } from '../../../src';
test('Constructor set all parameters', () => {
const cellOverlay = new CellOverlay(
// @ts-ignore
null,
'my tooltip',
'left',
'middle',
new Point(10, 20),
'custom'
);
expect(cellOverlay).toEqual(
expect.objectContaining({
align: 'left',
cursor: 'custom',
offset: new Point(10, 20),
tooltip: 'my tooltip',
verticalAlign: 'middle',
})
);
});

View File

@ -0,0 +1,6 @@
/** @type {import('ts-jest').JestConfigWithTsJest} */
module.exports = {
// preset: 'ts-jest',
preset: 'ts-jest/presets/default-esm',
testEnvironment: 'jsdom', // need to access to the browser objects
};

View File

@ -22,11 +22,15 @@
"build": "cross-env NODE_ENV=production webpack --mode=production",
"generate-types": "tsc --emitDeclarationOnly",
"generate-esm": "tsc --emitDeclarationOnly false --declaration false --declarationDir null",
"prepack": "run-s generate-types generate-esm build"
"prepack": "run-s generate-types generate-esm build",
"test": "jest"
},
"devDependencies": {
"circular-dependency-plugin": "^5.2.2",
"npm-run-all": "~4.1.5"
"jest": "^29.3.1",
"jest-environment-jsdom": "^29.3.1",
"npm-run-all": "~4.1.5",
"ts-jest": "^29.0.3"
},
"sideEffects": true
}

View File

@ -22,6 +22,7 @@ import EventSource from '../event/EventSource';
import ImageBox from '../image/ImageBox';
import CellState from './CellState';
import ObjectIdentity from '../../util/ObjectIdentity';
import { AlignValue, VAlignValue } from '../../types';
/**
* Extends {@link EventSource} to implement a graph overlay, represented by an icon
@ -77,8 +78,8 @@ class CellOverlay extends EventSource implements ObjectIdentity {
constructor(
image: ImageBox,
tooltip: string | null = null,
align = 'right',
verticalAlign = 'bottom',
align: AlignValue = 'right',
verticalAlign: VAlignValue = 'bottom',
offset: Point = new Point(),
cursor = 'help'
) {
@ -86,6 +87,8 @@ class CellOverlay extends EventSource implements ObjectIdentity {
this.image = image;
this.tooltip = tooltip;
this.align = align;
this.verticalAlign = verticalAlign;
this.offset = offset;
this.cursor = cursor;
}
@ -101,18 +104,20 @@ class CellOverlay extends EventSource implements ObjectIdentity {
tooltip?: string | null;
/**
* Holds the horizontal alignment for the overlay. Default is
* {@link Constants#ALIGN_RIGHT}. For edges, the overlay always appears in the
* center of the edge.
* Holds the horizontal alignment for the overlay.
*
* For edges, the overlay always appears in the center of the edge.
* @default 'right'
*/
align: 'left' | 'center' | 'right' = 'right';
align: AlignValue = 'right';
/**
* Holds the vertical alignment for the overlay. Default is
* {@link Constants#ALIGN_BOTTOM}. For edges, the overlay always appears in the
* center of the edge.
* Holds the vertical alignment for the overlay.
*
* For edges, the overlay always appears in the center of the edge.
* @default 'bottom'
*/
verticalAlign: 'top' | 'middle' | 'bottom' = 'bottom';
verticalAlign: VAlignValue = 'bottom';
/**
* Holds the offset as an {@link Point}. The offset will be scaled according to the
@ -121,7 +126,8 @@ class CellOverlay extends EventSource implements ObjectIdentity {
offset = new Point();
/**
* Holds the cursor for the overlay. Default is 'help'.
* Holds the cursor for the overlay.
* @default 'help'.
*/
cursor = 'help';

View File

@ -54,6 +54,14 @@ const Template = ({ label, ...args }) => {
// Enables tooltips for the overlays
graph.setTooltips(true);
function pickAlignValueRandomly() {
return ['left', 'center', 'right'][Math.floor(Math.random() * 3)];
}
function pickVerticalAlignValueRandomly() {
return ['top', 'bottom'][Math.floor(Math.random() * 2)];
}
// Installs a handler for click events in the graph
// that toggles the overlay for the respective cell
graph.addListener(InternalEvent.CLICK, (sender, evt) => {
@ -61,12 +69,13 @@ const Template = ({ label, ...args }) => {
if (cell != null) {
const overlays = graph.getCellOverlays(cell);
if (overlays.length == 0) {
if (overlays.length === 0) {
// Creates a new overlay with an image and a tooltip
const overlay = new CellOverlay(
new ImageBox('/images/check.png', 16, 16),
'Overlay tooltip'
'Overlay tooltip',
pickAlignValueRandomly(),
pickVerticalAlignValueRandomly()
);
// Installs a handler for clicks on the overlay
@ -104,7 +113,7 @@ const Template = ({ label, ...args }) => {
});
const v2 = graph.insertVertex({
parent,
value: 'Doubleclick',
value: 'Double Click',
position: [200, 150],
size: [100, 40],
});