json-diff icon indicating copy to clipboard operation
json-diff copied to clipboard

Need an Object matcher that can ignore fields from expected and/or received json

Open tokazio opened this issue 1 year ago • 1 comments

Needed an Object matcher that can ignore fields from expected and/or received json

I've made this one (in kotlin), maybe you could integrate it.

class CustomJsonObjectPartialMatcher(
  val excludingExpected: List<String> = emptyList(),
  val excludingReceived: List<String> = emptyList()
) : PartialJsonMatcher<ObjectNode> {

    override fun jsonDiff(path: Path, receivedJson: ObjectNode?, expectedJson: ObjectNode, jsonMatcher: JsonMatcher): JsonDiff {
        var jsonDiff = JsonObjectDiff(path)
        Objects.requireNonNull<ObjectNode>(receivedJson)
        val receivedJsonFields: MutableSet<String> = receivedJson!!.fieldNames().asSequence().toMutableSet()
        expectedJson.fields().forEachRemaining { (expectedPropertyName, expectedValue) ->
            if (!excludingExpected.contains(transformedPropertyName(path,expectedPropertyName) )) {
                var receivedValue = receivedJson.get(expectedPropertyName)
                if (receivedValue == null) {
                    jsonDiff.addNotFoundProperty(expectedPropertyName, expectedValue)
                } else {
                    var diff = jsonMatcher.diff(path.add(Path.PathItem.of(expectedPropertyName)), expectedValue, receivedValue)
                    jsonDiff.addPropertyDiff(expectedPropertyName, diff)
                }
                receivedJsonFields.remove(expectedPropertyName)
            }
        }
        receivedJson.fields().forEachRemaining { (receivedPropertyName, receivedPropertyValue) ->
            if (!excludingReceived.contains(transformedPropertyName(path,receivedPropertyName) )) {
                var expectedValue = expectedJson.get(receivedPropertyName)
                if (expectedValue == null) {
                    jsonDiff.addExtraProperty(receivedPropertyName, receivedPropertyValue)
                }
            }
        }
        return jsonDiff
    }

    val regex = "\\.\\d+|\\\$\\.".toRegex()

    private fun transformedPropertyName(path: Path, propertyName: String): String {
        return if("$"==path.toString())
            propertyName
        else {
            path.toString().replace(regex, "")+".$propertyName"
        }
    }

...( expectedJson = legacyProfileJson, excludingExpected = listOf( "talentId", "aptitudes.favorite", //sub fields from an array ($.aptitues.0.favorite) ), excludingReceived = listOf( "permissionScope", ) )

tokazio avatar May 19 '24 00:05 tokazio

Hi, Thank you for this proposal. I'm working on a refactoring of this project, I think it will be easier to implement this kind of feature afterwards.

deblockt avatar May 20 '24 15:05 deblockt