From 34b5704f4a213b082c164e3c0480a233d3ab0514 Mon Sep 17 00:00:00 2001 From: mayc Date: Fri, 12 Jun 2026 12:57:32 -0400 Subject: [PATCH 1/6] Fixed bug in STOP handling --- .../imsweb/staging/engine/DecisionEngine.java | 2 +- .../staging/engine/DecisionEngineTest.java | 39 +++++++++++++++++++ 2 files changed, 40 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/imsweb/staging/engine/DecisionEngine.java b/src/main/java/com/imsweb/staging/engine/DecisionEngine.java index 7211754fd..8a93bbc54 100644 --- a/src/main/java/com/imsweb/staging/engine/DecisionEngine.java +++ b/src/main/java/com/imsweb/staging/engine/DecisionEngine.java @@ -845,7 +845,7 @@ protected boolean process(String mappingId, String tableId, TablePath path, Resu for (Endpoint endpoint : endpoints) { if (EndpointType.STOP.equals(endpoint.getType())) continueProcessing = false; - else if (EndpointType.JUMP.equals(endpoint.getType())) + else if (EndpointType.JUMP.equals(endpoint.getType()) && continueProcessing) continueProcessing = process(mappingId, endpoint.getValue(), path, result, stack); else if (EndpointType.ERROR.equals(endpoint.getType())) { String message = endpoint.getValue(); diff --git a/src/test/java/com/imsweb/staging/engine/DecisionEngineTest.java b/src/test/java/com/imsweb/staging/engine/DecisionEngineTest.java index f5286ce77..4c612f431 100644 --- a/src/test/java/com/imsweb/staging/engine/DecisionEngineTest.java +++ b/src/test/java/com/imsweb/staging/engine/DecisionEngineTest.java @@ -967,6 +967,45 @@ void testProcessWithStop() { assertFalse(input.containsKey("shared_result")); } + @Test + void testStopIsNotOverwrittenByLaterJump() { + InMemoryDataProvider provider = new InMemoryDataProvider("Test", "1.0"); + + StagingTable table = new StagingTable("table_stop_then_jump"); + table.addColumnDefinition("input", ColumnType.INPUT); + table.addColumnDefinition("stop", ColumnType.ENDPOINT); + table.addColumnDefinition("jump", ColumnType.ENDPOINT); + table.addRawRow("1", "STOP", "JUMP:table_jump_target"); + provider.addTable(table); + + table = new StagingTable("table_jump_target"); + table.addColumnDefinition("input", ColumnType.INPUT); + table.addColumnDefinition("jumped", ColumnType.ENDPOINT); + table.addRawRow("1", "VALUE:YES"); + provider.addTable(table); + + table = new StagingTable("table_after_stop"); + table.addColumnDefinition("input", ColumnType.INPUT); + table.addColumnDefinition("continued", ColumnType.ENDPOINT); + table.addRawRow("1", "VALUE:YES"); + provider.addTable(table); + + StagingSchema schema = new StagingSchema("stop_then_jump"); + schema.setSchemaSelectionTable("table_stop_then_jump"); + schema.addInput("input"); + schema.addMapping(new StagingMapping("m1", Arrays.asList(new StagingTablePath("table_stop_then_jump"), new StagingTablePath("table_after_stop")))); + provider.addSchema(schema); + + Map context = new HashMap<>(); + context.put("input", "1"); + Result result = new DecisionEngine(provider).process(schema, context); + + assertFalse(result.hasErrors()); + assertEquals(Collections.singletonList("m1.table_stop_then_jump"), result.getPath()); + assertFalse(context.containsKey("jumped")); + assertFalse(context.containsKey("continued")); + } + @Test void testProcessWithBlanks() { Map input = new HashMap<>(); From 33e61b91e58073dd50c46c4711fba3b11d36b633 Mon Sep 17 00:00:00 2001 From: mayc Date: Fri, 12 Jun 2026 13:12:33 -0400 Subject: [PATCH 2/6] Fixed issue in default validation --- .../imsweb/staging/engine/DecisionEngine.java | 6 +- .../staging/engine/DecisionEngineTest.java | 83 +++++++++++++++++++ 2 files changed, 87 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/imsweb/staging/engine/DecisionEngine.java b/src/main/java/com/imsweb/staging/engine/DecisionEngine.java index 8a93bbc54..2b462af7b 100644 --- a/src/main/java/com/imsweb/staging/engine/DecisionEngine.java +++ b/src/main/java/com/imsweb/staging/engine/DecisionEngine.java @@ -666,8 +666,10 @@ public Result process(Schema schema, Map context) { String value = context.get(input.getKey()); // if value not supplied, use the default or defaultTable and set it back into the context; if not supplied and no default, set the input the blank - if (value == null) - context.put(input.getKey(), getDefault(input, context, result)); + if (value == null) { + value = getDefault(input, context, result); + context.put(input.getKey(), value); + } // validate value against associated table if supplied; if a value is not supplied, or blank, there is no need to validate it against the table if (value != null && !value.isEmpty() && input.getTable() != null) { diff --git a/src/test/java/com/imsweb/staging/engine/DecisionEngineTest.java b/src/test/java/com/imsweb/staging/engine/DecisionEngineTest.java index 4c612f431..5dbfc9fa2 100644 --- a/src/test/java/com/imsweb/staging/engine/DecisionEngineTest.java +++ b/src/test/java/com/imsweb/staging/engine/DecisionEngineTest.java @@ -1481,6 +1481,89 @@ void testOutputsAndDefaults() { assertEquals("", input.get("output2")); } + @Test + void testDefaultInputValidation() { + InMemoryDataProvider provider = new InMemoryDataProvider("Test", "1.0"); + + StagingTable table = new StagingTable("valid_inputs"); + table.addColumnDefinition("input", ColumnType.INPUT); + table.addRawRow("A"); + provider.addTable(table); + + table = new StagingTable("invalid_default"); + table.addColumnDefinition("selector", ColumnType.INPUT); + table.addColumnDefinition("input", ColumnType.ENDPOINT); + table.addRawRow("*", "VALUE:X"); + provider.addTable(table); + + StagingSchema schema = new StagingSchema("valid_literal_default"); + schema.setSchemaSelectionTable("valid_inputs"); + schema.setOnInvalidInput(Schema.StagingInputErrorHandler.FAIL); + StagingSchemaInput input = new StagingSchemaInput("input", "input", "valid_inputs"); + input.setDefault("A"); + schema.addInput(input); + provider.addSchema(schema); + + schema = new StagingSchema("invalid_literal_default"); + schema.setSchemaSelectionTable("valid_inputs"); + schema.setOnInvalidInput(Schema.StagingInputErrorHandler.FAIL); + input = new StagingSchemaInput("input", "input", "valid_inputs"); + input.setDefault("X"); + schema.addInput(input); + provider.addSchema(schema); + + schema = new StagingSchema("invalid_required_default"); + schema.setSchemaSelectionTable("valid_inputs"); + schema.setOnInvalidInput(Schema.StagingInputErrorHandler.FAIL_WHEN_USED_FOR_STAGING); + input = new StagingSchemaInput("input", "input", "valid_inputs"); + input.setDefault("X"); + input.setUsedForStaging(true); + schema.addInput(input); + provider.addSchema(schema); + + schema = new StagingSchema("invalid_non_required_default"); + schema.setSchemaSelectionTable("valid_inputs"); + schema.setOnInvalidInput(Schema.StagingInputErrorHandler.FAIL_WHEN_USED_FOR_STAGING); + input = new StagingSchemaInput("input", "input", "valid_inputs"); + input.setDefault("X"); + input.setUsedForStaging(false); + schema.addInput(input); + provider.addSchema(schema); + + schema = new StagingSchema("invalid_table_default"); + schema.setSchemaSelectionTable("valid_inputs"); + schema.setOnInvalidInput(Schema.StagingInputErrorHandler.FAIL); + input = new StagingSchemaInput("input", "input", "valid_inputs"); + input.setDefaultTable("invalid_default"); + schema.addInput(input); + provider.addSchema(schema); + + DecisionEngine engine = new DecisionEngine(provider); + + Result result = engine.process("valid_literal_default", new HashMap<>()); + assertEquals(Type.STAGED, result.getType()); + assertFalse(result.hasErrors()); + assertEquals("A", result.getContext().get("input")); + + result = engine.process("invalid_literal_default", new HashMap<>()); + assertEquals(Type.FAILED_INPUT, result.getType()); + assertEquals(Error.Type.INVALID_NON_REQUIRED_INPUT, result.getErrors().getFirst().getType()); + assertEquals("X", result.getContext().get("input")); + + result = engine.process("invalid_required_default", new HashMap<>()); + assertEquals(Type.FAILED_INPUT, result.getType()); + assertEquals(Error.Type.INVALID_REQUIRED_INPUT, result.getErrors().getFirst().getType()); + + result = engine.process("invalid_non_required_default", new HashMap<>()); + assertEquals(Type.STAGED, result.getType()); + assertEquals(Error.Type.INVALID_NON_REQUIRED_INPUT, result.getErrors().getFirst().getType()); + + result = engine.process("invalid_table_default", new HashMap<>()); + assertEquals(Type.FAILED_INPUT, result.getType()); + assertEquals(Error.Type.INVALID_NON_REQUIRED_INPUT, result.getErrors().getFirst().getType()); + assertEquals("X", result.getContext().get("input")); + } + @Test void testInitialContextReferences() { StagingSchema schema = new StagingSchema("test_initial_context"); From ba9d54e2ab4fc17d6c605de466cc2034d5efc921 Mon Sep 17 00:00:00 2001 From: mayc Date: Fri, 12 Jun 2026 13:28:39 -0400 Subject: [PATCH 3/6] Added clarifying Javadoc --- src/main/java/com/imsweb/staging/engine/DecisionEngine.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/main/java/com/imsweb/staging/engine/DecisionEngine.java b/src/main/java/com/imsweb/staging/engine/DecisionEngine.java index 2b462af7b..db8d44509 100644 --- a/src/main/java/com/imsweb/staging/engine/DecisionEngine.java +++ b/src/main/java/com/imsweb/staging/engine/DecisionEngine.java @@ -646,6 +646,10 @@ public Result process(String schemaId, Map context) { /** * Using the supplied context, process a schema. The results will be added to the context. + *

+ * Input-mapping destination keys on a table path are temporary aliases scoped to that path. They are added before the path is processed and removed afterward. An input-mapping + * destination must therefore not be used to preserve a pre-existing context value; any previous value with the same key is overwritten and is not restored. + *

* @param schema a schema * @param context a Map containing the context * @return a Result From 619dd3cd2679e37cfc3a35eae2982d1eca37fba9 Mon Sep 17 00:00:00 2001 From: mayc Date: Fri, 12 Jun 2026 13:37:26 -0400 Subject: [PATCH 4/6] Make DecisionEngine provider immutable and null-safe --- .../com/imsweb/staging/engine/DecisionEngine.java | 14 ++++---------- .../imsweb/staging/engine/DecisionEngineTest.java | 6 ++++++ 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/main/java/com/imsweb/staging/engine/DecisionEngine.java b/src/main/java/com/imsweb/staging/engine/DecisionEngine.java index db8d44509..103c06c96 100644 --- a/src/main/java/com/imsweb/staging/engine/DecisionEngine.java +++ b/src/main/java/com/imsweb/staging/engine/DecisionEngine.java @@ -14,6 +14,7 @@ import java.util.List; import java.util.Map; import java.util.Map.Entry; +import java.util.Objects; import java.util.Set; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -46,16 +47,17 @@ public class DecisionEngine { // string to use for blank or null in error strings public static final String _BLANK_OUTPUT = ""; private static final Pattern _TEMPLATE_REFERENCE = Pattern.compile("\\{\\{(.*?)}}"); - private DataProvider _provider; + private final DataProvider _provider; private static final String _CONTEXT_MISSING_MESSAGE = "Context must not be missing"; /** * Construct the decision engine with the passed data provider * @param provider a DataProvider + * @throws NullPointerException if provider is null */ public DecisionEngine(DataProvider provider) { - setProvider(provider); + _provider = Objects.requireNonNull(provider, "Provider must not be null"); } /** @@ -218,14 +220,6 @@ public DataProvider getProvider() { return _provider; } - /** - * Sets the provider and initiaizes all definitions and tables - * @param provider a DataProvider - */ - public void setProvider(DataProvider provider) { - _provider = provider; - } - /** * Given a mapping and a context, check the inclusion/exclusion tables to see if mapping should be processed * @param mapping a Mapping diff --git a/src/test/java/com/imsweb/staging/engine/DecisionEngineTest.java b/src/test/java/com/imsweb/staging/engine/DecisionEngineTest.java index 5dbfc9fa2..541776b11 100644 --- a/src/test/java/com/imsweb/staging/engine/DecisionEngineTest.java +++ b/src/test/java/com/imsweb/staging/engine/DecisionEngineTest.java @@ -53,6 +53,12 @@ class DecisionEngineTest { private static DecisionEngine _ENGINE; + @Test + void testProviderIsRequired() { + NullPointerException exception = assertThrows(NullPointerException.class, () -> new DecisionEngine(null)); + assertEquals("Provider must not be null", exception.getMessage()); + } + @BeforeAll static void init() { InMemoryDataProvider provider = new InMemoryDataProvider("test", "1.0"); From d0d35acfd1614089eb60c859556c873010eca727 Mon Sep 17 00:00:00 2001 From: mayc Date: Fri, 12 Jun 2026 13:47:09 -0400 Subject: [PATCH 5/6] Beef up unit tests --- .../staging/engine/DecisionEngineTest.java | 149 +++++++++++++++++- 1 file changed, 148 insertions(+), 1 deletion(-) diff --git a/src/test/java/com/imsweb/staging/engine/DecisionEngineTest.java b/src/test/java/com/imsweb/staging/engine/DecisionEngineTest.java index 541776b11..3a8984b3a 100644 --- a/src/test/java/com/imsweb/staging/engine/DecisionEngineTest.java +++ b/src/test/java/com/imsweb/staging/engine/DecisionEngineTest.java @@ -4,6 +4,7 @@ */ package com.imsweb.staging.engine; +import java.util.ArrayDeque; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; @@ -29,6 +30,7 @@ import com.imsweb.staging.entities.Schema; import com.imsweb.staging.entities.Table; import com.imsweb.staging.entities.impl.StagingColumnDefinition; +import com.imsweb.staging.entities.impl.StagingKeyValue; import com.imsweb.staging.entities.impl.StagingMapping; import com.imsweb.staging.entities.impl.StagingRange; import com.imsweb.staging.entities.impl.StagingSchema; @@ -59,6 +61,31 @@ void testProviderIsRequired() { assertEquals("Provider must not be null", exception.getMessage()); } + @Test + void testUtilityMethodEdgeCases() { + assertFalse(DecisionEngine.isReferenceVariable(null)); + assertFalse(DecisionEngine.isReferenceVariable("{{key}")); + assertTrue(DecisionEngine.isReferenceVariable("{{key}}")); + assertEquals("{{", DecisionEngine.trimBraces("{{")); + assertEquals("key", DecisionEngine.trimBraces("{{key}}")); + + assertTrue(DecisionEngine.testMatch(null, "anything", new HashMap<>())); + assertTrue(DecisionEngine.testMatch(Collections.emptyList(), "anything", new HashMap<>())); + assertNull(DecisionEngine.translateValue(null, new HashMap<>())); + assertEquals("{{key", DecisionEngine.translateValue("{{key", new HashMap<>())); + + StagingTable table = new StagingTable("matching"); + table.addColumnDefinition("input", ColumnType.INPUT); + table.addRawRow("A"); + InMemoryDataProvider provider = new InMemoryDataProvider("Test", "1.0"); + provider.addTable(table); + + Map context = new HashMap<>(); + context.put("input", "A"); + assertEquals(0, DecisionEngine.findMatchingTableRow(provider.getTable("matching"), context)); + assertThrows(IllegalStateException.class, () -> DecisionEngine.findMatchingTableRow(provider.getTable("matching"), null)); + } + @BeforeAll static void init() { InMemoryDataProvider provider = new InMemoryDataProvider("test", "1.0"); @@ -1337,6 +1364,58 @@ void testInclusionsAndExclusions() { assertEquals("SUCCESS", input.get("special")); } + @Test + void testMappedInclusionsAndExclusionsAndMissingTables() { + InMemoryDataProvider provider = new InMemoryDataProvider("Test", "1.0"); + StagingTable table = new StagingTable("criteria"); + table.addColumnDefinition("mapped", ColumnType.INPUT); + table.addRawRow("A"); + provider.addTable(table); + + DecisionEngine engine = new DecisionEngine(provider); + StagingTablePath path = new StagingTablePath("criteria"); + path.addInputMapping("source", "mapped"); + + StagingMapping inclusion = new StagingMapping("inclusion"); + inclusion.setInclusionTables(Collections.singletonList(path)); + Map context = new HashMap<>(); + context.put("source", "A"); + assertTrue(engine.isMappingInvolved(inclusion, context)); + context.put("source", "B"); + assertFalse(engine.isMappingInvolved(inclusion, context)); + + StagingMapping exclusion = new StagingMapping("exclusion"); + exclusion.setExclusionTables(Collections.singletonList(path)); + context.put("source", "A"); + assertFalse(engine.isMappingInvolved(exclusion, context)); + context.put("source", "B"); + assertTrue(engine.isMappingInvolved(exclusion, context)); + + assertThrows(IllegalStateException.class, () -> engine.isMappingInvolved(inclusion, null)); + assertThrows(IllegalStateException.class, () -> engine.getInvolvedMappings(new StagingSchema("schema"), null)); + + inclusion.setInclusionTables(Collections.singletonList(new StagingTablePath("missing"))); + assertThrows(IllegalStateException.class, () -> engine.isMappingInvolved(inclusion, context)); + exclusion.setExclusionTables(Collections.singletonList(new StagingTablePath("missing"))); + assertThrows(IllegalStateException.class, () -> engine.isMappingInvolved(exclusion, context)); + } + + @Test + void testMissingSchemaAndTableReferences() { + InMemoryDataProvider provider = new InMemoryDataProvider("Test", "1.0"); + DecisionEngine engine = new DecisionEngine(provider); + + assertThrows(IllegalStateException.class, () -> engine.process("missing", new HashMap<>())); + assertThrows(IllegalStateException.class, () -> engine.getInvolvedTables("missing")); + assertTrue(engine.getInputs(new StagingTablePath("missing")).isEmpty()); + assertTrue(engine.getOutputs(new StagingTablePath("missing")).isEmpty()); + + StagingTablePath path = new StagingTablePath("starting_table"); + Result result = new Result(new HashMap<>()); + assertTrue(engine.process("mapping", "missing", path, result, new ArrayDeque<>())); + assertEquals(Error.Type.UNKNOWN_TABLE, result.getErrors().getFirst().getType()); + } + @Test void testDuplicateAlgorithms() { InMemoryDataProvider provider = new InMemoryDataProvider("Test", "1.0"); @@ -1461,9 +1540,17 @@ void testOutputsAndDefaults() { assertEquals("A", input.get("output1")); // no default value so it should be blank assertEquals("", input.get("output2")); - assertFalse(result.hasErrors()); + // a blank default should use the standard blank marker in validation errors + schema.getOutputs().getFirst().setDefault(null); + provider.initSchema(schema); + input = new HashMap<>(); + input.put("input1", "000"); + result = engine.process("sample_outputs", input); + assertTrue(result.hasErrors()); + assertEquals("Invalid 'output1' value (" + DecisionEngine._BLANK_OUTPUT + ")", result.getErrors().getFirst().getMessage()); + assertEquals(new HashSet<>(Arrays.asList("table_input", "table_output")), engine.getInvolvedTables(schema)); // modify the definition to create a bad default value for output1 @@ -1570,6 +1657,66 @@ void testDefaultInputValidation() { assertEquals("X", result.getContext().get("input")); } + @Test + void testProcessingReferenceErrorsAndMappingInitialContext() { + InMemoryDataProvider provider = new InMemoryDataProvider("Test", "1.0"); + + StagingTable selection = new StagingTable("selection"); + selection.addColumnDefinition("selector", ColumnType.INPUT); + selection.addRawRow("*"); + provider.addTable(selection); + + StagingTable mappingTable = new StagingTable("mapping_table"); + mappingTable.addColumnDefinition("temporary", ColumnType.INPUT); + mappingTable.addColumnDefinition("result", ColumnType.ENDPOINT); + mappingTable.addRawRow("A", "VALUE:OK"); + provider.addTable(mappingTable); + + StagingSchema schema = new StagingSchema("mapping_initial_context"); + schema.setSchemaSelectionTable("selection"); + schema.addOutput(new StagingSchemaOutput("result")); + StagingMapping mapping = new StagingMapping("mapping"); + mapping.setInitialContext(Collections.singleton(new StagingKeyValue("temporary", "A"))); + mapping.addTablePath(new StagingTablePath("mapping_table")); + schema.addMapping(mapping); + provider.addSchema(schema); + + schema = new StagingSchema("unknown_input_mapping"); + schema.setSchemaSelectionTable("selection"); + schema.addOutput(new StagingSchemaOutput("result")); + StagingTablePath path = new StagingTablePath("mapping_table"); + path.addInputMapping("missing_source", "temporary"); + schema.addMapping(new StagingMapping("mapping", Collections.singletonList(path))); + provider.addSchema(schema); + + schema = new StagingSchema("unknown_input_table"); + schema.setSchemaSelectionTable("selection"); + schema.addInput(new StagingSchemaInput("input", "input", "missing_input_table")); + provider.addSchema(schema); + + schema = new StagingSchema("unknown_output_table"); + schema.setSchemaSelectionTable("selection"); + schema.addOutput(new StagingSchemaOutput("result", "result", "missing_output_table")); + provider.addSchema(schema); + + DecisionEngine engine = new DecisionEngine(provider); + assertTrue(engine.getInputs(mapping, new HashSet<>()).isEmpty()); + Result result = engine.process("mapping_initial_context", new HashMap<>()); + assertFalse(result.hasErrors()); + assertEquals("OK", result.getContext().get("result")); + + result = engine.process("unknown_input_mapping", new HashMap<>()); + assertThat(result.getErrors()).extracting(Error::getType).contains(Error.Type.UNKNOWN_INPUT_MAPPING); + + Map context = new HashMap<>(); + context.put("input", "A"); + result = engine.process("unknown_input_table", context); + assertThat(result.getErrors()).extracting(Error::getType).containsExactly(Error.Type.UNKNOWN_TABLE); + + result = engine.process("unknown_output_table", new HashMap<>()); + assertThat(result.getErrors()).extracting(Error::getType).containsExactly(Error.Type.UNKNOWN_TABLE); + } + @Test void testInitialContextReferences() { StagingSchema schema = new StagingSchema("test_initial_context"); From a07744280a2e6546424bb00dabe9ed55f049f1fe Mon Sep 17 00:00:00 2001 From: mayc Date: Fri, 12 Jun 2026 13:53:39 -0400 Subject: [PATCH 6/6] Sonarqube fixes --- .../com/imsweb/staging/engine/DecisionEngineTest.java | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/test/java/com/imsweb/staging/engine/DecisionEngineTest.java b/src/test/java/com/imsweb/staging/engine/DecisionEngineTest.java index 3a8984b3a..866b8cf14 100644 --- a/src/test/java/com/imsweb/staging/engine/DecisionEngineTest.java +++ b/src/test/java/com/imsweb/staging/engine/DecisionEngineTest.java @@ -82,8 +82,9 @@ void testUtilityMethodEdgeCases() { Map context = new HashMap<>(); context.put("input", "A"); - assertEquals(0, DecisionEngine.findMatchingTableRow(provider.getTable("matching"), context)); - assertThrows(IllegalStateException.class, () -> DecisionEngine.findMatchingTableRow(provider.getTable("matching"), null)); + Table matchingTable = provider.getTable("matching"); + assertEquals(0, DecisionEngine.findMatchingTableRow(matchingTable, context)); + assertThrows(IllegalStateException.class, () -> DecisionEngine.findMatchingTableRow(matchingTable, null)); } @BeforeAll @@ -1392,7 +1393,8 @@ void testMappedInclusionsAndExclusionsAndMissingTables() { assertTrue(engine.isMappingInvolved(exclusion, context)); assertThrows(IllegalStateException.class, () -> engine.isMappingInvolved(inclusion, null)); - assertThrows(IllegalStateException.class, () -> engine.getInvolvedMappings(new StagingSchema("schema"), null)); + StagingSchema schema = new StagingSchema("schema"); + assertThrows(IllegalStateException.class, () -> engine.getInvolvedMappings(schema, null)); inclusion.setInclusionTables(Collections.singletonList(new StagingTablePath("missing"))); assertThrows(IllegalStateException.class, () -> engine.isMappingInvolved(inclusion, context));