| // Copyright 2015 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| import 'package:flutter/rendering.dart'; |
| import 'package:flutter_test/flutter_test.dart'; |
| import 'package:flutter/widgets.dart'; |
| import 'package:flutter/gestures.dart'; |
| |
| void main() { |
| testWidgets('Events bubble up the tree', (WidgetTester tester) async { |
| final List<String> log = <String>[]; |
| |
| await tester.pumpWidget( |
| Listener( |
| onPointerDown: (_) { |
| log.add('top'); |
| }, |
| child: Listener( |
| onPointerDown: (_) { |
| log.add('middle'); |
| }, |
| child: DecoratedBox( |
| decoration: const BoxDecoration(), |
| child: Listener( |
| onPointerDown: (_) { |
| log.add('bottom'); |
| }, |
| child: const Text('X', textDirection: TextDirection.ltr), |
| ), |
| ), |
| ), |
| ) |
| ); |
| |
| await tester.tap(find.text('X')); |
| |
| expect(log, equals(<String>[ |
| 'bottom', |
| 'middle', |
| 'top', |
| ])); |
| }); |
| |
| group('Listener hover detection', () { |
| testWidgets('detects pointer enter', (WidgetTester tester) async { |
| PointerEnterEvent enter; |
| PointerHoverEvent move; |
| PointerExitEvent exit; |
| await tester.pumpWidget(Center( |
| child: Listener( |
| child: Container( |
| color: const Color.fromARGB(0xff, 0xff, 0x00, 0x00), |
| width: 100.0, |
| height: 100.0, |
| ), |
| onPointerEnter: (PointerEnterEvent details) => enter = details, |
| onPointerHover: (PointerHoverEvent details) => move = details, |
| onPointerExit: (PointerExitEvent details) => exit = details, |
| ), |
| )); |
| final TestGesture gesture = await tester.createGesture(kind: PointerDeviceKind.mouse); |
| await gesture.moveTo(const Offset(400.0, 300.0)); |
| await tester.pump(); |
| expect(move, isNotNull); |
| expect(move.position, equals(const Offset(400.0, 300.0))); |
| expect(enter, isNotNull); |
| expect(enter.position, equals(const Offset(400.0, 300.0))); |
| expect(exit, isNull); |
| }); |
| testWidgets('detects pointer exit', (WidgetTester tester) async { |
| PointerEnterEvent enter; |
| PointerHoverEvent move; |
| PointerExitEvent exit; |
| await tester.pumpWidget(Center( |
| child: Listener( |
| child: Container( |
| width: 100.0, |
| height: 100.0, |
| ), |
| onPointerEnter: (PointerEnterEvent details) => enter = details, |
| onPointerHover: (PointerHoverEvent details) => move = details, |
| onPointerExit: (PointerExitEvent details) => exit = details, |
| ), |
| )); |
| final TestGesture gesture = await tester.createGesture(kind: PointerDeviceKind.mouse); |
| await gesture.moveTo(const Offset(400.0, 300.0)); |
| await tester.pump(); |
| move = null; |
| enter = null; |
| await gesture.moveTo(const Offset(1.0, 1.0)); |
| await tester.pump(); |
| expect(move, isNull); |
| expect(enter, isNull); |
| expect(exit, isNotNull); |
| expect(exit.position, equals(const Offset(1.0, 1.0))); |
| }); |
| testWidgets('detects pointer exit when widget disappears', (WidgetTester tester) async { |
| PointerEnterEvent enter; |
| PointerHoverEvent move; |
| PointerExitEvent exit; |
| await tester.pumpWidget(Center( |
| child: Listener( |
| child: Container( |
| width: 100.0, |
| height: 100.0, |
| ), |
| onPointerEnter: (PointerEnterEvent details) => enter = details, |
| onPointerHover: (PointerHoverEvent details) => move = details, |
| onPointerExit: (PointerExitEvent details) => exit = details, |
| ), |
| )); |
| final RenderPointerListener renderListener = tester.renderObject(find.byType(Listener)); |
| final TestGesture gesture = await tester.createGesture(kind: PointerDeviceKind.mouse); |
| await gesture.moveTo(const Offset(400.0, 300.0)); |
| await tester.pump(); |
| expect(move, isNotNull); |
| expect(move.position, equals(const Offset(400.0, 300.0))); |
| expect(enter, isNotNull); |
| expect(enter.position, equals(const Offset(400.0, 300.0))); |
| expect(exit, isNull); |
| await tester.pumpWidget(Center( |
| child: Container( |
| width: 100.0, |
| height: 100.0, |
| ), |
| )); |
| expect(exit, isNotNull); |
| expect(exit.position, equals(const Offset(400.0, 300.0))); |
| expect(tester.binding.mouseTracker.isAnnotationAttached(renderListener.hoverAnnotation), isFalse); |
| }); |
| }); |
| } |