From b18ef006af6e8cf1aca80dd82987cc035f1f2b94 Mon Sep 17 00:00:00 2001 From: ruinivist Date: Sun, 6 Jul 2025 01:03:38 +0000 Subject: [PATCH] add tests --- lib/core/controller/controller.dart | 1 - test/canvas_view_test.dart | 73 +++++++++++++++++++++++++++++ 2 files changed, 73 insertions(+), 1 deletion(-) create mode 100644 test/canvas_view_test.dart diff --git a/lib/core/controller/controller.dart b/lib/core/controller/controller.dart index a4b2f4b..a286150 100644 --- a/lib/core/controller/controller.dart +++ b/lib/core/controller/controller.dart @@ -144,7 +144,6 @@ class CanvasController with ChangeNotifier { if (!_init) return []; final idsToBuild = _childrenWithinBuildArea(_gsCenter, _buildExtent); - print("building ${idsToBuild.length} widgets at ${_gsCenter.toPoint()} with extent ${_buildExtent.toPoint()}"); return idsToBuild.map((id) { final item = _children[id]!; diff --git a/test/canvas_view_test.dart b/test/canvas_view_test.dart new file mode 100644 index 0000000..2843579 --- /dev/null +++ b/test/canvas_view_test.dart @@ -0,0 +1,73 @@ +import 'package:flutter_test/flutter_test.dart'; +import 'package:flutter/material.dart'; +import 'package:infinite_lazy_2d_grid/core/render.dart'; +import 'package:infinite_lazy_2d_grid/core/controller/controller.dart'; +import 'package:infinite_lazy_2d_grid/core/background.dart'; + +class TestChild extends StatelessWidget { + final int index; + const TestChild({required this.index, super.key}); + @override + Widget build(BuildContext context) { + return GestureDetector(child: SizedBox(key: ValueKey('test_child_$index'), width: 50, height: 50)); + } +} + +void main() { + testWidgets('CanvasView renders only visible children and reduces count on zoom out', (WidgetTester tester) async { + final controller = CanvasController(debug: true, initialScale: 1); + for (int i = 0; i < 10000; i++) { + controller.addChild(Offset((i % 80) * 100.0, (i ~/ 80) * 100.0), () => TestChild(index: i)); + } + await tester.pumpWidget( + MaterialApp( + home: Scaffold( + body: CanvasView(controller: controller, canvasBackground: SingleColorBackround(Colors.white)), + ), + ), + ); + await tester.pumpAndSettle(); + + final initialChildren = find.byType(TestChild); + final initialCount = tester.widgetList(initialChildren).length; + + // should be less than 10000 children rendered (only those part of the visible viewport) + expect(initialCount, lessThan(10000)); + expect(initialCount, greaterThan(0)); + + controller.updateScalebyDelta(1); // 2x zoom in + await tester.pumpAndSettle(); + + // After zooming out, fewer children should be visible + final afterZoomChildren = find.byType(TestChild); + final afterZoomCount = tester.widgetList(afterZoomChildren).length; + expect(afterZoomCount, lessThan(initialCount)); + expect(afterZoomCount, greaterThan(0)); + }); + + testWidgets('CanvasView scales as expected', (WidgetTester tester) async { + final controller = CanvasController(debug: true, initialScale: 1); + controller.addChild(const Offset(0, 0), () => TestChild(index: 0)); + controller.addChild(const Offset(100, 100), () => TestChild(index: 1)); + await tester.pumpWidget( + MaterialApp( + home: Scaffold( + body: CanvasView(controller: controller, canvasBackground: SingleColorBackround(Colors.white)), + ), + ), + ); + await tester.pumpAndSettle(); + + // Initial size check + final finder = find.byType(TestChild); + expect(finder, findsNWidgets(2)); + + // Simulate a scale update to 2x, keeping the top-left at (0,0) + controller.onScaleStart(ScaleStartDetails(focalPoint: const Offset(0, 0))); + controller.onScaleUpdate(ScaleUpdateDetails(focalPoint: const Offset(0, 0), scale: 2.0)); + await tester.pumpAndSettle(); + expect(controller.scale, 2.0); + final ssPositions = controller.widgetsWithScreenPositions().map((e) => e.ssPosition).toList(); + expect(ssPositions, [Offset.zero, const Offset(200, 200)]); + }); +}