mildly silly way of fixing constraint inheritance for cached nodes following an edit

This commit is contained in:
stopflock committed 2026-10-04 23:24:55 -05:00
1 parent c317178117
commit 6c9abba15b
3 files changed
+75 -2

No files matched your search

+3 -1
View File
@@ -30,7 +30,9 @@ class NodeCache {
id: node.id,
coord: node.coord,
tags: mergedTags,
isConstrained: node.isConstrained, // Preserve constraint information
// Once a node is known to be constrained, keep it that way - see
// NodeSpatialCache.addOrUpdateNodes for the full explanation.
isConstrained: existing.isConstrained || node.isConstrained,
);
} else {
_nodes[node.id] = node;
+7 -1
View File
@@ -58,7 +58,13 @@ class NodeSpatialCache {
id: node.id,
coord: node.coord,
tags: mergedTags,
isConstrained: node.isConstrained,
// Once a node is known to be constrained (part of a way/relation),
// keep treating it as constrained. Callers that build a fresh
// OsmNode for cache updates (e.g. after an edit upload succeeds)
// don't have way/relation data and default to false, so blindly
// taking the incoming value would "unconstrain" the node until
// the next Overpass fetch.
isConstrained: existing.isConstrained || node.isConstrained,
);
} else {
_nodes[node.id] = node;
@@ -0,0 +1,65 @@
import 'package:deflockapp/models/osm_node.dart';
import 'package:deflockapp/services/node_spatial_cache.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:latlong2/latlong.dart';
void main() {
group('NodeSpatialCache constrained flag', () {
setUp(() {
// NodeSpatialCache is a singleton - start each test from a clean slate.
NodeSpatialCache().clear();
});
test('stays constrained after an update that omits the flag', () {
final cache = NodeSpatialCache();
const nodeId = 123;
cache.addOrUpdateNodes([
OsmNode(
id: nodeId,
coord: const LatLng(0, 0),
tags: const {},
isConstrained: true,
),
]);
// Simulate what happens after an edit upload succeeds: a brand-new
// OsmNode is built from upload data, which has no way/relation
// information and so defaults isConstrained to false.
cache.addOrUpdateNodes([
OsmNode(
id: nodeId,
coord: const LatLng(1, 1),
tags: const {'amenity': 'surveillance'},
),
]);
final updated = cache.getNodeById(nodeId);
expect(updated, isNotNull);
expect(updated!.isConstrained, isTrue);
// Non-constraint fields should still be updated as normal.
expect(updated.coord, const LatLng(1, 1));
expect(updated.tags['amenity'], 'surveillance');
});
test('becomes constrained if a later update says it is', () {
final cache = NodeSpatialCache();
const nodeId = 456;
cache.addOrUpdateNodes([
OsmNode(id: nodeId, coord: const LatLng(0, 0), tags: const {}),
]);
cache.addOrUpdateNodes([
OsmNode(
id: nodeId,
coord: const LatLng(0, 0),
tags: const {},
isConstrained: true,
),
]);
expect(cache.getNodeById(nodeId)!.isConstrained, isTrue);
});
});
}