jay_diff: fix two correctness bugs + add real-data round-trip tests

Bug 1 (crash): jay_merge_delete iterated _new.items() while _old (which
aliases _new sub-dicts due to jay_diff_rev's side-effect writes) was being
mutated.  Fixed by snapshotting with list(_new.items()) before iteration.

Bug 2 (wrong round-trip): When new has an empty dict {} at a location where
old had a non-empty dict, jay_merge_delete incorrectly pruned the now-empty
parent key.  Root cause: jay_diff_del stored the full old sub-dict in the
delete delta for both "key absent from new" and "key present but empty in
new", making them indistinguishable at merge time.

Fix: jay_diff_del is now a standalone recursive function that stores None
for dict keys entirely absent from new (sentinel for "delete entire key")
vs a sub-dict of specific sub-keys for partial deletions.  jay_merge_delete
no longer prunes empty dicts; None (or any non-dict value) in the delta is
the explicit signal to remove the parent key.

Also adds:
- tests/data/  — copy of 25 real JSON log files for integration testing
- tests/test_jay_diff_real_data.py — 2028 parametrised round-trip tests
  over 675 real vehicle snapshots; exposed and confirmed both bugs above

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-05-27 12:25:35 +02:00
co-authored by Claude Sonnet 4.6
parent 5ef7f13118
commit c8de234423
28 changed files with 92272 additions and 35 deletions
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,293 @@
{
"meta": {
"vin": "WVWZZZE1ZMP010760",
"created_at": "2026-05-26T11:37:05.156831+00:00",
"interval_seconds": 30
},
"records": [
{
"ts": "2026-05-26T11:37:08.127749+00:00",
"charging": {
"chargingStatus": {
"chargingState": "ChargingState.CHARGE_PURPOSE_REACHED_CONSERVATION",
"chargePower": {
"value": 0.0,
"unit": "kW"
},
"remainingChargingTimeToComplete": {
"value": 0,
"unit": "min"
},
"chargeType": "ChargeType.AC"
},
"batteryStatus": {
"currentSOC": {
"value": 80,
"unit": "%"
},
"cruisingRangeElectric": {
"value": 280,
"unit": "km"
}
},
"chargingSettings": {
"targetSOC": {
"value": 80,
"unit": "%"
},
"maxChargeCurrentAC": "MaximumChargeCurrent.MAXIMUM",
"autoUnlockPlugWhenCharged": "UnlockPlugState.OFF"
},
"plugStatus": {
"plugConnectionState": "PlugConnectionState.CONNECTED",
"plugLockState": "PlugLockState.LOCKED",
"externalPower": "ExternalPower.READY"
}
},
"measurements": {
"odometerStatus": {
"odometer": {
"value": 67419,
"unit": "km"
}
},
"rangeStatus": {
"electricRange": {
"value": 280,
"unit": "km"
},
"totalRange": {
"value": 280,
"unit": "km"
}
},
"temperatureBatteryStatus": {
"temperatureHvBatteryMax": {
"value": 23.5,
"unit": "degC"
},
"temperatureHvBatteryMin": {
"value": 22.0,
"unit": "degC"
}
}
},
"climatisation": {
"climatisationStatus": {
"climatisationState": "ClimatizationState.OFF",
"remainingClimatisationTime": {
"value": 0,
"unit": "min"
}
},
"climatisationSettings": {
"targetTemperature": {
"value": 21.0,
"unit": "degC"
},
"unitInCar": "UnitInCar.CELSIUS"
},
"windowHeatingStatus": {
"front": "WindowHeatingState.OFF",
"rear": "WindowHeatingState.OFF"
}
},
"access": {
"accessStatus": {
"overallStatus": "OverallState.SAFE",
"doors": {
"bonnet": {
"lockState": "LockState.UNKNOWN",
"openState": "OpenState.CLOSED"
},
"trunk": {
"lockState": "LockState.LOCKED",
"openState": "OpenState.CLOSED"
},
"rearRight": {
"lockState": "LockState.LOCKED",
"openState": "OpenState.CLOSED"
},
"rearLeft": {
"lockState": "LockState.LOCKED",
"openState": "OpenState.CLOSED"
},
"frontRight": {
"lockState": "LockState.LOCKED",
"openState": "OpenState.CLOSED"
},
"frontLeft": {
"lockState": "LockState.LOCKED",
"openState": "OpenState.CLOSED"
}
},
"windows": {
"sunRoof": {
"openState": "OpenState.UNSUPPORTED"
},
"roofCover": {
"openState": "OpenState.UNSUPPORTED"
},
"sunRoofRear": {
"openState": "OpenState.UNSUPPORTED"
},
"frontLeft": {
"openState": "OpenState.CLOSED"
},
"frontRight": {
"openState": "OpenState.CLOSED"
},
"rearLeft": {
"openState": "OpenState.CLOSED"
},
"rearRight": {
"openState": "OpenState.CLOSED"
}
}
}
}
},
{
"ts": "2026-05-26T11:37:43.660250+00:00",
"charging": {
"chargingStatus": {
"chargingState": "ChargingState.CHARGE_PURPOSE_REACHED_CONSERVATION",
"chargePower": {
"value": 0.0,
"unit": "kW"
},
"remainingChargingTimeToComplete": {
"value": 0,
"unit": "min"
},
"chargeType": "ChargeType.AC"
},
"batteryStatus": {
"currentSOC": {
"value": 80,
"unit": "%"
},
"cruisingRangeElectric": {
"value": 280,
"unit": "km"
}
},
"chargingSettings": {
"targetSOC": {
"value": 80,
"unit": "%"
},
"maxChargeCurrentAC": "MaximumChargeCurrent.MAXIMUM",
"autoUnlockPlugWhenCharged": "UnlockPlugState.OFF"
},
"plugStatus": {
"plugConnectionState": "PlugConnectionState.CONNECTED",
"plugLockState": "PlugLockState.LOCKED",
"externalPower": "ExternalPower.READY"
}
},
"measurements": {
"odometerStatus": {
"odometer": {
"value": 67419,
"unit": "km"
}
},
"rangeStatus": {
"electricRange": {
"value": 280,
"unit": "km"
},
"totalRange": {
"value": 280,
"unit": "km"
}
},
"temperatureBatteryStatus": {
"temperatureHvBatteryMax": {
"value": 23.5,
"unit": "degC"
},
"temperatureHvBatteryMin": {
"value": 22.0,
"unit": "degC"
}
}
},
"climatisation": {
"climatisationStatus": {
"climatisationState": "ClimatizationState.OFF",
"remainingClimatisationTime": {
"value": 0,
"unit": "min"
}
},
"climatisationSettings": {
"targetTemperature": {
"value": 21.0,
"unit": "degC"
},
"unitInCar": "UnitInCar.CELSIUS"
},
"windowHeatingStatus": {
"front": "WindowHeatingState.OFF",
"rear": "WindowHeatingState.OFF"
}
},
"access": {
"accessStatus": {
"overallStatus": "OverallState.SAFE",
"doors": {
"bonnet": {
"lockState": "LockState.UNKNOWN",
"openState": "OpenState.CLOSED"
},
"trunk": {
"lockState": "LockState.LOCKED",
"openState": "OpenState.CLOSED"
},
"rearRight": {
"lockState": "LockState.LOCKED",
"openState": "OpenState.CLOSED"
},
"rearLeft": {
"lockState": "LockState.LOCKED",
"openState": "OpenState.CLOSED"
},
"frontRight": {
"lockState": "LockState.LOCKED",
"openState": "OpenState.CLOSED"
},
"frontLeft": {
"lockState": "LockState.LOCKED",
"openState": "OpenState.CLOSED"
}
},
"windows": {
"sunRoof": {
"openState": "OpenState.UNSUPPORTED"
},
"roofCover": {
"openState": "OpenState.UNSUPPORTED"
},
"sunRoofRear": {
"openState": "OpenState.UNSUPPORTED"
},
"frontLeft": {
"openState": "OpenState.CLOSED"
},
"frontRight": {
"openState": "OpenState.CLOSED"
},
"rearLeft": {
"openState": "OpenState.CLOSED"
},
"rearRight": {
"openState": "OpenState.CLOSED"
}
}
}
}
}
]
}
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,485 @@
{
"meta": {
"vin": "WVWZZZE1ZMP010760",
"created_at": "2026-05-27T05:53:07.953894+00:00",
"interval_seconds": 30
},
"records": [
{
"ts": "2026-05-27T05:53:08.103087+00:00",
"charging": {
"chargingStatus": {
"chargingState": "off",
"chargeType": "invalid",
"chargePower": {
"value": 0.0,
"unit": "kW"
},
"remainingChargingTimeToComplete": {
"value": 0,
"unit": "min"
}
},
"batteryStatus": {
"currentSOC": {
"value": 58.0,
"unit": "%"
},
"cruisingRangeElectric": {
"value": 209.0,
"unit": "km"
}
},
"chargingSettings": {
"targetSOC": {
"value": 80.0,
"unit": "%"
},
"maxChargeCurrentAC": {
"value": 16.0,
"unit": "A"
},
"autoUnlockPlugWhenCharged": "False"
},
"plugStatus": {
"plugConnectionState": "disconnected",
"plugLockState": "unlocked",
"externalPower": "unavailable"
}
},
"measurements": {
"odometerStatus": {
"odometer": {
"value": 67489.0,
"unit": "km"
}
},
"rangeStatus": {
"electricRange": {
"value": 209.0,
"unit": "km"
},
"totalRange": {
"value": 209.0,
"unit": "km"
}
},
"temperatureBatteryStatus": {
"temperatureHvBatteryMax": {
"value": 295.15,
"unit": "degC"
},
"temperatureHvBatteryMin": {
"value": 294.15,
"unit": "degC"
}
},
"temperatureOutsideStatus": {
"temperatureOutside": {
"value": null,
"unit": "degC"
}
}
},
"readiness": {
"readinessStatus": {
"connectionState": {
"isOnline": false,
"isActive": true
}
}
},
"climatisation": {
"climatisationStatus": {
"climatisationState": "off",
"remainingClimatisationTime": {
"value": 0,
"unit": "min"
}
},
"climatisationSettings": {
"targetTemperature": {
"value": 21.0,
"unit": "degC"
}
}
},
"parking": {
"parkingPosition": {
"lat": null,
"lon": null
}
},
"access": {
"accessStatus": {
"overallStatus": "None",
"doors": {},
"windows": {}
}
},
"procedural": {
"range_at_100": {
"value": 360.3,
"unit": "km"
}
}
},
{
"ts": "2026-05-27T05:53:38.257550+00:00",
"charging": {
"chargingStatus": {
"chargingState": "off",
"chargeType": "invalid",
"chargePower": {
"value": 0.0,
"unit": "kW"
},
"remainingChargingTimeToComplete": {
"value": 0,
"unit": "min"
}
},
"batteryStatus": {
"currentSOC": {
"value": 58.0,
"unit": "%"
},
"cruisingRangeElectric": {
"value": 209.0,
"unit": "km"
}
},
"chargingSettings": {
"targetSOC": {
"value": 80.0,
"unit": "%"
},
"maxChargeCurrentAC": {
"value": 16.0,
"unit": "A"
},
"autoUnlockPlugWhenCharged": "False"
},
"plugStatus": {
"plugConnectionState": "disconnected",
"plugLockState": "unlocked",
"externalPower": "unavailable"
}
},
"measurements": {
"odometerStatus": {
"odometer": {
"value": 67489.0,
"unit": "km"
}
},
"rangeStatus": {
"electricRange": {
"value": 209.0,
"unit": "km"
},
"totalRange": {
"value": 209.0,
"unit": "km"
}
},
"temperatureBatteryStatus": {
"temperatureHvBatteryMax": {
"value": 295.15,
"unit": "degC"
},
"temperatureHvBatteryMin": {
"value": 294.15,
"unit": "degC"
}
},
"temperatureOutsideStatus": {
"temperatureOutside": {
"value": null,
"unit": "degC"
}
}
},
"readiness": {
"readinessStatus": {
"connectionState": {
"isOnline": false,
"isActive": true
}
}
},
"climatisation": {
"climatisationStatus": {
"climatisationState": "off",
"remainingClimatisationTime": {
"value": 0,
"unit": "min"
}
},
"climatisationSettings": {
"targetTemperature": {
"value": 21.0,
"unit": "degC"
}
}
},
"parking": {
"parkingPosition": {
"lat": null,
"lon": null
}
},
"access": {
"accessStatus": {
"overallStatus": "None",
"doors": {},
"windows": {}
}
},
"procedural": {
"range_at_100": {
"value": 360.3,
"unit": "km"
}
}
},
{
"ts": "2026-05-27T05:54:08.438969+00:00",
"charging": {
"chargingStatus": {
"chargingState": "off",
"chargeType": "invalid",
"chargePower": {
"value": 0.0,
"unit": "kW"
},
"remainingChargingTimeToComplete": {
"value": 0,
"unit": "min"
}
},
"batteryStatus": {
"currentSOC": {
"value": 58.0,
"unit": "%"
},
"cruisingRangeElectric": {
"value": 209.0,
"unit": "km"
}
},
"chargingSettings": {
"targetSOC": {
"value": 80.0,
"unit": "%"
},
"maxChargeCurrentAC": {
"value": 16.0,
"unit": "A"
},
"autoUnlockPlugWhenCharged": "False"
},
"plugStatus": {
"plugConnectionState": "disconnected",
"plugLockState": "unlocked",
"externalPower": "unavailable"
}
},
"measurements": {
"odometerStatus": {
"odometer": {
"value": 67489.0,
"unit": "km"
}
},
"rangeStatus": {
"electricRange": {
"value": 209.0,
"unit": "km"
},
"totalRange": {
"value": 209.0,
"unit": "km"
}
},
"temperatureBatteryStatus": {
"temperatureHvBatteryMax": {
"value": 295.15,
"unit": "degC"
},
"temperatureHvBatteryMin": {
"value": 294.15,
"unit": "degC"
}
},
"temperatureOutsideStatus": {
"temperatureOutside": {
"value": null,
"unit": "degC"
}
}
},
"readiness": {
"readinessStatus": {
"connectionState": {
"isOnline": false,
"isActive": true
}
}
},
"climatisation": {
"climatisationStatus": {
"climatisationState": "off",
"remainingClimatisationTime": {
"value": 0,
"unit": "min"
}
},
"climatisationSettings": {
"targetTemperature": {
"value": 21.0,
"unit": "degC"
}
}
},
"parking": {
"parkingPosition": {
"lat": null,
"lon": null
}
},
"access": {
"accessStatus": {
"overallStatus": "None",
"doors": {},
"windows": {}
}
},
"procedural": {
"range_at_100": {
"value": 360.3,
"unit": "km"
}
}
},
{
"ts": "2026-05-27T05:54:38.603661+00:00",
"charging": {
"chargingStatus": {
"chargingState": "off",
"chargeType": "invalid",
"chargePower": {
"value": 0.0,
"unit": "kW"
},
"remainingChargingTimeToComplete": {
"value": 0,
"unit": "min"
}
},
"batteryStatus": {
"currentSOC": {
"value": 58.0,
"unit": "%"
},
"cruisingRangeElectric": {
"value": 209.0,
"unit": "km"
}
},
"chargingSettings": {
"targetSOC": {
"value": 80.0,
"unit": "%"
},
"maxChargeCurrentAC": {
"value": 16.0,
"unit": "A"
},
"autoUnlockPlugWhenCharged": "False"
},
"plugStatus": {
"plugConnectionState": "disconnected",
"plugLockState": "unlocked",
"externalPower": "unavailable"
}
},
"measurements": {
"odometerStatus": {
"odometer": {
"value": 67489.0,
"unit": "km"
}
},
"rangeStatus": {
"electricRange": {
"value": 209.0,
"unit": "km"
},
"totalRange": {
"value": 209.0,
"unit": "km"
}
},
"temperatureBatteryStatus": {
"temperatureHvBatteryMax": {
"value": 295.15,
"unit": "degC"
},
"temperatureHvBatteryMin": {
"value": 294.15,
"unit": "degC"
}
},
"temperatureOutsideStatus": {
"temperatureOutside": {
"value": null,
"unit": "degC"
}
}
},
"readiness": {
"readinessStatus": {
"connectionState": {
"isOnline": false,
"isActive": true
}
}
},
"climatisation": {
"climatisationStatus": {
"climatisationState": "off",
"remainingClimatisationTime": {
"value": 0,
"unit": "min"
}
},
"climatisationSettings": {
"targetTemperature": {
"value": 21.0,
"unit": "degC"
}
}
},
"parking": {
"parkingPosition": {
"lat": null,
"lon": null
}
},
"access": {
"accessStatus": {
"overallStatus": "None",
"doors": {},
"windows": {}
}
},
"procedural": {
"range_at_100": {
"value": 360.3,
"unit": "km"
}
}
}
]
}
@@ -0,0 +1,128 @@
{
"meta": {
"vin": "WVWZZZE1ZMP010760",
"created_at": "2026-05-27T05:55:03.027525+00:00",
"interval_seconds": 30
},
"records": [
{
"ts": "2026-05-27T05:55:03.219238+00:00",
"charging": {
"chargingStatus": {
"chargingState": "off",
"chargeType": "invalid",
"chargePower": {
"value": 0.0,
"unit": "kW"
},
"remainingChargingTimeToComplete": {
"value": 0,
"unit": "min"
}
},
"batteryStatus": {
"currentSOC": {
"value": 58.0,
"unit": "%"
},
"cruisingRangeElectric": {
"value": 209.0,
"unit": "km"
}
},
"chargingSettings": {
"targetSOC": {
"value": 80.0,
"unit": "%"
},
"maxChargeCurrentAC": {
"value": 16.0,
"unit": "A"
},
"autoUnlockPlugWhenCharged": "False"
},
"plugStatus": {
"plugConnectionState": "disconnected",
"plugLockState": "unlocked",
"externalPower": "unavailable"
}
},
"measurements": {
"odometerStatus": {
"odometer": {
"value": 67489.0,
"unit": "km"
}
},
"rangeStatus": {
"electricRange": {
"value": 209.0,
"unit": "km"
},
"totalRange": {
"value": 209.0,
"unit": "km"
}
},
"temperatureBatteryStatus": {
"temperatureHvBatteryMax": {
"value": 295.15,
"unit": "degC"
},
"temperatureHvBatteryMin": {
"value": 294.15,
"unit": "degC"
}
},
"temperatureOutsideStatus": {
"temperatureOutside": {
"value": null,
"unit": "degC"
}
}
},
"readiness": {
"readinessStatus": {
"connectionState": {
"isOnline": false,
"isActive": true
}
}
},
"climatisation": {
"climatisationStatus": {
"climatisationState": "off",
"remainingClimatisationTime": {
"value": 0,
"unit": "min"
}
},
"climatisationSettings": {
"targetTemperature": {
"value": 21.0,
"unit": "degC"
}
}
},
"parking": {
"parkingPosition": {
"lat": null,
"lon": null
}
},
"access": {
"accessStatus": {
"overallStatus": "None",
"doors": {},
"windows": {}
}
},
"procedural": {
"range_at_100": {
"value": 360.3,
"unit": "km"
}
}
}
]
}
@@ -0,0 +1,130 @@
{
"meta": {
"vin": "WVWZZZE1ZMP010760",
"created_at": "2026-05-27T06:17:18.385566+00:00",
"interval_seconds": 30
},
"records": [
{
"ts": "2026-05-27T06:17:18.554491+00:00",
"charging": {
"chargingStatus": {
"chargingState": "off",
"chargeType": "invalid",
"chargePower": {
"value": 0.0,
"unit": "kW"
},
"remainingChargingTimeToComplete": {
"value": 0,
"unit": "min"
}
},
"batteryStatus": {
"currentSOC": {
"value": 58.0,
"unit": "%"
},
"cruisingRangeElectric": {
"value": 209.0,
"unit": "km"
}
},
"chargingSettings": {
"targetSOC": {
"value": 80.0,
"unit": "%"
},
"maxChargeCurrentAC": {
"value": 16.0,
"unit": "A"
},
"autoUnlockPlugWhenCharged": "False"
},
"plugStatus": {
"plugConnectionState": "disconnected",
"plugLockState": "unlocked",
"externalPower": "unavailable"
}
},
"measurements": {
"odometerStatus": {
"odometer": {
"value": 67489.0,
"unit": "km"
}
},
"rangeStatus": {
"electricRange": {
"value": 209.0,
"unit": "km"
},
"totalRange": {
"value": 209.0,
"unit": "km"
}
},
"temperatureBatteryStatus": {
"temperatureHvBatteryMax": {
"value": 295.15,
"unit": "degC"
},
"temperatureHvBatteryMin": {
"value": 294.15,
"unit": "degC"
}
},
"temperatureOutsideStatus": {
"temperatureOutside": {
"value": null,
"unit": "degC"
}
}
},
"vehicle": {
"vehicle": {
"state": "unknown vehicle state"
}
},
"connectivity": {
"connection": {
"state": "reachable"
}
},
"climatisation": {
"climatisationStatus": {
"climatisationState": "off",
"remainingClimatisationTime": {
"value": 0,
"unit": "min"
}
},
"climatisationSettings": {
"targetTemperature": {
"value": 21.0,
"unit": "degC"
}
}
},
"position": {
"position": {
"lat": null,
"lon": null
}
},
"doors": {
"doors": {
"overallState": "None",
"doors": {},
"windows": {}
}
},
"procedural": {
"range_at_100": {
"value": 360.3,
"unit": "km"
}
}
}
]
}
@@ -0,0 +1,130 @@
{
"meta": {
"vin": "WVWZZZE1ZMP010760",
"created_at": "2026-05-27T06:18:28.783719+00:00",
"interval_seconds": 30
},
"records": [
{
"ts": "2026-05-27T06:18:28.981339+00:00",
"charging": {
"chargingStatus": {
"chargingState": "off",
"chargeType": "invalid",
"chargePower": {
"value": 0.0,
"unit": "kW"
},
"remainingChargingTimeToComplete": {
"value": 0,
"unit": "min"
}
},
"batteryStatus": {
"currentSOC": {
"value": 58.0,
"unit": "%"
},
"cruisingRangeElectric": {
"value": 209.0,
"unit": "km"
}
},
"chargingSettings": {
"targetSOC": {
"value": 80.0,
"unit": "%"
},
"maxChargeCurrentAC": {
"value": 16.0,
"unit": "A"
},
"autoUnlockPlugWhenCharged": "False"
},
"plugStatus": {
"plugConnectionState": "disconnected",
"plugLockState": "unlocked",
"externalPower": "unavailable"
}
},
"measurements": {
"odometerStatus": {
"odometer": {
"value": 67489.0,
"unit": "km"
}
},
"rangeStatus": {
"electricRange": {
"value": 209.0,
"unit": "km"
},
"totalRange": {
"value": 209.0,
"unit": "km"
}
},
"temperatureBatteryStatus": {
"temperatureHvBatteryMax": {
"value": 295.15,
"unit": "degC"
},
"temperatureHvBatteryMin": {
"value": 294.15,
"unit": "degC"
}
},
"temperatureOutsideStatus": {
"temperatureOutside": {
"value": null,
"unit": "degC"
}
}
},
"vehicle": {
"vehicle": {
"state": "unknown vehicle state"
}
},
"connectivity": {
"connection": {
"state": "reachable"
}
},
"climatisation": {
"climatisationStatus": {
"climatisationState": "off",
"remainingClimatisationTime": {
"value": 0,
"unit": "min"
}
},
"climatisationSettings": {
"targetTemperature": {
"value": 21.0,
"unit": "degC"
}
}
},
"position": {
"position": {
"lat": null,
"lon": null
}
},
"doors": {
"doors": {
"overallState": "None",
"doors": {},
"windows": {}
}
},
"procedural": {
"range_at_100": {
"value": 360.3,
"unit": "km"
}
}
}
]
}
@@ -0,0 +1,130 @@
{
"meta": {
"vin": "WVWZZZE1ZMP010760",
"created_at": "2026-05-27T06:21:01.933728+00:00",
"interval_seconds": 30
},
"records": [
{
"ts": "2026-05-27T06:21:02.150738+00:00",
"charging": {
"chargingStatus": {
"chargingState": "off",
"chargeType": "invalid",
"chargePower": {
"value": 0.0,
"unit": "kW"
},
"remainingChargingTimeToComplete": {
"value": 0,
"unit": "min"
}
},
"batteryStatus": {
"currentSOC": {
"value": 58.0,
"unit": "%"
},
"cruisingRangeElectric": {
"value": 209.0,
"unit": "km"
}
},
"chargingSettings": {
"targetSOC": {
"value": 80.0,
"unit": "%"
},
"maxChargeCurrentAC": {
"value": 16.0,
"unit": "A"
},
"autoUnlockPlugWhenCharged": "False"
},
"plugStatus": {
"plugConnectionState": "disconnected",
"plugLockState": "unlocked",
"externalPower": "unavailable"
}
},
"measurements": {
"odometerStatus": {
"odometer": {
"value": 67489.0,
"unit": "km"
}
},
"rangeStatus": {
"electricRange": {
"value": 209.0,
"unit": "km"
},
"totalRange": {
"value": 209.0,
"unit": "km"
}
},
"temperatureBatteryStatus": {
"temperatureHvBatteryMax": {
"value": 295.15,
"unit": "degC"
},
"temperatureHvBatteryMin": {
"value": 294.15,
"unit": "degC"
}
},
"temperatureOutsideStatus": {
"temperatureOutside": {
"value": null,
"unit": "degC"
}
}
},
"vehicle": {
"vehicle": {
"state": "unknown vehicle state"
}
},
"connectivity": {
"connection": {
"state": "reachable"
}
},
"climatisation": {
"climatisationStatus": {
"climatisationState": "off",
"remainingClimatisationTime": {
"value": 0,
"unit": "min"
}
},
"climatisationSettings": {
"targetTemperature": {
"value": 21.0,
"unit": "degC"
}
}
},
"position": {
"position": {
"lat": null,
"lon": null
}
},
"doors": {
"doors": {
"overallState": "None",
"doors": {},
"windows": {}
}
},
"procedural": {
"range_at_100": {
"value": 360.3,
"unit": "km"
}
}
}
]
}
@@ -0,0 +1,130 @@
{
"meta": {
"vin": "WVWZZZE1ZMP010760",
"created_at": "2026-05-27T06:33:08.561803+00:00",
"interval_seconds": 30
},
"records": [
{
"ts": "2026-05-27T06:33:08.745827+00:00",
"charging": {
"chargingStatus": {
"chargingState": "off",
"chargeType": "invalid",
"chargePower": {
"value": 0.0,
"unit": "kW"
},
"remainingChargingTimeToComplete": {
"value": 0,
"unit": "min"
}
},
"batteryStatus": {
"currentSOC": {
"value": 58.0,
"unit": "%"
},
"cruisingRangeElectric": {
"value": 209.0,
"unit": "km"
}
},
"chargingSettings": {
"targetSOC": {
"value": 80.0,
"unit": "%"
},
"maxChargeCurrentAC": {
"value": 16.0,
"unit": "A"
},
"autoUnlockPlugWhenCharged": "False"
},
"plugStatus": {
"plugConnectionState": "disconnected",
"plugLockState": "unlocked",
"externalPower": "unavailable"
}
},
"electric_system": {
"electric_system": {
"range": {
"value": 209.0,
"unit": "km"
},
"range_full": {
"value": 360.3448275862069,
"unit": "km"
},
"battery": {
"temperature_max": {
"value": 295.15,
"unit": "degC"
},
"temperature_min": {
"value": 294.15,
"unit": "degC"
}
}
},
"odometer": {
"odometer": {
"value": 67489.0,
"unit": "km"
}
},
"environment": {
"temperature_outside": {
"value": null,
"unit": "degC"
}
}
},
"vehicle": {
"vehicle": {
"state": "unknown vehicle state"
}
},
"connectivity": {
"connectivity": {
"state": "reachable"
}
},
"climatisation": {
"climatisationStatus": {
"climatisationState": "off",
"remainingClimatisationTime": {
"value": 0,
"unit": "min"
}
},
"climatisationSettings": {
"targetTemperature": {
"value": 21.0,
"unit": "degC"
}
}
},
"position": {
"position": {
"lat": null,
"lon": null
}
},
"doors": {
"doors": {
"overallState": "None",
"doors": {},
"windows": {}
}
},
"procedural": {
"range_at_100": {
"value": 360.3,
"unit": "km"
}
}
}
]
}
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,627 @@
{
"meta": {
"vin": "WVWZZZE1ZMP010760",
"created_at": "2026-05-27T09:31:50.175248+00:00",
"interval_seconds": 30
},
"records": [
{
"ts": "2026-05-27T09:31:50.333801+00:00",
"charging": {
"state": "off",
"type": "invalid",
"power": {
"value": 0.0,
"unit": "kW"
},
"remain": {
"value": 0,
"unit": "min"
},
"settings": {
"target_level": {
"value": 80.0,
"unit": "%"
},
"maximum_current": {
"value": 16.0,
"unit": "A"
},
"auto_unlock": "False"
},
"plugStatus": {
"connection_state": "disconnected",
"lock_state": "unlocked",
"external_power": "unavailable"
}
},
"electric_drive": {
"range": {
"value": 209.0,
"unit": "km"
},
"range_full": {
"value": 360.3,
"unit": "km"
},
"battery": {
"soc": {
"value": 58.0,
"unit": "%"
},
"temperature_max": {
"value": 295.15,
"unit": "degC"
},
"temperature_min": {
"value": 294.15,
"unit": "degC"
}
},
"odometer": {
"odometer": {
"value": 67489.0,
"unit": "km"
}
}
},
"vehicle": {
"state": "unknown vehicle state"
},
"connectivity": {
"state": "reachable"
},
"climatisation": {
"state": "off",
"remain": {
"value": 0,
"unit": "min"
},
"settings": {
"target_temperature": {
"value": 21.0,
"unit": "degC"
}
},
"environment": {
"temperature_outside": {
"value": null,
"unit": "degC"
}
}
},
"position": {
"lat": null,
"lon": null
},
"doors": {
"doors": {
"overallState": "None",
"doors": {},
"windows": {}
}
},
"procedural": {
"range_at_100": {
"value": 360.3,
"unit": "km"
}
}
},
{
"ts": "2026-05-27T09:32:20.484182+00:00",
"charging": {
"state": "off",
"type": "invalid",
"power": {
"value": 0.0,
"unit": "kW"
},
"remain": {
"value": 0,
"unit": "min"
},
"settings": {
"target_level": {
"value": 80.0,
"unit": "%"
},
"maximum_current": {
"value": 16.0,
"unit": "A"
},
"auto_unlock": "False"
},
"plugStatus": {
"connection_state": "disconnected",
"lock_state": "unlocked",
"external_power": "unavailable"
}
},
"electric_drive": {
"range": {
"value": 209.0,
"unit": "km"
},
"range_full": {
"value": 360.3,
"unit": "km"
},
"battery": {
"soc": {
"value": 58.0,
"unit": "%"
},
"temperature_max": {
"value": 295.15,
"unit": "degC"
},
"temperature_min": {
"value": 294.15,
"unit": "degC"
}
},
"odometer": {
"odometer": {
"value": 67489.0,
"unit": "km"
}
}
},
"vehicle": {
"state": "unknown vehicle state"
},
"connectivity": {
"state": "reachable"
},
"climatisation": {
"state": "off",
"remain": {
"value": 0,
"unit": "min"
},
"settings": {
"target_temperature": {
"value": 21.0,
"unit": "degC"
}
},
"environment": {
"temperature_outside": {
"value": null,
"unit": "degC"
}
}
},
"position": {
"lat": null,
"lon": null
},
"doors": {
"doors": {
"overallState": "None",
"doors": {},
"windows": {}
}
},
"procedural": {
"range_at_100": {
"value": 360.3,
"unit": "km"
}
}
},
{
"ts": "2026-05-27T09:32:50.642394+00:00",
"charging": {
"state": "off",
"type": "invalid",
"power": {
"value": 0.0,
"unit": "kW"
},
"remain": {
"value": 0,
"unit": "min"
},
"settings": {
"target_level": {
"value": 80.0,
"unit": "%"
},
"maximum_current": {
"value": 16.0,
"unit": "A"
},
"auto_unlock": "False"
},
"plugStatus": {
"connection_state": "disconnected",
"lock_state": "unlocked",
"external_power": "unavailable"
}
},
"electric_drive": {
"range": {
"value": 209.0,
"unit": "km"
},
"range_full": {
"value": 360.3,
"unit": "km"
},
"battery": {
"soc": {
"value": 58.0,
"unit": "%"
},
"temperature_max": {
"value": 295.15,
"unit": "degC"
},
"temperature_min": {
"value": 294.15,
"unit": "degC"
}
},
"odometer": {
"odometer": {
"value": 67489.0,
"unit": "km"
}
}
},
"vehicle": {
"state": "unknown vehicle state"
},
"connectivity": {
"state": "reachable"
},
"climatisation": {
"state": "off",
"remain": {
"value": 0,
"unit": "min"
},
"settings": {
"target_temperature": {
"value": 21.0,
"unit": "degC"
}
},
"environment": {
"temperature_outside": {
"value": null,
"unit": "degC"
}
}
},
"position": {
"lat": null,
"lon": null
},
"doors": {
"doors": {
"overallState": "None",
"doors": {},
"windows": {}
}
},
"procedural": {
"range_at_100": {
"value": 360.3,
"unit": "km"
}
}
},
{
"ts": "2026-05-27T09:33:20.808989+00:00",
"charging": {
"state": "off",
"type": "invalid",
"power": {
"value": 0.0,
"unit": "kW"
},
"remain": {
"value": 0,
"unit": "min"
},
"settings": {
"target_level": {
"value": 80.0,
"unit": "%"
},
"maximum_current": {
"value": 16.0,
"unit": "A"
},
"auto_unlock": "False"
},
"plugStatus": {
"connection_state": "disconnected",
"lock_state": "unlocked",
"external_power": "unavailable"
}
},
"electric_drive": {
"range": {
"value": 209.0,
"unit": "km"
},
"range_full": {
"value": 360.3,
"unit": "km"
},
"battery": {
"soc": {
"value": 58.0,
"unit": "%"
},
"temperature_max": {
"value": 295.15,
"unit": "degC"
},
"temperature_min": {
"value": 294.15,
"unit": "degC"
}
},
"odometer": {
"odometer": {
"value": 67489.0,
"unit": "km"
}
}
},
"vehicle": {
"state": "unknown vehicle state"
},
"connectivity": {
"state": "reachable"
},
"climatisation": {
"state": "off",
"remain": {
"value": 0,
"unit": "min"
},
"settings": {
"target_temperature": {
"value": 21.0,
"unit": "degC"
}
},
"environment": {
"temperature_outside": {
"value": null,
"unit": "degC"
}
}
},
"position": {
"lat": null,
"lon": null
},
"doors": {
"doors": {
"overallState": "None",
"doors": {},
"windows": {}
}
},
"procedural": {
"range_at_100": {
"value": 360.3,
"unit": "km"
}
}
},
{
"ts": "2026-05-27T09:33:50.960434+00:00",
"charging": {
"state": "off",
"type": "invalid",
"power": {
"value": 0.0,
"unit": "kW"
},
"remain": {
"value": 0,
"unit": "min"
},
"settings": {
"target_level": {
"value": 80.0,
"unit": "%"
},
"maximum_current": {
"value": 16.0,
"unit": "A"
},
"auto_unlock": "False"
},
"plugStatus": {
"connection_state": "disconnected",
"lock_state": "unlocked",
"external_power": "unavailable"
}
},
"electric_drive": {
"range": {
"value": 209.0,
"unit": "km"
},
"range_full": {
"value": 360.3,
"unit": "km"
},
"battery": {
"soc": {
"value": 58.0,
"unit": "%"
},
"temperature_max": {
"value": 295.15,
"unit": "degC"
},
"temperature_min": {
"value": 294.15,
"unit": "degC"
}
},
"odometer": {
"odometer": {
"value": 67489.0,
"unit": "km"
}
}
},
"vehicle": {
"state": "unknown vehicle state"
},
"connectivity": {
"state": "reachable"
},
"climatisation": {
"state": "off",
"remain": {
"value": 0,
"unit": "min"
},
"settings": {
"target_temperature": {
"value": 21.0,
"unit": "degC"
}
},
"environment": {
"temperature_outside": {
"value": null,
"unit": "degC"
}
}
},
"position": {
"lat": null,
"lon": null
},
"doors": {
"doors": {
"overallState": "None",
"doors": {},
"windows": {}
}
},
"procedural": {
"range_at_100": {
"value": 360.3,
"unit": "km"
}
}
},
{
"ts": "2026-05-27T09:34:21.107584+00:00",
"charging": {
"state": "off",
"type": "invalid",
"power": {
"value": 0.0,
"unit": "kW"
},
"remain": {
"value": 0,
"unit": "min"
},
"settings": {
"target_level": {
"value": 80.0,
"unit": "%"
},
"maximum_current": {
"value": 16.0,
"unit": "A"
},
"auto_unlock": "False"
},
"plugStatus": {
"connection_state": "disconnected",
"lock_state": "unlocked",
"external_power": "unavailable"
}
},
"electric_drive": {
"range": {
"value": 209.0,
"unit": "km"
},
"range_full": {
"value": 360.3,
"unit": "km"
},
"battery": {
"soc": {
"value": 58.0,
"unit": "%"
},
"temperature_max": {
"value": 295.15,
"unit": "degC"
},
"temperature_min": {
"value": 294.15,
"unit": "degC"
}
},
"odometer": {
"odometer": {
"value": 67489.0,
"unit": "km"
}
}
},
"vehicle": {
"state": "unknown vehicle state"
},
"connectivity": {
"state": "reachable"
},
"climatisation": {
"state": "off",
"remain": {
"value": 0,
"unit": "min"
},
"settings": {
"target_temperature": {
"value": 21.0,
"unit": "degC"
}
},
"environment": {
"temperature_outside": {
"value": null,
"unit": "degC"
}
}
},
"position": {
"lat": null,
"lon": null
},
"doors": {
"doors": {
"overallState": "None",
"doors": {},
"windows": {}
}
},
"procedural": {
"range_at_100": {
"value": 360.3,
"unit": "km"
}
}
}
]
}
File diff suppressed because it is too large Load Diff
+17 -7
View File
@@ -60,8 +60,9 @@ class TestJayDiffDel:
{'a': 'hamburger', 'b': 'fries'}) == {'c': 'pepsi'}
def test_nested_deleted_key(self):
# 'c' is absent from _new → None signals "delete entire key"
assert jay_diff_del({'a': 'hamburger', 'b': 'fries', 'c': {'e': 'coke', 'f': 'coffee'}},
{'a': 'hamburger', 'b': 'fries'}) == {'c': {'e': 'coke', 'f': 'coffee'}}
{'a': 'hamburger', 'b': 'fries'}) == {'c': None}
def test_nested_partial_delete(self):
assert jay_diff_del({'a': 'hamburger', 'b': 'fries', 'c': {'e': 'coke', 'f': 'coffee'}},
@@ -164,7 +165,7 @@ class TestJayDiffFullSeparate:
def test_delete_nested(self):
assert jay_diff_full({'a': 'hamburger', 'b': 'fries', 'c': {'e': 'coke', 'f': 'coffee'}},
{'a': 'hamburger', 'b': 'fries'}, self.F) \
== {'delete': {'c': {'e': 'coke', 'f': 'coffee'}}}
== {'delete': {'c': None}}
def test_nested_partial_delete(self):
assert jay_diff_full({'a': 'hamburger', 'b': 'fries', 'c': {'e': 'coke', 'f': 'coffee'}},
@@ -174,12 +175,12 @@ class TestJayDiffFullSeparate:
def test_update_and_delete(self):
assert jay_diff_full({'a': 'hamburger', 'b': 'fries', 'c': {'e': 'coke', 'f': 'coffee'}},
{'a': 'hotdog', 'b': 'potatoes'}, self.F) \
== {'delete': {'c': {'e': 'coke', 'f': 'coffee'}}, 'update': {'a': 'hotdog', 'b': 'potatoes'}}
== {'delete': {'c': None}, 'update': {'a': 'hotdog', 'b': 'potatoes'}}
def test_nested_add_delete_update(self):
assert jay_diff_full({'a': 'hamburger', 'b': 'fries', 'c': {'e': 'coke', 'f': 'coffee'}},
{'a': 'hotdog', 'b': 'potatoes', 'd': 'icecream'}, self.F) \
== {'add': {'d': 'icecream'}, 'delete': {'c': {'e': 'coke', 'f': 'coffee'}}, 'update': {'a': 'hotdog', 'b': 'potatoes'}}
== {'add': {'d': 'icecream'}, 'delete': {'c': None}, 'update': {'a': 'hotdog', 'b': 'potatoes'}}
# ── jay_diff_full (combine_upd_add=True) ──────────────────────────────────────
@@ -213,12 +214,12 @@ class TestJayDiffFullCombined:
def test_delete_nested(self):
assert jay_diff_full({'a': 'hamburger', 'b': 'fries', 'c': {'e': 'coke', 'f': 'coffee'}},
{'a': 'hamburger', 'b': 'fries'}, self.T) \
== {'delete': {'c': {'e': 'coke', 'f': 'coffee'}}}
== {'delete': {'c': None}}
def test_update_and_delete_nested(self):
assert jay_diff_full({'a': 'hamburger', 'b': 'fries', 'c': {'e': 'coke', 'f': 'coffee'}},
{'a': 'hotdog', 'b': 'potatoes'}, self.T) \
== {'delete': {'c': {'e': 'coke', 'f': 'coffee'}}, 'update_add': {'a': 'hotdog', 'b': 'potatoes'}}
== {'delete': {'c': None}, 'update_add': {'a': 'hotdog', 'b': 'potatoes'}}
def test_nested_update_add_and_delete(self):
assert jay_diff_full({'a': 'hamburger', 'b': 'fries', 'c': {'e': 'coke', 'f': 'coffee'}},
@@ -412,7 +413,7 @@ class TestCompletelyDifferentStructure:
diff = jay_diff_full(old, new)
assert diff == {
'update_add': {'electric_drive': {'range': 300, 'soc': 80}},
'delete': {'charging': {'state': 'charging', 'power': 11}},
'delete': {'charging': None},
}
def test_merge_round_trip_all_keys_replaced(self):
@@ -465,6 +466,15 @@ class TestEmptyContainers:
diff = jay_diff_del(old, new)
assert diff == {'a': {'b': 'c'}}
def test_empty_dict_preserved_after_delete_all_subkeys(self):
# When new has an empty dict at a location, the key must survive with {}
# (not be pruned away). This would break if merge incorrectly prunes empty dicts.
old = {'x': {'p': 1, 'q': 2}}
new = {'x': {}}
diff = jay_diff_full(old, new)
result = jay_merge_full(deepcopy(old), diff)
assert result == new # 'x' must remain as {}
# ── Corner cases: deep nesting ────────────────────────────────────────────────
+93
View File
@@ -0,0 +1,93 @@
"""
Round-trip tests for jay_diff using real snapshot records from ./tests/data/.
For every pair of consecutive records (within a file and across adjacent files)
we verify:
jay_merge_full(a, jay_diff_full(a, b)) == b
We also verify that diffing identical records produces an empty diff, and that
applying an empty diff is a no-op.
"""
import json
import pathlib
import pytest
from utils.jay_diff import jay_diff_full, jay_merge_full
DATA_DIR = pathlib.Path(__file__).parent / "data"
def _load_all_records() -> list[dict]:
"""Return all records from all data files, sorted by timestamp."""
records: list[dict] = []
for path in sorted(DATA_DIR.glob("*.json")):
store = json.loads(path.read_text())
records.extend(store.get("records", []))
records.sort(key=lambda r: r.get("ts", ""))
return records
ALL_RECORDS = _load_all_records()
CONSECUTIVE_PAIRS = list(zip(ALL_RECORDS, ALL_RECORDS[1:]))
class TestRealDataRoundTrip:
"""Diff+merge of every consecutive snapshot pair must reconstruct the target."""
@pytest.mark.parametrize("pair_index", range(len(CONSECUTIVE_PAIRS)))
def test_consecutive_round_trip(self, pair_index: int) -> None:
a, b = CONSECUTIVE_PAIRS[pair_index]
diff = jay_diff_full(a, b)
result = jay_merge_full(a, diff)
assert result == b, (
f"Round-trip failed for pair #{pair_index} "
f"(ts: {a.get('ts')}{b.get('ts')})"
)
@pytest.mark.parametrize("pair_index", range(len(CONSECUTIVE_PAIRS)))
def test_diff_of_identical_is_empty(self, pair_index: int) -> None:
a, _ = CONSECUTIVE_PAIRS[pair_index]
assert jay_diff_full(a, a) == {}
@pytest.mark.parametrize("pair_index", range(len(CONSECUTIVE_PAIRS)))
def test_empty_diff_is_noop(self, pair_index: int) -> None:
a, _ = CONSECUTIVE_PAIRS[pair_index]
assert jay_merge_full(a, {}) == a
class TestRealDataProperties:
"""Structural invariants on the real snapshot data."""
def test_data_dir_has_files(self) -> None:
assert len(list(DATA_DIR.glob("*.json"))) > 0, "No JSON files in tests/data/"
def test_all_records_have_timestamp(self) -> None:
for rec in ALL_RECORDS:
assert "ts" in rec, f"Record missing 'ts': {list(rec.keys())}"
def test_records_are_sorted(self) -> None:
ts_list = [r["ts"] for r in ALL_RECORDS]
assert ts_list == sorted(ts_list), "Records are not in ascending timestamp order"
def test_total_record_count(self) -> None:
assert len(ALL_RECORDS) > 100, (
f"Expected >100 records across all files, got {len(ALL_RECORDS)}"
)
def test_diff_size_smaller_than_full_snapshot(self) -> None:
"""Diffs between similar consecutive records should usually be smaller."""
savings = 0
for a, b in CONSECUTIVE_PAIRS:
diff = jay_diff_full(a, b)
if diff: # skip identical pairs
diff_len = len(json.dumps(diff))
full_len = len(json.dumps(b))
if diff_len < full_len:
savings += 1
ratio = savings / len(CONSECUTIVE_PAIRS) if CONSECUTIVE_PAIRS else 1.0
assert ratio > 0.5, (
f"Expected diffs to be smaller than full snapshots for >50% of pairs, "
f"got {ratio:.0%}"
)
+34 -28
View File
@@ -25,8 +25,16 @@ def jay_diff_add(_old, _new):
def jay_diff_del(_old, _new):
__new = deepcopy(_new)
delta = jay_diff_rev(__new, _old)
delta = {}
for k in _old:
if k in _new:
if isinstance(_old[k], dict) and isinstance(_new[k], dict):
sub = jay_diff_del(_old[k], _new[k])
if sub:
delta[k] = sub
else:
# key absent from _new: None signals "delete entire key" for dicts
delta[k] = None if isinstance(_old[k], dict) else _old[k]
return delta
@@ -100,15 +108,13 @@ def jay_merge_add(_old, _new):
def jay_merge_delete(_old, _new):
for k, v in _new.items():
for k, v in list(_new.items()):
if isinstance(v, dict) and v:
jay_merge_delete(_old[k], _new[k])
if len(_old[k].keys()) == 0:
del _old[k]
if k in _old and isinstance(_old[k], dict):
jay_merge_delete(_old[k], v)
else:
if k in _old:
del _old[k]
return _old
@@ -171,7 +177,7 @@ def _legacy_assertions() -> None:
assert result == {}
result = jay_diff_del({'a': 'hamburger', 'b': 'fries', 'c': {'e': 'coke', 'f': 'coffee'}}, {'a': 'hamburger', 'b': 'fries'})
assert result == {'c': {'e': 'coke', 'f': 'coffee'}}
assert result == {'c': None}
result = jay_diff_del({'a': 'hamburger', 'b': 'fries', 'c': {'e': 'coke', 'f': 'coffee'}}, {'c': {'e': 'coke'}})
assert result == {'a':'hamburger', 'b':'fries', 'c': {'f': 'coffee'}}
@@ -275,7 +281,7 @@ def _legacy_assertions() -> None:
assert result == {'update': {'c': 'coke'}}
result = jay_diff_full({'a': 'hamburger', 'b': 'fries', 'c': {'e': 'coke', 'f': 'coffee'}}, {'a': 'hamburger', 'b': 'fries'}, combine_upd_add)
assert result == {'delete': {'c': {'e': 'coke', 'f': 'coffee'}}}
assert result == {'delete': {'c': None}}
result = jay_diff_full({'a': 'hamburger', 'b': 'fries', 'c': {'e': 'coke', 'f': 'coffee'}}, {'a': 'hamburger', 'b': 'fries', 'c': {'f': 'coffee'}}, combine_upd_add)
assert result == {'delete': {'c': {'e': 'coke'}}}
@@ -284,25 +290,25 @@ def _legacy_assertions() -> None:
assert result == {'delete': {'a': 'hamburger', 'b': 'fries', 'c': {'f': 'coffee'}}}
result = jay_diff_full({'a':'hamburger', 'b':'fries', 'c': {'e': 'coke', 'f': 'coffee'}}, {'a':'hotdog', 'b':'potatoes'}, combine_upd_add)
assert result == {'delete': {'c': {'e': 'coke', 'f': 'coffee'}}, 'update': {'a': 'hotdog', 'b': 'potatoes'}}
assert result == {'delete': {'c': None}, 'update': {'a': 'hotdog', 'b': 'potatoes'}}
result = jay_diff_full({'a':'hamburger', 'b':'fries', 'c': {'e': 'coke', 'f': 'coffee'}}, {'c': {'e': 'pepsi'}}, combine_upd_add)
assert result == {'delete': {'a': 'hamburger', 'b': 'fries', 'c': {'f': 'coffee'}}, 'update': {'c': {'e': 'pepsi'}}}
result = jay_diff_full({'a':'hamburger', 'b':'fries', 'c': {'e': 'coke', 'f': 'coffee'}}, {'a':'hotdog', 'b':'fries'}, combine_upd_add)
assert result == {'delete': {'c': {'e': 'coke', 'f': 'coffee'}}, 'update': {'a': 'hotdog'}}
assert result == {'delete': {'c': None}, 'update': {'a': 'hotdog'}}
result = jay_diff_full({'a':'hamburger', 'b':'fries', 'c': {'e': 'coke', 'f': 'coffee'}}, {'a':'hamburger', 'b':'fries', 'c': {'e': 'pepsi', 'f': 'coffee'}}, combine_upd_add)
assert result == {'update': {'c': {'e': 'pepsi'}}}
result = jay_diff_full({'a':'hamburger', 'b':'fries', 'c': {'e': 'coke', 'f': 'coffee'}}, {'a':'hotdog', 'b':'potatoes', 'd': 'icecream'}, combine_upd_add)
assert result == {'add': {'d': 'icecream'}, 'delete': {'c': {'e': 'coke', 'f': 'coffee'}}, 'update': {'a': 'hotdog', 'b': 'potatoes'}}
assert result == {'add': {'d': 'icecream'}, 'delete': {'c': None}, 'update': {'a': 'hotdog', 'b': 'potatoes'}}
result = jay_diff_full({'a':'hamburger', 'b':'fries', 'c': {'e': 'coke', 'f': 'coffee'}}, {'c': {'e': 'pepsi', 'g': 'tea', 'h': 'cake'}, 'b':'potatoes'}, combine_upd_add)
assert result == {'add': {'c': {'g': 'tea', 'h': 'cake'}}, 'delete': {'a': 'hamburger', 'c': {'f': 'coffee'}}, 'update': {'b': 'potatoes', 'c': {'e': 'pepsi'}}}
result = jay_diff_full({'a':'hamburger', 'b':'fries', 'c': {'e': 'coke', 'f': 'coffee'}}, {'a':'hotdog', 'b':'fries'}, combine_upd_add)
assert result == {'delete': {'c': {'e': 'coke', 'f': 'coffee'}}, 'update': {'a': 'hotdog'}}
assert result == {'delete': {'c': None}, 'update': {'a': 'hotdog'}}
result = jay_diff_full({'a':'hamburger', 'b':'fries', 'c': {'e': 'coke', 'f': 'coffee'}}, {'a':'hamburger', 'b':'fries', 'c': {'e': 'pepsi', 'f': 'coffee'}}, combine_upd_add)
assert result == {'update': {'c': {'e': 'pepsi'}}}
@@ -347,7 +353,7 @@ def _legacy_assertions() -> None:
assert result == {'update_add': {'c': 'coke'}}
result = jay_diff_full({'a': 'hamburger', 'b': 'fries', 'c': {'e': 'coke', 'f': 'coffee'}}, {'a': 'hamburger', 'b': 'fries'}, combine_upd_add)
assert result == {'delete': {'c': {'e': 'coke', 'f': 'coffee'}}}
assert result == {'delete': {'c': None}}
result = jay_diff_full({'a': 'hamburger', 'b': 'fries', 'c': {'e': 'coke', 'f': 'coffee'}}, {'a': 'hamburger', 'b': 'fries', 'c': {'f': 'coffee'}}, combine_upd_add)
assert result == {'delete': {'c': {'e': 'coke'}}}
@@ -356,25 +362,25 @@ def _legacy_assertions() -> None:
assert result == {'delete': {'a': 'hamburger', 'b': 'fries', 'c': {'f': 'coffee'}}}
result = jay_diff_full({'a':'hamburger', 'b':'fries', 'c': {'e': 'coke', 'f': 'coffee'}}, {'a':'hotdog', 'b':'potatoes'}, combine_upd_add)
assert result == {'delete': {'c': {'e': 'coke', 'f': 'coffee'}}, 'update_add': {'a': 'hotdog', 'b': 'potatoes'}}
assert result == {'delete': {'c': None}, 'update_add': {'a': 'hotdog', 'b': 'potatoes'}}
result = jay_diff_full({'a':'hamburger', 'b':'fries', 'c': {'e': 'coke', 'f': 'coffee'}}, {'c': {'e': 'pepsi'}}, combine_upd_add)
assert result == {'delete': {'a': 'hamburger', 'b': 'fries', 'c': {'f': 'coffee'}}, 'update_add': {'c': {'e': 'pepsi'}}}
result = jay_diff_full({'a':'hamburger', 'b':'fries', 'c': {'e': 'coke', 'f': 'coffee'}}, {'a':'hotdog', 'b':'fries'}, combine_upd_add)
assert result == {'delete': {'c': {'e': 'coke', 'f': 'coffee'}}, 'update_add': {'a': 'hotdog'}}
assert result == {'delete': {'c': None}, 'update_add': {'a': 'hotdog'}}
result = jay_diff_full({'a':'hamburger', 'b':'fries', 'c': {'e': 'coke', 'f': 'coffee'}}, {'a':'hamburger', 'b':'fries', 'c': {'e': 'pepsi', 'f': 'coffee'}}, combine_upd_add)
assert result == {'update_add': {'c': {'e': 'pepsi'}}}
result = jay_diff_full({'a':'hamburger', 'b':'fries', 'c': {'e': 'coke', 'f': 'coffee'}}, {'a':'hotdog', 'b':'potatoes', 'd': 'icecream'}, combine_upd_add)
assert result == {'delete': {'c': {'e': 'coke', 'f': 'coffee'}}, 'update_add': {'a': 'hotdog', 'b': 'potatoes', 'd': 'icecream'}}
assert result == {'delete': {'c': None}, 'update_add': {'a': 'hotdog', 'b': 'potatoes', 'd': 'icecream'}}
result = jay_diff_full({'a':'hamburger', 'b':'fries', 'c': {'e': 'coke', 'f': 'coffee'}}, {'c': {'e': 'pepsi', 'g': 'tea', 'h': 'cake'}, 'b':'potatoes'}, combine_upd_add)
assert result == {'delete': {'a': 'hamburger', 'c': {'f': 'coffee'}}, 'update_add': {'b': 'potatoes', 'c': {'e': 'pepsi', 'g': 'tea', 'h': 'cake'}}}
result = jay_diff_full({'a':'hamburger', 'b':'fries', 'c': {'e': 'coke', 'f': 'coffee'}}, {'a':'hotdog', 'b':'fries'}, combine_upd_add)
assert result == {'delete': {'c': {'e': 'coke', 'f': 'coffee'}}, 'update_add': {'a': 'hotdog'}}
assert result == {'delete': {'c': None}, 'update_add': {'a': 'hotdog'}}
result = jay_diff_full({'a':'hamburger', 'b':'fries', 'c': {'e': 'coke', 'f': 'coffee'}}, {'a':'hamburger', 'b':'fries', 'c': {'e': 'pepsi', 'f': 'coffee'}}, combine_upd_add)
assert result == {'update_add': {'c': {'e': 'pepsi'}}}
@@ -443,7 +449,7 @@ def _legacy_assertions() -> None:
result = jay_merge_full({'a': 'hamburger', 'b': 'fries', 'c': 'pepsi'}, {'update': {'c': 'coke'}})
assert result == {'a': 'hamburger', 'b': 'fries', 'c': 'coke'}
result = jay_merge_full({'a': 'hamburger', 'b': 'fries', 'c': {'e': 'coke', 'f': 'coffee'}}, {'delete': {'c': {'e': 'coke', 'f': 'coffee'}}})
result = jay_merge_full({'a': 'hamburger', 'b': 'fries', 'c': {'e': 'coke', 'f': 'coffee'}}, {'delete': {'c': None}})
assert result == {'a': 'hamburger', 'b': 'fries'}
result = jay_merge_full({'a': 'hamburger', 'b': 'fries', 'c': {'e': 'coke', 'f': 'coffee'}}, {'delete': {'c': {'e': 'coke'}}})
@@ -452,25 +458,25 @@ def _legacy_assertions() -> None:
result = jay_merge_full({'a': 'hamburger', 'b': 'fries', 'c': {'e': 'coke', 'f': 'coffee'}}, {'delete': {'a': 'hamburger', 'b': 'fries', 'c': {'f': 'coffee'}}})
assert result == {'c': {'e': 'coke'}}
result = jay_merge_full({'a':'hamburger', 'b':'fries', 'c': {'e': 'coke', 'f': 'coffee'}}, {'delete': {'c': {'e': 'coke', 'f': 'coffee'}}, 'update': {'a': 'hotdog', 'b': 'potatoes'}})
result = jay_merge_full({'a':'hamburger', 'b':'fries', 'c': {'e': 'coke', 'f': 'coffee'}}, {'delete': {'c': None}, 'update': {'a': 'hotdog', 'b': 'potatoes'}})
assert result == {'a':'hotdog', 'b':'potatoes'}
result = jay_merge_full({'a':'hamburger', 'b':'fries', 'c': {'e': 'coke', 'f': 'coffee'}}, {'delete': {'a': 'hamburger', 'b': 'fries', 'c': {'f': 'coffee'}}, 'update': {'c': {'e': 'pepsi'}}})
assert result == {'c': {'e': 'pepsi'}}
result = jay_merge_full({'a':'hamburger', 'b':'fries', 'c': {'e': 'coke', 'f': 'coffee'}}, {'delete': {'c': {'e': 'coke', 'f': 'coffee'}}, 'update': {'a': 'hotdog'}})
result = jay_merge_full({'a':'hamburger', 'b':'fries', 'c': {'e': 'coke', 'f': 'coffee'}}, {'delete': {'c': None}, 'update': {'a': 'hotdog'}})
assert result == {'a':'hotdog', 'b':'fries'}
result = jay_merge_full({'a':'hamburger', 'b':'fries', 'c': {'e': 'coke', 'f': 'coffee'}}, {'update': {'c': {'e': 'pepsi'}}})
assert result == {'a':'hamburger', 'b':'fries', 'c': {'e': 'pepsi', 'f': 'coffee'}}
result = jay_merge_full({'a':'hamburger', 'b':'fries', 'c': {'e': 'coke', 'f': 'coffee'}}, {'add': {'d': 'icecream'}, 'delete': {'c': {'e': 'coke', 'f': 'coffee'}}, 'update': {'a': 'hotdog', 'b': 'potatoes'}})
result = jay_merge_full({'a':'hamburger', 'b':'fries', 'c': {'e': 'coke', 'f': 'coffee'}}, {'add': {'d': 'icecream'}, 'delete': {'c': None}, 'update': {'a': 'hotdog', 'b': 'potatoes'}})
assert result == {'a':'hotdog', 'b':'potatoes', 'd': 'icecream'}
result = jay_merge_full({'a':'hamburger', 'b':'fries', 'c': {'e': 'coke', 'f': 'coffee'}}, {'add': {'c': {'g': 'tea', 'h': 'cake'}}, 'delete': {'a': 'hamburger', 'c': {'f': 'coffee'}}, 'update': {'b': 'potatoes', 'c': {'e': 'pepsi'}}})
assert result == {'c': {'e': 'pepsi', 'g': 'tea', 'h': 'cake'}, 'b':'potatoes'}
result = jay_merge_full({'a':'hamburger', 'b':'fries', 'c': {'e': 'coke', 'f': 'coffee'}}, {'delete': {'c': {'e': 'coke', 'f': 'coffee'}}, 'update': {'a': 'hotdog'}})
result = jay_merge_full({'a':'hamburger', 'b':'fries', 'c': {'e': 'coke', 'f': 'coffee'}}, {'delete': {'c': None}, 'update': {'a': 'hotdog'}})
assert result == {'a':'hotdog', 'b':'fries'}
result = jay_merge_full({'a':'hamburger', 'b':'fries', 'c': {'e': 'coke', 'f': 'coffee'}}, {'update': {'c': {'e': 'pepsi'}}})
@@ -515,7 +521,7 @@ def _legacy_assertions() -> None:
result = jay_merge_full({'a': 'hamburger', 'b': 'fries', 'c': 'pepsi'}, {'update_add': {'c': 'coke'}})
assert result == {'a': 'hamburger', 'b': 'fries', 'c': 'coke'}
result = jay_merge_full({'a': 'hamburger', 'b': 'fries', 'c': {'e': 'coke', 'f': 'coffee'}}, {'delete': {'c': {'e': 'coke', 'f': 'coffee'}}})
result = jay_merge_full({'a': 'hamburger', 'b': 'fries', 'c': {'e': 'coke', 'f': 'coffee'}}, {'delete': {'c': None}})
assert result == {'a': 'hamburger', 'b': 'fries'}
result = jay_merge_full({'a': 'hamburger', 'b': 'fries', 'c': {'e': 'coke', 'f': 'coffee'}}, {'delete': {'c': {'e': 'coke'}}})
@@ -524,25 +530,25 @@ def _legacy_assertions() -> None:
result = jay_merge_full({'a': 'hamburger', 'b': 'fries', 'c': {'e': 'coke', 'f': 'coffee'}}, {'delete': {'a': 'hamburger', 'b': 'fries', 'c': {'f': 'coffee'}}})
assert result == {'c': {'e': 'coke'}}
result = jay_merge_full({'a':'hamburger', 'b':'fries', 'c': {'e': 'coke', 'f': 'coffee'}}, {'delete': {'c': {'e': 'coke', 'f': 'coffee'}}, 'update_add': {'a': 'hotdog', 'b': 'potatoes'}})
result = jay_merge_full({'a':'hamburger', 'b':'fries', 'c': {'e': 'coke', 'f': 'coffee'}}, {'delete': {'c': None}, 'update_add': {'a': 'hotdog', 'b': 'potatoes'}})
assert result == {'a':'hotdog', 'b':'potatoes'}
result = jay_merge_full({'a':'hamburger', 'b':'fries', 'c': {'e': 'coke', 'f': 'coffee'}}, {'delete': {'a': 'hamburger', 'b': 'fries', 'c': {'f': 'coffee'}}, 'update_add': {'c': {'e': 'pepsi'}}})
assert result == {'c': {'e': 'pepsi'}}
result = jay_merge_full({'a':'hamburger', 'b':'fries', 'c': {'e': 'coke', 'f': 'coffee'}}, {'delete': {'c': {'e': 'coke', 'f': 'coffee'}}, 'update_add': {'a': 'hotdog'}})
result = jay_merge_full({'a':'hamburger', 'b':'fries', 'c': {'e': 'coke', 'f': 'coffee'}}, {'delete': {'c': None}, 'update_add': {'a': 'hotdog'}})
assert result == {'a':'hotdog', 'b':'fries'}
result = jay_merge_full({'a':'hamburger', 'b':'fries', 'c': {'e': 'coke', 'f': 'coffee'}}, {'update_add': {'c': {'e': 'pepsi'}}})
assert result == {'a':'hamburger', 'b':'fries', 'c': {'e': 'pepsi', 'f': 'coffee'}}
result = jay_merge_full({'a':'hamburger', 'b':'fries', 'c': {'e': 'coke', 'f': 'coffee'}}, {'delete': {'c': {'e': 'coke', 'f': 'coffee'}}, 'update_add': {'a': 'hotdog', 'b': 'potatoes', 'd': 'icecream'}})
result = jay_merge_full({'a':'hamburger', 'b':'fries', 'c': {'e': 'coke', 'f': 'coffee'}}, {'delete': {'c': None}, 'update_add': {'a': 'hotdog', 'b': 'potatoes', 'd': 'icecream'}})
assert result == {'a':'hotdog', 'b':'potatoes', 'd': 'icecream'}
result = jay_merge_full({'a':'hamburger', 'b':'fries', 'c': {'e': 'coke', 'f': 'coffee'}}, {'delete': {'a': 'hamburger', 'c': {'f': 'coffee'}}, 'update_add': {'b': 'potatoes', 'c': {'e': 'pepsi', 'g': 'tea', 'h': 'cake'}}})
assert result == {'b':'potatoes', 'c': {'e': 'pepsi', 'g': 'tea', 'h': 'cake'}}
result = jay_merge_full({'a':'hamburger', 'b':'fries', 'c': {'e': 'coke', 'f': 'coffee'}}, {'delete': {'c': {'e': 'coke', 'f': 'coffee'}}, 'update_add': {'a': 'hotdog'}})
result = jay_merge_full({'a':'hamburger', 'b':'fries', 'c': {'e': 'coke', 'f': 'coffee'}}, {'delete': {'c': None}, 'update_add': {'a': 'hotdog'}})
assert result == {'a':'hotdog', 'b':'fries'}
result = jay_merge_full({'a':'hamburger', 'b':'fries', 'c': {'e': 'coke', 'f': 'coffee'}}, {'update_add': {'c': {'e': 'pepsi'}}})