This is an automated email from the ASF dual-hosted git repository.

luigidemasi pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel.git

commit 05f2482ab839b4f2596126eff40b81c3665485f8
Author: Luigi De Masi <[email protected]>
AuthorDate: Thu Sep 24 12:49:29 2026 +0200

    CAMEL-24977: Refine semantic YAML diagnostics and completion coverage
    
    Use the common YAML enum parser while preserving question and field context.
    Leave malformed top-level entries to the route loader without replacing
    existing semantic definitions. Restore the inheritance-processing guard;
    regenerated schemas remain unchanged.
    
    Pin the Bean EIP versus Bean Method language metadata distinction and 
exercise
    TUI key/value completion through real ancestor paths and encoded map keys.
    Document the internal completion context format and link semantic examples
    to the TypeSafe AI component, YAML DSL and relevant EIPs.
    
    Co-authored-by: Codex <[email protected]>
    Signed-off-by: Luigi De Masi <[email protected]>
---
 .../camel/catalog/docs/semantic-language.adoc      | 11 +++---
 .../src/main/docs/semantic-language.adoc           | 11 +++---
 .../yaml/SemanticDefinitionDeserializer.java       | 16 +++++----
 .../jbang/core/commands/tui/SourceEditAssist.java  |  4 +--
 .../dsl/jbang/core/commands/tui/SourceViewer.java  |  2 +-
 .../core/commands/tui/SemanticCompletionTest.java  | 21 +++++++++---
 .../maven/dsl/yaml/GenerateYamlSchemaMojo.java     |  4 ++-
 .../camel/dsl/yaml/SemanticQuestionTest.java       | 39 ++++++++++++++++++++--
 .../camel/dsl/yaml/YamlCompletionTreeTest.java     | 12 +++++++
 9 files changed, 93 insertions(+), 27 deletions(-)

diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/semantic-language.adoc
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/semantic-language.adoc
index 3eddbfba958f..187ad719cdf8 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/semantic-language.adoc
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/semantic-language.adoc
@@ -16,8 +16,9 @@ inference runs. Provider errors propagate through normal 
Camel error handling.
 
 == Dependencies and providers
 
-Add `org.apache.camel:camel-semantic` and a provider, such as 
`camel-typesafe-ai`, using the
-same Camel version. The provider owns credentials, model selection, request 
timeout,
+Add `org.apache.camel:camel-semantic` and a provider, such as
+xref:ROOT:typesafe-ai-component.adoc[TypeSafe AI] (`camel-typesafe-ai`), using 
the same Camel version.
+The provider owns credentials, model selection, request timeout,
 concurrency limits and transport resources. TypeSafe AI uses
 `camel.component.typesafe-ai.*` settings even when a route contains no 
TypeSafe AI endpoint.
 
@@ -38,7 +39,7 @@ until generic-language starter configuration is available.
 
 == Named questions
 
-The YAML DSL supports declarations alongside routes, including declarations 
after their use:
+The xref:others:yaml-dsl.adoc[YAML DSL] supports declarations alongside 
routes, including declarations after their use:
 
 [source,yaml]
 ----
@@ -174,7 +175,7 @@ from("direct:tag")
         .otherwise().to("direct:technical");
 ----
 
-Storing the category before Choice performs one semantic evaluation each time 
execution
+Storing the category before xref:eips:choice-eip.adoc[Choice] performs one 
semantic evaluation each time execution
 reaches that Set Header or Set Property step. The branches compare the stored 
result without
 calling the provider again. Place that step inside a loop when the decision 
must be refreshed
 on each iteration. Nested decisions can use separate properties to retain 
their own results.
@@ -183,7 +184,7 @@ the existing EIP model and work with the Java, XML and YAML 
DSLs.
 
 === Aggregation and destinations
 
-For Java APIs accepting an `Expression`, use
+For xref:eips:aggregate-eip.adoc[Aggregate] and other Java APIs accepting an 
`Expression`, use
 `new LanguageExpression("semantic", "ref:department")` from 
`org.apache.camel.model.language`.
 For example, group messages with that expression and a 
