|
4 | 4 | */ |
5 | 5 | package com.imsweb.staging.engine; |
6 | 6 |
|
| 7 | +import java.util.ArrayDeque; |
7 | 8 | import java.util.ArrayList; |
8 | 9 | import java.util.Arrays; |
9 | 10 | import java.util.Collections; |
|
29 | 30 | import com.imsweb.staging.entities.Schema; |
30 | 31 | import com.imsweb.staging.entities.Table; |
31 | 32 | import com.imsweb.staging.entities.impl.StagingColumnDefinition; |
| 33 | +import com.imsweb.staging.entities.impl.StagingKeyValue; |
32 | 34 | import com.imsweb.staging.entities.impl.StagingMapping; |
33 | 35 | import com.imsweb.staging.entities.impl.StagingRange; |
34 | 36 | import com.imsweb.staging.entities.impl.StagingSchema; |
@@ -59,6 +61,31 @@ void testProviderIsRequired() { |
59 | 61 | assertEquals("Provider must not be null", exception.getMessage()); |
60 | 62 | } |
61 | 63 |
|
| 64 | + @Test |
| 65 | + void testUtilityMethodEdgeCases() { |
| 66 | + assertFalse(DecisionEngine.isReferenceVariable(null)); |
| 67 | + assertFalse(DecisionEngine.isReferenceVariable("{{key}")); |
| 68 | + assertTrue(DecisionEngine.isReferenceVariable("{{key}}")); |
| 69 | + assertEquals("{{", DecisionEngine.trimBraces("{{")); |
| 70 | + assertEquals("key", DecisionEngine.trimBraces("{{key}}")); |
| 71 | + |
| 72 | + assertTrue(DecisionEngine.testMatch(null, "anything", new HashMap<>())); |
| 73 | + assertTrue(DecisionEngine.testMatch(Collections.emptyList(), "anything", new HashMap<>())); |
| 74 | + assertNull(DecisionEngine.translateValue(null, new HashMap<>())); |
| 75 | + assertEquals("{{key", DecisionEngine.translateValue("{{key", new HashMap<>())); |
| 76 | + |
| 77 | + StagingTable table = new StagingTable("matching"); |
| 78 | + table.addColumnDefinition("input", ColumnType.INPUT); |
| 79 | + table.addRawRow("A"); |
| 80 | + InMemoryDataProvider provider = new InMemoryDataProvider("Test", "1.0"); |
| 81 | + provider.addTable(table); |
| 82 | + |
| 83 | + Map<String, String> context = new HashMap<>(); |
| 84 | + context.put("input", "A"); |
| 85 | + assertEquals(0, DecisionEngine.findMatchingTableRow(provider.getTable("matching"), context)); |
| 86 | + assertThrows(IllegalStateException.class, () -> DecisionEngine.findMatchingTableRow(provider.getTable("matching"), null)); |
| 87 | + } |
| 88 | + |
62 | 89 | @BeforeAll |
63 | 90 | static void init() { |
64 | 91 | InMemoryDataProvider provider = new InMemoryDataProvider("test", "1.0"); |
@@ -1337,6 +1364,58 @@ void testInclusionsAndExclusions() { |
1337 | 1364 | assertEquals("SUCCESS", input.get("special")); |
1338 | 1365 | } |
1339 | 1366 |
|
| 1367 | + @Test |
| 1368 | + void testMappedInclusionsAndExclusionsAndMissingTables() { |
| 1369 | + InMemoryDataProvider provider = new InMemoryDataProvider("Test", "1.0"); |
| 1370 | + StagingTable table = new StagingTable("criteria"); |
| 1371 | + table.addColumnDefinition("mapped", ColumnType.INPUT); |
| 1372 | + table.addRawRow("A"); |
| 1373 | + provider.addTable(table); |
| 1374 | + |
| 1375 | + DecisionEngine engine = new DecisionEngine(provider); |
| 1376 | + StagingTablePath path = new StagingTablePath("criteria"); |
| 1377 | + path.addInputMapping("source", "mapped"); |
| 1378 | + |
| 1379 | + StagingMapping inclusion = new StagingMapping("inclusion"); |
| 1380 | + inclusion.setInclusionTables(Collections.singletonList(path)); |
| 1381 | + Map<String, String> context = new HashMap<>(); |
| 1382 | + context.put("source", "A"); |
| 1383 | + assertTrue(engine.isMappingInvolved(inclusion, context)); |
| 1384 | + context.put("source", "B"); |
| 1385 | + assertFalse(engine.isMappingInvolved(inclusion, context)); |
| 1386 | + |
| 1387 | + StagingMapping exclusion = new StagingMapping("exclusion"); |
| 1388 | + exclusion.setExclusionTables(Collections.singletonList(path)); |
| 1389 | + context.put("source", "A"); |
| 1390 | + assertFalse(engine.isMappingInvolved(exclusion, context)); |
| 1391 | + context.put("source", "B"); |
| 1392 | + assertTrue(engine.isMappingInvolved(exclusion, context)); |
| 1393 | + |
| 1394 | + assertThrows(IllegalStateException.class, () -> engine.isMappingInvolved(inclusion, null)); |
| 1395 | + assertThrows(IllegalStateException.class, () -> engine.getInvolvedMappings(new StagingSchema("schema"), null)); |
| 1396 | + |
| 1397 | + inclusion.setInclusionTables(Collections.singletonList(new StagingTablePath("missing"))); |
| 1398 | + assertThrows(IllegalStateException.class, () -> engine.isMappingInvolved(inclusion, context)); |
| 1399 | + exclusion.setExclusionTables(Collections.singletonList(new StagingTablePath("missing"))); |
| 1400 | + assertThrows(IllegalStateException.class, () -> engine.isMappingInvolved(exclusion, context)); |
| 1401 | + } |
| 1402 | + |
| 1403 | + @Test |
| 1404 | + void testMissingSchemaAndTableReferences() { |
| 1405 | + InMemoryDataProvider provider = new InMemoryDataProvider("Test", "1.0"); |
| 1406 | + DecisionEngine engine = new DecisionEngine(provider); |
| 1407 | + |
| 1408 | + assertThrows(IllegalStateException.class, () -> engine.process("missing", new HashMap<>())); |
| 1409 | + assertThrows(IllegalStateException.class, () -> engine.getInvolvedTables("missing")); |
| 1410 | + assertTrue(engine.getInputs(new StagingTablePath("missing")).isEmpty()); |
| 1411 | + assertTrue(engine.getOutputs(new StagingTablePath("missing")).isEmpty()); |
| 1412 | + |
| 1413 | + StagingTablePath path = new StagingTablePath("starting_table"); |
| 1414 | + Result result = new Result(new HashMap<>()); |
| 1415 | + assertTrue(engine.process("mapping", "missing", path, result, new ArrayDeque<>())); |
| 1416 | + assertEquals(Error.Type.UNKNOWN_TABLE, result.getErrors().getFirst().getType()); |
| 1417 | + } |
| 1418 | + |
1340 | 1419 | @Test |
1341 | 1420 | void testDuplicateAlgorithms() { |
1342 | 1421 | InMemoryDataProvider provider = new InMemoryDataProvider("Test", "1.0"); |
@@ -1461,9 +1540,17 @@ void testOutputsAndDefaults() { |
1461 | 1540 | assertEquals("A", input.get("output1")); |
1462 | 1541 | // no default value so it should be blank |
1463 | 1542 | assertEquals("", input.get("output2")); |
1464 | | - |
1465 | 1543 | assertFalse(result.hasErrors()); |
1466 | 1544 |
|
| 1545 | + // a blank default should use the standard blank marker in validation errors |
| 1546 | + schema.getOutputs().getFirst().setDefault(null); |
| 1547 | + provider.initSchema(schema); |
| 1548 | + input = new HashMap<>(); |
| 1549 | + input.put("input1", "000"); |
| 1550 | + result = engine.process("sample_outputs", input); |
| 1551 | + assertTrue(result.hasErrors()); |
| 1552 | + assertEquals("Invalid 'output1' value (" + DecisionEngine._BLANK_OUTPUT + ")", result.getErrors().getFirst().getMessage()); |
| 1553 | + |
1467 | 1554 | assertEquals(new HashSet<>(Arrays.asList("table_input", "table_output")), engine.getInvolvedTables(schema)); |
1468 | 1555 |
|
1469 | 1556 | // modify the definition to create a bad default value for output1 |
@@ -1570,6 +1657,66 @@ void testDefaultInputValidation() { |
1570 | 1657 | assertEquals("X", result.getContext().get("input")); |
1571 | 1658 | } |
1572 | 1659 |
|
| 1660 | + @Test |
| 1661 | + void testProcessingReferenceErrorsAndMappingInitialContext() { |
| 1662 | + InMemoryDataProvider provider = new InMemoryDataProvider("Test", "1.0"); |
| 1663 | + |
| 1664 | + StagingTable selection = new StagingTable("selection"); |
| 1665 | + selection.addColumnDefinition("selector", ColumnType.INPUT); |
| 1666 | + selection.addRawRow("*"); |
| 1667 | + provider.addTable(selection); |
| 1668 | + |
| 1669 | + StagingTable mappingTable = new StagingTable("mapping_table"); |
| 1670 | + mappingTable.addColumnDefinition("temporary", ColumnType.INPUT); |
| 1671 | + mappingTable.addColumnDefinition("result", ColumnType.ENDPOINT); |
| 1672 | + mappingTable.addRawRow("A", "VALUE:OK"); |
| 1673 | + provider.addTable(mappingTable); |
| 1674 | + |
| 1675 | + StagingSchema schema = new StagingSchema("mapping_initial_context"); |
| 1676 | + schema.setSchemaSelectionTable("selection"); |
| 1677 | + schema.addOutput(new StagingSchemaOutput("result")); |
| 1678 | + StagingMapping mapping = new StagingMapping("mapping"); |
| 1679 | + mapping.setInitialContext(Collections.singleton(new StagingKeyValue("temporary", "A"))); |
| 1680 | + mapping.addTablePath(new StagingTablePath("mapping_table")); |
| 1681 | + schema.addMapping(mapping); |
| 1682 | + provider.addSchema(schema); |
| 1683 | + |
| 1684 | + schema = new StagingSchema("unknown_input_mapping"); |
| 1685 | + schema.setSchemaSelectionTable("selection"); |
| 1686 | + schema.addOutput(new StagingSchemaOutput("result")); |
| 1687 | + StagingTablePath path = new StagingTablePath("mapping_table"); |
| 1688 | + path.addInputMapping("missing_source", "temporary"); |
| 1689 | + schema.addMapping(new StagingMapping("mapping", Collections.singletonList(path))); |
| 1690 | + provider.addSchema(schema); |
| 1691 | + |
| 1692 | + schema = new StagingSchema("unknown_input_table"); |
| 1693 | + schema.setSchemaSelectionTable("selection"); |
| 1694 | + schema.addInput(new StagingSchemaInput("input", "input", "missing_input_table")); |
| 1695 | + provider.addSchema(schema); |
| 1696 | + |
| 1697 | + schema = new StagingSchema("unknown_output_table"); |
| 1698 | + schema.setSchemaSelectionTable("selection"); |
| 1699 | + schema.addOutput(new StagingSchemaOutput("result", "result", "missing_output_table")); |
| 1700 | + provider.addSchema(schema); |
| 1701 | + |
| 1702 | + DecisionEngine engine = new DecisionEngine(provider); |
| 1703 | + assertTrue(engine.getInputs(mapping, new HashSet<>()).isEmpty()); |
| 1704 | + Result result = engine.process("mapping_initial_context", new HashMap<>()); |
| 1705 | + assertFalse(result.hasErrors()); |
| 1706 | + assertEquals("OK", result.getContext().get("result")); |
| 1707 | + |
| 1708 | + result = engine.process("unknown_input_mapping", new HashMap<>()); |
| 1709 | + assertThat(result.getErrors()).extracting(Error::getType).contains(Error.Type.UNKNOWN_INPUT_MAPPING); |
| 1710 | + |
| 1711 | + Map<String, String> context = new HashMap<>(); |
| 1712 | + context.put("input", "A"); |
| 1713 | + result = engine.process("unknown_input_table", context); |
| 1714 | + assertThat(result.getErrors()).extracting(Error::getType).containsExactly(Error.Type.UNKNOWN_TABLE); |
| 1715 | + |
| 1716 | + result = engine.process("unknown_output_table", new HashMap<>()); |
| 1717 | + assertThat(result.getErrors()).extracting(Error::getType).containsExactly(Error.Type.UNKNOWN_TABLE); |
| 1718 | + } |
| 1719 | + |
1573 | 1720 | @Test |
1574 | 1721 | void testInitialContextReferences() { |
1575 | 1722 | StagingSchema schema = new StagingSchema("test_initial_context"); |
|
0 commit comments