-
Notifications
You must be signed in to change notification settings - Fork 157
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
issue #2313 - refactor FingerprintVisitor to avoid startsWith checks
Previously, we constructed the excludePaths on each leaf node, then checked whether the current path started with any of those values. This was faulty because the exclude path Resource.id accidentally resulted in us ignoring fields like Resource.identifier as well. Now we construct the excludePaths as a set during the initial doVisitStart and we don't need "startsWith" because we the visitor supports returning a boolean to control whether child paths should be visited or not. Signed-off-by: Lee Surprenant <lmsurpre@us.ibm.com>
- Loading branch information
Showing
2 changed files
with
219 additions
and
51 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
175 changes: 175 additions & 0 deletions
175
fhir-model/src/test/java/com/ibm/fhir/model/util/test/ResourceFingerprintVisitorTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,175 @@ | ||
/* | ||
* (C) Copyright IBM Corp. 2021 | ||
* | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
package com.ibm.fhir.model.util.test; | ||
|
||
import static com.ibm.fhir.model.type.String.string; | ||
import static org.junit.Assert.assertNotEquals; | ||
import static org.testng.Assert.assertEquals; | ||
|
||
import java.util.stream.Collectors; | ||
|
||
import org.testng.annotations.Test; | ||
|
||
import com.ibm.fhir.model.resource.Patient; | ||
import com.ibm.fhir.model.test.TestUtil; | ||
import com.ibm.fhir.model.type.Extension; | ||
import com.ibm.fhir.model.type.Id; | ||
import com.ibm.fhir.model.type.Identifier; | ||
import com.ibm.fhir.model.type.Instant; | ||
import com.ibm.fhir.model.type.code.IdentifierUse; | ||
import com.ibm.fhir.model.type.code.ResourceType; | ||
import com.ibm.fhir.model.util.SaltHash; | ||
import com.ibm.fhir.model.visitor.ResourceFingerprintVisitor; | ||
|
||
/** | ||
* | ||
*/ | ||
public class ResourceFingerprintVisitorTest { | ||
@Test | ||
public void testEqualResources() throws Exception { | ||
Patient patient = TestUtil.getMinimalResource(ResourceType.PATIENT); | ||
|
||
ResourceFingerprintVisitor resourceFingerprintVisitor = new ResourceFingerprintVisitor(); | ||
patient.accept(resourceFingerprintVisitor); | ||
SaltHash baseline = resourceFingerprintVisitor.getSaltAndHash(); | ||
|
||
// same resource should match | ||
resourceFingerprintVisitor = new ResourceFingerprintVisitor(baseline); | ||
patient.accept(resourceFingerprintVisitor); | ||
assertEquals(resourceFingerprintVisitor.getSaltAndHash(), baseline); | ||
|
||
// shallowly rebuilt resource should match | ||
resourceFingerprintVisitor = new ResourceFingerprintVisitor(baseline); | ||
patient.toBuilder().build().accept(resourceFingerprintVisitor); | ||
assertEquals(resourceFingerprintVisitor.getSaltAndHash(), baseline); | ||
|
||
// deeply rebuilt resource should match | ||
patient = patient.toBuilder() | ||
.meta(patient.getMeta().toBuilder() | ||
.tag(patient.getMeta().getTag().stream() | ||
.map(t -> t.toBuilder() | ||
.code(t.getCode().toBuilder().build()) | ||
.build()) | ||
.collect(Collectors.toList())) | ||
.build()) | ||
.build(); | ||
resourceFingerprintVisitor = new ResourceFingerprintVisitor(baseline); | ||
patient.accept(resourceFingerprintVisitor); | ||
assertEquals(resourceFingerprintVisitor.getSaltAndHash(), baseline); | ||
} | ||
|
||
@Test | ||
public void testUnequalResources_add() throws Exception { | ||
Patient patient = TestUtil.getMinimalResource(ResourceType.PATIENT); | ||
|
||
ResourceFingerprintVisitor resourceFingerprintVisitor = new ResourceFingerprintVisitor(); | ||
patient.accept(resourceFingerprintVisitor); | ||
SaltHash baseline = resourceFingerprintVisitor.getSaltAndHash(); | ||
|
||
patient = patient.toBuilder() | ||
.identifier(Identifier.builder() | ||
.use(IdentifierUse.USUAL) | ||
.build()) | ||
.build(); | ||
resourceFingerprintVisitor = new ResourceFingerprintVisitor(baseline); | ||
patient.accept(resourceFingerprintVisitor); | ||
assertNotEquals(resourceFingerprintVisitor.getSaltAndHash(), baseline); | ||
} | ||
|
||
@Test | ||
public void testUnequalResources_remove() throws Exception { | ||
Patient patient = TestUtil.getMinimalResource(ResourceType.PATIENT); | ||
|
||
ResourceFingerprintVisitor resourceFingerprintVisitor = new ResourceFingerprintVisitor(); | ||
patient.accept(resourceFingerprintVisitor); | ||
SaltHash baseline = resourceFingerprintVisitor.getSaltAndHash(); | ||
|
||
patient = patient.toBuilder() | ||
.meta(null) | ||
.build(); | ||
resourceFingerprintVisitor = new ResourceFingerprintVisitor(baseline); | ||
patient.accept(resourceFingerprintVisitor); | ||
assertNotEquals(resourceFingerprintVisitor.getSaltAndHash(), baseline); | ||
} | ||
|
||
@Test | ||
public void testUnequalResources_reorder() throws Exception { | ||
Patient patient = TestUtil.getMinimalResource(ResourceType.PATIENT); | ||
patient = patient.toBuilder() | ||
.identifier(Identifier.builder() | ||
.use(IdentifierUse.USUAL) | ||
.build()) | ||
.identifier(Identifier.builder() | ||
.use(IdentifierUse.OFFICIAL) | ||
.build()) | ||
.build(); | ||
|
||
ResourceFingerprintVisitor resourceFingerprintVisitor = new ResourceFingerprintVisitor(); | ||
patient.accept(resourceFingerprintVisitor); | ||
SaltHash baseline = resourceFingerprintVisitor.getSaltAndHash(); | ||
|
||
patient = patient.toBuilder() | ||
.identifier(Identifier.builder() | ||
.use(IdentifierUse.OFFICIAL) | ||
.build()) | ||
.identifier(Identifier.builder() | ||
.use(IdentifierUse.USUAL) | ||
.build()) | ||
.build(); | ||
resourceFingerprintVisitor = new ResourceFingerprintVisitor(baseline); | ||
patient.accept(resourceFingerprintVisitor); | ||
|
||
assertNotEquals(resourceFingerprintVisitor.getSaltAndHash(), baseline); | ||
} | ||
|
||
@Test | ||
public void testIgnoredPaths() throws Exception { | ||
Patient patient = TestUtil.getMinimalResource(ResourceType.PATIENT); | ||
|
||
ResourceFingerprintVisitor resourceFingerprintVisitor = new ResourceFingerprintVisitor(); | ||
patient.accept(resourceFingerprintVisitor); | ||
SaltHash baseline = resourceFingerprintVisitor.getSaltAndHash(); | ||
System.out.println(patient); | ||
|
||
patient = patient.toBuilder() | ||
.id("test") | ||
.meta(patient.getMeta().toBuilder() | ||
.versionId(Id.of("ignoreMe")) | ||
.lastUpdated(Instant.now()) | ||
.build()) | ||
.build(); | ||
resourceFingerprintVisitor = new ResourceFingerprintVisitor(baseline); | ||
patient.accept(resourceFingerprintVisitor); | ||
|
||
System.out.println(patient); | ||
assertEquals(resourceFingerprintVisitor.getSaltAndHash(), baseline); | ||
} | ||
|
||
@Test | ||
public void testUnequalResources_extension() throws Exception { | ||
Patient patient = TestUtil.getMinimalResource(ResourceType.PATIENT); | ||
|
||
ResourceFingerprintVisitor resourceFingerprintVisitor = new ResourceFingerprintVisitor(); | ||
patient.accept(resourceFingerprintVisitor); | ||
SaltHash baseline = resourceFingerprintVisitor.getSaltAndHash(); | ||
|
||
patient = patient.toBuilder() | ||
.meta(patient.getMeta().toBuilder() | ||
.tag(patient.getMeta().getTag().get(0).toBuilder() | ||
.code(patient.getMeta().getTag().get(0).getCode().toBuilder() | ||
.extension(Extension.builder() | ||
.url("http://example.com") | ||
.value(string("primitive extension")) | ||
.build()) | ||
.build()) | ||
.build()) | ||
.build()) | ||
.build(); | ||
resourceFingerprintVisitor = new ResourceFingerprintVisitor(baseline); | ||
patient.accept(resourceFingerprintVisitor); | ||
assertNotEquals(resourceFingerprintVisitor.getSaltAndHash(), baseline); | ||
} | ||
} |