`GroupedBodyAggregationStrategy`,
 using `completionSize(10)` and `completionTimeout(5000)` to bound the group. 
Include a trusted
diff --git 
a/components/camel-ai/camel-semantic/src/main/docs/semantic-language.adoc 
b/components/camel-ai/camel-semantic/src/main/docs/semantic-language.adoc
index 3eddbfba958f..187ad719cdf8 100644
--- a/components/camel-ai/camel-semantic/src/main/docs/semantic-language.adoc
+++ b/components/camel-ai/camel-semantic/src/main/docs/semantic-language.adoc
@@ -16,8 +16,9 @@ inference runs. Provider errors propagate through normal 
Camel error handling.
 
 == Dependencies and providers
 
-Add `org.apache.camel:camel-semantic` and a provider, such as 
`camel-typesafe-ai`, using the
-same Camel version. The provider owns credentials, model selection, request 
timeout,
+Add `org.apache.camel:camel-semantic` and a provider, such as
+xref:ROOT:typesafe-ai-component.adoc[TypeSafe AI] (`camel-typesafe-ai`), using 
the same Camel version.
+The provider owns credentials, model selection, request timeout,
 concurrency limits and transport resources. TypeSafe AI uses
 `camel.component.typesafe-ai.*` settings even when a route contains no 
TypeSafe AI endpoint.
 
@@ -38,7 +39,7 @@ until generic-language starter configuration is available.
 
 == Named questions
 
-The YAML DSL supports declarations alongside routes, including declarations 
after their use:
+The xref:others:yaml-dsl.adoc[YAML DSL] supports declarations alongside 
routes, including declarations after their use:
 
 [source,yaml]
 ----
@@ -174,7 +175,7 @@ from("direct:tag")
         .otherwise().to("direct:technical");
 ----
 
-Storing the category before Choice performs one semantic evaluation each time 
execution
+Storing the category before xref:eips:choice-eip.adoc[Choice] performs one 
semantic evaluation each time execution
 reaches that Set Header or Set Property step. The branches compare the stored 
result without
 calling the provider again. Place that step inside a loop when the decision 
must be refreshed
 on each iteration. Nested decisions can use separate properties to retain 
their own results.
@@ -183,7 +184,7 @@ the existing EIP model and work with the Java, XML and YAML 
DSLs.
 
 === Aggregation and destinations
 
-For Java APIs accepting an `Expression`, use
+For xref:eips:aggregate-eip.adoc[Aggregate] and other Java APIs accepting an 
`Expression`, use
 `new LanguageExpression("semantic", "ref:department")` from 
`org.apache.camel.model.language`.
 For example, group messages with that expression and a 
`GroupedBodyAggregationStrategy`,
 using `completionSize(10)` and `completionTimeout(5000)` to bound the group. 
Include a trusted
diff --git 
a/components/camel-ai/camel-semantic/src/main/java/org/apache/camel/semantic/yaml/SemanticDefinitionDeserializer.java
 
b/components/camel-ai/camel-semantic/src/main/java/org/apache/camel/semantic/yaml/SemanticDefinitionDeserializer.java
index a849031c2f2b..b4f049f8aca5 100644
--- 
a/components/camel-ai/camel-semantic/src/main/java/org/apache/camel/semantic/yaml/SemanticDefinitionDeserializer.java
+++ 
b/components/camel-ai/camel-semantic/src/main/java/org/apache/camel/semantic/yaml/SemanticDefinitionDeserializer.java
@@ -18,7 +18,6 @@ package org.apache.camel.semantic.yaml;
 
 import java.util.LinkedHashMap;
 import java.util.List;
-import java.util.Locale;
 import java.util.Map;
 import java.util.Set;
 
@@ -26,6 +25,7 @@ import org.apache.camel.CamelContext;
 import org.apache.camel.dsl.yaml.common.YamlDeserializationContext;
 import org.apache.camel.dsl.yaml.common.YamlDeserializerResolver;
 import org.apache.camel.dsl.yaml.common.YamlDeserializerSupport;
