// Tests for stroke spatial bounds + broad-phase visibility (F7 board culling). import 'dart:ui' show Rect; import 'package:flutter_test/flutter_test.dart'; import 'package:badnote/editor/engine/stroke_model.dart'; import 'package:badnote/editor/engine/stroke_bounds.dart'; EditorStroke _stroke(List> pts) => EditorStroke.create( id: 's', points: [for (final p in pts) EditorPoint(x: p[0], y: p[1])], ); void main() { test('strokeBounds is the tight box over points', () { final b = strokeBounds(_stroke([ [0.1, 0.2], [0.5, 0.1], [0.3, 0.6], ]))!; expect(b.left, closeTo(0.1, 1e-9)); expect(b.top, closeTo(0.1, 1e-9)); expect(b.right, closeTo(0.5, 1e-9)); expect(b.bottom, closeTo(0.6, 1e-9)); }); test('empty stroke → null', () { expect(strokeBounds(_stroke([])), isNull); }); test('single point → zero-size rect at that point', () { final b = strokeBounds(_stroke([ [0.4, 0.7], ]))!; expect(b.width, 0); expect(b.height, 0); expect(b.left, closeTo(0.4, 1e-9)); expect(b.top, closeTo(0.7, 1e-9)); }); test('strokesBounds is the union; skips empty strokes', () { final b = strokesBounds([ _stroke([ [0.1, 0.1], [0.2, 0.2], ]), _stroke([]), // skipped _stroke([ [0.8, 0.7], ]), ])!; expect(b.left, closeTo(0.1, 1e-9)); expect(b.top, closeTo(0.1, 1e-9)); expect(b.right, closeTo(0.8, 1e-9)); expect(b.bottom, closeTo(0.7, 1e-9)); }); test('strokesBounds of all-empty → null', () { expect(strokesBounds([_stroke([]), _stroke([])]), isNull); }); group('strokeIntersects (broad-phase)', () { final view = const Rect.fromLTRB(0.0, 0.0, 0.5, 0.5); test('inside the viewport intersects', () { expect(strokeIntersects(_stroke([ [0.1, 0.1], [0.2, 0.2], ]), view), isTrue); }); test('fully outside does NOT intersect', () { expect(strokeIntersects(_stroke([ [0.8, 0.8], [0.9, 0.9], ]), view), isFalse); }); test('partial overlap intersects', () { expect(strokeIntersects(_stroke([ [0.4, 0.4], [0.7, 0.7], ]), view), isTrue); }); test('touching edge counts as intersecting', () { expect(strokeIntersects(_stroke([ [0.5, 0.5], ]), view), isTrue); }); test('empty stroke is never visible', () { expect(strokeIntersects(_stroke([]), view), isFalse); }); }); }