Skip to content

Commit

Permalink
kie-issues#1376: The width information are not being deleted from DMN…
Browse files Browse the repository at this point in the history
… when the expression is deleted in the new Boxed Expression Editor (apache#2602)
  • Loading branch information
danielzhe committed Sep 23, 2024
1 parent 60c12fe commit 683be53
Show file tree
Hide file tree
Showing 7 changed files with 469 additions and 15 deletions.
30 changes: 30 additions & 0 deletions packages/dmn-editor/jest.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.
*/

const { config, babelTransform, typescriptTransform } = require("@kie-tools/jest-base/jest.config");

/** @type {import('ts-jest').JestConfigWithTsJest} */
module.exports = {
...config,
testEnvironment: "node",
transform: {
...babelTransform,
...typescriptTransform,
},
};
10 changes: 9 additions & 1 deletion packages/dmn-editor/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,14 @@
],
"scripts": {
"build:dev": "rimraf dist && pnpm copy:css && tsc -p tsconfig.json",
"build:prod": "rimraf dist && pnpm copy:css && pnpm lint && tsc -p tsconfig.json && pnpm test-e2e",
"build:prod": "rimraf dist && pnpm copy:css && pnpm lint && tsc -p tsconfig.json && pnpm test-e2e && pnpm test",
"build:storybook": "storybook build -o dist-storybook",
"copy:css": "copyfiles -u 1 \"src/**/*.{sass,scss,css}\" dist/",
"lint": "run-script-if --bool \"$(build-env linters.run)\" --then \"kie-tools--eslint ./src\"",
"start": "run-script-os",
"start:linux:darwin": "cross-env STORYBOOK_PORT=$(build-env dmnEditor.storybook.port) pnpm kie-tools--storybook --storybookArgs=\"dev --no-open\"",
"start:win32": "pnpm powershell \"cross-env STORYBOOK_PORT=$(build-env dmnEditor.storybook.port) pnpm kie-tools--storybook --storybookArgs='dev --no-open'",
"test": "run-script-if --ignore-errors \"$(build-env tests.ignoreFailures)\" --bool \"$(build-env tests.run)\" --then \"jest --silent --verbose --passWithNoTests\"",
"test-e2e": "run-script-if --ignore-errors \"$(build-env endToEndTests.ignoreFailures)\" --bool \"$(build-env endToEndTests.run)\" --then \"pnpm rimraf ./dist-tests-e2e\" \"pnpm test-e2e:run\"",
"test-e2e:open": "pnpm exec playwright show-report dist-tests-e2e/reports",
"test-e2e:run": "pnpm exec playwright test"
Expand Down Expand Up @@ -65,6 +66,7 @@
"@babel/preset-typescript": "^7.22.5",
"@kie-tools-core/webpack-base": "workspace:*",
"@kie-tools/eslint": "workspace:*",
"@kie-tools/jest-base": "workspace:*",
"@kie-tools/playwright-base": "workspace:*",
"@kie-tools/root-env": "workspace:*",
"@kie-tools/storybook-base": "workspace:*",
Expand All @@ -79,6 +81,8 @@
"@storybook/react-webpack5": "^7.3.2",
"@types/d3-drag": "^3.0.3",
"@types/d3-selection": "^3.0.6",
"@types/jest": "^29.5.12",
"@types/jest-when": "^3.5.5",
"@types/lodash": "^4.14.168",
"@types/node": "^20.14.2",
"@types/react": "^17.0.6",
Expand All @@ -89,11 +93,15 @@
"cross-env": "^7.0.3",
"deep-object-diff": "^1.1.9",
"file-loader": "^6.2.0",
"jest": "^29.7.0",
"jest-junit": "^16.0.0",
"jest-when": "^3.6.0",
"lodash": "^4.17.21",
"rimraf": "^3.0.2",
"run-script-os": "^1.1.6",
"start-server-and-test": "^2.0.3",
"storybook": "^7.3.2",
"ts-jest": "^29.1.5",
"typescript": "^5.5.3",
"webpack": "^5.94.0",
"webpack-cli": "^4.10.0",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,6 @@ export function BoxedExpressionScreen({ container }: { container: React.RefObjec
const dmnEditorStoreApi = useDmnEditorStoreApi();

const thisDmn = useDmnEditorStore((s) => s.dmn);
const diagram = useDmnEditorStore((s) => s.diagram);

const activeDrgElementId = useDmnEditorStore((s) => s.boxedExpressionEditor.activeDrgElementId);
const isPropertiesPanelOpen = useDmnEditorStore((s) => s.boxedExpressionEditor.propertiesPanel.isOpen);
Expand Down
15 changes: 2 additions & 13 deletions packages/dmn-editor/src/mutations/updateExpressionWidths.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,20 +30,9 @@ export function updateExpressionWidths({
drdIndex: number;
widthsById: Map<string, number[]>;
}): void {
const { widthsExtension, widths } = addOrGetDrd({ definitions, drdIndex });
const componentWidthsMap = widths.reduce(
(acc, e) =>
e["@_dmnElementRef"]
? acc.set(
e["@_dmnElementRef"],
(e["kie:width"] ?? []).map((vv) => vv.__$$text)
)
: acc,
new Map<string, number[]>()
);
const { widthsExtension } = addOrGetDrd({ definitions, drdIndex });

widthsById.forEach((v, k) => componentWidthsMap.set(k, v));
widthsExtension["kie:ComponentWidths"] = [...componentWidthsMap.entries()].map(([k, v]) => ({
widthsExtension["kie:ComponentWidths"] = [...widthsById.entries()].map(([k, v]) => ({
"@_dmnElementRef": k,
"kie:width": v.map((vv) => ({ __$$text: vv })),
}));
Expand Down
242 changes: 242 additions & 0 deletions packages/dmn-editor/tests/mutations/updateExpressionWidth.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,242 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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 { Normalized } from "@kie-tools/dmn-editor/dist/normalization/normalize";
import { DMN15__tDefinitions } from "@kie-tools/dmn-marshaller/dist/schemas/dmn-1_5/ts-gen/types";
import { generateUuid } from "@kie-tools/boxed-expression-component/dist/api";
import { KIE__tComponentsWidthsExtension } from "@kie-tools/dmn-marshaller/dist/schemas/kie-1_0/ts-gen/types";
import { updateExpressionWidths } from "@kie-tools/dmn-editor/dist/mutations/updateExpressionWidths";

describe("updateExpressionWidth", () => {
const drdIndex = 0;

test("when a definition is deleted from widthsFromId map, it should also be deleted from definitions", () => {
const widthEntryForElementA = { dmnElementRef: "a", widths: [10, 150, 110] };
const widthEntryForElementB = { dmnElementRef: "b", widths: [20, 250, 210] };
const widthEntryForElementC = { dmnElementRef: "c", widths: [30, 350, 310] };
const widthEntryForElementD = { dmnElementRef: "d", widths: [40, 450, 410] };

const definitions = createDefinitionsWithComponentWidths([
widthEntryForElementA,
widthEntryForElementB,
widthEntryForElementC,
widthEntryForElementD,
]);

const widthsById: Map<string, number[]> = new Map([
[widthEntryForElementA.dmnElementRef, widthEntryForElementA.widths],
[widthEntryForElementB.dmnElementRef, widthEntryForElementB.widths],
[widthEntryForElementC.dmnElementRef, widthEntryForElementC.widths],
]);

updateExpressionWidths({ definitions, drdIndex, widthsById });

expect(
definitionContainsWidthExtension({
widthEntry: widthEntryForElementA,
definitions: definitions,
})
).toBeTruthy();

expect(
definitionContainsWidthExtension({
widthEntry: widthEntryForElementB,
definitions: definitions,
})
).toBeTruthy();

expect(
definitionContainsWidthExtension({
widthEntry: widthEntryForElementC,
definitions: definitions,
})
).toBeTruthy();

expect(
definitionContainsWidthExtension({
widthEntry: widthEntryForElementD,
definitions: definitions,
})
).toBeFalsy();
});

test("when a definition is changed in widthsFromId map, it should be changed in definitions", () => {
const originalWidthEntryForElementA = { dmnElementRef: "a", widths: [1, 1, 1] };
const originalWidthEntryForElementB = { dmnElementRef: "b", widths: [2, 2, 2] };
const originalWidthEntryForElementC = { dmnElementRef: "c", widths: [3, 3, 3] };

const changedWidthEntryForElementA = { dmnElementRef: "a", widths: [11, 11, 11, 11, 11] };
const changedWidthEntryForElementB = { dmnElementRef: "b", widths: [20, 20, 20] };
const changedWidthEntryForElementC = { dmnElementRef: "c", widths: [3, 3] };

const definitions = createDefinitionsWithComponentWidths([
originalWidthEntryForElementA,
originalWidthEntryForElementB,
originalWidthEntryForElementC,
]);

const widthsById: Map<string, number[]> = new Map([
[changedWidthEntryForElementA.dmnElementRef, changedWidthEntryForElementA.widths],
[changedWidthEntryForElementB.dmnElementRef, changedWidthEntryForElementB.widths],
[changedWidthEntryForElementC.dmnElementRef, changedWidthEntryForElementC.widths],
]);

updateExpressionWidths({ definitions, drdIndex, widthsById });

expect(
definitionContainsWidthExtension({
widthEntry: originalWidthEntryForElementA,
definitions: definitions,
})
).toBeFalsy();

expect(
definitionContainsWidthExtension({
widthEntry: originalWidthEntryForElementB,
definitions: definitions,
})
).toBeFalsy();

expect(
definitionContainsWidthExtension({
widthEntry: originalWidthEntryForElementC,
definitions: definitions,
})
).toBeFalsy();

expect(
definitionContainsWidthExtension({
widthEntry: changedWidthEntryForElementA,
definitions: definitions,
})
).toBeTruthy();

expect(
definitionContainsWidthExtension({
widthEntry: changedWidthEntryForElementB,
definitions: definitions,
})
).toBeTruthy();

expect(
definitionContainsWidthExtension({
widthEntry: changedWidthEntryForElementC,
definitions: definitions,
})
).toBeTruthy();
});

test("when a definition is added in widthsFromId map, it should also be added in definitions", () => {
const originalWidthEntryForElementA = { dmnElementRef: "a", widths: [1, 1, 1] };
const originalWidthEntryForElementB = { dmnElementRef: "b", widths: [2, 2, 2] };

const newWidthEntry = { dmnElementRef: "c", widths: [3, 3] };

const definitions = createDefinitionsWithComponentWidths([
originalWidthEntryForElementA,
originalWidthEntryForElementB,
]);

const widthsById: Map<string, number[]> = new Map([
[originalWidthEntryForElementA.dmnElementRef, originalWidthEntryForElementA.widths],
[originalWidthEntryForElementB.dmnElementRef, originalWidthEntryForElementB.widths],
[newWidthEntry.dmnElementRef, newWidthEntry.widths],
]);

updateExpressionWidths({ definitions, drdIndex, widthsById });

expect(
definitionContainsWidthExtension({
widthEntry: originalWidthEntryForElementA,
definitions: definitions,
})
).toBeTruthy();

expect(
definitionContainsWidthExtension({
widthEntry: originalWidthEntryForElementB,
definitions: definitions,
})
).toBeTruthy();

expect(
definitionContainsWidthExtension({
widthEntry: newWidthEntry,
definitions: definitions,
})
).toBeTruthy();
});
});

function definitionContainsWidthExtension(args: {
widthEntry: { dmnElementRef: string; widths: number[] };
definitions: Normalized<DMN15__tDefinitions>;
}) {
const componentsWidthExtension =
args.definitions?.["dmndi:DMNDI"]?.["dmndi:DMNDiagram"]?.[0]["di:extension"]?.["kie:ComponentsWidthsExtension"];

const element = {
"@_dmnElementRef": args.widthEntry.dmnElementRef,
"kie:width": args.widthEntry.widths.map((w) => {
return { __$$text: w };
}),
};

return componentsWidthExtension?.["kie:ComponentWidths"]?.find(
(e) =>
e["@_dmnElementRef"] === element["@_dmnElementRef"] &&
e["kie:width"]?.length === element["kie:width"].length &&
e["kie:width"]?.every((val, index) => val.__$$text === element["kie:width"]?.[index].__$$text)
);
}

function createDefinitionsWithComponentWidths(widthDefinition: { dmnElementRef: string; widths: number[] }[]) {
// Do not inline this variable for type safety. See https://github.com/microsoft/TypeScript/issues/241
const definitions: Normalized<DMN15__tDefinitions> = {
"@_namespace": "https://kie.org/dmn/_982CA10C-B1B9-495C-9CFC-98FAA801BB50",
"@_id": generateUuid(),
"@_name": "my definitions",
"dmndi:DMNDI": {
"dmndi:DMNDiagram": [
{
"@_id": generateUuid(),
"di:extension": createComponentWidthExtension(widthDefinition),
},
],
},
};
return definitions;
}

function createComponentWidthExtension(widthDefinition: { dmnElementRef: string; widths: number[] }[]) {
// Do not inline this variable for type safety. See https://github.com/microsoft/TypeScript/issues/241
const componentsWidthsExtension: KIE__tComponentsWidthsExtension = {
ComponentWidths: [
...widthDefinition.map((w) => {
return {
"@_dmnElementRef": w.dmnElementRef,
width: w.widths.map((w) => {
return { __$$text: w };
}),
};
}),
],
};
return componentsWidthsExtension;
}
3 changes: 3 additions & 0 deletions packages/dmn-editor/tsconfig.tests.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"extends": "./tsconfig.json"
}
Loading

0 comments on commit 683be53

Please sign in to comment.