+import org.apache.camel.dsl.yaml.common.exception.InvalidEnumException;
 import org.apache.camel.dsl.yaml.common.exception.YamlDeserializationException;
 import org.apache.camel.semantic.SemanticQuestion;
 import org.apache.camel.semantic.SemanticQuestions;
@@ -34,6 +34,7 @@ import org.apache.camel.spi.annotations.YamlIn;
 import org.apache.camel.spi.annotations.YamlProperty;
 import org.apache.camel.spi.annotations.YamlType;
 import org.snakeyaml.engine.v2.api.ConstructNode;
+import org.snakeyaml.engine.v2.nodes.MappingNode;
 import org.snakeyaml.engine.v2.nodes.Node;
 import org.snakeyaml.engine.v2.nodes.NodeTuple;
 import org.snakeyaml.engine.v2.nodes.SequenceNode;
@@ -69,7 +70,11 @@ public class SemanticDefinitionDeserializer extends 
YamlDeserializerSupport impl
         }
         Map<String, SemanticQuestion> definitions = new LinkedHashMap<>();
         for (Node node : sequence.getValue()) {
-            for (NodeTuple tuple : asMappingNode(node).getValue()) {
+            if (!(node instanceof MappingNode mapping)) {
+                // Leave malformed entries to the route loader without 
replacing the resource's questions.
+                return;
+            }
+            for (NodeTuple tuple : mapping.getValue()) {
                 if ("semantic".equals(asText(tuple.getKeyNode()))) {
                     read(tuple.getValueNode()).forEach((name, question) -> {
                         if (definitions.putIfAbsent(name, question) != null) {
@@ -151,12 +156,11 @@ public class SemanticDefinitionDeserializer extends 
YamlDeserializerSupport impl
     }
 
     private static <T extends Enum<T>> T enumeration(Node node, String 
question, String field, Class<T> type) {
-        String raw = asText(node);
         try {
-            return Enum.valueOf(type, raw.replace('-', 
'_').toUpperCase(Locale.ROOT));
-        } catch (IllegalArgumentException e) {
+            return asEnum(node, type);
+        } catch (InvalidEnumException e) {
             throw new YamlDeserializationException(
-                    node, "Invalid value for '" + field + "' in semantic 
question '" + question + "': " + raw, e);
+                    node, "Invalid value for '" + field + "' in semantic 
question '" + question + "': " + asText(node), e);
         }
     }
 
diff --git 
a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/SourceEditAssist.java
 
b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/SourceEditAssist.java
index 8b7085f8f401..ca1c8e260148 100644
--- 
a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/SourceEditAssist.java
+++ 
b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/SourceEditAssist.java
@@ -1063,7 +1063,7 @@ final class SourceEditAssist {
     }
 
     List<AutocompletePopup.CompletionItem> provideTreeCompletions(String 
contextAfterPrefix) {
-        // context format: "nodeName" or 
"nodeName:existingKey1,existingKey2,..."
+        // The node is a name or slash-separated path with URL-encoded keys, 
optionally followed by :existingKey1,...
         String[] parts = contextAfterPrefix.split(":", 2);
         String nodeName = parts[0];
 
@@ -1120,7 +1120,7 @@ final class SourceEditAssist {
     }
 
     List<AutocompletePopup.CompletionItem> provideTreeValueCompletions(String 
contextAfterPrefix) {
-        // context format: "nodeName:optionName"
+        // The node is a name or slash-separated path with URL-encoded keys, 
followed by :optionName.
         String[] parts = contextAfterPrefix.split(":", 2);
         if (parts.length < 2) {
             return List.of();
diff --git 
a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/SourceViewer.java
 
b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/SourceViewer.java
index 61427ee054d2..1bdb50ecff74 100644
--- 
a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/SourceViewer.java
+++ 
b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/SourceViewer.java
@@ -1104,7 +1104,7 @@ class SourceViewer {
             return;
         }
 
-        // tree-driven completion — walk up to find parent key, use completion 
tree
+        // Tree completion uses the full YAML path so named map entries retain 
their schema context.
         if (autocompleteProvider != null) {
             String parentKey = yaml.findParentYamlKey(row);
             String parentPath = yaml.findParentYamlPath(row);
diff --git 
a/dsl/camel-jbang/camel-jbang-plugin-tui/src/test/java/org/apache/camel/dsl/jbang/core/commands/tui/SemanticCompletionTest.java
 
b/dsl/camel-jbang/camel-jbang-plugin-tui/src/test/java/org/apache/camel/dsl/jbang/core/commands/tui/SemanticCompletionTest.java
index 98934f8df4e4..8e860df56d4b 100644
--- 
a/dsl/camel-jbang/camel-jbang-plugin-tui/src/test/java/org/apache/camel/dsl/jbang/core/commands/tui/SemanticCompletionTest.java
+++ 
b/dsl/camel-jbang/camel-jbang-plugin-tui/src/test/java/org/apache/camel/dsl/jbang/core/commands/tui/SemanticCompletionTest.java
@@ -21,6 +21,8 @@ import java.util.concurrent.atomic.AtomicReference;
 
 import dev.tamboui.widgets.input.TextAreaState;
 import org.junit.jupiter.api.Test;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.CsvSource;
 
 import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.junit.jupiter.api.Assertions.assertFalse;
@@ -34,12 +36,13 @@ class SemanticCompletionTest {
                         new AtomicReference<List<InfraInfo>>(List.of())));
     }
 
-    @Test
-    void completionFollowsNamedQuestionMapAndOffersVariantFields() {
-        TextAreaState state = new TextAreaState("- semantic:\n    question:\n  
    department:\n        ");
+    @ParameterizedTest
+    @CsvSource({ "department,/semantic/question/department", 
"support/team,/semantic/question/support%2Fteam" })
+    void completionFollowsNamedQuestionMapAndOffersVariantFields(String 
question, String expectedPath) {
+        TextAreaState state = new TextAreaState("- semantic:\n    question:\n  
    " + question + ":\n        ");
         SourceEditorNavigation.positionCursor(state, 3, 8);
         String path = new YamlSourceContext(state).findParentYamlPath(3);
-        assertEquals("/semantic/question/department", path);
+        assertEquals(expectedPath, path);
         SourceEditAssist assist = assist();
         List<String> keys = 
assist.provideTreeCompletions(path).stream().map(AutocompletePopup.CompletionItem::key).toList();
         assertTrue(keys.containsAll(List.of("type", "instructions", "state", 
"criteria", "threshold", "uncertaintyPolicy")),
@@ -54,7 +57,15 @@ class SemanticCompletionTest {
 
     @Test
     void ordinaryRouteCompletionStillResolvesThroughItsAncestors() {
+        TextAreaState state = new TextAreaState(
+                "- route:\n    from:\n      uri: direct:start\n      steps:\n  
      - log:\n            ");
+        SourceEditorNavigation.positionCursor(state, 5, 12);
+        String path = new YamlSourceContext(state).findParentYamlPath(5);
+        assertEquals("/route/from/steps/log", path);
         SourceEditAssist assist = assist();
-        assertEquals(assist.provideTreeCompletions("log"), 
assist.provideTreeCompletions("/route/from/steps/log"));
+        assertEquals(assist.provideTreeCompletions("log"), 
assist.provideTreeCompletions(path));
+        assertEquals(assist.provideTreeValueCompletions("log:loggingLevel"),
+                assist.provideTreeValueCompletions(path + ":loggingLevel"));
+        assertFalse(assist.provideTreeValueCompletions(path + 
":loggingLevel").isEmpty());
     }
 }
diff --git 
a/dsl/camel-yaml-dsl/camel-yaml-dsl-maven-plugin/src/main/java/org/apache/camel/maven/dsl/yaml/GenerateYamlSchemaMojo.java
 
b/dsl/camel-yaml-dsl/camel-yaml-dsl-maven-plugin/src/main/java/org/apache/camel/maven/dsl/yaml/GenerateYamlSchemaMojo.java
index d7a3e141537a..a8b7f029af42 100644
--- 
a/dsl/camel-yaml-dsl/camel-yaml-dsl-maven-plugin/src/main/java/org/apache/camel/maven/dsl/yaml/GenerateYamlSchemaMojo.java
+++ 
b/dsl/camel-yaml-dsl/camel-yaml-dsl-maven-plugin/src/main/java/org/apache/camel/maven/dsl/yaml/GenerateYamlSchemaMojo.java
@@ -168,7 +168,9 @@ public class GenerateYamlSchemaMojo extends 
GenerateYamlSupportMojo {
         kebabToCamelCase(step);
         kebabToCamelCase(root.withObject("/items"));
 
-        postProcessInheritance(inheritedDefinitions, inlineDefinitions);
+        if (!inheritedDefinitions.isEmpty()) {
+            postProcessInheritance(inheritedDefinitions, inlineDefinitions);
+        }
 
         try {
             ToolingSupport.mkparents(outputFile);
diff --git 
a/dsl/camel-yaml-dsl/camel-yaml-dsl/src/test/java/org/apache/camel/dsl/yaml/SemanticQuestionTest.java
 
b/dsl/camel-yaml-dsl/camel-yaml-dsl/src/test/java/org/apache/camel/dsl/yaml/SemanticQuestionTest.java
index 97031b07a3f9..639141d0dc06 100644
--- 
a/dsl/camel-yaml-dsl/camel-yaml-dsl/src/test/java/org/apache/camel/dsl/yaml/SemanticQuestionTest.java
+++ 
b/dsl/camel-yaml-dsl/camel-yaml-dsl/src/test/java/org/apache/camel/dsl/yaml/SemanticQuestionTest.java
@@ -23,6 +23,7 @@ import java.util.concurrent.atomic.AtomicInteger;
 import java.util.stream.Stream;
 
 import org.apache.camel.component.mock.MockEndpoint;
+import org.apache.camel.dsl.yaml.common.exception.InvalidEnumException;
 import org.apache.camel.dsl.yaml.common.exception.YamlDeserializationException;
 import org.apache.camel.dsl.yaml.support.YamlTestSupport;
 import org.apache.camel.language.semantic.SemanticLanguage;
@@ -167,6 +168,24 @@ class SemanticQuestionTest extends YamlTestSupport {
         assertThatThrownBy(() -> 
SemanticQuestions.get(context).get("department")).hasMessageContaining("Unknown");
     }
 
+    @ParameterizedTest
+    @MethodSource("malformedTopLevelResources")
+    void malformedTopLevelEntriesUseNormalLoaderErrorsAndKeepQuestions(String 
yaml) throws Exception {
+        loadRoutes(ResourceHelper.fromString("questions.yaml", 
declarations("${body}")));
+        context.start();
+        SemanticQuestion original = 
SemanticQuestions.get(context).get("department");
+        assertThatThrownBy(() -> PluginHelper.getRoutesLoader(context)
+                .updateRoutes(ResourceHelper.fromString("questions.yaml", 
yaml)))
+                .isInstanceOf(YamlDeserializationException.class)
+                .hasMessageContaining("Unable to find constructor for node");
+        
assertThat(SemanticQuestions.get(context).get("department")).isSameAs(original);
+    }
+
+    static Stream<String> malformedTopLevelResources() {
+        return Stream.of("- invalid\n", "- []\n")
+                .flatMap(entry -> Stream.of(entry, 
declarations("${header.updated}") + entry));
+    }
+
     @Test
     void watcherDropsDeletedQuestionOnlyResourcesBeforeLoadingRenamedFiles() 
throws Exception {
         Path original = directory.resolve("questions.yaml");
@@ -203,7 +222,7 @@ class SemanticQuestionTest extends YamlTestSupport {
         assertThatThrownBy(() -> 
loadRoutesNoValidate(declarations("${body}").replace("instructions:", "typo:")))
                 .hasStackTraceContaining("Unknown property");
         assertThatThrownBy(() -> 
loadRoutesNoValidate(declarations("${body}").replace("type: choice", "type: 
unsupported")))
-                
.hasRootCauseInstanceOf(IllegalArgumentException.class).hasStackTraceContaining("UNSUPPORTED");
+                
.hasRootCauseInstanceOf(InvalidEnumException.class).hasStackTraceContaining("unsupported");
         assertThatThrownBy(() -> loadRoutesNoValidate(declarations("${body}")
                 .replace("instructions:", "uncertainty-policy: fail\n        
instructions:")))
                 .hasStackTraceContaining("Unknown property");
@@ -270,7 +289,7 @@ class SemanticQuestionTest extends YamlTestSupport {
         String source = yaml;
         assertThatThrownBy(() -> loadRoutesNoValidate(source))
                 .hasMessageContaining("route-0.yaml")
-                .hasRootCauseInstanceOf(IllegalArgumentException.class)
+                .hasRootCauseInstanceOf(InvalidEnumException.class)
                 
.cause().isInstanceOfSatisfying(YamlDeserializationException.class, error -> {
                     assertThat(error).hasMessageContaining("Invalid value for 
'" + field + "' in semantic question 'spam'");
                     assertThat(error.getProblemMark()).hasValueSatisfying(mark 
-> {
@@ -289,6 +308,22 @@ class SemanticQuestionTest extends YamlTestSupport {
                 Arguments.of("uncertaintyPolicy", "null", 5));
     }
 
+    @ParameterizedTest
+    @ValueSource(strings = { "non-match", "NON_MATCH", "nonMatch" })
+    void enumParsingFollowsYamlDslConventions(String policy) throws Exception {
+        loadRoutesNoValidate("""
+                - semantic:
+                    question:
+                      spam:
+                        type: BoOlEaN
+                        instructions: Is this spam?
+                        uncertaintyPolicy: %s
+                """.formatted(policy));
+        SemanticQuestion question = SemanticQuestions.get(context).get("spam");
+        
assertThat(question.getType()).isEqualTo(SemanticQuestion.Type.BOOLEAN);
+        
assertThat(question.getUncertaintyPolicy()).isEqualTo(SemanticQuestion.UncertaintyPolicy.NON_MATCH);
+    }
+
     @ParameterizedTest
     @MethodSource("invalidStructures")
     void invalidStructuresIdentifySourceAndOffendingNode(String yaml, String 
message, int line, int column) {
diff --git 
a/dsl/camel-yaml-dsl/camel-yaml-dsl/src/test/java/org/apache/camel/dsl/yaml/YamlCompletionTreeTest.java
 
b/dsl/camel-yaml-dsl/camel-yaml-dsl/src/test/java/org/apache/camel/dsl/yaml/YamlCompletionTreeTest.java
index 73872c14a910..36d10c2916ba 100644
--- 
a/dsl/camel-yaml-dsl/camel-yaml-dsl/src/test/java/org/apache/camel/dsl/yaml/YamlCompletionTreeTest.java
+++ 
b/dsl/camel-yaml-dsl/camel-yaml-dsl/src/test/java/org/apache/camel/dsl/yaml/YamlCompletionTreeTest.java
@@ -129,6 +129,18 @@ class YamlCompletionTreeTest {
         assertThat(exprChild.get("kind").asText()).isEqualTo("value");
     }
 
+    @Test
+    void beanEipMetadataIsNotOverwrittenByBeanLanguage() {
+        JsonNode bean = nodes.get("bean");
+        assertThat(bean.get("title").asText()).isEqualTo("Bean");
+        assertThat(bean.get("description").asText()).startsWith("Invokes a 
method on a Java bean");
+        
assertThat(bean.get("label").asText()).contains("eip").doesNotContain("language");
+        assertThat(childNames(bean)).contains("ref", "method", "scope");
+        JsonNode language = findChild(nodes.get("expression"), "method");
+        assertThat(language.get("title").asText()).isEqualTo("Bean Method");
+        
assertThat(language.get("label").asText()).contains("language").doesNotContain("eip");
+    }
+
     @Test
     void marshalNodeHasDataFormats() {
         JsonNode marshal = nodes.get("marshal");

Reply via email to