Skip to content

Commit 79d403d

Browse files
Replaced QR code metadata with PNG 'tEXt' property metadata encoding (Resolve #29) (#35)
1 parent 26ab527 commit 79d403d

30 files changed

+620
-307
lines changed

doc/website/source/golden-metadata/payload.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@ Every golden scene includes a metadata payload encoded within the image, which
66
tells `flutter_test_goldens` where to find each golden image, along with
77
other relevant data for verifying the test output.
88

9-
The metadata is encoded within QR codes so that they're guaranteed to always
10-
move with their associated golden pixels.
9+
The metadata is encoded within the PNG's `tEXt` property so that it's guaranteed to always
10+
move with its associated golden pixels.
1111

1212
## Schema
1313
TODO:

lib/flutter_test_goldens.dart

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ export 'src/goldens/golden_collections.dart';
55
export 'src/goldens/golden_comparisons.dart';
66
export 'src/goldens/golden_rendering.dart';
77
export 'src/goldens/golden_scenes.dart';
8-
export 'src/qr_codes/qr_code_image_scanning.dart';
98
export 'src/scenes/film_strip.dart';
109
export 'src/scenes/gallery.dart';
1110
export 'src/scenes/golden_scene.dart';

lib/src/goldens/golden_scenes.dart

Lines changed: 25 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,7 @@ import 'dart:ui' as ui;
55
import 'package:flutter/rendering.dart';
66
import 'package:flutter_test/flutter_test.dart';
77
import 'package:flutter_test_goldens/flutter_test_goldens.dart';
8-
import 'package:flutter_test_goldens/src/goldens/golden_collections.dart';
9-
import 'package:flutter_test_goldens/src/goldens/golden_rendering.dart';
10-
import 'package:flutter_test_goldens/src/qr_codes/qr_code_image_scanning.dart';
8+
import 'package:flutter_test_goldens/src/png/png_metadata.dart';
119
import 'package:image/image.dart';
1210

1311
/// Extracts a [GoldenCollection] from a golden scene within the given image [file].
@@ -20,15 +18,27 @@ import 'package:image/image.dart';
2018
GoldenCollection extractGoldenCollectionFromSceneFile(File file) {
2119
FtgLog.pipeline.fine("Extracting golden collection from golden image.");
2220

23-
// Load the scene image into memory.
24-
final sceneImage = decodePng(file.readAsBytesSync());
21+
// Read the scene PNG data into memory.
22+
final scenePngBytes = file.readAsBytesSync();
23+
24+
// Extract scene metadata from PNG.
25+
final pngText = scenePngBytes.readTextMetadata();
26+
final sceneJsonText = pngText["flutter_test_goldens"];
27+
if (sceneJsonText == null) {
28+
throw Exception("Golden image is missing scene metadata: ${file.path}");
29+
}
30+
final sceneJson = JsonDecoder().convert(sceneJsonText);
31+
final sceneMetadata = GoldenSceneMetadata.fromJson(sceneJson);
32+
33+
// Decode PNG data to an image.
34+
final sceneImage = decodePng(scenePngBytes);
2535
if (sceneImage == null) {
2636
// TODO: report error in structured way.
27-
throw Exception("Failed to load existing golden image.");
37+
throw Exception("Failed to decode golden scene as a PNG.");
2838
}
2939

3040
// Extract the golden images from the scene image.
31-
return _extractCollectionFromScene(sceneImage);
41+
return _extractCollectionFromScene(sceneMetadata, sceneImage);
3242
}
3343

3444
/// Extracts a [GoldenCollection] from a golden scene within the current widget tree.
@@ -51,7 +61,11 @@ GoldenCollection extractGoldenCollectionFromSceneFile(File file) {
5161
/// collection = await extractGoldenCollectionFromSceneWidgetTree(tester);
5262
/// });
5363
/// ```
54-
Future<GoldenCollection> extractGoldenCollectionFromSceneWidgetTree(WidgetTester tester, [Finder? sceneBounds]) async {
64+
Future<GoldenCollection> extractGoldenCollectionFromSceneWidgetTree(
65+
WidgetTester tester,
66+
GoldenSceneMetadata sceneMetadata, [
67+
Finder? sceneBounds,
68+
]) async {
5569
FtgLog.pipeline.fine("Extracting golden collection from widget tree.");
5670
final renderRepaintBoundary = _findNearestRepaintBoundary(sceneBounds ?? find.byType(GoldenSceneBounds));
5771
if (renderRepaintBoundary == null) {
@@ -67,21 +81,13 @@ Future<GoldenCollection> extractGoldenCollectionFromSceneWidgetTree(WidgetTester
6781
final treeImage = decodePng(treeRawImageData)!;
6882

6983
// Extract the golden images from the scene image.
70-
return _extractCollectionFromScene(treeImage);
84+
return _extractCollectionFromScene(sceneMetadata, treeImage);
7185
}
7286

73-
GoldenCollection _extractCollectionFromScene(Image sceneImage) {
74-
// Extract the scene metadata from the screenshot.
75-
final qrCode = sceneImage.readQrCode();
76-
if (qrCode == null) {
77-
throw Exception("Couldn't find a QR code in the golden scene image.");
78-
}
79-
final json = JsonDecoder().convert(qrCode.text);
80-
final scene = GoldenSceneMetadata.fromJson(json);
81-
87+
GoldenCollection _extractCollectionFromScene(GoldenSceneMetadata sceneMetadata, Image sceneImage) {
8288
// Cut each golden image out of the scene.
8389
final goldenImages = <String, GoldenImage>{};
84-
for (final imageRegion in scene.images) {
90+
for (final imageRegion in sceneMetadata.images) {
8591
goldenImages[imageRegion.id] = GoldenImage(
8692
imageRegion.id,
8793
copyCrop(

0 commit comments

Comments
 (0)