This is an automated email from the ASF dual-hosted git repository.
tiagobento pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/incubator-kie-tools.git
The following commit(s) were added to refs/heads/main by this push:
new eb0045d9275 kie-issues#1178: On the DMN Editor's Boxed Expression
Editor, FEEL identifiers with spaces should be treated as non-breaking spaces.
(#2490)
eb0045d9275 is described below
commit eb0045d927513b54d0f4513634481cd965c08baf
Author: Daniel José dos Santos <[email protected]>
AuthorDate: Wed Jul 31 10:15:35 2024 -0300
kie-issues#1178: On the DMN Editor's Boxed Expression Editor, FEEL
identifiers with spaces should be treated as non-breaking spaces. (#2490)
---
.../src/parser/grammar/ParserHelper.ts | 6 +-
packages/feel-input-component/jest.config.js | 30 +++
packages/feel-input-component/package.json | 12 +-
packages/feel-input-component/src/FeelInput.tsx | 103 +---------
.../src/semanticTokensProvider.ts | 168 +++++++++++++++++
.../tests/semanticTokensProvider.test.ts | 207 +++++++++++++++++++++
packages/feel-input-component/tsconfig.tests.json | 3 +
pnpm-lock.yaml | 35 ++--
8 files changed, 453 insertions(+), 111 deletions(-)
diff --git a/packages/dmn-feel-antlr4-parser/src/parser/grammar/ParserHelper.ts
b/packages/dmn-feel-antlr4-parser/src/parser/grammar/ParserHelper.ts
index 7c38be222dd..76c80d65760 100644
--- a/packages/dmn-feel-antlr4-parser/src/parser/grammar/ParserHelper.ts
+++ b/packages/dmn-feel-antlr4-parser/src/parser/grammar/ParserHelper.ts
@@ -186,7 +186,11 @@ export class ParserHelper {
const startLine = _n1.start.line - 1;
const endLine = _n1.stop?.line !== undefined ? _n1.stop.line - 1 :
startLine;
- const variableName = name.replaceAll("\n", "");
+ // Replace line-breaks and multiple blank-spaces, since it is considered
valid in variables names.
+ // Notice that line-brakes behave exactly like blank-spaces, that's why
we're replacing them to blank-spaces.
+ // The Regex is to replace all concatenated blank-spaces to a single one.
For example:
+ // "a b" becomes "a b", because that's how it is handled in the
DMN runner.
+ const variableName = name.replaceAll("\r\n", " ").replaceAll("\n", "
").replace(/\s\s+/g, " ");
if (this.currentScope?.getChildScopes().has(variableName)) {
this.variables.push(
new FeelVariable(start, length, startLine, endLine,
FeelSyntacticSymbolNature.GlobalVariable, variableName)
diff --git a/packages/feel-input-component/jest.config.js
b/packages/feel-input-component/jest.config.js
new file mode 100644
index 00000000000..cd848227e0f
--- /dev/null
+++ b/packages/feel-input-component/jest.config.js
@@ -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,
+ },
+};
diff --git a/packages/feel-input-component/package.json
b/packages/feel-input-component/package.json
index 15d0d15f17c..e3934cec91f 100644
--- a/packages/feel-input-component/package.json
+++ b/packages/feel-input-component/package.json
@@ -8,12 +8,13 @@
"main": "dist/index.js",
"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",
+ "build:prod": "rimraf dist && pnpm copy:css && pnpm lint && tsc -p
tsconfig.json && pnpm test",
"build:showcase": "rimraf ./dist-dev && webpack -c
./showcase/webpack.config.js --env prod",
"copy:css": "copyfiles -u 1 \"src/**/*.{sass,scss,css}\" dist/",
"deploy": "gh-pages -d dist-dev",
"lint": "run-script-if --bool \"$(build-env linters.run)\" --then
\"kie-tools--eslint ./src\"",
- "start": "webpack serve -c ./showcase/webpack.config.js --host 0.0.0.0
--env dev"
+ "start": "webpack serve -c ./showcase/webpack.config.js --host 0.0.0.0
--env dev",
+ "test": "rimraf dist-tests && run-script-if --ignore-errors \"$(build-env
tests.ignoreFailures)\" --bool \"$(build-env tests.run)\" --then \"jest
--silent --verbose --passWithNoTests\""
},
"dependencies": {
"@kie-tools-core/i18n": "workspace:*",
@@ -32,14 +33,21 @@
"@babel/preset-react": "^7.16.0",
"@kie-tools-core/webpack-base": "workspace:*",
"@kie-tools/eslint": "workspace:*",
+ "@kie-tools/jest-base": "workspace:*",
"@kie-tools/root-env": "workspace:*",
"@kie-tools/tsconfig": "workspace:*",
+ "@types/jest": "^29.5.12",
+ "@types/jest-when": "^3.5.5",
"@types/react": "^17.0.6",
"@types/react-dom": "^17.0.5",
"copy-webpack-plugin": "^11.0.0",
"copyfiles": "^2.4.1",
"file-loader": "^6.2.0",
+ "jest": "^29.7.0",
+ "jest-junit": "^16.0.0",
+ "jest-when": "^3.6.0",
"rimraf": "^3.0.2",
+ "ts-jest": "^29.1.5",
"typescript": "^5.5.3",
"webpack": "^5.88.2",
"webpack-cli": "^4.10.0",
diff --git a/packages/feel-input-component/src/FeelInput.tsx
b/packages/feel-input-component/src/FeelInput.tsx
index 9d5bc5e3631..650d7c26d09 100644
--- a/packages/feel-input-component/src/FeelInput.tsx
+++ b/packages/feel-input-component/src/FeelInput.tsx
@@ -30,7 +30,7 @@ import {
} from "./FeelConfigs";
import { FeelSyntacticSymbolNature, FeelVariables, ParsedExpression } from
"@kie-tools/dmn-feel-antlr4-parser";
-import { Element } from "./themes/Element";
+import { SemanticTokensProvider } from "./semanticTokensProvider";
export const EXPRESSION_PROPERTIES_SEPARATOR = ".";
@@ -76,23 +76,6 @@ Monaco.editor.defineTheme(MONACO_FEEL_THEME, feelTheme());
// Don't remove this mechanism. It's necessary for Monaco to initialize
correctly and display correct colors for FEEL.
let __firstTimeInitializingMonacoToEnableColorizingCorrectly = true;
-function getTokenTypeIndex(symbolType: FeelSyntacticSymbolNature) {
- switch (symbolType) {
- default:
- case FeelSyntacticSymbolNature.LocalVariable:
- case FeelSyntacticSymbolNature.GlobalVariable:
- return Element.Variable;
- case FeelSyntacticSymbolNature.DynamicVariable:
- return Element.DynamicVariable;
- case FeelSyntacticSymbolNature.Unknown:
- return Element.UnknownVariable;
- case FeelSyntacticSymbolNature.Invocable:
- return Element.FunctionCall;
- case FeelSyntacticSymbolNature.Parameter:
- return Element.FunctionParameterVariable;
- }
-}
-
export const FeelInput = React.forwardRef<FeelInputRef, FeelInputProps>(
(
{
@@ -115,6 +98,11 @@ export const FeelInput = React.forwardRef<FeelInputRef,
FeelInputProps>(
const [currentParsedExpression, setCurrentParsedExpression] =
useState<ParsedExpression>();
+ const semanticTokensProvider = useMemo(
+ () => new SemanticTokensProvider(feelVariables, expressionId,
setCurrentParsedExpression),
+ [expressionId, feelVariables]
+ );
+
const getLastValidSymbolAtPosition = useCallback((currentParsedExpression:
ParsedExpression, position: number) => {
let lastValidSymbol;
for (let i = 0; i < currentParsedExpression.feelVariables.length; i++) {
@@ -292,84 +280,7 @@ export const FeelInput = React.forwardRef<FeelInputRef,
FeelInputProps>(
const disposable =
Monaco.languages.registerDocumentSemanticTokensProvider(
{ language: MONACO_FEEL_LANGUAGE },
- {
- provideDocumentSemanticTokens: function (model) {
- const tokenTypes = new Array<number>();
-
- if (feelVariables) {
- const text = model.getValue();
- const contentByLines = model.getLinesContent();
- let startOfPreviousToken = 0;
- let previousLine = 0;
- let lineOffset = 0;
- let currentLine = 0;
- const parsedExpression = feelVariables.parser.parse(expressionId
?? "", text);
- setCurrentParsedExpression(parsedExpression);
-
- for (const variable of parsedExpression.feelVariables) {
- if (variable.startLine != currentLine) {
- lineOffset += contentByLines[currentLine].length + 1; // +1
= the line break
- currentLine = variable.startLine;
- }
- variable.startIndex -= lineOffset;
- }
-
- for (const variable of parsedExpression.feelVariables) {
- if (previousLine != variable.startLine) {
- startOfPreviousToken = 0;
- }
- if (variable.startLine === variable.endLine) {
- tokenTypes.push(
- variable.startLine - previousLine, // lineIndex = relative
to the PREVIOUS line
- variable.startIndex - startOfPreviousToken, // columnIndex
= relative to the start of the PREVIOUS token NOT to the start of the line
- variable.length,
- getTokenTypeIndex(variable.feelSymbolNature),
- 0 // token modifier = not used so we keep it 0
- );
-
- previousLine = variable.startLine;
- startOfPreviousToken = variable.startIndex;
- } else {
- tokenTypes.push(
- variable.startLine - previousLine,
- variable.startIndex - startOfPreviousToken,
- variable.length,
- getTokenTypeIndex(variable.feelSymbolNature),
- 0
- );
-
- const length =
- variable.length -
(contentByLines[variable.startLine].length - variable.startIndex + 1); // +1 =
the line break
-
- tokenTypes.push(
- variable.endLine - variable.startLine,
- 0,
- length,
- getTokenTypeIndex(variable.feelSymbolNature),
- 0
- );
-
- startOfPreviousToken = 0;
- previousLine = variable.endLine;
- }
- }
- }
-
- return {
- data: new Uint32Array(tokenTypes),
- resultId: undefined,
- };
- },
- getLegend: function (): Monaco.languages.SemanticTokensLegend {
- return {
- tokenTypes: Object.values(Element).filter((x) => typeof x ===
"string") as string[],
- tokenModifiers: [],
- };
- },
- releaseDocumentSemanticTokens: function (resultId: string |
undefined): void {
- // do nothing
- },
- }
+ semanticTokensProvider
);
return () => {
disposable.dispose();
diff --git a/packages/feel-input-component/src/semanticTokensProvider.ts
b/packages/feel-input-component/src/semanticTokensProvider.ts
new file mode 100644
index 00000000000..9b77c871119
--- /dev/null
+++ b/packages/feel-input-component/src/semanticTokensProvider.ts
@@ -0,0 +1,168 @@
+/*
+ * 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 * as Monaco from "@kie-tools-core/monaco-editor";
+import { Element } from "./themes/Element";
+import { FeelSyntacticSymbolNature, FeelVariables, ParsedExpression } from
"@kie-tools/dmn-feel-antlr4-parser";
+
+export class SemanticTokensProvider implements
Monaco.languages.DocumentSemanticTokensProvider {
+ constructor(
+ private feelVariables: FeelVariables | undefined,
+ private expressionId: string | undefined,
+ private setCurrentParsedExpression: (
+ value: ((prevState: ParsedExpression) => ParsedExpression) |
ParsedExpression
+ ) => void
+ ) {}
+
+ onDidChange?: Monaco.IEvent<void> | undefined;
+
+ getLegend(): Monaco.languages.SemanticTokensLegend {
+ return {
+ tokenTypes: Object.values(Element).filter((x) => typeof x === "string")
as string[],
+ tokenModifiers: [],
+ };
+ }
+
+ provideDocumentSemanticTokens(
+ model: Monaco.editor.ITextModel,
+ lastResultId: string | null,
+ token: Monaco.CancellationToken
+ ): Monaco.languages.ProviderResult<Monaco.languages.SemanticTokens> {
+ const tokenTypes = new Array<number>();
+
+ if (!this.feelVariables) {
+ return;
+ }
+
+ const text = model.getValue().replaceAll("\r\n", "\n");
+ const contentByLines = model.getLinesContent();
+ const parsedExpression = this.feelVariables.parser.parse(this.expressionId
?? "", text);
+
+ // This is to autocomplete, so we don't need to parse it again.
+ this.setCurrentParsedExpression(parsedExpression);
+
+ // The startIndex is set by parse relative to the ENTIRE EXPRESSION.
+ // But, here, we need a startIndex relative to LINE, because that's how
Monaco works.
+ //
+ // For example, consider the expression:
+ // "a" +
+ // "b" + someVar
+ //
+ // To the parser, the index of "someVar" is 13, because it reads the
expression in this format:
+ // "a" + "b" + someVar
+ //
+ // But, here, the real index of "someVar" is 7.
+ //
+ // The code bellow does this calculation fixing the startIndex solved by
the parser to the
+ // startIndex we need here, relative to the LINE where the variable is,
not to the full expression.
+ for (const variable of parsedExpression.feelVariables) {
+ let lineOffset = 0;
+ for (let i = 0; i < variable.startLine; i++) {
+ lineOffset += contentByLines[i].length + 1; // +1 = is the line break
+ }
+ variable.startIndex -= lineOffset;
+ }
+
+ let startOfPreviousVariable = 0;
+ let previousLine = 0;
+ for (const variable of parsedExpression.feelVariables) {
+ if (previousLine != variable.startLine) {
+ startOfPreviousVariable = 0;
+ }
+
+ // It is a variable that it is NOT split in multiple-lines
+ if (variable.startLine === variable.endLine) {
+ tokenTypes.push(
+ variable.startLine - previousLine, // lineIndex = relative to the
PREVIOUS line
+ variable.startIndex - startOfPreviousVariable, // columnIndex =
relative to the start of the PREVIOUS token NOT to the start of the line
+ variable.length,
+ this.getTokenTypeIndex(variable.feelSymbolNature),
+ 0 // token modifier = not used so we keep it 0
+ );
+
+ previousLine = variable.startLine;
+ startOfPreviousVariable = variable.startIndex;
+ } else {
+ // It is a MULTILINE variable.
+ // We colorize the first line of the variable and then other lines.
+ tokenTypes.push(
+ variable.startLine - previousLine,
+ variable.startIndex - startOfPreviousVariable,
+ contentByLines[variable.startLine - previousLine].length -
variable.startIndex,
+ this.getTokenTypeIndex(variable.feelSymbolNature),
+ 0
+ );
+
+ let remainingChars =
+ variable.length - 1 - (contentByLines[variable.startLine -
previousLine].length - variable.startIndex); // -1 = line break
+ const remainingLines = variable.endLine - variable.startLine;
+ let currentLine = variable.startLine + 1;
+
+ // We colorize the remaining lines here. It can be one of the
following cases:
+ // 1. The entire line is part of the variable, colorize the entire
line;
+ // 2. Only a few chars at the start of the currentLine is part of the
variable.
+ for (let i = 0; i < remainingLines; i++) {
+ // We try to colorize everything but, if it overflows the line, it
means that the variable does not end here.
+ let toColorize = remainingChars;
+ if (toColorize > contentByLines[currentLine].length) {
+ toColorize = contentByLines[currentLine].length;
+ }
+
+ tokenTypes.push(1, 0, toColorize,
this.getTokenTypeIndex(variable.feelSymbolNature), 0);
+
+ remainingChars -= toColorize + 1;
+ currentLine++;
+ }
+
+ // We need to track where is the start to previous colorized variable,
because it is used to calculate
+ // where we're going to paint the next variable. Monaco utilizes that
as the index NOT the start of
+ // the line. So, here, we're setting it to 0 because the last painted
"part of the variable"
+ // was painted at position 0 of the line.
+ startOfPreviousVariable = 0;
+ previousLine = variable.endLine;
+ }
+ }
+
+ return {
+ data: new Uint32Array(tokenTypes),
+ resultId: undefined,
+ };
+ }
+
+ releaseDocumentSemanticTokens(resultId: string | undefined): void {
+ // Do nothing
+ }
+
+ private getTokenTypeIndex(symbolType: FeelSyntacticSymbolNature) {
+ switch (symbolType) {
+ default:
+ case FeelSyntacticSymbolNature.LocalVariable:
+ case FeelSyntacticSymbolNature.GlobalVariable:
+ return Element.Variable;
+ case FeelSyntacticSymbolNature.DynamicVariable:
+ return Element.DynamicVariable;
+ case FeelSyntacticSymbolNature.Unknown:
+ return Element.UnknownVariable;
+ case FeelSyntacticSymbolNature.Invocable:
+ return Element.FunctionCall;
+ case FeelSyntacticSymbolNature.Parameter:
+ return Element.FunctionParameterVariable;
+ }
+ }
+}
diff --git a/packages/feel-input-component/tests/semanticTokensProvider.test.ts
b/packages/feel-input-component/tests/semanticTokensProvider.test.ts
new file mode 100644
index 00000000000..3f3c4e8ec8e
--- /dev/null
+++ b/packages/feel-input-component/tests/semanticTokensProvider.test.ts
@@ -0,0 +1,207 @@
+/*
+ * 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 { SemanticTokensProvider } from
"@kie-tools/feel-input-component/dist/semanticTokensProvider";
+import { DmnDefinitions, FeelVariables } from
"@kie-tools/dmn-feel-antlr4-parser";
+
+import * as Monaco from "@kie-tools-core/monaco-editor";
+
+describe("Semantic Tokens Provider", () => {
+ const cancellationTokenMock = {
+ isCancellationRequested: false,
+ onCancellationRequested: jest.fn().mockImplementation(),
+ };
+ describe("long variables with and without line breaks", () => {
+ const knownVariable =
+ "This is a variable with a very long name to reproduce the issue
thousand one hundred and seventy-eight";
+
+ /**
+ * The 'parsedTokens' are the tokens that parser should found in the
provided 'expression'.
+ * The 'expected' are the Monaco Semantic Tokens that we are expecting to
pass to Monaco to paint it on the screen.
+ *
+ * Each Monaco Semantic Tokens is an array of 5 positions
+ * 0 = The start line of the token RELATIVE TO THE PREVIOUS LINE
+ * 1 = The start index of the token relative to the START of the previous
token
+ * 2 = The length of the token
+ * 3 = The type of the token (GlobalVariable, Unknown, Function Parameter,
etc.). It determines the color of the token
+ * 4 = Token modifier. It's always zero since we don't have this feature.
+ */
+ test.each([
+ {
+ expression:
+ 'This is a variable with a very long name to reproduce the issue
thousand one hundred and seventy-eight + "bar"',
+ expected: [[0, 0, 102, 5, 0]],
+ },
+ {
+ expression: `This is a variable with a very long
+name to reproduce the issue thousand
+one hundred and seventy-eight + "bar"`,
+ expected: [
+ [0, 0, 36, 5, 0],
+ [1, 0, 37, 5, 0],
+ [1, 0, 29, 5, 0],
+ ],
+ },
+ {
+ expression: `"aaaaaa" +
+This is a variable with a very
+long name to
+ reproduce the issue thousand
+ one hundred and seventy-eight + "bar" + "NICE" + This is a variable with a
very long name to reproduce the issue thousand one hundred and seventy-eight`,
+ expected: [
+ [1, 0, 31, 5, 0],
+ [1, 0, 12, 5, 0],
+ [1, 0, 30, 5, 0],
+ [1, 0, 30, 5, 0],
+ [0, 50, 102, 5, 0],
+ ],
+ },
+ {
+ expression: `This is a variable with a very long name to
+reproduce
+the issue
+thousand
+one hundred
+and
+seventy-eight + "bar`,
+ expected: [
+ [0, 0, 44, 5, 0],
+ [1, 0, 10, 5, 0],
+ [1, 0, 10, 5, 0],
+ [1, 0, 9, 5, 0],
+ [1, 0, 12, 5, 0],
+ [1, 0, 4, 5, 0],
+ [1, 0, 13, 5, 0],
+ ],
+ },
+ {
+ expression: `"My " + This is a variable with a
very long name to reproduce
+ the issue thousand one hundred and
seventy-eight + "bar"`,
+ expected: [
+ [0, 8, 89, 5, 0],
+ [1, 0, 104, 5, 0],
+ ],
+ },
+ {
+ expression: `This is a variable with a very long name to
+reproduce the issue thousand one hundred and seventy-eight + "bar"`,
+ expected: [
+ [0, 0, 43, 5, 0],
+ [1, 0, 58, 5, 0],
+ ],
+ },
+ {
+ expression: `VeryLongVariableWithoutSpaces
+ThatShouldFailWhenBreakLine`,
+ expected: [
+ [0, 0, 29, 7, 0],
+ [1, 0, 27, 7, 0],
+ ],
+ },
+ ])("multiline variables", async ({ expression, expected }) => {
+ const modelMock = {
+ getValue: jest.fn().mockReturnValue(expression),
+ getLinesContent: jest.fn().mockReturnValue(expression.split("\n")),
+ };
+
+ const id = "expressionId";
+ const dmnDefinitions = getDmnModelWithContextEntry({
+ entry: {
+ variable: knownVariable,
+ expression: {
+ id: id,
+ value: expression,
+ },
+ },
+ });
+
+ const feelVariables = new FeelVariables(dmnDefinitions, new Map());
+ const semanticTokensProvider = new SemanticTokensProvider(feelVariables,
id, () => {});
+
+ const semanticMonacoTokens = await
semanticTokensProvider.provideDocumentSemanticTokens(
+ modelMock as unknown as Monaco.editor.ITextModel,
+ null,
+ cancellationTokenMock
+ );
+
+ const expectedSemanticMonacoTokens = expected.flat();
+
+ for (let i = 0; i < expectedSemanticMonacoTokens.length; i++) {
+
expect(semanticMonacoTokens?.data[i]).toEqual(expectedSemanticMonacoTokens[i]);
+ }
+ });
+ });
+});
+
+function getDmnModelWithContextEntry({
+ entry,
+}: {
+ entry: {
+ variable: string;
+ expression: {
+ value: string;
+ id: string;
+ };
+ };
+}) {
+ // Do not inline this variable for type safety. See
https://github.com/microsoft/TypeScript/issues/241
+ const dmnDefinitions: DmnDefinitions = {
+ "@_name": "DMN_3DB2E0BB-1A3A-4F52-A1F3-A0A5EBCB2C4E",
+ "@_namespace": "dmn",
+ drgElement: [
+ {
+ "@_id": "_5532AD11-7084-4A64-8838-239FBCF9BAF6",
+ __$$element: "decision",
+ "@_name": "Some Decision",
+ expression: {
+ "@_id": "_E15A1DB2-4621-45ED-825C-EBB8669095B2",
+ __$$element: "context",
+ contextEntry: [
+ {
+ "@_id": "_DD2E6BE8-B2AF-452C-A980-8937527FC3F2",
+ variable: {
+ "@_id": "_401F4E2D-442A-4A29-B6B9-906A121C6FC0",
+ "@_name": entry.variable,
+ },
+ expression: {
+ __$$element: "literalExpression",
+ "@_id": "_785F4412-9BD3-4D5A-9A39-E113780390D7",
+ text: { __$$text: "foo" },
+ },
+ },
+ {
+ "@_id": "_4AD499F5-BB34-4BD8-9B9D-DDA3D031AD97",
+ variable: {
+ "@_id": "_4C262520-1AD4-495F-A1BB-9BEB7BDD3841",
+ "@_name": "Test var",
+ },
+ expression: {
+ __$$element: "literalExpression",
+ "@_id": entry.expression.id,
+ text: { __$$text: entry.expression.value },
+ },
+ },
+ ],
+ },
+ },
+ ],
+ };
+
+ return dmnDefinitions;
+}
diff --git a/packages/feel-input-component/tsconfig.tests.json
b/packages/feel-input-component/tsconfig.tests.json
new file mode 100644
index 00000000000..fc8520e7376
--- /dev/null
+++ b/packages/feel-input-component/tsconfig.tests.json
@@ -0,0 +1,3 @@
+{
+ "extends": "./tsconfig.json"
+}
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index e018d23f802..039d5ea6572 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -4245,12 +4245,21 @@ importers:
'@kie-tools/eslint':
specifier: workspace:*
version: link:../eslint
+ '@kie-tools/jest-base':
+ specifier: workspace:*
+ version: link:../jest-base
'@kie-tools/root-env':
specifier: workspace:*
version: link:../root-env
'@kie-tools/tsconfig':
specifier: workspace:*
version: link:../tsconfig
+ '@types/jest':
+ specifier: ^29.5.12
+ version: 29.5.12
+ '@types/jest-when':
+ specifier: ^3.5.5
+ version: 3.5.5
'@types/react':
specifier: ^17.0.6
version: 17.0.21
@@ -4266,9 +4275,21 @@ importers:
file-loader:
specifier: ^6.2.0
version: 6.2.0([email protected]([email protected]))
+ jest:
+ specifier: ^29.7.0
+ version:
29.7.0(@types/[email protected])([email protected])([email protected](@types/[email protected])([email protected]))
+ jest-junit:
+ specifier: ^16.0.0
+ version: 16.0.0
+ jest-when:
+ specifier: ^3.6.0
+ version:
3.6.0([email protected](@types/[email protected])([email protected])([email protected](@types/[email protected])([email protected])))
rimraf:
specifier: ^3.0.2
version: 3.0.2
+ ts-jest:
+ specifier: ^29.1.5
+ version:
29.1.5(@babel/[email protected])(@jest/[email protected])(@jest/[email protected])([email protected](@babel/[email protected]))([email protected](@types/[email protected])([email protected])([email protected](@types/[email protected])([email protected])))([email protected])
typescript:
specifier: ^5.5.3
version: 5.5.3
@@ -22393,10 +22414,6 @@ packages:
resolution: {integrity:
sha512-1WUsZ9R1lA0HtBSohTkm39WTPlNKSJ5iFk7UwqXkBLoHQT+hfqPsfsTDVuZdKGaBwn7din9bS7SsnoAr943hvw==}
engines: {node: '>=10'}
- [email protected]:
- resolution: {integrity:
sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw==}
- engines: {node: '>=8'}
-
[email protected]:
resolution: {integrity:
sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==}
engines: {node: '>=10'}
@@ -33540,7 +33557,7 @@ snapshots:
graceful-fs: 4.2.11
istanbul-lib-coverage: 3.2.0
istanbul-lib-instrument: 6.0.2
- istanbul-lib-report: 3.0.0
+ istanbul-lib-report: 3.0.1
istanbul-lib-source-maps: 4.0.0
istanbul-reports: 3.1.6
jest-message-util: 29.7.0
@@ -40086,7 +40103,7 @@ snapshots:
find-up: 5.0.0
foreground-child: 2.0.0
istanbul-lib-coverage: 3.2.0
- istanbul-lib-report: 3.0.0
+ istanbul-lib-report: 3.0.1
istanbul-reports: 3.1.6
rimraf: 3.0.2
test-exclude: 6.0.0
@@ -44241,12 +44258,6 @@ snapshots:
transitivePeerDependencies:
- supports-color
- [email protected]:
- dependencies:
- istanbul-lib-coverage: 3.2.0
- make-dir: 3.1.0
- supports-color: 7.2.0
-
[email protected]:
dependencies:
istanbul-lib-coverage: 3.2.0
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]