Files
clide/test/widgets/src/clide_file_image_test.dart
T
jpmschweitzerandClaude Opus 4.8 a879238102 fix image stale-render on in-place overwrite (T-312)
Image cards, thumbnails, the lightbox, and `clide image show` rendered
via Image.file, whose FileImage keys Flutter's imageCache by (path,
scale) only — so overwriting a file at the same path handed back the
previously decoded frame (hit live re-exporting a wireframe PNG). Add
ClideFileImage, a FileImage that folds mtime + size into ==/hashCode so an
in-place change is a fresh cache key (miss → re-decode), and route the
five Image.file sites through it.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-10 13:25:58 +02:00

33 lines
1.2 KiB
Dart

/// [ClideFileImage] folds mtime + size into the imageCache key so an in-place
/// overwrite re-decodes instead of returning Flutter's stale frame (T-312).
library;
import 'dart:io';
import 'package:clide/widgets/widgets.dart';
import 'package:flutter_test/flutter_test.dart';
void main() {
test('an in-place overwrite produces a different cache key', () {
final dir = Directory.systemTemp.createTempSync('clide_fileimg_');
addTearDown(() => dir.deleteSync(recursive: true));
final f = File('${dir.path}/img.bin')..writeAsBytesSync([1, 2, 3]);
final before = ClideFileImage(f.path);
// Same bytes → same key (cache hit).
expect(before, ClideFileImage(f.path));
expect(before.hashCode, ClideFileImage(f.path).hashCode);
// Overwrite at the same path with a different length → different key.
f.writeAsBytesSync([9, 8, 7, 6]);
final after = ClideFileImage(f.path);
expect(after, isNot(before));
expect(after.hashCode, isNot(before.hashCode));
expect(after.file.path, before.file.path); // same path, just a fresh key
});
test('a missing file falls back to path-only keying', () {
expect(ClideFileImage('/no/such/clide/file.png'), ClideFileImage('/no/such/clide/file.png'));
});
}