import 'dart:math' as math; import 'package:flutter_test/flutter_test.dart'; import 'package:observer/detection/detection_result.dart'; import 'package:observer/detection/motion_aggregator.dart'; void main() { // 96x64 图,8x8 块 → 每块 12x8 像素 test('noMotion_returnsEmpty', () { final diff = List.filled(96 * 64, 0); expect(MotionAggregator.aggregate(diff, 96, 64), isEmpty); }); test('singleBlockMotion_detectsRegion', () { final diff = List.filled(96 * 64, 0); for (var y = 24; y < 32; y++) { for (var x = 24; x < 36; x++) { diff[y * 96 + x] = 1; } } final regions = MotionAggregator.aggregate(diff, 96, 64); expect(regions.length, 1); final r = regions[0]; expect(r.left, lessThanOrEqualTo(24 / 96)); expect(r.right, greaterThanOrEqualTo(36 / 96)); expect(r.top, lessThanOrEqualTo(24 / 64)); expect(r.bottom, greaterThanOrEqualTo(32 / 64)); }); test('twoSeparateMotions_detectsTwoRegions', () { final diff = List.filled(96 * 64, 0); for (var y = 0; y < 8; y++) { for (var x = 0; x < 12; x++) { diff[y * 96 + x] = 1; } } for (var y = 48; y < 64; y++) { for (var x = 72; x < 96; x++) { diff[y * 96 + x] = 1; } } expect(MotionAggregator.aggregate(diff, 96, 64).length, 2); }); test('globalNoise_filteredOut', () { final diff = List.filled(96 * 64, 0); final rnd = math.Random(42); for (var i = 0; i < diff.length; i++) { if (rnd.nextDouble() < 0.1) diff[i] = 1; } expect(MotionAggregator.aggregate(diff, 96, 64), isEmpty); }); test('centerInRegion_matches', () { final box = DetectionResult( label: 'hare', score: 0.30, left: 0.2, top: 0.3, right: 0.4, bottom: 0.5); expect(MotionAggregator.centerInRegion(box, MotionRegion(0.1, 0.2, 0.5, 0.6)), isTrue); expect(MotionAggregator.centerInRegion(box, MotionRegion(0.6, 0.7, 0.9, 0.9)), isFalse); }); }