Skip to content

Commit

Permalink
Add additional IBDO parameter diff options. (#609)
Browse files Browse the repository at this point in the history
  • Loading branch information
jdcove2 authored Nov 7, 2023
1 parent dd578ba commit a35b765
Show file tree
Hide file tree
Showing 4 changed files with 307 additions and 6 deletions.
72 changes: 69 additions & 3 deletions src/main/java/emissary/core/DiffCheckConfiguration.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package emissary.core;

import java.util.Arrays;
import java.util.Collections;
import java.util.EnumSet;
import java.util.Set;

Expand All @@ -12,13 +13,13 @@ public class DiffCheckConfiguration {
* Possible configuration options
*/
public enum DiffCheckOptions {
DATA, TIMESTAMP, INTERNAL_ID, TRANSFORM_HISTORY
DATA, TIMESTAMP, INTERNAL_ID, TRANSFORM_HISTORY, KEY_VALUE_PARAMETER_DIFF, DETAILED_PARAMETER_DIFF
}

/**
* Stateful field of 'enabled' options
*/
private final EnumSet<DiffCheckOptions> enabled;
private final Set<DiffCheckOptions> enabled;

/**
* Start building a new configuration
Expand Down Expand Up @@ -74,6 +75,24 @@ public boolean checkTransformHistory() {
return enabled.contains(DiffCheckOptions.TRANSFORM_HISTORY);
}

/**
* Check if parameter diff should produce detailed output
*
* @return if performing a detailed parameter diff
*/
public boolean performDetailedParameterDiff() {
return enabled.contains(DiffCheckOptions.DETAILED_PARAMETER_DIFF);
}

/**
* Check if parameter diff should produce non-matching key/value output
*
* @return if performing a key/value parameter diff
*/
public boolean performKeyValueParameterDiff() {
return enabled.contains(DiffCheckOptions.KEY_VALUE_PARAMETER_DIFF);
}

/**
* Accessor for enabled options
*
Expand All @@ -89,7 +108,7 @@ public Set<DiffCheckOptions> getEnabled() {
* @param enabled set of pre-configured options
*/
private DiffCheckConfiguration(final EnumSet<DiffCheckOptions> enabled) {
this.enabled = enabled;
this.enabled = Collections.unmodifiableSet(enabled);
}

/**
Expand Down Expand Up @@ -120,6 +139,11 @@ public DiffCheckConfiguration build() {
public DiffCheckConfiguration explicit(final DiffCheckOptions... options) {
reset();
building.addAll(Arrays.asList(options));

if (building.contains(DiffCheckOptions.DETAILED_PARAMETER_DIFF) && building.contains(DiffCheckOptions.KEY_VALUE_PARAMETER_DIFF)) {
throw new IllegalArgumentException("Cannot contain DETAILED_PARAMETER_DIFF and KEY_VALUE_PARAMETER_DIFF!");
}

return build();
}

Expand Down Expand Up @@ -219,5 +243,47 @@ public DiffCheckBuilder disableTransformHistory() {
building.remove(DiffCheckOptions.TRANSFORM_HISTORY);
return this;
}

/**
* Enable transform history for diff checking
*
* @return the builder
*/
public DiffCheckBuilder enableKeyValueParameterDiff() {
building.add(DiffCheckOptions.KEY_VALUE_PARAMETER_DIFF);
building.remove(DiffCheckOptions.DETAILED_PARAMETER_DIFF);
return this;
}

/**
* Disable transform history for diff checking
*
* @return the builder
*/
public DiffCheckBuilder disableKeyValueParameterDiff() {
building.remove(DiffCheckOptions.KEY_VALUE_PARAMETER_DIFF);
return this;
}

/**
* Enable transform history for diff checking
*
* @return the builder
*/
public DiffCheckBuilder enableDetailedParameterDiff() {
building.add(DiffCheckOptions.DETAILED_PARAMETER_DIFF);
building.remove(DiffCheckOptions.KEY_VALUE_PARAMETER_DIFF);
return this;
}

/**
* Disable transform history for diff checking
*
* @return the builder
*/
public DiffCheckBuilder disableDetailedParameterDiff() {
building.remove(DiffCheckOptions.DETAILED_PARAMETER_DIFF);
return this;
}
}
}
72 changes: 69 additions & 3 deletions src/main/java/emissary/core/IBaseDataObjectDiffHelper.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,15 @@
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Objects;
import java.util.Set;
import java.util.TreeMap;
import java.util.TreeSet;

public class IBaseDataObjectDiffHelper {

Expand Down Expand Up @@ -58,8 +63,15 @@ public static void diff(final IBaseDataObject ibdo1, final IBaseDataObject ibdo2
}

diff(ibdo1.getFontEncoding(), ibdo2.getFontEncoding(), "fontEncoding", differences);
// TreeMap automatically sorts parameters by key
diff(convertMap(ibdo1.getParameters()), convertMap(ibdo2.getParameters()), "parameters", differences);

if (options.performDetailedParameterDiff()) {
diff(convertMap(ibdo1.getParameters()), convertMap(ibdo2.getParameters()), "parameters", differences);
} else if (options.performKeyValueParameterDiff()) {
keyValueMapDiff(convertMap(ibdo1.getParameters()), convertMap(ibdo2.getParameters()), "parameters", differences);
} else {
minimalMapDiff(convertMap(ibdo1.getParameters()), convertMap(ibdo2.getParameters()), "parameters", differences);
}

diff(ibdo1.getNumChildren(), ibdo2.getNumChildren(), "numChildren", differences);
diff(ibdo1.getNumSiblings(), ibdo2.getNumSiblings(), "numSiblings", differences);
diff(ibdo1.getBirthOrder(), ibdo2.getBirthOrder(), "birthOrder", differences);
Expand Down Expand Up @@ -211,7 +223,7 @@ public static void diff(final boolean boolean1, final boolean boolean2, final St
* @param map1 the first map to compare.
* @param map2 the second map to compare.
* @param identifier an identifier to describe the context of this map comparison.
* @param differences the string list differences are to be added to.
* @param differences the string list of differences to be added to.
*/
public static void diff(final Map<String, byte[]> map1, final Map<String, byte[]> map2, final String identifier,
final List<String> differences) {
Expand All @@ -226,6 +238,60 @@ public static void diff(final Map<String, byte[]> map1, final Map<String, byte[]
}
}

/**
* This method compares two maps and adds only the key/value pairs that differ to the provided string list.
*
* @param parameter1 the first map to compare.
* @param parameter2 the second map to compare.
* @param identifier an identifier to describe the context of this map comparison.
* @param differences the string list of differences to be added to.
*/
public static void keyValueMapDiff(final Map<String, Collection<String>> parameter1, final Map<String, Collection<String>> parameter2,
final String identifier, final List<String> differences) {
final Set<Entry<String, Collection<String>>> p1Entries = new HashSet<>(parameter1.entrySet());
final Set<Entry<String, Collection<String>>> p2Entries = new HashSet<>(parameter2.entrySet());
final Map<String, Collection<String>> p1 = new HashMap<>(parameter1);
final Map<String, Collection<String>> p2 = new HashMap<>(parameter2);

for (Entry<String, Collection<String>> p1Entry : p1Entries) {
if (p2Entries.contains(p1Entry)) {
p1.remove(p1Entry.getKey());
p2.remove(p1Entry.getKey());
}
}

if (!p1.isEmpty() || !p2.isEmpty()) {
differences.add(String.format("%s%s: %s : %s", identifier, ARE_NOT_EQUAL + "-Differing Keys/Values", p1, p2));
}
}

/**
* This method compares two maps and adds only the keys that differ to the provided string list.
*
* @param parameter1 the first map to compare.
* @param parameter2 the second map to compare.
* @param identifier an identifier to describe the context of this map comparison.
* @param differences the string list of differences to be added to.
*/
public static void minimalMapDiff(final Map<String, Collection<String>> parameter1, final Map<String, Collection<String>> parameter2,
final String identifier, final List<String> differences) {
final Set<Entry<String, Collection<String>>> p1Entries = new HashSet<>(parameter1.entrySet());
final Set<Entry<String, Collection<String>>> p2Entries = new HashSet<>(parameter2.entrySet());
final Set<String> p1Keys = new TreeSet<>(parameter1.keySet());
final Set<String> p2Keys = new TreeSet<>(parameter2.keySet());

for (Entry<String, Collection<String>> p1Entry : p1Entries) {
if (p2Entries.contains(p1Entry)) {
p1Keys.remove(p1Entry.getKey());
p2Keys.remove(p1Entry.getKey());
}
}

if (!p1Keys.isEmpty() || !p2Keys.isEmpty()) {
differences.add(String.format("%s%s: %s : %s", identifier, ARE_NOT_EQUAL + "-Differing Keys", p1Keys, p2Keys));
}
}

/**
* This method converts the IBDO parameter map of Object values to a map of String values for better comparison.
*
Expand Down
134 changes: 134 additions & 0 deletions src/test/java/emissary/core/DiffCheckConfigurationTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
package emissary.core;

import emissary.core.DiffCheckConfiguration.DiffCheckBuilder;
import emissary.core.DiffCheckConfiguration.DiffCheckOptions;
import emissary.test.core.junit5.UnitTest;

import org.junit.jupiter.api.Test;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;

class DiffCheckConfigurationTest extends UnitTest {
@Test
void testNonParameter() {
final DiffCheckBuilder diffCheckBuilder = DiffCheckConfiguration.configure();
final DiffCheckConfiguration emptyConfiguration = diffCheckBuilder.build();

assertEquals(0, emptyConfiguration.getEnabled().size(), "Configuration should be empty!");

diffCheckBuilder.enableData();
diffCheckBuilder.enableInternalId();
diffCheckBuilder.enableTimestamp();
diffCheckBuilder.enableTransformHistory();

final DiffCheckConfiguration nonParameterConfiguration = diffCheckBuilder.build();

assertTrue(nonParameterConfiguration.checkData());
assertTrue(nonParameterConfiguration.checkInternalId());
assertTrue(nonParameterConfiguration.checkTimestamp());
assertTrue(nonParameterConfiguration.checkTransformHistory());
assertFalse(nonParameterConfiguration.performDetailedParameterDiff());
assertFalse(nonParameterConfiguration.performKeyValueParameterDiff());

diffCheckBuilder.disableData();
diffCheckBuilder.disableInternalId();
diffCheckBuilder.disableTimestamp();
diffCheckBuilder.disableTransformHistory();

assertEquals(0, diffCheckBuilder.build().getEnabled().size(), "Configuration should be empty!");
}

@Test
void testKeyValueDetailed() {
final DiffCheckBuilder diffCheckBuilder = DiffCheckConfiguration.configure();

diffCheckBuilder.enableDetailedParameterDiff();

final DiffCheckConfiguration detailedParameterConfiguration = diffCheckBuilder.build();

assertTrue(detailedParameterConfiguration.performDetailedParameterDiff());
assertFalse(detailedParameterConfiguration.performKeyValueParameterDiff());

diffCheckBuilder.enableKeyValueParameterDiff();

final DiffCheckConfiguration keyValueParameterConfiguration = diffCheckBuilder.build();

assertFalse(keyValueParameterConfiguration.performDetailedParameterDiff());
assertTrue(keyValueParameterConfiguration.performKeyValueParameterDiff());

diffCheckBuilder.disableKeyValueParameterDiff();

assertEquals(0, diffCheckBuilder.build().getEnabled().size(), "Configuration should be empty!");

diffCheckBuilder.enableKeyValueParameterDiff();

final DiffCheckConfiguration KeyValueParameterConfiguration2 = diffCheckBuilder.build();

assertFalse(KeyValueParameterConfiguration2.performDetailedParameterDiff());
assertTrue(KeyValueParameterConfiguration2.performKeyValueParameterDiff());

diffCheckBuilder.enableDetailedParameterDiff();

final DiffCheckConfiguration detailedParameterConfiguration2 = diffCheckBuilder.build();

assertTrue(detailedParameterConfiguration2.performDetailedParameterDiff());
assertFalse(detailedParameterConfiguration2.performKeyValueParameterDiff());

diffCheckBuilder.disableDetailedParameterDiff();

assertEquals(0, diffCheckBuilder.build().getEnabled().size(), "Configuration should be empty!");
}

@Test
void checkReset() {
final DiffCheckBuilder diffCheckBuilder = DiffCheckConfiguration.configure();

diffCheckBuilder.enableData();
diffCheckBuilder.enableInternalId();
diffCheckBuilder.enableTimestamp();
diffCheckBuilder.enableTransformHistory();
diffCheckBuilder.enableDetailedParameterDiff();
diffCheckBuilder.reset();

assertEquals(0, diffCheckBuilder.build().getEnabled().size(), "Configuration should be empty!");
}

@Test
void checkExplicit() {
final DiffCheckBuilder diffCheckBuilder = DiffCheckConfiguration.configure();
final DiffCheckConfiguration explicitDetailedConfiguration = diffCheckBuilder.explicit(
DiffCheckOptions.DATA,
DiffCheckOptions.DETAILED_PARAMETER_DIFF,
DiffCheckOptions.INTERNAL_ID,
DiffCheckOptions.TIMESTAMP,
DiffCheckOptions.TRANSFORM_HISTORY);

assertTrue(explicitDetailedConfiguration.checkData());
assertTrue(explicitDetailedConfiguration.checkInternalId());
assertTrue(explicitDetailedConfiguration.checkTimestamp());
assertTrue(explicitDetailedConfiguration.checkTransformHistory());
assertTrue(explicitDetailedConfiguration.performDetailedParameterDiff());
assertFalse(explicitDetailedConfiguration.performKeyValueParameterDiff());

final DiffCheckConfiguration explicitKeyValueConfiguration = diffCheckBuilder.explicit(
DiffCheckOptions.DATA,
DiffCheckOptions.KEY_VALUE_PARAMETER_DIFF,
DiffCheckOptions.INTERNAL_ID,
DiffCheckOptions.TIMESTAMP,
DiffCheckOptions.TRANSFORM_HISTORY);

assertTrue(explicitKeyValueConfiguration.checkData());
assertTrue(explicitKeyValueConfiguration.checkInternalId());
assertTrue(explicitKeyValueConfiguration.checkTimestamp());
assertTrue(explicitKeyValueConfiguration.checkTransformHistory());
assertFalse(explicitKeyValueConfiguration.performDetailedParameterDiff());
assertTrue(explicitKeyValueConfiguration.performKeyValueParameterDiff());

assertThrows(IllegalArgumentException.class, () -> diffCheckBuilder.explicit(
DiffCheckOptions.DETAILED_PARAMETER_DIFF,
DiffCheckOptions.KEY_VALUE_PARAMETER_DIFF));
}
}
Loading

0 comments on commit a35b765

Please sign in to comment.